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