]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/wccp.cc
Boilerplate: update copyright blurbs on src/
[thirdparty/squid.git] / src / wccp.cc
index fdad1a0a8229df7c5c5e374d73a071eb46bee60d..1325f2ca0620a9941b9bf3b52089886d212e1d90 100644 (file)
@@ -1,45 +1,21 @@
-
 /*
- * $Id$
- *
- * DEBUG: section 80    WCCP Support
- * AUTHOR: Glenn Chisholm
- *
- * 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.
+ * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
  *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
  */
-#include "config.h"
 
-#if USE_WCCP
+/* DEBUG: section 80    WCCP Support */
 
 #include "squid.h"
+
+#if USE_WCCP
 #include "comm.h"
+#include "comm/Connection.h"
 #include "comm/Loops.h"
 #include "event.h"
+#include "SquidConfig.h"
 
 #define WCCP_PORT 2048
 #define WCCP_REVISION 0
@@ -122,7 +98,7 @@ wccpInit(void)
     last_assign_buckets_change = 0;
     number_caches = 0;
 
-    if (!Config.Wccp.router.IsAnyAddr())
+    if (!Config.Wccp.router.isAnyAddr())
         if (!eventFind(wccpHereIam, NULL))
             eventAdd("wccpHereIam", wccpHereIam, NULL, 5.0, 1);
 }
@@ -130,26 +106,25 @@ wccpInit(void)
 void
 wccpConnectionOpen(void)
 {
-    struct addrinfo *router = NULL, *local = NULL;
     debugs(80, 5, "wccpConnectionOpen: Called");
 
-    if (Config.Wccp.router.IsAnyAddr()) {
+    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.");
+    if ( !Config.Wccp.router.setIPv4() ) {
+        debugs(80, DBG_CRITICAL, "WCCPv1 Disabled. Router " << Config.Wccp.router << " is not an IPv4 address.");
         return;
     }
 
-    if ( !Config.Wccp.address.SetIPv4() ) {
-        debugs(1, 1, "WCCPv1 Disabled. Local address " << Config.Wccp.address << " is not IPv4.");
+    if ( !Config.Wccp.address.setIPv4() ) {
+        debugs(80, DBG_CRITICAL, "WCCPv1 Disabled. Local address " << Config.Wccp.address << " is not an IPv4 address.");
         return;
     }
 
-    Config.Wccp.address.SetPort(WCCP_PORT);
-    Config.Wccp.router.SetPort(WCCP_PORT);
+    Config.Wccp.address.port(WCCP_PORT);
+    Config.Wccp.router.port(WCCP_PORT);
 
     theWccpConnection = comm_open_listener(SOCK_DGRAM,
                                            IPPROTO_UDP,
@@ -162,31 +137,29 @@ wccpConnectionOpen(void)
 
     Comm::SetSelect(theWccpConnection, COMM_SELECT_READ, wccpHandleUdp, NULL, 0);
 
-    debugs(80, 1, "Accepting WCCPv1 messages on " << Config.Wccp.address << ", FD " << theWccpConnection << ".");
+    debugs(80, DBG_IMPORTANT, "Accepting WCCPv1 messages on " << Config.Wccp.address << ", FD " << theWccpConnection << ".");
 
-    Config.Wccp.router.GetAddrInfo(router,AF_INET);
+    // Sadly WCCP only does IPv4
 
-    if (connect(theWccpConnection, router->ai_addr, router->ai_addrlen))
+    struct sockaddr_in router;
+    Config.Wccp.router.getSockAddr(router);
+    if (connect(theWccpConnection, (struct sockaddr*)&router, sizeof(router)))
         fatal("Unable to connect WCCP out socket");
 
-    Config.Wccp.router.FreeAddrInfo(router);
-
-    Config.Wccp.address.InitAddrInfo(local);
-
-    if (getsockname(theWccpConnection, local->ai_addr, &local->ai_addrlen))
+    struct sockaddr_in local;
+    memset(&local, '\0', sizeof(local));
+    socklen_t slen = sizeof(local);
+    if (getsockname(theWccpConnection, (struct sockaddr*)&local, &slen))
         fatal("Unable to getsockname on WCCP out socket");
 
-    local_ip = *local;
-
-    Config.Wccp.address.FreeAddrInfo(local);
+    local_ip = local;
 }
 
-
 void
 wccpConnectionClose(void)
 {
     if (theWccpConnection > -1) {
-        debugs(80, 1, "FD " << theWccpConnection << " Closing WCCPv1 socket");
+        debugs(80, DBG_IMPORTANT, "FD " << theWccpConnection << " Closing WCCPv1 socket");
         comm_close(theWccpConnection);
         theWccpConnection = -1;
     }
@@ -237,7 +210,7 @@ wccpHandleUdp(int sock, void *not_used)
         return;
 
     if (ntohl(wccp_i_see_you.number) > WCCP_ACTIVE_CACHES) {
-        debugs(80, 1, "Ignoring WCCP_I_SEE_YOU from " <<
+        debugs(80, DBG_IMPORTANT, "Ignoring WCCP_I_SEE_YOU from " <<
                from << " with number of caches set to " <<
                (int) ntohl(wccp_i_see_you.number));
 
@@ -283,7 +256,7 @@ wccpLowestIP(void)
      * We sanity checked wccp_i_see_you.number back in wccpHandleUdp()
      */
 
-    for (loop = 0; loop < (unsigned) ntohl(wccp_i_see_you.number); loop++) {
+    for (loop = 0; loop < (unsigned) ntohl(wccp_i_see_you.number); ++loop) {
         assert(loop < WCCP_ACTIVE_CACHES);
 
         if (local_ip > wccp_i_see_you.wccp_cache_entry[loop].ip_addr)
@@ -302,13 +275,18 @@ wccpHereIam(void *voidnotused)
     debugs(80, 6, "wccpHereIam: Called");
 
     wccp_here_i_am.id = last_id;
-    comm_udp_send(theWccpConnection,
-                  &wccp_here_i_am,
-                  sizeof(wccp_here_i_am),
-                  0);
+    double interval = 10.0; // TODO: make this configurable, possibly negotiate with the router.
+    errno = 0;
+    ssize_t sent = comm_udp_send(theWccpConnection, &wccp_here_i_am, sizeof(wccp_here_i_am), 0);
+
+    // if we failed to send the whole lot, try again at a shorter interval (20%)
+    if (sent != sizeof(wccp_here_i_am)) {
+        debugs(80, 2, "ERROR: failed to send WCCP HERE_I_AM packet: " << xstrerror());
+        interval = 2.0;
+    }
 
     if (!eventFind(wccpHereIam, NULL))
-        eventAdd("wccpHereIam", wccpHereIam, NULL, 10.0, 1);
+        eventAdd("wccpHereIam", wccpHereIam, NULL, interval, 1);
 }
 
 static void
@@ -345,26 +323,28 @@ wccpAssignBuckets(void)
 
     buckets = buf + wab_len + cache_len;
 
-    memset(wccp_assign_bucket, '\0', sizeof(wccp_assign_bucket));
+    memset(wccp_assign_bucket, '\0', sizeof(*wccp_assign_bucket));
 
     memset(buckets, 0xFF, WCCP_BUCKETS);
 
     buckets_per_cache = WCCP_BUCKETS / number_caches;
 
-    for (loop = 0; loop < number_caches; loop++) {
+    for (loop = 0; loop < number_caches; ++loop) {
         int i;
         memcpy(&caches[loop],
                &wccp_i_see_you.wccp_cache_entry[loop].ip_addr,
                sizeof(*caches));
 
-        for (i = 0; i < buckets_per_cache; i++) {
+        for (i = 0; i < buckets_per_cache; ++i) {
             assert(bucket < WCCP_BUCKETS);
-            buckets[bucket++] = loop;
+            buckets[bucket] = loop;
+            ++bucket;
         }
     }
 
     while (bucket < WCCP_BUCKETS) {
-        buckets[bucket++] = number_caches - 1;
+        buckets[bucket] = number_caches - 1;
+        ++bucket;
     }
 
     wccp_assign_bucket->type = htonl(WCCP_ASSIGN_BUCKET);