From deff3aa0ca19b0dc840491968ec0f5c6759a699f Mon Sep 17 00:00:00 2001 From: Karl Heyes Date: Thu, 8 Jan 2009 02:47:44 +0000 Subject: [PATCH] avoid SOCK_NONBLOCK name clash with recent glibc. Add support for optional bind parameter to connect_wto call. Some small compiler cleanups. svn path=/icecast/trunk/icecast/; revision=15611 --- src/connection.c | 12 ++++--- src/net/sock.c | 81 +++++++++++++++++++++++++++++++++++------------- src/net/sock.h | 7 +++-- src/slave.c | 2 +- 4 files changed, 72 insertions(+), 30 deletions(-) diff --git a/src/connection.c b/src/connection.c index 7056ba2f..ab7cdd61 100644 --- a/src/connection.c +++ b/src/connection.c @@ -723,6 +723,13 @@ void connection_accept_loop (void) /* setup client for reading incoming http */ client->refbuf->data [PER_CLIENT_REFBUF_SIZE-1] = '\000'; + if (sock_set_blocking (client->con->sock, 0) || sock_set_nodelay (client->con->sock)) + { + WARN0 ("failed to set tcp options on client connection, dropping"); + client_destroy (client); + continue; + } + node = calloc (1, sizeof (client_queue_t)); if (node == NULL) { @@ -745,9 +752,6 @@ void connection_accept_loop (void) } config_release_config(); - sock_set_blocking (client->con->sock, SOCK_NONBLOCK); - sock_set_nodelay (client->con->sock); - _add_request_queue (node); stats_event_inc (NULL, "connections"); duration = 5; @@ -1394,7 +1398,7 @@ int connection_setup_sockets (ice_config_t *config) sock_close (sock); break; } - sock_set_blocking (sock, SOCK_NONBLOCK); + sock_set_blocking (sock, 0); successful = 1; global.serversock [count] = sock; count++; diff --git a/src/net/sock.c b/src/net/sock.c index f5d1e675..75eaa3eb 100644 --- a/src/net/sock.c +++ b/src/net/sock.c @@ -131,7 +131,7 @@ int sock_error(void) #endif } -static void sock_set_error(int val) +void sock_set_error(int val) { #ifdef _WIN32 WSASetLastError (val); @@ -242,12 +242,12 @@ int inet_aton(const char *s, struct in_addr *a) #endif /* _WIN32 */ /* sock_set_blocking -** -** set the sock blocking or nonblocking -** SOCK_BLOCK for blocking -** SOCK_NONBLOCK for nonblocking -*/ -int sock_set_blocking(sock_t sock, const int block) + * + * set the sock blocking or nonblocking + * 1 for blocking + * 0 for nonblocking + */ +int sock_set_blocking(sock_t sock, int block) { #ifdef _WIN32 #ifdef __MINGW32__ @@ -263,7 +263,7 @@ int sock_set_blocking(sock_t sock, const int block) #ifdef _WIN32 return ioctlsocket(sock, FIONBIO, &varblock); #else - return fcntl(sock, F_SETFL, (block == SOCK_BLOCK) ? 0 : O_NONBLOCK); + return fcntl(sock, F_SETFL, (block) ? 0 : O_NONBLOCK); #endif } @@ -570,6 +570,11 @@ int sock_connected (sock_t sock, int timeout) } #endif +sock_t sock_connect_wto (const char *hostname, int port, int timeout) +{ + return sock_connect_wto_bind(hostname, port, NULL, timeout); +} + #ifdef HAVE_GETADDRINFO sock_t sock_connect_non_blocking (const char *hostname, unsigned port) @@ -593,7 +598,7 @@ sock_t sock_connect_non_blocking (const char *hostname, unsigned port) if ((sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol)) > -1) { - sock_set_blocking (sock, SOCK_NONBLOCK); + sock_set_blocking (sock, 0); if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0 && !sock_connect_pending(sock_error())) { @@ -614,10 +619,10 @@ sock_t sock_connect_non_blocking (const char *hostname, unsigned port) * timeout is 0 or less then we will wait until the OS gives up on the connect * The socket is returned */ -sock_t sock_connect_wto(const char *hostname, int port, int timeout) +sock_t sock_connect_wto_bind (const char *hostname, int port, const char *bnd, int timeout) { sock_t sock = SOCK_ERROR; - struct addrinfo *ai, *head, hints; + struct addrinfo *ai, *head, *b_head=NULL, hints; char service[8]; memset (&hints, 0, sizeof (hints)); @@ -634,7 +639,23 @@ sock_t sock_connect_wto(const char *hostname, int port, int timeout) if ((sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol)) >= 0) { if (timeout > 0) - sock_set_blocking (sock, SOCK_NONBLOCK); + sock_set_blocking (sock, 0); + + if (bnd) + { + struct addrinfo b_hints; + memset (&b_hints, 0, sizeof(b_hints)); + b_hints.ai_family = ai->ai_family; + b_hints.ai_socktype = ai->ai_socktype; + b_hints.ai_protocol = ai->ai_protocol; + if (getaddrinfo (bnd, NULL, &b_hints, &b_head) || + bind (sock, b_head->ai_addr, b_head->ai_addrlen) < 0) + { + sock_close (sock); + sock = SOCK_ERROR; + break; + } + } if (connect (sock, ai->ai_addr, ai->ai_addrlen) == 0) break; @@ -650,7 +671,7 @@ sock_t sock_connect_wto(const char *hostname, int port, int timeout) if (connected == 1) /* connected */ { if (timeout >= 0) - sock_set_blocking(sock, SOCK_BLOCK); + sock_set_blocking(sock, 1); break; } } @@ -662,8 +683,9 @@ sock_t sock_connect_wto(const char *hostname, int port, int timeout) } ai = ai->ai_next; } - if (head) - freeaddrinfo (head); + if (b_head) + freeaddrinfo (b_head); + freeaddrinfo (head); return sock; } @@ -747,7 +769,7 @@ int sock_try_connection (sock_t sock, const char *hostname, unsigned int port) memcpy(&server.sin_addr, &sin.sin_addr, sizeof(struct sockaddr_in)); server.sin_family = AF_INET; - server.sin_port = htons(port); + server.sin_port = htons((short)port); return connect(sock, (struct sockaddr *)&server, sizeof(server)); } @@ -760,13 +782,13 @@ sock_t sock_connect_non_blocking (const char *hostname, unsigned port) if (sock == SOCK_ERROR) return SOCK_ERROR; - sock_set_blocking (sock, SOCK_NONBLOCK); + sock_set_blocking (sock, 0); sock_try_connection (sock, hostname, port); return sock; } -sock_t sock_connect_wto(const char *hostname, int port, int timeout) +sock_t sock_connect_wto_bind (const char *hostname, int port, const char *bnd, int timeout) { sock_t sock; @@ -774,9 +796,24 @@ sock_t sock_connect_wto(const char *hostname, int port, int timeout) if (sock == SOCK_ERROR) return SOCK_ERROR; + if (bnd) + { + struct sockaddr_in sa; + + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + + if (inet_aton (bnd, &sa.sin_addr) == 0 || + bind (sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) + { + sock_close (sock); + return SOCK_ERROR; + } + } + if (timeout) { - sock_set_blocking (sock, SOCK_NONBLOCK); + sock_set_blocking (sock, 0); if (sock_try_connection (sock, hostname, port) < 0) { int ret = sock_connected (sock, timeout); @@ -786,7 +823,7 @@ sock_t sock_connect_wto(const char *hostname, int port, int timeout) return SOCK_ERROR; } } - sock_set_blocking(sock, SOCK_BLOCK); + sock_set_blocking(sock, 1); } else { @@ -828,12 +865,12 @@ sock_t sock_get_server_socket(int port, const char *sinterface) return SOCK_ERROR; } else { sa.sin_family = AF_INET; - sa.sin_port = htons(port); + sa.sin_port = htons((short)port); } } else { sa.sin_addr.s_addr = INADDR_ANY; sa.sin_family = AF_INET; - sa.sin_port = htons(port); + sa.sin_port = htons((short)port); } /* get a socket */ diff --git a/src/net/sock.h b/src/net/sock.h index 104550cc..301bc603 100644 --- a/src/net/sock.h +++ b/src/net/sock.h @@ -65,9 +65,6 @@ struct iovec #define SOCK_ERROR (sock_t)-1 #define SOCK_TIMEOUT -2 -#define SOCK_BLOCK 0 -#define SOCK_NONBLOCK 1 - /* sock connect macro */ #define sock_connect(h, p) sock_connect_wto(h, p, 0) @@ -76,6 +73,7 @@ struct iovec # define sock_shutdown _mangle(sock_shutdown) # define sock_get_localip _mangle(sock_get_localip) # define sock_error _mangle(sock_error) +# define sock_set_error _mangle(sock_set_error) # define sock_recoverable _mangle(sock_recoverable) # define sock_stalled _mangle(sock_stalled) # define sock_valid_socket _mangle(sock_valid_socket) @@ -85,6 +83,7 @@ struct iovec # define sock_set_keepalive _mangle(sock_set_keepalive) # define sock_close _mangle(sock_close) # define sock_connect_wto _mangle(sock_connect_wto) +# define sock_connect_wto_bind _mangle(sock_connect_wto_bind) # define sock_connect_non_blocking _mangle(sock_connect_non_blocking) # define sock_connected _mangle(sock_connected) # define sock_write_bytes _mangle(sock_write_bytes) @@ -112,10 +111,12 @@ int sock_set_blocking(sock_t sock, const int block); int sock_set_nolinger(sock_t sock); int sock_set_keepalive(sock_t sock); int sock_set_nodelay(sock_t sock); +void sock_set_error(int val); int sock_close(sock_t sock); /* Connection related socket functions */ sock_t sock_connect_wto(const char *hostname, int port, int timeout); +sock_t sock_connect_wto_bind(const char *hostname, int port, const char *bnd, int timeout); sock_t sock_connect_non_blocking(const char *host, unsigned port); int sock_connected(sock_t sock, int timeout); diff --git a/src/slave.c b/src/slave.c index 9d1ea224..89cdc0b4 100644 --- a/src/slave.c +++ b/src/slave.c @@ -277,7 +277,7 @@ static client_t *open_relay_connection (relay_server *relay) break; } global_unlock (); - sock_set_blocking (streamsock, SOCK_NONBLOCK); + sock_set_blocking (streamsock, 0); client_set_queue (client, NULL); free (server); free (mount); -- GitLab