X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=jbsockets.c;h=6a89f6834e19b7a1a78a4a69372a07bf44a37a3b;hb=a40aa0237d6ef1be4c333260f71403ac931008bc;hp=48f43c922b7819fb0ca428662be4b4929763b9fb;hpb=da9616d7948038f2e5f5b50ef6ce7d1a12835413;p=privoxy.git diff --git a/jbsockets.c b/jbsockets.c index 48f43c92..6a89f683 100644 --- a/jbsockets.c +++ b/jbsockets.c @@ -1,4 +1,4 @@ -const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.134 2015/11/06 13:37:35 fabiankeil Exp $"; +const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.139 2016/12/24 16:00:49 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jbsockets.c,v $ @@ -50,6 +50,7 @@ const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.134 2015/11/06 13:37:35 fabia #ifndef STRICT #define STRICT #endif +#include #include #include #include @@ -210,8 +211,12 @@ static jb_socket rfc2553_connect_to(const char *host, int portnum, struct client char service[6]; int retval; jb_socket fd; +#ifdef HAVE_POLL + struct pollfd poll_fd[1]; +#else fd_set wfds; struct timeval timeout; +#endif #if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) int flags; #endif @@ -299,6 +304,7 @@ static jb_socket rfc2553_connect_to(const char *host, int portnum, struct client continue; } +#ifndef HAVE_POLL #ifndef _WIN32 if (fd >= FD_SETSIZE) { @@ -310,6 +316,7 @@ static jb_socket rfc2553_connect_to(const char *host, int portnum, struct client return JB_INVALID_SOCKET; } #endif +#endif #ifdef FEATURE_EXTERNAL_FILTERS mark_socket_for_close_on_execute(fd); @@ -362,6 +369,12 @@ static jb_socket rfc2553_connect_to(const char *host, int portnum, struct client } #endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) */ +#ifdef HAVE_POLL + poll_fd[0].fd = fd; + poll_fd[0].events = POLLOUT; + + if (poll(poll_fd, 1, 30000) > 0) +#else /* wait for connection to complete */ FD_ZERO(&wfds); FD_SET(fd, &wfds); @@ -372,6 +385,7 @@ static jb_socket rfc2553_connect_to(const char *host, int portnum, struct client /* MS Windows uses int, not SOCKET, for the 1st arg of select(). Weird! */ if ((select((int)fd + 1, NULL, &wfds, NULL, &timeout) > 0) && FD_ISSET(fd, &wfds)) +#endif { socklen_t optlen = sizeof(socket_error); if (!getsockopt(fd, SOL_SOCKET, SO_ERROR, &socket_error, &optlen)) @@ -429,8 +443,12 @@ static jb_socket no_rfc2553_connect_to(const char *host, int portnum, struct cli struct sockaddr_in inaddr; jb_socket fd; unsigned int addr; +#ifdef HAVE_POLL + struct pollfd poll_fd[1]; +#else fd_set wfds; struct timeval tv[1]; +#endif #if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) int flags; #endif @@ -492,6 +510,7 @@ static jb_socket no_rfc2553_connect_to(const char *host, int portnum, struct cli return(JB_INVALID_SOCKET); } +#ifndef HAVE_POLL #ifndef _WIN32 if (fd >= FD_SETSIZE) { @@ -501,6 +520,7 @@ static jb_socket no_rfc2553_connect_to(const char *host, int portnum, struct cli close_socket(fd); return JB_INVALID_SOCKET; } +#endif #endif set_no_delay_flag(fd); @@ -548,6 +568,12 @@ static jb_socket no_rfc2553_connect_to(const char *host, int portnum, struct cli } #endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) */ +#ifdef HAVE_POLL + poll_fd[0].fd = fd; + poll_fd[0].events = POLLOUT; + + if (poll(poll_fd, 1, 30000) <= 0) +#else /* wait for connection to complete */ FD_ZERO(&wfds); FD_SET(fd, &wfds); @@ -557,6 +583,7 @@ static jb_socket no_rfc2553_connect_to(const char *host, int portnum, struct cli /* MS Windows uses int, not SOCKET, for the 1st arg of select(). Weird! */ if (select((int)fd + 1, NULL, &wfds, NULL, tv) <= 0) +#endif { close_socket(fd); return(JB_INVALID_SOCKET); @@ -593,6 +620,14 @@ int write_socket(jb_socket fd, const char *buf, size_t len) return 0; } +#ifdef FUZZ + if (!daemon_mode && fd <= 3) + { + log_error(LOG_LEVEL_WRITING, "Pretending to write to socket %d: %N", fd, len, buf); + return 0; + } +#endif + log_error(LOG_LEVEL_WRITING, "to socket %d: %N", fd, len, buf); #if defined(_WIN32) @@ -694,10 +729,18 @@ int read_socket(jb_socket fd, char *buf, int len) *********************************************************************/ int data_is_available(jb_socket fd, int seconds_to_wait) { + int n; char buf[10]; +#ifdef HAVE_POLL + struct pollfd poll_fd[1]; + + poll_fd[0].fd = fd; + poll_fd[0].events = POLLIN; + + n = poll(poll_fd, 1, seconds_to_wait * 1000); +#else fd_set rfds; struct timeval timeout; - int n; memset(&timeout, 0, sizeof(timeout)); timeout.tv_sec = seconds_to_wait; @@ -711,6 +754,7 @@ int data_is_available(jb_socket fd, int seconds_to_wait) FD_SET(fd, &rfds); n = select(fd+1, &rfds, NULL, NULL, &timeout); +#endif /* * XXX: Do we care about the different error conditions? @@ -1219,23 +1263,41 @@ int accept_connection(struct client_state * csp, jb_socket fds[]) int retval; int i; int max_selected_socket; +#ifdef HAVE_POLL + struct pollfd poll_fds[MAX_LISTENING_SOCKETS]; + nfds_t polled_sockets; +#else fd_set selected_fds; +#endif jb_socket fd; + const char *host_addr; + size_t listen_addr_size; c_length = sizeof(client); +#ifdef HAVE_POLL + memset(poll_fds, 0, sizeof(poll_fds)); + polled_sockets = 0; +#else /* * Wait for a connection on any socket. * Return immediately if no socket is listening. * XXX: Why not treat this as fatal error? */ FD_ZERO(&selected_fds); +#endif max_selected_socket = 0; for (i = 0; i < MAX_LISTENING_SOCKETS; i++) { if (JB_INVALID_SOCKET != fds[i]) { +#ifdef HAVE_POLL + poll_fds[i].fd = fds[i]; + poll_fds[i].events = POLLIN; + polled_sockets++; +#else FD_SET(fds[i], &selected_fds); +#endif if (max_selected_socket < fds[i] + 1) { max_selected_socket = fds[i] + 1; @@ -1248,7 +1310,11 @@ int accept_connection(struct client_state * csp, jb_socket fds[]) } do { +#ifdef HAVE_POLL + retval = poll(poll_fds, polled_sockets, -1); +#else retval = select(max_selected_socket, &selected_fds, NULL, NULL, NULL); +#endif } while (retval < 0 && errno == EINTR); if (retval <= 0) { @@ -1266,8 +1332,12 @@ int accept_connection(struct client_state * csp, jb_socket fds[]) } return 0; } +#ifdef HAVE_POLL + for (i = 0; i < MAX_LISTENING_SOCKETS && (poll_fds[i].revents == 0); i++); +#else for (i = 0; i < MAX_LISTENING_SOCKETS && !FD_ISSET(fds[i], &selected_fds); i++); +#endif if (i >= MAX_LISTENING_SOCKETS) { log_error(LOG_LEVEL_ERROR, @@ -1314,6 +1384,7 @@ int accept_connection(struct client_state * csp, jb_socket fds[]) } #endif +#ifndef HAVE_POLL #ifndef _WIN32 if (afd >= FD_SETSIZE) { @@ -1324,6 +1395,7 @@ int accept_connection(struct client_state * csp, jb_socket fds[]) return 0; } #endif +#endif #ifdef FEATURE_EXTERNAL_FILTERS mark_socket_for_close_on_execute(afd); @@ -1348,6 +1420,26 @@ int accept_connection(struct client_state * csp, jb_socket fds[]) csp->ip_addr_long = ntohl(client.sin_addr.s_addr); #endif /* def HAVE_RFC2553 */ + /* + * Save the name and port of the accepting socket for later lookup. + * + * The string needs space for strlen(...) + 7 characters: + * strlen(haddr[i]) + 1 (':') + 5 (port digits) + 1 ('\0') + */ + host_addr = (csp->config->haddr[i] != NULL) ? csp->config->haddr[i] : ""; + listen_addr_size = strlen(host_addr) + 7; + csp->listen_addr_str = malloc_or_die(listen_addr_size); + retval = snprintf(csp->listen_addr_str, listen_addr_size, + "%s:%d", host_addr, csp->config->hport[i]); + if ((-1 == retval) || listen_addr_size <= retval) + { + log_error(LOG_LEVEL_ERROR, + "Server name (%s) and port number (%d) ASCII decimal representation" + "don't fit into %d bytes", + host_addr, csp->config->hport[i], listen_addr_size); + return 0; + } + return 1; }