diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c index abfe9eb1a8..c63f2b1a00 100644 --- a/libs/esl/src/esl.c +++ b/libs/esl/src/esl.c @@ -34,6 +34,7 @@ #include #ifndef WIN32 #define closesocket(x) close(x) +#include #else #include #endif @@ -606,12 +607,13 @@ ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_list } -ESL_DECLARE(esl_status_t) esl_connect(esl_handle_t *handle, const char *host, esl_port_t port, const char *user, const char *password) +ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char *host, esl_port_t port, const char *user, const char *password, long timeout) { char sendbuf[256]; int rval = 0; const char *hval; struct addrinfo hints = { 0 }, *result; + int fd_flags; #ifdef WIN32 WORD wVersionRequested = MAKEWORD(2, 0); WSADATA wsaData; @@ -647,8 +649,58 @@ ESL_DECLARE(esl_status_t) esl_connect(esl_handle_t *handle, const char *host, es handle->sockaddr.sin_family = AF_INET; handle->sockaddr.sin_port = htons(port); + if (timeout != -1) { +#ifdef WIN32 + u_long arg = 1; + if (ioctlsocket(handle->sock, FIONBIO, &arg) == SOCKET_ERROR) { + snprintf(handle->err, sizeof(handle->err), "Socket Connection Error"); + goto fail; + } +#else + fd_flags = fcntl(handle->sock, F_GETFL, 0); + if (fcntl(handle->sock, F_SETFL, fd_flags | O_NONBLOCK)) { + snprintf(handle->err, sizeof(handle->err), "Socket Connection Error"); + goto fail; + } +#endif + } + rval = connect(handle->sock, (struct sockaddr*)&handle->sockaddr, sizeof(handle->sockaddr)); + if (timeout != -1) { + fd_set wfds; + struct timeval tv = { timeout / 1000, (timeout % 1000) * 1000 }; + int r; + + FD_ZERO(&wfds); + FD_SET(handle->sock, &wfds); + + r = select(handle->sock + 1, NULL, &wfds, NULL, &tv); + + if (r <= 0) { + snprintf(handle->err, sizeof(handle->err), "Connection timed out"); + goto fail; + } + + if (!FD_ISSET(handle->sock, &wfds)) { + snprintf(handle->err, sizeof(handle->err), "Connection timed out"); + goto fail; + } + +#ifdef WIN32 + { + u_long arg = 0; + if (ioctlsocket(handle->sock, FIONBIO, &arg) == SOCKET_ERROR) { + snprintf(handle->err, sizeof(handle->err), "Socket Connection Error"); + goto fail; + } + } +#else + fcntl(handle->sock, F_SETFL, fd_flags); +#endif + rval = 0; + } + freeaddrinfo(result); result = NULL; diff --git a/libs/esl/src/include/esl.h b/libs/esl/src/include/esl.h index 7b98988acc..d87f83f26b 100644 --- a/libs/esl/src/include/esl.h +++ b/libs/esl/src/include/esl.h @@ -387,8 +387,11 @@ ESL_DECLARE(esl_status_t) esl_sendevent(esl_handle_t *handle, esl_event_t *event \param port Port to be connected \param password FreeSWITCH server username (optional) \param password FreeSWITCH server password + \param timeout Connection timeout, in miliseconds */ -ESL_DECLARE(esl_status_t) esl_connect(esl_handle_t *handle, const char *host, esl_port_t port, const char *user, const char *password); +ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char *host, esl_port_t port, const char *user, const char *password, long timeout); +#define esl_connect(_handle, _host, _port, _user, _password) esl_connect_timeout(_handle, _host, _port, _user, _password, -1) + /*! \brief Disconnect a handle \param handle Handle to be disconnected