+++ /dev/null
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## 03_ipv6.dpatch by Petr Písař <petrp@users.sf.net>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: IPv6 support for privoxy.
-## DP: http://xpisar.wz.cz/privoxy-ipv6/privoxy-3.0.10-ipv6-all-6.diff
-## DP: Former versions by Lionel Elie Mamane <lionel@mamane.lu>
-
-@DPATCH@
-diff -urNad privoxy~/configure.in privoxy/configure.in
---- privoxy~/configure.in
-+++ privoxy/configure.in
-@@ -1237,7 +1237,7 @@
- AC_TYPE_SIGNAL
- dnl uncommenting does not work for swa. suse linux
- dnl AC_FUNC_STAT
--AC_CHECK_FUNCS([access atexit getcwd gethostbyaddr gethostbyaddr_r gethostbyname gethostbyname_r gettimeofday inet_ntoa localtime_r memchr memmove memset poll putenv random regcomp select setlocale snprintf socket strchr strdup strerror strftime strlcat strlcpy strptime strstr strtoul timegm tzset])
-+AC_CHECK_FUNCS([access atexit getaddrinfo getcwd gethostbyaddr gethostbyaddr_r gethostbyname gethostbyname_r getnameinfo gettimeofday inet_ntoa localtime_r memchr memmove memset poll putenv random regcomp select setlocale snprintf socket strchr strdup strerror strftime strlcat strlcpy strptime strstr strtoul timegm tzset])
-
-
- dnl =================================================================
-diff -urNad privoxy~/doc/source/p-config.sgml privoxy/doc/source/p-config.sgml
---- privoxy~/doc/source/p-config.sgml
-+++ privoxy/doc/source/p-config.sgml
-@@ -1213,9 +1213,9 @@
- <term>Effect if unset:</term>
- <listitem>
- <para>
-- Bind to 127.0.0.1 (localhost), port 8118. This is suitable and recommended for
-- home users who run <application>Privoxy</application> on the same machine as
-- their browser.
-+ Bind to 127.0.0.1 (IPv4 localhost), port 8118. This is suitable and
-+ recommended for home users who run <application>Privoxy</application> on
-+ the same machine as their browser.
- </para>
- </listitem>
- </varlistentry>
-@@ -1231,6 +1231,9 @@
- will need to override the default.
- </para>
- <para>
-+ IPv6 address containing colons has to be quoted by brackets.
-+ </para>
-+ <para>
- If you leave out the IP address, <application>Privoxy</application> will
- bind to all interfaces (addresses) on your machine and may become reachable
- from the Internet. In that case, consider using <link
-@@ -1259,6 +1262,15 @@
- listen-address 192.168.0.1:8118
- </programlisting>
- </para>
-+ <para>
-+ Suppose you are running <application>Privoxy</application> on IPv6 capable
-+ machine and you want to listen on IPv6 loopback device:
-+ </para>
-+ <para>
-+ <programlisting>
-+ listen-address [::1]:8118
-+</programlisting>
-+ </para>
- </listitem>
- </varlistentry>
- </variablelist>
-@@ -1611,23 +1623,41 @@
- <term>Type of value:</term>
- <listitem>
- <para>
-- <replaceable class="parameter">src_addr</replaceable>[/<replaceable class="parameter">src_masklen</replaceable>]
-- [<replaceable class="parameter">dst_addr</replaceable>[/<replaceable class="parameter">dst_masklen</replaceable>]]
-+ <replaceable class="parameter">src_addr</replaceable>[:<replaceable class="parameter">port</replaceable>][/<replaceable class="parameter">src_masklen</replaceable>]
-+ [<replaceable class="parameter">dst_addr</replaceable>[:<replaceable class="parameter">port</replaceable>][/<replaceable class="parameter">dst_masklen</replaceable>]]
- </para>
- <para>
- Where <replaceable class="parameter">src_addr</replaceable> and
-- <replaceable class="parameter">dst_addr</replaceable> are IP addresses in dotted decimal notation or valid
-- DNS names, and <replaceable class="parameter">src_masklen</replaceable> and
-+ <replaceable class="parameter">dst_addr</replaceable> are IPv4 addresses in dotted decimal notation or valid
-+ DNS names, <replaceable class="parameter">port</replaceable> is port
-+ number, and <replaceable class="parameter">src_masklen</replaceable> and
- <replaceable class="parameter">dst_masklen</replaceable> are subnet masks in CIDR notation, i.e. integer
- values from 2 to 30 representing the length (in bits) of the network address. The masks and the whole
- destination part are optional.
- </para>
-+ <para>
-+ If your system implements
-+ <ulink url="http://tools.ietf.org/html/rfc2553">RFC 2553</ulink>, then
-+ <replaceable class="parameter">src_addr</replaceable> and <replaceable
-+ class="parameter">dst_addr</replaceable> can be IPv6 addresses delimeted by
-+ brackets, <replaceable class="parameter">port</replaceable> can be number
-+ or service name, and
-+ <replaceable class="parameter">src_masklen</replaceable> and
-+ <replaceable class="parameter">dst_masklen</replaceable> can be number
-+ from 0 to 128.
-+ </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Default value:</term>
- <listitem>
- <para><emphasis>Unset</emphasis></para>
-+ <para>
-+ No <replaceable class="parameter">port</replaceable> means match any port
-+ and no <replaceable class="parameter">src_masklen</replaceable> or
-+ no <replaceable class="parameter">src_masklen</replaceable> means exactly
-+ given IP address (i.e. 32 for IPv4 and 128 for IPv6).
-+ </para>
- </listitem>
- </varlistentry>
- <varlistentry>
-@@ -1677,6 +1707,13 @@
- IP addresses, only the first one is used.
- </para>
- <para>
-+ Some systems allows IPv4 client to connect to IPv6 server socket.
-+ Then the client's IPv4 address will be translated by system into
-+ IPv6 address space with special prefix ::ffff/96 (so called IPv4
-+ mapped IPv6 address). <application>Privoxy</application> can handle it
-+ and maps such ACL addresses automatically.
-+ </para>
-+ <para>
- Denying access to particular sites by ACL may have undesired side effects
- if the site in question is hosted on a machine which also hosts other sites
- (most sites are).
-@@ -1717,6 +1754,24 @@
- deny-access 192.168.45.73 www.dirty-stuff.example.com
- </screen>
- </para>
-+ <para>
-+ Allow access from IPv4 network 192.0.2.0/24 even if listening on
-+ IPv6 wild card address (where supported by operating system):
-+ </para>
-+ <para>
-+ <programlisting>
-+ permit-access 192.0.2.0/24
-+</programlisting>
-+ </para>
-+ <para>
-+ This is equivalent to the following line even if listening on IPv4
-+ address (where supported by operating system):
-+ </para>
-+ <para>
-+ <programlisting>
-+ permit-access [::ffff:192.0.2.0]/120
-+</programlisting>
-+ </para>
- </listitem>
- </varlistentry>
- </variablelist>
-@@ -1838,7 +1893,7 @@
- denote <quote>all URLs</quote>.
- <replaceable class="parameter">http_parent</replaceable>[:<replaceable class="parameter">port</replaceable>]
- is the DNS name or IP address of the parent HTTP proxy through which the requests should be forwarded,
-- optionally followed by its listening port (default: 8080).
-+ optionally followed by its listening port (default: 8000).
- Use a single dot (<literal>.</literal>) to denote <quote>no forwarding</quote>.
- </para>
- </listitem>
-@@ -1865,6 +1920,16 @@
- forwarded to another HTTP proxy but are made directly to the web servers.
- </para>
- <para>
-+ <replaceable class="parameter">http_parent</replaceable> can be IPv6
-+ numerical address (if
-+ <ulink url="http://tools.ietf.org/html/rfc2553">RFC 2553</ulink> is
-+ implemented). However not to clash with port delimiter, quote
-+ whole IP address with brackets. On the other hand <replaceable
-+ class="parameter">target_pattern</replaceable> containing IPv6 address
-+ must be delimited by angle brackets (normal brackets are reserved for
-+ regular expression already).
-+ </para>
-+ <para>
- Multiple lines are OK, they are checked in sequence, and the last match wins.
- </para>
- </listitem>
-@@ -1891,6 +1956,24 @@
- forward .isp.example.net .
- </screen>
- </para>
-+ <para>
-+ Parent proxy specified by IPv6 address:
-+ </para>
-+ <para>
-+ <programlisting>
-+ foward / [2001:DB8::1]:8000
-+</programlisting>
-+ </para>
-+ <para>
-+ Suppose your parent proxy doesn't support IPv6:
-+ </para>
-+ <para>
-+ <programlisting>
-+ forward / parent-proxy.example.org:8000
-+ forward ipv6-server.example.org .
-+ forward <[2-3][0-9a-f][0-9a-f][0-9a-f]:*> .
-+</programlisting>
-+ </para>
- </listitem>
- </varlistentry>
- </variablelist>
-@@ -1963,6 +2046,18 @@
- With <literal>forward-socks5</literal> the DNS resolution will happen on the remote server as well.
- </para>
- <para>
-+ <replaceable class="parameter">socks_proxy</replaceable> and
-+ <replaceable class="parameter">http_parent</replaceable> can be IPv6
-+ numerical address (if
-+ <ulink url="http://tools.ietf.org/html/rfc2553">RFC 2553</ulink> is
-+ implemented). However not to clash with port
-+ delimiter, quote whole IP address with brackets. On the other
-+ hand <replaceable class="parameter">target_pattern</replaceable> containing
-+ IPv6 address must be delimited by angle brackets (normal brackets are
-+ reserved for regular expression already). The only exception is SOCKS 4
-+ version where only IPv4 is suppored.
-+ </para>
-+ <para>
- If <replaceable class="parameter">http_parent</replaceable> is <quote>.</quote>, then requests are not
- forwarded to another HTTP proxy but are made (HTTP-wise) directly to the web servers, albeit through
- a SOCKS proxy.
-diff -urNad privoxy~/doc/source/user-manual.sgml privoxy/doc/source/user-manual.sgml
---- privoxy~/doc/source/user-manual.sgml
-+++ privoxy/doc/source/user-manual.sgml
-@@ -2147,12 +2147,12 @@
-
- <para>
- Generally, an URL pattern has the form
-- <literal><domain>/<path></literal>, where both the
-- <literal><domain></literal> and <literal><path></literal> are
-- optional. (This is why the special <literal>/</literal> pattern matches all
-- URLs). Note that the protocol portion of the URL pattern (e.g.
-- <literal>http://</literal>) should <emphasis>not</emphasis> be included in
-- the pattern. This is assumed already!
-+ <literal><domain><port>/<path></literal>, where both the
-+ <literal><domain></literal> and <literal><port></literal>
-+ and <literal><path></literal> are optional. (This is why the special
-+ <literal>/</literal> pattern matches all URLs). Note that the protocol
-+ portion of the URL pattern (e.g. <literal>http://</literal>) should
-+ <emphasis>not</emphasis> be included in the pattern. This is assumed already!
- </para>
- <para>
- The pattern matching syntax is different for the domain and path parts of
-@@ -2161,6 +2161,12 @@
- <ulink url="http://en.wikipedia.org/wiki/Regular_expressions"><quote>Regular
- Expressions</quote></ulink> (POSIX 1003.2).
- </para>
-+<para>
-+ The port part of pattern is decimal port number preceeded by a colon
-+ (<literal>:</literal>). If domain part contains numeric IPv6 address, you
-+ will need to quote the domain part by angle brackets
-+ (<literal><</literal>, <literal>></literal>).
-+</para>
-
- <variablelist>
- <varlistentry>
-@@ -2211,6 +2217,23 @@
- </listitem>
- </varlistentry>
- <varlistentry>
-+ <term><literal>:8000/</literal></term>
-+ <listitem>
-+ <para>
-+ Matches any URL pointing to TCP port 8000.
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term><literal><2001:db8::1>/</literal></term>
-+ <listitem>
-+ <para>
-+ Matches any URL having <literal>2001:db8::1</literal> as a domain.
-+ (Note that real URL uses plain brackets, not an angle brackets.)
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
- <term><literal>index.html</literal></term>
- <listitem>
- <para>
-diff -urNad privoxy~/filters.c privoxy/filters.c
---- privoxy~/filters.c
-+++ privoxy/filters.c
-@@ -665,6 +665,11 @@
- #include <string.h>
- #include <assert.h>
-
-+#ifdef HAVE_GETADDRINFO
-+#include <netdb.h>
-+#include <sys/socket.h>
-+#endif /* def HAVE_GETADDRINFO */
-+
- #ifndef _WIN32
- #ifndef __OS2__
- #include <unistd.h>
-@@ -712,6 +717,152 @@
- static jb_err prepare_for_filtering(struct client_state *csp);
-
- #ifdef FEATURE_ACL
-+#ifdef HAVE_GETADDRINFO
-+/*********************************************************************
-+ *
-+ * Function : sockaddr_storage_to_ip
-+ *
-+ * Description : Access internal structure of sockaddr_storage
-+ *
-+ * Parameters :
-+ * 1 : addr = socket address
-+ * 2 : ip = IP address as array of octets in network order
-+ * (it points into addr)
-+ * 3 : len = length of IP address in octets
-+ * 4 : port = port number in network order;
-+ *
-+ * Returns : 0 = no errror; otherwise
-+ *
-+ *********************************************************************/
-+int sockaddr_storage_to_ip(const struct sockaddr_storage *addr, uint8_t **ip,
-+ unsigned int *len, in_port_t **port)
-+{
-+ if (!addr)
-+ {
-+ return(-1);
-+ }
-+
-+ switch (addr->ss_family)
-+ {
-+ case AF_INET:
-+ if (len)
-+ {
-+ *len = 4;
-+ }
-+ if (ip)
-+ {
-+ *ip = (uint8_t *)
-+ &(( (struct sockaddr_in *) addr)->sin_addr.s_addr);
-+ }
-+ if (port)
-+ {
-+ *port = &((struct sockaddr_in *) addr)->sin_port;
-+ }
-+ break;
-+
-+ case AF_INET6:
-+ if (len)
-+ {
-+ *len = 16;
-+ }
-+ if (ip)
-+ {
-+ *ip = (uint8_t *)
-+ &(( (struct sockaddr_in6 *) addr)->sin6_addr.s6_addr);
-+ }
-+ if (port)
-+ {
-+ *port = &((struct sockaddr_in6 *) addr)->sin6_port;
-+ }
-+ break;
-+
-+ default:
-+ /* Unsupported address family */
-+ return(-1);
-+ }
-+
-+ return(0);
-+}
-+
-+
-+/*********************************************************************
-+ *
-+ * Function : match_sockaddr
-+ *
-+ * Description : Check whether address matches network (IP address and port)
-+ *
-+ * Parameters :
-+ * 1 : network = socket address of subnework
-+ * 3 : netmask = network mask as socket address
-+ * 2 : address = checked socket address against given network
-+ *
-+ * Returns : 0 = doesn't match; 1 = does match
-+ *
-+ *********************************************************************/
-+int match_sockaddr(const struct sockaddr_storage *network,
-+ const struct sockaddr_storage *netmask,
-+ const struct sockaddr_storage *address)
-+{
-+ uint8_t *network_addr, *netmask_addr, *address_addr;
-+ unsigned int addr_len;
-+ in_port_t *network_port, *netmask_port, *address_port;
-+ int i;
-+
-+ if (network->ss_family != netmask->ss_family)
-+ {
-+ /* This should never happen */
-+ log_error(LOG_LEVEL_ERROR,
-+ "Internal error at %s:%llu: network and netmask differ in family",
-+ __FILE__, __LINE__);
-+ return 0;
-+ }
-+
-+ sockaddr_storage_to_ip(network, &network_addr, &addr_len, &network_port);
-+ sockaddr_storage_to_ip(netmask, &netmask_addr, NULL, &netmask_port);
-+ sockaddr_storage_to_ip(address, &address_addr, NULL, &address_port);
-+
-+ /* Check for family */
-+ if (network->ss_family == AF_INET && address->ss_family == AF_INET6 &&
-+ IN6_IS_ADDR_V4MAPPED(address_addr))
-+ {
-+ /* Map AF_INET6 V4MAPPED address into AF_INET */
-+ address_addr += 12;
-+ addr_len = 4;
-+ }
-+ else if (network->ss_family == AF_INET6 && address->ss_family == AF_INET &&
-+ IN6_IS_ADDR_V4MAPPED(network_addr))
-+ {
-+ /* Map AF_INET6 V4MAPPED network into AF_INET */
-+ network_addr += 12;
-+ netmask_addr += 12;
-+ addr_len = 4;
-+ }
-+ else if (network->ss_family != address->ss_family)
-+ {
-+ return 0;
-+ }
-+
-+ /* XXX: Port check is signaled in netmask */
-+ if (*netmask_port && *network_port != *address_port)
-+ {
-+ return 0;
-+ }
-+
-+ /* TODO: Optimize by checking by words insted of octets */
-+ for (i=0; i < addr_len && netmask_addr[i]; i++)
-+ {
-+ if ( (network_addr[i] & netmask_addr[i]) !=
-+ (address_addr[i] & netmask_addr[i]) )
-+ {
-+ return 0;
-+ }
-+ }
-+
-+ return 1;
-+}
-+#endif /* def HAVE_GETADDRINFO */
-+
-+
- /*********************************************************************
- *
- * Function : block_acl
-@@ -741,7 +892,13 @@
- /* search the list */
- while (acl != NULL)
- {
-- if ((csp->ip_addr_long & acl->src->mask) == acl->src->addr)
-+ if (
-+#ifdef HAVE_GETADDRINFO
-+ match_sockaddr(&acl->src->addr, &acl->src->mask, &csp->tcp_addr)
-+#else
-+ (csp->ip_addr_long & acl->src->mask) == acl->src->addr
-+#endif
-+ )
- {
- if (dst == NULL)
- {
-@@ -751,8 +908,23 @@
- return(0);
- }
- }
-- else if ( ((dst->addr & acl->dst->mask) == acl->dst->addr)
-- && ((dst->port == acl->dst->port) || (acl->dst->port == 0)))
-+ else if (
-+#ifdef HAVE_GETADDRINFO
-+ /* XXX: Undefined acl->dst is full of zeros and should be
-+ * considered as wildcard address.
-+ * sockaddr_storage_to_ip() failes on such dst because of
-+ * uknown sa_familly on glibc. However this test is not
-+ * portable.
-+ *
-+ * So, we signal the acl->dst is wildcard in wildcard_dst.
-+ */
-+ acl->wildcard_dst ||
-+ match_sockaddr(&acl->dst->addr, &acl->dst->mask, &dst->addr)
-+#else
-+ ((dst->addr & acl->dst->mask) == acl->dst->addr)
-+ && ((dst->port == acl->dst->port) || (acl->dst->port == 0))
-+#endif
-+ )
- {
- if (acl->action == ACL_PERMIT)
- {
-@@ -788,12 +960,24 @@
- int acl_addr(const char *aspec, struct access_control_addr *aca)
- {
- int i, masklength;
-+#ifdef HAVE_GETADDRINFO
-+ struct addrinfo hints, *result;
-+ uint8_t *mask_data;
-+ in_port_t *mask_port;
-+ unsigned int addr_len;
-+#else
- long port;
-+#endif /* def HAVE_GETADDRINFO */
- char *p;
- char *acl_spec = NULL;
-
-+#ifdef HAVE_GETADDRINFO
-+ /* FIXME: Depend on ai_family */
-+ masklength = 128;
-+#else
- masklength = 32;
- port = 0;
-+#endif
-
- /*
- * Use a temporary acl spec copy so we can log
-@@ -817,13 +1001,53 @@
- masklength = atoi(p);
- }
-
-- if ((masklength < 0) || (masklength > 32))
-+ if ((masklength < 0) ||
-+#ifdef HAVE_GETADDRINFO
-+ (masklength > 128)
-+#else
-+ (masklength > 32)
-+#endif
-+ )
- {
- freez(acl_spec);
- return(-1);
- }
-
-- if ((p = strchr(acl_spec, ':')) != NULL)
-+ if (*acl_spec == '[' && NULL != (p = strchr(acl_spec, ']')))
-+ {
-+ *p = '\0';
-+ memmove(acl_spec, acl_spec + 1, (size_t) (p - acl_spec));
-+
-+ if (*++p != ':')
-+ {
-+ p = NULL;
-+ }
-+ }
-+ else
-+ {
-+ p = strchr(acl_spec, ':');
-+ }
-+
-+#ifdef HAVE_GETADDRINFO
-+ memset(&hints, 0, sizeof(struct addrinfo));
-+ hints.ai_family = AF_UNSPEC;
-+ hints.ai_socktype = SOCK_STREAM;
-+
-+ i = getaddrinfo(acl_spec, (p) ? ++p : NULL, &hints, &result);
-+ freez(acl_spec);
-+
-+ if (i != 0)
-+ {
-+ log_error(LOG_LEVEL_ERROR, "Can not resolve [%s]:%s: %s", acl_spec, p,
-+ gai_strerror(i));
-+ return(-1);
-+ }
-+
-+ /* TODO: Allow multihomed hostnames */
-+ memcpy(&(aca->addr), result->ai_addr, sizeof(aca->addr));
-+ freeaddrinfo(result);
-+#else
-+ if (p != NULL)
- {
- char *endptr;
-
-@@ -847,8 +1071,49 @@
- /* XXX: This will be logged as parse error. */
- return(-1);
- }
-+#endif /* def HAVE_GETADDRINFO */
-
- /* build the netmask */
-+#ifdef HAVE_GETADDRINFO
-+ /* Clip masklength according current family */
-+ if (aca->addr.ss_family == AF_INET && masklength > 32)
-+ {
-+ masklength = 32;
-+ }
-+
-+ aca->mask.ss_family = aca->addr.ss_family;
-+ if (sockaddr_storage_to_ip(&aca->mask, &mask_data, &addr_len, &mask_port))
-+ {
-+ return(-1);
-+ }
-+
-+ if (p)
-+ {
-+ /* Port number in ACL has been specified, check ports in future */
-+ *mask_port = 1;
-+ }
-+
-+ /* XXX: This could be optimized to operate on whole words instead of octets
-+ * (128-bit CPU could do it in one iteration). */
-+ /* Octets after prefix can be ommitted because of previous initialization
-+ * to zeros. */
-+ for (i=0; i < addr_len && masklength; i++)
-+ {
-+ if (masklength >= 8)
-+ {
-+ mask_data[i] = 0xFF;
-+ masklength -= 8;
-+ }
-+ else
-+ {
-+ /* XXX: This assumes MSB of octet is on the left site. This should be
-+ * true for all architectures or solved on link layer of OSI model. */
-+ mask_data[i] = ~((1 << (8 - masklength)) - 1);
-+ masklength = 0;
-+ }
-+ }
-+
-+#else
- aca->mask = 0;
- for (i=1; i <= masklength ; i++)
- {
-@@ -859,6 +1124,7 @@
- * (i.e. save on the network portion of the address).
- */
- aca->addr = aca->addr & aca->mask;
-+#endif /* def HAVE_GETADDRINFO */
-
- return(0);
-
-@@ -2706,4 +2972,6 @@
- Local Variables:
- tab-width: 3
- end:
-+
-+ vim:softtabstop=3 shiftwidth=3
- */
-diff -urNad privoxy~/jbsockets.c privoxy/jbsockets.c
---- privoxy~/jbsockets.c
-+++ privoxy/jbsockets.c
-@@ -357,19 +357,52 @@
- *********************************************************************/
- jb_socket connect_to(const char *host, int portnum, struct client_state *csp)
- {
-+#ifdef HAVE_GETADDRINFO
-+ struct addrinfo hints, *result, *rp;
-+ char service[6];
-+ int retval;
-+#else
- struct sockaddr_in inaddr;
-- jb_socket fd;
- unsigned int addr;
-+#endif /* def HAVE_GETADDRINFO */
-+ jb_socket fd;
- fd_set wfds;
- struct timeval tv[1];
- #if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA)
- int flags;
- #endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) */
-+ int connect_failed;
-
- #ifdef FEATURE_ACL
- struct access_control_addr dst[1];
- #endif /* def FEATURE_ACL */
-
-+#ifdef HAVE_GETADDRINFO
-+ retval = snprintf(service, sizeof(service), "%d", portnum);
-+ if (-1 == retval || sizeof(service) <= retval)
-+ {
-+ log_error(LOG_LEVEL_ERROR,
-+ "Port number (%d) ASCII decimal representation doesn't fit into 6 bytes",
-+ portnum);
-+ csp->http->host_ip_addr_str = strdup("unknown");
-+ return(JB_INVALID_SOCKET);
-+ }
-+
-+ memset((char *)&hints, 0, sizeof hints);
-+ hints.ai_family = AF_UNSPEC;
-+ hints.ai_socktype = SOCK_STREAM;
-+ hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV; /* avoid service look-up */
-+ if ((retval = getaddrinfo(host, service, &hints, &result)))
-+ {
-+ log_error(LOG_LEVEL_INFO,
-+ "Can not resolve %s: %s", host, gai_strerror(retval));
-+ csp->http->host_ip_addr_str = strdup("unknown");
-+ return(JB_INVALID_SOCKET);
-+ }
-+
-+ for (rp = result; rp != NULL; rp = rp->ai_next)
-+ {
-+#else
- memset((char *)&inaddr, 0, sizeof inaddr);
-
- if ((addr = resolve_hostname_to_ip(host)) == INADDR_NONE)
-@@ -377,10 +410,15 @@
- csp->http->host_ip_addr_str = strdup("unknown");
- return(JB_INVALID_SOCKET);
- }
-+#endif /* def HAVE_GETADDRINFO */
-
- #ifdef FEATURE_ACL
-+#ifdef HAVE_GETADDRINFO
-+ memcpy(&dst->addr, rp->ai_addr, sizeof(dst->addr));
-+#else
- dst->addr = ntohl(addr);
- dst->port = portnum;
-+#endif /* def HAVE_GETADDRINFO */
-
- if (block_acl(dst, csp))
- {
-@@ -389,14 +427,43 @@
- #else
- errno = EPERM;
- #endif
-+#ifdef HAVE_GETADDRINFO
-+ continue;
-+#else
- return(JB_INVALID_SOCKET);
-+#endif /* def HAVE_GETADDRINFO */
- }
- #endif /* def FEATURE_ACL */
-
-+#ifdef HAVE_GETNAMEINFO
-+ csp->http->host_ip_addr_str = malloc(NI_MAXHOST);
-+ retval = getnameinfo(rp->ai_addr, rp->ai_addrlen,
-+ csp->http->host_ip_addr_str, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
-+ if (!csp->http->host_ip_addr_str || retval)
-+ {
-+ log_error(LOG_LEVEL_ERROR, "Can not save csp->http->host_ip_addr_str: %s",
-+ (csp->http->host_ip_addr_str) ? gai_strerror(retval) :
-+ "Insufficient memory");
-+ freez(csp->http->host_ip_addr_str);
-+ continue;
-+ }
-+#else
- inaddr.sin_addr.s_addr = addr;
- inaddr.sin_family = AF_INET;
- csp->http->host_ip_addr_str = strdup(inet_ntoa(inaddr.sin_addr));
-+#endif /* def HAVE_GETNAMERINFO */
-
-+#ifdef HAVE_GETADDRINFO
-+#ifdef _WIN32
-+ if ((fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) ==
-+ JB_INVALID_SOCKET)
-+#else
-+ if ((fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) < 0)
-+#endif
-+ {
-+ continue;
-+ }
-+#else
- #ifndef _WIN32
- if (sizeof(inaddr.sin_port) == sizeof(short))
- #endif /* ndef _WIN32 */
-@@ -418,6 +485,7 @@
- {
- return(JB_INVALID_SOCKET);
- }
-+#endif /* HAVE_GETADDRINFO */
-
- #ifdef TCP_NODELAY
- { /* turn off TCP coalescence */
-@@ -434,7 +502,12 @@
- }
- #endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) */
-
-+ connect_failed = 0;
-+#ifdef HAVE_GETADDRINFO
-+ while (connect(fd, rp->ai_addr, rp->ai_addrlen) == JB_INVALID_SOCKET)
-+#else
- while (connect(fd, (struct sockaddr *) & inaddr, sizeof inaddr) == JB_INVALID_SOCKET)
-+#endif /* HAVE_GETADDRINFO */
- {
- #ifdef _WIN32
- if (errno == WSAEINPROGRESS)
-@@ -454,9 +527,18 @@
- #endif /* __OS2__ */
- {
- close_socket(fd);
-- return(JB_INVALID_SOCKET);
-+ connect_failed = 1;
-+ break;
- }
- }
-+ if (connect_failed)
-+ {
-+#ifdef HAVE_GETADDRINFO
-+ continue;
-+#else
-+ return(JB_INVALID_SOCKET);
-+#endif
-+ }
-
- #if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
- if (flags != -1)
-@@ -477,8 +559,32 @@
- if (select((int)fd + 1, NULL, &wfds, NULL, tv) <= 0)
- {
- close_socket(fd);
-+#ifdef HAVE_GETADDRINFO
-+ continue;
-+#else
- return(JB_INVALID_SOCKET);
-+#endif
- }
-+
-+#ifdef HAVE_GETADDRINFO
-+ break; /* for */
-+ }
-+
-+ freeaddrinfo(result);
-+ if (!rp)
-+ {
-+ log_error(LOG_LEVEL_INFO, "Could not connect to TCP/[%s]:%s", host, service);
-+ return(JB_INVALID_SOCKET);
-+ }
-+ /* XXX: Current connection verification (EINPROGRESS && select() for
-+ * writing) is not sufficient. E.g. on my Linux-2.6.27 with glibc-2.6
-+ * select returns socket ready for writing, however subsequential write(2)
-+ * fails with ENOCONNECT. Read Linux connect(2) man page about non-blocking
-+ * sockets.
-+ * Thus we can not log here the socket is connected. */
-+ /*log_error(LOG_LEVEL_INFO, "Connected to TCP/[%s]:%s", host, service);*/
-+#endif
-+
- return(fd);
-
- }
-@@ -677,7 +783,16 @@
- *********************************************************************/
- int bind_port(const char *hostnam, int portnum, jb_socket *pfd)
- {
-+#ifdef HAVE_GETADDRINFO
-+ struct addrinfo hints;
-+ struct addrinfo *result, *rp;
-+ /* TODO: portnum shuld be string to allow symbolic service names in
-+ * configuration and to avoid following int2string */
-+ char servnam[6];
-+ int retval;
-+#else
- struct sockaddr_in inaddr;
-+#endif /* def HAVE_GETADDRINFO */
- jb_socket fd;
- #ifndef _WIN32
- int one = 1;
-@@ -685,6 +800,32 @@
-
- *pfd = JB_INVALID_SOCKET;
-
-+#ifdef HAVE_GETADDRINFO
-+ retval = snprintf(servnam, sizeof(servnam), "%d", portnum);
-+ if (-1 == retval || sizeof(servnam) <= retval)
-+ {
-+ log_error(LOG_LEVEL_ERROR,
-+ "Port number (%d) ASCII decimal representation doesn't fit into 6 bytes",
-+ portnum);
-+ return -1;
-+ }
-+
-+ memset(&hints, 0, sizeof(struct addrinfo));
-+ 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 */
-+ hints.ai_canonname=NULL;
-+ hints.ai_addr=NULL;
-+ hints.ai_next=NULL;
-+
-+ if ((retval = getaddrinfo(hostnam, servnam, &hints, &result)))
-+ {
-+ log_error(LOG_LEVEL_ERROR,
-+ "Can not resolve %s: %s", hostnam, gai_strerror(retval));
-+ return -2;
-+ }
-+#else
- memset((char *)&inaddr, '\0', sizeof inaddr);
-
- inaddr.sin_family = AF_INET;
-@@ -707,8 +848,15 @@
- inaddr.sin_port = htonl((unsigned long) portnum);
- }
- #endif /* ndef _WIN32 */
-+#endif /* def HAVE_GETADDRINFO */
-
-+#ifdef HAVE_GETADDRINFO
-+ 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 */
-
- #ifdef _WIN32
- if (fd == JB_INVALID_SOCKET)
-@@ -716,7 +864,11 @@
- if (fd < 0)
- #endif
- {
-+#ifdef HAVE_GETADDRINFO
-+ continue;
-+#else
- return(-1);
-+#endif
- }
-
- #ifndef _WIN32
-@@ -735,7 +887,11 @@
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));
- #endif /* ndef _WIN32 */
-
-+#ifdef HAVE_GETADDRINFO
-+ if (bind(fd, rp->ai_addr, rp->ai_addrlen) < 0)
-+#else
- if (bind(fd, (struct sockaddr *)&inaddr, sizeof(inaddr)) < 0)
-+#endif
- {
- #ifdef _WIN32
- errno = WSAGetLastError();
-@@ -744,15 +900,36 @@
- if (errno == EADDRINUSE)
- #endif
- {
-+#ifdef HAVE_GETADDRINFO
-+ freeaddrinfo(result);
-+#endif
- close_socket(fd);
- return(-3);
- }
- else
- {
- close_socket(fd);
-+#ifndef HAVE_GETADDRINFO
- return(-1);
- }
- }
-+#else
-+ }
-+ }
-+ else
-+ /* bind() succeeded, escape from for-loop */
-+ /* TODO: Support multiple listening sockets (e.g. localhost resolves to
-+ * AF_INET and AF_INET6, but only fist address is used */
-+ break;
-+ }
-+
-+ freeaddrinfo(result);
-+ if (rp == NULL)
-+ {
-+ /* All bind()s failed */
-+ return(-1);
-+ }
-+#endif /* ndef HAVE_GETADDRINFO */
-
- while (listen(fd, MAX_LISTEN_BACKLOG) == -1)
- {
-@@ -792,14 +969,20 @@
- *********************************************************************/
- void get_host_information(jb_socket afd, char **ip_address, char **hostname)
- {
-+#ifdef HAVE_GETNAMEINFO
-+ struct sockaddr_storage server;
-+ int retval;
-+#else
- struct sockaddr_in server;
- struct hostent *host = NULL;
-+#endif /* HAVE_GETNAMEINFO */
- #if defined(_WIN32) || defined(__OS2__) || defined(__APPLE_CC__) || defined(AMIGA)
- /* according to accept_connection() this fixes a warning. */
-- int s_length;
-+ int s_length, s_length_provided;
- #else
-- socklen_t s_length;
-+ socklen_t s_length, s_length_provided;
- #endif
-+#ifndef HAVE_GETNAMEINFO
- #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)
-@@ -809,7 +992,8 @@
- int thd_err;
- #endif /* def HAVE_GETHOSTBYADDR_R_5_ARGS */
- #endif /* def HAVE_GETHOSTBYADDR_R_(8|7|5)_ARGS */
-- s_length = sizeof(server);
-+#endif /* ifndef HAVE_GETNAMEINFO */
-+ s_length = s_length_provided = sizeof(server);
-
- if (NULL != hostname)
- {
-@@ -819,8 +1003,23 @@
-
- if (!getsockname(afd, (struct sockaddr *) &server, &s_length))
- {
-+ if (s_length > s_length_provided)
-+ {
-+ log_error(LOG_LEVEL_ERROR, "getsockname() truncated server address");
-+ return;
-+ }
-+#ifdef HAVE_GETNAMEINFO
-+ *ip_address = malloc(NI_MAXHOST);
-+ if ((retval = getnameinfo((struct sockaddr *) &server, s_length,
-+ *ip_address, NI_MAXHOST, NULL, 0, NI_NUMERICHOST))) {
-+ log_error(LOG_LEVEL_ERROR, "Unable to print my own IP address: %s",
-+ gai_strerror(retval));
-+ freez(*ip_address);
-+ return;
-+ }
-+#else
- *ip_address = strdup(inet_ntoa(server.sin_addr));
--
-+#endif /* HAVE_GETNAMEINFO */
- if (NULL == hostname)
- {
- /*
-@@ -829,6 +1028,16 @@
- */
- return;
- }
-+
-+#ifdef HAVE_GETNAMEINFO
-+ *hostname = malloc(NI_MAXHOST);
-+ if ((retval = getnameinfo((struct sockaddr *) &server, s_length,
-+ *hostname, NI_MAXHOST, NULL, 0, NI_NAMEREQD))) {
-+ log_error(LOG_LEVEL_ERROR, "Unable to resolve my own IP address: %s",
-+ gai_strerror(retval));
-+ freez(*hostname);
-+ }
-+#else
- #if defined(HAVE_GETHOSTBYADDR_R_8_ARGS)
- gethostbyaddr_r((const char *)&server.sin_addr,
- sizeof(server.sin_addr), AF_INET,
-@@ -866,6 +1075,7 @@
- {
- *hostname = strdup(host->h_name);
- }
-+#endif /* else def HAVE_GETNAMEINFO */
- }
-
- return;
-@@ -890,7 +1100,13 @@
- *********************************************************************/
- int accept_connection(struct client_state * csp, jb_socket fd)
- {
-+#ifdef HAVE_GETNAMEINFO
-+ /* XXX: client is stored directly into csp->tcp_addr */
-+#define client (csp->tcp_addr)
-+ int retval;
-+#else
- struct sockaddr_in client;
-+#endif
- jb_socket afd;
- #if defined(_WIN32) || defined(__OS2__) || defined(__APPLE_CC__) || defined(AMIGA)
- /* Wierdness - fix a warning. */
-@@ -919,8 +1135,21 @@
- #endif
-
- csp->cfd = afd;
-+#ifdef HAVE_GETNAMEINFO
-+ csp->ip_addr_str = malloc(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)
-+ {
-+ log_error(LOG_LEVEL_ERROR, "Can not save csp->ip_addr_str: %s",
-+ (csp->ip_addr_str) ? gai_strerror(retval) : "Insuffcient memory");
-+ freez(csp->ip_addr_str);
-+ }
-+#undef client
-+#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 */
-
- return 1;
-
-@@ -1051,4 +1280,6 @@
- Local Variables:
- tab-width: 3
- end:
-+
-+ vim:softtabstop=3 shiftwidth=3
- */
-diff -urNad privoxy~/jcc.c privoxy/jcc.c
---- privoxy~/jcc.c
-+++ privoxy/jcc.c
-@@ -2710,7 +2710,7 @@
-
- if (fwd->forward_host)
- {
-- log_error(LOG_LEVEL_CONNECT, "via %s:%d to: %s",
-+ log_error(LOG_LEVEL_CONNECT, "via [%s]:%d to: %s",
- fwd->forward_host, fwd->forward_port, http->hostport);
- }
- else
-@@ -4483,4 +4483,6 @@
- Local Variables:
- tab-width: 3
- end:
-+
-+ vim:softtabstop=3 shiftwidth=3
- */
-diff -urNad privoxy~/loadcfg.c privoxy/loadcfg.c
---- privoxy~/loadcfg.c
-+++ privoxy/loadcfg.c
-@@ -835,7 +835,6 @@
- * Set to defaults
- */
- config->multi_threaded = 1;
-- config->hport = HADDR_PORT;
- config->buffer_limit = 4096 * 1024;
- config->usermanual = strdup(USER_MANUAL_URL);
- config->proxy_args = strdup("");
-@@ -1044,6 +1043,12 @@
- break;
- }
- }
-+#ifdef HAVE_GETADDRINFO
-+ else
-+ {
-+ cur_acl->wildcard_dst = 1;
-+ }
-+#endif /* def HAVE_GETADDRINFO */
-
- /*
- * Add it to the list. Note we reverse the list to get the
-@@ -1193,7 +1198,18 @@
- {
- cur_fwd->forward_host = strdup(p);
-
-- if (NULL != (p = strchr(cur_fwd->forward_host, ':')))
-+ if (*cur_fwd->forward_host == '[' &&
-+ NULL != (p = strchr(cur_fwd->forward_host, ']')))
-+ {
-+ *p++ = '\0';
-+ memmove(cur_fwd->forward_host, cur_fwd->forward_host + 1,
-+ (size_t) (p - cur_fwd->forward_host));
-+ if (*p == ':')
-+ {
-+ cur_fwd->forward_port = atoi(++p);
-+ }
-+ }
-+ else if (NULL != (p = strchr(cur_fwd->forward_host, ':')))
- {
- *p++ = '\0';
- cur_fwd->forward_port = atoi(p);
-@@ -1257,11 +1273,23 @@
- {
- cur_fwd->gateway_host = strdup(p);
-
-- if (NULL != (p = strchr(cur_fwd->gateway_host, ':')))
-+ if (*cur_fwd->gateway_host == '[' &&
-+ NULL != (p = strchr(cur_fwd->gateway_host, ']')))
-+ {
-+ *p++ = '\0';
-+ memmove(cur_fwd->gateway_host, cur_fwd->gateway_host + 1,
-+ (size_t) (p - cur_fwd->gateway_host));
-+ if (*p == ':')
-+ {
-+ cur_fwd->gateway_port = atoi(++p);
-+ }
-+ }
-+ else if (NULL != (p = strchr(cur_fwd->gateway_host, ':')))
- {
- *p++ = '\0';
- cur_fwd->gateway_port = atoi(p);
- }
-+
- if (cur_fwd->gateway_port <= 0)
- {
- cur_fwd->gateway_port = 1080;
-@@ -1275,7 +1303,18 @@
- {
- cur_fwd->forward_host = strdup(p);
-
-- if (NULL != (p = strchr(cur_fwd->forward_host, ':')))
-+ if (*cur_fwd->forward_host == '[' &&
-+ NULL != (p = strchr(cur_fwd->forward_host, ']')))
-+ {
-+ *p++ = '\0';
-+ memmove(cur_fwd->forward_host, cur_fwd->forward_host + 1,
-+ (size_t) (p - cur_fwd->forward_host));
-+ if (*p == ':')
-+ {
-+ cur_fwd->forward_port = atoi(++p);
-+ }
-+ }
-+ else if (NULL != (p = strchr(cur_fwd->forward_host, ':')))
- {
- *p++ = '\0';
- cur_fwd->forward_port = atoi(p);
-@@ -1345,11 +1384,23 @@
-
- cur_fwd->gateway_host = strdup(p);
-
-- if (NULL != (p = strchr(cur_fwd->gateway_host, ':')))
-+ if (*cur_fwd->gateway_host == '[' &&
-+ NULL != (p = strchr(cur_fwd->gateway_host, ']')))
-+ {
-+ *p++ = '\0';
-+ memmove(cur_fwd->gateway_host, cur_fwd->gateway_host + 1,
-+ (size_t) (p - cur_fwd->gateway_host));
-+ if (*p == ':')
-+ {
-+ cur_fwd->gateway_port = atoi(++p);
-+ }
-+ }
-+ else if (NULL != (p = strchr(cur_fwd->gateway_host, ':')))
- {
- *p++ = '\0';
- cur_fwd->gateway_port = atoi(p);
- }
-+
- if (cur_fwd->gateway_port <= 0)
- {
- cur_fwd->gateway_port = 1080;
-@@ -1362,7 +1413,18 @@
- {
- cur_fwd->forward_host = strdup(p);
-
-- if (NULL != (p = strchr(cur_fwd->forward_host, ':')))
-+ if (*cur_fwd->forward_host == '[' &&
-+ NULL != (p = strchr(cur_fwd->forward_host, ']')))
-+ {
-+ *p++ = '\0';
-+ memmove(cur_fwd->forward_host, cur_fwd->forward_host + 1,
-+ (size_t) (p - cur_fwd->forward_host));
-+ if (*p == ':')
-+ {
-+ cur_fwd->forward_port = atoi(++p);
-+ }
-+ }
-+ else if (NULL != (p = strchr(cur_fwd->forward_host, ':')))
- {
- *p++ = '\0';
- cur_fwd->forward_port = atoi(p);
-@@ -1512,6 +1574,12 @@
- break;
- }
- }
-+#ifdef HAVE_GETADDRINFO
-+ else
-+ {
-+ cur_acl->wildcard_dst = 1;
-+ }
-+#endif /* def HAVE_GETADDRINFO */
-
- /*
- * Add it to the list. Note we reverse the list to get the
-@@ -1851,18 +1919,20 @@
-
- if ( NULL != config->haddr )
- {
-- if (NULL != (p = strchr(config->haddr, ':')))
-+ if (*config->haddr == '[' && NULL != (p = strchr(config->haddr, ']')) &&
-+ p[1] == ':' && 0 < (config->hport = atoi(p + 2)))
- {
-- *p++ = '\0';
-- if (*p)
-- {
-- config->hport = atoi(p);
-- }
-+ *p='\0';
-+ memmove((void *) config->haddr, config->haddr + 1,
-+ (size_t) (p - config->haddr));
- }
--
-- if (config->hport <= 0)
-+ else if (NULL != (p = strchr(config->haddr, ':')) &&
-+ 0 < (config->hport = atoi(p + 1)))
-+ {
-+ *p = '\0';
-+ }
-+ else
- {
-- *--p = ':';
- log_error(LOG_LEVEL_FATAL, "invalid bind port spec %s", config->haddr);
- /* Never get here - LOG_LEVEL_FATAL causes program exit */
- }
-@@ -2038,4 +2108,6 @@
- Local Variables:
- tab-width: 3
- end:
-+
-+ vim:softtabstop=3 shiftwidth=3
- */
-diff -urNad privoxy~/project.h privoxy/project.h
---- privoxy~/project.h
-+++ privoxy/project.h
-@@ -710,6 +710,12 @@
- /* Needed for pcre choice */
- #include "config.h"
-
-+#ifdef HAVE_GETADDRINFO
-+/* Need for struct sockaddr_storage */
-+#include <sys/socket.h>
-+#endif
-+
-+
- /*
- * Include appropriate regular expression libraries.
- * Note that pcrs and pcre (native) are needed for cgi
-@@ -861,16 +867,10 @@
- #define FOREVER 1
-
- /**
-- * Default IP address to listen on, as a string.
-- * Set to "127.0.0.1".
-- */
--#define HADDR_DEFAULT "127.0.0.1"
--
--/**
-- * Default port to listen on, as a number.
-- * Set to 8118.
-+ * Default TCP/IP address to listen on, as a string.
-+ * Set to "127.0.0.1:8118".
- */
--#define HADDR_PORT 8118
-+#define HADDR_DEFAULT "127.0.0.1:8118"
-
-
- /* Forward def for struct client_state */
-@@ -1424,9 +1424,15 @@
- /** Client PC's IP address, as reported by the accept() function.
- As a string. */
- char *ip_addr_str;
-+#ifdef HAVE_GETADDRINFO
-+ /** Client PC's TCP address, as reported by the accept() function.
-+ As a sockaddr. */
-+ struct sockaddr_storage tcp_addr;
-+#else
- /** Client PC's IP address, as reported by the accept() function.
- As a number. */
- unsigned long ip_addr_long;
-+#endif /* def HAVE_GETADDRINFO */
-
- /** The URL that was requested */
- struct http_request http[1];
-@@ -1660,9 +1666,14 @@
- */
- struct access_control_addr
- {
-+#ifdef HAVE_GETADDRINFO
-+ struct sockaddr_storage addr; /* <The TCP address in network order. */
-+ struct sockaddr_storage mask; /* <The TCP mask in network order. */
-+#else
- unsigned long addr; /**< The IP address as an integer. */
- unsigned long mask; /**< The network mask as an integer. */
- unsigned long port; /**< The port number. */
-+#endif /* HAVE_GETADDRINFO */
- };
-
- /**
-@@ -1674,6 +1685,9 @@
- {
- struct access_control_addr src[1]; /**< Client IP address */
- struct access_control_addr dst[1]; /**< Website or parent proxy IP address */
-+#ifdef HAVE_GETADDRINFO
-+ int wildcard_dst; /** < dst address is wildcard */
-+#endif
-
- short action; /**< ACL_PERMIT or ACL_DENY */
- struct access_control_list *next; /**< The next entry in the ACL. */
-@@ -1882,4 +1896,6 @@
- Local Variables:
- tab-width: 3
- end:
-+
-+ vim:softtabstop=3 shiftwidth=3
- */
-diff -urNad privoxy~/urlmatch.c privoxy/urlmatch.c
---- privoxy~/urlmatch.c
-+++ privoxy/urlmatch.c
-@@ -540,8 +540,40 @@
- host = buf;
- }
-
-+ /* Move after hostname before port number */
-+ if (*host == '[')
-+ {
-+ /* Numeric IPv6 address delimited by brackets */
-+ host++;
-+ port = strchr(host, ']');
-+
-+ if (port == NULL)
-+ {
-+ /* Missing closing bracket */
-+ freez(buf);
-+ return JB_ERR_PARSE;
-+ }
-+
-+ *port++='\0';
-+
-+ if (*port == '\0')
-+ {
-+ port = NULL;
-+ }
-+ else if (*port != ':')
-+ {
-+ /* Garbage after closing bracket */
-+ freez(buf);
-+ return JB_ERR_PARSE;
-+ }
-+ }
-+ else
-+ {
-+ /* Plain non-escaped hostname */
-+ port = strchr(host, ':');
-+ }
-+
- /* check if url contains port */
-- port = strchr(host, ':');
- if (port != NULL)
- {
- /* Contains port */
-@@ -844,7 +876,31 @@
- *p = '\0';
- }
-
-- p = strchr(buf, ':');
-+ /* XXX: IPv6 numeric hostname contains colons, thus we need to delimit the
-+ * hostname before real port separator. Because brackets are used in
-+ * hostname matching on lower layer, we can't use it. I decided to use
-+ * angle brackets '<' '>' instead. */
-+ if (buf[0] == '<' && NULL != (p = strchr(buf + 1, '>')))
-+ {
-+ *p++ = '\0';
-+ buf++;
-+
-+ if (*p == '\0')
-+ {
-+ /* Only IPv6 address without port number */
-+ p = NULL;
-+ }
-+ else if (*p != ':')
-+ {
-+ /* Garbage after address delimiter */
-+ return JB_ERR_PARSE;
-+ }
-+ }
-+ else
-+ {
-+ p = strchr(buf, ':');
-+ }
-+
- if (NULL != p)
- {
- *p++ = '\0';
-@@ -1449,4 +1505,6 @@
- Local Variables:
- tab-width: 3
- end:
-+
-+ vim:softtabstop=3 shiftwidth=3
- */