X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=libmemcached%2Fconnect.cc;h=68b5be728997774112521ec7c6f58c9191f18eee;hb=0f1151c684378650ee6ab21b96183ce88ed496ee;hp=22e259f41f3335fdfb75dcd23a040bfef4d00cb5;hpb=133a891bff0d9dd5b18af64cc6ba9ad3dda15a0d;p=awesomized%2Flibmemcached diff --git a/libmemcached/connect.cc b/libmemcached/connect.cc index 22e259f4..68b5be72 100644 --- a/libmemcached/connect.cc +++ b/libmemcached/connect.cc @@ -64,7 +64,7 @@ # define TCP_KEEPIDLE 0 #endif -static memcached_return_t connect_poll(org::libmemcached::Instance* server, const int connection_error) +static memcached_return_t connect_poll(memcached_instance_st* server, const int connection_error) { struct pollfd fds[1]; fds[0].fd= server->fd; @@ -76,7 +76,7 @@ static memcached_return_t connect_poll(org::libmemcached::Instance* server, cons if (server->root->poll_timeout == 0) { return memcached_set_error(*server, MEMCACHED_TIMEOUT, MEMCACHED_AT, - memcached_literal_param("The time to wait for a connection to be established was set to zero, which means it will always timeout (MEMCACHED_TIMEOUT).")); + memcached_literal_param("The time to wait for a connection to be established was set to zero which produces a timeout to every call to poll().")); } while (--loop_max) // Should only loop on cases of ERESTART or EINTR @@ -87,7 +87,7 @@ static memcached_return_t connect_poll(org::libmemcached::Instance* server, cons int local_errno= get_socket_errno(); // We cache in case closesocket() modifies errno switch (local_errno) { -#ifdef TARGET_OS_LINUX +#ifdef __linux__ case ERESTART: #endif case EINTR: @@ -103,22 +103,6 @@ static memcached_return_t connect_poll(org::libmemcached::Instance* server, cons default: // This should not happen break; -#if 0 - if (fds[0].revents & POLLERR) - { - int err; - socklen_t len= sizeof(err); - if (getsockopt(server->fd, SOL_SOCKET, SO_ERROR, (char*)&err, &len) == 0) - { - if (err == 0) - { - // This should never happen, if it does? Punt. - continue; - } - local_errno= err; - } - } -#endif } assert_msg(server->fd != INVALID_SOCKET, "poll() was passed an invalid file descriptor"); @@ -146,13 +130,9 @@ static memcached_return_t connect_poll(org::libmemcached::Instance* server, cons } } - return memcached_set_error(*server, MEMCACHED_TIMEOUT, MEMCACHED_AT); + return memcached_set_error(*server, MEMCACHED_TIMEOUT, MEMCACHED_AT, memcached_literal_param("(number_of == 0)")); } -#if 0 - server->revents(fds[0].revents); -#endif - assert (number_of == 1); if (fds[0].revents & POLLERR or @@ -201,14 +181,15 @@ static memcached_return_t connect_poll(org::libmemcached::Instance* server, cons return memcached_set_errno(*server, connection_error, MEMCACHED_AT, memcached_literal_param("connect_poll() was exhausted")); } -static memcached_return_t set_hostinfo(org::libmemcached::Instance* server) +static memcached_return_t set_hostinfo(memcached_instance_st* server) { assert(server->type != MEMCACHED_CONNECTION_UNIX_SOCKET); server->clear_addrinfo(); - char str_port[MEMCACHED_NI_MAXSERV]; + char str_port[MEMCACHED_NI_MAXSERV]= { 0 }; + errno= 0; int length= snprintf(str_port, MEMCACHED_NI_MAXSERV, "%u", uint32_t(server->port())); - if (length >= MEMCACHED_NI_MAXSERV or length <= 0) + if (length >= MEMCACHED_NI_MAXSERV or length <= 0 or errno != 0) { return memcached_set_error(*server, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT, memcached_literal_param("snprintf(NI_MAXSERV)")); @@ -217,7 +198,7 @@ static memcached_return_t set_hostinfo(org::libmemcached::Instance* server) struct addrinfo hints; memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family= AF_INET; + hints.ai_family= AF_UNSPEC; if (memcached_is_udp(server->root)) { hints.ai_protocol= IPPROTO_UDP; @@ -265,7 +246,7 @@ static memcached_return_t set_hostinfo(org::libmemcached::Instance* server) return MEMCACHED_SUCCESS; } -static inline void set_socket_nonblocking(org::libmemcached::Instance* server) +static inline void set_socket_nonblocking(memcached_instance_st* server) { #if defined(_WIN32) u_long arg= 1; @@ -305,7 +286,7 @@ static inline void set_socket_nonblocking(org::libmemcached::Instance* server) #endif } -static bool set_socket_options(org::libmemcached::Instance* server) +static bool set_socket_options(memcached_instance_st* server) { assert_msg(server->fd != INVALID_SOCKET, "invalid socket was passed to set_socket_options()"); @@ -313,7 +294,7 @@ static bool set_socket_options(org::libmemcached::Instance* server) // If SOCK_CLOEXEC exists then we don't need to call the following if (SOCK_CLOEXEC == 0) { - if (FD_CLOEXEC) + if (FD_CLOEXEC != 0) { int flags; do @@ -459,19 +440,19 @@ static bool set_socket_options(org::libmemcached::Instance* server) return true; } -static memcached_return_t unix_socket_connect(org::libmemcached::Instance* server) +static memcached_return_t unix_socket_connect(memcached_instance_st* server) { #ifndef _WIN32 WATCHPOINT_ASSERT(server->fd == INVALID_SOCKET); do { int type= SOCK_STREAM; - if (SOCK_CLOEXEC) + if (SOCK_CLOEXEC != 0) { type|= SOCK_CLOEXEC; } - if (SOCK_NONBLOCK) + if (SOCK_NONBLOCK != 0) { type|= SOCK_NONBLOCK; } @@ -485,7 +466,10 @@ static memcached_return_t unix_socket_connect(org::libmemcached::Instance* serve memset(&servAddr, 0, sizeof (struct sockaddr_un)); servAddr.sun_family= AF_UNIX; - strncpy(servAddr.sun_path, server->hostname(), sizeof(servAddr.sun_path)); /* Copy filename */ + if (strlen(server->hostname()) >= sizeof(servAddr.sun_path)) { + return memcached_set_error(*server, MEMCACHED_UNIX_SOCKET_PATH_TOO_BIG, MEMCACHED_AT); + } + strncpy(servAddr.sun_path, server->hostname(), sizeof(servAddr.sun_path)-1); /* Copy filename */ if (connect(server->fd, (struct sockaddr *)&servAddr, sizeof(servAddr)) == -1) { @@ -493,6 +477,7 @@ static memcached_return_t unix_socket_connect(org::libmemcached::Instance* serve { case EINPROGRESS: case EALREADY: + case EAGAIN: server->events(POLLOUT); break; @@ -525,7 +510,7 @@ static memcached_return_t unix_socket_connect(org::libmemcached::Instance* serve #endif } -static memcached_return_t network_connect(org::libmemcached::Instance* server) +static memcached_return_t network_connect(memcached_instance_st* server) { bool timeout_error_occured= false; @@ -553,20 +538,13 @@ static memcached_return_t network_connect(org::libmemcached::Instance* server) /* Create the socket */ while (server->address_info_next and server->fd == INVALID_SOCKET) { - /* Memcache server does not support IPV6 in udp mode, so skip if not ipv4 */ - if (memcached_is_udp(server->root) and server->address_info_next->ai_family != AF_INET) - { - server->address_info_next= server->address_info_next->ai_next; - continue; - } - int type= server->address_info_next->ai_socktype; - if (SOCK_CLOEXEC) + if (SOCK_CLOEXEC != 0) { type|= SOCK_CLOEXEC; } - if (SOCK_NONBLOCK) + if (SOCK_NONBLOCK != 0) { type|= SOCK_NONBLOCK; } @@ -663,7 +641,8 @@ static memcached_return_t network_connect(org::libmemcached::Instance* server) if (timeout_error_occured and server->state < MEMCACHED_SERVER_STATE_IN_PROGRESS) { - return memcached_set_error(*server, MEMCACHED_TIMEOUT, MEMCACHED_AT); + return memcached_set_error(*server, MEMCACHED_TIMEOUT, MEMCACHED_AT, + memcached_literal_param("if (timeout_error_occured and server->state < MEMCACHED_SERVER_STATE_IN_PROGRESS)")); } return memcached_set_error(*server, MEMCACHED_CONNECTION_FAILURE, MEMCACHED_AT); /* The last error should be from connect() */ @@ -676,7 +655,7 @@ static memcached_return_t network_connect(org::libmemcached::Instance* server) Based on time/failure count fail the connect without trying. This prevents waiting in a state where we get caught spending cycles just waiting. */ -static memcached_return_t backoff_handling(org::libmemcached::Instance* server, bool& in_timeout) +static memcached_return_t backoff_handling(memcached_instance_st* server, bool& in_timeout) { struct timeval curr_time; bool _gettime_success= (gettimeofday(&curr_time, NULL) == 0); @@ -731,6 +710,7 @@ static memcached_return_t backoff_handling(org::libmemcached::Instance* server, if (_gettime_success and server->next_retry < curr_time.tv_sec) { server->state= MEMCACHED_SERVER_STATE_NEW; + server->server_timeout_counter= 0; } else { @@ -743,7 +723,7 @@ static memcached_return_t backoff_handling(org::libmemcached::Instance* server, return MEMCACHED_SUCCESS; } -static memcached_return_t _memcached_connect(org::libmemcached::Instance* server, const bool set_last_disconnected) +static memcached_return_t _memcached_connect(memcached_instance_st* server, const bool set_last_disconnected) { assert(server); if (server->fd != INVALID_SOCKET) @@ -778,6 +758,7 @@ static memcached_return_t _memcached_connect(org::libmemcached::Instance* server case MEMCACHED_CONNECTION_TCP: rc= network_connect(server); +#if defined(LIBMEMCACHED_WITH_SASL_SUPPORT) if (LIBMEMCACHED_WITH_SASL_SUPPORT) { if (server->fd != INVALID_SOCKET and server->root->sasl.callbacks) @@ -790,6 +771,7 @@ static memcached_return_t _memcached_connect(org::libmemcached::Instance* server } } } +#endif break; case MEMCACHED_CONNECTION_UNIX_SOCKET: @@ -830,7 +812,7 @@ static memcached_return_t _memcached_connect(org::libmemcached::Instance* server return rc; } -memcached_return_t memcached_connect(org::libmemcached::Instance* server) +memcached_return_t memcached_connect(memcached_instance_st* server) { return _memcached_connect(server, true); }