p***@fake-box.com
2016-04-24 17:48:15 UTC
Hi,Please find attached (in-line and as attachment) a patch which allows totag a client's request with the port and/or the ip-address of the privoxyserver which handles the request.Example use case:privoxy listens on two addresses, e.g. localhost:8118 and localhost:9119.By tagging the request withThis is for example useful to distinguish request made through differenthosts/ports.Example:---- user.filter ----CLIENT-HEADER-TAGGER: tag-server-ports@^\w*\s+.*\s+HTTP/\d\.\d\s*@TAG-SERVERPORT: $***@DCLIENT-HEADER-TAGGER: tag-server-addrs@^\w*\s+.*\s+HTTP/\d\.\d\s*@TAG-SERVERADDR: $***@D---- user.filter -------- user.action ----# Tag every request with the server port{+client-header-tagger{tag-server-port}}/# Fun only for those connections through 9119{+filter{fun}}TAG:TAG-SERVERPORT: 9119---- user.action ----While we are at it. I propose adding CLIENT-HEADER-TAGGER for all'special' substitutions ($origin, $url, $host, $path), not only for$origin.The patches, sure, needs some polishing (and I'm willing to help, note I'm not subscribed). In particular the spots marked with FIXME. I alsotried to find all spots where the new introduced variablesserver_port_str, ... have to be freed, but I might have missed some.The naming of the newly introduced variables is up to discussion. Feelfree to change them.The patch itself is tested only on a Linux box, but with bothconfigurations: with and without HAVE_RFC2553 defined.Finally, in case it matters:Patch released under GNU General Public License as published by the FreeSoftware Foundation; either version 2 of the License, or (at youroption) any later version.Kind regardsdiff --git a/filters.c b/filters.cindex 245a9ce..e8b395b 100644--- a/filters.c+++ b/filters.c@@ -926,6 +926,8 @@ pcrs_job *compile_dynamic_pcrs_job_list(const struct client_state *csp, const st {"path", csp->http->path, 1}, {"host", csp->http->host, 1}, {"origin", csp->ip_addr_str, 1},+ {"serverport", csp->server_port_str, 1},+ {"serveraddr", csp->server_ip_addr_str, 1}, {NULL, NULL, 1} };@@ -1762,6 +1764,8 @@ static void set_privoxy_variables(const struct client_state *csp) { "PRIVOXY_PATH", csp->http->path }, { "PRIVOXY_HOST", csp->http->host }, { "PRIVOXY_ORIGIN", csp->ip_addr_str },+ { "PRIVOXY_SERVERPORT", csp->server_port_str, 1},+ { "PRIVOXY_SERVERADDR", csp->server_ip_addr_str, 1}, }; for (i = 0; i < SZ(env); i++)diff --git a/jbsockets.c b/jbsockets.cindex 2338423..7e7be77 100644--- a/jbsockets.c+++ b/jbsockets.c@@ -1348,6 +1348,78 @@ int accept_connection(struct client_state * csp, jb_socket fds[]) csp->ip_addr_long = ntohl(client.sin_addr.s_addr); #endif /* def HAVE_RFC2553 */++ /* Get the name/IP of the server which accepted the client and+ * store these in client_state.+ */+#ifdef HAVE_RFC2553+ struct sockaddr_storage server_sin;+#else+ struct sockaddr_in server_sin;+#endif /* def HAVE_RFC2553 */+#if defined(_WIN32) || defined(__OS2__) || defined(AMIGA)+ /* Wierdness - fix a warning. */+ int s_length;+#else+ socklen_t s_length;+#endif+ s_length = sizeof(server_sin);++ /* Resolve socket (a file descriptor) to sockaddr_* */+ if (getsockname(fd, (struct sockaddr *)&server_sin, &s_length) == -1)+ {+ log_error(LOG_LEVEL_ERROR, "Can not determine server socket for "+ "accepted connection.");+ /* FIXME free csp->ip_addr_str? */+ }+ else+ else+ {+ /* get the server port as number and as string */+ struct sockaddr_in *server_sin_in = (struct sockaddr_in *)&server_sin;+#ifndef _WIN32+ if (sizeof(server_sin_in->sin_port) == sizeof(short))+#endif /* ndef _WIN32 */+ {+ /* FIXME: Unnecessary conversation of integers? */+ csp->server_port_num = (int) ntohs(server_sin_in->sin_port);+ }+#ifndef _WIN32+ else+ {+ /* FIXME: Unnecessary conversation of integers? */+ csp->server_port_num = (int) ntohl(server_sin_in->sin_port);+ }+#endif /* ndef _WIN32 */+ char servnam[6];+ retval = snprintf(servnam, sizeof(servnam), "%d", csp->server_port_num);+ if ((-1 == retval) || (sizeof(servnam) <= retval))+ {+ log_error(LOG_LEVEL_ERROR,+ "Port number (%d) ASCII decimal representation doesn't fit into 6 bytes",+ csp->server_port_num);+ /* FIXME free csp->ip_addr_str? */+ }+ /* FIXME unecessary copying? */+ csp->server_port_str = strdup(servnam);++ /* Get the server name or IP as string and as sockaddr_storage/long. */+#ifdef HAVE_RFC2553+ csp->server_tcp_addr = server_sin;+ csp->server_ip_addr_str = malloc_or_die(NI_MAXHOST);+ retval = getnameinfo((struct sockaddr *) &server_sin, s_length,+ csp->server_ip_addr_str, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);+ if (!csp->server_ip_addr_str || retval)+ {+ log_error(LOG_LEVEL_ERROR, "Can not save csp->server_ip_addr_str: %s",+ (csp->server_ip_addr_str) ? gai_strerror(retval) : "Insuffcient memory");+ freez(csp->server_ip_addr_str);+ }+#else+ csp->server_ip_addr_str = strdup(inet_ntoa(server_sin.sin_addr));+ csp->server_ip_addr_long = ntohl(server_sin.sin_addr.s_addr);+#endif /* def HAVE_RFC2553 */+ } /* -END- if (getsockname(...) == -1) */+ return 1; }diff --git a/jcc.c b/jcc.cindex d8e785a..b97cc0b 100644--- a/jcc.c+++ b/jcc.c@@ -4038,6 +4038,8 @@ static void listen_loop(void) "Connection from %s on socket %d dropped due to ACL", csp->ip_addr_str, csp->cfd); close_socket(csp->cfd); freez(csp->ip_addr_str);+ freez(csp->server_port_str);+ freez(csp->server_ip_addr_str); freez(csp_list); continue; }@@ -4053,6 +4055,8 @@ static void listen_loop(void) strlen(TOO_MANY_CONNECTIONS_RESPONSE)); close_socket(csp->cfd); freez(csp->ip_addr_str);+ freez(csp->server_port_str);+ freez(csp->server_ip_addr_str); freez(csp_list); continue; }diff --git a/loaders.c b/loaders.cindex fd3db36..8968895 100644--- a/loaders.c+++ b/loaders.c@@ -182,6 +182,8 @@ unsigned int sweep(void) last_active->next = client_list->next; freez(csp->ip_addr_str);+ freez(csp->server_port_str);+ freez(csp->server_ip_addr_str); freez(csp->client_iob->buf); freez(csp->iob->buf); freez(csp->error_message);diff --git a/project.h b/project.hindex 0d23ef3..6daf178 100644--- a/project.h+++ b/project.h@@ -924,6 +924,31 @@ struct client_state unsigned long ip_addr_long; #endif /* def HAVE_RFC2553 */+ /** The port on which the privoxy server which accepted the+ client's connection.+ As a number. */+ int server_port_num;+ /** The port on which the privoxy server which accepted the+ client's connection.+ As a string. */+ char *server_port_str;+ /** The IP address oft he privoxy server which accepted the+ client's connection.+ As a string. */+ char *server_ip_addr_str;+#ifdef HAVE_RFC2553+ /** The TCP address oft he privoxy server which accepted the+ client's connection.+ As a sockaddr. */+ struct sockaddr_storage server_tcp_addr;+#else+ /** The IP address oft he privoxy server which accepted the+ client's connection.+ As a number. */+ unsigned long server_ip_addr_long;+#endif /* def HAVE_RFC2553 */++ /** The URL that was requested */ struct http_request http[1];