diff -u -r -N squid-3.2.6/ChangeLog squid-3.2.7/ChangeLog --- squid-3.2.6/ChangeLog 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/ChangeLog 2013-02-01 23:55:31.000000000 +1300 @@ -1,3 +1,20 @@ +Changes to squid-3.2.7 (01 Feb 2013): + + - Bug 3736: Floating point exception due to divide by zero + - Bug 3735: raw-IPv6 domain URLs crash if IPv6-disabled + - Bug 3732: Fix ConnOpener IPv6 awareness + - Bug 3729: 32-bit overflow in parsing 64-bit configuration values + - Bug 3728: Improve debug for cache_dir + - Bug 3687: unhandled exception: c when using interception and peers + - Bug 3678: external acl grace period causes acl lookup failures + - Bug 3567: Memory leak handling malformed requests + - Bug 3111: Mid-term fix for the forward.cc "err" assertion + - Support OpenSSL NO_Compression optio + - Fix IPv6 enabled pinger on split-stack or IPv6-disabled systems + - Fix "address.GetPort() != 0" assertion for helpers + - ... and several minor memory leaks + - ... and some cache.log message polishing + Changes to squid-3.2.6 (09 Jan 2013): - Regression Bug 3731: TOS setsockopt() requires int value diff -u -r -N squid-3.2.6/configure squid-3.2.7/configure --- squid-3.2.6/configure 2013-01-09 14:42:47.000000000 +1300 +++ squid-3.2.7/configure 2013-02-01 23:57:00.000000000 +1300 @@ -1,7 +1,7 @@ #! /bin/sh # From configure.ac Revision. # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for Squid Web Proxy 3.2.6. +# Generated by GNU Autoconf 2.68 for Squid Web Proxy 3.2.7. # # Report bugs to . # @@ -575,8 +575,8 @@ # Identity of this package. PACKAGE_NAME='Squid Web Proxy' PACKAGE_TARNAME='squid' -PACKAGE_VERSION='3.2.6' -PACKAGE_STRING='Squid Web Proxy 3.2.6' +PACKAGE_VERSION='3.2.7' +PACKAGE_STRING='Squid Web Proxy 3.2.7' PACKAGE_BUGREPORT='http://bugs.squid-cache.org/' PACKAGE_URL='' @@ -1571,7 +1571,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Squid Web Proxy 3.2.6 to adapt to many kinds of systems. +\`configure' configures Squid Web Proxy 3.2.7 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1641,7 +1641,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Squid Web Proxy 3.2.6:";; + short | recursive ) echo "Configuration of Squid Web Proxy 3.2.7:";; esac cat <<\_ACEOF @@ -2019,7 +2019,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Squid Web Proxy configure 3.2.6 +Squid Web Proxy configure 3.2.7 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -3115,7 +3115,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Squid Web Proxy $as_me 3.2.6, which was +It was created by Squid Web Proxy $as_me 3.2.7, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -3934,7 +3934,7 @@ # Define the identity of the package. PACKAGE='squid' - VERSION='3.2.6' + VERSION='3.2.7' cat >>confdefs.h <<_ACEOF @@ -30894,7 +30894,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Squid Web Proxy $as_me 3.2.6, which was +This file was extended by Squid Web Proxy $as_me 3.2.7, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -30960,7 +30960,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -Squid Web Proxy config.status 3.2.6 +Squid Web Proxy config.status 3.2.7 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff -u -r -N squid-3.2.6/configure.ac squid-3.2.7/configure.ac --- squid-3.2.6/configure.ac 2013-01-09 14:42:47.000000000 +1300 +++ squid-3.2.7/configure.ac 2013-02-01 23:56:59.000000000 +1300 @@ -1,4 +1,4 @@ -AC_INIT([Squid Web Proxy],[3.2.6],[http://bugs.squid-cache.org/],[squid]) +AC_INIT([Squid Web Proxy],[3.2.7],[http://bugs.squid-cache.org/],[squid]) AC_PREREQ(2.61) AC_CONFIG_HEADERS([include/autoconf.h]) AC_CONFIG_AUX_DIR(cfgaux) diff -u -r -N squid-3.2.6/helpers/basic_auth/DB/basic_db_auth.8 squid-3.2.7/helpers/basic_auth/DB/basic_db_auth.8 --- squid-3.2.6/helpers/basic_auth/DB/basic_db_auth.8 2013-01-09 15:05:47.000000000 +1300 +++ squid-3.2.7/helpers/basic_auth/DB/basic_db_auth.8 2013-02-02 00:21:45.000000000 +1300 @@ -124,7 +124,7 @@ .\" ======================================================================== .\" .IX Title "BASIC_DB_AUTH 1" -.TH BASIC_DB_AUTH 1 "2013-01-08" "perl v5.10.1" "User Contributed Perl Documentation" +.TH BASIC_DB_AUTH 1 "2013-02-01" "perl v5.10.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff -u -r -N squid-3.2.6/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 squid-3.2.7/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 --- squid-3.2.6/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 2013-01-09 15:05:51.000000000 +1300 +++ squid-3.2.7/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 2013-02-02 00:22:05.000000000 +1300 @@ -124,7 +124,7 @@ .\" ======================================================================== .\" .IX Title "EXT_WBINFO_GROUP_ACL.PL.IN 1" -.TH EXT_WBINFO_GROUP_ACL.PL.IN 1 "2013-01-08" "perl v5.10.1" "User Contributed Perl Documentation" +.TH EXT_WBINFO_GROUP_ACL.PL.IN 1 "2013-02-01" "perl v5.10.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff -u -r -N squid-3.2.6/include/version.h squid-3.2.7/include/version.h --- squid-3.2.6/include/version.h 2013-01-09 14:42:47.000000000 +1300 +++ squid-3.2.7/include/version.h 2013-02-01 23:57:00.000000000 +1300 @@ -9,7 +9,7 @@ */ #ifndef SQUID_RELEASE_TIME -#define SQUID_RELEASE_TIME 1357695708 +#define SQUID_RELEASE_TIME 1359716114 #endif #ifndef APP_SHORTNAME diff -u -r -N squid-3.2.6/lib/smblib/smblib.c squid-3.2.7/lib/smblib/smblib.c --- squid-3.2.6/lib/smblib/smblib.c 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/lib/smblib/smblib.c 2013-02-01 23:55:31.000000000 +1300 @@ -122,8 +122,10 @@ strcpy(con -> password, ""); strcpy(con -> sock_options, ""); strcpy(con -> address, ""); - strcpy(con -> desthost, server); - strcpy(con -> PDomain, NTdomain); + strncpy(con -> desthost, server, sizeof(con->desthost)); + con->desthost[sizeof(con->desthost) - 1] = '\0'; + strncpy(con -> PDomain, NTdomain, sizeof(con->PDomain)); + con->PDomain[sizeof(con->PDomain) - 1] = '\0'; strcpy(con -> OSName, SMBLIB_DEFAULT_OSNAME); strcpy(con -> LMType, SMBLIB_DEFAULT_LMTYPE); con -> first_tree = con -> last_tree = NULL; @@ -216,9 +218,12 @@ /* Init some things ... */ - strcpy(con -> service, service); - strcpy(con -> username, username); - strcpy(con -> password, password); + strncpy(con -> service, service, sizeof(con -> service)); + con -> service[sizeof(con -> service) - 1] = '\0'; + strncpy(con -> username, username, sizeof(con -> username)); + con -> username[sizeof(con -> username) - 1] = '\0'; + strncpy(con -> password, password, sizeof(con -> password)); + con -> password[sizeof(con -> password) - 1] = '\0'; strcpy(con -> sock_options, ""); strcpy(con -> address, ""); strcpy(con -> PDomain, SMBLIB_DEFAULT_DOMAIN); @@ -239,8 +244,17 @@ /* Now figure out the host portion of the service */ - strcpy(temp, service); + strncpy(temp, service, sizeof(temp)); + temp[sizeof(temp) - 1] = '\0'; host = strtok(temp, "/\\"); /* Separate host name portion */ + if (!host) { + if (Con_Handle == NULL) { + free(con); + Con_Handle = NULL; + } + SMBlib_errno = -SMBlibE_CallFailed; + return NULL; + } strcpy(con -> desthost, host); /* Now connect to the remote end, but first upper case the name of the @@ -283,9 +297,10 @@ if (SMB_Negotiate(con, SMB_Prots_Restrict) < 0) { - /* Hmmm what should we do here ... We have a connection, but could not - negotiate ... */ - + if (Con_Handle == NULL) { + free(con); + } + SMBlib_errno = -SMBlibE_NegNoProt; return NULL; } @@ -294,6 +309,10 @@ if ((*tree = SMB_TreeConnect(con, NULL, service, password, "A:")) == NULL) { + if (Con_Handle == NULL) { + free(con); + } + SMBlib_errno = -SMBlibE_BAD; return NULL; } @@ -328,7 +347,8 @@ pass_len = 24; memcpy(pword, PassWord, 24); } else { - strcpy(pword, PassWord); + strncpy(pword, PassWord, sizeof(pword)); + pword[sizeof(pword) - 1] = '\0'; #ifdef PAM_SMB_ENC_PASS if (Con_Handle->encrypt_passwords) { pass_len = 24; @@ -394,7 +414,7 @@ p = p + 1; - if (NtDomain != NULL) { + if (NtDomain == NULL) { strcpy(p, Con_Handle -> PDomain); p = p + strlen(Con_Handle -> PDomain); } else { diff -u -r -N squid-3.2.6/RELEASENOTES.html squid-3.2.7/RELEASENOTES.html --- squid-3.2.6/RELEASENOTES.html 2013-01-09 15:06:07.000000000 +1300 +++ squid-3.2.7/RELEASENOTES.html 2013-02-02 00:23:34.000000000 +1300 @@ -2,10 +2,10 @@ - Squid 3.2.6 release notes + Squid 3.2.7 release notes -

Squid 3.2.6 release notes

+

Squid 3.2.7 release notes

Squid Developers


@@ -72,7 +72,7 @@

1. Notice

-

The Squid Team are pleased to announce the release of Squid-3.2.6 for +

The Squid Team are pleased to announce the release of Squid-3.2.7 for testing.

This new release is available for download from http://www.squid-cache.org/Versions/v3/3.2/ or the diff -u -r -N squid-3.2.6/snmplib/parse.c squid-3.2.7/snmplib/parse.c --- squid-3.2.6/snmplib/parse.c 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/snmplib/parse.c 2013-02-01 23:55:31.000000000 +1300 @@ -408,7 +408,7 @@ np->enums = NULL; /* so we don't free them later */ if (root->child_list == NULL) { root->child_list = tp; - } else { + } else if (peer) { peer->next_peer = tp; } peer = tp; @@ -630,6 +630,16 @@ xfree((char *) np); } +static void +free_node_list(struct node *nl) +{ + while (nl) { + struct node *t = nl->next; + free_node(nl); + nl = t; + } +} + /* * Parse an entry of the form: * label OBJECT IDENTIFIER ::= { parent 2 } @@ -662,9 +672,9 @@ op++, nop++) { /* every node must have parent's name and child's name or number */ if (op->label && (nop->label || (nop->subid != -1))) { - strcpy(np->parent, op->label); + strncpy(np->parent, op->label, sizeof(np->parent) - 1); if (nop->label) - strcpy(np->label, nop->label); + strncpy(np->label, nop->label, sizeof(np->label) - 1); if (nop->subid != -1) np->subid = nop->subid; np->type = 0; @@ -685,8 +695,8 @@ */ if (count == (length - 2)) { if (op->label) { - strcpy(np->parent, op->label); - strcpy(np->label, name); + strncpy(np->parent, op->label, sizeof(np->parent)); + strncpy(np->label, name, sizeof(np->label)); if (nop->subid != -1) np->subid = nop->subid; else @@ -695,12 +705,14 @@ free_node(np); if (oldnp) oldnp->next = NULL; - else + else { + free_node_list(root); // we need to clear the newly allocated list return NULL; + } } } else { print_error("Missing end of oid", (char *) NULL, type); - free_node(np); /* the last node allocated wasn't used */ + free_node_list(root); // we need to clear the newly allocated list if (oldnp) oldnp->next = NULL; return NULL; @@ -950,9 +962,12 @@ length = getoid(fp, SubOid, 32); if (length > 1 && length <= 32) { /* just take the last pair in the oid list */ - if (SubOid[length - 2].label) + if (SubOid[length - 2].label) { strncpy(np->parent, SubOid[length - 2].label, 64); - strcpy(np->label, name); + np->parent[63] = '\0'; + } + strncpy(np->label, name, sizeof(np->label)); + np->label[sizeof(np->label) - 1] = '\0'; if (SubOid[length - 1].subid != -1) np->subid = SubOid[length - 1].subid; else @@ -995,9 +1010,11 @@ return root; } print_error(token, "is a reserved word", type); + free_node_list(root); return NULL; } strncpy(name, token, 64); + name[63] = '\0'; type = get_token(fp, token); if (type == OBJTYPE) { if (root == NULL) { @@ -1011,6 +1028,7 @@ np->next = parse_objecttype(fp, name); if (np->next == NULL) { print_error("Bad parse of objecttype", (char *) NULL, type); + free_node_list(root); return NULL; } } @@ -1029,6 +1047,7 @@ np->next = parse_objectid(fp, name); if (np->next == NULL) { print_error("Bad parse of object type", (char *) NULL, type); + free_node_list(root); return NULL; } } @@ -1041,6 +1060,7 @@ break; } else { print_error("Bad operator", (char *) NULL, type); + free_node_list(root); return NULL; } } @@ -1081,18 +1101,20 @@ strlen("DUMMY"))); if (!p) { snmplib_debug(0, "Bad MIB version or tag missing, install original!\n"); + fclose(fp); return NULL; } if (!strcmp(mbuf, "DUMMY")) { snmplib_debug(0, "You need to update your MIB!\n"); + fclose(fp); return NULL; } nodes = parse(fp); + fclose(fp); if (!nodes) { snmplib_debug(0, "Mib table is bad. Exiting\n"); return NULL; } tree = build_tree(nodes); - fclose(fp); return (tree); } diff -u -r -N squid-3.2.6/snmplib/snmp_vars.c squid-3.2.7/snmplib/snmp_vars.c --- squid-3.2.6/snmplib/snmp_vars.c 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/snmplib/snmp_vars.c 2013-02-01 23:55:31.000000000 +1300 @@ -377,6 +377,7 @@ u_char *DataPtr; int DataLen; oid TmpBuf[MAX_NAME_LEN]; + memset(TmpBuf, 0, MAX_NAME_LEN * sizeof(*TmpBuf)); int AllVarLen = *BufLen; int ThisVarLen = 0; diff -u -r -N squid-3.2.6/src/auth/digest/auth_digest.cc squid-3.2.7/src/auth/digest/auth_digest.cc --- squid-3.2.6/src/auth/digest/auth_digest.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/auth/digest/auth_digest.cc 2013-02-01 23:55:31.000000000 +1300 @@ -933,10 +933,14 @@ /* 2069 requirements */ + // return value. + Auth::UserRequest::Pointer rv; /* do we have a username ? */ if (!username || username[0] == '\0') { - debugs(29, 2, HERE << "Empty or not present username"); - return authDigestLogUsername(username, digest_request); + debugs(29, 2, "Empty or not present username"); + rv = authDigestLogUsername(username, digest_request); + safe_free(username); + return rv; } /* Sanity check of the username. @@ -944,33 +948,43 @@ * have been redone */ if (strchr(username, '"')) { - debugs(29, 2, HERE << "Unacceptable username '" << username << "'"); - return authDigestLogUsername(username, digest_request); + debugs(29, 2, "Unacceptable username '" << username << "'"); + rv = authDigestLogUsername(username, digest_request); + safe_free(username); + return rv; } /* do we have a realm ? */ if (!digest_request->realm || digest_request->realm[0] == '\0') { - debugs(29, 2, HERE << "Empty or not present realm"); - return authDigestLogUsername(username, digest_request); + debugs(29, 2, "Empty or not present realm"); + rv = authDigestLogUsername(username, digest_request); + safe_free(username); + return rv; } /* and a nonce? */ if (!digest_request->nonceb64 || digest_request->nonceb64[0] == '\0') { - debugs(29, 2, HERE << "Empty or not present nonce"); - return authDigestLogUsername(username, digest_request); + debugs(29, 2, "Empty or not present nonce"); + rv = authDigestLogUsername(username, digest_request); + safe_free(username); + return rv; } /* we can't check the URI just yet. We'll check it in the * authenticate phase, but needs to be given */ if (!digest_request->uri || digest_request->uri[0] == '\0') { - debugs(29, 2, HERE << "Missing URI field"); - return authDigestLogUsername(username, digest_request); + debugs(29, 2, "Missing URI field"); + rv = authDigestLogUsername(username, digest_request); + safe_free(username); + return rv; } /* is the response the correct length? */ if (!digest_request->response || strlen(digest_request->response) != 32) { - debugs(29, 2, HERE << "Response length invalid"); - return authDigestLogUsername(username, digest_request); + debugs(29, 2, "Response length invalid"); + rv = authDigestLogUsername(username, digest_request); + safe_free(username); + return rv; } /* check the algorithm is present and supported */ @@ -978,8 +992,10 @@ digest_request->algorithm = xstrndup("MD5", 4); else if (strcmp(digest_request->algorithm, "MD5") && strcmp(digest_request->algorithm, "MD5-sess")) { - debugs(29, 2, HERE << "invalid algorithm specified!"); - return authDigestLogUsername(username, digest_request); + debugs(29, 2, "invalid algorithm specified!"); + rv = authDigestLogUsername(username, digest_request); + safe_free(username); + return rv; } /* 2617 requirements, indicated by qop */ @@ -988,26 +1004,34 @@ /* check the qop is what we expected. */ if (strcmp(digest_request->qop, QOP_AUTH) != 0) { /* we received a qop option we didn't send */ - debugs(29, 2, HERE << "Invalid qop option received"); - return authDigestLogUsername(username, digest_request); + debugs(29, 2, "Invalid qop option received"); + rv = authDigestLogUsername(username, digest_request); + safe_free(username); + return rv; } /* check cnonce */ if (!digest_request->cnonce || digest_request->cnonce[0] == '\0') { - debugs(29, 2, HERE << "Missing cnonce field"); - return authDigestLogUsername(username, digest_request); + debugs(29, 2, "Missing cnonce field"); + rv = authDigestLogUsername(username, digest_request); + safe_free(username); + return rv; } /* check nc */ if (strlen(digest_request->nc) != 8 || strspn(digest_request->nc, "0123456789abcdefABCDEF") != 8) { - debugs(29, 2, HERE << "invalid nonce count"); - return authDigestLogUsername(username, digest_request); + debugs(29, 2, "invalid nonce count"); + rv = authDigestLogUsername(username, digest_request); + safe_free(username); + return rv; } } else { /* cnonce and nc both require qop */ if (digest_request->cnonce || digest_request->nc) { - debugs(29, 2, HERE << "missing qop!"); - return authDigestLogUsername(username, digest_request); + debugs(29, 2, "missing qop!"); + rv = authDigestLogUsername(username, digest_request); + safe_free(username); + return rv; } } @@ -1017,10 +1041,12 @@ nonce = authenticateDigestNonceFindNonce(digest_request->nonceb64); if (!nonce) { /* we couldn't find a matching nonce! */ - debugs(29, 2, HERE << "Unexpected or invalid nonce received"); + debugs(29, 2, "Unexpected or invalid nonce received"); if (digest_request->user() != NULL) digest_request->user()->credentials(Auth::Failed); - return authDigestLogUsername(username, digest_request); + rv = authDigestLogUsername(username, digest_request); + safe_free(username); + return rv; } digest_request->nonce = nonce; @@ -1028,8 +1054,10 @@ /* check that we're not being hacked / the username hasn't changed */ if (nonce->user && strcmp(username, nonce->user->username())) { - debugs(29, 2, HERE << "Username for the nonce does not equal the username for the request"); - return authDigestLogUsername(username, digest_request); + debugs(29, 2, "Username for the nonce does not equal the username for the request"); + rv = authDigestLogUsername(username, digest_request); + safe_free(username); + return rv; } /* the method we'll check at the authenticate step as well */ diff -u -r -N squid-3.2.6/src/cache_cf.cc squid-3.2.7/src/cache_cf.cc --- squid-3.2.6/src/cache_cf.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/cache_cf.cc 2013-02-01 23:55:31.000000000 +1300 @@ -2240,7 +2240,7 @@ p->sslcapath = xstrdup(token + 10); } else if (strncmp(token, "sslcrlfile=", 11) == 0) { safe_free(p->sslcrlfile); - p->sslcapath = xstrdup(token + 10); + p->sslcrlfile = xstrdup(token + 11); } else if (strncmp(token, "sslflags=", 9) == 0) { safe_free(p->sslflags); p->sslflags = xstrdup(token + 9); @@ -4135,7 +4135,7 @@ cpuAffinityMap->processes()[i]); } storeAppendPrintf(entry, " cores="); - for (size_t i = 0; i < cpuAffinityMap->processes().size(); ++i) { + for (size_t i = 0; i < cpuAffinityMap->cores().size(); ++i) { storeAppendPrintf(entry, "%s%i", (i ? "," : ""), cpuAffinityMap->cores()[i]); } diff -u -r -N squid-3.2.6/src/client_side.cc squid-3.2.7/src/client_side.cc --- squid-3.2.6/src/client_side.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/client_side.cc 2013-02-01 23:55:31.000000000 +1300 @@ -2447,7 +2447,7 @@ clientProcessRequest(ConnStateData *conn, HttpParser *hp, ClientSocketContext *context, const HttpRequestMethod& method, HttpVersion http_ver) { ClientHttpRequest *http = context->http; - HttpRequest *request = NULL; + HttpRequest::Pointer request; bool notedUseOfBuffer = false; bool chunked = false; bool mustReplyToOptions = false; diff -u -r -N squid-3.2.6/src/comm/ConnOpener.cc squid-3.2.7/src/comm/ConnOpener.cc --- squid-3.2.6/src/comm/ConnOpener.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/comm/ConnOpener.cc 2013-02-01 23:55:31.000000000 +1300 @@ -10,6 +10,7 @@ #include "fde.h" #include "icmp/net_db.h" #include "ipcache.h" +#include "ip/tools.h" #include "SquidTime.h" CBDATA_NAMESPACED_CLASS_INIT(Comm, ConnOpener); @@ -155,12 +156,10 @@ /* get a socket open ready for connecting with */ if (temporaryFd_ < 0) { -#if USE_IPV6 /* outbound sockets have no need to be protocol agnostic. */ - if (conn_->remote.IsIPv4()) { + if (!(Ip::EnableIpv6&IPV6_SPECIAL_V4MAPPING) && conn_->remote.IsIPv4()) { conn_->local.SetIPv4(); } -#endif temporaryFd_ = comm_openex(SOCK_STREAM, IPPROTO_TCP, conn_->local, conn_->flags, conn_->tos, conn_->nfmark, host_); if (temporaryFd_ < 0) { doneConnecting(COMM_ERR_CONNECT, 0); diff -u -r -N squid-3.2.6/src/defines.h squid-3.2.7/src/defines.h --- squid-3.2.6/src/defines.h 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/defines.h 2013-02-01 23:55:31.000000000 +1300 @@ -175,6 +175,11 @@ #define IPC_UNIX_STREAM 4 #define IPC_UNIX_DGRAM 5 +/* required for AF_UNIX below to be defined [on FreeBSD] */ +#if HAVE_SYS_SOCKET_H +#include +#endif + #if HAVE_SOCKETPAIR && defined (AF_UNIX) #define IPC_STREAM IPC_UNIX_STREAM #define IPC_DGRAM IPC_UNIX_DGRAM diff -u -r -N squid-3.2.6/src/DiskIO/AIO/AIODiskIOStrategy.cc squid-3.2.7/src/DiskIO/AIO/AIODiskIOStrategy.cc --- squid-3.2.6/src/DiskIO/AIO/AIODiskIOStrategy.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/DiskIO/AIO/AIODiskIOStrategy.cc 2013-02-01 23:55:31.000000000 +1300 @@ -49,9 +49,12 @@ #include "DiskIO/ReadRequest.h" #include "DiskIO/WriteRequest.h" -AIODiskIOStrategy::AIODiskIOStrategy() +AIODiskIOStrategy::AIODiskIOStrategy() : + fd(-1) { + aq.aq_state = AQ_STATE_NONE; aq.aq_numpending = 0; + memset(&aq.aq_queue, 0, sizeof(aq.aq_queue)); } AIODiskIOStrategy::~AIODiskIOStrategy() diff -u -r -N squid-3.2.6/src/DiskIO/DiskDaemon/diskd.cc squid-3.2.7/src/DiskIO/DiskDaemon/diskd.cc --- squid-3.2.6/src/DiskIO/DiskDaemon/diskd.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/DiskIO/DiskDaemon/diskd.cc 2013-02-01 23:55:31.000000000 +1300 @@ -266,6 +266,10 @@ if (s->shm_offset > -1) buf = shmbuf + s->shm_offset; + else { + fprintf(stderr, "%d UNLNK id(%u) Error: no filename in shm buffer\n", (int) mypid, s->id); + return; + } switch (r->mtype) { @@ -370,7 +374,10 @@ hash = hash_create(fsCmp, 1 << 4, fsHash); assert(hash); - fcntl(0, F_SETFL, SQUID_NONBLOCK); + if (fcntl(0, F_SETFL, SQUID_NONBLOCK) < 0) { + perror(xstrerror()); + return 1; + } memset(&sa, '\0', sizeof(sa)); sa.sa_handler = alarm_handler; sa.sa_flags = SA_RESTART; diff -u -r -N squid-3.2.6/src/DiskIO/DiskDaemon/DiskdFile.cc squid-3.2.7/src/DiskIO/DiskDaemon/DiskdFile.cc --- squid-3.2.6/src/DiskIO/DiskDaemon/DiskdFile.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/DiskIO/DiskDaemon/DiskdFile.cc 2013-02-01 23:55:31.000000000 +1300 @@ -69,8 +69,11 @@ cbdataFree(t); } -DiskdFile::DiskdFile(char const *aPath, DiskdIOStrategy *anIO) : errorOccured (false), IO(anIO), - inProgressIOs (0) +DiskdFile::DiskdFile(char const *aPath, DiskdIOStrategy *anIO) : + errorOccured(false), + IO(anIO), + mode(0), + inProgressIOs(0) { assert (aPath); debugs(79, 3, "DiskdFile::DiskdFile: " << aPath); @@ -382,8 +385,10 @@ debugs(79, 3, "DiskdFile::readDone: status " << M->status); assert (M->requestor); ReadRequest::Pointer readRequest = dynamic_cast(M->requestor); + /* remove the free protection */ - readRequest->RefCountDereference(); + if (readRequest != NULL) + readRequest->RefCountDereference(); if (M->status < 0) { ++diskd_stats.read.fail; @@ -407,7 +412,8 @@ assert (M->requestor); WriteRequest::Pointer writeRequest = dynamic_cast(M->requestor); /* remove the free protection */ - writeRequest->RefCountDereference(); + if (writeRequest != NULL) + writeRequest->RefCountDereference(); if (M->status < 0) { errorOccured = true; diff -u -r -N squid-3.2.6/src/DiskIO/DiskThreads/aiops.cc squid-3.2.7/src/DiskIO/DiskThreads/aiops.cc --- squid-3.2.6/src/DiskIO/DiskThreads/aiops.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/DiskIO/DiskThreads/aiops.cc 2013-02-01 23:55:31.000000000 +1300 @@ -729,8 +729,10 @@ static void squidaio_do_read(squidaio_request_t * requestp) { - lseek(requestp->fd, requestp->offset, requestp->whence); - requestp->ret = read(requestp->fd, requestp->bufferp, requestp->buflen); + if (lseek(requestp->fd, requestp->offset, requestp->whence) >= 0) + requestp->ret = read(requestp->fd, requestp->bufferp, requestp->buflen); + else + requestp->ret = -1; requestp->err = errno; } diff -u -r -N squid-3.2.6/src/DiskIO/DiskThreads/DiskThreadsIOStrategy.cc squid-3.2.7/src/DiskIO/DiskThreads/DiskThreadsIOStrategy.cc --- squid-3.2.6/src/DiskIO/DiskThreads/DiskThreadsIOStrategy.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/DiskIO/DiskThreads/DiskThreadsIOStrategy.cc 2013-02-01 23:55:31.000000000 +1300 @@ -190,7 +190,10 @@ debugs(32, 2, "aioSync: done"); } -DiskThreadsIOStrategy::DiskThreadsIOStrategy() : initialised (false) {} +DiskThreadsIOStrategy::DiskThreadsIOStrategy() : + initialised(false), + squidaio_ctrl_pool(NULL) +{} void DiskThreadsIOStrategy::aioStats(StoreEntry * sentry) diff -u -r -N squid-3.2.6/src/DiskIO/IpcIo/IpcIoFile.cc squid-3.2.7/src/DiskIO/IpcIo/IpcIoFile.cc --- squid-3.2.6/src/DiskIO/IpcIo/IpcIoFile.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/DiskIO/IpcIo/IpcIoFile.cc 2013-02-01 23:55:31.000000000 +1300 @@ -584,9 +584,14 @@ /* IpcIoMsg */ IpcIoMsg::IpcIoMsg(): - requestId(0), offset(0), len(0), command(IpcIo::cmdNone), xerrno(0) + requestId(0), + offset(0), + len(0), + command(IpcIo::cmdNone), + xerrno(0) { start.tv_sec = 0; + start.tv_usec = 0; } /* IpcIoPendingRequest */ diff -u -r -N squid-3.2.6/src/external_acl.cc squid-3.2.7/src/external_acl.cc --- squid-3.2.6/src/external_acl.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/external_acl.cc 2013-02-01 23:55:31.000000000 +1300 @@ -830,8 +830,13 @@ if (acl->def->theHelper->stats.queue_size <= (int)acl->def->theHelper->childs.n_active) { debugs(82, 2, "aclMatchExternal: \"" << key << "\": queueing a call."); ch->changeState(ExternalACLLookup::Instance()); - debugs(82, 2, "aclMatchExternal: \"" << key << "\": return -1."); - return -1; // to get here we have to have an expired cache entry. MUST not use. + if (!entry) { + debugs(82, 2, "aclMatchExternal: \"" << key << "\": return -1."); + return -1; // to get here we have to have an expired cache entry. MUST not use. + } + // else we have a usable entry in grace period + debugs(82, 2, "aclMatchExternal: \"" << key << "\": grace period active, will use results from entry."); + // Fall thru to processing below. } else { if (!entry) { debugs(82, 1, "aclMatchExternal: '" << acl->def->name << diff -u -r -N squid-3.2.6/src/forward.cc squid-3.2.7/src/forward.cc --- squid-3.2.6/src/forward.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/forward.cc 2013-02-01 23:55:31.000000000 +1300 @@ -196,6 +196,8 @@ if (entry->store_status == STORE_PENDING) { if (entry->isEmpty()) { + if (!err) // we quit (e.g., fd closed) before an error or content + fail(new ErrorState(ERR_READ_ERROR, HTTP_BAD_GATEWAY, request)); assert(err); errorAppendEntry(entry, err); err = NULL; diff -u -r -N squid-3.2.6/src/icmp/Icmp4.cc squid-3.2.7/src/icmp/Icmp4.cc --- squid-3.2.6/src/icmp/Icmp4.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/icmp/Icmp4.cc 2013-02-01 23:55:31.000000000 +1300 @@ -156,6 +156,7 @@ } Log(to, ' ', NULL, 0, 0); + to.FreeAddrInfo(S); } void @@ -221,11 +222,15 @@ icmp = (struct icmphdr *) (void *) (pkt + iphdrlen); - if (icmp->icmp_type != ICMP_ECHOREPLY) + if (icmp->icmp_type != ICMP_ECHOREPLY) { + preply.from.FreeAddrInfo(from); return; + } - if (icmp->icmp_id != icmp_ident) + if (icmp->icmp_id != icmp_ident) { + preply.from.FreeAddrInfo(from); return; + } echo = (icmpEchoData *) (void *) (icmp + 1); @@ -242,6 +247,7 @@ control.SendResult(preply, (sizeof(pingerReplyData) - MAX_PKT4_SZ + preply.psize) ); Log(preply.from, icmp->icmp_type, icmpPktStr[icmp->icmp_type], preply.rtt, preply.hops); + preply.from.FreeAddrInfo(from); } #endif /* USE_ICMP */ diff -u -r -N squid-3.2.6/src/icmp/Icmp6.cc squid-3.2.7/src/icmp/Icmp6.cc --- squid-3.2.6/src/icmp/Icmp6.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/icmp/Icmp6.cc 2013-02-01 23:55:31.000000000 +1300 @@ -202,6 +202,7 @@ debugs(42,9, HERE << "x=" << x); Log(to, 0, NULL, 0, 0); + to.FreeAddrInfo(S); } /** @@ -296,11 +297,13 @@ ( icmp6header->icmp6_type&0x80 ? icmp6HighPktStr[(int)(icmp6header->icmp6_type&0x7f)] : icmp6LowPktStr[(int)(icmp6header->icmp6_type&0x7f)] ) ); } + preply.from.FreeAddrInfo(from); return; } if (icmp6header->icmp6_id != icmp_ident) { debugs(42, 8, HERE << "dropping Icmp6 read. IDENT check failed. ident=='" << icmp_ident << "'=='" << icmp6header->icmp6_id << "'"); + preply.from.FreeAddrInfo(from); return; } @@ -337,6 +340,7 @@ /* send results of the lookup back to squid.*/ control.SendResult(preply, (sizeof(pingerReplyData) - PINGER_PAYLOAD_SZ + preply.psize) ); + preply.from.FreeAddrInfo(from); } #endif /* USE_ICMP */ diff -u -r -N squid-3.2.6/src/icmp/pinger.cc squid-3.2.7/src/icmp/pinger.cc --- squid-3.2.6/src/icmp/pinger.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/icmp/pinger.cc 2013-02-01 23:55:31.000000000 +1300 @@ -71,6 +71,7 @@ #include "Icmp4.h" #include "Icmp6.h" #include "IcmpPinger.h" +#include "ip/tools.h" #if _SQUID_MSWIN_ @@ -148,6 +149,9 @@ getCurrentTime(); + // determine IPv4 or IPv6 capabilities before using sockets. + Ip::ProbeTransport(); + _db_init(NULL, debug_args); debugs(42, 0, "pinger: Initialising ICMP pinger ..."); diff -u -r -N squid-3.2.6/src/ip/testAddress.cc squid-3.2.7/src/ip/testAddress.cc --- squid-3.2.6/src/ip/testAddress.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/ip/testAddress.cc 2013-02-01 23:55:31.000000000 +1300 @@ -714,6 +714,7 @@ CPPUNIT_ASSERT( memcmp( expect->ai_addr, ipval->ai_addr, expect->ai_addrlen ) == 0 ); freeaddrinfo(expect); + anIP.FreeAddrInfo(ipval); } void diff -u -r -N squid-3.2.6/src/mem_node.cc squid-3.2.7/src/mem_node.cc --- squid-3.2.6/src/mem_node.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/mem_node.cc 2013-02-01 23:55:31.000000000 +1300 @@ -65,8 +65,12 @@ n->write_pending = 0; } -mem_node::mem_node(int64_t offset):nodeBuffer(0,offset,data) -{} +mem_node::mem_node(int64_t offset) : + nodeBuffer(0,offset,data), + write_pending(0) +{ + *data = 0; +} mem_node::~mem_node() {} diff -u -r -N squid-3.2.6/src/Parsing.cc squid-3.2.7/src/Parsing.cc --- squid-3.2.6/src/Parsing.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/Parsing.cc 2013-02-01 23:55:31.000000000 +1300 @@ -85,7 +85,7 @@ GetInteger64(void) { char *token = strtok(NULL, w_space); - int i; + int64_t i; if (token == NULL) self_destruct(); diff -u -r -N squid-3.2.6/src/peer_select.cc squid-3.2.7/src/peer_select.cc --- squid-3.2.6/src/peer_select.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/peer_select.cc 2013-02-01 23:55:31.000000000 +1300 @@ -47,6 +47,7 @@ #include "SquidTime.h" #include "icmp/net_db.h" #include "ipcache.h" +#include "ip/tools.h" static struct { int timeouts; @@ -242,15 +243,18 @@ const bool useOriginalDst = Config.onoff.client_dst_passthru || !req->flags.hostVerified; const bool choseDirect = fs && fs->code == HIER_DIRECT; if (isIntercepted && useOriginalDst && choseDirect) { - // construct a "result" adding the ORIGINAL_DST to the set instead of DIRECT - Comm::ConnectionPointer p = new Comm::Connection(); - p->remote = req->clientConnectionManager->clientConnection->local; - p->peerType = fs->code; - p->setPeer(fs->_peer); - - // check for a configured outgoing address for this destination... - getOutgoingAddress(psstate->request, p); - psstate->paths->push_back(p); + // check the client is still around before using any of its details + if (req->clientConnectionManager.valid()) { + // construct a "result" adding the ORIGINAL_DST to the set instead of DIRECT + Comm::ConnectionPointer p = new Comm::Connection(); + p->remote = req->clientConnectionManager->clientConnection->local; + p->peerType = fs->code; + p->setPeer(fs->_peer); + + // check for a configured outgoing address for this destination... + getOutgoingAddress(psstate->request, p); + psstate->paths->push_back(p); + } // clear the used fs and continue psstate->servers = fs->next; @@ -352,6 +356,14 @@ p = new Comm::Connection(); p->remote = ia->in_addrs[n]; + + // when IPv6 is disabled we cannot use it + if (!Ip::EnableIpv6 && p->remote.IsIPv6()) { + const char *host = (fs->_peer ? fs->_peer->host : psstate->request->GetHost()); + ipcacheMarkBadAddr(host, p->remote); + continue; + } + if (fs->_peer) p->remote.SetPort(fs->_peer->http_port); else diff -u -r -N squid-3.2.6/src/ssl/support.cc squid-3.2.7/src/ssl/support.cc --- squid-3.2.6/src/ssl/support.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/ssl/support.cc 2013-02-01 23:55:31.000000000 +1300 @@ -400,6 +400,11 @@ "NO_TLSv1_2", SSL_OP_NO_TLSv1_2 }, #endif +#if SSL_OP_NO_COMPRESSION + { + "No_Compression", SSL_OP_NO_COMPRESSION + }, +#endif { "", 0 }, diff -u -r -N squid-3.2.6/src/store_client.cc squid-3.2.7/src/store_client.cc --- squid-3.2.6/src/store_client.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/store_client.cc 2013-02-01 23:55:31.000000000 +1300 @@ -61,7 +61,7 @@ static StoreIOState::STRCB storeClientReadHeader; static void storeClientCopy2(StoreEntry * e, store_client * sc); static EVH storeClientCopyEvent; -static int CheckQuickAbort2(StoreEntry * entry); +static bool CheckQuickAbortIsReasonable(StoreEntry * entry); static void CheckQuickAbort(StoreEntry * entry); CBDATA_CLASS_INIT(store_client); @@ -781,72 +781,72 @@ return npend; } -/* return 1 if the request should be aborted */ -static int -CheckQuickAbort2(StoreEntry * entry) +/* return true if the request should be aborted */ +static bool +CheckQuickAbortIsReasonable(StoreEntry * entry) { MemObject * const mem = entry->mem_obj; assert(mem); - debugs(90, 3, "CheckQuickAbort2: entry=" << entry << ", mem=" << mem); + debugs(90, 3, "entry=" << entry << ", mem=" << mem); if (mem->request && !mem->request->flags.cachable) { - debugs(90, 3, "CheckQuickAbort2: YES !mem->request->flags.cachable"); - return 1; + debugs(90, 3, "quick-abort? YES !mem->request->flags.cachable"); + return true; } if (EBIT_TEST(entry->flags, KEY_PRIVATE)) { - debugs(90, 3, "CheckQuickAbort2: YES KEY_PRIVATE"); - return 1; + debugs(90, 3, "quick-abort? YES KEY_PRIVATE"); + return true; } int64_t expectlen = entry->getReply()->content_length + entry->getReply()->hdr_sz; - if (expectlen < 0) + if (expectlen < 0) { /* expectlen is < 0 if *no* information about the object has been received */ - return 1; + debugs(90, 3, "quick-abort? YES no object data received yet"); + return true; + } - int64_t curlen = mem->endOffset (); + int64_t curlen = mem->endOffset(); if (Config.quickAbort.min < 0) { - debugs(90, 3, "CheckQuickAbort2: NO disabled"); - return 0; + debugs(90, 3, "quick-abort? NO disabled"); + return false; } - int64_t roffLimit = mem->request->getRangeOffsetLimit(); - - if ( roffLimit < 0 && mem->request && mem->request->range ) { + if (mem->request && mem->request->range && mem->request->getRangeOffsetLimit() < 0) { /* Don't abort if the admin has configured range_ofset -1 to download fully for caching. */ - debugs(90, 3, "CheckQuickAbort2: NO admin configured range replies to full-download"); - return 0; + debugs(90, 3, "quick-abort? NO admin configured range replies to full-download"); + return false; } if (curlen > expectlen) { - debugs(90, 3, "CheckQuickAbort2: YES bad content length"); - return 1; + debugs(90, 3, "quick-abort? YES bad content length"); + return true; } if ((expectlen - curlen) < (Config.quickAbort.min << 10)) { - debugs(90, 3, "CheckQuickAbort2: NO only little more left"); - return 0; + debugs(90, 3, "quick-abort? NO only a little more object left to receive"); + return false; } if ((expectlen - curlen) > (Config.quickAbort.max << 10)) { - debugs(90, 3, "CheckQuickAbort2: YES too much left to go"); - return 1; + debugs(90, 3, "quick-abort? YES too much left to go"); + return true; } if (expectlen < 100) { - debugs(90, 3, "CheckQuickAbort2: NO avoid FPE"); - return 0; + debugs(90, 3, "quick-abort? NO avoid FPE"); + return false; } if ((curlen / (expectlen / 100)) > (Config.quickAbort.pct)) { - debugs(90, 3, "CheckQuickAbort2: NO past point of no return"); - return 0; + debugs(90, 3, "quick-abort? NO past point of no return"); + return false; } - debugs(90, 3, "CheckQuickAbort2: YES default, returning 1"); - return 1; + debugs(90, 3, "quick-abort? YES default"); + return true; } static void @@ -863,7 +863,7 @@ if (EBIT_TEST(entry->flags, ENTRY_SPECIAL)) return; - if (CheckQuickAbort2(entry) == 0) + if (!CheckQuickAbortIsReasonable(entry)) return; entry->abort(); diff -u -r -N squid-3.2.6/src/store_dir.cc squid-3.2.7/src/store_dir.cc --- squid-3.2.6/src/store_dir.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/store_dir.cc 2013-02-01 23:55:31.000000000 +1300 @@ -907,6 +907,10 @@ void StoreHashIndex::create() { + if (Config.cacheSwap.n_configured == 0) { + debugs(0, DBG_PARSE_NOTE(DBG_CRITICAL), "No cache_dir stores are configured."); + } + for (int i = 0; i < Config.cacheSwap.n_configured; ++i) { if (dir(i).active()) store(i)->create(); @@ -934,6 +938,12 @@ void StoreHashIndex::init() { + if (Config.Store.objectsPerBucket <= 0) + fatal("'store_objects_per_bucket' should be larger than 0."); + + if (Config.Store.avgObjectSize <= 0) + fatal("'store_avg_object_size' should be larger than 0."); + /* Calculate size of hash table (maximum currently 64k buckets). */ /* this is very bogus, its specific to the any Store maintaining an * in-core index, not global */ diff -u -r -N squid-3.2.6/src/wccp2.cc squid-3.2.7/src/wccp2.cc --- squid-3.2.6/src/wccp2.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/wccp2.cc 2013-02-01 23:55:31.000000000 +1300 @@ -592,6 +592,7 @@ /* The password field, for the MD5 hash, needs to be 8 bytes and NUL padded. */ memset(pwd, 0, sizeof(pwd)); strncpy(pwd, password, sizeof(pwd)); + pwd[sizeof(pwd) - 1] = '\0'; ws = (struct wccp2_security_md5_t *) ptr; assert(ntohs(ws->security_type) == WCCP2_SECURITY_INFO); @@ -660,6 +661,7 @@ /* The password field, for the MD5 hash, needs to be 8 bytes and NUL padded. */ memset(pwd, 0, sizeof(pwd)); strncpy(pwd, srv->wccp_password, sizeof(pwd)); + pwd[sizeof(pwd) - 1] = '\0'; /* Take a copy of the challenge: we need to NUL it before comparing */ memcpy(md5_challenge, ws->security_implementation, 16); @@ -1008,7 +1010,8 @@ #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) { int i = IP_PMTUDISC_DONT; - setsockopt(theWccp2Connection, SOL_IP, IP_MTU_DISCOVER, &i, sizeof i); + if (setsockopt(theWccp2Connection, SOL_IP, IP_MTU_DISCOVER, &i, sizeof i) < 0) + debugs(80, 2, "WARNING: Path MTU discovery could not be disabled on FD " << theWccp2Connection << ": " << xstrerror()); } #endif @@ -1047,8 +1050,9 @@ /* Disconnect the sending socket. Note: FreeBSD returns error * but disconnects anyway so we have to just assume it worked */ - if (wccp2_numrouters > 1) - connect(theWccp2Connection, (struct sockaddr *) &null, router_len); + if (wccp2_numrouters > 1) { + (void)connect(theWccp2Connection, (struct sockaddr *) &null, router_len); + } } service_list_ptr = service_list_ptr->next; @@ -1606,10 +1610,9 @@ &service_list_ptr->wccp_packet, service_list_ptr->wccp_packet_size); } else { - send(theWccp2Connection, - &service_list_ptr->wccp_packet, - service_list_ptr->wccp_packet_size, - 0); + errno = 0; + if (send(theWccp2Connection, &service_list_ptr->wccp_packet, service_list_ptr->wccp_packet_size, 0) < static_cast(service_list_ptr->wccp_packet_size)) + debugs(80, 2, "ERROR: failed to send WCCPv2 HERE_I_AM packet to " << router << " : " << xstrerror()); } } @@ -1983,20 +1986,21 @@ if (ntohl(router_list_ptr->num_caches)) { /* send packet */ + /* FIXME INET6 : drop temp conversion */ + Ip::Address tmp_rtr(router); + if (wccp2_numrouters > 1) { - /* FIXME INET6 : drop temp conversion */ - Ip::Address tmp_rtr(router); comm_udp_sendto(theWccp2Connection, tmp_rtr, &wccp_packet, offset); } else { - send(theWccp2Connection, - &wccp_packet, - offset, - 0); + errno = 0; + if (send(theWccp2Connection, &wccp_packet, offset, 0) < static_cast(offset)) + debugs(80, 2, "ERROR: failed to send WCCPv2 HERE_I_AM packet to " << tmp_rtr << " : " << xstrerror()); } } + safe_free(weight); } service_list_ptr = service_list_ptr->next; diff -u -r -N squid-3.2.6/src/wccp.cc squid-3.2.7/src/wccp.cc --- squid-3.2.6/src/wccp.cc 2013-01-09 14:41:51.000000000 +1300 +++ squid-3.2.7/src/wccp.cc 2013-02-01 23:55:31.000000000 +1300 @@ -302,13 +302,18 @@ 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