]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/peer_select.cc
Cleanup: zap CVS Id tags
[thirdparty/squid.git] / src / peer_select.cc
index 3a0c8ab9c953366d8706de39b65bbe6b406784ee..a5eb32c2613075830576882abcc7a85090054f09 100644 (file)
@@ -1,6 +1,5 @@
-
 /*
- * $Id: peer_select.cc,v 1.143 2006/12/10 05:25:53 hno Exp $
+ * $Id$
  *
  * DEBUG: section 44    Peer Selection Algorithm
  * AUTHOR: Duane Wessels
  *  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 "ACLChecklist.h"
 #include "htcp.h"
 #include "forward.h"
-
-const char *hier_strings[] =
-    {
-        "NONE",
-        "DIRECT",
-        "SIBLING_HIT",
-        "PARENT_HIT",
-        "DEFAULT_PARENT",
-        "SINGLE_PARENT",
-        "FIRST_UP_PARENT",
-        "FIRST_PARENT_MISS",
-        "CLOSEST_PARENT_MISS",
-        "CLOSEST_PARENT",
-        "CLOSEST_DIRECT",
-        "NO_DIRECT_FAIL",
-        "SOURCE_FASTEST",
-        "ROUNDROBIN_PARENT",
+#include "SquidTime.h"
+#include "icmp/net_db.h"
+
+const char *hier_strings[] = {
+    "NONE",
+    "DIRECT",
+    "SIBLING_HIT",
+    "PARENT_HIT",
+    "DEFAULT_PARENT",
+    "SINGLE_PARENT",
+    "FIRST_UP_PARENT",
+    "FIRST_PARENT_MISS",
+    "CLOSEST_PARENT_MISS",
+    "CLOSEST_PARENT",
+    "CLOSEST_DIRECT",
+    "NO_DIRECT_FAIL",
+    "SOURCE_FASTEST",
+    "ROUNDROBIN_PARENT",
 #if USE_CACHE_DIGESTS
-        "CD_PARENT_HIT",
-        "CD_SIBLING_HIT",
-#endif
-#if USE_CARP
-        "CARP",
+    "CD_PARENT_HIT",
+    "CD_SIBLING_HIT",
 #endif
-        "ANY_PARENT",
-        "INVALID CODE"
-    };
-
-static struct
-{
+    "CARP",
+    "ANY_PARENT",
+    "USERHASH",
+    "SOURCEHASH",
+    "INVALID CODE"
+};
+
+static struct {
     int timeouts;
-}
-
-PeerStats;
+} PeerStats;
 
-static const char *DirectStr[] =
-    {
-        "DIRECT_UNKNOWN",
-        "DIRECT_NO",
-        "DIRECT_MAYBE",
-        "DIRECT_YES"
-    };
+static const char *DirectStr[] = {
+    "DIRECT_UNKNOWN",
+    "DIRECT_NO",
+    "DIRECT_MAYBE",
+    "DIRECT_YES"
+};
 
 static void peerSelectFoo(ps_state *);
 static void peerPingTimeout(void *data);
@@ -102,6 +98,7 @@ static void peerGetSomeDirect(ps_state *);
 static void peerGetSomeParent(ps_state *);
 static void peerGetAllParents(ps_state *);
 static void peerAddFwdServer(FwdServer **, peer *, hier_code);
+static void peerSelectPinned(ps_state * ps);
 
 CBDATA_CLASS_INIT(ps_state);
 
@@ -109,7 +106,7 @@ static void
 peerSelectStateFree(ps_state * psstate)
 {
     if (psstate->acl_checklist) {
-        debug(44, 1) ("calling aclChecklistFree() from peerSelectStateFree\n");
+        debugs(44, 1, "calling aclChecklistFree() from peerSelectStateFree");
         delete (psstate->acl_checklist);
     }
 
@@ -131,7 +128,7 @@ peerSelectIcpPing(HttpRequest * request, int direct, StoreEntry * entry)
     assert(entry);
     assert(entry->ping_status == PING_NONE);
     assert(direct != DIRECT_YES);
-    debug(44, 3) ("peerSelectIcpPing: %s\n", storeUrl(entry));
+    debugs(44, 3, "peerSelectIcpPing: " << entry->url()  );
 
     if (!request->flags.hierarchical && direct != DIRECT_NO)
         return 0;
@@ -142,7 +139,7 @@ peerSelectIcpPing(HttpRequest * request, int direct, StoreEntry * entry)
 
     n = neighborsCount(request);
 
-    debug(44, 3) ("peerSelectIcpPing: counted %d neighbors\n", n);
+    debugs(44, 3, "peerSelectIcpPing: counted " << n << " neighbors");
 
     return n;
 }
@@ -157,9 +154,9 @@ peerSelect(HttpRequest * request,
     ps_state *psstate;
 
     if (entry)
-        debug(44, 3) ("peerSelect: %s\n", storeUrl(entry));
+        debugs(44, 3, "peerSelect: " << entry->url()  );
     else
-        debug(44, 3) ("peerSelect: %s\n", RequestMethodStr[request->method]);
+        debugs(44, 3, "peerSelect: " << RequestMethodStr(request->method));
 
     psstate = new ps_state;
 
@@ -180,9 +177,7 @@ peerSelect(HttpRequest * request,
 #endif
 
     if (psstate->entry)
-        psstate->entry->lock()
-
-        ;
+        psstate->entry->lock();
 
     peerSelectFoo(psstate);
 }
@@ -192,7 +187,7 @@ peerCheckNeverDirectDone(int answer, void *data)
 {
     ps_state *psstate = (ps_state *) data;
     psstate->acl_checklist = NULL;
-    debug(44, 3) ("peerCheckNeverDirectDone: %d\n", answer);
+    debugs(44, 3, "peerCheckNeverDirectDone: " << answer);
     psstate->never_direct = answer ? 1 : -1;
     peerSelectFoo(psstate);
 }
@@ -202,7 +197,7 @@ peerCheckAlwaysDirectDone(int answer, void *data)
 {
     ps_state *psstate = (ps_state *)data;
     psstate->acl_checklist = NULL;
-    debug(44, 3) ("peerCheckAlwaysDirectDone: %d\n", answer);
+    debugs(44, 3, "peerCheckAlwaysDirectDone: " << answer);
     psstate->always_direct = answer ? 1 : -1;
     peerSelectFoo(psstate);
 }
@@ -216,7 +211,7 @@ peerSelectCallback(ps_state * psstate)
     void *cbdata;
 
     if (entry) {
-        debug(44, 3) ("peerSelectCallback: %s\n", storeUrl(entry));
+        debugs(44, 3, "peerSelectCallback: " << entry->url()  );
 
         if (entry->ping_status == PING_WAITING)
             eventDelete(peerPingTimeout, psstate);
@@ -225,10 +220,10 @@ peerSelectCallback(ps_state * psstate)
     }
 
     if (fs == NULL) {
-        debug(44, 1) ("Failed to select source for '%s'\n", storeUrl(entry));
-        debug(44, 1) ("  always_direct = %d\n", psstate->always_direct);
-        debug(44, 1) ("   never_direct = %d\n", psstate->never_direct);
-        debug(44, 1) ("       timedout = %d\n", psstate->ping.timedout);
+        debugs(44, 1, "Failed to select source for '" << entry->url() << "'" );
+        debugs(44, 1, "  always_direct = " << psstate->always_direct  );
+        debugs(44, 1, "   never_direct = " << psstate->never_direct  );
+        debugs(44, 1, "       timedout = " << psstate->ping.timedout  );
     }
 
     psstate->ping.stop = current_time;
@@ -247,6 +242,7 @@ peerSelectCallback(ps_state * psstate)
 static int
 peerCheckNetdbDirect(ps_state * psstate)
 {
+#if USE_ICMP
     peer *p;
     int myrtt;
     int myhops;
@@ -254,37 +250,36 @@ peerCheckNetdbDirect(ps_state * psstate)
     if (psstate->direct == DIRECT_NO)
         return 0;
 
-    myrtt = netdbHostRtt(psstate->request->host);
+    /* base lookup on RTT and Hops if ICMP NetDB is enabled. */
 
-    debug(44, 3) ("peerCheckNetdbDirect: MY RTT = %d msec\n", myrtt);
+    myrtt = netdbHostRtt(psstate->request->GetHost());
 
-    debug(44, 3) ("peerCheckNetdbDirect: minimum_direct_rtt = %d msec\n",
-                  Config.minDirectRtt);
+    debugs(44, 3, "peerCheckNetdbDirect: MY RTT = " << myrtt << " msec");
+    debugs(44, 3, "peerCheckNetdbDirect: minimum_direct_rtt = " << Config.minDirectRtt << " msec");
 
     if (myrtt && myrtt <= Config.minDirectRtt)
         return 1;
 
-    myhops = netdbHostHops(psstate->request->host);
-
-    debug(44, 3) ("peerCheckNetdbDirect: MY hops = %d\n", myhops);
+    myhops = netdbHostHops(psstate->request->GetHost());
 
-    debug(44, 3) ("peerCheckNetdbDirect: minimum_direct_hops = %d\n",
-                  Config.minDirectHops);
+    debugs(44, 3, "peerCheckNetdbDirect: MY hops = " << myhops);
+    debugs(44, 3, "peerCheckNetdbDirect: minimum_direct_hops = " << Config.minDirectHops);
 
     if (myhops && myhops <= Config.minDirectHops)
         return 1;
 
-    p = whichPeer(&psstate->closest_parent_miss);
+    p = whichPeer(psstate->closest_parent_miss);
 
     if (p == NULL)
         return 0;
 
-    debug(44, 3) ("peerCheckNetdbDirect: closest_parent_miss RTT = %d msec\n",
-                  psstate->ping.p_rtt);
+    debugs(44, 3, "peerCheckNetdbDirect: closest_parent_miss RTT = " << psstate->ping.p_rtt << " msec");
 
     if (myrtt && myrtt <= psstate->ping.p_rtt)
         return 1;
 
+#endif /* USE_ICMP */
+
     return 0;
 }
 
@@ -293,9 +288,7 @@ peerSelectFoo(ps_state * ps)
 {
     StoreEntry *entry = ps->entry;
     HttpRequest *request = ps->request;
-    debug(44, 3) ("peerSelectFoo: '%s %s'\n",
-                  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) {
@@ -328,10 +321,11 @@ peerSelectFoo(ps_state * ps)
             ps->direct = DIRECT_MAYBE;
         }
 
-        debug(44, 3) ("peerSelectFoo: direct = %s\n",
-                      DirectStr[ps->direct]);
+        debugs(44, 3, "peerSelectFoo: direct = " << DirectStr[ps->direct]);
     }
 
+    if (!entry || entry->ping_status == PING_NONE)
+        peerSelectPinned(ps);
     if (entry == NULL) {
         (void) 0;
     } else if (entry->ping_status == PING_NONE) {
@@ -372,14 +366,41 @@ peerSelectFoo(ps_state * ps)
     peerSelectCallback(ps);
 }
 
+/*
+ * peerSelectPinned
+ *
+ * Selects a pinned connection
+ */
+int peerAllowedToUse(const peer * p, HttpRequest * request);
+static void
+peerSelectPinned(ps_state * ps)
+{
+    HttpRequest *request = ps->request;
+    peer *peer;
+    if (!request->pinnedConnection())
+        return;
+    if (request->pinnedConnection()->validatePinnedConnection(request) != -1) {
+        peer = request->pinnedConnection()->pinnedPeer();
+        if (peer && peerAllowedToUse(peer, request)) {
+            peerAddFwdServer(&ps->servers, peer, PINNED);
+            if (ps->entry)
+                ps->entry->ping_status = PING_DONE;     /* Skip ICP */
+        } else if (!peer && ps->direct != DIRECT_NO) {
+            peerAddFwdServer(&ps->servers, NULL, PINNED);
+            if (ps->entry)
+                ps->entry->ping_status = PING_DONE;     /* Skip ICP */
+        }
+    }
+}
+
 /*
  * peerGetSomeNeighbor
- * 
+ *
  * Selects a neighbor (parent or sibling) based on one of the
  * following methods:
  *      Cache Digests
  *      CARP
- *      Netdb RTT estimates
+ *      ICMP Netdb RTT estimates
  *      ICP/HTCP queries
  */
 static void
@@ -407,7 +428,7 @@ peerGetSomeNeighbor(ps_state * ps)
         if ((p = netdbClosestParent(request))) {
             code = CLOSEST_PARENT;
         } else if (peerSelectIcpPing(request, ps->direct, entry)) {
-            debug(44, 3) ("peerSelect: Doing ICP pings\n");
+            debugs(44, 3, "peerSelect: Doing ICP pings");
             ps->ping.start = current_time;
             ps->ping.n_sent = neighborsUdpPing(request,
                                                entry,
@@ -417,10 +438,11 @@ peerGetSomeNeighbor(ps_state * ps)
                                                &ps->ping.timeout);
 
             if (ps->ping.n_sent == 0)
-                debug(44, 0) ("WARNING: neighborsUdpPing returned 0\n");
+                debugs(44, 0, "WARNING: neighborsUdpPing returned 0");
+            debugs(44, 3, "peerSelect: " << ps->ping.n_replies_expected <<
+                   " ICP replies expected, RTT " << ps->ping.timeout <<
+                   " msec");
 
-            debug(44, 3) ("peerSelect: %d ICP replies expected, RTT %d msec\n",
-                          ps->ping.n_replies_expected, ps->ping.timeout);
 
             if (ps->ping.n_replies_expected > 0) {
                 entry->ping_status = PING_WAITING;
@@ -435,7 +457,7 @@ peerGetSomeNeighbor(ps_state * ps)
 
     if (code != HIER_NONE) {
         assert(p);
-        debug(44, 3) ("peerSelect: %s/%s\n", hier_strings[code], p->host);
+        debugs(44, 3, "peerSelect: " << hier_strings[code] << "/" << p->host);
         peerAddFwdServer(&ps->servers, p, code);
     }
 
@@ -444,7 +466,7 @@ peerGetSomeNeighbor(ps_state * ps)
 
 /*
  * peerGetSomeNeighborReplies
- * 
+ *
  * Selects a neighbor (parent or sibling) based on ICP/HTCP replies.
  */
 static void
@@ -458,29 +480,24 @@ peerGetSomeNeighborReplies(ps_state * ps)
 
     if (peerCheckNetdbDirect(ps)) {
         code = CLOSEST_DIRECT;
-        debug(44, 3) ("peerSelect: %s/%s\n", hier_strings[code], request->host);
+        debugs(44, 3, "peerSelect: " << hier_strings[code] << "/" << request->GetHost());
         peerAddFwdServer(&ps->servers, NULL, code);
         return;
     }
 
     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;
-            }
-
+    } else {
+        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) {
-        debug(44, 3) ("peerSelect: %s/%s\n", hier_strings[code], p->host);
+        debugs(44, 3, "peerSelect: " << hier_strings[code] << "/" << p->host);
         peerAddFwdServer(&ps->servers, p, code);
     }
 }
@@ -488,7 +505,7 @@ peerGetSomeNeighborReplies(ps_state * ps)
 
 /*
  * peerGetSomeDirect
- * 
+ *
  * Simply adds a 'direct' entry to the FwdServers list if this
  * request can be forwarded directly to the origin server
  */
@@ -498,11 +515,11 @@ peerGetSomeDirect(ps_state * ps)
     if (ps->direct == DIRECT_NO)
         return;
 
+    /* WAIS is not implemented natively */
     if (ps->request->protocol == PROTO_WAIS)
-        /* Its not really DIRECT, now is it? */
-        peerAddFwdServer(&ps->servers, Config.Wais._peer, HIER_DIRECT);
-    else
-        peerAddFwdServer(&ps->servers, NULL, HIER_DIRECT);
+        return;
+
+    peerAddFwdServer(&ps->servers, NULL, HIER_DIRECT);
 }
 
 static void
@@ -511,21 +528,19 @@ peerGetSomeParent(ps_state * ps)
     peer *p;
     HttpRequest *request = ps->request;
     hier_code code = HIER_NONE;
-    debug(44, 3) ("peerGetSomeParent: %s %s\n",
-                  RequestMethodStr[request->method],
-                  request->host);
+    debugs(44, 3, "peerGetSomeParent: " << RequestMethodStr(request->method) << " " << request->GetHost());
 
     if (ps->direct == DIRECT_YES)
         return;
 
     if ((p = getDefaultParent(request))) {
         code = DEFAULT_PARENT;
-#if USE_CARP
-
+    } else if ((p = peerUserHashSelectParent(request))) {
+        code = USERHASH_PARENT;
+    } else if ((p = peerSourceHashSelectParent(request))) {
+        code = SOURCEHASH_PARENT;
     } else if ((p = carpSelectParent(request))) {
         code = CARP;
-#endif
-
     } else if ((p = getRoundRobinParent(request))) {
         code = ROUNDROBIN_PARENT;
     } else if ((p = getWeightedRoundRobinParent(request))) {
@@ -537,7 +552,7 @@ peerGetSomeParent(ps_state * ps)
     }
 
     if (code != HIER_NONE) {
-        debug(44, 3) ("peerSelect: %s/%s\n", hier_strings[code], p->host);
+        debugs(44, 3, "peerSelect: " << hier_strings[code] << "/" << p->host);
         peerAddFwdServer(&ps->servers, p, code);
     }
 }
@@ -562,7 +577,7 @@ peerGetAllParents(ps_state * ps)
         if (!peerHTTPOkay(p, request))
             continue;
 
-        debug(15, 3) ("peerGetAllParents: adding alive parent %s\n", p->host);
+        debugs(15, 3, "peerGetAllParents: adding alive parent " << p->host);
 
         peerAddFwdServer(&ps->servers, p, ANY_OLD_PARENT);
     }
@@ -584,7 +599,7 @@ peerPingTimeout(void *data)
     StoreEntry *entry = psstate->entry;
 
     if (entry)
-        debug(44, 3) ("peerPingTimeout: '%s'\n", storeUrl(entry));
+        debugs(44, 3, "peerPingTimeout: '" << entry->url() << "'" );
 
     if (!cbdataReferenceValid(psstate->callback_data)) {
         /* request aborted */
@@ -610,12 +625,12 @@ static void
 peerIcpParentMiss(peer * p, icp_common_t * header, ps_state * ps)
 {
     int rtt;
-    int hops;
 
+#if USE_ICMP
     if (Config.onoff.query_icmp) {
         if (header->flags & ICP_FLAG_SRC_RTT) {
             rtt = header->pad & 0xFFFF;
-            hops = (header->pad >> 16) & 0xFFFF;
+            int hops = (header->pad >> 16) & 0xFFFF;
 
             if (rtt > 0 && rtt < 0xFFFF)
                 netdbUpdatePeer(ps->request, p, rtt, hops);
@@ -626,13 +641,14 @@ peerIcpParentMiss(peer * p, icp_common_t * header, ps_state * ps)
             }
         }
     }
+#endif /* USE_ICMP */
 
     /* if closest-only is set, then don't allow FIRST_PARENT_MISS */
     if (p->options.closest_only)
         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;
@@ -640,8 +656,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;
     }
@@ -652,9 +667,7 @@ peerHandleIcpReply(peer * p, peer_t type, icp_common_t * header, void *data)
 {
     ps_state *psstate = (ps_state *)data;
     icp_opcode op = header->getOpCode();
-    debug(44, 3) ("peerHandleIcpReply: %s %s\n",
-                  icp_opcode_str[op],
-                  storeUrl(psstate->entry));
+    debugs(44, 3, "peerHandleIcpReply: " << icp_opcode_str[op] << " " << psstate->entry->url()  );
 #if USE_CACHE_DIGESTS && 0
     /* do cd lookup to count false misses */
 
@@ -676,14 +689,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;
 
@@ -695,9 +700,9 @@ static void
 peerHandleHtcpReply(peer * p, peer_t type, htcpReplyData * htcp, void *data)
 {
     ps_state *psstate = (ps_state *)data;
-    debug(44, 3) ("peerHandleHtcpReply: %s %s\n",
-                  htcp->hit ? "HIT" : "MISS",
-                  storeUrl(psstate->entry));
+    debugs(44, 3, "peerHandleHtcpReply: " <<
+           (htcp->hit ? "HIT" : "MISS") << " " <<
+           psstate->entry->url()  );
     psstate->ping.n_recv++;
 
     if (htcp->hit) {
@@ -720,12 +725,12 @@ static void
 peerHtcpParentMiss(peer * p, htcpReplyData * htcp, ps_state * ps)
 {
     int rtt;
-    int hops;
 
+#if USE_ICMP
     if (Config.onoff.query_icmp) {
         if (htcp->cto.rtt > 0) {
             rtt = (int) htcp->cto.rtt * 1000;
-            hops = (int) htcp->cto.hops * 1000;
+            int hops = (int) htcp->cto.hops * 1000;
             netdbUpdatePeer(ps->request, p, rtt, hops);
 
             if (rtt && (ps->ping.p_rtt == 0 || rtt < ps->ping.p_rtt)) {
@@ -734,13 +739,14 @@ peerHtcpParentMiss(peer * p, htcpReplyData * htcp, ps_state * ps)
             }
         }
     }
+#endif /* USE_ICMP */
 
     /* if closest-only is set, then don't allow FIRST_PARENT_MISS */
     if (p->options.closest_only)
         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;
@@ -748,8 +754,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;
     }
@@ -771,16 +776,16 @@ peerHandlePingReply(peer * p, peer_t type, protocol_t proto, void *pingdata, voi
 #endif
 
     else
-        debug(44, 1) ("peerHandlePingReply: unknown protocol_t %d\n", (int) proto);
+        debugs(44, 1, "peerHandlePingReply: unknown protocol_t " << proto);
 }
 
 static void
 peerAddFwdServer(FwdServer ** FSVR, peer * p, hier_code code)
 {
     FwdServer *fs = (FwdServer *)memAllocate(MEM_FWD_SERVER);
-    debug(44, 5) ("peerAddFwdServer: adding %s %s\n",
-                  p ? p->host : "DIRECT",
-                  hier_strings[code]);
+    debugs(44, 5, "peerAddFwdServer: adding " <<
+           (p ? p->host : "DIRECT")  << " " <<
+           hier_strings[code]  );
     fs->_peer = cbdataReference(p);
     fs->code = code;
 
@@ -805,16 +810,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() :