X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=jbsockets.c;h=3a862f5be3f440053446153054ac0e677e9e3d95;hp=4fb86123d40ea6a6075cf361e39b004f4f98320f;hb=1f28c399b73ef84fff9903a48bf7d14153be224f;hpb=915f23de10c8d1d24e70c79adeb1793ea98bf057 diff --git a/jbsockets.c b/jbsockets.c index 4fb86123..3a862f5b 100644 --- a/jbsockets.c +++ b/jbsockets.c @@ -1,4 +1,4 @@ -const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.133 2015/11/06 13:35:24 fabiankeil Exp $"; +const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.140 2017/05/25 11:16:56 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jbsockets.c,v $ @@ -8,7 +8,7 @@ const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.133 2015/11/06 13:35:24 fabia * OS-independent. Contains #ifdefs to make this work * on many platforms. * - * Copyright : Written by and Copyright (C) 2001-2014 the + * Copyright : Written by and Copyright (C) 2001-2017 the * Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written @@ -50,6 +50,7 @@ const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.133 2015/11/06 13:35:24 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; }