-
/*
- * $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-2020 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 "fatal.h"
+#include "SquidConfig.h"
#define WCCP_PORT 2048
#define WCCP_REVISION 0
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);
}
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,
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;
}
* Accept the UDP packet
*/
static void
-wccpHandleUdp(int sock, void *not_used)
+wccpHandleUdp(int sock, void *)
{
Ip::Address from;
int len;
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));
* 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)
}
static void
-wccpHereIam(void *voidnotused)
+wccpHereIam(void *)
{
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.
+ 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)) {
+ int xerrno = errno;
+ debugs(80, 2, "ERROR: failed to send WCCP HERE_I_AM packet: " << xstrerr(xerrno));
+ interval = 2.0;
+ }
if (!eventFind(wccpHereIam, NULL))
- eventAdd("wccpHereIam", wccpHereIam, NULL, 10.0, 1);
+ eventAdd("wccpHereIam", wccpHereIam, NULL, interval, 1);
}
static 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);
}
#endif /* USE_WCCP */
+