Ryan Phillips
Wed, 11 Jun 2008 22:40:53 -0700
Ryan Phillips <[EMAIL PROTECTED]> said: > Jeff Trawick <[EMAIL PROTECTED]> said: > > On Mon, Jun 9, 2008 at 9:19 PM, Ryan Phillips <[EMAIL PROTECTED]> wrote: > > > Ryan Phillips <[EMAIL PROTECTED]> said: > > >> So I needed to create some mod_rewrite rules only for IPv6 when httpd is > > >> configured for both ipv4 and ipv6 modes. This patch adds > > >> 'RewriteCond IPV6 on' support to the ruleset. > > >> > > >> I initially tried to see if the incoming socket was APR_INET6, but > > >> couldn't > > >> find the right structure within the request to query. > > >> > > > > > > Should r->connection->local_addr or remote_addr have the correct socket > > > family? If I try either of these over an IPv4 connection, I always get a > > > socket family of IPv6. > > > > On most platforms, httpd will handle IPv4 connections on an IPv6 > > socket; the address family will be APR_INET6 and the socket address > > will have a special format which indicates that the client is IPv4 > > (http://en.wikipedia.org/wiki/IPv4_mapped_address). > > > > Replace "Listen ##" with the combination "Listen 0.0.0.0:##" + "Listen > > [::]:##" and you should be able to distinguish between client > > connection type by checking the address family (not a real solution). > > > > The system macro IN6_IS_ADDR_V4MAPPED() can check if an IPv6 socket > > address represents an IPv4 client connection. Apparently APR doesn't > > provide an equivalent. > > Jeff, > > Thanks for the detailed explanation. I wasn't aware of this. Attached is a patch which uses IN6_IS_ADDR_V4MAPPED to see if the client is from an IPv4 socket. Thanks, Ryan
--- mod_rewrite.c.old 2008-06-09 16:50:04.000000000 -0500
+++ mod_rewrite.c 2008-06-11 12:09:50.000000000 -0500
@@ -1765,6 +1765,13 @@
rewritelog((r, 1, ctx->perdir, "RESULT='%s'", result));
return (char *)result;
}
+ else if (!strcmp(var, "IPV6")) {
+ apr_sockaddr_t *addr = r->connection->remote_addr;
+ int flag = (addr->family == AF_INET6 &&
+ !IN6_IS_ADDR_V4MAPPED((struct in6_addr *)addr->ipaddr_ptr));
+ rewritelog((r, 1, ctx->perdir, "IPV6='%s'", flag ? "on" : "off"));
+ return apr_pstrdup(r->pool, flag ? "on" : "off");
+ }
break;
case 5: