Index: main/tcptls.c =================================================================== --- main/tcptls.c (revision 156248) +++ main/tcptls.c (working copy) @@ -227,8 +227,10 @@ */ struct ast_tcptls_session_instance *ast_tcptls_client_start(struct server_args *desc) { - int flags; + int flags, res, waittime = 2000, waitconsumed = 0; struct ast_tcptls_session_instance *ser = NULL; + struct pollfd eventfd = { .events = POLLIN | POLLOUT }; + struct timeval orig; /* Do nothing if nothing has changed */ if(!memcmp(&desc->oldsin, &desc->sin, sizeof(desc->oldsin))) { @@ -248,12 +250,31 @@ return NULL; } - if (connect(desc->accept_fd, (const struct sockaddr *)&desc->sin, sizeof(desc->sin))) { - ast_log(LOG_ERROR, "Unable to connect %s to %s:%d: %s\n", - desc->name, - ast_inet_ntoa(desc->sin.sin_addr), ntohs(desc->sin.sin_port), - strerror(errno)); - goto error; + flags = fcntl(desc->accept_fd, F_GETFL); + fcntl(desc->accept_fd, F_SETFL, flags | O_NONBLOCK); + connect(desc->accept_fd, (const struct sockaddr *)&desc->sin, sizeof(desc->sin)); + eventfd.fd = desc->accept_fd; + orig = ast_tvnow(); + + while ((res = poll(&eventfd, 1, waittime - waitconsumed))) { + if (res > 0) { + size_t ressize = sizeof(res); + getsockopt(desc->accept_fd, SOL_SOCKET, SO_ERROR, &res, &ressize); + if (res == 0) { + break; + } else if (res != EINTR) { + ast_log(LOG_ERROR, "Unable to connect %s to %s:%d: %s\n", desc->name, + ast_inet_ntoa(desc->sin.sin_addr), ntohs(desc->sin.sin_port), + res > 0 ? strerror(res) : "unknown error"); + goto error; + } + } + waitconsumed = ast_tvdiff_ms(ast_tvnow(), orig); + if (waitconsumed >= waittime) { + ast_log(LOG_ERROR, "Unable to connect %s to %s:%d: Connection timed out\n", desc->name, + ast_inet_ntoa(desc->sin.sin_addr), ntohs(desc->sin.sin_port)); + goto error; + } } if (!(ser = ao2_alloc(sizeof(*ser), session_instance_destructor)))