Re: [Pound Mailing List] Location comparision with backend address & host
Bussi Andrea <[email protected]>
| Newsgroups | gmane.comp.web.pound.general |
|---|---|
| Message-ID | <[email protected]> |
On 03/16/2013 09:30 AM, Raj Kishore1/CHN/TCS wrote: > Hi Joe, > > Thanks for the previous replies. > > We have modified the pound 1.9 socket structures to listen IPV4/ipv6 > address. > > However when IPV4 request comes,it is mapped to IPV6 address as > ::ffff:<X.X.X.X> > In case of IPV6 client, it is fetching the IPV6 address only. > > Is it the right mechansim to handle ipv4 client in ipv4 mapped ipv6 > address mode in pound? > > Do we need to handele explicitly the IPV4-6 mapped address in dual stack? > I had the same problem with Pound 2.6; it seems to be an issue in the inet_ntop function, if I'm not mistaken. I don't believe my patch (attached below) is the right way to solve it; the proper way should be a patched inet_ntop. But this solved my troubles; maybe somebody else will find it useful too. Best regards, Bussi Andrea
pound-2.6-ipv4-mapped-in-ipv6-sockets.patch
(text/plain, 1.9 KB)
If an IPv4 connection is made to an IPv6 socket then the local and
remote network addresses will be represented as IPv4-mapped addresses.
We try to print the IPv4 addresses in the usual format.
From inet_ntop man page:
BUGS
AF_INET6 converts IPv4-mapped IPv6 addresses into an IPv6 format.
So this patch can be considered as a workaround for an inet_ntop bug.
--- Pound-2.6/svc.c.orig 2011-12-28 14:57:45.000000000 +0100
+++ Pound-2.6/svc.c 2012-10-11 11:56:15.342374373 +0200
@@ -280,10 +280,26 @@
strncpy(buf, "(UNKNOWN)", MAXBUF - 1);
break;
case AF_INET6:
- src = (void *)&((struct sockaddr_in6 *)addr->ai_addr)->sin6_addr.s6_addr;
- port = ntohs(((struct sockaddr_in6 *)addr->ai_addr)->sin6_port);
- if(inet_ntop(AF_INET6, src, buf, MAXBUF - 1) == NULL)
- strncpy(buf, "(UNKNOWN)", MAXBUF - 1);
+ {
+ struct sockaddr_in6* addr6=(struct sockaddr_in6 *)addr->ai_addr;
+ if( IN6_IS_ADDR_V4MAPPED( &(addr6->sin6_addr) ) ) {
+ struct sockaddr_in addr4;
+ memset(&addr4,0,sizeof(addr4));
+ addr4.sin_family=AF_INET;
+ addr4.sin_port=addr6->sin6_port;
+ memcpy(&addr4.sin_addr.s_addr,addr6->sin6_addr.s6_addr+12,
+ sizeof(addr4.sin_addr.s_addr));
+ if(inet_ntop(AF_INET, &(addr4.sin_addr.s_addr), buf,
+ MAXBUF - 1) == NULL) {
+ strncpy(buf, "(UNKNOWN)", MAXBUF - 1);
+ }
+ } else {
+ src = (void *)&((struct sockaddr_in6 *)addr->ai_addr)->sin6_addr.s6_addr;
+ port = ntohs(((struct sockaddr_in6 *)addr->ai_addr)->sin6_port);
+ if(inet_ntop(AF_INET6, src, buf, MAXBUF - 1) == NULL)
+ strncpy(buf, "(UNKNOWN)", MAXBUF - 1);
+ }
+ }
break;
case AF_UNIX:
strncpy(buf, (char *)addr->ai_addr, MAXBUF - 1);