]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Import IPv6 support from squid3-ipv6 branch to 3-HEAD.
authoramosjeffries <>
Sat, 15 Dec 2007 06:11:41 +0000 (06:11 +0000)
committeramosjeffries <>
Sat, 15 Dec 2007 06:11:41 +0000 (06:11 +0000)
This patch fully enables squid to handle IPv6 on internally supported
protocols which have IPv6 capability.
see 3.1 Release Notes for full details on the IPv6 changes.
also see squid.conf generated from this point for configuration changes.

TODO: Release-Notes fro 3.1 have yet to be created. The mentioned details
      documentation will come in a later patch.

146 files changed:
configure.in
helpers/negotiate_auth/squid_kerb_auth/squid_kerb_auth.c
helpers/ntlm_auth/SMB/smbval/rfcnb-priv.h
include/cache_snmp.h
include/config.h
include/rfc1035.h
include/snmp_vars.h
include/squid_mswin.h
include/util.h
lib/GNUregex.c
lib/Makefile.am
lib/rfc1035.c
lib/safe_inet_addr.c
lib/tests/testRFC1035.cc [new file with mode: 0644]
lib/tests/testRFC1035.h [new file with mode: 0644]
src/ACLARP.cc
src/ACLASN.h
src/ACLChecklist.cc
src/ACLChecklist.h
src/ACLDestinationASN.h
src/ACLDestinationDomain.cc
src/ACLDestinationIP.cc
src/ACLIP.cc
src/ACLIP.h
src/ACLIdent.cc
src/ACLMaxUserIP.cc
src/ACLMaxUserIP.h
src/ACLMyPort.cc
src/ACLSourceASN.h
src/ACLSourceDomain.cc
src/AccessLogEntry.h
src/AuthUser.cc
src/AuthUser.h
src/AuthUserRequest.cc
src/AuthUserRequest.h
src/CompositePoolNode.h
src/ConnectionDetail.h
src/Debug.h
src/DelayConfig.h
src/DelayId.cc
src/DiskIO/DiskDaemon/DiskdIOStrategy.cc
src/ESI.cc
src/HttpRequest.cc
src/HttpRequest.h
src/ICAP/ICAPModXact.cc
src/ICMP.h [new file with mode: 0644]
src/ICMPConfig.h [new file with mode: 0644]
src/ICMPPinger.cc [new file with mode: 0644]
src/ICMPPinger.h [new file with mode: 0644]
src/ICMPSquid.cc [new file with mode: 0644]
src/ICMPSquid.h [new file with mode: 0644]
src/ICMPv4.cc [new file with mode: 0644]
src/ICMPv4.h [new file with mode: 0644]
src/ICMPv6.cc [new file with mode: 0644]
src/ICMPv6.h [new file with mode: 0644]
src/ICP.h
src/IPInterception.cc
src/IPInterception.h
src/Makefile.am
src/PeerSelectState.h
src/SquidTime.h
src/access_log.cc
src/asn.cc
src/auth/digest/auth_digest.cc
src/auth/negotiate/auth_negotiate.cc
src/auth/ntlm/auth_ntlm.cc
src/cache_cf.cc
src/cf.data.depend
src/cf.data.pre
src/client_db.cc
src/client_side.cc
src/client_side.h
src/client_side_reply.cc
src/client_side_reply.h
src/client_side_request.cc
src/comm.cc
src/comm.h
src/comm_select.cc
src/debug.cc
src/defines.h
src/delay_pools.cc
src/dns_internal.cc
src/dnsserver.cc
src/errorpage.cc
src/errorpage.h
src/event.cc
src/external_acl.cc
src/fd.cc
src/fde.h
src/forward.cc
src/forward.h
src/fqdncache.cc
src/ftp.cc
src/globals.h
src/helper.cc
src/helper.h
src/htcp.cc
src/htcp.h
src/http.cc
src/icmp.cc
src/icp_v2.cc
src/icp_v3.cc
src/ident.cc
src/internal.cc
src/ipc.cc
src/ipc_win32.cc
src/ipcache.cc
src/main.cc
src/mib.txt
src/multicast.cc
src/neighbors.cc
src/net_db.cc
src/pconn.cc
src/pconn.h
src/peer_digest.cc
src/peer_select.cc
src/pinger.cc
src/protos.h
src/redirect.cc
src/send-announce.cc
src/snmp_agent.cc
src/snmp_core.cc
src/squid.h
src/stat.cc
src/store_log.cc
src/structs.h
src/tests/stub_comm.cc
src/tests/testEvent.cc
src/tests/testHttpRequest.cc
src/tests/testHttpRequest.h
src/tests/testICMP.cc [new file with mode: 0644]
src/tests/testICMP.h [new file with mode: 0644]
src/time.cc
src/tools.cc
src/tunnel.cc
src/typedefs.h
src/unlinkd.cc
src/url.cc
src/urn.cc
src/wccp.cc
src/wccp2.cc
src/win32.cc
test-suite/hash.h
test-suite/pconn-banger.c
tools/cachemgr.cc
tools/squidclient.cc

index 5a2f8c18d6077f0c594fdcff4c4f6747f6337def..a9c99a656f2a706149d65c1f9f8f439a94e9c147 100644 (file)
@@ -1,17 +1,17 @@
 
 dnl  Configuration input file for Squid
 dnl
-dnl  $Id: configure.in,v 1.489 2007/12/14 01:11:53 hno Exp $
+dnl  $Id: configure.in,v 1.490 2007/12/14 23:11:41 amosjeffries Exp $
 dnl
 dnl
 dnl
-AC_INIT(Squid Web Proxy, 3.HEAD-CVS, http://www.squid-cache.org/bugs/, squid)
+AC_INIT(Squid Web Proxy, 3.HEAD-IPv6-CVS, http://www.squid-cache.org/bugs/, squid)
 AC_PREREQ(2.52)
 AM_CONFIG_HEADER(include/autoconf.h)
 AC_CONFIG_AUX_DIR(cfgaux)
 AC_CONFIG_SRCDIR([src/main.cc])
 AM_INIT_AUTOMAKE([tar-ustar])
-AC_REVISION($Revision: 1.489 $)dnl
+AC_REVISION($Revision: 1.490 $)dnl
 AC_PREFIX_DEFAULT(/usr/local/squid)
 AM_MAINTAINER_MODE
 
@@ -668,14 +668,8 @@ AC_ARG_ENABLE(icmp,
 [ if test "$enableval" = "yes" ; then
     echo "ICMP enabled"
     AC_DEFINE(USE_ICMP,1,
-    [If you want to use Squid's ICMP features (highly recommended!) then
-    define this.  When USE_ICMP is defined, Squid will send ICMP pings
-    to origin server sites.  This information is used in numerous ways:
-            - Sent in ICP replies so neighbor caches know how close
-              you are to the source.
-           - For finding the closest instance of a URN.
-           - With the 'test_reachability' option.  Squid will return
-             ICP_OP_MISS_NOFETCH for sites which it cannot ping.])
+    [ Defined this to use Squid's ICMP features (highly recommended!)
+      When USE_ICMP is defined, Squid will send ICMP pings to origin server sites.])
     AM_CONDITIONAL(ENABLE_PINGER, true)
   fi
 ])
@@ -1733,6 +1727,72 @@ AC_ARG_ENABLE(x_accelerator_vary,
   fi
 ])
 
+dnl Enable IPv6 support
+AC_MSG_CHECKING([whether to enable IPv6])
+AC_ARG_ENABLE(ipv6,
+[  --enable-ipv6          Enable ipv6 support],
+[ AC_MSG_RESULT(yes)
+  AC_CACHE_CHECK([if PF_INET6 is available], $enableval,
+    AC_TRY_RUN(
+      [ /* PF_INET6 available check */
+#       include <sys/types.h>
+#       include <sys/socket.h>
+        void main() {
+          if (socket(PF_INET6, SOCK_STREAM, 0) < 0)
+            exit(1);
+          else
+            exit(0);
+        }
+      ],
+      [ AC_DEFINE(USE_IPV6,1,[Enable support for IPv6 ])
+        AC_MSG_RESULT(yes)
+      ],
+      [ AC_DEFINE(USE_IPV6,0,[0 == Disable support for IPv6])
+        AC_DEFINE(IPV6_SPECIAL_SPLITSTACK,0,[0 == Disable support for Split-Stack IPv6 Implementations])
+        AC_DEFINE(IPV6_SPECIAL_LOCALHOST,0,[0 == Keep IPv4 and IPv6 Localhosts seperate.])
+        AC_DEFINE(IPV6_SPECIAL_V4MAPPING,0,[0 == Leave all v4-mapping to OS Implementation])
+        AC_MSG_RESULT(no)
+      ])
+   )
+],
+[ AC_DEFINE(USE_IPV6,0,[Disable support for IPv6])
+  AC_DEFINE(IPV6_SPECIAL_SPLITSTACK,0,[ 0 == Disable support for Split-Stack IPv6 Implementations])
+  AC_DEFINE(IPV6_SPECIAL_LOCALHOST,0,[ 0 == Keep IPv4 and IPv6 Localhosts seperate.])
+  AC_DEFINE(IPV6_SPECIAL_V4MAPPING,0,[ 0 == Leave v4-mapping to OS Implementation])
+  AC_MSG_RESULT(no)
+])
+if test $ac_cv_enable_ipv6 ; then
+dnl Check for Windows XP option
+AC_MSG_CHECKING([for IPv6 split-stack requirement])
+AC_ARG_WITH(ipv6-split-stack,
+  [  --with-ipv6-split-stack  Require IPv6 split-stack support (Requires IPv6 Support)],
+  [AC_DEFINE(IPV6_SPECIAL_SPLITSTACK, 1, [ 1 == Enable support for IPv6 on split-stack implementations]) AC_MSG_RESULT(yes)],
+  [AC_DEFINE(IPV6_SPECIAL_SPLITSTACK, 0, [ 0 == Disable support for split-stack IPv6 implementations]) AC_MSG_RESULT(no)]
+)
+
+dnl Check for IPv6 Windows Vista option
+AC_MSG_CHECKING([for IPv6 v4-mapping requirement])
+AC_ARG_WITH(ipv4-mapped,
+  [  --with-ipv4-mapped  Hybrid-Stack OS require Squid to do any v4-mapping (Requires IPv6 Support)],
+  [AC_DEFINE(IPV6_SPECIAL_V4MAPPING, 1, [ 1 == Perform v4-mapping internally]) AC_MSG_RESULT(yes)],
+  [AC_DEFINE(IPV6_SPECIAL_V4MAPPING, 0, [ 0 == Leave all v4-mapping to the OS]) AC_MSG_RESULT(no)]
+)
+
+dnl Check for IPv6-pure option
+AC_MSG_CHECKING([for IPv6-Localhost requirement])
+AC_ARG_WITH(localhost-ipv6,
+  [  --with-localhost-ipv6    Prefer IPv6 localhost address over IPv4 (Requires IPv6 Support).
+                           Treats 127.0.0.1 and ::1 as identical and converts all inputs of to ::1
+                           This depends on Dual-Stack support in the OS and all applications
+                           squid contacts via localhost being IPv6 enabled.
+                           Default: OFF. Treats these two IP as different, squid.conf must
+                           define both 127.0.0.1 and ::1 for the localhost ACL, etc. ],
+  [AC_DEFINE(IPV6_SPECIAL_LOCALHOST, 1, [ 1 == Convert IPv4-localhost requests to IPv6.]) AC_MSG_RESULT(yes)],
+  [AC_DEFINE(IPV6_SPECIAL_LOCALHOST, 0, [ 0 == Keep IPv4 and IPv6 Localhosts seperate.]) AC_MSG_RESULT(no)]
+)
+# end IPv6-only options
+fi
+
 AC_ARG_WITH(filedescriptors,
 [  --with-filedescriptors=NUMBER
                           Force squid to support NUMBER filedescriptors],
@@ -1865,11 +1925,16 @@ AC_CHECK_HEADERS( \
        net/pfvar.h \
        netdb.h \
        netinet/in.h \
+       netinet/icmp6.h \
+       netinet/in_systm.h \
+       netinet/ip.h \
+       netinet/ip6.h \
+       netinet/ip_icmp.h \
        netinet/ip_fil_compat.h \
-       netinet/tcp.h \
        openssl/err.h \
        openssl/md5.h \
        openssl/ssl.h \
+       netinet/tcp.h \
        openssl/engine.h \
        paths.h \
        poll.h \
@@ -2543,7 +2608,11 @@ AC_CHECK_FUNCS(\
 dnl ... and some we provide local replacements for
 AC_REPLACE_FUNCS(\
        drand48 \
+       inet_ntop \
+       inet_pton \
        initgroups \
+       getaddrinfo \
+       getnameinfo \
        strerror \
        tempnam \
 )
@@ -3174,6 +3243,61 @@ if test "$ac_cv_func_statvfs" = "yes" ; then
 fi
 fi
 
+dnl Detect what resolver fields we have available to use...
+AC_CACHE_CHECK(for _res_ext.nsaddr_list, ac_cv_have_res_ext_nsaddr_list,
+AC_TRY_COMPILE([
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_ARPA_NAMESER_H
+#include <arpa/nameser.h>
+#endif
+#if HAVE_RESOLV_H
+#include <resolv.h>
+#endif
+],
+[_res_ext.nsaddr_list[[0]].s_addr;],
+ac_cv_have_res_ext_nsaddr_list="yes",
+ac_cv_have_res_ext_nsaddr_list="no"))
+if test "$ac_cv_have_res_ext_nsaddr_list" = "yes" ; then
+  AC_DEFINE(_SQUID_RES_NSADDR6_LARRAY,_res_ext.nsaddr_list,[If _res_ext structure has nsaddr_list member])
+  AC_DEFINE(_SQUID_RES_NSADDR6_COUNT,ns6count,[Nameserver Counter for IPv6 _res_ext])
+fi
+
+if test "$_SQUID_RES_NSADDR6_LIST" == ""; then
+AC_CACHE_CHECK(for _res._u._ext.nsaddrs, ac_cv_have_res_ext_nsaddrs,
+AC_TRY_COMPILE([
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_ARPA_NAMESER_H
+#include <arpa/nameser.h>
+#endif
+#if HAVE_RESOLV_H
+#include <resolv.h>
+#endif
+],
+[_res._u._ext.nsaddrs[[0]]->sin6_addr;],
+ac_cv_have_res_ext_nsaddrs="yes",
+ac_cv_have_res_ext_nsaddrs="no"))
+if test "$ac_cv_have_res_ext_nsaddrs" = "yes" ; then
+  AC_DEFINE(_SQUID_RES_NSADDR6_LPTR,_res._u._ext.nsaddrs,[If _res structure has _ext.nsaddrs member])
+  AC_DEFINE(_SQUID_RES_NSADDR6_COUNT,_res._u._ext.nscount6,[Nameserver Counter for IPv6 _res])
+fi
+fi
+
 AC_CACHE_CHECK(for _res.nsaddr_list, ac_cv_have_res_nsaddr_list,
 AC_TRY_COMPILE([
 #if HAVE_SYS_TYPES_H
@@ -3196,10 +3320,11 @@ AC_TRY_COMPILE([
 ac_cv_have_res_nsaddr_list="yes",
 ac_cv_have_res_nsaddr_list="no"))
 if test $ac_cv_have_res_nsaddr_list = "yes" ; then
-  AC_DEFINE(HAVE_RES_NSADDR_LIST,1,[If _res structure has nsaddr_list member])
+  AC_DEFINE(_SQUID_RES_NSADDR_LIST,_res.nsaddr_list,[If _res structure has nsaddr_list member])
+  AC_DEFINE(_SQUID_RES_NSADDR_COUNT,_res.nscount,[Nameserver counter for IPv4 _res])
 fi
 
-if test $ac_cv_have_res_nsaddr_list = "no" ; then
+if test "$_SQUID_RES_NSADDR_LIST" == ""; then
 AC_CACHE_CHECK(for _res.ns_list, ac_cv_have_res_ns_list,
 AC_TRY_COMPILE([
 #if HAVE_SYS_TYPES_H
@@ -3222,7 +3347,8 @@ AC_TRY_COMPILE([
 ac_cv_have_res_ns_list="yes",
 ac_cv_have_res_ns_list="no"))
 if test $ac_cv_have_res_ns_list = "yes" ; then
-  AC_DEFINE(HAVE_RES_NS_LIST,1,[If _res structure has ns_list member])
+  AC_DEFINE(_SQUID_RES_NSADDR_LIST,_res.ns_list,[If _res structure has ns_list member])
+  AC_DEFINE(_SQUID_RES_NSADDR_COUNT,_res.nscount,[Nameserver counter for IPv4 _res])
 fi
 fi
 
index fa4b4836cea83d73a64dd5797d4cbed054c822db..e4e2181e8404ebd805cf2f76b5dc0fa128391846 100755 (executable)
@@ -78,6 +78,7 @@ static const char *LogTime()
     return buf;
 }
 
+// AYJ: this looks like a duplicate of the lib/gethostname function */
 char *gethost_name(void) {
   char      hostname[MAXHOSTNAMELEN];
   struct addrinfo *hres=NULL, *hres_list;
@@ -89,9 +90,10 @@ char *gethost_name(void) {
       fprintf(stderr, "%s| %s: error while resolving hostname '%s'\n", LogTime(), PROGRAM, hostname);
       return NULL;
     }
-  rc = getaddrinfo(hostname,NULL,NULL,&hres);
+  rc = xgetaddrinfo(hostname,NULL,NULL,&hres);
   if (rc != 0) {
-    fprintf(stderr, "%s| %s: error while resolving hostname with getaddrinfo: %s\n", LogTime(), PROGRAM, gai_strerror(rc));
+    fprintf(stderr, "%s| %s: error while resolving hostname with getaddrinfo: %s\n", LogTime(), PROGRAM, xgai_strerror(rc));
+    xfreeaddrinfo(hres);
     return NULL;
   }
   hres_list=hres;
@@ -100,14 +102,14 @@ char *gethost_name(void) {
     count++;
     hres_list=hres_list->ai_next;
   }
-  rc = getnameinfo (hres->ai_addr, hres->ai_addrlen,hostname, sizeof (hostname), NULL, 0, 0);
+  rc = xgetnameinfo(hres->ai_addr, hres->ai_addrlen,hostname, sizeof (hostname), NULL, 0, 0);
   if (rc != 0) {
-    fprintf(stderr, "%s| %s: error while resolving ip address with getnameinfo: %s\n", LogTime(), PROGRAM, gai_strerror(rc));
-    freeaddrinfo(hres);
+    fprintf(stderr, "%s| %s: error while resolving ip address with getnameinfo: %s\n", LogTime(), PROGRAM, xgai_strerror(rc));
+    xfreeaddrinfo(hres);
     return NULL ;
   }
 
-  freeaddrinfo(hres);
+  xfreeaddrinfo(hres);
   hostname[MAXHOSTNAMELEN]='\0';
   return(strdup(hostname));
 }
index 40141cd81f2519419575c06f82628ee25313ee2f..766a66fb9261bd5146d5a657e0fe5ff9de86bd9a 100644 (file)
@@ -59,7 +59,7 @@ typedef struct redirect_addr *redirect_ptr;
 
 struct redirect_addr {
 
-    struct IN_ADDR ip_addr;
+    struct in_addr ip_addr;
     int port;
     redirect_ptr next;
 
index 34023c58dbc7bd24908d74ebf78d414799ed993b..e8cf9eae6bbd8e66b65c961cd02e62c8899dc58e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cache_snmp.h,v 1.29 2006/09/22 02:48:51 hno Exp $
+ * $Id: cache_snmp.h,v 1.30 2007/12/14 23:11:44 amosjeffries Exp $
  */
 
 #ifndef SQUID_CACHE_SNMP_H
 
 /* basic groups under .squid */
 
-#define SQ_SYS  SQUIDMIB, 1
+#define SQ_SYS  SQUIDMIB, 1           /* cacheSystem group { squid 1 } */
 #define LEN_SQ_SYS LEN_SQUIDMIB+1
-#define SQ_CONF SQUIDMIB, 2
+#define SQ_CONF SQUIDMIB, 2           /* cacheConfig group { squid 2 } */
 #define LEN_SQ_CONF LEN_SQUIDMIB+1
-#define SQ_PRF  SQUIDMIB, 3
+#define SQ_PRF  SQUIDMIB, 3           /* cachePerformance group { squid 3 } */
 #define LEN_SQ_PRF LEN_SQUIDMIB+1
-#define SQ_NET  SQUIDMIB, 4
+#define SQ_NET  SQUIDMIB, 4           /* cacheNetwork group { squid 4 }   */
 #define LEN_SQ_NET LEN_SQUIDMIB+1
-#define SQ_MESH  SQUIDMIB, 5
+#define SQ_MESH  SQUIDMIB, 5          /* cacheMesh group { squid 5 }    */
 #define LEN_SQ_MESH LEN_SQUIDMIB+1
 
 /* 
- * cacheSystem group 
+ * cacheSystem group { squid 1 }
  */
 
 enum {
     SYS_START,
-    SYSVMSIZ,
-    SYSSTOR,
-    SYS_UPTIME,
+    SYSVMSIZ,  /* cacheSysVMsize  */
+    SYSSTOR,   /* cacheSysStorage  */
+    SYS_UPTIME,/* cacheUptime  */
     SYS_END
 };
 
@@ -69,29 +69,33 @@ enum {
 #define LEN_SYS_INST LEN_SQ_SYS + 2
 
 /* 
- * cacheConfig group 
+ * cacheConfig group { squid 2 }
  */
 
 enum {
     CONF_START,
-    CONF_ADMIN,
-    CONF_VERSION,
-    CONF_VERSION_ID,
-    CONF_LOG_FAC,
-    CONF_STORAGE,
-    CONF_UNIQNAME,
+    CONF_ADMIN,      /* cacheAdmin */
+    CONF_VERSION,    /* cacheSoftware */
+    CONF_VERSION_ID, /* cacheVersionId */
+    CONF_LOG_FAC,    /* cacheLoggingFacility */
+    CONF_STORAGE,    /* cacheStorageConfig group */
+    CONF_UNIQNAME,   /* cacheUniqName */
     CONF_END
 };
 
 #define LEN_CONF LEN_SQ_CONF + 1
 #define LEN_CONF_INST LEN_SQ_CONF + 2
 
+
+/* 
+ * cacheStorageConfig group { cacheConfig 5 }
+ */
 enum {
     CONF_ST_START,
-    CONF_ST_MMAXSZ,
-    CONF_ST_SWMAXSZ,
-    CONF_ST_SWHIWM,
-    CONF_ST_SWLOWM,
+    CONF_ST_MMAXSZ, /* cacheMemMaxSize */
+    CONF_ST_SWMAXSZ, /* cacheSwapMaxSize */
+    CONF_ST_SWHIWM,  /* cacheSwapHighWM */
+    CONF_ST_SWLOWM,   /* cacheSwapLowWM  */
     CONF_ST_END
 };
 
@@ -99,164 +103,187 @@ enum {
 #define LEN_CONF_ST_INST LEN_CONF + 2
 
 /* 
- * cacheMesh group 
+ * Cache Performance Group  {squid 3}
  */
 
 enum {
-    MESH_START,
-    MESH_PTBL,
-    MESH_CTBL,
-    MESH_END
+    PERF_START,
+    PERF_SYS,  /* cacheSysPerf */
+    PERF_PROTO,   /* cacheProtoStats */
+    PERF_END
 };
 
-enum {                         /* cachePeerTable */
-    MESH_PTBL_START,
-    MESH_PTBL_NAME,
-    MESH_PTBL_IP,
-    MESH_PTBL_HTTP,
-    MESH_PTBL_ICP,
-    MESH_PTBL_TYPE,
-    MESH_PTBL_STATE,
-    MESH_PTBL_SENT,
-    MESH_PTBL_PACKED,
-    MESH_PTBL_FETCHES,
-    MESH_PTBL_RTT,
-    MESH_PTBL_IGN,
-    MESH_PTBL_KEEPAL_S,
-    MESH_PTBL_KEEPAL_R,
-    MESH_PTBL_END
+
+/* cacheSysPerf */
+enum {
+    PERF_SYS_START,
+    PERF_SYS_PF, /* cacheSysPageFaults */
+    PERF_SYS_NUMR, /* cacheSysNumReads */
+    PERF_SYS_MEMUSAGE,   /* cacheMemUsage */
+    PERF_SYS_CPUTIME,  /* cacheCpuTime */
+    PERF_SYS_CPUUSAGE,  /* cacheCpuUsage */
+    PERF_SYS_MAXRESSZ,   /* cacheMaxResSize */
+    PERF_SYS_NUMOBJCNT, /* cacheNumObjCount */
+    PERF_SYS_CURLRUEXP,  /* cacheCurrentLRUExpiration */
+    PERF_SYS_CURUNLREQ,  /* cacheCurrentUnlinkRequests */
+    PERF_SYS_CURUNUSED_FD, /* cacheCurrentUnusedFDescrCnt */
+    PERF_SYS_CURRESERVED_FD, /* cacheCurrentResFileDescrCnt */
+    PERF_SYS_CURUSED_FD, /* cacheCurrentFileDescrCnt */
+    PERF_SYS_CURMAX_FD, /* cacheCurrentFileDescrMax */
+    PERF_SYS_END
 };
 
-enum {                         /* cacheClientTable */
-    MESH_CTBL_START,
-    MESH_CTBL_ADDR,
-    MESH_CTBL_HTREQ,
-    MESH_CTBL_HTBYTES,
-    MESH_CTBL_HTHITS,
-    MESH_CTBL_HTHITBYTES,
-    MESH_CTBL_ICPREQ,
-    MESH_CTBL_ICPBYTES,
-    MESH_CTBL_ICPHITS,
-    MESH_CTBL_ICPHITBYTES,
-    MESH_CTBL_END
+/* cacheProtoStats */
+enum {
+    PERF_PROTOSTAT_START,
+    PERF_PROTOSTAT_AGGR, /* cacheProtoAggregateStats */
+    PERF_PROTOSTAT_MEDIAN,  /* cacheMedianSvcTable */
+    PERF_PROTOSTAT_END
+};
+
+/* cacheProtoAggregateStats */
+enum {
+    PERF_PROTOSTAT_AGGR_START,
+    PERF_PROTOSTAT_AGGR_HTTP_REQ, /* cacheProtoClientHttpRequests */
+    PERF_PROTOSTAT_AGGR_HTTP_HITS, /* cacheHttpHits */
+    PERF_PROTOSTAT_AGGR_HTTP_ERRORS, /* cacheHttpErrors */
+    PERF_PROTOSTAT_AGGR_HTTP_KBYTES_IN, /* cacheHttpInKb */
+    PERF_PROTOSTAT_AGGR_HTTP_KBYTES_OUT, /* cacheHttpOutKb */
+    PERF_PROTOSTAT_AGGR_ICP_S,  /* cacheIcpPktsSent */
+    PERF_PROTOSTAT_AGGR_ICP_R, /* cacheIcpPktsRecv */
+    PERF_PROTOSTAT_AGGR_ICP_SKB, /* cacheIcpKbSent */
+    PERF_PROTOSTAT_AGGR_ICP_RKB, /* cacheIcpKbRecv */
+    PERF_PROTOSTAT_AGGR_REQ, /* cacheServerRequests */
+    PERF_PROTOSTAT_AGGR_ERRORS, /* cacheServerErrors */
+    PERF_PROTOSTAT_AGGR_KBYTES_IN, /* cacheServerInKb */
+    PERF_PROTOSTAT_AGGR_KBYTES_OUT, /* cacheServerOutKb */
+    PERF_PROTOSTAT_AGGR_CURSWAP, /* cacheCurrentSwapSize */
+    PERF_PROTOSTAT_AGGR_CLIENTS, /* cacheClients */
+    PERF_PROTOSTAT_AGGR_END
+};
+
+
+/* CacheMedianSvcEntry */
+enum {
+    PERF_MEDIAN_START,
+    PERF_MEDIAN_TIME, /* cacheMedianTime */
+    PERF_MEDIAN_HTTP_ALL, /* cacheHttpAllSvcTime */
+    PERF_MEDIAN_HTTP_MISS, /* cacheHttpMissSvcTime */
+    PERF_MEDIAN_HTTP_NM, /* cacheHttpNmSvcTime */
+    PERF_MEDIAN_HTTP_HIT, /* cacheHttpHitSvcTime */
+    PERF_MEDIAN_ICP_QUERY, /* cacheIcpQuerySvcTime */
+    PERF_MEDIAN_ICP_REPLY, /* cacheIcpReplySvcTime */
+    PERF_MEDIAN_DNS, /* cacheDnsSvcTime */
+    PERF_MEDIAN_RHR, /* cacheRequestHitRatio */
+    PERF_MEDIAN_BHR, /* cacheRequestByteRatio */ 
+    PERF_MEDIAN_HTTP_NH, /* cacheHttpNhSvcTime */
+    PERF_MEDIAN_END
 };
 
+
+
+
 /* 
- * cacheNetwork group 
+ * cacheNetwork group  { squid 4 }
  */
 
 enum {
     NET_START,
-    NET_IP_CACHE,
-    NET_FQDN_CACHE,
-    NET_DNS_CACHE,
+    NET_IP_CACHE, /* cacheIpCache */
+    NET_FQDN_CACHE, /* cacheFqdnCache */
+    NET_DNS_CACHE,  /* cacheDns */
     NET_END
 };
 
+/* cacheIpCache */
 enum {
-    IP_START,
-    IP_ENT,
-    IP_REQ,
-    IP_HITS,
-    IP_PENDHIT,
-    IP_NEGHIT,
-    IP_MISS,
-    IP_GHBN,
-    IP_LOC,
+    IP_START, 
+    IP_ENT, /* cacheIpEntrie */
+    IP_REQ, /* cacheIpRequests */
+    IP_HITS, /* acheIpHits */
+    IP_PENDHIT, /* cacheIpPendingHits */
+    IP_NEGHIT, /* cacheIpNegativeHit */
+    IP_MISS,  /* cacheIpMisses */
+    IP_GHBN, /* cacheBlockingGetHostByName */
+    IP_LOC, /* cacheAttemptReleaseLckEntries */
     IP_END
 };
 
+/* cacheFqdnCache */
 enum {
     FQDN_START,
-    FQDN_ENT,
-    FQDN_REQ,
-    FQDN_HITS,
-    FQDN_PENDHIT,
-    FQDN_NEGHIT,
-    FQDN_MISS,
-    FQDN_GHBN,
+    FQDN_ENT, /* cacheFqdnEntries */
+    FQDN_REQ, /* cacheFqdnRequests */
+    FQDN_HITS, /* cacheFqdnHits */
+    FQDN_PENDHIT, /* cacheFqdnPendingHits */
+    FQDN_NEGHIT, /* cacheFqdnNegativeHits */
+    FQDN_MISS, /* cacheFqdnMisses */
+    FQDN_GHBN, /* cacheBlockingGetHostByAddr */
     FQDN_END
 };
 
+
+/* cacheDNS */
 enum {
     DNS_START,
-    DNS_REQ,
-    DNS_REP,
-    DNS_SERVERS,
+    DNS_REQ, /* cacheDnsRequests */
+    DNS_REP, /* cacheDnsReplies */
+    DNS_SERVERS, /* cacheDnsNumberServers */
     DNS_END
 };
 
+
+
+
 /* 
- * Cache Performance Group 
+ * cacheMesh group { squid 5 }
  */
 
 enum {
-    PERF_START,
-    PERF_SYS,
-    PERF_PROTO,
-    PERF_END
+    MESH_START,  
+    MESH_PTBL,  /* cachePeerTable  */
+    MESH_CTBL,  /* cacheClientTable */
+    MESH_END
 };
 
-enum {
-    PERF_SYS_START,
-    PERF_SYS_PF,
-    PERF_SYS_NUMR,
-    PERF_SYS_MEMUSAGE,
-    PERF_SYS_CPUTIME,
-    PERF_SYS_CPUUSAGE,
-    PERF_SYS_MAXRESSZ,
-    PERF_SYS_NUMOBJCNT,
-    PERF_SYS_CURLRUEXP,
-    PERF_SYS_CURUNLREQ,
-    PERF_SYS_CURUNUSED_FD,
-    PERF_SYS_CURRESERVED_FD,
-    PERF_SYS_CURUSED_FD,
-    PERF_SYS_CURMAX_FD,
-    PERF_SYS_END
+/* cachePeerEntry */
+enum {                 
+    MESH_PTBL_START,
+    MESH_PTBL_INDEX, /* cachePeerIndex  */
+    MESH_PTBL_NAME, /* cachePeerName  */
+    MESH_PTBL_ADDR_TYPE, /* cachePeerAddressType */
+    MESH_PTBL_ADDR,   /* cachePeerAddress */
+    MESH_PTBL_HTTP, /* cachePortHttp */
+    MESH_PTBL_ICP,  /* cachePeerPortIcp */
+    MESH_PTBL_TYPE,  /* cachePeerType  */
+    MESH_PTBL_STATE,  /* cachePeerStat */
+    MESH_PTBL_SENT,   /* cachePeerPingsSent */
+    MESH_PTBL_PACKED, /* cachePeerPingsAcked */
+    MESH_PTBL_FETCHES,  /* cachePeerFetches */
+    MESH_PTBL_RTT,   /* cachePeerRtt */
+    MESH_PTBL_IGN,  /* cachePeerIgnored */
+    MESH_PTBL_KEEPAL_S, /* cachePeerKeepAlSent */
+    MESH_PTBL_KEEPAL_R, /* cachePeerKeepAlRecv */
+    MESH_PTBL_END
 };
 
-enum {
-    PERF_PROTOSTAT_START,
-    PERF_PROTOSTAT_AGGR,
-    PERF_PROTOSTAT_MEDIAN,
-    PERF_PROTOSTAT_END
+/* cacheClientEntry */
+enum {                         
+    MESH_CTBL_START,
+    MESH_CTBL_ADDR_TYPE, /* cacheClientAddressType */
+    MESH_CTBL_ADDR,      /* cacheClientAddress */
+    MESH_CTBL_HTREQ,     /* cacheClientHttpRequests */
+    MESH_CTBL_HTBYTES,   /* cacheClientHttpKb */
+    MESH_CTBL_HTHITS,    /* cacheClientHttpHits */
+    MESH_CTBL_HTHITBYTES, /* cacheClientHTTPHitKb */
+    MESH_CTBL_ICPREQ,     /* cacheClientIcpRequests */
+    MESH_CTBL_ICPBYTES,   /* cacheClientIcpKb  */
+    MESH_CTBL_ICPHITS,    /* cacheClientIcpHits */
+    MESH_CTBL_ICPHITBYTES,/* cacheClientIcpHitKb */
+    MESH_CTBL_END
 };
 
-enum {
-    PERF_PROTOSTAT_AGGR_START,
-    PERF_PROTOSTAT_AGGR_HTTP_REQ,
-    PERF_PROTOSTAT_AGGR_HTTP_HITS,
-    PERF_PROTOSTAT_AGGR_HTTP_ERRORS,
-    PERF_PROTOSTAT_AGGR_HTTP_KBYTES_IN,
-    PERF_PROTOSTAT_AGGR_HTTP_KBYTES_OUT,
-    PERF_PROTOSTAT_AGGR_ICP_S,
-    PERF_PROTOSTAT_AGGR_ICP_R,
-    PERF_PROTOSTAT_AGGR_ICP_SKB,
-    PERF_PROTOSTAT_AGGR_ICP_RKB,
-    PERF_PROTOSTAT_AGGR_REQ,
-    PERF_PROTOSTAT_AGGR_ERRORS,
-    PERF_PROTOSTAT_AGGR_KBYTES_IN,
-    PERF_PROTOSTAT_AGGR_KBYTES_OUT,
-    PERF_PROTOSTAT_AGGR_CURSWAP,
-    PERF_PROTOSTAT_AGGR_CLIENTS,
-    PERF_PROTOSTAT_AGGR_END
-};
 
-enum {
-    PERF_MEDIAN_START,
-    PERF_MEDIAN_TIME,
-    PERF_MEDIAN_HTTP_ALL,
-    PERF_MEDIAN_HTTP_MISS,
-    PERF_MEDIAN_HTTP_NM,
-    PERF_MEDIAN_HTTP_HIT,
-    PERF_MEDIAN_ICP_QUERY,
-    PERF_MEDIAN_ICP_REPLY,
-    PERF_MEDIAN_DNS,
-    PERF_MEDIAN_RHR,
-    PERF_MEDIAN_BHR,
-    PERF_MEDIAN_HTTP_NH,
-    PERF_MEDIAN_END
-};
 
 #endif /* SQUID_SNMP */
 
index c4683203103aca25cf59ebc2601605ab4ba10fbf..7bb9d3755693d41ca2084b30261ddadaf9c61468 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: config.h,v 1.25 2007/09/20 11:07:53 amosjeffries Exp $
+ * $Id: config.h,v 1.26 2007/12/14 23:11:44 amosjeffries Exp $
  *
  * AUTHOR: Duane Wessels
  *
 #define FD_SETSIZE SQUID_MAXFD
 #endif
 
-
-
-/* 
- * This is hack to allow compiling IPv6-IPv4 version,
- * not disturbing branches others than squid3-ipv6 
- */
-#define IN_ADDR in_addr
-
 /* Typedefs for missing entries on a system */
 
 #include "squid_types.h"
index 8a9e9c798f66ff6e1c12c112e20ae7d4c4d00ff2..8ef3625c53342005ff1b089159950b1c35b32bbe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: rfc1035.h,v 1.18 2007/09/20 11:58:21 amosjeffries Exp $
+ * $Id: rfc1035.h,v 1.19 2007/12/14 23:11:44 amosjeffries Exp $
  *
  * AUTHOR: Duane Wessels
  *
@@ -95,7 +95,7 @@ SQUIDCEXTERN int rfc1035MessageUnpack(const char *buf,
     size_t sz,
     rfc1035_message ** answer);
 SQUIDCEXTERN int rfc1035QueryCompare(const rfc1035_query *, const rfc1035_query *);
-SQUIDCEXTERN void rfc1035MessageDestroy(rfc1035_message * message);
+SQUIDCEXTERN void rfc1035MessageDestroy(rfc1035_message ** message);
 SQUIDCEXTERN int rfc1035_errno;
 SQUIDCEXTERN const char *rfc1035_error_message;
 
index b0ba155498c43acdd43feb70244d054e5da90c92..0868f96294c013d84aab2c9d9817f6ae08ca42ad 100644 (file)
@@ -25,7 +25,7 @@
  * 
  * Author: Ryan Troll <ryan+@andrew.cmu.edu>
  * 
- * $Id: snmp_vars.h,v 1.13 2003/01/23 00:36:48 robertc Exp $
+ * $Id: snmp_vars.h,v 1.14 2007/12/14 23:11:44 amosjeffries Exp $
  * 
  **********************************************************************/
 
@@ -71,9 +71,47 @@ u_char *snmp_var_DecodeVarBind(u_char *, int *, struct variable_list **, int);
 #define SMI_TIMETICKS  (ASN_APPLICATION | 3)   /* INTEGER */
 #define SMI_OPAQUE     (ASN_APPLICATION | 4)   /* OCTET STRING */
 #define SMI_COUNTER64  (ASN_APPLICATION | 6)   /* INTEGER */
-#define SMI_NOSUCHOBJECT   (ASN_CONTEXT | ASN_PRIMITIVE | 0x0)
-#define SMI_NOSUCHINSTANCE (ASN_CONTEXT | ASN_PRIMITIVE | 0x1)
-#define SMI_ENDOFMIBVIEW   (ASN_CONTEXT | ASN_PRIMITIVE | 0x2)
+
+
+/* constants for enums for the MIB nodes
+ * cachePeerAddressType (InetAddressType / ASN_INTEGER)
+ * cacheClientAddressType (InetAddressType / ASN_INTEGER)
+ * Defined Types
+ */
+
+#ifndef INETADDRESSTYPE_ENUMS
+#define INETADDRESSTYPE_ENUMS
+
+#define INETADDRESSTYPE_UNKNOWN  0
+#define INETADDRESSTYPE_IPV4  1
+#define INETADDRESSTYPE_IPV6  2
+#define INETADDRESSTYPE_IPV4Z  3
+#define INETADDRESSTYPE_IPV6Z  4
+#define INETADDRESSTYPE_DNS  16
+
+#endif                          /* INETADDRESSTYPE_ENUMS */
+
+
+/*
+ * RFC 1905: Protocol Operations for SNMPv2
+ * 
+ * Variable binding.
+ * 
+ * VarBind ::= 
+ *   SEQUENCE {
+ *     name ObjectName
+ *     CHOICE {
+ *       value ObjectSyntax
+ *       unSpecified NULL
+ *       noSuchObject[0] NULL
+ *       noSuchInstance[1] NULL
+ *       endOfMibView[2] NULL
+ *     }
+ *   }
+ */
+#define SMI_NOSUCHOBJECT   (ASN_CONTEXT | ASN_PRIMITIVE | 0x0) /* noSuchObject[0] */
+#define SMI_NOSUCHINSTANCE (ASN_CONTEXT | ASN_PRIMITIVE | 0x1) /* noSuchInstance[1] */
+#define SMI_ENDOFMIBVIEW   (ASN_CONTEXT | ASN_PRIMITIVE | 0x2) /* endOfMibView[2] */
 typedef struct variable variable;
 typedef struct variable_list variable_list;
 
index 345aa436a5e05783e2ce35ca4841e2c40a71abf3..9c398df0b6e306c6200344f13856150dbad73ade 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * $Id: squid_mswin.h,v 1.6 2007/09/23 15:21:29 serassio Exp $
+ * $Id: squid_mswin.h,v 1.7 2007/12/14 23:11:44 amosjeffries Exp $
  *
  * AUTHOR: Andrey Shorin <tolsty@tushino.com>
  * AUTHOR: Guido Serassio <serassio@squid-cache.org>
@@ -211,6 +211,7 @@ struct timezone
 #include <stddef.h>
 #include <process.h>
 #include <errno.h>
+#include <ws2tcpip.h>
 #if defined(_MSC_VER) /* Microsoft C Compiler ONLY */
 /* Hack to suppress compiler warnings on FD_SET() & FD_CLR() */
 #pragma warning (push)
@@ -243,6 +244,7 @@ typedef char * caddr_t;
 #define ECONNRESET WSAECONNRESET
 #define ENOTCONN WSAENOTCONN
 #define ERESTART WSATRY_AGAIN
+#define EAFNOSUPPORT WSAEAFNOSUPPORT
 
 #undef h_errno
 #define h_errno errno /* we'll set it ourselves */
@@ -392,10 +394,10 @@ char *index(const char *s, int c)
 namespace Squid {
 
 inline
-int accept(int s, struct sockaddr * a, int * l)
+int accept(int s, struct sockaddr * a, size_t * l)
 {
     SOCKET result;
-    if ((result = ::accept(_get_osfhandle(s), a, l)) == INVALID_SOCKET) {
+    if ((result = ::accept(_get_osfhandle(s), a, (int *)l)) == INVALID_SOCKET) {
        if (WSAEMFILE == (errno = WSAGetLastError()))
            errno = EMFILE;
        return -1;
@@ -458,9 +460,9 @@ HOSTENT FAR * gethostbyaddr(const char * a, int l, int t)
 #define gethostbyaddr(a,l,t) Squid::gethostbyaddr(a,l,t)
 
 inline
-int getsockname(int s, struct sockaddr * n, int * l)
+int getsockname(int s, struct sockaddr * n, size_t * l)
 {
-    if ((::getsockname(_get_osfhandle(s), n, l)) == SOCKET_ERROR) {
+    if ((::getsockname(_get_osfhandle(s), n, (int *)l)) == SOCKET_ERROR) {
        errno = WSAGetLastError();
        return -1;
     }
@@ -541,10 +543,10 @@ int recv(int s, void * b, size_t l, int f)
 }
 
 inline
-int recvfrom(int s, void * b, size_t l, int f, struct sockaddr * fr, int * fl)
+int recvfrom(int s, void * b, size_t l, int f, struct sockaddr * fr, size_t * fl)
 {
     int result;
-    if ((result = ::recvfrom(_get_osfhandle(s), (char *)b, l, f, fr, fl)) == SOCKET_ERROR) {
+    if ((result = ::recvfrom(_get_osfhandle(s), (char *)b, l, f, fr, (int *)fl)) == SOCKET_ERROR) {
        errno = WSAGetLastError();
        return -1;
     }
index ec46aba06cac936e63c8823a66a483d4a95d9495..fa64e8418de041d0a0d86e75adae330af40b7858 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: util.h,v 1.78 2007/09/20 12:32:50 amosjeffries Exp $
+ * $Id: util.h,v 1.79 2007/12/14 23:11:44 amosjeffries Exp $
  *
  * AUTHOR: Harvest Derived
  *
@@ -45,6 +45,9 @@
 #if HAVE_SYS_TIME_H
 #include <sys/time.h>
 #endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
 
 #if !defined(SQUIDHOSTNAMELEN)
 #define SQUIDHOSTNAMELEN 256
@@ -125,8 +128,6 @@ extern size_t xmalloc_total;
 extern void xmalloc_find_leaks(void);
 #endif
 
-typedef struct IN_ADDR SIA;
-SQUIDCEXTERN int safe_inet_addr(const char *, SIA *);
 SQUIDCEXTERN time_t parse_iso3307_time(const char *buf);
 SQUIDCEXTERN char *base64_decode(const char *coded);
 SQUIDCEXTERN const char *base64_encode(const char *decoded);
@@ -143,6 +144,13 @@ SQUIDCEXTERN const char *xint64toa(int64_t num);
 SQUIDCEXTERN double drand48(void);
 #endif
 
+#ifndef xmax
+#define xmax(a,b) ((a) < (b) ? (b) : (a))
+#endif
+#ifndef xmin
+#define xmin(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
 typedef struct {
     size_t count;
     size_t bytes;
index 27a2b2ea1a6065ec3a752670dd375f0609512715..34635113cd5471005fe55f0a7cce9d79cdaab21e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: GNUregex.c,v 1.21 2005/04/30 19:32:01 serassio Exp $
+ * $Id: GNUregex.c,v 1.22 2007/12/14 23:11:44 amosjeffries Exp $
  */
 
 /* Extended regular expression matching and search library,
@@ -247,7 +247,9 @@ char *alloca();
 #define MAX(a, b) ((a) > (b) ? (a) : (b))
 #define MIN(a, b) ((a) < (b) ? (a) : (b))
 
+#if !defined(__MINGW32__)      /* MinGW defines boolean */
 typedef char boolean;
+#endif
 #define false 0
 #define true 1
 \f
index c6bb30821bdfe5987129d7b6ede1c0ea64f7fb04..7ece54d485afc7bcddf0a042fa63ce3d1687f68f 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in
 #
-#  $Id: Makefile.am,v 1.32 2007/12/14 04:42:24 amosjeffries Exp $
+#  $Id: Makefile.am,v 1.33 2007/12/14 23:11:44 amosjeffries Exp $
 #
 
 DIST_SUBDIRS = libTrie
@@ -67,7 +67,6 @@ libmiscutil_a_SOURCES = \
        rfc1738.c \
        rfc2617.c \
        rfc3596.c \
-       safe_inet_addr.c \
        $(SNPRINTFSOURCE) \
        Splay.cc \
        $(STRSEPSOURCE) \
@@ -104,6 +103,9 @@ tests_testAll_SOURCES= \
        tests/testArray.cc \
        tests/testIPAddress.h \
        tests/testIPAddress.cc \
+       IPAddress.cc \
+       tests/testRFC1035.h \
+       tests/testRFC1035.cc \
        tests/testMain.cc \
        $(XPROF_STATS_SOURCE) \
        $(WIN32SRC) \
index 77a4d6ddfecde4d8914b17c8b08c29d8a90f69cc..3faede1aec34d076eeeff5d769d605cd2ec5f35b 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: rfc1035.c,v 1.50 2007/12/06 02:37:15 amosjeffries Exp $
+ * $Id: rfc1035.c,v 1.51 2007/12/14 23:11:45 amosjeffries Exp $
  *
  * Low level DNS protocol routines
  * AUTHOR: Duane Wessels
@@ -472,16 +472,17 @@ rfc1035SetErrno(int n)
 }
 
 static void
-rfc1035RRDestroy(rfc1035_rr * rr, int n)
+rfc1035RRDestroy(rfc1035_rr ** rr, int n)
 {
-    if (rr == NULL)
+    if (*rr == NULL)
        return;
     assert(n > 0);
     while (n--) {
-       if (rr[n].rdata)
-           xfree(rr[n].rdata);
+       if ((*rr)[n].rdata)
+           xfree((*rr)[n].rdata);
     }
-    xfree(rr);
+    xfree(*rr);
+    *rr = NULL;
 }
 
 /*
@@ -517,15 +518,16 @@ rfc1035QueryUnpack(const char *buf, size_t sz, unsigned int *off, rfc1035_query
 }
 
 void
-rfc1035MessageDestroy(rfc1035_message * msg)
+rfc1035MessageDestroy(rfc1035_message ** msg)
 {
-    if (!msg)
+    if (!*msg)
        return;
-    if (msg->query)
-       xfree(msg->query);
-    if (msg->answer)
-       rfc1035RRDestroy(msg->answer, msg->ancount);
-    xfree(msg);
+    if ((*msg)->query)
+       xfree((*msg)->query);
+    if ((*msg)->answer)
+       rfc1035RRDestroy(&(*msg)->answer, (*msg)->ancount);
+    xfree(*msg);
+    *msg = NULL;
 }
 
 /*
@@ -602,7 +604,7 @@ rfc1035MessageUnpack(const char *buf,
        if (rfc1035QueryUnpack(buf, sz, &off, &querys[j])) {
            RFC1035_UNPACK_DEBUG;
            rfc1035SetErrno(rfc1035_unpack_error);
-           rfc1035MessageDestroy(msg);
+           rfc1035MessageDestroy(&msg);
            return -rfc1035_unpack_error;
        }
     }
@@ -615,7 +617,7 @@ rfc1035MessageUnpack(const char *buf,
     if (msg->ancount == 0)
        return 0;
     i = (unsigned int) msg->ancount;
-    recs = msg->answer = xcalloc(i, sizeof(*recs));
+    recs = msg->answer = (rfc1035_rr*)xcalloc(i, sizeof(*recs));
     for (j = 0; j < i; j++) {
        if (off >= sz) {        /* corrupt packet */
            RFC1035_UNPACK_DEBUG;
@@ -632,7 +634,7 @@ rfc1035MessageUnpack(const char *buf,
         * we expected to unpack some answers (ancount != 0), but
         * didn't actually get any.
         */
-       rfc1035MessageDestroy(msg);
+       rfc1035MessageDestroy(&msg);
        *answer = NULL;
        rfc1035SetErrno(rfc1035_unpack_error);
        return -rfc1035_unpack_error;
@@ -804,7 +806,7 @@ main(int argc, char *argv[])
                printf("%d answers\n", n);
                for (i = 0; i < n; i++) {
                    if (answers[i].type == RFC1035_TYPE_A) {
-                       struct IN_ADDR a;
+                       struct in_addr a;
                        memcpy(&a, answers[i].rdata, 4);
                        printf("A\t%d\t%s\n", answers[i].ttl, inet_ntoa(a));
                    } else if (answers[i].type == RFC1035_TYPE_PTR) {
index 23f63c575359dabee763ebc7f0f2c029650eff02..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,65 +0,0 @@
-
-/*
- * $Id: safe_inet_addr.c,v 1.15 2007/12/06 18:01:52 rousskov Exp $
- */
-
-#include "config.h"
-#include "util.h"
-
-#if HAVE_STDIO_H
-#include <stdio.h>
-#endif
-#if HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#if HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#if HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#if HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#if HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#if HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-
-
-int
-safe_inet_addr(const char *buf, struct IN_ADDR *addr)
-{
-    static char addrbuf[32];
-    int a1 = 0, a2 = 0, a3 = 0, a4 = 0;
-    struct IN_ADDR A;
-    char x;
-#if defined(_SQUID_HPUX_)
-    /*
-     * MIYOSHI Tsutomu <mijosxi@ike.tottori-u.ac.jp> says scanning 'buf'
-     * causes a bus error on hppa1.1-hp-hpux9.07, so we
-     * have a broad hack for all HP systems.
-     */
-    static char buftmp[32];
-    snprintf(buftmp, 32, "%s", buf);
-    if (sscanf(buftmp, "%d.%d.%d.%d%c", &a1, &a2, &a3, &a4, &x) != 4)
-#else
-    if (sscanf(buf, "%d.%d.%d.%d%c", &a1, &a2, &a3, &a4, &x) != 4)
-#endif
-       return 0;
-    if (a1 < 0 || a1 > 255)
-       return 0;
-    if (a2 < 0 || a2 > 255)
-       return 0;
-    if (a3 < 0 || a3 > 255)
-       return 0;
-    if (a4 < 0 || a4 > 255)
-       return 0;
-    snprintf(addrbuf, 32, "%d.%d.%d.%d", a1, a2, a3, a4);
-    A.s_addr = inet_addr(addrbuf);
-    if (addr)
-       addr->s_addr = A.s_addr;
-    return 1;
-}
diff --git a/lib/tests/testRFC1035.cc b/lib/tests/testRFC1035.cc
new file mode 100644 (file)
index 0000000..642d958
--- /dev/null
@@ -0,0 +1,110 @@
+#include "config.h"
+
+#if HAVE_ASSERT_H
+#include <assert.h>
+#endif
+
+#include "testRFC1035.h"
+
+/* Being a C library code it is best bodily included and tested with C++ type-safe techniques. */
+#include "rfc1035.c"
+
+CPPUNIT_TEST_SUITE_REGISTRATION( testRFC1035 );
+
+// TODO Test each function in the Library independently
+//     Just because we can for global functions.
+//     It's good for the code too.
+
+void testRFC1035::testHeaderUnpack()
+{
+      /* Setup a buffer with the known-content packet */
+    const char *buf = "\x76\xb1\x81\x80\x00\x01\x00\x01\x00\x02\x00\x02\x03\x77\x77\x77\x07\x67\x61\x6d\x65\x64\x65\x76\x03\x6e\x65\x74\x00\x00\x01\x00\x01\xc0\x0c\x00\x01\x00\x01\x00\x00\x00\xef\x00\x04\xd8\xb9\x60\xea\xc0\x10\x00\x02\x00\x01\x00\x00\x00\xef\x00\x0f\x03\x6e\x73\x32\x05\x7a\x77\x61\x76\x65\x03\x63\x6f\x6d\x00\xc0\x10\x00\x02\x00\x01\x00\x00\x00\xef\x00\x06\x03\x6e\x73\x31\xc0\x41\xc0\x3d\x00\x01\x00\x01\x00\x00\x29\x6b\x00\x04\xd8\xea\xee\x4a\xc0\x58\x00\x01\x00\x01\x00\x00\x29\x6b\x00\x04\xd8\xea\xee\x4b";
+    size_t len = 126;
+    rfc1035_message *msg = NULL;
+    int res = 0;
+    unsigned int off = 0;
+
+      /* Test the HeaderUnpack function */
+    msg = new rfc1035_message;
+    res = rfc1035HeaderUnpack(buf, len, &off, msg);
+    CPPUNIT_ASSERT(res == 0);
+    CPPUNIT_ASSERT_EQUAL((short unsigned int)0x76b1, msg->id);
+    CPPUNIT_ASSERT(msg->qr == 1);
+       /* flags */
+    CPPUNIT_ASSERT_EQUAL((unsigned int)0, msg->opcode);
+    CPPUNIT_ASSERT_EQUAL((unsigned int)0, msg->aa);
+    CPPUNIT_ASSERT_EQUAL((unsigned int)0, msg->tc);
+    CPPUNIT_ASSERT_EQUAL((unsigned int)1, msg->rd);
+    CPPUNIT_ASSERT_EQUAL((unsigned int)1, msg->ra);
+    CPPUNIT_ASSERT_EQUAL((unsigned int)0, msg->rcode);
+      /* RR counts */
+    CPPUNIT_ASSERT_EQUAL((unsigned short)1, msg->qdcount);
+    CPPUNIT_ASSERT_EQUAL((unsigned short)1, msg->ancount);
+    CPPUNIT_ASSERT_EQUAL((unsigned short)2, msg->nscount);
+    CPPUNIT_ASSERT_EQUAL((unsigned short)2, msg->arcount);
+
+      /* cleanup */
+    delete msg; msg = NULL;
+}
+
+void testRFC1035::testParseAPacket()
+{
+      /* Setup a buffer with the known-content packet */
+    const char *buf = "\x76\xb1\x81\x80\x00\x01\x00\x01\x00\x02\x00\x02\x03\x77\x77\x77\x07\x67\x61\x6d\x65\x64\x65\x76\x03\x6e\x65\x74\x00\x00\x01\x00\x01\xc0\x0c\x00\x01\x00\x01\x00\x00\x00\xef\x00\x04\xd8\xb9\x60\xea\xc0\x10\x00\x02\x00\x01\x00\x00\x00\xef\x00\x0f\x03\x6e\x73\x32\x05\x7a\x77\x61\x76\x65\x03\x63\x6f\x6d\x00\xc0\x10\x00\x02\x00\x01\x00\x00\x00\xef\x00\x06\x03\x6e\x73\x31\xc0\x41\xc0\x3d\x00\x01\x00\x01\x00\x00\x29\x6b\x00\x04\xd8\xea\xee\x4a\xc0\x58\x00\x01\x00\x01\x00\x00\x29\x6b\x00\x04\xd8\xea\xee\x4b";
+    size_t len = 126;
+    rfc1035_message *msg = NULL;
+    int res = 0;
+
+      /* Test the MessageUnpack function itself */
+    res = rfc1035MessageUnpack(buf, len, &msg);
+
+    CPPUNIT_ASSERT_EQUAL(1, res);
+    CPPUNIT_ASSERT(msg != NULL);
+      /* cleanup */
+    rfc1035MessageDestroy(&msg);
+    CPPUNIT_ASSERT(msg == NULL);
+}
+
+void testRFC1035::testBugPacketEndingOnCompressionPtr()
+{
+      /* Setup a buffer with the known-to-fail packet */
+    const char *buf = "\xec\x7b\x81\x80\x00\x01\x00\x01\x00\x00\x00\x00\x05\x62\x75\x72\x73\x74\x02\x74\x65\x06\x74\x61\x63\x6f\x64\x61\x03\x6e\x65\x74\x00\x00\x1c\x00\x01\xc0\x0c\x00\x05\x00\x01\x00\x00\x19\xe5\x00\x0a\x02\x74\x65\x04\x67\x73\x6c\x62\xc0\x15";
+    size_t len = 59;
+    rfc1035_message *msg = NULL;
+    int res = 0;
+    unsigned int off = 0;
+
+
+      /* Test the HeaderUnpack function results */
+    msg = new rfc1035_message;
+    res = rfc1035HeaderUnpack(buf, len, &off, msg);
+    CPPUNIT_ASSERT(0 == res);
+    CPPUNIT_ASSERT(0xec7b == msg->id);
+    CPPUNIT_ASSERT(1 == msg->qr);
+       /* flags */
+    CPPUNIT_ASSERT(0 == msg->opcode);
+    CPPUNIT_ASSERT(0 == msg->aa);
+    CPPUNIT_ASSERT(0 == msg->tc);
+    CPPUNIT_ASSERT(1 == msg->rd);
+    CPPUNIT_ASSERT(1 == msg->ra);
+    CPPUNIT_ASSERT(0 == msg->rcode);
+      /* RR counts */
+    CPPUNIT_ASSERT(1 == msg->qdcount);
+    CPPUNIT_ASSERT(1 == msg->ancount);
+    CPPUNIT_ASSERT(0 == msg->nscount);
+    CPPUNIT_ASSERT(0 == msg->arcount);
+    CPPUNIT_ASSERT(12 == off);
+    printf("\n  Header : OK");
+      /* cleanup */
+    delete msg; msg = NULL;
+
+// TODO explicitly test RR and Name unpack functions for this packet.
+
+      /* Test the MessageUnpack function itself */
+    res = rfc1035MessageUnpack(buf, len, &msg);
+
+    CPPUNIT_ASSERT_EQUAL((const char*)NULL, rfc1035_error_message);
+    CPPUNIT_ASSERT_EQUAL(1, res);
+    CPPUNIT_ASSERT(msg != NULL);
+    rfc1035MessageDestroy(&msg);
+}
diff --git a/lib/tests/testRFC1035.h b/lib/tests/testRFC1035.h
new file mode 100644 (file)
index 0000000..b994c9a
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef SQUID_SRC_TEST_RFC1035_H
+#define SQUID_SRC_TEST_RFC1035_H
+
+#include <cppunit/extensions/HelperMacros.h>
+
+/*
+ * test the DNS resolver RFC 1035 Engine
+ */
+
+class testRFC1035 : public CPPUNIT_NS::TestFixture
+{
+    CPPUNIT_TEST_SUITE( testRFC1035 );
+    CPPUNIT_TEST( testHeaderUnpack );
+    CPPUNIT_TEST( testParseAPacket );
+
+    CPPUNIT_TEST( testBugPacketEndingOnCompressionPtr );
+    CPPUNIT_TEST_SUITE_END();
+
+public:
+
+protected:
+    void testHeaderUnpack();
+    void testParseAPacket();
+
+    // bugs.
+    void testBugPacketEndingOnCompressionPtr();
+};
+
+#endif /* SQUID_SRC_TEST_IPADDRESS_H */
index 1af39c43adcada44a842e8dbbf825b78ada87ea5..6eda311e1d745d3641a4121f0b6016bc87b393a7 100644 (file)
@@ -1,5 +1,6 @@
+
 /*
- * $Id: ACLARP.cc,v 1.24 2007/04/28 22:26:37 hno Exp $
+ * $Id: ACLARP.cc,v 1.25 2007/12/14 23:11:45 amosjeffries Exp $
  *
  * DEBUG: section 28    Access Control
  * AUTHOR: Duane Wessels
 #include <squid_windows.h>
 #endif
 #include "squid.h"
+#include "IPAddress.h"
 
 #ifdef _SQUID_WIN32_
 
 struct arpreq
 {
 
-    struct sockaddr arp_pa;   /* protocol address */
+    IPAddress arp_pa;   /* protocol address */
 
     struct sockaddr arp_ha;   /* hardware address */
     int arp_flags;            /* flags */
@@ -83,7 +85,7 @@ struct arpreq
 #endif
 static void aclParseArpList(SplayNode<acl_arp_data *> **curlist);
 static int decode_eth(const char *asc, char *eth);
-static int aclMatchArp(SplayNode<acl_arp_data *> **dataptr, struct IN_ADDR c);
+static int aclMatchArp(SplayNode<acl_arp_data *> **dataptr, IPAddress &c);
 static SplayNode<acl_arp_data *>::SPLAYCMP aclArpCompare;
 static SplayNode<acl_arp_data *>::SPLAYWALKEE aclDumpArpListWalkee;
 
@@ -224,6 +226,13 @@ aclParseArpList(SplayNode<acl_arp_data *> **curlist)
 int
 ACLARP::match(ACLChecklist *checklist)
 {
+    /* IPv6 does not do ARP */
+    if(!checklist->src_addr.IsIPv4())
+    {
+        debugs(14, 3, "ACLARP::match: IPv4 Required for ARP Lookups. Skipping " << checklist->src_addr );
+        return 0;
+    }
+
     return aclMatchArp(&data, checklist->src_addr);
 }
 
@@ -231,13 +240,15 @@ ACLARP::match(ACLChecklist *checklist)
 /* aclMatchArp */
 /***************/
 int
-aclMatchArp(SplayNode<acl_arp_data *> **dataptr, struct IN_ADDR c)
+aclMatchArp(SplayNode<acl_arp_data *> **dataptr, IPAddress &c)
 {
-#if defined(_SQUID_LINUX_)
+    char ntoabuf[MAX_IPSTRLEN];
 
     struct arpreq arpReq;
 
-    struct sockaddr_in ipAddr;
+    IPAddress ipAddr = c;
+
+#if defined(_SQUID_LINUX_)
 
     unsigned char ifbuffer[sizeof(struct ifreq) * 64];
 
@@ -257,15 +268,13 @@ aclMatchArp(SplayNode<acl_arp_data *> **dataptr, struct IN_ADDR c)
      * name first. If that does not succeed, the try each interface
      * in turn
      */
+
     /*
      * Set up structures for ARP lookup with blank interface name
      */
-    ipAddr.sin_family = AF_INET;
-    ipAddr.sin_port = 0;
-    ipAddr.sin_addr = c;
     memset(&arpReq, '\0', sizeof(arpReq));
 
-    xmemcpy(&arpReq.arp_pa, &ipAddr, sizeof(struct sockaddr_in));
+    ipAddr.GetSockAddr(arpReq.arp_pa);
     /* Query ARP table */
 
     if (ioctl(HttpSockets[0], SIOCGARP, &arpReq) != -1) {
@@ -287,7 +296,7 @@ aclMatchArp(SplayNode<acl_arp_data *> **dataptr, struct IN_ADDR c)
         acl_arp_data X;
         memcpy (X.eth, arpReq.arp_ha.sa_data, 6);
         *Top = (*Top)->splay(&X, aclArpCompare);
-        debugs(28, 3, "aclMatchArp: '" << inet_ntoa(c) << "' " << (splayLastResult ? "NOT found" : "found"));
+        debugs(28, 3, "aclMatchArp: '" << c << "' " << (splayLastResult ? "NOT found" : "found"));
         return (0 == splayLastResult);
     }
 
@@ -321,18 +330,13 @@ aclMatchArp(SplayNode<acl_arp_data *> **dataptr, struct IN_ADDR c)
         if (NULL != strchr(ifr->ifr_name, ':'))
             continue;
 
-        debugs(28, 4, "Looking up ARP address for " << inet_ntoa(c) << " on " << ifr->ifr_name);
+        debugs(28, 4, "Looking up ARP address for " << c << " on " << ifr->ifr_name);
 
         /* Set up structures for ARP lookup */
-        ipAddr.sin_family = AF_INET;
-
-        ipAddr.sin_port = 0;
-
-        ipAddr.sin_addr = c;
 
         memset(&arpReq, '\0', sizeof(arpReq));
 
-        xmemcpy(&arpReq.arp_pa, &ipAddr, sizeof(struct sockaddr_in));
+        ipAddr.GetSockAddr(arpReq.arp_pa);
 
         strncpy(arpReq.arp_dev, ifr->ifr_name, sizeof(arpReq.arp_dev) - 1);
 
@@ -377,7 +381,7 @@ aclMatchArp(SplayNode<acl_arp_data *> **dataptr, struct IN_ADDR c)
 
         /* Return if match, otherwise continue to other interfaces */
         if (0 == splayLastResult) {
-            debugs(28, 3, "aclMatchArp: " << inet_ntoa(c) << " found on " << ifr->ifr_name);
+            debugs(28, 3, "aclMatchArp: " << c << " found on " << ifr->ifr_name);
             return 1;
         }
 
@@ -389,24 +393,15 @@ aclMatchArp(SplayNode<acl_arp_data *> **dataptr, struct IN_ADDR c)
 
 #elif defined(_SQUID_SOLARIS_)
 
-    struct arpreq arpReq;
-
-    struct sockaddr_in ipAddr;
-
     SplayNode<acl_arp_data *> **Top = dataptr;
 
     /*
     * Set up structures for ARP lookup with blank interface name
     */
-    ipAddr.sin_family = AF_INET;
-
-    ipAddr.sin_port = 0;
-
-    ipAddr.sin_addr = c;
 
     memset(&arpReq, '\0', sizeof(arpReq));
 
-    xmemcpy(&arpReq.arp_pa, &ipAddr, sizeof(struct sockaddr_in));
+    ipAddr.GetSockAddr(arpReq.arp_pa);
 
     /* Query ARP table */
     if (ioctl(HttpSockets[0], SIOCGARP, &arpReq) != -1) {
@@ -433,17 +428,13 @@ aclMatchArp(SplayNode<acl_arp_data *> **dataptr, struct IN_ADDR c)
         /* Do lookup */
         *Top = (*Top)->splay((acl_arp_data *)&arpReq.arp_ha.sa_data, aclArpCompare);
 
-        debugs(28, 3, "aclMatchArp: '" << inet_ntoa(c) << "' " << (splayLastResult ? "NOT found" : "found"));
+        debugs(28, 3, "aclMatchArp: '" << c << "' " << (splayLastResult ? "NOT found" : "found"));
 
         return (0 == splayLastResult);
     }
 
 #elif defined(_SQUID_FREEBSD_) || defined(_SQUID_NETBSD_) || defined(_SQUID_OPENBSD_)
 
-    struct arpreq arpReq;
-
-    struct sockaddr_in ipAddr;
-
     SplayNode<acl_arp_data *> **Top = dataptr;
 
     int mib[6];
@@ -461,15 +452,10 @@ aclMatchArp(SplayNode<acl_arp_data *> **dataptr, struct IN_ADDR c)
     /*
     * Set up structures for ARP lookup with blank interface name
     */
-    ipAddr.sin_family = AF_INET;
-
-    ipAddr.sin_port = 0;
-
-    ipAddr.sin_addr = c;
 
     memset(&arpReq, '\0', sizeof(arpReq));
 
-    xmemcpy(&arpReq.arp_pa, &ipAddr, sizeof(struct sockaddr_in));
+    ipAddr.GetSockAddr(arpReq.arp_pa);
 
     /* Query ARP table */
     mib[0] = CTL_NET;
@@ -514,7 +500,7 @@ aclMatchArp(SplayNode<acl_arp_data *> **dataptr, struct IN_ADDR c)
 
         sdl = (struct sockaddr_dl *)((char *) sin + ROUNDUP(sin->sin_len));
 
-        if (c.s_addr == sin->sin_addr.s_addr) {
+        if (c == sin->sin_addr) {
             if (sdl->sdl_alen) {
 
                 arpReq.arp_ha.sa_len = sizeof(struct sockaddr);
@@ -542,7 +528,7 @@ aclMatchArp(SplayNode<acl_arp_data *> **dataptr, struct IN_ADDR c)
     /* Do lookup */
     *Top = (*Top)->splay((acl_arp_data *)&arpReq.arp_ha.sa_data, aclArpCompare);
 
-    debugs(28, 3, "aclMatchArp: '" << inet_ntoa(c) << "' " << (splayLastResult ? "NOT found" : "found"));
+    debugs(28, 3, "aclMatchArp: '" << c << "' " << (splayLastResult ? "NOT found" : "found"));
 
     return (0 == splayLastResult);
 
@@ -558,8 +544,6 @@ aclMatchArp(SplayNode<acl_arp_data *> **dataptr, struct IN_ADDR c)
 
     SplayNode<acl_arp_data *> **Top = dataptr;
 
-    struct arpreq arpReq;
-
     memset(&arpReq, '\0', sizeof(arpReq));
 
     /* Get size of Windows ARP table */
@@ -583,7 +567,7 @@ aclMatchArp(SplayNode<acl_arp_data *> **dataptr, struct IN_ADDR c)
 
     /* Find MAC address from net table */
     for (i = 0 ; i < NetTable->dwNumEntries ; i++) {
-        if ((c.s_addr == NetTable->table[i].dwAddr) && (NetTable->table[i].dwType > 2)) {
+        if ((c == (struct in_addr)NetTable->table[i].dwAddr) && (NetTable->table[i].dwType > 2)) {
             arpReq.arp_ha.sa_family = AF_UNSPEC;
             memcpy(arpReq.arp_ha.sa_data, NetTable->table[i].bPhysAddr, NetTable->table[i].dwPhysAddrLen);
         }
@@ -607,7 +591,7 @@ aclMatchArp(SplayNode<acl_arp_data *> **dataptr, struct IN_ADDR c)
     /* Do lookup */
     *Top = (*Top)->splay((acl_arp_data *)&arpReq.arp_ha.sa_data, aclArpCompare);
 
-    debugs(28, 3, "aclMatchArp: '" << inet_ntoa(c) << "' " << (splayLastResult ? "NOT found" : "found"));
+    debugs(28, 3, "aclMatchArp: '" << c << "' " << (splayLastResult ? "NOT found" : "found"));
 
     return (0 == splayLastResult);
 
@@ -619,7 +603,7 @@ aclMatchArp(SplayNode<acl_arp_data *> **dataptr, struct IN_ADDR c)
     /*
      * Address was not found on any interface
      */
-    debugs(28, 3, "aclMatchArp: " << inet_ntoa(c) << " NOT found");
+    debugs(28, 3, "aclMatchArp: " << c << " NOT found");
 
     return 0;
 }
index ff1b0b08a3b030307331b7d6b1a34fd97f532762..b1244bc9fc6ee740449bd229c7ac71526137ab57 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ACLASN.h,v 1.8 2006/05/29 00:14:59 robertc Exp $
+ * $Id: ACLASN.h,v 1.9 2007/12/14 23:11:45 amosjeffries Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
 #include "List.h"
 #include "ACLStrategised.h"
 #include "ACLChecklist.h"
+#include "IPAddress.h"
 
 /* forward decls */
 
 class CacheManager;
 
-SQUIDCEXTERN int asnMatchIp(List<int> *, struct IN_ADDR);
+SQUIDCEXTERN int asnMatchIp(List<int> *, IPAddress &);
 SQUIDCEXTERN void asnInit(void);
 extern void asnRegisterWithCacheManager(CacheManager & manager);
 SQUIDCEXTERN void asnFreeMemory(void);
 
-class ACLASN : public ACLData<struct IN_ADDR>
+class ACLASN : public ACLData<IPAddress>
 {
 
 public:
@@ -57,18 +58,18 @@ public:
 
     virtual ~ACLASN();
 
-    virtual bool match(struct IN_ADDR);
+    virtual bool match(IPAddress);
     virtual wordlist *dump();
     virtual void parse();
     bool empty() const;
-    virtual ACLData<struct IN_ADDR> *clone() const;
+    virtual ACLData<IPAddress> *clone() const;
     virtual void prepareForUse();
 
 private:
     static ACL::Prototype SourceRegistryProtoype;
-    static ACLStrategised<struct IN_ADDR> SourceRegistryEntry_;
+    static ACLStrategised<IPAddress> SourceRegistryEntry_;
     static ACL::Prototype DestinationRegistryProtoype;
-    static ACLStrategised<struct IN_ADDR> DestinationRegistryEntry_;
+    static ACLStrategised<IPAddress> DestinationRegistryEntry_;
     List<int> *data;
 };
 
index f5d018194962ba6d2fd00bf363b66c6423c8bccc..6db36236698a5fa06a87c64ba8779a851ec417a2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ACLChecklist.cc,v 1.42 2007/09/01 05:56:37 amosjeffries Exp $
+ * $Id: ACLChecklist.cc,v 1.43 2007/12/14 23:11:45 amosjeffries Exp $
  *
  * DEBUG: section 28    Access Control
  * AUTHOR: Duane Wessels
@@ -356,7 +356,9 @@ ACLChecklist::operator delete (void *address)
     cbdataFree(t);
 }
 
-ACLChecklist::ACLChecklist() : accessList (NULL), my_port (0), request (NULL),
+ACLChecklist::ACLChecklist() :
+        accessList (NULL),
+        request (NULL),
         reply (NULL),
         auth_user_request (NULL),
 #if SQUID_SNMP
@@ -374,12 +376,9 @@ ACLChecklist::ACLChecklist() : accessList (NULL), my_port (0), request (NULL),
         sourceDomainChecked_(false),
         lastACLResult_(false)
 {
-
-    memset (&src_addr, '\0', sizeof (struct IN_ADDR));
-
-    memset (&dst_addr, '\0', sizeof (struct IN_ADDR));
-
-    memset (&my_addr, '\0', sizeof (struct IN_ADDR));
+    my_addr.SetEmpty();
+    src_addr.SetEmpty();
+    dst_addr.SetEmpty();
     rfc931[0] = '\0';
 }
 
@@ -399,6 +398,7 @@ ACLChecklist::~ACLChecklist()
      * If this fails, then we'll need a backup UNLOCK call in the
      * destructor.
      */
+    /* AYJ: It fails in builds without any Authentication configured */
     assert(auth_user_request == NULL);
 
     conn_ = NULL;
@@ -573,7 +573,6 @@ aclChecklistCreate(const acl_access * A, HttpRequest * request, const char *iden
         checklist->request = HTTPMSGLOCK(request);
         checklist->src_addr = request->client_addr;
         checklist->my_addr = request->my_addr;
-        checklist->my_port = request->my_port;
     }
 
 #if USE_IDENT
index 1862bab7e830483e5ac84cbb9969bd9c15ffb964..8746925b1f4f46a7615cb9448985b5ce9d64a010 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ACLChecklist.h,v 1.28 2007/09/01 05:56:37 amosjeffries Exp $
+ * $Id: ACLChecklist.h,v 1.29 2007/12/14 23:11:45 amosjeffries Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -115,12 +115,12 @@ class NullState : public AsyncState
 
     const acl_access *accessList;
 
-    struct IN_ADDR src_addr;
+    IPAddress src_addr;
 
-    struct IN_ADDR dst_addr;
+    IPAddress dst_addr;
+
+    IPAddress my_addr;
 
-    struct IN_ADDR my_addr;
-    unsigned short my_port;
     HttpRequest *request;
     /* for acls that look at reply data */
     HttpReply *reply;
index 02e19e843e7c2a0c9f61473326acb04612ea54b3..9ef42d62b47d073eedb3707e568581281db936d2 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ACLDestinationASN.h,v 1.2 2005/04/18 21:52:41 hno Exp $
+ * $Id: ACLDestinationASN.h,v 1.3 2007/12/14 23:11:45 amosjeffries Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -37,8 +37,9 @@
 #define SQUID_ACLDESTINATIONASN_H
 #include "ACLASN.h"
 #include "ACLStrategy.h"
+#include "IPAddress.h"
 
-class ACLDestinationASNStrategy : public ACLStrategy<struct IN_ADDR>
+class ACLDestinationASNStrategy : public ACLStrategy<IPAddress>
 {
 
 public:
index 68739f53bbda71594b82338e08025c8e38b07f44..51208e57267d71ea655e32c6bf614e94b5fb74ba 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ACLDestinationDomain.cc,v 1.15 2007/11/03 04:49:53 wessels Exp $
+ * $Id: ACLDestinationDomain.cc,v 1.16 2007/12/14 23:11:45 amosjeffries Exp $
  *
  * DEBUG: section 28    Access Control
  * AUTHOR: Duane Wessels
@@ -79,10 +79,11 @@ ACLDestinationDomainStrategy::match (ACLData<MatchType> * &data, ACLChecklist *c
     const ipcache_addrs *ia = NULL;
     const char *fqdn = NULL;
 
-    if (data->match(checklist->request->host))
+    if (data->match(checklist->request->GetHost()))
         return 1;
 
-    if ((ia = ipcacheCheckNumeric(checklist->request->host)) == NULL)
+    /* numeric IPA? */
+    if ((ia = ipcacheCheckNumeric(checklist->request->GetHost())) == NULL)
         return 0;
 
     checklist->dst_addr = ia->in_addrs[0];
@@ -92,7 +93,7 @@ ACLDestinationDomainStrategy::match (ACLData<MatchType> * &data, ACLChecklist *c
         return data->match(fqdn);
     } else if (!checklist->destinationDomainChecked()) {
         /* FIXME: Using AclMatchedName here is not OO correct. Should find a way to the current acl */
-        debugs(28, 3, "aclMatchAcl: Can't yet compare '" << AclMatchedName << "' ACL for '" << checklist->request->host << "'");
+        debugs(28, 3, "aclMatchAcl: Can't yet compare '" << AclMatchedName << "' ACL for '" << checklist->request->GetHost() << "'");
         checklist->changeState(DestinationDomainLookup::Instance());
         return 0;
     }
index e16a70ae2a9a0d447e5a9497ac01f45c8375b96b..4f0042e2fdd1f8482eb7a5ff6f3a0d05434e2d63 100644 (file)
@@ -47,7 +47,7 @@ ACLDestinationIP::typeString() const
 int
 ACLDestinationIP::match(ACLChecklist *checklist)
 {
-    const ipcache_addrs *ia = ipcache_gethostbyname(checklist->request->host, IP_LOOKUP_IF_MISS);
+    const ipcache_addrs *ia = ipcache_gethostbyname(checklist->request->GetHost(), IP_LOOKUP_IF_MISS);
 
     if (ia) {
         /* Entry in cache found */
@@ -60,7 +60,7 @@ ACLDestinationIP::match(ACLChecklist *checklist)
         return 0;
     } else if (!checklist->request->flags.destinationIPLookedUp()) {
         /* No entry in cache, lookup not attempted */
-        debugs(28, 3, "aclMatchAcl: Can't yet compare '" << name << "' ACL for '" << checklist->request->host << "'");
+        debugs(28, 3, "aclMatchAcl: Can't yet compare '" << name << "' ACL for '" << checklist->request->GetHost() << "'");
         checklist->changeState (DestinationIPLookup::Instance());
         return 0;
     } else {
@@ -80,7 +80,7 @@ void
 DestinationIPLookup::checkForAsync(ACLChecklist *checklist)const
 {
     checklist->asyncInProgress(true);
-    ipcache_nbgethostbyname(checklist->request->host, LookupDone, checklist);
+    ipcache_nbgethostbyname(checklist->request->GetHost(), LookupDone, checklist);
 }
 
 void
index 6bc249221e762389c04e50964600567e6952ebcb..1780ba646c95265fe7859268cfedbab52e9183eb 100644 (file)
@@ -55,16 +55,17 @@ ACLIP::operator delete (void *address)
 void
 ACLIP::DumpIpListWalkee(acl_ip_data * const & ip, void *state)
 {
+    char tmpbuf[MAX_IPSTRLEN];
     MemBuf mb;
     wordlist **W = static_cast<wordlist **>(state);
     mb.init();
-    mb.Printf("%s", inet_ntoa(ip->addr1));
+    mb.Printf("%s", ip->addr1.NtoA(tmpbuf,MAX_IPSTRLEN));
 
-    if (ip->addr2.s_addr != any_addr.s_addr)
-        mb.Printf("-%s", inet_ntoa(ip->addr2));
+    if (!ip->addr2.IsAnyAddr())
+        mb.Printf("-%s", ip->addr2.NtoA(tmpbuf,MAX_IPSTRLEN));
 
-    if (ip->mask.s_addr != no_addr.s_addr)
-        mb.Printf("/%s", inet_ntoa(ip->mask));
+    if (!ip->mask.IsNoAddr())
+        mb.Printf("/%s", ip->mask.NtoA(tmpbuf,MAX_IPSTRLEN));
 
     wordlistAdd(W, mb.buf);
 
@@ -78,22 +79,33 @@ ACLIP::DumpIpListWalkee(acl_ip_data * const & ip, void *state)
 void
 acl_ip_data::toStr(char *buf, int len) const
 {
-    char b1[20];
-    char b2[20];
-    char b3[20];
-    snprintf(b1, 20, "%s", inet_ntoa(addr1));
+    char *b1 = buf;
+    char *b2 = NULL;
+    char *b3 = NULL;
+    int rlen = 0;
 
-    if (addr2.s_addr != any_addr.s_addr)
-        snprintf(b2, 20, "-%s", inet_ntoa(addr2));
+    addr1.NtoA(b1, len - rlen );
+    rlen = strlen(buf);
+    b2 = buf + rlen;
+
+    if (!addr2.IsAnyAddr())
+    {
+        b2[0] = '-'; rlen++;
+        addr2.NtoA(&(b2[1]), len - rlen );
+        rlen = strlen(buf);
+    }
     else
         b2[0] = '\0';
 
-    if (mask.s_addr != no_addr.s_addr)
-        snprintf(b3, 20, "/%s", inet_ntoa(mask));
+    b3 = buf + rlen;
+
+    if (!mask.IsNoAddr())
+    {
+        b3[0] = '/'; rlen++;
+        mask.NtoA(&(b3[1]), len - rlen );
+    }
     else
         b3[0] = '\0';
-
-    snprintf(buf, len, "%s%s%s", b1, b2, b3);
 }
 
 /*
@@ -106,30 +118,21 @@ acl_ip_data::toStr(char *buf, int len) const
 int
 aclIpAddrNetworkCompare(acl_ip_data * const &p, acl_ip_data * const &q)
 {
+    IPAddress A = p->addr1;
 
-    struct IN_ADDR A = p->addr1;
+    /* apply netmask */
+    A.ApplyMask(q->mask);
 
-    const struct IN_ADDR B = q->addr1;
+    if (q->addr2.IsAnyAddr()) {       /* single address check */
 
-    const struct IN_ADDR C = q->addr2;
-    A.s_addr &= q->mask.s_addr;        /* apply netmask */
+        return A.matchIPAddr( q->addr1 );
 
-    if (C.s_addr == 0) {       /* single address check */
+    } else {                   /* range address check */
 
-        if (ntohl(A.s_addr) > ntohl(B.s_addr))
-            return 1;
-        else if (ntohl(A.s_addr) < ntohl(B.s_addr))
-            return -1;
+        if ( (A >= q->addr1) && (A <= q->addr2) )
+            return 0; /* valid. inside range. */
         else
-            return 0;
-    } else {                   /* range address check */
-
-        if (ntohl(A.s_addr) > ntohl(C.s_addr))
-            return  1;
-        else if (ntohl(A.s_addr) < ntohl(B.s_addr))
-            return -1;
-        else
-            return 0;
+            return A.matchIPAddr( q->addr1 ); /* outside of range, 'less than' */
     }
 }
 
@@ -147,26 +150,27 @@ int
 acl_ip_data::NetworkCompare(acl_ip_data * const & a, acl_ip_data * const &b)
 {
     int ret;
+    bool bina = true;
     ret = aclIpAddrNetworkCompare(b, a);
 
     if (ret != 0) {
+        bina = false;
         ret = aclIpAddrNetworkCompare(a, b);
     }
 
     if (ret == 0) {
-        char buf_n1[60];
-        char buf_n2[60];
-        char buf_a[60];
-        b->toStr(buf_n1, 60);
-        a->toStr(buf_n2, 60);
-        a->toStr(buf_a, 60);
-        /* TODO: this warning may display the wrong way around */
-        debugs(28, 0, "WARNING: '" << buf_n1 <<
-               "' is a subnetwork of '" << buf_n2 << "'");
-        debugs(28, 0, "WARNING: because of this '" << buf_a <<
-               "' is ignored to keep splay tree searching predictable");
-        debugs(28, 0, "WARNING: You should probably remove '" << buf_n1 <<
-               "' from the ACL named '" << AclMatchedName << "'");
+        char buf_n1[3*(MAX_IPSTRLEN+1)];
+        char buf_n2[3*(MAX_IPSTRLEN+1)];
+        if(bina) {
+            b->toStr(buf_n1, 3*(MAX_IPSTRLEN+1));
+            a->toStr(buf_n2, 3*(MAX_IPSTRLEN+1));
+        } else {
+            a->toStr(buf_n1, 3*(MAX_IPSTRLEN+1));
+            b->toStr(buf_n2, 3*(MAX_IPSTRLEN+1));
+        }
+        debugs(28, 0, "WARNING: (" << (bina?'B':'A') << ") '" << buf_n1 << "' is a subnetwork of (" << (bina?'A':'B') << ") '" << buf_n2 << "'");
+        debugs(28, 0, "WARNING: because of this '" << (bina?buf_n2:buf_n1) << "' is ignored to keep splay tree searching predictable");
+        debugs(28, 0, "WARNING: You should probably remove '" << buf_n1 << "' from the ACL named '" << AclMatchedName << "'");
     }
 
     return ret;
@@ -178,138 +182,221 @@ acl_ip_data::NetworkCompare(acl_ip_data * const & a, acl_ip_data * const &b)
  * This function should NOT be called if 'asc' is a hostname!
  */
 bool
-acl_ip_data::DecodeMask(const char *asc, struct IN_ADDR *mask)
+acl_ip_data::DecodeMask(const char *asc, IPAddress &mask, int ctype)
 {
     char junk;
     int a1 = 0;
 
+    /* default is a mask that doesn't change any IP */
+    mask.SetNoAddr();
+
     if (!asc || !*asc)
     {
-        mask->s_addr = htonl(0xFFFFFFFFul);
         return true;
     }
 
-    if (sscanf(asc, "%d%c", &a1, &junk) == 1 && a1 >= 0 && a1 < 33)
-    {          /* a significant bits value for a mask */
-        mask->s_addr = a1 ? htonl(0xfffffffful << (32 - a1)) : 0;
-        return true;
+    /* An int mask 128, 32 */
+    if ((sscanf(asc, "%d%c", &a1, &junk)==1) &&
+         (a1 <= 128) && (a1  >= 0)
+       )
+    {
+        return mask.ApplyMask(a1, ctype);
     }
 
     /* dotted notation */
-    if (safe_inet_addr(asc, mask))
+    /* assignment returns true if asc contained an IP address as text */
+    if ((mask = asc))
         return true;
 
     return false;
 }
 
-#define SCAN_ACL1       "%[0123456789.]-%[0123456789.]/%[0123456789.]"
-#define SCAN_ACL2       "%[0123456789.]-%[0123456789.]%c"
-#define SCAN_ACL3       "%[0123456789.]/%[0123456789.]"
-#define SCAN_ACL4      "%[0123456789.]%c"
+/* Handle either type of address, IPv6 will be discarded with a warning if disabled */
+#define SCAN_ACL1_6       "%[0123456789ABCDEFabcdef:]-%[0123456789ABCDEFabcdef:]/%[0123456789]"
+#define SCAN_ACL2_6       "%[0123456789ABCDEFabcdef:]-%[0123456789ABCDEFabcdef:]%c"
+#define SCAN_ACL3_6       "%[0123456789ABCDEFabcdef:]/%[0123456789]"
+#define SCAN_ACL4_6       "%[0123456789ABCDEFabcdef:]/%c"
+/* We DO need to know which is which though, for proper CIDR masking. */
+#define SCAN_ACL1_4       "%[0123456789.]-%[0123456789.]/%[0123456789.]"
+#define SCAN_ACL2_4       "%[0123456789.]-%[0123456789.]%c"
+#define SCAN_ACL3_4       "%[0123456789.]/%[0123456789.]"
+#define SCAN_ACL4_4       "%[0123456789.]/%c"
 
 acl_ip_data *
 acl_ip_data::FactoryParse(const char *t)
 {
+    LOCAL_ARRAY(char, addr1, 256);
     LOCAL_ARRAY(char, addr2, 256);
     LOCAL_ARRAY(char, mask, 256);
-    acl_ip_data *r;
-    acl_ip_data **Q;
-    char **x;
+    acl_ip_data *r = NULL;
+    acl_ip_data **Q = NULL;
+    IPAddress temp;
     char c;
-    debugs(28, 5, "aclParseIpData: " << t);
+    unsigned int changed;
     acl_ip_data *q = new acl_ip_data;
+    int iptype = AF_UNSPEC;
+
+    debugs(28, 5, "aclIpParseIpData: " << t);
 
-    if (!strcasecmp(t, "all")) {
-        q->addr1.s_addr = 0;
-        q->addr2.s_addr = 0;
-        q->mask.s_addr = 0;
+    /* Special ACL RHS "all" matches entire Internet */
+    if (strcasecmp(t, "all") == 0) {
+        q->addr1.SetAnyAddr();
+        q->addr2.SetEmpty();
+        q->mask.SetAnyAddr();
         return q;
     }
 
-    LOCAL_ARRAY(char, addr1, 256);
+#if USE_IPV6
+    /* Special ACL RHS "ipv6" matches IPv6-Unicast Internet */
+    if (strcasecmp(t, "ipv6") == 0) {
+        t = "2000::/3";
+    }
+#endif
 
-    if (sscanf(t, SCAN_ACL1, addr1, addr2, mask) == 3) {
-        (void) 0;
-    } else if (sscanf(t, SCAN_ACL2, addr1, addr2, &c) == 2) {
+// IPv4
+    if (sscanf(t, SCAN_ACL1_4, addr1, addr2, mask) == 3) {
+        iptype=AF_INET;
+    } else if (sscanf(t, SCAN_ACL2_4, addr1, addr2, &c) >= 2) {
         mask[0] = '\0';
-    } else if (sscanf(t, SCAN_ACL3, addr1, mask) == 2) {
+        iptype=AF_INET;
+    } else if (sscanf(t, SCAN_ACL3_4, addr1, mask) == 2) {
         addr2[0] = '\0';
-    } else if (sscanf(t, SCAN_ACL4, addr1, &c) == 1) {
-       addr2[0] = '\0';
-       mask[0] = '\0';
+        iptype=AF_INET;
+    } else if (sscanf(t, SCAN_ACL4_4, addr1,&c) == 2) {
+        addr2[0] = '\0';
+        mask[0] = '\0';
+        iptype=AF_INET;
+
+// IPv6
+    } else if (sscanf(t, SCAN_ACL1_6, addr1, addr2, mask) == 3) {
+        iptype=AF_INET6;
+    } else if (sscanf(t, SCAN_ACL2_6, addr1, addr2, &c) >= 2) {
+        mask[0] = '\0';
+        iptype=AF_INET6;
+    } else if (sscanf(t, SCAN_ACL3_6, addr1, mask) == 2) {
+        addr2[0] = '\0';
+        iptype=AF_INET6;
+    } else if (sscanf(t, SCAN_ACL4_6, addr1, mask) == 2) {
+        addr2[0] = '\0';
+        iptype=AF_INET6;
+
+// Neither
     } else if (sscanf(t, "%[^/]/%s", addr1, mask) == 2) {
         addr2[0] = '\0';
     } else if (sscanf(t, "%s", addr1) == 1) {
-
         /*
-         * Note, must use plain gethostbyname() here because at startup
+         * Note, must use plain xgetaddrinfo() here because at startup
          * ipcache hasn't been initialized
+         * TODO: offload this to one of the IPAddress lookups.
          */
 
-        struct hostent *hp;
+        debugs(28, 5, "aclIpParseIpData: Lookup Host/IP " << addr1);
+        struct addrinfo *hp = NULL, *x = NULL;
+        struct addrinfo hints;
+        IPAddress *prev_addr = NULL;
+
+        memset(&hints, 0, sizeof(struct addrinfo));
+
+        if( iptype != AF_UNSPEC ) {
+            hints.ai_flags |= AI_NUMERICHOST;
+        }
+
+#if 0 && USE_IPV6 && !IPV6_SPECIAL_SPLITSTACK
+        hints.ai_flags |= AI_V4MAPPED | AI_ALL;
+#endif
 
-        if ((hp = gethostbyname(addr1)) == NULL) {
-            debugs(28, 0, "aclParseIpData: Bad host/IP: '" << t << "'");
+        int errcode = xgetaddrinfo(addr1,NULL,&hints,&hp);
+        if (hp == NULL) {
+            debugs(28, 0, "aclIpParseIpData: Bad host/IP: '" << addr1 <<
+                          "' in '" << t << "', flags=" << hints.ai_flags <<
+                          " : (" << errcode << ") " << xgai_strerror(errcode) );
             self_destruct();
+            return NULL;
         }
 
         Q = &q;
 
-        for (x = hp->h_addr_list; x != NULL && *x != NULL; x++) {
+        for (x = hp; x != NULL;) {
             if ((r = *Q) == NULL)
                 r = *Q = new acl_ip_data;
 
-            xmemcpy(&r->addr1.s_addr, *x, sizeof(r->addr1.s_addr));
+            /* getaddrinfo given a host has a nasty tendency to return duplicate addr's */
+            /* BUT sorted fortunately, so we can drop most of them easily */
+            r->addr1 = *x;
+            x = x->ai_next;
+            if( prev_addr && r->addr1 == *prev_addr) {
+                debugs(28, 3, "aclIpParseIpData: Duplicate host/IP: '" << r->addr1 << "' dropped.");
+                delete r;
+                *Q = NULL;
+                continue;
+            }
+            else
+                prev_addr = &r->addr1;
+
+            debugs(28, 3, "aclIpParseIpData: Located host/IP: '" << r->addr1 << "'");
 
-            r->addr2.s_addr = 0;
-           DecodeMask(NULL, &r->mask);
+            r->addr2.SetAnyAddr();
+            r->mask.SetNoAddr();
 
             Q = &r->next;
 
-            debugs(28, 3, "" << addr1 << " --> " << inet_ntoa(r->addr1));
+            debugs(28, 3, "" << addr1 << " --> " << r->addr1 );
         }
 
         if (*Q != NULL) {
-            debugs(28, 0, "aclParseIpData: Bad host/IP: '" << t << "'");
+            debugs(28, 0, "aclIpParseIpData: Bad host/IP: '" << t << "'");
             self_destruct();
+            return NULL;
         }
 
+        xfreeaddrinfo(hp);
+
         return q;
     }
 
+#if !USE_IPV6
+    /* ignore IPv6 addresses when built with IPv4-only */
+    if( iptype == AF_INET6 ) {
+        debugs(28, 0, "aclIpParseIpData: IPv6 has not been enabled. build with '--enable-ipv6'");
+        return NULL;
+    }
+#endif
+
     /* Decode addr1 */
-    if (!safe_inet_addr(addr1, &q->addr1)) {
-        debugs(28, 0, "aclParseIpData: unknown first address in '" << t << "'");
+    if (!*addr1) {
+        debugs(28, 0, "aclIpParseIpData: unknown first address in '" << t << "'");
         delete q;
         self_destruct();
         return NULL;
     }
+    else q->addr1 = addr1;
 
     /* Decode addr2 */
-    if (*addr2 && !safe_inet_addr(addr2, &q->addr2)) {
-        debugs(28, 0, "aclParseIpData: unknown second address in '" << t << "'");
+    if (*addr2 && !(q->addr2=addr2) ) {
+        debugs(28, 0, "aclIpParseIpData: unknown second address in '" << t << "'");
         delete q;
         self_destruct();
         return NULL;
     }
+    else q->addr2 = addr2;
 
     /* Decode mask (NULL or empty means a exact host mask) */
-    if (!DecodeMask(mask, &q->mask)) {
+    if (!DecodeMask(mask, q->mask, iptype)) {
         debugs(28, 0, "aclParseIpData: unknown netmask '" << mask << "' in '" << t << "'");
         delete q;
         self_destruct();
         return NULL;
     }
 
-    if ((q->addr1.s_addr & q->mask.s_addr) != q->addr1.s_addr ||
-            (q->addr2.s_addr & q->mask.s_addr) != q->addr2.s_addr)
-        debugs(28, 0, "aclParseIpData: WARNING: Netmask masks away part of the specified IP in '" << t << "'");
-
-    q->addr1.s_addr &= q->mask.s_addr;
+    changed = 0;
+    changed += q->addr1.ApplyMask(q->mask);
+    changed += q->addr2.ApplyMask(q->mask);
 
-    q->addr2.s_addr &= q->mask.s_addr;
+    if (changed)
+        debugs(28, 0, "aclIpParseIpData: WARNING: Netmask masks away part of the specified IP in '" << t << "'");
 
     /* 1.2.3.4/255.255.255.0  --> 1.2.3.0 */
+    /* Same as IPv6 (not so trivial to depict) */
     return q;
 }
 
@@ -349,24 +436,24 @@ ACLIP::empty () const
 }
 
 int
-
-ACLIP::match(struct IN_ADDR &clientip)
+ACLIP::match(IPAddress &clientip)
 {
-    static acl_ip_data ClientAddress (any_addr, any_addr, no_addr, NULL);
+    static acl_ip_data ClientAddress;
     /*
      * aclIpAddrNetworkCompare() takes two acl_ip_data pointers as
      * arguments, so we must create a fake one for the client's IP
-     * address, and use a /32 netmask.  However, the current code
-     * probably only accesses the addr1 element of this argument,
-     * so it might be possible to leave addr2 and mask unset.
+     * address. Since we are scanning for a single IP mask and addr2
+     * MUST be set to empty.
      */
     ClientAddress.addr1 = clientip;
-    acl_ip_data *ClientAddressPointer = &ClientAddress;
-    data = data->splay(ClientAddressPointer, aclIpAddrNetworkCompare);
-    debugs(28, 3, "aclMatchIp: '" << inet_ntoa(clientip) << "' " << (splayLastResult ? "NOT found" : "found"));
+    ClientAddress.addr2.SetEmpty();
+    ClientAddress.mask.SetEmpty();
+
+    data = data->splay(&ClientAddress, aclIpAddrNetworkCompare);
+    debugs(28, 3, "aclIpMatchIp: '" << clientip << "' " << (splayLastResult ? "NOT found" : "found"));
     return !splayLastResult;
 }
 
-acl_ip_data::acl_ip_data () :addr1(any_addr), addr2(any_addr), mask (any_addr), next (NULL) {}
+acl_ip_data::acl_ip_data () :addr1(), addr2(), mask(), next (NULL) {}
 
-acl_ip_data::acl_ip_data (struct IN_ADDR const &anAddress1, struct IN_ADDR const &anAddress2, struct IN_ADDR const &aMask, acl_ip_data *aNext) : addr1(anAddress1), addr2(anAddress2), mask(aMask), next(aNext){}
+acl_ip_data::acl_ip_data (IPAddress const &anAddress1, IPAddress const &anAddress2, IPAddress const &aMask, acl_ip_data *aNext) : addr1(anAddress1), addr2(anAddress2), mask(aMask), next(aNext){}
index 891b30073d4ef4c616467909d4e09ac4945380cb..e1d25e4f2e62a66342a5e89ed600f945077b7e13 100644 (file)
@@ -37,6 +37,7 @@
 #define SQUID_ACLIP_H
 #include "ACL.h"
 #include "splay.h"
+#include "IPAddress.h"
 
 class acl_ip_data
 {
@@ -48,19 +49,20 @@ public:
 
     acl_ip_data ();
 
-    acl_ip_data (struct IN_ADDR const &, struct IN_ADDR const &, struct IN_ADDR const &, acl_ip_data *);
+    acl_ip_data (IPAddress const &, IPAddress const &, IPAddress const &, acl_ip_data *);
     void toStr(char *buf, int len) const;
 
-    struct IN_ADDR addr1;      /* if addr2 non-zero then its a range */
+    IPAddress addr1;
 
-    struct IN_ADDR addr2;
+    IPAddress addr2;
+
+    IPAddress mask; /* This should perhapse be stored as a CIDR range now instead of a full IP mask. */
 
-    struct IN_ADDR mask;
     acl_ip_data *next;         /* used for parsing, not for storing */
 
 private:
 
-    static bool DecodeMask(const char *asc, struct IN_ADDR *mask);
+    static bool DecodeMask(const char *asc, IPAddress &mask, int string_format_type);
 };
 
 MEMPROXY_CLASS_INLINE(acl_ip_data)
@@ -87,7 +89,7 @@ public:
 
 protected:
 
-    int match(struct IN_ADDR &);
+    int match(IPAddress &);
     IPSplay *data;
 
 private:
index e9c2ad1a3bcdc8e1a67984200691218d8f0c2bdf..da842b0824eec2ec1c8c67fa6cc0b6c4fbf3c081 100644 (file)
@@ -128,7 +128,7 @@ IdentLookup::checkForAsync(ACLChecklist *checklist)const
     if (checklist->conn() != NULL) {
         debugs(28, 3, "IdentLookup::checkForAsync: Doing ident lookup" );
         checklist->asyncInProgress(true);
-        identStart(&checklist->conn()->me, &checklist->conn()->peer,
+        identStart(checklist->conn()->me, checklist->conn()->peer,
                    LookupDone, checklist);
     } else {
         debugs(28, 1, "IdentLookup::checkForAsync: Can't start ident lookup. No client connection" );
index b5fac9baa6d61b60209f4230858d45b2052c0909..992ca0ebd6e689f2cff43d4feeb4527282eabcd7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ACLMaxUserIP.cc,v 1.14 2007/05/09 07:36:24 wessels Exp $
+ * $Id: ACLMaxUserIP.cc,v 1.15 2007/12/14 23:11:45 amosjeffries Exp $
  *
  * DEBUG: section 28    Access Control
  * AUTHOR: Duane Wessels
@@ -117,7 +117,7 @@ ACLMaxUserIP::parse()
 int
 ACLMaxUserIP::match(AuthUserRequest * auth_user_request,
 
-                    struct IN_ADDR const &src_addr)
+                    IPAddress const &src_addr)
 {
     /*
      * the logic for flush the ip list when the limit is hit vs keep
index 3a4b8d6db2203c4aabf5a0fcdf66c479082d563b..ddf7a6bf307aac71d846daee75187ec350dbc6e6 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ACLMaxUserIP.h,v 1.9 2007/05/09 07:36:24 wessels Exp $
+ * $Id: ACLMaxUserIP.h,v 1.10 2007/12/14 23:11:45 amosjeffries Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -66,7 +66,7 @@ private:
     static Prototype RegistryProtoype;
     static ACLMaxUserIP RegistryEntry_;
 
-    int match(AuthUserRequest *, struct IN_ADDR const &);
+    int match(AuthUserRequest *, IPAddress const &);
     char const *class_;
     int maximum;
 
index d3f7796134c8333597778df0f7007299c7474274..99e42a214759f158603608e8c1d5baf42a62ac90 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ACLMyPort.cc,v 1.2 2003/10/20 12:33:01 robertc Exp $
+ * $Id: ACLMyPort.cc,v 1.3 2007/12/14 23:11:45 amosjeffries Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -51,7 +51,7 @@ ACLStrategised<int> ACLMyPort::RegistryEntry_(new ACLIntRange, ACLMyPortStrategy
 int
 ACLMyPortStrategy::match (ACLData<MatchType> * &data, ACLChecklist *checklist)
 {
-    return data->match (checklist->my_port);
+    return data->match (checklist->my_addr.GetPort());
 }
 
 ACLMyPortStrategy *
index 7205c2e7c2ad4eadf2fa4fdf03cf8f432e5c2996..f25b2c1d9707a62d68443e021704b34ea39a3e72 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ACLSourceASN.h,v 1.2 2005/04/18 21:52:41 hno Exp $
+ * $Id: ACLSourceASN.h,v 1.3 2007/12/14 23:11:45 amosjeffries Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -37,8 +37,9 @@
 #define SQUID_ACLSOURCEASN_H
 #include "ACLASN.h"
 #include "ACLStrategy.h"
+#include "IPAddress.h"
 
-class ACLSourceASNStrategy : public ACLStrategy<struct IN_ADDR>
+class ACLSourceASNStrategy : public ACLStrategy<IPAddress>
 {
 
 public:
index 8e544da4b8b4ca5493518dc45633cf00cd84a485..da6b9f86e73b5560b47d6c71440edaa571126c24 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ACLSourceDomain.cc,v 1.6 2007/09/21 11:41:52 amosjeffries Exp $
+ * $Id: ACLSourceDomain.cc,v 1.7 2007/12/14 23:11:45 amosjeffries Exp $
  *
  * DEBUG: section 28    Access Control
  * AUTHOR: Duane Wessels
@@ -82,7 +82,7 @@ ACLSourceDomainStrategy::match (ACLData<MatchType> * &data, ACLChecklist *checkl
         return data->match(fqdn);
     } else if (!checklist->sourceDomainChecked()) {
         /* FIXME: Using AclMatchedName here is not OO correct. Should find a way to the current acl */
-        debugs(28, 3, "aclMatchAcl: Can't yet compare '" << AclMatchedName << "' ACL for '" << inet_ntoa(checklist->src_addr) << "'");
+        debugs(28, 3, "aclMatchAcl: Can't yet compare '" << AclMatchedName << "' ACL for '" << checklist->src_addr << "'");
         checklist->changeState(SourceDomainLookup::Instance());
         return 0;
     }
index bb4408294e085d16445c379862ce7dfcc0e5ce51..6e5367259501b6c82a7f2e5ac2310d1640913a3a 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: AccessLogEntry.h,v 1.6 2007/08/13 17:20:51 hno Exp $
+ * $Id: AccessLogEntry.h,v 1.7 2007/12/14 23:11:45 amosjeffries Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -37,6 +37,7 @@
 
 #include "HttpVersion.h"
 #include "HierarchyLogEntry.h"
+#include "IPAddress.h"
 
 /* forward decls */
 
@@ -79,7 +80,8 @@ public:
     {
 
     public:
-        CacheDetails() : size(0),
+        CacheDetails() : caddr(),
+                size(0),
                 highOffset(0),
                 objectSize(0),
                 code (LOG_TAG_NONE),
@@ -91,10 +93,10 @@ public:
                 ,ssluser(NULL)
 #endif
         {
-            memset(&caddr, '\0', sizeof(caddr));
+            ;
         }
 
-        struct IN_ADDR caddr;
+        IPAddress caddr;
         int64_t size;
         int64_t highOffset;
         int64_t objectSize;
index 81cbe22d900b7b4ca6c3cd61c827b54ae59b5f36..b0d49cfacee016d1359f6c2c1035bc1162820c09 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: AuthUser.cc,v 1.9 2007/05/29 13:31:36 amosjeffries Exp $
+ * $Id: AuthUser.cc,v 1.10 2007/12/14 23:11:45 amosjeffries Exp $
  *
  * DEBUG: section 29    Authenticator
  * AUTHOR:  Robert Collins
@@ -240,7 +240,7 @@ AuthUser::clearIp()
 }
 
 void
-AuthUser::removeIp(struct IN_ADDR ipaddr)
+AuthUser::removeIp(IPAddress ipaddr)
 {
     auth_user_ip_t *ipdata = (auth_user_ip_t *) ip_list.head;
 
@@ -248,7 +248,7 @@ AuthUser::removeIp(struct IN_ADDR ipaddr)
     {
         /* walk the ip list */
 
-        if (ipdata->ipaddr.s_addr == ipaddr.s_addr) {
+        if (ipdata->ipaddr == ipaddr) {
             /* remove the node */
             dlinkDelete(&ipdata->node, &ip_list);
             cbdataFree(ipdata);
@@ -264,10 +264,9 @@ AuthUser::removeIp(struct IN_ADDR ipaddr)
 }
 
 void
-AuthUser::addIp(struct IN_ADDR ipaddr)
+AuthUser::addIp(IPAddress ipaddr)
 {
     auth_user_ip_t *ipdata = (auth_user_ip_t *) ip_list.head;
-    char *ip1;
     int found = 0;
 
     CBDATA_INIT_TYPE(auth_user_ip_t);
@@ -282,8 +281,8 @@ AuthUser::addIp(struct IN_ADDR ipaddr)
         auth_user_ip_t *tempnode = (auth_user_ip_t *) ipdata->node.next;
         /* walk the ip list */
 
-        if (ipdata->ipaddr.s_addr == ipaddr.s_addr) {
-            /* This ip has alreadu been seen. */
+        if (ipdata->ipaddr == ipaddr) {
+            /* This ip has already been seen. */
             found = 1;
             /* update IP ttl */
             ipdata->ip_expiretime = squid_curtime;
@@ -313,11 +312,7 @@ AuthUser::addIp(struct IN_ADDR ipaddr)
 
     ipcount++;
 
-    ip1 = xstrdup(inet_ntoa(ipaddr));
-
-    debugs(29, 2, "authenticateAuthUserAddIp: user '" << username() << "' has been seen at a new IP address (" << ip1 << ")");
-
-    safe_free(ip1);
+    debugs(29, 2, "authenticateAuthUserAddIp: user '" << username() << "' has been seen at a new IP address (" << ipaddr << ")");
 }
 
 
index 8fa993625b78fadf821b9d4fb06e497e81deb909..6fe668fdfae9c5d6a4d71aef44b89fd0d686073d 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: AuthUser.h,v 1.5 2007/05/09 08:26:57 wessels Exp $
+ * $Id: AuthUser.h,v 1.6 2007/12/14 23:11:45 amosjeffries Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -35,6 +35,8 @@
 #ifndef SQUID_AUTHUSER_H
 #define SQUID_AUTHUSER_H
 
+#include "IPAddress.h"
+
 class AuthUserRequest;
 
 class AuthUser
@@ -70,8 +72,8 @@ public:
     _SQUID_INLINE_ char const *username() const;
     _SQUID_INLINE_ void username(char const *);
     void clearIp();
-    void removeIp(struct IN_ADDR);
-    void addIp(struct IN_ADDR);
+    void removeIp(IPAddress);
+    void addIp(IPAddress);
     _SQUID_INLINE_ void addRequest(AuthUserRequest *);
 
     void lock()
index 51204796be35aa9553cb479bd758403842765936..51bcf0b1562b76524fb3776759c0e47864dfbab1 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: AuthUserRequest.cc,v 1.17 2007/08/28 22:35:29 hno Exp $
+ * $Id: AuthUserRequest.cc,v 1.18 2007/12/14 23:11:45 amosjeffries Exp $
  *
  * DO NOT MODIFY NEXT 2 LINES:
  * arch-tag: 6803fde1-d5a2-4c29-9034-1c0c9f650eb4
@@ -200,7 +200,7 @@ AuthUserRequest::denyMessage(char const * const default_message)
 }
 
 static void
-authenticateAuthUserRequestSetIp(AuthUserRequest * auth_user_request, struct IN_ADDR ipaddr)
+authenticateAuthUserRequestSetIp(AuthUserRequest * auth_user_request, IPAddress &ipaddr)
 {
     auth_user_t *auth_user = auth_user_request->user();
 
@@ -211,7 +211,7 @@ authenticateAuthUserRequestSetIp(AuthUserRequest * auth_user_request, struct IN_
 }
 
 void
-authenticateAuthUserRequestRemoveIp(AuthUserRequest * auth_user_request, struct IN_ADDR ipaddr)
+authenticateAuthUserRequestRemoveIp(AuthUserRequest * auth_user_request, IPAddress const &ipaddr)
 {
     auth_user_t *auth_user = auth_user_request->user();
 
@@ -329,7 +329,7 @@ authTryGetUser (AuthUserRequest **auth_user_request, ConnStateData::Pointer & co
  */
 auth_acl_t
 
-AuthUserRequest::authenticate(AuthUserRequest ** auth_user_request, http_hdr_type headertype, HttpRequest * request, ConnStateData::Pointer conn, struct IN_ADDR src_addr)
+AuthUserRequest::authenticate(AuthUserRequest ** auth_user_request, http_hdr_type headertype, HttpRequest * request, ConnStateData::Pointer conn, IPAddress &src_addr)
 {
     const char *proxy_auth;
     assert(headertype != 0);
@@ -402,7 +402,7 @@ AuthUserRequest::authenticate(AuthUserRequest ** auth_user_request, http_hdr_typ
                 debugs(29, 1, "authenticateAuthenticate: Unexpected change of authentication scheme from '" <<
                        conn->auth_user_request->user()->config->type() <<
                        "' to '" << proxy_auth << "' (client " <<
-                       inet_ntoa(src_addr) << ")");
+                       src_addr << ")");
 
                AUTHUSERREQUESTUNLOCK(conn->auth_user_request, "conn");
                 conn->auth_type = AUTH_UNKNOWN;
@@ -508,7 +508,7 @@ AuthUserRequest::authenticate(AuthUserRequest ** auth_user_request, http_hdr_typ
 
 auth_acl_t
 
-AuthUserRequest::tryToAuthenticateAndSetAuthUser(AuthUserRequest ** auth_user_request, http_hdr_type headertype, HttpRequest * request, ConnStateData::Pointer conn, struct IN_ADDR src_addr)
+AuthUserRequest::tryToAuthenticateAndSetAuthUser(AuthUserRequest ** auth_user_request, http_hdr_type headertype, HttpRequest * request, ConnStateData::Pointer conn, IPAddress &src_addr)
 {
     /* If we have already been called, return the cached value */
     AuthUserRequest *t = authTryGetUser (auth_user_request, conn, request);
index ff0534f223392c2a7ebd31ae3935b5d1b2eab4e6..0089d76d0803fd2e3c2c85b2996704b873efcd17 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: AuthUserRequest.h,v 1.6 2007/05/09 09:07:38 wessels Exp $
+ * $Id: AuthUserRequest.h,v 1.7 2007/12/14 23:11:45 amosjeffries Exp $
  *
  * DO NOT MODIFY NEXT 2 LINES:
  * arch-tag: 674533af-8b21-4641-b71a-74c4639072a0
@@ -49,7 +49,7 @@ struct AuthUserIP
     dlink_node node;
     /* IP addr this user authenticated from */
 
-    struct IN_ADDR ipaddr;
+    IPAddress ipaddr;
     time_t ip_expiretime;
 };
 
@@ -78,7 +78,7 @@ public:
 
     virtual void user (AuthUser *aUser) {_auth_user=aUser;}
 
-    static auth_acl_t tryToAuthenticateAndSetAuthUser(AuthUserRequest **, http_hdr_type, HttpRequest *, ConnStateData::Pointer, struct IN_ADDR);
+    static auth_acl_t tryToAuthenticateAndSetAuthUser(AuthUserRequest **, http_hdr_type, HttpRequest *, ConnStateData::Pointer, IPAddress &);
     static void addReplyAuthHeader(HttpReply * rep, AuthUserRequest * auth_user_request, HttpRequest * request, int accelerated, int internal);
 
     AuthUserRequest();
@@ -105,7 +105,7 @@ public:
 
 private:
 
-    static auth_acl_t authenticate(AuthUserRequest ** auth_user_request, http_hdr_type headertype, HttpRequest * request, ConnStateData::Pointer conn, struct IN_ADDR src_addr);
+    static auth_acl_t authenticate(AuthUserRequest ** auth_user_request, http_hdr_type headertype, HttpRequest * request, ConnStateData::Pointer conn, IPAddress &src_addr);
 
     /* return a message on the 407 error pages */
     char *message;
@@ -126,7 +126,7 @@ extern size_t authenticateRequestRefCount (AuthUserRequest *);
 extern void authenticateFixHeader(HttpReply *, AuthUserRequest *, HttpRequest *, int, int);
 extern void authenticateAddTrailer(HttpReply *, AuthUserRequest *, HttpRequest *, int);
 
-extern void authenticateAuthUserRequestRemoveIp(AuthUserRequest *, struct IN_ADDR);
+extern void authenticateAuthUserRequestRemoveIp(AuthUserRequest *, IPAddress const &);
 extern void authenticateAuthUserRequestClearIp(AuthUserRequest *);
 extern int authenticateAuthUserRequestIPCount(AuthUserRequest *);
 extern int authenticateDirection(AuthUserRequest *);
index cdc7936d8de76f17d47b5ae34b4abde42f62c4ab..12cdb5958683d23fec24adede44cab7a2e81c572 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: CompositePoolNode.h,v 1.8 2007/05/29 13:31:36 amosjeffries Exp $
+ * $Id: CompositePoolNode.h,v 1.9 2007/12/14 23:11:45 amosjeffries Exp $
  *
  * DEBUG: section 77    Delay Pools
  * AUTHOR: Robert Collins <robertc@squid-cache.org>
@@ -47,6 +47,7 @@
 #include "DelayPools.h"
 #include "DelayIdComposite.h"
 #include "CommRead.h"
+#include "IPAddress.h"
 
 class StoreEntry;
 
@@ -76,7 +77,7 @@ public:
     public:
         CompositeSelectionDetails() {}
 
-        struct IN_ADDR src_addr;
+        IPAddress src_addr;
         AuthUserRequest *user;
         String tag;
     };
index 1173a487b69f647f75e593d4e90d84a5ba8f2587..637d434e8c00f95b59af310b6df4211ab372387b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ConnectionDetail.h,v 1.3 2003/03/08 09:35:15 robertc Exp $
+ * $Id: ConnectionDetail.h,v 1.4 2007/12/14 23:11:45 amosjeffries Exp $
  *
  * DEBUG: section 5     Socket Functions
  * AUTHOR: Robert Collins
@@ -37,6 +37,8 @@
 #ifndef _SQUIDCONNECTIONDETAIL_H_
 #define _SQUIDCONNECTIONDETAIL_H_
 
+#include "IPAddress.h"
+
 class ConnectionDetail
 {
 
@@ -44,9 +46,9 @@ public:
 
     ConnectionDetail();
 
-    struct sockaddr_in me;
+    IPAddress me;
 
-    struct sockaddr_in peer;
+    IPAddress peer;
 };
 
 #endif
index 64a64bca4d2dd90af5a7e166c70e980a55b7865e..dd14f96d3b69d191c0eadaa0d7410dbf4226b378 100644 (file)
@@ -1,6 +1,5 @@
-
 /*
- * $Id: Debug.h,v 1.10 2007/08/24 01:02:09 amosjeffries Exp $
+ * $Id: Debug.h,v 1.11 2007/12/14 23:11:45 amosjeffries Exp $
  *
  * DEBUG: section 0     Debug Routines
  * AUTHOR: Harvest Derived
@@ -81,9 +80,9 @@ private:
  *
  * debugs(1,1, HERE << "some message");
  */
-#define HERE __FILE__<<"("<<__LINE__<<") "
+#define HERE __FILE__<<"("<<__LINE__<<") "<<__FUNCTION__<<": "
 
-/* AYJ: some uint8_t do not like streaming control-chars (values 0-31, 127+) */
+/* some uint8_t do not like streaming control-chars (values 0-31, 127+) */
 inline std::ostream& operator <<(std::ostream &os, const uint8_t d) {
     return (os << (int)d);
 }
index 43d2f921576cfb6c86de884474e5c9bfeace9e0b..d5683b9ee40d5035e33f02f7cc0ae1b2666fb18b 100644 (file)
@@ -1,7 +1,8 @@
-
 /*
- * $Id: DelayConfig.h,v 1.3 2006/04/25 12:00:29 robertc Exp $
+ * $Id: DelayConfig.h,v 1.4 2007/12/14 23:11:45 amosjeffries Exp $
  *
+ * DEBUG: section 3     Configuration Settings
+ * AUTHOR: Robert Collins
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
  * ----------------------------------------------------------
index 85e2fea3d9f08d25c9cf262bee90d90248772cca..bd71b95cee55e1ec8203180d107e030cdca02f5a 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: DelayId.cc,v 1.23 2007/09/21 11:41:52 amosjeffries Exp $
+ * $Id: DelayId.cc,v 1.24 2007/12/14 23:11:45 amosjeffries Exp $
  *
  * DEBUG: section 77    Delay Pools
  * AUTHOR: Robert Collins <robertc@squid-cache.org>
@@ -98,8 +98,8 @@ DelayId::DelayClient(ClientHttpRequest * http)
     assert(http);
     r = http->request;
 
-    if (r->client_addr.s_addr == INADDR_BROADCAST) {
-        debugs(77, 2, "delayClient: WARNING: Called with 'allones' address, ignoring");
+    if (r->client_addr.IsNoAddr()) {
+        debugs(77, 2, "delayClient: WARNING: Called with 'NO_ADDR' address, ignoring");
         return DelayId();
     }
 
@@ -107,7 +107,6 @@ DelayId::DelayClient(ClientHttpRequest * http)
         ACLChecklist ch;
         ch.src_addr = r->client_addr;
         ch.my_addr = r->my_addr;
-        ch.my_port = r->my_port;
 
         if (http->getConn() != NULL)
             ch.conn(http->getConn());
index d73d24c7a1fc9b0379e374fe94fdf39b07e3acbf..2152a92df72f33bd5114a809df9ae924406452bd 100644 (file)
@@ -1,6 +1,5 @@
-
 /*
- * $Id: DiskdIOStrategy.cc,v 1.11 2007/08/16 23:32:28 hno Exp $
+ * $Id: DiskdIOStrategy.cc,v 1.12 2007/12/14 23:11:50 amosjeffries Exp $
  *
  * DEBUG: section 79    Squid-side DISKD I/O functions.
  * AUTHOR: Duane Wessels
@@ -158,6 +157,7 @@ DiskdIOStrategy::init()
     char skey1[32];
     char skey2[32];
     char skey3[32];
+    IPAddress localhost;
 
     ikey = (getpid() << 10) + (instanceID << 2);
     ikey &= 0x7fffffff;
@@ -184,10 +184,12 @@ DiskdIOStrategy::init()
     args[2] = skey2;
     args[3] = skey3;
     args[4] = NULL;
+    localhost.SetLocalhost();
     pid = ipcCreate(IPC_STREAM,
                     Config.Program.diskd,
                     args,
                     "diskd",
+                    localhost,
                     &rfd,
                     &wfd,
                     &hIpc);
index 6bfbd70732c0b441913d38725f050b7ab1999750..70e83e54497b97e1d50c06a7db20972a0322a714 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ESI.cc,v 1.26 2007/08/27 12:50:42 hno Exp $
+ * $Id: ESI.cc,v 1.27 2007/12/14 23:11:45 amosjeffries Exp $
  *
  * DEBUG: section 86    ESI processing
  * AUTHOR: Robert Collins
@@ -53,6 +53,7 @@
 #include "ESIExpression.h"
 #include "HttpRequest.h"
 #include "MemBuf.h"
+#include "IPAddress.h"
 
 /* quick reference on behaviour here.
  * The ESI specification 1.0 requires the ESI processor to be able to 
@@ -1451,7 +1452,7 @@ ESIContext::freeResources ()
     /* don't touch incoming, it's a pointer into buffered anyway */
 }
 
-extern ErrorState *clientBuildError (err_type, http_status, char const *, struct IN_ADDR *, HttpRequest *);
+extern ErrorState *clientBuildError (err_type, http_status, char const *, IPAddress &, HttpRequest *);
 
 
 /* This can ONLY be used before we have sent *any* data to the client */
@@ -1469,8 +1470,7 @@ ESIContext::fail ()
     /* don't honour range requests - for errors we send it all */
     flags.error = 1;
     /* create an error object */
-    ErrorState * err = clientBuildError(errorpage, errorstatus, NULL,
-                                        http->getConn().getRaw() != NULL ? &http->getConn()->peer.sin_addr : &no_addr, http->request);
+    ErrorState * err = clientBuildError(errorpage, errorstatus, NULL, http->getConn()->peer, http->request);
     err->err_msg = errormessage;
     errormessage = NULL;
     rep = errorBuildReply (err);
index 80a840dd8dcf937304886a07f64670f00ab37107..ddd416b0fc2fe3d14611a0c893341e7931af0308 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: HttpRequest.cc,v 1.77 2007/08/13 17:20:51 hno Exp $
+ * $Id: HttpRequest.cc,v 1.78 2007/12/14 23:11:45 amosjeffries Exp $
  *
  * DEBUG: section 73    HTTP Request
  * AUTHOR: Duane Wessels
@@ -82,10 +82,8 @@ HttpRequest::init()
     imslen = 0;
     lastmod = -1;
     max_forwards = -1;
-    client_addr = no_addr;
-    my_addr = no_addr;
-    my_port = 0;
-    client_port = 0;
+    client_addr.SetEmpty();
+    my_addr.SetEmpty();
     body_pipe = NULL;
     // hier
     errType = ERR_NONE;
index b926f3449fd447cd9238ed419a571b4eea33ee1a..f19344fb528a668256dc98e8b47e2ddfcecae4a9 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: HttpRequest.h,v 1.30 2007/08/13 17:20:51 hno Exp $
+ * $Id: HttpRequest.h,v 1.31 2007/12/14 23:11:45 amosjeffries Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -68,6 +68,24 @@ public:
     /* are responses to this request potentially cachable */
     bool cacheable() const;
 
+    /* Now that we care what host contains it is better off being protected. */
+    /* HACK: These two methods are only inline to get around Makefile dependancies */
+    /*      caused by HttpRequest being used in places it really shouldn't.        */
+    /*      ideally they would be methods of URL instead. */
+    inline void SetHost(const char *src)
+    {
+        host_addr.SetEmpty();
+        host_addr = src;
+        if( host_addr.IsAnyAddr() ) {
+            xstrncpy(host, src, SQUIDHOSTNAMELEN);
+        }
+        else {
+            host_addr.ToHostname(host, SQUIDHOSTNAMELEN);
+            debugs(23, 3, "HttpRequest::SetHost() given IP: " << host_addr);
+        }
+    };
+    inline const char* GetHost(void) const { return host; };
+
 protected:
     void clean();
 
@@ -78,7 +96,11 @@ public:
 
     char login[MAX_LOGIN_SZ];
 
-    char host[SQUIDHOSTNAMELEN + 1];
+private:
+    char host[SQUIDHOSTNAMELEN];
+
+public:
+    IPAddress host_addr;
 
     AuthUserRequest *auth_user_request;
 
@@ -98,15 +120,9 @@ public:
 
     int max_forwards;
 
-    /* these in_addr's could probably be sockaddr_in's */
-
-    struct IN_ADDR client_addr;
-
-    struct IN_ADDR my_addr;
-
-    unsigned short my_port;
+    IPAddress client_addr;
 
-    unsigned short client_port;
+    IPAddress my_addr;
 
     HierarchyLogEntry hier;
 
index 99324cab8455e340b89885f6fc2c8910a007dba3..e14f89b9e0cfe47cbc159b096aafff27cebfae7f 100644 (file)
@@ -1074,6 +1074,7 @@ void ICAPModXact::swanSong()
 
 void ICAPModXact::makeRequestHeaders(MemBuf &buf)
 {
+    char ntoabuf[MAX_IPSTRLEN];
     /*
      * XXX These should use HttpHdr interfaces instead of Printfs
      */
@@ -1140,9 +1141,8 @@ void ICAPModXact::makeRequestHeaders(MemBuf &buf)
     }
 
     if (TheICAPConfig.send_client_ip && request)
-        if (request->client_addr.s_addr != any_addr.s_addr &&
-            request->client_addr.s_addr != no_addr.s_addr)
-            buf.Printf("X-Client-IP: %s\r\n", inet_ntoa(request->client_addr));
+        if (!request->client_addr.IsAnyAddr() && !request->client_addr.IsNoAddr())
+            buf.Printf("X-Client-IP: %s\r\n", request->client_addr.NtoA(ntoabuf,MAX_IPSTRLEN));
 
     if (TheICAPConfig.send_client_username && request)
         makeUsernameHeader(request, buf);
diff --git a/src/ICMP.h b/src/ICMP.h
new file mode 100644 (file)
index 0000000..deb9951
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * $Id: ICMP.h,v 1.1 2007/12/14 23:11:45 amosjeffries Exp $
+ *
+ * DEBUG: section 37    ICMP Routines
+ * AUTHOR: Duane Wessels, Amos Jeffries
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+#ifndef _INCLUDE_ICMP_H
+#define _INCLUDE_ICMP_H
+
+#include "config.h"
+#include "IPAddress.h"
+
+#define PINGER_PAYLOAD_SZ      8192
+
+#define MAX_PAYLOAD 256 // WAS: SQUIDHOSTNAMELEN
+#define MAX_PKT4_SZ (MAX_PAYLOAD + sizeof(struct timeval) + sizeof (char) + sizeof(struct icmphdr) + 1)
+#if USE_IPV6
+#define MAX_PKT6_SZ (MAX_PAYLOAD + sizeof(struct timeval) + sizeof (char) + sizeof(struct icmp6_hdr) + 1)
+#endif
+
+#if USE_ICMP
+
+/* This is a line-data format struct. DO NOT alter. */
+struct pingerEchoData
+{
+    IPAddress to;
+    unsigned char opcode;
+    int psize;
+    char payload[PINGER_PAYLOAD_SZ];
+};
+
+/* This is a line-data format struct. DO NOT alter. */
+struct pingerReplyData
+{
+    IPAddress from;
+    unsigned char opcode;
+    int rtt;
+    int hops;
+    int psize;
+    char payload[PINGER_PAYLOAD_SZ];
+};
+
+struct icmpEchoData
+{
+    struct timeval tv;
+    unsigned char opcode;
+    char payload[MAX_PAYLOAD];
+};
+
+SQUIDCEXTERN int icmp_pkts_sent;
+
+#endif /* USE_ICMP */
+
+
+/**
+ * Implements the squid interface to access ICMP operations
+ *
+ \par
+ * Child implementations define specific parts of these operations
+ * using these methods as a naming and parameter template.
+ *
+ * ICMPSquid - implements the squid side of squid-pinger interface
+ * ICMPPinger - implements the pinger side of the squid-pinger interface
+ * ICMPv4 - implements pinger helper for ICMPv4
+ * ICMPv6 - implements pinger helper for ICMPv6
+ */
+class ICMP
+{
+public:
+    ICMP();
+    virtual ~ICMP() {};
+
+    /// Start pinger helper and initiate control channel
+    virtual int Open() =0;
+
+    /// Shutdown pinger helper and control channel
+    virtual void Close();
+
+#if USE_ICMP
+
+    /**
+     * Construct and Send an ECHO request
+     *
+     \param to        Destination address being 'pinged'
+     \param opcode    Specific code for ECHO request, see RFC ????.
+     \param payload   A payload MAY be sent in the ICMP message.
+     *                Content longer than MAX_PAYLOAD will be truncated.
+     \param len       Length of the payload in bytes if any is to be sent or 0.
+     */
+    virtual void SendEcho(IPAddress &to, int opcode, const char *payload=NULL, int len=0) =0;
+
+    /// Handle ICMP responses.
+    virtual void Recv(void) =0;
+
+protected:
+    /* shared internal methods */
+
+    /// Calculate a packet checksum
+    int CheckSum(unsigned short *ptr, int size);
+
+    /**
+     * Translate TTL to a hop distance
+     * 
+     \param ttl        negative     : n > 33
+     \param ttl        n(0...32)    : 32 >= n >= 1
+     \param ttl        n(33...62)   : 32 >= n >= 1
+     \param ttl        n(63...64)   : 2 >= n >= 1
+     \param ttl        n(65...128)  : 64 >= n >= 1
+     \param ttl        n(129...192) : 64 >= n >= 1
+     \param ttl        n(193...)    : n < 255
+     *
+     \bug BUG? ttl<0 can produce high hop values
+     \bug BUG? ttl>255 can produce zero or negative hop values
+     */
+    int ipHops(int ttl);
+
+    /// Log the packet.
+    void Log(const IPAddress &addr, const u_int8_t type, const char* pkt_str, const int rtt, const int hops);
+
+    /* no use wasting memory */
+    int icmp_sock;
+    int icmp_ident;
+#endif /* USE_ICMP */
+};
+
+#endif
diff --git a/src/ICMPConfig.h b/src/ICMPConfig.h
new file mode 100644 (file)
index 0000000..60be4bc
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * $Id: ICMPConfig.h,v 1.1 2007/12/14 23:11:45 amosjeffries Exp $
+ *
+ * DEBUG: section 3     Configuration Settings
+ * AUTHOR: Amos Jeffries
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from the
+ *  Internet community.  Development is led by Duane Wessels of the
+ *  National Laboratory for Applied Network Research and funded by the
+ *  National Science Foundation.  Squid is Copyrighted (C) 1998 by
+ *  the Regents of the University of California.  Please see the
+ *  COPYRIGHT file for full details.  Squid incorporates software
+ *  developed and/or copyrighted by other sources.  Please see the
+ *  CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ *  This code is copyright (C) 2007 by Treehouse Networks Ltd
+ *  of New Zealand. It is published and Lisenced as an extension of
+ *  squid under the same conditions as the main squid application.
+ */
+#ifndef ICMPCONFIG_H
+#define ICMPCONFIG_H
+
+#include "config.h"
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+/**
+ * Squid pinger Configuration settings
+ *
+ \par
+ * This structure is included as a child field of the global Config
+ * such that if ICMP is built it can be accessed as Config.pinger.*
+ */
+class ICMPConfig {
+
+public:
+
+    /** \todo These methods should really be defined in an ICMPConfig.cc file
+     * alongside any custom parsing routines needed for this component.
+     * First though, the whole global Config dependancy tree needs fixing */
+    ICMPConfig() : program(NULL), enable(0) {};
+    ~ICMPConfig() { if(program) delete program; program = NULL; };
+
+/* variables */
+
+    /** pinger helper application path */
+    char *program;
+
+    /** Whether the pinger helper is enabled for use or not */
+    /** \todo make this much more memory efficient for a boolean */
+    int enable;
+};
+
+#endif /* ICMPCONFIG_H */
diff --git a/src/ICMPPinger.cc b/src/ICMPPinger.cc
new file mode 100644 (file)
index 0000000..1d97469
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ * $Id: ICMPPinger.cc,v 1.1 2007/12/14 23:11:45 amosjeffries Exp $
+ *
+ * DEBUG: section 42    ICMP Pinger program
+ * AUTHOR: Duane Wessels
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+#define SQUID_HELPER 1
+
+#include "squid.h"
+
+#if USE_ICMP
+
+#include "SquidTime.h"
+#include "ICMPPinger.h"
+#include "ICMPv4.h"
+#include "ICMPv6.h"
+#include "Debug.h"
+
+ICMPPinger::ICMPPinger() : ICMP()
+{
+    // these start invalid. Setup properly in Open()
+    socket_from_squid = -1;
+    socket_to_squid = -1;
+}
+
+ICMPPinger::~ICMPPinger()
+{
+    Close();
+}
+
+int
+ICMPPinger::Open(void)
+{
+#ifdef _SQUID_MSWIN_
+
+    WSADATA wsaData;
+    WSAPROTOCOL_INFO wpi;
+    char buf[sizeof(wpi)];
+    int x;
+
+    struct sockaddr_in PS;
+
+    WSAStartup(2, &wsaData);
+
+    getCurrentTime();
+    _db_init(NULL, "ALL,1");
+    setmode(0, O_BINARY);
+    setmode(1, O_BINARY);
+    x = read(0, buf, sizeof(wpi));
+
+    if (x < (int)sizeof(wpi)) {
+        getCurrentTime();
+        debugs(42, 0, HERE << "read: FD 0: " << xstrerror());
+        write(1, "ERR\n", 4);
+        return -1;
+    }
+
+    xmemcpy(&wpi, buf, sizeof(wpi));
+
+    write(1, "OK\n", 3);
+    x = read(0, buf, sizeof(PS));
+
+    if (x < (int)sizeof(PS)) {
+        getCurrentTime();
+        debugs(42, 0, HERE << "read: FD 0: " << xstrerror());
+        write(1, "ERR\n", 4);
+        return -1;
+    }
+
+    xmemcpy(&PS, buf, sizeof(PS));
+
+    icmp_sock = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, &wpi, 0, 0);
+
+    if (icmp_sock == -1) {
+        getCurrentTime();
+        debugs(42, 0, HERE << "WSASocket: " << xstrerror());
+        write(1, "ERR\n", 4);
+        return -1;
+    }
+
+    x = connect(icmp_sock, (struct sockaddr *) &PS, sizeof(PS));
+
+    if (SOCKET_ERROR == x) {
+        getCurrentTime();
+        debugs(42, 0, HERE << "connect: " << xstrerror());
+        write(1, "ERR\n", 4);
+        return -1;
+    }
+
+    write(1, "OK\n", 3);
+    memset(buf, 0, sizeof(buf));
+    x = recv(icmp_sock, (void *) buf, sizeof(buf), 0);
+
+    if (x < 3) {
+        debugs(42, 0, HERE << "recv: " << xstrerror());
+        return -1;
+    }
+
+    x = send(icmp_sock, (const void *) buf, strlen(buf), 0);
+
+    if (x < 3 || strncmp("OK\n", buf, 3)) {
+        debugs(42, 0, HERE << "recv: " << xstrerror());
+        return -1;
+    }
+
+    getCurrentTime();
+    debugs(42, 1, "pinger: Squid socket opened");
+
+    /* windows uses a socket stream as a dual-direction channel */
+    socket_to_squid = icmp_sock;
+    socket_from_squid = icmp_sock;
+
+    return icmp_sock;
+
+#else /* !_SQUID_MSWIN_ */
+
+    /* non-windows apps use stdin/out pipes as the squid channel(s) */
+    socket_from_squid = 0; // use STDIN macro ??
+    socket_to_squid = 1; // use STDOUT macro ??
+    return socket_to_squid;
+#endif
+}
+
+void
+ICMPPinger::Close(void)
+{
+#ifdef _SQUID_MSWIN_
+
+    shutdown(icmp_sock, SD_BOTH);
+    close(icmp_sock);
+    icmp_sock = -1;
+#endif
+
+    /* also shutdown the helper engines */
+    icmp4.Close();
+#if USE_IPV6
+    icmp6.Close();
+#endif
+}
+
+void
+ICMPPinger::Recv(void)
+{
+    static pingerEchoData pecho;
+    int n;
+    int guess_size;
+
+    memset(&pecho, '\0', sizeof(pecho));
+    n = recv(socket_from_squid, &pecho, sizeof(pecho), 0);
+
+    if (n < 0) {
+        debugs(42, 1, "Pinger exiting.");
+        Close();
+        exit(1);
+    }
+
+    if (0 == n) {
+        /* EOF indicator */
+        debugs(42, 0, HERE << "EOF encountered. Pinger exiting.\n");
+        errno = 0;
+        Close();
+        exit(1);
+    }
+
+    guess_size = n - (sizeof(pingerEchoData) - PINGER_PAYLOAD_SZ);
+
+    if (guess_size != pecho.psize) {
+        debugs(42, 2, HERE << "size mismatch, guess=" << guess_size << ", psize=" << pecho.psize);
+        /* don't process this message, but keep running */
+        return;
+    }
+
+#if USE_IPV6
+    /* pass request for ICMPv6 handing */
+    if(pecho.to.IsIPv6()) {
+        debugs(42, 2, HERE << " Pass " << pecho.to << " off to ICMPv6 module.");
+        icmp6.SendEcho(pecho.to,
+                       pecho.opcode,
+                       pecho.payload,
+                       pecho.psize);
+    }
+#endif
+
+    /* pass the packet for ICMP handling */
+    else if(pecho.to.IsIPv4()) {
+        debugs(42, 2, HERE << " Pass " << pecho.to << " off to ICMPv4 module.");
+        icmp4.SendEcho(pecho.to,
+                       pecho.opcode,
+                       pecho.payload,
+                       pecho.psize);
+    }
+    else {
+        debugs(42, 1, HERE << " IP has unknown Type. " << pecho.to );
+    }
+}
+
+void
+ICMPPinger::SendResult(pingerReplyData &preply, int len)
+{
+    debugs(42, 2, HERE << "return result to squid. len=" << len);
+
+    if (send(socket_to_squid, &preply, len, 0) < 0) {
+        debugs(42, 0, "pinger: FATAL error on send: " << xstrerror());
+        Close();
+        exit(1);
+    }
+}
+
+#endif /* USE_ICMP */
diff --git a/src/ICMPPinger.h b/src/ICMPPinger.h
new file mode 100644 (file)
index 0000000..8c28c9a
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * $Id: ICMPPinger.h,v 1.1 2007/12/14 23:11:45 amosjeffries Exp $
+ *
+ * DEBUG: section 37    ICMP Routines
+ * AUTHOR: Duane Wessels, Amos Jeffries
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+#ifndef _INCLUDE_ICMPPINGER_H
+#define _INCLUDE_ICMPPINGER_H
+
+#include "config.h"
+#include "ICMP.h"
+
+/**
+ * Implements the interface to squid for ICMP operations
+ */
+class ICMPPinger : public ICMP
+{
+public:
+    ICMPPinger();
+    virtual ~ICMPPinger();
+
+    /// Start and initiate control channel to squid
+    virtual int Open();
+
+    /// Shutdown pinger helper and control channel
+    virtual void Close();
+
+#if USE_ICMP
+
+    /// Send ICMP results back to squid.
+    void SendResult(pingerReplyData &preply, int len);
+
+    /// Handle ICMP requests from squid, passing to helpers.
+    virtual void Recv(void);
+
+private:
+    // unused in ICMPPinger
+    virtual void SendEcho(IPAddress &to, int opcode, const char *payload, int len) {};
+
+    /**
+     * Control channel(s) to squid.
+     * May be STDIN/STDOUT pipes or an IP socket depending on the OS
+     */
+    int socket_from_squid;
+    int socket_to_squid;
+#endif /* USE_ICMP */
+};
+
+#if USE_ICMP
+
+/// pinger helper contains one of these as a global object.
+SQUIDCEXTERN ICMPPinger control;
+
+#endif
+
+#endif
diff --git a/src/ICMPSquid.cc b/src/ICMPSquid.cc
new file mode 100644 (file)
index 0000000..188cce3
--- /dev/null
@@ -0,0 +1,303 @@
+/*
+ * $Id: ICMPSquid.cc,v 1.1 2007/12/14 23:11:45 amosjeffries Exp $
+ *
+ * DEBUG: section 37    ICMP Routines
+ * AUTHOR: Duane Wessels, Amos Jeffries
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+#include "squid.h"
+#include "ICMPSquid.h"
+#include "comm.h"
+#include "SquidTime.h"
+
+// Instance global to be available in main() and elsewhere.
+ICMPSquid icmpEngine;
+
+#if USE_ICMP
+
+#define S_ICMP_ECHO     1
+#if DEAD_CODE
+#define S_ICMP_ICP      2
+#endif
+#define S_ICMP_DOM      3
+
+static void * hIpc;
+static pid_t pid;
+
+#endif /* USE_ICMP */
+
+
+ICMPSquid::ICMPSquid() : ICMP()
+{
+    ; // nothing new.
+}
+
+ICMPSquid::~ICMPSquid()
+{
+    Close();
+}
+
+
+#if USE_ICMP
+
+void
+ICMPSquid::SendEcho(IPAddress &to, int opcode, const char *payload, int len)
+{
+    static pingerEchoData pecho;
+    int x, slen;
+
+    /** \li Does nothing if the pinger socket is not available. */
+    if(icmp_sock < 0) {
+        debugs(37, 2, HERE << " Socket Closed. Aborted send to " << pecho.to << ", opcode " << opcode << ", len " << pecho.psize);
+        return;
+    }
+
+    /** \li  If no payload is given or is set as NULL it will ignore payload and len */
+    if(!payload)
+        len = 0;
+   
+    /** \li Otherwise if len is 0, uses strlen() to detect length of payload.
+     \bug This will result in part of the payload being truncated if it contains a NULL character.
+     \bug Or it may result in a buffer over-run if the payload is not nul-terminated properly.
+     */
+    else if (payload && len == 0)
+        len = strlen(payload);
+
+    /** \li
+     \bug If length specified or auto-detected is greater than the possible payload squid will die with an assert.
+     \todo This should perhapse be reduced to a truncated payload? or no payload. A WARNING is due anyway.
+     */
+    assert(len <= PINGER_PAYLOAD_SZ);
+
+    pecho.to = to;
+
+    pecho.opcode = (unsigned char) opcode;
+
+    pecho.psize = len;
+
+    if(len > 0)
+        xmemcpy(pecho.payload, payload, len);
+
+    slen = sizeof(pingerEchoData) - PINGER_PAYLOAD_SZ + pecho.psize;
+
+    debugs(37, 2, HERE << "to " << pecho.to << ", opcode " << opcode << ", len " << pecho.psize);
+
+    x = comm_udp_send(icmp_sock, (char *)&pecho, slen, 0);
+
+    if (x < 0) {
+        debugs(37, 1, HERE << "send: " << xstrerror());
+
+        /** \li  If the send results in ECONNREFUSED or EPIPE errors from helper, will cleanly shutdown the module. */
+        /** \todo This should try restarting the helper a few times?? before giving up? */
+        if (errno == ECONNREFUSED || errno == EPIPE) {
+            Close();
+            return;
+        }
+        /** All other send errors are ignored. */
+    } else if (x != len) {
+        debugs(37, 1, HERE << "Wrote " << x << " of " << slen << " bytes");
+    }
+}
+
+// static Callback to wrap the squid-side ICMP handler.
+// the ICMPSquid::Recv cannot be declared both static and virtual.
+static void
+icmpSquidRecv(int unused1, void *unused2)
+{
+    icmpEngine.Recv();
+}
+
+void
+ICMPSquid::Recv()
+{
+    int n;
+    static int fail_count = 0;
+    pingerReplyData preply;
+    static IPAddress F;
+
+    commSetSelect(icmp_sock, COMM_SELECT_READ, icmpSquidRecv, NULL, 0);
+    memset(&preply, '\0', sizeof(pingerReplyData));
+    n = comm_udp_recv(icmp_sock,
+                      (char *) &preply,
+                      sizeof(pingerReplyData),
+                      0);
+
+    if (n < 0 && EAGAIN != errno) {
+        debugs(37, 1, HERE << "recv: " << xstrerror());
+
+        if (errno == ECONNREFUSED)
+            Close();
+
+        if (errno == ECONNRESET)
+            Close();
+
+        if (++fail_count == 10)
+            Close();
+
+        return;
+    }
+
+    fail_count = 0;
+
+    /** If its a test probe from the pinger. Do nothing. */
+    if (n == 0) {
+        return;
+    }
+
+    F = preply.from;
+
+    F.SetPort(0);
+
+    switch (preply.opcode) {
+
+    case S_ICMP_ECHO:
+        debugs(37,4, HERE << " ICMP_ECHO of " << preply.from << " gave: hops=" << preply.hops <<", rtt=" << preply.rtt);
+        break;
+
+    case S_ICMP_DOM:
+        debugs(37,4, HERE << " DomainPing of " << preply.from << " gave: hops=" << preply.hops <<", rtt=" << preply.rtt);
+        netdbHandlePingReply(F, preply.hops, preply.rtt);
+        break;
+
+    default:
+        debugs(37, 1, HERE << "Bad opcode: " << preply.opcode << " from " << F);
+        break;
+    }
+}
+
+#endif /* USE_ICMP */
+
+void
+ICMPSquid::DomainPing(IPAddress &to, const char *domain)
+{
+#if USE_ICMP
+    debugs(37, 4, HERE << "'" << domain << "' (" << to << ")");
+    SendEcho(to, S_ICMP_DOM, domain, 0);
+#endif
+}
+
+int
+ICMPSquid::Open(void)
+{
+#if USE_ICMP
+    const char *args[2];
+    int rfd;
+    int wfd;
+    IPAddress localhost;
+
+    /* User configured disabled. */
+    if(!Config.pinger.enable) {
+        Close();
+        return -1;
+    }
+
+    args[0] = "(pinger)";
+    args[1] = NULL;
+    localhost.SetLocalhost();
+
+    /*
+     * Do NOT use IPC_DGRAM (=IPC_UNIX_DGRAM) here because you can't
+     * send() more than 4096 bytes on a socketpair() socket (at
+     * least on FreeBSD).
+     */
+    pid = ipcCreate(IPC_UDP_SOCKET,
+                    Config.pinger.program,
+                    args,
+                    "Pinger Socket",
+                    localhost,
+                    &rfd,
+                    &wfd,
+                    &hIpc);
+
+    if (pid < 0)
+        return -1;
+
+    assert(rfd == wfd);
+
+    icmp_sock = rfd;
+
+    fd_note(icmp_sock, "pinger");
+
+    commSetSelect(icmp_sock, COMM_SELECT_READ, icmpSquidRecv, NULL, 0);
+
+    commSetTimeout(icmp_sock, -1, NULL, NULL);
+
+    debugs(37, 1, HERE << "Pinger socket opened on FD " << icmp_sock);
+
+    /* Tests the pinger immediately using localhost */
+#if USE_IPV6
+    SendEcho(localhost, S_ICMP_ECHO, "ip6-localhost");
+#endif
+    if(localhost.SetIPv4())
+        SendEcho(localhost, S_ICMP_ECHO, "localhost");
+
+#ifdef _SQUID_MSWIN_
+
+    debugs(37, 4, HERE << "Pinger handle: 0x" << std::hex << hIpc << std::dec << ", PID: " << pid);
+
+#endif /* _SQUID_MSWIN_ */
+#endif /* USE_ICMP */
+    return icmp_sock;
+}
+
+void
+ICMPSquid::Close(void)
+{
+#if USE_ICMP
+
+    if (icmp_sock < 0)
+        return;
+
+    debugs(37, 1, HERE << "Closing Pinger socket on FD " << icmp_sock);
+
+#ifdef _SQUID_MSWIN_
+
+    send(icmp_sock, (const void *) "$shutdown\n", 10, 0);
+
+#endif
+
+    comm_close(icmp_sock);
+
+#ifdef _SQUID_MSWIN_
+
+    if (hIpc) {
+        if (WaitForSingleObject(hIpc, 12000) != WAIT_OBJECT_0) {
+            getCurrentTime();
+            debugs(37, 0, HERE << "WARNING: (pinger," << pid << ") didn't exit in 12 seconds");
+        }
+
+        CloseHandle(hIpc);
+    }
+
+#endif
+    icmp_sock = -1;
+
+#endif
+}
diff --git a/src/ICMPSquid.h b/src/ICMPSquid.h
new file mode 100644 (file)
index 0000000..bca5527
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * $Id: ICMPSquid.h,v 1.1 2007/12/14 23:11:45 amosjeffries Exp $
+ *
+ * DEBUG: section 37    ICMP Routines
+ * AUTHOR: Duane Wessels, Amos Jeffries
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+#ifndef _INCLUDE_ICMPSQUID_H
+#define _INCLUDE_ICMPSQUID_H
+
+#include "config.h"
+#include "ICMP.h"
+#include "IPAddress.h"
+
+/**
+ * Implements a non-blocking pseudo-ICMP engine for squid internally.
+ *
+ * Rather than doing all the work itself it passes each request off to
+ * an external pinger helper and returns results form that helper to squid.
+ *
+ * Provides ECHO-REQUEST, ECHO-REPLY in a protocol-neutral manner.
+ */
+class ICMPSquid : public ICMP
+{
+public:
+    ICMPSquid();
+    virtual ~ICMPSquid();
+
+    virtual int Open();
+    virtual void Close();
+
+    void DomainPing(IPAddress &to, const char *domain);
+
+#if USE_ICMP
+    virtual void SendEcho(IPAddress &to, int opcode, const char* payload=NULL, int len=0);
+    virtual void Recv(void);
+#endif
+};
+
+// global engine within squid.
+SQUIDCEXTERN ICMPSquid icmpEngine;
+
+#endif /* _INCLUDE_ICMPSQUID_H */
diff --git a/src/ICMPv4.cc b/src/ICMPv4.cc
new file mode 100644 (file)
index 0000000..9fceae3
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * $Id: ICMPv4.cc,v 1.1 2007/12/14 23:11:45 amosjeffries Exp $
+ *
+ * DEBUG: section 42    ICMP Pinger program
+ * AUTHOR: Duane Wessels, Amos Jeffries
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+//#define SQUID_HELPER 1
+
+#include "squid.h"
+
+#if USE_ICMP
+
+#include "SquidTime.h"
+#include "ICMPv4.h"
+#include "ICMPPinger.h"
+#include "Debug.h"
+
+const char *icmpPktStr[] =
+    {
+        "Echo Reply",
+        "ICMP 1",
+        "ICMP 2",
+        "Destination Unreachable",
+        "Source Quench",
+        "Redirect",
+        "ICMP 6",
+        "ICMP 7",
+        "Echo",
+        "ICMP 9",
+        "ICMP 10",
+        "Time Exceeded",
+        "Parameter Problem",
+        "Timestamp",
+        "Timestamp Reply",
+        "Info Request",
+        "Info Reply",
+        "Out of Range Type"
+    };
+
+ICMPv4::ICMPv4() : ICMP()
+{
+    ;
+}
+
+ICMPv4::~ICMPv4()
+{
+    Close();
+}
+
+int
+ICMPv4::Open(void)
+{
+    icmp_sock = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
+
+    if (icmp_sock < 0) {
+        debugs(50, 0, HERE << " icmp_sock: " << xstrerror());
+        return -1;
+    }
+
+    icmp_ident = getpid() & 0xffff;
+    debugs(42, 1, "pinger: ICMP socket opened.");
+
+    return icmp_sock;
+}
+
+void
+ICMPv4::SendEcho(IPAddress &to, int opcode, const char *payload, int len)
+{
+    int x;
+    LOCAL_ARRAY(char, pkt, MAX_PKT4_SZ);
+
+    struct icmphdr *icmp = NULL;
+    icmpEchoData *echo;
+    size_t icmp_pktsize = sizeof(struct icmphdr);
+    struct addrinfo *S = NULL;
+
+    memset(pkt, '\0', MAX_PKT4_SZ);
+
+    icmp = (struct icmphdr *) (void *) pkt;
+
+    /*
+     * cevans - beware signed/unsigned issues in untrusted data from
+     * the network!!
+     */
+    if (len < 0)
+    {
+        len = 0;
+    }
+
+    // Construct ICMP packet header
+    icmp->icmp_type = ICMP_ECHO;
+    icmp->icmp_code = 0;
+    icmp->icmp_cksum = 0;
+    icmp->icmp_id = icmp_ident;
+    icmp->icmp_seq = (u_short) icmp_pkts_sent++;
+
+    // Construct ICMP packet data content
+    echo = (icmpEchoData *) (icmp + 1);
+    echo->opcode = (unsigned char) opcode;
+    echo->tv = current_time;
+
+    icmp_pktsize += sizeof(struct timeval) + sizeof(char);
+
+    if (payload)
+    {
+        if (len > MAX_PAYLOAD)
+            len = MAX_PAYLOAD;
+
+        xmemcpy(echo->payload, payload, len);
+
+        icmp_pktsize += len;
+    }
+
+    icmp->icmp_cksum = CheckSum((u_short *) icmp, icmp_pktsize);
+
+    to.GetAddrInfo(S);
+    ((sockaddr_in*)S->ai_addr)->sin_port = 0;
+    assert(icmp_pktsize <= MAX_PKT4_SZ);
+
+    debugs(42, 2, HERE << "Send ICMP packet to " << to << ".");
+
+    x = sendto(icmp_sock,
+           (const void *) pkt,
+           icmp_pktsize,
+           0,
+           S->ai_addr,
+           S->ai_addrlen);
+
+    if(x < 0) {
+        debugs(42, 1, HERE << "Error sending to ICMP packet to " << to << ". ERR: " << xstrerror());
+    }
+
+    Log(to, ' ', NULL, 0, 0);
+}
+
+void
+ICMPv4::Recv(void)
+{
+    int n;
+    struct addrinfo *from = NULL;
+    int iphdrlen = sizeof(iphdr);
+    struct iphdr *ip = NULL;
+    struct icmphdr *icmp = NULL;
+    static char *pkt = NULL;
+    struct timeval now;
+    icmpEchoData *echo;
+    static pingerReplyData preply;
+
+    if(icmp_sock < 0) {
+        debugs(42, 0, HERE << "No socket! Recv() should not be called.");
+        return;
+    }
+
+    if (pkt == NULL)
+        pkt = (char *)xmalloc(MAX_PKT4_SZ);
+
+    preply.from.InitAddrInfo(from);
+    n = recvfrom(icmp_sock,
+                 (void *)pkt,
+                 MAX_PKT4_SZ,
+                 0,
+                 from->ai_addr,
+                 &from->ai_addrlen);
+
+    preply.from = *from;
+
+#if GETTIMEOFDAY_NO_TZP
+
+    gettimeofday(&now);
+
+#else
+
+    gettimeofday(&now, NULL);
+
+#endif
+
+    debugs(42, 8, HERE << n << " bytes from " << preply.from);
+
+    ip = (struct iphdr *) (void *) pkt;
+
+#if HAVE_STRUCT_IPHDR_IP_HL
+
+    iphdrlen = ip->ip_hl << 2;
+
+#else /* HAVE_STRUCT_IPHDR_IP_HL */
+#if WORDS_BIGENDIAN
+
+    iphdrlen = (ip->ip_vhl >> 4) << 2;
+
+#else
+
+    iphdrlen = (ip->ip_vhl & 0xF) << 2;
+
+#endif
+#endif /* HAVE_STRUCT_IPHDR_IP_HL */
+
+    icmp = (struct icmphdr *) (void *) (pkt + iphdrlen);
+
+    if (icmp->icmp_type != ICMP_ECHOREPLY)
+        return;
+
+    if (icmp->icmp_id != icmp_ident)
+        return;
+
+    echo = (icmpEchoData *) (void *) (icmp + 1);
+
+    preply.opcode = echo->opcode;
+
+    preply.hops = ipHops(ip->ip_ttl);
+
+    preply.rtt = tvSubMsec(echo->tv, now);
+
+    preply.psize = n - iphdrlen - (sizeof(icmpEchoData) - MAX_PKT4_SZ);
+
+    control.SendResult(preply, (sizeof(pingerReplyData) - MAX_PKT4_SZ + preply.psize) );
+
+    Log(preply.from, icmp->icmp_type, icmpPktStr[icmp->icmp_type], preply.rtt, preply.hops);
+}
+
+#endif /* USE_ICMP */
diff --git a/src/ICMPv4.h b/src/ICMPv4.h
new file mode 100644 (file)
index 0000000..05c06c2
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * $Id: ICMPv4.h,v 1.1 2007/12/14 23:11:45 amosjeffries Exp $
+ *
+ * DEBUG: section 37    ICMP Routines
+ * AUTHOR: Duane Wessels, Amos Jeffries
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+#ifndef _INCLUDE_ICMPV4_H
+#define _INCLUDE_ICMPV4_H
+
+#include "config.h"
+#include "ICMP.h"
+#include "IPAddress.h"
+
+#if HAVE_NETINET_IN_SYSTM_H
+#include <netinet/in_systm.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_NETINET_IP_H
+#include <netinet/ip.h>
+#endif
+#if HAVE_NETINET_IP_ICMP_H
+#include <netinet/ip_icmp.h>
+#endif
+
+/* Linux uses its own field names. */
+#if defined (_SQUID_LINUX_)
+#ifdef icmp_id
+#undef icmp_id
+#endif
+#ifdef icmp_seq
+#undef icmp_seq
+#endif
+#define icmp_type type
+#define icmp_code code
+#define icmp_cksum checksum
+#define icmp_id un.echo.id
+#define icmp_seq un.echo.sequence
+#define ip_hl ihl
+#define ip_v version
+#define ip_tos tos
+#define ip_len tot_len
+#define ip_id id
+#define ip_off frag_off
+#define ip_ttl ttl
+#define ip_p protocol
+#define ip_sum check
+#define ip_src saddr
+#define ip_dst daddr
+#endif
+
+
+/* Native Windows port doesn't have netinet support, so we emulate it.
+   At this time, Cygwin lacks icmp support in its include files, so we need
+   to use the native Windows port definitions.
+ */
+
+#ifdef _SQUID_WIN32_
+
+#include "fde.h"
+
+#ifdef _SQUID_MSWIN_
+
+#include <winsock2.h>
+#include <process.h>
+
+#endif
+
+/* IP Header */
+typedef struct iphdr
+{
+
+u_int8_t  ip_vhl:
+    4;          /* Length of the header in dwords */
+
+u_int8_t  version:
+    4;  /* Version of IP                  */
+    u_int8_t  tos;              /* Type of service                */
+    u_int16_t total_len;        /* Length of the packet in dwords */
+    u_int16_t ident;            /* unique identifier              */
+    u_int16_t flags;            /* Flags                          */
+    u_int8_t  ip_ttl;           /* Time to live                   */
+    u_int8_t  proto;            /* Protocol number (TCP, UDP etc) */
+    u_int16_t checksum;         /* IP checksum                    */
+    u_int32_t source_ip;
+    u_int32_t dest_ip;
+}
+iphdr;
+
+/* ICMP header */
+typedef struct icmphdr
+{
+    u_int8_t  icmp_type;        /* ICMP packet type                 */
+    u_int8_t  icmp_code;        /* Type sub code                    */
+    u_int16_t icmp_cksum;
+    u_int16_t icmp_id;
+    u_int16_t icmp_seq;
+    u_int32_t timestamp;        /* not part of ICMP, but we need it */
+}
+icmphdr;
+
+#endif  /* _SQUID_MSWIN_ */
+
+#ifndef ICMP_ECHO
+#define ICMP_ECHO 8
+#endif
+
+#ifndef ICMP_ECHOREPLY
+#define ICMP_ECHOREPLY 0
+#endif
+
+#ifndef IPPROTO_ICMP
+#define IPPROTO_ICMP 1
+#endif
+
+/* some OS apparently define icmp instead of icmphdr */
+#if !defined(icmphdr) && defined(icmp)
+#define icmphdr icmp
+#endif
+
+/* some OS apparently define ip instead of iphdr */
+#if !defined(iphdr) && defined(ip)
+#define iphdr ip
+#endif
+
+/**
+ * Class partially implementing RFC 792 - ICMP for IP version 4.
+ * Provides ECHO-REQUEST, ECHO-REPLY (secion 4.1)
+ */
+class ICMPv4 : public ICMP
+{
+public:
+    ICMPv4();
+    virtual ~ICMPv4();
+
+    virtual int Open();
+
+#if USE_ICMP
+    virtual void SendEcho(IPAddress &, int, const char*, int);
+    virtual void Recv(void);
+#endif
+};
+
+#if USE_ICMP
+
+/// pinger helper contains one of these as a global object.
+SQUIDCEXTERN ICMPv4 icmp4;
+
+#endif /* USE_ICMP && SQUID_HELPER */
+
+#endif
diff --git a/src/ICMPv6.cc b/src/ICMPv6.cc
new file mode 100644 (file)
index 0000000..4fd2d0e
--- /dev/null
@@ -0,0 +1,343 @@
+/*
+ * $Id: ICMPv6.cc,v 1.1 2007/12/14 23:11:45 amosjeffries Exp $
+ *
+ * DEBUG: section 42    ICMP Pinger program
+ * AUTHOR: Duane Wessels, Amos Jeffries
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+//#define SQUID_HELPER 1
+
+#include "squid.h"
+
+#if USE_ICMP && USE_IPV6
+
+#include "SquidTime.h"
+#include "Debug.h"
+#include "ICMPv6.h"
+#include "ICMPPinger.h"
+
+// Some system headers are only neeed internally here.
+// They should not be included via the header.
+
+#if HAVE_NETINET_IP6_H
+#include <netinet/ip6.h>
+#endif
+
+// ICMPv6 OP-Codes
+// see http://www.iana.org/assignments/icmpv6-parameters
+// NP: LowPktStr is for codes 0-127
+static const char *icmp6LowPktStr[] =
+    {
+        "ICMP 0",                      // 0
+        "Destination Unreachable",     // 1 - RFC2463
+        "Packet Too Big",              // 2 - RFC2463
+        "Time Exceeded",               // 3 - RFC2463
+        "Parameter Problem",           // 4 - RFC2463
+        "ICMP 5",                      // 5
+        "ICMP 6",                      // 6
+        "ICMP 7",                      // 7
+        "ICMP 8",                      // 8
+        "ICMP 9",                      // 9
+        "ICMP 10"                      // 10
+    };
+
+// NP: HighPktStr is for codes 128-255
+static const char *icmp6HighPktStr[] =
+    {
+        "Echo Request",                                        // 128 - RFC2463
+        "Echo Reply",                                  // 129 - RFC2463
+        "Multicast Listener Query",                    // 130 - RFC2710
+        "Multicast Listener Report",                   // 131 - RFC2710
+        "Multicast Listener Done",                     // 132 - RFC2710
+        "Router Solicitation",                         // 133 - RFC4861
+        "Router Advertisement",                                // 134 - RFC4861
+        "Neighbor Solicitation",                       // 135 - RFC4861
+        "Neighbor Advertisement",                      // 136 - RFC4861
+        "Redirect Message",                            // 137 - RFC4861
+        "Router Renumbering",                          // 138 - Crawford
+        "ICMP Node Information Query",                 // 139 - RFC4620
+        "ICMP Node Information Response",              // 140 - RFC4620
+        "Inverse Neighbor Discovery Solicitation",     // 141 - RFC3122
+        "Inverse Neighbor Discovery Advertisement",    // 142 - RFC3122
+        "Version 2 Multicast Listener Report",         // 143 - RFC3810       
+        "Home Agent Address Discovery Request",                // 144 - RFC3775
+        "Home Agent Address Discovery Reply",          // 145 - RFC3775
+        "Mobile Prefix Solicitation",                  // 146 - RFC3775
+        "Mobile Prefix Advertisement",                 // 147 - RFC3775
+        "Certification Path Solicitation",             // 148 - RFC3971
+        "Certification Path Advertisement",            // 149 - RFC3971
+        "ICMP Experimental (150)",                     // 150 - RFC4065
+        "Multicast Router Advertisement",              // 151 - RFC4286
+        "Multicast Router Solicitation",               // 152 - RFC4286
+        "Multicast Router Termination",                        // 153 - [RFC4286]
+        "ICMP 154",
+        "ICMP 155",
+        "ICMP 156",
+        "ICMP 157",
+        "ICMP 158",
+        "ICMP 159",
+        "ICMP 160"
+    };
+
+ICMPv6::ICMPv6() : ICMP()
+{
+    ; // nothing new.
+}
+
+ICMPv6::~ICMPv6()
+{
+    Close();
+}
+
+int
+ICMPv6::Open(void)
+{
+    icmp_sock = socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
+
+    if (icmp_sock < 0) {
+        debugs(50, 0, HERE << " icmp_sock: " << xstrerror());
+        return -1;
+    }
+
+    icmp_ident = getpid() & 0xffff;
+    debugs(42, 1, "pinger: ICMPv6 socket opened");
+
+    return icmp_sock;
+}
+
+/**
+ * Generates an RFC 4443 ICMPv6 ECHO Packet and sends into the network.
+ */
+void
+ICMPv6::SendEcho(IPAddress &to, int opcode, const char *payload, int len)
+{
+    int x;
+    LOCAL_ARRAY(char, pkt, MAX_PKT6_SZ);
+    struct icmp6_hdr *icmp = NULL;
+    icmpEchoData *echo = NULL;
+    struct addrinfo *S = NULL;
+    size_t icmp6_pktsize = 0;
+
+    memset(pkt, '\0', MAX_PKT6_SZ);
+    icmp = (struct icmp6_hdr *)pkt;
+
+    /*
+     * cevans - beware signed/unsigned issues in untrusted data from
+     * the network!!
+     */
+    if (len < 0) {
+        len = 0;
+    }
+
+    // Construct ICMPv6 ECHO header
+    icmp->icmp6_type = ICMP6_ECHO_REQUEST;
+    icmp->icmp6_code = 0;
+    icmp->icmp6_cksum = 0;
+    icmp->icmp6_id = icmp_ident;
+    icmp->icmp6_seq = (u_short) icmp_pkts_sent++;
+
+    icmp6_pktsize = sizeof(struct icmp6_hdr);
+
+
+    // Fill ICMPv6 ECHO data content
+    echo = (icmpEchoData *) (pkt + sizeof(icmp6_hdr));
+    echo->opcode = (unsigned char) opcode;
+    echo->tv = current_time;
+
+    icmp6_pktsize += sizeof(struct timeval) + sizeof(char);
+
+    if (payload)
+    {
+        if (len > MAX_PAYLOAD)
+            len = MAX_PAYLOAD;
+
+        xmemcpy(echo->payload, payload, len);
+
+        icmp6_pktsize += len;
+    }
+
+    icmp->icmp6_cksum = CheckSum((u_short *) icmp, icmp6_pktsize);
+
+    to.GetAddrInfo(S);
+    ((sockaddr_in6*)S->ai_addr)->sin6_port = 0;
+
+    assert(icmp6_pktsize <= MAX_PKT6_SZ);
+
+    debugs(42, 5, HERE << "Send ICMPv6 packet to " << to << ".");
+
+    x = sendto(icmp_sock,
+           (const void *) pkt,
+           icmp6_pktsize,
+           0,
+           S->ai_addr,
+           S->ai_addrlen);
+
+    if(x < 0) {
+        debugs(42, 1, HERE << "Error sending to ICMPv6 packet to " << to << ". ERR: " << xstrerror());
+    }
+    debugs(42,9, HERE << "x=" << x);
+
+    Log(to, 0, NULL, 0, 0);
+}
+
+/**
+ * Reads an RFC 4443 ICMPv6 ECHO-REPLY Packet from the network.
+ */
+void
+ICMPv6::Recv(void)
+{
+    int n;
+    struct addrinfo *from = NULL;
+//    struct ip6_hdr *ip = NULL;
+    static char *pkt = NULL;
+    struct icmp6_hdr *icmp6 = NULL;
+    icmpEchoData *echo = NULL;
+    struct timeval now;
+    static pingerReplyData preply;
+
+    if(icmp_sock < 0) {
+        debugs(42,0, HERE << "dropping ICMPv6 read. No socket!?");
+        return;
+    }
+
+    if (pkt == NULL) {
+        pkt = (char *)xmalloc(MAX_PKT6_SZ);
+    }
+
+    preply.from.InitAddrInfo(from);
+
+    n = recvfrom(icmp_sock,
+                 (void *)pkt,
+                 MAX_PKT6_SZ,
+                 0,
+                 from->ai_addr,
+                 &from->ai_addrlen);
+
+    preply.from = *from;
+
+#if GETTIMEOFDAY_NO_TZP
+
+    gettimeofday(&now);
+
+#else
+
+    gettimeofday(&now, NULL);
+
+#endif
+
+    debugs(42, 8, HERE << n << " bytes from " << preply.from);
+
+// FIXME INET6 : The IPv6 Header (ip6_hdr) is not availble directly >:-(
+//
+// TTL still has to come from the IP header somewhere.
+//     still need to strip and process it properly.
+//     probably have to rely on RTT as given by timestamp in data sent and current.
+/* IPv6 Header Structures (linux)
+struct ip6_hdr
+
+// fields (via simple define)
+#define ip6_vfc                // N.A
+#define ip6_flow       // N/A
+#define ip6_plen       // payload length.
+#define ip6_nxt                // expect to be type 0x3a - ICMPv6
+#define ip6_hlim       // MAX hops  (always 64, but no guarantee)
+#define ip6_hops       // HOPS!!!  (can it be true??)
+
+
+    ip = (struct ip6_hdr *) pkt;
+    pkt += sizeof(ip6_hdr);
+
+debugs(42,0, HERE << "ip6_nxt=" << ip->ip6_nxt <<
+               ", ip6_plen=" << ip->ip6_plen <<
+               ", ip6_hlim=" << ip->ip6_hlim <<
+               ", ip6_hops=" << ip->ip6_hops   <<
+               " ::: 40 == sizef(ip6_hdr) == " << sizeof(ip6_hdr)
+);
+*/
+
+    icmp6 = (struct icmp6_hdr *) pkt;
+    pkt += sizeof(icmp6_hdr);
+
+    if (icmp6->icmp6_type != ICMP6_ECHO_REPLY) {
+
+        switch(icmp6->icmp6_type) {
+            case 134:
+            case 135:
+            case 136:
+                /* ignore Router/Neighbour Advertisements */
+            break;
+
+            default:
+                debugs(42, 8, HERE << preply.from << " said: " << icmp6->icmp6_type << "/" << (int)icmp6->icmp6_code << " " <<
+                       ( icmp6->icmp6_type&0x80 ? icmp6HighPktStr[(int)(icmp6->icmp6_type&0x7f)] : icmp6LowPktStr[(int)(icmp6->icmp6_type&0x7f)] )
+                  );
+        }
+        return;
+    }
+
+    if (icmp6->icmp6_id != icmp_ident) {
+        debugs(42, 8, HERE << "dropping ICMPv6 read. IDENT check failed. ident=='" << icmp_ident << "'=='" << icmp6->icmp6_id << "'");
+        return;
+    }
+
+    echo = (icmpEchoData *) pkt;
+
+    preply.opcode = echo->opcode;
+
+    preply.rtt = tvSubMsec(echo->tv, now);
+
+/*
+ * FIXME INET6: Without access to the IPv6-Hops header we must rely on the total RTT
+ *      and could caculate the hops from that, but it produces some weird value mappings using ipHops
+ *     for now everything is 1 v6 hop away with variant RTT
+ * WANT:    preply.hops = ip->ip6_hops; // ipHops(ip->ip_hops);
+ */
+    preply.hops = 1;
+
+    preply.psize = n - /* sizeof(ip6_hdr) - */ sizeof(icmp6_hdr) - (sizeof(icmpEchoData) - MAX_PKT6_SZ);
+
+    /* Ensure the response packet has safe payload size */
+    if( preply.psize > (unsigned short) MAX_PKT6_SZ) {
+        preply.psize = MAX_PKT6_SZ;
+    }
+    else if( preply.psize < (unsigned short)0) {
+        preply.psize = 0;
+    }
+
+    Log(preply.from,
+        icmp6->icmp6_type,
+        ( icmp6->icmp6_type&0x80 ? icmp6HighPktStr[(int)(icmp6->icmp6_type&0x7f)] : icmp6LowPktStr[(int)(icmp6->icmp6_type&0x7f)] ),
+        preply.rtt,
+        preply.hops);
+
+    /* send results of the lookup back to squid.*/
+    control.SendResult(preply, (sizeof(pingerReplyData) - PINGER_PAYLOAD_SZ + preply.psize) );
+}
+
+#endif /* USE_ICMP && USE_IPV6 */
diff --git a/src/ICMPv6.h b/src/ICMPv6.h
new file mode 100644 (file)
index 0000000..4639ddc
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * $Id: ICMPv6.h,v 1.1 2007/12/14 23:11:45 amosjeffries Exp $
+ *
+ * DEBUG: section 37    ICMP Routines
+ * AUTHOR: Duane Wessels, Amos Jeffries
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+#ifndef _INCLUDE_ICMPV6_H
+#define _INCLUDE_ICMPV6_H
+
+#include "config.h"
+
+#if USE_IPV6
+
+#include "ICMP.h"
+#include "IPAddress.h"
+
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_NETINET_ICMP6_H
+#include <netinet/icmp6.h>
+#endif
+#if HAVE_NETINET_IP6_H
+#include <netinet/ip6.h>
+#endif
+
+/* see RFC 4443 section 2.1 */
+#ifndef ICMP6_ECHOREQUEST
+#define ICMP6_ECHOREQUEST 128
+#endif
+
+/* see RFC 4443 section 2.1 */
+#ifndef ICMP6_ECHOREPLY
+#define ICMP6_ECHOREPLY 129
+#endif
+
+/* see RFC 4443 section 2.1 */
+#ifndef IPPROTO_ICMPV6
+#define IPPROTO_ICMPV6 58
+#endif
+
+/**
+ * Class partially implementing RFC 4443 - ICMPv6 for IP version 6.
+ * Provides ECHO-REQUEST, ECHO-REPLY (secion 4)
+ */
+class ICMPv6 : public ICMP
+{
+public:
+    ICMPv6();
+    virtual ~ICMPv6();
+
+    virtual int Open();
+
+#if USE_ICMP
+    virtual void SendEcho(IPAddress &, int, const char*, int);
+    virtual void Recv(void);
+#endif
+};
+
+#if USE_ICMP
+
+/// pinger helper contains one of these as a global object.
+SQUIDCEXTERN ICMPv6 icmp6;
+
+#endif /* USE_ICMP && SQUID_HELPER */
+
+#endif /* USE_IPV6 */
+
+#endif /* _INCLUDE_ICMPV6_H */
index fd3f9045e9ed8346bd4a196695f73f241f2431b2..e57256c6f89ba9f5673b1e299b78d49ab23acdfd 100644 (file)
--- a/src/ICP.h
+++ b/src/ICP.h
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ICP.h,v 1.9 2007/10/31 04:52:15 amosjeffries Exp $
+ * $Id: ICP.h,v 1.10 2007/12/14 23:11:45 amosjeffries Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -55,7 +55,7 @@ struct _icp_common_t
     _icp_common_t();
     _icp_common_t(char *buf, unsigned int len);
 
-    void handleReply(char *buf, struct sockaddr_in *from);
+    void handleReply(char *buf, IPAddress &from);
     static _icp_common_t *createMessage(icp_opcode opcode, int flags, const char *url, int reqnum, int pad);
     icp_opcode getOpCode() const;
 #endif
@@ -82,7 +82,7 @@ public:
     HttpRequest *request;
     int fd;
 
-    struct sockaddr_in from;
+    IPAddress from;
     char *url;
 };
 
@@ -90,8 +90,7 @@ public:
 
 struct icpUdpData
 {
-
-    struct sockaddr_in address;
+    IPAddress address;
     void *msg;
     size_t len;
     icpUdpData *next;
@@ -106,21 +105,21 @@ struct icpUdpData
 };
 
 
-HttpRequest* icpGetRequest(char *url, int reqnum, int fd, struct sockaddr_in *from);
+HttpRequest* icpGetRequest(char *url, int reqnum, int fd, IPAddress &from);
 
-int icpAccessAllowed(struct sockaddr_in *from, HttpRequest * icp_request);
+int icpAccessAllowed(IPAddress &from, HttpRequest * icp_request);
 
-SQUIDCEXTERN void icpCreateAndSend(icp_opcode, int flags, char const *url, int reqnum, int pad, int fd, const struct sockaddr_in *from);
+SQUIDCEXTERN void icpCreateAndSend(icp_opcode, int flags, char const *url, int reqnum, int pad, int fd, const IPAddress &from);
 extern icp_opcode icpGetCommonOpcode();
 
-SQUIDCEXTERN int icpUdpSend(int, const struct sockaddr_in *, icp_common_t *, log_type, int);
+SQUIDCEXTERN int icpUdpSend(int, const IPAddress &, icp_common_t *, log_type, int);
 SQUIDCEXTERN log_type icpLogFromICPCode(icp_opcode opcode);
 
-void icpDenyAccess(struct sockaddr_in *from, char *url, int reqnum, int fd);
+void icpDenyAccess(IPAddress &from, char *url, int reqnum, int fd);
 SQUIDCEXTERN PF icpHandleUdp;
 SQUIDCEXTERN PF icpUdpSendQueue;
 
-SQUIDCEXTERN void icpHandleIcpV3(int, struct sockaddr_in, char *, int);
+SQUIDCEXTERN void icpHandleIcpV3(int, IPAddress &, char *, int);
 SQUIDCEXTERN int icpCheckUdpHit(StoreEntry *, HttpRequest * request);
 SQUIDCEXTERN void icpConnectionsOpen(void);
 SQUIDCEXTERN void icpConnectionShutdown(void);
index 83a9c2166749349cf5ebeeb9896c7dd151dacd7c..a8ec83b0bd1671429700598c49378d8f947d0c4b 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: IPInterception.cc,v 1.18 2007/11/07 10:20:47 amosjeffries Exp $
+ * $Id: IPInterception.cc,v 1.19 2007/12/14 23:11:45 amosjeffries Exp $
  *
  * DEBUG: section 89    NAT / IP Interception 
  * AUTHOR: Robert Collins
 #if IPF_TRANSPARENT
 int
 
-clientNatLookup(int fd, struct sockaddr_in me, struct sockaddr_in peer, struct sockaddr_in *dst)
+clientNatLookup(int fd, const IPAddress &me, const IPAddress &peer, IPAddress &dst)
 {
+    dst = me;
+    if( !me.IsIPv4() ) return -1;
+    if( !peer.IsIPv4() ) return -1;
 
 #if defined(IPFILTER_VERSION) && (IPFILTER_VERSION >= 4000027)
 
@@ -117,10 +120,10 @@ clientNatLookup(int fd, struct sockaddr_in me, struct sockaddr_in peer, struct s
     obj.ipfo_offset = 0;
 #endif
 
-    natLookup.nl_inport = me.sin_port;
-    natLookup.nl_outport = peer.sin_port;
-    natLookup.nl_inip = me.sin_addr;
-    natLookup.nl_outip = peer.sin_addr;
+    natLookup.nl_inport = htons(me.GetPort());
+    natLookup.nl_outport = htons(peer.GetPort());
+    me.GetInAddr(natLookup.nl_inip);
+    peer.GetInAddr(natLookup.nl_outip);
     natLookup.nl_flags = IPN_TCP;
 
     if (natfd < 0)
@@ -186,12 +189,12 @@ clientNatLookup(int fd, struct sockaddr_in me, struct sockaddr_in peer, struct s
         return -1;
     } else
     {
-        if (me.sin_addr.s_addr != natLookup.nl_realip.s_addr)
-            dst->sin_family = AF_INET;
+        if (me != natLookup.nl_realip) {
+            dst = natLookup.nl_realip;
 
-        dst->sin_port = natLookup.nl_realport;
-
-        dst->sin_addr = natLookup.nl_realip;
+            dst.SetPort(ntohs(natLookup.nl_realport));
+        }
+        // else. we already copied it.
 
         return 0;
     }
@@ -199,15 +202,21 @@ clientNatLookup(int fd, struct sockaddr_in me, struct sockaddr_in peer, struct s
 
 #elif LINUX_NETFILTER
 int
-
-clientNatLookup(int fd, struct sockaddr_in me, struct sockaddr_in peer, struct sockaddr_in *dst)
+clientNatLookup(int fd, const IPAddress &me, const IPAddress &peer, IPAddress &dst)
 {
+    dst = me;
+    if( !me.IsIPv4() ) return -1;
+    if( !peer.IsIPv4() ) return -1;
+
     static time_t last_reported = 0;
-    socklen_t sock_sz = sizeof(*dst);
-    memcpy(dst, &me, sizeof(*dst));
+    struct addrinfo *lookup = NULL;
+
+    dst.GetAddrInfo(lookup,AF_INET);
 
-    if (getsockopt(fd, SOL_IP, SO_ORIGINAL_DST, dst, &sock_sz) != 0)
+    if (getsockopt(fd, SOL_IP, SO_ORIGINAL_DST, lookup->ai_addr, &lookup->ai_addrlen) != 0)
     {
+        dst.FreeAddrInfo(lookup);
+
         if (squid_curtime - last_reported > 60) {
             debugs(89, 1, "clientNatLookup: NF getsockopt(SO_ORIGINAL_DST) failed: " << xstrerror());
             last_reported = squid_curtime;
@@ -215,10 +224,13 @@ clientNatLookup(int fd, struct sockaddr_in me, struct sockaddr_in peer, struct s
 
         return -1;
     }
+    dst = *lookup;
 
-    debugs(89, 5, "clientNatLookup: addr = " << inet_ntoa(dst->sin_addr) << "");
+    dst.FreeAddrInfo(lookup);
 
-    if (me.sin_addr.s_addr != dst->sin_addr.s_addr)
+    debugs(89, 5, "clientNatLookup: addr = " << dst << "");
+
+    if (me != dst)
         return 0;
     else
         return -1;
@@ -227,13 +239,16 @@ clientNatLookup(int fd, struct sockaddr_in me, struct sockaddr_in peer, struct s
 #elif PF_TRANSPARENT
 int
 
-clientNatLookup(int fd, struct sockaddr_in me, struct sockaddr_in peer, struct sockaddr_in *dst)
+clientNatLookup(int fd, const IPAddress &me, const IPAddress &peer, IPAddress dst)
 {
 
     struct pfioc_natlook nl;
     static int pffd = -1;
     static time_t last_reported = 0;
 
+    if( !me.IsIPv4() ) return -1;
+    if( !peer.IsIPv4() ) return -1;
+
     if (pffd < 0)
         pffd = open("/dev/pf", O_RDWR);
 
@@ -248,13 +263,15 @@ clientNatLookup(int fd, struct sockaddr_in me, struct sockaddr_in peer, struct s
 
     }
 
-    memset(dst, 0, sizeof(*dst));
+    dst.SetEmpty();
 
     memset(&nl, 0, sizeof(struct pfioc_natlook));
-    nl.saddr.v4.s_addr = peer.sin_addr.s_addr;
-    nl.sport = peer.sin_port;
-    nl.daddr.v4.s_addr = me.sin_addr.s_addr;
-    nl.dport = me.sin_port;
+    peer.GetInAddr(nl.saddr.v4);
+    nl.sport = htons(peer.GetPort());
+
+    me.GetInAddr(nl.daddr.v4);
+    nl.dport = htons(me.GetPort());
+
     nl.af = AF_INET;
     nl.proto = IPPROTO_TCP;
     nl.direction = PF_OUT;
@@ -274,10 +291,9 @@ clientNatLookup(int fd, struct sockaddr_in me, struct sockaddr_in peer, struct s
         return -1;
     } else
     {
-        int natted = me.sin_addr.s_addr != nl.rdaddr.v4.s_addr;
-        dst->sin_family = AF_INET;
-        dst->sin_port = nl.rdport;
-        dst->sin_addr = nl.rdaddr.v4;
+        int natted = (me != nl.rdaddr.v4);
+        dst = nl.rdaddr.v4;
+        dst.SetPort(ntohs(nl.rdport));
 
         if (natted)
             return 0;
@@ -288,27 +304,40 @@ clientNatLookup(int fd, struct sockaddr_in me, struct sockaddr_in peer, struct s
 
 #elif IPFW_TRANSPARENT
 int
-clientNatLookup(int fd, struct sockaddr_in me, struct sockaddr_in peer, struct sockaddr_in *dst)
+clientNatLookup(int fd, const IPAddress &me, const IPAddress &peer, IPAddress &dst)
 {
-       int ret;
-       struct sockaddr_in s;
-       int slen = sizeof(struct sockaddr_in);
-
-       ret = getsockname(fd, (struct sockaddr *) &s, (socklen_t * )&slen);
-       if (ret < 0) {
-               debugs(89, 1, "clientNatLookup: getpeername failed (fd " << fd << "), errstr " << xstrerror());
-               return -1;
-       }
-       *dst = s;
-       return 0;
+    int ret;
+    struct addrinfo *lookup = NULL;
+
+    if( !me.IsIPv4() ) return -1;
+    if( !peer.IsIPv4() ) return -1;
+
+    dst.GetAddrInfo(lookup,AF_INET);
+
+    ret = getsockname(fd, lookup->ai_addr, &lookup->ai_addrlen);
+
+    if (ret < 0) {
+
+        dst.FreeAddrInfo(lookup);
+
+        debugs(89, 1, "clientNatLookup: getpeername failed (fd " << fd << "), errstr " << xstrerror());
+
+        return -1;
+    }
+
+    dst = *lookup;
+
+    dst.FreeAddrInfo(lookup);
+
+    return 0;
 }
 
 #else
 int
-clientNatLookup(int fd, struct sockaddr_in me, struct sockaddr_in peer, struct sockaddr_in *dst)
+clientNatLookup(int fd, const IPAddress &me, const IPAddress &peer, IPAddress &dst)
 {
-       debugs(89, 1, "WARNING: transparent proxying not supported");
-       return -1;
+    debugs(89, 1, "WARNING: transparent proxying not supported");
+    return -1;
 }
 #endif
 
index 5a6bf609f78feeceee2c82f497fd70ce1c4d0411..7c810de544d0f10e47adc87dadeccecc87e3ee03 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: IPInterception.h,v 1.6 2003/02/21 22:50:05 robertc Exp $
+ * $Id: IPInterception.h,v 1.7 2007/12/14 23:11:45 amosjeffries Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -34,8 +34,9 @@
 #ifndef SQUID_IPINTERCEPTION_H
 #define SQUID_IPINTERCEPTION_H
 
-SQUIDCEXTERN int
+#include "IPAddress.h"
 
-clientNatLookup(int fd, struct sockaddr_in me, struct sockaddr_in peer, struct sockaddr_in *dst);
+SQUIDCEXTERN int
+clientNatLookup(int fd, const IPAddress &me, const IPAddress &peer, IPAddress &dst);
 
 #endif /* SQUID_IPINTERCEPTION_H */
index d4775064a9513753034e1a81d62cc76dc31b89d7..4c9b5391d7cb23083b2b97b14a3f215aa55c92a4 100644 (file)
@@ -1,7 +1,7 @@
 #
 #  Makefile for the Squid Object Cache server
 #
-#  $Id: Makefile.am,v 1.193 2007/10/31 04:52:15 amosjeffries Exp $
+#  $Id: Makefile.am,v 1.194 2007/12/14 23:11:45 amosjeffries Exp $
 #
 #  Uncomment and customize the following to suit your needs:
 #
@@ -127,6 +127,14 @@ else
 PINGER = 
 endif
 
+# Squid Internal ICMP sources
+ICMPSOURCE = \
+       ICMP.h \
+       icmp.cc \
+       ICMPConfig.h \
+       ICMPSquid.h \
+       ICMPSquid.cc
+
 SSL_ALL_SOURCE = \
        ACLCertificateData.cc \
        ACLCertificateData.h  \
@@ -134,6 +142,7 @@ SSL_ALL_SOURCE = \
        ACLCertificate.h  \
        ssl_support.cc \
        ssl_support.h
+
 if ENABLE_SSL
 SSL_SOURCE = $(SSL_ALL_SOURCE)
 else
@@ -507,7 +516,7 @@ squid_SOURCES = \
        HttpRequestMethod.cc \
        HttpRequestMethod.h \
        HttpVersion.h \
-       icmp.cc \
+       $(ICMPSOURCE) \
        ICP.h \
        icp_v2.cc \
        icp_v3.cc \
@@ -704,7 +713,17 @@ ICAP_libicap_a_SOURCES = \
 
 unlinkd_SOURCES = unlinkd_daemon.cc SquidNew.cc
 
+## NP: the pinger contains the squid-external helper code
+##     $(ICMPSOURCE) contains the interface bit to go inside squid
 pinger_SOURCES = \
+       ICMP.h \
+       icmp.cc \
+       ICMPPinger.h \
+       ICMPPinger.cc \
+       ICMPv4.h \
+       ICMPv4.cc \
+       ICMPv6.h \
+       ICMPv6.cc \
        pinger.cc \
        debug.cc \
        time.cc \
@@ -812,7 +831,7 @@ ufsdump_SOURCES = \
        HttpReply.cc \
        HttpRequest.cc \
        HttpRequestMethod.cc \
-       icmp.cc \
+       $(ICMPSOURCE) \
        icp_v2.cc \
        icp_v3.cc \
        $(IDENT_SOURCE) \
@@ -1121,6 +1140,7 @@ check_PROGRAMS+= \
        tests/testHeaders \
        tests/test_http_range \
        tests/testHttpRequest \
+       tests/testICMP \
        tests/testStore \
        tests/testString \
        tests/testURL \
@@ -1337,7 +1357,7 @@ tests_testCacheManager_SOURCES = \
        HttpMsg.cc \
        HttpReply.cc \
        HttpStatusLine.cc \
-       icmp.cc \
+       $(ICMPSOURCE) \
        icp_v2.cc \
        icp_v3.cc \
        $(IDENT_SOURCE) \
@@ -1503,7 +1523,7 @@ tests_testEvent_SOURCES = \
        HttpMsg.cc \
        HttpReply.cc \
        HttpStatusLine.cc \
-       icmp.cc \
+       $(ICMPSOURCE) \
        icp_v2.cc \
        icp_v3.cc \
        $(IDENT_SOURCE) \
@@ -1655,7 +1675,7 @@ tests_testEventLoop_SOURCES = \
        HttpMsg.cc \
        HttpReply.cc \
        HttpStatusLine.cc \
-       icmp.cc \
+       $(ICMPSOURCE) \
        icp_v2.cc \
        icp_v3.cc \
        $(IDENT_SOURCE) \
@@ -1835,7 +1855,7 @@ tests_test_http_range_SOURCES = \
        HttpRequest.cc \
        HttpRequestMethod.cc \
        HttpStatusLine.cc \
-       icmp.cc \
+       $(ICMPSOURCE) \
        icp_v2.cc \
        icp_v3.cc \
        $(IDENT_SOURCE) \
@@ -1990,7 +2010,7 @@ tests_testHttpRequest_SOURCES = \
        HttpMsg.cc \
        HttpReply.cc \
        HttpStatusLine.cc \
-       icmp.cc \
+       $(ICMPSOURCE) \
        icp_v2.cc \
        icp_v3.cc \
        $(IDENT_SOURCE) \
@@ -2075,6 +2095,24 @@ tests_testHttpRequest_DEPENDENCIES =  $(top_builddir)/lib/libmiscutil.a \
        @SQUID_CPPUNIT_LA@ \
        @ICAP_LIBS@
 
+## Tests of the ICMP base module.
+# Its used by pinger so SHOULD NOT require more dependancies! :-(
+tests_testICMP_SOURCES=\
+       ICMP.h \
+       icmp.cc \
+       tests/testICMP.h \
+       tests/testICMP.cc \
+       tests/testMain.cc \
+       SquidTime.h \
+       time.cc \
+       $(TESTSOURCES)
+tests_testICMP_LDFLAGS = $(LIBADD_DL)
+tests_testICMP_LDADD=\
+       @SQUID_CPPUNIT_LIBS@ \
+       @SQUID_CPPUNIT_LA@ \
+       -L../lib -lmiscutil
+tests_testICMP_DEPENDENCIES= @SQUID_CPPUNIT_LA@ \
+       $(top_builddir)/lib/libmiscutil.a
 
 # TODO:mime.cc drags in HttpReply.cc
 # delay pools need client_side_request.cc
@@ -2328,7 +2366,7 @@ tests_testURL_SOURCES = \
        HttpMsg.cc \
        HttpReply.cc \
        HttpStatusLine.cc \
-       icmp.cc \
+       $(ICMPSOURCE) \
        icp_v2.cc \
        icp_v3.cc \
        $(IDENT_SOURCE) \
index 84f162beda0ee636bd69d93dd8d40ad549697dc2..4a5bef1bb54fb3559a49ad0efdfe88c63425b14e 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: PeerSelectState.h,v 1.2 2006/08/21 00:50:41 robertc Exp $
+ * $Id: PeerSelectState.h,v 1.3 2007/12/14 23:11:45 amosjeffries Exp $
  *
  * AUTHOR: Robert Collins
  *
@@ -38,6 +38,7 @@
 
 #include "cbdata.h"
 #include "PingData.h"
+#include "IPAddress.h"
 
 class ps_state
 {
@@ -54,27 +55,22 @@ public:
     void *callback_data;
     FwdServer *servers;
     /*
-     * Why are these struct sockaddr_in instead of peer *?  Because a
+     * Why are these IPAddress instead of peer *?  Because a
      * peer structure can become invalid during the peer selection
      * phase, specifically after a reconfigure.  Thus we need to lookup
      * the peer * based on the address when we are finally ready to
      * reference the peer structure.
      */
 
-    struct sockaddr_in first_parent_miss;
+    IPAddress first_parent_miss;
 
-    struct sockaddr_in closest_parent_miss;
+    IPAddress closest_parent_miss;
     /*
-     * ->hit and ->secho can be peer* because they should only be
-     * accessed during the thread when they are set
+     * ->hit can be peer* because it should only be
+     * accessed during the thread when it is set
      */
     peer *hit;
     peer_t hit_type;
-#if ALLOW_SOURCE_PING
-
-    peer *secho;
-#endif
-
     ping_data ping;
     ACLChecklist *acl_checklist;
 private:
index 499521dcd623bdc7b797cdb44889a1d32db6aa53..0b88c955d155257361f37ef7515279fe057c75e1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: SquidTime.h,v 1.3 2007/10/31 04:52:16 amosjeffries Exp $
+ * $Id: SquidTime.h,v 1.4 2007/12/14 23:11:45 amosjeffries Exp $
  *
  * DEBUG: section 21    Time Functions
  * AUTHOR: Harvest Derived
 
 #include "squid.h"
 
+/* globals for accessing time */
+extern struct timeval current_time;
+extern double current_dtime;
+
 extern time_t squid_curtime;   /* 0 */
 
 time_t getCurrentTime(void);
index d763038dc5d71107ff5d122953b5c8d867f315b9..bc010f16874beab483dc5dfeb953aaf51bc217c4 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: access_log.cc,v 1.128 2007/08/13 18:25:14 hno Exp $
+ * $Id: access_log.cc,v 1.129 2007/12/14 23:11:45 amosjeffries Exp $
  *
  * DEBUG: section 46    Access Log
  * AUTHOR: Duane Wessels
@@ -545,20 +545,22 @@ accessLogCustom(AccessLogEntry * al, customlog * log)
             break;
 
         case LFT_CLIENT_IP_ADDRESS:
-            out = inet_ntoa(al->cache.caddr);
+            if (!out) {
+                out = al->cache.caddr.NtoA(tmp,1024);
+            }
             break;
 
         case LFT_CLIENT_FQDN:
             out = fqdncache_gethostbyaddr(al->cache.caddr, FQDN_LOOKUP_IF_MISS);
-
-            if (!out)
-                out = inet_ntoa(al->cache.caddr);
+            if (!out) {
+                out = al->cache.caddr.NtoA(tmp,1024);
+            }
 
             break;
 
         case LFT_CLIENT_PORT:
            if (al->request) {
-               outint = al->request->client_port;
+               outint = al->request->client_addr.GetPort();
                doint = 1;
            }
            break;
@@ -573,14 +575,15 @@ accessLogCustom(AccessLogEntry * al, customlog * log)
             /* case LFT_SERVER_PORT: */
 
         case LFT_LOCAL_IP:
-            if (al->request)
-                out = inet_ntoa(al->request->my_addr);
+            if (al->request) {
+                out = al->request->my_addr.NtoA(tmp,1024);
+            }
 
             break;
 
         case LFT_LOCAL_PORT:
             if (al->request) {
-                outint = al->request->my_port;
+                outint = al->request->my_addr.GetPort();
                 doint = 1;
             }
 
@@ -1269,12 +1272,15 @@ accessLogSquid(AccessLogEntry * al, Logfile * logfile)
 {
     const char *client = NULL;
     const char *user = NULL;
+    char buf[MAX_IPSTRLEN];
 
-    if (Config.onoff.log_fqdn)
+    if (Config.onoff.log_fqdn) {
         client = fqdncache_gethostbyaddr(al->cache.caddr, FQDN_LOOKUP_IF_MISS);
+    }
 
-    if (client == NULL)
-        client = inet_ntoa(al->cache.caddr);
+    if (client == NULL) {
+        client = al->cache.caddr.NtoA(buf,MAX_IPSTRLEN);
+    }
 
     user = accessLogFormatName(al->cache.authuser);
 
@@ -1342,12 +1348,15 @@ accessLogCommon(AccessLogEntry * al, Logfile * logfile)
 {
     const char *client = NULL;
     char *user1 = NULL, *user2 = NULL;
+    char buf[MAX_IPSTRLEN];
 
-    if (Config.onoff.log_fqdn)
+    if (Config.onoff.log_fqdn) {
         client = fqdncache_gethostbyaddr(al->cache.caddr, 0);
+    }
 
-    if (client == NULL)
-        client = inet_ntoa(al->cache.caddr);
+    if (client == NULL) {
+        client = al->cache.caddr.NtoA(buf,MAX_IPSTRLEN);
+    }
 
     user1 = accessLogFormatName(al->cache.authuser);
 
index a533f2dd112498927ecca745a07b17792e64ceb6..f123753a451dd0c1c813584c70a5f5432d404b74 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: asn.cc,v 1.115 2007/09/21 11:41:52 amosjeffries Exp $
+ * $Id: asn.cc,v 1.116 2007/12/14 23:11:45 amosjeffries Exp $
  *
  * DEBUG: section 53    AS Number handling
  * AUTHOR: Duane Wessels, Kostas Anagnostakis
 
 /* BEGIN of definitions for radix tree entries */
 
-/* int in memory with length */
-typedef u_char m_int[1 + sizeof(unsigned int)];
-#define store_m_int(i, m) \
-    (i = htonl(i), m[0] = sizeof(m_int), xmemcpy(m+1, &i, sizeof(unsigned int)))
-#define get_m_int(i, m) \
-    (xmemcpy(&i, m+1, sizeof(unsigned int)), ntohl(i))
+
+/* AYJ INET6 : Why are these objects being converted to raw u_char memory for use ? */
+
+/* 32/128 bits address in memory with length */
+typedef u_char m_ADDR[1 + sizeof(IPAddress)];
+#define store_m_ADDR(i, m) \
+    (m[0] = sizeof(IPAddress), xmemcpy(m+1, &i, sizeof(IPAddress)) )
+#define get_m_ADDR(i, m) \
+    xmemcpy(&i, m+1, sizeof(IPAddress))
 
 /* END of definitions for radix tree entries */
 
@@ -100,8 +103,8 @@ struct rtentry_t
 {
     struct squid_radix_node e_nodes[2];
     as_info *e_info;
-    m_int e_addr;
-    m_int e_mask;
+    m_ADDR e_addr;
+    m_ADDR e_mask;
 };
 
 static int asnAddNet(char *, int);
@@ -125,28 +128,26 @@ static OBJH asnStats;
 /* PUBLIC */
 
 int
-asnMatchIp(List<int> *data, struct IN_ADDR addr)
+asnMatchIp(List<int> *data, IPAddress &addr)
 {
-    unsigned long lh;
-
     struct squid_radix_node *rn;
     as_info *e;
-    m_int m_addr;
+    m_ADDR m_addr;
     List<int> *a = NULL;
     List<int> *b = NULL;
-    lh = ntohl(addr.s_addr);
-    debugs(53, 3, "asnMatchIp: Called for " << inet_ntoa(addr) << ".");
+
+    debugs(53, 3, "asnMatchIp: Called for " << addr );
 
     if (AS_tree_head == NULL)
         return 0;
 
-    if (addr.s_addr == no_addr.s_addr)
+    if (addr.IsNoAddr())
         return 0;
 
-    if (addr.s_addr == any_addr.s_addr)
+    if (addr.IsAnyAddr())
         return 0;
 
-    store_m_int(lh, m_addr);
+    store_m_ADDR(addr, m_addr);
 
     rn = squid_rn_match(m_addr, AS_tree_head);
 
@@ -389,13 +390,12 @@ asnAddNet(char *as_string, int as_number)
     rtentry_t *e;
 
     struct squid_radix_node *rn;
-    char dbg1[32], dbg2[32];
     List<int> **Tail = NULL;
     List<int> *q = NULL;
     as_info *asinfo = NULL;
 
-    struct IN_ADDR in_a, in_m;
-    long mask, addr;
+    IPAddress mask;
+    IPAddress addr;
     char *t;
     int bitl;
 
@@ -407,37 +407,28 @@ asnAddNet(char *as_string, int as_number)
     }
 
     *t = '\0';
-    addr = inet_addr(as_string);
+    addr = as_string;
     bitl = atoi(t + 1);
 
     if (bitl < 0)
         bitl = 0;
 
-    if (bitl > 32)
-        bitl = 32;
-
-    mask = bitl ? 0xfffffffful << (32 - bitl) : 0;
-
-    in_a.s_addr = addr;
+    // INET6 TODO : find a better way of identifying the base IPA family for mask than this.
+    t = strchr(as_string, '.');
 
-    in_m.s_addr = mask;
+    // generate Netbits Format Mask
+    mask.SetNoAddr();
+    mask.ApplyMask(bitl, (t!=NULL?AF_INET:AF_INET6) );
 
-    xstrncpy(dbg1, inet_ntoa(in_a), 32);
-
-    xstrncpy(dbg2, inet_ntoa(in_m), 32);
-
-    addr = ntohl(addr);
-
-    /*mask = ntohl(mask); */
-    debugs(53, 3, "asnAddNet: called for " << dbg1 << "/" << dbg2);
+    debugs(53, 3, "asnAddNet: called for " << addr << "/" << mask );
 
     e = (rtentry_t *)xmalloc(sizeof(rtentry_t));
 
     memset(e, '\0', sizeof(rtentry_t));
 
-    store_m_int(addr, e->e_addr);
+    store_m_ADDR(addr, e->e_addr);
 
-    store_m_int(mask, e->e_mask);
+    store_m_ADDR(mask, e->e_mask);
 
     rn = squid_rn_lookup(e->e_addr, e->e_mask, AS_tree_head);
 
@@ -445,7 +436,7 @@ asnAddNet(char *as_string, int as_number)
         asinfo = ((rtentry_t *) rn)->e_info;
 
         if (asinfo->as_number->find(as_number)) {
-            debugs(53, 3, "asnAddNet: Ignoring repeated network '" << dbg1 << "/" << bitl << "' for AS " << as_number);
+            debugs(53, 3, "asnAddNet: Ignoring repeated network '" << addr << "/" << bitl << "' for AS " << as_number);
         } else {
             debugs(53, 3, "asnAddNet: Warning: Found a network with multiple AS numbers!");
 
@@ -481,7 +472,6 @@ asnAddNet(char *as_string, int as_number)
 }
 
 static int
-
 destroyRadixNode(struct squid_radix_node *rn, void *w)
 {
 
@@ -519,39 +509,23 @@ destroyRadixNodeInfo(as_info * e_info)
 }
 
 static int
-mask_len(u_long mask)
-{
-    int len = 32;
-
-    if (mask == 0)
-        return 0;
-
-    while ((mask & 1) == 0) {
-        len--;
-        mask >>= 1;
-    }
-
-    return len;
-}
-
-static int
-
 printRadixNode(struct squid_radix_node *rn, void *_sentry)
 {
     StoreEntry *sentry = (StoreEntry *)_sentry;
     rtentry_t *e = (rtentry_t *) rn;
     List<int> *q;
     as_info *asinfo;
+    char buf[MAX_IPSTRLEN];
+    IPAddress addr;
+    IPAddress mask;
 
-    struct IN_ADDR addr;
-
-    struct IN_ADDR mask;
     assert(e);
     assert(e->e_info);
-    (void) get_m_int(addr.s_addr, e->e_addr);
-    (void) get_m_int(mask.s_addr, e->e_mask);
-    storeAppendPrintf(sentry, "%15s/%d\t",
-                      inet_ntoa(addr), mask_len(ntohl(mask.s_addr)));
+    (void) get_m_ADDR(addr, e->e_addr);
+    (void) get_m_ADDR(mask, e->e_mask);
+    storeAppendPrintf(sentry, "%s/%d\t",
+                      addr.NtoA(buf, MAX_IPSTRLEN),
+                      mask.GetCIDR() );
     asinfo = e->e_info;
     assert(asinfo->as_number);
 
@@ -571,7 +545,7 @@ ACLASN::~ACLASN()
 
 bool
 
-ACLASN::match(struct IN_ADDR toMatch)
+ACLASN::match(IPAddress toMatch)
 {
     return asnMatchIp(data, toMatch);
 }
@@ -616,7 +590,7 @@ ACLASN::parse()
     }
 }
 
-ACLData<struct IN_ADDR> *
+ACLData<IPAddress> *
 ACLASN::clone() const
 {
     if (data)
@@ -627,20 +601,20 @@ ACLASN::clone() const
 
 /* explicit template instantiation required for some systems */
 
-template class ACLStrategised<struct IN_ADDR>
+template class ACLStrategised<IPAddress>
 
 ;
 
 ACL::Prototype ACLASN::SourceRegistryProtoype(&ACLASN::SourceRegistryEntry_, "src_as");
 
-ACLStrategised<struct IN_ADDR> ACLASN::SourceRegistryEntry_(new ACLASN, ACLSourceASNStrategy::Instance(), "src_as");
+ACLStrategised<IPAddress> ACLASN::SourceRegistryEntry_(new ACLASN, ACLSourceASNStrategy::Instance(), "src_as");
 
 ACL::Prototype ACLASN::DestinationRegistryProtoype(&ACLASN::DestinationRegistryEntry_, "dst_as");
 
-ACLStrategised<struct IN_ADDR> ACLASN::DestinationRegistryEntry_(new ACLASN, ACLDestinationASNStrategy::Instance(), "dst_as");
+ACLStrategised<IPAddress> ACLASN::DestinationRegistryEntry_(new ACLASN, ACLDestinationASNStrategy::Instance(), "dst_as");
 
 int
-ACLSourceASNStrategy::match (ACLData<MatchType> * &data, ACLChecklist *checklist)
+ACLSourceASNStrategy::match (ACLData<IPAddress> * &data, ACLChecklist *checklist)
 {
     return data->match(checklist->src_addr);
 }
@@ -657,7 +631,7 @@ ACLSourceASNStrategy ACLSourceASNStrategy::Instance_;
 int
 ACLDestinationASNStrategy::match (ACLData<MatchType> * &data, ACLChecklist *checklist)
 {
-    const ipcache_addrs *ia = ipcache_gethostbyname(checklist->request->host, IP_LOOKUP_IF_MISS);
+    const ipcache_addrs *ia = ipcache_gethostbyname(checklist->request->GetHost(), IP_LOOKUP_IF_MISS);
 
     if (ia) {
         for (int k = 0; k < (int) ia->count; k++) {
@@ -666,13 +640,15 @@ ACLDestinationASNStrategy::match (ACLData<MatchType> * &data, ACLChecklist *chec
         }
 
         return 0;
+
     } else if (!checklist->request->flags.destinationIPLookedUp()) {
         /* No entry in cache, lookup not attempted */
         /* XXX FIXME: allow accessing the acl name here */
-        debugs(28, 3, "asnMatchAcl: Can't yet compare '" << "unknown" /*name*/ << "' ACL for '" << checklist->request->host << "'");
+        debugs(28, 3, "asnMatchAcl: Can't yet compare '" << "unknown" /*name*/ << "' ACL for '" << checklist->request->GetHost() << "'");
         checklist->changeState (DestinationIPLookup::Instance());
     } else {
-        return data->match(no_addr);
+        IPAddress noaddr; noaddr.SetNoAddr();
+        return data->match(noaddr);
     }
 
     return 0;
index 8e6a93148e2661c61434f61d11e48ef0b2ac9082..b01c4a69ed4ca4d9a50262988466b5235c995b17 100644 (file)
@@ -1,6 +1,5 @@
-
 /*
- * $Id: auth_digest.cc,v 1.59 2007/08/27 12:50:45 hno Exp $
+ * $Id: auth_digest.cc,v 1.60 2007/12/14 23:11:51 amosjeffries Exp $
  *
  * DEBUG: section 29    Authenticator
  * AUTHOR: Robert Collins
@@ -48,6 +47,7 @@
 #include "HttpRequest.h"
 #include "HttpReply.h"
 #include "wordlist.h"
+#include "SquidTime.h"
 /* TODO don't include this */
 #include "digestScheme.h"
 
@@ -647,17 +647,17 @@ AuthDigestUserRequest::authenticate(HttpRequest * request, ConnStateData::Pointe
             } else {
                 const char *useragent = request->header.getStr(HDR_USER_AGENT);
 
-                static struct IN_ADDR last_broken_addr;
+                static IPAddress last_broken_addr;
                 static int seen_broken_client = 0;
 
                 if (!seen_broken_client) {
-                    last_broken_addr = no_addr;
+                    last_broken_addr.SetNoAddr();
                     seen_broken_client = 1;
                 }
 
-                if (memcmp(&last_broken_addr, &request->client_addr, sizeof(last_broken_addr)) != 0) {
+                if (last_broken_addr != request->client_addr) {
                     debugs(29, 1, "\nDigest POST bug detected from " <<
-                           inet_ntoa(request->client_addr) << " using '" <<
+                           request->client_addr << " using '" <<
                            (useragent ? useragent : "-") <<
                            "'. Please upgrade browser. See Bug #630 for details.");
 
index 9f7ceaccdcf34bce3136faef9e66dec73f268f73..0f7431c5718213ebf44bdc0cd5e0380c66c8ea1a 100644 (file)
@@ -1,6 +1,5 @@
-
 /*
- * $Id: auth_negotiate.cc,v 1.27 2007/09/01 03:51:22 amosjeffries Exp $
+ * $Id: auth_negotiate.cc,v 1.28 2007/12/14 23:11:51 amosjeffries Exp $
  *
  * DEBUG: section 29    Negotiate Authenticator
  * AUTHOR: Robert Collins, Henrik Nordstrom, Francesco Chemolli
@@ -46,6 +45,7 @@
 #include "client_side.h"
 #include "HttpReply.h"
 #include "HttpRequest.h"
+#include "SquidTime.h"
 /* TODO remove this include */
 #include "negotiateScheme.h"
 #include "wordlist.h"
index 6e6d963bdf9c22f87d968490a938f49bc70d6b31..461c760df9dd5f2d9aad1da6582b3cd4e561c733 100644 (file)
@@ -1,6 +1,5 @@
-
 /*
- * $Id: auth_ntlm.cc,v 1.77 2007/09/01 03:51:23 amosjeffries Exp $
+ * $Id: auth_ntlm.cc,v 1.78 2007/12/14 23:11:51 amosjeffries Exp $
  *
  * DEBUG: section 29    NTLM Authenticator
  * AUTHOR: Robert Collins, Henrik Nordstrom, Francesco Chemolli
@@ -49,6 +48,7 @@
 /* TODO remove this include */
 #include "ntlmScheme.h"
 #include "wordlist.h"
+#include "SquidTime.h"
 
 static void
 authenticateNTLMReleaseServer(AuthUserRequest * auth_user_request);
index 0420478e07dffe51e5ca5b652bdd05aecbb8b526..0323d93d761de6c562d215f49751bad429dd00c1 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: cache_cf.cc,v 1.528 2007/11/15 23:33:05 wessels Exp $
+ * $Id: cache_cf.cc,v 1.529 2007/12/14 23:11:46 amosjeffries Exp $
  *
  * DEBUG: section 3     Configuration File Parsing
  * AUTHOR: Harvest Derived
@@ -127,11 +127,11 @@ static void dump_denyinfo(StoreEntry * entry, const char *name, acl_deny_info_li
 static void free_denyinfo(acl_deny_info_list ** var);
 
 #if USE_WCCPv2
-static void parse_sockaddr_in_list(sockaddr_in_list **);
-static void dump_sockaddr_in_list(StoreEntry *, const char *, const sockaddr_in_list *);
-static void free_sockaddr_in_list(sockaddr_in_list **);
+static void parse_IPAddress_list(IPAddress_list **);
+static void dump_IPAddress_list(StoreEntry *, const char *, const IPAddress_list *);
+static void free_IPAddress_list(IPAddress_list **);
 #if CURRENTLY_UNUSED
-static int check_null_sockaddr_in_list(const sockaddr_in_list *);
+static int check_null_IPAddress_list(const IPAddress_list *);
 #endif /* CURRENTLY_UNUSED */
 #endif /* USE_WCCPv2 */
 
@@ -637,9 +637,7 @@ configDoConfigure(void)
         https_port_list *s;
 
         for (s = Config.Sockaddr.https; s != NULL; s = (https_port_list *) s->http.next) {
-            debugs(3, 1, "Initializing https_port " <<
-                   inet_ntoa(s->http.s.sin_addr) << ":" <<
-                   ntohs(s->http.s.sin_port) << " SSL context");
+            debugs(3, 1, "Initializing https_port " << s->http.s << " SSL context");
 
             s->sslContext = sslCreateServerContext(s->cert, s->key, s->version, s->cipher, s->options, s->sslflags, s->clientca, s->cafile, s->capath, s->crlfile, s->dhfile, s->sslcontext);
         }
@@ -905,18 +903,15 @@ free_acl_access(acl_access ** head)
 }
 
 static void
-
-dump_address(StoreEntry * entry, const char *name, struct IN_ADDR addr)
+dump_address(StoreEntry * entry, const char *name, IPAddress &addr)
 {
-    storeAppendPrintf(entry, "%s %s\n", name, inet_ntoa(addr));
+    char buf[MAX_IPSTRLEN];
+    storeAppendPrintf(entry, "%s %s\n", name, addr.NtoA(buf,MAX_IPSTRLEN) );
 }
 
 static void
-
-parse_address(struct IN_ADDR *addr)
+parse_address(IPAddress *addr)
 {
-
-    const struct hostent *hp;
     char *token = strtok(NULL, w_space);
 
     if (!token) {
@@ -924,20 +919,24 @@ parse_address(struct IN_ADDR *addr)
         return;
     }
 
-    if (safe_inet_addr(token, addr) == 1)
-        (void) 0;
-    else if ((hp = gethostbyname(token)))      /* dont use ipcache */
-        *addr = inaddrFromHostent(hp);
+    if (!strcmp(token,"any_addr"))
+    {
+        addr->SetAnyAddr();
+       (void) 0;
+    }
+    else if ( (!strcmp(token,"no_addr")) || (!strcmp(token,"full_mask")) )
+    {
+        addr->SetNoAddr();
+       (void) 0;
+    }
     else
-        self_destruct();
+        *addr = token;
 }
 
 static void
-
-free_address(struct IN_ADDR *addr)
+free_address(IPAddress *addr)
 {
-
-    memset(addr, '\0', sizeof(struct IN_ADDR));
+    addr->SetEmpty();
 }
 
 CBDATA_TYPE(acl_address);
@@ -945,11 +944,12 @@ CBDATA_TYPE(acl_address);
 static void
 dump_acl_address(StoreEntry * entry, const char *name, acl_address * head)
 {
+    char buf[MAX_IPSTRLEN];
     acl_address *l;
 
     for (l = head; l; l = l->next) {
-        if (l->addr.s_addr != INADDR_ANY)
-            storeAppendPrintf(entry, "%s %s", name, inet_ntoa(l->addr));
+        if (!l->addr.IsAnyAddr())
+            storeAppendPrintf(entry, "%s %s", name, l->addr.NtoA(buf,MAX_IPSTRLEN));
         else
             storeAppendPrintf(entry, "%s autoselect", name);
 
@@ -1598,7 +1598,7 @@ parse_peer(peer ** head)
         self_destruct();
 
     p->host = xstrdup(token);
-
+                             
     p->name = xstrdup(token);
 
     if ((token = strtok(NULL, w_space)) == NULL)
@@ -1771,13 +1771,15 @@ parse_peer(peer ** head)
     }
 
 #endif
+
+    p->index =  ++Config.npeers;
+
+// FIXME INET6 : maybe sort peers so the SNMP indexing works better?
     while (*head != NULL)
         head = &(*head)->next;
 
     *head = p;
 
-    Config.npeers++;
-
     peerClearRR(p);
 }
 
@@ -2667,19 +2669,32 @@ parseNeighborType(const char *s)
 
 #if USE_WCCPv2
 void
-parse_sockaddr_in_list_token(sockaddr_in_list ** head, char *token)
+parse_IPAddress_list_token(IPAddress_list ** head, char *token)
 {
     char *t;
     char *host;
     char *tmp;
 
-    const struct hostent *hp;
+    IPAddress ipa;
     unsigned short port;
-    sockaddr_in_list *s;
+    IPAddress_list *s;
 
     host = NULL;
     port = 0;
 
+#if USE_IPV6
+    if (*token == '[') {
+        /* [host]:port */
+       host = token + 1;
+       t = strchr(host, ']');
+       if (!t)
+           self_destruct();
+       *t++ = '\0';
+       if (*t != ':')
+           self_destruct();
+       port = xatos(t + 1);
+    } else
+#endif
     if ((t = strchr(token, ':'))) {
         /* host:port */
         host = token;
@@ -2695,55 +2710,52 @@ parse_sockaddr_in_list_token(sockaddr_in_list ** head, char *token)
         port = 0;
     }
 
-    s = static_cast<sockaddr_in_list *>(xcalloc(1, sizeof(*s)));
-    s->s.sin_port = htons(port);
-
     if (NULL == host)
-        s->s.sin_addr = any_addr;
-    else if (1 == safe_inet_addr(host, &s->s.sin_addr))
+        ipa.SetAnyAddr();
+    else if ( ipa.GetHostByName(host) )        /* dont use ipcache. Accept either FQDN or IPA. */
         (void) 0;
-    else if ((hp = gethostbyname(host)))       /* dont use ipcache */
-        s->s.sin_addr = inaddrFromHostent(hp);
     else
         self_destruct();
 
+    /* port MUST be set after the IPA lookup/conversion is perofrmed. */
+    ipa.SetPort(port);
+
     while (*head)
         head = &(*head)->next;
 
+    s = static_cast<IPAddress_list *>(xcalloc(1, sizeof(*s)));
+    s->s = ipa;
+
     *head = s;
 }
 
 static void
-parse_sockaddr_in_list(sockaddr_in_list ** head)
+parse_IPAddress_list(IPAddress_list ** head)
 {
     char *token;
 
     while ((token = strtok(NULL, w_space))) {
-        parse_sockaddr_in_list_token(head, token);
+        parse_IPAddress_list_token(head, token);
     }
 }
 
 static void
-dump_sockaddr_in_list(StoreEntry * e, const char *n, const sockaddr_in_list * s)
+dump_IPAddress_list(StoreEntry * e, const char *n, const IPAddress_list * s)
 {
+    char ntoabuf[MAX_IPSTRLEN];
+
     while (s) {
-        storeAppendPrintf(e, "%s %s:%d\n",
+        storeAppendPrintf(e, "%s %s\n",
                           n,
-                          inet_ntoa(s->s.sin_addr),
-                          ntohs(s->s.sin_port));
+                          s->s.NtoA(ntoabuf,MAX_IPSTRLEN));
         s = s->next;
     }
 }
 
 static void
-free_sockaddr_in_list(sockaddr_in_list ** head)
+free_IPAddress_list(IPAddress_list ** head)
 {
-    sockaddr_in_list *s;
-
-    while ((s = *head) != NULL) {
-        *head = s->next;
-        xfree(s);
-    }
+    if(*head) delete *head; *head = NULL;
 }
 
 #if CURRENTLY_UNUSED
@@ -2751,7 +2763,7 @@ free_sockaddr_in_list(sockaddr_in_list ** head)
  * be used by icp_port and htcp_port
  */
 static int
-check_null_sockaddr_in_list(const sockaddr_in_list * s)
+check_null_IPAddress_list(const IPAdress_list * s)
 {
     return NULL == s;
 }
@@ -2763,38 +2775,68 @@ static void
 parse_http_port_specification(http_port_list * s, char *token)
 {
     char *host = NULL;
-
-    const struct hostent *hp;
     unsigned short port = 0;
-    char *t;
+    char *t = NULL;
+    char *junk = NULL;
 
     s->disable_pmtu_discovery = DISABLE_PMTU_OFF;
 
+#if USE_IPV6
+    if (*token == '[') {
+        /* [ipv6]:port */
+       host = token + 1;
+       t = strchr(host, ']');
+       if (!t) {
+            debugs(3, 0, "http(s)_port: missing ']' on IPv6 address: " << token);
+           self_destruct();
+        }
+       *t++ = '\0';
+       if (*t != ':') {
+            debugs(3, 0, "http(s)_port: missing Port in: " << token);
+           self_destruct();
+        }
+       port = xatos(t + 1);
+    } else
+#endif
     if ((t = strchr(token, ':'))) {
         /* host:port */
+        /* ipv4:port */
         host = token;
         *t = '\0';
         port = xatos(t + 1);
-    } else {
+
+    } else if ((port = strtol(token, &junk, 10)), !*junk) {
         /* port */
-        port = xatos(token);
+        debugs(3, 3, "http(s)_port: found Listen on Port: " << port);
+    } else {
+        debugs(3, 0, "http(s)_port: missing Port: " << token);
+        self_destruct();
     }
 
-    if (port == 0)
+    if (port == 0) {
+        debugs(3, 0, "http(s)_port: Port cannot be 0: " << token);
         self_destruct();
+    }
 
-    s->s.sin_port = htons(port);
-
-    if (NULL == host)
-        s->s.sin_addr = any_addr;
-    else if (1 == safe_inet_addr(host, &s->s.sin_addr))
-        (void) 0;
-    else if ((hp = gethostbyname(host))) {
+    if (NULL == host) {
+        s->s.SetAnyAddr();
+        s->s.SetPort(port);
+        debugs(3, 3, "http(s)_port: found Listen on wildcard address: " << s->s);
+    }
+    else if ( s->s = host ) { /* check/parse numeric IPA */
+        s->s.SetPort(port);
+        debugs(3, 3, "http(s)_port: Listen on Host/IP: " << host << " --> " << s->s);
+    }
+    else if ( s->s.GetHostByName(host) ) { /* check/parse for FQDN */
         /* dont use ipcache */
-        s->s.sin_addr = inaddrFromHostent(hp);
         s->defaultsite = xstrdup(host);
-    } else
+        s->s.SetPort(port);
+        debugs(3, 3, "http(s)_port: found Listen as Host " << s->defaultsite << " on IP: " << s->s);
+    }
+    else {
+        debugs(3, 0, "http(s)_port: failed to resolve Host/IP: " << host);
         self_destruct();
+    }
 }
 
 static void
@@ -2809,6 +2851,13 @@ parse_http_port_option(http_port_list * s, char *token)
         s->name = xstrdup(token + 5);
     } else if (strcmp(token, "transparent") == 0) {
         s->transparent = 1;
+#if USE_IPV6
+        /* INET6: until transparent REDIRECT works on IPv6 SOCKET, force wildcard to IPv4 */
+        if( !s->s.SetIPv4() ) {
+            debugs(3, 0, "http(s)_port: IPv6 addresses cannot be 'transparent' (protocol does not provide NAT)" << s->s );
+            self_destruct();
+        }
+#endif
     } else if (strcmp(token, "vhost") == 0) {
         s->vhost = 1;
         s->accel = 1;
@@ -2838,8 +2887,21 @@ parse_http_port_option(http_port_list * s, char *token)
     } else if (strcmp(token, "tproxy") == 0) {
         s->tproxy = 1;
         need_linux_tproxy = 1;
+#if USE_IPV6
+        /* INET6: until transparent REDIRECT works on IPv6 SOCKET, force wildcard to IPv4 */
+        if( s->s.IsIPv6() && !s->s.SetIPv4() ) {
+            debugs(3, 0, "http(s)_port: IPv6 addresses cannot be transparent (protocol does not provide NAT)" << s->s );
+            self_destruct();
+        }
+#endif
+#endif
+    } else if (strcmp(token, "ipv4") == 0) {
+#if USE_IPV6
+        if( !s->s.SetIPv4() ) {
+            debugs(3, 0, "http(s)_port: IPv6 addresses cannot be used a IPv4-Only." << s->s );
+            self_destruct();
+        }
 #endif
-
     } else {
         self_destruct();
     }
@@ -2905,10 +2967,11 @@ parse_http_port_list(http_port_list ** head)
 static void
 dump_generic_http_port(StoreEntry * e, const char *n, const http_port_list * s)
 {
-    storeAppendPrintf(e, "%s %s:%d",
+    char buf[MAX_IPSTRLEN];
+
+    storeAppendPrintf(e, "%s %s",
                       n,
-                      inet_ntoa(s->s.sin_addr),
-                      ntohs(s->s.sin_port));
+                      s->s.ToURL(buf,MAX_IPSTRLEN));
 
     if (s->defaultsite)
         storeAppendPrintf(e, " defaultsite=%s", s->defaultsite);
index dfce0774577834877fbe13608cb72c1b2ffbadd7..389f5107f3e84dfda910d7f4fb24a048725adf69 100644 (file)
@@ -38,7 +38,7 @@ peer_access           cache_peer acl
 refreshpattern
 removalpolicy
 size_t
-sockaddr_in_list
+IPAddress_list
 string
 string
 time_t
index 01070d1702231cd5aab8bd4d28ce56a8f1760150..aa85737ceed407c0baa9fcfaa08cfcbf55d5b4f6 100644 (file)
@@ -1,6 +1,6 @@
 
 #
-# $Id: cf.data.pre,v 1.488 2007/11/15 23:33:05 wessels Exp $
+# $Id: cf.data.pre,v 1.489 2007/12/14 23:11:46 amosjeffries Exp $
 #
 # SQUID Web Proxy Cache                http://www.squid-cache.org/
 # ----------------------------------------------------------
@@ -368,6 +368,11 @@ DOC_START
                        cached entry should be initiated without needing to
                        wait for a new reply. (default 0 for no grace period)
          protocol=2.5  Compatibility mode for Squid-2.5 external acl helpers
+         ipv4 / ipv6   IP-mode used to communicate to this helper.
+                       For compatability with older configurations and helpers
+                       'ipv4' is the default unless --with-localhost-ipv6 is used.
+                       --with-localhost-ipv6 changes the default to 'ipv6'.
+                       SPECIAL NOTE: these options override --with-localhost-ipv6
 
        FORMAT specifications
 
@@ -1110,6 +1115,28 @@ DOC_START
        incompatible with the use of server side persistent connections. To
        ensure correct results it is best to set server_persistent_connections
        to off when using this directive in such configurations.
+
+
+        IPv6 Magic:
+
+       Squid is built with a capability of bridging the IPv4 and IPv6 internets.
+       tcp_outgoing_address as exampled above breaks this bridging by forcing
+       all outbound traffic through a certain IPv4 which may be on the wrong
+       side of the IPv4/IPv6 boundary.
+
+       To operate with tcp_outgoing_address and keep the bridging benefits
+       an additional ACL needs to be used which ensures the IPv6-bound traffic
+       is never forced or permitted out the IPv4 interface.
+
+       acl to_ipv6 dst ipv6
+       tcp_outgoing_address 2002::c001 good_service_net to_ipv6
+       tcp_outgoing_address 10.0.0.2 good_service_net !to_ipv6
+
+       tcp_outgoing_address 2002::beef normal_service_net to_ipv6
+       tcp_outgoing_address 10.0.0.1 normal_service_net !to_ipv6
+
+       tcp_outgoing_address 2002::1 to_ipv6
+       tcp_outgoing_address 10.0.0.3 !to_ipv6
 DOC_END
 
 COMMENT_START
@@ -2343,12 +2370,23 @@ DOC_END
 NAME: pinger_program
 TYPE: string
 DEFAULT: @DEFAULT_PINGER@
-LOC: Config.Program.pinger
+LOC: Config.pinger.program
 IFDEF: USE_ICMP
 DOC_START
        Specify the location of the executable for the pinger process.
 DOC_END
 
+NAME: pinger_enable
+TYPE: onoff
+DEFAULT: on
+LOC: Config.pinger.enable
+IFDEF: USE_ICMP
+DOC_START
+       Control whether the pinger is active at run-time.
+       Enables turning ICMP pinger on and off with a simple squid -k reconfigure.
+DOC_END
+
+
 COMMENT_START
  OPTIONS FOR URL REWRITING
  -----------------------------------------------------------------------------
@@ -3603,7 +3641,7 @@ DEFAULT: 0.0.0.0
 IFDEF: USE_WCCP
 DOC_NONE
 NAME: wccp2_router
-TYPE: sockaddr_in_list
+TYPE: IPAddress_list
 LOC: Config.Wccp2.router
 DEFAULT: none
 IFDEF: USE_WCCPv2
@@ -5045,6 +5083,26 @@ DOC_START
        nameservers by setting this option to 'off'.
 DOC_END
 
+NAME: dns_v4_fallback
+TYPE: onoff
+DEFAULT: on
+LOC: Config.onoff.dns_require_A
+DOC_START
+       Standard practice with DNS is to lookup either A or AAAA records
+       and use the results if it succeeds. Only looking up the other if
+       the first attempt fails or otherwise produces no results.
+
+       That policy however will cause squid to produce error pages for some
+       servers that advertise AAAA but are unreachable over IPv6.
+
+       If this is ON  squid will always lookup both AAAA and A, using both.
+       If this is OFF squid will lookup AAAA and only try A if none found.
+
+       WARNING: There are some possibly unwanted side-effects with this on:
+               *) Doubles the load placed by squid on the DNS network.
+               *) May negatively impact connection delay times.
+DOC_END
+
 NAME: ipcache_size
 COMMENT: (number of entries)
 TYPE: int
@@ -5349,14 +5407,17 @@ DOC_END
 NAME: balance_on_multiple_ip
 TYPE: onoff
 LOC: Config.onoff.balance_on_multiple_ip
-DEFAULT: on
+DEFAULT: off
 DOC_START
+       Modern IP resolvers in squid sort lookup results by preferred access.
+       By default squid will use these IP in order and only rotates to
+       the next listed when the most preffered fails.
+
        Some load balancing servers based on round robin DNS have been
        found not to preserve user session state across requests
        to different IP addresses.
 
-       By default Squid rotates IP's per request. By disabling
-       this directive only connection failure triggers rotation.
+       Enabling this directive Squid rotates IP's per request.
 DOC_END
 
 NAME: pipeline_prefetch
index 5ce4ae61c00b21976840ba39972af3d83c7e8dfa..39df170a53908de6ffb723b3994fa720ea5b2492 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_db.cc,v 1.71 2007/09/21 11:41:52 amosjeffries Exp $
+ * $Id: client_db.cc,v 1.72 2007/12/14 23:11:46 amosjeffries Exp $
  *
  * DEBUG: section 0     Client Database
  * AUTHOR: Duane Wessels
@@ -42,7 +42,7 @@
 
 static hash_table *client_table = NULL;
 
-static ClientInfo *clientdbAdd(struct IN_ADDR addr);
+static ClientInfo *clientdbAdd(const IPAddress &addr);
 static FREE clientdbFreeItem;
 static void clientdbStartGC(void);
 static void clientdbScheduledGC(void *);
@@ -56,11 +56,12 @@ static int cleanup_removed;
 
 static ClientInfo *
 
-clientdbAdd(struct IN_ADDR addr)
+clientdbAdd(const IPAddress &addr)
 {
     ClientInfo *c;
+    char *buf = new char[MAX_IPSTRLEN];
     c = (ClientInfo *)memAllocate(MEM_CLIENT_INFO);
-    c->hash.key = xstrdup(inet_ntoa(addr));
+    c->hash.key = addr.NtoA(buf,MAX_IPSTRLEN);
     c->addr = addr;
     hash_join(client_table, &c->hash);
     statCounter.client_http.clients++;
@@ -94,15 +95,15 @@ clientdbRegisterWithCacheManager(CacheManager & manager)
 
 void
 
-clientdbUpdate(struct IN_ADDR addr, log_type ltype, protocol_t p, size_t size)
+clientdbUpdate(const IPAddress &addr, log_type ltype, protocol_t p, size_t size)
 {
-    char *key;
+    char key[MAX_IPSTRLEN];
     ClientInfo *c;
 
     if (!Config.onoff.client_db)
         return;
 
-    key = inet_ntoa(addr);
+    addr.NtoA(key,MAX_IPSTRLEN);
 
     c = (ClientInfo *) hash_lookup(client_table, key);
 
@@ -140,21 +141,21 @@ clientdbUpdate(struct IN_ADDR addr, log_type ltype, protocol_t p, size_t size)
  * -1.  To get the current value, simply call with delta = 0.
  */
 int
-
-clientdbEstablished(struct IN_ADDR addr, int delta)
+clientdbEstablished(const IPAddress &addr, int delta)
 {
-    char *key;
+    char key[MAX_IPSTRLEN];
     ClientInfo *c;
 
     if (!Config.onoff.client_db)
         return 0;
 
-    key = inet_ntoa(addr);
+    addr.NtoA(key,MAX_IPSTRLEN);
 
     c = (ClientInfo *) hash_lookup(client_table, key);
 
-    if (c == NULL)
+    if (c == NULL) {
         c = clientdbAdd(addr);
+    }
 
     if (c == NULL)
         debug_trap("clientdbUpdate: Failed to add entry");
@@ -167,9 +168,9 @@ clientdbEstablished(struct IN_ADDR addr, int delta)
 #define CUTOFF_SECONDS 3600
 int
 
-clientdbCutoffDenied(struct IN_ADDR addr)
+clientdbCutoffDenied(const IPAddress &addr)
 {
-    char *key;
+    char key[MAX_IPSTRLEN];
     int NR;
     int ND;
     double p;
@@ -178,7 +179,7 @@ clientdbCutoffDenied(struct IN_ADDR addr)
     if (!Config.onoff.client_db)
         return 0;
 
-    key = inet_ntoa(addr);
+    addr.NtoA(key,MAX_IPSTRLEN);
 
     c = (ClientInfo *) hash_lookup(client_table, key);
 
@@ -384,36 +385,35 @@ clientdbStartGC(void)
 
 #if SQUID_SNMP
 
-struct in_addr*
-client_entry(struct IN_ADDR *current)
+IPAddress *
+client_entry(IPAddress *current)
 {
     ClientInfo *c = NULL;
-    char *key;
+    char key[MAX_IPSTRLEN];
 
     if (current)
     {
-        key = inet_ntoa(*current);
+        current->NtoA(key,MAX_IPSTRLEN);
         hash_first(client_table);
-
         while ((c = (ClientInfo *) hash_next(client_table))) {
-            if (!strcmp(key, hashKeyStr(&c->hash)))
+         if (!strcmp(key, hashKeyStr(&c->hash)))
                 break;
         }
-
+       
         c = (ClientInfo *) hash_next(client_table);
     } else
     {
-        hash_first(client_table);
-        c = (ClientInfo *) hash_next(client_table);
+      hash_first(client_table);
+      c = (ClientInfo *) hash_next(client_table);
     }
 
     hash_last(client_table);
 
     if (c)
-        return (&c->addr);
+      return (&c->addr);
     else
-        return (NULL);
-
+      return (NULL);
+    
 }
 
 variable_list *
@@ -423,10 +423,12 @@ snmp_meshCtblFn(variable_list * Var, snint * ErrP)
     static char key[16];
     ClientInfo *c = NULL;
     int aggr = 0;
+
     log_type l;
     *ErrP = SNMP_ERR_NOERROR;
     debugs(49, 6, "snmp_meshCtblFn: Current : ");
     snmpDebugOid(6, Var->name, Var->name_length);
+    /* FIXME INET6 : This must implement the key for IPv6 address */
     snprintf(key, sizeof(key), "%d.%d.%d.%d", Var->name[LEN_SQ_NET + 3], Var->name[LEN_SQ_NET + 4],
              Var->name[LEN_SQ_NET + 5], Var->name[LEN_SQ_NET + 6]);
     debugs(49, 5, "snmp_meshCtblFn: [" << key << "] requested!");
@@ -440,12 +442,28 @@ snmp_meshCtblFn(variable_list * Var, snint * ErrP)
 
     switch (Var->name[LEN_SQ_NET + 2]) {
 
-    case MESH_CTBL_ADDR:
-        Answer = snmp_var_new_integer(Var->name, Var->name_length,
-                                      (snint) c->addr.s_addr,
-                                      SMI_IPADDRESS);
+    case MESH_CTBL_ADDR_TYPE:
+        {
+            int ival;
+            ival = c->addr.IsIPv4() ? INETADDRESSTYPE_IPV4 : INETADDRESSTYPE_IPV6 ;
+            Answer = snmp_var_new_integer(Var->name, Var->name_length,
+                                          ival, SMI_INTEGER);
+        }
         break;
 
+    case MESH_CTBL_ADDR:
+        {
+         Answer = snmp_var_new(Var->name, Var->name_length);
+            // InetAddress doesn't have its own ASN.1 type,
+            // like IpAddr does (SMI_IPADDRESS)
+            // See: rfc4001.txt
+         Answer->type = ASN_OCTET_STR;
+         char client[MAX_IPSTRLEN];
+         c->addr.NtoA(client,MAX_IPSTRLEN);
+         Answer->val_len = strlen(client);
+         Answer->val.string =  (u_char *) xstrdup(client);
+        }
+        break;
     case MESH_CTBL_HTBYTES:
         Answer = snmp_var_new_integer(Var->name, Var->name_length,
                                       (snint) c->Http.kbytes_out.kb,
index 06c9bb42ef0146334c8277a216f7fa8f110b49ac..8ee8a62c7914d41ad7a88a5569bc60f4eeeca6c8 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_side.cc,v 1.770 2007/12/04 03:35:52 hno Exp $
+ * $Id: client_side.cc,v 1.771 2007/12/14 23:11:46 amosjeffries Exp $
  *
  * DEBUG: section 33    Client-side Routines
  * AUTHOR: Duane Wessels
@@ -161,7 +161,7 @@ static void connNoteUseOfBuffer(ConnStateData* conn, size_t byteCount);
 static int connKeepReadingIncompleteRequest(ConnStateData::Pointer & conn);
 static void connCancelIncompleteRequests(ConnStateData::Pointer & conn);
 
-static ConnStateData *connStateCreate(struct sockaddr_in *peer, struct sockaddr_in *me, int fd, http_port_list *port);
+static ConnStateData *connStateCreate(const IPAddress &peer, const IPAddress &me, int fd, http_port_list *port);
 
 int
 ClientSocketContext::fd() const
@@ -492,7 +492,9 @@ ClientHttpRequest::logRequest()
         if (loggingEntry() && loggingEntry()->mem_obj)
             al.cache.objectSize = loggingEntry()->contentLen();
 
-        al.cache.caddr = getConn() != NULL ? getConn()->log_addr : no_addr;
+        al.cache.caddr.SetNoAddr();
+
+        if(getConn() != NULL) al.cache.caddr = getConn()->log_addr;
 
         al.cache.size = out.size;
 
@@ -529,7 +531,7 @@ ClientHttpRequest::logRequest()
             updateCounters();
 
             if (getConn() != NULL)
-                clientdbUpdate(getConn()->peer.sin_addr, logType, PROTO_HTTP, out.size);
+                clientdbUpdate(getConn()->peer, logType, PROTO_HTTP, out.size);
         }
 
         delete checklist;
@@ -604,7 +606,7 @@ ConnStateData::close()
     openReference = NULL;
     fd = -1;
     flags.readMoreRequests = false;
-    clientdbEstablished(peer.sin_addr, -1);    /* decrement */
+    clientdbEstablished(peer, -1);     /* decrement */
     assert(areAllContextsForThisConnection());
     freeAllContexts();
 
@@ -1720,6 +1722,7 @@ prepareAcceleratedURL(ConnStateData::Pointer & conn, ClientHttpRequest *http, ch
     int vhost = conn->port->vhost;
     int vport = conn->port->vport;
     char *host;
+    char ntoabuf[MAX_IPSTRLEN];
 
     http->flags.accel = 1;
 
@@ -1772,8 +1775,8 @@ prepareAcceleratedURL(ConnStateData::Pointer & conn, ClientHttpRequest *http, ch
         http->uri = (char *)xcalloc(url_sz, 1);
         snprintf(http->uri, url_sz, "%s://%s:%d%s",
                  http->getConn()->port->protocol,
-                 inet_ntoa(http->getConn()->me.sin_addr),
-                 ntohs(http->getConn()->me.sin_port), url);
+                 http->getConn()->me.NtoA(ntoabuf,MAX_IPSTRLEN),
+                 http->getConn()->me.GetPort(), url);
         debugs(33, 5, "ACCEL VPORT REWRITE: '" << http->uri << "'");
     } else if (vport > 0) {
         /* Put the local socket IP address as the hostname, but static port  */
@@ -1781,7 +1784,7 @@ prepareAcceleratedURL(ConnStateData::Pointer & conn, ClientHttpRequest *http, ch
         http->uri = (char *)xcalloc(url_sz, 1);
         snprintf(http->uri, url_sz, "%s://%s:%d%s",
                  http->getConn()->port->protocol,
-                 inet_ntoa(http->getConn()->me.sin_addr),
+                 http->getConn()->me.NtoA(ntoabuf,MAX_IPSTRLEN),
                  vport, url);
         debugs(33, 5, "ACCEL VPORT REWRITE: '" << http->uri << "'");
     }
@@ -1791,6 +1794,7 @@ static void
 prepareTransparentURL(ConnStateData::Pointer & conn, ClientHttpRequest *http, char *url, const char *req_hdr)
 {
     char *host;
+    char ntoabuf[MAX_IPSTRLEN];
 
     http->flags.transparent = 1;
 
@@ -1812,8 +1816,8 @@ prepareTransparentURL(ConnStateData::Pointer & conn, ClientHttpRequest *http, ch
         http->uri = (char *)xcalloc(url_sz, 1);
         snprintf(http->uri, url_sz, "%s://%s:%d%s",
                  http->getConn()->port->protocol,
-                 inet_ntoa(http->getConn()->me.sin_addr),
-                 ntohs(http->getConn()->me.sin_port), url);
+                 http->getConn()->me.NtoA(ntoabuf,MAX_IPSTRLEN),
+                 http->getConn()->me.GetPort(), url);
         debugs(33, 5, "TRANSPARENT REWRITE: '" << http->uri << "'");
     }
 }
@@ -2096,7 +2100,7 @@ connCancelIncompleteRequests(ConnStateData::Pointer & conn)
     assert (repContext);
     repContext->setReplyToError(ERR_TOO_BIG,
                                 HTTP_REQUEST_ENTITY_TOO_LARGE, METHOD_NONE, NULL,
-                                &conn->peer.sin_addr, NULL, NULL, NULL);
+                                conn->peer, NULL, NULL, NULL);
     context->registerWithConn();
     context->pullData();
 }
@@ -2147,8 +2151,7 @@ clientProcessRequest(ConnStateData::Pointer &conn, HttpParser *hp, ClientSocketC
         debugs(33, 1, "clientProcessRequest: Invalid Request");
         clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
         assert (repContext);
-        repContext->setReplyToError(ERR_INVALID_REQ, HTTP_BAD_REQUEST, method, NULL,
-                                    &conn->peer.sin_addr, NULL, conn->in.buf, NULL);
+        repContext->setReplyToError(ERR_INVALID_REQ, HTTP_BAD_REQUEST, method, NULL, conn->peer, NULL, conn->in.buf, NULL);
         assert(context->http->out.offset == 0);
         context->pullData();
         conn->flags.readMoreRequests = false;
@@ -2160,9 +2163,7 @@ clientProcessRequest(ConnStateData::Pointer &conn, HttpParser *hp, ClientSocketC
         debugs(33, 5, "Invalid URL: " << http->uri);
         clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
         assert (repContext);
-        repContext->setReplyToError(
-            ERR_INVALID_URL, HTTP_BAD_REQUEST, method, http->uri,
-            &conn->peer.sin_addr, NULL, NULL, NULL);
+        repContext->setReplyToError(ERR_INVALID_URL, HTTP_BAD_REQUEST, method, http->uri, conn->peer, NULL, NULL, NULL);
         assert(context->http->out.offset == 0);
         context->pullData();
         conn->flags.readMoreRequests = false;
@@ -2177,9 +2178,7 @@ clientProcessRequest(ConnStateData::Pointer &conn, HttpParser *hp, ClientSocketC
         debugs(33, 5, "Failed to parse request headers:\n" << HttpParserHdrBuf(hp));
         clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
         assert (repContext);
-        repContext->setReplyToError(
-            ERR_INVALID_URL, HTTP_BAD_REQUEST, method, http->uri,
-            &conn->peer.sin_addr, NULL, NULL, NULL);
+        repContext->setReplyToError(ERR_INVALID_URL, HTTP_BAD_REQUEST, method, http->uri, conn->peer, NULL, NULL, NULL);
         assert(context->http->out.offset == 0);
         context->pullData();
         conn->flags.readMoreRequests = false;
@@ -2196,12 +2195,11 @@ clientProcessRequest(ConnStateData::Pointer &conn, HttpParser *hp, ClientSocketC
 #endif
 
     if (internalCheck(request->urlpath.buf())) {
-        if (internalHostnameIs(request->host) &&
+        if (internalHostnameIs(request->GetHost()) &&
                 request->port == getMyPort()) {
             http->flags.internal = 1;
         } else if (Config.onoff.global_internal_static && internalStaticCheck(request->urlpath.buf())) {
-            xstrncpy(request->host, internalHostname(),
-                     SQUIDHOSTNAMELEN);
+            request->SetHost(internalHostname());
             request->port = getMyPort();
             http->flags.internal = 1;
         }
@@ -2214,10 +2212,8 @@ clientProcessRequest(ConnStateData::Pointer &conn, HttpParser *hp, ClientSocketC
 
     request->flags.internal = http->flags.internal;
     setLogUri (http, urlCanonicalClean(request));
-    request->client_addr = conn->peer.sin_addr;
-    request->client_port = ntohs(conn->peer.sin_port);
-    request->my_addr = conn->me.sin_addr;
-    request->my_port = ntohs(conn->me.sin_port);
+    request->client_addr = conn->peer;
+    request->my_addr = conn->me;
     request->http_ver = http_ver;
 
     if (!urlCheckRequest(request) ||
@@ -2227,7 +2223,7 @@ clientProcessRequest(ConnStateData::Pointer &conn, HttpParser *hp, ClientSocketC
         assert (repContext);
         repContext->setReplyToError(ERR_UNSUP_REQ,
                                     HTTP_NOT_IMPLEMENTED, request->method, NULL,
-                                    &conn->peer.sin_addr, request, NULL, NULL);
+                                    conn->peer, request, NULL, NULL);
         assert(context->http->out.offset == 0);
         context->pullData();
         conn->flags.readMoreRequests = false;
@@ -2241,7 +2237,7 @@ clientProcessRequest(ConnStateData::Pointer &conn, HttpParser *hp, ClientSocketC
         assert (repContext);
         repContext->setReplyToError(ERR_INVALID_REQ,
                                     HTTP_LENGTH_REQUIRED, request->method, NULL,
-                                    &conn->peer.sin_addr, request, NULL, NULL);
+                                    conn->peer, request, NULL, NULL);
         assert(context->http->out.offset == 0);
         context->pullData();
         conn->flags.readMoreRequests = false;
@@ -2277,7 +2273,7 @@ clientProcessRequest(ConnStateData::Pointer &conn, HttpParser *hp, ClientSocketC
             assert (repContext);
             repContext->setReplyToError(ERR_TOO_BIG,
                                         HTTP_REQUEST_ENTITY_TOO_LARGE, METHOD_NONE, NULL,
-                                        &conn->peer.sin_addr, http->request, NULL, NULL);
+                                        conn->peer, http->request, NULL, NULL);
             assert(context->http->out.offset == 0);
             context->pullData();
             goto finish;
@@ -2449,6 +2445,7 @@ clientReadRequest(int fd, char *buf, size_t size, comm_err_t flag, int xerrno,
     /* Bail out quickly on COMM_ERR_CLOSING - close handlers will tidy up */
 
     if (flag == COMM_ERR_CLOSING) {
+        debugs(33,5, HERE  << " FD " << fd << " closing Bailout.");
         return;
     }
 
@@ -2666,8 +2663,7 @@ static void
 clientLifetimeTimeout(int fd, void *data)
 {
     ClientHttpRequest *http = (ClientHttpRequest *)data;
-    debugs(33, 1, "WARNING: Closing client " << inet_ntoa(http->getConn()->peer.sin_addr) << 
-          " connection due to lifetime timeout");
+    debugs(33, 1, "WARNING: Closing client " << http->getConn()->peer << " connection due to lifetime timeout");
     debugs(33, 1, "\t" << http->uri);
     comm_close(fd);
 }
@@ -2690,13 +2686,13 @@ okToAccept()
 
 ConnStateData *
 
-connStateCreate(struct sockaddr_in *peer, struct sockaddr_in *me, int fd, http_port_list *port)
+connStateCreate(const IPAddress &peer, const IPAddress &me, int fd, http_port_list *port)
 {
     ConnStateData *result = new ConnStateData;
-    result->peer = *peer;
-    result->log_addr = peer->sin_addr;
-    result->log_addr.s_addr &= Config.Addrs.client_netmask.s_addr;
-    result->me = *me;
+    result->peer = peer;
+    result->log_addr = peer;
+    result->log_addr.ApplyMask(Config.Addrs.client_netmask.GetCIDR());
+    result->me = me;
     result->fd = fd;
     result->in.buf = (char *)memAllocBuf(CLIENT_REQ_BUF_SZ, &result->in.allocatedSize);
     result->port = cbdataReference(port);
@@ -2704,10 +2700,10 @@ connStateCreate(struct sockaddr_in *peer, struct sockaddr_in *me, int fd, http_p
     if (port->transparent)
     {
 
-        struct sockaddr_in dst;
+        IPAddress dst;
 
-        if (clientNatLookup(fd, *me, *peer, &dst) == 0) {
-            result->me = dst; /* XXX This should be moved to another field */
+        if (clientNatLookup(fd, me, peer, dst) == 0) {
+            result-> me = dst; /* XXX This should be moved to another field */
             result->transparent(true);
         }
     }
@@ -2761,11 +2757,11 @@ httpAccept(int sock, int newfd, ConnectionDetail *details,
 
     debugs(33, 4, "httpAccept: FD " << newfd << ": accepted");
     fd_note(newfd, "client http connect");
-    connState = connStateCreate(&details->peer, &details->me, newfd, s);
+    connState = connStateCreate(details->peer, details->me, newfd, s);
     comm_add_close_handler(newfd, connStateClosed, connState);
 
     if (Config.onoff.log_fqdn)
-        fqdncache_gethostbyaddr(details->peer.sin_addr, FQDN_LOOKUP_IF_MISS);
+        fqdncache_gethostbyaddr(details->peer, FQDN_LOOKUP_IF_MISS);
 
     commSetTimeout(newfd, Config.Timeout.request, requestTimeout, connState);
 
@@ -2773,25 +2769,22 @@ httpAccept(int sock, int newfd, ConnectionDetail *details,
 
     ACLChecklist identChecklist;
 
-    identChecklist.src_addr = details->peer.sin_addr;
-
-    identChecklist.my_addr = details->me.sin_addr;
+    identChecklist.src_addr = details->peer;
 
-    identChecklist.my_port = ntohs(details->me.sin_port);
+    identChecklist.my_addr = details->me;
 
     identChecklist.accessList = cbdataReference(Config.accessList.identLookup);
 
     /* cbdataReferenceDone() happens in either fastCheck() or ~ACLCheckList */
 
     if (identChecklist.fastCheck())
-        identStart(&details->me, &details->peer, clientIdentDone, connState);
-
+        identStart(details->me, details->peer, clientIdentDone, connState);
 
 #endif
 
     connState->readSomeData();
 
-    clientdbEstablished(details->peer.sin_addr, 1);
+    clientdbEstablished(details->peer, 1);
 
     incoming_sockets_accepted++;
 }
@@ -2958,11 +2951,11 @@ httpsAccept(int sock, int newfd, ConnectionDetail *details,
 
     debugs(33, 5, "httpsAccept: FD " << newfd << " accepted, starting SSL negotiation.");
     fd_note(newfd, "client https connect");
-    connState = connStateCreate(&details->peer, &details->me, newfd, (http_port_list *)s);
+    connState = connStateCreate(details->peer, details->me, newfd, (http_port_list *)s);
     comm_add_close_handler(newfd, connStateClosed, connState);
 
     if (Config.onoff.log_fqdn)
-        fqdncache_gethostbyaddr(details->peer.sin_addr, FQDN_LOOKUP_IF_MISS);
+        fqdncache_gethostbyaddr(details->peer, FQDN_LOOKUP_IF_MISS);
 
     commSetTimeout(newfd, Config.Timeout.request, requestTimeout, connState);
 
@@ -2970,24 +2963,22 @@ httpsAccept(int sock, int newfd, ConnectionDetail *details,
 
     ACLChecklist identChecklist;
 
-    identChecklist.src_addr = details->peer.sin_addr;
+    identChecklist.src_addr = details->peer;
 
-    identChecklist.my_addr = details->me.sin_addr;
-
-    identChecklist.my_port = ntohs(details->me.sin_port);
+    identChecklist.my_addr = details->me;
 
     identChecklist.accessList = cbdataReference(Config.accessList.identLookup);
 
     /* cbdataReferenceDone() happens in either fastCheck() or ~ACLCheckList */
 
     if (identChecklist.fastCheck())
-        identStart(&details->me, &details->peer, clientIdentDone, connState);
+        identStart(details->me, details->peer, clientIdentDone, connState);
 
 #endif
 
     commSetSelect(newfd, COMM_SELECT_READ, clientNegotiateSSL, connState, 0);
 
-    clientdbEstablished(details->peer.sin_addr, 1);
+    clientdbEstablished(details->peer, 1);
 
     incoming_sockets_accepted++;
 }
@@ -2998,8 +2989,8 @@ httpsAccept(int sock, int newfd, ConnectionDetail *details,
 static void
 clientHttpConnectionsOpen(void)
 {
-    http_port_list *s;
-    int fd;
+    http_port_list *s = NULL;
+    int fd = -1;
 
     for (s = Config.Sockaddr.http; s; s = s->next) {
         if (MAXHTTPPORTS == NHttpSockets) {
@@ -3011,8 +3002,8 @@ clientHttpConnectionsOpen(void)
         enter_suid();
         fd = comm_open(SOCK_STREAM,
                        IPPROTO_TCP,
-                       s->s.sin_addr,
-                       ntohs(s->s.sin_port), COMM_NONBLOCKING, "HTTP Socket");
+                       s->s,
+                       COMM_NONBLOCKING, "HTTP Socket");
         leave_suid();
 
         if (fd < 0)
@@ -3025,9 +3016,8 @@ clientHttpConnectionsOpen(void)
         debugs(1, 1, "Accepting " <<
                (s->transparent ? "transparently proxied" :
                        s->accel ? "accelerated" : "" ) 
-               << " HTTP connections at " 
-               << inet_ntoa(s->s.sin_addr) << ", port " 
-               << (int) ntohs(s->s.sin_port) << ", FD " << fd << "." );
+               << " HTTP connections at " << s->s
+               << ", FD " << fd << "." );
 
         HttpSockets[NHttpSockets++] = fd;
     }
@@ -3048,16 +3038,14 @@ clientHttpsConnectionsOpen(void)
         }
 
         if (s->sslContext == NULL) {
-            debugs(1, 1, "Can not accept HTTPS connections at " <<
-                   inet_ntoa(s->http.s.sin_addr) << ", port " <<
-                   (int) ntohs(s->http.s.sin_port));
+            debugs(1, 1, "Can not accept HTTPS connections at " << s->http.s);
         }
 
         enter_suid();
         fd = comm_open(SOCK_STREAM,
                        IPPROTO_TCP,
-                       s->http.s.sin_addr,
-                       ntohs(s->http.s.sin_port), COMM_NONBLOCKING, "HTTPS Socket");
+                       s->http.s,
+                       COMM_NONBLOCKING, "HTTPS Socket");
         leave_suid();
 
         if (fd < 0)
@@ -3067,9 +3055,7 @@ clientHttpsConnectionsOpen(void)
 
         comm_accept(fd, httpsAccept, s);
 
-        debugs(1, 1, "Accepting HTTPS connections at " <<
-               inet_ntoa(s->http.s.sin_addr) << ", port " <<
-               (int) ntohs(s->http.s.sin_port) << ", FD " << fd << ".");
+        debugs(1, 1, "Accepting HTTPS connections at " << s->http.s << ", FD " << fd << ".");
 
         HttpSockets[NHttpSockets++] = fd;
     }
index 5f40f37e1e23b972c1921798a6fbd2a8ca514c3d..8b7e73aa4672c834376d4049a974482daa7554d9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: client_side.h,v 1.26 2007/10/31 04:52:16 amosjeffries Exp $
+ * $Id: client_side.h,v 1.27 2007/12/14 23:11:46 amosjeffries Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -177,11 +177,11 @@ public:
      */
     ClientSocketContext::Pointer currentobject;
 
-    struct sockaddr_in peer;
+    IPAddress peer;
 
-    struct sockaddr_in me;
+    IPAddress me;
 
-    struct IN_ADDR log_addr;
+    IPAddress log_addr;
     char rfc931[USER_IDENT_SZ];
     int nrequests;
 
index 05ba37748e2fa5652eed56e135c56866c15dcc8f..8847abd6226b9b2e75b68578b0735d3b05e7807f 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_side_reply.cc,v 1.144 2007/11/27 09:36:07 amosjeffries Exp $
+ * $Id: client_side_reply.cc,v 1.145 2007/12/14 23:11:46 amosjeffries Exp $
  *
  * DEBUG: section 88    Client-side Reply Routines
  * AUTHOR: Robert Collins (Originally Duane Wessels in client_side.c)
@@ -60,9 +60,7 @@ CBDATA_CLASS_INIT(clientReplyContext);
 
 /* Local functions */
 extern "C" CSS clientReplyStatus;
-extern ErrorState *clientBuildError(err_type, http_status, char const *,
-
-                                        struct IN_ADDR *, HttpRequest *);
+extern ErrorState *clientBuildError(err_type, http_status, char const *, IPAddress &, HttpRequest *);
 
 /* privates */
 
@@ -91,7 +89,7 @@ clientReplyContext::clientReplyContext(ClientHttpRequest *clientContext) : http
 void
 clientReplyContext::setReplyToError(
     err_type err, http_status status, method_t method, char const *uri,
-    struct IN_ADDR *addr, HttpRequest * failedrequest, char *unparsedrequest,
+    IPAddress &addr, HttpRequest * failedrequest, char *unparsedrequest,
     AuthUserRequest * auth_user_request)
 {
     ErrorState *errstate =
@@ -690,9 +688,7 @@ clientReplyContext::processMiss()
      */
     if (http->flags.accel && r->flags.loopdetect) {
         http->al.http.code = HTTP_FORBIDDEN;
-        err =
-            clientBuildError(ERR_ACCESS_DENIED, HTTP_FORBIDDEN, NULL,
-                             &http->getConn()->peer.sin_addr, http->request);
+        err = clientBuildError(ERR_ACCESS_DENIED, HTTP_FORBIDDEN, NULL, http->getConn()->peer, http->request);
         createStoreEntry(r->method, request_flags());
         errorAppendEntry(http->storeEntry(), err);
         triggerInitialStoreRead();
@@ -738,8 +734,7 @@ clientReplyContext::processOnlyIfCachedMiss()
     debugs(88, 4, "clientProcessOnlyIfCachedMiss: '" <<
            RequestMethodStr[http->request->method] << " " << http->uri << "'");
     http->al.http.code = HTTP_GATEWAY_TIMEOUT;
-    err = clientBuildError(ERR_ONLY_IF_CACHED_MISS, HTTP_GATEWAY_TIMEOUT, NULL,
-                           &http->getConn()->peer.sin_addr, http->request);
+    err = clientBuildError(ERR_ONLY_IF_CACHED_MISS, HTTP_GATEWAY_TIMEOUT, NULL, http->getConn()->peer, http->request);
     removeClientStoreReference(&sc, http);
     startError(err);
 }
@@ -794,9 +789,7 @@ clientReplyContext::purgeFoundObject(StoreEntry *entry)
 
     if (EBIT_TEST(entry->flags, ENTRY_SPECIAL)) {
         http->logType = LOG_TCP_DENIED;
-        ErrorState *err =
-            clientBuildError(ERR_ACCESS_DENIED, HTTP_FORBIDDEN, NULL,
-                             &http->getConn()->peer.sin_addr, http->request);
+        ErrorState *err = clientBuildError(ERR_ACCESS_DENIED, HTTP_FORBIDDEN, NULL, http->getConn()->peer, http->request);
         startError(err);
         return;
     }
@@ -836,15 +829,13 @@ clientReplyContext::purgeRequest()
 
     if (!Config2.onoff.enable_purge) {
         http->logType = LOG_TCP_DENIED;
-        ErrorState *err =
-            clientBuildError(ERR_ACCESS_DENIED, HTTP_FORBIDDEN, NULL,
-                             &http->getConn()->peer.sin_addr, http->request);
+        ErrorState *err = clientBuildError(ERR_ACCESS_DENIED, HTTP_FORBIDDEN, NULL, http->getConn()->peer, http->request);
         startError(err);
         return;
     }
 
     /* Release both IP cache */
-    ipcacheInvalidate(http->request->host);
+    ipcacheInvalidate(http->request->GetHost());
 
     if (!http->flags.purging)
         purgeRequestFindObjectToPurge();
@@ -1054,7 +1045,7 @@ clientHttpRequestStatus(int fd, ClientHttpRequest const *http)
 #if SIZEOF_INT64_T == 4
     if (http->out.size > 0x7FFF0000) {
         debugs(88, 1, "WARNING: closing FD " << fd << " to prevent out.size counter overflow");
-        debugs(88, 1, "\tclient " << (inet_ntoa(http->getConn() != NULL ? http->getConn()->peer.sin_addr : no_addr)));
+        debugs(88, 1, "\tclient " << http->getConn()->peer);
         debugs(88, 1, "\treceived " << http->out.size << " bytes");
         debugs(88, 1, "\tURI " << http->log_uri);
         return 1;
@@ -1064,7 +1055,7 @@ clientHttpRequestStatus(int fd, ClientHttpRequest const *http)
 #if SIZEOF_INT64_T == 4
     if (http->out.offset > 0x7FFF0000) {
         debugs(88, 1, "WARNING: closing FD " << fd < " to prevent out.offset counter overflow");
-        debugs(88, 1, "\tclient " << (inet_ntoa(http->getConn() != NULL ? http->getConn()->peer.sin_addr : no_addr)));
+        debugs(88, 1, "\tclient " << http->getConn()->peer);
         debugs(88, 1, "\treceived " << http->out.size << " bytes, offset " << http->out.offset);
         debugs(88, 1, "\tURI " << http->log_uri);
         return 1;
@@ -1431,11 +1422,11 @@ clientReplyContext::identifyFoundObject(StoreEntry *newEntry)
 
 #if USE_DNSSERVERS
 
-        ipcacheInvalidate(r->host);
+        ipcacheInvalidate(r->GetHost());
 
 #else
 
-        ipcacheInvalidateNegative(r->host);
+        ipcacheInvalidateNegative(r->GetHost());
 
 #endif /* USE_DNSSERVERS */
 
@@ -1447,11 +1438,11 @@ clientReplyContext::identifyFoundObject(StoreEntry *newEntry)
 
 #if USE_DNSSERVERS
 
-        ipcacheInvalidate(r->host);
+        ipcacheInvalidate(r->GetHost());
 
 #else
 
-        ipcacheInvalidateNegative(r->host);
+        ipcacheInvalidateNegative(r->GetHost());
 
 #endif /* USE_DNSSERVERS */
 
@@ -1768,10 +1759,10 @@ clientReplyContext::processReplyAccess ()
     }
 
     if (http->isReplyBodyTooLarge(reply->content_length)) {
-        ErrorState *err =
-            clientBuildError(ERR_TOO_BIG, HTTP_FORBIDDEN, NULL,
-                             http->getConn() != NULL ? &http->getConn()->peer.sin_addr : &no_addr,
-                             http->request);
+        IPAddress tmp_noaddr; tmp_noaddr.SetNoAddr();
+        ErrorState *err = clientBuildError(ERR_TOO_BIG, HTTP_FORBIDDEN, NULL,
+                                           http->getConn() != NULL ? http->getConn()->peer : tmp_noaddr,
+                                           http->request);
         removeClientStoreReference(&sc, http);
         HTTPMSGUNLOCK(reply);
         startError(err);
@@ -1817,9 +1808,9 @@ clientReplyContext::processReplyAccessResult(bool accessAllowed)
         if (page_id == ERR_NONE)
             page_id = ERR_ACCESS_DENIED;
 
-        err =
-            clientBuildError(page_id, HTTP_FORBIDDEN, NULL,
-                             http->getConn() != NULL ? &http->getConn()->peer.sin_addr : &no_addr,
+        IPAddress tmp_noaddr; tmp_noaddr.SetNoAddr();
+        err = clientBuildError(page_id, HTTP_FORBIDDEN, NULL,
+                             http->getConn() != NULL ? http->getConn()->peer : tmp_noaddr,
                              http->request);
 
         removeClientStoreReference(&sc, http);
@@ -2078,11 +2069,10 @@ clientReplyContext::createStoreEntry(method_t m, request_flags flags)
 
 ErrorState *
 clientBuildError(err_type page_id, http_status status, char const *url,
-
-                 struct IN_ADDR * src_addr, HttpRequest * request)
+                 IPAddress &src_addr, HttpRequest * request)
 {
     ErrorState *err = errorCon(page_id, status, request);
-    err->src_addr = *src_addr;
+    err->src_addr = src_addr;
 
     if (url)
         err->url = xstrdup(url);
index de223bbc30e9790e7ed310bec3f247f47b8eadce..0b44eb42011b015703c1da0f31a843a1de4fe118 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_side_reply.h,v 1.17 2007/05/09 07:36:24 wessels Exp $
+ * $Id: client_side_reply.h,v 1.18 2007/12/14 23:11:46 amosjeffries Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -40,7 +40,7 @@
 #include "clientStream.h"
 #include "StoreClient.h"
 #include "client_side_request.h"
-
+#include "IPAddress.h"
 
 class ErrorState;
 
@@ -76,7 +76,7 @@ public:
     int storeOKTransferDone() const;
     int storeNotOKTransferDone() const;
 
-    void setReplyToError(err_type, http_status, method_t, char const *, struct IN_ADDR *, HttpRequest *, char *, AuthUserRequest *);
+    void setReplyToError(err_type, http_status, method_t, char const *, IPAddress &, HttpRequest *, char *, AuthUserRequest *);
     void createStoreEntry(method_t m, request_flags flags);
     void removeStoreReference(store_client ** scp, StoreEntry ** ep);
     void removeClientStoreReference(store_client **scp, ClientHttpRequest *http);
index f94e03ebebf27c2cdf776c0514b63f1892fc0fc9..81a5f9be313d92f241595dcb71f121a201ac7a7e 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_side_request.cc,v 1.96 2007/11/15 23:33:05 wessels Exp $
+ * $Id: client_side_request.cc,v 1.97 2007/12/14 23:11:46 amosjeffries Exp $
  * 
  * DEBUG: section 85    Client-side Request Routines
  * AUTHOR: Robert Collins (Originally Duane Wessels in client_side.c)
@@ -334,11 +334,11 @@ clientBeginRequest(method_t method, char const *url, CSCB * streamcallback,
     /* Internally created requests cannot have bodies today */
     request->content_length = 0;
 
-    request->client_addr = no_addr;
+    request->client_addr.SetNoAddr();
 
-    request->my_addr = no_addr;        /* undefined for internal requests */
+    request->my_addr.SetNoAddr();      /* undefined for internal requests */
 
-    request->my_port = 0;
+    request->my_addr.SetPort(0);
 
     request->http_ver = http_ver;
 
@@ -452,12 +452,15 @@ ClientRequestContext::clientAccessCheckDone(int answer)
         clientStreamNode *node = (clientStreamNode *)http->client_stream.tail->prev->data;
         clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
         assert (repContext);
+        IPAddress tmpnoaddr; tmpnoaddr.SetNoAddr();
         repContext->setReplyToError(page_id, status,
                                     http->request->method, NULL,
-                                    http->getConn() != NULL ? &http->getConn()->peer.sin_addr : &no_addr, http->request,
-                                    NULL, http->getConn() != NULL
-                                    && http->getConn()->auth_user_request ? http->getConn()->
-                                    auth_user_request : http->request->auth_user_request);
+                                    http->getConn() != NULL ? http->getConn()->peer : tmpnoaddr,
+                                    http->request,
+                                    NULL,
+                                    http->getConn() != NULL && http->getConn()->auth_user_request ?
+                                    http->getConn()->auth_user_request : http->request->auth_user_request);
+
         node = (clientStreamNode *)http->client_stream.tail->data;
         clientStreamRead(node, http, node->readBuffer);
         return;
@@ -808,9 +811,7 @@ ClientRequestContext::clientRedirectDone(char *result)
         new_request->http_ver = old_request->http_ver;
         new_request->header.append(&old_request->header);
         new_request->client_addr = old_request->client_addr;
-        new_request->client_port = old_request->client_port;
         new_request->my_addr = old_request->my_addr;
-        new_request->my_port = old_request->my_port;
         new_request->flags = old_request->flags;
         new_request->flags.redirected = 1;
 
@@ -1051,7 +1052,6 @@ ClientHttpRequest::doCallouts()
            ACLChecklist ch;
             ch.src_addr = request->client_addr;
             ch.my_addr = request->my_addr;
-            ch.my_port = request->my_port;
             ch.request = HTTPMSGLOCK(request);
            int tos = aclMapTOS(Config.accessList.clientside_tos, &ch);
            if (tos)
index 02157c538987b29b7093beee9fe69203d6049074..c2915271fdf2e5db392132bc9147669eacec1eb6 100644 (file)
@@ -1,5 +1,6 @@
+
 /*
- * $Id: comm.cc,v 1.438 2007/10/31 04:52:16 amosjeffries Exp $
+ * $Id: comm.cc,v 1.439 2007/12/14 23:11:46 amosjeffries Exp $
  *
  * DEBUG: section 5     Socket Functions
  * AUTHOR: Harvest Derived
@@ -45,6 +46,7 @@
 #include "MemBuf.h"
 #include "pconn.h"
 #include "SquidTime.h"
+#include "IPAddress.h"
 
 #if defined(_SQUID_CYGWIN_)
 #include <sys/ioctl.h>
@@ -229,13 +231,16 @@ public:
     void connect();
     void callCallback(comm_err_t status, int xerrno);
     void defaults();
+
+// defaults given by client
     char *host;
-    u_short port;
+    u_short default_port;
+    IPAddress default_addr;
+    // NP: CANNOT store the default addr:port together as it gets set/reset differently.
 
-    struct sockaddr_in S;
+    IPAddress S;
     CallBack<CNCB> callback;
 
-    struct IN_ADDR in_addr;
     int fd;
     int tries;
     int addrcount;
@@ -249,7 +254,7 @@ private:
 
 /* STATIC */
 
-static comm_err_t commBind(int s, struct IN_ADDR, u_short port);
+static comm_err_t commBind(int s, struct addrinfo &);
 static void commSetReuseAddr(int);
 static void commSetNoLinger(int);
 #ifdef TCP_NODELAY
@@ -595,10 +600,9 @@ comm_empty_os_read_buffers(int fd)
     /* prevent those nasty RST packets */
     char buf[SQUID_TCP_SO_RCVBUF];
 
-    if (fd_table[fd].flags.nonblocking == 1)
-        while (FD_READ_METHOD(fd, buf, SQUID_TCP_SO_RCVBUF) > 0)
-
-            ;
+    if (fd_table[fd].flags.nonblocking == 1) {
+        while (FD_READ_METHOD(fd, buf, SQUID_TCP_SO_RCVBUF) > 0) {};
+    }
 #endif
 }
 
@@ -713,17 +717,32 @@ fdc_open(int fd, unsigned int type, char const *desc)
  * synchronous wrapper around udp socket functions
  */
 int
-comm_udp_recvfrom(int fd, void *buf, size_t len, int flags,
-                  struct sockaddr *from, socklen_t *fromlen)
+comm_udp_recvfrom(int fd, void *buf, size_t len, int flags, IPAddress &from)
 {
     statCounter.syscalls.sock.recvfroms++;
-    return recvfrom(fd, buf, len, flags, from, fromlen);
+    int x = 0;
+    struct addrinfo *AI = NULL;
+
+    debugs(5,8, "comm_udp_recvfrom: FD " << fd << " from " << from);
+
+    assert( NULL == AI );
+
+    from.InitAddrInfo(AI);
+
+    x = recvfrom(fd, buf, len, flags, AI->ai_addr, &AI->ai_addrlen);
+
+    from = *AI;
+
+    from.FreeAddrInfo(AI);
+
+    return x;
 }
 
 int
 comm_udp_recv(int fd, void *buf, size_t len, int flags)
 {
-    return comm_udp_recvfrom(fd, buf, len, flags, NULL, 0);
+    IPAddress nul;
+    return comm_udp_recvfrom(fd, buf, len, flags, nul);
 }
 
 ssize_t
@@ -749,9 +768,8 @@ comm_has_incomplete_write(int fd)
 u_short
 comm_local_port(int fd)
 {
-
-    struct sockaddr_in addr;
-    socklen_t addr_len = 0;
+    IPAddress temp;
+    struct addrinfo *addr = NULL;
     fde *F = &fd_table[fd];
 
     /* If the fd is closed already, just return */
@@ -761,38 +779,42 @@ comm_local_port(int fd)
         return 0;
     }
 
-    if (F->local_port)
-        return F->local_port;
+    if (F->local_addr.GetPort())
+        return F->local_addr.GetPort();
 
-    addr_len = sizeof(addr);
+    temp.InitAddrInfo(addr);
 
-    if (getsockname(fd, (struct sockaddr *) &addr, &addr_len)) {
+    if (getsockname(fd, addr->ai_addr, &(addr->ai_addrlen)) ) {
         debugs(50, 1, "comm_local_port: Failed to retrieve TCP/UDP port number for socket: FD " << fd << ": " << xstrerror());
+        temp.FreeAddrInfo(addr);
         return 0;
     }
+    temp = *addr;
+
+    temp.FreeAddrInfo(addr);
+
+    F->local_addr.SetPort(temp.GetPort());
+
+    // grab default socket information for this address
+    temp.GetAddrInfo(addr);
+
+    F->sock_family = addr->ai_family;
+
+    temp.FreeAddrInfo(addr);
 
-    F->local_port = ntohs(addr.sin_port);
-    debugs(5, 6, "comm_local_port: FD " << fd << ": port " << F->local_port);
-    return F->local_port;
+    debugs(5, 6, "comm_local_port: FD " << fd << ": port " << F->local_addr.GetPort());
+    return F->local_addr.GetPort();
 }
 
 static comm_err_t
-commBind(int s, struct IN_ADDR in_addr, u_short port)
+commBind(int s, struct addrinfo &inaddr)
 {
-    struct sockaddr_in S;
-
-    memset(&S, '\0', sizeof(S));
-    S.sin_family = AF_INET;
-    S.sin_port = htons(port);
-    S.sin_addr = in_addr;
     statCounter.syscalls.sock.binds++;
 
-    if (bind(s, (struct sockaddr *) &S, sizeof(S)) == 0)
+    if (bind(s, inaddr.ai_addr, inaddr.ai_addrlen) == 0)
         return COMM_OK;
 
-    debugs(50, 0, "commBind: Cannot bind socket FD " << s << " to " <<
-           (S.sin_addr.s_addr == INADDR_ANY ? "*" : inet_ntoa(S.sin_addr)) <<
-           ":" << (int) port << ": " << xstrerror());
+    debugs(50, 0, "commBind: Cannot bind socket FD " << s << " to " << fd_table[s].local_addr << ": " << xstrerror());
 
     return COMM_ERROR;
 }
@@ -804,12 +826,11 @@ commBind(int s, struct IN_ADDR in_addr, u_short port)
 int
 comm_open(int sock_type,
           int proto,
-          struct IN_ADDR addr,
-          u_short port,
+          IPAddress &addr,
           int flags,
           const char *note)
 {
-    return comm_openex(sock_type, proto, addr, port, flags, 0, note);
+    return comm_openex(sock_type, proto, addr, flags, 0, note);
 }
 
 static bool
@@ -832,6 +853,17 @@ comm_set_tos(int fd, int tos)
 #endif
 }
 
+void
+comm_set_v6only(int fd, int tos)
+{
+#ifdef IPV6_V6ONLY
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &tos, sizeof(int)) < 0) {
+        debugs(50, 1, "comm_open: setsockopt(IPV6_V6ONLY) on FD " << fd << ": " << xstrerror());
+    }
+#else
+    debugs(50, 0, "WARNING: comm_open: setsockopt(IPV6_V6ONLY) not supported on this platform");
+#endif /* sockopt */
+}
 
 /**
  * Create a socket. Default is blocking, stream (TCP) socket.  IO_TYPE
@@ -840,21 +872,29 @@ comm_set_tos(int fd, int tos)
 int
 comm_openex(int sock_type,
             int proto,
-            struct IN_ADDR addr,
-            u_short port,
+            IPAddress &addr,
             int flags,
             unsigned char TOS,
             const char *note)
 {
     int new_socket;
-    int tos = 0;
     fde *F = NULL;
+    int tos = 0;
+    struct addrinfo *AI = NULL;
 
     PROF_start(comm_open);
     /* Create socket for accepting new connections. */
     statCounter.syscalls.sock.sockets++;
 
-    if ((new_socket = socket(AF_INET, sock_type, proto)) < 0)
+    /* Setup the socket addrinfo details for use */
+    addr.GetAddrInfo(AI);
+    AI->ai_socktype = sock_type;
+    AI->ai_protocol = proto;
+    AI->ai_flags = flags;
+
+    debugs(50, 3, "comm_openex: Attempt open socket for: " << addr );
+
+    if ((new_socket = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol)) < 0)
     {
         /* Increase the number of reserved fd's if calls to socket()
          * are failing because the open file table is full.  This
@@ -867,27 +907,33 @@ comm_openex(int sock_type,
             debugs(50, 0, "comm_open: socket failure: " << xstrerror());
         }
 
+        addr.FreeAddrInfo(AI);
+
         PROF_stop(comm_open);
         return -1;
     }
 
+    debugs(50, 3, "comm_openex: Opened socket FD " << new_socket << " : family=" << AI->ai_family << ", type=" << AI->ai_socktype << ", protocol=" << AI->ai_protocol );
+
     /* set TOS if needed */
-    if (TOS)
-    {
-#ifdef IP_TOS
+    if (TOS && comm_set_tos(new_socket, TOS) ) {
         tos = TOS;
+    }
 
-        if (setsockopt(new_socket, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(int)) < 0) {
-            debugs(50, 1, "comm_open: setsockopt(IP_TOS) on FD " << new_socket << ": " << xstrerror());
-        }
-
-#else
+#if IPV6_SPECIAL_SPLITSTACK
 
-        debugs(50, 0, "comm_open: setsockopt(IP_TOS) not supported on this platform");
+    if( addr.IsIPv6() )
+        comm_set_v6only(new_socket, tos);
 
 #endif
 
-    }
+#if IPV6_SPECIAL_V4MAPPED && defined(_SQUID_MSWIN_)
+
+    /* Windows Vista supports Dual-Sockets. BUT defaults them to V6ONLY. Turn it OFF. */
+    if( addr.IsIPv6() )
+        comm_set_v6only(new_socket, 0);
+
+#endif
 
     /* update fdstat */
     debugs(5, 5, "comm_open: FD " << new_socket << " is a new socket");
@@ -906,7 +952,9 @@ comm_openex(int sock_type,
 
     F->local_addr = addr;
 
-    F->tos = tos;
+    F->tos = TOS;
+
+    F->sock_family = AI->ai_family;
 
     if (!(flags & COMM_NOCLOEXEC))
         commSetCloseOnExec(new_socket);
@@ -914,7 +962,7 @@ comm_openex(int sock_type,
     if ((flags & COMM_REUSEADDR))
         commSetReuseAddr(new_socket);
 
-    if (port > (u_short) 0)
+    if (addr.GetPort() > (u_short) 0)
     {
 #ifdef _SQUID_MSWIN_
 
@@ -927,16 +975,17 @@ comm_openex(int sock_type,
             commSetReuseAddr(new_socket);
     }
 
-    if (addr.s_addr != no_addr.s_addr)
+    if (!addr.IsNoAddr())
     {
-        if (commBind(new_socket, addr, port) != COMM_OK) {
+        if (commBind(new_socket, *AI) != COMM_OK) {
             comm_close(new_socket);
+            addr.FreeAddrInfo(AI);
             return -1;
             PROF_stop(comm_open);
         }
     }
 
-    F->local_port = port;
+    addr.FreeAddrInfo(AI);
 
     if (flags & COMM_NONBLOCKING)
         if (commSetNonBlocking(new_socket) == COMM_ERROR)
@@ -982,7 +1031,7 @@ commConnectStart(int fd, const char *host, u_short port, CNCB * callback, void *
     cs = new ConnectStateData;
     cs->fd = fd;
     cs->host = xstrdup(host);
-    cs->port = port;
+    cs->default_port = port;
     cs->callback = CallBack<CNCB>(callback, data);
     comm_add_close_handler(fd, commConnectFree, cs);
     ipcache_nbgethostbyname(host, commConnectDnsHandle, cs);
@@ -1007,7 +1056,8 @@ commConnectDnsHandle(const ipcache_addrs * ia, void *data)
     }
 
     assert(ia->cur < ia->count);
-    cs->in_addr = ia->in_addrs[ia->cur];
+
+    cs->default_addr = ia->in_addrs[ia->cur];
 
     if (Config.onoff.balance_on_multiple_ip)
         ipcacheCycleAddr(cs->host, NULL);
@@ -1022,7 +1072,7 @@ commConnectDnsHandle(const ipcache_addrs * ia, void *data)
 void
 ConnectStateData::callCallback(comm_err_t status, int xerrno)
 {
-    debugs(5, 3, "commConnectCallback: FD " << fd << ", data " << callback.data);
+    debugs(5, 3, "commConnectCallback: FD " << fd << ", data " << callback.data << ", status " << status);
 
     comm_remove_close_handler(fd, commConnectFree, this);
     CallBack<CNCB> aCallback = callback;
@@ -1069,12 +1119,20 @@ copyFDFlags(int to, fde *F)
 int
 ConnectStateData::commResetFD()
 {
+    struct addrinfo *AI = NULL;
+    IPAddress nul;
+
     if (!cbdataReferenceValid(callback.data))
         return 0;
 
     statCounter.syscalls.sock.sockets++;
 
-    int fd2 = socket(AF_INET, SOCK_STREAM, 0);
+    /* setup a bare-bones addrinfo */
+    nul.GetAddrInfo(AI);
+
+    int fd2 = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol);
+
+    nul.FreeAddrInfo(AI);
 
     if (fd2 < 0) {
         debugs(5, 0, "commResetFD: socket: " << xstrerror());
@@ -1112,18 +1170,26 @@ ConnectStateData::commResetFD()
      * the original socket
      */
 
-    if (commBind(fd, F->local_addr, F->local_port) != COMM_OK) {
+    AI = NULL;
+    F->local_addr.GetAddrInfo(AI);
+
+    if (commBind(fd, *AI) != COMM_OK) {
         debugs(5, 0, "commResetFD: bind: " << xstrerror());
+        F->local_addr.FreeAddrInfo(AI);
         return 0;
     }
+    F->local_addr.FreeAddrInfo(AI);
 
-#ifdef IP_TOS
-    if (F->tos) {
-        if (setsockopt(fd, IPPROTO_IP, IP_TOS, (char *) &F->tos, sizeof(int)) < 0)
-            debugs(50, 1, "commResetFD: setsockopt(IP_TOS) on FD " << fd << ": " << xstrerror());
-    }
+    if (F->tos)
+        comm_set_tos(fd, F->tos);
+
+#if IPV6_SPECIAL_SPLITSTACK
+
+    if( F->local_addr.IsIPv6() )
+        comm_set_v6only(fd, F->tos);
 
 #endif
+
     copyFDFlags (fd, F);
 
     return 1;
@@ -1167,18 +1233,19 @@ ConnectStateData::Connect (int fd, void *me)
 void
 ConnectStateData::defaults()
 {
-    S.sin_family = AF_INET;
-    S.sin_addr = in_addr;
-    S.sin_port = htons(port);
+    S = default_addr;
+    S.SetPort(default_port);
 }
 
 void
 ConnectStateData::connect()
 {
-    if (S.sin_addr.s_addr == 0)
+    if (S.IsAnyAddr())
         defaults();
 
-    switch (comm_connect_addr(fd, &S)) {
+    debugs(5,5, "ConnectSateData::connect: to " << S);
+
+    switch (comm_connect_addr(fd, S) ) {
 
     case COMM_INPROGRESS:
         debugs(5, 5, "ConnectStateData::connect: FD " << fd << ": COMM_INPROGRESS");
@@ -1186,20 +1253,23 @@ ConnectStateData::connect()
         break;
 
     case COMM_OK:
-        ipcacheMarkGoodAddr(host, S.sin_addr);
+        debugs(5, 5, "ConnectStateData::connect: FD " << fd << ": COMM_OK - connected");
+        ipcacheMarkGoodAddr(host, S);
         callCallback(COMM_OK, 0);
         break;
 
     default:
+        debugs(5, 5, "ConnectStateData::connect: FD " << fd << ": * - try again");
         tries++;
-        ipcacheMarkBadAddr(host, S.sin_addr);
+        ipcacheMarkBadAddr(host, S);
 
         if (Config.onoff.test_reachability)
-            netdbDeleteAddrNetwork(S.sin_addr);
+            netdbDeleteAddrNetwork(S);
 
         if (commRetryConnect()) {
             eventAdd("commReconnect", commReconnect, this, this->addrcount == 1 ? 0.05 : 0.0, 0);
         } else {
+            debugs(5, 5, "ConnectStateData::connect: FD " << fd << ": * - ERR tried too many times already.");
             callCallback(COMM_ERR_CONNECT, errno);
         }
     }
@@ -1232,16 +1302,23 @@ commSetTimeout(int fd, int timeout, PF * handler, void *data)
 }
 
 int
-
-comm_connect_addr(int sock, const struct sockaddr_in *address)
+comm_connect_addr(int sock, const IPAddress &address)
 {
     comm_err_t status = COMM_OK;
     fde *F = &fd_table[sock];
-    int x;
+    int x = 0;
     int err = 0;
     socklen_t errlen;
-    assert(ntohs(address->sin_port) != 0);
+    struct addrinfo *AI = NULL;
     PROF_start(comm_connect_addr);
+
+    assert(address.GetPort() != 0);
+
+    debugs(5, 9, "comm_connect_addr: connecting socket " << sock << " to " << address << " (want family: " << F->sock_family <<
+                 ") Old-State=" << fdc_table[sock].active);
+
+    address.GetAddrInfo(AI, F->sock_family);
+
     /* Establish connection. */
     errno = 0;
 
@@ -1250,16 +1327,27 @@ comm_connect_addr(int sock, const struct sockaddr_in *address)
         F->flags.called_connect = 1;
         statCounter.syscalls.sock.connects++;
 
-        x = connect(sock, (struct sockaddr *) address, sizeof(*address));
+        x = connect(sock, AI->ai_addr, AI->ai_addrlen);
 
         if (x < 0)
-            debugs(5, 9, "connect FD " << sock << ": " << xstrerror());
+        {
+            debugs(5,5, "comm_connect_addr: sock=" << sock << ", addrinfo( " <<
+                         " flags=" << AI->ai_flags <<
+                         ", family=" << AI->ai_family <<
+                         ", socktype=" << AI->ai_socktype <<
+                         ", protocol=" << AI->ai_protocol <<
+                         ", &addr=" << AI->ai_addr <<
+                         ", addrlen=" << AI->ai_addrlen <<
+                         " )" );
+            debugs(5, 9, "connect FD " << sock << ": (" << x << ") " << xstrerror());
+            debugs(14,9, "connecting to: " << address );
+        }
     } else
     {
 #if defined(_SQUID_NEWSOS6_)
         /* Makoto MATSUSHITA <matusita@ics.es.osaka-u.ac.jp> */
 
-        connect(sock, (struct sockaddr *) address, sizeof(*address));
+        connect(sock, AI->ai_addr, AI->ai_addrlen);
 
         if (errno == EINVAL) {
             errlen = sizeof(err);
@@ -1292,6 +1380,20 @@ comm_connect_addr(int sock, const struct sockaddr_in *address)
 
     }
 
+#ifdef _SQUID_LINUX_
+    /* 2007-11-27:
+     * Linux Debian replaces our allocated AI pointer with garbage when 
+     * connect() fails. This leads to segmentation faults deallocating
+     * the system-allocated memory when we go to clean up our pointer.
+     * HACK: is to leak the memory returned since we can't deallocate.
+     */
+    if(errno != 0) {
+        AI = NULL;
+    }
+#endif
+
+    address.FreeAddrInfo(AI);
+
     PROF_stop(comm_connect_addr);
 
     if (errno == 0 || errno == EISCONN)
@@ -1299,15 +1401,31 @@ comm_connect_addr(int sock, const struct sockaddr_in *address)
     else if (ignoreErrno(errno))
         status = COMM_INPROGRESS;
     else
+#if USE_IPV6
+      if( address.IsIPv4() && F->sock_family == AF_INET6 ) {
+
+            /* failover to trying IPv4-only link if an IPv6 one fails */
+            /* to catch the edge case of apps listening on IPv4-localhost */
+        F->sock_family = AF_INET;
+        int res = comm_connect_addr(sock, address);
+
+           /* if that fails too, undo our temporary socktype hack so the repeat works properly. */
+        if(res == COMM_ERROR)
+             F->sock_family = AF_INET6;
+
+        return res;
+    }
+    else
+#endif
         return COMM_ERROR;
 
-    xstrncpy(F->ipaddr, inet_ntoa(address->sin_addr), 16);
+    address.NtoA(F->ipaddr, MAX_IPSTRLEN);
 
-    F->remote_port = ntohs(address->sin_port);
+    F->remote_port = address.GetPort(); /* remote_port is HS */
 
     if (status == COMM_OK)
     {
-        debugs(5, 10, "comm_connect_addr: FD " << sock << " connected to " << F->ipaddr << ":" << F->remote_port);
+        debugs(5, 10, "comm_connect_addr: FD " << sock << " connected to " << address);
     } else if (status == COMM_INPROGRESS)
     {
         debugs(5, 10, "comm_connect_addr: FD " << sock << " connection pending");
@@ -1324,9 +1442,13 @@ comm_old_accept(int fd, ConnectionDetail &details)
     PROF_start(comm_accept);
     statCounter.syscalls.sock.accepts++;
     int sock;
-    socklen_t Slen = sizeof(details.peer);
+    struct addrinfo *gai = NULL;
+    details.me.InitAddrInfo(gai);
+
+    if ((sock = accept(fd, gai->ai_addr, &gai->ai_addrlen)) < 0) {
+
+        details.me.FreeAddrInfo(gai);
 
-    if ((sock = accept(fd, (struct sockaddr *) &details.peer, &Slen)) < 0) {
         PROF_stop(comm_accept);
 
         if (ignoreErrno(errno))
@@ -1344,21 +1466,29 @@ comm_old_accept(int fd, ConnectionDetail &details)
         }
     }
 
-    Slen = sizeof(details.me);
-    memset(&details.me, '\0', Slen);
+    details.peer = *gai;
+
+    details.me.SetEmpty();
+    getsockname(sock, gai->ai_addr, &gai->ai_addrlen);
+    details.me = *gai;
 
-    getsockname(sock, (struct sockaddr *) &details.me, &Slen);
     commSetCloseOnExec(sock);
+
     /* fdstat update */
     fd_open(sock, FD_SOCKET, "HTTP Request");
     fdd_table[sock].close_file = NULL;
     fdd_table[sock].close_line = 0;
     fdc_table[sock].active = 1;
     fde *F = &fd_table[sock];
-    xstrncpy(F->ipaddr, inet_ntoa(details.peer.sin_addr), 16);
-    F->remote_port = htons(details.peer.sin_port);
-    F->local_port = htons(details.me.sin_port);
+    details.peer.NtoA(F->ipaddr,MAX_IPSTRLEN);
+    F->remote_port = details.peer.GetPort();
+    F->local_addr.SetPort(details.me.GetPort());
+    F->sock_family = gai->ai_family;
+
     commSetNonBlocking(sock);
+
+    details.me.FreeAddrInfo(gai);
+
     PROF_stop(comm_accept);
     return sock;
 }
@@ -1592,17 +1722,29 @@ _comm_close(int fd, char const *file, int line)
 /* Send a udp datagram to specified TO_ADDR. */
 int
 comm_udp_sendto(int fd,
-
-                const struct sockaddr_in *to_addr,
-                int addr_len,
+                const IPAddress &to_addr,
                 const void *buf,
                 int len)
 {
-    int x;
+    int x = 0;
+    struct addrinfo *AI = NULL;
+
     PROF_start(comm_udp_sendto);
     statCounter.syscalls.sock.sendtos++;
 
-    x = sendto(fd, buf, len, 0, (struct sockaddr *) to_addr, addr_len);
+    debugs(50, 3, "comm_udp_sendto: Attempt to send UDP packet to " << to_addr <<
+                  " using FD " << fd << " using Port " << comm_local_port(fd) );
+
+    /* BUG: something in the above macro appears to occasionally be setting AI to garbage. */
+    /* AYJ: 2007-08-27 : or was it because I wasn't then setting 'fd_table[fd].sock_family' to fill properly. */
+    assert( NULL == AI );
+
+    to_addr.GetAddrInfo(AI, fd_table[fd].sock_family);
+
+    x = sendto(fd, buf, len, 0, AI->ai_addr, AI->ai_addrlen);
+
+    to_addr.FreeAddrInfo(AI);
+
     PROF_stop(comm_udp_sendto);
 
     if (x >= 0)
@@ -1613,9 +1755,7 @@ comm_udp_sendto(int fd,
     if (ECONNREFUSED != errno)
 #endif
 
-        debugs(50, 1, "comm_udp_sendto: FD " << fd << ", " <<
-               inet_ntoa(to_addr->sin_addr) << ", port " <<
-               (int) htons(to_addr->sin_port) << ": " << xstrerror());
+        debugs(50, 1, "comm_udp_sendto: FD " << fd << ", (family=" << fd_table[fd].sock_family << ") " << to_addr << ": " << xstrerror());
 
     return COMM_ERROR;
 }
@@ -2508,9 +2648,7 @@ DeferredRead::markCancelled() {
     cancelled = true;
 }
 
-ConnectionDetail::ConnectionDetail() {
-    memset(&me, 0, sizeof(me));
-    memset(&peer, 0, sizeof(peer));
+ConnectionDetail::ConnectionDetail() : me(), peer() {
 }
 
 bool
index db8b62a9bb658f6850f18bd30c18e735b28f71c0..89ca9f09c7d52b779b1182ebc9c2dbf6d1ab8660 100644 (file)
@@ -6,6 +6,7 @@
 #include "CompletionDispatcher.h"
 #include "StoreIOBuffer.h"
 #include "Array.h"
+#include "IPAddress.h"
 
 #define COMMIO_FD_READCB(fd)    (&commfd_table[(fd)].readcb)
 #define COMMIO_FD_WRITECB(fd)   (&commfd_table[(fd)].writecb)
@@ -46,19 +47,19 @@ SQUIDCEXTERN void comm_lingering_close(int fd);
 #endif
 SQUIDCEXTERN void commConnectStart(int fd, const char *, u_short, CNCB *, void *);
 
-SQUIDCEXTERN int comm_connect_addr(int sock, const struct sockaddr_in *);
+SQUIDCEXTERN int comm_connect_addr(int sock, const IPAddress &addr);
 SQUIDCEXTERN void comm_init(void);
 SQUIDCEXTERN void comm_exit(void);
 
-SQUIDCEXTERN int comm_open(int, int, struct IN_ADDR, u_short port, int, const char *note);
+SQUIDCEXTERN int comm_open(int, int, IPAddress &, int, const char *note);
 
-SQUIDCEXTERN int comm_openex(int, int, struct IN_ADDR, u_short, int, unsigned char TOS, const char *);
+SQUIDCEXTERN int comm_openex(int, int, IPAddress &, int, unsigned char TOS, const char *);
 SQUIDCEXTERN u_short comm_local_port(int fd);
 SQUIDCEXTERN int comm_set_tos(int fd, int tos);
 
 SQUIDCEXTERN void commSetSelect(int, unsigned int, PF *, void *, time_t);
 
-SQUIDCEXTERN int comm_udp_sendto(int, const struct sockaddr_in *, int, const void *, int);
+SQUIDCEXTERN int comm_udp_sendto(int sock, const IPAddress &to, const void *buf, int buflen);
 extern void comm_write(int fd, const char *buf, int len, IOCB *callback, void *callback_data, FREE *func);
 SQUIDCEXTERN void comm_write_mbuf(int fd, MemBuf *mb, IOCB * handler, void *handler_data);
 SQUIDCEXTERN void commCallCloseHandlers(int fd);
@@ -86,9 +87,7 @@ extern bool comm_has_pending_read(int fd);
 extern void comm_read(int fd, char *buf, int len, IOCB *handler, void *data);
 extern void comm_read_cancel(int fd, IOCB *callback, void *data);
 extern void fdc_open(int fd, unsigned int type, char const *desc);
-extern int comm_udp_recvfrom(int fd, void *buf, size_t len, int flags,
-
-                                 struct sockaddr *from, socklen_t *fromlen);
+extern int comm_udp_recvfrom(int fd, void *buf, size_t len, int flags, IPAddress &from);
 extern int comm_udp_recv(int fd, void *buf, size_t len, int flags);
 extern ssize_t comm_udp_send(int s, const void *buf, size_t len, int flags);
 extern void commMarkHalfClosed(int);
index 64d90092e1a888f50589724a6a774942688ad792..ec4ddf842d897c5f05efb4d53f7748344ed9b3e9 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: comm_select.cc,v 1.81 2007/06/10 12:13:31 hno Exp $
+ * $Id: comm_select.cc,v 1.82 2007/12/14 23:11:46 amosjeffries Exp $
  *
  * DEBUG: section 5     Socket Functions
  *
@@ -227,7 +227,11 @@ comm_check_incoming_select_handlers(int nfds, int *fds)
 
     getCurrentTime();
 
+#if USE_POLL
+    statCounter.syscalls.polls++;
+#else
     statCounter.syscalls.selects++;
+#endif
 
     if (select(maxfd, &read_mask, &write_mask, NULL, &zero_tv) < 1)
         return incoming_sockets_accepted;
@@ -438,7 +442,11 @@ comm_select(int msec)
         for (;;) {
             poll_time.tv_sec = msec / 1000;
             poll_time.tv_usec = (msec % 1000) * 1000;
+#if USE_POLL
+            statCounter.syscalls.polls++;
+#else
             statCounter.syscalls.selects++;
+#endif
             num = select(maxfd, &readfds, &writefds, NULL, &poll_time);
             statCounter.select_loops++;
 
@@ -709,7 +717,11 @@ examine_select(fd_set * readfds, fd_set * writefds)
         else
             continue;
 
+#if USE_POLL
+        statCounter.syscalls.polls++;
+#else
         statCounter.syscalls.selects++;
+#endif
 
         errno = 0;
 
index c707ce80bbc78745a79e00a36c15063db584a20a..e14f25dc2231a980996d98a31a2423790cbe0dd4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: debug.cc,v 1.106 2007/12/04 15:20:22 rousskov Exp $
+ * $Id: debug.cc,v 1.107 2007/12/14 23:11:46 amosjeffries Exp $
  *
  * DEBUG: section 0     Debug Routines
  * AUTHOR: Harvest Derived
@@ -173,7 +173,7 @@ _db_print_file(const char *format, va_list args) {
 
     vfprintf(debug_log, format, args);
 
-    if (!Config.onoff.buffered_logs)
+//*AYJ:*/    if (!Config.onoff.buffered_logs)
         fflush(debug_log);
 }
 
index 50865647a2bffbbb991d2f468cda6a04eb436b79..9d9beb71fa7c27a81670edb3dc6126c26f2915dc 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: defines.h,v 1.122 2007/08/13 17:20:51 hno Exp $
+ * $Id: defines.h,v 1.123 2007/12/14 23:11:46 amosjeffries Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
 #define STORE_HDR_METASIZE (4*sizeof(time_t)+2*sizeof(u_short)+sizeof(uint64_t))
 #define STORE_HDR_METASIZE_OLD (4*sizeof(time_t)+2*sizeof(u_short)+sizeof(size_t))
 
-#define PINGER_PAYLOAD_SZ 8192
-
 #define COUNT_INTERVAL 60
 /*
  * keep 60 minutes' worth of per-minute readings (+ current reading)
index 7ac7af73add1e003165e9633025922286edfc4b6..5b3203d117870ce6fa8c62b34708ba63982908ba 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: delay_pools.cc,v 1.49 2007/11/13 23:25:34 rousskov Exp $
+ * $Id: delay_pools.cc,v 1.50 2007/12/14 23:11:46 amosjeffries Exp $
  *
  * DEBUG: section 77    Delay Pools
  * AUTHOR: Robert Collins <robertc@squid-cache.org>
@@ -62,6 +62,7 @@
 #include "DelayBucket.h"
 #include "DelayUser.h"
 #include "DelayTagged.h"
+#include "IPAddress.h"
 
 long DelayPools::MemoryUsed = 0;
 
@@ -152,7 +153,7 @@ protected:
 
     virtual char const *label() const = 0;
 
-    virtual unsigned int makeKey (struct IN_ADDR &src_addr) const = 0;
+    virtual unsigned int makeKey (IPAddress &src_addr) const = 0;
 
     DelaySpec spec;
 
@@ -182,7 +183,7 @@ public:
 protected:
     virtual char const *label() const {return "Individual";}
 
-    virtual unsigned int makeKey (struct IN_ADDR &src_addr) const;
+    virtual unsigned int makeKey (IPAddress &src_addr) const;
 
 };
 
@@ -196,7 +197,7 @@ public:
 protected:
     virtual char const *label() const {return "Network";}
 
-    virtual unsigned int makeKey (struct IN_ADDR &src_addr) const;
+    virtual unsigned int makeKey (IPAddress &src_addr) const;
 };
 
 /* don't use remote storage for these */
@@ -239,9 +240,9 @@ protected:
 
     virtual char const *label() const {return "Individual";}
 
-    virtual unsigned int makeKey (struct IN_ADDR &src_addr) const;
+    virtual unsigned int makeKey (IPAddress &src_addr) const;
 
-    unsigned char makeHostKey (struct IN_ADDR &src_addr) const;
+    unsigned char makeHostKey (IPAddress &src_addr) const;
 
     DelaySpec spec;
     VectorMap<unsigned char, ClassCBucket> buckets;
@@ -843,13 +844,17 @@ VectorPool::Id::bytesIn(int qty)
     theVector->buckets.values[theIndex].bytesIn (qty);
 }
 
-
 unsigned int
-IndividualPool::makeKey (struct IN_ADDR &src_addr) const
+IndividualPool::makeKey (IPAddress &src_addr) const
 {
-    unsigned int host;
-    host = ntohl(src_addr.s_addr) & 0xff;
-    return host;
+    /* FIXME INET6 : IPv6 requires a 64-128 bit result from this function */
+    if( !src_addr.IsIPv4() )
+        return 1;
+
+    /* Temporary bypass for IPv4-only */
+    struct in_addr host;
+    src_addr.GetInAddr(host);
+    return (ntohl(host.s_addr) & 0xff);
 }
 
 void *
@@ -867,11 +872,16 @@ ClassCNetPool::operator delete (void *address)
 }
 
 unsigned int
-ClassCNetPool::makeKey (struct IN_ADDR &src_addr) const
+ClassCNetPool::makeKey (IPAddress &src_addr) const
 {
-    unsigned int net;
-    net = (ntohl(src_addr.s_addr) >> 8) & 0xff;
-    return net;
+    /* FIXME INET6 : IPv6 requires a 64-128 bit result from this function */
+    if( !src_addr.IsIPv4() )
+        return 1;
+
+    /* Temporary bypass for IPv4-only */
+    struct in_addr net;
+    src_addr.GetInAddr(net);
+    return ( (ntohl(net.s_addr) >> 8) & 0xff);
 }
 
 
@@ -936,19 +946,29 @@ ClassCHostPool::keyAllocated (unsigned char const key) const
 }
 
 unsigned char
-ClassCHostPool::makeHostKey (struct IN_ADDR &src_addr) const
+ClassCHostPool::makeHostKey (IPAddress &src_addr) const
 {
-    unsigned int host;
-    host = ntohl(src_addr.s_addr) & 0xff;
-    return host;
+    /* FIXME INET6 : IPv6 requires a 64-128 bit result from this function */
+    if( !src_addr.IsIPv4() )
+        return 1;
+
+    /* Temporary bypass for IPv4-only */
+    struct in_addr host;
+    src_addr.GetInAddr(host);
+    return (ntohl(host.s_addr) & 0xff);
 }
 
 unsigned int
-ClassCHostPool::makeKey (struct IN_ADDR &src_addr) const
+ClassCHostPool::makeKey (IPAddress &src_addr) const
 {
-    unsigned int net;
-    net = (ntohl(src_addr.s_addr) >> 8) & 0xff;
-    return net;
+    /* FIXME INET6 : IPv6 requires a 64-128 bit result from this function */
+    if( !src_addr.IsIPv4() )
+        return 1;
+
+    /* Temporary bypass for IPv4-only */
+    struct in_addr net;
+    src_addr.GetInAddr(net);
+    return ( (ntohl(net.s_addr) >> 8) & 0xff);
 }
 
 DelayIdComposite::Pointer
index f927147477e65a3a4b283436ab8561c747c87c6f..7d16ac9c508100986f6d2be70aea3bf662b63ebb 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: dns_internal.cc,v 1.101 2007/06/23 21:08:39 hno Exp $
+ * $Id: dns_internal.cc,v 1.102 2007/12/14 23:11:46 amosjeffries Exp $
  *
  * DEBUG: section 78    DNS lookups; interacts with lib/rfc1035.c
  * AUTHOR: Duane Wessels
@@ -116,6 +116,7 @@ struct _idns_query
     idns_query *queue;
     unsigned short domain;
     unsigned short do_searchpath;
+    bool need_A;
 };
 
 struct _nsvc
@@ -131,8 +132,7 @@ struct _nsvc
 
 struct _ns
 {
-
-    struct sockaddr_in S;
+    IPAddress S;
     int nqueries;
     int nreplies;
     nsvc *vc;
@@ -176,7 +176,7 @@ static void idnsSendQuery(idns_query * q);
 static IOCB idnsReadVCHeader;
 static void idnsDoSendQueryVC(nsvc *vc);
 
-static int idnsFromKnownNameserver(struct sockaddr_in *from);
+static int idnsFromKnownNameserver(IPAddress const &from);
 static idns_query *idnsFindQuery(unsigned short id);
 static void idnsGrokReply(const char *buf, size_t sz);
 static PF idnsRead;
@@ -187,18 +187,17 @@ static void idnsRcodeCount(int, int);
 static void
 idnsAddNameserver(const char *buf)
 {
+    IPAddress A;
 
-    struct IN_ADDR A;
-
-    if (!safe_inet_addr(buf, &A)) {
+    if (!(A = buf)) {
         debugs(78, 0, "WARNING: rejecting '" << buf << "' as a name server, because it is not a numeric IP address");
         return;
     }
 
-    if (A.s_addr == 0) {
-        debugs(78, 0, "WARNING: Squid does not accept 0.0.0.0 in DNS server specifications.");
-        debugs(78, 0, "Will be using 127.0.0.1 instead, assuming you meant that DNS is running on the same machine");
-        safe_inet_addr("127.0.0.1", &A);
+    if (A.IsAnyAddr()) {
+        debugs(78, 0, "WARNING: Squid does not accept " << A << " in DNS server specifications.");
+        A = "127.0.0.1";
+        debugs(78, 0, "Will be using " << A << " instead, assuming you meant that DNS is running on the same machine");
     }
 
     if (nns == nns_alloc) {
@@ -220,10 +219,9 @@ idnsAddNameserver(const char *buf)
     }
 
     assert(nns < nns_alloc);
-    nameservers[nns].S.sin_family = AF_INET;
-    nameservers[nns].S.sin_port = htons(NS_DEFAULTPORT);
-    nameservers[nns].S.sin_addr.s_addr = A.s_addr;
-    debugs(78, 3, "idnsAddNameserver: Added nameserver #" << nns << ": " << inet_ntoa(nameservers[nns].S.sin_addr));
+    A.SetPort(NS_DEFAULTPORT);
+    nameservers[nns].S = A;
+    debugs(78, 3, "idnsAddNameserver: Added nameserver #" << nns << " (" << A << ")");
     nns++;
 }
 
@@ -567,6 +565,7 @@ idnsStats(StoreEntry * sentry)
     idns_query *q;
     int i;
     int j;
+    char buf[MAX_IPSTRLEN];
     storeAppendPrintf(sentry, "Internal DNS Statistics:\n");
     storeAppendPrintf(sentry, "\nThe Queue:\n");
     storeAppendPrintf(sentry, "                       DELAY SINCE\n");
@@ -582,12 +581,12 @@ idnsStats(StoreEntry * sentry)
     }
 
     storeAppendPrintf(sentry, "\nNameservers:\n");
-    storeAppendPrintf(sentry, "IP ADDRESS      # QUERIES # REPLIES\n");
-    storeAppendPrintf(sentry, "--------------- --------- ---------\n");
+    storeAppendPrintf(sentry, "IP ADDRESS                                     # QUERIES # REPLIES\n");
+    storeAppendPrintf(sentry, "---------------------------------------------- --------- ---------\n");
 
     for (i = 0; i < nns; i++) {
-        storeAppendPrintf(sentry, "%-15s %9d %9d\n",
-                          inet_ntoa(nameservers[i].S.sin_addr),
+        storeAppendPrintf(sentry, "%-45s %9d %9d\n",  /* Let's take the maximum: (15 IPv4/45 IPv6) */
+                          nameservers[i].S.NtoA(buf,MAX_IPSTRLEN),
                           nameservers[i].nqueries,
                           nameservers[i].nreplies);
     }
@@ -700,12 +699,14 @@ idnsVCClosed(int fd, void *data)
 static void
 idnsInitVC(int ns)
 {
+    char buf[MAX_IPSTRLEN];
+
     nsvc *vc = cbdataAlloc(nsvc);
     nameservers[ns].vc = vc;
 
-    struct IN_ADDR addr;
+    IPAddress addr;
 
-    if (Config.Addrs.udp_outgoing.s_addr != no_addr.s_addr)
+    if (!Config.Addrs.udp_outgoing.IsNoAddr())
         addr = Config.Addrs.udp_outgoing;
     else
         addr = Config.Addrs.udp_incoming;
@@ -717,7 +718,6 @@ idnsInitVC(int ns)
     vc->fd = comm_open(SOCK_STREAM,
                        IPPROTO_TCP,
                        addr,
-                       0,
                        COMM_NONBLOCKING,
                        "DNS TCP Socket");
 
@@ -728,7 +728,7 @@ idnsInitVC(int ns)
 
     vc->busy = 1;
 
-    commConnectStart(vc->fd, inet_ntoa(nameservers[ns].S.sin_addr), ntohs(nameservers[ns].S.sin_port), idnsInitVCConnected, vc);
+    commConnectStart(vc->fd, nameservers[ns].S.NtoA(buf,MAX_IPSTRLEN), nameservers[ns].S.GetPort(), idnsInitVCConnected, vc);
 }
 
 static void
@@ -757,12 +757,14 @@ idnsSendQuery(idns_query * q)
     int ns;
 
     if (DnsSocket < 0) {
-        debugs(78, 1, "idnsSendQuery: Can't send query, no DNS socket!");
+        debugs(78, 1, "WARNING: idnsSendQuery: Can't send query, no DNS socket!");
         return;
     }
 
-    /* XXX Select nameserver */
-    assert(nns > 0);
+    if (nns <= 0) {
+        debugs(78, 1, "WARNING: idnsSendQuery: Can't send query, no DNS nameservers known!");
+        return;
+    }
 
     assert(q->lru.next == NULL);
 
@@ -776,8 +778,7 @@ try_again:
         x = 0;
     } else
         x = comm_udp_sendto(DnsSocket,
-                            &nameservers[ns].S,
-                            sizeof(nameservers[ns].S),
+                            nameservers[ns].S,
                             q->buf,
                             q->sz);
 
@@ -801,17 +802,16 @@ try_again:
 }
 
 static int
-
-idnsFromKnownNameserver(struct sockaddr_in *from)
+idnsFromKnownNameserver(IPAddress const &from)
 {
     int i;
 
     for (i = 0; i < nns; i++)
     {
-        if (nameservers[i].S.sin_addr.s_addr != from->sin_addr.s_addr)
+        if (nameservers[i].S != from)
             continue;
 
-        if (nameservers[i].S.sin_port != from->sin_port)
+        if (nameservers[i].S.GetPort() != from.GetPort())
             continue;
 
         return i;
@@ -884,6 +884,16 @@ idnsCallback(idns_query *q, rfc1035_rr *answers, int n, const char *error)
     }
 }
 
+void
+idnsDropMessage(rfc1035_message *message, idns_query *q)
+{
+    rfc1035MessageDestroy(&message);
+    if (q->hash.key) {
+        hash_remove_link(idns_lookup_hash, &q->hash);
+        q->hash.key = NULL;
+    }
+}
+
 static void
 idnsGrokReply(const char *buf, size_t sz)
 {
@@ -891,34 +901,32 @@ idnsGrokReply(const char *buf, size_t sz)
     rfc1035_message *message = NULL;
     idns_query *q;
 
-    n = rfc1035MessageUnpack(buf,
-                             sz,
-                             &message);
+    n = rfc1035MessageUnpack(buf, sz, &message);
 
     if (message == NULL) {
         debugs(78, 1, "idnsGrokReply: Malformed DNS response");
         return;
     }
 
-    debugs(78, 3, "idnsGrokReply: ID 0x" << std::hex << message->id << ", " << std::dec << n << "answers");
+    debugs(78, 3, "idnsGrokReply: ID 0x" << std::hex << message->id << ", " << std::dec << n << " answers");
 
     q = idnsFindQuery(message->id);
 
     if (q == NULL) {
         debugs(78, 3, "idnsGrokReply: Late response");
-        rfc1035MessageDestroy(message);
+        rfc1035MessageDestroy(&message);
         return;
     }
 
     if (rfc1035QueryCompare(&q->query, message->query) != 0) {
         debugs(78, 3, "idnsGrokReply: Query mismatch (" << q->query.name << " != " << message->query->name << ")");
-        rfc1035MessageDestroy(message);
+        rfc1035MessageDestroy(&message);
         return;
     }
 
     if (message->tc) {
         dlinkDelete(&q->lru, &lru_list);
-        rfc1035MessageDestroy(message);
+        rfc1035MessageDestroy(&message);
 
         if (!q->need_vc) {
             q->need_vc = 1;
@@ -945,7 +953,8 @@ idnsGrokReply(const char *buf, size_t sz)
              * unable to process this query due to a problem with
              * the name server."
              */
-            rfc1035MessageDestroy(message);
+            debugs(78, 3, "idnsGrokReply: Query result: SERV_FAIL");
+            rfc1035MessageDestroy(&message);
             q->start_t = current_time;
             q->id = idnsQueryID();
             rfc1035SetQueryID(q->buf, q->id);
@@ -957,6 +966,8 @@ idnsGrokReply(const char *buf, size_t sz)
             assert(NULL == message->answer);
             strcpy(q->name, q->orig);
 
+            debugs(78, 3, "idnsGrokReply: Query result: NXDOMAIN - " << q->name );
+
             if (q->domain < npc) {
                 strcat(q->name, ".");
                 strcat(q->name, searchpath[q->domain].domain);
@@ -966,25 +977,60 @@ idnsGrokReply(const char *buf, size_t sz)
                 q->attempt++;
             }
 
-            rfc1035MessageDestroy(message);
-           if (q->hash.key) {
-               hash_remove_link(idns_lookup_hash, &q->hash);
-               q->hash.key = NULL;
-           }
+            idnsDropMessage(message, q);
+
             q->start_t = current_time;
             q->id = idnsQueryID();
             rfc1035SetQueryID(q->buf, q->id);
-            q->sz = rfc1035BuildAQuery(q->name, q->buf, sizeof(q->buf), q->id,
-                                       &q->query);
-
+#if USE_IPV6
+            if(q->query.qtype == RFC1035_TYPE_AAAA) {
+                debugs(78, 3, "idnsGrokReply: Trying AAAA Query for " << q->name);
+                q->sz = rfc3596BuildAAAAQuery(q->name, q->buf, sizeof(q->buf), q->id, &q->query);
+            }
+            else
+#endif
+            {
+                debugs(78, 3, "idnsGrokReply: Trying A Query for " << q->name);
+                q->sz = rfc3596BuildAQuery(q->name, q->buf, sizeof(q->buf), q->id, &q->query);
+            }
             idnsCacheQuery(q);
             idnsSendQuery(q);
             return;
         }
     }
 
+#if USE_IPV6
+    if(q->need_A && (Config.onoff.dns_require_A == 1 || n <= 0 ) )
+    {
+        /* ERROR or NO AAAA exist. Failover to A records. */
+        /* AYJ: Apparently its also a good idea to lookup and store the A records
+         *      just in case the AAAA are not available when we need them.
+         *      This could occur due to number of network failings beyond our control
+         *      thus the || above allowing the user to request always both.
+         */
+
+        if(n == 0)
+            debugs(78, 3, "idnsGrokReply: " << q->name << " has no AAAA records. Looking up A record instead.");
+        else if(q->need_A && n <= 0)
+            debugs(78, 3, "idnsGrokReply: " << q->name << " AAAA query failed. Trying A now instead.");
+        else // admin requested this.
+            debugs(78, 3, "idnsGrokReply: " << q->name << " AAAA query done. Configured to retrieve A now also.");
+
+        idnsDropMessage(message, q);
+
+        q->start_t = current_time;
+        q->id = idnsQueryID();
+        rfc1035SetQueryID(q->buf, q->id);
+        q->sz = rfc3596BuildAQuery(q->name, q->buf, sizeof(q->buf), q->id, &q->query);
+        q->need_A = false;
+        idnsCacheQuery(q);
+        idnsSendQuery(q);
+        return;
+    }
+#endif
+
     idnsCallback(q, message->answer, n, q->error);
-    rfc1035MessageDestroy(message);
+    rfc1035MessageDestroy(&message);
 
     cbdataFree(q);
 }
@@ -994,18 +1040,26 @@ idnsRead(int fd, void *data)
 {
     int *N = &incoming_sockets_accepted;
     int len;
-
-    struct sockaddr_in from;
-    socklen_t from_len;
     int max = INCOMING_DNS_MAX;
     static char rbuf[SQUID_UDP_SO_RCVBUF];
     int ns;
+    IPAddress from;
+
+    debugs(78, 1, "idnsRead: starting with FD " << fd);
+
+    /* BUG (UNRESOLVED)
+     *  two code lines after returning from comm_udprecvfrom()
+     *  something overwrites the memory behind the from parameter.
+     *  NO matter where in the stack declaration list above it is placed
+     *  The cause of this is still unknown, however copying the data appears
+     *  to allow it to be passed further without this erasure.
+     */
+    IPAddress bugbypass;
 
     while (max--) {
-        from_len = sizeof(from);
-        memset(&from, '\0', from_len);
+        len = comm_udp_recvfrom(fd, rbuf, SQUID_UDP_SO_RCVBUF, 0, bugbypass);
 
-        len = comm_udp_recvfrom(fd, rbuf, sizeof(rbuf), 0, (struct sockaddr *) &from, &from_len);
+        from = bugbypass; // BUG BYPASS. see notes above.
 
         if (len == 0)
             break;
@@ -1030,8 +1084,11 @@ idnsRead(int fd, void *data)
         fd_bytes(DnsSocket, len, FD_READ);
         assert(N);
         (*N)++;
-        debugs(78, 3, "idnsRead: FD " << fd << ": received " << len << " bytes from " << inet_ntoa(from.sin_addr) << ".");
-        ns = idnsFromKnownNameserver(&from);
+
+        debugs(78, 3, "idnsRead: FD " << fd << ": received " << len << " bytes from " << from);
+
+        /* BUG: see above. Its here that it becomes apparent that the content of bugbypass is gone. */
+        ns = idnsFromKnownNameserver(from);
 
         if (ns >= 0) {
             nameservers[ns].nreplies++;
@@ -1039,9 +1096,12 @@ idnsRead(int fd, void *data)
             static time_t last_warning = 0;
 
             if (squid_curtime - last_warning > 60) {
-                debugs(78, 1, "WARNING: Reply from unknown nameserver [" << inet_ntoa(from.sin_addr) << "]");
+                debugs(78, 1, "WARNING: Reply from unknown nameserver " << from);
                 last_warning = squid_curtime;
             }
+            else {
+                debugs(78, 1, "WARNING: Reply from unknown nameserver " << from << " (retrying..." <<  (squid_curtime-last_warning) << "<=60)" );
+            }
 
             continue;
         }
@@ -1118,7 +1178,7 @@ idnsReadVC(int fd, char *buf, size_t len, comm_err_t flag, int xerrno, void *dat
 
     debugs(78, 3, "idnsReadVC: FD " << fd << ": received " <<
            (int) vc->msg->contentSize() << " bytes via tcp from " <<
-           inet_ntoa(nameservers[vc->ns].S.sin_addr) << ".");
+           nameservers[vc->ns].S << ".");
 
     idnsGrokReply(vc->msg->buf, vc->msg->contentSize());
     vc->msg->clean();
@@ -1184,9 +1244,9 @@ idnsInit(void)
     if (DnsSocket < 0) {
         int port;
 
-        struct IN_ADDR addr;
+        IPAddress addr;
 
-        if (Config.Addrs.udp_outgoing.s_addr != no_addr.s_addr)
+        if (!Config.Addrs.udp_outgoing.IsNoAddr())
             addr = Config.Addrs.udp_outgoing;
         else
             addr = Config.Addrs.udp_incoming;
@@ -1194,10 +1254,11 @@ idnsInit(void)
         DnsSocket = comm_open(SOCK_DGRAM,
                               IPPROTO_UDP,
                               addr,
-                              0,
                               COMM_NONBLOCKING,
                               "DNS Socket");
 
+        debugs(78, 2, "idnsInit: attempt open DNS socket to: " << addr);
+
         if (DnsSocket < 0)
             fatal("Could not create a DNS socket");
 
@@ -1206,8 +1267,7 @@ idnsInit(void)
          */
         port = comm_local_port(DnsSocket);
 
-        debugs(78, 1, "DNS Socket created at " << inet_ntoa(addr) << ", port " <<
-               port << ", FD " << DnsSocket);
+        debugs(78, 1, "DNS Socket created at " << addr << ", FD " << DnsSocket);
     }
 
     assert(0 == nns);
@@ -1339,8 +1399,13 @@ idnsALookup(const char *name, IDNSCB * callback, void *data)
         debugs(78, 3, "idnsALookup: searchpath used for " << q->name);
     }
 
-    q->sz = rfc1035BuildAQuery(q->name, q->buf, sizeof(q->buf), q->id,
-                               &q->query);
+#if USE_IPV6
+    q->sz = rfc3596BuildAAAAQuery(q->name, q->buf, sizeof(q->buf), q->id, &q->query);    
+    q->need_A = true;
+#else
+    q->sz = rfc3596BuildAQuery(q->name, q->buf, sizeof(q->buf), q->id, &q->query);
+    q->need_A = false;
+#endif
 
     if (q->sz < 0) {
         /* problem with query data -- query not sent */
@@ -1364,18 +1429,34 @@ idnsALookup(const char *name, IDNSCB * callback, void *data)
 }
 
 void
-
-idnsPTRLookup(const struct IN_ADDR addr, IDNSCB * callback, void *data)
+idnsPTRLookup(const IPAddress &addr, IDNSCB * callback, void *data)
 {
     idns_query *q;
 
-    const char *ip = inet_ntoa(addr);
+    char ip[MAX_IPSTRLEN];
+
+    addr.NtoA(ip,MAX_IPSTRLEN);
 
     q = cbdataAlloc(idns_query);
 
     q->id = idnsQueryID();
 
-    q->sz = rfc1035BuildPTRQuery(addr, q->buf, sizeof(q->buf), q->id, &q->query);
+#if USE_IPV6
+    if( addr.IsIPv6() ) {
+        struct in6_addr addr6;
+        addr.GetInAddr(addr6);
+        q->sz = rfc3596BuildPTRQuery6(addr6, q->buf, sizeof(q->buf), q->id, &q->query);
+    }
+    else
+#endif
+    {
+        struct in_addr addr4;
+        addr.GetInAddr(addr4);
+        q->sz = rfc3596BuildPTRQuery4(addr4, q->buf, sizeof(q->buf), q->id, &q->query);
+    }
+
+    /* PTR does not do inbound A/AAAA */
+    q->need_A = false;
 
     if (q->sz < 0)
     {
index eb5deb4db46d6cb301c548b6d9df0c3b14d9c152..f5fd7f89816a59c4e2cbca7d8603accd4bd9dc2c 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: dnsserver.cc,v 1.72 2007/12/06 18:01:53 rousskov Exp $
+ * $Id: dnsserver.cc,v 1.73 2007/12/14 23:11:46 amosjeffries Exp $
  *
  * DEBUG: section 0     DNS Resolver
  * AUTHOR: Harvest Derived
 #endif
 
 #include "util.h"
-
-#if !defined(_SQUID_AIX_) && !defined(_SQUID_MSWIN_)
-extern int h_errno;
-#endif
+#include "IPAddress.h"
 
 #if LIBRESOLV_DNS_TTL_HACK
 extern int _dns_ttl_;          /* this is a really *dirty* hack - bne */
 #endif
 
-#ifdef _SQUID_NEXT_
-/* This is a really bloody hack. frank@langen.bull.de
- * Workaround bug in gethostbyname which sets h_errno wrong
- * WARNING: This hack queries only the resolver and not NetInfo or YP
+/*
+ * res_init() is a macro re-definition of __res_init on: Debian
  */
+#if !defined(HAVE_RES_INIT) && defined(HAVE___RES_INIT)
+#ifndef res_init
+#define res_init  __res_init
+#endif
+#define HAVE_RES_INIT   HAVE___RES_INIT
+#endif
 
-struct hostent *_res_gethostbyname(char *name);
-#define gethostbyname _res_gethostbyname
-#endif /* _SQUID_NEXT_ */
-
-static struct IN_ADDR no_addr;
-
-/* error messages from gethostbyname() */
-static char *
-my_h_msgs(int x)
-{
-    if (x == HOST_NOT_FOUND)
-        return (char *)"Host not found (authoritative)";
-    else if (x == TRY_AGAIN)
-        return (char *)"Host not found (non-authoritative)";
-    else if (x == NO_RECOVERY)
-        return (char *)"Non recoverable errors";
-    else if (x == NO_DATA || x == NO_ADDRESS)
-        return (char *)"Valid name, no data record of requested type";
-    else
-        return (char *)"Unknown DNS problem";
-}
 
 #define REQ_SZ 512
 
 static void
 lookup(const char *buf)
 {
-
-    const struct hostent *result = NULL;
-    int reverse = 0;
     int ttl = 0;
     int retry = 0;
-    int i;
-
-    struct IN_ADDR addr;
+    unsigned int i = 0;
+    IPAddress ipa;
+    char ntoabuf[MAX_IPSTRLEN];
+    struct addrinfo hints;
+    struct addrinfo *AI = NULL;
+    struct addrinfo *aiptr = NULL;
+    struct addrinfo *prev_addr = NULL;
+    int res = 0;
 
     if (0 == strcmp(buf, "$shutdown"))
         exit(0);
@@ -199,19 +181,19 @@ lookup(const char *buf)
         return;
     }
 
-    /* check if it's already an IP address in text form. */
+    /* setup 'hints' for the system lookup */
+    memset(&hints, '\0', sizeof(struct addrinfo));
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_flags = AI_CANONNAME;
+
     for (;;) {
-        if (safe_inet_addr(buf, &addr)) {
-            reverse = 1;
-            result = gethostbyaddr((char *) &addr.s_addr, 4, AF_INET);
-        } else {
-            result = gethostbyname(buf);
-        }
+        xfreeaddrinfo(AI);
+        AI = NULL;
 
-        if (NULL != result)
+        if( 0 == (res = xgetaddrinfo(buf,NULL,&hints,&AI)) )
             break;
 
-        if (h_errno != TRY_AGAIN)
+        if (res != EAI_AGAIN)
             break;
 
         if (++retry == 3)
@@ -220,147 +202,243 @@ lookup(const char *buf)
         sleep(1);
     }
 
-    if (NULL == result) {
-        if (h_errno == TRY_AGAIN) {
-            printf("$fail Name Server for domain '%s' is unavailable.\n", buf);
-        } else {
-            printf("$fail DNS Domain '%s' is invalid: %s.\n",
-                   buf, my_h_msgs(h_errno));
-        }
+    /* check if it's already an IP address in text form. */
+    ipa = buf;
+    if( ipa.IsAnyAddr() ) {
+        /* its a domain name. Use the forward-DNS lookup already done */
 
-        return;
+        if(res == 0) {
+#if LIBRESOLV_DNS_TTL_HACK
+            /* DNS TTL handling - bne@CareNet.hu
+             * for first try it's a dirty hack, by hacking getanswer
+             * to place the ttl in a global variable */
+            if (_dns_ttl_ > -1)
+                ttl = _dns_ttl_;
+#endif
+            printf("$addr %d", ttl);
+
+            i = 0;
+            aiptr = AI;
+            while(NULL != aiptr && 32 >= i) {
+                memset(ntoabuf, 0, MAX_IPSTRLEN);
+
+                /* getaddrinfo given a host has a nasty tendency to return duplicate addr's */
+                /* BUT sorted fortunately, so we can drop most of them easily */
+                if( prev_addr &&
+                   prev_addr->ai_family==aiptr->ai_family &&
+                   memcmp(aiptr->ai_addr, prev_addr->ai_addr, aiptr->ai_addrlen)==0
+                  ) {
+                    prev_addr = aiptr;
+                    aiptr = aiptr->ai_next;
+                    continue;
+                }
+                else {
+                    prev_addr = aiptr;
+                }
+
+                /* annoying inet_ntop breaks the nice code by requiring the in*_addr */
+                switch(aiptr->ai_family) {
+                case AF_INET:
+                    xinet_ntop(aiptr->ai_family, &((struct sockaddr_in*)aiptr->ai_addr)->sin_addr, ntoabuf, MAX_IPSTRLEN);
+                    break;
+#if USE_IPV6
+                case AF_INET6:
+                    xinet_ntop(aiptr->ai_family, &((struct sockaddr_in6*)aiptr->ai_addr)->sin6_addr, ntoabuf, MAX_IPSTRLEN);
+                    break;
+#endif
+                default:
+                    aiptr = aiptr->ai_next;
+                    continue;
+                }
+                printf(" %s", ntoabuf);
+                i++;
+                aiptr = aiptr->ai_next;
+            }
+
+            prev_addr=NULL;
+            printf("\n");
+        }
     }
+    else /* its an IPA in text form. perform rDNS */
+    {
+        /* You'd expect getaddrinfo given AI_CANONNAME would do a lookup on
+         * missing FQDN. But no, it only copies the input string to that
+         * position regardless of its content.
+         */
+        if(NULL != AI && NULL != AI->ai_addr) {
+            for(;;) {
+                if( 0 == (res = xgetnameinfo(AI->ai_addr, AI->ai_addrlen, ntoabuf, MAX_IPSTRLEN, NULL,0,0)) )
+                    break;
+
+                if (res != EAI_AGAIN)
+                    break;
+
+                if (++retry == 3)
+                    break;
+
+                sleep(1);
+            }
+        }
 
+        if(res == 0) {
 #if LIBRESOLV_DNS_TTL_HACK
-    /* DNS TTL handling - bne@CareNet.hu
-     * for first try it's a dirty hack, by hacking getanswer
-     * to place the ttl in a global variable */
-    if (_dns_ttl_ > -1)
-        ttl = _dns_ttl_;
-
+            /* DNS TTL handling - bne@CareNet.hu
+             * for first try it's a dirty hack, by hacking getanswer
+             * to place the ttl in a global variable */
+            if (_dns_ttl_ > -1)
+                ttl = _dns_ttl_;
 #endif
 
-    if (reverse) {
-        printf("$name %d %s\n", ttl, result->h_name);
-        return;
+            printf("$name %d %s\n", ttl, ntoabuf);
+        }
     }
 
-    printf("$addr %d", ttl);
+    switch(res) {
+        case 0:
+            /* no error. */
+            break;
 
-    for (i = 0; NULL != result->h_addr_list[i]; i++) {
-        if (32 == i)
+        case EAI_AGAIN:
+            printf("$fail Name Server for domain '%s' is unavailable.\n", buf);
             break;
 
-        xmemcpy(&addr, result->h_addr_list[i], sizeof(addr));
+        case EAI_FAIL:
+            printf("$fail DNS Domain/IP '%s' does not exist: %s.\n", buf, xgai_strerror(res));
+            break;
 
-        printf(" %s", inet_ntoa(addr));
+#if defined(EAI_NODATA) || defined(EAI_NONAME)
+#ifdef EAI_NODATA
+        /* deprecated. obsolete on some OS */
+        case EAI_NODATA:
+#endif
+#ifdef EAI_NONAME
+        case EAI_NONAME:
+#endif
+            printf("$fail DNS Domain/IP '%s' exists without any FQDN/IPs: %s.\n", buf, xgai_strerror(res));
+            break;
+#endif
+       default:
+            printf("$fail A system error occured looking up Domain/IP '%s': %s.\n", buf, xgai_strerror(res));
     }
 
-    printf("\n");
+    xfreeaddrinfo(AI);
 }
 
 static void
 usage(void)
 {
-    fprintf(stderr, "usage: dnsserver -Dhv -s nameserver\n"
-            "\t-D             Enable resolver RES_DEFNAMES and RES_DNSRCH options\n"
+    fprintf(stderr, "usage: dnsserver -hv -s nameserver\n"
             "\t-h             Help\n"
             "\t-v             Version\n"
             "\t-s nameserver  Specify alternate name server(s).  'nameserver'\n"
-            "\t               must be an IP address, -s option may be repeated\n");
+            "\t               must be an IPv4 address, -s option may be repeated\n"
+            );
 }
 
+#ifdef _SQUID_RES_NSADDR6_LARRAY
+#define _SQUID_RES_NSADDR6_LIST(i)     _SQUID_RES_NSADDR6_LARRAY[i].sin6_addr
+#endif
+#ifdef _SQUID_RES_NSADDR6_LPTR
+#define _SQUID_RES_NSADDR6_LIST(i)     _SQUID_RES_NSADDR6_LPTR[i]->sin6_addr
+#endif
+
 int
 main(int argc, char *argv[])
 {
     char request[512];
     char *t = NULL;
     int c;
+#if defined(_SQUID_FREEBSD_) && defined(_SQUID_RES_NSADDR6_COUNT)
+    /* Only seems to be valid on FreeBSD 5.5 where _res_ext was provided without an ns6addr counter! */
+    /* Gone again on FreeBSD 6.2 along with _res_ext itself in any form. */
+    int ns6count = 0;
+#endif
 #if HAVE_RES_INIT
 
+    IPAddress ipa;
     int opt_s = 0;
-#if HAVE_RES_NSADDR_LIST || HAVE_RES_NS_LIST
+#ifdef _SQUID_RES_NSADDR_LIST
 
     extern char *optarg;
 #endif
 #endif
 
-    safe_inet_addr("255.255.255.255", &no_addr);
-
 #if HAVE_RES_INIT
-
     res_init();
-#ifdef RES_DEFAULT
-
-    _res.options = RES_DEFAULT;
-#endif
-#ifdef RES_DEFNAMES
-
-    _res.options &= ~RES_DEFNAMES;
 #endif
-#ifdef RES_DNSRCH
 
-    _res.options &= ~RES_DNSRCH;
-#endif
+#if USE_IPV6
+    /* perform AAAA lookups *before* A lookups in IPv6 mode. */
+    _res.options |= RES_USE_INET6;
 #endif
 
     while ((c = getopt(argc, argv, "Dhs:v")) != -1) {
         switch (c) {
 
         case 'D':
-#ifdef RES_DEFNAMES
-
-            _res.options |= RES_DEFNAMES;
-#endif
-#ifdef RES_DNSRCH
-
-            _res.options |= RES_DNSRCH;
-#endif
-
+            fprintf(stderr, "-D is now default behaviour from this tool.\n");
             break;
 
         case 's':
-#if HAVE_RES_INIT
+#if HAVE_RES_INIT && (defined(_SQUID_RES_NSADDR_LIST) || defined(_SQUID_RES_NSADDR6_LIST))
 
             if (opt_s == 0) {
-                _res.nscount = 0;
-                /*
-                 * Setting RES_INIT here causes coredumps when -s is
-                 * used with -D option.  It looks to me like setting
-                 * RES_INIT is wrong.  The resolver code sets RES_INIT
-                 * after calling res_init().  When we change the _res
-                 * structure and set RES_INIT, some internal resolver
-                 * structures get confused.             -DW 2.1.p1
-                 */
-#if SEEMS_WRONG
-
-                _res.options |= RES_INIT;
+#if defined(_SQUID_RES_NSADDR_COUNT)
+                _SQUID_RES_NSADDR_COUNT = 0;
+                /* because I don't trust the nscount super-count entirely, make sure these are ALL invalid */
+                memset(_SQUID_RES_NSADDR_LIST, 0, sizeof(struct sockaddr_in)*MAXNS);
+#endif
+#if defined(_SQUID_RES_NSADDR6_COUNT)
+                _SQUID_RES_NSADDR6_COUNT = 0;
 #endif
-
                 opt_s = 1;
-            } else if (_res.nscount == MAXNS) {
-                fprintf(stderr, "Too many -s options, only %d are allowed\n",
-                        MAXNS);
-                break;
             }
 
-#if HAVE_RES_NSADDR_LIST
-            _res.nsaddr_list[_res.nscount] = _res.nsaddr_list[0];
-
-            safe_inet_addr(optarg, &_res.nsaddr_list[_res.nscount++].sin_addr);
-
-#elif HAVE_RES_NS_LIST
-
-            _res.ns_list[_res.nscount] = _res.ns_list[0];
-
-            safe_inet_addr(optarg, &_res.ns_list[_res.nscount++].addr.sin_addr);
-
-#else /* Unknown NS list format */
+/* AYJ:
+ *  I experimented with all the permutations of mixed/unmixed nscount/nscount6 IPv4/IPv6/Both/invalid
+ * 
+ *  I'm not sure if splitting them really helps.
+ *  I've seen no evidence of IPv4 resolver *ever* being used when some IPv6 are set (or not even)
+ *  BUT, have seen segfault when IPv4 is added to NSADDR6 list (_res._u._ext).
+ *  It also appears to not do ANY lookup when _res.nscount==0.
+ * 
+ *  BUT, even if _res.nsaddrs is memset to NULL, it resolves IFF IPv6 set in _ext.
+ * 
+ *  SO, am splittig the IPv4/v6 into the seperate _res fields
+ *      and making nscount a total of IPv4+IPv6 /w nscount6 the IPv6 sub-counter
+ *     ie. nscount = count(NSv4)+count(NSv6) & nscount6 = count(NSv6)
+ * 
+ * If ANYONE knows better please let us know.
+ * 
+ */
+            if( !(ipa = optarg) ) {
+                fprintf(stderr, "%s appears to be a bad nameserver FQDN/IP.\n",optarg);
+            }
+            else if( ipa.IsIPv4() ) {
+                if (_SQUID_RES_NSADDR_COUNT == MAXNS) {
+                    fprintf(stderr, "Too many -s options, only %d are allowed\n", MAXNS);
+                    break;
+                }
+                _SQUID_RES_NSADDR_LIST[_SQUID_RES_NSADDR_COUNT] = _SQUID_RES_NSADDR_LIST[0];
+                ipa.GetInAddr(_SQUID_RES_NSADDR_LIST[_SQUID_RES_NSADDR_COUNT++].sin_addr);
+            }
+            else if( ipa.IsIPv6() ) {
+#if USE_IPV6 && defined(_SQUID_RES_NSADDR6_LIST)
 
-            fprintf(stderr, "-s is not supported on this resolver\n");
+                /* because things NEVER seem to resolve in tests without _res.nscount being a total. */
+                if (_SQUID_RES_NSADDR_COUNT == MAXNS) {
+                    fprintf(stderr, "Too many -s options, only %d are allowed\n", MAXNS);
+                    break;
+                }
+                _SQUID_RES_NSADDR_COUNT++;
 
+                ipa.GetInAddr(_SQUID_RES_NSADDR6_LIST(_SQUID_RES_NSADDR6_COUNT++));
+#else
+                fprintf(stderr, "IPv6 nameservers not supported on this resolver\n");
 #endif
-#else /* !HAVE_RES_INIT */
+            }
+
+#else /* !HAVE_RES_INIT || !defined(_SQUID_RES_NSADDR_LIST) */
 
             fprintf(stderr, "-s is not supported on this resolver\n");
 
index 22d07f3e0dff9b9f16571ed5069a8a14e0acea49..1f2da04f4f95e080e660e58aca8f48777eb62a5f 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: errorpage.cc,v 1.227 2007/05/29 13:31:39 amosjeffries Exp $
+ * $Id: errorpage.cc,v 1.228 2007/12/14 23:11:46 amosjeffries Exp $
  *
  * DEBUG: section 4     Error Generation
  * AUTHOR: Duane Wessels
@@ -493,6 +493,8 @@ errorDump(ErrorState * err, MemBuf * mb)
     HttpRequest *r = err->request;
     MemBuf str;
     const char *p = NULL;      /* takes priority over mb if set */
+    char ntoabuf[MAX_IPSTRLEN];
+
     str.reset();
     /* email subject line */
     str.Printf("CacheErrorInfo - %s", errorPageName(err->type));
@@ -520,7 +522,7 @@ errorDump(ErrorState * err, MemBuf * mb)
     str.Printf("TimeStamp: %s\r\n\r\n", mkrfc1123(squid_curtime));
 
     /* - IP stuff */
-    str.Printf("ClientIP: %s\r\n", inet_ntoa(err->src_addr));
+    str.Printf("ClientIP: %s\r\n", err->src_addr.NtoA(ntoabuf,MAX_IPSTRLEN));
 
     if (r && r->hier.host) {
         str.Printf("ServerIP: %s\r\n", r->hier.host);
@@ -604,6 +606,7 @@ errorConvert(char token, ErrorState * err)
     static MemBuf mb;
     const char *p = NULL;      /* takes priority over mb if set */
     int do_quote = 1;
+    char ntoabuf[MAX_IPSTRLEN];
 
     mb.reset();
 
@@ -677,14 +680,14 @@ errorConvert(char token, ErrorState * err)
             if (r->hier.host)
                 p = r->hier.host;
             else
-                p = r->host;
+                p = r->GetHost();
         } else
             p = "[unknown host]";
 
         break;
 
     case 'i':
-        mb.Printf("%s", inet_ntoa(err->src_addr));
+        mb.Printf("%s", err->src_addr.NtoA(ntoabuf,MAX_IPSTRLEN));
 
         break;
 
index 316917f0845a41d6c246e57190a4a9f13b0dafbb..203f6151237790dd1fbd32dd95c8cd9bb31a6fcb 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: errorpage.h,v 1.4 2007/05/09 07:45:58 wessels Exp $
+ * $Id: errorpage.h,v 1.5 2007/12/14 23:11:46 amosjeffries Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -37,6 +37,7 @@
 
 #include "squid.h"
 #include "cbdata.h"
+#include "IPAddress.h"
 
 class AuthUserRequest;
 
@@ -55,7 +56,7 @@ public:
     char *dnsserver_msg;
     time_t ttl;
 
-    struct IN_ADDR src_addr;
+    IPAddress src_addr;
     char *redirect_url;
     ERCB *callback;
     void *callback_data;
index 93947595f40bce5eb2e2bbb5f60340a3bc1ca945..6b2d8f6ef02a380fe7ac2cd534dda04baae0d7b2 100644 (file)
@@ -1,6 +1,5 @@
-
 /*
- * $Id: event.cc,v 1.49 2007/07/30 15:05:42 hno Exp $
+ * $Id: event.cc,v 1.50 2007/12/14 23:11:46 amosjeffries Exp $
  *
  * DEBUG: section 41    Event Processing
  * AUTHOR: Henrik Nordstrom
@@ -36,6 +35,7 @@
 #include "event.h"
 #include "CacheManager.h"
 #include "Store.h"
+#include "SquidTime.h"
 
 /* The list of event processes */
 
@@ -268,14 +268,14 @@ EventScheduler::dump(StoreEntry * sentry)
     if (last_event_ran)
         storeAppendPrintf(sentry, "Last event to run: %s\n\n", last_event_ran);
 
-    storeAppendPrintf(sentry, "%s\t%s\t%s\t%s\n",
+    storeAppendPrintf(sentry, "%-25s\t%-15s\t%s\t%s\n",
                       "Operation",
                       "Next Execution",
                       "Weight",
                       "Callback Valid?");
 
     while (e != NULL) {
-        storeAppendPrintf(sentry, "%s\t%f seconds\t%d\t%s\n",
+        storeAppendPrintf(sentry, "%-25s\t%0.3f sec\t%5d\t %s\n",
                           e->name, e->when ? e->when - current_dtime : 0, e->weight,
                   (e->arg && e->cbdata) ? cbdataReferenceValid(e->arg) ? "yes" : "no" : "N/A");
         e = e->next;
index 81b979cfe9be2d8fa10341046397d600430f0f30..c7fb9c6113a5da99143a3ceec0ebe2933ace6118 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: external_acl.cc,v 1.80 2007/05/29 13:31:39 amosjeffries Exp $
+ * $Id: external_acl.cc,v 1.81 2007/12/14 23:11:46 amosjeffries Exp $
  *
  * DEBUG: section 82    External ACL
  * AUTHOR: Henrik Nordstrom, MARA Systems AB
@@ -129,6 +129,8 @@ public:
     }
 
     quote;
+
+    IPAddress local_addr;
 };
 
 struct _external_acl_format
@@ -220,9 +222,13 @@ parse_externalAclHelper(external_acl ** list)
 
     a = cbdataAlloc(external_acl);
 
+    /* set defaults */
     a->ttl = DEFAULT_EXTERNAL_ACL_TTL;
     a->negative_ttl = -1;
     a->children = DEFAULT_EXTERNAL_ACL_CHILDREN;
+    a->local_addr.SetLocalhost();
+    a->quote = external_acl::QUOTE_METHOD_URL;
+
 
     token = strtok(NULL, w_space);
 
@@ -233,8 +239,6 @@ parse_externalAclHelper(external_acl ** list)
 
     token = strtok(NULL, w_space);
 
-    a->quote = external_acl::QUOTE_METHOD_URL;
-
     /* Parse options */
     while (token) {
         if (strncmp(token, "ttl=", 4) == 0) {
@@ -257,6 +261,22 @@ parse_externalAclHelper(external_acl ** list)
             a->quote = external_acl::QUOTE_METHOD_URL;
         } else if (strcmp(token, "quote=shell") == 0) {
             a->quote = external_acl::QUOTE_METHOD_SHELL;
+
+    /* INET6: allow admin to configure some helpers explicitly to
+              bind to IPv4/v6 localhost port. */
+        } else if (strcmp(token, "ipv4") == 0) {
+#if IPV6_SPECIAL_LOCALHOST
+            debugs(3, 0, "WARNING: --with-localhost-ipv6 conflicts with external ACL helper to using IPv4: " << a->name );
+#endif
+            if( !a->local_addr.SetIPv4() ) {
+                debugs(3, 0, "WARNING: Error converting " << a->local_addr << " to IPv4 in " << a->name );
+            }
+        } else if (strcmp(token, "ipv6") == 0) {
+#if !USE_IPV6
+            debugs(3, 0, "WARNING: --enable-ipv6 required for external ACL helpers to use IPv6: " << a->name );
+#else
+            (void)0;
+#endif
         } else {
             break;
         }
@@ -406,6 +426,11 @@ dump_externalAclHelper(StoreEntry * sentry, const char *name, const external_acl
     for (node = list; node; node = node->next) {
         storeAppendPrintf(sentry, "%s %s", name, node->name);
 
+        if (!node->local_addr.IsIPv6())
+            storeAppendPrintf(sentry, " ipv4");
+        else
+            storeAppendPrintf(sentry, " ipv6");
+
         if (node->ttl != DEFAULT_EXTERNAL_ACL_TTL)
             storeAppendPrintf(sentry, " ttl=%d", node->ttl);
 
@@ -785,20 +810,20 @@ makeExternalAclKey(ACLChecklist * ch, external_acl_data * acl_data)
 #endif
 
         case _external_acl_format::EXT_ACL_SRC:
-            str = inet_ntoa(ch->src_addr);
+            str = ch->src_addr.NtoA(buf,sizeof(buf));
             break;
 
         case _external_acl_format::EXT_ACL_SRCPORT:
-            snprintf(buf, sizeof(buf), "%d", request->client_port);
+            snprintf(buf, sizeof(buf), "%d", request->client_addr.GetPort());
             str = buf;
             break;
 
         case _external_acl_format::EXT_ACL_MYADDR:
-            str = inet_ntoa(request->my_addr);
+            str = request->my_addr.NtoA(buf, sizeof(buf));
             break;
 
         case _external_acl_format::EXT_ACL_MYPORT:
-            snprintf(buf, sizeof(buf), "%d", request->my_port);
+            snprintf(buf, sizeof(buf), "%d", request->my_addr.GetPort());
             str = buf;
             break;
 
@@ -807,7 +832,7 @@ makeExternalAclKey(ACLChecklist * ch, external_acl_data * acl_data)
             break;
 
         case _external_acl_format::EXT_ACL_DST:
-            str = request->host;
+            str = request->GetHost();
             break;
 
         case _external_acl_format::EXT_ACL_PROTO:
@@ -1291,6 +1316,8 @@ externalAclInit(void)
 
         p->theHelper->ipc_type = IPC_TCP_SOCKET;
 
+        p->theHelper->addr = p->local_addr;
+
         helperOpenServers(p->theHelper);
     }
 
index 12ee236e1df4cd89b3033a1f996d5b2902178bba..04b5f7b0d75431dc082c033fe01342efdfe9f6b0 100644 (file)
--- a/src/fd.cc
+++ b/src/fd.cc
@@ -1,6 +1,6 @@
 
 /*
- * $Id: fd.cc,v 1.59 2007/09/25 13:24:59 hno Exp $
+ * $Id: fd.cc,v 1.60 2007/12/14 23:11:46 amosjeffries Exp $
  *
  * DEBUG: section 51    Filedescriptor Functions
  * AUTHOR: Duane Wessels
@@ -103,7 +103,7 @@ fd_close(int fd)
     F->flags.open = 0;
     fdUpdateBiggest(fd, 0);
     Number_FD--;
-    memset(F, '\0', sizeof(fde));
+    F->clear();
     F->timeout = 0;
 }
 
@@ -181,7 +181,7 @@ fd_open(int fd, unsigned int type, const char *desc)
     }
 
     assert(!F->flags.open);
-    debugs(51, 3, "fd_open FD " << fd << " " << desc);
+    debugs(51, 3, "fd_open() FD " << fd << " " << desc);
     F->type = type;
     F->flags.open = 1;
     F->epoll_state = 0;
index d53a17c73b9a7ccf089c076e0ab6b991e7d22534..72954e8bef772e9e9baabc35cf39393f7124873f 100644 (file)
--- a/src/fde.h
+++ b/src/fde.h
@@ -1,6 +1,6 @@
 
 /*
- * $Id: fde.h,v 1.13 2007/08/13 17:20:51 hno Exp $
+ * $Id: fde.h,v 1.14 2007/12/14 23:11:46 amosjeffries Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -33,7 +33,9 @@
 
 #ifndef SQUID_FDE_H
 #define SQUID_FDE_H
+
 #include "comm.h"
+#include "IPAddress.h"
 
 class PconnPool;
 
@@ -41,6 +43,13 @@ class fde
 {
 
 public:
+    fde() { clear(); };
+    /** Clear the fde class properly back to NULL equivalent. */
+    inline void clear() {
+        memset(this, 0, sizeof(fde));
+        local_addr.SetEmpty(); // IPAddress likes to be setup nicely.
+    }
+
     /* NOTE: memset is used on fdes today. 20030715 RBC */
     static void DumpStats (StoreEntry *);
 
@@ -50,12 +59,12 @@ public:
     void noteUse(PconnPool *);
 
     unsigned int type;
-    u_short local_port;
     u_short remote_port;
 
-    struct IN_ADDR local_addr;
+    IPAddress local_addr;
     unsigned char tos;
-    char ipaddr[16];            /* dotted decimal address of peer */
+    int sock_family;
+    char ipaddr[MAX_IPSTRLEN];            /* dotted decimal address of peer */
     char desc[FD_DESC_SZ];
 
     struct
index 69a2bf27650b321e8cd9c72830d2ab1043d4fda8..0da586558fd8a8b2aed9f9c5fda40e1f6dc4d247 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: forward.cc,v 1.168 2007/07/21 16:32:03 hno Exp $
+ * $Id: forward.cc,v 1.169 2007/12/14 23:11:46 amosjeffries Exp $
  *
  * DEBUG: section 17    Request Forwarding
  * AUTHOR: Duane Wessels
@@ -207,14 +207,13 @@ FwdState::fwdStart(int client_fd, StoreEntry *entry, HttpRequest *request)
      * be allowed.  yuck, I know.
      */
 
-    if (request->client_addr.s_addr != no_addr.s_addr && request->protocol != PROTO_INTERNAL && request->protocol != PROTO_CACHEOBJ) {
+    if ( !request->client_addr.IsNoAddr() && request->protocol != PROTO_INTERNAL && request->protocol != PROTO_CACHEOBJ) {
         /*
          * Check if this host is allowed to fetch MISSES from us (miss_access)
          */
         ACLChecklist ch;
         ch.src_addr = request->client_addr;
         ch.my_addr = request->my_addr;
-        ch.my_port = request->my_port;
         ch.request = HTTPMSGLOCK(request);
         ch.accessList = cbdataReference(Config.accessList.miss);
         /* cbdataReferenceDone() happens in either fastCheck() or ~ACLCheckList */
@@ -271,10 +270,8 @@ FwdState::fwdStart(int client_fd, StoreEntry *entry, HttpRequest *request)
         FwdState::Pointer fwd = new FwdState(client_fd, entry, request);
 #if LINUX_TPROXY
         /* If we need to transparently proxy the request
-         * then we need the client source address and port */
-        fwd->src.sin_family = AF_INET;
-        fwd->src.sin_addr = request->client_addr;
-        fwd->src.sin_port = request->client_port;
+         * then we need the client source protocol, address and port */
+        fwd->src = request->client_addr;
 #endif
 
         fwd->start(fwd);
@@ -660,7 +657,7 @@ FwdState::initiateSSL()
             SSL_set_session(ssl, peer->sslSession);
 
     } else {
-        SSL_set_ex_data(ssl, ssl_ex_index_server, request->host);
+        SSL_set_ex_data(ssl, ssl_ex_index_server, (void*)request->GetHost());
     }
 
     fd_table[fd].ssl = ssl;
@@ -690,7 +687,7 @@ FwdState::connectDone(int aServerFD, comm_err_t status, int xerrno)
         if (NULL == fs->_peer)
             flags.dont_retry = 1;
 
-        debugs(17, 4, "fwdConnectDone: Unknown host: " << request->host);
+        debugs(17, 4, "fwdConnectDone: Unknown host: " << request->GetHost());
 
         ErrorState *anErr = errorCon(ERR_DNS_FAIL, HTTP_SERVICE_UNAVAILABLE, request);
 
@@ -772,10 +769,10 @@ FwdState::connectStart()
     struct in_tproxy itp;
 #endif
 
-    struct IN_ADDR outgoing;
+    IPAddress outgoing;
     unsigned short tos;
 
-    struct IN_ADDR *client_addr = NULL;
+    IPAddress client_addr;
     assert(fs);
     assert(server_fd == -1);
     debugs(17, 3, "fwdConnectStart: " << url);
@@ -787,16 +784,16 @@ FwdState::connectStart()
                    : Config.Timeout.peer_connect;
 
         if (fs->_peer->options.originserver)
-            domain = request->host;
+            domain = request->GetHost();
     } else {
-        host = request->host;
+        host = request->GetHost();
         port = request->port;
         ctimeout = Config.Timeout.connect;
     }
 
 #if LINUX_TPROXY
     if (request->flags.tproxy)
-        client_addr = &request->client_addr;
+        client_addr = request->client_addr;
 
 #endif
 
@@ -831,16 +828,17 @@ FwdState::connectStart()
 
     tos = getOutgoingTOS(request);
 
-    debugs(17, 3, "fwdConnectStart: got addr " << inet_ntoa(outgoing) << ", tos " << tos);
+    debugs(17, 3, "fwdConnectStart: got outgoing addr " << outgoing << ", tos " << tos);
 
     fd = comm_openex(SOCK_STREAM,
                      IPPROTO_TCP,
                      outgoing,
-                     0,
                      COMM_NONBLOCKING,
                      tos,
                      url);
 
+    debugs(17, 3, "fwdConnectStart: got TCP FD " << fd);
+
     if (fd < 0) {
         debugs(50, 4, "fwdConnectStart: " << xstrerror());
         ErrorState *anErr = errorCon(ERR_SOCKET_FAILURE, HTTP_INTERNAL_SERVER_ERROR, request);
@@ -878,6 +876,8 @@ FwdState::connectStart()
 #if LINUX_TPROXY
 
         if (request->flags.tproxy) {
+            IPAddress addr;
+
             itp.v.addr.faddr.s_addr = src.sin_addr.s_addr;
             itp.v.addr.fport = 0;
 
@@ -886,10 +886,11 @@ FwdState::connectStart()
              */
             itp.op = TPROXY_ASSIGN;
 
+            addr = (struct in_addr)itp.v.addr.faddr;
+            addr.SetPort(itp.v.addr.fport);
+
             if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp, sizeof(itp)) == -1) {
-                debugs(20, 1, "tproxy ip=" << inet_ntoa(itp.v.addr.faddr) <<
-                       ",0x" << std::hex << itp.v.addr.faddr.s_addr << std::dec <<
-                       ",port=" << itp.v.addr.fport << " ERROR ASSIGN");
+                debugs(20, 1, "tproxy ip=" << addr << " ERROR ASSIGN");
 
                 request->flags.tproxy = 0;
             } else {
@@ -897,9 +898,7 @@ FwdState::connectStart()
                 itp.v.flags = ITP_CONNECT;
 
                 if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp, sizeof(itp)) == -1) {
-                    debugs(20, 1, "tproxy ip=" << std::hex <<
-                           itp.v.addr.faddr.s_addr << std::dec << ",port=" <<
-                           itp.v.addr.fport << " ERROR CONNECT");
+                    debugs(20, 1, "tproxy ip=" << addr << " ERROR CONNECT");
 
                     request->flags.tproxy = 0;
                 }
@@ -907,7 +906,7 @@ FwdState::connectStart()
         }
 
 #endif
-        hierarchyNote(&request->hier, fs->code, request->host);
+        hierarchyNote(&request->hier, fs->code, request->GetHost());
     }
 
     commConnectStart(fd, host, port, fwdConnectDoneWrapper, this);
@@ -959,7 +958,7 @@ FwdState::dispatch()
 
     EBIT_SET(entry->flags, ENTRY_DISPATCHED);
 
-    netdbPingSite(request->host);
+    netdbPingSite(request->GetHost());
 
     if (servers && (p = servers->_peer)) {
         p->stats.fetches++;
@@ -1136,7 +1135,7 @@ FwdState::reforwardableStatus(http_status s)
 
 void
 
-FwdState::pconnPush(int fd, const char *host, int port, const char *domain, struct IN_ADDR *client_addr)
+FwdState::pconnPush(int fd, const char *host, int port, const char *domain, IPAddress &client_addr)
 {
     fwdPconnPool->push(fd, host, port, domain, client_addr);
 }
@@ -1202,12 +1201,12 @@ fwdServerFree(FwdServer * fs)
     memFree(fs, MEM_FWD_SERVER);
 }
 
-static struct IN_ADDR
-            aclMapAddr(acl_address * head, ACLChecklist * ch)
+static IPAddress
+aclMapAddr(acl_address * head, ACLChecklist * ch)
 {
     acl_address *l;
 
-    struct IN_ADDR addr;
+    IPAddress addr;
 
     for (l = head; l; l = l->next)
     {
@@ -1215,7 +1214,7 @@ static struct IN_ADDR
             return l->addr;
     }
 
-    addr.s_addr = INADDR_ANY;
+    addr.SetAnyAddr();
     return addr;
 }
 
@@ -1236,8 +1235,8 @@ aclMapTOS(acl_tos * head, ACLChecklist * ch)
     return 0;
 }
 
-struct IN_ADDR
-            getOutgoingAddr(HttpRequest * request)
+IPAddress
+getOutgoingAddr(HttpRequest * request)
 {
     ACLChecklist ch;
 
@@ -1245,7 +1244,6 @@ struct IN_ADDR
     {
         ch.src_addr = request->client_addr;
         ch.my_addr = request->my_addr;
-        ch.my_port = request->my_port;
         ch.request = HTTPMSGLOCK(request);
     }
 
@@ -1260,7 +1258,6 @@ getOutgoingTOS(HttpRequest * request)
     if (request) {
         ch.src_addr = request->client_addr;
         ch.my_addr = request->my_addr;
-        ch.my_port = request->my_port;
         ch.request = HTTPMSGLOCK(request);
     }
 
index be43dfe6a11e4d3bf64b225f49f9202b57b729bf..60a6edd0ffdb185795c51fca7cb53e9b24cc5773 100644 (file)
@@ -7,6 +7,7 @@ class CacheManager;
 class ErrorState;
 
 #include "comm.h"
+#include "IPAddress.h"
 
 class FwdServer
 {
@@ -44,7 +45,7 @@ public:
     bool checkRetry();
     bool checkRetriable();
     void dispatch();
-    void pconnPush(int fd, const char *host, int port, const char *domain, struct IN_ADDR *client_addr);
+    void pconnPush(int fd, const char *host, int port, const char *domain, IPAddress &client_addr);
 
     bool dontRetry() { return flags.dont_retry; }
 
@@ -106,7 +107,7 @@ unsigned int forward_completed:1;
 
     flags;
 #if LINUX_NETFILTER
-    struct sockaddr_in src;
+    IPAddress src;
 #endif
 
 };
index adcf02eb4e6f9cc5edbe7511519822b905d34673..713f73e66502f50a1385301a8ee8ffb7b16ec82f 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: fqdncache.cc,v 1.175 2007/10/13 00:02:28 hno Exp $
+ * $Id: fqdncache.cc,v 1.176 2007/12/14 23:11:46 amosjeffries Exp $
  *
  * DEBUG: section 35    FQDN Cache
  * AUTHOR: Harvest Derived
@@ -440,17 +440,17 @@ fqdncacheHandleReply(void *data, rfc1035_rr * answers, int na, const char *error
 }
 
 void
-
-fqdncache_nbgethostbyaddr(struct IN_ADDR addr, FQDNH * handler, void *handlerData)
+fqdncache_nbgethostbyaddr(IPAddress &addr, FQDNH * handler, void *handlerData)
 {
     fqdncache_entry *f = NULL;
-    char *name = inet_ntoa(addr);
+    char name[MAX_IPSTRLEN];
     generic_cbdata *c;
     assert(handler);
+    addr.NtoA(name,MAX_IPSTRLEN);
     debugs(35, 4, "fqdncache_nbgethostbyaddr: Name '" << name << "'.");
     FqdncacheStats.requests++;
 
-    if (name == NULL || name[0] == '\0')
+    if (name[0] == '\0')
     {
         debugs(35, 4, "fqdncache_nbgethostbyaddr: Invalid name!");
         dns_error_message = "Invalid hostname";
@@ -499,7 +499,6 @@ fqdncache_nbgethostbyaddr(struct IN_ADDR addr, FQDNH * handler, void *handlerDat
 
     dnsSubmit(hashKeyStr(&f->hash), fqdncacheHandleReply, c);
 #else
-
     idnsPTRLookup(addr, fqdncacheHandleReply, c);
 #endif
 }
@@ -543,14 +542,13 @@ fqdncacheRegisterWithCacheManager(CacheManager & manager)
 }
 
 const char *
-
-fqdncache_gethostbyaddr(struct IN_ADDR addr, int flags)
+fqdncache_gethostbyaddr(IPAddress &addr, int flags)
 {
-    char *name = inet_ntoa(addr);
+    char name[MAX_IPSTRLEN];
     fqdncache_entry *f = NULL;
 
-    struct IN_ADDR ip;
-    assert(name);
+    assert(!addr.IsAnyAddr() && !addr.IsNoAddr());
+    addr.NtoA(name,MAX_IPSTRLEN);
     FqdncacheStats.requests++;
     f = fqdncache_get(name);
 
@@ -576,15 +574,12 @@ fqdncache_gethostbyaddr(struct IN_ADDR addr, int flags)
 
     dns_error_message = NULL;
 
-    /* check if it's already a FQDN address in text form. */
-
-    if (!safe_inet_addr(name, &ip))
-        return name;
-
     FqdncacheStats.misses++;
 
     if (flags & FQDN_LOOKUP_IF_MISS)
+    {
         fqdncache_nbgethostbyaddr(addr, dummy_handler, NULL);
+    }
 
     return NULL;
 }
@@ -620,14 +615,14 @@ fqdnStats(StoreEntry * sentry)
 
     storeAppendPrintf(sentry, "FQDN Cache Contents:\n\n");
 
-    storeAppendPrintf(sentry, "%-15.15s %3s %3s %3s %s\n",
+    storeAppendPrintf(sentry, "%-45.45s %3s %3s %3s %s\n",
                       "Address", "Flg", "TTL", "Cnt", "Hostnames");
 
     hash_first(fqdn_table);
 
     while ((f = (fqdncache_entry *) hash_next(fqdn_table))) {
         ttl = (f->flags.fromhosts ? -1 : (f->expires - squid_curtime));
-        storeAppendPrintf(sentry, "%-15.15s  %c%c %3.3d % 3d",
+        storeAppendPrintf(sentry, "%-45.45s  %c%c %3.3d % 3d",
                           hashKeyStr(&f->hash),
                           f->flags.negcached ? 'N' : ' ',
                           f->flags.fromhosts ? 'H' : ' ',
@@ -648,16 +643,15 @@ dummy_handler(const char *bufnotused, void *datanotused)
 }
 
 const char *
-
-fqdnFromAddr(struct IN_ADDR addr)
+fqdnFromAddr(IPAddress &addr)
 {
     const char *n;
-    static char buf[32];
+    static char buf[MAX_IPSTRLEN];
 
     if (Config.onoff.log_fqdn && (n = fqdncache_gethostbyaddr(addr, 0)))
         return n;
 
-    xstrncpy(buf, inet_ntoa(addr), 32);
+    addr.NtoA(buf, MAX_IPSTRLEN);
 
     return buf;
 }
index 4607c2b7909e838460a1e8ebbe8c63839c82a7dc..a816cb218087112ab92b3afd66f9cbbb13b783b6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ftp.cc,v 1.441 2007/09/27 14:34:06 rousskov Exp $
+ * $Id: ftp.cc,v 1.442 2007/12/14 23:11:46 amosjeffries Exp $
  *
  * DEBUG: section 9     File Transfer Protocol (FTP)
  * AUTHOR: Harvest Derived
@@ -64,7 +64,9 @@ typedef enum {
     SENT_TYPE,
     SENT_MDTM,
     SENT_SIZE,
+    SENT_EPRT,
     SENT_PORT,
+    SENT_EPSV,
     SENT_PASV,
     SENT_CWD,
     SENT_LIST,
@@ -275,8 +277,12 @@ static FTPSM ftpSendMdtm;
 static FTPSM ftpReadMdtm;
 static FTPSM ftpSendSize;
 static FTPSM ftpReadSize;
-static FTPSM ftpSendPort;
-static FTPSM ftpReadPort;
+static FTPSM ftpSendEPRT;
+static FTPSM ftpReadEPRT;
+static FTPSM ftpSendPORT;
+static FTPSM ftpReadPORT;
+//static FTPSM ftpSendEPSV;
+static FTPSM ftpReadEPSV;
 static FTPSM ftpSendPasv;
 static FTPSM ftpReadPasv;
 static FTPSM ftpTraverseDirectory;
@@ -339,7 +345,9 @@ FTPSM *FTP_SM_FUNCS[] =
         ftpReadType,           /* SENT_TYPE */
         ftpReadMdtm,           /* SENT_MDTM */
         ftpReadSize,           /* SENT_SIZE */
-        ftpReadPort,           /* SENT_PORT */
+        ftpReadEPRT,           /* SENT_EPRT */
+        ftpReadPORT,           /* SENT_PORT */
+        ftpReadEPSV,           /* SENT_EPSV */
         ftpReadPasv,           /* SENT_PASV */
         ftpReadCwd,                    /* SENT_CWD */
         ftpReadList,           /* SENT_LIST */
@@ -1439,7 +1447,7 @@ FtpStateData::buildTitleUrl()
         title_url.append("@");
     }
 
-    title_url.append(request->host);
+    title_url.append(request->GetHost());
 
     if (request->port != urlDefaultPort(PROTO_FTP)) {
         title_url.append(":");
@@ -1461,7 +1469,7 @@ FtpStateData::buildTitleUrl()
         base_href.append("@");
     }
 
-    base_href.append(request->host);
+    base_href.append(request->GetHost());
 
     if (request->port != urlDefaultPort(PROTO_FTP)) {
         base_href.append(":");
@@ -1505,7 +1513,7 @@ FtpStateData::start()
 
     checkUrlpath();
     buildTitleUrl();
-    debugs(9, 5, "ftpStart: host=" << request->host << ", path=" <<
+    debugs(9, 5, "ftpStart: host=" << request->GetHost() << ", path=" <<
            request->urlpath.buf() << ", user=" << user << ", passwd=" <<
            password);
 
@@ -1862,7 +1870,7 @@ ftpSendUser(FtpStateData * ftpState)
     if (ftpState->proxy_host != NULL)
         snprintf(cbuf, 1024, "USER %s@%s\r\n",
                  ftpState->user,
-                 ftpState->request->host);
+                 ftpState->request->GetHost());
     else
         snprintf(cbuf, 1024, "USER %s\r\n", ftpState->user);
 
@@ -2206,7 +2214,7 @@ static void
 ftpReadSize(FtpStateData * ftpState)
 {
     int code = ftpState->ctrl.replycode;
-    debugs(9, 3, "This is ftpReadSize");
+    debugs(9, 3, HERE << "ftpReadSize()");
 
     if (code == 213) {
         ftpState->unhack();
@@ -2226,11 +2234,30 @@ ftpReadSize(FtpStateData * ftpState)
     ftpSendPasv(ftpState);
 }
 
+/* FIXME INET6 : EPASV command not yet coded. */
+/*
+static void
+ftpSendEPSV(FtpStateData* ftpstate)
+{
+   // TODO.
+}
+*/
+
+static void
+ftpReadEPSV(FtpStateData* ftpstate)
+{
+    /* FIXME INET6 : EPASV command not yet coded. */
+
+    /* Failover to PASV */
+    ftpReadPasv(ftpstate);
+}
+
+
 static void
 ftpSendPasv(FtpStateData * ftpState)
 {
-    struct sockaddr_in addr;
-    socklen_t addr_len;
+    IPAddress addr;
+    struct addrinfo *AI = NULL;
 
     /* check the server control channel is still available */
     if(!ftpState || !ftpState->haveControlChannel("ftpSendPasv"))
@@ -2250,23 +2277,27 @@ ftpSendPasv(FtpStateData * ftpState)
     }
 
     if (!ftpState->flags.pasv_supported) {
-        ftpSendPort(ftpState);
+        ftpSendEPRT(ftpState);
         return;
     }
 
-    addr_len = sizeof(addr);
+    addr.InitAddrInfo(AI);
 
-    if (getsockname(ftpState->ctrl.fd, (struct sockaddr *) &addr, &addr_len)) {
-        debugs(9, 0, "ftpSendPasv: getsockname(" << ftpState->ctrl.fd << ",..): " << xstrerror());
+    if (getsockname(ftpState->ctrl.fd, AI->ai_addr, &AI->ai_addrlen)) {
+        addr.FreeAddrInfo(AI);
+        debugs(9, 0, "ftpSendPasv: getsockname(" << ftpState->ctrl.fd << ",'" << addr << "',...): " << xstrerror());
         ftpFail(ftpState);
         return;
     }
 
+    addr = *AI;
+
+    addr.FreeAddrInfo(AI);
+
     /* Open data channel with the same local address as control channel */
     int fd = comm_open(SOCK_STREAM,
                        IPPROTO_TCP,
-                       addr.sin_addr,
-                       0,
+                       addr,
                        COMM_NONBLOCKING,
                        ftpState->entry->url());
 
@@ -2338,14 +2369,15 @@ ftpReadPasv(FtpStateData * ftpState)
     int p1, p2;
     int n;
     u_short port;
+    IPAddress ipa_remote;
     int fd = ftpState->data.fd;
     char *buf;
     LOCAL_ARRAY(char, ipaddr, 1024);
-    debugs(9, 3, "This is ftpReadPasv");
+    debugs(9, 3, HERE << "ftpReadSize started");
 
     if (code != 227) {
         debugs(9, 3, "PASV not supported by remote end");
-        ftpSendPort(ftpState);
+        ftpSendEPRT(ftpState);
         return;
     }
 
@@ -2362,18 +2394,20 @@ ftpReadPasv(FtpStateData * ftpState)
                fd_table[ftpState->ctrl.fd].ipaddr << ": " <<
                ftpState->ctrl.last_reply);
 
-        ftpSendPort(ftpState);
+        ftpSendEPRT(ftpState);
         return;
     }
 
     snprintf(ipaddr, 1024, "%d.%d.%d.%d", h1, h2, h3, h4);
 
-    if (!safe_inet_addr(ipaddr, NULL)) {
+    ipa_remote = ipaddr;
+
+    if( ipa_remote.IsAnyAddr() ) {
         debugs(9, 1, "Unsafe PASV reply from " <<
                fd_table[ftpState->ctrl.fd].ipaddr << ": " <<
                ftpState->ctrl.last_reply);
 
-        ftpSendPort(ftpState);
+        ftpSendEPRT(ftpState);
         return;
     }
 
@@ -2384,7 +2418,7 @@ ftpReadPasv(FtpStateData * ftpState)
                fd_table[ftpState->ctrl.fd].ipaddr << ": " <<
                ftpState->ctrl.last_reply);
 
-        ftpSendPort(ftpState);
+        ftpSendEPRT(ftpState);
         return;
     }
 
@@ -2394,7 +2428,7 @@ ftpReadPasv(FtpStateData * ftpState)
                    fd_table[ftpState->ctrl.fd].ipaddr << ": " <<
                    ftpState->ctrl.last_reply);
 
-            ftpSendPort(ftpState);
+            ftpSendEPRT(ftpState);
             return;
         }
     }
@@ -2440,10 +2474,10 @@ ftpOpenListenSocket(FtpStateData * ftpState, int fallback)
 {
     int fd;
 
-    struct sockaddr_in addr;
-    socklen_t addr_len;
+    IPAddress addr;
+    struct addrinfo *AI = NULL;
     int on = 1;
-    u_short port = 0;
+    int x = 0;
     /*
      * Tear down any old data connection if any. We are about to
      * establish a new one.
@@ -2458,9 +2492,16 @@ ftpOpenListenSocket(FtpStateData * ftpState, int fallback)
      * Set up a listen socket on the same local address as the
      * control connection.
      */
-    addr_len = sizeof(addr);
 
-    if (getsockname(ftpState->ctrl.fd, (struct sockaddr *) &addr, &addr_len)) {
+    addr.InitAddrInfo(AI);
+
+    x = getsockname(ftpState->ctrl.fd, AI->ai_addr, &AI->ai_addrlen);
+
+    addr = *AI;
+
+    addr.FreeAddrInfo(AI);
+
+    if(x) {
         debugs(9, 0, "ftpOpenListenSocket: getsockname(" << ftpState->ctrl.fd << ",..): " << xstrerror());
         return -1;
     }
@@ -2471,13 +2512,11 @@ ftpOpenListenSocket(FtpStateData * ftpState, int fallback)
      */
     if (fallback) {
         setsockopt(ftpState->ctrl.fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on));
-        port = ntohs(addr.sin_port);
     }
 
     fd = comm_open(SOCK_STREAM,
                    IPPROTO_TCP,
-                   addr.sin_addr,
-                   port,
+                   addr,
                    COMM_NONBLOCKING | (fallback ? COMM_REUSEADDR : 0),
                    ftpState->entry->url());
     debugs(9, 3, "ftpOpenListenSocket: Unconnected data socket created on FD " << fd  );
@@ -2499,12 +2538,12 @@ ftpOpenListenSocket(FtpStateData * ftpState, int fallback)
 }
 
 static void
-ftpSendPort(FtpStateData * ftpState)
+ftpSendPORT(FtpStateData * ftpState)
 {
     int fd;
 
-    struct sockaddr_in addr;
-    socklen_t addr_len;
+    IPAddress ipa;
+    struct addrinfo *AI = NULL;
     unsigned char *addrptr;
     unsigned char *portptr;
 
@@ -2515,30 +2554,44 @@ ftpSendPort(FtpStateData * ftpState)
     debugs(9, 3, "This is ftpSendPort");
     ftpState->flags.pasv_supported = 0;
     fd = ftpOpenListenSocket(ftpState, 0);
-    addr_len = sizeof(addr);
+    ipa.InitAddrInfo(AI);
 
-    if (getsockname(fd, (struct sockaddr *) &addr, &addr_len)) {
-        debugs(9, 0, "ftpSendPort: getsockname(" << fd << ",..): " << xstrerror());
+    if (getsockname(fd, AI->ai_addr, &AI->ai_addrlen)) {
+        ipa.FreeAddrInfo(AI);
+        debugs(9, 0, "ftpSendPORT: getsockname(" << fd << ",..): " << xstrerror());
 
         /* XXX Need to set error message */
         ftpFail(ftpState);
         return;
     }
 
-    addrptr = (unsigned char *) &addr.sin_addr.s_addr;
-    portptr = (unsigned char *) &addr.sin_port;
+#if USE_IPV6
+    if( AI->ai_addrlen != sizeof(struct sockaddr_in) ) {
+        ipa.FreeAddrInfo(AI);
+       /* IPv6 CANNOT send PORT command.                           */
+       /* we got here by attempting and failing an EPRT            */
+       /* using the same reply code should simulate a PORT failure */
+       ftpReadPORT(ftpState);
+       return;
+    }
+#endif
+
+    addrptr = (unsigned char *) &((struct sockaddr_in*)AI->ai_addr)->sin_addr;
+    portptr = (unsigned char *) &((struct sockaddr_in*)AI->ai_addr)->sin_port;
     snprintf(cbuf, 1024, "PORT %d,%d,%d,%d,%d,%d\r\n",
              addrptr[0], addrptr[1], addrptr[2], addrptr[3],
              portptr[0], portptr[1]);
     ftpState->writeCommand(cbuf);
     ftpState->state = SENT_PORT;
+
+    ipa.FreeAddrInfo(AI);
 }
 
 static void
-ftpReadPort(FtpStateData * ftpState)
+ftpReadPORT(FtpStateData * ftpState)
 {
     int code = ftpState->ctrl.replycode;
-    debugs(9, 3, "This is ftpReadPort");
+    debugs(9, 3, HERE << "ftpReadPORT started");
 
     if (code != 200) {
         /* Fall back on using the same port as the control connection */
@@ -2549,11 +2602,66 @@ ftpReadPort(FtpStateData * ftpState)
     ftpRestOrList(ftpState);
 }
 
+static void
+ftpSendEPRT(FtpStateData * ftpState)
+{
+    int fd;
+    IPAddress addr;
+    struct addrinfo *AI = NULL;
+    char buf[MAX_IPSTRLEN];
+
+    debugs(9, 3, HERE << "ftpSendEPRT started");
+    ftpState->flags.pasv_supported = 0;
+    fd = ftpOpenListenSocket(ftpState, 0);
+
+    addr.InitAddrInfo(AI);
+
+    if (getsockname(fd, AI->ai_addr, &AI->ai_addrlen)) {
+        addr.FreeAddrInfo(AI);
+        debugs(9, 0, "ftpSendEPRT: getsockname(" << fd << ",..): " << xstrerror());
+
+        /* XXX Need to set error message */
+        ftpFail(ftpState);
+        return;
+    }
+
+    addr = *AI;
+
+    /* RFC 2428 defines EPRT as IPv6 equivalent to IPv4 PORT command. */
+    /* Which can be used by EITHER protocol. */
+    snprintf(cbuf, 1024, "EPRT |%d|%s|%d|\r\n",
+             AI->ai_family,
+             addr.NtoA(buf,MAX_IPSTRLEN),
+             addr.GetPort() );
+
+    ftpState->writeCommand(cbuf);
+    ftpState->state = SENT_EPRT;
+
+    addr.FreeAddrInfo(AI);
+}
+
+static void
+ftpReadEPRT(FtpStateData * ftpState)
+{
+    int code = ftpState->ctrl.replycode;
+    debugs(9, 3, HERE << " ftpReadEPRT started");
+
+    if (code != 200) {
+        /* Failover to attempting old PORT command. */
+        debugs(9, 3, "EPRT not supported by remote end");
+        ftpSendPORT(ftpState);
+        return;
+    }
+
+    ftpRestOrList(ftpState);
+}
+
 /* "read" handler to accept data connection */
 static void
 ftpAcceptDataConnection(int fd, int newfd, ConnectionDetail *details,
                         comm_err_t flag, int xerrno, void *data)
 {
+    char ntoapeer[MAX_IPSTRLEN];
     FtpStateData *ftpState = (FtpStateData *)data;
     debugs(9, 3, "ftpAcceptDataConnection");
 
@@ -2566,12 +2674,11 @@ ftpAcceptDataConnection(int fd, int newfd, ConnectionDetail *details,
     }
 
     if (Config.Ftp.sanitycheck) {
-        char *ipaddr = inet_ntoa(details->peer.sin_addr);
+        details->peer.NtoA(ntoapeer,MAX_IPSTRLEN);
 
-        if (strcmp(fd_table[ftpState->ctrl.fd].ipaddr, ipaddr) != 0) {
+        if (strcmp(fd_table[ftpState->ctrl.fd].ipaddr, ntoapeer) != 0) {
             debugs(9, 1, "FTP data connection from unexpected server (" <<
-                   ipaddr << ":" << (int) ntohs(details->peer.sin_port) <<
-                   "), expecting " << fd_table[ftpState->ctrl.fd].ipaddr);
+                   details->peer << "), expecting " << fd_table[ftpState->ctrl.fd].ipaddr);
 
             comm_close(newfd);
             comm_accept(ftpState->data.fd, ftpAcceptDataConnection, ftpState);
@@ -2593,14 +2700,13 @@ ftpAcceptDataConnection(int fd, int newfd, ConnectionDetail *details,
 
     ftpState->data.fd = newfd;
 
-    ftpState->data.port = ntohs(details->peer.sin_port);
+    ftpState->data.port = details->peer.GetPort();
 
-    ftpState->data.host = xstrdup(inet_ntoa(details->peer.sin_addr));
+    details->peer.NtoA(ftpState->data.host,SQUIDHOSTNAMELEN);
 
     commSetTimeout(ftpState->ctrl.fd, -1, NULL, NULL);
 
-    commSetTimeout(ftpState->data.fd, Config.Timeout.read, FtpStateData::ftpTimeout,
-                   ftpState);
+    commSetTimeout(ftpState->data.fd, Config.Timeout.read, FtpStateData::ftpTimeout, ftpState);
 
     /* XXX We should have a flag to track connect state...
      *    host NULL -> not connected, port == local port
@@ -3286,44 +3392,35 @@ FtpStateData::ftpAuthRequired(HttpRequest * request, const char *realm)
     return newrep;
 }
 
-char *
-ftpUrlWith2f(const HttpRequest * request)
+/**
+ *  Construct an URI with leading / in PATH portion for use by CWD command
+ *  possibly others. FTP encodes absolute paths as beginning with '/'
+ *  after the initial URI path delimiter, which happens to be / itself.
+ *  This makes FTP absolute URI appear as:  ftp:host:port//root/path
+ *  To encompass older software which compacts multiple // to / in transit
+ *  We use standard URI-encoding on the second / making it 
+ *  ftp:host:port/%2froot/path  AKA 'the FTP %2f hack'.
+ */
+const char *
+ftpUrlWith2f(HttpRequest * request)
 {
-    LOCAL_ARRAY(char, buf, MAX_URL);
-    LOCAL_ARRAY(char, loginbuf, MAX_LOGIN_SZ + 1);
-    LOCAL_ARRAY(char, portbuf, 32);
-    char *t;
-    portbuf[0] = '\0';
+    String newbuf = "%2f";
 
     if (request->protocol != PROTO_FTP)
         return NULL;
 
-    if (request->port != urlDefaultPort(request->protocol))
-        snprintf(portbuf, 32, ":%d", request->port);
-
-    loginbuf[0] = '\0';
-
-    if ((int) strlen(request->login) > 0) {
-        xstrncpy(loginbuf, request->login, sizeof(loginbuf) - 2);
-
-        if ((t = strchr(loginbuf, ':')))
-            *t = '\0';
-
-        strcat(loginbuf, "@");
+    if( !strncmp(request->urlpath.buf(), "/", 1) ) {
+        newbuf.append(request->urlpath);
+        request->urlpath.absorb(newbuf);
+        safe_free(request->canonical);
+    }
+    else if( !strncmp(request->urlpath.buf(), "%2f", 3) ) {
+        newbuf.append(request->urlpath.buf() +1);
+        request->urlpath.absorb(newbuf);
+        safe_free(request->canonical);
     }
 
-    snprintf(buf, MAX_URL, "%s://%s%s%s%s%s",
-             ProtocolStr[request->protocol],
-             loginbuf,
-             request->host,
-             portbuf,
-             "/%2f",
-             request->urlpath.buf());
-
-    if ((t = strchr(buf, '?')))
-        *t = '\0';
-
-    return buf;
+    return urlCanonical(request);
 }
 
 void
index d34a28d165acf6d4c7e18b9fcb90d6ecd8aa2e71..1df6f337728437c98a6316b91617f97cbc1b18ef 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: globals.h,v 1.141 2007/08/13 17:20:51 hno Exp $
+ * $Id: globals.h,v 1.142 2007/12/14 23:11:46 amosjeffries Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -55,7 +55,6 @@ extern "C"
     extern const char *cfg_filename;   /* NULL */
     extern const char *const appname;  /* "squid" */
     extern const char *const dash_str; /* "-" */
-    extern const char *const localhost;        /* "127.0.0.1" */
     extern const char *const null_string;      /* "" */
     extern const char *const version_string;   /* VERSION */
     extern const char *const full_appname_string;      /* PACKAGE "/" VERSION */
@@ -112,17 +111,9 @@ extern "C"
 
     extern struct _acl_deny_info_list *DenyInfoList;   /* NULL */
 
-    extern struct IN_ADDR any_addr;
+    extern IPAddress theOutICPAddr;
 
-    extern struct IN_ADDR local_addr;
-
-    extern struct IN_ADDR no_addr;
-
-    extern struct IN_ADDR theOutICPAddr;
-
-    extern struct IN_ADDR theOutSNMPAddr;
-
-    extern struct timeval current_time;
+    extern IPAddress theOutSNMPAddr;
 
     extern struct timeval squid_start;
     extern int shutting_down;  /* 0 */
@@ -135,7 +126,6 @@ extern "C"
     extern char *swap_log_op_str[];
     extern char *lookup_t_str[];
     extern double request_failure_ratio;       /* 0.0 */
-    extern double current_dtime;
     extern int store_hash_buckets;     /* 0 */
     extern hash_table *store_table;    /* NULL */
     extern dlink_list ClientActiveRequests;
index b95c28a61d71b2fc5e2045edb5a3978acae1ab39..7be7352bde007f41d5371240bb1dfd3a93b5b27c 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: helper.cc,v 1.90 2007/11/13 21:25:35 rousskov Exp $
+ * $Id: helper.cc,v 1.91 2007/12/14 23:11:46 amosjeffries Exp $
  *
  * DEBUG: section 84    Helper process maintenance
  * AUTHOR: Harvest Derived?
@@ -120,6 +120,7 @@ helperOpenServers(helper * hlp)
                         progname,
                         args,
                         shortname,
+                        hlp->addr,
                         &rfd,
                         &wfd,
                         &hIpc);
@@ -136,6 +137,7 @@ helperOpenServers(helper * hlp)
         srv->hIpc = hIpc;
         srv->pid = pid;
         srv->index = k;
+        srv->addr = hlp->addr;
         srv->rfd = rfd;
         srv->wfd = wfd;
         srv->rbuf = (char *)memAllocBuf(8192, &srv->rbuf_sz);
@@ -219,6 +221,7 @@ helperStatefulOpenServers(statefulhelper * hlp)
                         progname,
                         args,
                         shortname,
+                        hlp->addr,
                         &rfd,
                         &wfd,
                         &hIpc);
@@ -241,6 +244,7 @@ helperStatefulOpenServers(statefulhelper * hlp)
         srv->stats.submits = 0;
         srv->stats.releases = 0;
         srv->index = k;
+        srv->addr = hlp->addr;
         srv->rfd = rfd;
         srv->wfd = wfd;
         srv->rbuf = (char *)memAllocBuf(8192, &srv->rbuf_sz);
index 67992019d0f81f5e98b49c0fa06d4cddbf23dfe8..504fc1726b1198242a5ec34fb7326b76156732da 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: helper.h,v 1.9 2007/05/07 18:38:40 wessels Exp $
+ * $Id: helper.h,v 1.10 2007/12/14 23:11:46 amosjeffries Exp $
  *
  * DEBUG: section 84    Helper process maintenance
  * AUTHOR: Harvest Derived?
@@ -38,6 +38,7 @@
 
 #include "squid.h"
 #include "cbdata.h"
+#include "IPAddress.h"
 
 class helper_request;
 
@@ -65,6 +66,7 @@ struct _helper
     int n_running;
     int n_active;
     int ipc_type;
+    IPAddress addr;
     unsigned int concurrency;
     time_t last_queue_warn;
     time_t last_restart;
@@ -90,6 +92,7 @@ struct _helper_stateful
     int n_running;
     int n_active;
     int ipc_type;
+    IPAddress addr;
     MemAllocator *datapool;
     HLPSAVAIL *IsAvailable;
     HLPSONEQ *OnEmptyQueue;
@@ -111,6 +114,7 @@ struct _helper_server
 {
     int index;
     int pid;
+    IPAddress addr;
     int rfd;
     int wfd;
     MemBuf *wqueue;
@@ -149,6 +153,7 @@ unsigned int shutdown:
     }
 
     stats;
+
     void *hIpc;
 };
 
@@ -158,6 +163,7 @@ struct _helper_stateful_server
 {
     int index;
     int pid;
+    IPAddress addr;
     int rfd;
     int wfd;
     /* MemBuf wqueue; */
index 6a9ce5455dd4c9b6ce4f39175fba6988b8ca9d38..0455090d8c6b367e3979bdafde97bef576206987 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: htcp.cc,v 1.77 2007/11/15 16:47:35 wessels Exp $
+ * $Id: htcp.cc,v 1.78 2007/12/14 23:11:46 amosjeffries Exp $
  *
  * DEBUG: section 31    Hypertext Caching Protocol
  * AUTHOR: Duane Wesssels
@@ -182,7 +182,7 @@ public:
     void checkHit();
     void checkedHit(StoreEntry *e);
 
-    void setFrom (struct sockaddr_in *from);
+    void setFrom (IPAddress &from);
     void setDataHeader (htcpDataHeader *);
     char *method;
     char *uri;
@@ -193,7 +193,7 @@ public:
 private:
     HttpRequest *checkHitRequest;
 
-    struct sockaddr_in *from;
+    IPAddress from; // was a ptr. return to such IFF needed. otherwise copy should do.
     htcpDataHeader *dhdr;
 };
 
@@ -263,7 +263,7 @@ static int htcpOutSocket = -1;
 static u_int32_t queried_id[N_QUERIED_KEYS];
 static cache_key queried_keys[N_QUERIED_KEYS][SQUID_MD5_DIGEST_LENGTH];
 
-static struct sockaddr_in queried_addr[N_QUERIED_KEYS];
+static IPAddress queried_addr[N_QUERIED_KEYS];
 static MemAllocator *htcpDetailPool = NULL;
 
 static int old_squid_format = 0;
@@ -282,26 +282,26 @@ static ssize_t htcpBuildTstOpData(char *buf, size_t buflen, htcpStuff * stuff);
 static void htcpFreeSpecifier(htcpSpecifier * s);
 static void htcpFreeDetail(htcpDetail * s);
 
-static void htcpHandle(char *buf, int sz, struct sockaddr_in *from);
+static void htcpHandle(char *buf, int sz, IPAddress &from);
 
-static void htcpHandleData(char *buf, int sz, struct sockaddr_in *from);
+static void htcpHandleData(char *buf, int sz, IPAddress &from);
 
-static void htcpHandleMon(htcpDataHeader *, char *buf, int sz, struct sockaddr_in *from);
+static void htcpHandleMon(htcpDataHeader *, char *buf, int sz, IPAddress &from);
 
-static void htcpHandleNop(htcpDataHeader *, char *buf, int sz, struct sockaddr_in *from);
+static void htcpHandleNop(htcpDataHeader *, char *buf, int sz, IPAddress &from);
 
-static void htcpHandleSet(htcpDataHeader *, char *buf, int sz, struct sockaddr_in *from);
+static void htcpHandleSet(htcpDataHeader *, char *buf, int sz, IPAddress &from);
 
-static void htcpHandleTst(htcpDataHeader *, char *buf, int sz, struct sockaddr_in *from);
+static void htcpHandleTst(htcpDataHeader *, char *buf, int sz, IPAddress &from);
 static void htcpRecv(int fd, void *data);
 
-static void htcpSend(const char *buf, int len, struct sockaddr_in *to);
+static void htcpSend(const char *buf, int len, IPAddress &to);
 
-static void htcpTstReply(htcpDataHeader *, StoreEntry *, htcpSpecifier *, struct sockaddr_in *);
+static void htcpTstReply(htcpDataHeader *, StoreEntry *, htcpSpecifier *, IPAddress &);
 
-static void htcpHandleTstRequest(htcpDataHeader *, char *buf, int sz, struct sockaddr_in *from);
+static void htcpHandleTstRequest(htcpDataHeader *, char *buf, int sz, IPAddress &from);
 
-static void htcpHandleTstResponse(htcpDataHeader *, char *, int, struct sockaddr_in *);
+static void htcpHandleTstResponse(htcpDataHeader *, char *, int, IPAddress &);
 
 static void
 htcpHexdump(const char *tag, const char *s, int sz)
@@ -604,15 +604,15 @@ htcpBuildPacket(char *buf, size_t buflen, htcpStuff * stuff)
 
 static void
 
-htcpSend(const char *buf, int len, struct sockaddr_in *to)
+htcpSend(const char *buf, int len, IPAddress &to)
 {
     int x;
-    debugs(31, 3, "htcpSend: " << inet_ntoa(to->sin_addr) << "/" << ntohs(to->sin_port));
+
+    debugs(31, 3, "htcpSend: " << to );
     htcpHexdump("htcpSend", buf, len);
+
     x = comm_udp_sendto(htcpOutSocket,
                         to,
-
-                        sizeof(struct sockaddr_in),
                         buf,
                         len);
 
@@ -628,7 +628,7 @@ htcpSend(const char *buf, int len, struct sockaddr_in *to)
 
 void
 
-htcpSpecifier::setFrom (struct sockaddr_in *aSocket)
+htcpSpecifier::setFrom (IPAddress &aSocket)
 {
     from = aSocket;
 }
@@ -859,11 +859,11 @@ htcpUnpackDetail(char *buf, int sz)
 
 static int
 
-htcpAccessCheck(acl_access * acl, htcpSpecifier * s, struct sockaddr_in *from)
+htcpAccessCheck(acl_access * acl, htcpSpecifier * s, IPAddress &from)
 {
     ACLChecklist checklist;
-    checklist.src_addr = from->sin_addr;
-    checklist.my_addr = no_addr;
+    checklist.src_addr = from;
+    checklist.my_addr.SetNoAddr();
     checklist.request = HTTPMSGLOCK(s->request);
     checklist.accessList = cbdataReference(acl);
     /* cbdataReferenceDone() happens in either fastCheck() or ~ACLCheckList */
@@ -873,7 +873,7 @@ htcpAccessCheck(acl_access * acl, htcpSpecifier * s, struct sockaddr_in *from)
 
 static void
 
-htcpTstReply(htcpDataHeader * dhdr, StoreEntry * e, htcpSpecifier * spec, struct sockaddr_in *from)
+htcpTstReply(htcpDataHeader * dhdr, StoreEntry * e, htcpSpecifier * spec, IPAddress &from)
 {
     htcpStuff stuff;
     static char pkt[8192];
@@ -962,7 +962,7 @@ htcpTstReply(htcpDataHeader * dhdr, StoreEntry * e, htcpSpecifier * spec, struct
 
 static void
 
-htcpClrReply(htcpDataHeader * dhdr, int purgeSucceeded, struct sockaddr_in *from)
+htcpClrReply(htcpDataHeader * dhdr, int purgeSucceeded, IPAddress &from)
 {
     htcpStuff stuff;
     static char pkt[8192];
@@ -1000,7 +1000,7 @@ htcpClrReply(htcpDataHeader * dhdr, int purgeSucceeded, struct sockaddr_in *from
 
 static void
 
-htcpHandleNop(htcpDataHeader * hdr, char *buf, int sz, struct sockaddr_in *from)
+htcpHandleNop(htcpDataHeader * hdr, char *buf, int sz, IPAddress &from)
 {
     debugs(31, 3, "htcpHandleNop: Unimplemented");
 }
@@ -1038,23 +1038,18 @@ htcpSpecifier::created (StoreEntry *e)
 
     if (e->isNull()) {
         debugs(31, 3, "htcpCheckHit: NO; public object not found");
-        goto miss;
     }
-
-    if (!e->validToSend()) {
+    else if (!e->validToSend()) {
         debugs(31, 3, "htcpCheckHit: NO; entry not valid to send" );
-        goto miss;
     }
-
-    if (refreshCheckHTCP(e, checkHitRequest)) {
+    else if (refreshCheckHTCP(e, checkHitRequest)) {
         debugs(31, 3, "htcpCheckHit: NO; cached response is stale");
-        goto miss;
+    }
+    else {
+        debugs(31, 3, "htcpCheckHit: YES!?");
+        hit = e;
     }
 
-    debugs(31, 3, "htcpCheckHit: YES!?");
-    hit = e;
-
-miss:
     checkedHit (hit);
 }
 
@@ -1105,7 +1100,7 @@ htcpClrStore(const htcpSpecifier * s)
 
 static void
 
-htcpHandleTst(htcpDataHeader * hdr, char *buf, int sz, struct sockaddr_in *from)
+htcpHandleTst(htcpDataHeader * hdr, char *buf, int sz, IPAddress &from)
 {
     debugs(31, 3, "htcpHandleTst: sz = " << sz);
 
@@ -1120,22 +1115,21 @@ HtcpReplyData::HtcpReplyData() : hdr(hoHtcpReply)
 
 static void
 
-htcpHandleTstResponse(htcpDataHeader * hdr, char *buf, int sz, struct sockaddr_in *from)
+htcpHandleTstResponse(htcpDataHeader * hdr, char *buf, int sz, IPAddress &from)
 {
     htcpReplyData htcpReply;
     cache_key *key = NULL;
 
-    struct sockaddr_in *peer;
+    IPAddress *peer;
     htcpDetail *d = NULL;
     char *t;
 
-
     if (queried_id[hdr->msg_id % N_QUERIED_KEYS] != hdr->msg_id)
     {
         debugs(31, 2, "htcpHandleTstResponse: No matching query id '" <<
                hdr->msg_id << "' (expected " <<
                queried_id[hdr->msg_id % N_QUERIED_KEYS] << ") from '" <<
-               inet_ntoa(from->sin_addr) << "'");
+               from << "'");
 
         return;
     }
@@ -1144,15 +1138,15 @@ htcpHandleTstResponse(htcpDataHeader * hdr, char *buf, int sz, struct sockaddr_i
 
     if (!key)
     {
-        debugs(31, 1, "htcpHandleTstResponse: No query key for response id '" << hdr->msg_id << "' from '" << inet_ntoa(from->sin_addr) << "'");
+        debugs(31, 1, "htcpHandleTstResponse: No query key for response id '" << hdr->msg_id << "' from '" << from << "'");
         return;
     }
 
     peer = &queried_addr[hdr->msg_id % N_QUERIED_KEYS];
 
-    if (peer->sin_addr.s_addr != from->sin_addr.s_addr || peer->sin_port != from->sin_port)
+    if ( *peer != from || peer->GetPort() != from.GetPort() )
     {
-        debugs(31, 1, "htcpHandleTstResponse: Unexpected response source " << inet_ntoa(from->sin_addr));
+        debugs(31, 1, "htcpHandleTstResponse: Unexpected response source " << from );
         return;
     }
 
@@ -1199,7 +1193,7 @@ htcpHandleTstResponse(htcpDataHeader * hdr, char *buf, int sz, struct sockaddr_i
 
 static void
 
-htcpHandleTstRequest(htcpDataHeader * dhdr, char *buf, int sz, struct sockaddr_in *from)
+htcpHandleTstRequest(htcpDataHeader * dhdr, char *buf, int sz, IPAddress &from)
 {
     /* buf should be a SPECIFIER */
     htcpSpecifier *s;
@@ -1258,21 +1252,21 @@ htcpSpecifier::checkedHit(StoreEntry *e)
 
 static void
 
-htcpHandleMon(htcpDataHeader * hdr, char *buf, int sz, struct sockaddr_in *from)
+htcpHandleMon(htcpDataHeader * hdr, char *buf, int sz, IPAddress &from)
 {
     debugs(31, 3, "htcpHandleMon: Unimplemented");
 }
 
 static void
 
-htcpHandleSet(htcpDataHeader * hdr, char *buf, int sz, struct sockaddr_in *from)
+htcpHandleSet(htcpDataHeader * hdr, char *buf, int sz, IPAddress &from)
 {
     debugs(31, 3, "htcpHandleSet: Unimplemented");
 }
 
 static void
 
-htcpHandleClr(htcpDataHeader * hdr, char *buf, int sz, struct sockaddr_in *from)
+htcpHandleClr(htcpDataHeader * hdr, char *buf, int sz, IPAddress &from)
 {
     htcpSpecifier *s;
     /* buf[0/1] is reserved and reason */
@@ -1331,7 +1325,7 @@ htcpHandleClr(htcpDataHeader * hdr, char *buf, int sz, struct sockaddr_in *from)
 
 static void
 
-htcpHandleData(char *buf, int sz, struct sockaddr_in *from)
+htcpHandleData(char *buf, int sz, IPAddress &from)
 {
     htcpDataHeader hdr;
 
@@ -1364,7 +1358,7 @@ htcpHandleData(char *buf, int sz, struct sockaddr_in *from)
 
     if (hdr.opcode >= HTCP_END)
     {
-        debugs(31, 1, "htcpHandleData: client " << inet_ntoa(from->sin_addr) << ", opcode " << hdr.opcode << " out of range");
+        debugs(31, 1, "htcpHandleData: client " << from << ", opcode " << hdr.opcode << " out of range");
         return;
     }
 
@@ -1424,7 +1418,7 @@ htcpHandleData(char *buf, int sz, struct sockaddr_in *from)
 
 static void
 
-htcpHandle(char *buf, int sz, struct sockaddr_in *from)
+htcpHandle(char *buf, int sz, IPAddress &from)
 {
     htcpHeader htcpHdr;
     assert (sz >= 0);
@@ -1451,17 +1445,14 @@ htcpHandle(char *buf, int sz, struct sockaddr_in *from)
     if (sz != htcpHdr.length)
     {
         debugs(31, 1, "htcpHandle: sz/" << sz << " != htcpHdr.length/" <<
-               htcpHdr.length << " from " << inet_ntoa(from->sin_addr) << ":" <<
-               (int) ntohs(from->sin_port));
+               htcpHdr.length << " from " << from );
 
         return;
     }
 
     if (htcpHdr.major != 0)
     {
-        debugs(31, 1, "htcpHandle: Unknown major version " << htcpHdr.major <<
-               " from " << inet_ntoa(from->sin_addr) << ":" <<
-               (int) ntohs(from->sin_port));
+        debugs(31, 1, "htcpHandle: Unknown major version " << htcpHdr.major << " from " << from );
 
         return;
     }
@@ -1476,22 +1467,18 @@ htcpRecv(int fd, void *data)
 {
     static char buf[8192];
     int len;
-
-    static struct sockaddr_in from;
-
-    socklen_t flen = sizeof(struct sockaddr_in);
-    memset(&from, '\0', flen);
+    static IPAddress from;
 
     /* Receive up to 8191 bytes, leaving room for a null */
 
-    len = comm_udp_recvfrom(fd, buf, sizeof(buf) - 1, 0, (struct sockaddr *) &from, &flen);
-    debugs(31, 3, "htcpRecv: FD " << fd << ", " << len << " bytes from " <<
-           inet_ntoa(from.sin_addr) << ":" << ntohs(from.sin_port));
+    len = comm_udp_recvfrom(fd, buf, sizeof(buf) - 1, 0, from);
+
+    debugs(31, 3, "htcpRecv: FD " << fd << ", " << len << " bytes from " << from );
 
     if (len)
         statCounter.htcp.pkts_recv++;
 
-    htcpHandle(buf, len, &from);
+    htcpHandle(buf, len, from);
 
     commSetSelect(fd, COMM_SELECT_READ, htcpRecv, NULL, 0);
 }
@@ -1505,16 +1492,19 @@ htcpRecv(int fd, void *data)
 void
 htcpInit(void)
 {
+    IPAddress sendOn;
+
     if (Config.Port.htcp <= 0) {
         debugs(31, 1, "HTCP Disabled.");
         return;
     }
+    sendOn = Config.Addrs.udp_outgoing;
+    sendOn.SetPort(Config.Port.htcp);
 
     enter_suid();
     htcpInSocket = comm_open(SOCK_DGRAM,
                              IPPROTO_UDP,
-                             Config.Addrs.udp_incoming,
-                             Config.Port.htcp,
+                             sendOn,
                              COMM_NONBLOCKING,
                              "HTCP Socket");
     leave_suid();
@@ -1526,12 +1516,11 @@ htcpInit(void)
 
     debugs(31, 1, "Accepting HTCP messages on port " << Config.Port.htcp << ", FD " << htcpInSocket << ".");
 
-    if (Config.Addrs.udp_outgoing.s_addr != no_addr.s_addr) {
+    if (!Config.Addrs.udp_outgoing.IsNoAddr()) {
         enter_suid();
         htcpOutSocket = comm_open(SOCK_DGRAM,
                                   IPPROTO_UDP,
-                                  Config.Addrs.udp_outgoing,
-                                  Config.Port.htcp,
+                                  sendOn,
                                   COMM_NONBLOCKING,
                                   "Outgoing HTCP Socket");
         leave_suid();
@@ -1615,7 +1604,8 @@ htcpQuery(StoreEntry * e, HttpRequest * req, peer * p)
         return;
     }
 
-    htcpSend(pkt, (int) pktlen, &p->in_addr);
+    htcpSend(pkt, (int) pktlen, p->in_addr);
+
     queried_id[stuff.msg_id % N_QUERIED_KEYS] = stuff.msg_id;
     save_key = queried_keys[stuff.msg_id % N_QUERIED_KEYS];
     storeKeyCopy(save_key, (const cache_key *)e->key);
index 5f3791462c3b44e3aeb4872072b632926190d34e..992dc77a8f34ea2b4086e0235da87c8a8d7203a9 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: htcp.h,v 1.5 2003/08/10 11:00:43 robertc Exp $
+ * $Id: htcp.h,v 1.6 2007/12/14 23:11:47 amosjeffries Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -36,6 +36,7 @@
 
 #if USE_HTCP
 #include "HttpHeader.h"
+#include "IPAddress.h"
 
 class HtcpReplyData
 {
@@ -60,7 +61,7 @@ public:
 
 typedef class HtcpReplyData htcpReplyData;
 
-SQUIDCEXTERN void neighborsHtcpReply(const cache_key *, htcpReplyData *, const struct sockaddr_in *);
+SQUIDCEXTERN void neighborsHtcpReply(const cache_key *, htcpReplyData *, const IPAddress &);
 SQUIDCEXTERN void htcpInit(void);
 SQUIDCEXTERN void htcpQuery(StoreEntry * e, HttpRequest * req, peer * p);
 SQUIDCEXTERN void htcpSocketShutdown(void);
index 41913774a451ff573978639b771d860714c6fafb..33c4a8d416fef3858ba667fc3b87fa08742926bb 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: http.cc,v 1.541 2007/11/18 22:00:58 hno Exp $
+ * $Id: http.cc,v 1.542 2007/12/14 23:11:47 amosjeffries Exp $
  *
  * DEBUG: section 11    Hypertext Transfer Protocol (HTTP)
  * AUTHOR: Harvest Derived
@@ -92,7 +92,7 @@ HttpStateData::HttpStateData(FwdState *theFwdState) : ServerStateData(theFwdStat
         HttpRequest * proxy_req = new HttpRequest(orig_request->method,
                                   orig_request->protocol, url);
 
-        xstrncpy(proxy_req->host, _peer->host, SQUIDHOSTNAMELEN);
+        proxy_req->SetHost(_peer->host);
 
         proxy_req->port = _peer->http_port;
 
@@ -672,7 +672,7 @@ HttpStateData::checkDateSkew(HttpReply *reply)
         int skew = abs((int)(reply->date - squid_curtime));
 
         if (skew > 86400)
-            debugs(11, 3, "" << request->host << "'s clock is skewed by " << skew << " seconds!");
+            debugs(11, 3, "" << request->GetHost() << "'s clock is skewed by " << skew << " seconds!");
     }
 }
 
@@ -1115,7 +1115,7 @@ void
 HttpStateData::processReplyBody()
 {
 
-    struct IN_ADDR *client_addr = NULL;
+    IPAddress client_addr;
 
     if (!flags.headers_parsed) {
         flags.do_next_read = 1;
@@ -1170,17 +1170,17 @@ HttpStateData::processReplyBody()
 #if LINUX_TPROXY
 
             if (orig_request->flags.tproxy)
-                client_addr = &orig_request->client_addr;
+                client_addr = orig_request->client_addr;
 
 #endif
 
             if (_peer) {
                 if (_peer->options.originserver)
-                    fwd->pconnPush(fd, _peer->name, orig_request->port, orig_request->host, client_addr);
+                    fwd->pconnPush(fd, _peer->name, orig_request->port, orig_request->GetHost(), client_addr);
                 else
                     fwd->pconnPush(fd, _peer->name, _peer->http_port, NULL, client_addr);
             } else {
-                fwd->pconnPush(fd, request->host, request->port, NULL, client_addr);
+                fwd->pconnPush(fd, request->GetHost(), request->port, NULL, client_addr);
             }
 
             fd = -1;
@@ -1356,8 +1356,10 @@ HttpStateData::httpBuildRequestHeader(HttpRequest * request,
     /* append X-Forwarded-For */
     strFwd = hdr_in->getList(HDR_X_FORWARDED_FOR);
 
-    if (opt_forwarded_for && orig_request->client_addr.s_addr != no_addr.s_addr)
-        strListAdd(&strFwd, inet_ntoa(orig_request->client_addr), ',');
+    if (opt_forwarded_for && !orig_request->client_addr.IsNoAddr()) {
+        orig_request->client_addr.NtoA(bbuf,MAX_IPSTRLEN);
+        strListAdd(&strFwd, bbuf, ',');
+    }
     else
         strListAdd(&strFwd, "unknown", ',');
 
@@ -1371,10 +1373,11 @@ HttpStateData::httpBuildRequestHeader(HttpRequest * request,
             hdr_out->putStr(HDR_HOST, orig_request->peer_domain);
         } else if (orig_request->port == urlDefaultPort(orig_request->protocol)) {
             /* use port# only if not default */
-            hdr_out->putStr(HDR_HOST, orig_request->host);
+            hdr_out->putStr(HDR_HOST, orig_request->GetHost());
         } else {
             httpHeaderPutStrf(hdr_out, HDR_HOST, "%s:%d",
-                              orig_request->host, (int) orig_request->port);
+                              orig_request->GetHost(),
+                              (int) orig_request->port);
         }
     }
 
@@ -1566,10 +1569,11 @@ copyOneHeaderFromClientsideRequestToUpstreamRequest(const HttpHeaderEntry *e, St
             /* use port# only if not default */
 
             if (orig_request->port == urlDefaultPort(orig_request->protocol)) {
-                hdr_out->putStr(HDR_HOST, orig_request->host);
+                hdr_out->putStr(HDR_HOST, orig_request->GetHost());
             } else {
                 httpHeaderPutStrf(hdr_out, HDR_HOST, "%s:%d",
-                                  orig_request->host, (int) orig_request->port);
+                                  orig_request->GetHost(),
+                                  (int) orig_request->port);
             }
         }
 
@@ -1818,7 +1822,7 @@ HttpStateData::handleMoreRequestBodyAvailable()
 
         if (flags.headers_parsed && !flags.abuse_detected) {
             flags.abuse_detected = 1;
-            debugs(11, 1, "http handleMoreRequestBodyAvailable: Likely proxy abuse detected '" << inet_ntoa(orig_request->client_addr) << "' -> '" << entry->url() << "'" );
+            debugs(11, 1, "http handleMoreRequestBodyAvailable: Likely proxy abuse detected '" << orig_request->client_addr << "' -> '" << entry->url() << "'" );
 
             if (virginReply()->sline.status == HTTP_INVALID_HEADER) {
                 comm_close(fd);
index 51d4d797a545741686a224de2c548c30992306cd..ab4e77ec13c18005af1627897fdfc9504fed2ee0 100644 (file)
@@ -1,9 +1,8 @@
-
 /*
- * $Id: icmp.cc,v 1.93 2007/04/30 16:56:09 wessels Exp $
+ * $Id: icmp.cc,v 1.94 2007/12/14 23:11:47 amosjeffries Exp $
  *
  * DEBUG: section 37    ICMP Routines
- * AUTHOR: Duane Wessels
+ * AUTHOR: Duane Wessels, Amos Jeffries
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
  * ----------------------------------------------------------
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
  *
  */
-
-
 #include "squid.h"
-#include "comm.h"
+#include "ICMP.h"
 #include "SquidTime.h"
+#include "Debug.h"
 
+ICMP::ICMP()
+{
 #if USE_ICMP
-
-#define S_ICMP_ECHO    1
-#if ALLOW_SOURCE_PING
-#define S_ICMP_ICP     2
-#endif
-#define S_ICMP_DOM     3
-
-static PF icmpRecv;
-static void icmpSend(pingerEchoData * pkt, int len);
-#if ALLOW_SOURCE_PING
-
-static void icmpHandleSourcePing(const struct sockaddr_in *from, const char *buf);
+    icmp_sock = -1;
+    icmp_ident = 0;
 #endif
-
-static void * hIpc;
-static pid_t pid;
-
-static void
-
-icmpSendEcho(struct IN_ADDR to, int opcode, const char *payload, int len)
-{
-    static pingerEchoData pecho;
-
-    if (payload && len == 0)
-        len = strlen(payload);
-
-    assert(len <= PINGER_PAYLOAD_SZ);
-
-    pecho.to = to;
-
-    pecho.opcode = (unsigned char) opcode;
-
-    pecho.psize = len;
-
-    xmemcpy(pecho.payload, payload, len);
-
-    icmpSend(&pecho, sizeof(pingerEchoData) - PINGER_PAYLOAD_SZ + len);
 }
 
-static void
-icmpRecv(int unused1, void *unused2)
+void
+ICMP::Close()
 {
-    int n;
-    static int fail_count = 0;
-    pingerReplyData preply;
-
-    static struct sockaddr_in F;
-    commSetSelect(icmp_sock, COMM_SELECT_READ, icmpRecv, NULL, 0);
-    memset(&preply, '\0', sizeof(pingerReplyData));
-    n = comm_udp_recv(icmp_sock,
-                      (char *) &preply,
-                      sizeof(pingerReplyData),
-                      0);
-
-    if (n < 0 && EAGAIN != errno) {
-        debugs(37, 1, "icmpRecv: recv: " << xstrerror());
-
-        if (errno == ECONNREFUSED)
-            icmpClose();
-
-        if (errno == ECONNRESET)
-            icmpClose();
-
-        if (++fail_count == 10)
-            icmpClose();
-
-        return;
-    }
-
-    fail_count = 0;
-
-    if (n == 0)                        /* test probe from pinger */
-        return;
-
-    F.sin_family = AF_INET;
-
-    F.sin_addr = preply.from;
-
-    F.sin_port = 0;
-
-    switch (preply.opcode) {
-
-    case S_ICMP_ECHO:
-        break;
-#if ALLOW_SOURCE_PING
-
-    case S_ICMP_ICP:
-        icmpHandleSourcePing(&F, preply.payload);
-        break;
+#if USE_ICMP
+    if(icmp_sock > 0)
+        close(icmp_sock);
+    icmp_sock = -1;
+    icmp_ident = 0;
 #endif
-
-    case S_ICMP_DOM:
-        netdbHandlePingReply(&F, preply.hops, preply.rtt);
-        break;
-
-    default:
-        debugs(37, 1, "icmpRecv: Bad opcode: " << preply.opcode);
-        break;
-    }
 }
 
-static void
-icmpSend(pingerEchoData * pkt, int len)
-{
-    int x;
-
-    if (icmp_sock < 0)
-        return;
+#if USE_ICMP
 
-    debugs(37, 2, "icmpSend: to " << inet_ntoa(pkt->to) << ", opcode " <<
-           (int) pkt->opcode << ", len " << pkt->psize);
+int
+ICMP::CheckSum(unsigned short *ptr, int size)
+{
+    long sum;
+    unsigned short oddbyte;
+    unsigned short answer;
 
-    x = comm_udp_send(icmp_sock, (char *) pkt, len, 0);
+    if(!ptr) return 65535; // bad input.
 
-    if (x < 0) {
-        debugs(37, 1, "icmpSend: send: " << xstrerror());
+    sum = 0;
 
-        if (errno == ECONNREFUSED || errno == EPIPE) {
-            icmpClose();
-            return;
-        }
-    } else if (x != len) {
-        debugs(37, 1, "icmpSend: Wrote " << x << " of " << len << " bytes");
+    while (size > 1) {
+        sum += *ptr++;
+        size -= 2;
     }
-}
 
-#if ALLOW_SOURCE_PING
-static void
-
-icmpHandleSourcePing(const struct sockaddr_in *from, const char *buf)
-{
-    const cache_key *key;
-    icp_common_t header;
-    const char *url;
-    xmemcpy(&header, buf, sizeof(icp_common_t));
-    url = buf + sizeof(icp_common_t);
-    key = icpGetCacheKey(url, (int) header.reqnum);
-    debugs(37, 3, "icmpHandleSourcePing: from " << inet_ntoa(from->sin_addr) << ", key '" << storeKeyText(key) << "'");
+    if (size == 1) {
+        oddbyte = 0;
+        *((unsigned char *) &oddbyte) = *(unsigned char *) ptr;
+        sum += oddbyte;
+    }
 
-    /* call neighborsUdpAck even if ping_status != PING_WAITING */
-    neighborsUdpAck(key, &header, from);
+    sum = (sum >> 16) + (sum & 0xffff);
+    sum += (sum >> 16);
+    answer = (unsigned short) ~sum;
+    return (answer);
 }
 
-#endif
-
-#endif /* USE_ICMP */
-
-#if ALLOW_SOURCE_PING
-void
-
-icmpSourcePing(struct IN_ADDR to, const icp_common_t * header, const char *url)
+int
+ICMP::ipHops(int ttl)
 {
-#if USE_ICMP
-    char *payload;
-    int len;
-    int ulen;
-    debugs(37, 3, "icmpSourcePing: '" << url << "'");
-
-    if ((ulen = strlen(url)) > MAX_URL)
-        return;
-
-    payload = memAllocate(MEM_8K_BUF);
-
-    len = sizeof(icp_common_t);
+    if (ttl < 33)
+        return 33 - ttl;
 
-    xmemcpy(payload, header, len);
+    if (ttl < 63)
+        return 63 - ttl;        /* 62 = (64+60)/2 */
 
-    strcpy(payload + len, url);
-
-    len += ulen + 1;
-
-    icmpSendEcho(to, S_ICMP_ICP, payload, len);
-
-    memFree(payload, MEM_8K_BUF);
-
-#endif
-}
+    if (ttl < 65)
+        return 65 - ttl;        /* 62 = (64+60)/2 */
 
-#endif
+    if (ttl < 129)
+        return 129 - ttl;
 
-void
+    if (ttl < 193)
+        return 193 - ttl;
 
-icmpDomainPing(struct IN_ADDR to, const char *domain)
-{
-#if USE_ICMP
-    debugs(37, 3, "icmpDomainPing: '" << domain << "'");
-    icmpSendEcho(to, S_ICMP_DOM, domain, 0);
-#endif
+    return 256 - ttl;
 }
 
 void
-icmpOpen(void)
+ICMP::Log(const IPAddress &addr, const u_int8_t type, const char* pkt_str, const int rtt, const int hops)
 {
-#if USE_ICMP
-    const char *args[2];
-    int rfd;
-    int wfd;
-    args[0] = "(pinger)";
-    args[1] = NULL;
-    /*
-     * Do NOT use IPC_DGRAM (=IPC_UNIX_DGRAM) here because you can't
-     * send() more than 4096 bytes on a socketpair() socket (at
-     * least on FreeBSD).
-     */
-    pid = ipcCreate(IPC_UDP_SOCKET,
-                    Config.Program.pinger,
-                    args,
-                    "Pinger Socket",
-                    &rfd,
-                    &wfd,
-                    &hIpc);
-
-    if (pid < 0)
-        return;
-
-    assert(rfd == wfd);
-
-    icmp_sock = rfd;
-
-    fd_note(icmp_sock, "pinger");
-
-    commSetSelect(icmp_sock, COMM_SELECT_READ, icmpRecv, NULL, 0);
-
-    commSetTimeout(icmp_sock, -1, NULL, NULL);
-
-    debugs(37, 1, "Pinger socket opened on FD " << icmp_sock);
-
-#ifdef _SQUID_MSWIN_
-
-    debugs(37, 4, "Pinger handle: 0x" << std::hex << hIpc << std::dec << ", PID: " << pid);
-
-#endif
-#endif
+    debugs(42, 2, "pingerLog: " << std::setw(9) << current_time.tv_sec  <<
+           "." << std::setfill('0') << std::setw(6) <<
+           current_time.tv_usec  << " " << std::left << std::setfill(' ') <<
+           std::setw(45) << addr  << " " << type  <<
+           " " << std::setw(15) << pkt_str << " " << rtt  <<
+           "ms " << hops  << " hops");
 }
 
-void
-icmpClose(void)
-{
-#if USE_ICMP
-
-    if (icmp_sock < 0)
-        return;
-
-    debugs(37, 1, "Closing Pinger socket on FD " << icmp_sock);
-
-#ifdef _SQUID_MSWIN_
-
-    send(icmp_sock, (const void *) "$shutdown\n", 10, 0);
-
-#endif
-
-    comm_close(icmp_sock);
-
-#ifdef _SQUID_MSWIN_
-
-    if (hIpc) {
-        if (WaitForSingleObject(hIpc, 12000) != WAIT_OBJECT_0) {
-            getCurrentTime();
-            debugs(37, 1, "icmpClose: WARNING: (pinger," << pid << ") didn't exit in 12 seconds");
-        }
-
-        CloseHandle(hIpc);
-    }
-
-#endif
-    icmp_sock = -1;
-
-#endif
-}
+#endif /* USE_ICMP */
index 9ee1c1a9dff4ccc150bdf68431ad6d987ba46d69..771095fb954579addeb148fbeac03283aa0e9ed9 100644 (file)
@@ -1,8 +1,8 @@
 
 /*
- * $Id: icp_v2.cc,v 1.101 2007/11/15 16:47:35 wessels Exp $
+ * $Id: icp_v2.cc,v 1.102 2007/12/14 23:11:47 amosjeffries Exp $
  *
- * DEBUG: section 12    Internet Cache Protocol
+ * DEBUG: section 12    Internet Cache Protocol (ICP)
  * AUTHOR: Duane Wessels
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -45,9 +45,9 @@
 #include "SquidTime.h"
 #include "SwapDir.h"
 
-static void icpLogIcp(struct IN_ADDR, log_type, int, const char *, int);
+static void icpLogIcp(const IPAddress &, log_type, int, const char *, int);
 
-static void icpHandleIcpV2(int, struct sockaddr_in, char *, int);
+static void icpHandleIcpV2(int, IPAddress &, char *, int);
 static void icpCount(void *, int, size_t, int);
 
 /*
@@ -138,8 +138,8 @@ ICP2State::created (StoreEntry *newEntry)
         codeToSend = ICP_HIT;
     } else {
         if (Config.onoff.test_reachability && rtt == 0) {
-            if ((rtt = netdbHostRtt(request->host)) == 0)
-                netdbPingSite(request->host);
+            if ((rtt = netdbHostRtt(request->GetHost())) == 0)
+                netdbPingSite(request->GetHost());
         }
 
         if (icpGetCommonOpcode() != ICP_ERR)
@@ -150,7 +150,7 @@ ICP2State::created (StoreEntry *newEntry)
             codeToSend = ICP_MISS;
     }
 
-    icpCreateAndSend(codeToSend, flags, url, header.reqnum, src_rtt, fd, &from);
+    icpCreateAndSend(codeToSend, flags, url, header.reqnum, src_rtt, fd, from);
     delete this;
 }
 
@@ -158,7 +158,7 @@ ICP2State::created (StoreEntry *newEntry)
 
 static void
 
-icpLogIcp(struct IN_ADDR caddr, log_type logcode, int len, const char *url, int delay)
+icpLogIcp(const IPAddress &caddr, log_type logcode, int len, const char *url, int delay)
 {
     AccessLogEntry al;
 
@@ -198,7 +198,7 @@ icpUdpSendQueue(int fd, void *unused)
     while ((q = IcpQueueHead) != NULL) {
         delay = tvSubUsec(q->queue_time, current_time);
         /* increment delay to prevent looping */
-        x = icpUdpSend(fd, &q->address, (icp_common_t *) q->msg, q->logcode, ++delay);
+        x = icpUdpSend(fd, q->address, (icp_common_t *) q->msg, q->logcode, ++delay);
         IcpQueueHead = q->next;
         safe_free(q);
 
@@ -240,7 +240,7 @@ _icp_common_t::createMessage(
 
     headerp->pad = htonl(pad);
 
-    headerp->shostid = theOutICPAddr.s_addr;
+    theOutICPAddr.GetInAddr( *((struct in_addr*)&headerp->shostid) );
 
     urloffset = buf + sizeof(icp_common_t);
 
@@ -254,8 +254,7 @@ _icp_common_t::createMessage(
 
 int
 icpUdpSend(int fd,
-
-           const struct sockaddr_in *to,
+           const IPAddress &to,
            icp_common_t * msg,
            log_type logcode,
            int delay)
@@ -265,22 +264,21 @@ icpUdpSend(int fd,
     int len;
     len = (int) ntohs(msg->length);
     debugs(12, 5, "icpUdpSend: FD " << fd << " sending " <<
-           icp_opcode_str[msg->opcode] << ", " << len << " bytes to " <<
-           inet_ntoa(to->sin_addr) << ":" << ntohs(to->sin_port));
+           icp_opcode_str[msg->opcode] << ", " << len << " bytes to " << to);
 
-    x = comm_udp_sendto(fd, to, sizeof(*to), msg, len);
+    x = comm_udp_sendto(fd, to, msg, len);
 
     if (x >= 0)
     {
         /* successfully written */
-        icpLogIcp(to->sin_addr, logcode, len, (char *) (msg + 1), delay);
+        icpLogIcp(to, logcode, len, (char *) (msg + 1), delay);
         icpCount(msg, SENT, (size_t) len, delay);
         safe_free(msg);
     } else if (0 == delay)
     {
         /* send failed, but queue it */
         queue = (icpUdpData *) xcalloc(1, sizeof(icpUdpData));
-        queue->address = *to;
+        queue->address = to;
         queue->msg = msg;
         queue->len = (int) ntohs(msg->length);
         queue->queue_time = current_time;
@@ -368,7 +366,7 @@ icpLogFromICPCode(icp_opcode opcode)
 
 void
 
-icpCreateAndSend(icp_opcode opcode, int flags, char const *url, int reqnum, int pad, int fd, const struct sockaddr_in *from)
+icpCreateAndSend(icp_opcode opcode, int flags, char const *url, int reqnum, int pad, int fd, const IPAddress &from)
 {
     icp_common_t *reply = _icp_common_t::createMessage(opcode, flags, url, reqnum, pad);
     icpUdpSend(fd, from, reply, icpLogFromICPCode(opcode), 0);
@@ -376,17 +374,17 @@ icpCreateAndSend(icp_opcode opcode, int flags, char const *url, int reqnum, int
 
 void
 
-icpDenyAccess(struct sockaddr_in *from, char *url, int reqnum, int fd)
+icpDenyAccess(IPAddress &from, char *url, int reqnum, int fd)
 {
-    debugs(12, 2, "icpDenyAccess: Access Denied for " << inet_ntoa(from->sin_addr) << " by " << AclMatchedName << ".");
+    debugs(12, 2, "icpDenyAccess: Access Denied for " << from << " by " << AclMatchedName << ".");
 
-    if (clientdbCutoffDenied(from->sin_addr))
+    if (clientdbCutoffDenied(from))
     {
         /*
          * count this DENIED query in the clientdb, even though
          * we're not sending an ICP reply...
          */
-        clientdbUpdate(from->sin_addr, LOG_UDP_DENIED, PROTO_ICP, 0);
+        clientdbUpdate(from, LOG_UDP_DENIED, PROTO_ICP, 0);
     } else
     {
         icpCreateAndSend(ICP_DENIED, 0, url, reqnum, 0, fd, from);
@@ -395,11 +393,11 @@ icpDenyAccess(struct sockaddr_in *from, char *url, int reqnum, int fd)
 
 int
 
-icpAccessAllowed(struct sockaddr_in *from, HttpRequest * icp_request)
+icpAccessAllowed(IPAddress &from, HttpRequest * icp_request)
 {
     ACLChecklist checklist;
-    checklist.src_addr = from->sin_addr;
-    checklist.my_addr = no_addr;
+    checklist.src_addr = from;
+    checklist.my_addr.SetNoAddr();
     checklist.request = HTTPMSGLOCK(icp_request);
     checklist.accessList = cbdataReference(Config.accessList.icp);
     /* cbdataReferenceDone() happens in either fastCheck() or ~ACLCheckList */
@@ -418,7 +416,7 @@ icpGetUrlToSend(char *url)
 
 HttpRequest *
 
-icpGetRequest(char *url, int reqnum, int fd, struct sockaddr_in * from)
+icpGetRequest(char *url, int reqnum, int fd, IPAddress &from)
 {
     if (strpbrk(url, w_space))
     {
@@ -438,31 +436,31 @@ icpGetRequest(char *url, int reqnum, int fd, struct sockaddr_in * from)
 
 static void
 
-doV2Query(int fd, struct sockaddr_in from, char *buf, icp_common_t header)
+doV2Query(int fd, IPAddress &from, char *buf, icp_common_t header)
 {
     int rtt = 0;
     int src_rtt = 0;
     u_int32_t flags = 0;
     /* We have a valid packet */
     char *url = buf + sizeof(icp_common_t) + sizeof(u_int32_t);
-    HttpRequest *icp_request = icpGetRequest(url, header.reqnum, fd, &from);
+    HttpRequest *icp_request = icpGetRequest(url, header.reqnum, fd, from);
 
     if (!icp_request)
         return;
 
     HTTPMSGLOCK(icp_request);
 
-    if (!icpAccessAllowed(&from, icp_request))
+    if (!icpAccessAllowed(from, icp_request))
     {
-        icpDenyAccess(&from, url, header.reqnum, fd);
+        icpDenyAccess(from, url, header.reqnum, fd);
         HTTPMSGUNLOCK(icp_request);
         return;
     }
 
     if (header.flags & ICP_FLAG_SRC_RTT)
     {
-        rtt = netdbHostRtt(icp_request->host);
-        int hops = netdbHostHops(icp_request->host);
+        rtt = netdbHostRtt(icp_request->GetHost());
+        int hops = netdbHostHops(icp_request->GetHost());
         src_rtt = ((hops & 0xFFFF) << 16) | (rtt & 0xFFFF);
 
         if (rtt)
@@ -491,17 +489,17 @@ doV2Query(int fd, struct sockaddr_in from, char *buf, icp_common_t header)
 
 void
 
-_icp_common_t::handleReply(char *buf, struct sockaddr_in *from)
+_icp_common_t::handleReply(char *buf, IPAddress &from)
 {
     if (neighbors_do_private_keys && reqnum == 0)
     {
-        debugs(12, 0, "icpHandleIcpV2: Neighbor " << inet_ntoa(from->sin_addr) << " returned reqnum = 0");
+        debugs(12, 0, "icpHandleIcpV2: Neighbor " << from << " returned reqnum = 0");
         debugs(12, 0, "icpHandleIcpV2: Disabling use of private keys");
         neighbors_do_private_keys = 0;
     }
 
     char *url = buf + sizeof(icp_common_t);
-    debugs(12, 3, "icpHandleIcpV2: " << icp_opcode_str[opcode] << " from " << inet_ntoa(from->sin_addr) << " for '" << url << "'");
+    debugs(12, 3, "icpHandleIcpV2: " << icp_opcode_str[opcode] << " from " << from << " for '" << url << "'");
 
     const cache_key *key = icpGetCacheKey(url, (int) reqnum);
     /* call neighborsUdpAck even if ping_status != PING_WAITING */
@@ -510,7 +508,7 @@ _icp_common_t::handleReply(char *buf, struct sockaddr_in *from)
 
 static void
 
-icpHandleIcpV2(int fd, struct sockaddr_in from, char *buf, int len)
+icpHandleIcpV2(int fd, IPAddress &from, char *buf, int len)
 {
     if (len <= 0)
     {
@@ -538,10 +536,6 @@ icpHandleIcpV2(int fd, struct sockaddr_in from, char *buf, int len)
         break;
 
     case ICP_HIT:
-#if ALLOW_SOURCE_PING
-
-    case ICP_SECHO:
-#endif
 
     case ICP_DECHO:
 
@@ -550,7 +544,7 @@ icpHandleIcpV2(int fd, struct sockaddr_in from, char *buf, int len)
     case ICP_DENIED:
 
     case ICP_MISS_NOFETCH:
-        header.handleReply(buf, &from);
+        header.handleReply(buf, from);
         break;
 
     case ICP_INVALID:
@@ -559,7 +553,7 @@ icpHandleIcpV2(int fd, struct sockaddr_in from, char *buf, int len)
         break;
 
     default:
-        debugs(12, 0, "icpHandleIcpV2: UNKNOWN OPCODE: " << header.opcode << " from " << inet_ntoa(from.sin_addr));
+        debugs(12, 0, "icpHandleIcpV2: UNKNOWN OPCODE: " << header.opcode << " from " << from);
 
         break;
     }
@@ -570,15 +564,15 @@ static void
 icpPktDump(icp_common_t * pkt)
 {
 
-    struct IN_ADDR a;
+    IPAddress a;
 
     debugs(12, 9, "opcode:     " << std::setw(3) << pkt->opcode  << " " << icp_opcode_str[pkt->opcode]);
     debugs(12, 9, "version: "<< std::left << std::setw(8) << pkt->version);
     debugs(12, 9, "length:  "<< std::left << std::setw(8) << ntohs(pkt->length));
     debugs(12, 9, "reqnum:  "<< std::left << std::setw(8) << ntohl(pkt->reqnum));
     debugs(12, 9, "flags:   "<< std::left << std::hex << std::setw(8) << ntohl(pkt->flags));
-    a.s_addr = pkt->shostid;
-    debugs(12, 9, "shostid: " << inet_ntoa(a));
+    a = (struct in_addr)pkt->shostid;
+    debugs(12, 9, "shostid: " << );
     debugs(12, 9, "payload: " << (char *) pkt + sizeof(icp_common_t));
 }
 
@@ -589,8 +583,7 @@ icpHandleUdp(int sock, void *data)
 {
     int *N = &incoming_sockets_accepted;
 
-    struct sockaddr_in from;
-    socklen_t from_len;
+    IPAddress from;
     LOCAL_ARRAY(char, buf, SQUID_UDP_SO_RCVBUF);
     int len;
     int icp_version;
@@ -598,15 +591,11 @@ icpHandleUdp(int sock, void *data)
     commSetSelect(sock, COMM_SELECT_READ, icpHandleUdp, NULL, 0);
 
     while (max--) {
-        from_len = sizeof(from);
-        memset(&from, '\0', from_len);
         len = comm_udp_recvfrom(sock,
                                 buf,
                                 SQUID_UDP_SO_RCVBUF - 1,
                                 0,
-
-                                (struct sockaddr *) &from,
-                                &from_len);
+                                from);
 
         if (len == 0)
             break;
@@ -632,8 +621,7 @@ icpHandleUdp(int sock, void *data)
         icpCount(buf, RECV, (size_t) len, 0);
         buf[len] = '\0';
         debugs(12, 4, "icpHandleUdp: FD " << sock << ": received " <<
-               (unsigned long int)len << " bytes from " <<
-               inet_ntoa(from.sin_addr) << ".");
+               (unsigned long int)len << " bytes from " << from);
 
 #ifdef ICP_PACKET_DUMP
 
@@ -653,7 +641,7 @@ icpHandleUdp(int sock, void *data)
             icpHandleIcpV3(sock, from, buf, len);
         else
         debugs(12, 1, "WARNING: Unused ICP version " << icp_version <<
-               " received from " << inet_ntoa(from.sin_addr) << ":" << ntohs(from.sin_port));
+               " received from " << from);
     }
 }
 
@@ -662,11 +650,10 @@ icpConnectionsOpen(void)
 {
     u_int16_t port;
 
-    struct IN_ADDR addr;
+    IPAddress addr;
 
-    struct sockaddr_in xaddr;
+    struct addrinfo *xai = NULL;
     int x;
-    socklen_t len;
     wordlist *s;
 
     if ((port = Config.Port.icp) <= 0)
@@ -674,13 +661,13 @@ icpConnectionsOpen(void)
 
     enter_suid();
 
+    addr = Config.Addrs.udp_incoming;
+    addr.SetPort(port);
     theInIcpConnection = comm_open(SOCK_DGRAM,
                                    IPPROTO_UDP,
-                                   Config.Addrs.udp_incoming,
-                                   port,
+                                   addr,
                                    COMM_NONBLOCKING,
                                    "ICP Socket");
-
     leave_suid();
 
     if (theInIcpConnection < 0)
@@ -695,17 +682,16 @@ icpConnectionsOpen(void)
     for (s = Config.mcast_group_list; s; s = s->next)
         ipcache_nbgethostbyname(s->key, mcastJoinGroups, NULL);
 
-        debugs(12, 1, "Accepting ICP messages at " <<
-               inet_ntoa(Config.Addrs.udp_incoming) << ", port " << (int) port <<
-               ", FD " << theInIcpConnection << ".");
-
+    debugs(12, 1, "Accepting ICP messages at " << addr << ", FD " << theInIcpConnection << ".");
 
-    if ((addr = Config.Addrs.udp_outgoing).s_addr != no_addr.s_addr) {
+    addr.SetEmpty(); // clear for next use.
+    addr = Config.Addrs.udp_outgoing;
+    if ( !addr.IsNoAddr() ) {
         enter_suid();
+        addr.SetPort(port);
         theOutIcpConnection = comm_open(SOCK_DGRAM,
                                         IPPROTO_UDP,
                                         addr,
-                                        port,
                                         COMM_NONBLOCKING,
                                         "ICP Port");
         leave_suid();
@@ -719,7 +705,7 @@ icpConnectionsOpen(void)
                       NULL,
                       0);
 
-        debugs(12, 1, "Outgoing ICP messages on port " << port << ", FD " << theOutIcpConnection << ".");
+        debugs(12, 1, "Outgoing ICP messages on port " << addr.GetPort() << ", FD " << theOutIcpConnection << ".");
 
         fd_note(theOutIcpConnection, "Outgoing ICP socket");
 
@@ -728,18 +714,18 @@ icpConnectionsOpen(void)
         theOutIcpConnection = theInIcpConnection;
     }
 
-    memset(&theOutICPAddr, '\0', sizeof(struct IN_ADDR));
+    theOutICPAddr.SetEmpty();
 
-    len = sizeof(struct sockaddr_in);
-    memset(&xaddr, '\0', len);
-    x = getsockname(theOutIcpConnection,
+    theOutICPAddr.InitAddrInfo(xai);
 
-                    (struct sockaddr *) &xaddr, &len);
+    x = getsockname(theOutIcpConnection, xai->ai_addr, &xai->ai_addrlen);
 
     if (x < 0)
         debugs(50, 1, "theOutIcpConnection FD " << theOutIcpConnection << ": getsockname: " << xstrerror());
     else
-        theOutICPAddr = xaddr.sin_addr;
+        theOutICPAddr = *xai;
+
+    theOutICPAddr.FreeAddrInfo(xai);
 }
 
 /*
index 8b8c5874b7efa5cc736b05b6159148d82fdf1132..b318fe239147e358136369a96bc6edd2b50bb3a5 100644 (file)
@@ -1,8 +1,8 @@
 
 /*
- * $Id: icp_v3.cc,v 1.42 2007/04/28 22:26:37 hno Exp $
+ * $Id: icp_v3.cc,v 1.43 2007/12/14 23:11:47 amosjeffries Exp $
  *
- * DEBUG: section 12    Internet Cache Protocol
+ * DEBUG: section 12    Internet Cache Protocol (ICP)
  * AUTHOR: Duane Wessels
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -52,18 +52,18 @@ public:
 
 static void
 
-doV3Query(int fd, struct sockaddr_in from, char *buf, icp_common_t header)
+doV3Query(int fd, IPAddress &from, char *buf, icp_common_t header)
 {
     /* We have a valid packet */
     char *url = buf + sizeof(icp_common_t) + sizeof(u_int32_t);
-    HttpRequest *icp_request = icpGetRequest (url, header.reqnum, fd, &from);
+    HttpRequest *icp_request = icpGetRequest (url, header.reqnum, fd, from);
 
     if (!icp_request)
         return;
 
-    if (!icpAccessAllowed(&from, icp_request))
+    if (!icpAccessAllowed(from, icp_request))
     {
-        icpDenyAccess (&from, url, header.reqnum, fd);
+        icpDenyAccess (from, url, header.reqnum, fd);
         delete icp_request;
         return;
     }
@@ -97,7 +97,7 @@ ICP3State::created (StoreEntry *newEntry)
     else
         codeToSend = icpGetCommonOpcode();
 
-    icpCreateAndSend (codeToSend, 0, url, header.reqnum, 0, fd, &from);
+    icpCreateAndSend (codeToSend, 0, url, header.reqnum, 0, fd, from);
 
     delete this;
 }
@@ -105,7 +105,7 @@ ICP3State::created (StoreEntry *newEntry)
 /* Currently Harvest cached-2.x uses ICP_VERSION_3 */
 void
 
-icpHandleIcpV3(int fd, struct sockaddr_in from, char *buf, int len)
+icpHandleIcpV3(int fd, IPAddress&from, char *buf, int len)
 {
     if (len <= 0)
     {
@@ -128,14 +128,10 @@ icpHandleIcpV3(int fd, struct sockaddr_in from, char *buf, int len)
     {
 
     case ICP_QUERY:
-        doV3Query(fd, from,buf, header);
+        doV3Query(fd, from, buf, header);
         break;
 
     case ICP_HIT:
-#if ALLOW_SOURCE_PING
-
-    case ICP_SECHO:
-#endif
 
     case ICP_DECHO:
 
@@ -144,7 +140,7 @@ icpHandleIcpV3(int fd, struct sockaddr_in from, char *buf, int len)
     case ICP_DENIED:
 
     case ICP_MISS_NOFETCH:
-        header.handleReply(buf, &from);
+        header.handleReply(buf, from);
         break;
 
     case ICP_INVALID:
@@ -153,7 +149,7 @@ icpHandleIcpV3(int fd, struct sockaddr_in from, char *buf, int len)
         break;
 
     default:
-        debugs(12, 0, "icpHandleIcpV3: UNKNOWN OPCODE: " << header.opcode << " from " << inet_ntoa(from.sin_addr));
+        debugs(12, 0, "icpHandleIcpV3: UNKNOWN OPCODE: " << header.opcode << " from " << from);
         break;
     }
 }
index 7669782ed64f76105b0042bcf8ce9bb360744c3b..ece329c27681e04d168c97c69cd583885792f25a 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ident.cc,v 1.77 2007/05/29 13:31:40 amosjeffries Exp $
+ * $Id: ident.cc,v 1.78 2007/12/14 23:11:47 amosjeffries Exp $
  *
  * DEBUG: section 30    Ident (RFC 931)
  * AUTHOR: Duane Wessels
@@ -55,9 +55,9 @@ typedef struct _IdentStateData
     hash_link hash;            /* must be first */
     int fd;                    /* IDENT fd */
 
-    struct sockaddr_in me;
+    IPAddress me;
 
-    struct sockaddr_in my_peer;
+    IPAddress my_peer;
     IdentClient *clients;
     char buf[4096];
 }
@@ -107,7 +107,7 @@ static void
 identTimeout(int fd, void *data)
 {
     IdentStateData *state = (IdentStateData *)data;
-    debugs(30, 3, "identTimeout: FD " << fd << ", " << inet_ntoa(state->my_peer.sin_addr));
+    debugs(30, 3, "identTimeout: FD " << fd << ", " << state->my_peer);
 
     comm_close(fd);
 }
@@ -141,8 +141,8 @@ identConnectDone(int fd, comm_err_t status, int xerrno, void *data)
     MemBuf mb;
     mb.init();
     mb.Printf("%d, %d\r\n",
-              ntohs(state->my_peer.sin_port),
-              ntohs(state->me.sin_port));
+              state->my_peer.GetPort(),
+              state->me.GetPort());
     comm_write_mbuf(fd, &mb, NULL, state);
     comm_read(fd, state->buf, BUFSIZ, identReadReply, state);
     commSetTimeout(fd, Config.Timeout.ident, identTimeout, state);
@@ -212,20 +212,17 @@ CBDATA_TYPE(IdentStateData);
  * start a TCP connection to the peer host on port 113
  */
 void
-
-identStart(struct sockaddr_in *me, struct sockaddr_in *my_peer, IDCB * callback, void *data)
+identStart(IPAddress &me, IPAddress &my_peer, IDCB * callback, void *data)
 {
     IdentStateData *state;
     int fd;
     char key1[IDENT_KEY_SZ];
     char key2[IDENT_KEY_SZ];
     char key[IDENT_KEY_SZ];
-    snprintf(key1, IDENT_KEY_SZ, "%s:%d",
-             inet_ntoa(me->sin_addr),
-             ntohs(me->sin_port));
-    snprintf(key2, IDENT_KEY_SZ, "%s:%d",
-             inet_ntoa(my_peer->sin_addr),
-             ntohs(my_peer->sin_port));
+    char ntoabuf[MAX_IPSTRLEN];
+
+    me.ToURL(key1, IDENT_KEY_SZ);
+    my_peer.ToURL(key2, IDENT_KEY_SZ);
     snprintf(key, IDENT_KEY_SZ, "%s,%s", key1, key2);
 
     if ((state = (IdentStateData *)hash_lookup(ident_hash, key)) != NULL)
@@ -236,8 +233,7 @@ identStart(struct sockaddr_in *me, struct sockaddr_in *my_peer, IDCB * callback,
 
     fd = comm_open(SOCK_STREAM,
                    IPPROTO_TCP,
-                   me->sin_addr,
-                   0,
+                   me,
                    COMM_NONBLOCKING,
                    "ident");
 
@@ -252,8 +248,8 @@ identStart(struct sockaddr_in *me, struct sockaddr_in *my_peer, IDCB * callback,
     state = cbdataAlloc(IdentStateData);
     state->hash.key = xstrdup(key);
     state->fd = fd;
-    state->me = *me;
-    state->my_peer = *my_peer;
+    state->me = me;
+    state->my_peer = my_peer;
     identClientAdd(state, callback, data);
     hash_join(ident_hash, &state->hash);
     comm_add_close_handler(fd,
@@ -261,7 +257,7 @@ identStart(struct sockaddr_in *me, struct sockaddr_in *my_peer, IDCB * callback,
                            state);
     commSetTimeout(fd, Config.Timeout.ident, identTimeout, state);
     commConnectStart(fd,
-                     inet_ntoa(state->my_peer.sin_addr),
+                     state->my_peer.NtoA(ntoabuf,MAX_IPSTRLEN),
                      IDENT_PORT,
                      identConnectDone,
                      state);
index 472270928f841fb26a8b2bae3a666fbcb966cf19..d4a1ddeb0df002e76ea089e8cd7e79d1d2879f24 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: internal.cc,v 1.47 2007/05/29 13:31:40 amosjeffries Exp $
+ * $Id: internal.cc,v 1.48 2007/12/14 23:11:47 amosjeffries Exp $
  *
  * DEBUG: section 76    Internal Squid Object handling
  * AUTHOR: Duane, Alex, Henrik
@@ -51,7 +51,7 @@ internalStart(HttpRequest * request, StoreEntry * entry)
 {
     ErrorState *err;
     const char *upath = request->urlpath.buf();
-    debugs(76, 3, "internalStart: " << inet_ntoa(request->client_addr) << " requesting '" << upath << "'");
+    debugs(76, 3, "internalStart: " << request->client_addr << " requesting '" << upath << "'");
 
     if (0 == strcmp(upath, "/squid-internal-dynamic/netdb")) {
         netdbBinaryExchange(entry);
@@ -106,6 +106,15 @@ internalRemoteUri(const char *host, u_short port, const char *dir, const char *n
     /* convert host name to lower case */
     xstrncpy(lc_host, host, SQUIDHOSTNAMELEN);
     Tolower(lc_host);
+
+#if USE_IPV6
+    /* check for an IP address and format appropriately if found */
+    IPAddress test = lc_host;
+    if ( !test.IsAnyAddr() ) {
+        test.ToHostname(lc_host,SQUIDHOSTNAMELEN);
+    }
+#endif
+
     /*
      * append the domain in order to mirror the requests with appended
      * domains
index c844d136ee0e04900b59dfc71205957d603751b2..09339eaa4ba10ef27510ced13a45d4d0b6485372 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ipc.cc,v 1.46 2007/06/10 10:43:17 hno Exp $
+ * $Id: ipc.cc,v 1.47 2007/12/14 23:11:47 amosjeffries Exp $
  *
  * DEBUG: section 54    Interprocess Communication
  * AUTHOR: Duane Wessels
@@ -36,6 +36,7 @@
 #include "squid.h"
 #include "comm.h"
 #include "fde.h"
+#include "IPAddress.h"
 
 static const char *hello_string = "hi there\n";
 #define HELLO_BUF_SZ 32
@@ -74,20 +75,18 @@ PutEnvironment()
 }
 
 pid_t
-ipcCreate(int type, const char *prog, const char *const args[], const char *name, int *rfd, int *wfd, void **hIpc)
+ipcCreate(int type, const char *prog, const char *const args[], const char *name, IPAddress &local_addr, int *rfd, int *wfd, void **hIpc)
 {
     pid_t pid;
-
-    struct sockaddr_in ChS;
-
-    struct sockaddr_in PaS;
+    IPAddress ChS;
+    IPAddress PaS;
+    struct addrinfo *AI = NULL;
     int crfd = -1;
     int prfd = -1;
     int cwfd = -1;
     int pwfd = -1;
     int fd;
     int t1, t2, t3;
-    socklen_t len;
     int x;
 
 #if USE_POLL && defined(_SQUID_OSF_)
@@ -108,27 +107,23 @@ ipcCreate(int type, const char *prog, const char *const args[], const char *name
         crfd = cwfd = comm_open(SOCK_STREAM,
                                 0,
                                 local_addr,
-                                0,
                                 COMM_NOCLOEXEC,
                                 name);
         prfd = pwfd = comm_open(SOCK_STREAM,
                                 0,                     /* protocol */
                                 local_addr,
-                                0,                     /* port */
                                 0,                     /* blocking */
                                 name);
     } else if (type == IPC_UDP_SOCKET) {
         crfd = cwfd = comm_open(SOCK_DGRAM,
                                 0,
                                 local_addr,
-                                0,
                                 COMM_NOCLOEXEC,
                                 name);
         prfd = pwfd = comm_open(SOCK_DGRAM,
                                 0,
                                 local_addr,
                                 0,
-                                0,
                                 name);
     } else if (type == IPC_FIFO) {
         int p2c[2];
@@ -197,25 +192,33 @@ ipcCreate(int type, const char *prog, const char *const args[], const char *name
     }
 
     if (type == IPC_TCP_SOCKET || type == IPC_UDP_SOCKET) {
-        len = sizeof(PaS);
-        memset(&PaS, '\0', len);
+        PaS.InitAddrInfo(AI);
 
-        if (getsockname(pwfd, (struct sockaddr *) &PaS, &len) < 0) {
+        if (getsockname(pwfd, AI->ai_addr, &AI->ai_addrlen) < 0) {
+            PaS.FreeAddrInfo(AI);
             debugs(54, 0, "ipcCreate: getsockname: " << xstrerror());
             return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
         }
 
-        debugs(54, 3, "ipcCreate: FD " << pwfd << " sockaddr " << inet_ntoa(PaS.sin_addr) << ":" << ntohs(PaS.sin_port));
+        PaS = *AI;
 
-        len = sizeof(ChS);
-        memset(&ChS, '\0', len);
+        debugs(54, 3, "ipcCreate: FD " << pwfd << " sockaddr " << PaS);
 
-        if (getsockname(crfd, (struct sockaddr *) &ChS, &len) < 0) {
+        PaS.FreeAddrInfo(AI);
+
+        ChS.InitAddrInfo(AI);
+
+        if (getsockname(crfd, AI->ai_addr, &AI->ai_addrlen) < 0) {
+            ChS.FreeAddrInfo(AI);
             debugs(54, 0, "ipcCreate: getsockname: " << xstrerror());
             return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
         }
 
-        debugs(54, 3, "ipcCreate: FD " << crfd << " sockaddr " << inet_ntoa(ChS.sin_addr) << ":" << ntohs(ChS.sin_port));
+        ChS = *AI;
+
+        ChS.FreeAddrInfo(AI);
+
+        debugs(54, 3, "ipcCreate: FD " << crfd << " sockaddr " << ChS );
 
     }
 
@@ -246,7 +249,7 @@ ipcCreate(int type, const char *prog, const char *const args[], const char *name
         cwfd = crfd = -1;
 
         if (type == IPC_TCP_SOCKET || type == IPC_UDP_SOCKET) {
-            if (comm_connect_addr(pwfd, &ChS) == COMM_ERROR)
+            if (comm_connect_addr(pwfd, ChS) == COMM_ERROR)
                 return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
         }
 
@@ -317,7 +320,7 @@ ipcCreate(int type, const char *prog, const char *const args[], const char *name
         close(crfd);
         cwfd = crfd = fd;
     } else if (type == IPC_UDP_SOCKET) {
-        if (comm_connect_addr(crfd, &PaS) == COMM_ERROR)
+        if (comm_connect_addr(crfd, PaS) == COMM_ERROR)
             return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
     }
 
index 905f4f8327cb8c7f3517a4c8bd43090e47424e04..dc813966b5ae8c8d4d8b19a56976bf2515450403 100755 (executable)
@@ -1,6 +1,5 @@
-
 /*
- * $Id: ipc_win32.cc,v 1.4 2007/04/30 16:56:09 wessels Exp $
+ * $Id: ipc_win32.cc,v 1.5 2007/12/14 23:11:47 amosjeffries Exp $
  *
  * DEBUG: section 54    Windows Interprocess Communication
  * AUTHOR: Andrey Shorin <tolsty@tushino.com>
@@ -49,8 +48,8 @@ struct ipc_params
     int type;
     int crfd;
     int cwfd;
-
-    struct sockaddr_in PS;
+    IPAddress local_addr;
+    struct addrinfo PS;
     const char *prog;
     char **args;
 };
@@ -108,7 +107,7 @@ PutEnvironment()
 }
 
 pid_t
-ipcCreate(int type, const char *prog, const char *const args[], const char *name, int *rfd, int *wfd, void **hIpc)
+ipcCreate(int type, const char *prog, const char *const args[], const char *name, IPAddress &local_addr, int *rfd, int *wfd, void **hIpc)
 {
     unsigned long thread;
 
@@ -118,14 +117,14 @@ ipcCreate(int type, const char *prog, const char *const args[], const char *name
     DWORD ecode = 0;
     pid_t pid;
 
-    struct sockaddr_in CS;
+    IPAddress tmp_addr;
+    struct addrinfo *aiCS = NULL;
+    struct addrinfo *aiPS = NULL;
 
-    struct sockaddr_in PS;
     int crfd = -1;
     int prfd = -1;
     int cwfd = -1;
     int pwfd = -1;
-    socklen_t len;
     int x;
 
     requirePathnameExists(name, prog);
@@ -149,27 +148,23 @@ ipcCreate(int type, const char *prog, const char *const args[], const char *name
         crfd = cwfd = comm_open(SOCK_STREAM,
                                 IPPROTO_TCP,
                                 local_addr,
-                                0,
                                 COMM_NOCLOEXEC,
                                 name);
         prfd = pwfd = comm_open(SOCK_STREAM,
                                 IPPROTO_TCP,   /* protocol */
                                 local_addr,
-                                0,                     /* port */
                                 0,                     /* blocking */
                                 name);
     } else if (type == IPC_UDP_SOCKET) {
         crfd = cwfd = comm_open(SOCK_DGRAM,
                                 IPPROTO_UDP,
                                 local_addr,
-                                0,
                                 COMM_NOCLOEXEC,
                                 name);
         prfd = pwfd = comm_open(SOCK_DGRAM,
                                 IPPROTO_UDP,
                                 local_addr,
                                 0,
-                                0,
                                 name);
     } else if (type == IPC_FIFO) {
         debugs(54, 0, "ipcCreate: " << prog << ": use IPC_TCP_SOCKET instead of IP_FIFO on Windows");
@@ -199,25 +194,31 @@ ipcCreate(int type, const char *prog, const char *const args[], const char *name
         return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
     }
 
+// AYJ: these flags should be neutral, but if not IPv6 version needs adding
     if (type == IPC_TCP_SOCKET || type == IPC_UDP_SOCKET) {
-        len = sizeof(PS);
-        memset(&PS, '\0', len);
 
-        if (getsockname(pwfd, (struct sockaddr *) &PS, &len) < 0) {
+        tmp_addr.InitAddrInfo(aiPS);
+
+        if (getsockname(pwfd, aiPS->ai_addr, &(aiPS->ai_addrlen) ) < 0) {
             debugs(54, 0, "ipcCreate: getsockname: " << xstrerror());
             return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
         }
 
-        debugs(54, 3, "ipcCreate: FD " << pwfd << " sockaddr " << inet_ntoa(PS.sin_addr) << ":" << ntohs(PS.sin_port));
-        len = sizeof(CS);
-        memset(&CS, '\0', len);
+        tmp_addr = *aiPS;
+
+        debugs(54, 3, "ipcCreate: FD " << pwfd << " sockaddr " << tmp_addr );
 
-        if (getsockname(crfd, (struct sockaddr *) &CS, &len) < 0) {
+        tmp_addr.InitAddrInfo(aiCS);
+
+        if (getsockname(crfd, aiCS->ai_addr, &(aiCS->ai_addrlen) ) < 0) {
             debugs(54, 0, "ipcCreate: getsockname: " << xstrerror());
             return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
         }
 
-        debugs(54, 3, "ipcCreate: FD " << crfd << " sockaddr " << inet_ntoa(CS.sin_addr) << ":" << ntohs(CS.sin_port));
+        tmp_addr.SetEmpty();
+        tmp_addr = *aiCS;
+
+        debugs(54, 3, "ipcCreate: FD " << crfd << " sockaddr " << tmp_addr );
     }
 
     if (type == IPC_TCP_SOCKET) {
@@ -238,7 +239,9 @@ ipcCreate(int type, const char *prog, const char *const args[], const char *name
 
     params.cwfd = cwfd;
 
-    params.PS = PS;
+    params.PS = *aiPS;
+    
+    params.local_addr = local_addr;
 
     params.prog = prog;
 
@@ -251,7 +254,8 @@ ipcCreate(int type, const char *prog, const char *const args[], const char *name
         return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
     }
 
-    if (comm_connect_addr(pwfd, &CS) == COMM_ERROR) {
+    /* NP: tmp_addr was left with eiether empty or aiCS in IPAddress format */
+    if (comm_connect_addr(pwfd, tmp_addr) == COMM_ERROR) {
         CloseHandle((HANDLE) thread);
         return ipcCloseAllFD(prfd, pwfd, -1, -1);
     }
@@ -369,7 +373,7 @@ ipc_thread_1(void *in_params)
 
     struct thread_params thread_params;
     ssize_t x;
-    int tmp_s, fd = -1;
+    int fd = -1;
     char *str;
     STARTUPINFO si;
     PROCESS_INFORMATION pi;
@@ -377,7 +381,10 @@ ipc_thread_1(void *in_params)
     int prfd_ipc = -1, pwfd_ipc = -1, crfd_ipc = -1, cwfd_ipc = -1;
     char *prog = NULL, *buf1 = NULL;
 
-    struct sockaddr_in CS_ipc, PS_ipc;
+    IPAddress PS_ipc;
+    IPAddress CS_ipc;
+    struct addrinfo *aiPS_ipc = NULL;
+    struct addrinfo *aiCS_ipc = NULL;
 
     struct ipc_params *params = (struct ipc_params *) in_params;
     int type = params->type;
@@ -385,9 +392,9 @@ ipc_thread_1(void *in_params)
     int cwfd = params->cwfd;
     char **args = params->args;
 
-    struct sockaddr_in PS = params->PS;
-
-
+    IPAddress PS = params->PS;
+    IPAddress local_addr = params->local_addr;
+    
     buf1 = (char *)xcalloc(1, 8192);
     strcpy(buf1, params->prog);
     prog = strtok(buf1, w_space);
@@ -415,7 +422,7 @@ ipc_thread_1(void *in_params)
         fd_table[fd].flags.ipc = 1;
         cwfd = crfd = fd;
     } else if (type == IPC_UDP_SOCKET) {
-        if (comm_connect_addr(crfd, &PS) == COMM_ERROR)
+        if (comm_connect_addr(crfd, params->PS) == COMM_ERROR)
             goto cleanup;
     }
 
@@ -457,7 +464,7 @@ ipc_thread_1(void *in_params)
 
     if (type == IPC_UDP_SOCKET) {
         snprintf(buf1, 8192, "%s(%ld) <-> ipc CHILD socket", prog, -1L);
-        crfd_ipc = cwfd_ipc = comm_open(SOCK_DGRAM, IPPROTO_UDP, local_addr, 0, 0, buf1);
+        crfd_ipc = cwfd_ipc = comm_open(SOCK_DGRAM, IPPROTO_UDP, local_addr, 0, buf1);
 
         if (crfd_ipc < 0) {
             debugs(54, 0, "ipcCreate: CHILD: Failed to create child FD for " << prog << ".");
@@ -466,7 +473,7 @@ ipc_thread_1(void *in_params)
         }
 
         snprintf(buf1, 8192, "%s(%ld) <-> ipc PARENT socket", prog, -1L);
-        prfd_ipc = pwfd_ipc = comm_open(SOCK_DGRAM, IPPROTO_UDP, local_addr, 0, 0, buf1);
+        prfd_ipc = pwfd_ipc = comm_open(SOCK_DGRAM, IPPROTO_UDP, local_addr, 0, buf1);
 
         if (pwfd_ipc < 0) {
             debugs(54, 0, "ipcCreate: CHILD: Failed to create server FD for " << prog << ".");
@@ -474,36 +481,38 @@ ipc_thread_1(void *in_params)
             goto cleanup;
         }
 
-        tmp_s = sizeof(PS_ipc);
-        memset(&PS_ipc, '\0', tmp_s);
+        PS_ipc.InitAddrInfo(aiPS_ipc);
 
-        if (getsockname(pwfd_ipc, (struct sockaddr *) &PS_ipc, &tmp_s) < 0) {
+        if (getsockname(pwfd_ipc, aiPS_ipc->ai_addr, &(aiPS_ipc->ai_addrlen)) < 0) {
             debugs(54, 0, "ipcCreate: getsockname: " << xstrerror());
             ipcSend(cwfd, err_string, strlen(err_string));
             goto cleanup;
         }
 
-        debugs(54, 3, "ipcCreate: FD " << pwfd_ipc << " sockaddr " << inet_ntoa(PS_ipc.sin_addr) << ":" << ntohs(PS_ipc.sin_port));
+        PS_ipc = *aiPS_ipc;
+
+        debugs(54, 3, "ipcCreate: FD " << pwfd_ipc << " sockaddr " << PS_ipc);
 
-        tmp_s = sizeof(CS_ipc);
-        memset(&CS_ipc, '\0', tmp_s);
+        CS_ipc.InitAddrInfo(aiCS_ipc);
 
-        if (getsockname(crfd_ipc, (struct sockaddr *) &CS_ipc, &tmp_s) < 0) {
+        if (getsockname(crfd_ipc, aiCS_ipc->ai_addr, &(aiCS_ipc->ai_addrlen)) < 0) {
             debugs(54, 0, "ipcCreate: getsockname: " << xstrerror());
             ipcSend(cwfd, err_string, strlen(err_string));
             goto cleanup;
         }
 
-        debugs(54, 3, "ipcCreate: FD " << crfd_ipc << " sockaddr " << inet_ntoa(CS_ipc.sin_addr) << ":" << ntohs(CS_ipc.sin_port));
+        CS_ipc = *aiCS_ipc;
+
+        debugs(54, 3, "ipcCreate: FD " << crfd_ipc << " sockaddr " << CS_ipc);
 
-        if (comm_connect_addr(pwfd_ipc, &CS_ipc) == COMM_ERROR) {
+        if (comm_connect_addr(pwfd_ipc, CS_ipc) == COMM_ERROR) {
             ipcSend(cwfd, err_string, strlen(err_string));
             goto cleanup;
         }
 
         fd = crfd;
 
-        if (comm_connect_addr(crfd_ipc, &PS_ipc) == COMM_ERROR) {
+        if (comm_connect_addr(crfd_ipc, PS_ipc) == COMM_ERROR) {
             ipcSend(cwfd, err_string, strlen(err_string));
             goto cleanup;
         }
index 05c4f9d856a2e175e5539837b57341d3cc2e9e28..0c134307c78c88e42513de7260bec64a5a9f9e35 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ipcache.cc,v 1.264 2007/10/13 00:02:28 hno Exp $
+ * $Id: ipcache.cc,v 1.265 2007/12/14 23:11:47 amosjeffries Exp $
  *
  * DEBUG: section 14    IP Cache
  * AUTHOR: Harvest Derived
@@ -40,6 +40,7 @@
 #include "SquidTime.h"
 #include "Store.h"
 #include "wordlist.h"
+#include "IPAddress.h"
 
 typedef struct _ipcache_entry ipcache_entry;
 
@@ -56,6 +57,7 @@ struct _ipcache_entry
     struct timeval request_time;
     dlink_node lru;
     unsigned short locks;
+    unsigned short cname_wait;
 
     struct
     {
@@ -90,7 +92,7 @@ static HLPCB ipcacheHandleReply;
 #else
 static IDNSCB ipcacheHandleReply;
 #endif
-static IPH dummy_handler;
+static IPH ipcacheHandleCnameRecurse;
 static int ipcacheExpiredEntry(ipcache_entry *);
 static int ipcache_testname(void);
 #if USE_DNSSERVERS
@@ -102,7 +104,7 @@ static ipcache_entry *ipcache_get(const char *);
 static void ipcacheLockEntry(ipcache_entry *);
 static void ipcacheStatPrint(ipcache_entry *, StoreEntry *);
 static void ipcacheUnlockEntry(ipcache_entry *);
-static void ipcacheRelease(ipcache_entry *);
+static void ipcacheRelease(ipcache_entry *, bool dofree = true);
 
 static ipcache_addrs static_addrs;
 static hash_table *ip_table = NULL;
@@ -133,13 +135,24 @@ ipcache_testname(void)
 
 /* removes the given ipcache entry */
 static void
-ipcacheRelease(ipcache_entry * i)
+ipcacheRelease(ipcache_entry * i, bool dofree)
 {
+    if(!i) {
+        debugs(14, 0, "ipcacheRelease: Releasing entry with i=<NULL>");
+        return;
+    }
+
+    if(!i || !i->hash.key) {
+        debugs(14, 0, "ipcacheRelease: Releasing entry without hash link!");
+        return;
+    }
+
     debugs(14, 3, "ipcacheRelease: Releasing entry for '" << (const char *) i->hash.key << "'");
 
     hash_remove_link(ip_table, (hash_link *) i);
     dlinkDelete(&i->lru, &lru_list);
-    ipcacheFreeEntry(i);
+    if(dofree)
+        ipcacheFreeEntry(i);
 }
 
 static ipcache_entry *
@@ -238,10 +251,19 @@ ipcacheAddEntry(ipcache_entry * i)
 {
     hash_link *e = (hash_link *)hash_lookup(ip_table, i->hash.key);
 
+    /* INET6 : should NOT be adding this entry until all CNAME have been received. */
+    assert(i->cname_wait == 0);
+
     if (NULL != e) {
         /* avoid colission */
         ipcache_entry *q = (ipcache_entry *) e;
-        ipcacheRelease(q);
+        if(q == i)  {
+            /* can occur with Multiple-depth CNAME Recursion if parent returned early with additional */
+            /* just need to drop from the hash without releasing actual memory */
+            ipcacheRelease(q, false);
+        }
+        else
+            ipcacheRelease(q);
     }
 
     hash_join(ip_table, &i->hash);
@@ -254,7 +276,7 @@ static void
 ipcacheCallback(ipcache_entry * i)
 {
     IPH *callback = i->handler;
-    void *cbdata;
+    void *cbdata = NULL;
     i->lastref = squid_curtime;
 
     if (!i->handler)
@@ -343,11 +365,14 @@ ipcacheParse(ipcache_entry *i, const char *inbuf)
     if (ipcount > 0) {
         int j, k;
 
-        i->addrs.in_addrs = (struct IN_ADDR *)xcalloc(ipcount, sizeof(struct IN_ADDR));
+        i->addrs.in_addrs = (IPAddress *)xcalloc(ipcount, sizeof(IPAddress));
+        for(int l = 0; l < ipcount; l++)
+            i->addrs.in_addrs[l].SetEmpty(); // perform same init actions as constructor would.
         i->addrs.bad_mask = (unsigned char *)xcalloc(ipcount, sizeof(unsigned char));
+        memset(i->addrs.bad_mask, 0, sizeof(unsigned char) * ipcount);
 
         for (j = 0, k = 0; k < ipcount; k++) {
-            if (safe_inet_addr(A[k], &i->addrs.in_addrs[j]))
+            if ( i->addrs.in_addrs[j] = A[k] )
                 j++;
             else
                 debugs(14, 1, "ipcacheParse: Invalid IP address '" << A[k] << "' in response to '" << name << "'");
@@ -379,15 +404,18 @@ static int
 ipcacheParse(ipcache_entry *i, rfc1035_rr * answers, int nr, const char *error_message)
 {
     int k;
-    int j;
+    int j = 0;
     int na = 0;
     int ttl = 0;
     const char *name = (const char *)i->hash.key;
     i->expires = squid_curtime + Config.negativeDnsTtl;
     i->flags.negcached = 1;
     safe_free(i->addrs.in_addrs);
+    assert(i->addrs.in_addrs == NULL);
     safe_free(i->addrs.bad_mask);
+    assert(i->addrs.bad_mask == NULL);
     safe_free(i->error_message);
+    assert(i->error_message == NULL);
     i->addrs.count = 0;
 
     if (nr < 0) {
@@ -399,24 +427,54 @@ ipcacheParse(ipcache_entry *i, rfc1035_rr * answers, int nr, const char *error_m
     if (nr == 0) {
         debugs(14, 3, "ipcacheParse: No DNS records in response to '" << name << "'");
         i->error_message = xstrdup("No DNS records");
-        return 0;
+        return -1;
     }
 
     assert(answers);
 
     for (k = 0; k < nr; k++) {
-        if (answers[k].type != RFC1035_TYPE_A)
-            continue;
 
-        if (answers[k]._class != RFC1035_CLASS_IN)
-            continue;
+#if USE_IPV6
+        if (answers[k].type == RFC1035_TYPE_AAAA) {
+           if (answers[k].rdlength != sizeof(struct in6_addr)) {
+               debugs(14, 1, "ipcacheParse: Invalid IPv6 address in response to '" << name << "'");
+               continue;
+           }
+           na++;
+           continue;
+       }
+#endif
 
-        if (answers[k].rdlength != 4) {
-            debugs(14, 1, "ipcacheParse: Invalid IP address in response to '" << name << "'");
+        if (answers[k].type == RFC1035_TYPE_A) {
+           if (answers[k].rdlength != sizeof(struct in_addr)) {
+               debugs(14, 1, "ipcacheParse: Invalid IPv4 address in response to '" << name << "'");
+               continue;
+           }
+           na++;
+           continue;
+       }
+
+            /* With A and AAAA, the CNAME does not necessarily come with additional records to use. */
+        if (answers[k].type == RFC1035_TYPE_CNAME) {
+            debugs(14, 5, "ipcacheParse: " << name << " CNAME " << answers[k].rdata << " (checking destination: " << i << ").");
+            const ipcache_addrs *res = ipcache_gethostbyname(answers[k].rdata, 0);
+            if(res) {
+                na += res->count;
+                debugs(14, 5, "ipcacheParse: CNAME " << answers[k].rdata << " already has " << res->count << " IPs cached.");
+            }
+            else {
+                /* keep going on this, but flag the fact that we need to wait for a CNAME lookup to finish */
+                debugs(14, 5, "ipcacheParse: CNAME " << answers[k].rdata << " has no IPs! Recursing.");
+                ipcache_nbgethostbyname(answers[k].rdata, ipcacheHandleCnameRecurse, new generic_cbdata(i) );
+                i->cname_wait++;
+            }
             continue;
         }
+    }
 
-        na++;
+    if(na == 0 && i->cname_wait >0 ) {
+        /* don't set any error message (yet). Allow recursion to do its work first. */
+        return 0;
     }
 
     if (na == 0) {
@@ -425,27 +483,54 @@ ipcacheParse(ipcache_entry *i, rfc1035_rr * answers, int nr, const char *error_m
         return 0;
     }
 
-    i->addrs.in_addrs = (struct IN_ADDR *)xcalloc(na, sizeof(struct IN_ADDR));
+    i->addrs.in_addrs = (IPAddress *)xcalloc(na, sizeof(IPAddress));
+    for(int l = 0; l < na; l++)
+        i->addrs.in_addrs[l].SetEmpty(); // perform same init actions as constructor would.
     i->addrs.bad_mask = (unsigned char *)xcalloc(na, sizeof(unsigned char));
 
     for (j = 0, k = 0; k < nr; k++) {
-        if (answers[k]._class != RFC1035_CLASS_IN)
-            continue;
 
         if (answers[k].type == RFC1035_TYPE_A) {
-            if (answers[k].rdlength != 4)
+            if (answers[k].rdlength != sizeof(struct in_addr))
                 continue;
 
-            xmemcpy(&i->addrs.in_addrs[j++], answers[k].rdata, 4);
+            struct in_addr temp;
+            xmemcpy(&temp, answers[k].rdata, sizeof(struct in_addr));
+            i->addrs.in_addrs[j] = temp;
 
-            debugs(14, 3, "ipcacheParse: #" << j - 1 << " " << inet_ntoa(i->addrs.in_addrs[j - 1]));
+            debugs(14, 3, "ipcacheParse: " << name << " #" << j << " " << i->addrs.in_addrs[j]);
+            j++;
 
-        } else if (answers[k].type != RFC1035_TYPE_CNAME)
-            continue;
+#if USE_IPV6
+        } else if (answers[k].type == RFC1035_TYPE_AAAA) {
+            if (answers[k].rdlength != sizeof(struct in6_addr))
+                continue;
+
+            struct in6_addr temp;
+            xmemcpy(&temp, answers[k].rdata, sizeof(struct in6_addr));
+            i->addrs.in_addrs[j] = temp;
+
+            debugs(14, 3, "ipcacheParse: " << name << " #" << j << " " << i->addrs.in_addrs[j] );
+            j++;
+#endif
+        } else if (answers[k].type == RFC1035_TYPE_CNAME) {
+            debugs(14, 3, "ipcacheParse: " << name << " #x CNAME " << answers[k].rdata);
+            const ipcache_addrs *res = ipcache_gethostbyname(answers[k].rdata, 0);
+            if(res) {
+                /* NP: the results of *that* query need to be integrated in place of the CNAME */
+                /* Ideally we should also integrate the min TTL of the above IPA's into ttl.   */
+                for(int l = 0; l < res->count; l++, j++) {
+                    i->addrs.in_addrs[j] = res->in_addrs[l];
+                    debugs(14, 3, "ipcacheParse: " << name << " #" << j << " " << i->addrs.in_addrs[j] );
+                }
+            }
+            else {
+                debugs(14, 9, "ipcacheParse: " << answers[k].rdata << " (CNAME) waiting on A/AAAA records.");
+            }
+        }
 
         if (ttl == 0 || (int) answers[k].ttl < ttl)
             ttl = answers[k].ttl;
-
     }
 
     assert(j == na);
@@ -465,7 +550,13 @@ ipcacheParse(ipcache_entry *i, rfc1035_rr * answers, int nr, const char *error_m
 
     i->flags.negcached = 0;
 
-    return i->addrs.count;
+    /* SPECIAL CASE: may get here IFF CNAME received with Additional records */
+    /*               reurn  0/'wait for further details' value.              */
+    /*               NP: 'No DNS Results' is a return -1 +msg                */
+    if(i->cname_wait)
+        return 0;
+    else
+        return i->addrs.count;
 }
 
 #endif
@@ -477,6 +568,7 @@ ipcacheHandleReply(void *data, char *reply)
 ipcacheHandleReply(void *data, rfc1035_rr * answers, int na, const char *error_message)
 #endif
 {
+    int done;
     ipcache_entry *i;
     static_cast<generic_cbdata *>(data)->unwrap(&i);
     IpcacheStats.replies++;
@@ -484,14 +576,19 @@ ipcacheHandleReply(void *data, rfc1035_rr * answers, int na, const char *error_m
                   tvSubMsec(i->request_time, current_time));
 #if USE_DNSSERVERS
 
-    ipcacheParse(i, reply);
+    done = ipcacheParse(i, reply);
 #else
 
-    ipcacheParse(i, answers, na, error_message);
+    done = ipcacheParse(i, answers, na, error_message);
+
+    /* If we have not produced either IPs or Error immediately, wait for recursion to finish. */
+    if(done != 0 || error_message != NULL)
 #endif
 
-    ipcacheAddEntry(i);
-    ipcacheCallback(i);
+    {
+        ipcacheAddEntry(i);
+        ipcacheCallback(i);
+    }
 }
 
 void
@@ -513,6 +610,7 @@ ipcache_nbgethostbyname(const char *name, IPH * handler, void *handlerData)
     }
 
     if ((addrs = ipcacheCheckNumeric(name))) {
+        debugs(14, 4, "ipcache_nbgethostbyname: BYPASS for '" << name << "' (already numeric)");
         dns_error_message = NULL;
         IpcacheStats.numeric_hits++;
         handler(addrs, handlerData);
@@ -582,7 +680,8 @@ ipcache_init(void)
 
     memset(&static_addrs, '\0', sizeof(ipcache_addrs));
 
-    static_addrs.in_addrs = (struct IN_ADDR *)xcalloc(1, sizeof(struct IN_ADDR));
+    static_addrs.in_addrs = (IPAddress *)xcalloc(1, sizeof(IPAddress));
+    static_addrs.in_addrs->SetEmpty(); // properly setup the IPAddress!
     static_addrs.bad_mask = (unsigned char *)xcalloc(1, sizeof(unsigned char));
     ipcache_high = (long) (((float) Config.ipcache.size *
                             (float) Config.ipcache.high) / (float) 100);
@@ -637,7 +736,7 @@ ipcache_gethostbyname(const char *name, int flags)
     IpcacheStats.misses++;
 
     if (flags & IP_LOOKUP_IF_MISS)
-        ipcache_nbgethostbyname(name, dummy_handler, NULL);
+        ipcache_nbgethostbyname(name, ipcacheHandleCnameRecurse, NULL);
 
     return NULL;
 }
@@ -646,6 +745,19 @@ static void
 ipcacheStatPrint(ipcache_entry * i, StoreEntry * sentry)
 {
     int k;
+    int count = i->addrs.count;
+    char buf[MAX_IPSTRLEN];
+
+    if(!sentry) {
+        debugs(14, 0, HERE << "CRITICAL: sentry is NULL!");
+    }
+
+    if(!i) {
+        debugs(14, 0, HERE << "CRITICAL: ipcache_entry is NULL!");
+        storeAppendPrintf(sentry, "CRITICAL ERROR\n");
+        return;
+    }
+
     storeAppendPrintf(sentry, " %-32.32s %c%c %6d %6d %2d(%2d)",
                       hashKeyStr(&i->hash),
                       i->flags.fromhosts ? 'H' : ' ',
@@ -655,12 +767,27 @@ ipcacheStatPrint(ipcache_entry * i, StoreEntry * sentry)
                       (int) i->addrs.count,
                       (int) i->addrs.badcount);
 
-    for (k = 0; k < (int) i->addrs.count; k++) {
-        storeAppendPrintf(sentry, " %15s-%3s", inet_ntoa(i->addrs.in_addrs[k]),
-                          i->addrs.bad_mask[k] ? "BAD" : "OK ");
+    /** \par
+     * Negative-cached entries have no IPs listed. */
+    if(i->flags.negcached) {
+        storeAppendPrintf(sentry, "\n");
+        return;
     }
 
-    storeAppendPrintf(sentry, "\n");
+    /** \par
+     * Cached entries have IPs listed with a BNF of:   <IP> '-' ('OK'|'BAD') */
+    for (k = 0; k < count; k++) {
+        /* Display tidy-up: IPv6 are so big make the list vertical */
+        if(k == 0)
+            storeAppendPrintf(sentry, " %45.45s-%3s\n",
+                              i->addrs.in_addrs[k].NtoA(buf,MAX_IPSTRLEN),
+                              i->addrs.bad_mask[k] ? "BAD" : "OK ");
+        else
+            storeAppendPrintf(sentry, "%s %45.45s-%3s\n",
+                              "                                                         ", /* blank-space indenting IP list */
+                              i->addrs.in_addrs[k].NtoA(buf,MAX_IPSTRLEN),
+                              i->addrs.bad_mask[k] ? "BAD" : "OK ");
+    }
 }
 
 /* process objects list */
@@ -686,21 +813,229 @@ stat_ipcache_get(StoreEntry * sentry)
                       IpcacheStats.invalid);
     storeAppendPrintf(sentry, "\n\n");
     storeAppendPrintf(sentry, "IP Cache Contents:\n\n");
-    storeAppendPrintf(sentry, " %-29.29s %3s %6s %6s %1s\n",
+    storeAppendPrintf(sentry, " %-31.31s %3s %6s %6s  %4s\n",
                       "Hostname",
                       "Flg",
                       "lstref",
                       "TTL",
-                      "N");
+                      "N(b)");
 
-    for (m = lru_list.head; m; m = m->next)
+    for (m = lru_list.head; m; m = m->next) {
+        assert( m->next != m );
         ipcacheStatPrint((ipcache_entry *)m->data, sentry);
+    }
+}
+
+/**
+ * Takes two IPAddress arrays and merges them into a single array
+ * which is allocated dynamically to fit the number of unique addresses
+ *
+ \param aaddrs One list to merge
+ \param alen   Size of list aaddrs
+ \param baddrs Other list to merge
+ \param alen   Size of list baddrs
+ \param out    Combined list of unique addresses (sorted with IPv6 first in IPv6-mode)
+ \param outlen Size of list out
+ */
+void
+ipcacheMergeIPLists(IPAddress *aaddrs, int alen,
+                    IPAddress *baddrs, int blen,
+                    IPAddress **out, int &outlen )
+{
+    int fc=0, t=0, c=0;
+
+    IPAddress *ip4ptrs[255];
+#if USE_IPV6
+    IPAddress *ip6ptrs[255];
+#endif
+    int num_ip4 = 0;
+    int num_ip6 = 0;
+
+    memset(ip4ptrs, 0, sizeof(IPAddress*)*255);
+#if USE_IPV6
+    memset(ip6ptrs, 0, sizeof(IPAddress*)*255);
+#endif
+
+    // for each unique address in list A - grab ptr
+    for(t = 0; t < alen; t++) {
+        if(aaddrs[t].IsIPv4()) {
+            // check against IPv4 pruned list
+            for(c = 0; c <= num_ip4; c++) {
+                if(ip4ptrs[c] && aaddrs[t] == *(ip4ptrs[c]) ) break; // duplicate.
+            }
+            if(c > num_ip4) {
+                ip4ptrs[num_ip4] = &aaddrs[t];
+                num_ip4++;
+            }
+        }
+#if USE_IPV6
+        else if(aaddrs[t].IsIPv6()) {
+debugs(14,8, HERE << "A[" << t << "]=IPv6 " << aaddrs[t]);
+            // check against IPv6 pruned list
+            for(c = 0; c <= num_ip6; c++) {
+                if(ip6ptrs[c] && aaddrs[t] == *ip6ptrs[c]) break; // duplicate.
+            }
+            if(c > num_ip6) {
+                ip6ptrs[num_ip6] = &aaddrs[t];
+                num_ip6++;
+            }
+        }
+#endif
+    }
+
+    // for each unique address in list B - grab ptr
+    for(t = 0; t < blen; t++) {
+        if(baddrs[t].IsIPv4()) {
+            // check against IPv4 pruned list
+            for(c = 0; c <= num_ip4; c++) {
+                if(ip4ptrs[c] && baddrs[t] == *ip4ptrs[c]) break; // duplicate.
+            }
+            if(c > num_ip4) {
+                ip4ptrs[num_ip4] = &baddrs[t];
+                num_ip4++;
+            }
+        }
+#if USE_IPV6
+        else if(baddrs[t].IsIPv6()) {
+            // check against IPv6 pruned list
+            for(c = 0; c <= num_ip6; c++) {
+                if(ip6ptrs[c] && baddrs[t] == *ip6ptrs[c]) break; // duplicate.
+            }
+            if(c > num_ip6) {
+                ip6ptrs[num_ip6] = &baddrs[t];
+                num_ip6++;
+            }
+        }
+#endif
+    }
+
+    fc = num_ip6 + num_ip4;
+
+    assert(fc > 0);
+
+    debugs(14, 5, "ipcacheMergeIPLists: Merge " << alen << "+" << blen << " into " << fc << " unique IPs.");
+
+    // copy the old IPs into the new list buffer.
+    (*out) = (IPAddress*)xcalloc(fc, sizeof(IPAddress));
+    outlen=0;
+
+    assert(out != NULL);
+
+#if USE_IPV6
+    /* IPv6 are preferred (tried first) over IPv4 */
+
+    for(int l = 0; outlen < num_ip6; l++, outlen++) {
+        (*out)[outlen] = *ip6ptrs[l];
+        debugs(14, 5, "ipcacheMergeIPLists:  #" << outlen << " " << (*out)[outlen] );
+    }
+#endif /* USE_IPV6 */
+
+    for(int l = 0; outlen < num_ip4; l++, outlen++) {
+        (*out)[outlen] = *ip4ptrs[l];
+        debugs(14, 5, "ipcacheMergeIPLists:  #" << outlen << " " << (*out)[outlen] );
+    }
+
+    assert(outlen == fc); // otherwise something broke badly!
 }
 
 static void
-dummy_handler(const ipcache_addrs * addrsnotused, void *datanotused)
+ipcacheHandleCnameRecurse(const ipcache_addrs *addrs, void *cbdata)
 {
-    return;
+    ipcache_entry *i = NULL;
+    char *pname = NULL;
+    IPAddress *tmpbuf = NULL;
+    int fc = 0;
+    int ttl = 0;
+    generic_cbdata* gcb = (generic_cbdata*)cbdata;
+    // count of addrs at parent and child (REQ as .count is a char type!)
+    int ccount = 0, pcount = 0;
+
+    debugs(14, 5, "ipcacheHandleCnameRecurse: Handling basic A/AAAA response.");
+
+    /* IFF no CNAME recursion being processed. do nothing. */
+    if(cbdata == NULL)
+        return;
+
+    gcb->unwrap(&i);
+    assert(i != NULL);
+
+    // make sure we are actualy waiting for a CNAME callback to be run.
+    assert(i->cname_wait > 0);
+    // count this event. its being handled.
+    i->cname_wait--;
+
+    pname = (char*)i->hash.key;
+    assert(pname != NULL);
+
+    debugs(14, 5, "ipcacheHandleCnameRecurse: Handling CNAME recursion. CBDATA('" << gcb->data << "')='" << pname << "' -> " << std::hex << i);
+
+    if(i == NULL) {
+        return; // Parent has expired. Don't merge, just leave for future Ref:
+    }
+
+    /* IFF addrs is NULL (Usually an Error or Timeout occured on lookup.) */
+    /* Ignore it and HOPE that we got some Additional records to use.     */
+    if(addrs == NULL)
+        return;
+
+    ccount = (0+ addrs->count);
+    pcount = (0+ i->addrs.count);
+    ttl = i->expires;
+
+    /* IFF no CNAME results. do none of the processing BUT finish anyway. */
+    if(addrs) {
+
+        debugs(14, 5, "ipcacheHandleCnameRecurse: Merge IP Lists for " << pname << " (" << pcount << "+" << ccount << ")");
+
+            /* add new IP records to entry */
+        tmpbuf = i->addrs.in_addrs;
+        i->addrs.in_addrs = NULL;
+        ipcacheMergeIPLists(tmpbuf, pcount, addrs->in_addrs, ccount, &(i->addrs.in_addrs), fc);
+        debugs(14,8, HERE << "in=" << tmpbuf << ", out=" << i->addrs.in_addrs );
+        assert(tmpbuf);
+        safe_free(tmpbuf);
+
+        if( pcount > 0) {
+            /* IFF the parent initial lookup was given Additional records with A */
+            // clear the 'bad IP mask'
+            safe_free(i->addrs.bad_mask);
+        }
+        // create a new bad IP mask to fit the new size needed.
+        if(fc > 0) {
+            i->addrs.bad_mask = (unsigned char*)xcalloc(fc, sizeof(unsigned char));
+            memset(i->addrs.bad_mask, 0, sizeof(unsigned char)*fc);
+        }
+
+        if (fc < 256)
+            i->addrs.count = (unsigned char) fc;
+        else
+            i->addrs.count = 255;
+
+        if (ttl == 0 || ttl > Config.positiveDnsTtl)
+            ttl = Config.positiveDnsTtl;
+
+        if (ttl < Config.negativeDnsTtl)
+            ttl = Config.negativeDnsTtl;
+
+        i->expires = squid_curtime + ttl;
+
+        i->flags.negcached = 0;
+
+        i->addrs.cur = 0;
+
+        i->addrs.badcount = 0;
+    }
+
+    if(fc == 0) {
+        i->error_message = xstrdup("No DNS Records");
+    }
+
+    /* finish the lookup we were doing on parent when we got side-tracked for CNAME loop */
+    if(i->cname_wait == 0) {
+        ipcacheAddEntry(i);
+        ipcacheCallback(i);
+    }
+    // else still more CNAME to be found.
 }
 
 void
@@ -740,17 +1075,29 @@ ipcache_addrs *
 ipcacheCheckNumeric(const char *name)
 {
 
-    struct IN_ADDR ip;
+    IPAddress ip;
     /* check if it's already a IP address in text form. */
 
-    if (!safe_inet_addr(name, &ip))
+    /* it may be IPv6-wrapped */
+    if(name[0] == '[') {
+        char *tmp = xstrdup(&name[1]);
+        tmp[strlen(tmp)-1] = '\0';
+        if (!(ip = tmp)) {
+            delete tmp;
+            return NULL;
+        }
+        delete tmp;
+    }
+    else if (!(ip = name))
         return NULL;
 
+    debugs(14, 4, "ipcacheCheckNumeric: HIT_BYPASS for '" << name << "' == " << ip );
+
     static_addrs.count = 1;
 
     static_addrs.cur = 0;
 
-    static_addrs.in_addrs[0].s_addr = ip.s_addr;
+    static_addrs.in_addrs[0] = ip;
 
     static_addrs.bad_mask[0] = FALSE;
 
@@ -771,7 +1118,11 @@ ipcacheLockEntry(ipcache_entry * i)
 static void
 ipcacheUnlockEntry(ipcache_entry * i)
 {
-    assert(i->locks > 0);
+    if(i->locks < 1) {
+        debugs(14, 1, "WARNING: ipcacheEntry unlocked with no lock! locks=" << i->locks);
+        return;
+    }
+
     i->locks--;
 
     if (ipcacheExpiredEntry(i))
@@ -815,7 +1166,7 @@ ipcacheCycleAddr(const char *name, ipcache_addrs * ia)
         ia->cur = 0;
     }
 
-    debugs(14, 3, "ipcacheCycleAddr: " << name << " now at " << inet_ntoa(ia->in_addrs[ia->cur]));
+    debugs(14, 3, "ipcacheCycleAddr: " << name << " now at " << ia->in_addrs[ia->cur] << " (" << ia->cur << " of " << ia->count << ")");
 }
 
 /*
@@ -823,8 +1174,7 @@ ipcacheCycleAddr(const char *name, ipcache_addrs * ia)
  * advance the current pointer to the next OK address.
  */
 void
-
-ipcacheMarkBadAddr(const char *name, struct IN_ADDR addr)
+ipcacheMarkBadAddr(const char *name, IPAddress &addr)
 {
     ipcache_entry *i;
     ipcache_addrs *ia;
@@ -837,7 +1187,7 @@ ipcacheMarkBadAddr(const char *name, struct IN_ADDR addr)
 
     for (k = 0; k < (int) ia->count; k++)
     {
-        if (ia->in_addrs[k].s_addr == addr.s_addr)
+        if (addr == ia->in_addrs[k] )
             break;
     }
 
@@ -849,7 +1199,7 @@ ipcacheMarkBadAddr(const char *name, struct IN_ADDR addr)
         ia->bad_mask[k] = TRUE;
         ia->badcount++;
         i->expires = XMIN(squid_curtime + XMAX((time_t)60, Config.negativeDnsTtl), i->expires);
-        debugs(14, 2, "ipcacheMarkBadAddr: " << name << " [" << inet_ntoa(addr) << "]");
+        debugs(14, 2, "ipcacheMarkBadAddr: " << name << " " << addr );
     }
 
     ipcacheCycleAddr(name, ia);
@@ -857,7 +1207,7 @@ ipcacheMarkBadAddr(const char *name, struct IN_ADDR addr)
 
 void
 
-ipcacheMarkGoodAddr(const char *name, struct IN_ADDR addr)
+ipcacheMarkGoodAddr(const char *name, IPAddress &addr)
 {
     ipcache_entry *i;
     ipcache_addrs *ia;
@@ -870,7 +1220,7 @@ ipcacheMarkGoodAddr(const char *name, struct IN_ADDR addr)
 
     for (k = 0; k < (int) ia->count; k++)
     {
-        if (ia->in_addrs[k].s_addr == addr.s_addr)
+        if (addr == ia->in_addrs[k])
             break;
     }
 
@@ -884,7 +1234,7 @@ ipcacheMarkGoodAddr(const char *name, struct IN_ADDR addr)
 
     ia->badcount--;
 
-    debugs(14, 2, "ipcacheMarkGoodAddr: " << name << " [" << inet_ntoa(addr) << "]");
+    debugs(14, 2, "ipcacheMarkGoodAddr: " << name << " " << addr );
 }
 
 static void
@@ -926,14 +1276,18 @@ ipcacheAddEntryFromHosts(const char *name, const char *ipaddr)
 {
     ipcache_entry *i;
 
-    struct IN_ADDR ip;
+    IPAddress ip;
 
-    if (!safe_inet_addr(ipaddr, &ip)) {
+    if (!(ip = ipaddr)) {
+#if USE_IPV6
         if (strchr(ipaddr, ':') && strspn(ipaddr, "0123456789abcdefABCDEF:") == strlen(ipaddr)) {
             debugs(14, 3, "ipcacheAddEntryFromHosts: Skipping IPv6 address '" << ipaddr << "'");
         } else {
             debugs(14, 1, "ipcacheAddEntryFromHosts: Bad IP address '" << ipaddr << "'");
         }
+#else
+       debugs(14, 1, "ipcacheAddEntryFromHosts: Bad IP address '" << ipaddr << "'");
+#endif
 
         return 1;
     }
@@ -954,9 +1308,9 @@ ipcacheAddEntryFromHosts(const char *name, const char *ipaddr)
     i->addrs.cur = 0;
     i->addrs.badcount = 0;
 
-    i->addrs.in_addrs = (struct IN_ADDR *)xcalloc(1, sizeof(struct IN_ADDR));
+    i->addrs.in_addrs = (IPAddress *)xcalloc(1, sizeof(IPAddress));
     i->addrs.bad_mask = (unsigned char *)xcalloc(1, sizeof(unsigned char));
-    i->addrs.in_addrs[0].s_addr = ip.s_addr;
+    i->addrs.in_addrs[0] = ip;
     i->addrs.bad_mask[0] = FALSE;
     i->flags.fromhosts = 1;
     ipcacheAddEntry(i);
index cd3f631f756e099dc78ebad223b279c91fa61875..ed11df33dbb16ae9a2c3a50d9102dd09abe74818 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: main.cc,v 1.451 2007/12/02 08:23:56 amosjeffries Exp $
+ * $Id: main.cc,v 1.452 2007/12/14 23:11:47 amosjeffries Exp $
  *
  * DEBUG: section 1     Startup and Main Loop
  * AUTHOR: Harvest Derived
@@ -72,6 +72,7 @@
 #include "SwapDir.h"
 #include "forward.h"
 #include "MemPool.h"
+#include "ICMPSquid.h"
 
 #if USE_WIN32_SERVICE
 
@@ -561,7 +562,7 @@ serverConnectionsOpen(void)
 #endif
 
     clientdbInit();
-    icmpOpen();
+    icmpEngine.Open();
     netdbInit();
     asnInit();
     ACL::Initialize();
@@ -583,7 +584,7 @@ serverConnectionsClose(void)
     htcpSocketShutdown();
 #endif
 
-    icmpClose();
+    icmpEngine.Close();
 #ifdef SQUID_SNMP
 
     snmpConnectionShutdown();
@@ -693,7 +694,7 @@ mainReconfigure(void)
 static void
 mainRotate(void)
 {
-    icmpClose();
+    icmpEngine.Close();
 #if USE_DNSSERVERS
 
     dnsShutdown();
@@ -713,7 +714,7 @@ mainRotate(void)
     fwdLogRotate();
 #endif
 
-    icmpOpen();
+    icmpEngine.Open();
 #if USE_DNSSERVERS
 
     dnsInit();
@@ -1124,18 +1125,6 @@ main(int argc, char **argv)
     if (oldmask)
         umask(oldmask);
 
-    memset(&local_addr, '\0', sizeof(struct IN_ADDR));
-
-    safe_inet_addr(localhost, &local_addr);
-
-    memset(&any_addr, '\0', sizeof(struct IN_ADDR));
-
-    safe_inet_addr("0.0.0.0", &any_addr);
-
-    memset(&no_addr, '\0', sizeof(struct IN_ADDR));
-
-    safe_inet_addr("255.255.255.255", &no_addr);
-
     squid_srandom(time(NULL));
 
     getCurrentTime();
@@ -1550,8 +1539,8 @@ watch_child(char *argv[])
                    pid, WEXITSTATUS(status));
         } else if (WIFSIGNALED(status)) {
             syslog(LOG_NOTICE,
-                   "Squid Parent: child process %d exited due to signal %d",
-                   pid, WTERMSIG(status));
+                   "Squid Parent: child process %d exited due to signal %d with status %d",
+                   pid, WTERMSIG(status), WEXITSTATUS(status));
         } else {
             syslog(LOG_NOTICE, "Squid Parent: child process %d exited", pid);
         }
index 09432e94a319754e8f200a48a9a5cc4cf13aa60d..aa3d3524814327f59108632aa7ebf3b92a0e0e56 100644 (file)
@@ -2,7 +2,7 @@
 
 SQUID-MIB DEFINITIONS ::= BEGIN
 --
--- $Id: mib.txt,v 1.31 2007/08/27 12:50:43 hno Exp $
+-- $Id: mib.txt,v 1.32 2007/12/14 23:11:47 amosjeffries Exp $
 --
 
 IMPORTS
@@ -11,12 +11,15 @@ IMPORTS
                FROM SNMPv2-SMI
 
        DisplayString
-               FROM SNMPv2-TC;
+               FROM SNMPv2-TC
+
+       InetAddressType, InetAddress
+               FROM INET-ADDRESS-MIB;
 
 nlanr OBJECT IDENTIFIER ::= { enterprises 3495 }
 
 squid MODULE-IDENTITY
-    LAST-UPDATED "9809220000Z"
+    LAST-UPDATED "9708120000Z"
     ORGANIZATION "National Laboratory for Applied Network Research"
     CONTACT-INFO
             "        Squid Developers
@@ -26,6 +29,9 @@ squid MODULE-IDENTITY
                "Squid MIB defined for the management of the Squid
                proxy server. See http://www.squid-cache.org/."
        
+    REVISION      "9708120000Z"
+    DESCRIPTION
+               "Added support for IPv6 Technology."
     REVISION      "9809220000Z"
     DESCRIPTION
                "Move to SMIv2. Prepare to split into proxy/squid."
@@ -47,7 +53,7 @@ squid MODULE-IDENTITY
 
 
 --
--- cacheSystem group
+-- cacheSystem group { squid 1 }
 --
 
         cacheSysVMsize OBJECT-TYPE
@@ -75,7 +81,7 @@ squid MODULE-IDENTITY
        ::= { cacheSystem 3 }
 
 --
--- config group
+-- cacheConfig group { squid 2 }
 --
 -- Contains configuration information including peers etc.
 --
@@ -162,7 +168,7 @@ squid MODULE-IDENTITY
 
 
 --
--- performance group { squid 3 }
+-- cachePerformance group { squid 3 }
 --
 
        cacheSysPerf    OBJECT IDENTIFIER ::= { cachePerf 1 }
@@ -531,7 +537,7 @@ squid MODULE-IDENTITY
         ::= { cacheMedianSvcEntry 11 }
 
 --
--- cacheNetwork group
+-- cacheNetwork group { squid 4 }
 --
 -- This material is probably best suited elsewhere, however for now it
 -- will reside here until the both the Proxy and Squid MIBs are implimented.
@@ -698,7 +704,7 @@ squid MODULE-IDENTITY
         ::= { cacheDns 3 }
        
 --
--- cacheMesh group
+-- cacheMesh group { squid 5 }
 --
 
        cachePeerTable OBJECT-TYPE
@@ -716,12 +722,14 @@ squid MODULE-IDENTITY
                STATUS current
                DESCRIPTION
                        " An entry in cachePeerTable "
-               INDEX   { cachePeerAddr }
+               INDEX   { cachePeerIndex }
        ::= { cachePeerTable 1 }
 
        CachePeerEntry ::= SEQUENCE {
+         cachePeerIndex        CachePeerIndex, 
          cachePeerName         DisplayString,
-         cachePeerAddr         IpAddress,
+         cachePeerAddressType  InetAddressType,
+         cachePeerAddress      InetAddress,
          cachePeerPortHttp     Integer32 (1..65535),
          cachePeerPortIcp      Integer32 (1..65535),
          cachePeerType         Integer32,
@@ -735,6 +743,31 @@ squid MODULE-IDENTITY
          cachePeerKeepAlRecv   Counter32
        }
 
+       CachePeerIndex ::= TEXTUAL-CONVENTION
+             DISPLAY-HINT "d"
+             STATUS       current
+             DESCRIPTION
+               "A unique value, greater than zero for each
+               cache peer instance in the managed
+               system. It is recommended that values are assigned
+               contiguously starting from 1. The value for each
+               cache peer index must remain constant
+               at least from one re-initialization of the entity's
+               network management system to the next
+               re-initialization."
+             SYNTAX       Integer32 (1..2147483647)
+        END
+
+
+       cachePeerIndex OBJECT-TYPE
+               SYNTAX CachePeerIndex
+               MAX-ACCESS read-only
+               STATUS current
+               DESCRIPTION
+                          "A unique non-zero value identifying
+                            the particular cache Peer."
+       ::= { cachePeerEntry 1 }
+
        cachePeerName OBJECT-TYPE
                SYNTAX DisplayString
                MAX-ACCESS read-only
@@ -742,15 +775,43 @@ squid MODULE-IDENTITY
                DESCRIPTION
                          " The FQDN name or internal alias for the
                            peer cache "
-       ::= { cachePeerEntry 1 }
+       ::= { cachePeerEntry 2 }
+
+       cachePeerAddressType OBJECT-TYPE
+       SYNTAX      InetAddressType
+       MAX-ACCESS  read-only
+       STATUS      current
+       DESCRIPTION
+               "The type of Internet address by which the peer
+               cache is reachable."
+
+       ::= { cachePeerEntry 3 }
+
+       cachePeerAddress OBJECT-TYPE
+       SYNTAX      InetAddress (SIZE (1..64))
+       MAX-ACCESS  read-only
+       STATUS      current
+       DESCRIPTION
+       "The Internet address for the peer cache.  The type of this
+        address is determined by the value of the peerAddressType
+         object.  Note that implementations must limit themselves
+         to a single entry in this table per reachable peer.
+         The peerAddress may not be empty due to the SIZE
+         restriction.
+
+         If a row is created administratively by an SNMP
+         operation and the address type value is dns(16), then
+         the agent stores the DNS name internally.  A DNS name
+         lookup must be performed on the internally stored DNS
+         name whenever it is being used to contact the peer.
+
+         If a row is created by the managed entity itself and
+         the address type value is dns(16), then the agent
+         stores the IP address internally.  A DNS reverse lookup
+         must be performed on the internally stored IP address
+         whenever the value is retrieved via SNMP."
+        ::= { cachePeerEntry 4 }
 
-       cachePeerAddr OBJECT-TYPE
-                SYNTAX IpAddress
-                MAX-ACCESS read-only
-                STATUS current
-               DESCRIPTION
-                       " The IP Address of the peer cache "
-        ::= { cachePeerEntry 2 }
 
        cachePeerPortHttp OBJECT-TYPE
                 SYNTAX Integer32
@@ -758,7 +819,7 @@ squid MODULE-IDENTITY
                 STATUS current
                DESCRIPTION
                        " The port the peer listens for HTTP requests "
-        ::= { cachePeerEntry 3 }
+        ::= { cachePeerEntry 5 }
 
        cachePeerPortIcp OBJECT-TYPE
                 SYNTAX Integer32
@@ -767,7 +828,7 @@ squid MODULE-IDENTITY
                DESCRIPTION
                        " The port the peer listens for ICP requests
                          should be 0 if not configured to send ICP requests "
-        ::= { cachePeerEntry 4 }
+        ::= { cachePeerEntry 6 }
 
        cachePeerType OBJECT-TYPE
                 SYNTAX INTEGER
@@ -775,7 +836,7 @@ squid MODULE-IDENTITY
                 STATUS current
                 DESCRIPTION
                         " Peer Type "
-       ::= { cachePeerEntry 5 }
+       ::= { cachePeerEntry 7 }
 
        cachePeerState OBJECT-TYPE
                 SYNTAX INTEGER
@@ -783,7 +844,7 @@ squid MODULE-IDENTITY
                 STATUS current
                DESCRIPTION
                        " The operational state of this peer "
-        ::= { cachePeerEntry 6 }
+        ::= { cachePeerEntry 8 }
 
         cachePeerPingsSent OBJECT-TYPE
                 SYNTAX Counter32
@@ -791,7 +852,7 @@ squid MODULE-IDENTITY
                 STATUS current
                DESCRIPTION
                        " Number of pings sent to peer "
-        ::= { cachePeerEntry 7 }
+        ::= { cachePeerEntry 9 }
 
         cachePeerPingsAcked OBJECT-TYPE
                 SYNTAX Counter32
@@ -799,7 +860,7 @@ squid MODULE-IDENTITY
                 STATUS current
                DESCRIPTION
                        " Number of pings received from peer "
-        ::= {  cachePeerEntry 8 }
+        ::= {  cachePeerEntry 10 }
 
         cachePeerFetches OBJECT-TYPE
                 SYNTAX Counter32
@@ -807,7 +868,7 @@ squid MODULE-IDENTITY
                 STATUS current
                DESCRIPTION
                        " Number of times this peer was selected  "
-        ::= { cachePeerEntry 9 }
+        ::= { cachePeerEntry 11 }
 
         cachePeerRtt OBJECT-TYPE
                 SYNTAX Integer32
@@ -815,7 +876,7 @@ squid MODULE-IDENTITY
                 STATUS current
                DESCRIPTION
                        " Last known round-trip time to the peer (in ms) "
-        ::= { cachePeerEntry 10 }
+        ::= { cachePeerEntry 12 }
 
         cachePeerIgnored OBJECT-TYPE
                 SYNTAX Counter32
@@ -823,7 +884,7 @@ squid MODULE-IDENTITY
                 STATUS current
                DESCRIPTION
                        " How many times this peer was ignored "
-        ::= { cachePeerEntry 11 }
+        ::= { cachePeerEntry 13 }
 
         cachePeerKeepAlSent OBJECT-TYPE
                 SYNTAX Counter32
@@ -831,7 +892,7 @@ squid MODULE-IDENTITY
                 STATUS current
                DESCRIPTION
                        " Number of keepalives sent "
-        ::= { cachePeerEntry 12 }
+        ::= { cachePeerEntry 14 }
 
         cachePeerKeepAlRecv OBJECT-TYPE
                 SYNTAX Counter32
@@ -839,7 +900,7 @@ squid MODULE-IDENTITY
                 STATUS current
                DESCRIPTION
                        " Number of keepalives received "
-        ::= { cachePeerEntry 13 }
+        ::= { cachePeerEntry 15 }
 
 ---
 --- Table of cache's clients, with statistics. Children caches can be identified
@@ -854,17 +915,19 @@ squid MODULE-IDENTITY
                     "A list of cache client entries."
                ::= { cacheMesh 2 }
 
+
        cacheClientEntry OBJECT-TYPE
            SYNTAX CacheClientEntry
            ACCESS  not-accessible
            STATUS  mandatory
            DESCRIPTION
                     "An entry in cacheClientTable "
-          INDEX { cacheClientAddr }
+          INDEX { cacheClientAddressType, cacheClientAddress }
        ::= { cacheClientTable 1 }
 
        CacheClientEntry ::= SEQUENCE {
-                       cacheClientAddr         IpAddress,
+               cacheClientAddressType  InetAddressType,
+               cacheClientAddress      InetAddress,
                        cacheClientHttpRequests Counter32,
                        cacheClientHttpKb       Counter32,
                        cacheClientHttpHits     Counter32,
@@ -875,21 +938,46 @@ squid MODULE-IDENTITY
                        cacheClientIcpHitKb     Counter32
        }
 
-       cacheClientAddr OBJECT-TYPE
-                SYNTAX IpAddress
+       cacheClientAddressType OBJECT-TYPE
+                SYNTAX InetAddressType
                 MAX-ACCESS read-only
                 STATUS current
                DESCRIPTION
                     "The client's IP address "
         ::= { cacheClientEntry 1 }
 
+       cacheClientAddress OBJECT-TYPE
+       SYNTAX      InetAddress (SIZE (1..64))
+       MAX-ACCESS  read-only
+       STATUS      current
+       DESCRIPTION
+       "The Internet address for the client.  The type of this
+        address is determined by the value of the peerAddressType
+         object.  Note that implementations must limit themselves
+         to a single entry in this table per reachable peer.
+         The peerAddress may not be empty due to the SIZE
+         restriction.
+
+         If a row is created administratively by an SNMP
+         operation and the address type value is dns(16), then
+         the agent stores the DNS name internally.  A DNS name
+         lookup must be performed on the internally stored DNS
+         name whenever it is being used to contact the peer.
+
+         If a row is created by the managed entity itself and
+         the address type value is dns(16), then the agent
+         stores the IP address internally.  A DNS reverse lookup
+         must be performed on the internally stored IP address
+         whenever the value is retrieved via SNMP."
+        ::= { cacheClientEntry 2 }
+
        cacheClientHttpRequests OBJECT-TYPE
                 SYNTAX Counter32
                 MAX-ACCESS read-only
                 STATUS current
                DESCRIPTION
                     " Number of HTTP requests received from client "
-        ::= { cacheClientEntry 2 }
+        ::= { cacheClientEntry 3 }
 
        cacheClientHttpKb OBJECT-TYPE
                 SYNTAX Counter32
@@ -897,7 +985,7 @@ squid MODULE-IDENTITY
                 STATUS current
                DESCRIPTION
                     " Amount of total HTTP traffic to this client  "
-        ::= { cacheClientEntry 3 }
+        ::= { cacheClientEntry 4 }
 
         cacheClientHttpHits OBJECT-TYPE
                 SYNTAX Counter32
@@ -905,7 +993,7 @@ squid MODULE-IDENTITY
                 STATUS current
                DESCRIPTION
                     " Number of hits in response to this client's HTTP requests "
-        ::= { cacheClientEntry 4 }
+        ::= { cacheClientEntry 5 }
 
         cacheClientHTTPHitKb OBJECT-TYPE
                 SYNTAX Counter32
@@ -913,7 +1001,7 @@ squid MODULE-IDENTITY
                 STATUS current
                DESCRIPTION
                     " Amount of HTTP hit traffic in KB "
-        ::= { cacheClientEntry 5 }
+        ::= { cacheClientEntry 6 }
 
        cacheClientIcpRequests OBJECT-TYPE
                 SYNTAX Counter32
@@ -921,7 +1009,7 @@ squid MODULE-IDENTITY
                 STATUS current
                DESCRIPTION
                     " Number of ICP requests received from client "
-        ::= { cacheClientEntry 6 }
+        ::= { cacheClientEntry 7 }
 
        cacheClientIcpKb OBJECT-TYPE
                 SYNTAX Counter32
@@ -929,7 +1017,7 @@ squid MODULE-IDENTITY
                 STATUS current
                DESCRIPTION
                     " Amount of total ICP traffic to this client (child) "
-        ::= { cacheClientEntry 7 }
+        ::= { cacheClientEntry 8 }
 
         cacheClientIcpHits OBJECT-TYPE
                 SYNTAX Counter32
@@ -937,7 +1025,7 @@ squid MODULE-IDENTITY
                 STATUS current
                DESCRIPTION
                     " Number of hits in response to this client's ICP requests "
-        ::= { cacheClientEntry 8 }
+        ::= { cacheClientEntry 9 }
 
         cacheClientIcpHitKb OBJECT-TYPE
                 SYNTAX Counter32
index b43d0c072b88d8c724f510f368dc18881f8d0d9a..effe4137bdbaed6ac938e8bb4569adc1b6ec07a8 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: multicast.cc,v 1.12 2007/04/28 22:26:37 hno Exp $
+ * $Id: multicast.cc,v 1.13 2007/12/14 23:11:47 amosjeffries Exp $
  *
  * DEBUG: section 7     Multicast
  * AUTHOR: Martin Hamilton
@@ -66,15 +66,23 @@ mcastJoinGroups(const ipcache_addrs * ia, void *datanotused)
     }
 
     for (i = 0; i < (int) ia->count; i++) {
-        debugs(7, 10, "Listening for ICP requests on " << inet_ntoa(*(ia->in_addrs + i)));
-        mr.imr_multiaddr.s_addr = (ia->in_addrs + i)->s_addr;
+        debugs(7, 10, "Listening for ICP requests on " << ia->in_addrs[i] );
+
+#if USE_IPV6
+        if( ! ia->in_addrs[i].IsIPv4() ) {
+            debugs(7, 10, "ERROR: IPv6 Multicast Listen has not been implemented!");
+            continue;
+        }
+#endif
+
+        ia->in_addrs[i].GetInAddr(mr.imr_multiaddr);
+
         mr.imr_interface.s_addr = INADDR_ANY;
         x = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
-
                        (char *) &mr, sizeof(struct ip_mreq));
 
         if (x < 0)
-            debugs(7, 1, "comm_join_mcast_groups: FD " << fd << ", [" << inet_ntoa(*(ia->in_addrs + i)) << "]");
+            debugs(7, 1, "comm_join_mcast_groups: FD " << fd << ", IP=" << ia->in_addrs[i]);
 
         x = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &c, 1);
 
index b4e919eef842dfa9498031876b23c52837891995..df2aee9044dcc895a9739a2e7196b9eb133f2067 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: neighbors.cc,v 1.350 2007/11/13 23:25:34 rousskov Exp $
+ * $Id: neighbors.cc,v 1.351 2007/12/14 23:11:47 amosjeffries Exp $
  *
  * DEBUG: section 15    Neighbor Routines
  * AUTHOR: Harvest Derived
@@ -45,6 +45,7 @@
 #include "PeerSelectState.h"
 #include "SquidTime.h"
 #include "Store.h"
+#include "IPAddress.h"
 
 /* count mcast group peers every 15 minutes */
 #define MCAST_COUNT_RATE 900
@@ -66,7 +67,7 @@ static void peerCountMcastPeersStart(void *data);
 static void peerCountMcastPeersSchedule(peer * p, time_t when);
 static IRCB peerCountHandleIcpReply;
 
-static void neighborIgnoreNonPeer(const struct sockaddr_in *, icp_opcode);
+static void neighborIgnoreNonPeer(const IPAddress &, icp_opcode);
 static OBJH neighborDumpPeers;
 static OBJH neighborDumpNonPeers;
 static void dump_peers(StoreEntry * sentry, peer * peers);
@@ -94,20 +95,17 @@ neighborTypeStr(const peer * p)
 
 
 peer *
-
-whichPeer(const struct sockaddr_in * from)
+whichPeer(const IPAddress &from)
 {
     int j;
-    u_short port = ntohs(from->sin_port);
 
-    struct IN_ADDR ip = from->sin_addr;
     peer *p = NULL;
-    debugs(15, 3, "whichPeer: from " << inet_ntoa(ip) << " port " << port);
+    debugs(15, 3, "whichPeer: from " << from);
 
     for (p = Config.peers; p; p = p->next)
     {
         for (j = 0; j < p->n_addresses; j++) {
-            if (ip.s_addr == p->addresses[j].s_addr && port == p->icp.port) {
+            if (from == p->addresses[j] && from.GetPort() == p->icp.port) {
                 return p;
             }
         }
@@ -123,7 +121,7 @@ neighborType(const peer * p, const HttpRequest * request)
     const struct _domain_type *d = NULL;
 
     for (d = p->typelist; d; d = d->next) {
-        if (0 == matchDomainName(request->host, d->domain))
+        if (0 == matchDomainName(request->GetHost(), d->domain))
             if (d->type != PEER_NONE)
                 return d->type;
     }
@@ -165,7 +163,7 @@ peerAllowedToUse(const peer * p, HttpRequest * request)
     do_ping = 0;
 
     for (d = p->peer_domain; d; d = d->next) {
-        if (0 == matchDomainName(request->host, d->domain)) {
+        if (0 == matchDomainName(request->GetHost(), d->domain)) {
             do_ping = d->do_ping;
             break;
         }
@@ -185,8 +183,6 @@ peerAllowedToUse(const peer * p, HttpRequest * request)
 
     checklist.my_addr = request->my_addr;
 
-    checklist.my_port = request->my_port;
-
     checklist.request = HTTPMSGLOCK(request);
 
     checklist.accessList = cbdataReference(p->access);
@@ -490,33 +486,31 @@ neighborRemove(peer * target)
 void
 neighbors_init(void)
 {
-
-    struct sockaddr_in name;
-
-    socklen_t len = sizeof(struct sockaddr_in);
-
+    IPAddress nul;
+    struct addrinfo *AI = NULL;
     struct servent *sep = NULL;
     const char *me = getMyHostname();
-    peer *thisPeer;
-    peer *next;
+    peer *thisPeer = NULL;
+    peer *next = NULL;
     int fd = theInIcpConnection;
 
-    if (fd >= 0) {
+    /* setup addrinfo for use */
+    nul.InitAddrInfo(AI);
 
-        memset(&name, '\0', sizeof(struct sockaddr_in));
+    if (fd >= 0) {
 
-        if (getsockname(fd, (struct sockaddr *) &name, &len) < 0)
-            debugs(15, 1, "getsockname(" << fd << "," << &name << "," << &len << ") failed.");
+        if (getsockname(fd, AI->ai_addr, &AI->ai_addrlen) < 0)
+            debugs(15, 1, "getsockname(" << fd << "," << AI->ai_addr << "," << &AI->ai_addrlen << ") failed.");
 
         for (thisPeer = Config.peers; thisPeer; thisPeer = next) {
-            http_port_list *s;
+            http_port_list *s = NULL;
             next = thisPeer->next;
 
             if (0 != strcmp(thisPeer->host, me))
                 continue;
 
             for (s = Config.Sockaddr.http; s; s = s->next) {
-                if (thisPeer->http_port != ntohs(s->s.sin_port))
+                if (thisPeer->http_port != s->s.GetPort())
                     continue;
 
                 debugs(15, 1, "WARNING: Peer looks like this host");
@@ -526,7 +520,6 @@ neighbors_init(void)
                        "/" << thisPeer->http_port << "/" <<
                        thisPeer->icp.port);
 
-
                 neighborRemove(thisPeer);
             }
         }
@@ -541,12 +534,14 @@ neighbors_init(void)
         echo_hdr.reqnum = 0;
         echo_hdr.flags = 0;
         echo_hdr.pad = 0;
-        echo_hdr.shostid = name.sin_addr.s_addr;
+        nul = *AI;
+        nul.GetInAddr( *((struct in_addr*)&echo_hdr.shostid) );
         sep = getservbyname("echo", "udp");
         echo_port = sep ? ntohs((u_short) sep->s_port) : 7;
     }
 
     first_ping = Config.peers;
+    nul.FreeAddrInfo(AI);
 }
 
 void
@@ -640,7 +635,7 @@ neighborsUdpPing(HttpRequest * request,
                 echo_hdr.reqnum = reqnum;
                 query = _icp_common_t::createMessage(ICP_DECHO, 0, url, reqnum, 0);
                 icpUdpSend(theOutIcpConnection,
-                           &p->in_addr,
+                           p->in_addr,
                            query,
                            LOG_ICP_QUERY,
                            0);
@@ -654,7 +649,7 @@ neighborsUdpPing(HttpRequest * request,
                 query = _icp_common_t::createMessage(ICP_QUERY, flags, url, reqnum, 0);
 
                 icpUdpSend(theOutIcpConnection,
-                           &p->in_addr,
+                           p->in_addr,
                            query,
                            LOG_ICP_QUERY,
                            0);
@@ -701,39 +696,6 @@ neighborsUdpPing(HttpRequest * request,
     if ((first_ping = first_ping->next) == NULL)
         first_ping = Config.peers;
 
-#if ALLOW_SOURCE_PING
-    /* only do source_ping if we have neighbors */
-    if (Config.npeers) {
-        const ipcache_addrs *ia = NULL;
-
-        struct sockaddr_in to_addr;
-        char *host = request->host;
-
-        if (!Config.onoff.source_ping) {
-            debugs(15, 6, "neighborsUdpPing: Source Ping is disabled.");
-        } else if ((ia = ipcache_gethostbyname(host, 0))) {
-            debugs(15, 6, "neighborsUdpPing: Source Ping: to " << host << " for '" << url << "'");
-            echo_hdr.reqnum = reqnum;
-
-            if (icmp_sock != -1) {
-                icmpSourcePing(ia->in_addrs[ia->cur], &echo_hdr, url);
-            } else {
-                to_addr.sin_family = AF_INET;
-                to_addr.sin_addr = ia->in_addrs[ia->cur];
-                to_addr.sin_port = htons(echo_port);
-                query = _icp_common_t::createMessage(ICP_SECHO, 0, url, reqnum, 0);
-                icpUdpSend(theOutIcpConnection,
-                           &to_addr,
-                           query,
-                           LOG_ICP_QUERY,
-                           0);
-            }
-        } else {
-            debugs(15, 6, "neighborsUdpPing: Source Ping: unknown host: " << host);
-        }
-    }
-
-#endif
     /*
      * How many replies to expect?
      */
@@ -967,17 +929,16 @@ neighborCountIgnored(peer * p)
 static peer *non_peers = NULL;
 
 static void
-
-neighborIgnoreNonPeer(const struct sockaddr_in *from, icp_opcode opcode)
+neighborIgnoreNonPeer(const IPAddress &from, icp_opcode opcode)
 {
     peer *np;
 
     for (np = non_peers; np; np = np->next)
     {
-        if (np->in_addr.sin_addr.s_addr != from->sin_addr.s_addr)
+        if (np->in_addr != from)
             continue;
 
-        if (np->in_addr.sin_port != from->sin_port)
+        if (np->in_addr.GetPort() != from.GetPort())
             continue;
 
         break;
@@ -986,11 +947,11 @@ neighborIgnoreNonPeer(const struct sockaddr_in *from, icp_opcode opcode)
     if (np == NULL)
     {
         np = (peer *)xcalloc(1, sizeof(peer));
-        np->in_addr.sin_addr = from->sin_addr;
-        np->in_addr.sin_port = from->sin_port;
-        np->icp.port = ntohl(from->sin_port);
+        np->in_addr = from;
+        np->icp.port = from.GetPort();
         np->type = PEER_NONE;
-        np->host = xstrdup(inet_ntoa(from->sin_addr));
+        np->host = new char[MAX_IPSTRLEN];
+        from.NtoA(np->host,MAX_IPSTRLEN);
         np->next = non_peers;
         non_peers = np;
     }
@@ -1030,7 +991,7 @@ ignoreMulticastReply(peer * p, MemObject * mem)
  */
 void
 
-neighborsUdpAck(const cache_key * key, icp_common_t * header, const struct sockaddr_in *from)
+neighborsUdpAck(const cache_key * key, icp_common_t * header, const IPAddress &from)
 {
     peer *p = NULL;
     StoreEntry *entry;
@@ -1132,14 +1093,8 @@ neighborsUdpAck(const cache_key * key, icp_common_t * header, const struct socka
         if (p) {
             debugs(15, 1, "Ignoring SECHO from neighbor " << p->host);
             neighborCountIgnored(p);
-#if ALLOW_SOURCE_PING
-
-        } else if (Config.onoff.source_ping) {
-            mem->ping_reply_callback(NULL, ntype, PROTO_ICP, header, mem->ircb_data);
-#endif
-
         } else {
-            debugs(15, 1, "Unsolicited SECHO from " << inet_ntoa(from->sin_addr));
+            debugs(15, 1, "Unsolicited SECHO from " << from);
         }
     } else if (opcode == ICP_DENIED)
     {
@@ -1199,24 +1154,33 @@ int
 neighborUp(const peer * p)
 {
     if (!p->tcp_up) {
-        if (!peerProbeConnect((peer *) p))
+        if (!peerProbeConnect((peer *) p)) {
+            debugs(15, 8, "neighborUp: DOWN (probed): " << p->host << " (" << p->in_addr << ")");
             return 0;
+        }
     }
 
     /*
      * The peer can not be UP if we don't have any IP addresses
      * for it. 
      */
-    if (0 == p->n_addresses)
+    if (0 == p->n_addresses) {
+        debugs(15, 8, "neighborUp: DOWN (no-ip): " << p->host << " (" << p->in_addr << ")");
         return 0;
+    }
 
-    if (p->options.no_query)
+    if (p->options.no_query) {
+        debugs(15, 8, "neighborUp: UP (no-query): " << p->host << " (" << p->in_addr << ")");
         return 1;
+    }
 
     if (p->stats.probe_start != 0 &&
-            squid_curtime - p->stats.probe_start > Config.Timeout.deadPeer)
+            squid_curtime - p->stats.probe_start > Config.Timeout.deadPeer) {
+        debugs(15, 8, "neighborUp: DOWN (dead): " << p->host << " (" << p->in_addr << ")");
         return 0;
+    }
 
+    debugs(15, 8, "neighborUp: UP: " << p->host << " (" << p->in_addr << ")");
     return 1;
 }
 
@@ -1260,7 +1224,6 @@ peerDNSConfigure(const ipcache_addrs * ia, void *data)
 {
     peer *p = (peer *)data;
 
-    struct sockaddr_in *ap;
     int j;
 
     if (p->n_addresses == 0) {
@@ -1286,16 +1249,13 @@ peerDNSConfigure(const ipcache_addrs * ia, void *data)
 
     for (j = 0; j < (int) ia->count && j < PEER_MAX_ADDRESSES; j++) {
         p->addresses[j] = ia->in_addrs[j];
-        debugs(15, 2, "--> IP address #" << j << ": " << inet_ntoa(p->addresses[j]));
+        debugs(15, 2, "--> IP address #" << j << ": " << p->addresses[j]);
         p->n_addresses++;
     }
 
-    ap = &p->in_addr;
-
-    memset(ap, '\0', sizeof(struct sockaddr_in));
-    ap->sin_family = AF_INET;
-    ap->sin_addr = p->addresses[0];
-    ap->sin_port = htons(p->icp.port);
+    p->in_addr.SetEmpty();
+    p->in_addr = p->addresses[0];
+    p->in_addr.SetPort(p->icp.port);
 
     if (p->type == PEER_MULTICAST)
         peerCountMcastPeersSchedule(p, 10);
@@ -1392,8 +1352,9 @@ peerProbeConnect(peer * p)
     if (squid_curtime - p->stats.last_connect_probe == 0)
         return ret;/* don't probe to often */
 
-    fd = comm_open(SOCK_STREAM, IPPROTO_TCP, getOutgoingAddr(NULL),
-                   0, COMM_NONBLOCKING, p->host);
+    IPAddress temp(getOutgoingAddr(NULL));
+
+    fd = comm_open(SOCK_STREAM, IPPROTO_TCP, temp, COMM_NONBLOCKING, p->host);
 
     if (fd < 0)
         return ret;
@@ -1455,7 +1416,9 @@ peerCountMcastPeersStart(void *data)
     LOCAL_ARRAY(char, url, MAX_URL);
     assert(p->type == PEER_MULTICAST);
     p->mcast.flags.count_event_pending = 0;
-    snprintf(url, MAX_URL, "http://%s/", inet_ntoa(p->in_addr.sin_addr));
+    snprintf(url, MAX_URL, "http://");
+    p->in_addr.ToURL(url+7, MAX_URL -8 );
+    strcat(url, "/");
     fake = storeCreateEntry(url, url, request_flags(), METHOD_GET);
     HttpRequest *req = HttpRequest::CreateFromUrl(url);
     psstate = new ps_state;
@@ -1474,7 +1437,7 @@ peerCountMcastPeersStart(void *data)
     reqnum = icpSetCacheKey((const cache_key *)fake->key);
     query = _icp_common_t::createMessage(ICP_QUERY, 0, url, reqnum, 0);
     icpUdpSend(theOutIcpConnection,
-               &p->in_addr,
+               p->in_addr,
                query,
                LOG_ICP_QUERY,
                0);
@@ -1634,7 +1597,7 @@ static void
 dump_peers(StoreEntry * sentry, peer * peers)
 {
     peer *e = NULL;
-
+    char ntoabuf[MAX_IPSTRLEN];
     struct _domain_ping *d = NULL;
     icp_opcode op;
     int i;
@@ -1656,7 +1619,7 @@ dump_peers(StoreEntry * sentry, peer * peers)
 
         for (i = 0; i < e->n_addresses; i++) {
             storeAppendPrintf(sentry, "Address[%d] : %s\n", i,
-                              inet_ntoa(e->addresses[i]));
+                              e->addresses[i].NtoA(ntoabuf,MAX_IPSTRLEN) );
         }
 
         storeAppendPrintf(sentry, "Status     : %s\n",
@@ -1742,7 +1705,7 @@ dump_peers(StoreEntry * sentry, peer * peers)
 #if USE_HTCP
 void
 
-neighborsHtcpReply(const cache_key * key, htcpReplyData * htcp, const struct sockaddr_in *from)
+neighborsHtcpReply(const cache_key * key, htcpReplyData * htcp, const IPAddress &from)
 {
     StoreEntry *e = Store::Root().get(key);
     MemObject *mem = NULL;
index 96ceead08a31a0d945ab1a85a2955dc734a8b3ad..e6051bdf32eb44ec3fa0276e06303d8c12e45dad 100644 (file)
@@ -1,6 +1,5 @@
-
 /*
- * $Id: net_db.cc,v 1.198 2007/11/27 07:48:40 amosjeffries Exp $
+ * $Id: net_db.cc,v 1.199 2007/12/14 23:11:47 amosjeffries Exp $
  *
  * DEBUG: section 38    Network Measurement Database
  * AUTHOR: Duane Wessels
 #include "forward.h"
 #include "SquidTime.h"
 #include "wordlist.h"
+#include "IPAddress.h"
 
 #if USE_ICMP
+#include "ICMPSquid.h"
 #include "StoreClient.h"
 
 #define        NETDB_REQBUF_SZ 4096
@@ -84,10 +85,10 @@ netdbExchangeState;
 static hash_table *addr_table = NULL;
 static hash_table *host_table = NULL;
 
-static struct IN_ADDR networkFromInaddr(struct IN_ADDR a);
+IPAddress networkFromInaddr(const IPAddress &a);
 static void netdbRelease(netdbEntry * n);
 
-static void netdbHashInsert(netdbEntry * n, struct IN_ADDR addr);
+static void netdbHashInsert(netdbEntry * n, IPAddress &addr);
 static void netdbHashDelete(const char *key);
 static void netdbHostInsert(netdbEntry * n, const char *hostname);
 static void netdbHostDelete(const net_db_name * x);
@@ -112,10 +113,9 @@ static void netdbExchangeDone(void *);
 static wordlist *peer_names = NULL;
 
 static void
-
-netdbHashInsert(netdbEntry * n, struct IN_ADDR addr)
+netdbHashInsert(netdbEntry * n, IPAddress &addr)
 {
-    xstrncpy(n->network, inet_ntoa(networkFromInaddr(addr)), 16);
+    networkFromInaddr(addr).NtoA(n->network, MAX_IPSTRLEN);
     n->hash.key = n->network;
     assert(hash_lookup(addr_table, n->network) == NULL);
     hash_join(addr_table, &n->hash);
@@ -249,18 +249,17 @@ netdbPurgeLRU(void)
 }
 
 static netdbEntry *
-
-netdbLookupAddr(struct IN_ADDR addr)
+netdbLookupAddr(const IPAddress &addr)
 {
     netdbEntry *n;
-    char *key = inet_ntoa(networkFromInaddr(addr));
+    char *key = new char[MAX_IPSTRLEN];
+    networkFromInaddr(addr).NtoA(key,MAX_IPSTRLEN);
     n = (netdbEntry *) hash_lookup(addr_table, key);
     return n;
 }
 
 static netdbEntry *
-
-netdbAdd(struct IN_ADDR addr)
+netdbAdd(IPAddress &addr)
 {
     netdbEntry *n;
 
@@ -279,8 +278,7 @@ netdbAdd(struct IN_ADDR addr)
 static void
 netdbSendPing(const ipcache_addrs * ia, void *data)
 {
-
-    struct IN_ADDR addr;
+    IPAddress addr;
     char *hostname = NULL;
     static_cast<generic_cbdata *>(data)->unwrap(&hostname);
     netdbEntry *n;
@@ -336,7 +334,7 @@ netdbSendPing(const ipcache_addrs * ia, void *data)
 
     if (n->next_ping_time <= squid_curtime) {
         debugs(38, 3, "netdbSendPing: pinging " << hostname);
-        icmpDomainPing(addr, hostname);
+        icmpEngine.DomainPing(addr, hostname);
         n->pings_sent++;
         n->next_ping_time = squid_curtime + Config.Netdb.period;
         n->last_use_time = squid_curtime;
@@ -345,14 +343,28 @@ netdbSendPing(const ipcache_addrs * ia, void *data)
     xfree(hostname);
 }
 
-static struct IN_ADDR
-
-            networkFromInaddr(struct IN_ADDR a)
+IPAddress
+networkFromInaddr(const IPAddress &in)
 {
+    IPAddress out;
+
+    out = in;
+#if USE_IPV6
+
+    /* in IPv6 the 'network' should be the routing section. */
+
+    if( in.IsIPv6() )
+    {
+        out.ApplyMask(64, AF_INET6);
+        debugs(14, 5, "networkFromInaddr : Masked IPv6 Address to " << in << "/64 routing part.");
+        return out;
+    }
+#endif
 
-    struct IN_ADDR b;
-    b.s_addr = ntohl(a.s_addr);
 #if USE_CLASSFUL
+    struct in_addr b;
+
+    in.GetInAddr(b);
 
     if (IN_CLASSC(b.s_addr))
         b.s_addr &= IN_CLASSC_NET;
@@ -361,15 +373,17 @@ static struct IN_ADDR
     else if (IN_CLASSA(b.s_addr))
         b.s_addr &= IN_CLASSA_NET;
 
-#else
-    /* use /24 for everything */
-    b.s_addr &= IN_CLASSC_NET;
+    out = b;
 
 #endif
 
-    b.s_addr = htonl(b.s_addr);
+    debugs(14, 5, "networkFromInaddr : Masked IPv4 Address to " << out << "/24.");
 
-    return b;
+    /* use /24 for everything under IPv4 */
+    out.ApplyMask(24, AF_INET);
+    debugs(14, 5, "networkFromInaddr : Masked IPv4 Address to " << in << "/24.");
+
+    return out;
 }
 
 static int
@@ -534,7 +548,7 @@ netdbReloadState(void)
     netdbEntry *n;
     netdbEntry N;
 
-    struct IN_ADDR addr;
+    IPAddress addr;
     int count = 0;
 
     struct timeval start = current_time;
@@ -576,7 +590,7 @@ netdbReloadState(void)
         if (NULL == q)
             continue;
 
-        if (!safe_inet_addr(q, &addr))
+        if (! (addr = q) )
             continue;
 
         if (netdbLookupAddr(addr) != NULL)     /* no dups! */
@@ -676,11 +690,13 @@ netdbFreeNameEntry(void *data)
 static void
 netdbExchangeHandleReply(void *data, StoreIOBuffer receivedData)
 {
+    IPAddress addr;
+
     netdbExchangeState *ex = (netdbExchangeState *)data;
     int rec_sz = 0;
     off_t o;
 
-    struct IN_ADDR addr;
+    struct in_addr line_addr;
     double rtt;
     double hops;
     char *p;
@@ -692,7 +708,7 @@ netdbExchangeHandleReply(void *data, StoreIOBuffer receivedData)
     int oldbufofs = ex->buf_ofs;
 
     rec_sz = 0;
-    rec_sz += 1 + sizeof(addr.s_addr);
+    rec_sz += 1 + sizeof(struct in_addr);
     rec_sz += 1 + sizeof(int);
     rec_sz += 1 + sizeof(int);
     debugs(38, 3, "netdbExchangeHandleReply: " << receivedData.length << " read bytes");
@@ -769,7 +785,7 @@ netdbExchangeHandleReply(void *data, StoreIOBuffer receivedData)
 
     while (size >= rec_sz) {
         debugs(38, 5, "netdbExchangeHandleReply: in parsing loop, size = " << size);
-        addr.s_addr = any_addr.s_addr;
+        addr.SetAnyAddr();
         hops = rtt = 0.0;
 
         for (o = 0; o < rec_sz;) {
@@ -777,8 +793,10 @@ netdbExchangeHandleReply(void *data, StoreIOBuffer receivedData)
 
             case NETDB_EX_NETWORK:
                 o++;
-                xmemcpy(&addr.s_addr, p + o, sizeof(addr.s_addr));
-                o += sizeof(addr.s_addr);
+                /* FIXME INET6 : NetDB can still ony send IPv4 */
+                xmemcpy(&line_addr, p + o, sizeof(struct in_addr));
+                addr = line_addr;
+                o += sizeof(struct in_addr);
                 break;
 
             case NETDB_EX_RTT:
@@ -802,7 +820,7 @@ netdbExchangeHandleReply(void *data, StoreIOBuffer receivedData)
             }
         }
 
-        if (addr.s_addr != any_addr.s_addr && rtt > 0)
+        if (!addr.IsAnyAddr() && rtt > 0)
             netdbExchangeUpdatePeer(addr, ex->p, rtt, hops);
 
         assert(o == rec_sz);
@@ -933,15 +951,14 @@ netdbPingSite(const char *hostname)
 }
 
 void
-
-netdbHandlePingReply(const struct sockaddr_in *from, int hops, int rtt)
+netdbHandlePingReply(const IPAddress &from, int hops, int rtt)
 {
 #if USE_ICMP
     netdbEntry *n;
     int N;
-    debugs(38, 3, "netdbHandlePingReply: from " << inet_ntoa(from->sin_addr));
+    debugs(38, 3, "netdbHandlePingReply: from " << from);
 
-    if ((n = netdbLookupAddr(from->sin_addr)) == NULL)
+    if ((n = netdbLookupAddr(from)) == NULL)
         return;
 
     N = ++n->pings_recv;
@@ -978,9 +995,10 @@ netdbFreeMemory(void)
 #endif
 }
 
-int
 
-netdbHops(struct IN_ADDR addr)
+#if 0 // AYJ: Looks to be unused code.
+int
+netdbHops(IPAddress &addr)
 {
 #if USE_ICMP
     netdbEntry *n = netdbLookupAddr(addr);
@@ -994,6 +1012,7 @@ netdbHops(struct IN_ADDR addr)
 #endif
     return 256;
 }
+#endif
 
 void
 netdbDump(StoreEntry * sentry)
@@ -1007,7 +1026,7 @@ netdbDump(StoreEntry * sentry)
     int j;
     net_db_peer *p;
     storeAppendPrintf(sentry, "Network DB Statistics:\n");
-    storeAppendPrintf(sentry, "%-16.16s %9s %7s %5s %s\n",
+    storeAppendPrintf(sentry, "%-46.46s %9s %7s %5s %s\n",  /* Max between 16 (IPv4) or 46 (IPv6)   */
                       "Network",
                       "recv/sent",
                       "RTT",
@@ -1031,7 +1050,7 @@ netdbDump(StoreEntry * sentry)
 
     for (k = 0; k < i; k++) {
         n = *(list + k);
-        storeAppendPrintf(sentry, "%-16.16s %4d/%4d %7.1f %5.1f",
+        storeAppendPrintf(sentry, "%-46.46s %4d/%4d %7.1f %5.1f", /* Max between 16 (IPv4) or 46 (IPv6)   */
                           n->network,
                           n->pings_recv,
                           n->pings_sent,
@@ -1119,11 +1138,11 @@ netdbUpdatePeer(HttpRequest * r, peer * e, int irtt, int ihops)
     double rtt = (double) irtt;
     double hops = (double) ihops;
     net_db_peer *p;
-    debugs(38, 3, "netdbUpdatePeer: '" << r->host << "', " << ihops << " hops, " << irtt << " rtt");
-    n = netdbLookupHost(r->host);
+    debugs(38, 3, "netdbUpdatePeer: '" << r->GetHost() << "', " << ihops << " hops, " << irtt << " rtt");
+    n = netdbLookupHost(r->GetHost());
 
     if (n == NULL) {
-        debugs(38, 3, "netdbUpdatePeer: host '" << r->host << "' not found");
+        debugs(38, 3, "netdbUpdatePeer: host '" << r->GetHost() << "' not found");
         return;
     }
 
@@ -1148,16 +1167,20 @@ netdbUpdatePeer(HttpRequest * r, peer * e, int irtt, int ihops)
 }
 
 void
-
-netdbExchangeUpdatePeer(struct IN_ADDR addr, peer * e, double rtt, double hops)
+netdbExchangeUpdatePeer(IPAddress &addr, peer * e, double rtt, double hops)
 {
 #if USE_ICMP
     netdbEntry *n;
     net_db_peer *p;
-    debugs(38, 5, "netdbExchangeUpdatePeer: '" << inet_ntoa(addr)  << "', "<<
+    debugs(38, 5, "netdbExchangeUpdatePeer: '" << addr << "', "<<
            std::setfill('0')<< std::setprecision(2) << hops << " hops, " <<
            rtt << " rtt");
 
+    if( !addr.IsIPv4() ) {
+        debugs(38, 5, "netdbExchangeUpdatePeer: Aborting peer update for '" << addr << "', NetDB cannot handle IPv6.");
+        return;
+    }
+
     n = netdbLookupAddr(addr);
 
     if (n == NULL)
@@ -1187,7 +1210,7 @@ netdbExchangeUpdatePeer(struct IN_ADDR addr, peer * e, double rtt, double hops)
 
 void
 
-netdbDeleteAddrNetwork(struct IN_ADDR addr)
+netdbDeleteAddrNetwork(IPAddress &addr)
 {
 #if USE_ICMP
     netdbEntry *n = netdbLookupAddr(addr);
@@ -1208,19 +1231,21 @@ netdbBinaryExchange(StoreEntry * s)
     HttpReply *reply = new HttpReply;
 #if USE_ICMP
 
+    IPAddress addr;
+
     netdbEntry *n;
     int i;
     int j;
     int rec_sz;
     char *buf;
 
-    struct IN_ADDR addr;
+    struct in_addr line_addr;
     s->buffer();
     HttpVersion version(1, 0);
     reply->setHeaders(version, HTTP_OK, "OK", NULL, -1, squid_curtime, -2);
     s->replaceHttpReply(reply);
     rec_sz = 0;
-    rec_sz += 1 + sizeof(addr.s_addr);
+    rec_sz += 1 + sizeof(struct in_addr);
     rec_sz += 1 + sizeof(int);
     rec_sz += 1 + sizeof(int);
     buf = (char *)memAllocate(MEM_4K_BUF);
@@ -1234,14 +1259,19 @@ netdbBinaryExchange(StoreEntry * s)
         if (n->rtt > 60000)    /* RTT > 1 MIN probably bogus */
             continue;
 
-        if (!safe_inet_addr(n->network, &addr))
+        if (! (addr = n->network) )
+            continue;
+
+        /* FIXME INET6 : NetDB cannot yet handle IPv6 addresses. Ensure only IPv4 get sent. */
+        if( !addr.IsIPv4() )
             continue;
 
         buf[i++] = (char) NETDB_EX_NETWORK;
 
-        xmemcpy(&buf[i], &addr.s_addr, sizeof(addr.s_addr));
+        addr.GetInAddr(line_addr);
+        xmemcpy(&buf[i], &line_addr, sizeof(struct in_addr));
 
-        i += sizeof(addr.s_addr);
+        i += sizeof(struct in_addr);
 
         buf[i++] = (char) NETDB_EX_RTT;
 
@@ -1342,11 +1372,11 @@ netdbClosestParent(HttpRequest * request)
     const ipcache_addrs *ia;
     net_db_peer *h;
     int i;
-    n = netdbLookupHost(request->host);
+    n = netdbLookupHost(request->GetHost());
 
     if (NULL == n) {
         /* try IP addr */
-        ia = ipcache_gethostbyname(request->host, 0);
+        ia = ipcache_gethostbyname(request->GetHost(), 0);
 
         if (NULL != ia)
             n = netdbLookupAddr(ia->in_addrs[ia->cur]);
index d6d3f5f25f8286c6cbd0a5a259c50e692bc0adda..22071156670f5a49bcc6ac3efe7f0af69e8c2c9f 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: pconn.cc,v 1.53 2007/05/29 13:31:40 amosjeffries Exp $
+ * $Id: pconn.cc,v 1.54 2007/12/14 23:11:47 amosjeffries Exp $
  *
  * DEBUG: section 48    Persistent Connections
  * AUTHOR: Duane Wessels
@@ -175,17 +175,17 @@ IdleConnList::timeout(int fd, void *data)
 /* ========== PconnPool PRIVATE FUNCTIONS ============================================ */
 
 const char *
-
-PconnPool::key(const char *host, u_short port, const char *domain, struct IN_ADDR *client_address)
+PconnPool::key(const char *host, u_short port, const char *domain, IPAddress &client_address)
 {
     LOCAL_ARRAY(char, buf, SQUIDHOSTNAMELEN * 2 + 10);
+    char ntoabuf[MAX_IPSTRLEN];
 
-    if (domain && client_address)
-        snprintf(buf, SQUIDHOSTNAMELEN * 2 + 10, "%s:%d-%s/%s", host, (int) port, inet_ntoa(*client_address), domain);
-    else if (domain && (!client_address))
+    if (domain && !client_address.IsAnyAddr())
+        snprintf(buf, SQUIDHOSTNAMELEN * 2 + 10, "%s:%d-%s/%s", host, (int) port, client_address.NtoA(ntoabuf,MAX_IPSTRLEN), domain);
+    else if (domain && client_address.IsAnyAddr())
         snprintf(buf, SQUIDHOSTNAMELEN * 2 + 10, "%s:%d/%s", host, (int) port, domain);
-    else if ((!domain) && client_address)
-        snprintf(buf, SQUIDHOSTNAMELEN * 2 + 10, "%s:%d-%s", host, (int) port, inet_ntoa(*client_address));
+    else if ((!domain) && !client_address.IsAnyAddr())
+        snprintf(buf, SQUIDHOSTNAMELEN * 2 + 10, "%s:%d-%s", host, (int) port, client_address.NtoA(ntoabuf,MAX_IPSTRLEN));
     else
         snprintf(buf, SQUIDHOSTNAMELEN * 2 + 10, "%s:%d", host, (int) port);
 
@@ -227,8 +227,7 @@ PconnPool::PconnPool(const char *aDescr) : table(NULL), descr(aDescr)
 }
 
 void
-
-PconnPool::push(int fd, const char *host, u_short port, const char *domain, struct IN_ADDR *client_address)
+PconnPool::push(int fd, const char *host, u_short port, const char *domain, IPAddress &client_address)
 {
 
     IdleConnList *list;
@@ -275,7 +274,7 @@ PconnPool::push(int fd, const char *host, u_short port, const char *domain, stru
  */
 int
 
-PconnPool::pop(const char *host, u_short port, const char *domain, struct IN_ADDR *client_address, bool isRetriable)
+PconnPool::pop(const char *host, u_short port, const char *domain, IPAddress &client_address, bool isRetriable)
 {
     IdleConnList *list;
     const char * aKey = key(host, port, domain, client_address);
index a2d4df6ec51e26c045d00f716185a20649c3ddfa..6629c7224968e9f538241d8271030e9390696db2 100644 (file)
@@ -48,15 +48,15 @@ public:
     PconnPool(const char *);
 
     void moduleInit();
-    void push(int fd, const char *host, u_short port, const char *domain, struct IN_ADDR *client_address);
-    int pop(const char *host, u_short port, const char *domain, struct IN_ADDR *client_address, bool retriable);
+    void push(int fd, const char *host, u_short port, const char *domain, IPAddress &client_address);
+    int pop(const char *host, u_short port, const char *domain, IPAddress &client_address, bool retriable);
     void count(int uses);
     void dumpHist(StoreEntry *e);
     void unlinkList(IdleConnList *list) const;
 
 private:
 
-    static const char *key(const char *host, u_short port, const char *domain, struct IN_ADDR *client_address);
+    static const char *key(const char *host, u_short port, const char *domain, IPAddress &client_address);
 
     int hist[PCONN_HIST_SZ];
     hash_table *table;
index 602a0162f15ac0cc842f99d204af5de8ca323c85..ecebc907b312b9e9a66230b48a668a8e533efc97 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: peer_digest.cc,v 1.127 2007/08/27 12:50:43 hno Exp $
+ * $Id: peer_digest.cc,v 1.128 2007/12/14 23:11:47 amosjeffries Exp $
  *
  * DEBUG: section 72    Peer Digest Routines
  * AUTHOR: Alex Rousskov
@@ -257,6 +257,7 @@ peerDigestCheck(void *data)
 {
     PeerDigest *pd = (PeerDigest *)data;
     time_t req_time;
+    char buf[MAX_IPSTRLEN];
 
     assert(!pd->flags.requested);
 
@@ -267,7 +268,7 @@ peerDigestCheck(void *data)
         return;
     }
 
-    debugs(72, 3, "peerDigestCheck: peer " << pd->peer->host << ":" << pd->peer->http_port);
+    debugs(72, 3, "peerDigestCheck: peer " <<  pd->peer->host << ":" << pd->peer->http_port);
     debugs(72, 3, "peerDigestCheck: time: " << squid_curtime << 
            ", last received: " << (long int) pd->times.received << "  (" << 
            std::showpos << (int) (squid_curtime - pd->times.received) << ")");
index 6ffd0e217387ee7a381923cec5a9d17f31689077..76a65aca57c7a10bb080201656cafbe5e259810e 100644 (file)
@@ -1,6 +1,5 @@
-
 /*
- * $Id: peer_select.cc,v 1.147 2007/04/30 16:56:09 wessels Exp $
+ * $Id: peer_select.cc,v 1.148 2007/12/14 23:11:47 amosjeffries Exp $
  *
  * DEBUG: section 44    Peer Selection Algorithm
  * AUTHOR: Duane Wessels
@@ -42,6 +41,7 @@
 #include "ACLChecklist.h"
 #include "htcp.h"
 #include "forward.h"
+#include "SquidTime.h"
 
 const char *hier_strings[] =
     {
@@ -180,9 +180,7 @@ peerSelect(HttpRequest * request,
 #endif
 
     if (psstate->entry)
-        psstate->entry->lock()
-
-        ;
+        psstate->entry->lock();
 
     peerSelectFoo(psstate);
 }
@@ -254,7 +252,7 @@ peerCheckNetdbDirect(ps_state * psstate)
     if (psstate->direct == DIRECT_NO)
         return 0;
 
-    myrtt = netdbHostRtt(psstate->request->host);
+    myrtt = netdbHostRtt(psstate->request->GetHost());
 
     debugs(44, 3, "peerCheckNetdbDirect: MY RTT = " << myrtt << " msec");
     debugs(44, 3, "peerCheckNetdbDirect: minimum_direct_rtt = " << Config.minDirectRtt << " msec");
@@ -263,7 +261,7 @@ peerCheckNetdbDirect(ps_state * psstate)
     if (myrtt && myrtt <= Config.minDirectRtt)
         return 1;
 
-    myhops = netdbHostHops(psstate->request->host);
+    myhops = netdbHostHops(psstate->request->GetHost());
 
     debugs(44, 3, "peerCheckNetdbDirect: MY hops = " << myhops);
     debugs(44, 3, "peerCheckNetdbDirect: minimum_direct_hops = " << Config.minDirectHops);
@@ -272,7 +270,7 @@ peerCheckNetdbDirect(ps_state * psstate)
     if (myhops && myhops <= Config.minDirectHops)
         return 1;
 
-    p = whichPeer(&psstate->closest_parent_miss);
+    p = whichPeer(psstate->closest_parent_miss);
 
     if (p == NULL)
         return 0;
@@ -290,7 +288,7 @@ peerSelectFoo(ps_state * ps)
 {
     StoreEntry *entry = ps->entry;
     HttpRequest *request = ps->request;
-    debugs(44, 3, "peerSelectFoo: '" << RequestMethodStr[request->method] << " " << request->host << "'");
+    debugs(44, 3, "peerSelectFoo: '" << RequestMethodStr[request->method] << " " << request->GetHost() << "'");
 
     if (ps->direct == DIRECT_UNKNOWN) {
         if (ps->always_direct == 0 && Config.accessList.AlwaysDirect) {
@@ -453,7 +451,7 @@ peerGetSomeNeighborReplies(ps_state * ps)
 
     if (peerCheckNetdbDirect(ps)) {
         code = CLOSEST_DIRECT;
-        debugs(44, 3, "peerSelect: " << hier_strings[code] << "/" << request->host);
+        debugs(44, 3, "peerSelect: " << hier_strings[code] << "/" << request->GetHost());
         peerAddFwdServer(&ps->servers, NULL, code);
         return;
     }
@@ -461,19 +459,15 @@ peerGetSomeNeighborReplies(ps_state * ps)
     if ((p = ps->hit)) {
         code = ps->hit_type == PEER_PARENT ? PARENT_HIT : SIBLING_HIT;
     } else
-#if ALLOW_SOURCE_PING
-        if ((p = ps->secho)) {
-            code = SOURCE_FASTEST;
-        } else
-#endif
-            if (ps->closest_parent_miss.sin_addr.s_addr != any_addr.s_addr) {
-                p = whichPeer(&ps->closest_parent_miss);
-                code = CLOSEST_PARENT_MISS;
-            } else if (ps->first_parent_miss.sin_addr.s_addr != any_addr.s_addr) {
-                p = whichPeer(&ps->first_parent_miss);
-                code = FIRST_PARENT_MISS;
-            }
-
+    {
+        if (!ps->closest_parent_miss.IsAnyAddr()) {
+            p = whichPeer(ps->closest_parent_miss);
+            code = CLOSEST_PARENT_MISS;
+        } else if (!ps->first_parent_miss.IsAnyAddr()) {
+            p = whichPeer(ps->first_parent_miss);
+            code = FIRST_PARENT_MISS;
+        }
+    }
     if (p && code != HIER_NONE) {
         debugs(44, 3, "peerSelect: " << hier_strings[code] << "/" << p->host);
         peerAddFwdServer(&ps->servers, p, code);
@@ -506,7 +500,7 @@ peerGetSomeParent(ps_state * ps)
     peer *p;
     HttpRequest *request = ps->request;
     hier_code code = HIER_NONE;
-    debugs(44, 3, "peerGetSomeParent: " << RequestMethodStr[request->method] << " " << request->host);
+    debugs(44, 3, "peerGetSomeParent: " << RequestMethodStr[request->method] << " " << request->GetHost());
 
     if (ps->direct == DIRECT_YES)
         return;
@@ -625,7 +619,7 @@ peerIcpParentMiss(peer * p, icp_common_t * header, ps_state * ps)
         return;
 
     /* set FIRST_MISS if there is no CLOSEST parent */
-    if (ps->closest_parent_miss.sin_addr.s_addr != any_addr.s_addr)
+    if (!ps->closest_parent_miss.IsAnyAddr())
         return;
 
     rtt = (tvSubMsec(ps->ping.start, current_time) - p->basetime) / p->weight;
@@ -633,8 +627,7 @@ peerIcpParentMiss(peer * p, icp_common_t * header, ps_state * ps)
     if (rtt < 1)
         rtt = 1;
 
-    if (ps->first_parent_miss.sin_addr.s_addr == any_addr.s_addr ||
-            rtt < ps->ping.w_rtt) {
+    if (ps->first_parent_miss.IsAnyAddr() || rtt < ps->ping.w_rtt) {
         ps->first_parent_miss = p->in_addr;
         ps->ping.w_rtt = rtt;
     }
@@ -667,14 +660,6 @@ peerHandleIcpReply(peer * p, peer_t type, icp_common_t * header, void *data)
         return;
     }
 
-#if ALLOW_SOURCE_PING
-    else if (op == ICP_SECHO) {
-        psstate->secho = p;
-        peerSelectFoo(psstate);
-        return;
-    }
-
-#endif
     if (psstate->ping.n_recv < psstate->ping.n_replies_expected)
         return;
 
@@ -731,7 +716,7 @@ peerHtcpParentMiss(peer * p, htcpReplyData * htcp, ps_state * ps)
         return;
 
     /* set FIRST_MISS if there is no CLOSEST parent */
-    if (ps->closest_parent_miss.sin_addr.s_addr != any_addr.s_addr)
+    if (!ps->closest_parent_miss.IsAnyAddr())
         return;
 
     rtt = (tvSubMsec(ps->ping.start, current_time) - p->basetime) / p->weight;
@@ -739,8 +724,7 @@ peerHtcpParentMiss(peer * p, htcpReplyData * htcp, ps_state * ps)
     if (rtt < 1)
         rtt = 1;
 
-    if (ps->first_parent_miss.sin_addr.s_addr == any_addr.s_addr ||
-            rtt < ps->ping.w_rtt) {
+    if (ps->first_parent_miss.IsAnyAddr() || rtt < ps->ping.w_rtt) {
         ps->first_parent_miss = p->in_addr;
         ps->ping.w_rtt = rtt;
     }
@@ -796,16 +780,13 @@ ps_state::ps_state() : request (NULL),
         callback (NULL),
         callback_data (NULL),
         servers (NULL),
+        first_parent_miss(),
+        closest_parent_miss(),
         hit(NULL),
         hit_type(PEER_NONE),
-#if ALLOW_SOURCE_PING
-
-        secho( NULL),
-#endif
         acl_checklist (NULL)
 {
-    memset(&first_parent_miss, '\0', sizeof(first_parent_miss));
-    memset(&closest_parent_miss, '\0', sizeof(closest_parent_miss));
+    ; // no local defaults.
 }
 
 ping_data::ping_data() :
index f906f3fd83f5f868fb585cff7b8695ed5028eda8..bd8feba7069a4579dcbb47612b12d24b16cac207 100644 (file)
@@ -1,6 +1,5 @@
-
 /*
- * $Id: pinger.cc,v 1.59 2007/04/30 16:56:09 wessels Exp $
+ * $Id: pinger.cc,v 1.60 2007/12/14 23:11:47 amosjeffries Exp $
  *
  * DEBUG: section 42    ICMP Pinger program
  * AUTHOR: Duane Wessels
 
 #if USE_ICMP
 
-/* Native Windows port doesn't have netinet support, so we emulate it.
-   At this time, Cygwin lacks icmp support in its include files, so we need
-   to use the native Windows port definitions.
- */
-
-#ifndef _SQUID_WIN32_
-
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/ip_icmp.h>
-
-#define PINGER_TIMEOUT 10
-
-static int socket_from_squid = 0;
-static int socket_to_squid = 1;
-
-#else /* _SQUID_WIN32_ */
-
-#include "fde.h"
+#include "ICMPv4.h"
+#include "ICMPv6.h"
+#include "ICMPPinger.h"
 
 #ifdef _SQUID_MSWIN_
 
 #include <winsock2.h>
 #include <process.h>
+#include "fde.h"
 
 #define PINGER_TIMEOUT 5
 
-static int socket_to_squid = -1;
-#define socket_from_squid socket_to_squid
-
-#else /* _SQUID_CYGWIN_ */ 
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/ip_icmp.h>
-
-#define PINGER_TIMEOUT 10
-
-static int socket_from_squid = 0;
-static int socket_to_squid = 1;
-
-#endif
+/* windows uses the control socket for feedback to squid */
+#define LINK_TO_SQUID squid_link
 
-#define ICMP_ECHO 8
-#define ICMP_ECHOREPLY 0
+// windows still requires WSAFD but there are too many dependancy problems
+// to just link to win32.cc where it is normally defined.
 
-typedef struct iphdr
+int
+Win32__WSAFDIsSet(int fd, fd_set FAR * set)
 {
+    fde *F = &fd_table[fd];
+    SOCKET s = F->win32.handle;
 
-u_int8_t  ip_vhl:
-    4;         /* Length of the header in dwords */
-
-u_int8_t  version:
-    4; /* Version of IP                  */
-    u_int8_t  tos;             /* Type of service                */
-    u_int16_t total_len;       /* Length of the packet in dwords */
-    u_int16_t ident;           /* unique identifier              */
-    u_int16_t flags;           /* Flags                          */
-    u_int8_t  ip_ttl;          /* Time to live                   */
-    u_int8_t  proto;           /* Protocol number (TCP, UDP etc) */
-    u_int16_t checksum;                /* IP checksum                    */
-    u_int32_t source_ip;
-    u_int32_t dest_ip;
+    return __WSAFDIsSet(s, set);
 }
 
-iphdr;
-
-/* ICMP header */
+#else
 
-typedef struct icmphdr
-{
-    u_int8_t  icmp_type;       /* ICMP packet type                 */
-    u_int8_t  icmp_code;       /* Type sub code                    */
-    u_int16_t icmp_cksum;
-    u_int16_t icmp_id;
-    u_int16_t icmp_seq;
-    u_int32_t timestamp;       /* not part of ICMP, but we need it */
-}
+#define PINGER_TIMEOUT 10
 
-icmphdr;
+/* non-windows use STDOUT for feedback to squid */
+#define LINK_TO_SQUID  1
 
 #endif /* _SQUID_MSWIN_ */
 
-#ifndef _SQUID_LINUX_
-#ifndef _SQUID_CYGWIN_
-#ifndef _SQUID_MSWIN_
-#define icmphdr icmp
-#define iphdr ip
-#endif
-#endif
-#endif
-
-#if defined (_SQUID_LINUX_)
-#ifdef icmp_id
-#undef icmp_id
-#endif
-#ifdef icmp_seq
-#undef icmp_seq
+// ICMP Engines are declared global here so they can call each other easily.
+ICMPPinger control;
+ICMPv4 icmp4;
+#if USE_IPV6
+ICMPv6 icmp6;
 #endif
-#define icmp_type type
-#define icmp_code code
-#define icmp_cksum checksum
-#define icmp_id un.echo.id
-#define icmp_seq un.echo.sequence
-#define ip_hl ihl
-#define ip_v version
-#define ip_tos tos
-#define ip_len tot_len
-#define ip_id id
-#define ip_off frag_off
-#define ip_ttl ttl
-#define ip_p protocol
-#define ip_sum check
-#define ip_src saddr
-#define ip_dst daddr
-#endif
-
-#if ALLOW_SOURCE_PING
-#define MAX_PKT_SZ 8192
-#define MAX_PAYLOAD (MAX_PKT_SZ - sizeof(struct icmphdr) - sizeof (char) - sizeof(struct timeval) - 1)
-#else
-#define MAX_PAYLOAD SQUIDHOSTNAMELEN
-#define MAX_PKT_SZ (MAX_PAYLOAD + sizeof(struct timeval) + sizeof (char) + sizeof(struct icmphdr) + 1)
-#endif
-
-typedef struct
-{
-
-    struct timeval tv;
-    unsigned char opcode;
-    char payload[MAX_PAYLOAD];
-}
 
-icmpEchoData;
-
-int icmp_ident = -1;
 int icmp_pkts_sent = 0;
 
-static const char *icmpPktStr[] =
-    {
-        "Echo Reply",
-        "ICMP 1",
-        "ICMP 2",
-        "Destination Unreachable",
-        "Source Quench",
-        "Redirect",
-        "ICMP 6",
-        "ICMP 7",
-        "Echo",
-        "ICMP 9",
-        "ICMP 10",
-        "Time Exceeded",
-        "Parameter Problem",
-        "Timestamp",
-        "Timestamp Reply",
-        "Info Request",
-        "Info Reply",
-        "Out of Range Type"
-    };
-
-static int in_cksum(unsigned short *ptr, int size);
-static void pingerRecv(void);
-
-static void pingerLog(struct icmphdr *, struct IN_ADDR, int, int);
-static int ipHops(int ttl);
-static void pingerSendtoSquid(pingerReplyData * preply);
-static void pingerOpen(void);
-static void pingerClose(void);
-
-#ifdef _SQUID_MSWIN_
-
-int Win32__WSAFDIsSet(int fd, fd_set FAR * set
-                         )
-{
-    fde *F = &fd_table[fd];
-    SOCKET s = F->win32.handle;
-
-    return __WSAFDIsSet(s, set
-                           );
-}
-
-#endif
-
-void
-pingerOpen(void)
+int
+main(int argc, char *argv[])
 {
-
-    struct protoent *proto = NULL;
-#ifdef _SQUID_MSWIN_
-
-    WSADATA wsaData;
-    WSAPROTOCOL_INFO wpi;
-    char buf[sizeof(wpi)];
+    fd_set R;
     int x;
+    int max_fd = 0;
 
-    struct sockaddr_in PS;
-
-    WSAStartup(2, &wsaData);
-
-    getCurrentTime();
-    _db_init(NULL, "ALL,1");
-    setmode(0, O_BINARY);
-    setmode(1, O_BINARY);
-    x = read(0, buf, sizeof(wpi));
-
-    if (x < (int)sizeof(wpi)) {
-        getCurrentTime();
-        debugs(42, 0, "pingerOpen: read: FD 0: " << xstrerror());
-        write(1, "ERR\n", 4);
-        exit(1);
-    }
-
-    xmemcpy(&wpi, buf, sizeof(wpi));
-
-    write(1, "OK\n", 3);
-    x = read(0, buf, sizeof(PS));
-
-    if (x < (int)sizeof(PS)) {
-        getCurrentTime();
-        debugs(42, 0, "pingerOpen: read: FD 0: " << xstrerror());
-        write(1, "ERR\n", 4);
-        exit(1);
-    }
+    struct timeval tv;
+    const char *debug_args = "ALL,10";
+    char *t;
+    time_t last_check_time = 0;
 
-    xmemcpy(&PS, buf, sizeof(PS));
+    /*
+     * cevans - do this first. It grabs a raw socket. After this we can
+     * drop privs
+     */
+    int icmp4_worker = -1;
+#if USE_IPV6
+    int icmp6_worker = -1;
 #endif
+    int squid_link = -1;
 
-    if ((proto = getprotobyname("icmp")) == 0) {
-        debugs(42, 0, "pingerOpen: unknown protocol: icmp");
-        exit(1);
-    }
-
-    icmp_sock = socket(PF_INET, SOCK_RAW, proto->p_proto);
-
-    if (icmp_sock < 0) {
-        debugs(50, 0, "pingerOpen: icmp_sock: " << xstrerror());
-        exit(1);
-    }
-
-    icmp_ident = getpid() & 0xffff;
-    debugs(42, 0, "pinger: ICMP socket opened");
-#ifdef _SQUID_MSWIN_
-
-    socket_to_squid =
-        WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
-                  &wpi, 0, 0);
-
-    if (socket_to_squid == -1) {
-        getCurrentTime();
-        debugs(42, 0, "pingerOpen: WSASocket: " << xstrerror());
-        write(1, "ERR\n", 4);
-        exit(1);
-    }
-
-    x = connect(socket_to_squid, (struct sockaddr *) &PS, sizeof(PS));
-
-    if (SOCKET_ERROR == x) {
-        getCurrentTime();
-        debugs(42, 0, "pingerOpen: connect: " << xstrerror());
-        write(1, "ERR\n", 4);
-        exit(1);
-    }
-
-    write(1, "OK\n", 3);
-    memset(buf, 0, sizeof(buf));
-    x = recv(socket_to_squid, (void *) buf, sizeof(buf), 0);
-
-    if (x < 3) {
-        debugs(42, 0, "icmpOpen: recv: " << xstrerror());
-        exit(1);
-    }
-
-    x = send(socket_to_squid, (const void *) buf, strlen(buf), 0);
-
-    if (x < 3 || strncmp("OK\n", buf, 3)) {
-        debugs(42, 0, "icmpOpen: recv: " << xstrerror());
-        exit(1);
-    }
+    /* start by initializing the pinger debug cache.log-pinger */
+    if ((t = getenv("SQUID_DEBUG")))
+        debug_args = xstrdup(t);
 
     getCurrentTime();
-    debugs(42, 0, "pinger: Squid socket opened");
-#endif
-}
-
-void
-pingerClose(void)
-{
-    close(icmp_sock);
-#ifdef _SQUID_MSWIN_
-
-    shutdown(socket_to_squid, SD_BOTH);
-    close(socket_to_squid);
-    socket_to_squid = -1;
-#endif
-
-    icmp_sock = -1;
-    icmp_ident = 0;
-}
-
-static void
-
-pingerSendEcho(struct IN_ADDR to, int opcode, char *payload, int len)
-{
-    LOCAL_ARRAY(char, pkt, MAX_PKT_SZ);
-
-    struct icmphdr *icmp = NULL;
-    icmpEchoData *echo;
-
-    size_t icmp_pktsize = sizeof(struct icmphdr);
-
-    struct sockaddr_in S;
-    memset(pkt, '\0', MAX_PKT_SZ);
 
-    icmp = (struct icmphdr *) (void *) pkt;
+    _db_init(NULL, debug_args);
 
-    /*
-     * cevans - beware signed/unsigned issues in untrusted data from
-     * the network!!
-     */
+    debugs(42, 0, "pinger: Initialising ICMP pinger ...");
 
-    if (len < 0)
-    {
-        len = 0;
+    icmp4_worker = icmp4.Open();
+    if(icmp4_worker < 0) {
+        debugs(42, 0, "pinger: Unable to start ICMP pinger.");
     }
+    max_fd = max(max_fd, icmp4_worker);
 
-    icmp->icmp_type = ICMP_ECHO;
-    icmp->icmp_code = 0;
-    icmp->icmp_cksum = 0;
-    icmp->icmp_id = icmp_ident;
-    icmp->icmp_seq = (u_short) icmp_pkts_sent++;
-    echo = (icmpEchoData *) (icmp + 1);
-    echo->opcode = (unsigned char) opcode;
-    echo->tv = current_time;
-
-    icmp_pktsize += sizeof(struct timeval) + sizeof(char);
-
-    if (payload)
-    {
-        if (len > MAX_PAYLOAD)
-            len = MAX_PAYLOAD;
-
-        xmemcpy(echo->payload, payload, len);
-
-        icmp_pktsize += len;
+#if USE_IPV6
+    icmp6_worker = icmp6.Open();
+    if(icmp6_worker <0 ) {
+        debugs(42, 0, "pinger: Unable to start ICMPv6 pinger.");
     }
-
-    icmp->icmp_cksum = in_cksum((u_short *) icmp, icmp_pktsize);
-    S.sin_family = AF_INET;
-    /*
-     * cevans: alert: trusting to-host, was supplied in network packet
-     */
-    S.sin_addr = to;
-    S.sin_port = 0;
-    assert(icmp_pktsize <= MAX_PKT_SZ);
-    sendto(icmp_sock,
-           (const void *) pkt,
-           icmp_pktsize,
-           0,
-
-           (struct sockaddr *) &S,
-
-           sizeof(struct sockaddr_in));
-    pingerLog(icmp, to, 0, 0);
-}
-
-static void
-pingerRecv(void)
-{
-    int n;
-    socklen_t fromlen;
-
-    struct sockaddr_in from;
-    int iphdrlen = 20;
-
-    struct iphdr *ip = NULL;
-
-    struct icmphdr *icmp = NULL;
-    static char *pkt = NULL;
-
-    struct timeval now;
-    icmpEchoData *echo;
-    static pingerReplyData preply;
-
-    if (pkt == NULL)
-        pkt = (char *)xmalloc(MAX_PKT_SZ);
-
-    fromlen = sizeof(from);
-
-    n = recvfrom(icmp_sock,
-                 (void *)pkt,
-                 MAX_PKT_SZ,
-                 0,
-
-                 (struct sockaddr *) &from,
-                 &fromlen);
-
-#if GETTIMEOFDAY_NO_TZP
-
-    gettimeofday(&now);
-
-#else
-
-    gettimeofday(&now, NULL);
-
+    max_fd = max(max_fd, icmp6_worker);
 #endif
 
-    debugs(42, 9, "pingerRecv: " << n << " bytes from " <<
-           inet_ntoa(from.sin_addr));
-
-    ip = (struct iphdr *) (void *) pkt;
-
-#if HAVE_STRUCT_IPHDR_IP_HL
-
-    iphdrlen = ip->ip_hl << 2;
-
-#else /* HAVE_STRUCT_IPHDR_IP_HL */
-#if WORDS_BIGENDIAN
-
-    iphdrlen = (ip->ip_vhl >> 4) << 2;
-
-#else
-
-    iphdrlen = (ip->ip_vhl & 0xF) << 2;
-
+    // abort if neither worker could open a socket.
+    if(icmp4_worker == -1) {
+#if USE_IPV6
+        if(icmp6_worker == -1)
 #endif
-#endif /* HAVE_STRUCT_IPHDR_IP_HL */
-
-    icmp = (struct icmphdr *) (void *) (pkt + iphdrlen);
-
-    if (icmp->icmp_type != ICMP_ECHOREPLY)
-        return;
-
-    if (icmp->icmp_id != icmp_ident)
-        return;
-
-    echo = (icmpEchoData *) (void *) (icmp + 1);
-
-    preply.from = from.sin_addr;
-
-    preply.opcode = echo->opcode;
-
-    preply.hops = ipHops(ip->ip_ttl);
-
-    preply.rtt = tvSubMsec(echo->tv, now);
-
-    preply.psize = n - iphdrlen - (sizeof(icmpEchoData) - MAX_PKT_SZ);
-
-    pingerSendtoSquid(&preply);
-
-    pingerLog(icmp, from.sin_addr, preply.rtt, preply.hops);
-}
-
-
-static int
-in_cksum(unsigned short *ptr, int size)
-{
-    long sum;
-    unsigned short oddbyte;
-    unsigned short answer;
-    sum = 0;
-
-    while (size > 1) {
-        sum += *ptr++;
-        size -= 2;
-    }
-
-    if (size == 1) {
-        oddbyte = 0;
-        *((unsigned char *) &oddbyte) = *(unsigned char *) ptr;
-        sum += oddbyte;
-    }
-
-    sum = (sum >> 16) + (sum & 0xffff);
-    sum += (sum >> 16);
-    answer = (unsigned short) ~sum;
-    return (answer);
-}
-
-static void
-
-pingerLog(struct icmphdr *icmp, struct IN_ADDR addr, int rtt, int hops)
-{
-    debugs(42, 2, "pingerLog: " << std::setw(9) << current_time.tv_sec  <<
-           "."<< std::setfill('0') << std::setw(6) <<
-           current_time.tv_usec  << " "<< std::left << std::setfill(' ')<<
-           std::setw(16) << inet_ntoa(addr)  << " "<< icmp->icmp_type  <<
-           " " << std::setw(15) <<  icmpPktStr[icmp->icmp_type] << " " << rtt  <<
-           "ms " << hops  << " hops");
-}
-
-static int
-ipHops(int ttl)
-{
-    if (ttl < 33)
-        return 33 - ttl;
-
-    if (ttl < 63)
-        return 63 - ttl;       /* 62 = (64+60)/2 */
-
-    if (ttl < 65)
-        return 65 - ttl;       /* 62 = (64+60)/2 */
-
-    if (ttl < 129)
-        return 129 - ttl;
-
-    if (ttl < 193)
-        return 193 - ttl;
-
-    return 256 - ttl;
-}
-
-static int
-pingerReadRequest(void)
-{
-    static pingerEchoData pecho;
-    int n;
-    int guess_size;
-    memset(&pecho, '\0', sizeof(pecho));
-    n = recv(socket_from_squid, &pecho, sizeof(pecho), 0);
-
-    if (n < 0)
-        return n;
-
-    if (0 == n) {
-        /* EOF indicator */
-        fprintf(stderr, "EOF encountered\n");
-        errno = 0;
-        return -1;
-    }
-
-    guess_size = n - (sizeof(pingerEchoData) - PINGER_PAYLOAD_SZ);
-
-    if (guess_size != pecho.psize) {
-        fprintf(stderr, "size mismatch, guess=%d psize=%d\n",
-                guess_size, pecho.psize);
-        /* don't process this message, but keep running */
-        return 0;
+            debugs(42, 0, "FATAL: pinger: Unable to open any ICMP sockets.");
+            exit(1);
     }
 
-    pingerSendEcho(pecho.to,
-                   pecho.opcode,
-                   pecho.payload,
-                   pecho.psize);
-    return n;
-}
-
-static void
-pingerSendtoSquid(pingerReplyData * preply)
-{
-    int len = sizeof(pingerReplyData) - MAX_PKT_SZ + preply->psize;
-
-    if (send(socket_to_squid, preply, len, 0) < 0) {
-        debugs(50, 0, "pinger: send: " << xstrerror());
-        pingerClose();
-        exit(1);
+    if( (squid_link = control.Open()) < 0) {
+        debugs(42, 0, "FATAL: pinger: Unable to setup Pinger control sockets.");
+        icmp4.Close();
+#if USE_IPV6
+        icmp6.Close();
+#endif
+        exit(1); // fatal error if the control channel fails.
     }
-}
-
-int
-main(int argc, char *argv[])
-{
-    fd_set R;
-    int x;
+    max_fd = max(max_fd, squid_link);
 
-    struct timeval tv;
-    const char *debug_args = "ALL,1";
-    char *t;
-    time_t last_check_time = 0;
-
-    /*
-     * cevans - do this first. It grabs a raw socket. After this we can
-     * drop privs
-     */
-    pingerOpen();
     setgid(getgid());
     setuid(getuid());
 
-    if ((t = getenv("SQUID_DEBUG")))
-        debug_args = xstrdup(t);
-
-    getCurrentTime();
-
-    _db_init(NULL, debug_args);
-
     for (;;) {
         tv.tv_sec = PINGER_TIMEOUT;
         tv.tv_usec = 0;
         FD_ZERO(&R);
-        FD_SET(socket_from_squid, &R);
-        FD_SET(icmp_sock, &R);
-        x = select(icmp_sock + 1, &R, NULL, NULL, &tv);
+        if(icmp4_worker >= 0) {
+            FD_SET(icmp4_worker, &R);
+        }
+#if USE_IPV6
+
+        if(icmp6_worker >= 0) {
+            FD_SET(icmp6_worker, &R);
+        }
+#endif
+        FD_SET(squid_link, &R);
+        x = select(10, &R, NULL, NULL, &tv);
         getCurrentTime();
 
         if (x < 0) {
-            pingerClose();
+            debugs(42, 0, HERE << " FATAL Shutdown. select()==" << x << ", ERR: " << xstrerror());
+            control.Close();
             exit(1);
         }
 
-        if (FD_ISSET(socket_from_squid, &R))
-            if (pingerReadRequest() < 0) {
-                debugs(42, 0, "Pinger exiting.");
-                pingerClose();
-                exit(1);
-            }
+        if (FD_ISSET(squid_link, &R)) {
+            control.Recv();
+        }
 
-        if (FD_ISSET(icmp_sock, &R))
-            pingerRecv();
+#if USE_IPV6
+        if (icmp6_worker >= 0 && FD_ISSET(icmp6_worker, &R)) {
+            icmp6.Recv();
+        }
+#endif
+
+        if (icmp4_worker >= 0 && FD_ISSET(icmp4_worker, &R)) {
+            icmp4.Recv();
+        }
 
         if (PINGER_TIMEOUT + last_check_time < squid_curtime) {
-            if (send(socket_to_squid, &tv, 0, 0) < 0) {
-                pingerClose();
+            if (send(LINK_TO_SQUID, &tv, 0, 0) < 0) {
+                debugs(42, 0, "pinger: Closing. No requests in last " << PINGER_TIMEOUT << " seconds.");
+                control.Close();
                 exit(1);
             }
 
index 333463e3bcd336ad4acb8789b59d29171026f5fe..11023aaafe7966fe155b5399d1743ccd0f543751 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: protos.h,v 1.550 2007/09/28 00:22:38 hno Exp $
+ * $Id: protos.h,v 1.551 2007/12/14 23:11:47 amosjeffries Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -43,6 +43,8 @@
  */
 #include "HttpRequestMethod.h"
 /* for routines still in this file that take CacheManager parameters */
+#include "IPAddress.h"
+/* for routines in here that need it as a parameter. */
 
 class CacheManager;
 
@@ -75,7 +77,7 @@ SQUIDCEXTERN void parse_wordlist(wordlist ** list);
 SQUIDCEXTERN void requirePathnameExists(const char *name, const char *path);
 SQUIDCEXTERN void parse_time_t(time_t * var);
 
-SQUIDCEXTERN void parse_sockaddr_in_list_token(sockaddr_in_list **, char *);
+SQUIDCEXTERN void parse_IPAddress_list_token(IPAddress_list **, char *);
 
 
 /* client_side.c - FD related client side routines */
@@ -83,13 +85,13 @@ SQUIDCEXTERN void parse_sockaddr_in_list_token(sockaddr_in_list **, char *);
 SQUIDCEXTERN void clientdbInit(void);
 extern void clientdbRegisterWithCacheManager(CacheManager & manager);
 
-SQUIDCEXTERN void clientdbUpdate(struct IN_ADDR, log_type, protocol_t, size_t);
+SQUIDCEXTERN void clientdbUpdate(const IPAddress &, log_type, protocol_t, size_t);
 
-SQUIDCEXTERN int clientdbCutoffDenied(struct IN_ADDR);
+SQUIDCEXTERN int clientdbCutoffDenied(const IPAddress &);
 SQUIDCEXTERN void clientdbDump(StoreEntry *);
 SQUIDCEXTERN void clientdbFreeMemory(void);
 
-SQUIDCEXTERN int clientdbEstablished(struct IN_ADDR, int);
+SQUIDCEXTERN int clientdbEstablished(const IPAddress &, int);
 SQUIDCEXTERN void clientOpenListenSockets(void);
 SQUIDCEXTERN void clientHttpConnectionsClose(void);
 SQUIDCEXTERN void httpRequestFree(void *);
@@ -142,7 +144,7 @@ SQUIDCEXTERN void idnsShutdown(void);
 extern void idnsRegisterWithCacheManager(CacheManager & manager);
 SQUIDCEXTERN void idnsALookup(const char *, IDNSCB *, void *);
 
-SQUIDCEXTERN void idnsPTRLookup(const struct IN_ADDR, IDNSCB *, void *);
+SQUIDCEXTERN void idnsPTRLookup(const IPAddress &, IDNSCB *, void *);
 
 SQUIDCEXTERN void fd_close(int fd);
 SQUIDCEXTERN void fd_open(int fd, unsigned int type, const char *);
@@ -161,15 +163,15 @@ SQUIDCEXTERN void file_map_bit_reset(fileMap *, int);
 SQUIDCEXTERN void filemapFreeMemory(fileMap *);
 
 
-SQUIDCEXTERN void fqdncache_nbgethostbyaddr(struct IN_ADDR, FQDNH *, void *);
+SQUIDCEXTERN void fqdncache_nbgethostbyaddr(IPAddress &, FQDNH *, void *);
 
-SQUIDCEXTERN const char *fqdncache_gethostbyaddr(struct IN_ADDR, int flags);
+SQUIDCEXTERN const char *fqdncache_gethostbyaddr(IPAddress &, int flags);
 SQUIDCEXTERN void fqdncache_init(void);
 extern void fqdncacheRegisterWithCacheManager(CacheManager & manager);
 SQUIDCEXTERN void fqdnStats(StoreEntry *);
 SQUIDCEXTERN void fqdncacheReleaseInvalid(const char *);
 
-SQUIDCEXTERN const char *fqdnFromAddr(struct IN_ADDR);
+SQUIDCEXTERN const char *fqdnFromAddr(IPAddress &);
 SQUIDCEXTERN int fqdncacheQueueDrain(void);
 SQUIDCEXTERN void fqdncacheFreeMemory(void);
 SQUIDCEXTERN void fqdncache_restart(void);
@@ -178,7 +180,7 @@ SQUIDCEXTERN void fqdncacheAddEntryFromHosts(char *addr, wordlist * hostnames);
 
 class FwdState;
 SQUIDCEXTERN void ftpStart(FwdState *);
-SQUIDCEXTERN char *ftpUrlWith2f(const HttpRequest *);
+SQUIDCEXTERN const char *ftpUrlWith2f(HttpRequest *);
 
 SQUIDCEXTERN void gopherStart(FwdState *);
 SQUIDCEXTERN int gopherCachable(const HttpRequest *);
@@ -261,13 +263,6 @@ SQUIDCEXTERN void httpHeaderStoreReport(StoreEntry * e);
 SQUIDCEXTERN void httpHdrMangleList(HttpHeader *, HttpRequest *, int req_or_rep);
 SQUIDCEXTERN int httpReqHdrManglersConfigured();
 
-SQUIDCEXTERN void icmpOpen(void);
-SQUIDCEXTERN void icmpClose(void);
-
-SQUIDCEXTERN void icmpSourcePing(struct IN_ADDR to, const icp_common_t *, const char *url);
-
-SQUIDCEXTERN void icmpDomainPing(struct IN_ADDR to, const char *domain);
-
 #ifdef SQUID_SNMP
 SQUIDCEXTERN PF snmpHandleUdp;
 SQUIDCEXTERN void snmpInit(void);
@@ -276,11 +271,10 @@ SQUIDCEXTERN void snmpConnectionShutdown(void);
 SQUIDCEXTERN void snmpConnectionClose(void);
 SQUIDCEXTERN void snmpDebugOid(int lvl, oid * Name, snint Len);
 
-SQUIDCEXTERN void addr2oid(struct IN_ADDR addr, oid * Dest);
+SQUIDCEXTERN void addr2oid(IPAddress &addr, oid *Dest);
+SQUIDCEXTERN void oid2addr(oid *Dest, IPAddress &addr, u_int code);
 
-SQUIDCEXTERN struct IN_ADDR *oid2addr(oid * id);
-
-SQUIDCEXTERN struct IN_ADDR *client_entry(struct IN_ADDR *current);
+SQUIDCEXTERN IPAddress *client_entry(IPAddress *current);
 SQUIDCEXTERN variable_list *snmp_basicFn(variable_list *, snint *);
 SQUIDCEXTERN variable_list *snmp_confFn(variable_list *, snint *);
 SQUIDCEXTERN variable_list *snmp_sysFn(variable_list *, snint *);
@@ -322,9 +316,9 @@ extern void ipcacheRegisterWithCacheManager(CacheManager & manager);
 SQUIDCEXTERN void stat_ipcache_get(StoreEntry *);
 SQUIDCEXTERN void ipcacheCycleAddr(const char *name, ipcache_addrs *);
 
-SQUIDCEXTERN void ipcacheMarkBadAddr(const char *name, struct IN_ADDR);
+SQUIDCEXTERN void ipcacheMarkBadAddr(const char *name, IPAddress &);
 
-SQUIDCEXTERN void ipcacheMarkGoodAddr(const char *name, struct IN_ADDR);
+SQUIDCEXTERN void ipcacheMarkGoodAddr(const char *name, IPAddress &);
 SQUIDCEXTERN void ipcacheFreeMemory(void);
 SQUIDCEXTERN ipcache_addrs *ipcacheCheckNumeric(const char *name);
 SQUIDCEXTERN void ipcache_restart(void);
@@ -364,7 +358,7 @@ SQUIDCEXTERN int neighborsUdpPing(HttpRequest *,
                                   int *timeout);
 SQUIDCEXTERN void neighborAddAcl(const char *, const char *);
 
-SQUIDCEXTERN void neighborsUdpAck(const cache_key *, icp_common_t *, const struct sockaddr_in *);
+SQUIDCEXTERN void neighborsUdpAck(const cache_key *, icp_common_t *, const IPAddress &);
 SQUIDCEXTERN void neighborAdd(const char *, const char *, int, int, int, int, int);
 SQUIDCEXTERN void neighbors_init(void);
 extern void neighborsRegisterWithCacheManager(CacheManager & manager);
@@ -388,26 +382,28 @@ SQUIDCEXTERN void peerConnectSucceded(peer *);
 SQUIDCEXTERN void dump_peer_options(StoreEntry *, peer *);
 SQUIDCEXTERN int peerHTTPOkay(const peer *, HttpRequest *);
 
-SQUIDCEXTERN peer *whichPeer(const struct sockaddr_in *from);
+SQUIDCEXTERN peer *whichPeer(const IPAddress &from);
 
 SQUIDCEXTERN void netdbInit(void);
 extern void netdbRegisterWitHCacheManager(CacheManager & manager);
 
-SQUIDCEXTERN void netdbHandlePingReply(const struct sockaddr_in *from, int hops, int rtt);
+SQUIDCEXTERN void netdbHandlePingReply(const IPAddress &from, int hops, int rtt);
 SQUIDCEXTERN void netdbPingSite(const char *hostname);
 SQUIDCEXTERN void netdbDump(StoreEntry *);
 
-SQUIDCEXTERN int netdbHops(struct IN_ADDR);
+#if 0 // AYJ: Looks to be unused now.
+SQUIDCEXTERN int netdbHops(IPAddress &);
+#endif
 SQUIDCEXTERN void netdbFreeMemory(void);
 SQUIDCEXTERN int netdbHostHops(const char *host);
 SQUIDCEXTERN int netdbHostRtt(const char *host);
 SQUIDCEXTERN void netdbUpdatePeer(HttpRequest *, peer * e, int rtt, int hops);
 
-SQUIDCEXTERN void netdbDeleteAddrNetwork(struct IN_ADDR addr);
+SQUIDCEXTERN void netdbDeleteAddrNetwork(IPAddress &addr);
 SQUIDCEXTERN void netdbBinaryExchange(StoreEntry *);
 SQUIDCEXTERN void netdbExchangeStart(void *);
 
-SQUIDCEXTERN void netdbExchangeUpdatePeer(struct IN_ADDR, peer *, double, double);
+SQUIDCEXTERN void netdbExchangeUpdatePeer(IPAddress &, peer *, double, double);
 SQUIDCEXTERN peer *netdbClosestParent(HttpRequest *);
 SQUIDCEXTERN void netdbHostData(const char *host, int *samp, int *rtt, int *hops);
 
@@ -420,7 +416,7 @@ SQUIDCEXTERN void peerDigestNeeded(PeerDigest * pd);
 SQUIDCEXTERN void peerDigestNotePeerGone(PeerDigest * pd);
 SQUIDCEXTERN void peerDigestStatsReport(const PeerDigest * pd, StoreEntry * e);
 
-SQUIDCEXTERN struct IN_ADDR getOutgoingAddr(HttpRequest * request);
+SQUIDCEXTERN IPAddress getOutgoingAddr(HttpRequest * request);
 unsigned long getOutgoingTOS(HttpRequest * request);
 
 SQUIDCEXTERN void urnStart(HttpRequest *, StoreEntry *);
@@ -452,7 +448,7 @@ extern void waisStart(FwdState *);
 /* ident.c */
 #if USE_IDENT
 
-SQUIDCEXTERN void identStart(struct sockaddr_in *me, struct sockaddr_in *my_peer,
+SQUIDCEXTERN void identStart(IPAddress &me, IPAddress &my_peer,
                              IDCB * callback, void *cbdata);
 SQUIDCEXTERN void identInit(void);
 #endif
@@ -599,7 +595,9 @@ SQUIDCEXTERN void squid_signal(int sig, SIGHDLR *, int flags);
 SQUIDCEXTERN pid_t readPidFile(void);
 SQUIDCEXTERN void keepCapabilities(void);
 
-SQUIDCEXTERN struct IN_ADDR inaddrFromHostent(const struct hostent *hp);
+/* AYJ debugs function to show locations being reset with memset() */
+SQUIDCEXTERN void *xmemset(void *dst, int, size_t);
+
 SQUIDCEXTERN int intAverage(int, int, int, int);
 SQUIDCEXTERN double doubleAverage(double, double, int, int);
 SQUIDCEXTERN void debug_trap(const char *);
@@ -675,6 +673,7 @@ SQUIDCEXTERN pid_t ipcCreate(int type,
                              const char *prog,
                              const char *const args[],
                              const char *name,
+                             IPAddress &local_addr,
                              int *rfd,
                              int *wfd,
                              void **hIpc);
index f9142a303e954d25fb7d08f4eb61c44c9c4f2fc3..cba04a10ad5afd81d02a8b958555e37dd99ceecf 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: redirect.cc,v 1.122 2007/11/06 21:19:31 wessels Exp $
+ * $Id: redirect.cc,v 1.123 2007/12/14 23:11:48 amosjeffries Exp $
  *
  * DEBUG: section 61    Redirector
  * AUTHOR: Duane Wessels
@@ -49,7 +49,7 @@ typedef struct
     void *data;
     char *orig_url;
 
-    struct IN_ADDR client_addr;
+    IPAddress client_addr;
     const char *client_ident;
     const char *method_s;
     RH *handler;
@@ -117,8 +117,8 @@ redirectStart(ClientHttpRequest * http, RH * handler, void *data)
     redirectStateData *r = NULL;
     const char *fqdn;
     char buf[8192];
-    char claddr[20];
-    char myaddr[20];
+    char claddr[MAX_IPSTRLEN];
+    char myaddr[MAX_IPSTRLEN];
     assert(http);
     assert(handler);
     debugs(61, 5, "redirectStart: '" << http->uri << "'");
@@ -132,7 +132,10 @@ redirectStart(ClientHttpRequest * http, RH * handler, void *data)
 
     r = cbdataAlloc(redirectStateData);
     r->orig_url = xstrdup(http->uri);
-    r->client_addr = conn != NULL ? conn->log_addr : no_addr;
+    if(conn != NULL)
+        r->client_addr = conn->log_addr;
+    else
+        r->client_addr.SetNoAddr();
     r->client_ident = NULL;
 
     if (http->request->auth_user_request)
@@ -163,16 +166,14 @@ redirectStart(ClientHttpRequest * http, RH * handler, void *data)
     if ((fqdn = fqdncache_gethostbyaddr(r->client_addr, 0)) == NULL)
         fqdn = dash_str;
 
-    xstrncpy(claddr, inet_ntoa(r->client_addr), 20);
-    xstrncpy(myaddr, inet_ntoa(http->request->my_addr), 20);
     snprintf(buf, 8192, "%s %s/%s %s %s myip=%s myport=%d\n",
              r->orig_url,
-             claddr,
+             r->client_addr.NtoA(claddr,MAX_IPSTRLEN),
              fqdn,
              r->client_ident[0] ? rfc1738_escape(r->client_ident) : dash_str,
              r->method_s,
-            myaddr,
-            http->request->my_port);
+             http->request->my_addr.NtoA(myaddr,MAX_IPSTRLEN),
+             http->request->my_addr.GetPort());
 
     helperSubmit(redirectors, buf, redirectHandleReply, r);
 }
index 5e9a45d45784ea23aa7f59603aa6fa6b5d3832d4..2914fbf5a8e0609baa8b62ebd11f919c2e087847 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: send-announce.cc,v 1.68 2007/04/28 22:26:37 hno Exp $
+ * $Id: send-announce.cc,v 1.69 2007/12/14 23:11:48 amosjeffries Exp $
  *
  * DEBUG: section 27    Cache Announcer
  * AUTHOR: Duane Wessels
@@ -60,7 +60,7 @@ send_announce(const ipcache_addrs * ia, void *junk)
     LOCAL_ARRAY(char, tbuf, 256);
     LOCAL_ARRAY(char, sndbuf, BUFSIZ);
 
-    struct sockaddr_in S;
+    IPAddress S;
     char *host = Config.Announce.host;
     char *file = NULL;
     u_short port = Config.Announce.port;
@@ -109,14 +109,10 @@ send_announce(const ipcache_addrs * ia, void *junk)
         }
     }
 
-    memset(&S, '\0', sizeof(S));
-    S.sin_family = AF_INET;
-    S.sin_port = htons(port);
-    S.sin_addr = ia->in_addrs[0];
+    S.SetPort(port);
+    S = ia->in_addrs[0];
     assert(theOutIcpConnection > 0);
-    x = comm_udp_sendto(theOutIcpConnection,
-                        &S, sizeof(S),
-                        sndbuf, strlen(sndbuf) + 1);
+    x = comm_udp_sendto(theOutIcpConnection, S, sndbuf, strlen(sndbuf) + 1);
 
     if (x < 0)
         debugs(27, 1, "send_announce: FD " << theOutIcpConnection << ": " << xstrerror());
index d57bc55e8149ebd54fd706b48f6404ac6d1f15ae..90ba56d010bdd0920c20d2579fb39a93ac49aa90 100644 (file)
@@ -1,6 +1,5 @@
-
 /*
- * $Id: snmp_agent.cc,v 1.96 2007/04/28 22:26:37 hno Exp $
+ * $Id: snmp_agent.cc,v 1.97 2007/12/14 23:11:48 amosjeffries Exp $
  *
  * DEBUG: section 49    SNMP Interface
  * AUTHOR: Kostas Anagnostakis
  *
  */
 
-
 #include "squid.h"
 #include "cache_snmp.h"
 #include "Store.h"
 #include "mem_node.h"
+#include "SquidTime.h"
 
 /************************************************************************
  
  
  ************************************************************************/
 
+/* 
+ * cacheSystem group 
+ */
+
 variable_list *
 snmp_sysFn(variable_list * Var, snint * ErrP)
 {
@@ -81,6 +84,9 @@ snmp_sysFn(variable_list * Var, snint * ErrP)
     return Answer;
 }
 
+/* 
+ * cacheConfig group 
+ */
 variable_list *
 snmp_confFn(variable_list * Var, snint * ErrP)
 {
@@ -183,29 +189,47 @@ snmp_confFn(variable_list * Var, snint * ErrP)
     return Answer;
 }
 
+
+/* 
+ * cacheMesh group
+ *   - cachePeerTable
+ */
 variable_list *
 snmp_meshPtblFn(variable_list * Var, snint * ErrP)
 {
     variable_list *Answer = NULL;
 
-    struct IN_ADDR *laddr;
+    IPAddress laddr;
     char *cp = NULL;
     peer *p = NULL;
     int cnt = 0;
     debugs(49, 5, "snmp_meshPtblFn: peer " << Var->name[LEN_SQ_MESH + 3] << " requested!");
     *ErrP = SNMP_ERR_NOERROR;
-    laddr = oid2addr(&Var->name[LEN_SQ_MESH + 3]);
 
+    u_int index = Var->name[LEN_SQ_MESH + 3] ; 
     for (p = Config.peers; p != NULL; p = p->next, cnt++)
-        if (p->in_addr.sin_addr.s_addr == laddr->s_addr)
-            break;
+      {
+        if (p->index == index)
+         {
+           laddr = p->in_addr ;
+           break;
+         }
+      }
 
     if (p == NULL) {
-        *ErrP = SNMP_ERR_NOSUCHNAME;
-        return NULL;
+      *ErrP = SNMP_ERR_NOSUCHNAME;
+      return NULL;
     }
 
+
     switch (Var->name[LEN_SQ_MESH + 2]) {
+    case MESH_PTBL_INDEX: // FIXME INET6: Should be visible?
+        {
+            Answer = snmp_var_new_integer(Var->name, Var->name_length,
+                                          (snint)p->index, SMI_INTEGER);
+        }
+        break;
+
 
     case MESH_PTBL_NAME:
         cp = p->host;
@@ -213,12 +237,29 @@ snmp_meshPtblFn(variable_list * Var, snint * ErrP)
         Answer->type = ASN_OCTET_STR;
         Answer->val_len = strlen(cp);
         Answer->val.string = (u_char *) xstrdup(cp);
+
         break;
 
-    case MESH_PTBL_IP:
-        Answer = snmp_var_new_integer(Var->name, Var->name_length,
-                                      (snint) p->in_addr.sin_addr.s_addr,
-                                      SMI_IPADDRESS);
+    case MESH_PTBL_ADDR_TYPE:
+        {
+            int ival;
+            ival = laddr.IsIPv4() ? INETADDRESSTYPE_IPV4 : INETADDRESSTYPE_IPV6 ;
+            Answer = snmp_var_new_integer(Var->name, Var->name_length,
+                                          ival, SMI_INTEGER);
+        }
+        break;
+    case MESH_PTBL_ADDR:
+        {
+            Answer = snmp_var_new(Var->name, Var->name_length);
+            // InetAddress doesn't have its own ASN.1 type,
+            // like IpAddr does (SMI_IPADDRESS)
+            // See: rfc4001.txt
+            Answer->type = ASN_OCTET_STR;
+           char host[MAX_IPSTRLEN];
+           laddr.NtoA(host,MAX_IPSTRLEN);
+           Answer->val_len = strlen(host);
+           Answer->val.string =  (u_char *) xstrdup(host);
+        }
         break;
 
     case MESH_PTBL_HTTP:
index 2e006caccaccfff0d226ff66ea869376bd30b934..401a8edd84eede1d275f7beeac718f5397b248fd 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: snmp_core.cc,v 1.79 2007/07/06 11:30:45 amosjeffries Exp $
+ * $Id: snmp_core.cc,v 1.80 2007/12/14 23:11:48 amosjeffries Exp $
  *
  * DEBUG: section 49    SNMP support
  * AUTHOR: Glenn Chisholm
@@ -81,7 +81,6 @@ static mib_tree_entry *snmpTreeEntry(oid entry, snint len, mib_tree_entry * curr
 static mib_tree_entry *snmpTreeSiblingEntry(oid entry, snint len, mib_tree_entry * current);
 static void snmpSnmplibDebug(int lvl, char *buf);
 
-
 /*
  * The functions used during startup:
  * snmpInit
@@ -150,91 +149,91 @@ snmpInit(void)
                                                                                                                                 LEN_SQ_PRF, NULL, NULL, 2,
                                                                                                                                 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 1, SQ_PRF, PERF_SYS),
                                                                                                                                             LEN_SQ_PRF + 1, NULL, NULL, 13,
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 1),
+                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_PF),
                                                                                                                                                         LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 2),
+                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_NUMR),
                                                                                                                                                         LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 3),
+                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_MEMUSAGE),
                                                                                                                                                         LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 4),
+                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_CPUTIME),
                                                                                                                                                         LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 5),
+                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_CPUUSAGE),
                                                                                                                                                         LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 6),
+                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_MAXRESSZ),
                                                                                                                                                         LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 7),
+                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_NUMOBJCNT),
                                                                                                                                                         LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 8),
+                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_CURLRUEXP),
                                                                                                                                                         LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 9),
+                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_CURUNLREQ),
                                                                                                                                                         LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 10),
+                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_CURUNUSED_FD),
                                                                                                                                                         LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 11),
+                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_CURRESERVED_FD),
                                                                                                                                                         LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                           snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 12),
+                                                                                                                                           snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_CURUSED_FD),
                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0),
-                                                                                                                                           snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, 13),
+                                                                                                                                           snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_SYS, PERF_SYS_CURMAX_FD),
                                                                                                                                                        LEN_SQ_PRF + 2, snmp_prfSysFn, static_Inst, 0)),
                                                                                                                                 snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 1, SQ_PRF, PERF_PROTO),
                                                                                                                                             LEN_SQ_PRF + 1, NULL, NULL, 2,
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_PROTO, 1),
+                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR),
                                                                                                                                                         LEN_SQ_PRF + 2, NULL, NULL, 15,
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 1),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_HTTP_REQ),
                                                                                                                                                                     LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 2),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_HTTP_HITS),
                                                                                                                                                                     LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 3),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_HTTP_ERRORS),
                                                                                                                                                                     LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 4),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_HTTP_KBYTES_IN),
                                                                                                                                                                     LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 5),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_HTTP_KBYTES_OUT),
                                                                                                                                                                     LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 6),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_ICP_S),
                                                                                                                                                                     LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 7),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_ICP_R),
                                                                                                                                                                     LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 8),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_ICP_SKB),
                                                                                                                                                                     LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 9),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_ICP_RKB),
                                                                                                                                                                     LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 10),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_REQ),
                                                                                                                                                                     LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 11),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_ERRORS),
                                                                                                                                                                     LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 12),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_KBYTES_IN),
                                                                                                                                                                     LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 13),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_KBYTES_OUT),
                                                                                                                                                                     LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 14),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_CURSWAP),
                                                                                                                                                                     LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 1, 15),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_AGGR, PERF_PROTOSTAT_AGGR_CLIENTS),
                                                                                                                                                                     LEN_SQ_PRF + 3, snmp_prfProtoFn, static_Inst, 0)),
                                                                                                                                             snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, PERF_PROTO, 2),
                                                                                                                                                         LEN_SQ_PRF + 2, NULL, NULL, 1,
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, 2, 1),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1),
                                                                                                                                                                     LEN_SQ_PRF + 3, NULL, NULL, 11,
-                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 1),
+                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_TIME),
                                                                                                                                                                                 LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
-                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 2),
+                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_HTTP_ALL),
                                                                                                                                                                                 LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
-                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 3),
+                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_HTTP_MISS),
                                                                                                                                                                                 LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
-                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 4),
+                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_HTTP_NM),
                                                                                                                                                                                 LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
-                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 5),
+                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_HTTP_HIT),
                                                                                                                                                                                 LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
-                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 6),
+                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_ICP_QUERY),
                                                                                                                                                                                 LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
-                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 7),
+                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_ICP_REPLY),
                                                                                                                                                                                 LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
-                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 8),
+                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_DNS),
                                                                                                                                                                                 LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
-                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 9),
+                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_RHR),
                                                                                                                                                                                 LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
-                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 10),
+                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_BHR),
                                                                                                                                                                                 LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0),
-                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, 2, 1, 11),
+                                                                                                                                                                    snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, PERF_PROTO, PERF_PROTOSTAT_MEDIAN, 1, PERF_MEDIAN_HTTP_NH),
                                                                                                                                                                                 LEN_SQ_PRF + 4, snmp_prfProtoFn, time_Inst, 0))))),
                                                                                                                     snmpAddNode(snmpCreateOid(LEN_SQ_NET, SQ_NET),
                                                                                                                                 LEN_SQ_NET, NULL, NULL, 3,
@@ -291,57 +290,63 @@ snmpInit(void)
 #endif
                                                                                                                     snmpAddNode(snmpCreateOid(LEN_SQ_MESH, SQ_MESH),
                                                                                                                                 LEN_SQ_MESH, NULL, NULL, 2,
-                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 1, SQ_MESH, 1),
+                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 1, SQ_MESH, MESH_PTBL),
                                                                                                                                             LEN_SQ_MESH + 1, NULL, NULL, 1,
                                                                                                                                             snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 2, SQ_MESH, 1, 1),
-                                                                                                                                                        LEN_SQ_MESH + 2, NULL, NULL, 13,
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 1),
+                                                                                                                                                        LEN_SQ_MESH + 2, NULL, NULL, 15,
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_INDEX),
+                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_NAME),
                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 2),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_ADDR_TYPE),
                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 3),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_ADDR),
                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 4),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_HTTP),
                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 5),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_ICP),
                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 6),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_TYPE),
                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 7),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_STATE),
                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 8),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_SENT),
                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 9),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_PACKED),
                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 10),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_FETCHES),
                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 11),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_RTT),
                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 12),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_IGN),
                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 13),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_KEEPAL_S),
+                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_PTBL, 1, MESH_PTBL_KEEPAL_R),
                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshPtblFn, peer_Inst, 0))),
-                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 1, SQ_MESH, 2),
+                                                                                                                                snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 1, SQ_MESH, MESH_CTBL),
                                                                                                                                             LEN_SQ_MESH + 1, NULL, NULL, 1,
-                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 2, SQ_MESH, 2, 1),
-                                                                                                                                                        LEN_SQ_MESH + 2, NULL, NULL, 9,
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 1),
+                                                                                                                                            snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 2, SQ_MESH, MESH_CTBL, 1),
+                                                                                                                                                        LEN_SQ_MESH + 2, NULL, NULL, 10,
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_CTBL, 1, MESH_CTBL_ADDR_TYPE),
+                                                                                                                                                                    LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_CTBL, 1, MESH_CTBL_ADDR),
                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 2),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_CTBL, 1, MESH_CTBL_HTREQ),
                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 3),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_CTBL, 1, MESH_CTBL_HTBYTES),
                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 4),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_CTBL, 1, MESH_CTBL_HTHITS),
                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 5),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_CTBL, 1, MESH_CTBL_HTHITBYTES),
                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 6),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_CTBL, 1, MESH_CTBL_ICPREQ),
                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 7),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_CTBL, 1, MESH_CTBL_ICPBYTES),
                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
-                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 8),
+                                                                                                                                                        snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_CTBL, 1, MESH_CTBL_ICPHITS),
                                                                                                                                                                     LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0),
-                                                                                                                                                        (mib_tree_last = snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 9),
+                                                                                                                                                        (mib_tree_last = snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, MESH_CTBL, 1, MESH_CTBL_ICPHITBYTES),
                                                                                                                                                                                      LEN_SQ_MESH + 3, snmp_meshCtblFn, client_Inst, 0)))))
                                                                                                                    )
                                                                                                        )
@@ -358,20 +363,17 @@ snmpInit(void)
 void
 snmpConnectionOpen(void)
 {
-    u_short port;
-
-    struct sockaddr_in xaddr;
-    socklen_t len;
+    struct addrinfo *xaddr = NULL;
     int x;
 
     debugs(49, 5, "snmpConnectionOpen: Called");
 
-    if ((port = Config.Port.snmp) > (u_short) 0) {
+    if (Config.Port.snmp > 0) {
+        Config.Addrs.snmp_incoming.SetPort(Config.Port.snmp);
         enter_suid();
         theInSnmpConnection = comm_open(SOCK_DGRAM,
                                         IPPROTO_UDP,
                                         Config.Addrs.snmp_incoming,
-                                        port,
                                         COMM_NONBLOCKING,
                                         "SNMP Port");
         leave_suid();
@@ -381,14 +383,14 @@ snmpConnectionOpen(void)
 
         commSetSelect(theInSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
 
-        debugs(1, 1, "Accepting SNMP messages on port " << port << ", FD " << theInSnmpConnection << ".");
+        debugs(1, 1, "Accepting SNMP messages on " << Config.Addrs.snmp_incoming << ", FD " << theInSnmpConnection << ".");
 
-        if (Config.Addrs.snmp_outgoing.s_addr != no_addr.s_addr) {
+        if (!Config.Addrs.snmp_outgoing.IsNoAddr()) {
+            Config.Addrs.snmp_outgoing.SetPort(Config.Port.snmp);
             enter_suid();
             theOutSnmpConnection = comm_open(SOCK_DGRAM,
                                              IPPROTO_UDP,
                                              Config.Addrs.snmp_outgoing,
-                                             port,
                                              COMM_NONBLOCKING,
                                              "SNMP Port");
             leave_suid();
@@ -401,7 +403,7 @@ snmpConnectionOpen(void)
                           snmpHandleUdp,
                           NULL, 0);
 
-            debugs(1, 1, "Outgoing SNMP messages on port " << port << ", FD " << theOutSnmpConnection << ".");
+            debugs(1, 1, "Outgoing SNMP messages on " << Config.Addrs.snmp_outgoing << ", FD " << theOutSnmpConnection << ".");
 
             fd_note(theOutSnmpConnection, "Outgoing SNMP socket");
 
@@ -410,18 +412,18 @@ snmpConnectionOpen(void)
             theOutSnmpConnection = theInSnmpConnection;
         }
 
-        memset(&theOutSNMPAddr, '\0', sizeof(struct IN_ADDR));
+        theOutSNMPAddr.SetEmpty();
 
-        len = sizeof(struct sockaddr_in);
-        memset(&xaddr, '\0', len);
-        x = getsockname(theOutSnmpConnection,
+        theOutSNMPAddr.InitAddrInfo(xaddr);
 
-                        (struct sockaddr *) &xaddr, &len);
+        x = getsockname(theOutSnmpConnection, xaddr->ai_addr, &xaddr->ai_addrlen);
 
         if (x < 0)
             debugs(51, 1, "theOutSnmpConnection FD " << theOutSnmpConnection << ": getsockname: " << xstrerror());
         else
-            theOutSNMPAddr = xaddr.sin_addr;
+           theOutSNMPAddr = *xaddr;
+
+        theOutSNMPAddr.FreeAddrInfo(xaddr);
     }
 }
 
@@ -476,9 +478,7 @@ void
 snmpHandleUdp(int sock, void *not_used)
 {
     LOCAL_ARRAY(char, buf, SNMP_REQUEST_SIZE);
-
-    struct sockaddr_in from;
-    socklen_t from_len;
+    IPAddress from;
     snmp_request_t *snmp_rq;
     int len;
 
@@ -486,29 +486,24 @@ snmpHandleUdp(int sock, void *not_used)
 
     commSetSelect(sock, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
 
-    from_len = sizeof(struct sockaddr_in);
-    memset(&from, '\0', from_len);
     memset(buf, '\0', SNMP_REQUEST_SIZE);
 
     len = comm_udp_recvfrom(sock,
                             buf,
                             SNMP_REQUEST_SIZE,
                             0,
-
-                            (struct sockaddr *) &from,
-                            &from_len);
+                            from);
 
     if (len > 0) {
         buf[len] = '\0';
-        debugs(49, 3, "snmpHandleUdp: FD " << sock << ": received " << len << " bytes from " << inet_ntoa(from.sin_addr) << ".");
+        debugs(49, 3, "snmpHandleUdp: FD " << sock << ": received " << len << " bytes from " << from << ".");
 
         snmp_rq = (snmp_request_t *)xcalloc(1, sizeof(snmp_request_t));
         snmp_rq->buf = (u_char *) buf;
         snmp_rq->len = len;
         snmp_rq->sock = sock;
         snmp_rq->outbuf = (unsigned char *)xmalloc(snmp_rq->outlen = SNMP_REQUEST_SIZE);
-
-        xmemcpy(&snmp_rq->from, &from, sizeof(struct sockaddr_in));
+        snmp_rq->from = from;
         snmpDecodePacket(snmp_rq);
         xfree(snmp_rq->outbuf);
         xfree(snmp_rq);
@@ -523,36 +518,39 @@ snmpHandleUdp(int sock, void *not_used)
 static void
 snmpDecodePacket(snmp_request_t * rq)
 {
-
     struct snmp_pdu *PDU;
-
     u_char *Community;
     u_char *buf = rq->buf;
     int len = rq->len;
     int allow = 0;
 
-    debugs(49, 5, "snmpDecodePacket: Called.");
-    /* Now that we have the data, turn it into a PDU */
+    debugs(49, 5, HERE << "Called.");
     PDU = snmp_pdu_create(0);
+    /* Allways answer on SNMPv1 */
     rq->session.Version = SNMP_VERSION_1;
     Community = snmp_parse(&rq->session, PDU, buf, len);
 
     if (Community) {
         ACLChecklist checklist;
         checklist.accessList = cbdataReference(Config.accessList.snmp);
-        checklist.src_addr = rq->from.sin_addr;
+        checklist.src_addr = rq->from;
         checklist.snmp_community = (char *) Community;
         /* cbdataReferenceDone() happens in either fastCheck() or ~ACLCheckList */
         allow = checklist.fastCheck();
     }
 
+#if 1 /* FIXME INET6 : Kill this block before committing to HEAD. */
+    /* RAFA, Amos, DO NOT COMMIT INTO AHEAD with this !!! */
+    allow = 1 ;
+    /* allow */
+#endif /* KILL */
     if ((snmp_coexist_V2toV1(PDU)) && (Community) && (allow)) {
         rq->community = Community;
         rq->PDU = PDU;
         debugs(49, 5, "snmpAgentParse: reqid=[" << PDU->reqid << "]");
         snmpConstructReponse(rq);
     } else {
-        debugs(49, 1, "Failed SNMP agent query from : " << inet_ntoa(rq->from.sin_addr) << ".");
+        debugs(49, 1, HERE << "Failed SNMP agent query from : " << rq->from);
         snmp_free_pdu(PDU);
     }
 
@@ -575,7 +573,7 @@ snmpConstructReponse(snmp_request_t * rq)
 
     if (RespPDU != NULL) {
         snmp_build(&rq->session, RespPDU, rq->outbuf, &rq->outlen);
-        comm_udp_sendto(rq->sock, &rq->from, sizeof(rq->from), rq->outbuf, rq->outlen);
+        comm_udp_sendto(rq->sock, rq->from, rq->outbuf, rq->outlen);
         snmp_free_pdu(RespPDU);
     }
 }
@@ -600,6 +598,7 @@ static struct snmp_pdu *
         Answer->errindex = 0;
 
         if (PDU->command == SNMP_PDU_GET || PDU->command == SNMP_PDU_GETNEXT) {
+         /* Indirect way */
             int get_next = (PDU->command == SNMP_PDU_GETNEXT);
             variable_list *VarPtr_;
             variable_list **RespVars = &(Answer->variables);
@@ -615,8 +614,6 @@ static struct snmp_pdu *
 
                 index++;
 
-                /* Find the parsing function for this variable */
-
                 if (get_next)
                     ParseFn = snmpTreeNext(VarPtr->name, VarPtr->name_length, &NextOidName, &NextOidNameLen);
                 else
@@ -639,7 +636,6 @@ static struct snmp_pdu *
                         snmp_var_free(VarPtr);
                 }
 
-                /* Was there an error? */
                 if ((Answer->errstat != SNMP_ERR_NOERROR) || (VarNew == NULL)) {
                     Answer->errindex = index;
                     debugs(49, 5, "snmpAgentResponse: error.");
@@ -647,7 +643,6 @@ static struct snmp_pdu *
                     if (VarNew)
                         snmp_var_free(VarNew);
 
-                    /* Free the already processed results, if any */
                     while ((VarPtr = Answer->variables) != NULL) {
                         Answer->variables = VarPtr->next_variable;
                         snmp_var_free(VarPtr);
@@ -666,8 +661,8 @@ static struct snmp_pdu *
                 *RespVars = VarNew;
 
                 RespVars = &(VarNew->next_variable);
-            }
-        }
+            } 
+        } 
     }
 
     return (Answer);
@@ -724,14 +719,13 @@ snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen)
         while ((mibTreeEntry) && (count < CurrentLen) && (!mibTreeEntry->parsefunction)) {
             mib_tree_entry *nextmibTreeEntry = snmpTreeEntry(Current[count], count, mibTreeEntry);
 
-            if (!nextmibTreeEntry)
+            if (!nextmibTreeEntry)  
                 break;
             else
                 mibTreeEntry = nextmibTreeEntry;
 
             count++;
         }
-
         debugs(49, 5, "snmpTreeNext: Recursed down to requested object");
     } else {
         return NULL;
@@ -740,20 +734,23 @@ snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen)
     if (mibTreeEntry == mib_tree_last)
         return (Fn);
 
-    if ((mibTreeEntry) && (mibTreeEntry->parsefunction)) {
-        *NextLen = CurrentLen;
-        *Next = (*mibTreeEntry->instancefunction) (Current, NextLen, mibTreeEntry, &Fn);
 
-        if (*Next)
-            return (Fn);
+    if ((mibTreeEntry) && (mibTreeEntry->parsefunction)) {
+      *NextLen = CurrentLen;  
+      *Next = (*mibTreeEntry->instancefunction) (Current, NextLen, mibTreeEntry, &Fn);
+      if (*Next)
+       {
+         debugs(49, 6, "snmpTreeNext: Next : ");
+         snmpDebugOid(6, *Next, *NextLen);
+         return (Fn);
+       }
     }
 
     if ((mibTreeEntry) && (mibTreeEntry->parsefunction)) {
         count--;
         nextoid = snmpTreeSiblingEntry(Current[count], count, mibTreeEntry->parent);
-
         if (nextoid) {
-            debugs(49, 5, "snmpTreeNext: Next OID found for sibling");
+         debugs(49, 5, "snmpTreeNext: Next OID found for sibling" << nextoid );
             mibTreeEntry = nextoid;
             count++;
         } else {
@@ -777,7 +774,6 @@ snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen)
             }
         }
     }
-
     while ((mibTreeEntry) && (!mibTreeEntry->parsefunction)) {
         mibTreeEntry = mibTreeEntry->leaves[0];
     }
@@ -788,7 +784,11 @@ snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen)
     }
 
     if (*Next)
-        return (Fn);
+       {
+         debugs(49, 6, "snmpTreeNext: Next : ");
+         snmpDebugOid(6, *Next, *NextLen);
+         return (Fn);
+       }
     else
         return NULL;
 }
@@ -797,14 +797,12 @@ static oid *
 static_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
 {
     oid *instance = NULL;
-
     if (*len <= current->len) {
         instance = (oid *)xmalloc(sizeof(name) * (*len + 1));
         xmemcpy(instance, name, (sizeof(name) * *len));
         instance[*len] = 0;
         *len += 1;
     }
-
     *Fn = current->parsefunction;
     return (instance);
 }
@@ -814,8 +812,7 @@ time_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
 {
     oid *instance = NULL;
     int identifier = 0, loop = 0;
-    int index[TIME_INDEX_LEN] =
-        {TIME_INDEX};
+    int index[TIME_INDEX_LEN] = {TIME_INDEX};
 
     if (*len <= current->len) {
         instance = (oid *)xmalloc(sizeof(name) * (*len + 1));
@@ -828,7 +825,7 @@ time_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
         while ((loop < TIME_INDEX_LEN) && (identifier != index[loop]))
             loop++;
 
-        if (loop < TIME_INDEX_LEN - 1) {
+        if (loop < (TIME_INDEX_LEN - 1)) { 
             instance = (oid *)xmalloc(sizeof(name) * (*len));
             xmemcpy(instance, name, (sizeof(name) * *len));
             instance[*len - 1] = index[++loop];
@@ -839,68 +836,38 @@ time_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
     return (instance);
 }
 
+
 static oid *
 peer_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
 {
     oid *instance = NULL;
-    u_char *cp = NULL;
     peer *peers = Config.peers;
 
-    struct IN_ADDR *laddr = NULL;
-    char *host_addr = NULL, *current_addr = NULL, *last_addr = NULL;
-
     if (peers == NULL) {
         current = current->parent->parent->parent->leaves[1];
-
         while ((current) && (!current->parsefunction))
             current = current->leaves[0];
 
         instance = client_Inst(current->name, len, current, Fn);
-    } else if (*len <= current->len) {
-        instance = (oid *)xmalloc(sizeof(name) * (*len + 4));
-        xmemcpy(instance, name, (sizeof(name) * *len));
-        cp = (u_char *) & (peers->in_addr.sin_addr.s_addr);
-        instance[*len] = *cp++;
-        instance[*len + 1] = *cp++;
-        instance[*len + 2] = *cp++;
-        instance[*len + 3] = *cp++;
-        *len += 4;
+    } else if (*len <= current->len) { 
+      instance = (oid *)xmalloc(sizeof(name) * ( *len + 1));
+      xmemcpy(instance, name, (sizeof(name) * *len));
+      instance[*len] = 1 ;
+      *len += 1;  
     } else {
-        laddr = oid2addr(&name[*len - 4]);
-        host_addr = inet_ntoa(*laddr);
-        last_addr = (char *)xmalloc(strlen(host_addr));
-        strncpy(last_addr, host_addr, strlen(host_addr));
-        current_addr = inet_ntoa(peers->in_addr.sin_addr);
-
-        while ((peers) && (strncmp(last_addr, current_addr, strlen(current_addr)))) {
-            if (peers->next) {
-                peers = peers->next;
-                current_addr = inet_ntoa(peers->in_addr.sin_addr);
-            } else {
-                peers = NULL;
-            }
-        }
-
-        xfree(last_addr);
-
-        if (peers) {
-            if (peers->next) {
-                peers = peers->next;
-                instance = (oid *)xmalloc(sizeof(name) * (*len));
-                xmemcpy(instance, name, (sizeof(name) * *len));
-                cp = (u_char *) & (peers->in_addr.sin_addr.s_addr);
-                instance[*len - 4] = *cp++;
-                instance[*len - 3] = *cp++;
-                instance[*len - 2] = *cp++;
-                instance[*len - 1] = *cp++;
-            } else {
-                return (instance);
-            }
-        } else {
-            return (instance);
-        }
+      int no = name[current->len] ;
+      int i ; // Note: This works because the Confifg.peers 
+              // keep its index acording to its position.
+      for ( i=0 ; peers && (i < no) ; peers = peers->next , i++ ) ;
+      
+      if (peers) {
+         instance = (oid *)xmalloc(sizeof(name) * (current->len + 1 ));
+         xmemcpy(instance, name, (sizeof(name) * current->len ));
+         instance[current->len] = no + 1 ; // i.e. the next index on cache_peeer table.
+      } else {
+       return (instance);
+      }
     }
-
     *Fn = current->parsefunction;
     return (instance);
 }
@@ -909,38 +876,50 @@ static oid *
 client_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
 {
     oid *instance = NULL;
-    u_char *cp = NULL;
-
-    struct IN_ADDR *laddr = NULL;
+    IPAddress laddr;
+    IPAddress *aux;
 
     if (*len <= current->len) {
-        instance = (oid *)xmalloc(sizeof(name) * (*len + 4));
-        xmemcpy(instance, name, (sizeof(name) * *len));
-        laddr = client_entry(NULL);
-
-        if (laddr) {
-            cp = (u_char *) & (laddr->s_addr);
-            instance[*len] = *cp++;
-            instance[*len + 1] = *cp++;
-            instance[*len + 2] = *cp++;
-            instance[*len + 3] = *cp++;
-            *len += 4;
-        }
-    } else {
-        laddr = oid2addr(&name[*len - 4]);
-        laddr = client_entry(laddr);
+      aux  = client_entry(NULL);  
+      // FIXME INET6 . is this good C++ style ?
+      // What otherwise ?
+      if (aux) laddr = *aux ; else laddr.SetAnyAddr();
+
+#if USE_IPV6
+      int size = laddr.IsIPv4()? sizeof(in_addr) : sizeof(in6_addr)  ;
+#else 
+      int size = sizeof(in_addr);
+#endif
 
-        if (laddr) {
-            instance = (oid *)xmalloc(sizeof(name) * (*len));
-            xmemcpy(instance, name, (sizeof(name) * *len));
-            cp = (u_char *) & (laddr->s_addr);
-            instance[*len - 4] = *cp++;
-            instance[*len - 3] = *cp++;
-            instance[*len - 2] = *cp++;
-            instance[*len - 1] = *cp++;
-        }
-    }
+      instance = (oid *)xmalloc(sizeof(name) * (*len + size ));
+      xmemcpy(instance, name, (sizeof(name) * (*len)));
 
+      if ( !laddr.IsAnyAddr() ) {
+       addr2oid(laddr, &instance[ *len]);  // the addr
+       *len += size ;
+      }
+    } else {
+      int shift = *len - current->len ; // i.e 4 or 16 
+      oid2addr(&name[*len - shift], laddr,shift); 
+      aux = client_entry(&laddr);  
+      // FIXME INET6 . is this good C++ style ?
+      // What otherwise ?
+      if (aux) laddr = *aux ; else laddr.SetAnyAddr();
+
+      
+      if (!laddr.IsAnyAddr()) {
+#if USE_IPV6
+         int newshift = laddr.IsIPv4()? sizeof(in_addr) : sizeof(in6_addr)  ;
+#else
+         int newshift = sizeof(in_addr) ;
+#endif
+       instance = (oid *)xmalloc(sizeof(name) * (current->len +  newshift));
+       xmemcpy(instance, name, (sizeof(name) * (current->len)));
+       addr2oid(laddr, &instance[current->len]);  // the addr.
+       *len = current->len + newshift ;
+      }
+    }
+    
     *Fn = current->parsefunction;
     return (instance);
 }
@@ -955,7 +934,8 @@ client_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn
  */
 
 /*
- * Returns a the sibling object in the tree
+ * Returns a sibling object for the requested child object or NULL
+ * if it does not exit
  */
 static mib_tree_entry *
 snmpTreeSiblingEntry(oid entry, snint len, mib_tree_entry * current)
@@ -971,6 +951,7 @@ snmpTreeSiblingEntry(oid entry, snint len, mib_tree_entry * current)
         count++;
     }
 
+    /* Exactly the sibling on rigth */
     if (count < current->children) {
         next = current->leaves[count];
     } else {
@@ -1118,30 +1099,86 @@ snmpSnmplibDebug(int lvl, char *buf)
     debug(49, lvl) ("%s", buf);
 }
 
-void
 
-addr2oid(struct IN_ADDR addr, oid * Dest)
+
+/* 
+   IPv4 address: 10.10.0.9  ==>
+   oid == 10.10.0.9 
+   IPv6 adress : 20:01:32:ef:a2:21:fb:32:00:00:00:00:00:00:00:00:OO:01 ==> 
+   oid == 32.1.50.239.162.33.251.20.50.0.0.0.0.0.0.0.0.0.1 
+*/
+void
+addr2oid(IPAddress &addr, oid * Dest)
 {
-    u_char *cp;
-    cp = (u_char *) & (addr.s_addr);
-    Dest[0] = *cp++;
-    Dest[1] = *cp++;
-    Dest[2] = *cp++;
-    Dest[3] = *cp++;
+  u_int i ;
+  u_char *cp = NULL;
+  struct in_addr iaddr;
+#if USE_IPV6
+  struct in6_addr i6addr;
+  oid code = addr.IsIPv4()? INETADDRESSTYPE_IPV4  : INETADDRESSTYPE_IPV6 ;
+  u_int size = (code == INETADDRESSTYPE_IPV4) ? sizeof(struct in_addr):sizeof(struct in6_addr);
+#else
+  oid code = INETADDRESSTYPE_IPV4 ;
+  u_int size = sizeof(struct in_addr) ;
+#endif /* USE_IPV6 */
+  //  Dest[0] = code ;
+  if ( code == INETADDRESSTYPE_IPV4 ) {
+    addr.GetInAddr(iaddr);
+    cp = (u_char *) &(iaddr.s_addr);
+  }
+#if USE_IPV6
+  else 
+   {
+    addr.GetInAddr(i6addr);
+    cp = (u_char *) &i6addr;
+   }
+#endif
+  for ( i=0 ; i < size ; i++)
+    {
+      // OID's are in network order
+      Dest[i] = *cp++;  
+    }
+  debugs(49, 7, "addr2oid: Dest : ");
+  snmpDebugOid(7, Dest, size );
+
 }
 
-struct IN_ADDR
-            *
-            oid2addr(oid * id)
+/* 
+   oid == 10.10.0.9 ==>
+   IPv4 address: 10.10.0.9
+   oid == 32.1.50.239.162.33.251.20.50.0.0.0.0.0.0.0.0.0.1 ==> 
+   IPv6 adress : 20:01:32:ef:a2:21:fb:32:00:00:00:00:00:00:00:00:OO:01
+*/
+void
+oid2addr(oid * id, IPAddress &addr, u_int size)
 {
+  struct in_addr iaddr;
+  u_int i;
+  u_char *cp;
+#if USE_IPV6
+  struct in6_addr i6addr;
+  if ( size == sizeof(struct in_addr) )
+#endif /* USE_IPV6 */
+  cp = (u_char *) &(iaddr.s_addr);
+#if USE_IPV6
+  else 
+  cp = (u_char *) &(i6addr);
+#endif /* USE_IPV6 */
+  debugs(49, 7, "oid2addr: id : ");
+  snmpDebugOid(7, id, size  );
+  for(i=0 ; i<size; i++)
+    {
+    cp[i] = id[i];
+    }
+#if USE_IPV6
+  if ( size == sizeof(struct in_addr) )
+#endif
+      addr = iaddr;
+#if USE_IPV6
+  else
+      addr = i6addr;
+#endif
 
-    static struct IN_ADDR laddr;
-    u_char *cp = (u_char *) & (laddr.s_addr);
-    cp[0] = id[0];
-    cp[1] = id[1];
-    cp[2] = id[2];
-    cp[3] = id[3];
-    return &laddr;
 }
 
 /* SNMP checklists */
index 195d05ff30fbd75ec112e9710ed7daa6b1650ebe..7308ff2f508fa47d6bef2ed8348cd65238038a36 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: squid.h,v 1.268 2007/12/04 13:31:11 hno Exp $
+ * $Id: squid.h,v 1.269 2007/12/14 23:11:48 amosjeffries Exp $
  *
  * AUTHOR: Duane Wessels
  *
@@ -364,7 +364,7 @@ extern "C"
 #endif
 
 #include "hash.h"
-#include "rfc1035.h"
+#include "rfc3596.h"
 
 
 #include "defines.h"
@@ -374,6 +374,8 @@ extern "C"
 #include "profiling.h"
 #include "MemPool.h"
 
+#include "IPAddress.h"
+
 #if !HAVE_TEMPNAM
 #include "tempnam.h"
 #endif
index e8f928f7e45ef4e7077e7074952aca40cb706529..6eb81ec5cf431a84aaf188fac14cb07f22a671a0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: stat.cc,v 1.410 2007/09/20 20:22:20 hno Exp $
+ * $Id: stat.cc,v 1.411 2007/12/14 23:11:48 amosjeffries Exp $
  *
  * DEBUG: section 18    Cache Manager Statistics
  * AUTHOR: Harvest Derived
@@ -48,6 +48,7 @@
 #include "client_side_request.h"
 #include "client_side.h"
 #include "MemBuf.h"
+#include "SquidTime.h"
 
 /* these are included because they expose stats calls */
 /* TODO: provide a self registration mechanism for those classes
@@ -1644,6 +1645,7 @@ statClientRequests(StoreEntry * s)
     ClientHttpRequest *http;
     StoreEntry *e;
     int fd;
+    char buf[MAX_IPSTRLEN];
 
     for (i = ClientActiveRequests.head; i; i = i->next) {
         const char *p = NULL;
@@ -1660,11 +1662,11 @@ statClientRequests(StoreEntry * s)
             storeAppendPrintf(s, "\tin: buf %p, offset %ld, size %ld\n",
                               conn->in.buf, (long int) conn->in.notYetUsed, (long int) conn->in.allocatedSize);
             storeAppendPrintf(s, "\tpeer: %s:%d\n",
-                              inet_ntoa(conn->peer.sin_addr),
-                              ntohs(conn->peer.sin_port));
+                              conn->peer.NtoA(buf,MAX_IPSTRLEN),
+                              conn->peer.GetPort());
             storeAppendPrintf(s, "\tme: %s:%d\n",
-                              inet_ntoa(conn->me.sin_addr),
-                              ntohs(conn->me.sin_port));
+                              conn->me.NtoA(buf,MAX_IPSTRLEN),
+                              conn->me.GetPort());
             storeAppendPrintf(s, "\tnrequests: %d\n",
                               conn->nrequests);
         }
index 2d1be05e20116445538ecbedb5c6769563225bbc..7a0a992e1b55c7fa0fc99e627bbee5728225ad14 100644 (file)
@@ -1,6 +1,5 @@
-
 /*
- * $Id: store_log.cc,v 1.35 2007/08/13 17:20:51 hno Exp $
+ * $Id: store_log.cc,v 1.36 2007/12/14 23:11:48 amosjeffries Exp $
  *
  * DEBUG: section 20    Storage Manager Logging Functions
  * AUTHOR: Duane Wessels
@@ -38,6 +37,7 @@
 #include "MemObject.h"
 #include "HttpReply.h"
 #include "CacheManager.h"
+#include "SquidTime.h"
 
 static const char *storeLogTags[] =
     {
index ce2a077bf36d0cf161010550ace3ff695bdc496d..625fbd69de9e34e922e6c74992688093731af2a7 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: structs.h,v 1.568 2007/12/02 08:23:56 amosjeffries Exp $
+ * $Id: structs.h,v 1.569 2007/12/14 23:11:48 amosjeffries Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -76,7 +76,7 @@ struct _snmp_request_t
     long reqid;
     int outlen;
 
-    struct sockaddr_in from;
+    IPAddress from;
 
     struct snmp_pdu *PDU;
     ACLChecklist *acl_checklist;
@@ -93,7 +93,7 @@ struct _acl_address
     acl_address *next;
     ACLList *aclList;
 
-    struct IN_ADDR addr;
+    IPAddress addr;
 };
 
 struct _acl_tos
@@ -123,18 +123,11 @@ struct _relist
     relist *next;
 };
 
-struct _sockaddr_in_list
-{
-
-    struct sockaddr_in s;
-    sockaddr_in_list *next;
-};
-
 struct _http_port_list
 {
     http_port_list *next;
 
-    struct sockaddr_in s;
+    IPAddress s;
     char *protocol;            /* protocol name */
     char *name;                /* visible name */
     char *defaultsite;         /* default web site */
@@ -183,6 +176,10 @@ struct _https_port_list
 #include "DelayConfig.h"
 #endif
 
+#if USE_ICMP
+#include "ICMPConfig.h"
+#endif
+
 /* forward decl for SquidConfig, see RemovalPolicy.h */
 
 class RemovalPolicySettings;
@@ -300,9 +297,9 @@ struct _SquidConfig
     struct
     {
 
-        struct IN_ADDR router;
+        IPAddress router;
 
-        struct IN_ADDR address;
+        IPAddress address;
         int version;
     }
 
@@ -312,9 +309,9 @@ struct _SquidConfig
 
     struct
     {
-        sockaddr_in_list *router;
+        IPAddress_list *router;
 
-        struct IN_ADDR address;
+        IPAddress address;
         int forwarding_method;
         int return_method;
         int assignment_method;
@@ -326,6 +323,10 @@ struct _SquidConfig
     Wccp2;
 #endif
 
+#if USE_ICMP
+    ICMPConfig pinger;
+#endif
+
     char *as_whois_server;
 
     struct
@@ -368,10 +369,6 @@ struct _SquidConfig
 #endif
 
         wordlist *redirect;
-#if USE_ICMP
-
-        char *pinger;
-#endif
 #if USE_UNLINKD
 
         char *unlinkd;
@@ -430,17 +427,17 @@ struct _SquidConfig
     struct
     {
 
-        struct IN_ADDR udp_incoming;
+        IPAddress udp_incoming;
 
-        struct IN_ADDR udp_outgoing;
+        IPAddress udp_outgoing;
 #if SQUID_SNMP
 
-        struct IN_ADDR snmp_incoming;
+        IPAddress snmp_incoming;
 
-        struct IN_ADDR snmp_outgoing;
+        IPAddress snmp_outgoing;
 #endif
-
-        struct IN_ADDR client_netmask;
+        /* FIXME INET6 : this should really be a CIDR value */
+        IPAddress client_netmask;
     }
 
     Addrs;
@@ -501,11 +498,6 @@ struct _SquidConfig
         int query_icmp;
         int icp_hit_stale;
         int buffered_logs;
-#if ALLOW_SOURCE_PING
-
-        int source_ping;
-#endif
-
         int common_log;
         int log_mime_hdrs;
         int log_fqdn;
@@ -553,6 +545,7 @@ struct _SquidConfig
         int emailErrData;
         int httpd_suppress_version_string;
         int global_internal_static;
+        int dns_require_A;
         int debug_override_X;
     }
 
@@ -667,7 +660,7 @@ struct _SquidConfig
     struct
     {
 
-        struct IN_ADDR addr;
+        IPAddress addr;
         int ttl;
         unsigned short port;
         char *encode_key;
@@ -940,8 +933,7 @@ unsigned int consume_body_data:
 
 struct _ipcache_addrs
 {
-
-    struct IN_ADDR *in_addrs;
+    IPAddress *in_addrs;
     unsigned char *bad_mask;
     unsigned char count;
     unsigned char cur;
@@ -980,11 +972,12 @@ struct _cd_guess_stats
 
 struct _peer
 {
+    u_int index;
     char *name;
     char *host;
     peer_t type;
 
-    struct sockaddr_in in_addr;
+    IPAddress in_addr;
 
     struct
     {
@@ -1123,7 +1116,7 @@ unsigned int counting:
 
     int tcp_up;                        /* 0 if a connect() fails */
 
-    struct IN_ADDR addresses[10];
+    IPAddress addresses[10];
     int n_addresses;
     int rr_count;
     int rr_lastcount;
@@ -1183,7 +1176,7 @@ struct _net_db_peer
 struct _netdbEntry
 {
     hash_link hash;            /* must be first */
-    char network[16];
+    char network[MAX_IPSTRLEN];
     int pings_sent;
     int pings_recv;
     double hops;
@@ -1198,30 +1191,6 @@ struct _netdbEntry
 };
 
 
-#if USE_ICMP
-
-struct _pingerEchoData
-{
-
-    struct IN_ADDR to;
-    unsigned char opcode;
-    int psize;
-    char payload[PINGER_PAYLOAD_SZ];
-};
-
-struct _pingerReplyData
-{
-
-    struct IN_ADDR from;
-    unsigned char opcode;
-    int rtt;
-    int hops;
-    int psize;
-    char payload[PINGER_PAYLOAD_SZ];
-};
-
-#endif
-
 struct _iostats
 {
 
@@ -1608,7 +1577,7 @@ struct _ClientInfo
 {
     hash_link hash;            /* must be first */
 
-    struct IN_ADDR addr;
+    IPAddress addr;
 
     struct
     {
index 018d453a75f06dffd8ebd82e26c778165964b71c..69d8580fb30d9804c628d4adb04b8d99ffc36096 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: stub_comm.cc,v 1.5 2006/09/14 20:13:23 serassio Exp $
+ * $Id: stub_comm.cc,v 1.6 2007/12/14 23:11:53 amosjeffries Exp $
  *
  * DEBUG: section 84    Helper process maintenance
  * AUTHOR: Robert Collins
@@ -114,7 +114,7 @@ commUnsetNonBlocking(int fd)
 /* bah, cheating on stub count */
 
 pid_t
-ipcCreate(int type, const char *prog, const char *const args[], const char *name, int *rfd, int *wfd, void **hIpc)
+ipcCreate(int type, const char *prog, const char *const args[], const char *name, IPAddress &local_addr, int *rfd, int *wfd, void **hIpc)
 {
     fatal ("Not implemented");
     return -1;
index d91db9fb32baa7f2d63588c5facb2ddebc6fb15e..290024846b3702c03eea49baff7f1907ed25a19f 100644 (file)
@@ -93,20 +93,44 @@ testEvent::testDump()
     CalledEvent event;
     CalledEvent event2;
     CapturingStoreEntry * anEntry = new CapturingStoreEntry();
+    String expect =  "Last event to run: last event\n"
+                     "\n"
+                     "Operation                \tNext Execution \tWeight\tCallback Valid?\n"
+                     "test event               \t0.000 sec\t    0\t N/A\n"
+                     "test event2              \t0.000 sec\t    0\t N/A\n"
+                     ;
+
     scheduler.schedule("last event", CalledEvent::Handler, &event, 0, 0, false);
+
     /* schedule and dispatch to set the last run event */
     scheduler.checkEvents(0);
     dispatcher.dispatch();
     scheduler.schedule("test event", CalledEvent::Handler, &event, 0, 0, false);
     scheduler.schedule("test event2", CalledEvent::Handler, &event2, 0, 0, false);
     scheduler.dump(anEntry);
-    CPPUNIT_ASSERT_EQUAL(String(
-                             "Last event to run: last event\n"
-                             "\n"
-                             "Operation\tNext Execution\tWeight\tCallback Valid?\n"
-                             "test event\t0.000000 seconds\t0\tN/A\n"
-                             "test event2\t0.000000 seconds\t0\tN/A\n"
-                         ), anEntry->_appended_text);
+
+    /* loop over the strings, showing exactly where they differ (if at all) */
+    printf("Actual Text:\n");
+    /* TODO: these should really be just [] lookups, but String doesn't have those here yet. */
+    for( int i = 0; i < anEntry->_appended_text.size(); i++) {
+        CPPUNIT_ASSERT( expect.buf()[i] );
+        CPPUNIT_ASSERT( anEntry->_appended_text.buf()[i] );
+
+        /* slight hack to make special chars visible */
+        switch(anEntry->_appended_text.buf()[i])
+        {
+        case '\t':
+            printf("\\t"); break;
+        default:
+            printf("%c", anEntry->_appended_text.buf()[i] );
+        }
+        /* make this an int comparison, so that we can see the ASCII code at failure */
+        CPPUNIT_ASSERT_EQUAL( (int)expect.buf()[i], (int)anEntry->_appended_text.buf()[i] );
+    }
+    printf("\n");
+    CPPUNIT_ASSERT_EQUAL( expect, anEntry->_appended_text);
+
+    /* cleanup */
     delete anEntry;
 }
 
index d0840cca6afe809cef4a6da5eec7b684d06a9e7f..d0864a0e8b3f1404e63f44474d4629d7719a4981 100644 (file)
@@ -37,33 +37,36 @@ testHttpRequest::testCreateFromUrlAndMethod()
     HttpRequest *nullRequest = NULL;
     CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
     CPPUNIT_ASSERT_EQUAL(METHOD_GET, aRequest->method);
-    CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->host));
+    CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->GetHost()));
     CPPUNIT_ASSERT_EQUAL(String("/bar"), aRequest->urlpath);
     CPPUNIT_ASSERT_EQUAL(PROTO_HTTP, aRequest->protocol);
     CPPUNIT_ASSERT_EQUAL(String("http://foo:90/bar"), String(url));
     xfree(url);
+
     /* vanilla url, different method */
     url = xstrdup("http://foo/bar");
     aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_PUT);
     expected_port = 80;
     CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
     CPPUNIT_ASSERT_EQUAL(METHOD_PUT, aRequest->method);
-    CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->host));
+    CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->GetHost()));
     CPPUNIT_ASSERT_EQUAL(String("/bar"), aRequest->urlpath);
     CPPUNIT_ASSERT_EQUAL(PROTO_HTTP, aRequest->protocol);
     CPPUNIT_ASSERT_EQUAL(String("http://foo/bar"), String(url));
+
     /* a connect url with non-CONNECT data */
     url = xstrdup(":foo/bar");
     aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_CONNECT);
     xfree(url);
     CPPUNIT_ASSERT_EQUAL(nullRequest, aRequest);
+
     /* a CONNECT url with CONNECT data */
     url = xstrdup("foo:45");
     aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_CONNECT);
     expected_port = 45;
     CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
     CPPUNIT_ASSERT_EQUAL(METHOD_CONNECT, aRequest->method);
-    CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->host));
+    CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->GetHost()));
     CPPUNIT_ASSERT_EQUAL(String(""), aRequest->urlpath);
     CPPUNIT_ASSERT_EQUAL(PROTO_NONE, aRequest->protocol);
     CPPUNIT_ASSERT_EQUAL(String("foo:45"), String(url));
@@ -83,9 +86,62 @@ testHttpRequest::testCreateFromUrl()
     expected_port = 90;
     CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
     CPPUNIT_ASSERT_EQUAL(METHOD_GET, aRequest->method);
-    CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->host));
+    CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->GetHost()));
     CPPUNIT_ASSERT_EQUAL(String("/bar"), aRequest->urlpath);
     CPPUNIT_ASSERT_EQUAL(PROTO_HTTP, aRequest->protocol);
     CPPUNIT_ASSERT_EQUAL(String("http://foo:90/bar"), String(url));
     xfree(url);
 }
+
+/*
+ * Test BUG: URL '2000:800:45' opens host 2000 port 800 !!
+ */
+void
+testHttpRequest::testIPv6HostColonBug()
+{
+    ushort expected_port;
+    char * url = NULL;
+    HttpRequest *aRequest = NULL;
+
+    /* valid IPv6 address without port */
+    url = xstrdup("http://[2000:800::45]/foo");
+    aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_GET);
+    expected_port = 80;
+    CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
+    CPPUNIT_ASSERT_EQUAL(METHOD_GET, aRequest->method);
+    CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest->GetHost()));
+    CPPUNIT_ASSERT_EQUAL(String("/foo"), aRequest->urlpath);
+    CPPUNIT_ASSERT_EQUAL(PROTO_HTTP, aRequest->protocol);
+    CPPUNIT_ASSERT_EQUAL(String("http://[2000:800::45]/foo"), String(url));
+    xfree(url);
+
+    /* valid IPv6 address with port */
+    url = xstrdup("http://[2000:800::45]:90/foo");
+    aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_GET);
+    expected_port = 90;
+    CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
+    CPPUNIT_ASSERT_EQUAL(METHOD_GET, aRequest->method);
+    CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest->GetHost()));
+    CPPUNIT_ASSERT_EQUAL(String("/foo"), aRequest->urlpath);
+    CPPUNIT_ASSERT_EQUAL(PROTO_HTTP, aRequest->protocol);
+    CPPUNIT_ASSERT_EQUAL(String("http://[2000:800::45]:90/foo"), String(url));
+    xfree(url);
+
+    /* IPv6 address as invalid (bug trigger) */
+    url = xstrdup("http://2000:800::45/foo");
+    aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_GET);
+    expected_port = 80;
+    CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
+    CPPUNIT_ASSERT_EQUAL(METHOD_GET, aRequest->method);
+#if USE_IPV6
+      /* We hasve fixed this in IPv6 build. */
+    CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest->GetHost()));
+#else
+      /* NO fix is possible in IPv4-pure build. */
+    CPPUNIT_ASSERT_EQUAL(String("2000:800::45"), String(aRequest->GetHost()));
+#endif
+    CPPUNIT_ASSERT_EQUAL(String("/foo"), aRequest->urlpath);
+    CPPUNIT_ASSERT_EQUAL(PROTO_HTTP, aRequest->protocol);
+    CPPUNIT_ASSERT_EQUAL(String("http://2000:800::45/foo"), String(url));
+    xfree(url);
+}
index e81c73a7d889c3825810355f33917949bb3d89a5..9e0735f34fdff99a1045d1b1ad680a76de9b0284 100644 (file)
@@ -13,6 +13,7 @@ class testHttpRequest : public CPPUNIT_NS::TestFixture
     CPPUNIT_TEST_SUITE( testHttpRequest );
     CPPUNIT_TEST( testCreateFromUrlAndMethod );
     CPPUNIT_TEST( testCreateFromUrl );
+    CPPUNIT_TEST( testIPv6HostColonBug );
     CPPUNIT_TEST_SUITE_END();
 
 public:
@@ -21,6 +22,7 @@ public:
 protected:
     void testCreateFromUrlAndMethod();
     void testCreateFromUrl();
+    void testIPv6HostColonBug();
 };
 
 #endif
diff --git a/src/tests/testICMP.cc b/src/tests/testICMP.cc
new file mode 100644 (file)
index 0000000..5d223c6
--- /dev/null
@@ -0,0 +1,84 @@
+
+#define SQUID_HELPER 1
+#include "squid.h"
+
+#include <cppunit/TestAssert.h>
+
+#include "testICMP.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION( testICMP );
+
+#if USE_ICMP
+
+void
+testICMP::testChecksum()
+{
+    stubICMP icmp;
+    short unsigned int buf[10] = {1,2,3,4,5,6,7,8,9};
+
+    // NULL data
+    CPPUNIT_ASSERT_EQUAL(65535, icmp.testChecksum(NULL,0));
+
+    // NULL data with length!!
+    CPPUNIT_ASSERT_EQUAL(65535, icmp.testChecksum(NULL,1));
+
+    // data with 0 length
+    CPPUNIT_ASSERT_EQUAL(65535, icmp.testChecksum(buf,0));
+
+    // data with invalid length (low)
+    CPPUNIT_ASSERT_EQUAL(65534, icmp.testChecksum(buf,1));
+
+    // data with invalid length (max-low)
+    CPPUNIT_ASSERT_EQUAL(65520, icmp.testChecksum(buf,9));
+
+    // data with accurate length
+    CPPUNIT_ASSERT_EQUAL(65520, icmp.testChecksum(buf,10));
+
+    // data with invalid length (overrun)
+    CPPUNIT_ASSERT_EQUAL(65514, icmp.testChecksum(buf,11));
+}
+
+void
+testICMP::testHops()
+{
+    stubICMP icmp;
+
+    /* test invalid -(under values) */
+    // negative     : n > 33
+    CPPUNIT_ASSERT_EQUAL(34, icmp.testHops(-1));
+    // zero
+    CPPUNIT_ASSERT_EQUAL(33, icmp.testHops(0));
+
+        /* test each valid case boundary */
+    // n(1...32)    : 32 >= n >= 1
+    CPPUNIT_ASSERT_EQUAL(32, icmp.testHops(1));
+    CPPUNIT_ASSERT_EQUAL(1, icmp.testHops(32));
+
+    // n(33...62)   : 30 >= n >= 1
+    CPPUNIT_ASSERT_EQUAL(30, icmp.testHops(33));
+    CPPUNIT_ASSERT_EQUAL(1, icmp.testHops(62));
+
+    // n(63...64)  : 2 >= n >= 1
+    CPPUNIT_ASSERT_EQUAL(2, icmp.testHops(63));
+    CPPUNIT_ASSERT_EQUAL(1, icmp.testHops(64));
+
+    // n(65...128)  : 64 >= n >= 1
+    CPPUNIT_ASSERT_EQUAL(64, icmp.testHops(65));
+    CPPUNIT_ASSERT_EQUAL(1, icmp.testHops(128));
+
+    // n(129...192) : 64 >= n >= 1
+    CPPUNIT_ASSERT_EQUAL(64, icmp.testHops(129));
+    CPPUNIT_ASSERT_EQUAL(1, icmp.testHops(192));
+
+    // n(193...)    : n < 63
+    CPPUNIT_ASSERT_EQUAL(63, icmp.testHops(193));
+    CPPUNIT_ASSERT_EQUAL(1, icmp.testHops(255));
+
+        /* test invalid (over values) */
+    // 256 - produces zero
+    CPPUNIT_ASSERT_EQUAL(0, icmp.testHops(256));
+    // 257 - produces negative hops
+    CPPUNIT_ASSERT_EQUAL(-1, icmp.testHops(257));
+}
+
+#endif /* USE_ICMP */
diff --git a/src/tests/testICMP.h b/src/tests/testICMP.h
new file mode 100644 (file)
index 0000000..da50d67
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef SQUID_SRC_TEST_URL_H
+#define SQUID_SRC_TEST_URL_H
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "ICMP.h"
+
+#if USE_ICMP
+
+class stubICMP : public ICMP
+{
+public:
+    stubICMP() {};
+    virtual ~stubICMP() {};
+    virtual int Open() { return 0; };
+    virtual void Close() {};
+
+    /// Construct ECHO request
+    virtual void SendEcho(IPAddress &to, int opcode, const char *payload, int len) {};
+
+    /// Handle ICMP responses.
+    virtual void Recv(void) {};
+
+/* methods to relay test data from tester to private methods being tested */
+    int testChecksum(unsigned short *ptr, int size) { return CheckSum(ptr,size); };
+    int testHops(int ttl) { return ipHops(ttl); };
+};
+
+#endif /* USE_ICMP */
+
+/**
+ * test the ICMP base class.
+ */
+class testICMP : public CPPUNIT_NS::TestFixture
+{
+    CPPUNIT_TEST_SUITE( testICMP );
+#if USE_ICMP
+    CPPUNIT_TEST( testChecksum );
+    CPPUNIT_TEST( testHops );
+#endif /* USE_ICMP */
+    CPPUNIT_TEST_SUITE_END();
+
+protected:
+#if USE_ICMP
+    void testChecksum();
+    void testHops();
+#endif /* USE_ICMP */
+};
+
+#endif
index 75101b5de0c3fab4f472bd15449632ff812e68de..2b15c5872acd5d65a4e99f49f1d5463df18b7392 100644 (file)
@@ -1,6 +1,5 @@
-
 /*
- * $Id: time.cc,v 1.3 2006/08/12 01:43:11 robertc Exp $
+ * $Id: time.cc,v 1.4 2007/12/14 23:11:48 amosjeffries Exp $
  *
  * DEBUG: section 21    Time Functions
  * AUTHOR: Harvest Derived
@@ -35,6 +34,9 @@
 
 #include "SquidTime.h"
 
+struct timeval current_time;
+double current_dtime;
+
 time_t squid_curtime = 0;
 
 time_t
index 9f890a52c91e694e79f1d729d9fc1e0cac2f06e5..d2eb3260b33f7035a99d4520b783cb16455d93d8 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: tools.cc,v 1.279 2007/09/23 09:18:10 serassio Exp $
+ * $Id: tools.cc,v 1.280 2007/12/14 23:11:48 amosjeffries Exp $
  *
  * DEBUG: section 21    Misc Functions
  * AUTHOR: Harvest Derived
@@ -595,10 +595,8 @@ getMyHostname(void)
 {
     LOCAL_ARRAY(char, host, SQUIDHOSTNAMELEN + 1);
     static int present = 0;
-
-    const struct hostent *h = NULL;
-
-    struct IN_ADDR sa;
+    struct addrinfo *AI = NULL;
+    IPAddress sa;
 
     if (Config.visibleHostname != NULL)
         return Config.visibleHostname;
@@ -608,59 +606,72 @@ getMyHostname(void)
 
     host[0] = '\0';
 
-    memcpy(&sa, &any_addr, sizeof(sa));
-
-    if (Config.Sockaddr.http && sa.s_addr == any_addr.s_addr)
-        memcpy(&sa, &Config.Sockaddr.http->s.sin_addr, sizeof(sa));
+    if (Config.Sockaddr.http && sa.IsAnyAddr())
+        sa = Config.Sockaddr.http->s;
 
 #if USE_SSL
 
-    if (Config.Sockaddr.https && sa.s_addr == any_addr.s_addr)
-        memcpy(&sa, &Config.Sockaddr.https->http.s.sin_addr, sizeof(sa));
+    if (Config.Sockaddr.https && sa.IsAnyAddr())
+        sa = Config.Sockaddr.https->http.s;
 
 #endif
+
     /*
      * If the first http_port address has a specific address, try a
      * reverse DNS lookup on it.
      */
-    if (sa.s_addr != any_addr.s_addr) {
-        h = gethostbyaddr((char *) &sa,
-                          sizeof(sa), AF_INET);
+    if( !sa.IsAnyAddr() ) {
 
-        if (h != NULL) {
+        sa.GetAddrInfo(AI);
+        /* we are looking for a name. */
+        if(xgetnameinfo(AI->ai_addr, AI->ai_addrlen, host, SQUIDHOSTNAMELEN, NULL, 0, NI_NAMEREQD ) == 0) {
             /* DNS lookup successful */
             /* use the official name from DNS lookup */
-            xstrncpy(host, h->h_name, SQUIDHOSTNAMELEN);
-            debugs(50, 4, "getMyHostname: resolved " << inet_ntoa(sa) << " to '" << host << "'");
+            debugs(50, 4, "getMyHostname: resolved " << sa << " to '" << host << "'");
 
             present = 1;
 
+            sa.FreeAddrInfo(AI);
+
             if (strchr(host, '.'))
                 return host;
-
         }
 
-        debugs(50, 1, "WARNING: failed to resolve " << inet_ntoa(sa) << " to a fully qualified hostname");
+        sa.FreeAddrInfo(AI);
+        debugs(50, 1, "WARNING: failed to resolve " << sa << " to a fully qualified hostname");
     }
+    else {
+        if (gethostname(host, SQUIDHOSTNAMELEN) < 0) {
+            debugs(50, 1, "WARNING: gethostname failed: " << xstrerror());
+        }
+        else {
+            /* Verify that the hostname given resolves properly */
+            struct addrinfo hints;
+            memset(&hints, 0, sizeof(addrinfo));
+            hints.ai_flags = AI_CANONNAME;
+
+            if(xgetaddrinfo(host, NULL, NULL, &AI) == 0) {
+                /* DNS lookup successful */
+                /* use the official name from DNS lookup */
+                debugs(50, 6, "getMyHostname: '" << host << "' resolved into '" << AI->ai_canonname << "'");
+                xstrncpy(host, AI->ai_canonname, SQUIDHOSTNAMELEN);
+                present = 1;
+
+                /* AYJ: do we want to flag AI_ALL and cache the result anywhere. ie as our local host IPs? */
+                if(AI) {
+                    xfreeaddrinfo(AI);
+                    AI = NULL;
+                }
 
-    /*
-     * Get the host name and store it in host to return
-     */
-    if (gethostname(host, SQUIDHOSTNAMELEN) < 0) {
-        debugs(50, 1, "WARNING: gethostname failed: " << xstrerror());
-    } else if ((h = gethostbyname(host)) == NULL) {
-        debugs(50, 1, "WARNING: gethostbyname failed for " << host);
-    } else {
-        debugs(50, 6, "getMyHostname: '" << host << "' resolved into '" << h->h_name << "'");
-        /* DNS lookup successful */
-        /* use the official name from DNS lookup */
-        xstrncpy(host, h->h_name, SQUIDHOSTNAMELEN);
-        present = 1;
-
-        if (strchr(host, '.'))
-            return host;
+                return host;
+            }
+
+            if(AI) xfreeaddrinfo(AI);
+            debugs(50, 1, "WARNING: getaddrinfo('" << host << "') failed: " << xstrerror());
+        }
     }
 
+    /* throw a fatal configuration error when the Host/IP given has bad DNS/rDNS. */
     if (opt_send_signal == -1)
         fatal("Could not determine fully qualified hostname.  Please set 'visible_hostname'\n");
     else
@@ -1019,16 +1030,6 @@ squid_signal(int sig, SIGHDLR * func, int flags)
 #endif
 }
 
-struct IN_ADDR
-
-            inaddrFromHostent(const struct hostent *hp)
-{
-
-    struct IN_ADDR s;
-    xmemcpy(&s.s_addr, hp->h_addr, sizeof(s.s_addr));
-    return s;
-}
-
 double
 doubleAverage(double cur, double newD, int N, int max)
 {
@@ -1258,12 +1259,12 @@ int
 getMyPort(void)
 {
     if (Config.Sockaddr.http)
-        return ntohs(Config.Sockaddr.http->s.sin_port);
+        return Config.Sockaddr.http->s.GetPort();
 
 #if USE_SSL
 
     if (Config.Sockaddr.https)
-        return ntohs(Config.Sockaddr.https->http.s.sin_port);
+        return Config.Sockaddr.https->http.s.GetPort();
 
 #endif
 
@@ -1400,3 +1401,13 @@ nocap:
 
 #endif
 }
+
+void *
+xmemset(void *dst, int val, size_t sz)
+{
+    // do debugs output
+    debugs(63, 9, "memset: dst=" << dst << ", val=" << val << ", bytes=" << sz);
+
+    // call the system one to do the actual work ~safely.
+    return memset(dst, val, sz);
+}
index da4fdcb6d82d47cc51937b13e20b4193b1e04d4e..ed3a1a7582f0a25ef5dd539c1552913701c890c7 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: tunnel.cc,v 1.175 2007/10/16 14:38:18 rousskov Exp $
+ * $Id: tunnel.cc,v 1.176 2007/12/14 23:11:48 amosjeffries Exp $
  *
  * DEBUG: section 26    Secure Sockets Layer Proxy
  * AUTHOR: Duane Wessels
@@ -604,19 +604,18 @@ tunnelStart(ClientHttpRequest * http, int64_t * size_ptr, int *status_ptr)
     HttpRequest *request = http->request;
     char *url = http->uri;
     /*
-     * client_addr == no_addr indicates this is an "internal" request
+     * client_addr.IsNoAddr()  indicates this is an "internal" request
      * from peer_digest.c, asn.c, netdb.c, etc and should always
      * be allowed.  yuck, I know.
      */
 
-    if (request->client_addr.s_addr != no_addr.s_addr) {
+    if (!request->client_addr.IsNoAddr()) {
         /*
          * Check if this host is allowed to fetch MISSES from us (miss_access)
          */
         ACLChecklist ch;
         ch.src_addr = request->client_addr;
         ch.my_addr = request->my_addr;
-        ch.my_port = request->my_port;
         ch.request = HTTPMSGLOCK(request);
         ch.accessList = cbdataReference(Config.accessList.miss);
         /* cbdataReferenceDone() happens in either fastCheck() or ~ACLCheckList */
@@ -634,10 +633,10 @@ tunnelStart(ClientHttpRequest * http, int64_t * size_ptr, int *status_ptr)
     statCounter.server.all.requests++;
     statCounter.server.other.requests++;
     /* Create socket. */
+    IPAddress temp = getOutgoingAddr(request);
     sock = comm_openex(SOCK_STREAM,
                        IPPROTO_TCP,
-                       getOutgoingAddr(request),
-                       0,
+                       temp,
                        COMM_NONBLOCKING,
                        getOutgoingTOS(request),
                        url);
@@ -734,7 +733,7 @@ tunnelPeerSelectComplete(FwdServer * fs, void *data)
     }
 
     tunnelState->servers = fs;
-    tunnelState->host = fs->_peer ? fs->_peer->host : request->host;
+    tunnelState->host = fs->_peer ? fs->_peer->host : xstrdup(request->GetHost());
 
     if (fs->_peer == NULL) {
         tunnelState->port = request->port;
index 2246ba0ba6071b22b013653e8a5362dd340e6e75..82c11b6356da0eee558434bcb80da73b6be12737 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: typedefs.h,v 1.190 2007/05/09 07:45:58 wessels Exp $
+ * $Id: typedefs.h,v 1.191 2007/12/14 23:11:48 amosjeffries Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -84,8 +84,6 @@ typedef struct _ushortlist ushortlist;
 
 typedef struct _relist relist;
 
-typedef struct _sockaddr_in_list sockaddr_in_list;
-
 typedef struct _http_port_list http_port_list;
 
 typedef struct _https_port_list https_port_list;
@@ -148,10 +146,6 @@ typedef struct _net_db_peer net_db_peer;
 
 typedef struct _netdbEntry netdbEntry;
 
-typedef struct _pingerEchoData pingerEchoData;
-
-typedef struct _pingerReplyData pingerReplyData;
-
 typedef struct _icp_common_t icp_common_t;
 
 typedef struct _Meta_data Meta_data;
index 3f8f5e18a05277fea3afea038872669705ae0604..61e26baaf45493142171f3c095f6e7bfa2638210 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: unlinkd.cc,v 1.64 2007/04/30 16:56:09 wessels Exp $
+ * $Id: unlinkd.cc,v 1.65 2007/12/14 23:11:48 amosjeffries Exp $
  *
  * DEBUG: section 2     Unlink Daemon
  * AUTHOR: Duane Wessels
@@ -194,9 +194,12 @@ void
 unlinkdInit(void)
 {
     const char *args[2];
+    IPAddress localhost;
 
     args[0] = "(unlinkd)";
     args[1] = NULL;
+    localhost.SetLocalhost();
+
     pid = ipcCreate(
 #if USE_POLL && defined(_SQUID_OSF_)
               /* pipes and poll() don't get along on DUNIX -DW */
@@ -211,6 +214,7 @@ IPC_FIFO,
               Config.Program.unlinkd,
               args,
               "unlinkd",
+              localhost,
               &unlinkd_rfd,
               &unlinkd_wfd,
               &hIpc);
index af21d6dd3d2cf10aff369118177e051cbb8223b1..c747eeed8beafd26a4072e754dd6eb2abdcab07b 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: url.cc,v 1.162 2007/05/29 13:31:41 amosjeffries Exp $
+ * $Id: url.cc,v 1.163 2007/12/14 23:11:48 amosjeffries Exp $
  *
  * DEBUG: section 23    URL Parsing
  * AUTHOR: Duane Wessels
@@ -42,11 +42,17 @@ static const char valid_hostname_chars_u[] =
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     "abcdefghijklmnopqrstuvwxyz"
     "0123456789-._"
+#if USE_IPV6
+    "[:]"
+#endif
     ;
 static const char valid_hostname_chars[] =
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     "abcdefghijklmnopqrstuvwxyz"
     "0123456789-."
+#if USE_IPV6
+    "[:]"
+#endif
     ;
 
 void
@@ -81,7 +87,7 @@ urlInitialize(void)
     /* more cases? */
 }
 
-/*
+/**
  * urlParseProtocol() takes begin (b) and end (e) pointers, but for
  * backwards compatibility, e defaults to NULL, in which case we
  * assume b is NULL-terminated.
@@ -181,6 +187,14 @@ urlDefaultPort(protocol_t p)
  * looked for.
  * The url is non const so that if its too long we can NULL-terminate it in place.
  */
+
+/*
+ * This routine parses a URL. Its assumed that the URL is complete -
+ * ie, the end of the string is the end of the URL. Don't pass a partial
+ * URL here as this routine doesn't have any way of knowing whether
+ * its partial or not (ie, it handles the case of no trailing slash as
+ * being "end of host with implied path of /".
+ */
 HttpRequest *
 urlParse(method_t method, char *url, HttpRequest *request)
 {
@@ -193,6 +207,9 @@ urlParse(method_t method, char *url, HttpRequest *request)
     int port;
     protocol_t protocol = PROTO_NONE;
     int l;
+    int i;
+    const char *src;
+    char *dst;
     proto[0] = host[0] = urlpath[0] = login[0] = '\0';
 
     if ((l = strlen(url)) + Config.appendDomainLen > (MAX_URL - 1)) {
@@ -201,23 +218,67 @@ urlParse(method_t method, char *url, HttpRequest *request)
         debugs(23, 1, "urlParse: URL too large (" << l << " bytes)");
         return NULL;
     }
-
     if (method == METHOD_CONNECT) {
         port = CONNECT_PORT;
 
-        if (sscanf(url, "%[^:]:%d", host, &port) < 1)
-            return NULL;
+        if (sscanf(url, "[%[^:]]:%d", host, &port) < 1)
+            if (sscanf(url, "%[^:]:%d", host, &port) < 1)
+                return NULL;
+
     } else if (!strncmp(url, "urn:", 4)) {
         return urnParse(method, url);
     } else {
-        if (sscanf(url, "%[^:]://%[^/]%[^\r\n]", proto, host, urlpath) < 2)
+        /* Parse the URL: */
+        src = url;
+        i = 0;
+        /* Find first : - everything before is protocol */
+        for (i = 0, dst = proto; i < l && *src != ':'; i++, src++, dst++) {
+            *dst = *src;
+        }
+        if (i >= l)
+           return NULL;
+        *dst = '\0';
+
+        /* Then its :// */
+        /* (XXX yah, I'm not checking we've got enough data left before checking the array..) */
+        if (*src != ':' || *(src + 1) != '/' || *(src + 2) != '/')
             return NULL;
+        i += 3;
+        src += 3;
 
-        protocol = urlParseProtocol(proto);
+        /* Then everything until first /; thats host (and port; which we'll look for here later) */
+        /* bug 1881: If we don't get a "/" then we imply it was there */
+        for (dst = host; i < l && *src != '/' && src != '\0'; i++, src++, dst++) {
+            *dst = *src;
+        }
+
+        /* 
+         * We can't check for "i >= l" here because we could be at the end of the line
+         * and have a perfectly valid URL w/ no trailing '/'. In this case we assume we've
+         * been -given- a valid URL and the path is just '/'.
+         */
+        if (i > l)
+            return NULL;
+        *dst = '\0';
+
+        /* Then everything from / (inclusive) until \r\n or \0 - thats urlpath */
+        for (dst = urlpath; i < l && *src != '\r' && *src != '\n' && *src != '\0'; i++, src++, dst++) {
+            *dst = *src;
+        }
 
+        /* We -could- be at the end of the buffer here */
+        if (i > l)
+            return NULL;
+        /* If the URL path is empty we set it to be "/" */
+        if (dst == urlpath) {
+            *(dst++) = '/';
+        }
+        *dst = '\0';
+
+        protocol = urlParseProtocol(proto);
         port = urlDefaultPort(protocol);
 
-        /* Is there any login informaiton? */
+        /* Is there any login information? (we should eventually parse it above) */
         if ((t = strrchr(host, '@'))) {
             strcpy((char *) login, (char *) host);
             t = strrchr(login, '@');
@@ -225,11 +286,43 @@ urlParse(method_t method, char *url, HttpRequest *request)
             strcpy((char *) host, t + 1);
         }
 
-        if ((t = strrchr(host, ':'))) {
-            *t++ = '\0';
+        /* Is there any host information? (we should eventually parse it above) */
+        if(*host == '[') {
+            /* strip any IPA brackets. valid under IPv6. */
+            dst = host;
+#if USE_IPV6
+            /* only for IPv6 sadly, pre-IPv6/URL code can't handle the clean result properly anyway. */
+            src = host; src++;
+            l = strlen(host);
+            i = 1;
+            for (; i < l && *src != ']' && *src != '\0'; i++, src++, dst++) {
+                *dst = *src;
+            }
+
+            /* we moved in-place, so truncate the actual hostname found */
+            *(dst++) = '\0';
+#else
+            /* IPv4-pure needs to skip the whole hostname to ']' inclusive for now */
+            while(*dst != '\0' && *dst != ']') dst++;
+#endif
+
+            /* skip ahead to either start of port, or original EOS */
+            while(*dst != '\0' && *dst != ':') dst++;
+            t = dst;
+        } else {
+            t = strrchr(host, ':');
+
+            if(t != strchr(host,':') ) {
+                /* RFC 2732 states IPv6 "SHOULD" be bracketed. allowing for times when its not. */
+                /* RFC 3986 'update' simply modifies this to an "is" with no emphasis at all! */
+                /* therefore we MUST accept the case where they are not bracketed at all. */
+                t = NULL;
+            }
+        }
 
-            if (*t != '\0')
-                port = atoi(t);
+        if (t && *t == ':') {
+            *t = '\0'; t++;
+            port = atoi(t);
         }
     }
 
@@ -239,36 +332,34 @@ urlParse(method_t method, char *url, HttpRequest *request)
     if (stringHasWhitespace(host)) {
         if (URI_WHITESPACE_STRIP == Config.uri_whitespace) {
             t = q = host;
-
             while (*t) {
                 if (!xisspace(*t))
                     *q++ = *t;
-
                 t++;
             }
-
             *q = '\0';
         }
     }
 
+    debugs(23, 3, "urlParse: Split URL '" << url << "' into proto='" << proto << "', host='" << host << "', port='" << port << "', path='" << urlpath << "'");
+
     if (Config.onoff.check_hostnames && strspn(host, Config.onoff.allow_underscore ? valid_hostname_chars_u : valid_hostname_chars) != strlen(host)) {
         debugs(23, 1, "urlParse: Illegal character in hostname '" << host << "'");
         return NULL;
     }
 
-#if DONT_DO_THIS_IT_BREAKS_SEMANTIC_TRANSPARENCY
+    if (Config.appendDomain && !strchr(host, '.'))
+        strncat(host, Config.appendDomain, SQUIDHOSTNAMELEN - strlen(host) - 1);
+
     /* remove trailing dots from hostnames */
     while ((l = strlen(host)) > 0 && host[--l] == '.')
         host[l] = '\0';
 
-    /* remove duplicate dots */
-    while ((t = strstr(host, "..")))
-        xmemmove(t, t + 1, strlen(t));
-
-#endif
-
-    if (Config.appendDomain && !strchr(host, '.'))
-        strncat(host, Config.appendDomain, SQUIDHOSTNAMELEN - strlen(host) - 1);
+    /* reject duplicate or leading dots */
+    if (strstr(host, "..") || *host == '.') {
+        debug(23, 1) ("urlParse: Illegal hostname '%s'\n", host);
+        return NULL;
+    }
 
     if (port < 1 || port > 65535) {
         debugs(23, 3, "urlParse: Invalid port '" << port << "'");
@@ -282,8 +373,8 @@ urlParse(method_t method, char *url, HttpRequest *request)
         debugs(23, 0, "urlParse: Deny access to port " << port);
         return NULL;
     }
-
 #endif
+
     if (stringHasWhitespace(urlpath)) {
         debugs(23, 2, "urlParse: URI has whitespace: {" << url << "}");
 
@@ -305,17 +396,13 @@ urlParse(method_t method, char *url, HttpRequest *request)
             break;
 
         case URI_WHITESPACE_STRIP:
-
         default:
             t = q = urlpath;
-
             while (*t) {
                 if (!xisspace(*t))
                     *q++ = *t;
-
                 t++;
             }
-
             *q = '\0';
         }
     }
@@ -326,7 +413,7 @@ urlParse(method_t method, char *url, HttpRequest *request)
         request->initHTTP(method, protocol, urlpath);
     }
 
-    xstrncpy(request->host, host, SQUIDHOSTNAMELEN);
+    request->SetHost(host);
     xstrncpy(request->login, login, MAX_LOGIN_SZ);
     request->port = (u_short) port;
     return request;
@@ -354,7 +441,7 @@ urlCanonical(HttpRequest * request)
         switch (request->method) {
 
         case METHOD_CONNECT:
-            snprintf(urlbuf, MAX_URL, "%s:%d", request->host, request->port);
+            snprintf(urlbuf, MAX_URL, "%s:%d", request->GetHost(), request->port);
             break;
 
         default:
@@ -367,7 +454,7 @@ urlCanonical(HttpRequest * request)
                      ProtocolStr[request->protocol],
                      request->login,
                      *request->login ? "@" : null_string,
-                     request->host,
+                     request->GetHost(),
                      portbuf,
                      request->urlpath.buf());
 
@@ -392,7 +479,9 @@ urlCanonicalClean(const HttpRequest * request)
         switch (request->method) {
 
         case METHOD_CONNECT:
-            snprintf(buf, MAX_URL, "%s:%d", request->host, request->port);
+            snprintf(buf, MAX_URL, "%s:%d", 
+                     request->GetHost(),
+                     request->port);
             break;
 
         default:
@@ -415,7 +504,7 @@ urlCanonicalClean(const HttpRequest * request)
             snprintf(buf, MAX_URL, "%s://%s%s%s%s",
                      ProtocolStr[request->protocol],
                      loginbuf,
-                     request->host,
+                     request->GetHost(),
                      portbuf,
                      request->urlpath.buf());
             /*
@@ -660,6 +749,12 @@ URLHostName::findHostStart()
 
     while (*hostStart != '\0' && *hostStart == '/')
         ++hostStart;
+
+#if USE_IPV6
+    if (*hostStart == ']')
+        ++hostStart;
+#endif
+
 }
 
 void
@@ -670,8 +765,14 @@ URLHostName::trimTrailingChars()
     if ((t = strchr(Host, '/')))
         *t = '\0';
 
-    if ((t = strchr(Host, ':')))
+    if ((t = strrchr(Host, ':')))
         *t = '\0';
+
+#if USE_IPV6
+    if ((t = strchr(Host, ']')))
+        *t = '\0';
+#endif
+
 }
 
 void
index d1d9c34923e43ccddc4e440d46725f862538028d..d8db3baf491f9b718e501bedccc7929526410ccb 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: urn.cc,v 1.107 2007/05/29 13:31:41 amosjeffries Exp $
+ * $Id: urn.cc,v 1.108 2007/12/14 23:11:48 amosjeffries Exp $
  *
  * DEBUG: section 52    URN Parsing
  * AUTHOR: Kostas Anagnostakis
@@ -179,6 +179,9 @@ UrnState::getHost (String &urlpath)
     char * result;
     char const *t;
 
+/* FIXME: this appears to be parsing the URL. *very* badly. */
+/* FIXME: a proper encapsulated URI/URL type needs to clear this up. */
+
     if ((t = urlpath.pos(':')) != NULL) {
         urlpath.set(t, '\0');
         result = xstrdup(urlpath.buf());
index 4c87569412bb7f60792ca5da1dc19f52f2245f0a..c99e9f7440a94f329255d2496f3b778c0b1e22fb 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: wccp.cc,v 1.44 2007/08/08 14:47:41 rousskov Exp $
+ * $Id: wccp.cc,v 1.45 2007/12/14 23:11:48 amosjeffries Exp $
  *
  * DEBUG: section 80    WCCP Support
  * AUTHOR: Glenn Chisholm
@@ -61,8 +61,7 @@ struct wccp_here_i_am_t
 
 struct wccp_cache_entry_t
 {
-
-    struct IN_ADDR ip_addr;
+    IPAddress ip_addr;
     int revision;
     char hash[WCCP_HASH_SIZE];
     int reserved;
@@ -96,7 +95,7 @@ static int last_id;
 static int last_assign_buckets_change;
 static unsigned int number_caches;
 
-static struct IN_ADDR local_ip;
+static IPAddress local_ip;
 
 static PF wccpHandleUdp;
 static int wccpLowestIP(void);
@@ -124,7 +123,7 @@ wccpInit(void)
     last_assign_buckets_change = 0;
     number_caches = 0;
 
-    if (Config.Wccp.router.s_addr != any_addr.s_addr)
+    if (!Config.Wccp.router.IsAnyAddr())
         if (!eventFind(wccpHereIam, NULL))
             eventAdd("wccpHereIam", wccpHereIam, NULL, 5.0, 1);
 }
@@ -132,21 +131,29 @@ wccpInit(void)
 void
 wccpConnectionOpen(void)
 {
-    u_short port = WCCP_PORT;
-
-    struct sockaddr_in router, local;
-    socklen_t local_len, router_len;
+    struct addrinfo *router = NULL, *local = NULL;
     debugs(80, 5, "wccpConnectionOpen: Called");
 
-    if (Config.Wccp.router.s_addr == any_addr.s_addr) {
+    if (Config.Wccp.router.IsAnyAddr()) {
         debugs(80, 2, "WCCPv1 disabled.");
         return;
     }
 
+    if ( !Config.Wccp.router.SetIPv4() ) {
+        debugs(1, 1, "WCCPv1 Disabled. Router " << Config.Wccp.router << " is not IPv4.");
+        return;
+    }
+
+    if ( !Config.Wccp.address.SetIPv4() ) {
+        debugs(1, 1, "WCCPv1 Disabled. Local address " << Config.Wccp.address << " is not IPv4.");
+        return;
+    }
+
+    Config.Wccp.address.SetPort(WCCP_PORT);
+
     theWccpConnection = comm_open(SOCK_DGRAM,
                                   IPPROTO_UDP,
                                   Config.Wccp.address,
-                                  port,
                                   COMM_NONBLOCKING,
                                   "WCCP Socket");
 
@@ -159,30 +166,23 @@ wccpConnectionOpen(void)
                   NULL,
                   0);
 
-    debugs(80, 1, "Accepting WCCPv1 messages on port " << port << ", FD " << theWccpConnection << ".");
-
-
-    router_len = sizeof(router);
-
-    memset(&router, '\0', router_len);
+    debugs(80, 1, "Accepting WCCPv1 messages on " << Config.Wccp.address << ", FD " << theWccpConnection << ".");
 
-    router.sin_family = AF_INET;
+    Config.Wccp.router.GetAddrInfo(router,AF_INET);
 
-    router.sin_port = htons(port);
-
-    router.sin_addr = Config.Wccp.router;
-
-    if (connect(theWccpConnection, (struct sockaddr *) &router, router_len))
+    if (connect(theWccpConnection, router->ai_addr, router->ai_addrlen))
         fatal("Unable to connect WCCP out socket");
 
-    local_len = sizeof(local);
+    Config.Wccp.router.FreeAddrInfo(router);
 
-    memset(&local, '\0', local_len);
+    Config.Wccp.address.InitAddrInfo(local);
 
-    if (getsockname(theWccpConnection, (struct sockaddr *) &local, &local_len))
+    if (getsockname(theWccpConnection, local->ai_addr, &local->ai_addrlen))
         fatal("Unable to getsockname on WCCP out socket");
 
-    local_ip.s_addr = local.sin_addr.s_addr;
+    local_ip = *local;
+
+    Config.Wccp.address.FreeAddrInfo(local);
 }
 
 
@@ -207,27 +207,22 @@ static void
 wccpHandleUdp(int sock, void *not_used)
 {
 
-    struct sockaddr_in from;
-    socklen_t from_len;
+    IPAddress from;
     int len;
 
     debugs(80, 6, "wccpHandleUdp: Called.");
 
     commSetSelect(sock, COMM_SELECT_READ, wccpHandleUdp, NULL, 0);
 
-    from_len = sizeof(struct sockaddr_in);
-    memset(&from, '\0', from_len);
     memset(&wccp_i_see_you, '\0', sizeof(wccp_i_see_you));
 
     len = comm_udp_recvfrom(sock,
                             (void *) &wccp_i_see_you,
                             sizeof(wccp_i_see_you),
                             0,
-
-                            (struct sockaddr *) &from,
-                            &from_len);
-    debugs(80, 3, "wccpHandleUdp: " << len << " bytes WCCP pkt from " <<
-           inet_ntoa(from.sin_addr) << ": type=" <<
+                            from);
+    debugs(80, 3, "wccpHandleUdp: " << len << " bytes WCCP pkt from " << from <<
+            ": type=" <<
            (unsigned) ntohl(wccp_i_see_you.type) << ", version=" <<
            (unsigned) ntohl(wccp_i_see_you.version) << ", change=" <<
            (unsigned) ntohl(wccp_i_see_you.change) << ", id=" <<
@@ -237,7 +232,7 @@ wccpHandleUdp(int sock, void *not_used)
     if (len < 0)
         return;
 
-    if (Config.Wccp.router.s_addr != from.sin_addr.s_addr)
+    if (from != Config.Wccp.router)
         return;
 
     if ((unsigned) ntohl(wccp_i_see_you.version) != (unsigned) Config.Wccp.version)
@@ -248,7 +243,7 @@ wccpHandleUdp(int sock, void *not_used)
 
     if (ntohl(wccp_i_see_you.number) > WCCP_ACTIVE_CACHES) {
         debugs(80, 1, "Ignoring WCCP_I_SEE_YOU from " <<
-               inet_ntoa(from.sin_addr) << " with number of caches set to " <<
+               from << " with number of caches set to " <<
                (int) ntohl(wccp_i_see_you.number));
 
         return;
@@ -296,10 +291,10 @@ wccpLowestIP(void)
     for (loop = 0; loop < (unsigned) ntohl(wccp_i_see_you.number); loop++) {
         assert(loop < WCCP_ACTIVE_CACHES);
 
-        if (wccp_i_see_you.wccp_cache_entry[loop].ip_addr.s_addr < local_ip.s_addr)
+        if (wccp_i_see_you.wccp_cache_entry[loop].ip_addr < local_ip)
             return 0;
 
-        if (wccp_i_see_you.wccp_cache_entry[loop].ip_addr.s_addr == local_ip.s_addr)
+        if (wccp_i_see_you.wccp_cache_entry[loop].ip_addr == local_ip)
             found = 1;
     }
 
@@ -364,7 +359,7 @@ wccpAssignBuckets(void)
     for (loop = 0; loop < number_caches; loop++) {
         int i;
         xmemcpy(&caches[loop],
-                &wccp_i_see_you.wccp_cache_entry[loop].ip_addr.s_addr,
+                &wccp_i_see_you.wccp_cache_entry[loop].ip_addr,
                 sizeof(*caches));
 
         for (i = 0; i < buckets_per_cache; i++) {
index 98e214195b7cdd1a05f777d947323489f037f7eb..f579d910ad74b59971b80174126908e6882b7ddf 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: wccp2.cc,v 1.19 2007/11/15 16:47:35 wessels Exp $
+ * $Id: wccp2.cc,v 1.20 2007/12/14 23:11:48 amosjeffries Exp $
  *
  * DEBUG: section 80    WCCP Support
  * AUTHOR: Steven Wilton
@@ -39,6 +39,7 @@
 #include "Parsing.h"
 #include "Store.h"
 #include "SwapDir.h"
+#include "IPAddress.h"
 
 #if USE_WCCPv2
 #include <netdb.h>
@@ -127,6 +128,7 @@ static EVH wccp2AssignBuckets;
 
 /* WCCP v2 packet header */
 
+/// \interface WCCPv2 Protocol
 struct wccp2_here_i_am_header_t
 {
     uint32_t type;
@@ -145,6 +147,7 @@ struct wccp2_security_none_t
     uint32_t security_option;
 };
 
+/// \interface WCCPv2 Protocol
 struct wccp2_security_md5_t
 {
     uint16_t security_type;
@@ -155,6 +158,7 @@ struct wccp2_security_md5_t
 
 /* Service info struct */
 
+/// \interface WCCPv2 Protocol
 struct wccp2_service_info_t
 {
     uint16_t service_type;
@@ -174,10 +178,10 @@ struct wccp2_service_info_t
     uint16_t port7;
 };
 
+/// \interface WCCPv2 Protocol
 struct wccp2_cache_identity_info_t
 {
-
-    struct IN_ADDR addr;
+    struct in_addr addr;
     uint16_t hash_revision;
     char bits[2];
     char buckets[32];
@@ -187,6 +191,7 @@ struct wccp2_cache_identity_info_t
 
 /* Web Cache identity info */
 
+/// \interface WCCPv2 Protocol
 struct wccp2_identity_info_t
 {
     uint16_t cache_identity_type;
@@ -197,10 +202,10 @@ struct wccp2_identity_info_t
 
 static struct wccp2_identity_info_t wccp2_identity_info;
 
+/// \interface WCCPv2 Protocol
 struct wccp2_cache_mask_identity_info_t
 {
-
-    struct IN_ADDR addr;
+    struct in_addr addr;
     uint32_t num1;
     uint32_t num2;
     uint32_t source_ip_mask;
@@ -213,6 +218,7 @@ struct wccp2_cache_mask_identity_info_t
 
 /* Web Cache identity info */
 
+/// \interface WCCPv2 Protocol
 struct wccp2_mask_identity_info_t
 {
     uint16_t cache_identity_type;
@@ -225,6 +231,7 @@ static struct wccp2_mask_identity_info_t wccp2_mask_identity_info;
 
 /* View header */
 
+/// \interface WCCPv2 Protocol
 struct wccp2_cache_view_header_t
 {
     uint16_t cache_view_type;
@@ -236,6 +243,7 @@ static struct wccp2_cache_view_header_t wccp2_cache_view_header;
 
 /* View info */
 
+/// \interface WCCPv2 Protocol
 struct wccp2_cache_view_info_t
 {
     uint32_t num_routers;
@@ -246,10 +254,10 @@ static struct wccp2_cache_view_info_t wccp2_cache_view_info;
 
 /* Router ID element */
 
+/// \interface WCCPv2 Protocol
 struct wccp2_router_id_element_t
 {
-
-    struct IN_ADDR router_address;
+    struct in_addr router_address;
     uint32_t received_id;
 };
 
@@ -257,6 +265,7 @@ static struct wccp2_router_id_element_t wccp2_router_id_element;
 
 /* Capability info header */
 
+/// \interface WCCpv2 Protocol
 struct wccp2_capability_info_header_t
 {
     uint16_t capability_info_type;
@@ -267,6 +276,7 @@ static struct wccp2_capability_info_header_t wccp2_capability_info_header;
 
 /* Capability element header */
 
+/// \interface WCCPv2 Protocol
 struct wccp2_capability_element_header_t
 {
     uint16_t capability_type;
@@ -275,6 +285,7 @@ struct wccp2_capability_element_header_t
 
 /* Capability element */
 
+/// \interface WCCPv2 Protocol
 struct wccp2_capability_element_t
 {
     uint16_t capability_type;
@@ -286,6 +297,7 @@ static struct wccp2_capability_element_t wccp2_capability_element;
 
 /* Mask Element */
 
+/// \interface WCCPv2 Protocol
 struct wccp2_mask_element_t
 {
     uint32_t source_ip_mask;
@@ -297,6 +309,7 @@ struct wccp2_mask_element_t
 
 /* Value Element */
 
+/// \interface WCCPv2 Protocol
 struct wccp2_value_element_t
 {
     uint32_t source_ip_value;
@@ -304,11 +317,12 @@ struct wccp2_value_element_t
     uint16_t source_port_value;
     uint16_t dest_port_value;
 
-    struct IN_ADDR cache_ip;
+    struct in_addr cache_ip;
 };
 
 /* RECEIVED PACKET STRUCTURE */
 
+/// \interface WCCPv2 Protocol
 struct wccp2_i_see_you_t
 {
     uint32_t type;
@@ -321,16 +335,17 @@ static struct wccp2_i_see_you_t wccp2_i_see_you;
 
 /* Router ID element */
 
+/// \interface WCCPv2 Protocol
 struct wccp2_router_assign_element_t
 {
-
-    struct IN_ADDR router_address;
+    struct in_addr router_address;
     uint32_t received_id;
     uint32_t change_number;
 };
 
 /* Generic header struct */
 
+/// \interface WCCPv2 Protocol
 struct wccp2_item_header_t
 {
     uint16_t type;
@@ -339,6 +354,7 @@ struct wccp2_item_header_t
 
 /* Router identity struct */
 
+/// \interface WCCPv2 Protocol
 struct router_identity_info_t
 {
 
@@ -352,10 +368,10 @@ struct router_identity_info_t
 
 /* The received packet for a mask assignment is unusual */
 
+/// \interface WCCPv2 Protocol
 struct cache_mask_info_t
 {
-
-    struct IN_ADDR addr;
+    struct in_addr addr;
     uint32_t num1;
     uint32_t num2;
     uint32_t num3;
@@ -363,15 +379,16 @@ struct cache_mask_info_t
 
 /* assigment key */
 
+/// \interface WCCPv2 Protocol
 struct assignment_key_t
 {
-
-    struct IN_ADDR master_ip;
+    struct in_addr master_ip;
     uint32_t master_number;
 };
 
 /* Router view of WCCP */
 
+/// \interface WCCPv2 Protocol
 struct router_view_t
 {
 
@@ -383,24 +400,26 @@ struct router_view_t
 
 /* Lists used to keep track of caches, routers and services */
 
+/// \interface WCCPv2 Protocol
 struct wccp2_cache_list_t
 {
 
-    struct IN_ADDR cache_ip;
+    struct in_addr cache_ip;
 
     int weight;
 
     struct wccp2_cache_list_t *next;
 };
 
+/// \interface WCCPv2 Protocol
 struct wccp2_router_list_t
 {
 
     struct wccp2_router_id_element_t *info;
 
-    struct IN_ADDR local_ip;
+    struct in_addr local_ip;
 
-    struct IN_ADDR router_sendto_address;
+    struct in_addr router_sendto_address;
     uint32_t member_change;
     uint32_t num_caches;
 
@@ -411,6 +430,7 @@ struct wccp2_router_list_t
 
 static int wccp2_numrouters;
 
+/// \interface WCCPv2 Protocol
 struct wccp2_service_list_t
 {
 
@@ -638,7 +658,7 @@ wccp2_check_security(struct wccp2_service_list_t *srv, char *security, char *pac
 void
 wccp2Init(void)
 {
-    sockaddr_in_list *s;
+    IPAddress_list *s;
     char *ptr;
     uint32_t service_flags;
 
@@ -657,7 +677,7 @@ wccp2Init(void)
 
     /* Calculate the number of routers configured in the config file */
     for (s = Config.Wccp2.router; s; s = s->next) {
-        if (s->s.sin_addr.s_addr != any_addr.s_addr) {
+        if (!s->s.IsAnyAddr()) {
             /* Increment the counter */
             wccp2_numrouters++;
         }
@@ -736,7 +756,7 @@ wccp2Init(void)
             assert(wccp2_here_i_am_header.length <= WCCP_RESPONSE_SIZE);
             wccp2_identity_info.cache_identity_type = htons(WCCP2_WC_ID_INFO);
             wccp2_identity_info.cache_identity_length = htons(sizeof(wccp2_identity_info.cache_identity));
-            memset(&wccp2_identity_info.cache_identity.addr, '\0', sizeof(wccp2_identity_info.cache_identity.addr));
+            memset(&wccp2_identity_info.cache_identity.addr, '\0', sizeof(struct in_addr));
             memset(&wccp2_identity_info.cache_identity.hash_revision, '\0', sizeof(wccp2_identity_info.cache_identity.hash_revision));
             memset(&wccp2_identity_info.cache_identity.bits, '\0', sizeof(wccp2_identity_info.cache_identity.bits));
             memset(&wccp2_identity_info.cache_identity.buckets, '\0', sizeof(wccp2_identity_info.cache_identity.buckets));
@@ -755,7 +775,7 @@ wccp2Init(void)
             assert(wccp2_here_i_am_header.length <= WCCP_RESPONSE_SIZE);
             wccp2_mask_identity_info.cache_identity_type = htons(WCCP2_WC_ID_INFO);
             wccp2_mask_identity_info.cache_identity_length = htons(sizeof(wccp2_mask_identity_info.cache_identity));
-            memset(&wccp2_mask_identity_info.cache_identity.addr, '\0', sizeof(wccp2_mask_identity_info.cache_identity.addr));
+            memset(&wccp2_mask_identity_info.cache_identity.addr, '\0', sizeof(struct in_addr));
             wccp2_mask_identity_info.cache_identity.num1 = htonl(2);
             wccp2_mask_identity_info.cache_identity.num2 = htonl(1);
             service_flags = ntohl(service_list_ptr->service_info->service_flags);
@@ -826,7 +846,7 @@ wccp2Init(void)
 
         /* Add each router.  Keep this functionality here to make sure the received_id can be updated in the packet */
         for (s = Config.Wccp2.router; s; s = s->next) {
-            if (s->s.sin_addr.s_addr != any_addr.s_addr) {
+            if (!s->s.IsAnyAddr()) {
 
                 wccp2_here_i_am_header.length += sizeof(struct wccp2_router_id_element_t);
                 assert(wccp2_here_i_am_header.length <= WCCP_RESPONSE_SIZE);
@@ -834,9 +854,9 @@ wccp2Init(void)
                 /* Add a pointer to the router list for this router */
 
                 router_list_ptr->info = (struct wccp2_router_id_element_t *) ptr;
-                router_list_ptr->info->router_address = s->s.sin_addr;
+                s->s.GetInAddr(router_list_ptr->info->router_address);
                 router_list_ptr->info->received_id = htonl(0);
-                router_list_ptr->router_sendto_address = s->s.sin_addr;
+                s->s.GetInAddr(router_list_ptr->router_sendto_address);
                 router_list_ptr->member_change = htonl(0);
 
                 /* Build the next struct */
@@ -943,8 +963,6 @@ wccp2Init(void)
 void
 wccp2ConnectionOpen(void)
 {
-    u_short port = WCCP_PORT;
-
     struct sockaddr_in router, local, null;
     socklen_t local_len, router_len;
 
@@ -959,10 +977,15 @@ wccp2ConnectionOpen(void)
         return;
     }
 
+    if( !Config.Wccp2.address.SetIPv4() ) {
+        debugs(80, 0, "WCCPv2 Disabled. " << Config.Wccp2.address << " is not an IPv4 address.");
+        return;
+    }
+
+    Config.Wccp2.address.SetPort(WCCP_PORT);
     theWccp2Connection = comm_open(SOCK_DGRAM,
                                    0,
                                    Config.Wccp2.address,
-                                   port,
                                    COMM_NONBLOCKING,
                                    "WCCPv2 Socket");
 
@@ -982,7 +1005,7 @@ wccp2ConnectionOpen(void)
                   NULL,
                   0);
 
-    debugs(80, 1, "Accepting WCCPv2 messages on port " << port << ", FD " << theWccp2Connection << ".");
+    debugs(80, 1, "Accepting WCCPv2 messages on port " << WCCP_PORT << ", FD " << theWccp2Connection << ".");
     debugs(80, 1, "Initialising all WCCPv2 lists");
 
     /* Initialise all routers on all services */
@@ -997,7 +1020,7 @@ wccp2ConnectionOpen(void)
             router_len = sizeof(router);
             memset(&router, '\0', router_len);
             router.sin_family = AF_INET;
-            router.sin_port = htons(port);
+            router.sin_port = htons(WCCP_PORT);
             router.sin_addr = router_list_ptr->router_sendto_address;
 
             if (connect(theWccp2Connection, (struct sockaddr *) &router, router_len))
@@ -1016,7 +1039,6 @@ wccp2ConnectionOpen(void)
              * but disconnects anyway so we have to just assume it worked
              */
             if (wccp2_numrouters > 1)
-
                 connect(theWccp2Connection, (struct sockaddr *) &null, router_len);
         }
 
@@ -1134,7 +1156,6 @@ wccp2HandleUdp(int sock, void *not_used)
     struct sockaddr_in from;
 
     struct IN_ADDR cache_address;
-    socklen_t from_len;
     int len, found;
     short int data_length, offset;
     uint32_t tmp;
@@ -1145,16 +1166,14 @@ wccp2HandleUdp(int sock, void *not_used)
 
     commSetSelect(sock, COMM_SELECT_READ, wccp2HandleUdp, NULL, 0);
 
-    from_len = sizeof(struct sockaddr_in);
-    memset(&from, '\0', from_len);
+/* FIXME INET6 : drop conversion boundary */ IPAddress from_tmp;
 
     len = comm_udp_recvfrom(sock,
                             &wccp2_i_see_you,
                             WCCP_RESPONSE_SIZE,
                             0,
-
-                            (struct sockaddr *) &from,
-                            &from_len);
+                            from_tmp);
+/* FIXME INET6 : drop conversion boundary */ from_tmp.GetSockAddr(from);
 
     if (len < 0)
         return;
@@ -1505,9 +1524,7 @@ wccp2HereIam(void *voidnotused)
 
     struct wccp2_mask_identity_info_t *wccp2_mask_identity_info_ptr;
 
-    struct sockaddr_in router;
-    int router_len;
-    u_short port = WCCP_PORT;
+    IPAddress router;
 
     debugs(80, 6, "wccp2HereIam: Called");
 
@@ -1522,10 +1539,7 @@ wccp2HereIam(void *voidnotused)
         return;
     }
 
-    router_len = sizeof(router);
-    memset(&router, '\0', router_len);
-    router.sin_family = AF_INET;
-    router.sin_port = htons(port);
+    router.SetPort(WCCP_PORT);
 
     /* for each router on each service send a packet */
     service_list_ptr = wccp2_service_list_head;
@@ -1534,7 +1548,7 @@ wccp2HereIam(void *voidnotused)
         debugs(80, 5, "wccp2HereIam: sending to service id " << service_list_ptr->info.service_id);
 
         for (router_list_ptr = &service_list_ptr->router_list_head; router_list_ptr->next != NULL; router_list_ptr = router_list_ptr->next) {
-            router.sin_addr = router_list_ptr->router_sendto_address;
+            router = router_list_ptr->router_sendto_address;
 
             /* Set the cache id (ip) */
 
@@ -1567,8 +1581,7 @@ wccp2HereIam(void *voidnotused)
 
             if (wccp2_numrouters > 1) {
                 comm_udp_sendto(theWccp2Connection,
-                                &router,
-                                router_len,
+                                router,
                                 &service_list_ptr->wccp_packet,
                                 service_list_ptr->wccp_packet_size);
             } else {
@@ -1950,9 +1963,9 @@ wccp2AssignBuckets(void *voidnotused)
                 /* send packet */
 
                 if (wccp2_numrouters > 1) {
+/* FIXME INET6 : drop temp conversion */ IPAddress tmp_rtr(router);
                     comm_udp_sendto(theWccp2Connection,
-                                    &router,
-                                    router_len,
+                                    tmp_rtr,
                                     &wccp_packet,
                                     offset);
                 } else {
index 68cfb236151d143bfab79aef88f1e692f0d525df..eeb085bf964b658c774da7107d8a57f3a355cf9c 100644 (file)
@@ -1,6 +1,5 @@
-
 /*
- * $Id: win32.cc,v 1.25 2006/09/13 19:05:11 serassio Exp $
+ * $Id: win32.cc,v 1.26 2007/12/14 23:11:48 amosjeffries Exp $
  *
  * Windows support
  * AUTHOR: Guido Serassio <serassio@squid-cache.org>
@@ -56,36 +55,46 @@ int WIN32_pipe(int handles[2])
     int new_socket;
     fde *F = NULL;
 
-    struct sockaddr_in serv_addr;
-    int len = sizeof(serv_addr);
-    u_short handle1_port;
+    IPAddress localhost;
+    IPAddress handle0;
+    IPAddress handle1;
+    struct addrinfo *AI = NULL;
 
-    handles[0] = handles[1] = -1;
+    localhost.SetLocalhost;
 
-    statCounter.syscalls.sock.sockets++;
-
-    if ((new_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
-        return -1;
+#if !IPV6_SPECIAL_LOCALHOST
+    /* INET6: back-compatible: localhost pipes default to IPv4 unless set otherwise.
+     *        it is blocked by untested helpers on many admins configs
+     *        if this proves to be wrong it can die easily.
+     */
+    localhost.SetIPv4();
+#endif
 
-    memset((void *) &serv_addr, 0, sizeof(serv_addr));
+    handles[0] = handles[1] = -1;
 
-    serv_addr.sin_family = AF_INET;
+    statCounter.syscalls.sock.sockets++;
 
-    serv_addr.sin_port = htons(0);
+    handle0 = localhost;
+    handle0.SetPort(0);
+    handle0.GetAddrInfo(AI);
 
-    serv_addr.sin_addr = local_addr;
+    if ((new_socket = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol)) < 0)
+        return -1;
 
-    if (bind(new_socket, (SOCKADDR *) & serv_addr, len) < 0 ||
-            listen(new_socket, 1) < 0 || getsockname(new_socket, (SOCKADDR *) & serv_addr, &len) < 0 ||
-            (handles[1] = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
+    if (bind(new_socket, AI->ai_addr, AI->ai_addrlen) < 0 ||
+            listen(new_socket, 1) < 0 || getsockname(new_socket, AI->ai_addr, &(AI->ai_addrlen) ) < 0 ||
+            (handles[1] = socket(AI->ai_family, AI->ai_socktype, 0)) < 0) {
         closesocket(new_socket);
         return -1;
     }
 
-    handle1_port = ntohs(serv_addr.sin_port);
+    handle0 = *AI; // retrieve the new details returned by connect()
+
+    handle1.SetPort(handle1.GetPort());
+    handle1.GetAddrInfo(AI);
 
-    if (connect(handles[1], (SOCKADDR *) & serv_addr, len) < 0 ||
-            (handles[0] = accept(new_socket, (SOCKADDR *) & serv_addr, &len)) < 0) {
+    if (connect(handles[1], AI->ai_addr, AI->ai_addrlen) < 0 ||
+            (handles[0] = accept(new_socket, AI->ai_addr, &(AI->ai_addrlen)) ) < 0) {
         closesocket(handles[1]);
         handles[1] = -1;
         closesocket(new_socket);
@@ -95,13 +104,12 @@ int WIN32_pipe(int handles[2])
     closesocket(new_socket);
 
     F = &fd_table[handles[0]];
-    F->local_addr = local_addr;
-    F->local_port = ntohs(serv_addr.sin_port);
+    F->local_addr = handle0;
 
     F = &fd_table[handles[1]];
-    F->local_addr = local_addr;
-    xstrncpy(F->ipaddr, inet_ntoa(local_addr), 16);
-    F->remote_port = handle1_port;
+    F->local_addr = localhost;
+    handle1.NtoA(F->ipaddr, MAX_IPSTRLEN);
+    F->remote_port = handle1.GetPort();
 
     return 0;
 }
@@ -160,8 +168,7 @@ int Win32__WSAFDIsSet(int fd, fd_set FAR * set
     fde *F = &fd_table[fd];
     SOCKET s = F->win32.handle;
 
-    return __WSAFDIsSet(s, set
-                           );
+    return __WSAFDIsSet(s, set);
 }
 
 LONG CALLBACK WIN32_ExceptionHandler(EXCEPTION_POINTERS* ep)
index f24588067a7ed828c51991e7961f8fef5c520064..b2c13c42a1af54b02c40e252b16420939a2ad28e 100644 (file)
@@ -22,8 +22,9 @@ struct _hash_table {
 typedef struct _hash_table hash_table;
 
 extern int hash_links_allocated;
-extern int store_hash_buckets; /* 0 */
-extern hash_table *store_table;        /* NULL */
+/* AYJ: defined by globals.h */
+//extern int store_hash_buckets;       /* 0 */
+//extern hash_table *store_table;      /* NULL */
 extern hash_table *hash_create(HASHCMP *, int, HASHHASH *);
 extern void hash_insert(hash_table *, const char *, void *);
 extern int hash_delete(hash_table *, const char *);
index 7e075445406f28468634198dc82bd711d905ca89..14578088f6b732ab19f2fbf5184a1136330b0c72 100644 (file)
@@ -90,7 +90,9 @@
 #include <sys/stat.h>
 #endif
 
-#define PROXY_PORT 3128
+#include "getaddrinfo.h"
+
+#define PROXY_PORT "3128"
 #define PROXY_ADDR "127.0.0.1"
 #define MAX_FDS 1024
 #define READ_BUF_SZ 4096
@@ -170,20 +172,30 @@ int
 open_http_socket(void)
 {
     int s;
-    struct sockaddr_in S;
-    if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
+    struct addrinfo *AI = NULL;
+    struct addrinfo hints;
+
+    memset(&hints, '\0', sizeof(struct addrinfo));
+    hints.ai_flags = AI_NUMERICHOST|AI_NUMERICSERV;
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+
+    xgetaddrinfo(proxy_addr, proxy_port, &hints, AI);
+
+    if ((s = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol)) < 0) {
        perror("socket");
+        xfreeaddrinfo(AI);
        return -1;
     }
-    memset(&S, '\0', sizeof(struct sockaddr_in));
-    S.sin_family = AF_INET;
-    S.sin_port = htons(proxy_port);
-    S.sin_addr.s_addr = inet_addr(proxy_addr);
-    if (connect(s, (struct sockaddr *) &S, sizeof(S)) < 0) {
+
+    if (connect(s, AI->ai_addr, AI->ai_addrlen) < 0) {
        close(s);
        perror("connect");
+        xfreeaddrinfo(AI);
        return -1;
     }
+
+    xfreeaddrinfo(AI);
     return s;
 }
 
index 277524d0612183ece13450cb6a7b770d4d04ac6a..966e401f10c2f2d1ff099ffe3e257c86d005f367 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: cachemgr.cc,v 1.5 2007/12/06 02:37:17 amosjeffries Exp $
+ * $Id: cachemgr.cc,v 1.6 2007/12/14 23:11:53 amosjeffries Exp $
  *
  * DEBUG: section 0     CGI Cache Manager
  * AUTHOR: Duane Wessels
@@ -134,6 +134,7 @@ extern "C"
 
 #include "assert.h"
 #include "util.h"
+#include "IPAddress.h"
 
 #ifndef DEFAULT_CACHEMGR_CONFIG
 #define DEFAULT_CACHEMGR_CONFIG "/etc/squid/cachemgr.conf"
@@ -171,8 +172,6 @@ static const char *script_name = "/cgi-bin/cachemgr.cgi";
 static const char *progname = NULL;
 static time_t now;
 
-static struct IN_ADDR no_addr;
-
 /*
  * Function prototypes
  */
@@ -764,9 +763,9 @@ static int
 process_request(cachemgr_request * req)
 {
 
-    const struct hostent *hp;
-
-    static struct sockaddr_in S;
+    char ipbuf[MAX_IPSTRLEN];
+    struct addrinfo *AI = NULL;
+    IPAddress S;
     int s;
     int l;
 
@@ -800,19 +799,21 @@ process_request(cachemgr_request * req)
         return 1;
     }
 
+#if USE_IPV6
+    if ((s = socket(PF_INET6, SOCK_STREAM, 0)) < 0) {
+#else
     if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
+#endif
         snprintf(buf, 1024, "socket: %s\n", xstrerror());
         error_html(buf);
         return 1;
     }
 
-    memset(&S, '\0', sizeof(S));
-    S.sin_family = AF_INET;
+    S = *gethostbyname(req->hostname);
 
-    if ((hp = gethostbyname(req->hostname)) != NULL) {
-        assert(hp->h_length >= 0 && (size_t)hp->h_length <= sizeof(S.sin_addr.s_addr));
-        xmemcpy(&S.sin_addr.s_addr, hp->h_addr, hp->h_length);
-    } else if (safe_inet_addr(req->hostname, &S.sin_addr))
+    if ( !S.IsAnyAddr() ) {
+        (void) 0;
+    } else if ( S = req->hostname)
         (void) 0;
     else {
         snprintf(buf, 1024, "Unknown host: %s\n", req->hostname);
@@ -820,17 +821,21 @@ process_request(cachemgr_request * req)
         return 1;
     }
 
-    S.sin_port = htons(req->port);
+    S.SetPort(req->port);
+
+    S.GetAddrInfo(AI);
 
-    if (connect(s, (struct sockaddr *) &S, sizeof(S)) < 0) {
-        snprintf(buf, 1024, "connect %s:%d: %s\n",
-                 inet_ntoa(S.sin_addr),
-                 ntohs(S.sin_port),
+    if (connect(s, AI->ai_addr, AI->ai_addrlen) < 0) {
+        snprintf(buf, 1024, "connect %s: %s\n",
+                 S.ToURL(ipbuf,MAX_IPSTRLEN),
                  xstrerror());
         error_html(buf);
+        S.FreeAddrInfo(AI);
         return 1;
     }
 
+    S.FreeAddrInfo(AI);
+
     l = snprintf(buf, sizeof(buf),
                  "GET cache_object://%s/%s HTTP/1.0\r\n"
                  "Accept: */*\r\n"
@@ -850,7 +855,6 @@ main(int argc, char *argv[])
     char *s;
     cachemgr_request *req;
 
-    safe_inet_addr("255.255.255.255", &no_addr);
     now = time(NULL);
 #ifdef _SQUID_MSWIN_
 
index 279bfb7ceaec2e07fda2b1efbc1a9f14bad05d1d..8fc683b85ffa93033d1bce623ed59c16cf86bc82 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: squidclient.cc,v 1.9 2007/09/01 19:51:30 hno Exp $
+ * $Id: squidclient.cc,v 1.10 2007/12/14 23:11:53 amosjeffries Exp $
  *
  * DEBUG: section 0     WWW Client
  * AUTHOR: Harvest Derived
@@ -84,6 +84,7 @@ using namespace Squid;
 #endif
 
 #include "util.h"
+#include "IPAddress.h"
 
 #ifndef BUFSIZ
 #define BUFSIZ 8192
@@ -92,9 +93,9 @@ using namespace Squid;
 typedef void SIGHDLR(int sig);
 
 /* Local functions */
-static int client_comm_bind(int, const char *);
+static int client_comm_bind(int, const IPAddress &);
 
-static int client_comm_connect(int, const char *, u_short, struct timeval *);
+static int client_comm_connect(int, const IPAddress &, struct timeval *);
 static void usage(const char *progname);
 
 static int Now(struct timeval *);
@@ -151,6 +152,7 @@ main(int argc, char *argv[])
     int opt_noaccept = 0;
     int opt_verbose = 0;
     const char *hostname, *localhost;
+    IPAddress iaddr;
     char url[BUFSIZ], msg[49152], buf[BUFSIZ];
     char extra_hdrs[32768];
     const char *method = "GET";
@@ -434,28 +436,59 @@ main(int argc, char *argv[])
 
     for (i = 0; loops == 0 || i < loops; i++) {
        int fsize = 0;
+        struct addrinfo *AI = NULL;
+
        /* Connect to the server */
 
-       if ((conn = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
-           perror("client: socket");
-           exit(1);
-       }
-       if (localhost && client_comm_bind(conn, localhost) < 0) {
-           perror("client: bind");
-           exit(1);
-       }
-       if (client_comm_connect(conn, hostname, port, ping ? &tv1 : NULL) < 0) {
-           if (errno == 0) {
-               fprintf(stderr, "client: ERROR: Cannot connect to %s:%d: Host unknown.\n", hostname, port);
-           } else {
-               char tbuf[BUFSIZ];
-               snprintf(tbuf, BUFSIZ, "client: ERROR: Cannot connect to %s:%d",
-                   hostname, port);
-               perror(tbuf);
-           }
+        if(localhost) {
+            if( !iaddr.GetHostByName(localhost) ) {
+                fprintf(stderr, "client: ERROR: Cannot resolve %s: Host unknown.\n", localhost);
+                exit(1);
+            }
+        }
+        else {
+            /* Process the remote host name to locate the Protocol required
+               in case we are being asked to link to another version of squid */
+            if( !iaddr.GetHostByName(hostname) ) {
+                fprintf(stderr, "client: ERROR: Cannot resolve %s: Host unknown.\n", hostname);
+                exit(1);
+            }
+        }
+
+        iaddr.GetAddrInfo(AI);
+        if ((conn = socket(AI->ai_family, AI->ai_socktype, 0)) < 0) {
+            perror("client: socket");
+            iaddr.FreeAddrInfo(AI);
+            exit(1);
+        }
+        iaddr.FreeAddrInfo(AI);
+
+        if (localhost && client_comm_bind(conn, iaddr) < 0) {
+            perror("client: bind");
+            exit(1);
+        }
+
+        iaddr.SetEmpty();
+         if( !iaddr.GetHostByName(hostname) ) {
+            fprintf(stderr, "client: ERROR: Cannot resolve %s: Host unknown.\n", hostname);
+            exit(1);
+        }
+
+        iaddr.SetPort(port);
+
+        if (client_comm_connect(conn, iaddr, ping ? &tv1 : NULL) < 0) {
+            char buf[MAX_IPSTRLEN];
+            iaddr.ToURL(buf, MAX_IPSTRLEN);
+            if (errno == 0) {
+                fprintf(stderr, "client: ERROR: Cannot connect to %s: Host unknown.\n", buf);
+            } else {
+                char tbuf[BUFSIZ];
+                snprintf(tbuf, BUFSIZ, "client: ERROR: Cannot connect to %s", buf);
+                perror(tbuf);
+            }
+            exit(1);
+        }
 
-           exit(1);
-       }
        /* Send the HTTP request */
        bytesWritten = mywrite(conn, msg, strlen(msg));
 
@@ -466,6 +499,7 @@ main(int argc, char *argv[])
            fprintf(stderr, "client: ERROR: Cannot send request?: %s\n", msg);
            exit(1);
        }
+
        if (put_file) {
            int x;
            lseek(put_fd, 0, SEEK_SET);
@@ -561,50 +595,42 @@ main(int argc, char *argv[])
 }
 
 static int
-client_comm_bind(int sock, const char *local_host)
+client_comm_bind(int sock, const IPAddress &addr)
 {
 
-    static const struct hostent *hp = NULL;
+    int res;
 
-    static struct sockaddr_in from_addr;
+    static struct addrinfo *AI = NULL;
 
     /* Set up the source socket address from which to send. */
 
-    if (hp == NULL) {
-       from_addr.sin_family = AF_INET;
+    addr.GetAddrInfo(AI);
 
-       if ((hp = gethostbyname(local_host)) == 0) {
-           return (-1);
-       }
-       xmemcpy(&from_addr.sin_addr, hp->h_addr, hp->h_length);
-       from_addr.sin_port = 0;
-    }
-    return bind(sock, (struct sockaddr *) &from_addr, sizeof(struct sockaddr_in));
+    res = bind(sock, AI->ai_addr, AI->ai_addrlen);
+
+    addr.FreeAddrInfo(AI);
+
+    return res;
 }
 
 static int
-client_comm_connect(int sock, const char *dest_host, u_short dest_port, struct timeval *tvp)
+client_comm_connect(int sock, const IPAddress &addr, struct timeval *tvp)
 {
+    int res;
+    static struct addrinfo *AI = NULL;
 
-    static const struct hostent *hp = NULL;
+    /* Set up the destination socket address for message to send to. */
 
-    static struct sockaddr_in to_addr;
+    addr.GetAddrInfo(AI);
 
-    /* Set up the destination socket address for message to send to. */
+    res = connect(sock, AI->ai_addr, AI->ai_addrlen);
 
-    if (hp == NULL) {
-       to_addr.sin_family = AF_INET;
+    addr.FreeAddrInfo(AI);
 
-       if ((hp = gethostbyname(dest_host)) == 0) {
-           return (-1);
-       }
-       xmemcpy(&to_addr.sin_addr, hp->h_addr, hp->h_length);
-       to_addr.sin_port = htons(dest_port);
-    }
     if (tvp)
-       (void) Now(tvp);
+        (void) Now(tvp);
 
-    return connect(sock, (struct sockaddr *) &to_addr, sizeof(struct sockaddr_in));
+    return res;
 }
 
 static int