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 #include <arpa/inet.h>
     18 #include <errno.h>
     19 #include <netdb.h>
     20 #include <netinet/in.h>
     21 #include <netinet/tcp.h>
     22 #include <stdio.h>
     23 #include <stdlib.h>
     24 #include <string.h>
     25 #include <sys/socket.h>
     26 #include <sys/types.h>
     27 #include <unistd.h>
     28 
     29 #include "base/logging.h"
     30 #include "base/stringprintf.h"
     31 #include "jdwp/jdwp_priv.h"
     32 
     33 #define kBasePort           8000
     34 #define kMaxPort            8040
     35 
     36 namespace art {
     37 
     38 namespace JDWP {
     39 
     40 /*
     41  * JDWP network state.
     42  *
     43  * We only talk to one debugger at a time.
     44  */
     45 struct JdwpSocketState : public JdwpNetStateBase {
     46   uint16_t listenPort;
     47   int     listenSock;         /* listen for connection from debugger */
     48 
     49   explicit JdwpSocketState(JdwpState* state) : JdwpNetStateBase(state) {
     50     listenPort  = 0;
     51     listenSock  = -1;
     52   }
     53 
     54   virtual bool Accept();
     55   virtual bool Establish(const JdwpOptions*);
     56   virtual void Shutdown();
     57   virtual bool ProcessIncoming();
     58 
     59  private:
     60   in_addr remote_addr_;
     61   uint16_t remote_port_;
     62 };
     63 
     64 static JdwpSocketState* SocketStartup(JdwpState* state, uint16_t port, bool probe);
     65 
     66 /*
     67  * Set up some stuff for transport=dt_socket.
     68  */
     69 bool InitSocketTransport(JdwpState* state, const JdwpOptions* options) {
     70   uint16_t port = options->port;
     71 
     72   if (options->server) {
     73     if (options->port != 0) {
     74       /* try only the specified port */
     75       state->netState = SocketStartup(state, port, false);
     76     } else {
     77       /* scan through a range of ports, binding to the first available */
     78       for (port = kBasePort; port <= kMaxPort; port++) {
     79         state->netState = SocketStartup(state, port, true);
     80         if (state->netState != NULL) {
     81           break;
     82         }
     83       }
     84     }
     85     if (state->netState == NULL) {
     86       LOG(ERROR) << "JDWP net startup failed (req port=" << options->port << ")";
     87       return false;
     88     }
     89   } else {
     90     state->netState = SocketStartup(state, 0, false);
     91   }
     92 
     93   if (options->suspend) {
     94     LOG(INFO) << "JDWP will wait for debugger on port " << port;
     95   } else {
     96     LOG(INFO) << "JDWP will " << (options->server ? "listen" : "connect") << " on port " << port;
     97   }
     98 
     99   return true;
    100 }
    101 
    102 /*
    103  * Initialize JDWP stuff.
    104  *
    105  * Allocates a new state structure.  If "port" is non-zero, this also
    106  * tries to bind to a listen port.  If "port" is zero, we assume
    107  * we're preparing for an outbound connection, and return without binding
    108  * to anything.
    109  *
    110  * This may be called several times if we're probing for a port.
    111  *
    112  * Returns 0 on success.
    113  */
    114 static JdwpSocketState* SocketStartup(JdwpState* state, uint16_t port, bool probe) {
    115   JdwpSocketState* netState = new JdwpSocketState(state);
    116   if (port == 0) {
    117     return netState;
    118   }
    119 
    120   netState->listenSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    121   if (netState->listenSock < 0) {
    122     PLOG(probe ? ERROR : FATAL) << "Socket create failed";
    123     goto fail;
    124   }
    125 
    126   /* allow immediate re-use */
    127   {
    128     int one = 1;
    129     if (setsockopt(netState->listenSock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) {
    130       PLOG(probe ? ERROR : FATAL) << "setsockopt(SO_REUSEADDR) failed";
    131       goto fail;
    132     }
    133   }
    134 
    135   union {
    136     sockaddr_in  addrInet;
    137     sockaddr     addrPlain;
    138   } addr;
    139   addr.addrInet.sin_family = AF_INET;
    140   addr.addrInet.sin_port = htons(port);
    141   inet_aton("127.0.0.1", &addr.addrInet.sin_addr);
    142 
    143   if (bind(netState->listenSock, &addr.addrPlain, sizeof(addr)) != 0) {
    144     PLOG(probe ? ERROR : FATAL) << "Attempt to bind to port " << port << " failed";
    145     goto fail;
    146   }
    147 
    148   netState->listenPort = port;
    149 
    150   if (listen(netState->listenSock, 5) != 0) {
    151     PLOG(probe ? ERROR : FATAL) << "Listen failed";
    152     goto fail;
    153   }
    154 
    155   return netState;
    156 
    157  fail:
    158   netState->Shutdown();
    159   delete netState;
    160   return NULL;
    161 }
    162 
    163 /*
    164  * Shut down JDWP listener.  Don't free state.
    165  *
    166  * This may be called from a non-JDWP thread as part of shutting the
    167  * JDWP thread down.
    168  *
    169  * (This is currently called several times during startup as we probe
    170  * for an open port.)
    171  */
    172 void JdwpSocketState::Shutdown() {
    173   int listenSock = this->listenSock;
    174   int clientSock = this->clientSock;
    175 
    176   /* clear these out so it doesn't wake up and try to reuse them */
    177   this->listenSock = this->clientSock = -1;
    178 
    179   /* "shutdown" dislodges blocking read() and accept() calls */
    180   if (listenSock != -1) {
    181     shutdown(listenSock, SHUT_RDWR);
    182     close(listenSock);
    183   }
    184   if (clientSock != -1) {
    185     shutdown(clientSock, SHUT_RDWR);
    186     close(clientSock);
    187   }
    188 
    189   WakePipe();
    190 }
    191 
    192 /*
    193  * Disable the TCP Nagle algorithm, which delays transmission of outbound
    194  * packets until the previous transmissions have been acked.  JDWP does a
    195  * lot of back-and-forth with small packets, so this may help.
    196  */
    197 static int SetNoDelay(int fd) {
    198   int on = 1;
    199   int cc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
    200   CHECK_EQ(cc, 0);
    201   return cc;
    202 }
    203 
    204 /*
    205  * Accept a connection.  This will block waiting for somebody to show up.
    206  * If that's not desirable, use checkConnection() to make sure something
    207  * is pending.
    208  */
    209 bool JdwpSocketState::Accept() {
    210   union {
    211     sockaddr_in  addrInet;
    212     sockaddr     addrPlain;
    213   } addr;
    214   socklen_t addrlen;
    215   int sock;
    216 
    217   if (listenSock < 0) {
    218     return false;       /* you're not listening! */
    219   }
    220 
    221   CHECK_EQ(clientSock, -1);      /* must not already be talking */
    222 
    223   addrlen = sizeof(addr);
    224   do {
    225     sock = accept(listenSock, &addr.addrPlain, &addrlen);
    226     if (sock < 0 && errno != EINTR) {
    227       // When we call shutdown() on the socket, accept() returns with
    228       // EINVAL.  Don't gripe about it.
    229       if (errno == EINVAL) {
    230         if (VLOG_IS_ON(jdwp)) {
    231           PLOG(ERROR) << "accept failed";
    232         }
    233       } else {
    234         PLOG(ERROR) << "accept failed";
    235         return false;
    236       }
    237     }
    238   } while (sock < 0);
    239 
    240   remote_addr_ = addr.addrInet.sin_addr;
    241   remote_port_ = ntohs(addr.addrInet.sin_port);
    242   VLOG(jdwp) << "+++ accepted connection from " << inet_ntoa(remote_addr_) << ":" << remote_port_;
    243 
    244   clientSock = sock;
    245   SetAwaitingHandshake(true);
    246   input_count_ = 0;
    247 
    248   VLOG(jdwp) << "Setting TCP_NODELAY on accepted socket";
    249   SetNoDelay(clientSock);
    250 
    251   if (!MakePipe()) {
    252     return false;
    253   }
    254 
    255   return true;
    256 }
    257 
    258 /*
    259  * Create a connection to a waiting debugger.
    260  */
    261 bool JdwpSocketState::Establish(const JdwpOptions* options) {
    262   union {
    263     sockaddr_in  addrInet;
    264     sockaddr     addrPlain;
    265   } addr;
    266   hostent* pEntry;
    267 
    268   CHECK(!options->server);
    269   CHECK(!options->host.empty());
    270   CHECK_NE(options->port, 0);
    271 
    272   /*
    273    * Start by resolving the host name.
    274    */
    275 #ifdef HAVE_GETHOSTBYNAME_R
    276   hostent he;
    277   char auxBuf[128];
    278   int error;
    279   int cc = gethostbyname_r(options->host.c_str(), &he, auxBuf, sizeof(auxBuf), &pEntry, &error);
    280   if (cc != 0) {
    281     LOG(WARNING) << "gethostbyname_r('" << options->host << "') failed: " << hstrerror(error);
    282     return false;
    283   }
    284 #else
    285   h_errno = 0;
    286   pEntry = gethostbyname(options->host.c_str());
    287   if (pEntry == NULL) {
    288     PLOG(WARNING) << "gethostbyname('" << options->host << "') failed";
    289     return false;
    290   }
    291 #endif
    292 
    293   /* copy it out ASAP to minimize risk of multithreaded annoyances */
    294   memcpy(&addr.addrInet.sin_addr, pEntry->h_addr, pEntry->h_length);
    295   addr.addrInet.sin_family = pEntry->h_addrtype;
    296 
    297   addr.addrInet.sin_port = htons(options->port);
    298 
    299   LOG(INFO) << "Connecting out to " << inet_ntoa(addr.addrInet.sin_addr) << ":" << ntohs(addr.addrInet.sin_port);
    300 
    301   /*
    302    * Create a socket.
    303    */
    304   clientSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    305   if (clientSock < 0) {
    306     PLOG(ERROR) << "Unable to create socket";
    307     return false;
    308   }
    309 
    310   /*
    311    * Try to connect.
    312    */
    313   if (connect(clientSock, &addr.addrPlain, sizeof(addr)) != 0) {
    314     PLOG(ERROR) << "Unable to connect to " << inet_ntoa(addr.addrInet.sin_addr) << ":" << ntohs(addr.addrInet.sin_port);
    315     close(clientSock);
    316     clientSock = -1;
    317     return false;
    318   }
    319 
    320   LOG(INFO) << "Connection established to " << options->host << " (" << inet_ntoa(addr.addrInet.sin_addr) << ":" << ntohs(addr.addrInet.sin_port) << ")";
    321   SetAwaitingHandshake(true);
    322   input_count_ = 0;
    323 
    324   SetNoDelay(clientSock);
    325 
    326   if (!MakePipe()) {
    327     return false;
    328   }
    329 
    330   return true;
    331 }
    332 
    333 /*
    334  * Process incoming data.  If no data is available, this will block until
    335  * some arrives.
    336  *
    337  * If we get a full packet, handle it.
    338  *
    339  * To take some of the mystery out of life, we want to reject incoming
    340  * connections if we already have a debugger attached.  If we don't, the
    341  * debugger will just mysteriously hang until it times out.  We could just
    342  * close the listen socket, but there's a good chance we won't be able to
    343  * bind to the same port again, which would confuse utilities.
    344  *
    345  * Returns "false" on error (indicating that the connection has been severed),
    346  * "true" if things are still okay.
    347  */
    348 bool JdwpSocketState::ProcessIncoming() {
    349   int readCount;
    350 
    351   CHECK_NE(clientSock, -1);
    352 
    353   if (!HaveFullPacket()) {
    354     /* read some more, looping until we have data */
    355     errno = 0;
    356     while (1) {
    357       int selCount;
    358       fd_set readfds;
    359       int maxfd = -1;
    360       int fd;
    361 
    362       FD_ZERO(&readfds);
    363 
    364       /* configure fds; note these may get zapped by another thread */
    365       fd = listenSock;
    366       if (fd >= 0) {
    367         FD_SET(fd, &readfds);
    368         if (maxfd < fd) {
    369           maxfd = fd;
    370         }
    371       }
    372       fd = clientSock;
    373       if (fd >= 0) {
    374         FD_SET(fd, &readfds);
    375         if (maxfd < fd) {
    376           maxfd = fd;
    377         }
    378       }
    379       fd = wake_pipe_[0];
    380       if (fd >= 0) {
    381         FD_SET(fd, &readfds);
    382         if (maxfd < fd) {
    383           maxfd = fd;
    384         }
    385       } else {
    386         LOG(INFO) << "NOTE: entering select w/o wakepipe";
    387       }
    388 
    389       if (maxfd < 0) {
    390         VLOG(jdwp) << "+++ all fds are closed";
    391         return false;
    392       }
    393 
    394       /*
    395        * Select blocks until it sees activity on the file descriptors.
    396        * Closing the local file descriptor does not count as activity,
    397        * so we can't rely on that to wake us up (it works for read()
    398        * and accept(), but not select()).
    399        *
    400        * We can do one of three things: (1) send a signal and catch
    401        * EINTR, (2) open an additional fd ("wake pipe") and write to
    402        * it when it's time to exit, or (3) time out periodically and
    403        * re-issue the select.  We're currently using #2, as it's more
    404        * reliable than #1 and generally better than #3.  Wastes two fds.
    405        */
    406       selCount = select(maxfd+1, &readfds, NULL, NULL, NULL);
    407       if (selCount < 0) {
    408         if (errno == EINTR) {
    409           continue;
    410         }
    411         PLOG(ERROR) << "select failed";
    412         goto fail;
    413       }
    414 
    415       if (wake_pipe_[0] >= 0 && FD_ISSET(wake_pipe_[0], &readfds)) {
    416         if (listenSock >= 0) {
    417           LOG(ERROR) << "Exit wake set, but not exiting?";
    418         } else {
    419           VLOG(jdwp) << "Got wake-up signal, bailing out of select";
    420         }
    421         goto fail;
    422       }
    423       if (listenSock >= 0 && FD_ISSET(listenSock, &readfds)) {
    424         LOG(INFO) << "Ignoring second debugger -- accepting and dropping";
    425         union {
    426           sockaddr_in   addrInet;
    427           sockaddr      addrPlain;
    428         } addr;
    429         socklen_t addrlen;
    430         int tmpSock;
    431         tmpSock = accept(listenSock, &addr.addrPlain, &addrlen);
    432         if (tmpSock < 0) {
    433           LOG(INFO) << "Weird -- accept failed";
    434         } else {
    435           close(tmpSock);
    436         }
    437       }
    438       if (clientSock >= 0 && FD_ISSET(clientSock, &readfds)) {
    439         readCount = read(clientSock, input_buffer_ + input_count_, sizeof(input_buffer_) - input_count_);
    440         if (readCount < 0) {
    441           /* read failed */
    442           if (errno != EINTR) {
    443             goto fail;
    444           }
    445           VLOG(jdwp) << "+++ EINTR hit";
    446           return true;
    447         } else if (readCount == 0) {
    448           /* EOF hit -- far end went away */
    449           VLOG(jdwp) << "+++ peer disconnected";
    450           goto fail;
    451         } else {
    452           break;
    453         }
    454       }
    455     }
    456 
    457     input_count_ += readCount;
    458     if (!HaveFullPacket()) {
    459       return true;        /* still not there yet */
    460     }
    461   }
    462 
    463   /*
    464    * Special-case the initial handshake.  For some bizarre reason we're
    465    * expected to emulate bad tty settings by echoing the request back
    466    * exactly as it was sent.  Note the handshake is always initiated by
    467    * the debugger, no matter who connects to whom.
    468    *
    469    * Other than this one case, the protocol [claims to be] stateless.
    470    */
    471   if (IsAwaitingHandshake()) {
    472     if (memcmp(input_buffer_, kMagicHandshake, kMagicHandshakeLen) != 0) {
    473       LOG(ERROR) << StringPrintf("ERROR: bad handshake '%.14s'", input_buffer_);
    474       goto fail;
    475     }
    476 
    477     errno = 0;
    478     int cc = TEMP_FAILURE_RETRY(write(clientSock, input_buffer_, kMagicHandshakeLen));
    479     if (cc != kMagicHandshakeLen) {
    480       PLOG(ERROR) << "Failed writing handshake bytes (" << cc << " of " << kMagicHandshakeLen << ")";
    481       goto fail;
    482     }
    483 
    484     ConsumeBytes(kMagicHandshakeLen);
    485     SetAwaitingHandshake(false);
    486     VLOG(jdwp) << "+++ handshake complete";
    487     return true;
    488   }
    489 
    490   /*
    491    * Handle this packet.
    492    */
    493   return state_->HandlePacket();
    494 
    495  fail:
    496   Close();
    497   return false;
    498 }
    499 
    500 }  // namespace JDWP
    501 
    502 }  // namespace art
    503