THRIFT-2156: fix errno handling in server socket

Client: C++
Patch: Jim King <jim.king@simplivity.com>

This closes #1033
This commit is contained in:
Jim King 2016-06-20 01:08:58 -04:00 committed by Jens Geyer
parent 47f9b9d7c8
commit e5176241c3

View File

@ -284,7 +284,7 @@ void TServerSocket::listen() {
hints.ai_family = PF_UNSPEC; hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
sprintf(port, "%d", port_); snprintf(port, sizeof("65535"), "%d", port_);
// If address is not specified use wildcard address (NULL) // If address is not specified use wildcard address (NULL)
TGetAddrInfoWrapper info(address_.empty() ? NULL : &address_[0], port, &hints); TGetAddrInfoWrapper info(address_.empty() ? NULL : &address_[0], port, &hints);
@ -445,6 +445,7 @@ void TServerSocket::listen() {
// we may want to try to bind more than once, since THRIFT_NO_SOCKET_CACHING doesn't // we may want to try to bind more than once, since THRIFT_NO_SOCKET_CACHING doesn't
// always seem to work. The client can configure the retry variables. // always seem to work. The client can configure the retry variables.
int retries = 0; int retries = 0;
int errno_copy = 0;
if (!path_.empty()) { if (!path_.empty()) {
@ -453,7 +454,7 @@ void TServerSocket::listen() {
// Unix Domain Socket // Unix Domain Socket
size_t len = path_.size() + 1; size_t len = path_.size() + 1;
if (len > sizeof(((sockaddr_un*)NULL)->sun_path)) { if (len > sizeof(((sockaddr_un*)NULL)->sun_path)) {
int errno_copy = THRIFT_GET_SOCKET_ERROR; errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TSocket::listen() Unix Domain socket path too long", errno_copy); GlobalOutput.perror("TSocket::listen() Unix Domain socket path too long", errno_copy);
throw TTransportException(TTransportException::NOT_OPEN, throw TTransportException(TTransportException::NOT_OPEN,
"Unix Domain socket path too long", "Unix Domain socket path too long",
@ -481,6 +482,7 @@ void TServerSocket::listen() {
if (0 == ::bind(serverSocket_, (struct sockaddr*)&address, structlen)) { if (0 == ::bind(serverSocket_, (struct sockaddr*)&address, structlen)) {
break; break;
} }
errno_copy = THRIFT_GET_SOCKET_ERROR;
// use short circuit evaluation here to only sleep if we need to // use short circuit evaluation here to only sleep if we need to
} while ((retries++ < retryLimit_) && (THRIFT_SLEEP_SEC(retryDelay_) == 0)); } while ((retries++ < retryLimit_) && (THRIFT_SLEEP_SEC(retryDelay_) == 0));
#else #else
@ -493,6 +495,7 @@ void TServerSocket::listen() {
if (0 == ::bind(serverSocket_, res->ai_addr, static_cast<int>(res->ai_addrlen))) { if (0 == ::bind(serverSocket_, res->ai_addr, static_cast<int>(res->ai_addrlen))) {
break; break;
} }
errno_copy = THRIFT_GET_SOCKET_ERROR;
// use short circuit evaluation here to only sleep if we need to // use short circuit evaluation here to only sleep if we need to
} while ((retries++ < retryLimit_) && (THRIFT_SLEEP_SEC(retryDelay_) == 0)); } while ((retries++ < retryLimit_) && (THRIFT_SLEEP_SEC(retryDelay_) == 0));
@ -502,7 +505,7 @@ void TServerSocket::listen() {
socklen_t len = sizeof(sa); socklen_t len = sizeof(sa);
std::memset(&sa, 0, len); std::memset(&sa, 0, len);
if (::getsockname(serverSocket_, reinterpret_cast<struct sockaddr*>(&sa), &len) < 0) { if (::getsockname(serverSocket_, reinterpret_cast<struct sockaddr*>(&sa), &len) < 0) {
int errno_copy = errno; errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TServerSocket::getPort() getsockname() ", errno_copy); GlobalOutput.perror("TServerSocket::getPort() getsockname() ", errno_copy);
} else { } else {
if (sa.ss_family == AF_INET6) { if (sa.ss_family == AF_INET6) {
@ -520,15 +523,15 @@ void TServerSocket::listen() {
if (retries > retryLimit_) { if (retries > retryLimit_) {
char errbuf[1024]; char errbuf[1024];
if (!path_.empty()) { if (!path_.empty()) {
sprintf(errbuf, "TServerSocket::listen() PATH %s", path_.c_str()); snprintf(errbuf, 1024, "TServerSocket::listen() PATH %s", path_.c_str());
} else { } else {
sprintf(errbuf, "TServerSocket::listen() BIND %d", port_); snprintf(errbuf, 1024, "TServerSocket::listen() BIND %d", port_);
} }
GlobalOutput(errbuf); GlobalOutput(errbuf);
close(); close();
throw TTransportException(TTransportException::NOT_OPEN, throw TTransportException(TTransportException::NOT_OPEN,
"Could not bind", "Could not bind",
THRIFT_GET_SOCKET_ERROR); errno_copy);
} }
if (listenCallback_) if (listenCallback_)
@ -536,7 +539,7 @@ void TServerSocket::listen() {
// Call listen // Call listen
if (-1 == ::listen(serverSocket_, acceptBacklog_)) { if (-1 == ::listen(serverSocket_, acceptBacklog_)) {
int errno_copy = THRIFT_GET_SOCKET_ERROR; errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TServerSocket::listen() listen() ", errno_copy); GlobalOutput.perror("TServerSocket::listen() listen() ", errno_copy);
close(); close();
throw TTransportException(TTransportException::NOT_OPEN, "Could not listen", errno_copy); throw TTransportException(TTransportException::NOT_OPEN, "Could not listen", errno_copy);