X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;f=jbsockets.c;h=96f229463421cf7918fd890dc52bab7e47e2652d;hb=c00b4ad9eb9ee9d9d023934a0c313fb54250fdc8;hp=c16e75f21c1a2d2349ffe4322101a691b855ad86;hpb=2e7cd6056991ba7484e8869a335f59335b0549a6;p=privoxy.git diff --git a/jbsockets.c b/jbsockets.c index c16e75f2..96f22946 100644 --- a/jbsockets.c +++ b/jbsockets.c @@ -1,4 +1,4 @@ -const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.118 2012/10/21 12:44:58 fabiankeil Exp $"; +const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.126 2014/06/02 06:22:20 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jbsockets.c,v $ @@ -8,7 +8,7 @@ const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.118 2012/10/21 12:44:58 fabia * OS-independent. Contains #ifdefs to make this work * on many platforms. * - * Copyright : Written by and Copyright (C) 2001-2011 the + * Copyright : Written by and Copyright (C) 2001-2014 the * Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written @@ -99,6 +99,7 @@ const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.118 2012/10/21 12:44:58 fabia #include "jbsockets.h" #include "filters.h" #include "errlog.h" +#include "miscutil.h" /* Mac OSX doesn't define AI_NUMERICSESRV */ #ifndef AI_NUMERICSERV @@ -131,7 +132,7 @@ static jb_socket no_rfc2553_connect_to(const char *host, int portnum, struct cli * * Parameters : * 1 : host = hostname to connect to - * 2 : portnum = port to connent on (XXX: should be unsigned) + * 2 : portnum = port to connect to (XXX: should be unsigned) * 3 : csp = Current client state (buffers, headers, etc...) * * Returns : JB_INVALID_SOCKET => failure, else it is the socket @@ -232,14 +233,7 @@ static jb_socket rfc2553_connect_to(const char *host, int portnum, struct client return(JB_INVALID_SOCKET); } - csp->http->host_ip_addr_str = malloc(NI_MAXHOST); - if (NULL == csp->http->host_ip_addr_str) - { - freeaddrinfo(result); - log_error(LOG_LEVEL_ERROR, - "Out of memory while getting the server IP address."); - return JB_INVALID_SOCKET; - } + csp->http->host_ip_addr_str = malloc_or_die(NI_MAXHOST); for (rp = result; rp != NULL; rp = rp->ai_next) { @@ -278,6 +272,21 @@ static jb_socket rfc2553_connect_to(const char *host, int portnum, struct client continue; } +#ifndef _WIN32 + if (fd >= FD_SETSIZE) + { + log_error(LOG_LEVEL_ERROR, + "Server socket number too high to use select(): %d >= %d", + fd, FD_SETSIZE); + close_socket(fd); + return JB_INVALID_SOCKET; + } +#endif + +#ifdef FEATURE_EXTERNAL_FILTERS + mark_socket_for_close_on_execute(fd); +#endif + #ifdef TCP_NODELAY { /* turn off TCP coalescence */ int mi = 1; @@ -460,6 +469,17 @@ static jb_socket no_rfc2553_connect_to(const char *host, int portnum, struct cli return(JB_INVALID_SOCKET); } +#ifndef _WIN32 + if (fd >= FD_SETSIZE) + { + log_error(LOG_LEVEL_ERROR, + "Server socket number too high to use select(): %d >= %d", + fd, FD_SETSIZE); + close_socket(fd); + return JB_INVALID_SOCKET; + } +#endif + #ifdef TCP_NODELAY { /* turn off TCP coalescence */ int mi = 1; @@ -472,6 +492,9 @@ static jb_socket no_rfc2553_connect_to(const char *host, int portnum, struct cli { flags |= O_NDELAY; fcntl(fd, F_SETFL, flags); +#ifdef FEATURE_EXTERNAL_FILTERS + mark_socket_for_close_on_execute(fd); +#endif } #endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) */ @@ -740,6 +763,15 @@ void drain_and_close_socket(jb_socket fd) { char drainage[500]; + if (!data_is_available(fd, 0)) + { + /* + * If there is no data available right now, don't try + * to drain the socket as read_socket() could block. + */ + break; + } + bytes_drained = read_socket(fd, drainage, sizeof(drainage)); if (bytes_drained < 0) { @@ -877,6 +909,10 @@ int bind_port(const char *hostnam, int portnum, jb_socket *pfd) fd = socket(AF_INET, SOCK_STREAM, 0); #endif /* def HAVE_RFC2553 */ +#ifdef FEATURE_EXTERNAL_FILTERS + mark_socket_for_close_on_execute(fd); +#endif + #ifdef _WIN32 if (fd == JB_INVALID_SOCKET) #else @@ -1003,7 +1039,7 @@ void get_host_information(jb_socket afd, char **ip_address, char **port, struct sockaddr_in server; struct hostent *host = NULL; #endif /* HAVE_RFC2553 */ -#if defined(_WIN32) || defined(__OS2__) || defined(__APPLE_CC__) || defined(AMIGA) +#if defined(_WIN32) || defined(__OS2__) || defined(AMIGA) /* according to accept_connection() this fixes a warning. */ int s_length, s_length_provided; #else @@ -1041,27 +1077,15 @@ void get_host_information(jb_socket afd, char **ip_address, char **port, * configured with --disable-ipv6-support. * The proper fix is to not use NI_MAXSERV in * that case. It works by accident on other platforms - * as in included unconditionally there. + * as is included unconditionally there. */ #ifndef NI_MAXSERV #define NI_MAXSERV 32 #endif - *port = malloc(NI_MAXSERV); - if (NULL == *port) - { - log_error(LOG_LEVEL_ERROR, - "Out of memory while getting the client's port."); - return; - } + *port = malloc_or_die(NI_MAXSERV); + #ifdef HAVE_RFC2553 - *ip_address = malloc(NI_MAXHOST); - if (NULL == *ip_address) - { - log_error(LOG_LEVEL_ERROR, - "Out of memory while getting the client's IP address."); - freez(*port); - return; - } + *ip_address = malloc_or_die(NI_MAXHOST); retval = getnameinfo((struct sockaddr *) &server, s_length, *ip_address, NI_MAXHOST, *port, NI_MAXSERV, NI_NUMERICHOST|NI_NUMERICSERV); @@ -1087,13 +1111,7 @@ void get_host_information(jb_socket afd, char **ip_address, char **port, } #ifdef HAVE_RFC2553 - *hostname = malloc(NI_MAXHOST); - if (NULL == *hostname) - { - log_error(LOG_LEVEL_ERROR, - "Out of memory while getting the client's hostname."); - return; - } + *hostname = malloc_or_die(NI_MAXHOST); retval = getnameinfo((struct sockaddr *) &server, s_length, *hostname, NI_MAXHOST, NULL, 0, NI_NAMEREQD); if (retval) @@ -1173,7 +1191,7 @@ int accept_connection(struct client_state * csp, jb_socket fds[]) struct sockaddr_in client; #endif jb_socket afd; -#if defined(_WIN32) || defined(__OS2__) || defined(__APPLE_CC__) || defined(AMIGA) +#if defined(_WIN32) || defined(__OS2__) || defined(AMIGA) /* Wierdness - fix a warning. */ int c_length; #else @@ -1277,15 +1295,24 @@ int accept_connection(struct client_state * csp, jb_socket fds[]) } #endif - csp->cfd = afd; -#ifdef HAVE_RFC2553 - csp->ip_addr_str = malloc(NI_MAXHOST); - if (NULL == csp->ip_addr_str) +#ifndef _WIN32 + if (afd >= FD_SETSIZE) { log_error(LOG_LEVEL_ERROR, - "Out of memory while getting the client's IP address."); + "Client socket number too high to use select(): %d >= %d", + afd, FD_SETSIZE); + close_socket(afd); return 0; } +#endif + +#ifdef FEATURE_EXTERNAL_FILTERS + mark_socket_for_close_on_execute(afd); +#endif + + csp->cfd = afd; +#ifdef HAVE_RFC2553 + csp->ip_addr_str = malloc_or_die(NI_MAXHOST); retval = getnameinfo((struct sockaddr *) &client, c_length, csp->ip_addr_str, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); if (!csp->ip_addr_str || retval) @@ -1476,6 +1503,42 @@ int socket_is_still_alive(jb_socket sfd) } +#ifdef FEATURE_EXTERNAL_FILTERS +/********************************************************************* + * + * Function : mark_socket_for_close_on_execute + * + * Description : Marks a socket for close on execute. + * + * Used so that external filters have no direct + * access to sockets they shouldn't care about. + * + * Not implemented for all platforms. + * + * Parameters : + * 1 : fd = The socket to mark + * + * Returns : void. + * + *********************************************************************/ +void mark_socket_for_close_on_execute(jb_socket fd) +{ +#ifdef FEATURE_PTHREAD + int ret; + + ret = fcntl(fd, F_SETFD, FD_CLOEXEC); + + if (ret == -1) + { + log_error(LOG_LEVEL_ERROR, + "fcntl(%d, F_SETFD, FD_CLOEXEC) failed", fd); + } +#else +#warning "Sockets will be visible to external filters" +#endif +} +#endif /* def FEATURE_EXTERNAL_FILTERS */ + /* Local Variables: tab-width: 3