Loading adb/adb.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -963,9 +963,11 @@ int handle_host_request(const char* service, TransportType type, fflush(stdout); SendOkay(reply_fd); // At least on Windows, if we exit() without shutdown(SD_SEND) or // closesocket(), the client's next recv() will error-out with // WSAECONNRESET and they'll never read the OKAY. // On Windows, if the process exits with open sockets that // shutdown(SD_SEND) has not been called on, TCP RST segments will be // sent to the peers which will cause their next recv() to error-out // with WSAECONNRESET. In the case of this code, that means the client // may not read the OKAY sent above. adb_shutdown(reply_fd); exit(0); Loading adb/adb_client.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -206,6 +206,7 @@ int adb_connect(const std::string& service, std::string* error) { return -1; } ReadOrderlyShutdown(fd); adb_close(fd); if (sscanf(&version_string[0], "%04x", &version) != 1) { Loading @@ -227,6 +228,7 @@ int adb_connect(const std::string& service, std::string* error) { version, ADB_SERVER_VERSION); fd = _adb_connect("host:kill", error); if (fd >= 0) { ReadOrderlyShutdown(fd); adb_close(fd); } else { // If we couldn't connect to the server or had some other error, Loading Loading @@ -271,6 +273,8 @@ bool adb_command(const std::string& service) { return false; } ReadOrderlyShutdown(fd); adb_close(fd); return true; } Loading @@ -286,5 +290,8 @@ bool adb_query(const std::string& service, std::string* result, std::string* err adb_close(fd); return false; } ReadOrderlyShutdown(fd); adb_close(fd); return true; } adb/adb_io.cpp +40 −0 Original line number Diff line number Diff line Loading @@ -137,3 +137,43 @@ bool WriteFdFmt(int fd, const char* fmt, ...) { return WriteFdExactly(fd, str); } bool ReadOrderlyShutdown(int fd) { char buf[16]; // Only call this function if you're sure that the peer does // orderly/graceful shutdown of the socket, closing the socket so that // adb_read() will return 0. If the peer keeps the socket open, adb_read() // will never return. int result = adb_read(fd, buf, sizeof(buf)); if (result == -1) { // If errno is EAGAIN, that means this function was called on a // nonblocking socket and it would have blocked (which would be bad // because we'd probably block the main thread where nonblocking IO is // done). Don't do that. If you have a nonblocking socket, use the // fdevent APIs to get called on FDE_READ, and then call this function // if you really need to, but it shouldn't be needed for server sockets. CHECK_NE(errno, EAGAIN); // Note that on Windows, orderly shutdown sometimes causes // recv() == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET. That // can be ignored. return false; } else if (result == 0) { // Peer has performed an orderly/graceful shutdown. return true; } else { // Unexpectedly received data. This is essentially a protocol error // because you should not call this function unless you expect no more // data. We don't repeatedly call adb_read() until we get zero because // we don't know how long that would take, but we do know that the // caller wants to close the socket soon. VLOG(RWX) << "ReadOrderlyShutdown(" << fd << ") unexpectedly read " << dump_hex(buf, result); // Shutdown the socket to prevent the caller from reading or writing to // it which doesn't make sense if we just read and discarded some data. adb_shutdown(fd); errno = EINVAL; return false; } } adb/adb_io.h +18 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,24 @@ bool ReadProtocolString(int fd, std::string* s, std::string* error); // If this function fails, the contents of buf are undefined. bool ReadFdExactly(int fd, void* buf, size_t len); // Given a client socket, wait for orderly/graceful shutdown. Call this: // // * Before closing a client socket. // * Only when no more data is expected to come in. // * Only when the server is not waiting for data from the client (because then // the client and server will deadlock waiting for each other). // * Only when the server is expected to close its socket right now. // * Don't call shutdown(SHUT_WR) before calling this because that will shutdown // the client socket early, defeating the purpose of calling this. // // Waiting for orderly/graceful shutdown of the server socket will cause the // server socket to close before the client socket. That prevents the client // socket from staying in TIME_WAIT which eventually causes subsequent // connect()s from the client to fail with WSAEADDRINUSE on Windows. // Returns true if it is sure that orderly/graceful shutdown has occurred with // no additional data read from the server. bool ReadOrderlyShutdown(int fd); // Writes exactly len bytes from buf to fd. // // Returns false if there is an error or if the fd was closed before the write Loading adb/commandline.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -649,6 +649,7 @@ static int adb_download_buffer(const char *service, const char *fn, const void* std::string error; adb_status(fd, &error); fprintf(stderr,"* failed to write data '%s' *\n", error.c_str()); adb_close(fd); return -1; } sz -= xfer; Loading @@ -664,6 +665,7 @@ static int adb_download_buffer(const char *service, const char *fn, const void* if (!adb_status(fd, &error)) { fprintf(stderr,"* error response '%s' *\n", error.c_str()); adb_close(fd); return -1; } Loading Loading @@ -1468,6 +1470,7 @@ int adb_commandline(int argc, const char **argv) { } else { // Successfully connected, kill command sent, okay status came back. // Server should exit() in a moment, if not already. ReadOrderlyShutdown(fd); adb_close(fd); return 0; } Loading Loading
adb/adb.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -963,9 +963,11 @@ int handle_host_request(const char* service, TransportType type, fflush(stdout); SendOkay(reply_fd); // At least on Windows, if we exit() without shutdown(SD_SEND) or // closesocket(), the client's next recv() will error-out with // WSAECONNRESET and they'll never read the OKAY. // On Windows, if the process exits with open sockets that // shutdown(SD_SEND) has not been called on, TCP RST segments will be // sent to the peers which will cause their next recv() to error-out // with WSAECONNRESET. In the case of this code, that means the client // may not read the OKAY sent above. adb_shutdown(reply_fd); exit(0); Loading
adb/adb_client.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -206,6 +206,7 @@ int adb_connect(const std::string& service, std::string* error) { return -1; } ReadOrderlyShutdown(fd); adb_close(fd); if (sscanf(&version_string[0], "%04x", &version) != 1) { Loading @@ -227,6 +228,7 @@ int adb_connect(const std::string& service, std::string* error) { version, ADB_SERVER_VERSION); fd = _adb_connect("host:kill", error); if (fd >= 0) { ReadOrderlyShutdown(fd); adb_close(fd); } else { // If we couldn't connect to the server or had some other error, Loading Loading @@ -271,6 +273,8 @@ bool adb_command(const std::string& service) { return false; } ReadOrderlyShutdown(fd); adb_close(fd); return true; } Loading @@ -286,5 +290,8 @@ bool adb_query(const std::string& service, std::string* result, std::string* err adb_close(fd); return false; } ReadOrderlyShutdown(fd); adb_close(fd); return true; }
adb/adb_io.cpp +40 −0 Original line number Diff line number Diff line Loading @@ -137,3 +137,43 @@ bool WriteFdFmt(int fd, const char* fmt, ...) { return WriteFdExactly(fd, str); } bool ReadOrderlyShutdown(int fd) { char buf[16]; // Only call this function if you're sure that the peer does // orderly/graceful shutdown of the socket, closing the socket so that // adb_read() will return 0. If the peer keeps the socket open, adb_read() // will never return. int result = adb_read(fd, buf, sizeof(buf)); if (result == -1) { // If errno is EAGAIN, that means this function was called on a // nonblocking socket and it would have blocked (which would be bad // because we'd probably block the main thread where nonblocking IO is // done). Don't do that. If you have a nonblocking socket, use the // fdevent APIs to get called on FDE_READ, and then call this function // if you really need to, but it shouldn't be needed for server sockets. CHECK_NE(errno, EAGAIN); // Note that on Windows, orderly shutdown sometimes causes // recv() == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET. That // can be ignored. return false; } else if (result == 0) { // Peer has performed an orderly/graceful shutdown. return true; } else { // Unexpectedly received data. This is essentially a protocol error // because you should not call this function unless you expect no more // data. We don't repeatedly call adb_read() until we get zero because // we don't know how long that would take, but we do know that the // caller wants to close the socket soon. VLOG(RWX) << "ReadOrderlyShutdown(" << fd << ") unexpectedly read " << dump_hex(buf, result); // Shutdown the socket to prevent the caller from reading or writing to // it which doesn't make sense if we just read and discarded some data. adb_shutdown(fd); errno = EINVAL; return false; } }
adb/adb_io.h +18 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,24 @@ bool ReadProtocolString(int fd, std::string* s, std::string* error); // If this function fails, the contents of buf are undefined. bool ReadFdExactly(int fd, void* buf, size_t len); // Given a client socket, wait for orderly/graceful shutdown. Call this: // // * Before closing a client socket. // * Only when no more data is expected to come in. // * Only when the server is not waiting for data from the client (because then // the client and server will deadlock waiting for each other). // * Only when the server is expected to close its socket right now. // * Don't call shutdown(SHUT_WR) before calling this because that will shutdown // the client socket early, defeating the purpose of calling this. // // Waiting for orderly/graceful shutdown of the server socket will cause the // server socket to close before the client socket. That prevents the client // socket from staying in TIME_WAIT which eventually causes subsequent // connect()s from the client to fail with WSAEADDRINUSE on Windows. // Returns true if it is sure that orderly/graceful shutdown has occurred with // no additional data read from the server. bool ReadOrderlyShutdown(int fd); // Writes exactly len bytes from buf to fd. // // Returns false if there is an error or if the fd was closed before the write Loading
adb/commandline.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -649,6 +649,7 @@ static int adb_download_buffer(const char *service, const char *fn, const void* std::string error; adb_status(fd, &error); fprintf(stderr,"* failed to write data '%s' *\n", error.c_str()); adb_close(fd); return -1; } sz -= xfer; Loading @@ -664,6 +665,7 @@ static int adb_download_buffer(const char *service, const char *fn, const void* if (!adb_status(fd, &error)) { fprintf(stderr,"* error response '%s' *\n", error.c_str()); adb_close(fd); return -1; } Loading Loading @@ -1468,6 +1470,7 @@ int adb_commandline(int argc, const char **argv) { } else { // Successfully connected, kill command sent, okay status came back. // Server should exit() in a moment, if not already. ReadOrderlyShutdown(fd); adb_close(fd); return 0; } Loading