Home | History | Annotate | Download | only in jdwp
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 /*
     17  * JDWP TCP socket network code.
     18  */
     19 #include "jdwp/JdwpPriv.h"
     20 #include "jdwp/JdwpHandler.h"
     21 #include "Bits.h"
     22 
     23 #include <stdlib.h>
     24 #include <unistd.h>
     25 #include <stdio.h>
     26 #include <string.h>
     27 #include <errno.h>
     28 #include <sys/types.h>
     29 #include <sys/socket.h>
     30 #include <netinet/in.h>
     31 #include <netinet/tcp.h>
     32 #include <arpa/inet.h>
     33 #include <netdb.h>
     34 
     35 #define kBasePort           8000
     36 #define kMaxPort            8040
     37 
     38 #define kInputBufferSize    8192
     39 
     40 #define kMagicHandshake     "JDWP-Handshake"
     41 #define kMagicHandshakeLen  (sizeof(kMagicHandshake)-1)
     42 
     43 // fwd
     44 static void netShutdown(JdwpNetState* state);
     45 static void netFree(JdwpNetState* state);
     46 
     47 
     48 /*
     49  * JDWP network state.
     50  *
     51  * We only talk to one debugger at a time.
     52  */
     53 struct JdwpNetState : public JdwpNetStateBase {
     54     short   listenPort;
     55     int     listenSock;         /* listen for connection from debugger */
     56     int     wakePipe[2];        /* break out of select */
     57 
     58     struct in_addr remoteAddr;
     59     unsigned short remotePort;
     60 
     61     bool    awaitingHandshake;  /* waiting for "JDWP-Handshake" */
     62 
     63     /* pending data from the network; would be more efficient as circular buf */
     64     unsigned char  inputBuffer[kInputBufferSize];
     65     int     inputCount;
     66 
     67     JdwpNetState()
     68     {
     69         listenPort  = 0;
     70         listenSock  = -1;
     71         wakePipe[0] = -1;
     72         wakePipe[1] = -1;
     73 
     74         awaitingHandshake = false;
     75 
     76         inputCount = 0;
     77     }
     78 };
     79 
     80 static JdwpNetState* netStartup(short port);
     81 
     82 /*
     83  * Set up some stuff for transport=dt_socket.
     84  */
     85 static bool prepareSocket(JdwpState* state, const JdwpStartupParams* pParams)
     86 {
     87     unsigned short port;
     88 
     89     if (pParams->server) {
     90         if (pParams->port != 0) {
     91             /* try only the specified port */
     92             port = pParams->port;
     93             state->netState = netStartup(port);
     94         } else {
     95             /* scan through a range of ports, binding to the first available */
     96             for (port = kBasePort; port <= kMaxPort; port++) {
     97                 state->netState = netStartup(port);
     98                 if (state->netState != NULL)
     99                     break;
    100             }
    101         }
    102         if (state->netState == NULL) {
    103             ALOGE("JDWP net startup failed (req port=%d)", pParams->port);
    104             return false;
    105         }
    106     } else {
    107         port = pParams->port;   // used in a debug msg later
    108         state->netState = netStartup(-1);
    109     }
    110 
    111     if (pParams->suspend)
    112         ALOGI("JDWP will wait for debugger on port %d", port);
    113     else
    114         ALOGD("JDWP will %s on port %d",
    115             pParams->server ? "listen" : "connect", port);
    116 
    117     return true;
    118 }
    119 
    120 
    121 /*
    122  * Are we still waiting for the handshake string?
    123  */
    124 static bool awaitingHandshake(JdwpState* state)
    125 {
    126     return state->netState->awaitingHandshake;
    127 }
    128 
    129 /*
    130  * Initialize JDWP stuff.
    131  *
    132  * Allocates a new state structure.  If "port" is non-negative, this also
    133  * tries to bind to a listen port.  If "port" is less than zero, we assume
    134  * we're preparing for an outbound connection, and return without binding
    135  * to anything.
    136  *
    137  * This may be called several times if we're probing for a port.
    138  *
    139  * Returns 0 on success.
    140  */
    141 static JdwpNetState* netStartup(short port)
    142 {
    143     int one = 1;
    144     JdwpNetState* netState = new JdwpNetState;
    145 
    146     if (port < 0)
    147         return netState;
    148 
    149     assert(port != 0);
    150 
    151     netState->listenSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    152     if (netState->listenSock < 0) {
    153         ALOGE("Socket create failed: %s", strerror(errno));
    154         goto fail;
    155     }
    156 
    157     /* allow immediate re-use */
    158     if (setsockopt(netState->listenSock, SOL_SOCKET, SO_REUSEADDR, &one,
    159             sizeof(one)) < 0)
    160     {
    161         ALOGE("setsockopt(SO_REUSEADDR) failed: %s", strerror(errno));
    162         goto fail;
    163     }
    164 
    165     union {
    166         struct sockaddr_in  addrInet;
    167         struct sockaddr     addrPlain;
    168     } addr;
    169     addr.addrInet.sin_family = AF_INET;
    170     addr.addrInet.sin_port = htons(port);
    171     inet_aton("127.0.0.1", &addr.addrInet.sin_addr);
    172 
    173     if (bind(netState->listenSock, &addr.addrPlain, sizeof(addr)) != 0) {
    174         ALOGV("attempt to bind to port %u failed: %s", port, strerror(errno));
    175         goto fail;
    176     }
    177 
    178     netState->listenPort = port;
    179     LOGVV("+++ bound to port %d", netState->listenPort);
    180 
    181     if (listen(netState->listenSock, 5) != 0) {
    182         ALOGE("Listen failed: %s", strerror(errno));
    183         goto fail;
    184     }
    185 
    186     return netState;
    187 
    188 fail:
    189     netShutdown(netState);
    190     netFree(netState);
    191     return NULL;
    192 }
    193 
    194 /*
    195  * Shut down JDWP listener.  Don't free state.
    196  *
    197  * Note that "netState" may be partially initialized if "startup" failed.
    198  *
    199  * This may be called from a non-JDWP thread as part of shutting the
    200  * JDWP thread down.
    201  *
    202  * (This is currently called several times during startup as we probe
    203  * for an open port.)
    204  */
    205 static void netShutdown(JdwpNetState* netState)
    206 {
    207     if (netState == NULL)
    208         return;
    209 
    210     int listenSock = netState->listenSock;
    211     int clientSock = netState->clientSock;
    212 
    213     /* clear these out so it doesn't wake up and try to reuse them */
    214     netState->listenSock = netState->clientSock = -1;
    215 
    216     /* "shutdown" dislodges blocking read() and accept() calls */
    217     if (listenSock >= 0) {
    218         shutdown(listenSock, SHUT_RDWR);
    219         close(listenSock);
    220     }
    221     if (clientSock >= 0) {
    222         shutdown(clientSock, SHUT_RDWR);
    223         close(clientSock);
    224     }
    225 
    226     /* if we might be sitting in select, kick us loose */
    227     if (netState->wakePipe[1] >= 0) {
    228         ALOGV("+++ writing to wakePipe");
    229         TEMP_FAILURE_RETRY(write(netState->wakePipe[1], "", 1));
    230     }
    231 }
    232 static void netShutdownExtern(JdwpState* state)
    233 {
    234     netShutdown(state->netState);
    235 }
    236 
    237 /*
    238  * Free JDWP state.
    239  *
    240  * Call this after shutting the network down with netShutdown().
    241  */
    242 static void netFree(JdwpNetState* netState)
    243 {
    244     if (netState == NULL)
    245         return;
    246     assert(netState->listenSock == -1);
    247     assert(netState->clientSock == -1);
    248 
    249     if (netState->wakePipe[0] >= 0) {
    250         close(netState->wakePipe[0]);
    251         netState->wakePipe[0] = -1;
    252     }
    253     if (netState->wakePipe[1] >= 0) {
    254         close(netState->wakePipe[1]);
    255         netState->wakePipe[1] = -1;
    256     }
    257 
    258     delete netState;
    259 }
    260 static void netFreeExtern(JdwpState* state)
    261 {
    262     netFree(state->netState);
    263 }
    264 
    265 /*
    266  * Returns "true" if we're connected to a debugger.
    267  */
    268 static bool isConnected(JdwpState* state)
    269 {
    270     return (state->netState != NULL &&
    271             state->netState->clientSock >= 0);
    272 }
    273 
    274 /*
    275  * Returns "true" if the fd is ready, "false" if not.
    276  */
    277 #if 0
    278 static bool isFdReadable(int sock)
    279 {
    280     fd_set readfds;
    281     struct timeval tv;
    282     int count;
    283 
    284     FD_ZERO(&readfds);
    285     FD_SET(sock, &readfds);
    286 
    287     tv.tv_sec = 0;
    288     tv.tv_usec = 0;
    289     count = select(sock+1, &readfds, NULL, NULL, &tv);
    290     if (count <= 0)
    291         return false;
    292 
    293     if (FD_ISSET(sock, &readfds))   /* make sure it's our fd */
    294         return true;
    295 
    296     ALOGE("WEIRD: odd behavior in select (count=%d)", count);
    297     return false;
    298 }
    299 #endif
    300 
    301 #if 0
    302 /*
    303  * Check to see if we have a pending connection from the debugger.
    304  *
    305  * Returns true on success (meaning a connection is available).
    306  */
    307 static bool checkConnection(JdwpState* state)
    308 {
    309     JdwpNetState* netState = state->netState;
    310 
    311     assert(netState->listenSock >= 0);
    312     /* not expecting to be called when debugger is actively connected */
    313     assert(netState->clientSock < 0);
    314 
    315     if (!isFdReadable(netState->listenSock))
    316         return false;
    317     return true;
    318 }
    319 #endif
    320 
    321 /*
    322  * Disable the TCP Nagle algorithm, which delays transmission of outbound
    323  * packets until the previous transmissions have been acked.  JDWP does a
    324  * lot of back-and-forth with small packets, so this may help.
    325  */
    326 static int setNoDelay(int fd)
    327 {
    328     int cc, on = 1;
    329 
    330     cc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
    331     assert(cc == 0);
    332     return cc;
    333 }
    334 
    335 /*
    336  * Accept a connection.  This will block waiting for somebody to show up.
    337  * If that's not desirable, use checkConnection() to make sure something
    338  * is pending.
    339  */
    340 static bool acceptConnection(JdwpState* state)
    341 {
    342     JdwpNetState* netState = state->netState;
    343     union {
    344         struct sockaddr_in  addrInet;
    345         struct sockaddr     addrPlain;
    346     } addr;
    347     socklen_t addrlen;
    348     int sock;
    349 
    350     if (netState->listenSock < 0)
    351         return false;       /* you're not listening! */
    352 
    353     assert(netState->clientSock < 0);      /* must not already be talking */
    354 
    355     addrlen = sizeof(addr);
    356     do {
    357         sock = accept(netState->listenSock, &addr.addrPlain, &addrlen);
    358         if (sock < 0 && errno != EINTR) {
    359             // When we call shutdown() on the socket, accept() returns with
    360             // EINVAL.  Don't gripe about it.
    361             if (errno == EINVAL)
    362                 LOGVV("accept failed: %s", strerror(errno));
    363             else
    364                 ALOGE("accept failed: %s", strerror(errno));
    365             return false;
    366         }
    367     } while (sock < 0);
    368 
    369     netState->remoteAddr = addr.addrInet.sin_addr;
    370     netState->remotePort = ntohs(addr.addrInet.sin_port);
    371     ALOGV("+++ accepted connection from %s:%u",
    372         inet_ntoa(netState->remoteAddr), netState->remotePort);
    373 
    374     netState->clientSock = sock;
    375     netState->awaitingHandshake = true;
    376     netState->inputCount = 0;
    377 
    378     ALOGV("Setting TCP_NODELAY on accepted socket");
    379     setNoDelay(netState->clientSock);
    380 
    381     if (pipe(netState->wakePipe) < 0) {
    382         ALOGE("pipe failed");
    383         return false;
    384     }
    385 
    386     return true;
    387 }
    388 
    389 /*
    390  * Create a connection to a waiting debugger.
    391  */
    392 static bool establishConnection(JdwpState* state)
    393 {
    394     union {
    395         struct sockaddr_in  addrInet;
    396         struct sockaddr     addrPlain;
    397     } addr;
    398     struct hostent* pEntry;
    399     int h_errno;
    400 
    401     assert(state != NULL && state->netState != NULL);
    402     assert(!state->params.server);
    403     assert(state->params.host[0] != '\0');
    404     assert(state->params.port != 0);
    405 
    406     /*
    407      * Start by resolving the host name.
    408      */
    409 //#undef HAVE_GETHOSTBYNAME_R
    410 //#warning "forcing non-R"
    411 #ifdef HAVE_GETHOSTBYNAME_R
    412     struct hostent he;
    413     char auxBuf[128];
    414     int cc = gethostbyname_r(state->params.host, &he, auxBuf, sizeof(auxBuf),
    415             &pEntry, &h_errno);
    416     if (cc != 0) {
    417         ALOGW("gethostbyname_r('%s') failed: %s",
    418             state->params.host, strerror(errno));
    419         return false;
    420     }
    421 
    422 #else
    423     h_errno = 0;
    424     pEntry = gethostbyname(state->params.host);
    425     if (pEntry == NULL) {
    426         ALOGW("gethostbyname('%s') failed: %s",
    427             state->params.host, strerror(h_errno));
    428         return false;
    429     }
    430 #endif
    431 
    432     /* copy it out ASAP to minimize risk of multithreaded annoyances */
    433     memcpy(&addr.addrInet.sin_addr, pEntry->h_addr, pEntry->h_length);
    434     addr.addrInet.sin_family = pEntry->h_addrtype;
    435 
    436     addr.addrInet.sin_port = htons(state->params.port);
    437 
    438     ALOGI("Connecting out to '%s' %d",
    439         inet_ntoa(addr.addrInet.sin_addr), ntohs(addr.addrInet.sin_port));
    440 
    441     /*
    442      * Create a socket.
    443      */
    444     JdwpNetState* netState;
    445     netState = state->netState;
    446     netState->clientSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    447     if (netState->clientSock < 0) {
    448         ALOGE("Unable to create socket: %s", strerror(errno));
    449         return false;
    450     }
    451 
    452     /*
    453      * Try to connect.
    454      */
    455     if (connect(netState->clientSock, &addr.addrPlain, sizeof(addr)) != 0) {
    456         ALOGE("Unable to connect to %s:%d: %s",
    457             inet_ntoa(addr.addrInet.sin_addr), ntohs(addr.addrInet.sin_port),
    458             strerror(errno));
    459         close(netState->clientSock);
    460         netState->clientSock = -1;
    461         return false;
    462     }
    463 
    464     ALOGI("Connection established to %s (%s:%d)",
    465         state->params.host, inet_ntoa(addr.addrInet.sin_addr),
    466         ntohs(addr.addrInet.sin_port));
    467     netState->awaitingHandshake = true;
    468     netState->inputCount = 0;
    469 
    470     setNoDelay(netState->clientSock);
    471 
    472     if (pipe(netState->wakePipe) < 0) {
    473         ALOGE("pipe failed");
    474         return false;
    475     }
    476 
    477     return true;
    478 }
    479 
    480 /*
    481  * Close the connection to the debugger.
    482  *
    483  * Reset the state so we're ready to receive a new connection.
    484  */
    485 static void closeConnection(JdwpState* state)
    486 {
    487     JdwpNetState* netState;
    488 
    489     assert(state != NULL && state->netState != NULL);
    490 
    491     netState = state->netState;
    492     if (netState->clientSock < 0)
    493         return;
    494 
    495     ALOGV("+++ closed connection to %s:%u",
    496         inet_ntoa(netState->remoteAddr), netState->remotePort);
    497 
    498     close(netState->clientSock);
    499     netState->clientSock = -1;
    500 
    501     return;
    502 }
    503 
    504 /*
    505  * Figure out if we have a full packet in the buffer.
    506  */
    507 static bool haveFullPacket(JdwpNetState* netState)
    508 {
    509     long length;
    510 
    511     if (netState->awaitingHandshake)
    512         return (netState->inputCount >= (int) kMagicHandshakeLen);
    513 
    514     if (netState->inputCount < 4)
    515         return false;
    516 
    517     length = get4BE(netState->inputBuffer);
    518     return (netState->inputCount >= length);
    519 }
    520 
    521 /*
    522  * Consume bytes from the buffer.
    523  *
    524  * This would be more efficient with a circular buffer.  However, we're
    525  * usually only going to find one packet, which is trivial to handle.
    526  */
    527 static void consumeBytes(JdwpNetState* netState, int count)
    528 {
    529     assert(count > 0);
    530     assert(count <= netState->inputCount);
    531 
    532     if (count == netState->inputCount) {
    533         netState->inputCount = 0;
    534         return;
    535     }
    536 
    537     memmove(netState->inputBuffer, netState->inputBuffer + count,
    538         netState->inputCount - count);
    539     netState->inputCount -= count;
    540 }
    541 
    542 /*
    543  * Dump the contents of a packet to stdout.
    544  */
    545 #if 0
    546 static void dumpPacket(const unsigned char* packetBuf)
    547 {
    548     const unsigned char* buf = packetBuf;
    549     u4 length, id;
    550     u1 flags, cmdSet, cmd;
    551     u2 error;
    552     bool reply;
    553     int dataLen;
    554 
    555     cmd = cmdSet = 0xcc;
    556 
    557     length = read4BE(&buf);
    558     id = read4BE(&buf);
    559     flags = read1(&buf);
    560     if ((flags & kJDWPFlagReply) != 0) {
    561         reply = true;
    562         error = read2BE(&buf);
    563     } else {
    564         reply = false;
    565         cmdSet = read1(&buf);
    566         cmd = read1(&buf);
    567     }
    568 
    569     dataLen = length - (buf - packetBuf);
    570 
    571     ALOGV("--- %s: dataLen=%u id=0x%08x flags=0x%02x cmd=%d/%d",
    572         reply ? "reply" : "req",
    573         dataLen, id, flags, cmdSet, cmd);
    574     if (dataLen > 0)
    575         dvmPrintHexDumpDbg(buf, dataLen, LOG_TAG);
    576 }
    577 #endif
    578 
    579 /*
    580  * Handle a packet.  Returns "false" if we encounter a connection-fatal error.
    581  */
    582 static bool handlePacket(JdwpState* state)
    583 {
    584     JdwpNetState* netState = state->netState;
    585     const unsigned char* buf = netState->inputBuffer;
    586     JdwpReqHeader hdr;
    587     u4 length, id;
    588     u1 flags, cmdSet, cmd;
    589     u2 error;
    590     bool reply;
    591     int dataLen;
    592 
    593     cmd = cmdSet = 0;       // shut up gcc
    594 
    595     /*dumpPacket(netState->inputBuffer);*/
    596 
    597     length = read4BE(&buf);
    598     id = read4BE(&buf);
    599     flags = read1(&buf);
    600     if ((flags & kJDWPFlagReply) != 0) {
    601         reply = true;
    602         error = read2BE(&buf);
    603     } else {
    604         reply = false;
    605         cmdSet = read1(&buf);
    606         cmd = read1(&buf);
    607     }
    608 
    609     assert((int) length <= netState->inputCount);
    610     dataLen = length - (buf - netState->inputBuffer);
    611 
    612     if (!reply) {
    613         ExpandBuf* pReply = expandBufAlloc();
    614 
    615         hdr.length = length;
    616         hdr.id = id;
    617         hdr.cmdSet = cmdSet;
    618         hdr.cmd = cmd;
    619         dvmJdwpProcessRequest(state, &hdr, buf, dataLen, pReply);
    620         if (expandBufGetLength(pReply) > 0) {
    621             ssize_t cc = netState->writePacket(pReply);
    622 
    623             if (cc != (ssize_t) expandBufGetLength(pReply)) {
    624                 ALOGE("Failed sending reply to debugger: %s", strerror(errno));
    625                 expandBufFree(pReply);
    626                 return false;
    627             }
    628         } else {
    629             ALOGW("No reply created for set=%d cmd=%d", cmdSet, cmd);
    630         }
    631         expandBufFree(pReply);
    632     } else {
    633         ALOGV("reply?!");
    634         assert(false);
    635     }
    636 
    637     ALOGV("----------");
    638 
    639     consumeBytes(netState, length);
    640     return true;
    641 }
    642 
    643 /*
    644  * Process incoming data.  If no data is available, this will block until
    645  * some arrives.
    646  *
    647  * If we get a full packet, handle it.
    648  *
    649  * To take some of the mystery out of life, we want to reject incoming
    650  * connections if we already have a debugger attached.  If we don't, the
    651  * debugger will just mysteriously hang until it times out.  We could just
    652  * close the listen socket, but there's a good chance we won't be able to
    653  * bind to the same port again, which would confuse utilities.
    654  *
    655  * Returns "false" on error (indicating that the connection has been severed),
    656  * "true" if things are still okay.
    657  */
    658 static bool processIncoming(JdwpState* state)
    659 {
    660     JdwpNetState* netState = state->netState;
    661     int readCount;
    662 
    663     assert(netState->clientSock >= 0);
    664 
    665     if (!haveFullPacket(netState)) {
    666         /* read some more, looping until we have data */
    667         errno = 0;
    668         while (1) {
    669             int selCount;
    670             fd_set readfds;
    671             int maxfd;
    672             int fd;
    673 
    674             maxfd = netState->listenSock;
    675             if (netState->clientSock > maxfd)
    676                 maxfd = netState->clientSock;
    677             if (netState->wakePipe[0] > maxfd)
    678                 maxfd = netState->wakePipe[0];
    679 
    680             if (maxfd < 0) {
    681                 ALOGV("+++ all fds are closed");
    682                 return false;
    683             }
    684 
    685             FD_ZERO(&readfds);
    686 
    687             /* configure fds; note these may get zapped by another thread */
    688             fd = netState->listenSock;
    689             if (fd >= 0)
    690                 FD_SET(fd, &readfds);
    691             fd = netState->clientSock;
    692             if (fd >= 0)
    693                 FD_SET(fd, &readfds);
    694             fd = netState->wakePipe[0];
    695             if (fd >= 0) {
    696                 FD_SET(fd, &readfds);
    697             } else {
    698                 ALOGI("NOTE: entering select w/o wakepipe");
    699             }
    700 
    701             /*
    702              * Select blocks until it sees activity on the file descriptors.
    703              * Closing the local file descriptor does not count as activity,
    704              * so we can't rely on that to wake us up (it works for read()
    705              * and accept(), but not select()).
    706              *
    707              * We can do one of three things: (1) send a signal and catch
    708              * EINTR, (2) open an additional fd ("wakePipe") and write to
    709              * it when it's time to exit, or (3) time out periodically and
    710              * re-issue the select.  We're currently using #2, as it's more
    711              * reliable than #1 and generally better than #3.  Wastes two fds.
    712              */
    713             selCount = select(maxfd+1, &readfds, NULL, NULL, NULL);
    714             if (selCount < 0) {
    715                 if (errno == EINTR)
    716                     continue;
    717                 ALOGE("select failed: %s", strerror(errno));
    718                 goto fail;
    719             }
    720 
    721             if (netState->wakePipe[0] >= 0 &&
    722                 FD_ISSET(netState->wakePipe[0], &readfds))
    723             {
    724                 if (netState->listenSock >= 0)
    725                     ALOGE("Exit wake set, but not exiting?");
    726                 else
    727                     ALOGD("Got wake-up signal, bailing out of select");
    728                 goto fail;
    729             }
    730             if (netState->listenSock >= 0 &&
    731                 FD_ISSET(netState->listenSock, &readfds))
    732             {
    733                 ALOGI("Ignoring second debugger -- accepting and dropping");
    734                 union {
    735                     struct sockaddr_in   addrInet;
    736                     struct sockaddr      addrPlain;
    737                 } addr;
    738                 socklen_t addrlen;
    739                 int tmpSock;
    740                 tmpSock = accept(netState->listenSock, &addr.addrPlain,
    741                                 &addrlen);
    742                 if (tmpSock < 0)
    743                     ALOGI("Weird -- accept failed");
    744                 else
    745                     close(tmpSock);
    746             }
    747             if (netState->clientSock >= 0 &&
    748                 FD_ISSET(netState->clientSock, &readfds))
    749             {
    750                 readCount = read(netState->clientSock,
    751                                 netState->inputBuffer + netState->inputCount,
    752                     sizeof(netState->inputBuffer) - netState->inputCount);
    753                 if (readCount < 0) {
    754                     /* read failed */
    755                     if (errno != EINTR)
    756                         goto fail;
    757                     ALOGD("+++ EINTR hit");
    758                     return true;
    759                 } else if (readCount == 0) {
    760                     /* EOF hit -- far end went away */
    761                     ALOGD("+++ peer disconnected");
    762                     goto fail;
    763                 } else
    764                     break;
    765             }
    766         }
    767 
    768         netState->inputCount += readCount;
    769         if (!haveFullPacket(netState))
    770             return true;        /* still not there yet */
    771     }
    772 
    773     /*
    774      * Special-case the initial handshake.  For some bizarre reason we're
    775      * expected to emulate bad tty settings by echoing the request back
    776      * exactly as it was sent.  Note the handshake is always initiated by
    777      * the debugger, no matter who connects to whom.
    778      *
    779      * Other than this one case, the protocol [claims to be] stateless.
    780      */
    781     if (netState->awaitingHandshake) {
    782         int cc;
    783 
    784         if (memcmp(netState->inputBuffer,
    785                 kMagicHandshake, kMagicHandshakeLen) != 0)
    786         {
    787             ALOGE("ERROR: bad handshake '%.14s'", netState->inputBuffer);
    788             goto fail;
    789         }
    790 
    791         errno = 0;
    792         cc = TEMP_FAILURE_RETRY(write(netState->clientSock, netState->inputBuffer,
    793                                       kMagicHandshakeLen));
    794         if (cc != kMagicHandshakeLen) {
    795             ALOGE("Failed writing handshake bytes: %s (%d of %d)",
    796                 strerror(errno), cc, (int) kMagicHandshakeLen);
    797             goto fail;
    798         }
    799 
    800         consumeBytes(netState, kMagicHandshakeLen);
    801         netState->awaitingHandshake = false;
    802         ALOGV("+++ handshake complete");
    803         return true;
    804     }
    805 
    806     /*
    807      * Handle this packet.
    808      */
    809     return handlePacket(state);
    810 
    811 fail:
    812     closeConnection(state);
    813     return false;
    814 }
    815 
    816 /*
    817  * Send a request.
    818  *
    819  * The entire packet must be sent with a single write() call to avoid
    820  * threading issues.
    821  *
    822  * Returns "true" if it was sent successfully.
    823  */
    824 static bool sendRequest(JdwpState* state, ExpandBuf* pReq)
    825 {
    826     JdwpNetState* netState = state->netState;
    827 
    828     /*dumpPacket(expandBufGetBuffer(pReq));*/
    829     if (netState->clientSock < 0) {
    830         /* can happen with some DDMS events */
    831         ALOGV("NOT sending request -- no debugger is attached");
    832         return false;
    833     }
    834 
    835     errno = 0;
    836     ssize_t cc = netState->writePacket(pReq);
    837 
    838     if (cc != (ssize_t) expandBufGetLength(pReq)) {
    839         ALOGE("Failed sending req to debugger: %s (%d of %d)",
    840             strerror(errno), (int) cc, (int) expandBufGetLength(pReq));
    841         return false;
    842     }
    843 
    844     return true;
    845 }
    846 
    847 /*
    848  * Send a request that was split into multiple buffers.
    849  *
    850  * The entire packet must be sent with a single writev() call to avoid
    851  * threading issues.
    852  *
    853  * Returns "true" if it was sent successfully.
    854  */
    855 static bool sendBufferedRequest(JdwpState* state, const struct iovec* iov,
    856     int iovcnt)
    857 {
    858     JdwpNetState* netState = state->netState;
    859 
    860     if (netState->clientSock < 0) {
    861         /* can happen with some DDMS events */
    862         ALOGV("NOT sending request -- no debugger is attached");
    863         return false;
    864     }
    865 
    866     size_t expected = 0;
    867     int i;
    868     for (i = 0; i < iovcnt; i++)
    869         expected += iov[i].iov_len;
    870 
    871     ssize_t actual = netState->writeBufferedPacket(iov, iovcnt);
    872 
    873     if ((size_t)actual != expected) {
    874         ALOGE("Failed sending b-req to debugger: %s (%d of %zu)",
    875             strerror(errno), (int) actual, expected);
    876         return false;
    877     }
    878 
    879     return true;
    880 }
    881 
    882 
    883 /*
    884  * Our functions.
    885  *
    886  * We can't generally share the implementations with other transports,
    887  * even if they're also socket-based, because our JdwpNetState will be
    888  * different from theirs.
    889  */
    890 static const JdwpTransport socketTransport = {
    891     prepareSocket,
    892     acceptConnection,
    893     establishConnection,
    894     closeConnection,
    895     netShutdownExtern,
    896     netFreeExtern,
    897     isConnected,
    898     awaitingHandshake,
    899     processIncoming,
    900     sendRequest,
    901     sendBufferedRequest,
    902 };
    903 
    904 /*
    905  * Return our set.
    906  */
    907 const JdwpTransport* dvmJdwpSocketTransport()
    908 {
    909     return &socketTransport;
    910 }
    911