X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=jbsockets.c;h=18e424698ae9ebf962fa3c2b1f91b77a7f82eb7b;hp=6d4923e44b052ac5c64e5be072c2faf45160bf0d;hb=e8db07c2f0720685bb504013a6a1e576b0cf718f;hpb=e14447d0f0ebc27b37232fbb8d68a232d2a553a0 diff --git a/jbsockets.c b/jbsockets.c index 6d4923e4..18e42469 100644 --- a/jbsockets.c +++ b/jbsockets.c @@ -1,4 +1,4 @@ -const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.51 2009/04/17 11:27:49 fabiankeil Exp $"; +const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.54 2009/04/17 11:45:19 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jbsockets.c,v $ @@ -8,7 +8,7 @@ const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.51 2009/04/17 11:27:49 fabian * OS-independent. Contains #ifdefs to make this work * on many platforms. * - * Copyright : Written by and Copyright (C) 2001-2007 the SourceForge + * Copyright : Written by and Copyright (C) 2001-2009 the * Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written @@ -35,6 +35,16 @@ const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.51 2009/04/17 11:27:49 fabian * * Revisions : * $Log: jbsockets.c,v $ + * Revision 1.54 2009/04/17 11:45:19 fabiankeil + * Replace HAVE_GETADDRINFO and HAVE_GETNAMEINFO macros + * with HAVE_RFC2553 macro. Original patch by Petr Pisar. + * + * Revision 1.53 2009/04/17 11:39:52 fabiankeil + * If the hostname is 'localhost' or not specified, request an AF_INET address. + * + * Revision 1.52 2009/04/17 11:34:34 fabiankeil + * Style cosmetics for the IPv6 code. + * * Revision 1.51 2009/04/17 11:27:49 fabiankeil * Petr Pisar's privoxy-3.0.12-ipv6-3.diff. * @@ -318,6 +328,16 @@ const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.51 2009/04/17 11:27:49 fabian #endif +#ifdef FEATURE_CONNECTION_KEEP_ALIVE +#ifdef HAVE_POLL +#ifdef __GLIBC__ +#include +#else +#include +#endif /* def __GLIBC__ */ +#endif /* HAVE_POLL */ +#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ + #include "project.h" #ifdef FEATURE_PTHREAD @@ -328,6 +348,7 @@ const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.51 2009/04/17 11:27:49 fabian #include "jbsockets.h" #include "filters.h" #include "errlog.h" +#include "miscutil.h" const char jbsockets_h_rcs[] = JBSOCKETS_H_VERSION; @@ -358,7 +379,7 @@ const char jbsockets_h_rcs[] = JBSOCKETS_H_VERSION; * file descriptor. * *********************************************************************/ -#ifdef HAVE_GETADDRINFO +#ifdef HAVE_RFC2553 /* Getaddrinfo implementation */ jb_socket connect_to(const char *host, int portnum, struct client_state *csp) { @@ -530,7 +551,7 @@ jb_socket connect_to(const char *host, int portnum, struct client_state *csp) } -# else /* ndef HAVE_GETADDRINFO */ +#else /* ndef HAVE_RFC2553 */ /* Pre-getaddrinfo implementation */ jb_socket connect_to(const char *host, int portnum, struct client_state *csp) @@ -660,7 +681,7 @@ jb_socket connect_to(const char *host, int portnum, struct client_state *csp) return(fd); } -#endif /* ndef HAVE_GETADDRINFO */ +#endif /* ndef HAVE_RFC2553 */ /********************************************************************* @@ -856,7 +877,7 @@ void close_socket(jb_socket fd) *********************************************************************/ int bind_port(const char *hostnam, int portnum, jb_socket *pfd) { -#ifdef HAVE_GETADDRINFO +#ifdef HAVE_RFC2553 struct addrinfo hints; struct addrinfo *result, *rp; /* @@ -868,7 +889,7 @@ int bind_port(const char *hostnam, int portnum, jb_socket *pfd) int retval; #else struct sockaddr_in inaddr; -#endif /* def HAVE_GETADDRINFO */ +#endif /* def HAVE_RFC2553 */ jb_socket fd; #ifndef _WIN32 int one = 1; @@ -876,7 +897,7 @@ int bind_port(const char *hostnam, int portnum, jb_socket *pfd) *pfd = JB_INVALID_SOCKET; -#ifdef HAVE_GETADDRINFO +#ifdef HAVE_RFC2553 retval = snprintf(servnam, sizeof(servnam), "%d", portnum); if ((-1 == retval) || (sizeof(servnam) <= retval)) { @@ -887,7 +908,20 @@ int bind_port(const char *hostnam, int portnum, jb_socket *pfd) } memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; + if ((hostnam == NULL) || !strcmpic(hostnam, "localhost")) + { + /* + * XXX: This is a hack. The right thing to do + * would be to bind to both AF_INET and AF_INET6. + * This will also fail if there is no AF_INET + * version available. + */ + hints.ai_family = AF_INET; + } + else + { + hints.ai_family = AF_UNSPEC; + } hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; hints.ai_protocol = 0; /* Realy any stream protocol or TCP only */ @@ -924,15 +958,15 @@ int bind_port(const char *hostnam, int portnum, jb_socket *pfd) inaddr.sin_port = htonl((unsigned long) portnum); } #endif /* ndef _WIN32 */ -#endif /* def HAVE_GETADDRINFO */ +#endif /* def HAVE_RFC2553 */ -#ifdef HAVE_GETADDRINFO +#ifdef HAVE_RFC2553 for (rp = result; rp != NULL; rp = rp->ai_next) { fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); #else fd = socket(AF_INET, SOCK_STREAM, 0); -#endif /* def HAVE_GETADDRINFO */ +#endif /* def HAVE_RFC2553 */ #ifdef _WIN32 if (fd == JB_INVALID_SOCKET) @@ -940,7 +974,7 @@ int bind_port(const char *hostnam, int portnum, jb_socket *pfd) if (fd < 0) #endif { -#ifdef HAVE_GETADDRINFO +#ifdef HAVE_RFC2553 continue; #else return(-1); @@ -963,7 +997,7 @@ int bind_port(const char *hostnam, int portnum, jb_socket *pfd) setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)); #endif /* ndef _WIN32 */ -#ifdef HAVE_GETADDRINFO +#ifdef HAVE_RFC2553 if (bind(fd, rp->ai_addr, rp->ai_addrlen) < 0) #else if (bind(fd, (struct sockaddr *)&inaddr, sizeof(inaddr)) < 0) @@ -976,7 +1010,7 @@ int bind_port(const char *hostnam, int portnum, jb_socket *pfd) if (errno == EADDRINUSE) #endif { -#ifdef HAVE_GETADDRINFO +#ifdef HAVE_RFC2553 freeaddrinfo(result); #endif close_socket(fd); @@ -985,7 +1019,7 @@ int bind_port(const char *hostnam, int portnum, jb_socket *pfd) else { close_socket(fd); -#ifndef HAVE_GETADDRINFO +#ifndef HAVE_RFC2553 return(-1); } } @@ -1010,7 +1044,7 @@ int bind_port(const char *hostnam, int portnum, jb_socket *pfd) /* All bind()s failed */ return(-1); } -#endif /* ndef HAVE_GETADDRINFO */ +#endif /* ndef HAVE_RFC2553 */ while (listen(fd, MAX_LISTEN_BACKLOG) == -1) { @@ -1050,20 +1084,20 @@ int bind_port(const char *hostnam, int portnum, jb_socket *pfd) *********************************************************************/ void get_host_information(jb_socket afd, char **ip_address, char **hostname) { -#ifdef HAVE_GETNAMEINFO +#ifdef HAVE_RFC2553 struct sockaddr_storage server; int retval; #else struct sockaddr_in server; struct hostent *host = NULL; -#endif /* HAVE_GETNAMEINFO */ +#endif /* HAVE_RFC2553 */ #if defined(_WIN32) || defined(__OS2__) || defined(__APPLE_CC__) || defined(AMIGA) /* according to accept_connection() this fixes a warning. */ int s_length, s_length_provided; #else socklen_t s_length, s_length_provided; #endif -#ifndef HAVE_GETNAMEINFO +#ifndef HAVE_RFC2553 #if defined(HAVE_GETHOSTBYADDR_R_8_ARGS) || defined(HAVE_GETHOSTBYADDR_R_7_ARGS) || defined(HAVE_GETHOSTBYADDR_R_5_ARGS) struct hostent result; #if defined(HAVE_GETHOSTBYADDR_R_5_ARGS) @@ -1073,7 +1107,7 @@ void get_host_information(jb_socket afd, char **ip_address, char **hostname) int thd_err; #endif /* def HAVE_GETHOSTBYADDR_R_5_ARGS */ #endif /* def HAVE_GETHOSTBYADDR_R_(8|7|5)_ARGS */ -#endif /* ifndef HAVE_GETNAMEINFO */ +#endif /* ifndef HAVE_RFC2553 */ s_length = s_length_provided = sizeof(server); if (NULL != hostname) @@ -1089,7 +1123,7 @@ void get_host_information(jb_socket afd, char **ip_address, char **hostname) log_error(LOG_LEVEL_ERROR, "getsockname() truncated server address"); return; } -#ifdef HAVE_GETNAMEINFO +#ifdef HAVE_RFC2553 *ip_address = malloc(NI_MAXHOST); retval = getnameinfo((struct sockaddr *) &server, s_length, *ip_address, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); @@ -1102,7 +1136,7 @@ void get_host_information(jb_socket afd, char **ip_address, char **hostname) } #else *ip_address = strdup(inet_ntoa(server.sin_addr)); -#endif /* HAVE_GETNAMEINFO */ +#endif /* HAVE_RFC2553 */ if (NULL == hostname) { /* @@ -1112,7 +1146,7 @@ void get_host_information(jb_socket afd, char **ip_address, char **hostname) return; } -#ifdef HAVE_GETNAMEINFO +#ifdef HAVE_RFC2553 *hostname = malloc(NI_MAXHOST); retval = getnameinfo((struct sockaddr *) &server, s_length, *hostname, NI_MAXHOST, NULL, 0, NI_NAMEREQD); @@ -1160,7 +1194,7 @@ void get_host_information(jb_socket afd, char **ip_address, char **hostname) { *hostname = strdup(host->h_name); } -#endif /* else def HAVE_GETNAMEINFO */ +#endif /* else def HAVE_RFC2553 */ } return; @@ -1185,7 +1219,7 @@ void get_host_information(jb_socket afd, char **ip_address, char **hostname) *********************************************************************/ int accept_connection(struct client_state * csp, jb_socket fd) { -#ifdef HAVE_GETNAMEINFO +#ifdef HAVE_RFC2553 /* XXX: client is stored directly into csp->tcp_addr */ #define client (csp->tcp_addr) int retval; @@ -1220,7 +1254,7 @@ int accept_connection(struct client_state * csp, jb_socket fd) #endif csp->cfd = afd; -#ifdef HAVE_GETNAMEINFO +#ifdef HAVE_RFC2553 csp->ip_addr_str = malloc(NI_MAXHOST); retval = getnameinfo((struct sockaddr *) &client, c_length, csp->ip_addr_str, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); @@ -1234,7 +1268,7 @@ int accept_connection(struct client_state * csp, jb_socket fd) #else csp->ip_addr_str = strdup(inet_ntoa(client.sin_addr)); csp->ip_addr_long = ntohl(client.sin_addr.s_addr); -#endif /* def HAVE_GETNAMEINFO */ +#endif /* def HAVE_RFC2553 */ return 1; @@ -1361,6 +1395,68 @@ unsigned long resolve_hostname_to_ip(const char *host) } +#ifdef FEATURE_CONNECTION_KEEP_ALIVE +/********************************************************************* + * + * Function : socket_is_still_usable + * + * Description : Decides whether or not an open socket is still usable. + * + * Parameters : + * 1 : sfd = The socket to check. + * + * Returns : TRUE for yes, otherwise FALSE. + * + *********************************************************************/ +int socket_is_still_usable(jb_socket sfd) +{ +#ifdef HAVE_POLL + int poll_result; + struct pollfd poll_fd[1]; + + memset(poll_fd, 0, sizeof(poll_fd)); + poll_fd[0].fd = sfd; + poll_fd[0].events = POLLIN; + + poll_result = poll(poll_fd, 1, 0); + + if (-1 != poll_result) + { + return !(poll_fd[0].revents & POLLIN); + } + else + { + log_error(LOG_LEVEL_CONNECT, "Polling socket %d failed.", sfd); + return FALSE; + } +#else + fd_set readable_fds; + struct timeval timeout; + int ret; + int socket_is_alive = 0; + + memset(&timeout, '\0', sizeof(timeout)); + FD_ZERO(&readable_fds); + FD_SET(sfd, &readable_fds); + + ret = select((int)sfd+1, &readable_fds, NULL, NULL, &timeout); + if (ret < 0) + { + log_error(LOG_LEVEL_ERROR, "select() failed!: %E"); + } + + /* + * XXX: I'm not sure why !FD_ISSET() works, + * but apparently it does. + */ + socket_is_alive = !FD_ISSET(sfd, &readable_fds); + + return socket_is_alive; +#endif /* def HAVE_POLL */ +} +#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ + + /* Local Variables: tab-width: 3