From: Amos Jeffries Date: Wed, 4 Nov 2009 04:43:47 +0000 (+1300) Subject: Bug 2795: pt 2: ARP lookups require IPv4-only socket on Linux/Solaris X-Git-Tag: SQUID_3_1_0_15~44 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0a6c56183424be2e08f4a3922cac143c8350ae47;p=thirdparty%2Fsquid.git Bug 2795: pt 2: ARP lookups require IPv4-only socket on Linux/Solaris --- diff --git a/src/acl/Arp.cc b/src/acl/Arp.cc index 49eaade5c3..dd4e971cd8 100644 --- a/src/acl/Arp.cc +++ b/src/acl/Arp.cc @@ -259,6 +259,10 @@ aclMatchArp(SplayNode **dataptr, IpAddress &c) int offset; SplayNode **Top = dataptr; + + /* IPv6 builds do not provide the first http_port as an IPv4 socket for ARP */ + int tmpSocket = socket(AF_INET,SOCK_STREAM,0); + /* * The linux kernel 2.2 maintains per interface ARP caches and * thus requires an interface name when doing ARP queries. @@ -280,8 +284,9 @@ aclMatchArp(SplayNode **dataptr, IpAddress &c) ipAddr.GetSockAddr(*sa); /* Query ARP table */ - if (ioctl(HttpSockets[0], SIOCGARP, &arpReq) != -1) { + if (ioctl(tmpSocket, SIOCGARP, &arpReq) != -1) { /* Skip non-ethernet interfaces */ + close(tmpSocket); if (arpReq.arp_ha.sa_family != ARPHRD_ETHER) { return 0; @@ -308,13 +313,15 @@ aclMatchArp(SplayNode **dataptr, IpAddress &c) ifc.ifc_buf = (char *)ifbuffer; - if (ioctl(HttpSockets[0], SIOCGIFCONF, &ifc) < 0) { + if (ioctl(tmpSocket, SIOCGIFCONF, &ifc) < 0) { debugs(28, 1, "Attempt to retrieve interface list failed: " << xstrerror()); + close(tmpSocket); return 0; } if (ifc.ifc_len > (int)sizeof(ifbuffer)) { debugs(28, 1, "Interface list too long - " << ifc.ifc_len); + close(tmpSocket); return 0; } @@ -347,7 +354,7 @@ aclMatchArp(SplayNode **dataptr, IpAddress &c) arpReq.arp_dev[sizeof(arpReq.arp_dev) - 1] = '\0'; /* Query ARP table */ - if (-1 == ioctl(HttpSockets[0], SIOCGARP, &arpReq)) { + if (-1 == ioctl(tmpSocket, SIOCGARP, &arpReq)) { /* * Query failed. Do not log failed lookups or "device * not supported" @@ -386,6 +393,7 @@ aclMatchArp(SplayNode **dataptr, IpAddress &c) /* Return if match, otherwise continue to other interfaces */ if (0 == splayLastResult) { debugs(28, 3, "aclMatchArp: " << ipAddr << " found on " << ifr->ifr_name); + close(tmpSocket); return 1; } @@ -395,10 +403,15 @@ aclMatchArp(SplayNode **dataptr, IpAddress &c) */ } + close(tmpSocket); + #elif defined(_SQUID_SOLARIS_) SplayNode **Top = dataptr; + /* IPv6 builds do not provide the first http_port as an IPv4 socket for ARP */ + int tmpSocket = socket(AF_INET,SOCK_STREAM,0); + /* * Set up structures for ARP lookup with blank interface name */ @@ -409,11 +422,12 @@ aclMatchArp(SplayNode **dataptr, IpAddress &c) ipAddr.GetSockAddr(*sa); /* Query ARP table */ - if (ioctl(HttpSockets[0], SIOCGARP, &arpReq) != -1) { + if (ioctl(tmpSocket, SIOCGARP, &arpReq) != -1) { /* * Solaris (at least 2.6/x86) does not use arp_ha.sa_family - * it returns 00:00:00:00:00:00 for non-ethernet media */ + close(tmpSocket); if (arpReq.arp_ha.sa_data[0] == 0 && arpReq.arp_ha.sa_data[1] == 0 && @@ -438,6 +452,8 @@ aclMatchArp(SplayNode **dataptr, IpAddress &c) return (0 == splayLastResult); } + close(tmpSocket); + #elif defined(_SQUID_FREEBSD_) || defined(_SQUID_NETBSD_) || defined(_SQUID_OPENBSD_) || defined(_SQUID_DRAGONFLY_) || defined(_SQUID_KFREEBSD_) SplayNode **Top = dataptr;