Changeset: 9f2d3d897cb3 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/9f2d3d897cb3 Modified Files: clients/mapilib/connect.c clients/mapilib/connect_unix.c common/stream/socket_stream.c Branch: odbc-tls Log Message:
Obey MP_CONNECT_TIMEOUT and MP_REPLY_TIMEOUT in libmapi diffs (132 lines): diff --git a/clients/mapilib/connect.c b/clients/mapilib/connect.c --- a/clients/mapilib/connect.c +++ b/clients/mapilib/connect.c @@ -144,6 +144,17 @@ establish_connection(Mapi mid) msg = mapi_handshake(mid); } + // Switch from MP_CONNECT_TIMEOUT to MP_REPLY_TIMEOUT + if (msg == MOK) { + long connect_timeout = msetting_long(mid->settings, MP_CONNECT_TIMEOUT); + long reply_timeout = msetting_long(mid->settings, MP_REPLY_TIMEOUT); + if (connect_timeout > 0 || reply_timeout > 0) { + if (reply_timeout < 0) + reply_timeout = 0; + msg = mapi_timeout(mid, reply_timeout); + } + } + return msg; } @@ -153,6 +164,7 @@ connect_socket(Mapi mid) assert(!mid->connected); const char *sockname = msettings_connect_unix(mid->settings); const char *tcp_host = msettings_connect_tcp(mid->settings); + long timeout = msetting_long(mid->settings, MP_CONNECT_TIMEOUT); assert(*sockname || *tcp_host); do { @@ -165,6 +177,11 @@ connect_socket(Mapi mid) return mid->error; } while (0); + // the socket code may have set SO_SNDTIMEO and SO_RCVTIMEO but + // the mapi layer doesn't know this yet. + if (timeout > 0) + mapi_timeout(mid, timeout); + mid->connected = true; return MOK; } @@ -293,6 +310,8 @@ connect_socket_tcp(Mapi mid) static SOCKET connect_socket_tcp_addr(Mapi mid, struct addrinfo *info) { + long timeout = msetting_long(mid->settings, MP_CONNECT_TIMEOUT); + if (mid->tracelog) { char addrbuf[100] = {0}; const char *addrtext; @@ -332,6 +351,22 @@ connect_socket_tcp_addr(Mapi mid, struct (void) fcntl(s, F_SETFD, FD_CLOEXEC); #endif + if (timeout > 0) { + struct timeval tv = { + .tv_sec = timeout / 1000, + .tv_usec = timeout % 1000, + }; + if ( + setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == SOCKET_ERROR + || setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == SOCKET_ERROR + ) { + closesocket(s); + return mapi_printError( + mid, __func__, MERROR, + "could not set connect timeout: %s", strerror(errno)); + } + } + // cast addrlen to int to satisfy Windows. if (connect(s, info->ai_addr, (int)info->ai_addrlen) == SOCKET_ERROR) { mapi_printError( diff --git a/clients/mapilib/connect_unix.c b/clients/mapilib/connect_unix.c --- a/clients/mapilib/connect_unix.c +++ b/clients/mapilib/connect_unix.c @@ -130,15 +130,16 @@ connect_socket_unix(Mapi mid) { const char *sockname = msettings_connect_unix(mid->settings); assert (*sockname != '\0'); + long timeout = msetting_long(mid->settings, MP_CONNECT_TIMEOUT); - mapi_log_record(mid, "CONN", "Connecting to Unix domain socket %s", sockname); + mapi_log_record(mid, "CONN", "Connecting to Unix domain socket %s with timeout %ld", sockname, timeout); struct sockaddr_un userver; if (strlen(sockname) >= sizeof(userver.sun_path)) { return mapi_printError(mid, __func__, MERROR, "path name '%s' too long", sockname); } - // Create the socket, taking care of CLOEXEC + // Create the socket, taking care of CLOEXEC and SNDTIMEO #ifdef SOCK_CLOEXEC int s = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); @@ -154,6 +155,22 @@ connect_socket_unix(Mapi mid) (void) fcntl(s, F_SETFD, FD_CLOEXEC); #endif + if (timeout > 0) { + struct timeval tv = { + .tv_sec = timeout / 1000, + .tv_usec = timeout % 1000, + }; + if ( + setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == SOCKET_ERROR + || setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == SOCKET_ERROR + ) { + closesocket(s); + return mapi_printError( + mid, __func__, MERROR, + "could not set connect timeout: %s", strerror(errno)); + } + } + // Attempt to connect userver = (struct sockaddr_un) { diff --git a/common/stream/socket_stream.c b/common/stream/socket_stream.c --- a/common/stream/socket_stream.c +++ b/common/stream/socket_stream.c @@ -259,7 +259,9 @@ socket_update_timeout(stream *s) tv.tv_sec = s->timeout / 1000; tv.tv_usec = (s->timeout % 1000) * 1000; /* cast to char * for Windows, no harm on "normal" systems */ - if (!s->readonly) + if (s->readonly) + (void) setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *) &tv, (socklen_t) sizeof(tv)); + else (void) setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *) &tv, (socklen_t) sizeof(tv)); } _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org