]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Author: Leonid Evdokimov <leon@darkk.net.ru>
authorAmos Jeffries <squid3@treenet.co.nz>
Sun, 6 Feb 2011 08:36:12 +0000 (01:36 -0700)
committerAmos Jeffries <squid3@treenet.co.nz>
Sun, 6 Feb 2011 08:36:12 +0000 (01:36 -0700)
bootstrap.sh: Detect DEB package naming style of multiple autoconf versions

358 files changed:
CREDITS
ChangeLog
SPONSORS
acinclude/compiler-flags.m4
acinclude/krb5.m4
acinclude/os-deps.m4
bootstrap.sh
compat/GnuRegex.c
compat/Makefile.am
compat/compat.dox [new file with mode: 0644]
compat/compat_shared.h
compat/os/mswin.h
compat/os/solaris.h
compat/os/windows.h
compat/osdetect.h
compat/strnstr.cc [moved from lib/strnstr.cc with 96% similarity]
compat/xalloc.cc
compat/xalloc.h
compat/xis.h [new file with mode: 0644]
compat/xstring.cc
configure.ac [moved from configure.in with 97% similarity]
doc/Programming-Guide/02_CodingConventions.dox
doc/debug-sections.txt
doc/release-notes/release-3.1.sgml
doc/release-notes/release-3.2.sgml
errors/Makefile.am
errors/alias-upgrade
errors/fr.po
errors/hy.po
errors/templates/ERR_GATEWAY_FAILURE [new file with mode: 0644]
helpers/basic_auth/MSNT/msntauth.h
helpers/basic_auth/PAM/basic_pam_auth.cc
helpers/basic_auth/RADIUS/basic_radius_auth.cc
helpers/basic_auth/SMB/Makefile.am
helpers/basic_auth/SMB/basic_smb_auth.cc
helpers/basic_auth/SMB/basic_smb_auth.sh
helpers/basic_auth/SMB/config.test
helpers/basic_auth/SSPI/basic_sspi_auth.cc
helpers/basic_auth/SSPI/valid.cc
helpers/basic_auth/SSPI/valid.h
helpers/external_acl/AD_group/ext_ad_group_acl.cc
helpers/external_acl/LM_group/ext_lm_group_acl.cc
helpers/external_acl/eDirectory_userip/ext_edirectory_userip_acl.cc
helpers/external_acl/kerberos_ldap_group/config.test
helpers/external_acl/kerberos_ldap_group/support.h
helpers/external_acl/kerberos_ldap_group/support_log.cc
helpers/external_acl/wbinfo_group/config.test
helpers/log_daemon/DB/Makefile.am [new file with mode: 0644]
helpers/log_daemon/DB/config.test [new file with mode: 0755]
helpers/log_daemon/DB/doc/date_day_column.sql [new file with mode: 0644]
helpers/log_daemon/DB/doc/views.sql [new file with mode: 0644]
helpers/log_daemon/DB/log_db_daemon.pl.in [new file with mode: 0755]
helpers/log_daemon/Makefile.am
helpers/log_daemon/file/log_file_daemon.cc
helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc
helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc
helpers/ntlm_auth/fake/ntlm_fake_auth.cc
helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.cc
include/Range.h
include/config.h
include/fatal.h
include/radix.h
include/splay.h
include/squid_windows.h
include/sspwin32.h
include/strnstr.h [deleted file]
include/util.h
lib/Makefile.am
lib/MemPool.cc
lib/MemPoolChunked.cc
lib/MemPoolMalloc.cc
lib/libTrie/INSTALL
lib/libTrie/configure.ac [moved from lib/libTrie/configure.in with 100% similarity]
lib/libTrie/include/Trie.h
lib/libTrie/include/TrieCharTransform.h
lib/libTrie/include/TrieNode.h
lib/libTrie/src/Trie.cc
lib/libTrie/src/TrieNode.cc
lib/md5-test.c
lib/profiler/Profiler.h
lib/profiler/get_tick.h
lib/profiler/xprof_type.h
lib/rfc1123.c
lib/rfcnb/byteorder.h
lib/rfcnb/rfcnb-common.h
lib/rfcnb/rfcnb-error.h
lib/rfcnb/rfcnb-io.c
lib/rfcnb/rfcnb-io.h
lib/rfcnb/rfcnb-priv.h
lib/rfcnb/rfcnb-util.c
lib/rfcnb/rfcnb-util.h
lib/rfcnb/rfcnb.h
lib/rfcnb/session.c
lib/rfcnb/std-includes.h
lib/smblib/smbencrypt.c
lib/smblib/smblib-util.c
lib/smblib/smblib.c
mkrelease.sh
mksnapshot.sh
scripts/source-maintenance.sh
scripts/www/build-cfg-help.pl
snmplib/Makefile.am
snmplib/asn1.c
snmplib/snmp_pdu.c
snmplib/snmp_vars.c
src/CacheDigest.cc
src/CommCalls.h
src/ConfigOption.h
src/ConfigParser.cc
src/CpuAffinitySet.cc
src/Debug.h
src/DiskIO/AIO/AIODiskFile.cc
src/DiskIO/AIO/aio_win32.cc
src/DiskIO/AIO/aio_win32.h
src/DiskIO/AIO/async_io.h
src/DiskIO/DiskDaemon/DiskdFile.cc
src/DiskIO/DiskDaemon/DiskdIOStrategy.cc
src/DiskIO/DiskDaemon/diskd.cc
src/DiskIO/DiskThreads/aiops.cc
src/DiskIO/DiskThreads/aiops_win32.cc
src/HelperChildConfig.cc
src/HelperChildConfig.h
src/HttpHdrCc.cc
src/HttpHeader.cc
src/HttpHeaderRange.h
src/HttpMsg.cc
src/HttpRequest.cc
src/Makefile.am
src/MemBlob.cc
src/MemBuf.cc
src/MemObject.cc
src/ProfStats.cc
src/ProtoPort.cc
src/ProtoPort.h
src/SquidMath.cc
src/SquidMath.h
src/SquidTime.h
src/StatHist.cc
src/Store.h
src/StoreFileSystem.h
src/StoreHashIndex.h
src/StoreMeta.cc
src/StoreMetaUnpacker.cc
src/String.cc
src/String.cci
src/SwapDir.cc
src/SwapDir.h
src/acl/Asn.cc
src/acl/HttpStatus.cc
src/acl/SslErrorData.cc
src/acl/SslErrorData.h
src/acl/TimeData.cc
src/adaptation/ServiceConfig.cc
src/adaptation/ecap/Host.cc
src/adaptation/ecap/Host.h
src/adaptation/ecap/XactionRep.cc
src/adaptation/icap/icap_log.cc
src/auth/negotiate/auth_negotiate.cc
src/auth/ntlm/auth_ntlm.cc
src/base/AsyncCall.cc
src/base/AsyncCall.h
src/base/Subscription.h
src/base/TidyPointer.h
src/cache_cf.cc
src/cache_diff.cc
src/cache_manager.cc
src/cf.data.pre
src/cf_gen.cc
src/cf_gen_defines
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/AcceptLimiter.cc
src/comm/AcceptLimiter.h
src/comm/IoCallback.cc
src/comm/IoCallback.h
src/comm/ListenStateData.h [deleted file]
src/comm/Loops.h [new file with mode: 0644]
src/comm/Makefile.am
src/comm/ModDevPoll.cc [moved from src/comm_devpoll.cc with 96% similarity]
src/comm/ModEpoll.cc [moved from src/comm_epoll.cc with 86% similarity]
src/comm/ModKqueue.cc [moved from src/comm_kqueue.cc with 97% similarity]
src/comm/ModPoll.cc [moved from src/comm_poll.cc with 98% similarity]
src/comm/ModSelect.cc [moved from src/comm_select.cc with 96% similarity]
src/comm/ModSelectWin32.cc [moved from src/comm_select_win32.cc with 97% similarity]
src/comm/TcpAcceptor.cc [moved from src/comm/ListenStateData.cc with 53% similarity]
src/comm/TcpAcceptor.h [new file with mode: 0644]
src/comm_err_t.h
src/comm_kqueue.h [deleted file]
src/debug.cc
src/defines.h
src/disk.cc
src/dns_internal.cc
src/enums.h
src/err_detail_type.h
src/err_type.h
src/errorpage.cc
src/errorpage.h
src/esi/Esi.cc
src/esi/Expression.cc
src/esi/Include.cc
src/esi/Segment.cc
src/eui/Eui48.cc
src/external_acl.cc
src/fd.cc
src/filemap.cc
src/forward.cc
src/forward.h
src/fqdncache.cc
src/fs/coss/store_dir_coss.cc
src/fs/coss/store_io_coss.cc
src/fs/ufs/store_dir_ufs.cc
src/fs/ufs/ufscommon.cc
src/ftp.cc
src/globals.h
src/gopher.cc
src/helper.cc
src/htcp.cc
src/http.cc
src/icmp/Icmp4.cc
src/icmp/Icmp4.h
src/icmp/Icmp6.cc
src/icmp/IcmpPinger.cc
src/icmp/IcmpSquid.cc
src/icmp/net_db.cc
src/icp_v2.cc
src/ip/Address.cc
src/ip/Address.h
src/ipc/Coordinator.cc
src/ipc/Coordinator.h
src/ipc/FdNotes.cc
src/ipc/FdNotes.h
src/ipc/Forwarder.cc [new file with mode: 0644]
src/ipc/Forwarder.h [new file with mode: 0644]
src/ipc/Inquirer.cc [new file with mode: 0644]
src/ipc/Inquirer.h [new file with mode: 0644]
src/ipc/Makefile.am
src/ipc/Messages.h
src/ipc/Request.h [new file with mode: 0644]
src/ipc/Response.h [new file with mode: 0644]
src/ipc/StartListening.cc
src/ipc/Strand.cc
src/ipc/Strand.h
src/ipc/TypedMsgHdr.cc
src/ipc/UdsOp.cc
src/ipc/UdsOp.h
src/ipc/forward.h
src/ipc_win32.cc
src/ipcache.cc
src/log/Config.cc
src/log/Config.h
src/log/FormatHttpdCombined.cc [new file with mode: 0644]
src/log/FormatHttpdCommon.cc [moved from src/useragent.cc with 50% similarity]
src/log/FormatSquidCustom.cc [new file with mode: 0644]
src/log/FormatSquidIcap.cc [moved from src/referer.cc with 50% similarity]
src/log/FormatSquidNative.cc [new file with mode: 0644]
src/log/FormatSquidReferer.cc [moved from src/comm_epoll.h with 60% similarity]
src/log/FormatSquidUseragent.cc [moved from src/comm_select.h with 63% similarity]
src/log/Formats.h [new file with mode: 0644]
src/log/Gadgets.cc [new file with mode: 0644]
src/log/Gadgets.h [new file with mode: 0644]
src/log/Makefile.am
src/log/ModDaemon.cc
src/log/ModStdio.cc
src/log/ModTcp.cc
src/log/ModUdp.cc
src/log/Tokens.cc [new file with mode: 0644]
src/log/Tokens.h [new file with mode: 0644]
src/log/access_log.cc
src/main.cc
src/mgr/Forwarder.cc
src/mgr/Forwarder.h
src/mgr/FunAction.cc
src/mgr/InfoAction.cc
src/mgr/Inquirer.cc
src/mgr/Inquirer.h
src/mgr/Request.cc
src/mgr/Request.h
src/mgr/Response.cc
src/mgr/Response.h
src/mgr/StoreToCommWriter.cc
src/mgr/StoreToCommWriter.h
src/mime.cc
src/mk-string-arrays.awk
src/neighbors.cc
src/pconn.cc
src/peer_digest.cc
src/peer_proxy_negotiate_auth.cc
src/protos.h
src/recv-announce.cc
src/redirect.cc
src/refresh.cc
src/send-announce.cc
src/snmp/Forwarder.cc [new file with mode: 0644]
src/snmp/Forwarder.h [new file with mode: 0644]
src/snmp/Inquirer.cc [new file with mode: 0644]
src/snmp/Inquirer.h [new file with mode: 0644]
src/snmp/Makefile.am [new file with mode: 0644]
src/snmp/Pdu.cc [new file with mode: 0644]
src/snmp/Pdu.h [new file with mode: 0644]
src/snmp/Request.cc [new file with mode: 0644]
src/snmp/Request.h [new file with mode: 0644]
src/snmp/Response.cc [new file with mode: 0644]
src/snmp/Response.h [new file with mode: 0644]
src/snmp/Session.cc [new file with mode: 0644]
src/snmp/Session.h [new file with mode: 0644]
src/snmp/Var.cc [new file with mode: 0644]
src/snmp/Var.h [new file with mode: 0644]
src/snmp/forward.h [new file with mode: 0644]
src/snmp_core.cc
src/snmp_core.h [new file with mode: 0644]
src/squid.h
src/ssl/ErrorDetail.cc [new file with mode: 0644]
src/ssl/ErrorDetail.h [new file with mode: 0644]
src/ssl/Makefile.am
src/ssl/crtd_message.cc
src/ssl/gadgets.cc
src/ssl/gadgets.h
src/ssl/support.cc
src/ssl/support.h
src/stat.cc
src/stmem.cc
src/store_client.cc
src/store_dir.cc
src/store_key_md5.cc
src/store_log.cc
src/store_swapmeta.cc
src/store_swapout.cc
src/structs.h
src/test_cache_digest.cc
src/tests/TestSwapDir.cc
src/tests/TestSwapDir.h
src/tests/stub_HelperChildConfig.cc
src/tests/stub_cache_manager.cc
src/tests/stub_comm.cc
src/tests/stub_ipc_Forwarder.cc [new file with mode: 0644]
src/tests/stub_store.cc
src/tests/testStore.cc
src/tests/testStore.h
src/time.cc
src/tools.cc
src/typedefs.h
src/url.cc
src/urn.cc
src/wccp.cc
src/wccp2.cc
test-suite/buildtest.sh
test-suite/buildtests/layer-01-minimal.opts
test-suite/buildtests/layer-02-maximus.opts
test-suite/pconn-banger.c
test-suite/testheaders.sh
tools/Makefile.am
tools/squidclient.cc

diff --git a/CREDITS b/CREDITS
index 3138fc61afcc7bc525c200b0297b0aed0bd24ca3..400230b5218077b7c55e756885d6d1ba451c5520 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -524,3 +524,13 @@ helpers/external_acl/kerberos_ldap_group/support_ldap.cc
  * <http://www.OpenLDAP.org/license.html>.
  */
 
+==============================================================================
+
+helpers/log_daemon/DB/doc/:
+helpers/log_daemon/DB/log_db_daemon.pl.in:
+
+  Copyright (C) 2008 by Marcello Romani
+
+  This library is free software; you can redistribute it and/or modify
+  it under the same terms as Perl itself, either Perl version 5.8.8 or,
+  at your option, any later version of Perl 5 you may have available.
index 8482c3b05a331500c8e27483b8e9044100a6f34b..b25494b66d6f86743f030a902036b4d5dff601a2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+Changes to squid-3.2.0.4 (22 Dec 2010):
+
+       - Port 2.x: cache_dir min-size setting
+       - Bug 3059: Crash on digest auth headers with unknown nonce
+       - Fix cachemgr reported HTTP/ICP requests/messages per minute when multiple workers used
+       - Fix cachemgr mem-pools reporting
+       - Add Dynamic SSL certificate generation
+       - Add useragent, referer, combined built-in log formats
+       - Obsolete log_fqdn directive
+       - Obsolete useragent/referer/forward_log directives
+       - HTTP/1.1: Send 1.1 on CONNECT responses
+       - Updated Kerberos support for newer GSSAPI releases
+       - Improve handling of adapted body delivery failures in REQMOD request satisfaction mode
+       - Improve handling of early eCAP transaction failures
+       - Various ext_edirectory_acl fixes
+       - ... all bug and feature fixes included in 3.1.10 release
+       - ... and a lot of code and documentation polishing
+
 Changes to squid-3.2.0.3 (07 Nov 2010):
 
        - Regression fix: SMP broke ICP outgoing IP lookup if no udp_outgoing_addr set
@@ -89,6 +107,30 @@ Changes to squid-3.2.0.1 (03 Aug 2010):
        - ... and a great many testing improvements
        - ... and many documentation updates
 
+Changes to squid-3.1.10 (22 Dec 2010):
+
+       - Bug 3121: memory leak in DigestAuth: AuthUser object is locked twice
+       - Bug 3113: Consuming too much memory when uploading files
+       - Bug 3110: 'reply_body_max_size none' does not work with x-forwarded-for
+       - Bug 3096: Consuming too much memory when delaying traffic
+       - Bug 3091: Bypassed ICAP errors are not counted as service failures
+       - Bug 3090: Polish FTP login error handing
+       - Bug 3068: cache_dir capacity and usage overflows
+       - Bug 3028: Permit wbinfo_group.pl to authenticate Kerberos users with NT domain
+       - Bug  427: HTTP Compliance: Support If-Match and If-None-Match requests
+       - Fix memory leak in adaptation_access
+       - Fix /dev/poll and poll() selection priority
+       - Fix PREFIX/var/run creation during install
+       - Fix cachemgr http_port config report display
+       - Add upgrade help process for obsolete options
+       - Accept RFC 2965 Set-Cookie2 / Cookie2 headers as 'known'
+       - HTTP/1.1: entry is stale if request has max-age=0
+       - HTTP/1.1: do not forward TRACE with Max-Forwards: 0 after REQMOD
+       - Toolchain update to support newer auto-tools
+       - ... and updated error page translations
+       - ... and updated documentation
+       - ... and some code optimization/simplification polish
+
 Changes to squid-3.1.9 (25 Oct 2010):
 
        - Bug 3088: dnsserver is segfaulting
index 02855238f13128718da5dc2f9f211651e147634e..1c570e925fa3e28b322ab32d57b07aebbebe5be3 100644 (file)
--- a/SPONSORS
+++ b/SPONSORS
@@ -82,3 +82,9 @@ BBC (UK) and Siemens IT Solutions and Services (UK)
 
        Provided developement and testing resources for Solaris /dev/poll
        support.
+
+Yahoo! Inc. - http://www.yahoo.com/
+
+       Yahoo! Inc. supported the development of improved refresh
+       logics. Many thanks to Yahoo! Inc. for supporting the development
+       of these features.
index 65221c7e4b78496552097e85f1b3f8a98ff6a09f..5b4a5fb852bf48c712d4d539055132f3512a1078 100644 (file)
@@ -86,6 +86,15 @@ AC_DEFUN([SQUID_CC_GUESS_VARIANT], [
 #endif
     ]])],[squid_cv_compiler="sunstudio"],[])
   fi
+  dnl Intel CC
+  if test -z "$squid_cv_compiler" ; then
+   AC_COMPILE_IFELSE([
+    AC_LANG_PROGRAM([[
+#if !defined(__ICC)
+#error "not Intel(R) C++ Compiler"
+#endif
+    ]])],[squid_cv_compiler="icc"],[])
+  fi
   dnl end of block to be repeated
   if test -z "$squid_cv_compiler" ; then
    squid_cv_compiler="none"
@@ -122,6 +131,13 @@ AC_DEFUN([SQUID_CC_GUESS_OPTIONS], [
    squid_cv_cc_option_optimize="-fast"
    squid_cv_cc_arg_pipe=""
    ;;
+  icc) 
+   squid_cv_cxx_option_werror="-Werror"
+   squid_cv_cc_option_werror="$squid_cv_cxx_option_werror" 
+   squid_cv_cc_option_wall="-Wall"
+   squid_cv_cc_option_optimize="-O2"
+   squid_cv_cc_arg_pipe=""
+   ;;
   *) 
    squid_cv_cxx_option_werror="" 
    squid_cv_cc_option_werror="" 
index f572b3da99a2be2038c7f0fb546e6f09bae3f385..19dfd31668d2c845d8cabb39535c64ec70c79d7e 100644 (file)
@@ -27,7 +27,7 @@ dnl along with this program; if not, write to the Free Software
 dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
 
 dnl these checks must be performed in the same order as here defined,
-dnl and have mostly been lifted out of an inlined configure.in.
+dnl and have mostly been lifted out of an inlined configure.ac.
 
 dnl checks for a broken solaris header file, and sets squid_cv_broken_krb5_h
 dnl to yes if that's the case
@@ -51,6 +51,42 @@ int i;
 ]) dnl SQUID_CHECK_KRB5_SOLARIS_BROKEN_KRB5_H
 
 
+AC_DEFUN([SQUID_CHECK_KRB5_HEIMDAL_BROKEN_KRB5_H], [
+  AC_CACHE_CHECK([for broken Heimdal krb5.h],squid_cv_broken_heimdal_krb5_h, [
+    AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#include <krb5.h>
+int
+main(void)
+{
+        krb5_context context;
+
+        krb5_init_context(&context);
+
+        return 0;
+}
+]])], [ squid_cv_broken_heimdal_krb5_h=no ], [
+    AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#if defined(__cplusplus)
+extern "C" {
+#endif
+#include <krb5.h>
+#if defined(__cplusplus)
+}
+#endif
+int
+main(void)
+{
+        krb5_context context;
+
+        krb5_init_context(&context);
+
+        return 0;
+}
+]])], [ squid_cv_broken_heimdal_krb5_h=yes ], [ squid_cv_broken_heimdal_krb5_h=no ])
+    ])
+  ])
+]) dnl SQUID_CHECK_KRB5_HEIMDAL_BROKEN_KRB5_H
+
 dnl check the max skew in the krb5 context, and sets squid_cv_max_skew_context
 AC_DEFUN([SQUID_CHECK_MAX_SKEW_IN_KRB5_CONTEXT],[
   AC_CACHE_CHECK([for max_skew in struct krb5_context],
@@ -195,7 +231,13 @@ AC_DEFUN([SQUID_CHECK_WORKING_KRB5],[
 KRB5INT_BEGIN_DECLS
 #endif
 #endif
+#if HAVE_BROKEN_HEIMDAL_KRB5_H
+extern "C" {
 #include <krb5.h>
+}
+#else
+#include <krb5.h>
+#endif
 #endif
 
 int
index a71c8ecb43ce8ab71b30f149bad0d6856bb60bbe..dfe1433462dc3837f2568c75ceec99738521a987 100644 (file)
@@ -837,3 +837,27 @@ AC_DEFUN([SQUID_CHECK_SETRESUID_WORKS],[
     squid_cv_resuid_works="no" ],[:])
   )
 ])
+
+dnl check that we have functional CPU clock access for the profiler
+dnl sets squid_cv_profiler_works to "yes" or "no"
+
+AC_DEFUN([SQUID_CHECK_FUNCTIONAL_CPU_PROFILER],[
+  AC_CACHE_CHECK([for operational CPU clock access], 
+                 squid_cv_cpu_profiler_works,
+    AC_PREPROC_IFELSE([AC_LANG_SOURCE([[
+#if defined(__GNUC__) && ( defined(__i386) || defined(__i386__) )
+// okay
+#elif defined(__GNUC__) && ( defined(__x86_64) || defined(__x86_64__) )
+// okay
+#elif defined(__GNUC__) && defined(__alpha)
+// okay
+#elif defined(_M_IX86) && defined(_MSC_VER) /* x86 platform on Microsoft C Compiler ONLY */
+// okay
+#else
+#error This CPU is unsupported. No profiling available here.
+#endif
+  ]])],[
+  squid_cv_cpu_profiler_works=yes],[
+  squid_cv_cpu_profiler_works=no])
+  )
+])
index bdccd29e265d59106236ed63fa157649acf0ad02..9a2d1add497b647a1491a3c7f815755c1aad7ce5 100755 (executable)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Used to setup the configure.in, autoheader and Makefile.in's if configure
+# Used to setup the configure.ac, autoheader and Makefile.in's if configure
 # has not been generated. This script is only needed for developers when
 # configure has not been run, or if a Makefile.am in a non-configured directory
 # has been updated
@@ -7,9 +7,9 @@
 # Autotool versions preferred. To override either edit the script
 # to match the versions you want to use, or set the variables on
 # the command line like "env acver=.. amver=... ./bootstrap.sh"
-acversions="${acver:-2.64 2.63 2.62 2.61}"
-amversions="${amver:-1.11 1.10 1.9}"
-ltversions="${ltver:-2.2}"
+acversions="${acver:-.}" # 2.68 2.67 2.66 2.65 2.64 2.63 2.62 2.61}"
+amversions="${amver:-.}" # 1.11 1.10 1.9}"
+ltversions="${ltver:-.}" # 2.2}"
 
 check_version()
 {
@@ -19,24 +19,8 @@ check_version()
 show_version()
 {
   tool=$1
-  found="NOT_FOUND"
-  shift
-  versions="$*"
-  for version in $versions; do
-    for variant in "" "${version}" "-${version}" "`echo $version | sed -e 's/\.//g'`"; do
-      if check_version $tool ${tool}${variant} $version; then
-       found="${version}"
-       break
-      fi
-    done
-    if [ "x$found" != "xNOT_FOUND" ]; then
-      break
-    fi
-  done
-  if [ "x$found" = "xNOT_FOUND" ]; then
-    found="??"
-  fi
-  echo $found
+  variant=$2
+  ${tool}${variant} --version 2>/dev/null | head -1 | sed -e 's/.*) //'
 }
 
 find_variant()
@@ -92,7 +76,7 @@ bootstrap_libtoolize() {
 
     # TODO: when we have libtool2, tell libtoolize where to put its files
     # instead of manualy moving files from ltdl to lib/libLtdl
-    if egrep -q '^[[:space:]]*AC_LIBLTDL_' configure.in
+    if egrep -q '^[[:space:]]*AC_LIBLTDL_' configure.ac
     then
        ltdl="--ltdl"
     else
@@ -122,9 +106,9 @@ acver=`find_variant autoconf ${acversions}`
 ltver=`find_variant libtool ${ltversions}`
 
 # Produce debug output about what version actually found.
-amversion=`show_version automake ${amversions}`
-acversion=`show_version autoconf ${acversions}`
-ltversion=`show_version libtool ${ltversions}`
+amversion=`show_version automake "${amver}"`
+acversion=`show_version autoconf "${acver}"`
+ltversion=`show_version libtool "${ltver}"`
 
 # Find the libtool path to get the right aclocal includes
 ltpath=`find_path libtool$ltver`
index 86cdc2962fa4f5beb32ff8691ae54d445e413bff..3bfa598942fa3e011b62b25d06d594f3305fecf4 100644 (file)
@@ -214,7 +214,7 @@ char *alloca();
 /* Assumes a `char *destination' variable.  */
 #define REGEX_REALLOCATE(source, osize, nsize)                         \
   (destination = (char *) alloca (nsize),                              \
-   xmemcpy (destination, source, osize),                               \
+   memcpy (destination, source, osize),                                \
    destination)
 
 #endif /* not REGEX_MALLOC */
index 21abe287e7f852ac3024072b72fe79ee0d8de829..671c5106d1d0ab293290b0625e9ae5f262380cb6 100644 (file)
@@ -32,6 +32,7 @@ libcompat_squid_a_SOURCES = \
        osdetect.h \
        psignal.h \
        stdvarargs.h \
+       strnstr.cc \
        strsep.h \
        strtoll.h \
        tempnam.h \
@@ -40,6 +41,7 @@ libcompat_squid_a_SOURCES = \
        valgrind.h \
        xalloc.cc \
        xalloc.h \
+       xis.h \
        xstrerror.cc \
        xstrerror.h \
        xstring.cc \
diff --git a/compat/compat.dox b/compat/compat.dox
new file mode 100644 (file)
index 0000000..bcad2ef
--- /dev/null
@@ -0,0 +1,96 @@
+/**
+\defgroup compat Portability Library
+
+\title Squid Portability
+
+
+\section 1 Aim
+
+\par 
+Squid aims to build and run on many modern systems. To do this we have traditionally
+added small hacks and wrappers all over the code whenever one was needed.
+The final result of that is a vast amount of code duplication, dodgy licensing on
+some older hacks, and some cases of obsolete algorithms sitting side by side with their
+current equivalent.
+
+\par
+The Portability library libcompat-squid.la has been created to correct the three issues of
+stable build portability, code cleanliness, and clearer licensing.
+
+
+\section 2 Requirements
+
+\par
+The system calls used by Squid are not required to be standard. Often we depend on
+some non-standard call which can give great performance benefits.
+But they are required to meet several other criteria:
+ \li  They must be of actual benefit to Squid during its operation.
+ \li  A better alternative must not exist.
+ \li  If not available on all OS an open-source GPLv2+ implementation must be available
+      to be included with the Squid sources and used when required.
+
+\par
+To be built into the libcompat-squid.la as a layer below all Squid-bundled binaries. The code
+must also qualify by being provided natively by some OS where Squid builds. \br
+Code and Algorithms which do not meet this final criteria are relegated to the slightly
+higher level of basic component, rather than portability.
+
+
+\section 3 Component Types
+
+\par Macro re-definition
+Where the only difference between systems is their naming scheme. One of the schemes is
+chosen by the developers for use and mappings are created in the form of Macros.
+
+\par Inline Functions
+
+\par Algorithm Templates and Inline functions
+Being C++ we are able to use templates in place of inline functions where that is more
+convenient. Care is taken to provide no additional requirements upon the callers when
+using the template as to when using the native constructs.
+
+\par Emulators
+As mentioned above if a useful library function calls or global is not available on all
+operating systems a GPLv2+ alternative may be added to the compat layer. As an emulator
+it retains the exact naming and definition of the source systems. Thus being able to be
+used seamlessly across all platforms by the main code.
+
+\par Wrappers
+Sometimes common and useful library functions are not always as safe as they could be.
+An alternative which wraps the original in extra safety checks is provided under the
+same name with an 'x' pre-pended. Currently these extra protections are added on string
+handling and memory allocation.
+
+
+\section 4 Layout
+The internal code structure of libcompat-squid.la files has a hierarchy. The API has a flat
+global scope separate from the file layout. The API is pulled in by including compat/compat.h.
+The strict dependency requirements which exist within the compat API make including
+individual part separately a risky operation.
+
+\par
+Squid coding guidelines require each .c and .cc file to include config.h or squid.h first
+in their included files. config.h begin with an order-specific sequence of defines and
+includes compat/compat.h to incorporate the compat layer appropriately in every soure file.
+squid.h begins by including config.h to prepare for its sub-includes and definitions.
+
+\par
+Internally the compat/ directory contains the public API file compat/compat.h which structures
+order-specific includes as documented inside that file. Included by that is compat/osdetect.h
+which determines which operating system and in some cases compiler is being used.
+
+\par
+The compat/os/ directory contains separate files for each supported system which requires
+special compat layer handling. Hacks for specific systems should be restricted to these files
+as much as possible.
+
+\par
+compat/compat_shared.h file contains the shared portability definitions which are shared
+across a great many systems. These should be written with protective macros to prevent any
+symbols or code being defined which is not necessary. Protections here must not be system-specific.
+
+\par
+Also in compat/ directory are the .h and .c files for emulators detected by autoconf. These
+are added by autoconf to the build objects as required.
+
+*/
index 6e63e635bdbb1da68def1b824d5ecae01b52f39c..94644419ba35d29242e3809bb5ba8415254232d8 100644 (file)
@@ -205,6 +205,45 @@ extern "C" {
 #include "compat/xstrerror.h"
 #include "compat/xstring.h"
 #include "compat/xstrto.h"
+#include "compat/xis.h"
 
+#if !HAVE_MEMCPY
+#if HAVE_BCOPY
+#define memcpy(d,s,n) bcopy((s),(d),(n))
+#elif HAVE_MEMMOVE
+#define memcpy(d,s,n) memmove((d),(s),(n))
+#endif
+#endif
+
+#if !HAVE_MEMMOVE && HAVE_BCOPY
+#define memmove(d,s,n) bcopy((s),(d),(n))
+#endif
+
+/*
+ * strnstr() is needed. The OS may not provide a working copy.
+ */
+#if HAVE_STRNSTR
+/* If strnstr exists and is usable we do so. */
+#define squid_strnstr(a,b,c)    strnstr(a,b,c)
+#else
+/* If not we have our own copy imported from FreeBSD */
+const char * squid_strnstr(const char *s, const char *find, size_t slen);
+#endif
+
+#if __GNUC__
+#if !defined(PRINTF_FORMAT_ARG1)
+#define PRINTF_FORMAT_ARG1 __attribute__ ((format (printf, 1, 2)))
+#endif
+#if !defined(PRINTF_FORMAT_ARG2)
+#define PRINTF_FORMAT_ARG2 __attribute__ ((format (printf, 2, 3)))
+#endif
+#if !defined(PRINTF_FORMAT_ARG3)
+#define PRINTF_FORMAT_ARG3 __attribute__ ((format (printf, 3, 4)))
+#endif
+#else /* !__GNU__ */
+#define PRINTF_FORMAT_ARG1
+#define PRINTF_FORMAT_ARG2
+#define PRINTF_FORMAT_ARG3
+#endif
 
 #endif /* _SQUID_COMPAT_SHARED_H */
index f59dd621d8a1d272a796d8b59dd011919d577de8..2ba94f92c2ce09d98f79d83d72841dad8bc0d7d1 100644 (file)
@@ -34,7 +34,7 @@
 #ifndef SQUID_OS_MSWIN_H
 #define SQUID_OS_MSWIN_H
 
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
 
 #define ACL WindowsACL
 #if defined(_MSC_VER) /* Microsoft C Compiler ONLY */
@@ -749,5 +749,14 @@ struct rusage {
 SQUIDCEXTERN size_t getpagesize(void);
 #endif
 
-#endif /* _SQUID_WIN32_ */
+/* gcc doesn't recognize the Windows native 64 bit formatting tags causing
+ * the compile fail, so we must disable the check on native Windows.
+ */
+#if __GNUC__
+#define PRINTF_FORMAT_ARG1
+#define PRINTF_FORMAT_ARG2
+#define PRINTF_FORMAT_ARG3
+#endif
+
+#endif /* _SQUID_WINDOWS_ */
 #endif /* SQUID_OS_MSWIN_H */
index c833615330e449ce4f99cf12256d9b9e1168565a..750e1652bc77269697d683103ada25b8f90116b8 100644 (file)
@@ -42,7 +42,6 @@ typedef union {
 #include <sys/resource.h>
 SQUIDCEXTERN int getrusage(int, struct rusage *);
 
-
 /**
  * prototypes for system function missing from system includes
  * on some Solaris systems.
index e49fd28c9972b0e6b5d503988a33a52739ff9ad5..05d9bcc3ec32e3811ead7226b37cc0e6675197e6 100644 (file)
@@ -33,7 +33,7 @@
 #ifndef SQUID_OS_WINDOWS_H
 #define SQUID_OS_WINDOWS_H
 
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
 
 #ifndef ACL
 #define ACL WindowsACL
@@ -45,5 +45,5 @@
 #undef _MSWIN_ACL_WAS_NOT_DEFINED
 #endif
 
-#endif /* _SQUID_WIN32_ */
+#endif /* _SQUID_WINDOWS_ */
 #endif /* SQUID_OS_WINDOWS_H */
index e5a08904e516899a57d50654069187fdc85fadeb..258e082ac34bf83db254db8d219518a07db3caf6 100644 (file)
 #elif defined(__DragonFly__)
 #define _SQUID_DRAGONFLY_ 1
 
-#elif defined(__CYGWIN32__)  || defined(__CYGWIN__)
+#elif defined(__CYGWIN32__) || defined(__CYGWIN__)
 #define _SQUID_CYGWIN_ 1
-#define _SQUID_WIN32_ 1
+#define _SQUID_WINDOWS_ 1
+
+#elif defined(__MINGW32__) || defined(__MINGW__)
+#define _SQUID_MINGW_ 1
+#define _SQUID_WINDOWS_ 1
 
 #elif defined(WIN32) || defined(WINNT) || defined(__WIN32__) || defined(__WIN32)
 /* We are using _SQUID_MSWIN_ define in cf.data.pre, so
    it must be defined to 1 to avoid the build failure of cfgen.
  */
 #define _SQUID_MSWIN_ 1
-#define _SQUID_WIN32_ 1
+#define _SQUID_WINDOWS_ 1
 
 #elif defined(__APPLE__)
 #define _SQUID_APPLE_ 1
similarity index 96%
rename from lib/strnstr.cc
rename to compat/strnstr.cc
index 4d7676fdb6ffe977cb76d09e8e23491e19585e50..3c86e170c00eb7a88dd3b5ad35d49536d137f60a 100644 (file)
@@ -1,5 +1,6 @@
-#ifndef _SQUID_COMPAT_STRNSTR_C_
-#define _SQUID_COMPAT_STRNSTR_C_
+#ifndef _SQUID_COMPAT_STRNSTR_CC_
+#define _SQUID_COMPAT_STRNSTR_CC_
+
 /*
  *  Shamelessly duplicated from the FreeBSD public sources
  *  for use by the Squid Project under GNU Public License.
@@ -17,7 +18,6 @@
  */
 
 #include "config.h"
-#include "strnstr.h"
 
 #if !HAVE_STRNSTR
 
@@ -65,7 +65,7 @@
 #include <string.h>
 #endif
 
-/*
+/**
  * Find the first occurrence of find in s, where the search is limited to the
  * first slen characters of s.
  */
@@ -93,4 +93,4 @@ squid_strnstr(const char *s, const char *find, size_t slen)
 }
 
 #endif /* !HAVE_STRNSTR */
-#endif /* _SQUID_COMPAT_STRNSTR_C_ */
+#endif /* _SQUID_COMPAT_STRNSTR_CC_ */
index c1e59773c617db1b55f936d946c7b6aa3611f0e5..f7bcfe22b7d53f953bbe2057b1c075c0165b0906 100644 (file)
@@ -56,7 +56,7 @@ malloc_statistics(void (*func) (int, int, int, void *), void *data)
     for (; i <= XMS_DBG_MAXSIZE; i += XMS_DBG_GRAIN)
         func(i, malloc_sizes[XMS_DBG_INDEX(i)], malloc_histo[XMS_DBG_INDEX(i)], data);
 
-    xmemcpy(&malloc_histo, &malloc_sizes, sizeof(malloc_sizes));
+    memcpy(&malloc_histo, &malloc_sizes, sizeof(malloc_sizes));
 }
 #endif /* XMALLOC_STATISTICS */
 
@@ -79,7 +79,7 @@ xcalloc(size_t n, size_t sz)
         if (failure_notify) {
             static char msg[128];
             snprintf(msg, 128, "xcalloc: Unable to allocate %Zu blocks of %Zu bytes!\n", n, sz);
-            (*failure_notify) (msg);
+            failure_notify(msg);
         } else {
             perror("xcalloc");
         }
@@ -120,7 +120,7 @@ xmalloc(size_t sz)
         if (failure_notify) {
             static char msg[128];
             snprintf(msg, 128, "xmalloc: Unable to allocate %Zu bytes!\n", sz);
-            (*failure_notify) (msg);
+            failure_notify(msg);
         } else {
             perror("malloc");
         }
@@ -168,7 +168,7 @@ xrealloc(void *s, size_t sz)
         if (failure_notify) {
             static char msg[128];
             snprintf(msg, 128, "xrealloc: Unable to reallocate %Zu bytes!\n", sz);
-            (*failure_notify) (msg);
+            failure_notify(msg);
         } else {
             perror("realloc");
         }
index fd9260145924436651b69f5a97fae33464d35a0a..1d86f404e240873374684da1845fcbc31e512296 100644 (file)
@@ -62,13 +62,12 @@ extern "C" {
      */
 #define safe_free(x)    while (x) { xxfree(x); (x) = NULL; }
 
-
-#if XMALLOC_STATISTICS
-    void malloc_statistics(void (*func) (int, int, int, void *), void *data);
-#endif
-
 #ifdef __cplusplus
 }
 #endif
 
+#if XMALLOC_STATISTICS
+extern void malloc_statistics(void (*func) (int, int, int, void *), void *data);
+#endif
+
 #endif /* _SQUID_COMPAT_XALLOC_H */
diff --git a/compat/xis.h b/compat/xis.h
new file mode 100644 (file)
index 0000000..0e5eac1
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef _SQUID_COMPAT_XIS_H
+#define _SQUID_COMPAT_XIS_H
+
+#if HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+#define xisspace(x) isspace((unsigned char)x)
+#define xtoupper(x) toupper((unsigned char)x)
+#define xtolower(x) tolower((unsigned char)x)
+#define xisdigit(x) isdigit((unsigned char)x)
+#define xisascii(x) isascii((unsigned char)x)
+#define xislower(x) islower((unsigned char)x)
+#define xisalpha(x) isalpha((unsigned char)x)
+#define xisprint(x) isprint((unsigned char)x)
+#define xisalnum(x) isalnum((unsigned char)x)
+#define xiscntrl(x) iscntrl((unsigned char)x)
+#define xispunct(x) ispunct((unsigned char)x)
+#define xisupper(x) isupper((unsigned char)x)
+#define xisxdigit(x) isxdigit((unsigned char)x)
+#define xisgraph(x) isgraph((unsigned char)x)
+
+#endif /* _SQUID_COMPAT_XIS_H */
index 1e8376cace7ab35f68044c95188548329803cc8f..34d2ecd8a9d5c738cc15b0888ee7a291b907a3a7 100644 (file)
@@ -61,17 +61,9 @@ xstrndup(const char *s, size_t n)
         }
         exit(1);
     }
-    if (n < 0) {
-        errno = EINVAL;
-        if (failure_notify) {
-            (*failure_notify) ("xstrndup: tried to dup a negative length string!\n");
-        } else {
-            perror("xstrndup: tried to dup a negative length string!");
-        }
-        exit(1);
-    }
 
     sz = strlen(s) + 1;
+    // size_t is unsigned, as mandated by c99 and c++ standards.
     if (sz > n)
         sz = n;
 
similarity index 97%
rename from configure.in
rename to configure.ac
index d557f397b0ab15d6a9a1bf6edddef4a3cec30015..27454acbf680cd34d175f5b0081a453de5b6afab 100644 (file)
@@ -37,8 +37,13 @@ AC_LANG([C++])
 AC_CANONICAL_HOST
 
 AC_MSG_CHECKING([simplified host os])
-squid_host_os=`echo $host_os|sed 's/[0-9].*//;s/-.*//g'`
+simple_host_os=`echo $host_os|sed 's/[0-9].*//g;s/-.*//g'`
 squid_host_os_version=`echo $host_os|tr -d "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-"`
+if test -n "$squid_host_os_version"; then
+       squid_host_os="`echo $simple_host_os| sed s/$squid_host_os_version//g`"
+else
+       squid_host_os="$simple_host_os"
+fi
 AC_MSG_RESULT($squid_host_os (version $squid_host_os_version))
 # on windows squid_host_os is either mingw or cygwin, version is 32
 
@@ -276,14 +281,20 @@ fi
 
 dnl set squid required flags
 if test "x$GCC" = "xyes"; then
+  case "$squid_host_os" in
+  mingw)
 dnl Guido Serassio (serassio@squid-cache.org) 20070811
 dnl Using the latest MinGW (gcc 3.4.5 + mingw-runtime 3.13) cannot build with
 dnl -Werror -Wmissing-prototypes -Wmissing-declarations
 dnl TODO: check if the problem will be present in any other newer MinGW release.
-  case "$host_os" in
-  mingw|mingw32)
     SQUID_CFLAGS="$squid_cv_cc_option_wall -Wpointer-arith -Wwrite-strings -Wcomments"
     ;;
+  freebsd)
+    # FreeBSD places local libraries and packages in /usr/local
+    CFLAGS="$CFLAGS -I/usr/local/include"
+    CXXFLAGS="$CXXFLAGS -I/usr/local/include"
+    LDFLAGS="$LDFLAGS -L/usr/local/lib -Wl,-R/usr/local/lib"
+    ;;
   *)
     SQUID_CFLAGS="$squid_cv_cc_option_wall -Wpointer-arith -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wcomments"
     ;;
@@ -503,10 +514,15 @@ for module in $squid_disk_module_candidates none; do
             AC_MSG_NOTICE([Windows threads support automatically enabled])
             ;;
           freebsd)
-            SQUID_CFLAGS="$SQUID_CFLAGS -D_REENTRANT"
-            SQUID_CXXFLAGS="$SQUID_CXXFLAGS -D_REENTRANT"
-            if test "x$GCC" = "xyes" -a "x$PRESET_LDFLAGS" = "x" ; then
-              LDFLAGS="$LDFLAGS -pthread"
+            if test `echo "$squid_host_os_version" | cut -b1` -lt 7 ; then
+                AC_MSG_NOTICE(pthread library requires FreeBSD 7 or later)
+                squid_opt_use_diskthreads="no"
+            else
+              SQUID_CFLAGS="$SQUID_CFLAGS -D_REENTRANT"
+              SQUID_CXXFLAGS="$SQUID_CXXFLAGS -D_REENTRANT"
+              if test "x$GCC" = "xyes" -a "x$PRESET_LDFLAGS" = "x" ; then
+                LDFLAGS="$LDFLAGS -pthread"
+              fi
             fi
             ;;
           solaris)
@@ -573,8 +589,8 @@ for module in $squid_disk_module_candidates none; do
         else
           dnl Windows does things differently. We provide wrappers.
           dnl TODO: Windows really needs its own DiskIO module or its Overlaped IO
-          case "$host_os" in
-            mingw|mingw32)
+          case "$squid_host_os" in
+            mingw)
               squid_opt_use_aio="yes"
               AC_MSG_NOTICE([Windows being built. Maybe-enable POSIX AIO.])
               ;;
@@ -594,8 +610,8 @@ for module in $squid_disk_module_candidates none; do
         DISK_MODULES="$DISK_MODULES AIO"
         DISK_LIBS="$DISK_LIBS libAIO.a"
         DISK_LINKOBJS="$DISK_LINKOBJS DiskIO/AIO/AIODiskIOModule.o"
-        case "$host_os" in
-          mingw|mingw32)
+        case "$squid_host_os" in
+          mingw)
             USE_AIO_WIN32=1
             AC_MSG_NOTICE([Replacing AIO DiskIO module with: Windows overlapped I/O support])
             ;;
@@ -693,7 +709,7 @@ for fs in $squid_storeio_module_candidates none; do
       if ! test "x$squid_disk_module_candidates_AIO" = "xyes"; then
         AC_MSG_ERROR([COSS requires POSIX AIO which is not available.])
       fi
-      # Automake om MinGW needs explicit exe extension
+      # Automake on MinGW needs explicit exe extension
       # for STORE_TESTS substition
       STORE_TESTS="$STORE_TESTS tests/testCoss$EXEEXT"
       ;;
@@ -776,7 +792,7 @@ AC_ARG_ENABLE(delay-pools,
 [ if test "x$enableval" = "xyes" ; then
     AC_MSG_NOTICE([Delay pools enabled])
     AC_DEFINE([USE_DELAY_POOLS],1,[Traffic management via "delay pools".])
-    AM_CONDITIONAL(ENABLE_DELAY_POOLS, true,)
+    AM_CONDITIONAL(ENABLE_DELAY_POOLS, true)
   fi
 ])
 
@@ -819,16 +835,26 @@ AC_ARG_WITH(libxml2, AS_HELP_STRING([--without-libxml2],[Do not use libxml2 for
 if test "x$squid_opt_use_esi" = "xyes" -a "x$with_libxml2" != "xno" ; then
   AC_CHECK_LIB([xml2], [main], [XMLLIB="-lxml2"; HAVE_LIBXML2=1])
   dnl Find the main header and include path...
+  ac_cv_libxml2_include='no'
   AC_CHECK_HEADERS([libxml/parser.h], [], [
+      AC_MSG_NOTICE([Testing in /usr/include/libxml2])
       SAVED_CPPFLAGS="$CPPFLAGS"
       CPPFLAGS="-I/usr/include/libxml2 $CPPFLAGS"
       unset ac_cv_header_libxml_parser_h
-      AC_CHECK_HEADERS([libxml/parser.h], [ac_cv_libxml2_include=yes], [])
+      AC_CHECK_HEADERS([libxml/parser.h], [ac_cv_libxml2_include="/usr/include/libxml2"], [])
       CPPFLAGS="$SAVED_CPPFLAGS"
+      if test "x$ac_cv_libxml2_include" = "xno"; then
+          AC_MSG_NOTICE([Testing in /usr/local/include/libxml2])
+          SAVED_CPPFLAGS="$CPPFLAGS"
+          CPPFLAGS="-I/usr/local/include/libxml2 $CPPFLAGS"
+          unset ac_cv_header_libxml_parser_h
+          AC_CHECK_HEADERS([libxml/parser.h], [ac_cv_libxml2_include="/usr/local/include/libxml2"], [])
+          CPPFLAGS="$SAVED_CPPFLAGS"
+      fi
       ])
-  if test "x$ac_cv_libxml2_include" = "xyes"; then
-      SQUID_CXXFLAGS="-I/usr/include/libxml2 $SQUID_CXXFLAGS"
-      CPPFLAGS="-I/usr/include/libxml2 $CPPFLAGS"
+  if test "x$ac_cv_libxml2_include" != "xno"; then
+      SQUID_CXXFLAGS="-I$ac_cv_libxml2_include $SQUID_CXXFLAGS"
+      CPPFLAGS="-I$ac_cv_libxml2_include $CPPFLAGS"
   fi
   dnl Now that we know where to look find the other headers...
   AC_CHECK_HEADERS(libxml/HTMLparser.h libxml/HTMLtree.h)
@@ -932,28 +958,6 @@ dnl   fi
 dnl ])
 
 
-AC_ARG_ENABLE(useragent-log,
-  AS_HELP_STRING([--enable-useragent-log],
-                 [Enable logging of User-Agent header]), [ 
-SQUID_YESNO([$enableval],
-            [unrecognized argument to --enable-useragent-log: $enableval])
-  enable_useragent_log=$enableval
-])
-SQUID_DEFINE_BOOL(USE_USERAGENT_LOG,${enable_useragent_log:=no},
-    [If you want to log User-Agent request header values, define this.])
-AC_MSG_NOTICE([User-Agent logging enabled: $enable_useragent_log])
-
-AC_ARG_ENABLE(referer-log,
-  AS_HELP_STRING([--enable-referer-log],[Enable logging of Referer header]), [ 
-SQUID_YESNO([$enableval],
-            [unrecognized argument to --enable-referer-log: $enableval])
-])
-SQUID_DEFINE_BOOL(USE_REFERER_LOG,${enable_referer_log:=no},
-       [If you want to log Referer request header values, define this.
-        By default, they are written to referer.log in the Squid logdir.
-        This feature is deprecated in favour of custom log formats])
-AC_MSG_NOTICE([Referer logging enabled: $enable_referer_log])
-
 AC_ARG_ENABLE(wccp,
   AS_HELP_STRING([--disable-wccp],[Disable Web Cache Coordination Protocol]), [
 SQUID_YESNO([$enableval],[unrecognized argument to --disable-wccp: $enableval])
@@ -989,9 +993,9 @@ AC_ARG_ENABLE(snmp,
 ])
 SQUID_DEFINE_BOOL(SQUID_SNMP,${enable_snmp:=yes},
    [Define to enable SNMP monitoring of Squid])
-AM_CONDITIONAL(USE_SNMP, [test "x$enable_snmp" = "xyes"])
+AM_CONDITIONAL(ENABLE_SNMP, [test "x$enable_snmp" = "xyes"])
 if test "x$enable_snmp" = "xyes"; then
-    SNMPLIB='../snmplib/libsnmp.a'
+    SNMPLIB='../snmplib/libsnmplib.a'
     makesnmplib=snmplib
 fi
 AC_MSG_NOTICE([SNMP support enabled: $enable_snmp])
@@ -1185,7 +1189,13 @@ AC_ARG_ENABLE(select,
   AS_HELP_STRING([--disable-select],[Disable select(2) support.]),
 [
 SQUID_YESNO($enableval,[--disable-select takes no extra argument])
-test "x$enableval" = "xyes" && squid_opt_io_loop_engine="select"
+if test "x$enableval" = "xyes"; then
+  if test "x$squid_host_os" = "xmingw"; then
+    squid_opt_io_loop_engine="select_win32"
+  else
+    squid_opt_io_loop_engine="select"
+  fi
+fi
 ])
 AC_MSG_NOTICE([enabling select syscall for net I/O: ${enable_select:=auto}])
 
@@ -1373,6 +1383,10 @@ if test "x$with_netfilter_conntrack" != "xno"; then
             AC_MSG_ERROR([--with-netfilter-conntrack specified but libnetfilter-conntrack headers not found])
         fi
         with_netfilter_conntrack=no])
+  # If nothing is broken; enable the libraries usage.
+  if test "x$with_netfilter_conntrack" != "xno"; then
+    with_netfilter_conntrack=yes
+  fi
 fi
 AC_MSG_NOTICE([Linux Netfilter Conntrack support enabled: ${with_netfilter_conntrack} ${squid_opt_netfilterconntrackpath}])
 
@@ -1835,12 +1849,16 @@ if test "x$ac_krb5_config" = "xyes" ; then
 
   SQUID_CHECK_KRB5_SOLARIS_BROKEN_KRB5_H
   if test "x$squid_cv_broken_krb5_h" = "xyes"; then
-    AC_DEFINE(HAVE_BROKEN_SOLARIS_KRB5_H, 1, [Define to 1 if krb5.h is broken for C++])
+    AC_DEFINE(HAVE_BROKEN_SOLARIS_KRB5_H, 1, [Define to 1 if Solaris krb5.h is broken for C++])
     AC_MSG_WARN([You have a broken Solaris <krb5.h> system include.])
     AC_MSG_WARN([Please see http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=6837512])
     AC_MSG_WARN([If you need Kerberos support you'll have to patch])
     AC_MSG_WARN([your system. See contrib/solaris/solaris-krb5-include.patch])
   fi
+  SQUID_CHECK_KRB5_HEIMDAL_BROKEN_KRB5_H
+  if test "x$squid_cv_broken_heimdal_krb5_h" = "xyes"; then
+    AC_DEFINE(HAVE_BROKEN_HEIMDAL_KRB5_H, 1, [Define to 1 if Heimdal krb5.h is broken for C++])
+  fi
   AC_CHECK_HEADERS(krb5.h com_err.h et/com_err.h)
 
   ac_com_error_message=no
@@ -2044,7 +2062,7 @@ if test "x$squid_require_sasl" = "xyes"; then
       AC_MSG_ERROR(Neither SASL nor SASL2 found)
     ])
   ])
-  case "$host_os" in
+  case "$squid_host_os" in
     Darwin)
       if test "$ac_cv_lib_sasl2_sasl_errstring" = "yes" ; then
         AC_DEFINE(HAVE_SASL_DARWIN,1,[Define to 1 if Mac Darwin without sasl.h])
@@ -2095,6 +2113,13 @@ AC_ARG_ENABLE(cpu-profiling,
 SQUID_YESNO([$enableval],
             [unrecognized argument to --enable-cpu-profiling: $enableval])
 ])
+# Default OFF. This is a debug feature. Only check and enable if forced ON.
+if test "x$enable_cpu_profiling" = "xyes"; then
+  SQUID_CHECK_FUNCTIONAL_CPU_PROFILER
+  if test "x$squid_cv_cpu_profiler_works" = "xno"; then
+    AC_MSG_ERROR([CPU profiling will not be functional in this build.])
+  fi
+fi
 SQUID_DEFINE_BOOL(USE_XPROF_STATS,${enable_cpu_profiling:=no},
                       [Define to enable CPU profiling within Squid])
 AM_CONDITIONAL(ENABLE_XPROF_STATS,
@@ -2357,8 +2382,8 @@ AC_CHECK_MEMBERS([struct tm.tm_gmtoff],,,[
 SQUID_HAVE_STRUCT_MALLINFO
 
 dnl Override rusage() detect on MinGW because is emulated in source code
-case "$host_os" in
-  mingw|mingw32)
+case "$squid_host_os" in
+  mingw)
     AC_DEFINE(HAVE_STRUCT_RUSAGE)
     ac_cv_func_getrusage='yes'
     AC_MSG_NOTICE([Using own rusage on Windows.])
@@ -2519,17 +2544,17 @@ else
   esac
 fi
 
-case "$host_os" in
-mingw|mingw32)
-       AC_MSG_NOTICE([Use MSVCRT for math functions.])
-       ;;
-       *)
-       dnl rint() and log() are only used in old C code for now.
-       AC_LANG_PUSH([C])
-       AC_SEARCH_LIBS([rint],[m])
-       AC_SEARCH_LIBS([log],[m])
-       AC_LANG_POP([C])
-       ;;
+case "$squid_host_os" in
+  mingw)
+    AC_MSG_NOTICE([Use MSVCRT for math functions.])
+    ;;
+  *)
+    dnl rint() and log() are only used in old C code for now.
+    AC_LANG_PUSH([C])
+    AC_SEARCH_LIBS([rint],[m])
+    AC_SEARCH_LIBS([log],[m])
+    AC_LANG_POP([C])
+    ;;
 esac
 
 
@@ -2624,8 +2649,8 @@ esac
 
 dnl On MinGW OpenLDAP is not available, so LDAP helpers can be linked 
 dnl only with Windows LDAP libraries using -lwldap32
-case "$host_os" in
-       mingw|mingw32)
+case "$squid_host_os" in
+       mingw)
                LDAPLIB="-lwldap32"
                LBERLIB=""
                ;;
@@ -2984,12 +3009,10 @@ if test "x$ac_cv_func_poll" = "x" ; then
   esac
 fi
 
-dnl Override statfs() detect on MinGW becasue is emulated in source code
-case "$host_os" in
-mingw|mingw32)
+dnl Override statfs() detect on MinGW because it is emulated in source code
+if test "x$squid_host_os" = "xmingw" ; then
   ac_cv_func_statfs='yes'
-  ;;
-esac
+fi
 
 dnl Check for library functions
 AC_CHECK_FUNCS(\
@@ -3085,11 +3108,10 @@ elif test "x$enable_devpoll" != "xno" ; then
   squid_opt_io_loop_engine="devpoll"
 elif test "x$enable_poll" != "xno" -a "x$ac_cv_func_poll" = "xyes" ; then
   squid_opt_io_loop_engine="poll"
-elif test "x$enable_select" != "xno" -a "x$ac_cv_func_select" = "xyes" ; then
+elif test "x$enable_select" != "xno" -a "x$ac_cv_func_select" = "xyes"; then
   squid_opt_io_loop_engine="select"
-  if test "x$squid_host_os" = "xmingw" ; then
-    squid_opt_io_loop_engine="select_win32"
-  fi
+elif test "x$enable_select" != "xno" -a "x$squid_host_os" = "xmingw"; then
+  squid_opt_io_loop_engine="select_win32"
 else
   AC_MSG_WARN([Eep!  Cannot find epoll, kqueue, /dev/poll, poll or select!])
   AC_MSG_WARN([Will try select and hope for the best.])
@@ -3101,7 +3123,6 @@ AC_MSG_NOTICE([Using ${squid_opt_io_loop_engine} for the IO loop.])
 AM_CONDITIONAL([USE_POLL], [test $squid_opt_io_loop_engine = poll])
 AM_CONDITIONAL([USE_EPOLL], [test $squid_opt_io_loop_engine = epoll])
 AM_CONDITIONAL([USE_SELECT], [test $squid_opt_io_loop_engine = select])
-AM_CONDITIONAL([USE_SELECT_SIMPLE], [test $squid_opt_io_loop_engine = select_simple])
 AM_CONDITIONAL([USE_SELECT_WIN32], [test $squid_opt_io_loop_engine = select_win32])
 AM_CONDITIONAL([USE_KQUEUE], [test $squid_opt_io_loop_engine = kqueue])
 AM_CONDITIONAL([USE_DEVPOLL], [test $squid_opt_io_loop_engine = devpoll])
@@ -3353,6 +3374,7 @@ AC_CONFIG_FILES([\
        src/ipc/Makefile \
        src/ssl/Makefile \
        src/mgr/Makefile \
+       src/snmp/Makefile \
        contrib/Makefile \
        snmplib/Makefile \
        icons/Makefile \
@@ -3398,6 +3420,7 @@ AC_CONFIG_FILES([\
        helpers/external_acl/unix_group/Makefile \
        helpers/external_acl/wbinfo_group/Makefile \
        helpers/log_daemon/Makefile \
+       helpers/log_daemon/DB/Makefile \
        helpers/log_daemon/file/Makefile \
        helpers/url_rewrite/Makefile \
        helpers/url_rewrite/fake/Makefile \
index bb99c8d2f859c40a66ccbe77731c3f1cd4bb2b85..22bccd5d5249d32fade98864cd821febd1560bea 100644 (file)
@@ -176,7 +176,7 @@ fubar(char *g, int glen, void *state) {
      * then passes the state off to FUBAR.
      * No check for null-termination is done.
      */
-   xmemcpy(g, glen, state->foo_end_ptr );
+   memcpy(g, glen, state->foo_end_ptr );
    state->foo_end_ptr += glen;
    fubar(state);
 }
index 1289116ac050c45b3dce0914cb4ae45efaa100ed..4ab90d7ef3e4249b26f3d7a5fa3a3f13765cce43 100644 (file)
@@ -70,8 +70,6 @@ section 38    Network Measurement Database
 section 39    Cache Array Routing Protocol
 section 39    Peer source hash based selection
 section 39    Peer user hash based selection
-section 40    Referer Logging
-section 40    User-Agent Logging
 section 41    Event Processing
 section 42    ICMP Pinger program
 section 43    AIOPS
@@ -79,6 +77,14 @@ section 43    Windows AIOPS
 section 44    Peer Selection Algorithm
 section 45    Callback Data Registry
 section 46    Access Log
+section 46    Access Log - Apache combined format
+section 46    Access Log - Apache common format
+section 46    Access Log - Squid Custom format
+section 46    Access Log - Squid ICAP Logging
+section 46    Access Log - Squid format
+section 46    Access Log - Squid referer format
+section 46    Access Log - Squid useragent format
+section 46    Access Log Format Tokens
 section 47    Store COSS Directory Routines
 section 47    Store Directory Routines
 section 48    Persistent Connections
index b4ec311fc5760870d8450e12bd51216b9364eb80..646b465c7a1e17f6117b940e40f105aa67f13825 100644 (file)
@@ -1,6 +1,6 @@
 <!doctype linuxdoc system>
 <article>
-<title>Squid 3.1.9 release notes</title>
+<title>Squid 3.1.10 release notes</title>
 <author>Squid Developers</author>
 
 <abstract>
@@ -13,7 +13,7 @@ for Applied Network Research and members of the Web Caching community.
 
 <sect>Notice
 <p>
-The Squid Team are pleased to announce the release of Squid-3.1.9
+The Squid Team are pleased to announce the release of Squid-3.1.10
 
 This new release is available for download from <url url="http://www.squid-cache.org/Versions/v3/3.1/"> or the <url url="http://www.squid-cache.org/Mirrors/http-mirrors.html" name="mirrors">.
 
@@ -563,6 +563,10 @@ This section gives a thorough account of those changes in three categories:
        direct client address in delay pools.
        </verb>
 
+       <tag>client_request_buffer_max_size</tag>
+       <p>New directive added with squid-3.1.10 to set limits on the amount of buffer space allocated
+       for receiving upload and request data from clients.
+
         <tag>dns_v4_fallback</tag>
         <p>New option to prevent Squid from always looking up IPv4 regardless of whether IPv6 addresses are found.
            Squid will follow a policy of prefering IPv6 links, keeping the IPv4 only as a safety net behind IPv6.
@@ -681,39 +685,17 @@ This section gives a thorough account of those changes in three categories:
                follow_x_forwarded_for allow my_other_proxy
        </verb>
 
-       <tag>ftp_epsv</tag>
-       <verb>
-       FTP Protocol extensions permit the use of a special "EPSV" command.
-
-       NATs may be able to put the connection on a "fast path" through the
-       translator using EPSV, as the EPRT command will never be used and therefore,
-       translation of the data portion of the segments will never be needed.
+       <tag>ftp_eprt</tag>
+       <p>New directive to control whether Squid uses EPRT extension for
+          efficient NAT handling and IPv6 protocol support in FTP.
 
-       Turning this OFF will prevent EPSV being attempted.
-
-       WARNING: Doing so will convert Squid back to the old behavior with all
-       the related problems with external NAT devices/layers.
-
-       Requires ftp_passive to be ON (default) for any effect.
-       </verb>
+       <tag>ftp_epsv</tag>
+       <p>New directive to control whether Squid uses EPSV extension for
+          efficient NAT handling and IPv6 protocol support in FTP.
 
        <tag>ftp_epsv_all</tag>
-       <verb>
-       FTP Protocol extensions permit the use of a special "EPSV ALL" command.
-
-       NATs may be able to put the connection on a "fast path" through the
-       translator, as the EPRT command will never be used and therefore,
-       translation of the data portion of the segments will never be needed.
-
-       When a client only expects to do two-way FTP transfers this may be useful.
-       If Squid finds that it must do a three-way FTP transfer after issuing
-       an EPSV ALL command, the FTP session will fail.
-
-       If you have any doubts about this option do not use it.
-       Squid will nicely attempt all other connection methods.
-
-       Requires ftp_passive to be ON (default)
-       </verb>
+       <p>New directive to control whether Squid uses "EPSV ALL" extension for
+          efficient NAT handling and IPv6 protocol support in FTP.
 
        <tag>forward_max_tries</tag>
        <p>Controls how many different forward paths Squid will try
@@ -1106,7 +1088,7 @@ NOCOMMENT_START
        X-Forwarded-For header.
 
        If set to "truncate", Squid will remove all existing
-       X-Forwarded-For entries, and place itself as the sole entry.
+       X-Forwarded-For entries, and place the client IP as the sole entry.
        </verb>
 
        <tag>http_port transparent intercept ssl-bump connection-auth[=on|off] ignore-cc</tag>
index 91d0c23809be24158df03aeafafbed385499a4d0..6fa64cd30277e89b1369aef0ed8968e82d2f4afa 100644 (file)
@@ -1,6 +1,6 @@
 <!doctype linuxdoc system>
 <article>
-<title>Squid 3.2.0.3 release notes</title>
+<title>Squid 3.2.0.4 release notes</title>
 <author>Squid Developers</author>
 
 <abstract>
@@ -13,7 +13,7 @@ for Applied Network Research and members of the Web Caching community.
 
 <sect>Notice
 <p>
-The Squid Team are pleased to announce the release of Squid-3.2.0.3 for testing.
+The Squid Team are pleased to announce the release of Squid-3.2.0.4 for testing.
 
 This new release is available for download from <url url="http://www.squid-cache.org/Versions/v3/3.2/"> or the <url url="http://www.squid-cache.org/Mirrors/http-mirrors.html" name="mirrors">.
 
@@ -287,6 +287,8 @@ Most user-facing changes are reflected in squid.conf (see below).
   logging a single cache.log at relatively high debug levels on a high-traffic system. Or one which is
   required to store a long period of access.log and needs to conserve disk space.
 
+<p>The referer_log and useragent_log directives have been converted to built-in log formats.
+  These logs are now created using an access_log line with the format "referrer" or "useragent".
 
 <sect1> Client Bandwidth Limits
 <p>In mobile environments, Squid may need to limit Squid-to-client bandwidth
@@ -396,6 +398,9 @@ This section gives a thorough account of those changes in three categories:
        <p>The else part is optional. The keywords <em>if</em>, <em>else</em> and <em>endif</em> 
        must be typed on their own lines, as if they were regular configuration directives.
 
+       <tag>max_stale</tag>
+       <p>Places an upper limit on how stale content Squid will serve from the cache if cache validation fails
+
        <tag>memory_cache_mode</tag>
        <p>Controls which objects to keep in the memory cache (cache_mem)
        <verb>
@@ -448,6 +453,8 @@ This section gives a thorough account of those changes in three categories:
        New installs, or installs with no logs configured explicitly will use this module by default.
        <p>New <em>tcp</em> module to send each log line as text data to a TCP receiver.
        <p>New <em>udp</em> module to send each log line as text data to a UDP receiver.
+       <p>New format <em>referrer</em> to log with the format prevously used by referer_log directive.
+       <p>New format <em>useragent</em> to log with the format prevously used by useragent_log directive.
 
        <tag>acl random</tag>
        <p>New type <em>random</em>. Pseudo-randomly match requests based on a configured probability.
@@ -459,6 +466,9 @@ This section gives a thorough account of those changes in three categories:
           <em>concurrency=N</em> previously called <em>auth_param ... concurrency</em> as a separate option.
        <p>Removed Basic, Digest, NTLM, Negotiate <em>auth_param ... concurrency</em> setting option.
 
+       <tag>cache_dir</tag>
+       <p><em>min-size</em> option ported from Squid-2
+
        <tag>cache_peer</tag>
        <p><em>htcp-*</em> options collapsed into <em>htcp=</em> taking an optional comma-separated list of flags.
           The old form is deprecated but still accepted.
@@ -485,7 +495,7 @@ This section gives a thorough account of those changes in three categories:
         <p><em>icap::%&gt;bs</em> Number of message body bytes received from the ICAP server.
        <p><em>%&gt;lp</em> Local TCP port used by transactions with http servers.
        <p><em>%sn</em> Unique sequence number per log line. Ported from 2.7
-       <p><em>%&lt;eui</em> EUI logging (EUI-48 / MAC address for IPv4, EUI-64 for IPv6)
+       <p><em>%&gt;eui</em> EUI logging (EUI-48 / MAC address for IPv4, EUI-64 for IPv6)
           Both EUI forms are logged in the same field. Type can be identified by length or byte delimiter.
         <p><em>%err_code</em> The ID of an error response served by Squid or
           a similar internal error identifier
@@ -507,6 +517,10 @@ This section gives a thorough account of those changes in three categories:
           This will be included by default if available (see the --without-netfilter-conntrack configure option for more details).
        <p><em>miss</em> sets a value for a cache miss. It is available for both the tos and mark options and takes precedence over the preserve-miss feature.
 
+       <tag>refresh_pattern</tag>
+       <p>New option <em>max-stale=</em> to provide a maximum staleness factor. Squid won't
+          serve objects more stale than this even if it failed to validate the object.
+
        <tag>tcp_outgoing_mark</tag>
        <p>New configuration parameter <em>tcp_outgoing_mark</em>
        <p>Allows packets leaving Squid on the server side to be marked with a Netfilter mark value in the same way as the existing tcp_outgoing_tos feature.
@@ -532,6 +546,12 @@ This section gives a thorough account of those changes in three categories:
 <sect1>Removed tags<label id="removedtags">
 <p>
 <descrip>
+       <tag>emulate_httpd_log</tag>
+       <p>Replaced by <em>common</em> format option on an <em>access_log</em> directive.
+
+       <tag>forward_log</tag>
+       <p>Obsolete.
+
        <tag>ftp_list_width</tag>
        <p>Obsolete.
 
@@ -541,9 +561,14 @@ This section gives a thorough account of those changes in three categories:
        <tag>log_fqdn</tag>
        <p>Obsolete. Replaced by automatic detection of the %>A logformat tag.
 
+       <tag>referer_log</tag>
+       <p>Replaced by the <em>referrer</em> format option on an <em>access_log</em> directive.
+
        <tag>url_rewrite_concurrency</tag>
        <p>Replaced by url_rewrite_children ... concurrency=N option.
 
+       <tag>useragent_log</tag>
+       <p>Replaced by the <em>useragent</em> format option on an <em>access_log</em> directive.
 </descrip>
 
 
@@ -644,6 +669,12 @@ This section gives an account of those changes in three categories:
        <tag>--enable-auth-ntlm-helpers</tag>
        <p>replaced by <em>--enable-auth-ntlm</em>.
 
+       <tag>--enable-referer-log</tag>
+       <p>Obsolete.
+
+       <tag>--enable-useragent-log</tag>
+       <p>Obsolete.
+
 </descrip>
 
 
@@ -792,7 +823,6 @@ This section gives an account of those changes in three categories:
        <p>Not yet ported from 2.6
 
        <tag>cache_dir</tag>
-       <p><em>min-size</em> option not yet ported from Squid-2
        <p><em>COSS</em> storage type is lacking stability fixes from 2.6
        <p>COSS <em>overwrite-percent=</em> option not yet ported from 2.6
        <p>COSS <em>max-stripe-waste=</em> option not yet ported from 2.6
@@ -844,13 +874,9 @@ This section gives an account of those changes in three categories:
        <tag>logformat</tag>
        <p><em>%oa</em> tag not yet ported from 2.7
 
-       <tag>max_stale</tag>
-       <p>Not yet ported from 2.7
-
        <tag>refresh_pattern</tag>
        <p><em>stale-while-revalidate=</em> not yet ported from 2.7
        <p><em>ignore-stale-while-revalidate=</em> not yet ported from 2.7
-       <p><em>max-stale=</em> not yet ported from 2.7
        <p><em>negative-ttl=</em> not yet ported from 2.7
 
        <tag>refresh_stale_hit</tag>
index f45bab175a8ce2560ba126e1d42d97754e87b5db..5bafab0a9db318789eb2dc500bfcb2e0d8b2fb4e 100644 (file)
@@ -29,6 +29,7 @@ ERROR_TEMPLATES =  \
        templates/ERR_FTP_PUT_ERROR \
        templates/ERR_FTP_PUT_MODIFIED \
        templates/ERR_FTP_UNAVAILABLE \
+       templates/ERR_GATEWAY_FAILURE \
        templates/ERR_ICAP_FAILURE \
        templates/ERR_INVALID_REQ \
        templates/ERR_INVALID_RESP \
index 7b9c64590f041a47191f43b386624bde7cbc734e..92754c3a2d68bb142e909dfb954cec51aed557c2 100644 (file)
@@ -3,7 +3,7 @@
 az     Azerbaijani
 bg     Bulgarian
 ca     Catalan
-cz     Czech
+cs     Czech
 da     Danish
 de     German
 el     Greek
@@ -20,7 +20,7 @@ ja    Japanese
 ko     Korean
 lt     Lithuanian
 nl     Dutch
-po     Polish
+pl     Polish
 pt     Portuguese
 ro     Romanian
 ru     Russian-1251 Russian-koi8-r
index 96e72e5a1947583adc87af3fadd44aeb35059a79..d6b53d589396ddb0f1b529eadf1f5297ae172d26 100644 (file)
@@ -3,7 +3,7 @@ msgstr ""
 "Project-Id-Version: Squid-3\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2010-11-06 03:26+1300\n"
-"PO-Revision-Date: 2010-11-17 19:36+0200\n"
+"PO-Revision-Date: 2011-01-24 19:52+0200\n"
 "Last-Translator: Bernard <fli4l.charrier@free.fr>\n"
 "Language-Team: Squid Developers <squid-dev@squid-cache.org>\n"
 "Language: fr\n"
@@ -106,7 +106,7 @@ msgid ""
 "has failed."
 msgstr ""
 "Au moins une précondition indiquée dans l'en-tête de la requête du client "
-"HTTP  a échoué."
+"HTTP a échoué."
 
 #: templates/ERR_CACHE_ACCESS_DENIED:3 templates/ERR_CACHE_ACCESS_DENIED:5
 msgid "Cache Access Denied."
@@ -222,7 +222,7 @@ msgstr "FTP est désactivé"
 
 #: templates/ERR_SECURE_CONNECT_FAIL:5
 msgid "Failed to establish a secure connection to %I"
-msgstr "Il n'a pas été possible d'établir d'une connexion sécurisée vers %I"
+msgstr "Il n'a pas été possible d'établir une connexion sécurisée vers %I"
 
 #: templates/ERR_FTP_PUT_CREATED:3
 msgid "File created"
@@ -322,8 +322,8 @@ msgstr "Les double espaces ne sont pas valides dans une adresse URL"
 #: templates/ERR_AGENT_CONFIGURE:14
 msgid "In the HTTP proxy box type the proxy name %h and port 3128."
 msgstr ""
-"Dans l'onglet proxy HTTP, vous devez indiquer le chemin du proxy %h et le "
-"port 3128"
+"Dans l'onglet proxy HTTP, vous devez indiquer le nom du proxy %h et le port "
+"3128"
 
 #: templates/ERR_INVALID_URL:5
 msgid "Invalid URL"
@@ -405,7 +405,7 @@ msgstr "La requête est trop volumineuse"
 
 #: templates/ERR_AGENT_WPAD:10
 msgid "Select Automatically detect settings"
-msgstr "Sélectionnez détection automatique les paramètres"
+msgstr "Sélectionnez la détection automatique les paramètres"
 
 #: templates/ERR_AGENT_WPAD:13
 msgid "Select Use Automatic proxy configuration"
@@ -449,7 +449,7 @@ msgid ""
 "Squid does not support all request methods for all access protocols. For "
 "example, you can not POST a Gopher request."
 msgstr ""
-"Squid ne prend pas en charge tout les types de requêtes par rapport à tous "
+"Squid ne prend pas en charge tous les types de requêtes par rapport à tous "
 "les protocoles d'accès. Vous ne pouvez pas par exemple utiliser le protocole "
 "POST dans une requête Gopher."
 
@@ -465,7 +465,7 @@ msgid ""
 "Squid is unable to create a TCP socket, presumably due to excessive load. "
 "Please retry your request."
 msgstr ""
-"Squid n'est pas en mesure d'ouvrir une socket TCP, probablement due à une "
+"Squid n'est pas en mesure d'ouvrir le socket TCP, probablement due à une "
 "surcharge. Veuillez renouveler votre requête."
 
 #: templates/ERR_FTP_FAILURE:5 templates/ERR_FTP_FORBIDDEN:5
@@ -485,16 +485,16 @@ msgstr "Le processeur ESI a répondu :"
 #: templates/ERR_FTP_UNAVAILABLE:4
 msgid "The FTP server was too busy to retrieve the URL: <a href=\"%U\">%U</a>"
 msgstr ""
-"Le serveur FTP était surchargé et ne permettent pas l'accès à l'URL : <a "
-"href=\"%U\">%U</a>"
+"Le serveur FTP est surchargé et ne permet pas l'accès à l'URL : <a href=\"%"
+"U\">%U</a>"
 
 #: templates/ERR_INVALID_RESP:5
 msgid ""
 "The HTTP Response message received from the contacted server could not be "
 "understood or was otherwise malformed. Please contact the site operator."
 msgstr ""
-"Le message reçu par le serveur HTTP contacté, n'a pas pu être compris ou a "
-"été mal formulé. Veuillez contacter le responsable du site."
+"La réponse HTTP reçu, qui a été envoyée par le serveur n'a pas pu être "
+"compris ou a été mal formulé. Veuillez contacter le responsable du site."
 
 #: templates/ERR_ICAP_FAILURE:9
 msgid "The ICAP server is not reachable."
@@ -625,7 +625,7 @@ msgid ""
 "file. Check the path, permissions, diskspace and try again."
 msgstr ""
 "Cela signifie que le serveur FTP n'a pas les autorisations ou pas assez "
-"d'espace pour stocker ce fichier. Veuillez vérifier l'emplacement, les "
+"d'espace pour stocker ce fichier. Veuillez vérifier le chemin, les "
 "autorisations et l'espace disque puis essayez de nouveau."
 
 #: templates/ERR_DNS_FAIL:7
@@ -654,9 +654,9 @@ msgid ""
 "comply with RFC 1738). If this is the cause, then the file can be found at "
 "<a href=\"%B\">%B</a>."
 msgstr ""
-"Cela pourrait être causé par une URL FTP qui contient les chemins absolus "
-"(ce qui n'est pas compatible avec la RFC 1738). Si tel est le cas, le "
-"fichier peut être disponible à l'adresse <a% href=\\\"%B\\\"> B </ a>."
+"Cela pourrait être causé par une URL FTP qui contient un chemin absolut (ce "
+"qui n'est pas compatible avec la RFC 1738). Si tel est le cas, le fichier "
+"peut être disponible à l'adresse <a% href=\\\"%B\\\"> B </ a>."
 
 #: templates/ERR_SECURE_CONNECT_FAIL:7
 msgid ""
@@ -666,7 +666,7 @@ msgid ""
 "the host security credentials."
 msgstr ""
 "Ce proxy et l'hôte distant n'ont pas pu négocier mutuellement une connexion "
-"de sécurité pour le traitement de votre requête. Il est possible que l'hôte "
+"sécurisée pour le traitement de votre requête. Il est possible que l'hôte "
 "distant ne supporte pas les connexions sécurisées, ou que le proxy n'est pas "
 "satisfait du certificat de sécurité de l'hôte distant."
 
@@ -721,8 +721,8 @@ msgid ""
 "Valid document was not found in the cache and <q>only-if-cached</q> "
 "directive was specified."
 msgstr ""
-"Aucun document valide n'a été trouvé dans le cache et la directive <q>only-"
-"if-cached</q> a été spécifiée."
+"Aucun document valide n'a été trouvé dans le cache, de plus la directive <q"
+">only-if-cached</q> a été spécifiée."
 
 #: templates/ERR_AGENT_CONFIGURE:1 templates/ERR_AGENT_CONFIGURE:3
 #: templates/ERR_AGENT_WPAD:1 templates/ERR_AGENT_WPAD:3
index 8785e3bf8c46854f4fd73ecfb77a6513a00b1204..8f2115d60a35e68ac4a2fd9d92792461ea0852e4 100644 (file)
@@ -3,7 +3,7 @@ msgstr ""
 "Project-Id-Version: Squid-3\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2010-11-06 03:26+1300\n"
-"PO-Revision-Date: 2010-08-21 17:08+0200\n"
+"PO-Revision-Date: 2011-01-20 21:35+0200\n"
 "Last-Translator: Arthur <arthurtumanyan@yahoo.com>\n"
 "Language-Team: Squid Developers <squid-dev@squid-cache.org>\n"
 "Language: hy\n"
@@ -11,7 +11,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Pootle 2.0.1\n"
+"X-Generator: Pootle 2.0.5\n"
 
 #: templates/ERR_DIR_LISTING:6
 msgid "<a href=\"../\">Parent Directory</a> (<a href=\"/\">Root Directory</a>)"
@@ -100,7 +100,7 @@ msgstr ""
 msgid ""
 "At least one precondition specified by the HTTP client in the request header "
 "has failed."
-msgstr ""
+msgstr "HTTP հարցումի նախապայմաններից առնվազն մեկը անհնար է մշակել"
 
 #: templates/ERR_CACHE_ACCESS_DENIED:3 templates/ERR_CACHE_ACCESS_DENIED:5
 msgid "Cache Access Denied."
@@ -112,9 +112,8 @@ msgid "Cache Manager Access Denied."
 msgstr "Քեշի կառավառման մուտքն արգելված է."
 
 #: templates/ERR_URN_RESOLVE:5
-#, fuzzy
 msgid "Cannot Resolve URN"
-msgstr "Cannot Resolve URN"
+msgstr "Չհաջողվեց մշակել URN հարցումը"
 
 #: templates/ERR_LIFETIME_EXP:5
 msgid "Connection Lifetime Expired"
@@ -122,7 +121,7 @@ msgstr "Կապի հաստատման ժամանակը սպառվեց"
 
 #: templates/ERR_CONNECT_FAIL:5
 msgid "Connection to %I failed."
-msgstr ""
+msgstr "Չհաջողվեց կապ հաստատել %I -ի հետ"
 
 #: templates/ERR_INVALID_REQ:10
 msgid "Content-Length missing for POST or PUT requests."
@@ -134,7 +133,7 @@ msgstr "Դիրեկտորիայի պարունակությունը:"
 
 #: templates/ERR_DIR_LISTING:4
 msgid "Directory Listing"
-msgstr ""
+msgstr "Դիրեկտորիայի պարունակությունը"
 
 #: templates/ERR_DIR_LISTING:1
 msgid "Directory: %U"
@@ -199,7 +198,7 @@ msgstr "ՍԽԱԼ: Պահանջվող URL-ն հնարավոր չէ ստանալ"
 
 #: templates/ERR_ESI:5
 msgid "ESI Processing failed."
-msgstr ""
+msgstr "Չհաջողվեց մշակել ESI հարցումը"
 
 #: templates/ERR_FTP_PUT_CREATED:1 templates/ERR_FTP_PUT_MODIFIED:1
 msgid "FTP PUT Successful."
@@ -281,25 +280,19 @@ msgstr "Ինչպես փնտրել այս կարգաբերումները քո բ
 
 #: templates/ERR_ICAP_FAILURE:5
 msgid "ICAP protocol error."
-msgstr ""
+msgstr "ICAP արձանարության սխալ"
 
 #: templates/ERR_TOO_BIG:7
-#, fuzzy
 msgid ""
 "If you are making a GET request, then the item you are trying to download is "
 "too large."
-msgstr ""
-"Եթե Դուք GET հարցում եք ձևակերպում, ապա տարրը ,որը Դուք փորձում եք "
-"բեռնավորել, շատ մեծ ծավալ ունի."
+msgstr "GET հարցման օբյեկտը շատ մեծ ծավալ ունի."
 
 #: templates/ERR_TOO_BIG:6
-#, fuzzy
 msgid ""
 "If you are making a POST or PUT request, then the item you are trying to "
 "upload is too large."
-msgstr ""
-"Եթե Դուք POST կամ PUT  հարցում եք ձևակերպում, ապա տարրը ,որը Դուք փորձում եք "
-"բեռնավորել, շատ մեծ ծավալ ունի"
+msgstr "POST հարցման օբյեկտը շատ մեծ ծավալ ունի."
 
 #: templates/ERR_INVALID_REQ:11 templates/ERR_INVALID_URL:11
 msgid "Illegal character in hostname; underscores are not allowed."
@@ -376,7 +369,7 @@ msgstr ""
 
 #: templates/ERR_PRECONDITION_FAILED:5
 msgid "Precondition Failed."
-msgstr ""
+msgstr "Չհաջողվեց մշակել նախապայմանը"
 
 #: templates/ERR_READ_ERROR:5
 msgid "Read Error"
@@ -466,9 +459,8 @@ msgid "The DNS server returned:"
 msgstr "DNS սերվերի պատասխանը:"
 
 #: templates/ERR_ESI:6
-#, fuzzy
 msgid "The ESI processor returned:"
-msgstr "ESI ÕºÖ\80Õ¸Ö\81Õ¥Õ½Õ¸Ö\80Õ¨ ÕºÕ¡Õ¿Õ¡Õ½Õ­Õ¡Õ¶Õ¥Ö\81:"
+msgstr "ESI Õ°Õ¡Ö\80Ö\81Õ´Õ¡Õ¶ ÕºÕ¡Õ¿Õ¡Õ½Õ­Õ¡Õ¶Õ¶ Õ§Ö\89"
 
 #: templates/ERR_FTP_UNAVAILABLE:4
 msgid "The FTP server was too busy to retrieve the URL: <a href=\"%U\">%U</a>"
diff --git a/errors/templates/ERR_GATEWAY_FAILURE b/errors/templates/ERR_GATEWAY_FAILURE
new file mode 100644 (file)
index 0000000..0a0cfeb
--- /dev/null
@@ -0,0 +1,39 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html><head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>ERROR: The requested URL could not be retrieved</title>
+<style type="text/css"><!-- 
+ %l
+
+body
+:lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; }
+:lang(he) { direction: rtl; float: right; }
+ --></style>
+</head><body>
+<div id="titles">
+<h1>ERROR</h1>
+<h2>The requested URL could not be retrieved</h2>
+</div>
+<hr>
+
+<div id="content">
+<p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>
+
+<blockquote id="error">
+<p><b>Gateway Proxy Failure</b></p>
+</blockquote>
+
+<p>A non-recoverable internal failure or configuration problem prevents this request from being completed.</p>
+
+<p>This may be due to limits established by the Internet Service Provider who operates this cache. Please contact them directly for more information.</p>
+
+<p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p>
+<br>
+</div>
+
+<hr>
+<div id="footer">
+<p>Generated %T by %h (%s)</p>
+<!-- %c -->
+</div>
+</body></html>
index dd33cb77f28e20c1c10d154053779396944c946f..7eadb18d59f05598fb408ff723e00e68f8898ffc 100644 (file)
@@ -1,7 +1,10 @@
+#ifndef _SQUID_HELPERS_BASIC_AUTH_MSNT_MSNTAUTH_H
+#define _SQUID_HELPERS_BASIC_AUTH_MSNT_MSNTAUTH_H
+
 extern int OpenConfigFile(void);
 extern int QueryServers(char *, char *);
 extern void Checktimer(void);
-extern void Check_forchange(int);
+extern "C" void Check_forchange(int);
 extern int Read_denyusers(void);
 extern int Read_allowusers(void);
 extern int Check_user(char *);
@@ -9,3 +12,4 @@ extern int QueryServers(char *, char *);
 extern int Check_ifuserallowed(char *ConnectingUser);
 extern void Check_forallowchange(void);
 
+#endif /* _SQUID_HELPERS_BASIC_AUTH_MSNT_MSNTAUTH_H */
index 9130d03e733e9a12333300494712b952ac3d2faf..6a103c58f748a4b1171a493c54a7f6f45afc90a7 100644 (file)
 static char *password = NULL;  /* Workaround for Solaris 2.6 brokenness */
 #endif
 
+extern "C" int password_conversation(int num_msg, PAM_CONV_FUNC_CONST_PARM struct pam_message **msg,
+                                     struct pam_response **resp, void *appdata_ptr);
+
 /**
  * A simple "conversation" function returning the supplied password.
  * Has a bit to much error control, but this is my first PAM application
  * so I'd rather check everything than make any mistakes. The function
  * expects a single converstation message of type PAM_PROMPT_ECHO_OFF.
  */
-static int
+int
 password_conversation(int num_msg, PAM_CONV_FUNC_CONST_PARM struct pam_message **msg, struct pam_response **resp, void *appdata_ptr)
 {
     if (num_msg != 1 || msg[0]->msg_style != PAM_PROMPT_ECHO_OFF) {
index f6329c388c80c065bd6aea3ca9832b17d4ef4a46..81043b70d370c4c16866d2c0c0aa28809cf7808f 100644 (file)
@@ -63,7 +63,7 @@
 #if HAVE_FCNTL_H
 #include <fcntl.h>
 #endif
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
 #include <io.h>
 #endif
 #if HAVE_CTYPE_H
index 0d52e7b3de8a923a9c2c6faf74dc37f6534d6dd9..561c3bca55017047165fde2f3a20fc3446ccc93b 100644 (file)
@@ -1,21 +1,9 @@
 include $(top_srcdir)/src/Common.am
 
-# SAMBAPREFIX must point to the directory where Samba has been installed.
-# By default, Samba is installed in /usr/local/samba. If you changed this
-# by using the --prefix option when configuring Samba, you need to change
-# SAMBAPREFIX accordingly.
-
-## FIXME: autoconf should test for the samba path.
-
-SMB_AUTH_HELPER        = basic_smb_auth.sh
-SAMBAPREFIX=/usr/local/samba
-SMB_AUTH_HELPER_PATH = $(libexecdir)/$(SMB_AUTH_HELPER)
-
-libexec_SCRIPTS        = $(SMB_AUTH_HELPER)
-
+libexec_SCRIPTS        = basic_smb_auth.sh
 libexec_PROGRAMS = basic_smb_auth
 basic_smb_auth_SOURCES= basic_smb_auth.cc
-basic_smb_auth_CXXFLAGS = -DSAMBAPREFIX=\"$(SAMBAPREFIX)\" -DHELPERSCRIPT=\"$(SMB_AUTH_HELPER_PATH)\"
+basic_smb_auth_CXXFLAGS = -DHELPERSCRIPT=\"$(libexecdir)/basic_smb_auth.sh\"
 basic_smb_auth_LDADD = \
                $(top_builddir)/lib/libmiscencoding.la \
                $(COMPAT_LIB) \
index 1f84f7f386dec51b1398ebc2380427d2128d7b78..bdaf3ca4863feabf4904a8a86299e8da5255e1b1 100644 (file)
@@ -197,10 +197,6 @@ main(int argc, char *argv[])
 
     shcmd = debug_enabled ? HELPERSCRIPT : HELPERSCRIPT " > /dev/null 2>&1";
 
-    /* pass to helper script */
-    if (putenv((char *)"SAMBAPREFIX=" SAMBAPREFIX) != 0)
-        return 1;
-
     while (fgets(buf, HELPER_INPUT_BUFFER, stdin) != NULL) {
 
         if ((s = strchr(buf, '\n')) == NULL)
index 99f86150b361e405029169890245f1df1e998152..2a1abb3b6e970fde01ace15997453cd405dc1d76 100755 (executable)
@@ -47,13 +47,13 @@ else
   addropt=""
 fi
 echo "Query address options: $addropt"
-dcip=`$SAMBAPREFIX/bin/nmblookup $addropt "$PASSTHROUGH#1c" | awk '/^[0-9.]+ / { print $1 ; exit }'`
+dcip=`nmblookup $addropt "$PASSTHROUGH#1c" | awk '/^[0-9.]+ / { print $1 ; exit }'`
 echo "Domain controller IP address: $dcip"
 [ -n "$dcip" ] || exit 1
 
 # All right, we have the IP address of a domain controller,
 # but we need its name too
-dcname=`$SAMBAPREFIX/bin/nmblookup -A $dcip | awk '$2 == "<00>" { print $1 ; exit }'`
+dcname=`nmblookup -A $dcip | awk '$2 == "<00>" { print $1 ; exit }'`
 echo "Domain controller NETBIOS name: $dcname"
 [ -n "$dcname" ] || exit 1
 
@@ -63,7 +63,7 @@ export USER
 
 # Read the contents of the file $AUTHFILE on the $AUTHSHARE share
 authfilebs=`echo "$AUTHFILE" | tr / '\\\\'`
-authinfo=`$SAMBAPREFIX/bin/smbclient "//$dcname/$AUTHSHARE" -I $dcip -d 0 -E -W "$DOMAINNAME" -c "get $authfilebs -" 2>/dev/null`
+authinfo=`smbclient "//$dcname/$AUTHSHARE" -I $dcip -d 0 -E -W "$DOMAINNAME" -c "get $authfilebs -" 2>/dev/null`
 echo "Contents of //$dcname/$AUTHSHARE/$AUTHFILE: $authinfo"
 
 # Allow for both \n and \r\n end-of-line termination
index f41b21fd12ec709d7b79571bfcdd0f2c1cf9e8f3..ece056001df8a0c5a60dcbbdd6687662070324e2 100755 (executable)
@@ -1,8 +1,10 @@
 #!/bin/sh
-for prefix in ${SAMBAPREFIX} /usr/local /opt /opt/samba /usr/local/samba /usr
+for prefix in /usr/local /opt /opt/samba /usr/local/samba /usr
 do
     if [ -x ${prefix}/bin/smbclient ]; then
         exit 0
     fi
 done
-exit 1
+echo "WARNING: Samba smbclient not found in default location. basic_smb_auth may not work on this machine"
+# allow script install anyway.
+exit 0
index 855c973b714a128a779c4b06e5e0525245867f57..7bfcf053ef81fa7a7b61b8394b8dbf67d66efba0 100644 (file)
 #endif
 
 /* Check if we try to compile on a Windows Platform */
-#if defined(_SQUID_CYGWIN_) || defined(_SQUID_MSWIN_)
+#if !_SQUID_WINDOWS_
+/* NON Windows Platform !!! */
+#error NON WINDOWS PLATFORM
+#endif
 
 #include "valid.h"
 
@@ -174,9 +177,3 @@ main(int argc, char **argv)
     }
     return 0;
 }
-
-#else  /* NON Windows Platform !!! */
-
-#error NON WINDOWS PLATFORM
-
-#endif
index 9e7d901c07254c7cd958bfa8acd7c2d4bd7c50f3..147ac0c5b0d07cb27e39b81358fae33bf9584322 100644 (file)
 #include "util.h"
 
 /* Check if we try to compile on a Windows Platform */
-#if defined(_SQUID_CYGWIN_) || defined(_SQUID_MSWIN_)
+#if !_SQUID_WINDOWS_
+/* NON Windows Platform !!! */
+#error NON WINDOWS PLATFORM
+#endif
 
-#if defined(_SQUID_CYGWIN_)
+#if _SQUID_CYGWIN_
 #include <wchar.h>
 #endif
 #include "valid.h"
@@ -175,8 +178,3 @@ Valid_User(char *UserName, char *Password, char *Group)
     }
     return result;
 }
-#else  /* NON Windows Platform !!! */
-
-#error NON WINDOWS PLATFORM
-
-#endif
index 8e8ef50b2573c36723e46b3a47ee498aab9778e9..39c599639c556f813bcaf0941bd058da76200887 100644 (file)
@@ -28,7 +28,7 @@
 #ifndef _VALID_H_
 #define _VALID_H_
 
-#ifdef _SQUID_CYGWIN_
+#if _SQUID_CYGWIN_
 #include <windows.h>
 #endif
 #include <lm.h>
index 9ed185fde54b88e50b29f37c36f9b34a5aea01ee..c45eefae5f3dcb3b4afbf7444de15324e547eb16 100644 (file)
@@ -61,7 +61,7 @@
 #include "helpers/defines.h"
 #include "include/util.h"
 
-#ifdef _SQUID_CYGWIN_
+#if _SQUID_CYGWIN_
 #include <wchar.h>
 int _wcsicmp(const wchar_t *, const wchar_t *);
 #endif
index 209d008152baef910630788dd6ee696093e0195d..5cb49c6231a7f3c3b4413acd6253e0e033cb1e8f 100644 (file)
@@ -72,7 +72,7 @@
 #include "include/util.h"
 
 
-#ifdef _SQUID_CYGWIN_
+#if _SQUID_CYGWIN_
 #include <wchar.h>
 int _wcsicmp(const wchar_t *, const wchar_t *);
 #endif
index bcccf57d6a48373f7d09d99ad6eac91d11c2c239..b552130bfd3cd9260cd7e402b792bea823e1159a 100644 (file)
@@ -19,7 +19,7 @@
  *
  ********************************************************************************
  *
- * ext_edirectory_userip_acl.c -- Rev 2010-09-22
+ * ext_edirectory_userip_acl.cc -- Rev 2010-12-15
  *
  */
 
@@ -163,7 +163,7 @@ typedef struct {
     char passwd[EDUI_MAXLEN];
     char search_filter[EDUI_MAXLEN];                   /* search_group gets appended here by GroupLDAP */
     char search_ip[EDUI_MAXLEN];                       /* Could be IPv4 or IPv6, set by ConvertIP */
-    char userid[EDUI_MAXLEN];                                /* Resulting userid */
+    char userid[EDUI_MAXLEN];                           /* Resulting userid */
     unsigned int status;
     unsigned int port;
     unsigned long type;                                /* Type of bind */
@@ -176,11 +176,9 @@ typedef struct {
 } edui_ldap_t;
 
 /* Global function prototypes */
-/* DISABLED BELOW IN FAVOR OF SQUID debug() */
-//void local_debug(const char *, const char *,...);
-//void local_debugx(const char *,...);
 void local_printfx(const char *,...);
-int SplitString(char *, size_t, char, char *, size_t);
+int StringSplit(char *, char, char *, size_t);
+int BinarySplit(void *, size_t, char, void *, size_t);
 static void DisplayVersion();
 static void DisplayUsage();
 static void InitConf();
@@ -194,10 +192,9 @@ int ConvertIP(edui_ldap_t *, char *);
 int ResetLDAP(edui_ldap_t *);
 int SearchFilterLDAP(edui_ldap_t *, char *);
 int SearchLDAP(edui_ldap_t *, int, char *, char **);
-int GetValLDAP(edui_ldap_t *, char *);
-int SearchIPLDAP(edui_ldap_t *, char *);
+int SearchIPLDAP(edui_ldap_t *);
 const char *ErrLDAP(int);
-void SigTrap(int);
+extern "C" void SigTrap(int);
 
 /* Global variables */
 const char *search_attrib[] = { "cn", "uid", "networkAddress", "groupMembership", NULL };
@@ -206,85 +203,6 @@ edui_ldap_t edui_ldap;
 time_t edui_now;
 time_t edui_elap;
 
-/* local_debug() -
- *
- * Print formatted message of func() to stderr if EDUI_MODE_DEBUG is set.
- *
- */
-/*
-void local_debug(const char *func, const char *msg,...)
-{
-    char prog[EDUI_MAXLEN], dbuf[EDUI_MAXLEN], cbuf[EDUI_MAXLEN], bbuf[EDUI_MAXLEN];
-    size_t sz, x;
-    va_list ap;
-    if (!(edui_conf.mode & EDUI_MODE_DEBUG))
-        return;
-
-    if (edui_conf.program[0] == '\0')
-        xstrncpy(prog, EDUI_PROGRAM_NAME, sizeof(prog));
-    else
-        xstrncpy(prog, edui_conf.program, sizeof(prog));
-    if ((func == NULL) || (msg == NULL) || (strlen(prog) > 256)) {
-        snprintf(dbuf, sizeof(dbuf), "%s: local_debug() EPIC FAILURE.\n", prog);
-        fputs(dbuf, stderr);
-        return;
-    }
-    sz = sizeof(dbuf);
-    memset(cbuf, '\0', sizeof(cbuf));
-    xstrncpy(cbuf, prog, sizeof(cbuf));
-    strncat(cbuf, ": [DB] ", 7);
-    strncat(cbuf, func, strlen(func));
-    strncat(cbuf, "() - ", 5);
-    va_start(ap, msg);
-    x = vsnprintf(dbuf, sz, msg, ap);
-    va_end(ap);
-    if (x > 0) {
-        strncat(cbuf, dbuf, x);
-        fputs(cbuf, stderr);
-        memset(dbuf, '\0', sizeof(dbuf));
-    } else {
-        snprintf(bbuf, sz, "%s: local_debug(%s) FAILURE: %zd\n", prog, dbuf, x);
-        fputs(bbuf, stderr);
-    }
-}
-*/
-/* local_debugx() -
- *
- * Print formatted message to stderr if EDUI_MODE_DEBUG is set, without preformatting.
- *
- */
-/*
-void local_debugx(const char *msg,...)
-{
-    char prog[EDUI_MAXLEN], dbuf[EDUI_MAXLEN], bbuf[EDUI_MAXLEN];
-    size_t sz, x;
-    va_list ap;
-    if (!(edui_conf.mode & EDUI_MODE_DEBUG))
-        return;
-
-    if (edui_conf.program[0] == '\0')
-        xstrncpy(prog, EDUI_PROGRAM_NAME, sizeof(prog));
-    else
-        xstrncpy(prog, edui_conf.program, sizeof(prog));
-    if ((msg == NULL) || (strlen(prog) > 256)) {
-        snprintf(dbuf, sizeof(dbuf), "%s: local_debugx() EPIC FAILURE.\n", prog);
-        fputs(dbuf, stderr);
-        return;
-    }
-    sz = sizeof(dbuf);
-    va_start(ap, msg);
-    x = vsnprintf(dbuf, sz, msg, ap);
-    va_end(ap);
-    if (x > 0) {
-        fputs(dbuf, stderr);
-        memset(dbuf, '\0', sizeof(dbuf));
-    } else {
-        snprintf(bbuf, sz, "%s: local_debugx(%s) FAILURE: %zd\n", prog, dbuf, x);
-        fputs(bbuf, stderr);
-    }
-}
-*/
-
 /* local_printfx() -
  *
  * Print formatted message to stderr AND stdout, without preformatting.
@@ -303,10 +221,6 @@ void local_printfx(const char *msg,...)
 
     if ((msg == NULL) || (strlen(prog) > 256)) {
         /* FAIL */
-        /*
-                snprintf(dbuf, sizeof(dbuf), "%s: local_printfx() EPIC FAILURE.\n", prog);
-                fputs(dbuf, stderr);
-        */
         debug("local_printfx() EPIC FAIL.\n");
         return;
     }
@@ -318,13 +232,9 @@ void local_printfx(const char *msg,...)
         dbuf[x] = '\0';
         x++;
         fputs(dbuf, stdout);
-        memset(dbuf, '\0', sizeof(dbuf));
+        *(dbuf) = '\0';
     } else {
         /* FAIL */
-        /*
-                snprintf(bbuf, sz, "%s: local_printfx(%s) FAILURE: %zd\n", prog, dbuf, x);
-                fputs(bbuf, stderr);
-        */
         debug("local_printfx() FAILURE: %zd\n", x);
     }
 
@@ -333,70 +243,107 @@ void local_printfx(const char *msg,...)
 }
 
 /*
- * SplitString() - <string> <string-size> <char> <split-object> <obj-size>
+ * StringSplit() - <string-to-split> <char> <split-object> <obj-size>
  *
  * Breaks down string, splitting out element <char> into <split-object>, and removing it from string.
  * Will not exceed size tolerances.
  *
- * NOTE:  We could have used a strchr() pointer, but then '\0' would break it.
- *       (Which DOES commonly exist in IP Addressing)
+ */
+int
+StringSplit(char *In_Str, char chr, char *Out_Str, size_t Out_Sz)
+{
+    if ((In_Str == NULL) || (Out_Str == NULL))
+        return (-1);
+
+    size_t In_Len = strlen(In_Str) + 1;
+
+    // find the char delimiter position...
+    char *p = In_Str;
+    while (*p != chr && *p != '\0' && (In_Str+In_Len) > p) {
+        p++;
+    }
+
+    size_t i = (p-In_Str);
+
+    // token to big for the output buffer
+    if (i >= Out_Sz)
+        return (-2);
+
+    // wipe the unused Out_Obj area
+    memset(Out_Str+i, 0, Out_Sz-i);
+    // copy token from In_Str to Out_Str
+    memcpy(Out_Str, In_Str, i);
+
+    // omit the delimiter
+    if (*p == chr) {
+        p++;
+        i++;
+    } else {
+        // chr not found (or \0 found first). Wipe whole input buffer.
+        memset(In_Str, 0, In_Len);
+//        return (-3);
+// Returning <0 breaks current ConvertIP() code for last object
+        return (i);
+    }
+
+    // move the unused In_Str forward
+    memmove(In_Str, p, In_Len-i);
+    // wipe the end of In_Str
+    memset(In_Str+In_Len-i, 0, i);
+    return (i-1);
+}
+
+/*
+ * BinarySplit() - <binary-to-split> <bin-size> <char> <split-object> <obj-size>
+ *
+ * Breaks down Binary Block, splitting out element <char> into <split-object>, and removing it from Block, padding remainder with '\0'.
+ * Will not exceed size tolerances.
  *
  */
-int SplitString(char *input, size_t insz, char c, char *obj, size_t objsz)
+int
+BinarySplit(void *In_Obj, size_t In_Sz, char chr, void *Out_Obj, size_t Out_Sz)
 {
-    size_t i, j;
-    int swi;
-    char buf[EDUI_MAXLEN];
-    if ((input == NULL) || (obj == NULL) || (insz <= 0) || (objsz <= 0)) return -1;
-
-    /* Copy input, and clear */
-    memset(buf, '\0', sizeof(buf));
-    memcpy(buf, input, insz);
-    memset(input, '\0', insz);
-    memset(obj, '\0', objsz);
-    j = 0;                /* obj position */
-    swi = 0;              /* found data yet ? */
-
-    /* Scan for data, and copy */
-    for (i = 0; i < insz; i++) {
-        /* Scan input for first non-space character */
-        if (buf[i] != c) {
-            if (swi == 0) {
-                swi++;          /* Data found, begin copying. */
-                obj[j] = buf[i];
-                j++;
-            } else if (swi == 1) {
-                obj[j] = buf[i];
-                j++;
-            } else
-                break;          /* end of data */
-        } else {
-            /* Found a character c */
-            if (swi == 1)
-                swi++;
-            else if (swi == 2)
-                break;          /* end of data */
-        }
+    // check tolerances
+    if ((In_Obj == NULL) || (Out_Obj == NULL))
+        return (-1);
+
+    char *in = static_cast<char*>(In_Obj);
+    char *out = static_cast<char*>(Out_Obj);
+
+    // find the char delimiter position...
+    char *p = static_cast<char*>(In_Obj);
+    while (*p != chr && (in+In_Sz) > p) {
+        p++;
     }
-    obj[j] = '\0';        /* Terminate, i = point of split */
-
-    j = 0;                /* Position of input */
-    for (; i < insz; i++) {
-        /*      Commented out for BINARY MODE, ie. May have '\0' as legit data *
-            if (buf[i] == '\0')
-              break;
-        */
-        input[j] = buf[i];
-        j++;
+
+    size_t i = (p-in);
+
+    // token to big for the output buffer
+    if (i > Out_Sz)
+        return (-2);
+
+    // wipe the unused Out_Obj area
+    memset(out+i, 0, Out_Sz-i);
+    // copy token from In_Obj to Out_Obj
+    memcpy(Out_Obj, In_Obj, i);
+
+    // omit the delimiter
+    if (*p == chr) {
+        p++;
+        i++;
+    } else {
+        // chr not found
+        memset(In_Obj, 0, In_Sz);
+//        return (-3);
+// Returning <0 breaks current code for last object
+        return (i);
     }
-    /* Should be correctly split back into input, and
-     * split object in obj.  memset() at next call will
-     * clear array data.
-     */
-    i = strlen(input);
-    j = strlen(obj);
-
-    return j;
+
+    // move the unused In_Obj forward
+    memmove(In_Obj, p, In_Sz-i);
+    // wipe the end of In_Obj
+    memset(in+In_Sz-i, 0, i);
+    return (i-1);
 }
 
 /* Displays version information */
@@ -437,13 +384,13 @@ static void DisplayUsage()
 /* Initalizes program's configuration paremeters */
 static void InitConf()
 {
-    memset(edui_conf.program, '\0', sizeof(edui_conf.program));
-    memset(edui_conf.basedn, '\0', sizeof(edui_conf.basedn));
-    memset(edui_conf.host, '\0', sizeof(edui_conf.host));
-    memset(edui_conf.attrib, '\0', sizeof(edui_conf.attrib));
-    memset(edui_conf.dn, '\0', sizeof(edui_conf.dn));
-    memset(edui_conf.passwd, '\0', sizeof(edui_conf.passwd));
-    memset(edui_conf.search_filter, '\0', sizeof(edui_conf.search_filter));
+    *(edui_conf.program) = '\0';
+    *(edui_conf.basedn) = '\0';
+    *(edui_conf.host) = '\0';
+    *(edui_conf.attrib) = '\0';
+    *(edui_conf.dn) = '\0';
+    *(edui_conf.passwd) = '\0';
+    *(edui_conf.search_filter) = '\0';
     edui_conf.scope = -1;
     edui_conf.ver = -1;
     edui_conf.port = -1;
@@ -597,7 +544,7 @@ static void DisplayConf()
  */
 static void InitLDAP(edui_ldap_t *l)
 {
-    if (l == NULL) return;                     /* Duh! */
+    if (l == NULL) return;
 
     l->lp = NULL;
     if (l->lm != NULL)
@@ -606,13 +553,13 @@ static void InitLDAP(edui_ldap_t *l)
         ldap_value_free_len(l->val);
     l->lm = NULL;
     l->val = NULL;
-    memset(l->basedn, '\0', sizeof(l->basedn));
-    memset(l->host, '\0', sizeof(l->host));
-    memset(l->dn, '\0', sizeof(l->dn));
-    memset(l->passwd, '\0', sizeof(l->passwd));
-    memset(l->search_filter, '\0', sizeof(l->search_filter));
+    *(l->basedn) = '\0';
+    *(l->host) = '\0';
+    *(l->dn) = '\0';
+    *(l->passwd) = '\0';
+    *(l->search_filter) = '\0';
+    *(l->userid) = '\0';
     memset(l->search_ip, '\0', sizeof(l->search_ip));
-    memset(l->userid, '\0', sizeof(l->userid));
     l->status = 0;
     l->status |= LDAP_INIT_S;
     l->port = 0;
@@ -621,8 +568,8 @@ static void InitLDAP(edui_ldap_t *l)
     l->err = -1;                                       /* Set error to LDAP_SUCCESS by default */
     l->ver = 0;
     l->idle_time = 0;
-    l->num_ent = 0;                            /* Number of entries in l->lm */
-    l->num_val = 0;                            /* Number of entries in l->val */
+    l->num_ent = 0;                                    /* Number of entries in l->lm */
+    l->num_val = 0;                                    /* Number of entries in l->val */
 
     /* Set default settings from conf */
     if (edui_conf.basedn[0] != '\0')
@@ -639,8 +586,6 @@ static void InitLDAP(edui_ldap_t *l)
         xstrncpy(l->search_filter, edui_conf.search_filter, sizeof(l->search_filter));
     if (!(edui_conf.scope < 0))
         l->scope = edui_conf.scope;
-//    * We Dont Need Bit-Status updates in gerneal debugging. *
-//    debug("New status = %u\n", l->status);
 }
 
 /* OpenLDAP() - <edui_ldap_t> <host> <port>
@@ -652,18 +597,18 @@ int OpenLDAP(edui_ldap_t *l, char *h, unsigned int p)
 {
     if ((l == NULL) || (h == NULL)) return LDAP_ERR_NULL;
     if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT;              /* Not initalized, or might be in use */
-    if (l->status & LDAP_OPEN_S) return LDAP_ERR_OPEN;         /* Already open */
-    if (l->status & LDAP_BIND_S) return LDAP_ERR_BIND;         /* Already bound */
+    if (l->status & LDAP_OPEN_S) return LDAP_ERR_OPEN;                 /* Already open */
+    if (l->status & LDAP_BIND_S) return LDAP_ERR_BIND;                 /* Already bound */
 
     xstrncpy(l->host, h, sizeof(l->host));
     if (p > 0)
         l->port = p;
     else
-        l->port = LDAP_PORT;                           /* Default is port 389 */
+        l->port = LDAP_PORT;                                           /* Default is port 389 */
 
 #ifdef NETSCAPE_SSL
     if (l->port == LDAPS_PORT)
-        l->status |= (LDAP_SSL_S | LDAP_TLS_S);                /* SSL Port: 636 */
+        l->status |= (LDAP_SSL_S | LDAP_TLS_S);                                /* SSL Port: 636 */
 #endif
 
 #ifdef USE_LDAP_INIT
@@ -673,7 +618,7 @@ int OpenLDAP(edui_ldap_t *l, char *h, unsigned int p)
 #endif
     if (l->lp == NULL) {
         l->err = LDAP_CONNECT_ERROR;
-        return LDAP_ERR_CONNECT;                               /* Unable to connect */
+        return LDAP_ERR_CONNECT;                                       /* Unable to connect */
     } else {
         /* set status */
 //    l->status &= ~(LDAP_INIT_S);
@@ -709,8 +654,6 @@ int CloseLDAP(edui_ldap_t *l)
     s = ldap_unbind(l->lp);
     if (s == LDAP_SUCCESS) {
         l->status = LDAP_INIT_S;
-//        * We Dont Need Bit-Status updates in gerneal debugging. *
-//        debug("New status = %u\n", l->status);
         l->idle_time = 0;
         l->err = s;                                                    /* Set LDAP error code */
         return LDAP_ERR_SUCCESS;
@@ -733,7 +676,7 @@ int SetVerLDAP(edui_ldap_t *l, int v)
     if (l->lp == NULL) return LDAP_ERR_POINTER;
     if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT;              /* Not initalized */
     if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN;              /* Not open */
-    if (l->status & LDAP_BIND_S) return LDAP_ERR_BIND;         /* Already bound */
+    if (l->status & LDAP_BIND_S) return LDAP_ERR_BIND;                 /* Already bound */
 
     /* set version */
     x = ldap_set_option(l->lp, LDAP_OPT_PROTOCOL_VERSION, &v);
@@ -758,8 +701,8 @@ int BindLDAP(edui_ldap_t *l, char *dn, char *pw, unsigned int t)
     if (l == NULL) return LDAP_ERR_NULL;
     if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT;              /* Not initalized */
     if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN;              /* Not open */
-    if (l->status & LDAP_BIND_S) return LDAP_ERR_BIND;         /* Already bound */
-    if (l->lp == NULL) return LDAP_ERR_POINTER;                        /* Error */
+    if (l->status & LDAP_BIND_S) return LDAP_ERR_BIND;                 /* Already bound */
+    if (l->lp == NULL) return LDAP_ERR_POINTER;                                /* Error */
 
     /* Copy details - dn and pw CAN be NULL for anonymous and/or TLS */
     if (dn != NULL) {
@@ -774,7 +717,7 @@ int BindLDAP(edui_ldap_t *l, char *dn, char *pw, unsigned int t)
     if (pw != NULL)
         xstrncpy(l->passwd, pw, sizeof(l->passwd));
 
-    /* Type */
+    /* Type */
     switch (t) {
     case LDAP_AUTH_NONE:
         l->type = t;
@@ -801,13 +744,13 @@ int BindLDAP(edui_ldap_t *l, char *dn, char *pw, unsigned int t)
         break;
 #endif
 #ifdef LDAP_AUTH_TLS
-    case LDAP_AUTH_TLS:                                        /* Added for chicken switch to TLS-enabled without using SSL */
+    case LDAP_AUTH_TLS:                                                /* Added for chicken switch to TLS-enabled without using SSL */
         l->type = t;
         break;
 #endif
     default:
         l->type = LDAP_AUTH_NONE;
-        break;                                         /* Default to anonymous bind */
+        break;                                                 /* Default to anonymous bind */
     }
 
     /* Bind */
@@ -843,12 +786,12 @@ int ConvertIP(edui_ldap_t *l, char *ip)
     void *y, *z;
     size_t s;
     long x;
-    int i, j, t, swi;                                                          /* IPv6 "::" cut over toggle */
+    int i, j, t, swi;                                                  /* IPv6 "::" cut over toggle */
     if (l == NULL) return LDAP_ERR_NULL;
     if (ip == NULL) return LDAP_ERR_PARAM;
-    if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT;                      /* Not initalized */
-    if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN;                      /* Not open */
-    if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND;                      /* Not bound */
+    if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT;              /* Not initalized */
+    if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN;              /* Not open */
+    if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND;              /* Not bound */
 
     y = memchr((void *)ip, ':', EDUI_MAXLEN);
     z = memchr((void *)ip, '.', EDUI_MAXLEN);
@@ -862,8 +805,6 @@ int ConvertIP(edui_ldap_t *l, char *ip)
         return LDAP_ERR_INVALID;
     } else if (y != NULL) {
         /* Set IPv6 mode */
-// Taboo debug() call.
-        debug("Setting IPv6 Mode.\n");
         if (l->status & LDAP_IPV4_S)
             l->status &= ~(LDAP_IPV4_S);
         if (!(l->status & LDAP_IPV6_S))
@@ -874,8 +815,6 @@ int ConvertIP(edui_ldap_t *l, char *ip)
         /* IPv6 Mode forced */
         return LDAP_ERR_INVALID;
     } else if (z != NULL) {
-// Taboo debug() call.
-        debug("Setting IPv4 Mode.\n");
         /* Set IPv4 mode */
         if (l->status & LDAP_IPV6_S)
             l->status &= ~(LDAP_IPV6_S);
@@ -884,10 +823,10 @@ int ConvertIP(edui_ldap_t *l, char *ip)
         z = NULL;
     }
     s = strlen(ip);
-    memset(bufa, '\0', sizeof(bufa));
-    memset(bufb, '\0', sizeof(bufb));
-    memset(obj, '\0', sizeof(obj));
-    /* SplitString() will zero out bufa & obj at each call */
+    *(bufa) = '\0';
+    *(bufb) = '\0';
+    *(obj) = '\0';
+    /* StringSplit() will zero out bufa & obj at each call */
     memset(l->search_ip, '\0', sizeof(l->search_ip));
     xstrncpy(bufa, ip, sizeof(bufa));                                          /* To avoid segfaults, use bufa instead of ip */
     swi = 0;
@@ -896,19 +835,19 @@ int ConvertIP(edui_ldap_t *l, char *ip)
         if ((bufa[0] == ':') && (bufa[1] == ':')) {
             /* bufa starts with a ::, so just copy and clear */
             xstrncpy(bufb, bufa, sizeof(bufb));
-            memset(bufa, '\0', strlen(bufa));
+            *(bufa) = '\0';
             swi++;                                                             /* Indicates that there is a bufb */
         } else if ((bufa[0] == ':') && (bufa[1] != ':')) {
             /* bufa starts with a :, a typo so just fill in a ':', cat and clear */
             bufb[0] = ':';
             strncat(bufb, bufa, strlen(bufa));
-            memset(bufa, '\0', strlen(bufa));
+            *(bufa) = '\0';
             swi++;                                                             /* Indicates that there is a bufb */
         } else {
             p = strstr(bufa, "::");
             if (p != NULL) {
                 /* Found it, break bufa down and split into bufb here */
-                memset(bufb, '\0', strlen(bufb));
+                *(bufb) = '\0';
                 i = strlen(p);
                 memcpy(bufb, p, i);
                 *p = '\0';
@@ -923,23 +862,23 @@ int ConvertIP(edui_ldap_t *l, char *ip)
     while (s > 0) {
         if ((l->status & LDAP_IPV4_S) && (swi == 0)) {
             /* Break down IPv4 address  */
-            t = SplitString(bufa, s, '.', obj, sizeof(obj));
+            t = StringSplit(bufa, '.', obj, sizeof(obj));
             if (t > 0) {
                 errno = 0;
                 x = strtol(obj, (char **)NULL, 10);
                 if (((x < 0) || (x > 255)) || ((errno != 0) && (x == 0)) || ((obj[0] != '0') && (x == 0)))
                     return LDAP_ERR_OOB;                                               /* Out of bounds -- Invalid address */
                 memset(hexc, '\0', sizeof(hexc));
-                int hlen = snprintf(hexc, sizeof(hexc), "%.2X", (int)x);
+                int hlen = snprintf(hexc, sizeof(hexc), "%02X", (int)x);
                 strncat(l->search_ip, hexc, hlen);
             } else
                 break;                                                         /* reached end of octet */
         } else if (l->status & LDAP_IPV6_S) {
             /* Break down IPv6 address */
             if (swi > 1)
-                t = SplitString(bufb, s, ':', obj, sizeof(obj));               /* After "::" */
+                t = StringSplit(bufb, ':', obj, sizeof(obj));                  /* After "::" */
             else
-                t = SplitString(bufa, s, ':', obj, sizeof(obj));               /* Before "::" */
+                t = StringSplit(bufa, ':', obj, sizeof(obj));                  /* Before "::" */
             /* Convert octet by size (t) - and fill 0's */
             switch (t) {                                                       /* IPv6 is already in HEX, copy contents */
             case 4:
@@ -1077,7 +1016,6 @@ int ResetLDAP(edui_ldap_t *l)
     if (!(l->status & LDAP_PERSIST_S)) return LDAP_ERR_PERSIST;           /* Not persistent */
 
     /* Cleanup data struct */
-//    debug("Resetting LDAP connection for next query. (status = %u)\n", l->status);
     if (l->status & LDAP_VAL_S)
         l->status &= ~(LDAP_VAL_S);
     if (l->status & LDAP_SEARCH_S)
@@ -1095,14 +1033,13 @@ int ResetLDAP(edui_ldap_t *l)
         l->val = NULL;
     }
     memset(l->search_ip, '\0', sizeof(l->search_ip));
-    memset(l->search_filter, '\0', strlen(l->search_filter));
+    *(l->search_filter) = '\0';
     xstrncpy(l->search_filter, edui_conf.search_filter, sizeof(l->search_filter));
-    memset(l->userid, '\0', strlen(l->userid));
+    *(l->userid) = '\0';
     if (!(l->status & LDAP_IDLE_S))
         l->status |= LDAP_IDLE_S;                                           /* Set idle mode */
     l->num_ent = 0;
     l->num_val = 0;
-//    debug("New status = %u\n", l->status);
     l->err = LDAP_SUCCESS;
     return LDAP_ERR_SUCCESS;
 }
@@ -1119,20 +1056,18 @@ int SearchFilterLDAP(edui_ldap_t *l, char *group)
     int swi;
     char bufa[EDUI_MAXLEN], bufb[EDUI_MAXLEN], bufc[EDUI_MAXLEN], bufd[EDUI_MAXLEN], bufg[EDUI_MAXLEN];
     if (l == NULL) return LDAP_ERR_NULL;
-//  if (group == NULL) return LDAP_ERR_PARAM;
     if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT;                      /* Not initalized */
     if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN;                      /* Not open */
     if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND;                      /* Not Bound */
     if (l->search_ip[0] == '\0') return LDAP_ERR_DATA;                         /* Search IP is required */
 
     /* Zero out if not already */
-    memset(bufa, '\0', sizeof(bufa));
-    memset(bufb, '\0', sizeof(bufb));
-    memset(bufc, '\0', sizeof(bufc));
-    memset(bufd, '\0', sizeof(bufd));
-    memset(bufg, '\0', sizeof(bufg));
+    *(bufa) = '\0';
+    *(bufb) = '\0';
+    *(bufc) = '\0';
+    *(bufd) = '\0';
+    *(bufg) = '\0';
 
-//  debug("Building... (Adding '\\' to IP...) - search_ip: %s\n", l->search_ip);
     s = strlen(l->search_ip);
     bufc[0] = '\134';
     swi = 0;
@@ -1214,9 +1149,9 @@ int SearchLDAP(edui_ldap_t *l, int scope, char *filter, char **attrs)
     if (l == NULL) return LDAP_ERR_NULL;
     if ((scope < 0) || (filter == NULL)) return LDAP_ERR_PARAM;                /* If attrs is NULL, then all attrs will return */
     if (l->lp == NULL) return LDAP_ERR_POINTER;
-    if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT;                      /* Not initalized */
-    if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN;                      /* Not open */
-    if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND;                      /* Not bound */
+    if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT;              /* Not initalized */
+    if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN;              /* Not open */
+    if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND;              /* Not bound */
     if (l->status & LDAP_SEARCH_S) return LDAP_ERR_SEARCHED;           /* Already searching */
     if (l->basedn[0] == '\0') return LDAP_ERR_DATA;                    /* We require a basedn */
     if (l->lm != NULL)
@@ -1246,7 +1181,7 @@ int SearchLDAP(edui_ldap_t *l, int scope, char *filter, char **attrs)
     if (s == LDAP_SUCCESS) {
         l->status |= (LDAP_SEARCH_S);                                  /* Mark as searched */
         l->err = s;
-        l->idle_time = 0;                                                      /* Connection in use, reset idle timer */
+        l->idle_time = 0;                                              /* Connection in use, reset idle timer */
         l->num_ent = ldap_count_entries(l->lp, l->lm);                 /* Counted */
         return LDAP_ERR_SUCCESS;
     } else {
@@ -1257,97 +1192,13 @@ int SearchLDAP(edui_ldap_t *l, int scope, char *filter, char **attrs)
 }
 
 /*
- * GetValLDAP() - <edui_ldap_t> <search-attr>
- *
- * Scan LDAP and look for search-attr, then return results in l->val
- *
- */
-int GetValLDAP(edui_ldap_t *l, char *attr)
-{
-    ber_len_t x;
-    /*
-      ber_len_t i, j;
-      int c;
-    */
-    LDAPMessage *ent;
-    if (l == NULL) return LDAP_ERR_NULL;
-    if (attr == NULL) return LDAP_ERR_PARAM;
-    if (l->lp == NULL) return LDAP_ERR_POINTER;
-    if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT;                      /* Not initalized */
-    if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN;                      /* Not open */
-    if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND;                      /* Not bound */
-    if (!(l->status & LDAP_SEARCH_S)) return LDAP_ERR_NOT_SEARCHED;    /* Not searched */
-    if (l->num_ent <= 0) return LDAP_ERR_DATA;                         /* No entries found */
-    if (l->val != NULL)
-        ldap_value_free_len(l->val);                                   /* Clear data before populating */
-    l->num_val = 0;
-    if (l->status & LDAP_VAL_S)
-        l->status &= ~(LDAP_VAL_S);                                            /* Clear VAL bit */
-
-    /* Sift through entries -- Look for matches */
-    for (ent = ldap_first_entry(l->lp, l->lm); ent != NULL; ent = ldap_next_entry(l->lp, ent)) {
-        l->val = ldap_get_values_len(l->lp, ent, attr);
-        if (l->val != NULL) {
-            x = ldap_count_values_len(l->val);                         /* We got x values ... */
-            l->num_val = x;
-            if (x > 0) {
-                /* Display all values */
-                /* DEBUGGING ONLY *
-                       for (i = 0; i < x; i++) {
-                         local_debug("GetValLDAP", "value[%zd]: \"%s\"\n", i, l->val[i]->bv_val);
-                         local_debug("GetValLDAP", "value[%zd]: ", i);
-                         for (j = 0; j < (l->val[i]->bv_len); j++) {
-                           c = (int) l->val[i]->bv_val[j];
-                           if (c < 0)
-                             c = c + 256;
-                           local_debugx("%.2X", c);
-                         }
-                         local_debugx("\n");
-                       }
-                */
-                /*     CRASHES?!?!
-                       if (ent != NULL)
-                         ldap_msgfree(ent);
-                */
-                if (l->lm != NULL) {
-                    ldap_msgfree(l->lm);
-                    l->lm = NULL;
-                }
-                l->num_ent = 0;
-                l->status &= ~(LDAP_SEARCH_S);
-                l->status |= LDAP_VAL_S;
-                l->err = LDAP_SUCCESS;
-                return LDAP_ERR_SUCCESS;                                       /* Found it */
-            }
-        }
-        /* Attr not found, continue */
-    }
-    /* No entries found using attr */
-    if (l->val != NULL)
-        ldap_value_free_len(l->val);
-    /*
-      if (ent != NULL)
-        ldap_msgfree(ent);
-    */
-    if (l->lm != NULL) {
-        ldap_msgfree(l->lm);
-        l->lm = NULL;
-    }
-    l->num_ent = 0;
-    l->num_val = 0;
-    l->err = LDAP_NO_SUCH_OBJECT;
-    l->status &= ~(LDAP_SEARCH_S);
-    return LDAP_ERR_NOTFOUND;                                          /* Not found */
-}
-
-/*
- * SearchIPLDAP() - <edui_ldap_t> <result-uid>
+ * SearchIPLDAP() - <edui_ldap_t>
  *
  * Scan LDAP and get all networkAddress Values, and see if they match l->search_ip
  * Actual IP matching routine for eDirectory
  *
  */
-int SearchIPLDAP(edui_ldap_t *l, char *uid)
+int SearchIPLDAP(edui_ldap_t *l)
 {
     ber_len_t i, x;
     ber_len_t j, k;
@@ -1356,20 +1207,22 @@ int SearchIPLDAP(edui_ldap_t *l, char *uid)
     char bufa[EDUI_MAXLEN], bufb[EDUI_MAXLEN], hexc[4];
     LDAPMessage *ent;
     if (l == NULL) return LDAP_ERR_NULL;
-    if (uid == NULL) return LDAP_ERR_PARAM;
     if (l->lp == NULL) return LDAP_ERR_POINTER;
     if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT;                              /* Not initalized */
     if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN;                              /* Not open */
     if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND;                              /* Not bound */
     if (!(l->status & LDAP_SEARCH_S)) return LDAP_ERR_NOT_SEARCHED;                    /* Not searched */
-    if (l->num_ent <= 0) return LDAP_ERR_DATA;                                         /* No entries found */
+    if (l->num_ent <= 0) {
+        debug("l->num_ent: %d\n", l->num_ent);
+        return LDAP_ERR_DATA;                                                          /* No entries found */
+    }
     if (l->val != NULL)
         ldap_value_free_len(l->val);                                                   /* Clear data before populating */
     l->num_val = 0;
     if (l->status & LDAP_VAL_S)
         l->status &= ~(LDAP_VAL_S);                                                    /* Clear VAL bit */
     if (edui_conf.attrib[0] == '\0')
-        xstrncpy(edui_conf.attrib, "cn", sizeof(edui_conf.attrib));            /* Make sure edui_conf.attrib is set */
+        xstrncpy(edui_conf.attrib, "cn", sizeof(edui_conf.attrib));                    /* Make sure edui_conf.attrib is set */
 
     /* Sift through entries */
     struct berval **ber = NULL;
@@ -1384,30 +1237,28 @@ int SearchIPLDAP(edui_ldap_t *l, char *uid)
                 for (i = 0; i < x; i++) {
                     j = l->val[i]->bv_len;
                     memcpy(bufa, l->val[i]->bv_val, j);
-                    z = SplitString(bufa, j, '#', bufb, sizeof(bufb));
-                    /* DEBUGGING ONLY *
-                         local_debug("SearchIPLDAP", "value[%zd]: SplitString(", i);
-                         for (k = 0; k < z; k++) {
-                           c = (int) bufb[k];
-                           if (c < 0)
-                             c = c + 256;
-                           local_debugx("%.2X", c);
-                         }
-                         local_debugx(", ");
-                         for (k = 0; k < (j - z - 1); k++) {
-                           c = (int) bufa[k];
-                           if (c < 0)
-                             c = c + 256;
-                           local_debugx("%.2X", c);
-                         }
-                         local_debugx("): %zd\n", z);
-                    */
+                    z = BinarySplit(bufa, j, '#', bufb, sizeof(bufb));
+                    /* BINARY DEBUGGING *
+                                                 local_printfx("value[%zd]: BinarySplit(", (size_t) i);
+                                                 for (k = 0; k < z; k++) {
+                                                   c = (int) bufb[k];
+                                                   if (c < 0)
+                                                     c = c + 256;
+                                                   local_printfx("%02X", c);
+                                                 }
+                                                 local_printfx(", ");
+                                                 for (k = 0; k < (j - z - 1); k++) {
+                                                   c = (int) bufa[k];
+                                                   if (c < 0)
+                                                     c = c + 256;
+                                                   local_printfx("%02X", c);
+                                                 }
+                                                 local_printfx("): %zd\n", (size_t) z);
+                    * BINARY DEBUGGING */
                     z = j - z - 1;
                     j = atoi(bufb);
-                    switch (j) {
-                    case 0:                                                    /* IPX address (We don't support these right now) */
-                        break;
-                    case 1:                                                    /* IPv4 address (eDirectory 8.7 and below) */
+                    if (j == 1) {
+                        /* IPv4 address (eDirectory 8.7 and below) */
                         /* bufa is the address, just compare it */
                         if (!(l->status & LDAP_IPV4_S) || (l->status & LDAP_IPV6_S))
                             break;                                                     /* Not looking for IPv4 */
@@ -1415,7 +1266,7 @@ int SearchIPLDAP(edui_ldap_t *l, char *uid)
                             c = (int) bufa[k];
                             if (c < 0)
                                 c = c + 256;
-                            int hlen = snprintf(hexc, sizeof(hexc), "%.2X", c);
+                            int hlen = snprintf(hexc, sizeof(hexc), "%02X", c);
                             if (k == 0)
                                 xstrncpy(bufb, hexc, sizeof(bufb));
                             else
@@ -1426,40 +1277,11 @@ int SearchIPLDAP(edui_ldap_t *l, char *uid)
                         if (memcmp(l->search_ip, bufb, y) == 0) {
                             /* We got a match! - Scan 'ber' for 'cn' values */
                             z = ldap_count_values_len(ber);
-                            for (j = 0; j < z; j++)
-                                xstrncpy(uid, ber[j]->bv_val, min(sizeof(uid),static_cast<size_t>(ber[j]->bv_len)));
-                            ldap_value_free_len(l->val);
-                            l->val = NULL;
-                            ldap_value_free_len(ber);
-                            ber = NULL;
-                            l->num_val = 0;
-                            l->err = LDAP_SUCCESS;
-                            l->status &= ~(LDAP_SEARCH_S);
-                            return LDAP_ERR_SUCCESS;                           /* We got our userid */
-                        }
-                        /* Not matched, continue */
-                        break;
-                    case 8:                                                    /* IPv4 (UDP) address (eDirectory 8.8 and higher) */
-                        /* bufa + 2 is the address (skip 2 digit port) */
-                        if (!(l->status & LDAP_IPV4_S) || (l->status & LDAP_IPV6_S))
-                            break;                                                     /* Not looking for IPv4 */
-                        for (k = 2; k < z; k++) {
-                            c = (int) bufa[k];
-                            if (c < 0)
-                                c = c + 256;
-                            int hlen = snprintf(hexc, sizeof(hexc), "%.2X", c);
-                            if (k == 2)
-                                xstrncpy(bufb, hexc, sizeof(bufb));
-                            else
-                                strncat(bufb, hexc, hlen);
-                        }
-                        y = strlen(bufb);
-                        /* Compare value with IP */
-                        if (memcmp(l->search_ip, bufb, y) == 0) {
-                            /* We got a match! - Scan 'ber' for 'cn' values */
-                            z = ldap_count_values_len(ber);
-                            for (j = 0; j < z; j++)
-                                xstrncpy(uid, ber[j]->bv_val, min(sizeof(uid),static_cast<size_t>(ber[j]->bv_len)));
+                            for (j = 0; j < z; j++) {
+// broken?                        xstrncpy(l->userid, ber[j]->bv_val, min(sizeof(l->userid),static_cast<size_t>(ber[j]->bv_len)));
+                                xstrncpy(l->userid, ber[j]->bv_val, sizeof(l->userid));
+                                /* Using bv_len of min() breaks the result by 2 chars */
+                            }
                             ldap_value_free_len(l->val);
                             l->val = NULL;
                             ldap_value_free_len(ber);
@@ -1470,8 +1292,8 @@ int SearchIPLDAP(edui_ldap_t *l, char *uid)
                             return LDAP_ERR_SUCCESS;                           /* We got our userid */
                         }
                         /* Not matched, continue */
-                        break;
-                    case 9:                                                    /* IPv4 (TCP) address (eDirectory 8.8 and higher) */
+                    } else if ((j == 8) || (j == 9)) {
+                        /* IPv4 (UDP/TCP) address (eDirectory 8.8 and higher) */
                         /* bufa + 2 is the address (skip 2 digit port) */
                         if (!(l->status & LDAP_IPV4_S) || (l->status & LDAP_IPV6_S))
                             break;                                                     /* Not looking for IPv4 */
@@ -1479,7 +1301,7 @@ int SearchIPLDAP(edui_ldap_t *l, char *uid)
                             c = (int) bufa[k];
                             if (c < 0)
                                 c = c + 256;
-                            int hlen = snprintf(hexc, sizeof(hexc), "%.2X", c);
+                            int hlen = snprintf(hexc, sizeof(hexc), "%02X", c);
                             if (k == 2)
                                 xstrncpy(bufb, hexc, sizeof(bufb));
                             else
@@ -1491,7 +1313,8 @@ int SearchIPLDAP(edui_ldap_t *l, char *uid)
                             /* We got a match! - Scan 'ber' for 'cn' values */
                             z = ldap_count_values_len(ber);
                             for (j = 0; j < z; j++)
-                                xstrncpy(uid, ber[j]->bv_val, min(sizeof(uid),static_cast<size_t>(ber[j]->bv_len)));
+// broken?                        xstrncpy(l->userid, ber[j]->bv_val, min(sizeof(l->userid),static_cast<size_t>(ber[j]->bv_len)));
+                                xstrncpy(l->userid, ber[j]->bv_val, sizeof(l->userid));
                             ldap_value_free_len(l->val);
                             l->val = NULL;
                             ldap_value_free_len(ber);
@@ -1502,8 +1325,8 @@ int SearchIPLDAP(edui_ldap_t *l, char *uid)
                             return LDAP_ERR_SUCCESS;                           /* We got our userid */
                         }
                         /* Not matched, continue */
-                        break;
-                    case 10:                                                   /* IPv6 (UDP) address (eDirectory 8.8 and higher) */
+                    } else if ((j == 10) || (j == 11)) {
+                        /* IPv6 (UDP/TCP) address (eDirectory 8.8 and higher) */
                         /* bufa + 2 is the address (skip 2 digit port) */
                         if (!(l->status & LDAP_IPV6_S))
                             break;                                                     /* Not looking for IPv6 */
@@ -1511,7 +1334,7 @@ int SearchIPLDAP(edui_ldap_t *l, char *uid)
                             c = (int) bufa[k];
                             if (c < 0)
                                 c = c + 256;
-                            int hlen = snprintf(hexc, sizeof(hexc), "%.2X", c);
+                            int hlen = snprintf(hexc, sizeof(hexc), "%02X", c);
                             if (k == 2)
                                 xstrncpy(bufb, hexc, sizeof(bufb));
                             else
@@ -1523,7 +1346,8 @@ int SearchIPLDAP(edui_ldap_t *l, char *uid)
                             /* We got a match! - Scan 'ber' for 'cn' values */
                             z = ldap_count_values_len(ber);
                             for (j = 0; j < z; j++)
-                                xstrncpy(uid, ber[j]->bv_val, min(sizeof(uid),static_cast<size_t>(ber[j]->bv_len)));
+// broken?                        xstrncpy(l->userid, ber[j]->bv_val, min(sizeof(l->userid),static_cast<size_t>(ber[j]->bv_len)));
+                                xstrncpy(l->userid, ber[j]->bv_val, sizeof(l->userid));
                             ldap_value_free_len(l->val);
                             l->val = NULL;
                             ldap_value_free_len(ber);
@@ -1534,42 +1358,10 @@ int SearchIPLDAP(edui_ldap_t *l, char *uid)
                             return LDAP_ERR_SUCCESS;                           /* We got our userid */
                         }
                         /* Not matched, continue */
-                        break;
-                    case 11:                                                   /* IPv6 (TCP) address (eDirectory 8.8 and higher) */
-                        /* bufa + 2 is the address (skip 2 digit port) */
-                        if (!(l->status & LDAP_IPV6_S))
-                            break;                                                     /* Not looking for IPv6 */
-                        for (k = 2; k < z; k++) {
-                            c = (int) bufa[k];
-                            if (c < 0)
-                                c = c + 256;
-                            int hlen = snprintf(hexc, sizeof(hexc), "%.2X", c);
-                            if (k == 2)
-                                xstrncpy(bufb, hexc, sizeof(bufb));
-                            else
-                                strncat(bufb, hexc, hlen);
-                        }
-                        y = strlen(bufb);
-                        /* Compare value with IP */
-                        if (memcmp(l->search_ip, bufb, y) == 0) {
-                            /* We got a match! - Scan 'ber' for 'cn' values */
-                            z = ldap_count_values_len(ber);
-                            for (j = 0; j < z; j++)
-                                xstrncpy(uid, ber[j]->bv_val, min(sizeof(uid),static_cast<size_t>(ber[j]->bv_len)));
-                            ldap_value_free_len(l->val);
-                            l->val = NULL;
-                            ldap_value_free_len(ber);
-                            ber = NULL;
-                            l->num_val = 0;
-                            l->err = LDAP_SUCCESS;
-                            l->status &= ~(LDAP_SEARCH_S);
-                            return LDAP_ERR_SUCCESS;                           /* We gout our userid */
-                        }
-                        /* Not matched, continue */
-                        break;
-                    default:                                                   /* Other, unsupported */
-                        break;
                     }
+//                 else {
+                    /* Others are unsupported */
+//                    }
                 }
                 if (ber != NULL) {
                     ldap_value_free_len(ber);
@@ -1682,11 +1474,11 @@ int main(int argc, char **argv)
     memset(bufb, '\0', sizeof(bufb));
     memset(bufc, '\0', sizeof(bufc));
     memset(sfmod, '\0', sizeof(sfmod));
+
     InitConf();
     xstrncpy(edui_conf.program, argv[0], sizeof(edui_conf.program));
     edui_now = -1;
     t = -1;
-//    debug("InitConf() done.\n");
 
     /* Scan args */
     if (k > 1) {
@@ -1714,26 +1506,26 @@ int main(int argc, char **argv)
                     case 'd':
                         if (!(edui_conf.mode & EDUI_MODE_DEBUG))
                             edui_conf.mode |= EDUI_MODE_DEBUG;         /* Don't set mode more than once */
-                        debug_enabled = 1;                             /* Squid-3 Debug Mode */
+                        debug_enabled = 1;                             /* Official Squid-3 Debug Mode */
                         break;
                     case '4':
                         if (!(edui_conf.mode & EDUI_MODE_IPV4) || !(edui_conf.mode & EDUI_MODE_IPV6))
-                            edui_conf.mode |= EDUI_MODE_IPV4;                  /* Don't set mode more than once */
+                            edui_conf.mode |= EDUI_MODE_IPV4;          /* Don't set mode more than once */
                         break;
                     case '6':
                         if (!(edui_conf.mode & EDUI_MODE_IPV4) || !(edui_conf.mode & EDUI_MODE_IPV6))
-                            edui_conf.mode |= EDUI_MODE_IPV6;                  /* Don't set mode more than once */
+                            edui_conf.mode |= EDUI_MODE_IPV6;          /* Don't set mode more than once */
                         break;
                     case 'Z':
                         if (!(edui_conf.mode & EDUI_MODE_TLS))
-                            edui_conf.mode |= EDUI_MODE_TLS;                   /* Don't set mode more than once */
+                            edui_conf.mode |= EDUI_MODE_TLS;           /* Don't set mode more than once */
                         break;
                     case 'P':
                         if (!(edui_conf.mode & EDUI_MODE_PERSIST))
-                            edui_conf.mode |= EDUI_MODE_PERSIST;                       /* Don't set mode more than once */
+                            edui_conf.mode |= EDUI_MODE_PERSIST;       /* Don't set mode more than once */
                         break;
                     case 'v':
-                        i++;
+                        i++;                                           /* Set LDAP version */
                         if (argv[i] != NULL) {
                             edui_conf.ver = atoi(argv[i]);
                             if (edui_conf.ver < 1)
@@ -1747,7 +1539,7 @@ int main(int argc, char **argv)
                         }
                         break;
                     case 't':
-                        i++;
+                        i++;                                           /* Set Persistent timeout */
                         if (argv[i] != NULL) {
                             edui_conf.persist_timeout = atoi(argv[i]);
                             if (edui_conf.persist_timeout < 0)
@@ -1759,7 +1551,7 @@ int main(int argc, char **argv)
                         }
                         break;
                     case 'b':
-                        i++;                                   /* Set Base DN */
+                        i++;                                           /* Set Base DN */
                         if (argv[i] != NULL)
                             xstrncpy(edui_conf.basedn, argv[i], sizeof(edui_conf.basedn));
                         else {
@@ -1769,7 +1561,7 @@ int main(int argc, char **argv)
                         }
                         break;
                     case 'H':
-                        i++;                                   /* Set Hostname */
+                        i++;                                           /* Set Hostname */
                         if (argv[i] != NULL)
                             xstrncpy(edui_conf.host, argv[i], sizeof(edui_conf.host));
                         else {
@@ -1779,7 +1571,7 @@ int main(int argc, char **argv)
                         }
                         break;
                     case 'p':
-                        i++;                                   /* Set port */
+                        i++;                                           /* Set port */
                         if (argv[i] != NULL)
                             edui_conf.port = atoi(argv[i]);
                         else {
@@ -1789,7 +1581,7 @@ int main(int argc, char **argv)
                         }
                         break;
                     case 'D':
-                        i++;                                   /* Set Bind DN */
+                        i++;                                           /* Set Bind DN */
                         if (argv[i] != NULL)
                             xstrncpy(edui_conf.dn, argv[i], sizeof(edui_conf.dn));
                         else {
@@ -1799,7 +1591,7 @@ int main(int argc, char **argv)
                         }
                         break;
                     case 'W':
-                        i++;                                   /* Set Bind PWD */
+                        i++;                                           /* Set Bind PWD */
                         if (argv[i] != NULL)
                             xstrncpy(edui_conf.passwd, argv[i], sizeof(edui_conf.passwd));
                         else {
@@ -1809,7 +1601,7 @@ int main(int argc, char **argv)
                         }
                         break;
                     case 'F':
-                        i++;                                   /* Set Search Filter */
+                        i++;                                           /* Set Search Filter */
                         if (argv[i] != NULL)
                             xstrncpy(edui_conf.search_filter, argv[i], sizeof(edui_conf.search_filter));
                         else {
@@ -1823,7 +1615,7 @@ int main(int argc, char **argv)
                             edui_conf.mode |= EDUI_MODE_GROUP;         /* Don't set mode more than once */
                         break;
                     case 's':
-                        i++;                                   /* Set Scope Level */
+                        i++;                                           /* Set Scope Level */
                         if (argv[i] != NULL) {
                             if (!strncmp(argv[i], "base", 4))
                                 edui_conf.scope = 0;
@@ -1849,7 +1641,7 @@ int main(int argc, char **argv)
                             return 1;
                         }
                         break;
-                    case '-':                                  /* We got a second '-' ... ignore */
+                    case '-':                                          /* We got a second '-' ... ignore */
                         break;
                     default:
                         local_printfx("Invalid parameter - '%c'.\n", argv[i][j]);
@@ -1890,11 +1682,6 @@ int main(int argc, char **argv)
         DisplayUsage();
         return 1;
     }
-    debug("Configuration done.\n");
-
-    DisplayConf();
-    /* Done with arguments */
-
     /* Trap the following signals */
     sigemptyset(&sv.sa_mask);
     sv.sa_handler = SigTrap;
@@ -1907,12 +1694,13 @@ int main(int argc, char **argv)
     sigaction(SIGINT, &sv, NULL);
     sv.sa_handler = SigTrap;
     sigaction(SIGSEGV, &sv, NULL);
-//    debug("Signals trapped.\n");
+
+    DisplayConf();
+    /* Done with arguments */
 
     /* Set elap timer */
     time(&edui_now);
     t = edui_now;
-
     /* Main loop -- Waits for stdin input before action */
     while (fgets(bufa, sizeof(bufa), stdin) != NULL) {
         if (edui_conf.mode & EDUI_MODE_KILL)
@@ -1921,18 +1709,16 @@ int main(int argc, char **argv)
         if (t < edui_now) {
             /* Elapse seconds */
             edui_elap = edui_now - t;
-//      debug("while() -> %d seconds elapsed.\n", edui_elap);
             t = edui_now;
         } else
             edui_elap = 0;
         k = strlen(bufa);
-        /* *** Extended DEBUGGING ONLY ***
-            local_debug("main", "while() -> bufa[%zd]: %s", k, bufa);
-            local_debug("main", "while() -> bufa[%zd]: ");
-            for (i = 0; i < k; i++)
-              local_debugx("%.2X", bufa[i]);
-            local_debugx("\n");
-        */
+        /* BINARY DEBUGGING *
+                    local_printfx("while() -> bufa[%zd]: %s", k, bufa);
+                    for (i = 0; i < k; i++)
+                      local_printfx("%02X", bufa[i]);
+                    local_printfx("\n");
+        * BINARY DEBUGGING */
         /* Check for CRLF */
         p = strchr(bufa, '\n');
         if (p != NULL)
@@ -2035,10 +1821,10 @@ int main(int argc, char **argv)
         /* If we got a group string, split it */
         if (p != NULL) {
             /* Split string */
-//            debug("SplitString(%s, %zd, ' ', %s, %zd)\n", bufa, strlen(bufa), bufb, sizeof(bufb));
-            i = SplitString(bufa, strlen(bufa), ' ', bufb, sizeof(bufb));
+            debug("StringSplit(%s, ' ', %s, %zd)\n", bufa, bufb, sizeof(bufb));
+            i = StringSplit(bufa, ' ', bufb, sizeof(bufb));
             if (i > 0) {
-                debug("SplitString(%s, %s) done.  Result: %zd\n", bufa, bufb, i);
+                debug("StringSplit(%s, %s) done.  Result: %zd\n", bufa, bufb, i);
                 /* Got a group to match against */
                 x = ConvertIP(&edui_ldap, bufb);
                 if (x < 0) {
@@ -2062,22 +1848,22 @@ int main(int argc, char **argv)
                         } else {
                             edui_ldap.err = -1;
                             debug("SearchLDAP(-, %d, %s, -) -> %s\n", edui_conf.scope, edui_ldap.search_filter, ErrLDAP(x));
-                            x = SearchIPLDAP(&edui_ldap, bufc);
+                            x = SearchIPLDAP(&edui_ldap);
                             if (x != LDAP_ERR_SUCCESS) {
                                 debug("SearchIPLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(edui_ldap.err));
                                 local_printfx("ERR (SearchIPLDAP: %s)\n", ErrLDAP(x));
                             } else {
-                                debug("SearchIPLDAP(-, %s) -> %s\n", bufc, ErrLDAP(x));
-                                local_printfx("OK user=%s\n", bufc);                   /* Got userid --> OK user=<userid> */
+                                debug("SearchIPLDAP(-, %s) -> %s\n", edui_ldap.userid, ErrLDAP(x));
+                                local_printfx("OK user=%s\n", edui_ldap.userid);                       /* Got userid --> OK user=<userid> */
                             }
                         }
                         /* Clear for next query */
-                        memset(bufc, '\0', strlen(bufc));
+                        memset(bufc, '\0', sizeof(bufc));
                     }
                 }
             } else {
-                debug("SplitString() -> Error: %Zu\n", i);
-                local_printfx("ERR (SplitString Error %d)\n", i);
+                debug("StringSplit() -> Error: %Zu\n", i);
+                local_printfx("ERR (StringSplit Error %d)\n", i);
             }
         } else {
             /* No group to match against, only an IP */
@@ -2102,24 +1888,24 @@ int main(int argc, char **argv)
                     } else {
                         edui_ldap.err = -1;
                         debug("SearchLDAP(-, %d, %s, -) -> %s\n", edui_conf.scope, edui_ldap.search_filter, ErrLDAP(x));
-                        x = SearchIPLDAP(&edui_ldap, bufc);
+                        x = SearchIPLDAP(&edui_ldap);
                         if (x != LDAP_ERR_SUCCESS) {
                             debug("SearchIPLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(edui_ldap.err));
                             local_printfx("ERR (SearchIPLDAP: %s)\n", ErrLDAP(x));
                         } else {
-                            debug("SearchIPLDAP(-, %s) -> %s\n", bufc, ErrLDAP(x));
-                            local_printfx("OK user=%s\n", bufc);                               /* Got a userid --> OK user=<userid> */
+                            debug("SearchIPLDAP(-, %s) -> %s\n", edui_ldap.userid, ErrLDAP(x));
+                            local_printfx("OK user=%s\n", edui_ldap.userid);                           /* Got a userid --> OK user=<userid> */
                         }
                     }
                 }
                 /* Clear for next query */
-                memset(bufc, '\0', strlen(bufc));
+                memset(bufc, '\0', sizeof(bufc));
             }
         }
 
         /* Clear buffer and close for next data, if not persistent */
         edui_ldap.err = -1;
-        memset(bufa, '\0', strlen(bufa));
+        memset(bufa, '\0', sizeof(bufa));
         if (!(edui_ldap.status & LDAP_PERSIST_S)) {
             x = CloseLDAP(&edui_ldap);
             debug("CloseLDAP(-) -> %s\n", ErrLDAP(x));
index 4c1c762e9f7757b061fb1a3091f61ee7de6ffbf9..62849da1bb2ae98e2792c4ade88233f8ebcb1ee8 100644 (file)
@@ -2,13 +2,19 @@
 # Don't build without gssapi.h
 if [ -f /usr/include/ldap.h -o -f /usr/local/include/ldap.h ]; then
        # Won't link without SASL as well
-       if [ -f /usr/include/sasl.h -o -f /usr/include/sasl/sasl.h ]; then
+       if [ -f /usr/include/sasl.h -o -f /usr/include/sasl/sasl.h -o -f /usr/local/include/sasl.h -o -f /usr/local/include/sasl/sasl.h ]; then
                if [ -f /usr/lib/libsasl.a -o -f /usr/lib/libsasl2.a ]; then
                        exit 0
                fi
                if [ -f /usr/lib/libsasl.la -o -f /usr/lib/libsasl2.la ]; then
                        exit 0
                fi
+               if [ -f /usr/lib/libsasl.so -o -f /usr/lib/libsasl2.so ]; then
+                       exit 0
+               fi
+               if [ -f  /usr/local/lib/libsasl.so -o -f  /usr/local/lib/libsasl2.so ]; then
+                       exit 0
+               fi
        fi
 fi
 exit 1
index 996b7525267ae88ed99a2e645a7f149b8f542ec1..46b141676a4d0c7c0db1c98ac7a789fe20c58b47 100644 (file)
 #include <string.h>
 #endif
 
-#if HAVE_HEIMDAL_KERBEROS
 #if HAVE_GSSAPI_GSSAPI_H
 #include <gssapi/gssapi.h>
 #elif HAVE_GSSAPI_H
 #include <gssapi.h>
 #endif /* HAVE_GSSAPI_GSSAPI_H/HAVE_GSSAPI_H */
-#if HAVE_KRB5_H
-#if HAVE_BROKEN_SOLARIS_KRB5_H
-#warn "Warning! You have a broken Solaris <krb5.h> fsystem header"
-#warn "http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=6837512"
-#endif /* HAVE_BROKEN_SOLARIS_KRB5_H */
-#include <krb5.h>
-#endif /* HAVE_KRB5_H */
-#if HAVE_COM_ERR_H
-#include <com_err.h>
-#else
-#define error_message(code) krb5_get_err_text(kparam.context,code)
-#endif /* HAVE_COM_ERR_H */
-#else /*MIT */
-#ifdef HAVE_GSSAPI_GSSAPI_H
-#include <gssapi/gssapi.h>
-#elif defined(HAVE_GSSAPI_H)
-#include <gssapi.h>
-#endif
-#ifdef HAVE_GSSAPI_GSSAPI_KRB5_H
+
+#if !HAVE_HEIMDAL_KERBEROS
+#if HAVE_GSSAPI_GSSAPI_KRB5_H
 #include <gssapi/gssapi_krb5.h>
 #endif
-#ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H
+#if HAVE_GSSAPI_GSSAPI_GENERIC_H
 #include <gssapi/gssapi_generic.h>
 #endif
-#ifdef HAVE_GSSAPI_GSSAPI_EXT_H
+#if HAVE_GSSAPI_GSSAPI_EXT_H
 #include <gssapi/gssapi_ext.h>
 #endif
-#ifdef HAVE_KRB5_H
+#endif
+
+#if HAVE_KRB5_H
 #if HAVE_BROKEN_SOLARIS_KRB5_H
+#warn "Warning! You have a broken Solaris <krb5.h> system header"
+#warn "http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=6837512"
 #if defined(__cplusplus)
 #define KRB5INT_BEGIN_DECLS     extern "C" {
 #define KRB5INT_END_DECLS
 KRB5INT_BEGIN_DECLS
 #endif
-#endif
+#endif /* HAVE_BROKEN_SOLARIS_KRB5_H */
+#if HAVE_BROKEN_HEIMDAL_KRB5_H
+extern "C" {
+#include <krb5.h>
+}
+#else
 #include <krb5.h>
 #endif
-#ifdef HAVE_COM_ERR_H
+#endif /* HAVE_KRB5_H */
+
+#if HAVE_COM_ERR_H
 #include <com_err.h>
-#endif
-#endif
+#elif HAVE_HEIMDAL_KERBEROS
+#define error_message(code) krb5_get_err_text(kparam.context,code)
+#endif /* HAVE_COM_ERR_H */
+
 #ifndef gss_nt_service_name
 #define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
 #endif
index 3d43d985f8c6383987ec2d654e37d9f58a7d051b..d2421f8c7d5f62c701703028700a15f5eb7685b2 100644 (file)
@@ -41,7 +41,8 @@ LogTime()
 
     gettimeofday(&now, NULL);
     if (now.tv_sec != last_t) {
-        tm = localtime(&now.tv_sec);
+        time_t tmp = now.tv_sec;
+        tm = localtime(&tmp);
         strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm);
         last_t = now.tv_sec;
     }
index fdaf038639ae1e918d170258b7d18808eb74697d..ea9995da349130e8088e5fca6a58c4fe6056cd9d 100755 (executable)
@@ -1,12 +1,18 @@
 #!/bin/sh
-
-for sambaprefix in ${SAMBAPREFIX} /usr/local /opt /opt/samba /usr/local/samba /usr
+samba_found="no"
+for sambaprefix in /usr/local /opt /opt/samba /usr/local/samba /usr
 do
-    for perlprefix in /usr /usr/local /opt /opt/perl
-    do
-        if [ -x $sambaprefix/bin/wbinfo -a -x $perlprefix/bin/perl ]; then
-            exit 0
-        fi
-    done
+    if [ -x $sambaprefix/bin/wbinfo ]; then
+      samba_found="yes"
+    fi
+done
+if test "$samba_found" = "no"; then
+    echo "WARNING: Samba wbinfo not found in default location. ext_wbinfo_group_acl may not work on this machine"
+fi
+for perlprefix in /usr /usr/local /opt /opt/perl
+do
+    if [ -x $perlprefix/bin/perl ]; then
+        exit 0
+    fi
 done
 exit 1
diff --git a/helpers/log_daemon/DB/Makefile.am b/helpers/log_daemon/DB/Makefile.am
new file mode 100644 (file)
index 0000000..25a9b08
--- /dev/null
@@ -0,0 +1,17 @@
+include $(top_srcdir)/src/Common.am
+
+libexec_SCRIPTS        = log_db_daemon
+CLEANFILES += log_db_daemon log_db_daemon.8
+man_MANS = log_db_daemon.8
+EXTRA_DIST= \
+       config.test \
+       doc/views.sql \
+       doc/date_day_column.sql \
+       log_db_daemon.8 \
+       log_db_daemon.pl.in
+
+log_db_daemon.8: log_db_daemon
+       pod2man log_db_daemon log_db_daemon.8
+
+log_db_daemon: log_db_daemon.pl.in
+       $(subst_perlshell)
diff --git a/helpers/log_daemon/DB/config.test b/helpers/log_daemon/DB/config.test
new file mode 100755 (executable)
index 0000000..387b7b1
--- /dev/null
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+## Test: do we have perl to build the helper scripts?
+## Test: do we have pod2man to build the manual?
+perl --version >/dev/null && echo | pod2man >/dev/null
+
+exit $?
diff --git a/helpers/log_daemon/DB/doc/date_day_column.sql b/helpers/log_daemon/DB/doc/date_day_column.sql
new file mode 100644 (file)
index 0000000..b5067b2
--- /dev/null
@@ -0,0 +1,28 @@
+-- we need a separate column to store the date and time of the request
+ALTER TABLE access_log ADD COLUMN date_day DATE;
+ALTER TABLE access_log ADD COLUMN date_time TIME;
+
+-- let's populate the new columns, in case some rows already exist;
+-- the date and time values should be set by a trigger
+UPDATE access_log SET date_day  = DATE(FROM_UNIXTIME(time_since_epoch));
+UPDATE access_log SET date_time = TIME(FROM_UNIXTIME(time_since_epoch));
+
+-- let's create a view that uses the date column
+CREATE VIEW requests_per_day_2 AS SELECT date_day, COUNT(*) AS num_of_requests FROM access_log GROUP BY 1 ORDER BY 1;
+
+-- that view needs an index on the group by column
+CREATE INDEX date_day_idx ON access_log(date_day);
+
+
+-- a trigger that automatically extracts the date value from the time_since_epoch column
+-- and stores it in the date_day column
+DELIMITER //
+CREATE TRIGGER extract_date_day_bi BEFORE INSERT ON access_log FOR EACH ROW
+BEGIN
+       SET NEW.date_day  = DATE(FROM_UNIXTIME(NEW.time_since_epoch));
+    SET NEW.date_time = TIME(FROM_UNIXTIME(NEW.time_since_epoch));
+END //
+
+
+-- Note: after running this script against an already populated access_log,
+-- views have to be recreated, or the new date_day column will not show up.
diff --git a/helpers/log_daemon/DB/doc/views.sql b/helpers/log_daemon/DB/doc/views.sql
new file mode 100644 (file)
index 0000000..b363c3b
--- /dev/null
@@ -0,0 +1,405 @@
+--
+-- Sample views
+--
+
+-- ip address of hosts accessing the cache
+CREATE OR REPLACE VIEW cache_clients AS
+    SELECT DISTINCT ip_client FROM access_log ORDER BY 1;
+
+-- this index helps view 'cache_clients'
+CREATE INDEX client_ip_idx ON access_log(ip_client);
+
+
+-- traffic by client
+CREATE OR REPLACE VIEW traffic_by_client AS
+    SELECT
+        ip_client,
+        SUM(http_reply_size)         AS total_bytes,
+        SUM(http_reply_size)/1024    AS total_kilobytes,
+        SUM(http_reply_size)/1048576 AS total_megabytes
+    FROM access_log
+    GROUP BY 1
+    ORDER BY 1;
+
+-- most active clients
+-- same as before, but sorted by traffic;
+-- show only the 10 most active clients
+CREATE OR REPLACE VIEW most_active_clients AS
+    SELECT
+        ip_client,
+        SUM(http_reply_size)         AS total_bytes,
+        SUM(http_reply_size)/1024    AS total_kilobytes,
+        SUM(http_reply_size)/1048576 AS total_megabytes
+    FROM access_log
+    GROUP BY 1
+    ORDER BY 2 DESC
+    LIMIT 10;
+
+
+-- traffic per day
+CREATE OR REPLACE VIEW traffic_per_day AS
+    SELECT
+        date_day,
+        SUM(http_reply_size)         AS total_bytes,
+        SUM(http_reply_size)/1024    AS total_kilobytes,
+        SUM(http_reply_size)/1048576 AS total_megabytes
+    FROM access_log
+    GROUP BY 1
+    ORDER BY 1;
+
+-- traffic by client per day
+CREATE OR REPLACE VIEW traffic_per_day_per_client AS
+    SELECT
+        date_day,
+        ip_client,
+        SUM(http_reply_size)         AS total_bytes,
+        SUM(http_reply_size)/1024    AS total_kilobytes,
+        SUM(http_reply_size)/1048576 AS total_megabytes
+    FROM access_log
+    GROUP BY 1,2
+    ORDER BY 1,2 DESC;
+
+CREATE OR REPLACE VIEW traffic_per_month_per_client AS
+    SELECT
+        YEAR(date_day)          AS date_year,
+        MONTH(date_day)         AS date_month,
+        ip_client,
+        SUM(http_reply_size)         AS total_bytes,
+        SUM(http_reply_size)/1024    AS total_kilobytes,
+        SUM(http_reply_size)/1048576 AS total_megabytes
+    FROM access_log
+    GROUP BY 2,3
+    ORDER BY 1,2,3;
+
+-- list of clients with some stats
+CREATE OR REPLACE VIEW cache_clients_with_infos AS
+SELECT
+    a.ip_client,
+    COUNT(*)                                                         AS total_requests,
+    (COUNT(*)/(SELECT COUNT(*) FROM access_log))*100                 AS requests_perc,
+    SUM(a.http_reply_size)                                                AS total_traffic,
+    (SUM(a.http_reply_size)/(SELECT SUM(http_reply_size) FROM access_log))*100 AS traffic_perc,
+    (SELECT COUNT(*) FROM access_log a1 WHERE a1.ip_client=a.ip_client AND squid_request_status LIKE '%HIT%')
+    /
+    (SELECT COUNT(*) FROM access_log)
+    * 100                                                            AS hit_perc,
+    (SELECT COUNT(*) FROM access_log a1 WHERE a1.ip_client=a.ip_client AND squid_request_status LIKE '%MISS%')
+    /
+    (SELECT COUNT(*) FROM access_log)
+    * 100                                                            AS miss_perc,
+    MIN(date_day) AS first_access_date,
+    MIN(date_time) AS first_access_time,
+    MAX(date_day) AS last_access_date,
+    MAX(date_time) AS last_access_time
+FROM access_log a
+GROUP BY 1
+ORDER BY 1;
+
+-- this index helps view 'cache_clients_with_infos'
+CREATE INDEX client_req_status_idx ON access_log(ip_client, squid_request_status);
+
+
+-- number of requests per day
+CREATE OR REPLACE VIEW requests_per_day AS
+    SELECT
+        DATE(FROM_UNIXTIME(time_since_epoch)) AS date_day,
+        COUNT(*) AS num_of_requests
+    FROM access_log
+    GROUP BY 1
+    ORDER BY 1;
+
+-- number of requests per minute
+CREATE OR REPLACE VIEW requests_per_minute AS
+    SELECT
+        DATE(FROM_UNIXTIME(time_since_epoch)) AS date_day,
+        HOUR(FROM_UNIXTIME(time_since_epoch)) AS date_hour,
+        MINUTE(FROM_UNIXTIME(time_since_epoch)) AS date_minute,
+        COUNT(*) AS num_of_requests
+    FROM access_log
+    GROUP BY 1,2,3
+    ORDER BY 1,2,3;
+
+-- number of requests per day of each cache client
+CREATE OR REPLACE VIEW requests_per_day_per_client AS
+    SELECT
+        DATE(FROM_UNIXTIME(time_since_epoch)) AS date_day,
+        ip_client,
+        COUNT(*) AS num_of_requests
+        FROM access_log
+        GROUP BY 1,2
+        ORDER BY 1,2;
+
+-- percentage of each request status
+CREATE OR REPLACE VIEW requests_status_perc AS
+    SELECT
+        squid_request_status,
+        (COUNT(*)/(SELECT COUNT(*) FROM access_log)*100) AS percentage
+    FROM access_log
+    GROUP BY squid_request_status
+    ORDER BY 2 DESC;
+
+-- this index helps view 'requests_status_perc'
+CREATE INDEX req_status_idx ON access_log(squid_request_status);
+
+-- request hits and misses, in percentage
+CREATE OR REPLACE VIEW hits_misses_perc AS
+    SELECT
+        'hits',
+        (SELECT COUNT(*) FROM access_log WHERE squid_request_status LIKE '%HIT%')
+        /
+        (SELECT COUNT(*) FROM access_log)*100
+        AS percentage
+UNION
+    SELECT
+        'misses',
+        (SELECT COUNT(*) FROM access_log WHERE squid_request_status LIKE '%MISS%')
+        /
+        (SELECT COUNT(*) FROM access_log)*100
+        AS pecentage;
+
+-- response times
+CREATE OR REPLACE VIEW time_response_ranges AS
+    SELECT
+        '0..500',
+        COUNT(*) / (SELECT COUNT(*) FROM access_log)*100 AS percentage
+    FROM access_log
+    WHERE time_response >= 0 AND time_response < 500
+UNION
+    SELECT
+        '500..1000',
+        COUNT(*) / (SELECT COUNT(*) FROM access_log)*100 AS percentage
+    FROM access_log
+    WHERE time_response >= 500 AND time_response < 1000
+UNION
+    SELECT
+        '1000..2000',
+        COUNT(*) / (SELECT COUNT(*) FROM access_log)*100 AS percentage
+    FROM access_log
+    WHERE time_response >= 1000 AND time_response < 2000
+UNION
+    SELECT
+        '>= 2000',
+        COUNT(*) / (SELECT COUNT(*) FROM access_log)*100 AS percentage
+    FROM access_log
+    WHERE time_response >= 2000;
+
+-- this index helps view 'time_response_ranges'
+CREATE INDEX time_response_idx ON access_log(time_response);
+
+-- response time graph
+CREATE OR REPLACE VIEW time_response_graph AS
+    SELECT
+        time_response,
+        COUNT(*) AS num_req
+    FROM access_log
+    GROUP BY 1
+    ORDER BY 1;
+
+-- traffic by mime type
+CREATE OR REPLACE VIEW traffic_by_http_mime_type AS
+    SELECT
+        http_mime_type,
+        SUM(http_reply_size) as total_bytes
+    FROM access_log
+    GROUP BY http_mime_type
+    ORDER BY 2 DESC;
+
+-- last 10 queries
+CREATE OR REPLACE VIEW last_10_queries AS
+    SELECT *
+    FROM access_log
+    WHERE
+        id > (SELECT MAX(id) FROM access_log) - 10
+    ORDER BY id DESC;
+
+-- id of the last query of each client
+-- this view is required by the "last n queries by ip" view
+CREATE OR REPLACE VIEW last_query_by_client AS
+    SELECT
+        ip_client,
+        MAX(id) AS last_query_id
+    FROM access_log
+    GROUP BY ip_client;
+
+
+-- last 10 queries of each client
+-- NOTE: this query is conceptually wrong because it assumes that no holes exist
+-- in the values of column 'id'.
+-- This can be false if e.g. some access_log entries get deleted...
+CREATE OR REPLACE VIEW last_10_queries_by_client AS
+    SELECT *
+    FROM access_log a
+    WHERE
+        id > (
+            SELECT l.last_query_id
+            FROM last_query_by_client l
+            WHERE l.ip_client = a.ip_client
+        ) - 10
+    ORDER BY a.ip_client, a.id DESC;
+
+-- this index helps the "last_10_queries_by_client" view
+CREATE INDEX client_ip_record_id_idx ON access_log(ip_client, id);
+
+
+-- number of HIT requests per day
+CREATE OR REPLACE VIEW hits_per_day AS
+    SELECT
+        date_day,
+        COUNT(*) AS num_hits
+    FROM access_log
+    WHERE squid_request_status LIKE '%HIT%'
+    GROUP BY 1;
+
+-- HIT requests per day, percent (100% = total number of requests that day)
+CREATE OR REPLACE VIEW hits_per_day_perc AS
+    SELECT
+        r.date_day,
+        h.num_hits/r.num_of_requests*100 AS hits_per_day_perc
+    FROM requests_per_day r
+    JOIN
+        hits_per_day h
+        ON r.date_day = h.date_day;
+
+
+-- request methods (count)
+CREATE OR REPLACE VIEW http_methods AS
+    SELECT
+        http_method,
+        COUNT(*)
+    FROM access_log
+    GROUP BY 1
+    ORDER BY 1;
+
+-- request methods by percent
+CREATE OR REPLACE VIEW http_methods_perc AS
+    SELECT
+        http_method,
+        COUNT(*) / (SELECT COUNT(*) FROM access_log) * 100 AS perc
+    FROM access_log
+    GROUP BY 1
+    ORDER BY 2 DESC;
+
+
+-- slowest queries
+CREATE OR REPLACE VIEW slowest_requests AS
+    SELECT *
+    FROM access_log
+    ORDER BY time_response DESC
+    LIMIT 10;
+
+
+CREATE OR REPLACE VIEW slowest_request_by_method AS
+    SELECT *
+    FROM access_log
+    GROUP BY http_method
+    ORDER BY http_method, time_response DESC;
+
+
+-- requests with the biggest reply size
+CREATE OR REPLACE VIEW biggest_requests AS
+    SELECT *
+    FROM access_log
+    ORDER BY http_reply_size DESC
+    LIMIT 10;
+
+
+
+-- list each day which has at least one request, with some statistics
+CREATE OR REPLACE VIEW days_with_infos AS
+    SELECT
+    date_day,
+    MIN(date_time)                        AS first_req_time,
+    MAX(date_time)                        AS last_req_time,
+    COUNT(*)                              AS number_of_requests,
+    SUM(http_reply_size)                       AS total_traffic_bytes,
+    SUM(http_reply_size) / 1048576             AS total_traffic_megabytes,
+    COUNT(DISTINCT ip_client)    AS number_of_clients,
+    AVG(time_response)                    AS avg_time_response,
+    MAX(time_response)                    AS max_time_response,
+
+    -- client that has made the highest number of requests that day
+    (
+        SELECT ip_client
+        FROM requests_per_day_per_client r
+        WHERE r.date_day = a.date_day
+        ORDER BY r.num_of_requests DESC LIMIT 1
+    )                                     AS most_active_client_r,
+
+    -- the number of requests that client actually made
+    (
+        SELECT r.num_of_requests
+        FROM requests_per_day_per_client r
+        WHERE r.date_day = a.date_day
+        ORDER BY r.num_of_requests DESC LIMIT 1
+    )                                     AS most_active_client_r_nr,
+
+    -- same info but as percentage on the total number of requests that day
+    -- we have to repeat the whole query because we cannot reference aliases
+    -- defined in previous columns
+    -- a date_day column with an index on it would help here; a view would probably help too...
+    (
+        (
+            SELECT r.num_of_requests
+            FROM requests_per_day_per_client r
+            WHERE r.date_day = a.date_day
+            ORDER BY 1 DESC LIMIT 1
+        ) / (
+            SELECT COUNT(*)
+            FROM access_log a1
+            WHERE a.date_day = a1.date_day
+        ) * 100
+    )                                     AS most_active_client_r_pc,
+
+    -- client that has generated the highest traffic that day
+    (
+        SELECT t.ip_client
+        FROM traffic_per_day_per_client t
+        WHERE t.date_day = a.date_day
+        ORDER BY t.total_bytes DESC LIMIT 1
+    )                                     AS most_active_client_t,
+
+    -- the actual traffic generated by that client
+    (
+        SELECT t.total_bytes
+        FROM traffic_per_day_per_client t
+        WHERE t.date_day = a.date_day
+        ORDER BY t.total_bytes DESC LIMIT 1
+    )                                     AS most_active_client_t_b,
+
+    -- same info expressed in megabytes
+    (
+        SELECT t.total_bytes
+        FROM traffic_per_day_per_client t
+        WHERE t.date_day = a.date_day
+        ORDER BY t.total_bytes DESC LIMIT 1
+    ) / 1048576                           AS most_active_client_t_mb,
+
+    -- same info in percentage on the total traffic that day
+    -- see previous comments
+    (
+        (
+            SELECT t.total_bytes
+            FROM traffic_per_day_per_client t
+            WHERE t.date_day = a.date_day
+            ORDER BY t.total_bytes DESC LIMIT 1
+        ) / (
+            SELECT SUM(http_reply_size)
+            FROM access_log a1
+            WHERE a.date_day = a1.date_day
+        ) * 100                               
+    )                                     AS most_active_client_t_pc
+
+    FROM access_log a
+    GROUP BY 1
+    ORDER BY 1;
+
+-- this index helps the "days_with_info" view
+CREATE INDEX date_day_idx ON access_log(date_day);
+
+
+CREATE OR REPLACE VIEW requests_in_last_minute AS
+    select * from access_log where time_since_epoch >= ( (select max(time_since_epoch) from access_log) - 60);
+
+
+CREATE OR REPLACE VIEW avg_req_per_minute AS
+    SELECT COUNT(*) FROM requests_in_last_minute;
diff --git a/helpers/log_daemon/DB/log_db_daemon.pl.in b/helpers/log_daemon/DB/log_db_daemon.pl.in
new file mode 100755 (executable)
index 0000000..01dd863
--- /dev/null
@@ -0,0 +1,453 @@
+#!@PERL@
+use strict;
+use warnings;
+use DBI;
+use English qw( -no_match_vars );
+use Getopt::Long;
+use Pod::Usage;
+
+$|=1;
+
+=pod
+
+=head1 NAME
+
+log_db_daemon - Database logging daemon for Squid
+
+=head1 SYNOPSIS
+
+log_db_daemon DSN [options]
+
+=head1 DESCRIPTOIN
+
+This program writes Squid access.log entries to a database.
+Presently only accepts the B<squid> native format
+
+=over 8
+
+=item   B<DSN>
+
+Database DSN encoded as a path. This is sent as the access_log file path.
+
+Sample configuration:
+  access_log daemon:/host/database/table/username/password squid
+
+  to leave a parameter unspecified use a double slash:
+  access_log daemon://database/table/username/password squid
+
+Default "DBI:mysql:database=squid"
+
+=item   B<--debug>
+
+Write debug messages to Squid stderr or cache.log
+
+=cut
+
+# the first argument to this script is the log file path describing the DSN
+my $log_file = shift;
+
+# others may be options
+my $debug = 0;
+GetOptions(
+        'debug' => \$debug,
+        );
+
+
+# utility routine to print messages on stderr (so they appear in cache log)
+# without using warn, which would clutter the log with source line numbers
+sub log_info {
+    my $msg = shift;
+    print STDERR "$msg\n";
+}
+
+# we use logfile to pass database access information to this script
+# sample configuration:
+# access_log daemon:/host/database/table/username/password squid
+# to let a parmeter unspecified, e.g. the database host, use a double slash:
+# access_log daemon://database/table/username/password squid
+my ( $host, $database, $table, $user, $pass ) = $log_file =~ / \/(.*?)\/(.*?)\/(.*?)\/(.*?)\/(.*?) \z /xms;
+
+if ( !$host ) {
+    $host = 'localhost';
+    log_info("Database host not specified. Using $host.");
+}
+
+if ( !$database ) {
+    $database = 'squid_log';
+    log_info("Database name not specified. Using $database.");
+}
+
+if ( !$table ) {
+    $table = 'access_log';
+    log_info("Table parameter not specified. Using $table.");
+}
+
+if ( !$user ) {
+    $user = 'squid';
+    log_info("User parameter not specified. Using $user.");
+}
+
+if ( !$pass ) {
+    log_info('No password specified. Connecting with NO password.');
+}
+
+# fields that we should have in the table
+# Order here must match the order of fields in the Log format and parse() output array.
+my @db_fields = qw(
+    id
+    time_since_epoch
+    time_response
+    ip_client
+    squid_request_status
+    http_status_code
+    http_reply_size
+    http_method
+    http_url
+    http_username
+    squid_hier_status
+    ip_server
+    http_mime_type
+);
+
+# perform db connection
+my $dsn = "DBI:mysql:database=$database" . ($host ne "localhost" ? ":$host" : "");
+my $dbh;
+my $sth;
+eval {
+    warn "Connecting... dsn='$dsn', username='$user', password='...'";
+    $dbh = DBI->connect($dsn, $user, $pass, { AutoCommit => 1, RaiseError => 1, PrintError => 1 });
+};
+if ($EVAL_ERROR) {
+    die "Cannot connect to database: $DBI::errstr";
+}
+
+
+# a simple test to assure the specified table exists
+eval {
+    my $q = 'SELECT ' . join(',',@db_fields) . " FROM $table LIMIT 1";
+    my $sth = $dbh->prepare($q);
+    $sth->execute;
+};
+if ($EVAL_ERROR) {
+    # run a query to create the table of required syntax
+    my $create_query = 'CREATE TABLE ' . $table . ' (' .
+    " id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY," .
+    " time_since_epoch     DECIMAL(15,3)," .
+    " time_response        INTEGER," .
+    " ip_client            CHAR(15)," .
+    " ip_server            CHAR(15)," .
+    " http_status_code     VARCHAR(10)," .
+    " http_reply_size      INTEGER," .
+    " http_method          VARCHAR(20)," .
+    " http_url             TEXT," .
+    " http_username        VARCHAR(20)," .
+    " http_mime_type       VARCHAR(50)," .
+    " squid_request_status VARCHAR(50)," .
+    " squid_hier_status    VARCHAR(20)" .
+    ");" ;
+
+    $sth = $dbh->prepare($create_query);
+    $sth->execute;
+    # test again and fail hard if it is still broken.
+    eval {
+        my $q = 'SELECT ' . join(',',@db_fields) . " FROM $table LIMIT 1";
+        my $sth = $dbh->prepare($q);
+        $sth->execute;
+    };
+    if ($EVAL_ERROR) {
+        die "Error initializing database table: $EVAL_ERROR";
+    };
+}
+# test 
+
+# for better performance, prepare the statement at startup
+eval {
+    my $q = "INSERT INTO $table (" . join(',',@db_fields) . ") VALUES(NULL" . ',?' x (scalar(@db_fields)-1) . ')';
+    #$sth = $dbh->prepare("INSERT INTO $table VALUES(NULL,?,?,?,?,?,?,?,?,?,?,?,?)");
+    $sth = $dbh->prepare($q);
+};
+if ($EVAL_ERROR) {
+    die "Error while preparing sql statement: $EVAL_ERROR";
+}
+
+sub parse($) {
+    my ($line) = @_;
+    my (@t) = $line =~ /^L(\d+\.\d+) *(\d+?) (.*?) (.*?)\/(\d+?) (\d+?) (.*?) (.*?) (.*?) (.*?)\/(.*?) (.*)$/;
+}
+
+# main loop
+while (my $line = <>) {
+    chomp $line;
+
+    my $cmd = substr($line, 0, 1);      # extract command byte
+
+    if ( $cmd eq 'L' ) {
+        my @log_entry = parse($line);
+        eval {                  # we catch db errors to avoid crashing squid in case something goes wrong...
+            $sth->execute(@log_entry) or die $sth->errstr
+        };
+        if ( $EVAL_ERROR ) {    # leave a trace of the error in the logs
+            warn $EVAL_ERROR . " values=(" . join(', ', @log_entry) . ')';
+        }
+    }
+}
+
+$dbh->disconnect();
+
+__END__
+
+=head1 DESCRIPTION
+
+This module exploits the new logfile daemon support available in squid 2.7 and 3.2 to store access log entries in a MySQL database.
+
+=head1 CONFIGURATION
+
+=head2 Squid configuration
+
+=head3 access_log directive
+
+The path to the access log file is used to provide the database connection parameters.
+
+  access_log daemon:/mysql_host:port/database/table/username/password squid
+
+The 'daemon' prefix is mandatory and tells squid that the B<logfile_daemon> helper is to be used instead of the normal file logging.
+
+The last parameter tells squid which log format to use when writing lines to the log daemon.
+Presently B<squid> format is supported.
+
+=over 4
+
+=item mysql_host:port
+
+Host where the mysql server is running. If left empty, 'localhost' is assumed.
+
+=item database
+
+Name of the database to connect to. If left empty, 'squid_log' is assumed.
+
+=item table
+
+Name of the database table where log lines are stored. If left empty, 'access_log' is assumed.
+
+=item username
+
+Username to use when connecting to the database. If left empty, 'squid' is assumed.
+
+=item password
+
+Password to use when connecting to the database. If left empty, no password is used.
+
+=back
+
+To leave all fields to their default values, you can use a single slash:
+
+  access_log daemon:/ squid
+
+To specify only the database password, which by default is empty, you must leave unspecified all the other parameters by using null strings:
+
+  access_log daemon://///password squid
+
+=head3 logfile_daemon directive
+
+This is the current way of telling squid where the logfile daemon resides.
+
+  logfile_daemon /path/to/squid/libexec/logfile-daemon_mysql.pl
+
+The script must be copied to the location specified in the directive.
+
+=head2 Database configuration
+
+Let's call the database 'squid_log' and the log table 'access_log'. The username and password for the db connection will be both 'squid'.
+
+=head3 Database
+
+Create the database:
+
+  CREATE DATABASE squid_log;
+
+=head3 User
+
+Create the user:
+
+  GRANT INSERT,SELECT,CREATE ON squid_log.* TO 'squid'@'localhost' IDENTIFIED BY 'squid';
+  FLUSH PRIVILEGES;
+
+Note that only CREATE, INSERT and SELECT privileges are granted to the 'squid' user. This ensures that the logfile daemon script cannot change or modify the log entries.
+
+=head3 Table
+
+The Daemon will attempt to initialize this table if none exists when it starts.
+
+The table created should look like:
+
+  CREATE TABLE access_log (
+    id                   INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
+    time_since_epoch     DECIMAL(15,3),
+    time_response        INTEGER,
+    ip_client            CHAR(15),
+    ip_server            CHAR(15),
+    http_status_code     VARCHAR(10),
+    http_reply_size      INTEGER,
+    http_method          VARCHAR(20),
+    http_url             TEXT,
+    http_username        VARCHAR(20),
+    http_mime_type       VARCHAR(50),
+    squid_hier_status    VARCHAR(20),
+    squid_request_status VARCHAR(20)
+  );
+
+=head1 VERSION INFORMATION
+
+This document refers to C<log_db_daemon> script version 0.5.
+
+The script has been developed and tested in the following environment:
+
+=over 4
+
+=item squid-2.7 Squid-3.2
+
+=item mysql 5.0.26 and 5.1
+
+=item perl 5.8.8
+
+=item OpenSUSE 10.2
+
+=back
+
+=head1 DATA EXTRACTION
+
+=head2 Sample queries.
+
+=over 4
+
+=item Clients accessing the cache
+
+  SELECT DISTINCT ip_client FROM access_log;
+
+=item Number of request per day
+
+  SELECT
+    DATE(FROM_UNIXTIME(time_since_epoch)) AS date_day,
+    COUNT(*) AS num_of_requests
+  FROM access_log
+  GROUP BY 1
+  ORDER BY 1;
+
+=item Request status count
+
+To obtain the raw count of each request status:
+
+  SELECT squid_request_status, COUNT(*) AS n
+  FROM access_log
+  GROUP BY squid_request_status
+  ORDER BY 2 DESC;
+
+To calculate the percentage of each request status:
+
+  SELECT
+    squid_request_status,
+    (COUNT(*)/(SELECT COUNT(*) FROM access_log)*100) AS percentage
+  FROM access_log
+  GROUP BY squid_request_status
+  ORDER BY 2 DESC;
+
+To distinguish only between HITs and MISSes:
+
+  SELECT
+    'hits',
+    (SELECT COUNT(*)
+    FROM access_log
+    WHERE squid_request_status LIKE '%HIT%')
+    /
+    (SELECT COUNT(*) FROM access_log)*100
+    AS percentage
+  UNION
+  SELECT
+    'misses',
+    (SELECT COUNT(*)
+    FROM access_log
+    WHERE squid_request_status LIKE '%MISS%')
+    /
+    (SELECT COUNT(*) FROM access_log)*100
+    AS pecentage;
+
+=item Response time ranges
+
+  SELECT
+    '0..500',
+    COUNT(*)/(SELECT COUNT(*) FROM access_log)*100 AS percentage
+  FROM access_log
+  WHERE time_response >= 0 AND time_response < 500
+  UNION
+  SELECT
+    '500..1000',
+    COUNT(*)/(SELECT COUNT(*) FROM access_log)*100 AS percentage
+  FROM access_log
+  WHERE time_response >= 500 AND time_response < 1000
+  UNION
+  SELECT
+    '1000..2000',
+    COUNT(*)/(SELECT COUNT(*) FROM access_log)*100 AS percentage
+  FROM access_log
+  WHERE time_response >= 1000 AND time_response < 2000
+  UNION
+  SELECT
+    '>= 2000',
+    COUNT(*)/(SELECT COUNT(*) FROM access_log)*100 AS percentage
+  FROM access_log
+  WHERE time_response >= 2000;
+
+=item Traffic by mime type
+
+  SELECT
+    http_mime_type,
+    SUM(http_reply_size) as total_bytes
+  FROM access_log
+  GROUP BY http_mime_type
+  ORDER BY 2 DESC;
+
+=item Traffic by client
+
+  SELECT
+    ip_client,
+    SUM(http_reply_size) AS total_bytes
+  FROM access_log
+  GROUP BY 1
+  ORDER BY 2 DESC;
+
+=back
+
+=head2 Speed issues
+
+The MyISAM storage engine is known to be faster than the InnoDB one, so although it doesn't support transactions and referential integrity, it might be more appropriate in this scenario. You might want to append "ENGINE=MYISAM" at the end of the table creation code in the above SQL script.
+
+Indexes should be created according to the queries that are more frequently run. The DDL script only creates an implicit index for the primary key column.
+
+=head1 TODO
+
+=head2 Table cleanup
+
+This script currently implements only the C<L> (i.e. "append a line to the log") command, therefore the log lines are never purged from the table. This approach has an obvious scalability problem.
+
+One solution would be to implement e.g. the "rotate log" command in a way that would calculate some summary values, put them in a "summary table" and then delete the lines used to caluclate those values.
+
+Similar cleanup code could be implemented in an external script and run periodically independently from squid log commands.
+
+=head2 Testing
+
+This script has only been tested in low-volume scenarios (single client, less than 10 req/s). Tests in high volume environments could reveal performance bottlenecks and bugs.
+
+=head1 AUTHOR
+
+Marcello Romani, marcello.romani@libero.it
+Amos Jeffries, amosjeffries@squid-cache.org
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2008 by Marcello Romani
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself, either Perl version 5.8.8 or,
+at your option, any later version of Perl 5 you may have available.
+
+=cut
index 1208bc4f9eeac7509d77cf001586d020d8138726..2526de06beaa6c540bd206d92cc3231f10d0d5cc 100644 (file)
@@ -1,5 +1,6 @@
 ## Alphabetical list of sub-directories to distribute with Squid:
 DIST_SUBDIRS = \
+       DB \
        file
 
 SUBDIRS        = $(LOG_DAEMON_HELPERS)
index 24a7af31c846087592bc11e0ec36d640d069dc81..48cd3782b96ee1df30794469371a4548ef23a547 100644 (file)
@@ -56,14 +56,14 @@ rotate(const char *path, int rotate_count)
         i--;
         snprintf(from, MAXPATHLEN, "%s.%d", path, i - 1);
         snprintf(to, MAXPATHLEN, "%s.%d", path, i);
-#if defined(_SQUID_OS2_) || defined(_SQUID_WIN32_)
+#if _SQUID_OS2_ || _SQUID_WINDOWS_
         remove(to);
 #endif
         rename(from, to);
     }
     if (rotate_count > 0) {
         snprintf(to, MAXPATHLEN, "%s.%d", path, 0);
-#if defined(_SQUID_OS2_) || defined(_SQUID_WIN32_)
+#if _SQUID_OS2_ || _SQUID_WINDOWS_
         remove(to);
 #endif
         rename(path, to);
index eb36689ec9288ec1fe1fea1fe674bbb69f59378a..9631d5f841f65e190fd3a2f9fb1252a2d5173565 100644 (file)
 #include <gssapi/gssapi.h>
 #elif HAVE_GSSAPI_H
 #include <gssapi.h>
-#endif /* HAVE_GSSAPI_GSSAPI_H */
+#endif
+
+#if !HAVE_HEIMDAL_KERBEROS
 #if HAVE_GSSAPI_GSSAPI_KRB5_H
 #include <gssapi/gssapi_krb5.h>
-#endif /* HAVE_GSSAPI_GSSAPI_KRB5_H */
+#endif
 #if HAVE_GSSAPI_GSSAPI_GENERIC_H
 #include <gssapi/gssapi_generic.h>
-#endif /* HAVE_GSSAPI_GSSAPI_GENERIC_H */
+#endif
+#if HAVE_GSSAPI_GSSAPI_EXT_H
+#include <gssapi/gssapi_ext.h>
+#endif
+#endif
+
 #ifndef gss_nt_service_name
 #define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
 #endif
index f1d139161755e12eca64ef324ebb6e42b3101c59..afa2712e690fa1d3e19251bedcdb43cfedba14fe 100644 (file)
 #include <gssapi/gssapi.h>
 #elif HAVE_GSSAPI_H
 #include <gssapi.h>
-#endif /* HAVE_GSSAPI_GSSAPI_H */
+#endif
+
+#if !HAVE_HEIMDAL_KERBEROS
 #if HAVE_GSSAPI_GSSAPI_KRB5_H
 #include <gssapi/gssapi_krb5.h>
-#endif /* HAVE_GSSAPI_GSSAPI_KRB5_H */
+#endif
 #if HAVE_GSSAPI_GSSAPI_GENERIC_H
 #include <gssapi/gssapi_generic.h>
-#endif /* HAVE_GSSAPI_GSSAPI_GENERIC_H */
+#endif
+#if HAVE_GSSAPI_GSSAPI_EXT_H
+#include <gssapi/gssapi_ext.h>
+#endif
+#endif
+
 #ifndef gss_nt_service_name
 #define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
 #endif
index 85b7761528c227165b0f6271240755fcc4ba244c..4a02db77f5ebae721e1e3113e2c047ed2e3027f2 100644 (file)
@@ -84,7 +84,7 @@
 #else
 /* no gcc, no debugging. varargs macros are a gcc extension */
 #define SEND2(X,Y) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y);
-#define SEND4(X,Y,Z,W) debug("sending '" X "' to squid\n",Y,Z); printf(X "\n",Y,Z);
+#define SEND4(X,Y,Z,W) debug("sending '" X "' to squid\n",Y,Z,W); printf(X "\n",Y,Z,W);
 #endif
 
 const char *authenticate_ntlm_domain = "WORKGROUP";
index 6319e3056526abf429e103ef7b753415811d3c40..5249d838456161d453138e891d819af9d59b5f80 100644 (file)
@@ -317,10 +317,12 @@ ntlm_check_auth(ntlm_authenticate * auth, int auth_length)
     return credentials;
 }
 
-/* signal handler to be invoked when the authentication operation
- * times out */
+extern "C" void timeout_during_auth(int signum);
+
 static char got_timeout = 0;
-static void
+/** signal handler to be invoked when the authentication operation
+ * times out */
+void
 timeout_during_auth(int signum)
 {
     dc_disconnect();
index 7229729677d28c7d36b765bc29f934a65f99ce12..a77147513a54a587c02241f98e261475604c8477 100644 (file)
@@ -42,7 +42,7 @@
 
 /* represents [start, end) */
 
-template <class C>
+template <class C, class S = size_t>
 class Range
 {
 
@@ -52,35 +52,35 @@ public:
     C start;
     C end;
     Range intersection (Range const &) const;
-    C size() const;
+    S size() const;
 };
 
-template <class C>
-std::ostream& operator << (std::ostream &os, Range<C> const &aRange)
+template <class C, class S>
+std::ostream& operator << (std::ostream &os, Range<C, S> const &aRange)
 {
     os << "[" << aRange.start << "," << aRange.end << ")";
     return os;
 }
 
-template<class C>
-Range<C>::Range () : start(), end() {}
+template<class C, class S>
+Range<C, S>::Range () : start(), end() {}
 
-template<class C>
-Range<C>::Range (C start_, C end_) : start(start_), end(end_) {}
+template<class C, class S>
+Range<C, S>::Range (C start_, C end_) : start(start_), end(end_) {}
 
-template<class C>
-Range<C>
-Range<C>::intersection (Range const &rhs) const
+template<class C, class S>
+Range<C, S>
+Range<C, S>::intersection (Range const &rhs) const
 {
-    Range<C> result (max(start, rhs.start), min(end, rhs.end));
+    Range<C, S> result (max(start, rhs.start), min(end, rhs.end));
     return result;
 }
 
-template<class C>
-C
-Range<C>::size() const
+template<class C, class S>
+S
+Range<C, S>::size() const
 {
-    return end > start ? end - start : 0;
+    return (S) (end > start ? end - start : 0);
 }
 
 #endif /* SQUID_RANGE_H */
index 4ae2da08ffcd6e566d6427b115c37b4319ccddde..34ae37b4170c50f8e3eccd8f76449ec08867f467 100644 (file)
 #define SQUID_UDP_SO_RCVBUF SQUID_DETECT_UDP_SO_RCVBUF
 #endif
 
-#if HAVE_MEMCPY
-#define xmemcpy(d,s,n) memcpy((d),(s),(n))
-#elif HAVE_BCOPY
-#define xmemcpy(d,s,n) bcopy((s),(d),(n))
-#elif HAVE_MEMMOVE
-#define xmemcpy(d,s,n) memmove((d),(s),(n))
-#endif
-
-#if HAVE_MEMMOVE
-#define xmemmove(d,s,n) memmove((d),(s),(n))
-#elif HAVE_BCOPY
-#define xmemmove(d,s,n) bcopy((s),(d),(n))
-#endif
-
-#if HAVE_CTYPE_H
-#include <ctype.h>
-#endif
-#define xisspace(x) isspace((unsigned char)x)
-#define xtoupper(x) toupper((unsigned char)x)
-#define xtolower(x) tolower((unsigned char)x)
-#define xisdigit(x) isdigit((unsigned char)x)
-#define xisascii(x) isascii((unsigned char)x)
-#define xislower(x) islower((unsigned char)x)
-#define xisalpha(x) isalpha((unsigned char)x)
-#define xisprint(x) isprint((unsigned char)x)
-#define xisalnum(x) isalnum((unsigned char)x)
-#define xiscntrl(x) iscntrl((unsigned char)x)
-#define xispunct(x) ispunct((unsigned char)x)
-#define xisupper(x) isupper((unsigned char)x)
-#define xisxdigit(x) isxdigit((unsigned char)x)
-#define xisgraph(x) isgraph((unsigned char)x)
-
 #if HAVE_RANDOM
 #define squid_random random
 #define squid_srandom srandom
 #define squid_srandom srand
 #endif
 
-/* gcc doesn't recognize the Windows native 64 bit formatting tags causing
- * the compile fail, so we must disable the check on native Windows.
- */
-
-#if __GNUC__ && !defined(_SQUID_MSWIN_)
-#define PRINTF_FORMAT_ARG1 __attribute__ ((format (printf, 1, 2)))
-#define PRINTF_FORMAT_ARG2 __attribute__ ((format (printf, 2, 3)))
-#define PRINTF_FORMAT_ARG3 __attribute__ ((format (printf, 3, 4)))
-#else
-#define PRINTF_FORMAT_ARG1
-#define PRINTF_FORMAT_ARG2
-#define PRINTF_FORMAT_ARG3
-#endif
-
 /*
  * Determine if this is a leak check build or standard
  */
 /* temp hack: needs to be pre-defined for now. */
 #define SQUID_MAXPATHLEN 256
 
-/*
- * strnstr() is needed. The OS may not provide a working copy.
- */
-#include "strnstr.h"
-
 #endif /* SQUID_CONFIG_H */
index 6a887308df6f3d0f22094d60137274ddafc9ed9a..4a8892c5e8fa60fd360522c35491729ff0d90166 100644 (file)
@@ -3,6 +3,6 @@
 
 SQUIDCEXTERN void fatal(const char *message);
 SQUIDCEXTERN void fatalf(const char *fmt,...) PRINTF_FORMAT_ARG1;
-SQUIDCEXTERN void fatal_dump(const char *message);
+extern void fatal_dump(const char *message);
 
-#endif
+#endif /* SQUID_FATAL_H */
index aafc3e90c2671e5df55bd8aacd8fb412faa7f14b..d94ab98ffcfdf41db8f6dc04fb90331d8a5c40ef 100644 (file)
@@ -117,15 +117,12 @@ struct squid_radix_node_head {
     (void *v, void *mask, struct squid_radix_node_head * head, struct squid_radix_node nodes[]);
 
     struct squid_radix_node *(*rnh_deladdr)    /* remove based on sockaddr */
-
     (void *v, void *mask, struct squid_radix_node_head * head);
 
     struct squid_radix_node *(*rnh_delpkt)     /* remove based on packet hdr */
-
     (void *v, void *mask, struct squid_radix_node_head * head);
 
     struct squid_radix_node *(*rnh_matchaddr)          /* locate based on sockaddr */
-
     (void *v, struct squid_radix_node_head * head);
 
     struct squid_radix_node *(*rnh_lookup)     /* locate based on sockaddr */
@@ -133,11 +130,9 @@ struct squid_radix_node_head {
     (void *v, void *mask, struct squid_radix_node_head * head);
 
     struct squid_radix_node *(*rnh_matchpkt)   /* locate based on packet hdr */
-
     (void *v, struct squid_radix_node_head * head);
 
     int (*rnh_walktree)                /* traverse tree */
-
     (struct squid_radix_node_head * head, int (*f) (struct squid_radix_node *, void *), void *w);
 
     struct squid_radix_node rnh_nodes[3];      /* empty tree for common case */
index 12d40335654a75d08e7f57df9267ebafbb4807bd..b31b2caae0e65b12414e882324f315a366a486d1 100644 (file)
@@ -11,7 +11,6 @@
 #include "Stack.h"
 
 template <class V>
-
 class SplayNode
 {
 
@@ -32,8 +31,7 @@ public:
     SplayNode<V> const * start() const;
     SplayNode<V> const * finish() const;
 
-    SplayNode<V> * remove
-    (const Value data, SPLAYCMP * compare);
+    SplayNode<V> * remove(const Value data, SPLAYCMP * compare);
 
     SplayNode<V> * insert(Value data, SPLAYCMP * compare);
 
@@ -43,15 +41,12 @@ public:
 typedef SplayNode<void *> splayNode;
 
 template <class V>
-
 class SplayConstIterator;
 
 template <class V>
-
 class SplayIterator;
 
 template <class V>
-
 class Splay
 {
 
@@ -67,8 +62,7 @@ public:
     template <class FindValue> Value const *find (FindValue const &, int( * compare)(FindValue const &a, Value const &b)) const;
     void insert(Value const &, SPLAYCMP *compare);
 
-    void remove
-    (Value const &, SPLAYCMP *compare);
+    void remove(Value const &, SPLAYCMP *compare);
 
     void destroy(SPLAYFREE *);
 
@@ -158,8 +152,7 @@ SplayNode<V>::destroy(SPLAYFREE * free_func)
 
 template<class V>
 SplayNode<V> *
-SplayNode<V>::remove
-(Value const dataToRemove, SPLAYCMP * compare)
+SplayNode<V>::remove(Value const dataToRemove, SPLAYCMP * compare)
 {
     if (this == NULL)
         return NULL;
@@ -311,13 +304,11 @@ Splay<V>::insert(Value const &value, SPLAYCMP *compare)
 
 template <class V>
 void
-Splay<V>::remove
-(Value const &value, SPLAYCMP *compare)
+Splay<V>::remove(Value const &value, SPLAYCMP *compare)
 {
     assert (find (value, compare));
 
-    head = head->remove
-           (value, compare);
+    head = head->remove(value, compare);
 
     --elements;
 }
@@ -376,7 +367,6 @@ Splay<V>::end() const
 }
 
 template <class V>
-
 class SplayConstIterator
 {
 
index 5cf14de50404fdc053c3717e1b98ee3dd87f8018..b9d193b36c54550c7bfa6c200b8272d927abcc62 100644 (file)
@@ -33,7 +33,7 @@
 #ifndef _INC_SQUID_WINDOWS_H
 #define _INC_SQUID_WINDOWS_H
 
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
 
 #ifndef ACL
 #define ACL WindowsACL
@@ -45,6 +45,5 @@
 #undef _MSWIN_ACL_WAS_NOT_DEFINED
 #endif
 
-#endif /* _SQUID_WIN32_ */
-
+#endif /* _SQUID_WINDOWS_ */
 #endif /* _INC_SQUID_WINDOWS_H */
index bce5f82a5c295e8d22ad3601f9873fd90dc217de..d01abafdaf8ae0369df7e4433238ea712ceee5b4 100644 (file)
 #ifndef _LIBSSPWIN32_H_
 #define _LIBSSPWIN32_H_
 
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
 
 #define SECURITY_WIN32
 #define NTLM_PACKAGE_NAME "NTLM"
 #define NEGOTIATE_PACKAGE_NAME "Negotiate"
 
-#ifdef _SQUID_CYGWIN_
+#if _SQUID_CYGWIN_
 #include <wchar.h>
 #define _T(x) TEXT(x)
 #else
@@ -77,6 +77,5 @@ const char * WINAPI SSP_MakeNegotiateBlob(PVOID, int, PBOOL, int *, char *);
 extern BOOL Use_Unicode;
 extern BOOL NTLM_LocalCall;
 
-#endif /* _SQUID_WIN32_ */
-
+#endif /* _SQUID_WINDOWS_ */
 #endif /* LIBSSPWIN32_H_ */
diff --git a/include/strnstr.h b/include/strnstr.h
deleted file mode 100644 (file)
index 4173160..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#if HAVE_STRNSTR
-
-/* Is strnstr exists and is usable we do so. */
-#define squid_strnstr(a,b,c)   strnstr(a,b,c)
-
-#else /* not HAVE_STRNSTR */
-
-/* If its not usable we have our own copy imported from FreeBSD */
-const char * squid_strnstr(const char *s, const char *find, size_t slen);
-
-#endif /* HAVE_STRNSTR*/
index f3d1c40c5c887818a9b534dca91fbd40db3d2835..4f4e426a75ea4693bc5bed1a4dcfd6b6853c6d69 100644 (file)
@@ -66,10 +66,6 @@ SQUIDCEXTERN void Tolower(char *);
 #include "SquidNew.h"
 #endif
 
-#if 0 && XMALLOC_STATISTICS
-SQUIDCEXTERN void malloc_statistics(void (*)(int, int, int, void *), void *);
-#endif
-
 #if XMALLOC_TRACE
 #define xmalloc(size) (xmalloc_func="xmalloc",xmalloc_line=__LINE__,xmalloc_file=__FILE__,xmalloc(size))
 #define xfree(ptr) (xmalloc_func="xfree",xmalloc_line=__LINE__,xmalloc_file=__FILE__,xfree(ptr))
index 01366d15bc5f2d8aed2dc5c2021ad064d25798fc..11bbba253f8e0df13c6e2803747bea1bcae814de 100644 (file)
@@ -70,7 +70,6 @@ libmiscutil_la_SOURCES = \
        rfc3596.c \
        $(SNPRINTFSOURCE) \
        Splay.cc \
-       strnstr.cc \
        stub_memaccount.c \
        util.c \
        xusleep.c \
index fd58d41bf8ab3f01a742e9e1b4a8bda58d272888..3e6143af90cd257efb9a9f930c54c4c4282f8b78 100644 (file)
@@ -430,12 +430,15 @@ MemImplementingAllocator::~MemImplementingAllocator()
 {
     MemImplementingAllocator *find_pool, *prev_pool;
 
-    assert(MemPools::GetInstance().pools != NULL && "Called MemImplementingAllocator::~MemImplementingAllocator, but no pool exists!");
+    /* Abort if the associated pool doesn't exist */
+    assert(MemPools::GetInstance().pools != NULL );
 
     /* Pool clean, remove it from List and free */
     for (find_pool = MemPools::GetInstance().pools, prev_pool = NULL; (find_pool && this != find_pool); find_pool = find_pool->next)
         prev_pool = find_pool;
-    assert(find_pool != NULL && "pool to destroy not found");
+
+    /* make sure that we found the pool to destroy */
+    assert(find_pool != NULL);
 
     if (prev_pool)
         prev_pool->next = next;
index aa0786603ed57a638134707f06dbee0e52e60bed..6485b426b66dda0dcb75d91168022581567f6163 100644 (file)
@@ -321,7 +321,7 @@ MemPoolChunked::~MemPoolChunked()
 
     flushMetersFull();
     clean(0);
-    assert(meter.inuse.level == 0 && "While trying to destroy pool");
+    assert(meter.inuse.level == 0);
 
     chunk = Chunks;
     while ( (fchunk = chunk) != NULL) {
index bca0e9ff432517be77ad7c8e2508fdff30f28848..75759932da2550c99ff35e3edd9aca4aeb8ce487 100644 (file)
@@ -120,7 +120,7 @@ MemPoolMalloc::MemPoolMalloc(char const *aLabel, size_t aSize) : MemImplementing
 
 MemPoolMalloc::~MemPoolMalloc()
 {
-    assert(meter.inuse.level == 0 && "While trying to destroy pool");
+    assert(meter.inuse.level == 0);
     clean(0);
 }
 
index a4b34144dcffac7fc134e117fd7ce17efc45e22a..46dd6d005f93b4901f2478105967720becf22d1d 100644 (file)
@@ -31,7 +31,7 @@ be considered for the next release.  If you are using the cache, and at
 some point `config.cache' contains results you don't want to keep, you
 may remove or edit it.
 
-   The file `configure.ac' (or `configure.in') is used to create
+   The file `configure.ac' is used to create
 `configure' by a program called `autoconf'.  You only need
 `configure.ac' if you want to change it or regenerate `configure' using
 a newer version of `autoconf'.
index 0c33c444659da2461e9bc44ea39161ffcbffc864..b5d32e4680473b5618734d2ff5a82e46ebf79b74 100644 (file)
  * bindings. libtrie itself is written in C++.
  */
 
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
 #if HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
index 71174f8cf96c0ad4117e8e1977f713a7f2851eba..f020dee359fce8498135266b1f5086773b968ff7 100644 (file)
  * For C bindings see Trie.h
  */
 
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
 /* C bindings */
 #ifndef   __cplusplus
 
index b113ae3a577cead987626184e543dc94c7247cd0..dc978d25f5c40838ab83d7a8f1188f209997c2df 100644 (file)
  * For C bindings see Trei.h
  */
 
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
 /* C bindings */
 #ifndef   __cplusplus
 
index 5a93709de6c396631f11f78cdc457314c5fb7a02..557fcf0a7950716b6dbe3df7f6e141ec2f177ab1 100644 (file)
 #include "Trie.cci"
 #endif
 
-Trie::Trie (TrieCharTransform *aTransform) : head (0) , transform (aTransform)
+Trie::Trie(TrieCharTransform *aTransform) : head(0) , transform(aTransform)
 {}
 
-extern "C" void *TrieCreate ()
+extern "C" void *TrieCreate()
 {
     return new Trie;
 }
 
-Trie::~Trie ()
+Trie::~Trie()
 {
     delete head;
     delete transform;
 }
 
-extern "C" void TrieDestroy (void *aTrie)
+extern "C" void TrieDestroy(void *aTrie)
 {
     delete (Trie *)aTrie;
 }
 
-extern "C" void *TrieFind (void *aTrie, char const *aString, size_t theLength)
+extern "C" void *TrieFind(void *aTrie, char const *aString, size_t theLength)
 {
-    return ((Trie *)aTrie)->find (aString, theLength);
+    return ((Trie *)aTrie)->find(aString, theLength);
 }
 
 bool
-
-Trie::add
-(char const *aString, size_t theLength, void *privatedata)
+Trie::add(char const *aString, size_t theLength, void *privatedata)
 {
     if (!privatedata)
         return false;
 
     if (head) {
-        if (find (aString, theLength))
+        if (find(aString, theLength))
             return false;
 
-        return head->add
-               (aString, theLength, privatedata, transform);
+        return head->add(aString, theLength, privatedata, transform);
     }
 
     head = new TrieNode;
 
-    return head->add
-           (aString, theLength, privatedata, transform);
+    return head->add(aString, theLength, privatedata, transform);
 }
 
-extern "C" int TrieAdd (void *aTrie, char const *aString, size_t theLength, void *privatedata)
+extern "C" int TrieAdd(void *aTrie, char const *aString, size_t theLength, void *privatedata)
 {
 
-    return ((Trie *)aTrie)->add
-           (aString, theLength, privatedata);
+    return ((Trie *)aTrie)->add(aString, theLength, privatedata);
 }
index 458589d80895ad0da409eb28fe246863d80d1a8b..e81f62bb989e4a62e79366d39d45c73af5e72e96 100644 (file)
 #include <unistd.h>
 #endif
 
-TrieNode::TrieNode () : _privateData (NULL)
+TrieNode::TrieNode() : _privateData(NULL)
 {
     for (int i = 0; i < 256; ++i)
         internal[i] = NULL;
 }
 
-TrieNode::~TrieNode ()
+TrieNode::~TrieNode()
 {
     for (int i = 0; i < 256; ++i)
         delete internal[i];
@@ -38,20 +38,17 @@ TrieNode::~TrieNode ()
 
 /* as for find */
 bool
-
-TrieNode::add
-(char const *aString, size_t theLength, void *privatedata, TrieCharTransform *transform)
+TrieNode::add(char const *aString, size_t theLength, void *privatedata, TrieCharTransform *transform)
 {
     /* We trust that privatedata and existant keys have already been checked */
 
     if (theLength) {
-        int index = transform ? (*transform) (*aString): *aString;
+        int index = transform ? (*transform)(*aString): *aString;
 
         if (!internal[index])
             internal[index] = new TrieNode;
 
-        return internal[index]->add
-               (aString + 1, theLength - 1, privatedata, transform);
+        return internal[index]->add(aString + 1, theLength - 1, privatedata, transform);
     } else {
         /* terminal node */
 
index 031d8e591d21a4c8725a6bd185eee422ca2886d7..aa10c97f82a11ac23d31cc974369ee11fed16281 100644 (file)
@@ -45,10 +45,8 @@ main(int argc, char **argv)
     MDString("abc");
     MDString("message digest");
     MDString("abcdefghijklmnopqrstuvwxyz");
-    MDString
-    ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
-    MDString
-    ("1234567890123456789012345678901234567890\
-1234567890123456789012345678901234567890");
+    MDString("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
+    MDString("1234567890123456789012345678901234567890"
+             "1234567890123456789012345678901234567890");
     return 0;
 }
index 8e57feb2c0d52a83d14bfb7bd61e0114702bc4ee..4b3b0fd64348c920d69fc122ee5602f94685587b 100644 (file)
@@ -13,8 +13,8 @@ extern "C" {
 
 #if !USE_XPROF_STATS
 
-#define PROF_start(ARGS) ((void)0)
-#define PROF_stop(ARGS) ((void)0)
+#define PROF_start(probename) ((void)0)
+#define PROF_stop(probename) ((void)0)
 
 #else /* USE_XPROF_STATS */
 
@@ -51,8 +51,8 @@ extern "C" {
     extern void xprof_stop(xprof_type type, const char *timer);
     extern void xprof_event(void *data);
 
-#define PROF_start(type) xprof_start(XPROF_##type, #type)
-#define PROF_stop(type) xprof_stop(XPROF_##type, #type)
+#define PROF_start(probename) xprof_start(XPROF_##probename, #probename)
+#define PROF_stop(probename) xprof_stop(XPROF_##probename, #probename)
 
 #endif /* USE_XPROF_STATS */
 
index 70f101380adefebbc0c4aa1d468f37ef5adc52bc..eea491c99040cd1699c95cec9a8ed3358b0c05d0 100644 (file)
@@ -3,6 +3,10 @@
 
 #if USE_XPROF_STATS
 
+/*
+ * Ensure that any changes here are synchronised with SQUID_CHECK_FUNCTIONAL_CPU_PROFILER
+ */
+
 #if !_SQUID_SOLARIS_
 typedef int64_t  hrtime_t;
 #endif
@@ -57,9 +61,8 @@ get_tick(void)
 
 #else
 /* This CPU is unsupported. Short-circuit, no profiling here */
-#define get_tick() 0
-#undef USE_XPROF_STATS
-#define USE_XPROF_STATS 0
+// #error for configure tests to prevent library construction
+#error This CPU is unsupported. No profiling available here.
 #endif
 
 #endif /* USE_XPROF_STATS */
index 9315aafe6b7498f4ac16676c574c0ad5721cb030..f3060388084109277a9ade42ddfa3673ee283cfb 100644 (file)
 #ifndef _PROFILER_XPROF_TYPE_H_
 #define _PROFILER_XPROF_TYPE_H_
-
+/* AUTO-GENERATED FILE */
 #if USE_XPROF_STATS
-
-// TODO: auto-generate this list from a scan of the source code.
-
-// This list MUST be kept in sync with the PROF_start()/PROF_stop() macros
-// used throughout the rest of the sources.
-
 typedef enum {
     XPROF_PROF_UNACCOUNTED,
+    XPROF_HttpHeaderClean,
+    XPROF_HttpHeaderParse,
+    XPROF_HttpHeader_getCc,
+    XPROF_HttpMsg_httpMsgParseStep,
+    XPROF_HttpParserParseReqLine,
+    XPROF_HttpStateData_processReplyBody,
+    XPROF_HttpStateData_processReplyHeader,
+    XPROF_HttpStateData_readReply,
+    XPROF_InvokeHandlers,
+    XPROF_MemBuf_append,
+    XPROF_MemBuf_consume,
+    XPROF_MemBuf_grow,
+    XPROF_MemObject_write,
     XPROF_PROF_OVERHEAD,
-    XPROF_hash_lookup,
-    XPROF_splay_splay,
-    XPROF_xmalloc,
-    XPROF_malloc,
-    XPROF_free,
-    XPROF_free_const,
-    XPROF_xrealloc,
-    XPROF_realloc,
-    XPROF_xcalloc,
-    XPROF_calloc,
-    XPROF_xstrdup,
-    XPROF_xstrndup,
-    XPROF_xstrncpy,
-    XPROF_xcountws,
-    XPROF_socket,
-    XPROF_read,
-    XPROF_write,
-    XPROF_send,
-    XPROF_recv,
-    XPROF_sendto,
-    XPROF_recvfrom,
-    XPROF_accept,
-    XPROF_connect,
-    XPROF_memPoolChunkNew,
-    XPROF_memPoolAlloc,
-    XPROF_memPoolFree,
-    XPROF_memPoolClean,
-    XPROF_aclMatchAclList,
+    XPROF_SignalEngine_checkEvents,
+    XPROF_StoreEntry_write,
+    XPROF_StringAllocAndFill,
+    XPROF_StringAppend,
+    XPROF_StringClean,
+    XPROF_StringInitBuf,
+    XPROF_StringReset,
     XPROF_aclCheckFast,
-    XPROF_comm_open,
-    XPROF_comm_connect_addr,
-    XPROF_comm_accept,
-    XPROF_comm_close,
-    XPROF_comm_udp_sendto,
+    XPROF_aclMatchAclList,
+    XPROF_calloc,
+    XPROF_clientSocketRecipient,
     XPROF_commHandleWrite,
+    XPROF_comm_accept,
     XPROF_comm_check_incoming,
-    XPROF_comm_poll_prep_pfds,
-    XPROF_comm_poll_normal,
+    XPROF_comm_close,
+    XPROF_comm_connect_addr,
     XPROF_comm_handle_ready_fd,
+    XPROF_comm_open,
+    XPROF_comm_poll_normal,
+    XPROF_comm_poll_prep_pfds,
     XPROF_comm_read_handler,
+    XPROF_comm_udp_sendto,
     XPROF_comm_write_handler,
-    XPROF_storeGet,
-    XPROF_storeMaintainSwapSpace,
-    XPROF_storeRelease,
-    XPROF_diskHandleWrite,
     XPROF_diskHandleRead,
+    XPROF_diskHandleWrite,
+    XPROF_esiExpressionEval,
+    XPROF_esiParsing,
+    XPROF_esiProcessing,
+    XPROF_eventRun,
+    XPROF_file_close,
     XPROF_file_open,
     XPROF_file_read,
     XPROF_file_write,
-    XPROF_file_close,
-    XPROF_esiExpressionEval,
-    XPROF_esiProcessing,
-    XPROF_esiParsing,
+    XPROF_free,
+    XPROF_free_const,
+    XPROF_hash_lookup,
+    XPROF_headersEnd,
+    XPROF_httpRequestFree,
+    XPROF_httpStart,
+    XPROF_malloc,
+    XPROF_mem_hdr_write,
+    XPROF_parseHttpRequest,
+    XPROF_read,
+    XPROF_realloc,
+    XPROF_recv,
+    XPROF_send,
     XPROF_storeClient_kickReads,
-    XPROF_eventRun,
     XPROF_storeDirCallback,
-    XPROF_comm_calliocallback,
-    XPROF_CommReadCallbackData_callCallback,
-    XPROF_CommAcceptCallbackData_callCallback,
-    XPROF_CommWriteCallbackData_callCallback,
-    XPROF_CommFillCallbackData_callCallback,
-    XPROF_HttpStateData_readReply,
-    XPROF_HttpStateData_processReplyBody,
-    XPROF_StoreEntry_write,
+    XPROF_storeGet,
     XPROF_storeGetMemSpace,
-    XPROF_MemObject_write,
+    XPROF_storeMaintainSwapSpace,
+    XPROF_storeRelease,
     XPROF_storeWriteComplete,
-    XPROF_mem_hdr_write,
-    XPROF_headersEnd,
-    XPROF_parseHttpRequest,
-    XPROF_HttpStateData_processReplyHeader,
-    XPROF_MemBuf_consume,
-    XPROF_MemBuf_append,
-    XPROF_MemBuf_grow,
-    XPROF_InvokeHandlers,
-    XPROF_HttpMsg_httpMsgParseStep,
-    XPROF_EventDispatcher_dispatch,
-    XPROF_SignalEngine_checkEvents,
-    XPROF_Temp1,
-    XPROF_Temp2,
-    XPROF_Temp3,
-    XPROF_clientSocketRecipient,
-    XPROF_httpStart,
-    XPROF_HttpParserParseReqLine,
-    XPROF_httpRequestFree,
-    XPROF_HttpHeaderParse,
-    XPROF_HttpHeaderClean,
-    XPROF_StringInitBuf,
-    XPROF_StringAllocAndFill,
-    XPROF_StringClean,
-    XPROF_StringReset,
-    XPROF_StringAppend,
-    XPROF_HttpHeader_findEntry,
-    XPROF_HttpHeader_getCc,
-    XPROF_HttpHeader_getRange,
-    XPROF_checkTimeouts,
-    XPROF_CommSelect,
+    XPROF_write,
+    XPROF_xcalloc,
+    XPROF_xcountws,
+    XPROF_xmalloc,
+    XPROF_xrealloc,
     XPROF_LAST
 } xprof_type;
-
-#endif /* USE_XPROF_STATS */
-#endif /* _PROFILING_H_ */
+#endif
+#endif
index 7d5573743709ac536756a03344cf17a229caa71a..1c16e88bfaebd2de9d4af4ed2681baae5c736edb 100644 (file)
@@ -209,14 +209,8 @@ parse_rfc1123(const char *str)
     t = mktime(tm);
     if (t != -1) {
         time_t dst = 0;
-#if defined (_TIMEZONE)
-#elif defined (_timezone)
-#elif defined(_SQUID_AIX_)
-#elif defined(_SQUID_CYGWIN_)
-#elif defined(_SQUID_MSWIN_)
-#elif defined(_SQUID_SGI_)
-#else
-    extern long timezone;
+#if !(defined(_TIMEZONE) || defined(_timezone) || _SQUID_AIX_ || _SQUID_WINDOWS_ || _SQUID_SGI_)
+        extern long timezone;
 #endif
         /*
          * The following assumes a fixed DST offset of 1 hour,
@@ -224,7 +218,7 @@ parse_rfc1123(const char *str)
          */
         if (tm->tm_isdst > 0)
             dst = -3600;
-#if defined ( _timezone) || defined(_SQUID_WIN32_)
+#if defined(_timezone) || _SQUID_WINDOWS_
         t -= (_timezone + dst);
 #else
     t -= (timezone + dst);
@@ -246,48 +240,6 @@ mkrfc1123(time_t t)
     return buf;
 }
 
-const char *
-mkhttpdlogtime(const time_t * t)
-{
-    static char buf[128];
-
-    struct tm *gmt = gmtime(t);
-
-#if !USE_GMT
-    int gmt_min, gmt_hour, gmt_yday, day_offset;
-    size_t len;
-    struct tm *lt;
-    int min_offset;
-
-    /* localtime & gmtime may use the same static data */
-    gmt_min = gmt->tm_min;
-    gmt_hour = gmt->tm_hour;
-    gmt_yday = gmt->tm_yday;
-
-    lt = localtime(t);
-
-    day_offset = lt->tm_yday - gmt_yday;
-    /* wrap round on end of year */
-    if (day_offset > 1)
-        day_offset = -1;
-    else if (day_offset < -1)
-        day_offset = 1;
-
-    min_offset = day_offset * 1440 + (lt->tm_hour - gmt_hour) * 60
-                 + (lt->tm_min - gmt_min);
-
-    len = strftime(buf, 127 - 5, "%d/%b/%Y:%H:%M:%S ", lt);
-    snprintf(buf + len, 128 - len, "%+03d%02d",
-             (min_offset / 60) % 24,
-             min_offset % 60);
-#else /* USE_GMT */
-    buf[0] = '\0';
-    strftime(buf, 127, "%d/%b/%Y:%H:%M:%S -000", gmt);
-#endif /* USE_GMT */
-
-    return buf;
-}
-
 #if 0
 int
 main()
index 2dae575619c03e938148411048d91681b06575b7..de91c4574f3c0286c830ec4810be907be185bcf4 100644 (file)
@@ -1,33 +1,33 @@
 /*
  Unix SMB/Netbios implementation.
  Version 1.9.
  SMB Byte handling
  Copyright (C) Andrew Tridgell 1992-1995
-
  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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
* Unix SMB/Netbios implementation.
* Version 1.9.
* SMB Byte handling
* Copyright (C) Andrew Tridgell 1992-1995
+ *
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 
 /*
  This file implements macros for machine independent short and
  int manipulation
-*/
* This file implements macros for machine independent short and
* int manipulation
+ */
 
 #undef CAREFUL_ALIGNMENT
 
 /* we know that the 386 can handle misalignment and has the "right"
  byteorder */
* byteorder */
 #ifdef __i386__
 #define CAREFUL_ALIGNMENT 0
 #endif
 #define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32)(val)))
 #else
 /* this handles things for architectures like the 386 that can handle
  alignment errors */
* alignment errors */
 /*
  WARNING: This section is dependent on the length of int16 and int32
  being correct
-*/
* WARNING: This section is dependent on the length of int16 and int32
* being correct
+ */
 #define SVAL(buf,pos) (*(uint16 *)((char *)(buf) + (pos)))
 #define IVAL(buf,pos) (*(uint32 *)((char *)(buf) + (pos)))
 #define SVALS(buf,pos) (*(int16 *)((char *)(buf) + (pos)))
index c3532eafdee97073f065c2f03b31c96c0ab4e578..9f5828f27d691eff4c07a4af969a1fce508d2bc0 100644 (file)
@@ -1,27 +1,27 @@
 /* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
-
  Version 1.0
  RFCNB Common Structures etc Defines
-
  Copyright (C) Richard Sharpe 1996
-
-*/
+ *
* Version 1.0
* RFCNB Common Structures etc Defines
+ *
* Copyright (C) Richard Sharpe 1996
+ *
+ */
 
 /*
  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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 
 #ifndef _RFCNB_RFCNB_COMMON_H
 #define _RFCNB_RFCNB_COMMON_H
@@ -34,7 +34,7 @@ extern "C" {
 
     typedef struct RFCNB_Pkt {
 
-        char * data;                   /* The data in this portion */
+        char *data;             /* The data in this portion */
         int len;
         struct RFCNB_Pkt *next;
 
@@ -42,5 +42,6 @@ extern "C" {
 
 #ifdef __cplusplus
 }
+
 #endif
-#endif /* _RFCNB_RFCNB_COMMON_H */
+#endif                          /* _RFCNB_RFCNB_COMMON_H */
index 2f51884ec61d8a50404053df5cfd3e073e2ccd42..3432fc63e4a6fc50b11d655bb2ccea0dbb7e3f99 100644 (file)
@@ -1,27 +1,27 @@
 /* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
-
  Version 1.0
  RFCNB Error Response Defines
-
  Copyright (C) Richard Sharpe 1996
-
-*/
+ *
* Version 1.0
* RFCNB Error Response Defines
+ *
* Copyright (C) Richard Sharpe 1996
+ *
+ */
 
 /*
  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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 
 #ifndef _RFCNB_ERROR_H_
 #define _RFCNB_ERROR_H_
@@ -32,27 +32,27 @@ extern "C" {
 
     /* Error responses */
 
-#define RFCNBE_Bad -1          /* Bad response */
+#define RFCNBE_Bad -1           /* Bad response */
 #define RFCNBE_OK 0
 
-    /* these should follow the spec ... is there one ?*/
+    /* these should follow the spec ... is there one ? */
 
-#define RFCNBE_NoSpace 1       /* Could not allocate space for a struct */
-#define RFCNBE_BadName 2       /* Could not translate a name            */
-#define RFCNBE_BadRead 3       /* Read sys call failed                  */
-#define RFCNBE_BadWrite 4      /* Write Sys call failed                 */
-#define RFCNBE_ProtErr 5       /* Protocol Error                        */
-#define RFCNBE_ConGone 6       /* Connection dropped                    */
-#define RFCNBE_BadHandle 7     /* Handle passed was bad                 */
-#define RFCNBE_BadSocket 8     /* Problems creating socket              */
-#define RFCNBE_ConnectFailed 9 /* Connect failed                        */
-#define RFCNBE_CallRejNLOCN 10 /* Call rejected, not listening on CN    */
-#define RFCNBE_CallRejNLFCN 11 /* Call rejected, not listening for CN   */
-#define RFCNBE_CallRejCNNP  12 /* Call rejected, called name not present */
-#define RFCNBE_CallRejInfRes 13/* Call rejetced, name ok, no resources   */
-#define RFCNBE_CallRejUnSpec 14/* Call rejected, unspecified error      */
-#define RFCNBE_BadParam      15/* Bad parameters passed ...             */
-#define RFCNBE_Timeout       16/* IO Timed out                          */
+#define RFCNBE_NoSpace 1        /* Could not allocate space for a struct */
+#define RFCNBE_BadName 2        /* Could not translate a name            */
+#define RFCNBE_BadRead 3        /* Read sys call failed                  */
+#define RFCNBE_BadWrite 4       /* Write Sys call failed                 */
+#define RFCNBE_ProtErr 5        /* Protocol Error                        */
+#define RFCNBE_ConGone 6        /* Connection dropped                    */
+#define RFCNBE_BadHandle 7      /* Handle passed was bad                 */
+#define RFCNBE_BadSocket 8      /* Problems creating socket              */
+#define RFCNBE_ConnectFailed 9  /* Connect failed                        */
+#define RFCNBE_CallRejNLOCN 10  /* Call rejected, not listening on CN    */
+#define RFCNBE_CallRejNLFCN 11  /* Call rejected, not listening for CN   */
+#define RFCNBE_CallRejCNNP  12  /* Call rejected, called name not present */
+#define RFCNBE_CallRejInfRes 13 /* Call rejetced, name ok, no resources   */
+#define RFCNBE_CallRejUnSpec 14 /* Call rejected, unspecified error      */
+#define RFCNBE_BadParam      15 /* Bad parameters passed ...             */
+#define RFCNBE_Timeout       16 /* IO Timed out                          */
 
     /* Text strings for the error responses                                 */
 
@@ -60,5 +60,6 @@ extern "C" {
 
 #ifdef __cplusplus
 }
+
 #endif
-#endif /* _RFCNB_ERROR_H_ */
+#endif                          /* _RFCNB_ERROR_H_ */
index 3ad3ab1cd3df600b5de6d30de069ff7e46e7d39d..06786c4e46c276156012f931cb7599a358182a44 100644 (file)
@@ -1,29 +1,29 @@
 #include "config.h"
 
 /* UNIX RFCNB (RFC1001/RFC1002) NEtBIOS implementation
-
  Version 1.0
  RFCNB IO Routines ...
-
  Copyright (C) Richard Sharpe 1996
-
-*/
+ *
* Version 1.0
* RFCNB IO Routines ...
+ *
* Copyright (C) Richard Sharpe 1996
+ *
+ */
 
 /*
  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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 
 #include "rfcnb/std-includes.h"
 #include "rfcnb/rfcnb-priv.h"
 #include <string.h>
 #endif
 
-int RFCNB_Timeout = 0;    /* Timeout in seconds ... */
+int RFCNB_Timeout = 0;          /* Timeout in seconds ... */
 
-int RFCNB_Discard_Rest(struct RFCNB_Con *con, int len);
+static int RFCNB_Discard_Rest(struct RFCNB_Con *con, int len);
 
 #ifdef NOT_USED
-void rfcnb_alarm(int sig)
-
+void
+rfcnb_alarm(int sig)
 {
 
     fprintf(stderr, "IO Timed out ...\n");
 
 }
 
-/* Set timeout value and setup signal handling */
-
-int RFCNB_Set_Timeout(int seconds)
+#endif /* NOT_USED */
 
+#ifdef NOT_USED
+/* Set timeout value and setup signal handling */
+int
+RFCNB_Set_Timeout(int seconds)
 {
     /* If we are on a Bezerkeley system, use sigvec, else sigaction */
 
@@ -65,36 +67,35 @@ int RFCNB_Set_Timeout(int seconds)
 
     RFCNB_Timeout = seconds;
 
-    if (RFCNB_Timeout > 0) { /* Set up handler to ignore but not restart */
+    if (RFCNB_Timeout > 0) {    /* Set up handler to ignore but not restart */
 
 #ifndef SA_RESTART
-        invec.sv_handler = (void (*)())rfcnb_alarm;
+        invec.sv_handler = (void (*)()) rfcnb_alarm;
         invec.sv_mask = 0;
         invec.sv_flags = SV_INTERRUPT;
 
-        if (sigvec(SIGALRM, &invec, &outvec)  < 0)
-            return(-1);
-#else
-        inact.sa_handler = (void (*)())rfcnb_alarm;
+        if (sigvec(SIGALRM, &invec, &outvec) < 0)
+            return (-1);
+#else /* !SA_RESTART */
+        inact.sa_handler = (void (*)()) rfcnb_alarm;
 #ifdef Solaris
         /* Solaris seems to have an array of vectors ... */
         inact.sa_mask.__sigbits[0] = 0;
         inact.sa_mask.__sigbits[1] = 0;
         inact.sa_mask.__sigbits[2] = 0;
         inact.sa_mask.__sigbits[3] = 0;
-#else
-        inact.sa_mask = (sigset_t)0;
-#endif
-        inact.sa_flags = 0;    /* Don't restart */
+#else /* !Solaris */
+        inact.sa_mask = (sigset_t) 0;
+#endif /* Solaris */
+        inact.sa_flags = 0;     /* Don't restart */
 
         if (sigaction(SIGALRM, &inact, &outact) < 0)
-            return(-1);
+            return (-1);
 
-#endif
+#endif /* !SA_RESTART */
 
     }
-
-#else /* ADAPTED SQUID CODE */
+#else /* !ORIGINAL_SAMBA_CODE ADAPTED SQUID CODE */
 #if HAVE_SIGACTION
     struct sigaction inact, outact;
 #else
@@ -112,28 +113,27 @@ int RFCNB_Set_Timeout(int seconds)
 
         if (sigaction(SIGALRM, &inact, &outact) < 0)
             return (-1);
-#else
+#else /* !HAVE_SIGACTION */
     invec.sv_handler = (void (*)()) rfcnb_alarm;
     invec.sv_mask = 0;
     invec.sv_flags = SV_INTERRUPT;
 
     if (sigvec(SIGALRM, &invec, &outvec) < 0)
         return (-1);
-#endif
-
-#endif
-    return(0);
-
+#endif /* !HAVE_SIGACTION */
+    }
+#endif /* !ORIGINAL_SAMBA_CODE ADAPTED SQUID CODE */
+    return (0);
 }
-#endif
+#endif /* NOT_USED */
 
 /* Discard the rest of an incoming packet as we do not have space for it
-   in the buffer we allocated or were passed ...                         */
-
-int RFCNB_Discard_Rest(struct RFCNB_Con *con, int len)
+ * in the buffer we allocated or were passed ...                         */
 
+int
+RFCNB_Discard_Rest(struct RFCNB_Con *con, int len)
 {
-    char temp[100];   /* Read into here */
+    char temp[100];             /* Read into here */
     int rest, this_read, bytes_read;
 
     /* len is the amount we should read */
@@ -146,11 +146,11 @@ int RFCNB_Discard_Rest(struct RFCNB_Con *con, int len)
 
     while (rest > 0) {
 
-        this_read = (rest > sizeof(temp)?sizeof(temp):rest);
+        this_read = (rest > sizeof(temp) ? sizeof(temp) : rest);
 
-        bytes_read = read(con -> fd, temp, this_read);
+        bytes_read = read(con->fd, temp, this_read);
 
-        if (bytes_read <= 0) { /* Error so return */
+        if (bytes_read <= 0) {  /* Error so return */
 
             if (bytes_read < 0)
                 RFCNB_errno = RFCNBE_BadRead;
@@ -158,51 +158,50 @@ int RFCNB_Discard_Rest(struct RFCNB_Con *con, int len)
                 RFCNB_errno = RFCNBE_ConGone;
 
             RFCNB_saved_errno = errno;
-            return(RFCNBE_Bad);
+            return (RFCNBE_Bad);
 
         }
-
         rest = rest - bytes_read;
 
     }
 
-    return(0);
+    return (0);
 
 }
 
 
 /* Send an RFCNB packet to the connection.
-
  We just send each of the blocks linked together ...
-
  If we can, try to send it as one iovec ...
-
-*/
-
-int RFCNB_Put_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len)
-
+ *
* We just send each of the blocks linked together ...
+ *
* If we can, try to send it as one iovec ...
+ *
+ */
+
+int
+RFCNB_Put_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len)
 {
     int len_sent, tot_sent, this_len;
     struct RFCNB_Pkt *pkt_ptr;
     char *this_data;
     int i;
-    struct iovec io_list[10];          /* We should never have more      */
-    /* If we do, this will blow up ...*/
+    struct iovec io_list[10];   /* We should never have more      */
+    /* If we do, this will blow up ... */
 
     /* Try to send the data ... We only send as many bytes as len claims */
     /* We should try to stuff it into an IOVEC and send as one write     */
 
 
     pkt_ptr = pkt;
-    len_sent =  tot_sent = 0;             /* Nothing sent so far */
+    len_sent = tot_sent = 0;    /* Nothing sent so far */
     i = 0;
 
-    while ((pkt_ptr != NULL) & (i < 10)) {  /* Watch that magic number! */
+    while ((pkt_ptr != NULL) & (i < 10)) {      /* Watch that magic number! */
 
-        this_len = pkt_ptr -> len;
-        this_data = pkt_ptr -> data;
+        this_len = pkt_ptr->len;
+        this_data = pkt_ptr->data;
         if ((tot_sent + this_len) > len)
-            this_len = len - tot_sent;        /* Adjust so we don't send too much */
+            this_len = len - tot_sent;  /* Adjust so we don't send too much */
 
         /* Now plug into the iovec ... */
 
@@ -212,9 +211,10 @@ int RFCNB_Put_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len)
 
         tot_sent += this_len;
 
-        if (tot_sent == len) break;   /* Let's not send too much */
+        if (tot_sent == len)
+            break;              /* Let's not send too much */
 
-        pkt_ptr = pkt_ptr -> next;
+        pkt_ptr = pkt_ptr->next;
 
     }
 
@@ -227,71 +227,68 @@ int RFCNB_Put_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len)
     if (RFCNB_Timeout > 0)
         alarm(RFCNB_Timeout);
 
-    if ((len_sent = writev(con -> fd, io_list, i)) < 0) { /* An error */
+    if ((len_sent = writev(con->fd, io_list, i)) < 0) {         /* An error */
 
-        con -> errn = errno;
-        if (errno == EINTR)  /* We were interrupted ... */
+        con->errn = errno;
+        if (errno == EINTR)     /* We were interrupted ... */
             RFCNB_errno = RFCNBE_Timeout;
         else
             RFCNB_errno = RFCNBE_BadWrite;
         RFCNB_saved_errno = errno;
-        return(RFCNBE_Bad);
+        return (RFCNBE_Bad);
 
     }
-
-    if (len_sent < tot_sent) { /* Less than we wanted */
-        if (errno == EINTR)      /* We were interrupted */
+    if (len_sent < tot_sent) {  /* Less than we wanted */
+        if (errno == EINTR)     /* We were interrupted */
             RFCNB_errno = RFCNBE_Timeout;
         else
             RFCNB_errno = RFCNBE_BadWrite;
         RFCNB_saved_errno = errno;
-        return(RFCNBE_Bad);
+        return (RFCNBE_Bad);
     }
-
     if (RFCNB_Timeout > 0)
-        alarm(0);                /* Reset that sucker */
+        alarm(0);               /* Reset that sucker */
 
 #ifdef RFCNB_DEBUG
 
     fprintf(stderr, "Len sent = %i ...\n", len_sent);
-    RFCNB_Print_Pkt(stderr, "sent", pkt, len_sent); /* Print what send ... */
+    RFCNB_Print_Pkt(stderr, "sent", pkt, len_sent);     /* Print what send ... */
 
 #endif
 
-    return(len_sent);
+    return (len_sent);
 
 }
 
 /* Read an RFCNB packet off the connection.
+ *
+ * We read the first 4 bytes, that tells us the length, then read the
+ * rest. We should implement a timeout, but we don't just yet
+ *
+ */
 
-   We read the first 4 bytes, that tells us the length, then read the
-   rest. We should implement a timeout, but we don't just yet
-
-*/
-
-
-int RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len)
 
+int
+RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len)
 {
     int read_len, pkt_len;
-    char hdr[RFCNB_Pkt_Hdr_Len];      /* Local space for the header */
+    char hdr[RFCNB_Pkt_Hdr_Len];        /* Local space for the header */
     struct RFCNB_Pkt *pkt_frag;
     int more, this_time, offset, frag_len, this_len;
     BOOL seen_keep_alive = TRUE;
 
     /* Read that header straight into the buffer */
 
-    if (len < RFCNB_Pkt_Hdr_Len) { /* What a bozo */
+    if (len < RFCNB_Pkt_Hdr_Len) {      /* What a bozo */
 
 #ifdef RFCNB_DEBUG
         fprintf(stderr, "Trying to read less than a packet:");
         perror("");
 #endif
         RFCNB_errno = RFCNBE_BadParam;
-        return(RFCNBE_Bad);
+        return (RFCNBE_Bad);
 
     }
-
     /* We discard keep alives here ... */
 
     if (RFCNB_Timeout > 0)
@@ -299,7 +296,7 @@ int RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len)
 
     while (seen_keep_alive) {
 
-        if ((read_len = read(con -> fd, hdr, sizeof(hdr))) < 0) { /* Problems */
+        if ((read_len = read(con->fd, hdr, sizeof(hdr))) < 0) {         /* Problems */
 #ifdef RFCNB_DEBUG
             fprintf(stderr, "Reading the packet, we got:");
             perror("");
@@ -309,13 +306,12 @@ int RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len)
             else
                 RFCNB_errno = RFCNBE_BadRead;
             RFCNB_saved_errno = errno;
-            return(RFCNBE_Bad);
+            return (RFCNBE_Bad);
 
         }
-
         /* Now we check out what we got */
 
-        if (read_len == 0) { /* Connection closed, send back eof?  */
+        if (read_len == 0) {    /* Connection closed, send back eof?  */
 
 #ifdef RFCNB_DEBUG
             fprintf(stderr, "Connection closed reading\n");
@@ -326,10 +322,9 @@ int RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len)
             else
                 RFCNB_errno = RFCNBE_ConGone;
             RFCNB_saved_errno = errno;
-            return(RFCNBE_Bad);
+            return (RFCNBE_Bad);
 
         }
-
         if (RFCNB_Pkt_Type(hdr) == RFCNB_SESSION_KEEP_ALIVE) {
 
 #ifdef RFCNB_DEBUG
@@ -344,20 +339,19 @@ int RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len)
 
     /* What if we got less than or equal to a hdr size in bytes? */
 
-    if (read_len < sizeof(hdr)) { /* We got a small packet */
+    if (read_len < sizeof(hdr)) {       /* We got a small packet */
 
         /* Now we need to copy the hdr portion we got into the supplied packet */
 
-        memcpy(pkt -> data, hdr, read_len);  /*Copy data */
+        memcpy(pkt->data, hdr, read_len);       /*Copy data */
 
 #ifdef RFCNB_DEBUG
         RFCNB_Print_Pkt(stderr, "rcvd", pkt, read_len);
 #endif
 
-        return(read_len);
+        return (read_len);
 
     }
-
     /* Now, if we got at least a hdr size, alloc space for rest, if we need it */
 
     pkt_len = RFCNB_Pkt_Len(hdr);
@@ -368,13 +362,13 @@ int RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len)
 
     /* Now copy in the hdr */
 
-    memcpy(pkt -> data, hdr, sizeof(hdr));
+    memcpy(pkt->data, hdr, sizeof(hdr));
 
     /* Get the rest of the packet ... first figure out how big our buf is? */
     /* And make sure that we handle the fragments properly ... Sure should */
     /* use an iovec ...                                                    */
 
-    if (len < pkt_len)            /* Only get as much as we have space for */
+    if (len < pkt_len)          /* Only get as much as we have space for */
         more = len - RFCNB_Pkt_Hdr_Len;
     else
         more = pkt_len;
@@ -383,24 +377,24 @@ int RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len)
 
     /* We read for each fragment ... */
 
-    if (pkt -> len == read_len) {    /* If this frag was exact size */
-        pkt_frag = pkt -> next;        /* Stick next lot in next frag */
-        offset = 0;                    /* then we start at 0 in next  */
+    if (pkt->len == read_len) { /* If this frag was exact size */
+        pkt_frag = pkt->next;   /* Stick next lot in next frag */
+        offset = 0;             /* then we start at 0 in next  */
     } else {
-        pkt_frag = pkt;                /* Otherwise use rest of this frag */
-        offset = RFCNB_Pkt_Hdr_Len;    /* Otherwise skip the header       */
+        pkt_frag = pkt;         /* Otherwise use rest of this frag */
+        offset = RFCNB_Pkt_Hdr_Len;     /* Otherwise skip the header       */
     }
 
-    frag_len = pkt_frag -> len;
+    frag_len = pkt_frag->len;
 
-    if (more <= frag_len)     /* If len left to get less than frag space */
+    if (more <= frag_len)       /* If len left to get less than frag space */
         this_len = more;        /* Get the rest ...                        */
     else
         this_len = frag_len - offset;
 
     while (more > 0) {
 
-        if ((this_time = read(con -> fd, (pkt_frag -> data) + offset, this_len)) <= 0) { /* Problems */
+        if ((this_time = read(con->fd, (pkt_frag->data) + offset, this_len)) <= 0) {    /* Problems */
 
             if (errno == EINTR) {
 
@@ -414,23 +408,23 @@ int RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len)
             }
 
             RFCNB_saved_errno = errno;
-            return(RFCNBE_Bad);
+            return (RFCNBE_Bad);
 
         }
-
 #ifdef RFCNB_DEBUG
         fprintf(stderr, "Frag_Len = %i, this_time = %i, this_len = %i, more = %i\n", frag_len,
                 this_time, this_len, more);
 #endif
 
-        read_len = read_len + this_time;  /* How much have we read ... */
+        read_len = read_len + this_time;        /* How much have we read ... */
 
         /* Now set up the next part */
 
-        if (pkt_frag -> next == NULL) break;       /* That's it here */
+        if (pkt_frag->next == NULL)
+            break;              /* That's it here */
 
-        pkt_frag = pkt_frag -> next;
-        this_len = pkt_frag -> len;
+        pkt_frag = pkt_frag->next;
+        this_len = pkt_frag->len;
         offset = 0;
 
         more = more - this_time;
@@ -438,18 +432,17 @@ int RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len)
     }
 
 #ifdef RFCNB_DEBUG
-    fprintf(stderr,"Pkt Len = %i, read_len = %i\n", pkt_len, read_len);
+    fprintf(stderr, "Pkt Len = %i, read_len = %i\n", pkt_len, read_len);
     RFCNB_Print_Pkt(stderr, "rcvd", pkt, read_len + sizeof(hdr));
 #endif
 
-    if (read_len < (pkt_len + sizeof(hdr))) {  /* Discard the rest */
+    if (read_len < (pkt_len + sizeof(hdr))) {   /* Discard the rest */
 
-        return(RFCNB_Discard_Rest(con, (pkt_len + sizeof(hdr)) - read_len));
+        return (RFCNB_Discard_Rest(con, (pkt_len + sizeof(hdr)) - read_len));
 
     }
-
     if (RFCNB_Timeout > 0)
-        alarm(0);                /* Reset that sucker */
+        alarm(0);               /* Reset that sucker */
 
-    return(read_len + sizeof(RFCNB_Hdr));
+    return (read_len + sizeof(RFCNB_Hdr));
 }
index 9af8e90cdf41cc1965d3180258c19de07314bc6e..6b54e86e0593c6530d15e89f34ebe16dead2e42f 100644 (file)
@@ -1,27 +1,27 @@
 /* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
-
  Version 1.0
  RFCNB IO Routines Defines
-
  Copyright (C) Richard Sharpe 1996
-
-*/
+ *
* Version 1.0
* RFCNB IO Routines Defines
+ *
* Copyright (C) Richard Sharpe 1996
+ *
+ */
 
 /*
  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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 
 int RFCNB_Put_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len);
 
index ebb78f5836e703c3c75ed9287acde5ca862486a9..65fb9d08d5844e574cb2825afa1f0db2cac4180f 100644 (file)
@@ -1,27 +1,27 @@
 /* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
-
  Version 1.0
  RFCNB Defines
-
  Copyright (C) Richard Sharpe 1996
-
-*/
+ *
* Version 1.0
* RFCNB Defines
+ *
* Copyright (C) Richard Sharpe 1996
+ *
+ */
 
 /*
  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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 
 #ifndef _RFCNB_RFCNB_PRIV_H
 #define _RFCNB_RFCNB_PRIV_H
@@ -55,7 +55,7 @@ typedef unsigned short uint16;
 
 /* Structures      */
 
-typedef struct redirect_addr * redirect_ptr;
+typedef struct redirect_addr *redirect_ptr;
 
 struct redirect_addr {
 
@@ -68,20 +68,20 @@ struct redirect_addr {
 typedef struct RFCNB_Con {
 
     int fd;                     /* File descripter for TCP/IP connection */
-    int errn;                  /* last error                            */
-    int timeout;                     /* How many milli-secs before IO times out */
-    int redirects;           /* How many times we were redirected     */
-    struct redirect_addr *redirect_list;  /* First is first address */
+    int errn;                   /* last error                            */
+    int timeout;                /* How many milli-secs before IO times out */
+    int redirects;              /* How many times we were redirected     */
+    struct redirect_addr *redirect_list;        /* First is first address */
     struct redirect_addr *last_addr;
 
 } RFCNB_Con;
 
-typedef char RFCNB_Hdr[4]; /* The header is 4 bytes long with  */
+typedef char RFCNB_Hdr[4];      /* The header is 4 bytes long with  */
 /* char[0] as the type, char[1] the */
 /* flags, and char[2..3] the length */
 
 /* Macros to extract things from the header. These are for portability
  between architecture types where we are worried about byte order     */
* between architecture types where we are worried about byte order     */
 
 #define RFCNB_Pkt_Hdr_Len        4
 #define RFCNB_Pkt_Sess_Len       72
@@ -89,7 +89,7 @@ typedef char RFCNB_Hdr[4]; /* The header is 4 bytes long with  */
 #define RFCNB_Pkt_Nack_Len       5
 #define RFCNB_Pkt_Type_Offset    0
 #define RFCNB_Pkt_Flags_Offset   1
-#define RFCNB_Pkt_Len_Offset     2   /* Length is 2 bytes plus a flag bit */
+#define RFCNB_Pkt_Len_Offset     2      /* Length is 2 bytes plus a flag bit */
 #define RFCNB_Pkt_N1Len_Offset   4
 #define RFCNB_Pkt_Called_Offset  5
 #define RFCNB_Pkt_N2Len_Offset   38
@@ -99,24 +99,23 @@ typedef char RFCNB_Hdr[4]; /* The header is 4 bytes long with  */
 #define RFCNB_Pkt_Port_Offset    8
 
 /* The next macro isolates the length of a packet, including the bit in the
  flags                                                                   */
* flags                                                                   */
 
 #define RFCNB_Pkt_Len(p)  (PVAL((p), 3) | (PVAL((p), 2) << 8) |     \
                           ((PVAL((p), RFCNB_Pkt_Flags_Offset) & 0x01) << 16))
 
 #define RFCNB_Put_Pkt_Len(p, v) ((p)[1] = (((v) >> 16) & 1)); \
-                               ((p)[2] = (((v) >> 8) & 0xFF)); \
-                               ((p)[3] = ((v) & 0xFF));
+                                ((p)[2] = (((v) >> 8) & 0xFF)); \
+                                ((p)[3] = ((v) & 0xFF));
 
 #define RFCNB_Pkt_Type(p) (CVAL((p), RFCNB_Pkt_Type_Offset))
 
-/*typedef struct RFCNB_Hdr {
-
-  unsigned char type;
-  unsigned char flags;
-  int16 len;
-
-  } RFCNB_Hdr;
+#if UNUSED_CODE
+typedef struct RFCNB_Hdr {
+    unsigned char type;
+    unsigned char flags;
+    int16 len;
+} RFCNB_Hdr;
 
 typedef struct RFCNB_Sess_Pkt {
     unsigned char type;
@@ -126,23 +125,20 @@ typedef struct RFCNB_Sess_Pkt {
     char called_name[33];
     unsigned char n2_len;
     char calling_name[33];
-  } RFCNB_Sess_Pkt;
+} RFCNB_Sess_Pkt;
 
 
 typedef struct RFCNB_Nack_Pkt {
-
-  struct RFCNB_Hdr hdr;
-  unsigned char error;
-
-  } RFCNB_Nack_Pkt;
+    struct RFCNB_Hdr hdr;
+    unsigned char error;
+} RFCNB_Nack_Pkt;
 
 typedef struct RFCNB_Retarget_Pkt {
-
-  struct RFCNB_Hdr hdr;
-  int dest_ip;
-  unsigned char port;
-
-  } RFCNB_Redir_Pkt; */
+    struct RFCNB_Hdr hdr;
+    int dest_ip;
+    unsigned char port;
+} RFCNB_Redir_Pkt;
+#endif /* UNUSED_CODE */
 
 /* Static variables */
 
@@ -150,7 +146,7 @@ typedef struct RFCNB_Retarget_Pkt {
 
 #ifndef RFCNB_ERRNO
 extern int RFCNB_errno;
-extern int RFCNB_saved_errno;    /* Save this from point of error */
+extern int RFCNB_saved_errno;   /* Save this from point of error */
 #endif
 
 #endif /* _RFCNB_RFCNB_PRIV_H */
index f548b491e01b2b02dc9507983e241f4fb42101b4..c28f43fa7f0c59b7575a47eb4b948838a9c76586 100644 (file)
@@ -1,29 +1,29 @@
 #include "config.h"
 
 /* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
-
  Version 1.0
  RFCNB Utility Routines ...
-
  Copyright (C) Richard Sharpe 1996
-
-*/
+ *
* Version 1.0
* RFCNB Utility Routines ...
+ *
* Copyright (C) Richard Sharpe 1996
+ *
+ */
 
 /*
  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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 
 #include "rfcnb/rfcnb.h"
 #include "rfcnb/std-includes.h"
 #include <string.h>
 #endif
 
-extern void (*Prot_Print_Routine)(); /* Pointer to protocol print routine */
-
 const char *RFCNB_Error_Strings[] = {
-
     "RFCNBE_OK: Routine completed successfully.",
     "RFCNBE_NoSpace: No space available for a malloc call.",
     "RFCNBE_BadName: NetBIOS name could not be translated to IP address.",
@@ -59,15 +56,13 @@ const char *RFCNB_Error_Strings[] = {
     "RFCNBE_CallRejUnSpec: Call rejected. Unspecified error.",
     "RFCNBE_BadParam: Bad parameters passed to a routine.",
     "RFCNBE_Timeout: IO Operation timed out ..."
-
 };
 
 /* Convert name and pad to 16 chars as needed */
 /* Name 1 is a C string with null termination, name 2 may not be */
 /* If SysName is true, then put a <00> on end, else space>       */
-
-void RFCNB_CvtPad_Name(char *name1, char *name2)
-
+void
+RFCNB_CvtPad_Name(char *name1, char *name2)
 {
     char c, c1, c2;
     int i, len;
@@ -79,81 +74,75 @@ void RFCNB_CvtPad_Name(char *name1, char *name2)
         if (i >= len) {
 
             c1 = 'C';
-            c2 = 'A'; /* CA is a space */
+            c2 = 'A';           /* CA is a space */
 
         } else {
 
             c = name1[i];
-            c1 = (char)((int)c/16 + (int)'A');
-            c2 = (char)((int)c%16 + (int)'A');
+            c1 = (char) ((int) c / 16 + (int) 'A');
+            c2 = (char) ((int) c % 16 + (int) 'A');
         }
 
-        name2[i*2] = c1;
-        name2[i*2+1] = c2;
+        name2[i * 2] = c1;
+        name2[i * 2 + 1] = c2;
 
     }
 
-    name2[32] = 0;   /* Put in the nll ...*/
+    name2[32] = 0;              /* Put in the nll ... */
 
 }
 
 /* Converts an Ascii NB Name (16 chars) to an RFCNB Name (32 chars)
-   Uses the encoding in RFC1001. Each nibble of byte is added to 'A'
-   to produce the next byte in the name.
-
-   This routine assumes that AName is 16 bytes long and that NBName has
-   space for 32 chars, so be careful ...
-
-*/
-
-void RFCNB_AName_To_NBName(char *AName, char *NBName)
-
+ * Uses the encoding in RFC1001. Each nibble of byte is added to 'A'
+ * to produce the next byte in the name.
+ *
+ * This routine assumes that AName is 16 bytes long and that NBName has
+ * space for 32 chars, so be careful ...
+ */
+void
+RFCNB_AName_To_NBName(char *AName, char *NBName)
 {
     char c, c1, c2;
     int i;
 
-    for (i=0; i < 16; i++) {
+    for (i = 0; i < 16; i++) {
 
         c = AName[i];
 
-        c1 = (char)((c >> 4) + 'A');
-        c2 = (char)((c & 0xF) + 'A');
+        c1 = (char) ((c >> 4) + 'A');
+        c2 = (char) ((c & 0xF) + 'A');
 
-        NBName[i*2] = c1;
-        NBName[i*2+1] = c2;
+        NBName[i * 2] = c1;
+        NBName[i * 2 + 1] = c2;
     }
 
-    NBName[32] = 0; /* Put in a null */
-
+    NBName[32] = 0;             /* Put in a null */
 }
 
 /* Do the reverse of the above ... */
-
-void RFCNB_NBName_To_AName(char *NBName, char *AName)
-
+void
+RFCNB_NBName_To_AName(char *NBName, char *AName)
 {
     char c, c1, c2;
     int i;
 
-    for (i=0; i < 16; i++) {
+    for (i = 0; i < 16; i++) {
 
-        c1 = NBName[i*2];
-        c2 = NBName[i*2+1];
+        c1 = NBName[i * 2];
+        c2 = NBName[i * 2 + 1];
 
-        c = (char)(((int)c1 - (int)'A') * 16 + ((int)c2 - (int)'A'));
+        c = (char) (((int) c1 - (int) 'A') * 16 + ((int) c2 - (int) 'A'));
 
         AName[i] = c;
 
     }
 
-    AName[i] = 0;   /* Put a null on the end ... */
-
+    AName[i] = 0;               /* Put a null on the end ... */
 }
 
 /* Print a string of bytes in HEX etc */
-
-void RFCNB_Print_Hex(FILE *fd, struct RFCNB_Pkt *pkt, int Offset, int Len)
-
+void
+RFCNB_Print_Hex(FILE * fd, struct RFCNB_Pkt *pkt, int Offset, int Len)
 {
     char c1, c2, outbuf1[33];
     unsigned char c;
@@ -168,27 +157,26 @@ void RFCNB_Print_Hex(FILE *fd, struct RFCNB_Pkt *pkt, int Offset, int Len)
     while (pkt_ptr != NULL) {
 
         for (i = 0;
-                i < ((Len > (pkt_ptr -> len)?pkt_ptr -> len:Len) - Offset);
+                i < ((Len > (pkt_ptr->len) ? pkt_ptr->len : Len) - Offset);
                 i++) {
 
-            c = pkt_ptr -> data[i + Offset];
+            c = pkt_ptr->data[i + Offset];
             c1 = Hex_List[c >> 4];
             c2 = Hex_List[c & 0xF];
 
             outbuf1[j++] = c1;
             outbuf1[j++] = c2;
 
-            if (j == 32) { /* Print and reset */
+            if (j == 32) {      /* Print and reset */
                 outbuf1[j] = 0;
                 fprintf(fd, "    %s\n", outbuf1);
                 j = 0;
             }
-
         }
 
         Offset = 0;
-        Len = Len - pkt_ptr -> len;   /* Reduce amount by this much */
-        pkt_ptr = pkt_ptr -> next;
+        Len = Len - pkt_ptr->len;       /* Reduce amount by this much */
+        pkt_ptr = pkt_ptr->next;
 
     }
 
@@ -200,57 +188,50 @@ void RFCNB_Print_Hex(FILE *fd, struct RFCNB_Pkt *pkt, int Offset, int Len)
         fprintf(fd, "    %s\n", outbuf1);
 
     }
-
     fprintf(fd, "\n");
-
 }
 
 /* Get a packet of size n */
-
-struct RFCNB_Pkt *RFCNB_Alloc_Pkt(int n)
-
-{
+struct RFCNB_Pkt *
+RFCNB_Alloc_Pkt(int n) {
     RFCNB_Pkt *pkt;
 
-    if ((pkt = (struct RFCNB_Pkt *)malloc(sizeof(struct RFCNB_Pkt))) == NULL) {
+    if ((pkt = (struct RFCNB_Pkt *) malloc(sizeof(struct RFCNB_Pkt))) == NULL) {
 
         RFCNB_errno = RFCNBE_NoSpace;
         RFCNB_saved_errno = errno;
-        return(NULL);
+        return (NULL);
 
     }
+    pkt->next = NULL;
+    pkt->len = n;
 
-    pkt -> next = NULL;
-    pkt -> len = n;
-
-    if (n == 0) return(pkt);
+    if (n == 0)
+        return (pkt);
 
-    if ((pkt -> data = (char *)malloc(n)) == NULL) {
+    if ((pkt->data = (char *) malloc(n)) == NULL) {
 
         RFCNB_errno = RFCNBE_NoSpace;
         RFCNB_saved_errno = errno;
         free(pkt);
-        return(NULL);
+        return (NULL);
 
     }
-
-    return(pkt);
-
+    return (pkt);
 }
 
 /* Free up a packet */
-
-void RFCNB_Free_Pkt(struct RFCNB_Pkt *pkt)
-
+void
+RFCNB_Free_Pkt(struct RFCNB_Pkt *pkt)
 {
     struct RFCNB_Pkt *pkt_next;
     char *data_ptr;
 
     while (pkt != NULL) {
 
-        pkt_next = pkt -> next;
+        pkt_next = pkt->next;
 
-        data_ptr = pkt -> data;
+        data_ptr = pkt->data;
 
         if (data_ptr != NULL)
             free(data_ptr);
@@ -260,13 +241,11 @@ void RFCNB_Free_Pkt(struct RFCNB_Pkt *pkt)
         pkt = pkt_next;
 
     }
-
 }
 
 /* Print an RFCNB packet */
-
-void RFCNB_Print_Pkt(FILE *fd, char *dirn, struct RFCNB_Pkt *pkt, int len)
-
+void
+RFCNB_Print_Pkt(FILE * fd, char *dirn, struct RFCNB_Pkt *pkt, int len)
 {
     char lname[17];
 
@@ -275,34 +254,33 @@ void RFCNB_Print_Pkt(FILE *fd, char *dirn, struct RFCNB_Pkt *pkt, int len)
 
     fprintf(fd, "RFCNB Pkt %s:", dirn);
 
-    switch (RFCNB_Pkt_Type(pkt -> data)) {
+    switch (RFCNB_Pkt_Type(pkt->data)) {
 
     case RFCNB_SESSION_MESSAGE:
 
-        fprintf(fd, "SESSION MESSAGE: Length = %i\n", RFCNB_Pkt_Len(pkt -> data));
+        fprintf(fd, "SESSION MESSAGE: Length = %i\n", RFCNB_Pkt_Len(pkt->data));
         RFCNB_Print_Hex(fd, pkt, RFCNB_Pkt_Hdr_Len,
 #ifdef RFCNB_PRINT_DATA
-                        RFCNB_Pkt_Len(pkt -> data) - RFCNB_Pkt_Hdr_Len);
+                        RFCNB_Pkt_Len(pkt->data) - RFCNB_Pkt_Hdr_Len);
 #else
                         40);
 #endif
 
-        if (Prot_Print_Routine != 0) { /* Print the rest of the packet */
+        if (Prot_Print_Routine) {       /* Print the rest of the packet */
 
             Prot_Print_Routine(fd, strcmp(dirn, "sent"), pkt, RFCNB_Pkt_Hdr_Len,
-                               RFCNB_Pkt_Len(pkt -> data) - RFCNB_Pkt_Hdr_Len);
+                               RFCNB_Pkt_Len(pkt->data) - RFCNB_Pkt_Hdr_Len);
 
         }
-
         break;
 
     case RFCNB_SESSION_REQUEST:
 
         fprintf(fd, "SESSION REQUEST: Length = %i\n",
-                RFCNB_Pkt_Len(pkt -> data));
-        RFCNB_NBName_To_AName((char *)(pkt -> data + RFCNB_Pkt_Called_Offset), lname);
+                RFCNB_Pkt_Len(pkt->data));
+        RFCNB_NBName_To_AName((char *) (pkt->data + RFCNB_Pkt_Called_Offset), lname);
         fprintf(fd, "  Called Name: %s\n", lname);
-        RFCNB_NBName_To_AName((char *)(pkt -> data + RFCNB_Pkt_Calling_Offset), lname);
+        RFCNB_NBName_To_AName((char *) (pkt->data + RFCNB_Pkt_Calling_Offset), lname);
         fprintf(fd, "  Calling Name: %s\n", lname);
 
         break;
@@ -310,18 +288,18 @@ void RFCNB_Print_Pkt(FILE *fd, char *dirn, struct RFCNB_Pkt *pkt, int len)
     case RFCNB_SESSION_ACK:
 
         fprintf(fd, "RFCNB SESSION ACK: Length = %i\n",
-                RFCNB_Pkt_Len(pkt -> data));
+                RFCNB_Pkt_Len(pkt->data));
 
         break;
 
     case RFCNB_SESSION_REJ:
         fprintf(fd, "RFCNB SESSION REJECT: Length = %i\n",
-                RFCNB_Pkt_Len(pkt -> data));
+                RFCNB_Pkt_Len(pkt->data));
 
-        if (RFCNB_Pkt_Len(pkt -> data) < 1) {
+        if (RFCNB_Pkt_Len(pkt->data) < 1) {
             fprintf(fd, "   Protocol Error, short Reject packet!\n");
         } else {
-            fprintf(fd, "   Error = %x\n", CVAL(pkt -> data, RFCNB_Pkt_Error_Offset));
+            fprintf(fd, "   Error = %x\n", CVAL(pkt->data, RFCNB_Pkt_Error_Offset));
         }
 
         break;
@@ -329,7 +307,7 @@ void RFCNB_Print_Pkt(FILE *fd, char *dirn, struct RFCNB_Pkt *pkt, int len)
     case RFCNB_SESSION_RETARGET:
 
         fprintf(fd, "RFCNB SESSION RETARGET: Length = %i\n",
-                RFCNB_Pkt_Len(pkt -> data));
+                RFCNB_Pkt_Len(pkt->data));
 
         /* Print out the IP address etc and the port? */
 
@@ -338,57 +316,53 @@ void RFCNB_Print_Pkt(FILE *fd, char *dirn, struct RFCNB_Pkt *pkt, int len)
     case RFCNB_SESSION_KEEP_ALIVE:
 
         fprintf(fd, "RFCNB SESSION KEEP ALIVE: Length = %i\n",
-                RFCNB_Pkt_Len(pkt -> data));
+                RFCNB_Pkt_Len(pkt->data));
         break;
 
     default:
 
         break;
     }
-
 }
 
 /* Resolve a name into an address */
-
-int RFCNB_Name_To_IP(char *host, struct in_addr *Dest_IP)
-
+int
+RFCNB_Name_To_IP(char *host, struct in_addr *Dest_IP)
 {
-    int addr;         /* Assumes IP4, 32 bit network addresses */
+    int addr;                   /* Assumes IP4, 32 bit network addresses */
     struct hostent *hp;
 
     /* Use inet_addr to try to convert the address */
 
-    if ((addr = inet_addr(host)) == INADDR_NONE) { /* Oh well, a good try :-) */
+    if ((addr = inet_addr(host)) == INADDR_NONE) {      /* Oh well, a good try :-) */
 
         /* Now try a name look up with gethostbyname */
 
-        if ((hp = gethostbyname(host)) == NULL) { /* Not in DNS */
+        if ((hp = gethostbyname(host)) == NULL) {       /* Not in DNS */
 
             /* Try NetBIOS name lookup, how the hell do we do that? */
 
-            RFCNB_errno = RFCNBE_BadName;   /* Is this right? */
+            RFCNB_errno = RFCNBE_BadName;       /* Is this right? */
             RFCNB_saved_errno = errno;
-            return(RFCNBE_Bad);
+            return (RFCNBE_Bad);
 
-        } else { /* We got a name */
+        } else {                /* We got a name */
 
-            memcpy((void *)Dest_IP, (void *)hp -> h_addr_list[0], sizeof(struct in_addr));
+            memcpy((void *) Dest_IP, (void *) hp->h_addr_list[0], sizeof(struct in_addr));
 
         }
-    } else { /* It was an IP address */
+    } else {                    /* It was an IP address */
 
-        memcpy((void *)Dest_IP, (void *)&addr, sizeof(struct in_addr));
+        memcpy((void *) Dest_IP, (void *) &addr, sizeof(struct in_addr));
 
     }
 
     return 0;
-
 }
 
 /* Disconnect the TCP connection to the server */
-
-int RFCNB_Close(int socket)
-
+int
+RFCNB_Close(int socket)
 {
 
     close(socket);
@@ -396,59 +370,52 @@ int RFCNB_Close(int socket)
     /* If we want to do error recovery, here is where we put it */
 
     return 0;
-
 }
 
 /* Connect to the server specified in the IP address.
-   Not sure how to handle socket options etc.         */
-
-int RFCNB_IP_Connect(struct in_addr Dest_IP, int port)
-
+ * Not sure how to handle socket options etc.         */
+int
+RFCNB_IP_Connect(struct in_addr Dest_IP, int port)
 {
     struct sockaddr_in Socket;
     int fd;
 
     /* Create a socket */
 
-    if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { /* Handle the error */
+    if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {   /* Handle the error */
 
         RFCNB_errno = RFCNBE_BadSocket;
         RFCNB_saved_errno = errno;
-        return(RFCNBE_Bad);
+        return (RFCNBE_Bad);
     }
-
-    memset((char *)&Socket, 0, sizeof(Socket));
-    memcpy((char *)&Socket.sin_addr, (char *)&Dest_IP, sizeof(Dest_IP));
+    memset((char *) &Socket, 0, sizeof(Socket));
+    memcpy((char *) &Socket.sin_addr, (char *) &Dest_IP, sizeof(Dest_IP));
 
     Socket.sin_port = htons(port);
     Socket.sin_family = PF_INET;
 
     /* Now connect to the destination */
 
-    if (connect(fd, (struct sockaddr *)&Socket, sizeof(Socket)) < 0) { /* Error */
+    if (connect(fd, (struct sockaddr *) &Socket, sizeof(Socket)) < 0) {         /* Error */
 
         close(fd);
         RFCNB_errno = RFCNBE_ConnectFailed;
         RFCNB_saved_errno = errno;
-        return(RFCNBE_Bad);
+        return (RFCNBE_Bad);
     }
-
-    return(fd);
-
+    return (fd);
 }
 
 /* handle the details of establishing the RFCNB session with remote
-   end
-
-*/
-
-int RFCNB_Session_Req(struct RFCNB_Con *con,
-                      char *Called_Name,
-                      char *Calling_Name,
-                      BOOL *redirect,
-                      struct in_addr *Dest_IP,
-                      int * port)
-
+ * end
+ */
+int
+RFCNB_Session_Req(struct RFCNB_Con *con,
+                  char *Called_Name,
+                  char *Calling_Name,
+                  BOOL * redirect,
+                  struct in_addr *Dest_IP,
+                  int *port)
 {
     char *sess_pkt;
 
@@ -464,15 +431,12 @@ int RFCNB_Session_Req(struct RFCNB_Con *con,
     pkt = RFCNB_Alloc_Pkt(RFCNB_Pkt_Sess_Len);
 
     if (pkt == NULL) {
-
-        return(RFCNBE_Bad);  /* Leave the error that RFCNB_Alloc_Pkt gives) */
-
+        return (RFCNBE_Bad);    /* Leave the error that RFCNB_Alloc_Pkt gives) */
     }
+    sess_pkt = pkt->data;       /* Get pointer to packet proper */
 
-    sess_pkt = pkt -> data;    /* Get pointer to packet proper */
-
-    sess_pkt[RFCNB_Pkt_Type_Offset]  = RFCNB_SESSION_REQUEST;
-    RFCNB_Put_Pkt_Len(sess_pkt, RFCNB_Pkt_Sess_Len-RFCNB_Pkt_Hdr_Len);
+    sess_pkt[RFCNB_Pkt_Type_Offset] = RFCNB_SESSION_REQUEST;
+    RFCNB_Put_Pkt_Len(sess_pkt, RFCNB_Pkt_Sess_Len - RFCNB_Pkt_Hdr_Len);
     sess_pkt[RFCNB_Pkt_N1Len_Offset] = 32;
     sess_pkt[RFCNB_Pkt_N2Len_Offset] = 32;
 
@@ -482,42 +446,36 @@ int RFCNB_Session_Req(struct RFCNB_Con *con,
     /* Now send the packet */
 
 #ifdef RFCNB_DEBUG
-
     fprintf(stderr, "Sending packet: ");
-
 #endif
 
     if ((len = RFCNB_Put_Pkt(con, pkt, RFCNB_Pkt_Sess_Len)) < 0) {
 
-        return(RFCNBE_Bad);       /* Should be able to write that lot ... */
+        return (RFCNBE_Bad);    /* Should be able to write that lot ... */
 
     }
-
 #ifdef RFCNB_DEBUG
-
     fprintf(stderr, "Getting packet.\n");
-
 #endif
 
     res_pkt.data = resp;
-    res_pkt.len  = sizeof(resp);
+    res_pkt.len = sizeof(resp);
     res_pkt.next = NULL;
 
     if ((len = RFCNB_Get_Pkt(con, &res_pkt, sizeof(resp))) < 0) {
 
-        return(RFCNBE_Bad);
+        return (RFCNBE_Bad);
 
     }
-
     /* Now analyze the packet ... */
 
     switch (RFCNB_Pkt_Type(resp)) {
 
-    case RFCNB_SESSION_REJ:         /* Didnt like us ... too bad */
+    case RFCNB_SESSION_REJ:     /* Didnt like us ... too bad */
 
         /* Why did we get rejected ? */
 
-        switch (CVAL(resp,RFCNB_Pkt_Error_Offset)) {
+        switch (CVAL(resp, RFCNB_Pkt_Error_Offset)) {
 
         case 0x80:
             RFCNB_errno = RFCNBE_CallRejNLOCN;
@@ -539,37 +497,28 @@ int RFCNB_Session_Req(struct RFCNB_Con *con,
             break;
         }
 
-        return(RFCNBE_Bad);
+        return (RFCNBE_Bad);
         break;
 
-    case RFCNB_SESSION_ACK:        /* Got what we wanted ...      */
+    case RFCNB_SESSION_ACK:     /* Got what we wanted ...      */
 
-        return(0);
+        return (0);
         break;
 
-    case RFCNB_SESSION_RETARGET:   /* Go elsewhere                */
+    case RFCNB_SESSION_RETARGET:        /* Go elsewhere                */
 
         *redirect = TRUE;       /* Copy port and ip addr       */
 
         memcpy(Dest_IP, (resp + RFCNB_Pkt_IP_Offset), sizeof(struct in_addr));
         *port = SVAL(resp, RFCNB_Pkt_Port_Offset);
 
-        return(0);
+        return (0);
         break;
 
-    default:  /* A protocol error */
+    default:                    /* A protocol error */
 
         RFCNB_errno = RFCNBE_ProtErr;
-        return(RFCNBE_Bad);
+        return (RFCNBE_Bad);
         break;
     }
 }
-
-
-
-
-
-
-
-
-
index e977e549fb92c6d7f8739a597fb2e7fc6f732264..1fe1a4a8f132cd4e2e092d580f269a91c96d6d96 100644 (file)
@@ -1,27 +1,27 @@
 /* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
-
  Version 1.0
  RFCNB Utility Defines
-
  Copyright (C) Richard Sharpe 1996
-
-*/
+ *
* Version 1.0
* RFCNB Utility Defines
+ *
* Copyright (C) Richard Sharpe 1996
+ *
+ */
 
 /*
  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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 
 void RFCNB_CvtPad_Name(char *name1, char *name2);
 
@@ -29,9 +29,9 @@ void RFCNB_AName_To_NBName(char *AName, char *NBName);
 
 void RFCNB_NBName_To_AName(char *NBName, char *AName);
 
-void RFCNB_Print_Hex(FILE *fd, struct RFCNB_Pkt *pkt, int Offset, int Len);
+void RFCNB_Print_Hex(FILE * fd, struct RFCNB_Pkt *pkt, int Offset, int Len);
 
-void RFCNB_Print_Pkt(FILE *fd, char *dirn, struct RFCNB_Pkt *pkt, int len);
+void RFCNB_Print_Pkt(FILE * fd, char *dirn, struct RFCNB_Pkt *pkt, int len);
 
 int RFCNB_Name_To_IP(char *host, struct in_addr *Dest_IP);
 
@@ -42,7 +42,9 @@ int RFCNB_IP_Connect(struct in_addr Dest_IP, int port);
 int RFCNB_Session_Req(struct RFCNB_Con *con,
                       char *Called_Name,
                       char *Calling_Name,
-                      BOOL *redirect,
+                      BOOL * redirect,
                       struct in_addr *Dest_IP,
-                      int * port);
+                      int *port);
 
+typedef void RFCNB_Prot_Print_Routine(FILE * fd, int dir, struct RFCNB_Pkt *pkt, int header, int payload);
+extern RFCNB_Prot_Print_Routine *Prot_Print_Routine;
index 28002e800d35ace344bb75afd358f4d2b270f4a7..1e4c3d9cb283522dc93babd39d9661af6e576e85 100644 (file)
@@ -1,27 +1,27 @@
 /* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
-
  Version 1.0
  RFCNB Defines
-
  Copyright (C) Richard Sharpe 1996
-
-*/
+ *
* Version 1.0
* RFCNB Defines
+ *
* Copyright (C) Richard Sharpe 1996
+ *
+ */
 
 /*
  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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 
 #ifndef _RFCNB_RFCNB_H
 #define _RFCNB_RFCNB_H
@@ -52,7 +52,7 @@ extern "C" {
 
     int RFCNB_Hangup(struct RFCNB_Con *con_Handle);
 
-    void *RFCNB_Listen();
+    void *RFCNB_Listen(void);
 
     void RFCNB_Get_Error(char *buffer, int buf_len);
 
@@ -66,5 +66,6 @@ extern "C" {
 
 #ifdef __cplusplus
 }
+
 #endif
-#endif /* _RFCNB_RFCNB_H */
+#endif                          /* _RFCNB_RFCNB_H */
index 1baafc1b43c7d43f65d7c5835c9549f4c2cee78d..0a4878e3fee16885d35b3cccdfb12c611ec1d871 100644 (file)
@@ -1,29 +1,29 @@
 #include "config.h"
 
 /* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
-
  Version 1.0
  Session Routines ...
-
  Copyright (C) Richard Sharpe 1996
-
-*/
+ *
* Version 1.0
* Session Routines ...
+ *
* Copyright (C) Richard Sharpe 1996
+ *
+ */
 
 /*
  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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 
 int RFCNB_errno = 0;
 int RFCNB_saved_errno = 0;
@@ -42,22 +42,17 @@ int RFCNB_saved_errno = 0;
 
 int RFCNB_Stats[RFCNB_MAX_STATS];
 
-void (*Prot_Print_Routine)() = NULL;      /* Pointer to print routine */
-
-int RFCNB_Get_Last_Errno(void);
-int RFCNB_Get_Error_Msg(int code, char *msg_buf, int len);
-void RFCNB_Register_Print_Routine(void (*fn)());
+RFCNB_Prot_Print_Routine *Prot_Print_Routine = NULL;   /* Pointer to protocol print routine */
 
 /* Set up a session with a remote name. We are passed Called_Name as a
-   string which we convert to a NetBIOS name, ie space terminated, up to
-   16 characters only if we need to. If Called_Address is not empty, then
-   we use it to connect to the remote end, but put in Called_Name ... Called
-   Address can be a DNS based name, or a TCP/IP address ...
-*/
-
-void *RFCNB_Call(char *Called_Name, char *Calling_Name, char *Called_Address,
-                 int port)
-
+ * string which we convert to a NetBIOS name, ie space terminated, up to
+ * 16 characters only if we need to. If Called_Address is not empty, then
+ * we use it to connect to the remote end, but put in Called_Name ... Called
+ * Address can be a DNS based name, or a TCP/IP address ...
+ */
+
+void *
+RFCNB_Call(char *Called_Name, char *Calling_Name, char *Called_Address, int port)
 {
     struct RFCNB_Con *con;
     struct in_addr Dest_IP;
@@ -68,88 +63,84 @@ void *RFCNB_Call(char *Called_Name, char *Calling_Name, char *Called_Address,
 
     /* Now, we really should look up the port in /etc/services ... */
 
-    if (port == 0) port = RFCNB_Default_Port;
+    if (port == 0)
+        port = RFCNB_Default_Port;
 
     /* Create a connection structure first */
 
-    if ((con = (struct RFCNB_Con *)malloc(sizeof(struct RFCNB_Con))) == NULL) { /* Error in size */
+    if ((con = (struct RFCNB_Con *) malloc(sizeof(struct RFCNB_Con))) == NULL) {        /* Error in size */
 
         RFCNB_errno = RFCNBE_NoSpace;
         RFCNB_saved_errno = errno;
-        return(NULL);
+        return (NULL);
 
     }
-
-    con -> fd = -0;             /* no descriptor yet */
-    con -> errn = 0;            /* no error yet */
-    con -> timeout = 0;         /* no timeout   */
-    con -> redirects = 0;
+    con->fd = -0;               /* no descriptor yet */
+    con->errn = 0;              /* no error yet */
+    con->timeout = 0;           /* no timeout   */
+    con->redirects = 0;
 
     /* Resolve that name into an IP address */
 
     Service_Address = Called_Name;
-    if (strcmp(Called_Address, "") != 0) { /* If the Called Address = "" */
+    if (strcmp(Called_Address, "") != 0) {      /* If the Called Address = "" */
         Service_Address = Called_Address;
     }
-
-    if ((errno = RFCNB_Name_To_IP(Service_Address, &Dest_IP)) < 0) { /* Error */
+    if ((errno = RFCNB_Name_To_IP(Service_Address, &Dest_IP)) < 0) {    /* Error */
 
         /* No need to modify RFCNB_errno as it was done by RFCNB_Name_To_IP */
         free(con);
-        return(NULL);
+        return (NULL);
 
     }
-
     /* Now connect to the remote end */
 
-    redirect = TRUE;     /* Fudge this one so we go once through */
+    redirect = TRUE;            /* Fudge this one so we go once through */
 
-    while (redirect) {   /* Connect and get session info etc */
+    while (redirect) {          /* Connect and get session info etc */
 
-        redirect = FALSE;  /* Assume all OK */
+        redirect = FALSE;       /* Assume all OK */
 
         /* Build the redirect info. First one is first addr called */
         /* And tack it onto the list of addresses we called        */
 
-        if ((redir_addr = (struct redirect_addr *)malloc(sizeof(struct redirect_addr))) == NULL) { /* Could not get space */
+        if ((redir_addr = (struct redirect_addr *) malloc(sizeof(struct redirect_addr))) == NULL) {     /* Could not get space */
 
             RFCNB_errno = RFCNBE_NoSpace;
             RFCNB_saved_errno = errno;
             free(con);
-            return(NULL);
+            return (NULL);
 
         }
+        memcpy((char *) &(redir_addr->ip_addr), (char *) &Dest_IP, sizeof(Dest_IP));
+        redir_addr->port = port;
+        redir_addr->next = NULL;
 
-        memcpy((char *)&(redir_addr -> ip_addr), (char *)&Dest_IP, sizeof(Dest_IP));
-        redir_addr -> port = port;
-        redir_addr -> next = NULL;
+        if (con->redirect_list == NULL) {       /* Stick on head */
 
-        if (con -> redirect_list == NULL) { /* Stick on head */
-
-            con -> redirect_list = con -> last_addr = redir_addr;
+            con->redirect_list = con->last_addr = redir_addr;
 
         } else {
 
-            con -> last_addr -> next = redir_addr;
-            con -> last_addr = redir_addr;
+            con->last_addr->next = redir_addr;
+            con->last_addr = redir_addr;
 
         }
 
         /* Now, make that connection */
 
-        if ((Client = RFCNB_IP_Connect(Dest_IP, port)) < 0) { /* Error */
+        if ((Client = RFCNB_IP_Connect(Dest_IP, port)) < 0) {   /* Error */
 
             /* No need to modify RFCNB_errno as it was done by RFCNB_IP_Connect */
             free(con);
-            return(NULL);
+            return (NULL);
 
         }
-
-        con -> fd = Client;
+        con->fd = Client;
 
         /* Now send and handle the RFCNB session request              */
         /* If we get a redirect, we will comeback with redirect true
-           and a new IP address in DEST_IP                            */
+         * and a new IP address in DEST_IP                            */
 
         if ((errno = RFCNB_Session_Req(con,
                                        Called_Name,
@@ -158,33 +149,30 @@ void *RFCNB_Call(char *Called_Name, char *Calling_Name, char *Called_Address,
 
             /* No need to modify RFCNB_errno as it was done by RFCNB_Session.. */
 
-            RFCNB_Close(con->fd);      /* Close it */
+            RFCNB_Close(con->fd);       /* Close it */
             free(con);
-            return(NULL);
+            return (NULL);
 
         }
-
         if (redirect) {
 
             /* We have to close the connection, and then try again */
 
-            (con -> redirects)++;
+            (con->redirects)++;
 
-            RFCNB_Close(con -> fd);  /* Close it */
+            RFCNB_Close(con->fd);       /* Close it */
 
         }
     }
 
-    return(con);
-
+    return (con);
 }
 
 /* We send a packet to the other end ... for the moment, we treat the
-   data as a series of pointers to blocks of data ... we should check the
-   length ... */
-
-int RFCNB_Send(struct RFCNB_Con *Con_Handle, struct RFCNB_Pkt *udata, int Length)
-
+ * data as a series of pointers to blocks of data ... we should check the
+ * length ... */
+int
+RFCNB_Send(struct RFCNB_Con *Con_Handle, struct RFCNB_Pkt *udata, int Length)
 {
     struct RFCNB_Pkt *pkt;
     char *hdr;
@@ -198,17 +186,16 @@ int RFCNB_Send(struct RFCNB_Con *Con_Handle, struct RFCNB_Pkt *udata, int Length
 
         RFCNB_errno = RFCNBE_NoSpace;
         RFCNB_saved_errno = errno;
-        return(RFCNBE_Bad);
+        return (RFCNBE_Bad);
 
     }
+    pkt->next = udata;          /* The user data we want to send */
 
-    pkt -> next = udata;   /* The user data we want to send */
-
-    hdr = pkt -> data;
+    hdr = pkt->data;
 
     /* Following crap is for portability across multiple UNIX machines */
 
-    *(hdr + RFCNB_Pkt_Type_Offset)  = RFCNB_SESSION_MESSAGE;
+    *(hdr + RFCNB_Pkt_Type_Offset) = RFCNB_SESSION_MESSAGE;
     RFCNB_Put_Pkt_Len(hdr, Length);
 
 #ifdef RFCNB_DEBUG
@@ -221,25 +208,22 @@ int RFCNB_Send(struct RFCNB_Con *Con_Handle, struct RFCNB_Pkt *udata, int Length
 
         /* No need to change RFCNB_errno as it was done by put_pkt ...     */
 
-        return(RFCNBE_Bad);   /* Should be able to write that lot ... */
+        return (RFCNBE_Bad);    /* Should be able to write that lot ... */
 
     }
-
     /* Now we have sent that lot, let's get rid of the RFCNB Header and return */
 
-    pkt -> next = NULL;
+    pkt->next = NULL;
 
     RFCNB_Free_Pkt(pkt);
 
-    return(len);
-
+    return (len);
 }
 
 /* We pick up a message from the internet ... We have to worry about
-   non-message packets ...                                           */
-
-int RFCNB_Recv(void *con_Handle, struct RFCNB_Pkt *Data, int Length)
-
+ * non-message packets ...                                           */
+int
+RFCNB_Recv(void *con_Handle, struct RFCNB_Pkt *Data, int Length)
 {
     struct RFCNB_Pkt *pkt;
 //    struct RFCNB_Hdr *hdr;
@@ -249,10 +233,9 @@ int RFCNB_Recv(void *con_Handle, struct RFCNB_Pkt *Data, int Length)
 
         RFCNB_errno = RFCNBE_BadHandle;
         RFCNB_saved_errno = errno;
-        return(RFCNBE_Bad);
+        return (RFCNBE_Bad);
 
     }
-
     /* Now get a packet from below. We allocate a header first */
 
     /* Plug in the header and send the data */
@@ -263,11 +246,10 @@ int RFCNB_Recv(void *con_Handle, struct RFCNB_Pkt *Data, int Length)
 
         RFCNB_errno = RFCNBE_NoSpace;
         RFCNB_saved_errno = errno;
-        return(RFCNBE_Bad);
+        return (RFCNBE_Bad);
 
     }
-
-    pkt -> next = Data;  /* Plug in the data portion */
+    pkt->next = Data;           /* Plug in the data portion */
 
     if ((ret_len = RFCNB_Get_Pkt(con_Handle, pkt, Length + RFCNB_Pkt_Hdr_Len)) < 0) {
 
@@ -275,112 +257,67 @@ int RFCNB_Recv(void *con_Handle, struct RFCNB_Pkt *Data, int Length)
         fprintf(stderr, "Bad packet return in RFCNB_Recv... \n");
 #endif
 
-        return(RFCNBE_Bad);
+        return (RFCNBE_Bad);
 
     }
-
     /* We should check that we go a message and not a keep alive */
 
-    pkt -> next = NULL;
+    pkt->next = NULL;
 
     RFCNB_Free_Pkt(pkt);
 
-    return(ret_len);
-
+    return (ret_len);
 }
 
 /* We just disconnect from the other end, as there is nothing in the RFCNB */
 /* protocol that specifies any exchange as far as I can see                */
-
-int RFCNB_Hangup(struct RFCNB_Con *con_Handle)
-
+int
+RFCNB_Hangup(struct RFCNB_Con *con_Handle)
 {
 
     if (con_Handle != NULL) {
-        RFCNB_Close(con_Handle -> fd);  /* Could this fail? */
+        RFCNB_Close(con_Handle->fd);    /* Could this fail? */
         free(con_Handle);
     }
-
     return 0;
-
-
 }
 
 /* Set TCP_NODELAY on the socket                                          */
-
-int RFCNB_Set_Sock_NoDelay(struct RFCNB_Con *con_Handle, BOOL yn)
-
+int
+RFCNB_Set_Sock_NoDelay(struct RFCNB_Con *con_Handle, BOOL yn)
 {
 
-    return(setsockopt(con_Handle -> fd, IPPROTO_TCP, TCP_NODELAY,
-                      (char *)&yn, sizeof(yn)));
-
+    return (setsockopt(con_Handle->fd, IPPROTO_TCP, TCP_NODELAY,
+                       (char *) &yn, sizeof(yn)));
 }
 
 #if NOT_IMPLEMENTED
-
 /* Listen for a connection on a port???, when                             */
 /* the connection comes in, we return with the connection                 */
-
-void *RFCNB_Listen()
-
+void *
+RFCNB_Listen()
 {
-
 }
+
 #endif
 
 /* Pick up the last error response as a string, hmmm, this routine should */
 /* have been different ...                                                */
-
-void RFCNB_Get_Error(char *buffer, int buf_len)
-
+void
+RFCNB_Get_Error(char *buffer, int buf_len)
 {
 
     if (RFCNB_saved_errno <= 0) {
-        snprintf(buffer, (buf_len-1) ,"%s", RFCNB_Error_Strings[RFCNB_errno]);
+        snprintf(buffer, (buf_len - 1), "%s", RFCNB_Error_Strings[RFCNB_errno]);
     } else {
-        snprintf(buffer, (buf_len-1), "%s\n\terrno:%s", RFCNB_Error_Strings[RFCNB_errno],
+        snprintf(buffer, (buf_len - 1), "%s\n\terrno:%s", RFCNB_Error_Strings[RFCNB_errno],
                  strerror(RFCNB_saved_errno));
     }
-
 }
 
 /* Pick up the last error response and returns as a code                 */
-
-int RFCNB_Get_Last_Error()
-
-{
-
-    return(RFCNB_errno);
-
-}
-
-/* Pick up saved errno as well */
-
-int RFCNB_Get_Last_Errno()
-
+int
+RFCNB_Get_Last_Error()
 {
-
-    return(RFCNB_saved_errno);
-
-}
-
-/* Pick up the last error response and return in string ...             */
-
-int RFCNB_Get_Error_Msg(int code, char *msg_buf, int len)
-
-{
-
-    return (strncpy(msg_buf, RFCNB_Error_Strings[abs(code)], len) != NULL);
-
-}
-
-/* Register a higher level protocol print routine */
-
-void RFCNB_Register_Print_Routine(void (*fn)())
-
-{
-
-    Prot_Print_Routine = fn;
-
+    return (RFCNB_errno);
 }
index e52bd40874d3630b9b30d0160b9628f72f4de6c9..0ae24dee5bff953338d31308b4f1cc1599560a0f 100644 (file)
@@ -1,28 +1,28 @@
 /* RFCNB Standard includes ... */
 /*
-
  RFCNB Standard Includes
-
  Copyright (C) 1996, Richard Sharpe
-*/
+ *
* RFCNB Standard Includes
+ *
* Copyright (C) 1996, Richard Sharpe
+ */
 
 /* One day we will conditionalize these on OS types ... */
 
 /*
  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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 #ifndef _RFCNB_STD_INCLUDES_H
 #define _RFCNB_STD_INCLUDES_H
 
index 1be0241b72281891e7865edbef086c548c5fc453..9afce50b547e097d223412ebec2b3bc202e87fbd 100644 (file)
@@ -38,7 +38,6 @@
 
 #include "smblib/smblib-priv.h"
 #define uchar unsigned char
-extern int DEBUGLEVEL;
 
 #include "rfcnb/byteorder.h"
 
index affee554f268ba50cc77f333091ffe892eb112c5..b556be0b38dd3531bd356f03e42f0cf6e9fd70e0 100644 (file)
@@ -48,11 +48,13 @@ int SMB_Types[] = {SMB_P_Core,
                    -1
                   };
 
+#if UNDEFINED
 char *SMB_DOSTimToStr(int DOS_time);
 char *SMB_AtrToStr(int attribs, BOOL verbose);
 int SMB_Get_Tree_MBS(SMB_Tree_Handle tree);
 int SMB_Get_Max_Buf_Siz(SMB_Handle_Type Con_Handle);
 int SMB_Get_Protocol_IDX(SMB_Handle_Type Con_Handle);
+#endif /* UNDEFINED */
 int SMB_Get_Protocol(SMB_Handle_Type Con_Handle);
 int SMB_Figure_Protocol(const char *dialects[], int prot_index);
 int SMB_TreeDisconnect(SMB_Tree_Handle Tree_Handle, BOOL discard);
@@ -80,6 +82,7 @@ void SMB_Print_Pkt(FILE fd, RFCNB_Pkt *pkt, BOOL command, int Offset, int Len)
 
 /* Convert a DOS Date_Time to a local host type date time for printing */
 
+#if UNDEFINED
 char *SMB_DOSTimToStr(int DOS_time)
 
 {
@@ -172,6 +175,7 @@ int SMB_Get_Protocol_IDX(SMB_Handle_Type Con_Handle)
     }
 
 }
+#endif /* UNDEFINED */
 
 /* Pick up the protocol from the connection structure                       */
 
index 2364cebd40c3629db92bb2d2536ed3f8388d7ecf..45ff27a88d1f519bc0d5d4c441c1a2c6e24dcbd3 100644 (file)
@@ -55,8 +55,6 @@ const char *SMB_Prots[] = {"PC NETWORK PROGRAM 1.0",
                            NULL
                           };
 
-int SMB_Term(void);
-int SMBlib_Set_Sock_NoDelay(SMB_Handle_Type Con_Handle, BOOL yn);
 
 /* Initialize the SMBlib package     */
 
@@ -79,20 +77,6 @@ int SMB_Init()
 
 }
 
-int SMB_Term()
-
-{
-
-#ifdef SMBLIB_INSTRUMENT
-
-    SMBlib_Instrument_Term();       /* Clean up and print results */
-
-#endif
-
-    return 0;
-
-}
-
 /* SMB_Create: Create a connection structure and return for later use */
 /* We have other helper routines to set variables                     */
 
@@ -105,24 +89,6 @@ SMB_Handle_Type SMB_Create_Con_Handle()
 
 }
 
-int SMBlib_Set_Sock_NoDelay(SMB_Handle_Type Con_Handle, BOOL yn)
-
-{
-
-
-    if (RFCNB_Set_Sock_NoDelay(Con_Handle -> Trans_Connect, yn) < 0) {
-
-#ifdef DEBUG
-#endif
-
-        fprintf(stderr, "Setting no-delay on TCP socket failed ...\n");
-
-    }
-
-    return(0);
-
-}
-
 /* SMB_Connect_Server: Connect to a server, but don't negotiate protocol */
 /* or anything else ...                                                  */
 
index d1e8c3df70574b46914e2a895ea54deef7d1319b..9ddb8ee29757c767bc427e3165c92822bf291940 100755 (executable)
@@ -53,7 +53,7 @@ if [ ${name} != ${PACKAGE}-${VERSION} ]; then
        exit 1
 fi
 RELEASE=`echo $VERSION | cut -d. -f1,2 | cut -d- -f1`
-ed -s configure.in <<EOS
+ed -s configure.ac <<EOS
 g/${VERSION}-BZR/ s//${VERSION}/
 w
 EOS
index 89b38d80d8912d593f170a6230f1859d63ece8dc..82543621592554009fd31ee555c34c0d8ac30b55 100755 (executable)
@@ -25,7 +25,7 @@ trap "echo FAIL-BUILD_${VERSION} ; rm -rf ${tmpdir}" 0
 
 rm -f ${tag}.out
 bzr export ${tmpdir} ${BZRROOT}/${module}/${branchpath} || exit 1
-if [ ! -f ${tmpdir}/configure ] && [ -f ${tmpdir}/configure.in ]; then
+if [ ! -f ${tmpdir}/configure ] && [ -f ${tmpdir}/configure.ac ]; then
        sh -c "cd ${tmpdir} && ./bootstrap.sh"
 fi
 if [ ! -f ${tmpdir}/configure ]; then
@@ -35,7 +35,7 @@ fi
 cd ${tmpdir}
 eval `grep "^ *PACKAGE_VERSION=" configure | sed -e 's/-BZR//' | sed -e 's/PACKAGE_//'`
 eval `grep "^ *PACKAGE_TARNAME=" configure | sed -e 's/_TARNAME//'`
-ed -s configure.in <<EOS
+ed -s configure.ac <<EOS
 g/${VERSION}-[A-Z]*/ s//${VERSION}-${date}/
 w
 EOS
index 65c3d496ba1598ca9806a75c6deaca7fe06fc2ba..fea3842ce52b49561861cced18ee8c8b9467280d 100755 (executable)
@@ -114,6 +114,20 @@ for FILENAME in `ls -1`; do
 done
 }
 
+# Build XPROF types file from current sources
+echo "#ifndef _PROFILER_XPROF_TYPE_H_" >${ROOT}/lib/profiler/list
+echo "#define _PROFILER_XPROF_TYPE_H_" >>${ROOT}/lib/profiler/list
+echo "/* AUTO-GENERATED FILE */" >>${ROOT}/lib/profiler/list
+echo "#if USE_XPROF_STATS" >>${ROOT}/lib/profiler/list
+echo "typedef enum {" >>${ROOT}/lib/profiler/list
+echo "XPROF_PROF_UNACCOUNTED," >>${ROOT}/lib/profiler/list
+grep -R -h "PROF_start.*" ./* | grep -v probename | sed -e 's/ //g; s/PROF_start(/XPROF_/; s/);/,/' | sort -u >>${ROOT}/lib/profiler/list
+echo "  XPROF_LAST } xprof_type;" >>${ROOT}/lib/profiler/list
+echo "#endif" >>${ROOT}/lib/profiler/list
+echo "#endif" >>${ROOT}/lib/profiler/list
+mv ${ROOT}/lib/profiler/list ${ROOT}/lib/profiler/xprof_type.h
+
+# Run formating
 echo "" >${ROOT}/doc/debug-sections.tmp
 srcformat || exit 1
 sort -u <${ROOT}/doc/debug-sections.tmp | sort -n >${ROOT}/doc/debug-sections.txt
index 44f23d3371bffb727ab168c2ee1ad4161a15db32..075ab0ec24e7ab539ff88b8aa9f86aa281da6d6d 100755 (executable)
@@ -202,13 +202,14 @@ my ($name, $data);
 my (@chained);
 
 my $in_options = 0;
-sub start_option($)
+sub start_option($$)
 {
-    my ($name) = @_;
+    my ($name, $type) = @_;
     if (!$in_options) {
        print $index "<ul>\n";
        $in_options = 1;
     }
+    return if $type eq "obsolete";
     print $index '    <li><a href="' . htmlescape(section_link($name)) . '" name="toc_' . htmlescape($name) . '">' . htmlescape($name) . "</a></li>\n";
 }
 sub end_options()
@@ -241,12 +242,12 @@ while (<>) {
                $data->{'name'} = $name;
                $data->{'aliases'} = \@aliases;
 
-               start_option($name);
                print "DEBUG: new option: $name\n" if $verbose;
        } elsif ($_ =~ /^COMMENT: (.*)$/) {
                $data->{"comment"} = $1;
        } elsif ($_ =~ /^TYPE: (.*)$/) {
                $data->{"type"} = $1;
+               start_option($data->{"name"}, $data->{"type"});
        } elsif ($_ =~ /^DEFAULT: (.*)$/) {
                if ($1 eq "none") {
                    $data->{"default"} = "$1";
index 027d617b197606b78a7ddaf50631052a5df4b160..391e10464a425b3879f0c11e4b5bd2d215c93b82 100644 (file)
@@ -4,8 +4,8 @@
 ## 
 AM_CFLAGS = $(SQUID_CFLAGS)
 AM_CXXFLAGS = $(SQUID_CXXFLAGS)
-noinst_LIBRARIES = libsnmp.a
-libsnmp_a_SOURCES  = asn1.c parse.c snmp_vars.c \
+noinst_LIBRARIES = libsnmplib.a
+libsnmplib_a_SOURCES  = asn1.c parse.c snmp_vars.c \
        coexistance.c snmp_api.c snmp_error.c  \
        mib.c snmp_api_error.c   \
        snmp_msg.c \
index b2ccfde3dc78838cda6cca03951f515421d7b629..46b154ac5a135da4ad3c8076d71dbc965556795e 100644 (file)
@@ -409,7 +409,7 @@ asn_parse_string(u_char * data, int *datalength,
         snmp_set_api_error(SNMPERR_ASN_DECODE);
         return (NULL);
     }
-    xmemcpy((char *) string, (char *) bufp, (int) asn_length);
+    memcpy((char *) string, (char *) bufp, (int) asn_length);
     *strlength = (int) asn_length;
     *datalength -= (int) asn_length + (bufp - data);
     return (bufp + asn_length);
@@ -448,7 +448,7 @@ asn_build_string(u_char * data, int *datalength,
         snmp_set_api_error(SNMPERR_ASN_DECODE);
         return (NULL);
     }
-    xmemcpy((char *) data, (char *) string, strlength);
+    memcpy((char *) data, (char *) string, strlength);
     *datalength -= strlength;
     return (data + strlength);
 }
@@ -587,7 +587,7 @@ asn_parse_length(u_char * data, u_int * length)
             return (NULL);
         }
         *length = (u_int) 0;
-        xmemcpy((char *) (length), (char *) data + 1, (int) lengthbyte);
+        memcpy((char *) (length), (char *) data + 1, (int) lengthbyte);
         *length = ntohl(*length);
         *length >>= (8 * ((sizeof *length) - lengthbyte));
         return (data + lengthbyte + 1);
@@ -818,7 +818,7 @@ asn_build_objid(u_char * data, int *datalength,
         snmp_set_api_error(SNMPERR_ASN_DECODE);
         return (NULL);
     }
-    xmemcpy((char *) data, (char *) buf, asnlength);
+    memcpy((char *) data, (char *) buf, asnlength);
     *datalength -= asnlength;
     return (data + asnlength);
 }
@@ -932,7 +932,7 @@ asn_parse_bitstring(u_char * data, int *datalength,
         snmp_set_api_error(SNMPERR_ASN_DECODE);
         return (NULL);
     }
-    xmemcpy((char *) string, (char *) bufp, (int) asn_length);
+    memcpy((char *) string, (char *) bufp, (int) asn_length);
     *strlength = (int) asn_length;
     *datalength -= (int) asn_length + (bufp - data);
     return (bufp + asn_length);
@@ -973,7 +973,7 @@ asn_build_bitstring(u_char * data, int *datalength,
         snmp_set_api_error(SNMPERR_ASN_ENCODE);
         return (NULL);
     }
-    xmemcpy((char *) data, (char *) string, strlength);
+    memcpy((char *) data, (char *) string, strlength);
     *datalength -= strlength;
     return (data + strlength);
 }
index 418e4969c2183cfd8945f684dddb3b1d80e7d777..0acbf7eab2af07d424304b4b127c455eb8b7efd1 100644 (file)
@@ -150,7 +150,7 @@ snmp_pdu_clone(struct snmp_pdu *Src) {
         snmp_set_api_error(SNMPERR_OS_ERR);
         return (NULL);
     }
-    xmemcpy((char *) Dest, (char *) Src, sizeof(struct snmp_pdu));
+    memcpy((char *) Dest, (char *) Src, sizeof(struct snmp_pdu));
 
 #if DEBUG_PDU
     snmplib_debug(8, "PDU %x:  Created %x\n", (unsigned int) Src, (unsigned int) Dest);
@@ -518,8 +518,8 @@ snmp_pdu_decode(u_char * Packet,    /* data */
             snmp_set_api_error(SNMPERR_OS_ERR);
             return (NULL);
         }
-        xmemcpy((char *) PDU->enterprise, (char *) objid,
-                PDU->enterprise_length * sizeof(oid));
+        memcpy((char *) PDU->enterprise, (char *) objid,
+               PDU->enterprise_length * sizeof(oid));
 
         /* Agent-addr */
         four = 4;
index 09d5680051823e6e862d26673e40c0803e411c3b..f438d0348cb05d3ad4494a575b2b0f4b68a76f35 100644 (file)
@@ -141,7 +141,7 @@ snmp_var_new(oid * Name, int Len) {
 
     /* Only copy a name if it was specified. */
     if (Name)
-        xmemcpy((char *) New->name, (char *) Name, Len * sizeof(oid));
+        memcpy((char *) New->name, (char *) Name, Len * sizeof(oid));
 
     return (New);
 }
@@ -179,7 +179,7 @@ snmp_var_clone(struct variable_list *Src) {
            sizeof(struct variable_list));
 #endif
 
-    xmemcpy((char *) Dest, (char *) Src, sizeof(struct variable_list));
+    memcpy((char *) Dest, (char *) Src, sizeof(struct variable_list));
 
     if (Src->name != NULL) {
         Dest->name = (oid *) xmalloc(Src->name_length * sizeof(oid));
@@ -191,8 +191,8 @@ snmp_var_clone(struct variable_list *Src) {
 #if DEBUG_VARS
         printf("VARS: Copying name OID. (Size %d)\n", Src->name_length);
 #endif
-        xmemcpy((char *) Dest->name, (char *) Src->name,
-                Src->name_length * sizeof(oid));
+        memcpy((char *) Dest->name, (char *) Src->name,
+               Src->name_length * sizeof(oid));
     }
     /* CISCO Catalyst 2900 returns NULL strings as data of length 0. */
     if ((Src->val.string != NULL) &&
@@ -207,7 +207,7 @@ snmp_var_clone(struct variable_list *Src) {
 #if DEBUG_VARS
         printf("VARS: Copying value (Size %d)\n", Src->val_len);
 #endif
-        xmemcpy((char *) Dest->val.string, (char *) Src->val.string, Src->val_len);
+        memcpy((char *) Dest->val.string, (char *) Src->val.string, Src->val_len);
     }
 #if DEBUG_VARS
     printf("VARS: Cloned %x.\n", (unsigned int) Dest);
@@ -530,7 +530,7 @@ snmp_var_DecodeVarBind(u_char * Buffer, int *BufLen,
             }
             /* Only copy if we successfully decoded something */
             if (bufp) {
-                xmemcpy((char *) Var->val.objid, (char *) TmpBuf, Var->val_len);
+                memcpy((char *) Var->val.objid, (char *) TmpBuf, Var->val_len);
             }
 #if DEBUG_VARS_DECODE
             printf("VARS: Decoded OBJID (length %d) (%d bytes left)\n",
index 6f0988abbac90fcdd4850c27aac87a661a2504c4..0830c480f68f5beebae52a620333dbef84c4ecdd 100644 (file)
@@ -102,7 +102,7 @@ cacheDigestClone(const CacheDigest * cd)
     clone->count = cd->count;
     clone->del_count = cd->del_count;
     assert(cd->mask_size == clone->mask_size);
-    xmemcpy(clone->mask, cd->mask, cd->mask_size);
+    memcpy(clone->mask, cd->mask, cd->mask_size);
     return clone;
 }
 
@@ -328,7 +328,7 @@ cacheDigestHashKey(const CacheDigest * cd, const cache_key * key)
     const unsigned int bit_count = cd->mask_size * 8;
     unsigned int tmp_keys[4];
     /* we must memcpy to ensure alignment */
-    xmemcpy(tmp_keys, key, sizeof(tmp_keys));
+    memcpy(tmp_keys, key, sizeof(tmp_keys));
     hashed_keys[0] = htonl(tmp_keys[0]) % bit_count;
     hashed_keys[1] = htonl(tmp_keys[1]) % bit_count;
     hashed_keys[2] = htonl(tmp_keys[2]) % bit_count;
index 84e4a72875a308653fa7c64675a410dd470306ad..945c2d0ca34487fbe7dd8295f72e7edd0cc5eca4 100644 (file)
@@ -176,6 +176,7 @@ class CommAcceptCbPtrFun: public CallDialer,
 {
 public:
     typedef CommAcceptCbParams Params;
+    typedef RefCount<CommAcceptCbPtrFun> Pointer;
 
     CommAcceptCbPtrFun(IOACB *aHandler, const CommAcceptCbParams &aParams);
     void dial();
@@ -259,11 +260,18 @@ template <class Dialer>
 class CommCbFunPtrCallT: public AsyncCall
 {
 public:
+    typedef RefCount<CommCbFunPtrCallT<Dialer> > Pointer;
     typedef typename Dialer::Params Params;
 
     inline CommCbFunPtrCallT(int debugSection, int debugLevel,
                              const char *callName, const Dialer &aDialer);
 
+    inline CommCbFunPtrCallT(const CommCbFunPtrCallT &o) :
+            AsyncCall(o.debugSection, o.debugLevel, o.name),
+            dialer(o.dialer) {}
+
+    ~CommCbFunPtrCallT() {}
+
     virtual CallDialer* getDialer() { return &dialer; }
 
 public:
@@ -272,6 +280,9 @@ public:
 protected:
     inline virtual bool canFire();
     inline virtual void fire();
+
+private:
+    CommCbFunPtrCallT & operator=(const CommCbFunPtrCallT &); // not defined. not permitted.
 };
 
 // Conveninece wrapper: It is often easier to call a templated function than
index 786350f4a21a358b195970721914615d534158d8..227b1502db43c3de076a9c1ced6650e4e660e619 100644 (file)
@@ -47,7 +47,7 @@ public:
     virtual ~ConfigOption() {}
 
     virtual bool parse(char const *option, const char *value, int reconfiguring) = 0;
-    virtual void dump (StoreEntry * e) const = 0;
+    virtual void dump(StoreEntry * e) const = 0;
 };
 
 class ConfigOptionVector : public ConfigOption
@@ -65,7 +65,7 @@ class ConfigOptionAdapter : public ConfigOption
 {
 
 public:
-    ConfigOptionAdapter(C& theObject, bool (C::*parseFP)(char const *option, const char *value, int reconfiguring), void (C::*dumpFP) (StoreEntry * e) const) : object(theObject), parser (parseFP), dumper(dumpFP) {}
+    ConfigOptionAdapter(C& theObject, bool (C::*parseFP)(char const *option, const char *value, int reconfiguring), void (C::*dumpFP)(StoreEntry * e) const) : object(theObject), parser(parseFP), dumper(dumpFP) {}
 
     bool parse(char const *option, const char *value, int isaReconf) {
         if (parser)
@@ -76,12 +76,12 @@ public:
 
     void dump(StoreEntry * e) const {
         if (dumper)
-            (object.*dumper) (e);
+            (object.*dumper)(e);
     }
 
 private:
     C &object;
-    bool (C::*parser) (char const *option, const char *value, int reconfiguring) ;
+    bool (C::*parser)(char const *option, const char *value, int reconfiguring) ;
     void (C::*dumper)(StoreEntry * e) const;
 };
 
index 9a7511af5d7982b1456c6cb4e6ae0143133ca532..45084b4edd64de4cf7f578f5ada2f17d2e4570dc 100644 (file)
@@ -75,9 +75,8 @@ ConfigParser::strtokFile(void)
                     return (NULL);
                 }
 
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
                 setmode(fileno(wordFile), O_TEXT);
-
 #endif
 
                 fromFile = 1;
index dded9f8f4945095b6cfd12a726489006c5c556ff..80e1406357951e986f31d5340db6ad989415b0c8 100644 (file)
@@ -38,7 +38,7 @@ CpuAffinitySet::apply()
                "this process: " << xstrerror());
     } else {
         cpu_set_t cpuSet;
-        xmemcpy(&cpuSet, &theCpuSet, sizeof(cpuSet));
+        memcpy(&cpuSet, &theCpuSet, sizeof(cpuSet));
         CPU_AND(&cpuSet, &cpuSet, &theOrigCpuSet);
         if (CPU_COUNT(&cpuSet) <= 0) {
             debugs(54, DBG_IMPORTANT, "ERROR: invalid CPU affinity for process "
@@ -76,5 +76,5 @@ CpuAffinitySet::applied() const
 void
 CpuAffinitySet::set(const cpu_set_t &aCpuSet)
 {
-    xmemcpy(&theCpuSet, &aCpuSet, sizeof(theCpuSet));
+    memcpy(&theCpuSet, &aCpuSet, sizeof(theCpuSet));
 }
index 6e5b90d4128bef0d579ef6a80f1e9ff5efd8263d..c9f1fce3f01156bfdd355a6cba2f03d028b14a6f 100644 (file)
@@ -100,7 +100,7 @@ private:
 
 extern FILE *debug_log;
 
-const size_t BuildPrefixInit();
+size_t BuildPrefixInit();
 const char * SkipBuildPrefix(const char* path);
 
 /* Debug stream */
index 3ed4d48eb027e3758f59c4cff5a6e506120658a9..99be575f2877186d5e06d04429c18c848899273d 100644 (file)
@@ -86,7 +86,7 @@ void
 AIODiskFile::open(int flags, mode_t mode, RefCount<IORequestor> callback)
 {
     /* Simulate async calls */
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
     fd = aio_open(path.termedBuf(), flags);
 #else
     fd = file_open(path.termedBuf() , flags);
@@ -232,11 +232,9 @@ void
 AIODiskFile::close ()
 {
     assert (!closed);
-#ifdef _SQUID_WIN32_
-
+#if _SQUID_WINDOWS_
     aio_close(fd);
 #else
-
     file_close(fd);
 #endif
 
index afcfdae440c5c99660e1c9ca9ed8e37c652a1e39..6f31515bef5af8c18b977b330017cb183232c575 100644 (file)
@@ -37,7 +37,7 @@
 #include "comm.h"
 #include "aio_win32.h"
 
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
 VOID CALLBACK IoCompletionRoutine(DWORD dwErrorCode,
                                   DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
 {
@@ -351,4 +351,4 @@ ssize_t aio_return64(struct aiocb64 * aiocbp)
 {
     return aiocbp->aio_sigevent.sigev_signo;
 }
-#endif /* _SQUID_WIN32_ */
+#endif /* _SQUID_WINDOWS_ */
index 28f5df80be946e270ef1cc8416b2989d30f6ce2c..cea94bacfae20dae8a088038bf6f3e171c0fed3b 100644 (file)
@@ -36,7 +36,7 @@
 
 #if USE_DISKIO_AIO
 
-#ifdef _SQUID_CYGWIN_
+#if _SQUID_CYGWIN_
 #include "squid_windows.h"
 #endif
 
index 94626a1fdf637662fd985f40a2454bc7c95a7e40..9eefc0891d4bc77b11a9353a7039d80b5ab41acf 100644 (file)
@@ -3,7 +3,7 @@
 
 #if USE_DISKIO_AIO
 
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
 #include "aio_win32.h"
 #else
 #if HAVE_AIO_H
index 398431b991f7c48f70ff66722669c955005ba9be..10e6c52137cb706f736a004139966477390a6666 100644 (file)
@@ -312,7 +312,7 @@ DiskdFile::write(WriteRequest *aRequest)
     debugs(79, 3, "DiskdFile::write: this " << (void *)this << ", buf " << (void *)aRequest->buf << ", off " << aRequest->offset << ", len " << aRequest->len);
     ssize_t shm_offset;
     char *sbuf = (char *)IO->shm.get(&shm_offset);
-    xmemcpy(sbuf, aRequest->buf, aRequest->len);
+    memcpy(sbuf, aRequest->buf, aRequest->len);
 
     if (aRequest->free_func)
         aRequest->free_func(const_cast<char *>(aRequest->buf));
index f143bd827794b93c9936ce4efae1b556b4d63343..6d054e3056c9a21876538dd5168fd091566e6352 100644 (file)
@@ -34,6 +34,7 @@
  */
 
 #include "squid.h"
+#include "comm/Loops.h"
 
 #include <sys/ipc.h>
 #include <sys/msg.h>
@@ -203,10 +204,8 @@ DiskdIOStrategy::init()
     fd_note(wfd, "squid -> diskd");
 
     commSetTimeout(wfd, -1, NULL, NULL);
-
     commSetNonBlocking(wfd);
-
-    comm_quick_poll_required();
+    Comm::QuickPollRequired();
 }
 
 /*
index d3e39ac71fed90ec068be00a51445b01b0519fdd..17846a390956b4e0e202fdf39a80de1ab2859c77 100644 (file)
@@ -88,15 +88,16 @@ do_open(diomsg * r, int len, const char *buf)
 
     fs = (file_state *)xcalloc(1, sizeof(*fs));
     fs->id = r->id;
-    fs->key = &fs->id;         /* gack */
+    fs->key = &fs->id;          /* gack */
     fs->fd = fd;
     hash_join(hash, (hash_link *) fs);
-    DEBUG(2)
-    fprintf(stderr, "%d OPEN  id %d, FD %d, fs %p\n",
-            (int) mypid,
-            fs->id,
-            fs->fd,
-            fs);
+    DEBUG(2) {
+        fprintf(stderr, "%d OPEN  id %d, FD %d, fs %p\n",
+                (int) mypid,
+                fs->id,
+                fs->fd,
+                fs);
+    }
     return fd;
 }
 
@@ -119,12 +120,13 @@ do_close(diomsg * r, int len)
 
     fd = fs->fd;
     hash_remove_link(hash, (hash_link *) fs);
-    DEBUG(2)
-    fprintf(stderr, "%d CLOSE id %d, FD %d, fs %p\n",
-            (int) mypid,
-            r->id,
-            fs->fd,
-            fs);
+    DEBUG(2) {
+        fprintf(stderr, "%d CLOSE id %d, FD %d, fs %p\n",
+                (int) mypid,
+                r->id,
+                fs->fd,
+                fs);
+    }
     xfree(fs);
     return close(fd);
 }
@@ -148,8 +150,9 @@ do_read(diomsg * r, int len, char *buf)
     }
 
     if (r->offset > -1 && r->offset != fs->offset) {
-        DEBUG(2)
-        fprintf(stderr, "seeking to %"PRId64"\n", (int64_t)r->offset);
+        DEBUG(2) {
+            fprintf(stderr, "seeking to %"PRId64"\n", (int64_t)r->offset);
+        }
 
         if (lseek(fs->fd, r->offset, SEEK_SET) < 0) {
             DEBUG(1) {
@@ -160,9 +163,10 @@ do_read(diomsg * r, int len, char *buf)
     }
 
     x = read(fs->fd, buf, readlen);
-    DEBUG(2)
-    fprintf(stderr, "%d READ %d,%d,%"PRId64" ret %d\n", (int) mypid,
-            fs->fd, readlen, (int64_t)r->offset, x);
+    DEBUG(2) {
+        fprintf(stderr, "%d READ %d,%d,%"PRId64" ret %d\n", (int) mypid,
+                fs->fd, readlen, (int64_t)r->offset, x);
+    }
 
     if (x < 0) {
         DEBUG(1) {
@@ -204,9 +208,10 @@ do_write(diomsg * r, int len, const char *buf)
         }
     }
 
-    DEBUG(2)
-    fprintf(stderr, "%d WRITE %d,%d,%"PRId64"\n", (int) mypid,
-            fs->fd, wrtlen, (int64_t)r->offset);
+    DEBUG(2) {
+        fprintf(stderr, "%d WRITE %d,%d,%"PRId64"\n", (int) mypid,
+                fs->fd, wrtlen, (int64_t)r->offset);
+    }
     x = write(fs->fd, buf, wrtlen);
 
     if (x < 0) {
@@ -234,8 +239,9 @@ do_unlink(diomsg * r, int len, const char *buf)
         return -errno;
     }
 
-    DEBUG(2)
-    fprintf(stderr, "%d UNLNK %s\n", (int) mypid, buf);
+    DEBUG(2) {
+        fprintf(stderr, "%d UNLNK %s\n", (int) mypid, buf);
+    }
     return 0;
 }
 
@@ -245,11 +251,11 @@ msg_handle(diomsg * r, int rl, diomsg * s)
     char *buf = NULL;
     s->mtype = r->mtype;
     s->id = r->id;
-    s->seq_no = r->seq_no;     /* optional, debugging */
+    s->seq_no = r->seq_no;      /* optional, debugging */
     s->callback_data = r->callback_data;
     s->requestor = r->requestor;
-    s->size = 0;               /* optional, debugging */
-    s->offset = 0;             /* optional, debugging */
+    s->size = 0;                /* optional, debugging */
+    s->offset = 0;              /* optional, debugging */
     s->shm_offset = r->shm_offset;
     s->newstyle = r->newstyle;
 
@@ -368,10 +374,11 @@ main(int argc, char *argv[])
     for (;;) {
         alarm(1);
         memset(&rmsg, '\0', sizeof(rmsg));
-        DEBUG(2)
-        std::cerr << "msgrcv: " << rmsgid << ", "
-                  << &rmsg << ", " << diomsg::msg_snd_rcv_sz
-                  << ", " << 0 << ", " << 0 << std::endl;
+        DEBUG(2) {
+            std::cerr << "msgrcv: " << rmsgid << ", "
+                      << &rmsg << ", " << diomsg::msg_snd_rcv_sz
+                      << ", " << 0 << ", " << 0 << std::endl;
+        }
         rlen = msgrcv(rmsgid, &rmsg, diomsg::msg_snd_rcv_sz, 0, 0);
 
         if (rlen < 0) {
@@ -403,8 +410,9 @@ main(int argc, char *argv[])
         }
     }
 
-    DEBUG(2)
-    fprintf(stderr, "%d diskd exiting\n", (int) mypid);
+    DEBUG(2) {
+        fprintf(stderr, "%d diskd exiting\n", (int) mypid);
+    }
 
     if (msgctl(rmsgid, IPC_RMID, 0) < 0)
         perror("msgctl IPC_RMID");
index dadcfed3ed5096a7006f2fd937dc365bc93b8dfa..38a54a0bf2ac03303ffb6af4cab696cf058a869f 100644 (file)
@@ -587,8 +587,7 @@ squidaio_cleanup_request(squidaio_request_t * requestp)
     case _AIO_OP_STAT:
 
         if (!cancelled && requestp->ret == 0)
-
-            xmemcpy(requestp->statp, requestp->tmpstatp, sizeof(struct stat));
+            memcpy(requestp->statp, requestp->tmpstatp, sizeof(struct stat));
 
         squidaio_xfree(requestp->tmpstatp, sizeof(struct stat));
 
index 0440a92a7a48747646e84f3e0dabdef34384181d..7fcb2526ae53620fc2cf5d3d7d10c90c415889ed 100644 (file)
@@ -672,8 +672,7 @@ squidaio_cleanup_request(squidaio_request_t * requestp)
     case _AIO_OP_STAT:
 
         if (!cancelled && requestp->ret == 0)
-
-            xmemcpy(requestp->statp, requestp->tmpstatp, sizeof(struct stat));
+            memcpy(requestp->statp, requestp->tmpstatp, sizeof(struct stat));
 
         squidaio_xfree(requestp->tmpstatp, sizeof(struct stat));
 
index 09dd5a167e2333bf02823ad243807e9c6b2d48ed..69f0b3b640c05c5aae1e66b35cc06dd8131a0c1b 100644 (file)
@@ -23,7 +23,7 @@ HelperChildConfig::operator =(const HelperChildConfig &rhs)
     return *this;
 }
 
-const int
+int
 HelperChildConfig::needNew() const
 {
     /* during the startup and reconfigure use our special amount... */
index 07af956db88a4a063abdba90a8fb0623132dcf66..06c507fd93c3782428f3cdff3e9819ed6b17a247 100644 (file)
@@ -21,7 +21,7 @@ public:
      * \retval N < 0   Error. No more helpers may be started.
      * \retval N       N more helpers may be started immediately.
      */
-    const int needNew() const;
+    int needNew() const;
     void parseConfig();
 
     /* values from squid.conf */
index 502ba8e864320ef7341fa36cfa0e1e5f5a521725..3214313148a90bd0ae97f73266451c161cb178af 100644 (file)
@@ -51,6 +51,7 @@ static const HttpHeaderFieldAttrs CcAttrs[CC_ENUM_END] = {
     {"max-age", (http_hdr_type)CC_MAX_AGE},
     {"s-maxage", (http_hdr_type)CC_S_MAXAGE},
     {"max-stale", (http_hdr_type)CC_MAX_STALE},
+    {"stale-if-error", (http_hdr_type)CC_STALE_IF_ERROR},
     {"min-fresh", (http_hdr_type)CC_MIN_FRESH},
     {"Other,", (http_hdr_type)CC_OTHER}        /* ',' will protect from matches */
 };
@@ -192,6 +193,14 @@ httpHdrCcParseInit(HttpHdrCc * cc, const String * str)
 
             break;
 
+        case CC_STALE_IF_ERROR:
+            if (!p || !httpHeaderParseInt(p, &cc->stale_if_error)) {
+                debugs(65, 2, "cc: invalid stale-if-error specs near '" << item << "'");
+                cc->stale_if_error = -1;
+                EBIT_CLR(cc->mask, type);
+            }
+            break;
+
         case CC_OTHER:
 
             if (cc->other.size())
index 057ac4af362f2de82b83cc6e6f1d0c5dc3fe6738..3c5ab7da7ab224e9b84563c3c545be2303f3ffd4 100644 (file)
@@ -1186,7 +1186,7 @@ HttpHeader::putSc(HttpHdrSc *sc)
     Packer p;
     assert(sc);
     /* remove old directives if any */
-    delById(HDR_RANGE);
+    delById(HDR_SURROGATE_CONTROL);
     /* pack into mb */
     mb.init();
     packerToMemInit(&p, &mb);
index 6c377493817d8503ded8fcb20af5d34622a315ec..e9b79d880160a458c78e17271a5fd5897aa27ad8 100644 (file)
@@ -48,7 +48,7 @@ class HttpHdrRangeSpec
 
 public:
     MEMPROXY_CLASS(HttpHdrRangeSpec);
-    typedef Range<int64_t> HttpRange;
+    typedef Range<int64_t, uint64_t> HttpRange;
     static int64_t const UnknownPosition;
 
     HttpHdrRangeSpec();
index c2ed19009b0e6e39450d9d745965530f1ec2d7e5..276ca59acffb66b9067c253ece0483a0276c459d 100644 (file)
@@ -326,21 +326,6 @@ HttpMsg::persistent() const
          */
         return !httpHeaderHasConnDir(&header, "close");
     } else {
-        /*
-         * Persistent connections in Netscape 3.x are allegedly broken,
-         * return false if it is a browser connection.  If there is a
-         * VIA header, then we assume this is NOT a browser connection.
-         */
-        const char *agent = header.getStr(HDR_USER_AGENT);
-
-        if (agent && !header.has(HDR_VIA)) {
-            if (!strncasecmp(agent, "Mozilla/3.", 10))
-                return 0;
-
-            if (!strncasecmp(agent, "Netscape/3.", 11))
-                return 0;
-        }
-
         /* for old versions of HTTP: persistent if has "keep-alive" */
         return httpHeaderHasConnDir(&header, "keep-alive");
     }
index feefc7cd85349b8a3cf47d6d6ef8b1fcede754fe..5430a979de5b2da92ef07675036020efee039192 100644 (file)
@@ -502,7 +502,7 @@ void HttpRequest::packFirstLineInto(Packer * p, bool full_uri) const
 }
 
 /*
- * Indicate whether or not we would usually expect an entity-body
+ * Indicate whether or not we would expect an entity-body
  * along with this request
  */
 bool
@@ -511,28 +511,18 @@ HttpRequest::expectingBody(const HttpRequestMethod& unused, int64_t& theSize) co
     bool expectBody = false;
 
     /*
-     * GET and HEAD don't usually have bodies, but we should be prepared
-     * to accept one if the request_entities directive is set
+     * Note: Checks for message validity is in clientIsContentLengthValid().
+     * this just checks if a entity-body is expected based on HTTP message syntax
      */
-
-    if (method == METHOD_GET || method == METHOD_HEAD)
-        expectBody = Config.onoff.request_entities ? true : false;
-    else if (method == METHOD_PUT || method == METHOD_POST)
-        expectBody = true;
-    else if (header.chunked())
+    if (header.chunked()) {
         expectBody = true;
-    else if (content_length >= 0)
+        theSize = -1;
+    } else if (content_length >= 0) {
         expectBody = true;
-    else
+        theSize = content_length;
+    } else {
         expectBody = false;
-
-    if (expectBody) {
-        if (header.chunked())
-            theSize = -1;
-        else if (content_length >= 0)
-            theSize = content_length;
-        else
-            theSize = -1;
+        // theSize undefined
     }
 
     return expectBody;
index 1402f4f106ce5613cbee8f46398e836273770a4d..eb8c697f20c3bcec98df57e2391e13ff007f9739 100644 (file)
@@ -24,15 +24,6 @@ SBUF_SOURCE= \
        MemBlob.h \
        MemBlob.cc
 
-SNMP_ALL_SOURCE = \
-       snmp_core.cc \
-       snmp_agent.cc
-if USE_SNMP
-SNMP_SOURCE = $(SNMP_ALL_SOURCE)
-else
-SNMP_SOURCE = 
-endif
-
 LOADABLE_MODULES_SOURCES = \
        LoadableModule.h \
        LoadableModule.cc \
@@ -50,6 +41,18 @@ else
 SSL_LOCAL_LIBS =
 endif
 
+SNMP_ALL_SOURCE = \
+       snmp_core.h \
+       snmp_core.cc \
+       snmp_agent.cc
+if ENABLE_SNMP
+SNMP_SOURCE = $(SNMP_ALL_SOURCE)
+SUBDIRS += snmp
+SNMP_LIBS = snmp/libsnmp.la $(SNMPLIB)
+else
+SNMP_SOURCE = 
+endif
+
 if USE_ADAPTATION
 SUBDIRS += adaptation
 endif
@@ -236,19 +239,6 @@ DiskIO/DiskIOModules_gen.cc: Makefile
        $(SHELL) $(srcdir)/DiskIO/modules.sh $(DISK_MODULES) > DiskIO/DiskIOModules_gen.cc
 
 
-squid_COMMSOURCES = \
-       comm_select.cc \
-       comm_select.h \
-       comm_select_win32.cc \
-       comm_poll.cc \
-       comm_poll.h \
-       comm_devpoll.cc \
-       comm_epoll.cc \
-       comm_epoll.h \
-       comm_kqueue.cc \
-       comm_kqueue.h
-
-
 # common library for all the binaries and tests. This is kindof a catch all
 # and smaller libraries split from this are encouraged. Using lt convenience
 # libraries, dependencies should not be a problem either.
@@ -295,7 +285,6 @@ squid_SOURCES = \
        CommIO.h \
        CompletionDispatcher.cc \
        CompletionDispatcher.h \
-       $(squid_COMMSOURCES) \
        CommRead.h \
        ConfigOption.cc \
        ConfigParser.cc \
@@ -419,7 +408,6 @@ squid_SOURCES = \
        PingData.h \
        protos.h \
        redirect.cc \
-       referer.cc \
        refresh.cc \
        RemovalPolicy.cc \
        RemovalPolicy.h \
@@ -488,7 +476,6 @@ squid_SOURCES = \
        URLScheme.cc \
        URLScheme.h \
        urn.cc \
-       useragent.cc \
        wccp.cc \
        wccp2.cc \
        whois.cc \
@@ -562,10 +549,10 @@ squid_LDADD = \
        $(DISK_OS_LIBS) \
        $(CRYPTLIB) \
        $(REGEXLIB) \
-       $(SNMPLIB) \
-       ${ADAPTATION_LIBS} \
+       $(ADAPTATION_LIBS) \
        $(ESI_LIBS) \
        $(SSL_LIBS) \
+       $(SNMP_LIBS) \
        $(top_builddir)/lib/libmisccontainers.la \
        $(top_builddir)/lib/libmiscencoding.la \
        $(top_builddir)/lib/libmiscutil.la \
@@ -579,8 +566,7 @@ squid_DEPENDENCIES = \
        $(DISK_LIBS) \
        $(DISK_LINKOBJS) \
        $(REPL_OBJS) \
-       $(SNMPLIB) \
-       ${ADAPTATION_LIBS} \
+       $(ADAPTATION_LIBS) \
        $(ESI_LOCAL_LIBS) \
        $(SSL_LIBS) \
        $(COMMON_LIBS)
@@ -662,7 +648,6 @@ ufsdump_LDADD = \
        $(REPL_OBJS) \
        $(CRYPTLIB) \
        $(REGEXLIB) \
-       $(SNMPLIB) \
        $(SSLLIB) \
        $(COMPAT_LIB) \
        $(EPOLL_LIBS) \
@@ -779,7 +764,7 @@ DEFAULT_ERROR_DIR   = $(datadir)/errors
 # Make location configure settings available to the code
 DEFS += -DDEFAULT_CONFIG_FILE=\"$(DEFAULT_CONFIG_FILE)\" -DDEFAULT_SQUID_DATA_DIR=\"$(datadir)\" -DDEFAULT_SQUID_CONFIG_DIR=\"$(sysconfdir)\"
 
-snmp_core.o snmp_agent.o: ../snmplib/libsnmp.a $(top_srcdir)/include/cache_snmp.h
+snmp_core.o snmp_agent.o: ../snmplib/libsnmplib.a $(top_srcdir)/include/cache_snmp.h
 
 globals.cc: globals.h mk-globals-c.awk
        $(AWK) -f $(srcdir)/mk-globals-c.awk < $(srcdir)/globals.h > $@ || ($(RM) -f $@ && exit 1)
@@ -832,7 +817,7 @@ cf.data: cf.data.pre Makefile
        sed \
        -e "s%[@]DEFAULT_HTTP_PORT[@]%$(DEFAULT_HTTP_PORT)%g" \
        -e "s%[@]DEFAULT_ICP_PORT[@]%$(DEFAULT_ICP_PORT)%g" \
-       -e "s%[@]DEFAULT_CACHE_EFFECTIVE_USER[@]%${CACHE_EFFECTIVE_USER}%g" \
+       -e "s%[@]DEFAULT_CACHE_EFFECTIVE_USER[@]%$(CACHE_EFFECTIVE_USER)%g" \
        -e "s%[@]DEFAULT_MIME_TABLE[@]%$(DEFAULT_MIME_TABLE)%g" \
        -e "s%[@]DEFAULT_DNSSERVER[@]%$(DEFAULT_DNSSERVER)%g" \
        -e "s%[@]DEFAULT_SSL_CRTD[@]%$(DEFAULT_SSL_CRTD)%g" \
@@ -1113,7 +1098,17 @@ tests_testACLMaxUserIP_SOURCES= \
 nodist_tests_testACLMaxUserIP_SOURCES= \
        $(TESTSOURCES)
 tests_testACLMaxUserIP_LDADD= \
-       $(COMMON_LIBS) \
+       auth/libacls.la \
+       ident/libident.la \
+       acl/libacls.la \
+       eui/libeui.la \
+       acl/libstate.la \
+       auth/libauth.la \
+       acl/libapi.la \
+       base/libbase.la \
+       libsquid.la \
+       ip/libip.la \
+       fs/libfs.la \
        $(top_builddir)/lib/libmisccontainers.la \
        $(top_builddir)/lib/libmiscencoding.la \
        $(top_builddir)/lib/libmiscutil.la \
@@ -1156,6 +1151,7 @@ tests_testCacheManager_SOURCES = \
        tests/testCacheManager.h \
        tests/testMain.cc \
        tests/stub_main_cc.cc \
+       tests/stub_ipc_Forwarder.cc \
        time.cc \
        BodyPipe.cc \
        cache_manager.cc \
@@ -1172,7 +1168,6 @@ tests_testCacheManager_SOURCES = \
        client_side_request.cc \
        ClientInfo.h \
        clientStream.cc \
-       $(squid_COMMSOURCES) \
        ConfigOption.cc \
        ConfigParser.cc \
        CpuAffinityMap.cc \
@@ -1234,7 +1229,6 @@ tests_testCacheManager_SOURCES = \
        peer_sourcehash.cc \
        peer_userhash.cc \
        redirect.cc \
-       referer.cc \
        refresh.cc \
        RemovalPolicy.cc \
        Server.cc \
@@ -1272,7 +1266,6 @@ tests_testCacheManager_SOURCES = \
        url.cc \
        URLScheme.cc \
        urn.cc \
-       useragent.cc \
        wccp2.cc \
        whois.cc \
        FadingCounter.cc \
@@ -1282,19 +1275,31 @@ nodist_tests_testCacheManager_SOURCES = \
        $(BUILT_SOURCES)
 # comm.cc only requires comm/libcomm.la until fdc_table is dead.
 tests_testCacheManager_LDADD = \
-       $(COMMON_LIBS) \
+       auth/libacls.la \
+       ident/libident.la \
+       acl/libacls.la \
+       eui/libeui.la \
+       acl/libstate.la \
+       auth/libauth.la \
+       acl/libapi.la \
+       base/libbase.la \
+       libsquid.la \
+       ip/libip.la \
+       fs/libfs.la \
+       ipc/libipc.la \
+       mgr/libmgr.la \
+       $(SNMP_LIBS) \
        comm/libcomm.la \
        icmp/libicmp.la icmp/libicmp-core.la \
        log/liblog.la \
        $(REPL_OBJS) \
-       ${ADAPTATION_LIBS} \
+       $(ADAPTATION_LIBS) \
        $(ESI_LIBS) \
        $(SSL_LIBS) \
        $(top_builddir)/lib/libmisccontainers.la \
        $(top_builddir)/lib/libmiscencoding.la \
        $(top_builddir)/lib/libmiscutil.la \
        $(REGEXLIB) \
-       $(SNMPLIB) \
        $(SQUID_CPPUNIT_LIBS) \
        $(SQUID_CPPUNIT_LA) \
        $(SSLLIB) \
@@ -1325,11 +1330,21 @@ tests_testDiskIO_LDADD = \
        SquidConfig.o \
        CommCalls.o \
        DnsLookupDetails.o \
-       $(COMMON_LIBS) \
+       auth/libacls.la \
+       ident/libident.la \
+       acl/libacls.la \
+       eui/libeui.la \
+       acl/libstate.la \
+       auth/libauth.la \
+       base/libbase.la \
+       libsquid.la \
+       ip/libip.la \
+       fs/libfs.la \
        $(REPL_OBJS) \
        $(DISK_LIBS) \
        $(DISK_OS_LIBS) \
        acl/libapi.la \
+       mgr/libmgr.la \
        $(top_builddir)/lib/libmisccontainers.la \
        $(top_builddir)/lib/libmiscencoding.la \
        $(top_builddir)/lib/libmiscutil.la \
@@ -1361,6 +1376,7 @@ tests_testEvent_SOURCES = \
        tests/testEvent.h \
        tests/testMain.cc \
        tests/stub_main_cc.cc \
+       tests/stub_ipc_Forwarder.cc \
        time.cc \
        BodyPipe.cc \
        cache_manager.cc \
@@ -1377,7 +1393,6 @@ tests_testEvent_SOURCES = \
        client_side_request.cc \
        ClientInfo.h \
        clientStream.cc \
-       $(squid_COMMSOURCES) \
        ConfigOption.cc \
        ConfigParser.cc \
        CpuAffinityMap.cc \
@@ -1439,7 +1454,6 @@ tests_testEvent_SOURCES = \
        peer_sourcehash.cc \
        peer_userhash.cc \
        redirect.cc \
-       referer.cc \
        refresh.cc \
        Server.cc \
        $(SNMP_SOURCE) \
@@ -1476,7 +1490,6 @@ tests_testEvent_SOURCES = \
        url.cc \
        URLScheme.cc \
        urn.cc \
-       useragent.cc \
        wccp2.cc \
        whois.cc \
        FadingCounter.cc \
@@ -1486,18 +1499,18 @@ nodist_tests_testEvent_SOURCES = \
        $(BUILT_SOURCES)
 tests_testEvent_LDADD = \
        $(COMMON_LIBS) \
+       $(SNMP_LIBS) \
        icmp/libicmp.la icmp/libicmp-core.la \
        comm/libcomm.la \
        log/liblog.la \
        $(REPL_OBJS) \
-       ${ADAPTATION_LIBS} \
+       $(ADAPTATION_LIBS) \
        $(ESI_LIBS) \
        $(SSL_LIBS) \
        $(top_builddir)/lib/libmisccontainers.la \
        $(top_builddir)/lib/libmiscencoding.la \
        $(top_builddir)/lib/libmiscutil.la \
        $(REGEXLIB) \
-       $(SNMPLIB) \
        $(SQUID_CPPUNIT_LIBS) \
        $(SQUID_CPPUNIT_LA) \
        $(SSLLIB) \
@@ -1524,6 +1537,7 @@ tests_testEventLoop_SOURCES = \
        tests/testEventLoop.h \
        tests/testMain.cc \
        tests/stub_main_cc.cc \
+       tests/stub_ipc_Forwarder.cc \
        time.cc \
        BodyPipe.cc \
        cache_manager.cc \
@@ -1540,7 +1554,6 @@ tests_testEventLoop_SOURCES = \
        client_side_request.cc \
        ClientInfo.h \
        clientStream.cc \
-       $(squid_COMMSOURCES) \
        ConfigOption.cc \
        ConfigParser.cc \
        CpuAffinityMap.cc \
@@ -1602,7 +1615,6 @@ tests_testEventLoop_SOURCES = \
        peer_sourcehash.cc \
        peer_userhash.cc \
        redirect.cc \
-       referer.cc \
        refresh.cc \
        Server.cc \
        $(SNMP_SOURCE) \
@@ -1639,7 +1651,6 @@ tests_testEventLoop_SOURCES = \
        url.cc \
        URLScheme.cc \
        urn.cc \
-       useragent.cc \
        wccp2.cc \
        whois.cc \
        FadingCounter.cc \
@@ -1649,18 +1660,18 @@ nodist_tests_testEventLoop_SOURCES = \
        $(BUILT_SOURCES)
 tests_testEventLoop_LDADD = \
        $(COMMON_LIBS) \
+       $(SNMP_LIBS) \
        icmp/libicmp.la icmp/libicmp-core.la \
        comm/libcomm.la \
        log/liblog.la \
        $(REPL_OBJS) \
-       ${ADAPTATION_LIBS} \
+       $(ADAPTATION_LIBS) \
        $(ESI_LIBS) \
        $(SSL_LIBS) \
        $(top_builddir)/lib/libmisccontainers.la \
        $(top_builddir)/lib/libmiscencoding.la \
        $(top_builddir)/lib/libmiscutil.la \
        $(REGEXLIB) \
-       $(SNMPLIB) \
        $(SQUID_CPPUNIT_LIBS) \
        $(SQUID_CPPUNIT_LA) \
        $(SSLLIB) \
@@ -1690,7 +1701,6 @@ tests_test_http_range_SOURCES = \
        client_side_request.cc \
        ClientInfo.h \
        clientStream.cc \
-       $(squid_COMMSOURCES) \
        ConfigOption.cc \
        ConfigParser.cc \
        CpuAffinityMap.cc \
@@ -1698,6 +1708,7 @@ tests_test_http_range_SOURCES = \
        CpuAffinitySet.cc \
        CpuAffinitySet.h \
        tests/stub_main_cc.cc \
+       tests/stub_ipc_Forwarder.cc \
        debug.cc \
        $(DELAY_POOL_SOURCE) \
        disk.cc \
@@ -1755,7 +1766,6 @@ tests_test_http_range_SOURCES = \
        peer_userhash.cc \
        pconn.cc \
        redirect.cc \
-       referer.cc \
        refresh.cc \
        RemovalPolicy.cc \
        Server.cc \
@@ -1795,7 +1805,6 @@ tests_test_http_range_SOURCES = \
        url.cc \
        URLScheme.cc \
        urn.cc \
-       useragent.cc \
        wccp2.cc \
        whois.cc \
        FadingCounter.cc \
@@ -1807,18 +1816,18 @@ nodist_tests_test_http_range_SOURCES = \
        $(BUILT_SOURCES)
 tests_test_http_range_LDADD = \
        $(COMMON_LIBS) \
+       $(SNMP_LIBS) \
        icmp/libicmp.la icmp/libicmp-core.la \
        comm/libcomm.la \
        log/liblog.la \
        $(REPL_OBJS) \
-       ${ADAPTATION_LIBS} \
+       $(ADAPTATION_LIBS) \
        $(ESI_LIBS) \
        $(SSL_LIBS) \
        $(top_builddir)/lib/libmisccontainers.la \
        $(top_builddir)/lib/libmiscencoding.la \
        $(top_builddir)/lib/libmiscutil.la \
        $(REGEXLIB) \
-       $(SNMPLIB) \
        $(SQUID_CPPUNIT_LIBS) \
        $(SQUID_CPPUNIT_LA) \
        $(SSLLIB) \
@@ -1843,6 +1852,7 @@ tests_testHttpRequest_SOURCES = \
        tests/testHttpRequestMethod.cc \
        tests/testMain.cc \
        tests/stub_main_cc.cc \
+       tests/stub_ipc_Forwarder.cc \
        time.cc \
        BodyPipe.cc \
        cache_manager.cc \
@@ -1860,7 +1870,6 @@ tests_testHttpRequest_SOURCES = \
        client_side_request.cc \
        ClientInfo.h \
        clientStream.cc \
-       $(squid_COMMSOURCES) \
        ConfigOption.cc \
        ConfigParser.cc \
        CpuAffinityMap.cc \
@@ -1922,7 +1931,6 @@ tests_testHttpRequest_SOURCES = \
        peer_sourcehash.cc \
        peer_userhash.cc \
        redirect.cc \
-       referer.cc \
        refresh.cc \
        RemovalPolicy.cc \
        Server.cc \
@@ -1960,7 +1968,6 @@ tests_testHttpRequest_SOURCES = \
        url.cc \
        URLScheme.cc \
        urn.cc \
-       useragent.cc \
        wccp2.cc \
        whois.cc \
        FadingCounter.cc \
@@ -1970,18 +1977,18 @@ nodist_tests_testHttpRequest_SOURCES = \
        $(BUILT_SOURCES)
 tests_testHttpRequest_LDADD = \
        $(COMMON_LIBS) \
+       $(SNMP_LIBS) \
        icmp/libicmp.la icmp/libicmp-core.la \
        comm/libcomm.la \
        log/liblog.la \
        $(REPL_OBJS) \
-       ${ADAPTATION_LIBS} \
+       $(ADAPTATION_LIBS) \
        $(ESI_LIBS) \
        $(SSL_LIBS) \
        $(top_builddir)/lib/libmisccontainers.la \
        $(top_builddir)/lib/libmiscencoding.la \
        $(top_builddir)/lib/libmiscutil.la \
        $(REGEXLIB) \
-       $(SNMPLIB) \
        $(SQUID_CPPUNIT_LIBS) \
        $(SQUID_CPPUNIT_LA) \
        $(SSLLIB) \
@@ -2099,7 +2106,9 @@ tests_testString_SOURCES = \
 nodist_tests_testString_SOURCES = \
        $(TESTSOURCES)
 tests_testString_LDADD = \
-       $(COMMON_LIBS) \
+       base/libbase.la \
+       libsquid.la \
+       ip/libip.la \
        $(top_builddir)/lib/libmiscutil.la \
        $(REGEXLIB) \
        $(SQUID_CPPUNIT_LIBS) \
@@ -2262,6 +2271,7 @@ tests_testURL_SOURCES = \
        tests/testMain.cc \
        tests/stub_debug.cc \
        tests/stub_main_cc.cc \
+       tests/stub_ipc_Forwarder.cc \
        time.cc \
        BodyPipe.cc \
        cache_manager.cc \
@@ -2278,7 +2288,6 @@ tests_testURL_SOURCES = \
        client_side_request.cc \
        ClientInfo.h \
        clientStream.cc \
-       $(squid_COMMSOURCES) \
        ConfigOption.cc \
        ConfigParser.cc \
        CpuAffinityMap.cc \
@@ -2340,7 +2349,6 @@ tests_testURL_SOURCES = \
        peer_sourcehash.cc \
        peer_userhash.cc \
        redirect.cc \
-       referer.cc \
        refresh.cc \
        Server.cc \
        $(SNMP_SOURCE) \
@@ -2375,7 +2383,6 @@ tests_testURL_SOURCES = \
        tunnel.cc \
        SwapDir.cc \
        urn.cc \
-       useragent.cc \
        wccp2.cc \
        whois.cc \
        FadingCounter.cc \
@@ -2385,15 +2392,15 @@ nodist_tests_testURL_SOURCES = \
        $(BUILT_SOURCES)
 tests_testURL_LDADD = \
        $(COMMON_LIBS) \
+       $(SNMP_LIBS) \
        icmp/libicmp.la icmp/libicmp-core.la \
        comm/libcomm.la \
        log/liblog.la \
        $(REGEXLIB) \
        $(REPL_OBJS) \
-       ${ADAPTATION_LIBS} \
+       $(ADAPTATION_LIBS) \
        $(ESI_LIBS) \
        $(SSL_LIBS) \
-       $(SNMPLIB) \
        $(top_builddir)/lib/libmisccontainers.la \
        $(top_builddir)/lib/libmiscencoding.la \
        $(top_builddir)/lib/libmiscutil.la \
index ad16dbef44b5d6a092c7e001450d7c31d5315757..7da391d23284d499c2842fece9cf5373554681b0 100644 (file)
@@ -113,18 +113,18 @@ MemBlob::~MemBlob()
  * by MemPools via memAllocString.
  */
 MemBlob::size_type
-MemBlob::calcAllocSize(const size_type size) const
+MemBlob::calcAllocSize(const size_type sz) const
 {
-    if (size <= 36) return 36;
-    if (size <= 128) return 128;
-    if (size <= 512) return 512;
-    if (size <= 4096) return RoundTo(size, 512);
+    if (sz <= 36) return 36;
+    if (sz <= 128) return 128;
+    if (sz <= 512) return 512;
+    if (sz <= 4096) return RoundTo(sz, 512);
     // XXX: recover squidSystemPageSize functionality. It's easy for
     //      the main squid, harder for tests
 #if 0
-    return RoundTo(size, squidSystemPageSize);
+    return RoundTo(sz, squidSystemPageSize);
 #else
-    return RoundTo(size, 4096);
+    return RoundTo(sz, 4096);
 #endif
 }
 
index 70480bec6506f9e6780aa386a509ab99525e10d4..46c5ec1fc6dbf6ffbc6a84b8258c09cf95bd466b 100644 (file)
@@ -217,7 +217,7 @@ void MemBuf::consume(mb_size_t shiftSize)
     PROF_start(MemBuf_consume);
     if (shiftSize > 0) {
         if (shiftSize < cSize)
-            xmemmove(buf, buf + shiftSize, cSize - shiftSize);
+            memmove(buf, buf + shiftSize, cSize - shiftSize);
 
         size -= shiftSize;
 
@@ -251,9 +251,7 @@ void MemBuf::append(const char *newContent, mb_size_t sz)
             grow(size + sz + 1);
 
         assert(size + sz <= capacity); /* paranoid */
-
-        xmemcpy(space(), newContent, sz);
-
+        memcpy(space(), newContent, sz);
         appended(sz);
     }
     PROF_stop(MemBuf_append);
index 1f93fe93cbaa8460c004357557519eb4667c0525..478868f8151b3c43bad11a592b14b6a37ed722dd 100644 (file)
@@ -57,7 +57,7 @@ url_checksum(const char *url)
     SquidMD5Init(&M);
     SquidMD5Update(&M, (unsigned char *) url, strlen(url));
     SquidMD5Final(digest, &M);
-    xmemcpy(&ck, digest, sizeof(ck));
+    memcpy(&ck, digest, sizeof(ck));
     return ck;
 }
 
@@ -207,10 +207,12 @@ struct StoreClientStats : public unary_function<store_client, void> {
 };
 
 void
-MemObject::stat (MemBuf * mb) const
+MemObject::stat(MemBuf * mb) const
 {
     mb->Printf("\t%s %s\n",
                RequestMethodStr(method), log_url);
+    if (vary_headers)
+        mb->Printf("\tvary_headers: %s\n", vary_headers);
     mb->Printf("\tinmem_lo: %"PRId64"\n", inmem_lo);
     mb->Printf("\tinmem_hi: %"PRId64"\n", data_hdr.endOffset());
     mb->Printf("\tswapout: %"PRId64" bytes queued\n",
index fa671cf9a0996c5a167c0daa6d5c7b5994c366a9..6a311dcff069c31b438723be845ec99e153d67e9 100644 (file)
@@ -100,13 +100,11 @@ xprof_comp(xprof_stats_node ** ii, xprof_stats_node ** jj)
 static void
 xprof_sorthist(TimersArray * xprof_list)
 {
-    int i;
-
-    for (i = 0; i < XPROF_LAST; i++) {
+    for (int i = 0; i < XPROF_LAST; i++) {
         sortlist[i] = xprof_list[i];
     }
 
-    qsort(&sortlist[XPROF_hash_lookup], XPROF_LAST - XPROF_hash_lookup, sizeof(xprof_stats_node *), (QS *) xprof_comp);
+    qsort(&sortlist[XPROF_PROF_UNACCOUNTED+1], XPROF_LAST - XPROF_PROF_UNACCOUNTED+1, sizeof(xprof_stats_node *), (QS *) xprof_comp);
 }
 
 static double time_frame;
index 98d4142a62992876fab889434fe8270f3c67ff77..de42e8e204afe832c110319585a246670affd3c1 100644 (file)
@@ -3,15 +3,17 @@
  */
 
 #include "squid.h"
+#include "comm.h"
 #include "ProtoPort.h"
 #if HAVE_LIMITS
 #include <limits>
 #endif
 
-http_port_list::http_port_list(const char *aProtocol)
+http_port_list::http_port_list(const char *aProtocol) :
+        listenFd(-1)
 #if USE_SSL
-        :
-        http(*this), dynamicCertMemCacheSize(std::numeric_limits<size_t>::max())
+        , http(*this)
+        , dynamicCertMemCacheSize(std::numeric_limits<size_t>::max())
 #endif
 {
     protocol = xstrdup(aProtocol);
@@ -19,7 +21,10 @@ http_port_list::http_port_list(const char *aProtocol)
 
 http_port_list::~http_port_list()
 {
-    delete listener;
+    if (listenFd >= 0) {
+        comm_close(listenFd);
+        listenFd = -1;
+    }
 
     safe_free(name);
     safe_free(defaultsite);
index 6bee84f57862711765bd6f1524e163600461efd3..323a6d2084b3de3ced6ec77b2ce653dc9d10a8fe 100644 (file)
@@ -4,9 +4,7 @@
 #ifndef SQUID_PROTO_PORT_H
 #define SQUID_PROTO_PORT_H
 
-//#include "typedefs.h"
 #include "cbdata.h"
-#include "comm/ListenStateData.h"
 
 #if USE_SSL
 #include "ssl/gadgets.h"
@@ -43,11 +41,11 @@ struct http_port_list {
     } tcp_keepalive;
 
     /**
-     * The FD listening socket handler.
-     * If not NULL we are actively listening for client requests.
-     * delete to close the socket.
+     * The FD listening socket.
+     * If >= 0 we are actively listening for client requests.
+     * use comm_close(listenFd) to stop.
      */
-    Comm::ListenStateData *listener;
+    int listenFd;
 
 #if USE_SSL
     // XXX: temporary hack to ease move of SSL options to http_port
index 946d3f15c51ff9c8607a0912098d1436254249f1..b4160ba6d1f452d369d7c4488300bbcc2fef27d3 100644 (file)
@@ -7,6 +7,12 @@ Math::intPercent(const int a, const int b)
     return b ? ((int) (100.0 * a / b + 0.5)) : 0;
 }
 
+int64_t
+Math::int64Percent(const int64_t a, const int64_t b)
+{
+    return b ? ((int64_t) (100.0 * a / b + 0.5)) : 0;
+}
+
 double
 Math::doublePercent(const double a, const double b)
 {
index a6061a62b2db24499cd9f8504e6e96d42f1dafe8..c31a13a08bbc0d49b096b40d70f00efb87f84732 100644 (file)
@@ -6,6 +6,7 @@ namespace Math
 {
 
 extern int intPercent(const int a, const int b);
+extern int64_t int64Percent(const int64_t a, const int64_t b);
 extern double doublePercent(const double, const double);
 extern int intAverage(const int, const int, int, const int);
 extern double doubleAverage(const double, const double, int, const int);
index 47bd9533f17315c9fe6f2e6b980b9d497b46b3fa..46a84a47c3d729171bb8f2178e3ab7fda836cd71 100644 (file)
@@ -58,4 +58,25 @@ public:
     virtual void tick();
 };
 
+namespace Time
+{
+
+/** Display time as a formatted human-readable string.
+ * Time syntax is
+ * "YYYY/MM/DD hh:mm:ss"
+ *
+ * Output is only valid until next call to this function.
+ */
+const char *FormatStrf(time_t t);
+
+/** Display time as a formatted human-readable string.
+ * Time string syntax used is that of Apache httpd.
+ * "DD/MMM/YYYY:hh:mm:ss zzzz"
+ *
+ * Output is only valid until next call to this function.
+ */
+const char *FormatHttpd(time_t t);
+
+} // namespace Time
+
 #endif /* SQUID_TIME_H */
index 26092e7e118998b7b4dbfc03e899cd7d7e80648e..6b82e9bfd5e229d2514738f5caec3b83085bd028 100644 (file)
@@ -53,15 +53,13 @@ static void statHistInit(StatHist * H, int capacity, hbase_f * val_in, hbase_f *
 static int statHistBin(const StatHist * H, double v);
 static double statHistVal(const StatHist * H, int bin);
 static StatHistBinDumper statHistBinDumper;
-#if !defined(_SQUID_HPUX_) || !defined(__GNUC__)
-/*
- * HP-UX and GCC (2.8?) give strange errors when these simple
- * functions are static.
- */
-static hbase_f Log;
-static hbase_f Exp;
-static hbase_f Null;
-#endif
+
+namespace Math
+{
+hbase_f Log;
+hbase_f Exp;
+hbase_f Null;
+};
 
 /* low level init, higher level functions has less params */
 static void
@@ -125,7 +123,7 @@ statHistCopy(StatHist * Dest, const StatHist * Orig)
            (long int) (Dest->capacity * sizeof(*Dest->bins)) << " bytes to " <<
            Dest->bins << " from " << Orig->bins);
 
-    xmemcpy(Dest->bins, Orig->bins, Dest->capacity * sizeof(*Dest->bins));
+    memcpy(Dest->bins, Orig->bins, Dest->capacity * sizeof(*Dest->bins));
 }
 
 /*
@@ -274,21 +272,15 @@ statHistDump(const StatHist * H, StoreEntry * sentry, StatHistBinDumper * bd)
 }
 
 /* log based histogram */
-#if !defined(_SQUID_HPUX_) || !defined(__GNUC__)
-static
-#endif
 double
-Log(double x)
+Math::Log(double x)
 {
     assert((x + 1.0) >= 0.0);
     return log(x + 1.0);
 }
 
-#if !defined(_SQUID_HPUX_) || !defined(__GNUC__)
-static
-#endif
 double
-Exp(double x)
+Math::Exp(double x)
 {
     return exp(x) - 1.0;
 }
@@ -296,16 +288,13 @@ Exp(double x)
 void
 statHistLogInit(StatHist * H, int capacity, double min, double max)
 {
-    statHistInit(H, capacity, Log, Exp, min, max);
+    statHistInit(H, capacity, Math::Log, Math::Exp, min, max);
 }
 
 /* linear histogram for enums */
 /* we want to be have [-1,last_enum+1] range to track out of range enums */
-#if !defined(_SQUID_HPUX_) || !defined(__GNUC__)
-static
-#endif
 double
-Null(double x)
+Math::Null(double x)
 {
     return x;
 }
@@ -313,7 +302,7 @@ Null(double x)
 void
 statHistEnumInit(StatHist * H, int last_enum)
 {
-    statHistInit(H, last_enum + 3, Null, Null, (double) -1, (double) (last_enum + 1 + 1));
+    statHistInit(H, last_enum + 3, Math::Null, Math::Null, (double) -1, (double) (last_enum + 1 + 1));
 }
 
 void
@@ -327,7 +316,7 @@ statHistEnumDumper(StoreEntry * sentry, int idx, double val, double size, int co
 void
 statHistIntInit(StatHist * H, int n)
 {
-    statHistInit(H, n, Null, Null, (double) 0, (double) n - 1);
+    statHistInit(H, n, Math::Null, Math::Null, (double) 0, (double) n - 1);
 }
 
 void
index af0f6b3e7713bb78161a85ca85167c7a31a595f4..b3ba501b1d0fd30d32c331847cc4f5b254335115 100644 (file)
@@ -290,10 +290,10 @@ public:
      * The maximum size the store will support in normal use. Inaccuracy is permitted,
      * but may throw estimates for memory etc out of whack.
      */
-    virtual size_t maxSize() const = 0;
+    virtual uint64_t maxSize() const = 0;
 
     /** The minimum size the store will shrink to via normal housekeeping */
-    virtual size_t minSize() const = 0;
+    virtual uint64_t minSize() const = 0;
 
     /**
      * Output stats to the provided store entry.
@@ -364,7 +364,7 @@ SQUIDCEXTERN int expiresMoreThan(time_t, time_t);
 SQUIDCEXTERN void storeAppendPrintf(StoreEntry *, const char *,...) PRINTF_FORMAT_ARG2;
 
 /// \ingroup StoreAPI
-SQUIDCEXTERN void storeAppendVPrintf(StoreEntry *, const char *, va_list ap);
+extern void storeAppendVPrintf(StoreEntry *, const char *, va_list ap);
 
 /// \ingroup StoreAPI
 SQUIDCEXTERN int storeTooManyDiskFilesOpen(void);
index 7702b6be7ed203e4bcc84e6b74a4f6b15b873f36..586ef6113d14550b7f184ebddc2bd37c41bf7e23 100644 (file)
  \par
  * The storage types live in \em src/fs/. Each subdirectory corresponds
  * to the name of the storage type. When a new storage type is implemented
- * configure.in must be updated to autogenerate a Makefile in
+ * configure.ac must be updated to autogenerate a Makefile in
  * \em src/fs/foo/ from a Makefile.in file.
  *
- \todo DOCS: add template addition to configure.in for storage module addition.
+ \todo DOCS: add template addition to configure.ac for storage module addition.
  \todo DOCS: add template Makefile.am for storage module addition.
  *
  \par
index bc602a9f142532db859267fe36291381f2e90117..1b76377eb789cc481cf9a94247b16e27c57da806 100644 (file)
@@ -63,9 +63,9 @@ public:
 
     virtual void sync();
 
-    virtual size_t maxSize() const;
+    virtual uint64_t maxSize() const;
 
-    virtual size_t minSize() const;
+    virtual uint64_t minSize() const;
 
     virtual void stat(StoreEntry&) const;
 
index 4065a4854cdea85eb0743a03313a3c3d791c6f57..f784a8c2099ff2bf9c059334c8a0a7512ab3c393 100644 (file)
@@ -158,7 +158,7 @@ StoreMeta::Factory (char type, size_t len, void const *value)
 
     result->length = len;
     result->value = xmalloc(len);
-    xmemcpy(result->value, value, len);
+    memcpy(result->value, value, len);
     return result;
 }
 
index e9e1b266f8f42f5f1621948e4efc05227559d22c..a92165192a9b4ade5650c28a9d4d8c55a8479c2a 100644 (file)
@@ -63,7 +63,7 @@ StoreMetaUnpacker::isBufferSane()
 void
 StoreMetaUnpacker::getBufferLength()
 {
-    xmemcpy(hdr_len, &buf[1], sizeof(int));
+    memcpy(hdr_len, &buf[1], sizeof(int));
 }
 
 StoreMetaUnpacker::StoreMetaUnpacker (char const *aBuffer, ssize_t aLen, int *anInt) : buf (aBuffer), buflen(aLen), hdr_len(anInt), position(1 + sizeof(int))
@@ -80,7 +80,7 @@ StoreMetaUnpacker::getType()
 void
 StoreMetaUnpacker::getLength()
 {
-    xmemcpy(&length, &buf[position], sizeof(int));
+    memcpy(&length, &buf[position], sizeof(int));
     position += sizeof(int);
 }
 
index c86696a86f3a941981eb08239f8a297335efa163..bf4366cf656f3d7fa989e8bbdeafdee953a0987e 100644 (file)
@@ -130,7 +130,7 @@ String::allocAndFill(const char *str, int len)
     assert(this && str);
     allocBuffer(len + 1);
     len_ = len;
-    xmemcpy(buf_, str, len);
+    memcpy(buf_, str, len);
     buf_[len] = '\0';
     PROF_stop(StringAllocAndFill);
 }
@@ -200,10 +200,10 @@ String::append(const char *str, int len)
         snew.allocBuffer(snew.len_ + 1);
 
         if (len_)
-            xmemcpy(snew.buf_, rawBuf(), len_);
+            memcpy(snew.buf_, rawBuf(), len_);
 
         if (len)
-            xmemcpy(snew.buf_ + len_, str, len);
+            memcpy(snew.buf_ + len_, str, len);
 
         snew.buf_[snew.len_] = '\0';
 
@@ -287,17 +287,13 @@ StringRegistry::StringRegistry()
 }
 
 void
-
-StringRegistry::add
-(String const *entry)
+StringRegistry::add(String const *entry)
 {
     entries.insert(entry, ptrcmp);
 }
 
 void
-
-StringRegistry::remove
-(String const *entry)
+StringRegistry::remove(String const *entry)
 {
     entries.remove(entry, ptrcmp);
 }
index abe17e518402331967900bafde58de31f0a81396..fe6b8fed741780a30612a553bee56acb6058592f 100644 (file)
@@ -174,7 +174,8 @@ String::set(char const *loc, char const ch)
 void
 String::cut(String::size_type newLength)
 {
-    if (newLength < 0 || newLength > len_) return;
+    // size_type is size_t, unsigned. No need to check for newLength <0
+    if (newLength > len_) return;
 
     len_ = newLength;
 
index 40c04099b816f27fdd239a7a5d11efd72536d536..ba48794dc9249c9ae07deb68b7549a1d686c44a1 100644 (file)
@@ -81,11 +81,10 @@ SwapDir::statfs(StoreEntry &)const {}
 void
 SwapDir::maintain() {}
 
-size_t
+uint64_t
 SwapDir::minSize() const
 {
-    return (size_t) (((float) maxSize() *
-                      (float) Config.Swap.lowWaterMark) / 100.0);
+    return ((maxSize() * Config.Swap.lowWaterMark) / 100);
 }
 
 void
@@ -160,7 +159,7 @@ SwapDir::getOptionTree() const
 {
     ConfigOptionVector *result = new ConfigOptionVector;
     result->options.push_back(new ConfigOptionAdapter<SwapDir>(*const_cast<SwapDir *>(this), &SwapDir::optionReadOnlyParse, &SwapDir::optionReadOnlyDump));
-    result->options.push_back(new ConfigOptionAdapter<SwapDir>(*const_cast<SwapDir *>(this), &SwapDir::optionMaxSizeParse, &SwapDir::optionMaxSizeDump));
+    result->options.push_back(new ConfigOptionAdapter<SwapDir>(*const_cast<SwapDir *>(this), &SwapDir::optionObjectSizeParse, &SwapDir::optionObjectSizeDump));
     return result;
 }
 
@@ -237,9 +236,14 @@ SwapDir::optionReadOnlyDump(StoreEntry * e) const
 }
 
 bool
-SwapDir::optionMaxSizeParse(char const *option, const char *value, int isaReconfig)
+SwapDir::optionObjectSizeParse(char const *option, const char *value, int isaReconfig)
 {
-    if (strcmp(option, "max-size") != 0)
+    int64_t *val;
+    if (strcmp(option, "max-size") == 0) {
+        val = &max_objsize;
+    } else if (strcmp(option, "min-size") == 0) {
+        val = &min_objsize;
+    } else
         return false;
 
     if (!value)
@@ -247,17 +251,20 @@ SwapDir::optionMaxSizeParse(char const *option, const char *value, int isaReconf
 
     int64_t size = strtoll(value, NULL, 10);
 
-    if (isaReconfig && max_objsize != size)
-        debugs(3, 1, "Cache dir '" << path << "' max object size now " << size);
+    if (isaReconfig && *val != size)
+        debugs(3, 1, "Cache dir '" << path << "' object " << option << " now " << size);
 
-    max_objsize = size;
+    *val = size;
 
     return true;
 }
 
 void
-SwapDir::optionMaxSizeDump(StoreEntry * e) const
+SwapDir::optionObjectSizeDump(StoreEntry * e) const
 {
+    if (min_objsize != 0)
+        storeAppendPrintf(e, " min-size=%"PRId64, min_objsize);
+
     if (max_objsize != -1)
         storeAppendPrintf(e, " max-size=%"PRId64, max_objsize);
 }
@@ -266,17 +273,13 @@ SwapDir::optionMaxSizeDump(StoreEntry * e) const
  * but the parent child relationship isn't implemented yet
  */
 StoreEntry *
-
-SwapDir::get
-(const cache_key *key)
+SwapDir::get(const cache_key *key)
 {
     return Store::Root().get(key);
 }
 
 void
-
-SwapDir::get
-(String const key, STOREGETCLIENT aCallback, void *aCallbackData)
+SwapDir::get(String const key, STOREGETCLIENT aCallback, void *aCallbackData)
 {
     fatal("not implemented");
 }
index a3930158b10148bff0b41023399178986f2869ca..534106bbfa397dce7e1ab23feffd88807280e04a 100644 (file)
@@ -62,9 +62,9 @@ public:
 
     virtual void maintain(); /* perform regular maintenance should be private and self registered ... */
 
-    virtual size_t maxSize() const;
+    virtual uint64_t maxSize() const;
 
-    virtual size_t minSize() const;
+    virtual uint64_t minSize() const;
 
     virtual void stat(StoreEntry &) const;
 
@@ -113,7 +113,7 @@ class SwapDir : public Store
 {
 
 public:
-    SwapDir(char const *aType) : theType (aType), cur_size(0), max_size(0), max_objsize (-1), cleanLog(NULL) {
+    SwapDir(char const *aType) : theType (aType), cur_size(0), max_size(0), min_objsize(0), max_objsize(-1), cleanLog(NULL) {
         fs.blksize = 1024;
         path = NULL;
     }
@@ -129,9 +129,9 @@ public:
 
     virtual void get(String const, STOREGETCLIENT, void * cbdata);
 
-    virtual size_t maxSize() const { return max_size;}
+    virtual uint64_t maxSize() const { return max_size;}
 
-    virtual size_t minSize() const;
+    virtual uint64_t minSize() const;
     virtual void stat (StoreEntry &anEntry) const;
     virtual StoreSearch *search(String const url, HttpRequest *) = 0;
 
@@ -148,15 +148,16 @@ protected:
 private:
     bool optionReadOnlyParse(char const *option, const char *value, int reconfiguring);
     void optionReadOnlyDump(StoreEntry * e) const;
-    bool optionMaxSizeParse(char const *option, const char *value, int reconfiguring);
-    void optionMaxSizeDump(StoreEntry * e) const;
+    bool optionObjectSizeParse(char const *option, const char *value, int reconfiguring);
+    void optionObjectSizeDump(StoreEntry * e) const;
     char const *theType;
 
 public:
-    size_t cur_size;
-    size_t max_size;
+    uint64_t cur_size;        ///< currently used space in the storage area
+    uint64_t max_size;        ///< maximum allocatable size of the storage area
     char *path;
     int index;                 /* This entry's index into the swapDirs array */
+    int64_t min_objsize;
     int64_t max_objsize;
     RemovalPolicy *repl;
     int removals;
index 552a2e9670eb2400f520b4813210d457a31ed99f..2137edf3e42a86784de358b7b7a8e3a58e1ee4ad 100644 (file)
@@ -341,7 +341,7 @@ asHandleReply(void *data, StoreIOBuffer result)
      * Next, copy the left over data, from s to s + leftoversz to the
      * beginning of the buffer
      */
-    xmemmove(buf, s, leftoversz);
+    memmove(buf, s, leftoversz);
 
     /*
      * Next, update our offset and reqofs, and kick off a copy if required
index a05fb9755071ec47e3237ecf44fa37820b252c3c..2514a8cb3fb95d1cecdee75239301d6f852755ec 100644 (file)
@@ -35,7 +35,7 @@
  */
 
 #include "config.h"
-#ifdef _SQUID_CYGWIN_
+#if _SQUID_CYGWIN_
 #include <squid_windows.h>
 #endif
 #include "squid.h"
index 3de564c1c8852c9a77f4cd47916765ffe2c47260..d565253f296c6579e6a6c93df5cd47e05cf06c47 100644 (file)
@@ -22,7 +22,7 @@ ACLSslErrorData::~ACLSslErrorData()
 }
 
 bool
-ACLSslErrorData::match(ssl_error_t toFind)
+ACLSslErrorData::match(Ssl::ssl_error_t toFind)
 {
     return values->findAndTune (toFind);
 }
@@ -30,17 +30,17 @@ ACLSslErrorData::match(ssl_error_t toFind)
 /* explicit instantiation required for some systems */
 /** \cond AUTODOCS-IGNORE */
 // AYJ: 2009-05-20 : Removing. clashes with template <int> instantiation for other ACLs.
-// template cbdata_type CbDataList<ssl_error_t>::CBDATA_CbDataList;
+// template cbdata_type CbDataList<Ssl::ssl_error_t>::CBDATA_CbDataList;
 /** \endcond */
 
 wordlist *
 ACLSslErrorData::dump()
 {
     wordlist *W = NULL;
-    CbDataList<ssl_error_t> *data = values;
+    CbDataList<Ssl::ssl_error_t> *data = values;
 
     while (data != NULL) {
-        wordlistAdd(&W, sslFindErrorString(data->element));
+        wordlistAdd(&W, Ssl::getErrorName(data->element));
         data = data->next;
     }
 
@@ -50,12 +50,12 @@ ACLSslErrorData::dump()
 void
 ACLSslErrorData::parse()
 {
-    CbDataList<ssl_error_t> **Tail;
+    CbDataList<Ssl::ssl_error_t> **Tail;
     char *t = NULL;
 
     for (Tail = &values; *Tail; Tail = &((*Tail)->next));
     while ((t = strtokFile())) {
-        CbDataList<ssl_error_t> *q = new CbDataList<ssl_error_t>(sslParseErrorString(t));
+        CbDataList<Ssl::ssl_error_t> *q = new CbDataList<Ssl::ssl_error_t>(Ssl::parseErrorString(t));
         *(Tail) = q;
         Tail = &q->next;
     }
@@ -67,7 +67,7 @@ ACLSslErrorData::empty() const
     return values == NULL;
 }
 
-ACLData<ssl_error_t> *
+ACLData<Ssl::ssl_error_t> *
 ACLSslErrorData::clone() const
 {
     /* Splay trees don't clone yet. */
index fc0afff5498900a9beaa8c700c131cd0c835ff14..1f21a7ceae0fe94b48d1f94b0ff162ecf45b72d1 100644 (file)
@@ -9,8 +9,9 @@
 #include "acl/Data.h"
 #include "CbDataList.h"
 #include "ssl/support.h"
+#include "ssl/ErrorDetail.h"
 
-class ACLSslErrorData : public ACLData<ssl_error_t>
+class ACLSslErrorData : public ACLData<Ssl::ssl_error_t>
 {
 
 public:
@@ -20,13 +21,13 @@ public:
     ACLSslErrorData(ACLSslErrorData const &);
     ACLSslErrorData &operator= (ACLSslErrorData const &);
     virtual ~ACLSslErrorData();
-    bool match(ssl_error_t);
+    bool match(Ssl::ssl_error_t);
     wordlist *dump();
     void parse();
     bool empty() const;
-    virtual ACLData<ssl_error_t> *clone() const;
+    virtual ACLData<Ssl::ssl_error_t> *clone() const;
 
-    CbDataList<ssl_error_t> *values;
+    CbDataList<Ssl::ssl_error_t> *values;
 };
 
 MEMPROXY_CLASS_INLINE(ACLSslErrorData);
index c2d677395f910e9a1aa4461bd27cb4f805541c7e..f90a269d13675acbcb18da2f3616ef8cd4ad8d85 100644 (file)
@@ -77,8 +77,7 @@ ACLTimeData::match(time_t when)
 
     if (when != last_when) {
         last_when = when;
-
-        xmemcpy(&tm, localtime(&when), sizeof(struct tm));
+        memcpy(&tm, localtime(&when), sizeof(struct tm));
     }
 
     t = (time_t) (tm.tm_hour * 60 + tm.tm_min);
index 9751422f056f38fa5d2bf9028dc0c9e2eff9df15..176ce2110ae20cfd5ae2c71b5f75418ebca04f31 100644 (file)
@@ -57,12 +57,12 @@ Adaptation::ServiceConfig::parseVectPoint(const char *service_configConfig) cons
 bool
 Adaptation::ServiceConfig::parse()
 {
-    char *method_point = NULL;
+    String method_point;
 
     ConfigParser::ParseString(&key);
     ConfigParser::ParseString(&method_point);
-    method = parseMethod(method_point);
-    point = parseVectPoint(method_point);
+    method = parseMethod(method_point.termedBuf());
+    point = parseVectPoint(method_point.termedBuf());
 
     // reset optional parameters in case we are reconfiguring
     bypass = routing = false;
index 9efe3ba05cedf44f9466d8856f0d1d61ae616ad5..830ab457a16418892761c6ee83df27ddf4134af5 100644 (file)
@@ -8,6 +8,9 @@
 #include "base/TextException.h"
 #include "adaptation/ecap/ServiceRep.h"
 #include "adaptation/ecap/Host.h"
+#include "adaptation/ecap/MessageRep.h"
+#include "HttpRequest.h"
+#include "HttpReply.h"
 
 const libecap::Name Adaptation::Ecap::protocolInternal("internal", libecap::Name::NextId());
 const libecap::Name Adaptation::Ecap::protocolCacheObj("cache_object", libecap::Name::NextId());
@@ -94,6 +97,19 @@ Adaptation::Ecap::Host::closeDebug(std::ostream *debug)
         Debug::finishDebug();
 }
 
+
+Adaptation::Ecap::Host::MessagePtr
+Adaptation::Ecap::Host::newRequest() const
+{
+    return MessagePtr(new Adaptation::Ecap::MessageRep(new HttpRequest));
+}
+
+Adaptation::Ecap::Host::MessagePtr
+Adaptation::Ecap::Host::newResponse() const
+{
+    return MessagePtr(new Adaptation::Ecap::MessageRep(new HttpReply));
+}
+
 void
 Adaptation::Ecap::Host::Register()
 {
index 8d5f32fa02cbbda221cd177e8ed1d9a5f587a052..6ec696b9075005143a010fd6880c00b3c8672103 100644 (file)
@@ -28,6 +28,11 @@ public:
     virtual std::ostream *openDebug(libecap::LogVerbosity lv);
     virtual void closeDebug(std::ostream *debug);
 
+    // Message creation
+    typedef libecap::shared_ptr<libecap::Message> MessagePtr;
+    virtual MessagePtr newRequest() const;
+    virtual MessagePtr newResponse() const;
+
     static void Register(); ///< register adaptation host
 
 private:
index 95f2ae53dc7be10a0eeb054876792a232db1af38..a638049cc9575e209e45480f1ba48a2469f1236f 100644 (file)
@@ -88,7 +88,7 @@ Adaptation::Ecap::XactionRep::swanSong()
         }
     }
 
-    {
+    if (proxyingVb == opOn) {
         BodyPipe::Pointer body_pipe = theVirginRep.raw().body_pipe;
         if (body_pipe != NULL) {
             Must(body_pipe->stillConsuming(this));
index b9f85e60731f54e6be42d52645840b8d5eee9373..8aee8e7cc547e5fa3b6acc0d59a023d0e580d2f3 100644 (file)
@@ -2,6 +2,7 @@
 #include "icap_log.h"
 #include "AccessLogEntry.h"
 #include "log/File.h"
+#include "log/Formats.h"
 
 int IcapLogfileStatus = LOG_DISABLE;
 
@@ -11,12 +12,9 @@ icapLogOpen()
     customlog *log;
 
     for (log = Config.Log.icaplogs; log; log = log->next) {
-        if (log->type == CLF_NONE)
+        if (log->type == Log::Format::CLF_NONE)
             continue;
 
-        if (log->type == CLF_AUTO)
-            log->type = CLF_ICAP_SQUID;
-
         log->logfile = logfileOpen(log->filename, MAX_URL << 1, 1);
 
         IcapLogfileStatus = LOG_ENABLE;
index 73a2b15c8e22a690819ed0cd93ce0ac722a72891..a2c954ec8a7a89ea5c7183afcc0ca4642fcb9dc5 100644 (file)
@@ -147,17 +147,6 @@ AuthNegotiateConfig::parse(AuthConfig * scheme, int n_configured, char *param_st
     } else {
         debugs(29, 0, "AuthNegotiateConfig::parse: unrecognised negotiate auth scheme parameter '" << param_str << "'");
     }
-
-    /*
-     * disable client side request pipelining. There is a race with
-     * Negotiate when the client sends a second request on an Negotiate
-     * connection before the authenticate challenge is sent. With
-     * this patch, the client may fail to authenticate, but squid's
-     * state will be preserved.  Caveats: this should be a post-parse
-     * test, but that can wait for the modular parser to be integrated.
-     */
-    if (authenticate)
-        Config.onoff.pipeline_prefetch = 0;
 }
 
 const char *
index 18f63bffe8b8efb178f95bed8d9d08f7931b570e..b1d2328c6f8392ba1abcb64b6b6c936e80c6c121 100644 (file)
@@ -135,17 +135,6 @@ AuthNTLMConfig::parse(AuthConfig * scheme, int n_configured, char *param_str)
     } else {
         debugs(29, 0, "AuthNTLMConfig::parse: unrecognised ntlm auth scheme parameter '" << param_str << "'");
     }
-
-    /*
-     * disable client side request pipelining. There is a race with
-     * NTLM when the client sends a second request on an NTLM
-     * connection before the authenticate challenge is sent. With
-     * this patch, the client may fail to authenticate, but squid's
-     * state will be preserved.  Caveats: this should be a post-parse
-     * test, but that can wait for the modular parser to be integrated.
-     */
-    if (authenticate)
-        Config.onoff.pipeline_prefetch = 0;
 }
 
 const char *
index 8b241f34613103b650c18ecc74a10a5b9964f8d1..f144bbab9d91417768109ae23c52740e55c386aa 100644 (file)
@@ -69,6 +69,16 @@ AsyncCall::print(std::ostream &os)
         os << "(?" << this << "?)";
 }
 
+void
+AsyncCall::dequeue(AsyncCall::Pointer &head, AsyncCall::Pointer &prev)
+{
+    if (prev != NULL)
+        prev->setNext(Next());
+    else
+        head = Next();
+    setNext(NULL);
+}
+
 bool
 ScheduleCall(const char *fileName, int fileLine, AsyncCall::Pointer &call)
 {
index 01066ca2ce3b4d05af23c468103a47efdd60d4b2..74f2864baec27256474106b4283c3bc52a46fecc 100644 (file)
@@ -58,6 +58,9 @@ public:
 
     void print(std::ostream &os);
 
+    /// remove us from the queue; we are head unless we are queued after prev
+    void dequeue(AsyncCall::Pointer &head, AsyncCall::Pointer &prev);
+
     void setNext(AsyncCall::Pointer aNext) {
         theNext = aNext;
     }
@@ -81,6 +84,10 @@ protected:
 
 private:
     const char *isCanceled; // set to the cancelation reason by cancel()
+
+    // not implemented to prevent nil calls from being passed around and unknowingly scheduled, for now.
+    AsyncCall();
+    AsyncCall(const AsyncCall &);
 };
 
 inline
@@ -119,6 +126,12 @@ public:
                const Dialer &aDialer): AsyncCall(aDebugSection, aDebugLevel, aName),
             dialer(aDialer) {}
 
+    AsyncCallT(const AsyncCallT<Dialer> &o):
+            AsyncCall(o.debugSection, o.debugLevel, o.name),
+            dialer(o.dialer) {}
+
+    ~AsyncCallT() {}
+
     CallDialer *getDialer() { return &dialer; }
 
 protected:
@@ -129,6 +142,9 @@ protected:
     virtual void fire() { dialer.dial(*this); }
 
     Dialer dialer;
+
+private:
+    AsyncCallT & operator=(const AsyncCallT &); // not defined. call assignments not permitted.
 };
 
 template <class Dialer>
index ec9cc517f726d0159e83e59c12d14fa1858cfd75..74e97bba8755f533796c9556b5ae091d882f64ab 100644 (file)
@@ -42,7 +42,7 @@ class CallSubscription: public Subscription
 public:
     /// Must be passed an object. nil pointers are not permitted.
     explicit CallSubscription(const RefCount<Call_> &aCall) : call(aCall) { assert(aCall != NULL); }
-    virtual AsyncCall::Pointer callback() const { return new Call_(call); }
+    virtual AsyncCall::Pointer callback() const { return new Call_(*call); }
 
 private:
     const RefCount<Call_> call; ///< gets copied to create callback calls
index d6621902b3ee9e4a741e0136e0973c34ad3f412b..4f50c8535473e9fd99d4810c2a2a4b5f1cbf1545 100644 (file)
@@ -17,7 +17,7 @@ public:
     /// Delete callback.
     typedef void DCB (T *t);
     TidyPointer(T *t = NULL)
-            :   raw(t), deAllocator(DeAllocator) {}
+            :   raw(t) {}
 public:
     bool operator !() const { return !raw; }
     /// Returns raw and possibly NULL pointer
@@ -48,12 +48,11 @@ private:
     /// Deallocate raw pointer. Become a nil pointer.
     void deletePointer() {
         if (raw) {
-            deAllocator(raw);
+            DeAllocator(raw);
         }
         raw = NULL;
     }
     T *raw; ///< pointer to T object or NULL
-    DCB *deAllocator; ///< cleanup function
 };
 
 /// DeAllocator for pointers that need free(3) from the std C library
index 77c27712627d265f045b4a64a50003cc127da943..9efa10be91fd444fe0690efa046d3423fd978d82 100644 (file)
@@ -47,6 +47,7 @@
 #include "adaptation/ecap/Config.h"
 #endif
 #if USE_SSL
+#include "ssl/support.h"
 #include "ssl/Config.h"
 #endif
 #include "auth/Config.h"
@@ -132,13 +133,9 @@ static const char *const B_GBYTES_STR = "GB";
 
 static const char *const list_sep = ", \t\n\r";
 
-static void parse_logformat(logformat ** logformat_definitions);
 static void parse_access_log(customlog ** customlog_definitions);
 static int check_null_access_log(customlog *customlog_definitions);
-
-static void dump_logformat(StoreEntry * entry, const char *name, logformat * definitions);
 static void dump_access_log(StoreEntry * entry, const char *name, customlog * definitions);
-static void free_logformat(logformat ** definitions);
 static void free_access_log(customlog ** definitions);
 
 static void update_maxobjsize(void);
@@ -422,10 +419,8 @@ parseOneConfigFile(const char *file_name, unsigned int depth)
     if (fp == NULL)
         fatalf("Unable to open configuration file: %s: %s", file_name, xstrerror());
 
-#ifdef _SQUID_WIN32_
-
+#if _SQUID_WINDOWS_
     setmode(fileno(fp), O_TEXT);
-
 #endif
 
     SetConfigFilename(file_name, bool(is_pipe));
@@ -911,6 +906,30 @@ configDoConfigure(void)
     }
 
 #endif
+
+    // prevent infinite fetch loops in the request parser
+    // due to buffer full but not enough data recived to finish parse
+    if (Config.maxRequestBufferSize <= Config.maxRequestHeaderSize) {
+        fatalf("Client request buffer of %u bytes cannot hold a request with %u bytes of headers." \
+               " Change client_request_buffer_max or request_header_max_size limits.",
+               (uint32_t)Config.maxRequestBufferSize, (uint32_t)Config.maxRequestHeaderSize);
+    }
+
+    /*
+     * disable client side request pipelining. There is a race with
+     * Negotiate and NTLM when the client sends a second request on an
+     * connection before the authenticate challenge is sent. With
+     * pipelining OFF, the client may fail to authenticate, but squid's
+     * state will be preserved.
+     */
+    if (Config.onoff.pipeline_prefetch) {
+        AuthConfig *nego = AuthConfig::Find("Negotiate");
+        AuthConfig *ntlm = AuthConfig::Find("NTLM");
+        if ((nego && nego->active()) || (ntlm && ntlm->active())) {
+            debugs(3, DBG_IMPORTANT, "WARNING: pipeline_prefetch breaks NTLM and Negotiate authentication. Forced OFF.");
+            Config.onoff.pipeline_prefetch = 0;
+        }
+    }
 }
 
 /** Parse a line containing an obsolete directive.
@@ -2646,6 +2665,9 @@ dump_refreshpattern(StoreEntry * entry, const char *name, refresh_t * head)
                           (int) (100.0 * head->pct + 0.5),
                           (int) head->max / 60);
 
+        if (head->max_stale >= 0)
+            storeAppendPrintf(entry, " max-stale=%d", head->max_stale);
+
         if (head->flags.refresh_ims)
             storeAppendPrintf(entry, " refresh-ims");
 
@@ -2699,6 +2721,7 @@ parse_refreshpattern(refresh_t ** head)
     time_t max = 0;
     int refresh_ims = 0;
     int store_stale = 0;
+    int max_stale = -1;
 
 #if USE_HTTP_VIOLATIONS
 
@@ -2777,6 +2800,8 @@ parse_refreshpattern(refresh_t ** head)
             refresh_ims = 1;
         } else if (!strcmp(token, "store-stale")) {
             store_stale = 1;
+        } else if (!strncmp(token, "max-stale=", 10)) {
+            max_stale = atoi(token + 10);
 #if USE_HTTP_VIOLATIONS
 
         } else if (!strcmp(token, "override-expire"))
@@ -2804,7 +2829,7 @@ parse_refreshpattern(refresh_t ** head)
 #endif
 
         } else
-            debugs(22, 0, "redreshAddToList: Unknown option '" << pattern << "': " << token);
+            debugs(22, 0, "refreshAddToList: Unknown option '" << pattern << "': " << token);
     }
 
     if ((errcode = regcomp(&comp, pattern, flags)) != 0) {
@@ -2833,6 +2858,8 @@ parse_refreshpattern(refresh_t ** head)
     if (store_stale)
         t->flags.store_stale = 1;
 
+    t->max_stale = max_stale;
+
 #if USE_HTTP_VIOLATIONS
 
     if (override_expire)
@@ -3789,7 +3816,7 @@ dump_generic_http_port(StoreEntry * e, const char *n, const http_port_list * s)
     if (s->name)
         storeAppendPrintf(e, " name=%s", s->name);
 
-#if !USE_HTTP_VIOLATIONS
+#if USE_HTTP_VIOLATIONS
     if (!s->accel && s->ignore_cc)
         storeAppendPrintf(e, " ignore-cc");
 #endif
@@ -3944,6 +3971,9 @@ void
 configFreeMemory(void)
 {
     free_all();
+#if USE_SSL
+    SSL_CTX_free(Config.ssl_client.sslContext);
+#endif
 }
 
 void
@@ -3974,36 +4004,6 @@ strtokFile(void)
 }
 
 #include "AccessLogEntry.h"
-/* TODO: split out parsing somehow ...*/
-static void
-parse_logformat(logformat ** logformat_definitions)
-{
-    logformat *nlf;
-    char *name, *def;
-
-    if ((name = strtok(NULL, w_space)) == NULL)
-        self_destruct();
-
-    if ((def = strtok(NULL, "\r\n")) == NULL) {
-        self_destruct();
-        return;
-    }
-
-    debugs(3, 2, "Logformat for '" << name << "' is '" << def << "'");
-
-    nlf = (logformat *)xcalloc(1, sizeof(logformat));
-
-    nlf->name = xstrdup(name);
-
-    if (!accessLogParseLogFormat(&nlf->format, def)) {
-        self_destruct();
-        return;
-    }
-
-    nlf->next = *logformat_definitions;
-
-    *logformat_definitions = nlf;
-}
 
 static void
 parse_access_log(customlog ** logs)
@@ -4020,19 +4020,19 @@ parse_access_log(customlog ** logs)
     }
 
     if (strcmp(filename, "none") == 0) {
-        cl->type = CLF_NONE;
+        cl->type = Log::Format::CLF_NONE;
         goto done;
     }
 
     if ((logdef_name = strtok(NULL, w_space)) == NULL)
-        logdef_name = "auto";
+        logdef_name = "squid";
 
     debugs(3, 9, "Log definition name '" << logdef_name << "' file '" << filename << "'");
 
     cl->filename = xstrdup(filename);
 
     /* look for the definition pointer corresponding to this name */
-    lf = Config.Log.logformats;
+    lf = Log::TheConfig.logformats;
 
     while (lf != NULL) {
         debugs(3, 9, "Comparing against '" << lf->name << "'");
@@ -4044,18 +4044,25 @@ parse_access_log(customlog ** logs)
     }
 
     if (lf != NULL) {
-        cl->type = CLF_CUSTOM;
+        cl->type = Log::Format::CLF_CUSTOM;
         cl->logFormat = lf;
     } else if (strcmp(logdef_name, "auto") == 0) {
-        cl->type = CLF_AUTO;
+        debugs(0,0, "WARNING: Log format 'auto' no longer exists. Using 'squid' instead.");
+        cl->type = Log::Format::CLF_SQUID;
     } else if (strcmp(logdef_name, "squid") == 0) {
-        cl->type = CLF_SQUID;
+        cl->type = Log::Format::CLF_SQUID;
     } else if (strcmp(logdef_name, "common") == 0) {
-        cl->type = CLF_COMMON;
+        cl->type = Log::Format::CLF_COMMON;
+    } else if (strcmp(logdef_name, "combined") == 0) {
+        cl->type = Log::Format::CLF_COMBINED;
 #if ICAP_CLIENT
     } else if (strcmp(logdef_name, "icap_squid") == 0) {
-        cl->type = CLF_ICAP_SQUID;
+        cl->type = Log::Format::CLF_ICAP_SQUID;
 #endif
+    } else if (strcmp(logdef_name, "useragent") == 0) {
+        cl->type = Log::Format::CLF_USERAGENT;
+    } else if (strcmp(logdef_name, "referrer") == 0) {
+        cl->type = Log::Format::CLF_REFERER;
     } else {
         debugs(3, 0, "Log format '" << logdef_name << "' is not defined");
         self_destruct();
@@ -4077,12 +4084,6 @@ check_null_access_log(customlog *customlog_definitions)
     return customlog_definitions == NULL;
 }
 
-static void
-dump_logformat(StoreEntry * entry, const char *name, logformat * definitions)
-{
-    accessLogDumpLogFormat(entry, name, definitions);
-}
-
 static void
 dump_access_log(StoreEntry * entry, const char *name, customlog * logs)
 {
@@ -4093,36 +4094,40 @@ dump_access_log(StoreEntry * entry, const char *name, customlog * logs)
 
         switch (log->type) {
 
-        case CLF_CUSTOM:
+        case Log::Format::CLF_CUSTOM:
             storeAppendPrintf(entry, "%s %s", log->filename, log->logFormat->name);
             break;
 
-        case CLF_NONE:
+        case Log::Format::CLF_NONE:
             storeAppendPrintf(entry, "none");
             break;
 
-        case CLF_SQUID:
+        case Log::Format::CLF_SQUID:
             storeAppendPrintf(entry, "%s squid", log->filename);
             break;
 
-        case CLF_COMMON:
-            storeAppendPrintf(entry, "%s squid", log->filename);
+        case Log::Format::CLF_COMBINED:
+            storeAppendPrintf(entry, "%s combined", log->filename);
             break;
+
+        case Log::Format::CLF_COMMON:
+            storeAppendPrintf(entry, "%s common", log->filename);
+            break;
+
 #if ICAP_CLIENT
-        case CLF_ICAP_SQUID:
+        case Log::Format::CLF_ICAP_SQUID:
             storeAppendPrintf(entry, "%s icap_squid", log->filename);
             break;
 #endif
-        case CLF_AUTO:
-
-            if (log->aclList)
-                storeAppendPrintf(entry, "%s auto", log->filename);
-            else
-                storeAppendPrintf(entry, "%s", log->filename);
+        case Log::Format::CLF_USERAGENT:
+            storeAppendPrintf(entry, "%s useragent", log->filename);
+            break;
 
+        case Log::Format::CLF_REFERER:
+            storeAppendPrintf(entry, "%s referrer", log->filename);
             break;
 
-        case CLF_UNKNOWN:
+        case Log::Format::CLF_UNKNOWN:
             break;
         }
 
@@ -4133,18 +4138,6 @@ dump_access_log(StoreEntry * entry, const char *name, customlog * logs)
     }
 }
 
-static void
-free_logformat(logformat ** definitions)
-{
-    while (*definitions) {
-        logformat *format = *definitions;
-        *definitions = format->next;
-        safe_free(format->name);
-        accessLogFreeLogFormat(&format->format);
-        xfree(format);
-    }
-}
-
 static void
 free_access_log(customlog ** definitions)
 {
@@ -4153,7 +4146,7 @@ free_access_log(customlog ** definitions)
         *definitions = log->next;
 
         log->logFormat = NULL;
-        log->type = CLF_UNKNOWN;
+        log->type = Log::Format::CLF_UNKNOWN;
 
         if (log->aclList)
             aclDestroyAclList(&log->aclList);
index 782dc6f2a7ccd7fd991a3fdf4ea3df5cd79ef94d..3c50a27db23fe011d19c287c56480162fbfd173d 100644 (file)
@@ -81,7 +81,7 @@ cacheEntryCreate(const StoreSwapLogData * s)
     CacheEntry *e = xcalloc(1, sizeof(CacheEntry));
     assert(s);
     /* e->s = *s; */
-    xmemcpy(e->key_arr, s->key, SQUID_MD5_DIGEST_LENGTH);
+    memcpy(e->key_arr, s->key, SQUID_MD5_DIGEST_LENGTH);
     e->key = &e->key_arr[0];
     return e;
 }
@@ -146,9 +146,8 @@ cacheIndexAddLog(CacheIndex * idx, const char *fname)
         return 0;
     }
 
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
     setmode(fileno(file), O_BINARY);
-
 #endif
 
     scanned_count = cacheIndexScan(idx, fname, file);
index 95c9d27c5bebeaadcf1d982cc8e8138b1bca227f..95c4ac8f67440ca3aad036d9140ed8a79a084912 100644 (file)
@@ -221,18 +221,21 @@ CacheManager::ParseUrl(const char *url)
 void
 CacheManager::ParseHeaders(const HttpRequest * request, Mgr::ActionParams &params)
 {
-    const char *basic_cookie;  /* base 64 _decoded_ user:passwd pair */
-    const char *passwd_del;
     assert(request);
 
     params.httpMethod = request->method.id();
     params.httpFlags = request->flags;
 
-    basic_cookie = request->header.getAuth(HDR_AUTHORIZATION, "Basic");
+#if HAVE_AUTH_MODULE_BASIC
+    // TODO: use the authentication system decode to retrieve these details properly.
+
+    /* base 64 _decoded_ user:passwd pair */
+    const char *basic_cookie = request->header.getAuth(HDR_AUTHORIZATION, "Basic");
 
     if (!basic_cookie)
         return;
 
+    const char *passwd_del;
     if (!(passwd_del = strchr(basic_cookie, ':'))) {
         debugs(16, DBG_IMPORTANT, "CacheManager::ParseHeaders: unknown basic_cookie format '" << basic_cookie << "'");
         return;
@@ -242,9 +245,10 @@ CacheManager::ParseHeaders(const HttpRequest * request, Mgr::ActionParams &param
     params.userName.limitInit(basic_cookie, passwd_del - basic_cookie);
     params.password = passwd_del + 1;
 
-    /* warning: this prints decoded password which maybe not what you want to do @?@ @?@ */
+    /* warning: this prints decoded password which maybe not be what you want to do @?@ @?@ */
     debugs(16, 9, "CacheManager::ParseHeaders: got user: '" <<
            params.userName << "' passwd: '" << params.password << "'");
+#endif
 }
 
 /**
@@ -336,11 +340,13 @@ CacheManager::Start(int fd, HttpRequest * request, StoreEntry * entry)
 
         errorStateFree(errState);
 
+#if HAVE_AUTH_MODULE_BASIC
         /*
          * add Authenticate header using action name as a realm because
          * password depends on the action
          */
         rep->header.putAuth("Basic", actionName);
+#endif
 
         /* store the reply */
         entry->replaceHttpReply(rep);
index 8a958044b37d3f8b88a400627a8af5f6acf77eaf..cc705f0ad782d7c76d69121c236e2f4aeec150e9 100644 (file)
@@ -770,7 +770,9 @@ DOC_START
 
        acl aclname maxconn number
          # This will be matched when the client's IP address has
-         # more than <number> HTTP connections established. [fast]
+         # more than <number> TCP connections established. [fast]
+         # NOTE: This only measures direct TCP links so X-Forwarded-For
+         # indirect clients are not counted.
 
        acl aclname max_user_ip [-s] number
          # This will be matched when the user attempts to log in from more
@@ -943,6 +945,9 @@ DOC_START
        Controls whether the indirect client address
        (see follow_x_forwarded_for) is used instead of the
        direct client address in acl matching.
+
+       NOTE: maxconn ACL considers direct TCP links and indirect
+             clients will always have zero. So no match.
 DOC_END
 
 NAME: delay_pool_uses_indirect_client
@@ -1765,14 +1770,18 @@ DOC_START
        an additional ACL needs to be used which ensures the IPv6-bound traffic
        is never forced or permitted out the IPv4 interface.
 
+       # IPv6 destination test along with a dummy access control to perofrm the required DNS
+       # This MUST be place before any ALLOW rules.
        acl to_ipv6 dst ipv6
-       tcp_outgoing_address 2002::c001 good_service_net to_ipv6
+       http_access deny ipv6 !all
+
+       tcp_outgoing_address 2001:db8::c001 good_service_net to_ipv6
        tcp_outgoing_address 10.1.0.2 good_service_net !to_ipv6
 
-       tcp_outgoing_address 2002::beef normal_service_net to_ipv6
+       tcp_outgoing_address 2001:db8::beef normal_service_net to_ipv6
        tcp_outgoing_address 10.1.0.1 normal_service_net !to_ipv6
 
-       tcp_outgoing_address 2002::1 to_ipv6
+       tcp_outgoing_address 2001:db8::1 to_ipv6
        tcp_outgoing_address 10.1.0.3 !to_ipv6
 
        WARNING:
@@ -2714,8 +2723,13 @@ DOC_START
 
        no-store, no new objects should be stored to this cache_dir
 
-       max-size=n, refers to the max object size this storedir supports.
-       It is used to initially choose the storedir to dump the object.
+       min-size=n, refers to the min object size in bytes this cache_dir
+       will accept.  It's used to restrict a cache_dir to only store
+       large objects (e.g. aufs) while other storedirs are optimized
+       for smaller objects (e.g. COSS). Defaults to 0.
+
+       max-size=n, refers to the max object size in bytes this cache_dir
+       supports.  It is used to select the cache_dir to store the object.
        Note: To make optimal use of the max-size limits you should order
        the cache_dir lines with the smallest max-size value first and the
        ones with no max-size specification last.
@@ -2812,7 +2826,7 @@ COMMENT_END
 
 NAME: logformat
 TYPE: logformat
-LOC: Config.Log.logformats
+LOC: Log::TheConfig
 DEFAULT: none
 DOC_START
        Usage:
@@ -2854,6 +2868,7 @@ DOC_START
                >a      Client source IP address
                >A      Client FQDN
                >p      Client source port
+               >eui    Client EUI (MAC address, EUI-48 or EUI-64 identifier)
                <A      Server IP address or peer name
                la      Local IP address (http_port)
                lp      Local port number (http_port)
@@ -2957,10 +2972,18 @@ DOC_START
 
        The default formats available (which do not need re-defining) are:
 
-logformat squid %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt
-logformat squidmime %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt [%>h] [%<h]
-logformat common %>a %ui %un [%tl] "%rm %ru HTTP/%rv" %>Hs %<st %Ss:%Sh
-logformat combined %>a %ui %un [%tl] "%rm %ru HTTP/%rv" %>Hs %<st "%{Referer}>h" "%{User-Agent}>h" %Ss:%Sh
+logformat squid      %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt
+logformat common     %>a %ui %un [%tl] "%rm %ru HTTP/%rv" %>Hs %<st %Ss:%Sh
+logformat combined   %>a %ui %un [%tl] "%rm %ru HTTP/%rv" %>Hs %<st "%{Referer}>h" "%{User-Agent}>h" %Ss:%Sh
+logformat referrer   %ts.%03tu %>a %{Referer}>h %ru
+logformat useragent  %>a [%tl] "%{User-Agent}>h"
+
+       When the log_mime_hdrs directive is set to ON. The squid, common and combined
+       formats have a safely encoded copy of the mime headers appended to each line
+       within a pair of brackets.
+
+       The common and combined formats are not quite true to the Apache definition.
+       The logs from Squid contain an extra status and hierarchy code appended.
 DOC_END
 
 NAME: access_log cache_access_log
@@ -3116,7 +3139,7 @@ DOC_START
          L<data>\n - logfile data
          R\n - rotate file
          T\n - truncate file
-         O\n - repoen file
+         O\n - reopen file
          F\n - flush file
          r<n>\n - set rotate count to <n>
          b<n>\n - 1 = buffer output, 0 = don't buffer output
@@ -3221,16 +3244,9 @@ DOC_START
 DOC_END
 
 NAME: emulate_httpd_log
-COMMENT: on|off
-TYPE: onoff
-DEFAULT: off
-LOC: Config.onoff.common_log
+TYPE: obsolete
 DOC_START
-       The Cache can emulate the log file format which many 'httpd'
-       programs use.  To disable/enable this emulation, set
-       emulate_httpd_log to 'off' or 'on'.  The default
-       is to use the native log format since it includes useful
-       information Squid-specific log analyzers use.
+       Replace this with an access_log directive using the format 'common' or 'combined'.
 DOC_END
 
 NAME: log_ip_on_direct
@@ -3268,27 +3284,15 @@ DOC_START
 DOC_END
 
 NAME: useragent_log
-TYPE: string
-LOC: Config.Log.useragent
-DEFAULT: none
-IFDEF: USE_USERAGENT_LOG
+TYPE: obsolete
 DOC_START
-       Squid will write the User-Agent field from HTTP requests
-       to the filename specified here.  By default useragent_log
-       is disabled.
+       Replace this with an access_log directive using the format 'useragent'.
 DOC_END
 
 NAME: referer_log referrer_log
-TYPE: string
-LOC: Config.Log.referer
-DEFAULT: none
-IFDEF: USE_REFERER_LOG
+TYPE: obsolete
 DOC_START
-       Squid will write the Referer field from HTTP requests to the
-       filename specified here.  By default referer_log is disabled.
-       Note that "referer" is actually a misspelling of "referrer"
-       however the misspelt version has been accepted into the HTTP RFCs
-       and we accept both.
+       Replace this with an access_log directive using the format 'referrer'.
 DOC_END
 
 NAME: pid_filename
@@ -3317,14 +3321,9 @@ DOC_START
 DOC_END
 
 NAME: forward_log
-IFDEF: WIP_FWD_LOG
-TYPE: string
-DEFAULT: none
-LOC: Config.Log.forward
+TYPE: obsolete
 DOC_START
-       Logs the server-side requests.
-
-       This is currently work in progress.
+       Use a regular access.log with ACL limiting it to MISS events.
 DOC_END
 
 NAME: strip_query_terms
@@ -3484,6 +3483,29 @@ DOC_START
        Requires ftp_passive to be ON (default) for any effect.
 DOC_END
 
+NAME: ftp_eprt
+TYPE: onoff
+DEFAULT: on
+LOC: Config.Ftp.eprt
+DOC_START
+       FTP Protocol extensions permit the use of a special "EPRT" command.
+
+       This extension provides a protocol neutral alternative to the
+       IPv4-only PORT command. When supported it enables active FTP data
+       channels over IPv6 and efficient NAT handling.
+
+       Turning this OFF will prevent EPRT being attempted and will skip
+       straight to using PORT for IPv4 servers.
+
+       Some devices are known to not handle this extension correctly and
+       may result in crashes. Devices which suport EPRT enough to fail
+       cleanly will result in Squid attempting PORT anyway. This directive
+       should only be disabled when EPRT results in device failures.
+
+       WARNING: Doing so will convert Squid back to the old behavior with all
+       the related problems with external NAT devices/layers and IPv4-only FTP.
+DOC_END
+
 NAME: ftp_sanitycheck
 TYPE: onoff
 DEFAULT: on
@@ -3697,6 +3719,17 @@ DOC_START
        See http://wiki.squid-cache.org/SquidFaq/SquidAcl for details.
 DOC_END
 
+NAME: max_stale
+COMMENT: time-units
+TYPE: time_t
+LOC: Config.maxStale
+DEFAULT: 1 week
+DOC_START
+       This option puts an upper limit on how stale content Squid
+       will serve from the cache if cache validation fails.
+       Can be overriden by the refresh_pattern max-stale option.
+DOC_END
+
 NAME: refresh_pattern
 TYPE: refreshpattern
 LOC: Config.Refresh
@@ -3729,6 +3762,7 @@ DOC_START
                 ignore-must-revalidate
                 ignore-private
                 ignore-auth
+                max-stale=NN
                 refresh-ims
                 store-stale
 
@@ -3794,6 +3828,10 @@ DOC_START
                not cache such responses because they usually can't be
                reused. Note that such responses will be stale by default.
 
+               max-stale=NN provide a maximum staleness factor. Squid won't
+               serve objects more stale than this even if it failed to
+               validate the object. Default: use the max_stale global limit.
+
        Basically a cached object is:
 
                FRESH if expires < now, else STALE
@@ -4044,6 +4082,17 @@ DOC_START
        be no limit imposed.
 DOC_END
 
+NAME: client_request_buffer_max_size
+COMMENT: (bytes)
+TYPE: b_size_t
+DEFAULT: 512 KB
+LOC: Config.maxRequestBufferSize
+DOC_START
+       This specifies the maximum buffer size of a client request.
+       It prevents squid eating too much memory when somebody uploads
+       a large file.
+DOC_END
+
 NAME: chunked_request_body_max_size
 COMMENT: (bytes)
 TYPE: b_int64_t
@@ -5917,12 +5966,18 @@ DOC_START
            you may also specify them by your custom file name:
            Example: deny_info ERR_CUSTOM_ACCESS_DENIED bad_guys
 
+       By defaut Squid will send "403 Forbidden". A different 4xx or 5xx
+       may be specified by prefixing the file name with the code and a colon.
+       e.g. 404:ERR_CUSTOM_ACCESS_DENIED
+
        Alternatively you can tell Squid to reset the TCP connection
        by specifying TCP_RESET.
 
        Or you can specify an error URL or URL pattern. The browsers will
-       get redirected (302) to the specified URL after formatting tags have
-       been replaced.
+       get redirected to the specified URL after formatting tags have
+       been replaced. Redirect will be done with 302 or 307 according to
+       HTTP/1.1 specs. A different 3xx code may be specified by prefixing
+       the URL. e.g. 303:http://example.com/
 
        URL FORMAT TAGS:
                %a      - username (if available. Password NOT included)
@@ -7067,7 +7122,7 @@ DOC_START
        X-Forwarded-For header.
 
        If set to "truncate", Squid will remove all existing
-       X-Forwarded-For entries, and place itself as the sole entry.
+       X-Forwarded-For entries, and place the client IP as the sole entry.
 DOC_END
 
 NAME: cachemgr_passwd
@@ -7286,6 +7341,8 @@ DOC_START
 
        Defaults to off for bandwidth management and access logging
        reasons.
+
+       WARNING: pipelining breaks NTLM and Negotiate/Kerberos authentication.
 DOC_END
 
 NAME: high_response_time_warning
index 95dbc5eeaf3f64fc7ad771d942d1b75bce26cba8..1f940076249edddc9f994c3f72336c291e19eb92 100644 (file)
@@ -239,7 +239,7 @@ main(int argc, char *argv[])
         exit(1);
     }
 
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
     setmode(fileno(fp), O_TEXT);
 
 #endif
@@ -465,9 +465,8 @@ main(int argc, char *argv[])
         exit(1);
     }
 
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
     setmode(fileno(fp), O_TEXT);
-
 #endif
 
     fprintf(fp,
@@ -501,9 +500,8 @@ main(int argc, char *argv[])
         exit(1);
     }
 
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
     setmode(fileno(fp), O_TEXT);
-
 #endif
 
     gen_conf(entries, fp, 1);
@@ -514,7 +512,7 @@ main(int argc, char *argv[])
         perror(conf_filename_short);
         exit(1);
     }
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
     setmode(fileno(fp), O_TEXT);
 #endif
     gen_conf(entries, fp, 0);
index a26081be0d3c131ce1315c33b6d2113e9d268c66..aa5464ab39947ed8ce220ec10c1071d5eda2baf8 100644 (file)
@@ -23,11 +23,9 @@ BEGIN {
        define["USE_ICMP"]="--enable-icmp"
        define["USE_IDENT"]="--enable-ident-lookups"
        define["USE_LOADABLE_MODULES"]="--enable-loadable-modules"
-       define["USE_REFERER_LOG"]="--enable-referer-log"
        define["USE_SQUID_ESI"]="--enable-esi"
        define["USE_SSL"]="--enable-ssl"
        define["USE_UNLINKD"]="--enable-unlinkd"
-       define["USE_USERAGENT_LOG"]="--enable-useragent-log"
        define["USE_WCCP"]="--enable-wccp"
        define["USE_WCCPv2"]="--enable-wccpv2"
        define["USE_QOS_TOS"]="--enable-zph-qos"
index d476980693475bbfd3af5bd7522d9a24133a664d..90e5d513556f1f14cd6cd0e8ca6c92c43e68ca0d 100644 (file)
@@ -36,6 +36,7 @@
 #include "event.h"
 #include "ClientInfo.h"
 #include "ip/Address.h"
+#include "log/Tokens.h"
 #include "mgr/Registration.h"
 #include "SquidMath.h"
 #include "SquidTime.h"
index 58eb9e7bdde5845c2d5c00d3063cf06e0d9b1df5..5e18b7b2c2b0a72d046cb5523ae9025026ee21e0 100644 (file)
 
 #include "acl/FilledChecklist.h"
 #include "auth/UserRequest.h"
+#include "base/TextException.h"
 #include "ChunkedCodingParser.h"
 #include "client_side.h"
 #include "client_side_reply.h"
 #include "client_side_request.h"
+#if USE_DELAY_POOLS
+#include "ClientInfo.h"
+#endif
 #include "ClientRequestContext.h"
 #include "clientStream.h"
 #include "comm.h"
+#include "CommCalls.h"
+#include "comm/Loops.h"
 #include "comm/Write.h"
-#include "comm/ListenStateData.h"
-#include "base/TextException.h"
+#include "comm/TcpAcceptor.h"
 #include "ConnectionDetail.h"
 #include "eui/Config.h"
 #include "fde.h"
 #include "ident/Config.h"
 #include "ident/Ident.h"
 #include "ip/Intercept.h"
+#include "ipc/FdNotes.h"
 #include "ipc/StartListening.h"
 #include "MemBuf.h"
 #include "MemObject.h"
 #include "ProtoPort.h"
 #include "rfc1738.h"
 #include "SquidTime.h"
-#include "Store.h"
-
-#if USE_DELAY_POOLS
-#include "ClientInfo.h"
-#endif
-
 #if USE_SSL
 #include "ssl/context_storage.h"
 #include "ssl/helper.h"
+#include "ssl/support.h"
 #include "ssl/gadgets.h"
 #endif
 #if USE_SSL_CRTD
 #include "ssl/crtd_message.h"
 #include "ssl/certificate_db.h"
 #endif
+#include "Store.h"
 
 #if HAVE_LIMITS
 #include <limits>
 #define comm_close comm_lingering_close
 #endif
 
-/// dials clientHttpConnectionOpened or clientHttpsConnectionOpened call
+/// dials clientListenerConnectionOpened call
 class ListeningStartedDialer: public CallDialer, public Ipc::StartListeningCb
 {
 public:
-    typedef void (*Handler)(int fd, int errNo, http_port_list *portCfg);
-    ListeningStartedDialer(Handler aHandler, http_port_list *aPortCfg):
-            handler(aHandler), portCfg(aPortCfg) {}
+    typedef void (*Handler)(int fd, int flags, int errNo, http_port_list *portCfg, const Ipc::FdNoteId note, const Subscription::Pointer &sub);
+    ListeningStartedDialer(Handler aHandler, int openFlags, http_port_list *aPortCfg, const Ipc::FdNoteId note, const Subscription::Pointer &aSub):
+            handler(aHandler), portCfg(aPortCfg), portTypeNote(note), commOpenListenerFlags(openFlags), sub(aSub) {}
 
     virtual void print(std::ostream &os) const {
         startPrint(os) <<
@@ -148,20 +150,19 @@ public:
     }
 
     virtual bool canDial(AsyncCall &) const { return true; }
-    virtual void dial(AsyncCall &) { (handler)(fd, errNo, portCfg); }
+    virtual void dial(AsyncCall &) { (handler)(fd, commOpenListenerFlags, errNo, portCfg, portTypeNote, sub); }
 
 public:
     Handler handler;
 
 private:
-    http_port_list *portCfg; ///< from Config.Sockaddr.http
+    http_port_list *portCfg;   ///< from Config.Sockaddr.http
+    Ipc::FdNoteId portTypeNote;    ///< Type of IPC socket being opened
+    int commOpenListenerFlags; ///< flags used by comm_open_listener
+    Subscription::Pointer sub; ///< The handler to be subscribed for this connetion listener
 };
 
-
-static void clientHttpConnectionOpened(int fd, int errNo, http_port_list *s);
-#if USE_SSL
-static void clientHttpsConnectionOpened(int fd, int errNo, http_port_list *s);
-#endif
+static void clientListenerConnectionOpened(int fd, int flags, int errNo, http_port_list *s, const Ipc::FdNoteId portTypeNote, const Subscription::Pointer &sub);
 
 /* our socket-related context */
 
@@ -255,7 +256,8 @@ ConnStateData::readSomeData()
 
     debugs(33, 4, "clientReadSomeData: FD " << fd << ": reading request...");
 
-    makeSpaceAvailable();
+    if (!maybeMakeSpaceAvailable())
+        return;
 
     typedef CommCbMemFunT<ConnStateData, CommIoCbParams> Dialer;
     reader = JobCallback(33, 5,
@@ -824,12 +826,6 @@ clientIsContentLengthValid(HttpRequest * r)
 {
     switch (r->method.id()) {
 
-    case METHOD_PUT:
-
-    case METHOD_POST:
-        /* PUT/POST requires a request entity */
-        return (r->content_length >= 0);
-
     case METHOD_GET:
 
     case METHOD_HEAD:
@@ -1059,7 +1055,7 @@ ClientSocketContext::packRange(StoreIOBuffer const &source, MemBuf * mb)
              * intersection of "have" and "need" ranges must not be empty
              */
             assert(http->out.offset < i->currentSpec()->offset + i->currentSpec()->length);
-            assert(http->out.offset + available.size() > i->currentSpec()->offset);
+            assert(http->out.offset + (int64_t)available.size() > i->currentSpec()->offset);
 
             /*
              * put boundary and headers at the beginning of a range in a
@@ -1117,7 +1113,7 @@ ClientSocketContext::packRange(StoreIOBuffer const &source, MemBuf * mb)
         /* adjust for not to be transmitted bytes */
         http->out.offset = nextOffset;
 
-        if (available.size() <= skip)
+        if (available.size() <= (uint64_t)skip)
             return;
 
         available.start += skip;
@@ -2248,13 +2244,22 @@ ConnStateData::getAvailableBufferLength() const
     return result;
 }
 
-void
-ConnStateData::makeSpaceAvailable()
+bool
+ConnStateData::maybeMakeSpaceAvailable()
 {
     if (getAvailableBufferLength() < 2) {
-        in.buf = (char *)memReallocBuf(in.buf, in.allocatedSize * 2, &in.allocatedSize);
+        size_t newSize;
+        if (in.allocatedSize >= Config.maxRequestBufferSize) {
+            debugs(33, 4, "request buffer full: client_request_buffer_max_size=" << Config.maxRequestBufferSize);
+            return false;
+        }
+        if ((newSize=in.allocatedSize * 2) > Config.maxRequestBufferSize) {
+            newSize=Config.maxRequestBufferSize;
+        }
+        in.buf = (char *)memReallocBuf(in.buf, newSize, &in.allocatedSize);
         debugs(33, 2, "growing request buffer: notYetUsed=" << in.notYetUsed << " size=" << in.allocatedSize);
     }
+    return true;
 }
 
 void
@@ -2331,8 +2336,7 @@ connNoteUseOfBuffer(ConnStateData* conn, size_t byteCount)
      */
 
     if (conn->in.notYetUsed > 0)
-        xmemmove(conn->in.buf, conn->in.buf + byteCount,
-                 conn->in.notYetUsed);
+        memmove(conn->in.buf, conn->in.buf + byteCount, conn->in.notYetUsed);
 }
 
 /// respond with ERR_TOO_BIG if request header exceeds request_header_max_size
@@ -2623,7 +2627,7 @@ static void
 connStripBufferWhitespace (ConnStateData * conn)
 {
     while (conn->in.notYetUsed > 0 && xisspace(conn->in.buf[0])) {
-        xmemmove(conn->in.buf, conn->in.buf + 1, conn->in.notYetUsed - 1);
+        memmove(conn->in.buf, conn->in.buf + 1, conn->in.notYetUsed - 1);
         --conn->in.notYetUsed;
     }
 }
@@ -2826,7 +2830,7 @@ ConnStateData::handleReadData(char *buf, size_t size)
     char *current_buf = in.addressToReadInto();
 
     if (buf != current_buf)
-        xmemmove(current_buf, buf, size);
+        memmove(current_buf, buf, size);
 
     in.notYetUsed += size;
 
@@ -2968,7 +2972,10 @@ ConnStateData::abortChunkedRequestBody(const err_type error)
 void
 ConnStateData::noteMoreBodySpaceAvailable(BodyPipe::Pointer )
 {
-    handleRequestBodyData();
+    if (!handleRequestBodyData())
+        return;
+
+    readSomeData();
 }
 
 void
@@ -3032,7 +3039,7 @@ ConnStateData::requestTimeout(const CommTimeoutCbParams &io)
         /*
          * Aha, but we don't want a read handler!
          */
-        commSetSelect(io.fd, COMM_SELECT_READ, NULL, NULL, 0);
+        Comm::SetSelect(io.fd, COMM_SELECT_READ, NULL, NULL, 0);
     }
 
 #else
@@ -3109,14 +3116,14 @@ connStateCreate(const Ip::Address &peer, const Ip::Address &me, int fd, http_por
 
 /** Handle a new connection on HTTP socket. */
 void
-httpAccept(int sock, int newfd, ConnectionDetail *details,
-           comm_err_t flag, int xerrno, void *data)
+httpAccept(int, int newfd, ConnectionDetail *details, comm_err_t flag, int xerrno, void *data)
 {
     http_port_list *s = (http_port_list *)data;
     ConnStateData *connState = NULL;
 
     if (flag != COMM_OK) {
-        debugs(33, 1, "httpAccept: FD " << sock << ": accept failure: " << xstrerr(xerrno));
+        // Its possible the call was still queued when the client disconnected
+        debugs(33, 2, "httpAccept: FD " << s->listenFd << ": accept failure: " << xstrerr(xerrno));
         return;
     }
 
@@ -3249,11 +3256,11 @@ clientNegotiateSSL(int fd, void *data)
         switch (ssl_error) {
 
         case SSL_ERROR_WANT_READ:
-            commSetSelect(fd, COMM_SELECT_READ, clientNegotiateSSL, conn, 0);
+            Comm::SetSelect(fd, COMM_SELECT_READ, clientNegotiateSSL, conn, 0);
             return;
 
         case SSL_ERROR_WANT_WRITE:
-            commSetSelect(fd, COMM_SELECT_WRITE, clientNegotiateSSL, conn, 0);
+            Comm::SetSelect(fd, COMM_SELECT_WRITE, clientNegotiateSSL, conn, 0);
             return;
 
         case SSL_ERROR_SYSCALL:
@@ -3355,15 +3362,14 @@ clientNegotiateSSL(int fd, void *data)
 
 /** handle a new HTTPS connection */
 static void
-httpsAccept(int sock, int newfd, ConnectionDetail *details,
-            comm_err_t flag, int xerrno, void *data)
+httpsAccept(int, int newfd, ConnectionDetail *details, comm_err_t flag, int xerrno, void *data)
 {
     https_port_list *s = (https_port_list *)data;
     SSL_CTX *sslContext = s->staticSslContext.get();
 
     if (flag != COMM_OK) {
-        errno = xerrno;
-        debugs(33, 1, "httpsAccept: FD " << sock << ": accept failure: " << xstrerr(xerrno));
+        // Its possible the call was still queued when the client disconnected
+        debugs(33, 2, "httpsAccept: FD " << s->listenFd << ": accept failure: " << xstrerr(xerrno));
         return;
     }
 
@@ -3402,7 +3408,7 @@ httpsAccept(int sock, int newfd, ConnectionDetail *details,
         commSetTcpKeepalive(newfd, s->http.tcp_keepalive.idle, s->http.tcp_keepalive.interval, s->http.tcp_keepalive.timeout);
     }
 
-    commSetSelect(newfd, COMM_SELECT_READ, clientNegotiateSSL, connState, 0);
+    Comm::SetSelect(newfd, COMM_SELECT_READ, clientNegotiateSSL, connState, 0);
 
     clientdbEstablished(details->peer, 1);
 
@@ -3519,10 +3525,8 @@ ConnStateData::getSslContextDone(SSL_CTX * sslContext, bool isNew)
     // commSetTimeout() was called for this request before we switched.
 
     // Disable the client read handler until peer selection is complete
-    commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
-
-    commSetSelect(fd, COMM_SELECT_READ, clientNegotiateSSL, this, 0);
-
+    Comm::SetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
+    Comm::SetSelect(fd, COMM_SELECT_READ, clientNegotiateSSL, this, 0);
     switchedToHttps_ = true;
     return true;
 }
@@ -3548,7 +3552,7 @@ ConnStateData::switchToHttps(const char *host)
 
 /// check FD after clientHttp[s]ConnectionOpened, adjust HttpSockets as needed
 static bool
-OpenedHttpSocket(int fd, const char *msgIfFail)
+OpenedHttpSocket(int fd, const Ipc::FdNoteId portType)
 {
     if (fd < 0) {
         Must(NHttpSockets > 0); // we tried to open some
@@ -3556,7 +3560,7 @@ OpenedHttpSocket(int fd, const char *msgIfFail)
         Must(HttpSockets[NHttpSockets] < 0); // no extra fds received
 
         if (!NHttpSockets) // we could not open any listen sockets at all
-            fatal(msgIfFail);
+            fatalf("Unable to open %s",FdNote(portType));
 
         return false;
     }
@@ -3612,13 +3616,16 @@ clientHttpConnectionsOpen(void)
         const int openFlags = COMM_NONBLOCKING |
                               (s->spoof_client_ip ? COMM_TRANSPARENT : 0);
 
-        AsyncCall::Pointer callback = asyncCall(33,2,
-                                                "clientHttpConnectionOpened",
-                                                ListeningStartedDialer(&clientHttpConnectionOpened, s));
-        Ipc::StartListening(SOCK_STREAM, IPPROTO_TCP, s->s, openFlags,
-                            Ipc::fdnHttpSocket, callback);
+        // setup the subscriptions such that new connections accepted by listenConn are handled by HTTP
+        typedef CommCbFunPtrCallT<CommAcceptCbPtrFun> AcceptCall;
+        RefCount<AcceptCall> subCall = commCbCall(5, 5, "httpAccept", CommAcceptCbPtrFun(httpAccept, s));
+        Subscription::Pointer sub = new CallSubscription<AcceptCall>(subCall);
+
+        AsyncCall::Pointer listenCall = asyncCall(33,2, "clientListenerConnectionOpened",
+                                        ListeningStartedDialer(&clientListenerConnectionOpened, openFlags, s, Ipc::fdnHttpSocket, sub));
+        Ipc::StartListening(SOCK_STREAM, IPPROTO_TCP, s->s, openFlags, Ipc::fdnHttpSocket, listenCall);
 
-        HttpSockets[NHttpSockets++] = -1; // set in clientHttpConnectionOpened
+        HttpSockets[NHttpSockets++] = -1; // set in clientListenerConnectionOpened
     }
 
 #if USE_SSL
@@ -3631,27 +3638,27 @@ clientHttpConnectionsOpen(void)
 
 /// process clientHttpConnectionsOpen result
 static void
-clientHttpConnectionOpened(int fd, int, http_port_list *s)
+clientListenerConnectionOpened(int fd, int flags, int errNo, http_port_list *s, const Ipc::FdNoteId portTypeNote, const Subscription::Pointer &sub)
 {
-    if (!OpenedHttpSocket(fd, "Cannot open HTTP Port"))
+    s->listenFd = fd;
+    if (!OpenedHttpSocket(s->listenFd, portTypeNote))
         return;
 
     Must(s);
+    Must(s->listenFd >= 0);
 
-    AsyncCall::Pointer call = commCbCall(5,5, "SomeCommAcceptHandler(httpAccept)",
-                                         CommAcceptCbPtrFun(httpAccept, s));
+    // TCP: setup a job to handle accept() with subscribed handler
+    AsyncJob::Start(new Comm::TcpAcceptor(s->listenFd, s->s, flags, FdNote(portTypeNote), sub));
 
-    s->listener = new Comm::ListenStateData(fd, call, true);
-
-    debugs(1, 1, "Accepting " <<
+    debugs(1, 1, "Accepting" <<
            (s->intercepted ? " intercepted" : "") <<
            (s->spoof_client_ip ? " spoofing" : "") <<
            (s->sslBump ? " bumpy" : "") <<
            (s->accel ? " accelerated" : "")
-           << " HTTP connections at " << s->s
-           << ", FD " << fd << "." );
+           << FdNote(portTypeNote) << " connections at "
+           << " FD " << s->listenFd << " on " << s->s);
 
-    Must(AddOpenedHttpSocket(fd)); // otherwise, we have received a fd we did not ask for
+    Must(AddOpenedHttpSocket(s->listenFd)); // otherwise, we have received a fd we did not ask for
 }
 
 #if USE_SSL
@@ -3673,35 +3680,23 @@ clientHttpsConnectionsOpen(void)
             continue;
         }
 
-        AsyncCall::Pointer call = asyncCall(33, 2, "clientHttpsConnectionOpened",
-                                            ListeningStartedDialer(&clientHttpsConnectionOpened, &s->http));
-
-        Ipc::StartListening(SOCK_STREAM, IPPROTO_TCP, s->http.s, COMM_NONBLOCKING,
-                            Ipc::fdnHttpsSocket, call);
-
-        HttpSockets[NHttpSockets++] = -1;
-    }
-}
-
-/// process clientHttpsConnectionsOpen result
-static void
-clientHttpsConnectionOpened(int fd, int, http_port_list *s)
-{
-    if (!OpenedHttpSocket(fd, "Cannot open HTTPS Port"))
-        return;
-
-    Must(s);
+        const int openFlags = COMM_NONBLOCKING |
+                              (s->spoof_client_ip ? COMM_TRANSPARENT : 0);
 
-    AsyncCall::Pointer call = commCbCall(5,5, "SomeCommAcceptHandler(httpsAccept)",
-                                         CommAcceptCbPtrFun(httpsAccept, s));
+        // setup the subscriptions such that new connections accepted by listenConn are handled by HTTPS
+        typedef CommCbFunPtrCallT<CommAcceptCbPtrFun> AcceptCall;
+        RefCount<AcceptCall> subCall = commCbCall(5, 5, "httpsAccept", CommAcceptCbPtrFun(httpsAccept, s));
+        Subscription::Pointer sub = new CallSubscription<AcceptCall>(subCall);
 
-    s->listener = new Comm::ListenStateData(fd, call, true);
+        AsyncCall::Pointer listenCall = asyncCall(33, 2, "clientListenerConnectionOpened",
+                                        ListeningStartedDialer(&clientListenerConnectionOpened, openFlags,
+                                                               &s->http, Ipc::fdnHttpsSocket, sub));
 
-    debugs(1, 1, "Accepting HTTPS connections at " << s->s << ", FD " << fd << ".");
+        Ipc::StartListening(SOCK_STREAM, IPPROTO_TCP, s->s, openFlags, Ipc::fdnHttpsSocket, listenCall);
 
-    Must(AddOpenedHttpSocket(fd)); // otherwise, we have received a fd we did not ask for
+        HttpSockets[NHttpSockets++] = -1;
+    }
 }
-
 #endif
 
 void
@@ -3720,19 +3715,19 @@ void
 clientHttpConnectionsClose(void)
 {
     for (http_port_list *s = Config.Sockaddr.http; s; s = s->next) {
-        if (s->listener) {
-            debugs(1, 1, "FD " << s->listener->fd << " Closing HTTP connection");
-            delete s->listener;
-            s->listener = NULL;
+        if (s->listenFd >= 0) {
+            debugs(1, 1, "FD " << s->listenFd << " Closing HTTP connection");
+            comm_close(s->listenFd);
+            s->listenFd = -1;
         }
     }
 
 #if USE_SSL
     for (http_port_list *s = Config.Sockaddr.https; s; s = s->next) {
-        if (s->listener) {
-            debugs(1, 1, "FD " << s->listener->fd << " Closing HTTPS connection");
-            delete s->listener;
-            s->listener = NULL;
+        if (s->listenFd >= 0) {
+            debugs(1, 1, "FD " << s->listenFd << " Closing HTTPS connection");
+            comm_close(s->listenFd);
+            s->listenFd = -1;
         }
     }
 #endif
index 707b748eac0ecdafe5a0c0f9a953c62a338087ba..ab7b6c3cec0164be8e18b35650d0e9c3e564ed16 100644 (file)
@@ -50,9 +50,6 @@ class clientStreamNode;
 class ChunkedCodingParser;
 class HttpParser;
 
-template <class T>
-class Range;
-
 class ClientSocketContext : public RefCountable
 {
 
@@ -153,7 +150,7 @@ public:
     void freeAllContexts();
     void notifyAllContexts(const int xerrno); ///< tell everybody about the err
     void readNextRequest();
-    void makeSpaceAvailable();
+    bool maybeMakeSpaceAvailable();
     ClientSocketContext::Pointer getCurrentContext() const;
     void addContextToQueue(ClientSocketContext * context);
     int getConcurrentRequestCount() const;
index afcaafaa4fa86aec6d57e0ab4064bbfc948ddc62..d6ada937d2289ac07d574759cfbeb3c829cfe776 100644 (file)
@@ -56,6 +56,7 @@
 #include "HttpReply.h"
 #include "HttpRequest.h"
 #include "ip/QosConfig.h"
+#include "log/Tokens.h"
 #include "MemObject.h"
 #include "SquidTime.h"
 #include "StoreClient.h"
@@ -683,7 +684,7 @@ clientReplyContext::processOnlyIfCachedMiss()
 void
 clientReplyContext::processConditional(StoreIOBuffer &result)
 {
-    StoreEntry *e = http->storeEntry();
+    StoreEntry *const e = http->storeEntry();
 
     if (e->getReply()->sline.status != HTTP_OK) {
         debugs(88, 4, "clientReplyContext::processConditional: Reply code " <<
@@ -716,12 +717,12 @@ clientReplyContext::processConditional(StoreIOBuffer &result)
 
         if (!r.flags.ims) {
             // RFC 2616: if If-None-Match matched and there is no IMS,
-            // reply with 412 Precondition Failed
-            sendPreconditionFailedError();
+            // reply with 304 Not Modified or 412 Precondition Failed
+            sendNotModifiedOrPreconditionFailedError();
             return;
         }
 
-        // otherwise check IMS below to decide if we reply with 412
+        // otherwise check IMS below to decide if we reply with 304 or 412
         matchedIfNoneMatch = true;
     }
 
@@ -734,29 +735,14 @@ clientReplyContext::processConditional(StoreIOBuffer &result)
         }
 
         if (matchedIfNoneMatch) {
-            // If-None-Match matched, reply with 412 Precondition Failed
-            sendPreconditionFailedError();
+            // If-None-Match matched, reply with 304 Not Modified or
+            // 412 Precondition Failed
+            sendNotModifiedOrPreconditionFailedError();
             return;
         }
 
         // otherwise reply with 304 Not Modified
-        const time_t timestamp = e->timestamp;
-        HttpReply *const temprep = e->getReply()->make304();
-        http->logType = LOG_TCP_IMS_HIT;
-        removeClientStoreReference(&sc, http);
-        createStoreEntry(http->request->method, request_flags());
-        e = http->storeEntry();
-        // Copy timestamp from the original entry so the 304
-        // reply has a meaningful Age: header.
-        e->timestamp = timestamp;
-        e->replaceHttpReply(temprep);
-        e->complete();
-        /*
-         * TODO: why put this in the store and then serialise it and
-         * then parse it again. Simply mark the request complete in
-         * our context and write the reply struct to the client side.
-         */
-        triggerInitialStoreRead();
+        sendNotModified();
     }
 }
 
@@ -1865,6 +1851,42 @@ clientReplyContext::sendPreconditionFailedError()
     startError(err);
 }
 
+/// send 304 (Not Modified) to client
+void
+clientReplyContext::sendNotModified()
+{
+    StoreEntry *e = http->storeEntry();
+    const time_t timestamp = e->timestamp;
+    HttpReply *const temprep = e->getReply()->make304();
+    http->logType = LOG_TCP_IMS_HIT;
+    removeClientStoreReference(&sc, http);
+    createStoreEntry(http->request->method, request_flags());
+    e = http->storeEntry();
+    // Copy timestamp from the original entry so the 304
+    // reply has a meaningful Age: header.
+    e->timestamp = timestamp;
+    e->replaceHttpReply(temprep);
+    e->complete();
+    /*
+     * TODO: why put this in the store and then serialise it and
+     * then parse it again. Simply mark the request complete in
+     * our context and write the reply struct to the client side.
+     */
+    triggerInitialStoreRead();
+}
+
+/// send 304 (Not Modified) or 412 (Precondition Failed) to client
+/// depending on request method
+void
+clientReplyContext::sendNotModifiedOrPreconditionFailedError()
+{
+    if (http->request->method == METHOD_GET ||
+            http->request->method == METHOD_HEAD)
+        sendNotModified();
+    else
+        sendPreconditionFailedError();
+}
+
 void
 clientReplyContext::processReplyAccess ()
 {
@@ -2034,7 +2056,7 @@ clientReplyContext::sendMoreData (StoreIOBuffer result)
     if (buf != result.data) {
         /* we've got to copy some data */
         assert(result.length <= next()->readBuffer.length);
-        xmemcpy(buf, result.data, result.length);
+        memcpy(buf, result.data, result.length);
         body_buf = buf;
     }
 
index c1787f736dbd651e0338c61fd26a18668577bbbc..77c023fb3f90f2694a36635085c7b94a95d851db 100644 (file)
@@ -138,6 +138,8 @@ private:
 
     void sendBodyTooLargeError();
     void sendPreconditionFailedError();
+    void sendNotModified();
+    void sendNotModifiedOrPreconditionFailedError();
 
     StoreEntry *old_entry;
     store_client *old_sc;      /* ... for entry to be validated */
index 280828ea1cc7a956460b636d18a2dae4a9e1067b..f59086eca4bffaea829d08990514f9cff0c14b1e 100644 (file)
 #include "HttpReply.h"
 #include "HttpRequest.h"
 #include "ip/QosConfig.h"
+#include "log/Tokens.h"
 #include "MemObject.h"
 #include "ProtoPort.h"
 #include "Store.h"
 #include "SquidTime.h"
 #include "wordlist.h"
 #include "err_detail_type.h"
+#if USE_SSL
+#include "ssl/support.h"
+#endif
 
 
 #if LINGERING_CLOSE
@@ -951,21 +955,6 @@ clientInterpretRequestHeaders(ClientHttpRequest * http)
         s.clean();
     }
 
-    /**
-     \todo  --enable-useragent-log and --enable-referer-log. We should
-            probably drop those two as the custom log formats accomplish pretty much the same thing..
-    */
-#if USE_USERAGENT_LOG
-    if ((str = req_hdr->getStr(HDR_USER_AGENT)))
-        logUserAgent(fqdnFromAddr(http->getConn()->log_addr), str);
-
-#endif
-#if USE_REFERER_LOG
-
-    if ((str = req_hdr->getStr(HDR_REFERER)))
-        logReferer(fqdnFromAddr(http->getConn()->log_addr), str, http->log_uri);
-
-#endif
 #if USE_FORW_VIA_DB
 
     if (req_hdr->has(HDR_X_FORWARDED_FOR)) {
@@ -1459,7 +1448,7 @@ ClientHttpRequest::noteAdaptationQueryAbort(bool final)
 {
     clearAdaptation(virginHeadSource);
     assert(!adaptedBodySource);
-    handleAdaptationFailure(ERR_DETAIL_ICAP_REQMOD_ABORT, !final);
+    handleAdaptationFailure(ERR_DETAIL_CLT_REQMOD_ABORT, !final);
 }
 
 void
@@ -1512,7 +1501,16 @@ ClientHttpRequest::noteBodyProducerAborted(BodyPipe::Pointer)
 {
     assert(!virginHeadSource);
     stopConsumingFrom(adaptedBodySource);
-    handleAdaptationFailure(ERR_DETAIL_ICAP_RESPMOD_CLT_SIDE_BODY);
+
+    debugs(85,3, HERE << "REQMOD body production failed");
+    if (request_satisfaction_mode) { // too late to recover or serve an error
+        request->detailError(ERR_ICAP_FAILURE, ERR_DETAIL_CLT_REQMOD_RESP_BODY);
+        const int fd = getConn()->fd;
+        Must(fd >= 0);
+        comm_close(fd); // drastic, but we may be writing a response already
+    } else {
+        handleAdaptationFailure(ERR_DETAIL_CLT_REQMOD_REQ_BODY);
+    }
 }
 
 void
index 7cc28e5b7a6ec31f598187e6c5f0770ddb35dd99..b92dc8e92f1808174cafc85d1594641af30d124d 100644 (file)
@@ -40,8 +40,9 @@
 #include "comm/AcceptLimiter.h"
 #include "comm/comm_internal.h"
 #include "comm/IoCallback.h"
+#include "comm/Loops.h"
 #include "comm/Write.h"
-#include "comm/ListenStateData.h"
+#include "comm/TcpAcceptor.h"
 #include "CommIO.h"
 #include "CommRead.h"
 #include "ConnectionDetail.h"
 #include "ip/QosConfig.h"
 #include "ip/tools.h"
 #include "ClientInfo.h"
+#if USE_SSL
+#include "ssl/support.h"
+#endif
 
 #include "cbdata.h"
-#if defined(_SQUID_CYGWIN_)
+#if _SQUID_CYGWIN_
 #include <sys/ioctl.h>
 #endif
 #ifdef HAVE_NETINET_TCP_H
@@ -140,7 +144,7 @@ fd_debug_t *fdd_table = NULL;
 bool
 isOpen(const int fd)
 {
-    return fd_table[fd].flags.open != 0;
+    return fd >= 0 && fd_table[fd].flags.open != 0;
 }
 
 /**
@@ -180,7 +184,7 @@ commHandleRead(int fd, void *data)
     }
 
     /* Nope, register for some more IO */
-    commSetSelect(fd, COMM_SELECT_READ, commHandleRead, data, 0);
+    Comm::SetSelect(fd, COMM_SELECT_READ, commHandleRead, data, 0);
 }
 
 /**
@@ -216,7 +220,7 @@ comm_read(int fd, char *buf, int size, AsyncCall::Pointer &callback)
 
     /* Queue the read */
     ccb->setCallback(Comm::IOCB_READ, callback, (char *)buf, NULL, size);
-    commSetSelect(fd, COMM_SELECT_READ, commHandleRead, ccb, 0);
+    Comm::SetSelect(fd, COMM_SELECT_READ, commHandleRead, ccb, 0);
 }
 
 /**
@@ -316,7 +320,7 @@ comm_read_cancel(int fd, IOCB *callback, void *data)
     cb->cancel("old comm_read_cancel");
 
     /* And the IO event */
-    commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
+    Comm::SetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
 }
 
 void
@@ -346,7 +350,7 @@ comm_read_cancel(int fd, AsyncCall::Pointer &callback)
     cb->cancel("comm_read_cancel");
 
     /* And the IO event */
-    commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
+    Comm::SetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
 }
 
 
@@ -933,7 +937,7 @@ ConnectStateData::commResetFD()
         F->local_addr.FreeAddrInfo(AI);
         return 0;
     }
-    commResetSelect(fd);
+    Comm::ResetSelect(fd);
 
     close(fd2);
 
@@ -1033,7 +1037,7 @@ ConnectStateData::connect()
 
     case COMM_INPROGRESS:
         debugs(5, 5, HERE << "FD " << fd << ": COMM_INPROGRESS");
-        commSetSelect(fd, COMM_SELECT_WRITE, ConnectStateData::Connect, this, 0);
+        Comm::SetSelect(fd, COMM_SELECT_WRITE, ConnectStateData::Connect, this, 0);
         break;
 
     case COMM_OK:
@@ -1353,7 +1357,7 @@ comm_lingering_close(int fd)
 
     fd_note(fd, "lingering close");
     commSetTimeout(fd, 10, commLingerTimeout, NULL);
-    commSetSelect(fd, COMM_SELECT_READ, commLingerClose, NULL, 0);
+    Comm::SetSelect(fd, COMM_SELECT_READ, commLingerClose, NULL, 0);
 }
 
 #endif
@@ -1465,11 +1469,11 @@ _comm_close(int fd, char const *file, int line)
 
     // notify read/write handlers after canceling select reservations, if any
     if (COMMIO_FD_WRITECB(fd)->active()) {
-        commSetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0);
+        Comm::SetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0);
         COMMIO_FD_WRITECB(fd)->finish(COMM_ERR_CLOSING, errno);
     }
     if (COMMIO_FD_READCB(fd)->active()) {
-        commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
+        Comm::SetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
         COMMIO_FD_READCB(fd)->finish(COMM_ERR_CLOSING, errno);
     }
 
@@ -1578,8 +1582,8 @@ comm_remove_close_handler(int fd, PF * handler, void *data)
     debugs(5, 5, "comm_remove_close_handler: FD " << fd << ", handler=" <<
            handler << ", data=" << data);
 
-    AsyncCall::Pointer p;
-    for (p = fd_table[fd].closeHandler; p != NULL; p = p->Next()) {
+    AsyncCall::Pointer p, prev = NULL;
+    for (p = fd_table[fd].closeHandler; p != NULL; prev = p, p = p->Next()) {
         typedef CommCbFunPtrCallT<CommCloseCbPtrFun> Call;
         const Call *call = dynamic_cast<const Call*>(p.getRaw());
         if (!call) // method callbacks have their own comm_remove_close_handler
@@ -1592,9 +1596,10 @@ comm_remove_close_handler(int fd, PF * handler, void *data)
     }
 
     // comm_close removes all close handlers so our handler may be gone
-    if (p != NULL)
+    if (p != NULL) {
+        p->dequeue(fd_table[fd].closeHandler, prev);
         p->cancel("comm_remove_close_handler");
-    // TODO: should we remove the handler from the close handlers list?
+    }
 }
 
 // remove method-based close handler
@@ -1605,15 +1610,11 @@ comm_remove_close_handler(int fd, AsyncCall::Pointer &call)
     debugs(5, 5, "comm_remove_close_handler: FD " << fd << ", AsyncCall=" << call);
 
     // comm_close removes all close handlers so our handler may be gone
-    // TODO: should we remove the handler from the close handlers list?
-#if 0
-    // Check to see if really exist  the given AsyncCall in comm_close handlers
-    // TODO: optimize: this slow code is only needed for the assert() below
-    AsyncCall::Pointer p;
-    for (p = fd_table[fd].closeHandler; p != NULL && p != call; p = p->Next());
-    assert(p == call);
-#endif
+    AsyncCall::Pointer p, prev = NULL;
+    for (p = fd_table[fd].closeHandler; p != NULL && p != call; prev = p, p = p->Next());
 
+    if (p != NULL)
+        p->dequeue(fd_table[fd].closeHandler, prev);
     call->cancel("comm_remove_close_handler");
 }
 
@@ -1660,12 +1661,10 @@ commSetNonBlocking(int fd)
     int flags;
     int dummy = 0;
 #endif
-#ifdef _SQUID_WIN32_
-
+#if _SQUID_WINDOWS_
     int nonblocking = TRUE;
 
-#ifdef _SQUID_CYGWIN_
-
+#if _SQUID_CYGWIN_
     if (fd_table[fd].type != FD_PIPE) {
 #endif
 
@@ -1674,8 +1673,7 @@ commSetNonBlocking(int fd)
             return COMM_ERROR;
         }
 
-#ifdef _SQUID_CYGWIN_
-
+#if _SQUID_CYGWIN_
     } else {
 #endif
 #endif
@@ -1692,10 +1690,8 @@ commSetNonBlocking(int fd)
         }
 
 #endif
-#ifdef _SQUID_CYGWIN_
-
+#if _SQUID_CYGWIN_
     }
-
 #endif
     fd_table[fd].flags.nonblocking = 1;
 
@@ -1810,6 +1806,9 @@ comm_init(void)
     conn_close_pool = memPoolCreate("close_handler", sizeof(close_handler));
 
     TheHalfClosed = new DescriptorSet;
+
+    /* setup the select loop module */
+    Comm::SelectLoopInit();
 }
 
 void
@@ -1851,7 +1850,7 @@ commHandleWriteHelper(void * data)
                 !fd_table[head].closing()) {
 
             // wait for the head descriptor to become ready for writing
-            commSetSelect(head, COMM_SELECT_WRITE, Comm::HandleWrite, ccb, 0);
+            Comm::SetSelect(head, COMM_SELECT_WRITE, Comm::HandleWrite, ccb, 0);
             clientInfo->selectWaiting = true;
             return;
         }
@@ -2154,7 +2153,7 @@ checkTimeouts(void)
         if (writeTimedOut(fd)) {
             // We have an active write callback and we are timed out
             debugs(5, 5, "checkTimeouts: FD " << fd << " auto write timeout");
-            commSetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0);
+            Comm::SetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0);
             COMMIO_FD_WRITECB(fd)->finish(COMM_ERROR, ETIMEDOUT);
         } else if (AlreadyTimedOut(F))
             continue;
@@ -2184,7 +2183,7 @@ void CommIO::Initialise()
     fd_open(DoneFD, FD_PIPE, "async-io completetion event: threads");
     commSetNonBlocking(DoneReadFD);
     commSetNonBlocking(DoneFD);
-    commSetSelect(DoneReadFD, COMM_SELECT_READ, NULLFDHandler, NULL, 0);
+    Comm::SetSelect(DoneReadFD, COMM_SELECT_READ, NULLFDHandler, NULL, 0);
     Initialised = true;
 }
 
@@ -2215,7 +2214,7 @@ void
 CommIO::NULLFDHandler(int fd, void *data)
 {
     FlushPipe();
-    commSetSelect(fd, COMM_SELECT_READ, NULLFDHandler, NULL, 0);
+    Comm::SetSelect(fd, COMM_SELECT_READ, NULLFDHandler, NULL, 0);
 }
 
 void
@@ -2458,7 +2457,7 @@ CommSelectEngine::checkEvents(int timeout)
         checkTimeouts();
     }
 
-    switch (comm_select(timeout)) {
+    switch (Comm::DoSelect(timeout)) {
 
     case COMM_OK:
 
index ed3217c8b82b0f3012c5ff292cb6bf3a87e3e21c..fb206c93de3a944940feb47c0321b8c9d7818480 100644 (file)
@@ -61,9 +61,6 @@ SQUIDCEXTERN int comm_open_listener(int sock_type, int proto, Ip::Address &addr,
 SQUIDCEXTERN int comm_openex(int, int, Ip::Address &, int, tos_t tos, nfmark_t nfmark, const char *);
 SQUIDCEXTERN u_short comm_local_port(int fd);
 
-SQUIDCEXTERN void commSetSelect(int, unsigned int, PF *, void *, time_t);
-SQUIDCEXTERN void commResetSelect(int);
-
 SQUIDCEXTERN int comm_udp_sendto(int sock, const Ip::Address &to, const void *buf, int buflen);
 SQUIDCEXTERN void commCallCloseHandlers(int fd);
 SQUIDCEXTERN int commSetTimeout(int fd, int, PF *, void *);
@@ -73,13 +70,6 @@ SQUIDCEXTERN void commCloseAllSockets(void);
 SQUIDCEXTERN void checkTimeouts(void);
 
 
-/*
- * comm_select.c
- */
-SQUIDCEXTERN void comm_select_init(void);
-SQUIDCEXTERN comm_err_t comm_select(int);
-SQUIDCEXTERN void comm_quick_poll_required(void);
-
 class ConnectionDetail;
 typedef void IOACB(int fd, int nfd, ConnectionDetail *details, comm_err_t flag, int xerrno, void *data);
 extern void comm_add_close_handler(int fd, PF *, void *);
index 7881db0348afa300fce9286a761da5ff6282d66d..d0f5763e0f08c4e2bf72ad8f2a9fbbf6327a9577 100644 (file)
@@ -1,6 +1,6 @@
 #include "config.h"
 #include "comm/AcceptLimiter.h"
-#include "comm/ListenStateData.h"
+#include "comm/TcpAcceptor.h"
 #include "fde.h"
 
 Comm::AcceptLimiter Comm::AcceptLimiter::Instance_;
@@ -11,22 +11,41 @@ Comm::AcceptLimiter &Comm::AcceptLimiter::Instance()
 }
 
 void
-Comm::AcceptLimiter::defer(Comm::ListenStateData *afd)
+Comm::AcceptLimiter::defer(Comm::TcpAcceptor *afd)
 {
     afd->isLimited++;
     debugs(5, 5, HERE << "FD " << afd->fd << " x" << afd->isLimited);
     deferred.push_back(afd);
 }
 
+void
+Comm::AcceptLimiter::removeDead(const Comm::TcpAcceptor *afd)
+{
+    for (unsigned int i = 0; i < deferred.size() && afd->isLimited > 0; i++) {
+        if (deferred[i] == afd) {
+            deferred[i]->isLimited--;
+            deferred[i] = NULL; // fast. kick() will skip empty entries later.
+            debugs(5, 5, HERE << "FD " << afd->fd << " x" << afd->isLimited);
+        }
+    }
+}
+
 void
 Comm::AcceptLimiter::kick()
 {
+    // TODO: this could be optimized further with an iterator to search
+    //       looking for first non-NULL, followed by dumping the first N
+    //       with only one shift()/pop_front operation
+
     debugs(5, 5, HERE << " size=" << deferred.size());
-    if (deferred.size() > 0 && fdNFree() >= RESERVED_FD) {
-        debugs(5, 5, HERE << " doing one.");
+    while (deferred.size() > 0 && fdNFree() >= RESERVED_FD) {
         /* NP: shift() is equivalent to pop_front(). Giving us a FIFO queue. */
-        ListenStateData *temp = deferred.shift();
-        temp->isLimited--;
-        temp->acceptNext();
+        TcpAcceptor *temp = deferred.shift();
+        if (temp != NULL) {
+            debugs(5, 5, HERE << " doing one.");
+            temp->isLimited--;
+            temp->acceptNext();
+            break;
+        }
     }
 }
index 57313b142c1161af76df115a2495e663bfe803fa..3d5540f7e474cc3ab84556287ad36e0cfd886341 100644 (file)
@@ -6,7 +6,7 @@
 namespace Comm
 {
 
-class ListenStateData;
+class TcpAcceptor;
 
 /**
  * FIFO Queue holding listener socket handlers which have been activated
@@ -25,7 +25,10 @@ public:
     static AcceptLimiter &Instance();
 
     /** delay accepting a new client connection. */
-    void defer(Comm::ListenStateData *afd);
+    void defer(Comm::TcpAcceptor *afd);
+
+    /** remove all records of an acceptor. Only to be called by the ConnAcceptor::swanSong() */
+    void removeDead(const Comm::TcpAcceptor *afd);
 
     /** try to accept and begin processing any delayed client connections. */
     void kick();
@@ -34,7 +37,7 @@ private:
     static AcceptLimiter Instance_;
 
     /** FIFO queue */
-    Vector<Comm::ListenStateData*> deferred;
+    Vector<Comm::TcpAcceptor*> deferred;
 };
 
 }; // namepace Comm
index 4e5b2bdf560b7f3a90d2cd84366f004dc8c394aa..4026737754f8837cfe4e1ab8e09d7f860e976ed0 100644 (file)
@@ -1,6 +1,7 @@
 #include "config.h"
 #include "ClientInfo.h"
 #include "comm/IoCallback.h"
+#include "comm/Loops.h"
 #include "comm/Write.h"
 #include "CommCalls.h"
 #include "fde.h"
@@ -65,7 +66,7 @@ Comm::IoCallback::selectOrQueueWrite()
     }
 #endif
 
-    commSetSelect(fd, COMM_SELECT_WRITE, Comm::HandleWrite, this, 0);
+    SetSelect(fd, COMM_SELECT_WRITE, Comm::HandleWrite, this, 0);
 }
 
 void
index 9ce281a0ec431ace0cea377ce2264c7a88bb69c0..1d2b770672d047d20741998f107c70506102ae45 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef _SQUID_COMM_IOCALLBACK_H
 #define _SQUID_COMM_IOCALLBACK_H
 
-#include "config.h"
 #include "base/AsyncCall.h"
 #include "comm_err_t.h"
 
diff --git a/src/comm/ListenStateData.h b/src/comm/ListenStateData.h
deleted file mode 100644 (file)
index b5b5872..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-#ifndef SQUID_LISTENERSTATEDATA_H
-#define SQUID_LISTENERSTATEDATA_H
-
-#include "base/AsyncCall.h"
-#include "comm.h"
-#if HAVE_MAP
-#include <map>
-#endif
-
-class ConnectionDetail;
-
-namespace Comm
-{
-
-class ListenStateData
-{
-
-public:
-    ListenStateData(int fd, AsyncCall::Pointer &call, bool accept_many);
-    ListenStateData(const ListenStateData &r); // not implemented.
-    ~ListenStateData();
-
-    void subscribe(AsyncCall::Pointer &call);
-    void acceptNext();
-    void notify(int newfd, comm_err_t flag, const ConnectionDetail &details);
-
-    int fd;
-
-    /// errno code of the last accept() or listen() action if one occurred.
-    int errcode;
-
-    /// whether this socket is delayed and on the AcceptLimiter queue.
-    int32_t isLimited;
-
-private:
-    /// Method to test if there are enough file escriptors to open a new client connection
-    /// if not the accept() will be postponed
-    static bool okToAccept();
-
-    /// Method callback for whenever an FD is ready to accept a client connection.
-    static void doAccept(int fd, void *data);
-
-    void acceptOne();
-    int oldAccept(ConnectionDetail &details);
-
-    AsyncCall::Pointer theCallback;
-    bool mayAcceptMore;
-
-    void setListen();
-};
-
-} // namespace Comm
-
-#endif /* SQUID_LISTENERSTATEDATA_H */
diff --git a/src/comm/Loops.h b/src/comm/Loops.h
new file mode 100644 (file)
index 0000000..915abba
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef _SQUID_SRC_COMM_LOOPS_H
+#define _SQUID_SRC_COMM_LOOPS_H
+
+#include "comm_err_t.h"
+
+/* Comm layer select loops API.
+ *
+ * These API functions must be implemented by all FD IO loops used by Squid.
+ * Defines are provided short-term for legacy code. These will disappear soon.
+ */
+
+namespace Comm
+{
+
+/// Initialize the module on Squid startup
+extern void SelectLoopInit(void);
+
+/// Mark an FD to be watched for its IO status.
+extern void SetSelect(int, unsigned int, PF *, void *, time_t);
+
+/// reset/undo/unregister the watch for an FD which was set by Comm::SetSelect()
+extern void ResetSelect(int);
+
+/** Perform a select() or equivalent call.
+ * This is used by the main select loop engine to check for FD with IO available.
+ */
+extern comm_err_t DoSelect(int);
+
+extern void QuickPollRequired(void);
+
+} // namespace Comm
+
+#endif /* _SQUID_SRC_COMM_LOOPS_H */
index 6a2c3f38716c589fb58fc125cf15cc792e03fd2c..cdb8f5032a8dcbf072fd4e0c1edaa524de3ea9d3 100644 (file)
@@ -7,8 +7,15 @@ noinst_LTLIBRARIES = libcomm.la
 libcomm_la_SOURCES= \
        AcceptLimiter.cc \
        AcceptLimiter.h \
-       ListenStateData.cc \
-       ListenStateData.h \
+       Loops.h \
+       ModDevPoll.cc \
+       ModEpoll.cc \
+       ModKqueue.cc \
+       ModPoll.cc \
+       ModSelect.cc \
+       ModSelectWin32.cc \
+       TcpAcceptor.cc \
+       TcpAcceptor.h \
        \
        IoCallback.cc \
        IoCallback.h \
similarity index 96%
rename from src/comm_devpoll.cc
rename to src/comm/ModDevPoll.cc
index c42ecea31ff29eb6b53a8e49f87aaa93e75774a4..7cf65131a0eff10918269694e44d3ce54e3ffea8 100644 (file)
  * Last modified 2010-10-08
  */
 
-
-#include "squid.h"
-
 /*
  * There are several poll types in Squid, ALL of which are compiled and linked
  * in. Thus conditional compile-time flags are used to prevent the different
  * modules from creating several versions of the same function simultaneously.
  */
 
+#include "config.h"
+
 #if USE_DEVPOLL
 
-#include "Store.h"
+#include "squid.h"
+#include "comm/Loops.h"
 #include "fde.h"
 #include "mgr/Registration.h"
 #include "SquidTime.h"
+#include "Store.h"
 
 #if HAVE_SYS_DEVPOLL_H
 /* Solaris /dev/poll support, see "man -s 7D poll" */
@@ -198,7 +199,7 @@ commDevPollRegisterWithCacheManager(void)
  * Allocates memory, opens /dev/poll device handle.
  */
 void
-comm_select_init(void)
+Comm::SelectLoopInit(void)
 {
     /* allocate memory first before attempting to open poll device */
     /* This tracks the FD devpoll offset+state */
@@ -243,8 +244,7 @@ comm_select_init(void)
  * @param timeout if non-zero then timeout relative to now
  */
 void
-commSetSelect(int fd, unsigned int type, PF * handler,
-              void *client_data, time_t timeout)
+Comm::SetSelect(int fd, unsigned int type, PF * handler, void *client_data, time_t timeout)
 {
     assert(fd >= 0);
     debugs(
@@ -325,10 +325,10 @@ commSetSelect(int fd, unsigned int type, PF * handler,
  * @param fd file descriptor to clear polling on
  */
 void
-commResetSelect(int fd)
+Comm::ResetSelect(int fd)
 {
-    commSetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0);
-    commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
+    SetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0);
+    SetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
 }
 
 
@@ -346,7 +346,7 @@ commResetSelect(int fd)
  * @param msec milliseconds to poll for (limited by max_poll_time)
  */
 comm_err_t
-comm_select(int msec)
+Comm::DoSelect(int msec)
 {
     int num, i;
     fde *F;
@@ -432,7 +432,7 @@ comm_select(int msec)
                     HERE << "no read handler for FD " << fd
                 );
                 // remove interest since no handler exist for this event.
-                commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
+                SetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
             }
         }
 
@@ -456,7 +456,7 @@ comm_select(int msec)
                     HERE << "no write handler for FD " << fd
                 );
                 // remove interest since no handler exist for this event.
-                commSetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0);
+                SetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0);
             }
         }
     }
@@ -465,9 +465,8 @@ comm_select(int msec)
     return COMM_OK;
 }
 
-
 void
-comm_quick_poll_required(void)
+Comm::QuickPollRequired(void)
 {
     max_poll_time = 10;
 }
similarity index 86%
rename from src/comm_epoll.cc
rename to src/comm/ModEpoll.cc
index d46279c206cc13d370198bc1cd2bea4c79543a29..af9790ace8f6ad382b7d12e9435203a527a40ab0 100644 (file)
  *
  */
 
+#include "config.h"
+
+#if USE_EPOLL
+
 #include "squid.h"
-#include "comm_epoll.h"
-#include "mgr/Registration.h"
-#include "Store.h"
+#include "comm/Loops.h"
 #include "fde.h"
+#include "mgr/Registration.h"
 #include "SquidTime.h"
-
-#if USE_EPOLL
+#include "Store.h"
 
 #define DEBUG_EPOLL 0
 
@@ -79,15 +81,12 @@ static void commEPollRegisterWithCacheManager(void);
 
 
 /*
- * comm_select_init
- *
  * This is a needed exported function which will be called to initialise
  * the network loop code.
  */
 void
-comm_select_init(void)
+Comm::SelectLoopInit(void)
 {
-
     pevents = (struct epoll_event *) xmalloc(SQUID_MAXFD * sizeof(struct epoll_event));
 
     if (!pevents) {
@@ -121,25 +120,21 @@ static const char* epolltype_atoi(int x)
     }
 }
 
-/*
- * comm_setselect
- *
+/**
  * This is a needed exported function which will be called to register
  * and deregister interest in a pending IO state for a given FD.
- *
  */
 void
-commSetSelect(int fd, unsigned int type, PF * handler,
-              void *client_data, time_t timeout)
+Comm::SetSelect(int fd, unsigned int type, PF * handler, void *client_data, time_t timeout)
 {
     fde *F = &fd_table[fd];
     int epoll_ctl_type = 0;
 
     struct epoll_event ev;
     assert(fd >= 0);
-    debugs(5, DEBUG_EPOLL ? 0 : 8, "commSetSelect(FD " << fd << ",type=" << type <<
-           ",handler=" << handler << ",client_data=" << client_data <<
-           ",timeout=" << timeout << ")");
+    debugs(5, DEBUG_EPOLL ? 0 : 8, HERE << "FD " << fd << ", type=" << type <<
+           ", handler=" << handler << ", client_data=" << client_data <<
+           ", timeout=" << timeout);
 
     if (RUNNING_ON_VALGRIND) {
         /* Keep valgrind happy.. complains about uninitialized bytes otherwise */
@@ -198,7 +193,7 @@ commSetSelect(int fd, unsigned int type, PF * handler,
         F->epoll_state = ev.events;
 
         if (epoll_ctl(kdpfd, epoll_ctl_type, fd, &ev) < 0) {
-            debugs(5, DEBUG_EPOLL ? 0 : 8, "commSetSelect: epoll_ctl(," << epolltype_atoi(epoll_ctl_type) <<
+            debugs(5, DEBUG_EPOLL ? 0 : 8, HERE << "epoll_ctl(," << epolltype_atoi(epoll_ctl_type) <<
                    ",,): failed on FD " << fd << ": " << xstrerror());
         }
     }
@@ -208,11 +203,11 @@ commSetSelect(int fd, unsigned int type, PF * handler,
 }
 
 void
-commResetSelect(int fd)
+Comm::ResetSelect(int fd)
 {
     fde *F = &fd_table[fd];
     F->epoll_state = 0;
-    commSetSelect(fd, 0, NULL, NULL, 0);
+    SetSelect(fd, 0, NULL, NULL, 0);
 }
 
 
@@ -235,8 +230,7 @@ commIncomingStats(StoreEntry * sentry)
     statHistDump(&f->select_fds_hist, sentry, statHistIntDumper);
 }
 
-/*
- * comm_select
+/**
  * Check all connections for new connections and input data that is to be
  * processed. Also check for connections with data queued and whether we can
  * write it out.
@@ -246,9 +240,8 @@ commIncomingStats(StoreEntry * sentry)
  * comm_setselect and fd_table[] and calls callbacks for IO ready
  * events.
  */
-
 comm_err_t
-comm_select(int msec)
+Comm::DoSelect(int msec)
 {
     int num, i,fd;
     fde *F;
@@ -291,7 +284,7 @@ comm_select(int msec)
     for (i = 0, cevents = pevents; i < num; i++, cevents++) {
         fd = cevents->data.fd;
         F = &fd_table[fd];
-        debugs(5, DEBUG_EPOLL ? 0 : 8, "comm_select(): got FD " << fd << " events=" <<
+        debugs(5, DEBUG_EPOLL ? 0 : 8, HERE << "got FD " << fd << " events=" <<
                std::hex << cevents->events << " monitoring=" << F->epoll_state <<
                " F->read_handler=" << F->read_handler << " F->write_handler=" << F->write_handler);
 
@@ -299,7 +292,7 @@ comm_select(int msec)
 
         if (cevents->events & (EPOLLIN|EPOLLHUP|EPOLLERR) || F->flags.read_pending) {
             if ((hdl = F->read_handler) != NULL) {
-                debugs(5, DEBUG_EPOLL ? 0 : 8, "comm_select(): Calling read handler on FD " << fd);
+                debugs(5, DEBUG_EPOLL ? 0 : 8, HERE << "Calling read handler on FD " << fd);
                 PROF_start(comm_write_handler);
                 F->flags.read_pending = 0;
                 F->read_handler = NULL;
@@ -307,24 +300,24 @@ comm_select(int msec)
                 PROF_stop(comm_write_handler);
                 statCounter.select_fds++;
             } else {
-                debugs(5, DEBUG_EPOLL ? 0 : 8, "comm_select(): no read handler for FD " << fd);
+                debugs(5, DEBUG_EPOLL ? 0 : 8, HERE << "no read handler for FD " << fd);
                 // remove interest since no handler exist for this event.
-                commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
+                SetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
             }
         }
 
         if (cevents->events & (EPOLLOUT|EPOLLHUP|EPOLLERR)) {
             if ((hdl = F->write_handler) != NULL) {
-                debugs(5, DEBUG_EPOLL ? 0 : 8, "comm_select(): Calling write handler on FD " << fd);
+                debugs(5, DEBUG_EPOLL ? 0 : 8, HERE << "Calling write handler on FD " << fd);
                 PROF_start(comm_read_handler);
                 F->write_handler = NULL;
                 hdl(fd, F->write_data);
                 PROF_stop(comm_read_handler);
                 statCounter.select_fds++;
             } else {
-                debugs(5, DEBUG_EPOLL ? 0 : 8, "comm_select(): no write handler for FD " << fd);
+                debugs(5, DEBUG_EPOLL ? 0 : 8, HERE << "no write handler for FD " << fd);
                 // remove interest since no handler exist for this event.
-                commSetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0);
+                SetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0);
             }
         }
     }
@@ -335,7 +328,7 @@ comm_select(int msec)
 }
 
 void
-comm_quick_poll_required(void)
+Comm::QuickPollRequired(void)
 {
     max_poll_time = 10;
 }
similarity index 97%
rename from src/comm_kqueue.cc
rename to src/comm/ModKqueue.cc
index 70b94ddeba1fc7a4a33990b75b9db893c39dcdd4..3364853d343ac2e140b873d94d57b2d89b05c404 100644 (file)
  * so deferred reads aren't required.
  *  -- adrian
  */
-
-#include "squid.h"
+#include "config.h"
 
 #if USE_KQUEUE
 
-#include "comm_kqueue.h"
-#include "Store.h"
+#include "squid.h"
+#include "comm/Loops.h"
 #include "fde.h"
+#include "Store.h"
 #include "SquidTime.h"
 
 #if HAVE_SYS_EVENT_H
@@ -165,7 +165,7 @@ kq_update_events(int fd, short filter, PF * handler)
  * the network loop code.
  */
 void
-comm_select_init(void)
+Comm::SelectLoopInit(void)
 {
     kq = kqueue();
 
@@ -189,8 +189,7 @@ comm_select_init(void)
  * and deregister interest in a pending IO state for a given FD.
  */
 void
-commSetSelect(int fd, unsigned int type, PF * handler,
-              void *client_data, time_t timeout)
+Comm::SetSelect(int fd, unsigned int type, PF * handler, void *client_data, time_t timeout)
 {
     fde *F = &fd_table[fd];
     assert(fd >= 0);
@@ -214,7 +213,7 @@ commSetSelect(int fd, unsigned int type, PF * handler,
 }
 
 void
-commResetSelect(int fd)
+Comm::ResetSelect(int fd)
 {
     fde *F = &fd_table[fd];
     if (F->read_handler) {
@@ -241,7 +240,7 @@ commResetSelect(int fd)
  */
 
 comm_err_t
-comm_select(int msec)
+Comm::DoSelect(int msec)
 {
     int num, i;
 
@@ -322,7 +321,7 @@ comm_select(int msec)
 }
 
 void
-comm_quick_poll_required(void)
+Comm::QuickPollRequired(void)
 {
     max_poll_time = 10;
 }
similarity index 98%
rename from src/comm_poll.cc
rename to src/comm/ModPoll.cc
index 60bc70a29add1cb14ea9343e6c1071ce753295bd..095d0b56e4df65894639843f08e6676ff5d20335 100644 (file)
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
  *
  */
+#include "config.h"
+
+#if USE_POLL
 
 #include "squid.h"
-#include "comm_poll.h"
+#include "comm/Loops.h"
+#include "fde.h"
 #include "mgr/Registration.h"
 #include "SquidTime.h"
 #include "Store.h"
-#include "fde.h"
-
-#if USE_POLL
 
 #if HAVE_POLL_H
 #include <poll.h>
@@ -54,7 +55,7 @@
 #endif
 #endif
 
-static int MAX_POLL_TIME = 1000;       /* see also comm_quick_poll_required() */
+static int MAX_POLL_TIME = 1000;       /* see also Comm::QuickPollRequired() */
 
 #ifndef        howmany
 #define howmany(x, y)   (((x)+((y)-1))/(y))
@@ -136,8 +137,7 @@ static int incoming_http_interval = 16 << INCOMING_FACTOR;
 
 
 void
-commSetSelect(int fd, unsigned int type, PF * handler, void *client_data,
-              time_t timeout)
+Comm::SetSelect(int fd, unsigned int type, PF * handler, void *client_data, time_t timeout)
 {
     fde *F = &fd_table[fd];
     assert(fd >= 0);
@@ -159,7 +159,7 @@ commSetSelect(int fd, unsigned int type, PF * handler, void *client_data,
 }
 
 void
-commResetSelect(int fd)
+Comm::ResetSelect(int fd)
 {
 }
 
@@ -341,9 +341,8 @@ comm_poll_http_incoming(void)
 
 /* poll all sockets; call handlers for those that are ready. */
 comm_err_t
-comm_select(int msec)
+Comm::DoSelect(int msec)
 {
-
     struct pollfd pfds[SQUID_MAXFD];
 
     PF *hdl = NULL;
@@ -631,7 +630,7 @@ commPollRegisterWithCacheManager(void)
 }
 
 void
-comm_select_init(void)
+Comm::SelectLoopInit(void)
 {
     commPollRegisterWithCacheManager();
 }
@@ -658,7 +657,7 @@ commIncomingStats(StoreEntry * sentry)
 
 /* Called by async-io or diskd to speed up the polling */
 void
-comm_quick_poll_required(void)
+Comm::QuickPollRequired(void)
 {
     MAX_POLL_TIME = 10;
 }
similarity index 96%
rename from src/comm_select.cc
rename to src/comm/ModSelect.cc
index 46c39664c3eefaf6eaa632c6e2080b662e8e5188..a32b47bbc019bcd83e30872f5ba216e2774a9ef8 100644 (file)
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
  *
  */
+#include "config.h"
+
+#if USE_SELECT
 
 #include "squid.h"
-#include "comm_select.h"
+#include "comm/Loops.h"
 #include "mgr/Registration.h"
 #include "SquidTime.h"
-
-#if USE_SELECT
 #include "Store.h"
 #include "fde.h"
 
-static int MAX_POLL_TIME = 1000;       /* see also comm_quick_poll_required() */
+static int MAX_POLL_TIME = 1000;       /* see also Comm::QuickPollRequired() */
 
 #ifndef        howmany
 #define howmany(x, y)   (((x)+((y)-1))/(y))
@@ -131,13 +132,12 @@ static int incoming_http_interval = 16 << INCOMING_FACTOR;
 #define commCheckHTTPIncoming (++http_io_events > (incoming_http_interval>> INCOMING_FACTOR))
 
 void
-commSetSelect(int fd, unsigned int type, PF * handler, void *client_data,
-              time_t timeout)
+Comm::SetSelect(int fd, unsigned int type, PF * handler, void *client_data, time_t timeout)
 {
     fde *F = &fd_table[fd];
     assert(fd >= 0);
     assert(F->flags.open);
-    debugs(5, 5, "commSetSelect: FD " << fd << " type " << type);
+    debugs(5, 5, HERE << "FD " << fd << " type " << type);
 
     if (type & COMM_SELECT_READ) {
         F->read_handler = handler;
@@ -156,7 +156,7 @@ commSetSelect(int fd, unsigned int type, PF * handler, void *client_data,
 }
 
 void
-commResetSelect(int fd)
+Comm::ResetSelect(int fd)
 {
 }
 
@@ -333,7 +333,7 @@ comm_select_http_incoming(void)
 #define DEBUG_FDBITS 0
 /* Select on all sockets; call handlers for those that are ready. */
 comm_err_t
-comm_select(int msec)
+Comm::DoSelect(int msec)
 {
     fd_set readfds;
     fd_set pendingfds;
@@ -380,11 +380,11 @@ comm_select(int msec)
 
         maxfd = Biggest_FD + 1;
 
-        xmemcpy(&readfds, &global_readfds,
-                howmany(maxfd, FD_MASK_BITS) * FD_MASK_BYTES);
+        memcpy(&readfds, &global_readfds,
+               howmany(maxfd, FD_MASK_BITS) * FD_MASK_BYTES);
 
-        xmemcpy(&writefds, &global_writefds,
-                howmany(maxfd, FD_MASK_BITS) * FD_MASK_BYTES);
+        memcpy(&writefds, &global_writefds,
+               howmany(maxfd, FD_MASK_BITS) * FD_MASK_BYTES);
 
         /* remove stalled FDs, and deal with pending descriptors */
         pending = 0;
@@ -660,16 +660,8 @@ comm_select_dns_incoming(void)
     statHistCount(&statCounter.comm_dns_incoming, nevents);
 }
 
-static void
-commSelectRegisterWithCacheManager(void)
-{
-    Mgr::RegisterAction("comm_select_incoming",
-                        "comm_incoming() stats",
-                        commIncomingStats, 0, 1);
-}
-
 void
-comm_select_init(void)
+Comm::SelectLoopInit(void)
 {
     zero_tv.tv_sec = 0;
     zero_tv.tv_usec = 0;
@@ -677,7 +669,9 @@ comm_select_init(void)
     FD_ZERO(&global_writefds);
     nreadfds = nwritefds = 0;
 
-    commSelectRegisterWithCacheManager();
+    Mgr::RegisterAction("comm_select_incoming",
+                        "comm_incoming() stats",
+                        commIncomingStats, 0, 1);
 }
 
 /*
@@ -798,7 +792,7 @@ commUpdateWriteBits(int fd, PF * handler)
 
 /* Called by async-io or diskd to speed up the polling */
 void
-comm_quick_poll_required(void)
+Comm::QuickPollRequired(void)
 {
     MAX_POLL_TIME = 10;
 }
similarity index 97%
rename from src/comm_select_win32.cc
rename to src/comm/ModSelectWin32.cc
index 58c93cb576ec6b88c273cda3122b851c504e28c2..2e190904fa8c38e42f746081d3c89f9a2bb2ddd5 100644 (file)
  *
  */
 
+#include "config.h"
+
+#if USE_SELECT_WIN32
+
 #include "squid.h"
-#include "comm_select.h"
+#include "comm/Loops.h"
+#include "fde.h"
 #include "mgr/Registration.h"
 #include "SquidTime.h"
-
-#if USE_SELECT_WIN32
 #include "Store.h"
-#include "fde.h"
 
-static int MAX_POLL_TIME = 1000;       /* see also comm_quick_poll_required() */
+static int MAX_POLL_TIME = 1000;       /* see also Comm::QuickPollRequired() */
 
 #ifndef        howmany
 #define howmany(x, y)   (((x)+((y)-1))/(y))
@@ -131,8 +133,7 @@ static int incoming_http_interval = 16 << INCOMING_FACTOR;
 #define commCheckHTTPIncoming (++http_io_events > (incoming_http_interval>> INCOMING_FACTOR))
 
 void
-commSetSelect(int fd, unsigned int type, PF * handler, void *client_data,
-              time_t timeout)
+Comm::SetSelect(int fd, unsigned int type, PF * handler, void *client_data, time_t timeout)
 {
     fde *F = &fd_table[fd];
     assert(fd >= 0);
@@ -156,7 +157,7 @@ commSetSelect(int fd, unsigned int type, PF * handler, void *client_data,
 }
 
 void
-commResetSelect(int fd)
+Comm::ResetSelect(int fd)
 {
 }
 
@@ -336,7 +337,7 @@ comm_select_http_incoming(void)
 #define DEBUG_FDBITS 0
 /* Select on all sockets; call handlers for those that are ready. */
 comm_err_t
-comm_select(int msec)
+Comm::DoSelect(int msec)
 {
     fd_set readfds;
     fd_set pendingfds;
@@ -380,11 +381,11 @@ comm_select(int msec)
 
         maxfd = Biggest_FD + 1;
 
-        xmemcpy(&readfds, &global_readfds, sizeof(global_readfds));
+        memcpy(&readfds, &global_readfds, sizeof(global_readfds));
 
-        xmemcpy(&writefds, &global_writefds, sizeof(global_writefds));
+        memcpy(&writefds, &global_writefds, sizeof(global_writefds));
 
-        xmemcpy(&errfds, &global_writefds, sizeof(global_writefds));
+        memcpy(&errfds, &global_writefds, sizeof(global_writefds));
 
         /* remove stalled FDs, and deal with pending descriptors */
         pending = 0;
@@ -682,16 +683,8 @@ comm_select_dns_incoming(void)
     statHistCount(&statCounter.comm_dns_incoming, nevents);
 }
 
-static void
-commSelectRegisterWithCacheManager(void)
-{
-    Mgr::RegisterAction("comm_select_incoming",
-                        "comm_incoming() stats",
-                        commIncomingStats, 0, 1);
-}
-
 void
-comm_select_init(void)
+Comm::SelectLoopInit(void)
 {
     zero_tv.tv_sec = 0;
     zero_tv.tv_usec = 0;
@@ -699,7 +692,9 @@ comm_select_init(void)
     FD_ZERO(&global_writefds);
     nreadfds = nwritefds = 0;
 
-    commSelectRegisterWithCacheManager();
+    Mgr::RegisterAction("comm_select_incoming",
+                        "comm_incoming() stats",
+                        commIncomingStats, 0, 1);
 }
 
 /*
@@ -820,7 +815,7 @@ commUpdateWriteBits(int fd, PF * handler)
 
 /* Called by async-io or diskd to speed up the polling */
 void
-comm_quick_poll_required(void)
+Comm::QuickPollRequired(void)
 {
     MAX_POLL_TIME = 10;
 }
similarity index 53%
rename from src/comm/ListenStateData.cc
rename to src/comm/TcpAcceptor.cc
index 838d7ff5f7ed9c3ecae6d1f7b3230bb46f542783..db0275af0d673c96fcebcbaa53d452b7b8da91fb 100644 (file)
  */
 
 #include "squid.h"
+#include "base/TextException.h"
 #include "CommCalls.h"
 #include "comm/AcceptLimiter.h"
 #include "comm/comm_internal.h"
-#include "comm/ListenStateData.h"
+#include "comm/Loops.h"
+#include "comm/TcpAcceptor.h"
 #include "ConnectionDetail.h"
 #include "fde.h"
 #include "protos.h"
 #include "SquidTime.h"
 
+namespace Comm
+{
+CBDATA_CLASS_INIT(TcpAcceptor);
+};
+
+Comm::TcpAcceptor::TcpAcceptor(const int listenFd, const Ip::Address &laddr, int flags,
+                               const char *note, const Subscription::Pointer &aSub) :
+        AsyncJob("Comm::TcpAcceptor"),
+        errcode(0),
+        fd(listenFd),
+        isLimited(0),
+        theCallSub(aSub),
+        local_addr(laddr)
+{}
+
+void
+Comm::TcpAcceptor::subscribe(const Subscription::Pointer &aSub)
+{
+    debugs(5, 5, HERE << status() << " AsyncCall Subscription: " << aSub);
+    unsubscribe("subscription change");
+    theCallSub = aSub;
+}
+
+void
+Comm::TcpAcceptor::unsubscribe(const char *reason)
+{
+    debugs(5, 5, HERE << status() << " AsyncCall Subscription " << theCallSub << " removed: " << reason);
+    theCallSub = NULL;
+}
+
+void
+Comm::TcpAcceptor::start()
+{
+    debugs(5, 5, HERE << status() << " AsyncCall Subscription: " << theCallSub);
+
+    Must(isOpen(fd));
+
+    setListen();
+
+    // if no error so far start accepting connections.
+    if (errcode == 0)
+        SetSelect(fd, COMM_SELECT_READ, doAccept, this, 0);
+}
+
+bool
+Comm::TcpAcceptor::doneAll() const
+{
+    // stop when FD is closed
+    if (!isOpen(fd)) {
+        return AsyncJob::doneAll();
+    }
+
+    // stop when handlers are gone
+    if (theCallSub == NULL) {
+        return AsyncJob::doneAll();
+    }
+
+    // open FD with handlers...keep accepting.
+    return false;
+}
+
+void
+Comm::TcpAcceptor::swanSong()
+{
+    debugs(5,5, HERE);
+    unsubscribe("swanSong");
+    fd = -1;
+    AcceptLimiter::Instance().removeDead(this);
+    AsyncJob::swanSong();
+}
+
+const char *
+Comm::TcpAcceptor::status() const
+{
+    static char ipbuf[MAX_IPSTRLEN] = {'\0'};
+    if (ipbuf[0] == '\0')
+        local_addr.ToHostname(ipbuf, MAX_IPSTRLEN);
+
+    static MemBuf buf;
+    buf.reset();
+    buf.Printf(" FD %d, %s",fd, ipbuf);
+
+    const char *jobStatus = AsyncJob::status();
+    buf.append(jobStatus, strlen(jobStatus));
+
+    return buf.content();
+}
+
 /**
  * New-style listen and accept routines
  *
  * accept()ed some time later.
  */
 void
-Comm::ListenStateData::setListen()
+Comm::TcpAcceptor::setListen()
 {
     errcode = 0; // reset local errno copy.
     if (listen(fd, Squid_MaxFD >> 2) < 0) {
-        debugs(50, 0, HERE << "listen(FD " << fd << ", " << (Squid_MaxFD >> 2) << "): " << xstrerror());
+        debugs(50, DBG_CRITICAL, "ERROR: listen(" << status() << ", " << (Squid_MaxFD >> 2) << "): " << xstrerror());
         errcode = errno;
         return;
     }
@@ -66,37 +156,19 @@ Comm::ListenStateData::setListen()
         debugs(5, DBG_IMPORTANT, "Installing accept filter '" << Config.accept_filter << "' on FD " << fd);
         xstrncpy(afa.af_name, Config.accept_filter, sizeof(afa.af_name));
         if (setsockopt(fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa)) < 0)
-            debugs(5, DBG_CRITICAL, "SO_ACCEPTFILTER '" << Config.accept_filter << "': '" << xstrerror());
+            debugs(5, DBG_CRITICAL, "WARNING: SO_ACCEPTFILTER '" << Config.accept_filter << "': '" << xstrerror());
 #elif defined(TCP_DEFER_ACCEPT)
         int seconds = 30;
         if (strncmp(Config.accept_filter, "data=", 5) == 0)
             seconds = atoi(Config.accept_filter + 5);
         if (setsockopt(fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &seconds, sizeof(seconds)) < 0)
-            debugs(5, DBG_CRITICAL, "TCP_DEFER_ACCEPT '" << Config.accept_filter << "': '" << xstrerror());
+            debugs(5, DBG_CRITICAL, "WARNING: TCP_DEFER_ACCEPT '" << Config.accept_filter << "': '" << xstrerror());
 #else
-        debugs(5, DBG_CRITICAL, "accept_filter not supported on your OS");
+        debugs(5, DBG_CRITICAL, "WARNING: accept_filter not supported on your OS");
 #endif
     }
 }
 
-Comm::ListenStateData::ListenStateData(int aFd, AsyncCall::Pointer &call, bool accept_many) :
-        fd(aFd),
-        theCallback(call),
-        mayAcceptMore(accept_many)
-{
-    assert(aFd >= 0);
-    debugs(5, 5, HERE << "FD " << fd << " AsyncCall: " << call);
-    assert(isOpen(aFd));
-    setListen();
-    commSetSelect(fd, COMM_SELECT_READ, doAccept, this, 0);
-}
-
-Comm::ListenStateData::~ListenStateData()
-{
-    comm_close(fd);
-    fd = -1;
-}
-
 /**
  * This private callback is called whenever a filedescriptor is ready
  * to dupe itself and fob off an accept()ed connection
@@ -107,23 +179,30 @@ Comm::ListenStateData::~ListenStateData()
  * done later when enough sockets become available.
  */
 void
-Comm::ListenStateData::doAccept(int fd, void *data)
+Comm::TcpAcceptor::doAccept(int fd, void *data)
 {
-    debugs(5, 2, HERE << "New connection on FD " << fd);
+    try {
+        debugs(5, 2, HERE << "New connection on FD " << fd);
 
-    assert(isOpen(fd));
-    ListenStateData *afd = static_cast<ListenStateData*>(data);
+        Must(isOpen(fd));
+        TcpAcceptor *afd = static_cast<TcpAcceptor*>(data);
+
+        if (!okToAccept()) {
+            AcceptLimiter::Instance().defer(afd);
+        } else {
+            afd->acceptNext();
+        }
+        SetSelect(fd, COMM_SELECT_READ, Comm::TcpAcceptor::doAccept, afd, 0);
 
-    if (!okToAccept()) {
-        AcceptLimiter::Instance().defer(afd);
-    } else {
-        afd->acceptNext();
+    } catch (const std::exception &e) {
+        fatalf("FATAL: error while accepting new client connection: %s\n", e.what());
+    } catch (...) {
+        fatal("FATAL: error while accepting new client connection: [unkown]\n");
     }
-    commSetSelect(fd, COMM_SELECT_READ, Comm::ListenStateData::doAccept, afd, 0);
 }
 
 bool
-Comm::ListenStateData::okToAccept()
+Comm::TcpAcceptor::okToAccept()
 {
     static time_t last_warn = 0;
 
@@ -139,7 +218,7 @@ Comm::ListenStateData::okToAccept()
 }
 
 void
-Comm::ListenStateData::acceptOne()
+Comm::TcpAcceptor::acceptOne()
 {
     /*
      * We don't worry about running low on FDs here.  Instead,
@@ -148,42 +227,45 @@ Comm::ListenStateData::acceptOne()
      */
 
     /* Accept a new connection */
-    ConnectionDetail connDetails;
-    int newfd = oldAccept(connDetails);
+    ConnectionDetail newConnDetails;
+    int newFd = -1;
+    const comm_err_t flag = oldAccept(newConnDetails, &newFd);
 
     /* Check for errors */
-    if (newfd < 0) {
+    if (!isOpen(newFd)) {
 
-        if (newfd == COMM_NOMESSAGE) {
+        if (flag == COMM_NOMESSAGE) {
             /* register interest again */
-            debugs(5, 5, HERE << "try later: FD " << fd << " handler: " << theCallback);
-            commSetSelect(fd, COMM_SELECT_READ, doAccept, this, 0);
+            debugs(5, 5, HERE << "try later: FD " << fd << " handler Subscription: " << theCallSub);
+            SetSelect(fd, COMM_SELECT_READ, doAccept, this, 0);
             return;
         }
 
         // A non-recoverable error; notify the caller */
-        debugs(5, 5, HERE << "non-recoverable error: FD " << fd << " handler: " << theCallback);
-        notify(-1, COMM_ERROR, connDetails);
-        mayAcceptMore = false;
+        debugs(5, 5, HERE << "non-recoverable error:" << status() << " handler Subscription: " << theCallSub);
+        notify(flag, newConnDetails, newFd);
+        mustStop("Listener socket closed");
         return;
     }
 
-    debugs(5, 5, HERE << "accepted: FD " << fd <<
-           " newfd: " << newfd << " from: " << connDetails.peer <<
-           " handler: " << theCallback);
-    notify(newfd, COMM_OK, connDetails);
+    debugs(5, 5, HERE << "Listener: FD " << fd <<
+           " accepted new connection from " << newConnDetails.peer <<
+           " handler Subscription: " << theCallSub);
+    notify(flag, newConnDetails, newFd);
 }
 
 void
-Comm::ListenStateData::acceptNext()
+Comm::TcpAcceptor::acceptNext()
 {
-    assert(isOpen(fd));
+    Must(isOpen(fd));
     debugs(5, 2, HERE << "connection on FD " << fd);
     acceptOne();
 }
 
+// XXX: obsolete comment?
+// NP: can't be a const function because syncWithComm() side effects hit theCallSub->callback().
 void
-Comm::ListenStateData::notify(int newfd, comm_err_t flag, const ConnectionDetail &connDetails)
+Comm::TcpAcceptor::notify(const comm_err_t flag, const ConnectionDetail &connDetails, int newFd) const
 {
     // listener socket handlers just abandon the port with COMM_ERR_CLOSING
     // it should only happen when this object is deleted...
@@ -191,26 +273,29 @@ Comm::ListenStateData::notify(int newfd, comm_err_t flag, const ConnectionDetail
         return;
     }
 
-    if (theCallback != NULL) {
-        typedef CommAcceptCbParams Params;
-        Params &params = GetCommParams<Params>(theCallback);
+    if (theCallSub != NULL) {
+        AsyncCall::Pointer call = theCallSub->callback();
+        CommAcceptCbParams &params = GetCommParams<CommAcceptCbParams>(call);
         params.fd = fd;
-        params.nfd = newfd;
+        params.nfd = newFd;
         params.details = connDetails;
         params.flag = flag;
         params.xerrno = errcode;
-        ScheduleCallHere(theCallback);
-        if (!mayAcceptMore)
-            theCallback = NULL;
+        ScheduleCallHere(call);
     }
 }
 
 /**
  * accept() and process
- * Wait for an incoming connection on FD.
+ * Wait for an incoming connection on our listener socket.
+ *
+ * \retval COMM_OK         success. details parameter filled.
+ * \retval COMM_NOMESSAGE  attempted accept() but nothing useful came in.
+ * \retval COMM_ERROR      an outright failure occured.
+ *                         Or if this client has too many connections already.
  */
-int
-Comm::ListenStateData::oldAccept(ConnectionDetail &details)
+comm_err_t
+Comm::TcpAcceptor::oldAccept(ConnectionDetail &details, int *newFd)
 {
     PROF_start(comm_accept);
     statCounter.syscalls.sock.accepts++;
@@ -227,17 +312,19 @@ Comm::ListenStateData::oldAccept(ConnectionDetail &details)
         PROF_stop(comm_accept);
 
         if (ignoreErrno(errno)) {
-            debugs(50, 5, HERE << "FD " << fd << ": " << xstrerror());
+            debugs(50, 5, HERE << status() << ": " << xstrerror());
             return COMM_NOMESSAGE;
         } else if (ENFILE == errno || EMFILE == errno) {
-            debugs(50, 3, HERE << "FD " << fd << ": " << xstrerror());
+            debugs(50, 3, HERE << status() << ": " << xstrerror());
             return COMM_ERROR;
         } else {
-            debugs(50, 1, HERE << "FD " << fd << ": " << xstrerror());
+            debugs(50, 1, HERE << status() << ": " << xstrerror());
             return COMM_ERROR;
         }
     }
 
+    Must(sock >= 0);
+    *newFd = sock;
     details.peer = *gai;
 
     if ( Config.client_ip_max_connections >= 0) {
@@ -248,15 +335,16 @@ Comm::ListenStateData::oldAccept(ConnectionDetail &details)
         }
     }
 
+    // lookup the local-end details of this new connection
     details.me.InitAddrInfo(gai);
-
     details.me.SetEmpty();
     getsockname(sock, gai->ai_addr, &gai->ai_addrlen);
     details.me = *gai;
-
-    commSetCloseOnExec(sock);
+    details.me.FreeAddrInfo(gai);
 
     /* fdstat update */
+    // XXX : these are not all HTTP requests. use a note about type and ip:port details->
+    // so we end up with a uniform "(HTTP|FTP-data|HTTPS|...) remote-ip:remote-port"
     fd_open(sock, FD_SOCKET, "HTTP Request");
 
     fdd_table[sock].close_file = NULL;
@@ -265,15 +353,16 @@ Comm::ListenStateData::oldAccept(ConnectionDetail &details)
     fde *F = &fd_table[sock];
     details.peer.NtoA(F->ipaddr,MAX_IPSTRLEN);
     F->remote_port = details.peer.GetPort();
-    F->local_addr.SetPort(details.me.GetPort());
+    F->local_addr = details.me;
     F->sock_family = details.me.IsIPv6()?AF_INET6:AF_INET;
-    details.me.FreeAddrInfo(gai);
 
+    // set socket flags
+    commSetCloseOnExec(sock);
     commSetNonBlocking(sock);
 
     /* IFF the socket is (tproxy) transparent, pass the flag down to allow spoofing */
     F->flags.transparent = fd_table[fd].flags.transparent;
 
     PROF_stop(comm_accept);
-    return sock;
+    return COMM_OK;
 }
diff --git a/src/comm/TcpAcceptor.h b/src/comm/TcpAcceptor.h
new file mode 100644 (file)
index 0000000..1c3a12f
--- /dev/null
@@ -0,0 +1,99 @@
+#ifndef SQUID_COMM_TCPACCEPTOR_H
+#define SQUID_COMM_TCPACCEPTOR_H
+
+#include "base/AsyncCall.h"
+#include "base/Subscription.h"
+#include "CommCalls.h"
+#include "comm_err_t.h"
+#include "comm/TcpAcceptor.h"
+#include "ip/Address.h"
+
+#if HAVE_MAP
+#include <map>
+#endif
+
+namespace Comm
+{
+
+class AcceptLimiter;
+
+/**
+ * Listens on an FD for new incoming connections and
+ * emits an active FD descriptor for the new client.
+ *
+ * Handles all event limiting required to quash inbound connection
+ * floods within the global FD limits of available Squid_MaxFD and
+ * client_ip_max_connections.
+ *
+ * Fills the emitted connection with all connection details able to
+ * be looked up. Currently these are the local/remote IP:port details
+ * and the listening socket transparent-mode flag.
+ */
+class TcpAcceptor : public AsyncJob
+{
+private:
+    virtual void start();
+    virtual bool doneAll() const;
+    virtual void swanSong();
+    virtual const char *status() const;
+
+    TcpAcceptor(const TcpAcceptor &); // not implemented.
+
+public:
+    TcpAcceptor(const int listenFd, const Ip::Address &laddr, int flags,
+                const char *note, const Subscription::Pointer &aSub);
+
+    /** Subscribe a handler to receive calls back about new connections.
+     * Unsubscribes any existing subscribed handler.
+     */
+    void subscribe(const Subscription::Pointer &aSub);
+
+    /** Remove the currently waiting callback subscription.
+     * Already scheduled callbacks remain scheduled.
+     */
+    void unsubscribe(const char *reason);
+
+    /** Try and accept another connection (synchronous).
+     * If one is pending already the subscribed callback handler will be scheduled
+     * to handle it before this method returns.
+     */
+    void acceptNext();
+
+    /// Call the subscribed callback handler with details about a new connection.
+    void notify(const comm_err_t flags, const ConnectionDetail &newConnDetails, const int newFd) const;
+
+    /// errno code of the last accept() or listen() action if one occurred.
+    int errcode;
+
+    /// conn being listened on for new connections
+    /// Reserved for read-only use.
+    // NP: public only until we can hide it behind connection handles
+    int fd;
+
+protected:
+    friend class AcceptLimiter;
+    int32_t isLimited;                   ///< whether this socket is delayed and on the AcceptLimiter queue.
+
+private:
+    Subscription::Pointer theCallSub;    ///< used to generate AsyncCalls handling our events.
+
+    /// IP Address and port being listened on
+    Ip::Address local_addr;
+
+    /// Method to test if there are enough file descriptors to open a new client connection
+    /// if not the accept() will be postponed
+    static bool okToAccept();
+
+    /// Method callback for whenever an FD is ready to accept a client connection.
+    static void doAccept(int fd, void *data);
+
+    void acceptOne();
+    comm_err_t oldAccept(ConnectionDetail &newConnDetails, int *fd);
+    void setListen();
+
+    CBDATA_CLASS2(TcpAcceptor);
+};
+
+} // namespace Comm
+
+#endif /* SQUID_COMM_TCPACCEPTOR_H */
index 1cad2a36b9773822e94b69dcb69215a239a28b11..1b22d3bbfc20e6e0188579930e8dbb394df22788 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef _SQUID_COMM_COMM_ERR_T_H
 #define _SQUID_COMM_COMM_ERR_T_H
 
-#include "config.h"
-
 typedef enum {
     COMM_OK = 0,
     COMM_ERROR = -1,
diff --git a/src/comm_kqueue.h b/src/comm_kqueue.h
deleted file mode 100644 (file)
index 0c8e248..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-
-/*
- * $Id$
- *
- *
- * 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 SQUID_COMM_KQUEUE_H
-#define SQUID_COMM_KQUEUE_H
-
-#endif /* SQUID_COMM_KQUEUE_H */
index 75bdeb480b038889886799ed0fe5e9f49759f594..f6e6b50471326116bb559aa7cc5e5db4a92fd8a3 100644 (file)
@@ -255,9 +255,8 @@ debugOpenLog(const char *logfile)
         debug_log = stderr;
     }
 
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
     setmode(fileno(debug_log), O_TEXT);
-
 #endif
 }
 
@@ -783,7 +782,7 @@ Debug::xassert(const char *msg, const char *file, int line)
 
 std::ostringstream (*Debug::CurrentDebug)(NULL);
 
-const size_t
+size_t
 BuildPrefixInit()
 {
     // XXX: This must be kept in sync with the actual debug.cc location
index 1496edf250c77948353d1f5bbf3cc370c4e94205..f7b283726dcc1b8fcb4c365e4afe879ee0b9a754 100644 (file)
 #define        HTTP_REQBUF_SZ  4096
 
 /* CygWin & Windows NT Port */
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
 #define _WIN_SQUID_SERVICE_CONTROL_STOP SERVICE_CONTROL_STOP
 #define _WIN_SQUID_SERVICE_CONTROL_SHUTDOWN SERVICE_CONTROL_SHUTDOWN
 #define _WIN_SQUID_SERVICE_CONTROL_INTERROGATE SERVICE_CONTROL_INTERROGATE
index 85936a4ed0412d3ba0eb4e949954989c38d37e35..b9b6e503f2817f95be1ab12e8075ad4d889fd96a 100644 (file)
  */
 
 #include "squid.h"
+#include "comm/Loops.h"
 #include "fde.h"
 #include "MemBuf.h"
 
 static PF diskHandleRead;
 static PF diskHandleWrite;
 
-#if defined(_SQUID_WIN32_) || defined(_SQUID_OS2_)
+#if _SQUID_WINDOWS_ || _SQUID_OS2_
 static int
 diskWriteIsComplete(int fd)
 {
@@ -109,25 +110,18 @@ file_close(int fd)
     }
 
     if (F->flags.write_daemon) {
-#if defined(_SQUID_WIN32_) || defined(_SQUID_OS2_)
+#if _SQUID_WINDOWS_ || _SQUID_OS2_
         /*
          * on some operating systems, you can not delete or rename
          * open files, so we won't allow delayed close.
          */
-
         while (!diskWriteIsComplete(fd))
             diskHandleWrite(fd, NULL);
-
 #else
-
         F->flags.close_request = 1;
-
         debugs(6, 2, "file_close: FD " << fd << ", delaying close");
-
         PROF_stop(file_close);
-
         return;
-
 #endif
 
     }
@@ -196,12 +190,12 @@ diskCombineWrites(struct _fde_disk *fdd)
             dwrite_q *q = fdd->write_q;
 
             len = q->len - q->buf_offset;
-            xmemcpy(wq->buf + wq->len, q->buf + q->buf_offset, len);
+            memcpy(wq->buf + wq->len, q->buf + q->buf_offset, len);
             wq->len += len;
             fdd->write_q = q->next;
 
             if (q->free_func)
-                (q->free_func) (q->buf);
+                q->free_func(q->buf);
 
             memFree(q, MEM_DWRITE_Q);
         };
@@ -285,7 +279,7 @@ diskHandleWrite(int fd, void *notused)
                 fdd->write_q = q->next;
 
                 if (q->free_func)
-                    (q->free_func) (q->buf);
+                    q->free_func(q->buf);
 
                 if (q) {
                     memFree(q, MEM_DWRITE_Q);
@@ -314,7 +308,7 @@ diskHandleWrite(int fd, void *notused)
             fdd->write_q = q->next;
 
             if (q->free_func)
-                (q->free_func) (q->buf);
+                q->free_func(q->buf);
 
             if (q) {
                 memFree(q, MEM_DWRITE_Q);
@@ -329,7 +323,7 @@ diskHandleWrite(int fd, void *notused)
     } else {
         /* another block is queued */
         diskCombineWrites(fdd);
-        commSetSelect(fd, COMM_SELECT_WRITE, diskHandleWrite, NULL, 0);
+        Comm::SetSelect(fd, COMM_SELECT_WRITE, diskHandleWrite, NULL, 0);
         F->flags.write_daemon = 1;
     }
 
@@ -458,7 +452,7 @@ diskHandleRead(int fd, void *data)
 
     if (len < 0) {
         if (ignoreErrno(errno)) {
-            commSetSelect(fd, COMM_SELECT_READ, diskHandleRead, ctrl_dat, 0);
+            Comm::SetSelect(fd, COMM_SELECT_READ, diskHandleRead, ctrl_dat, 0);
             PROF_stop(diskHandleRead);
             return;
         }
@@ -521,11 +515,8 @@ int
 xrename(const char *from, const char *to)
 {
     debugs(21, 2, "xrename: renaming " << from << " to " << to);
-#if defined (_SQUID_OS2_) || defined (_SQUID_WIN32_)
-
-    remove
-    (to);
-
+#if _SQUID_OS2_ || _SQUID_WINDOWS_
+    remove(to);
 #endif
 
     if (0 == rename(from, to))
index c6fe4a04f4d0b77357c610d8ae5e33e73b5538ca..4e16c7274bccd50003f26148ac969db57c94bac2 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * $Id$
  *
  *
  */
 
-#include "config.h"
 #include "squid.h"
+#include "comm.h"
+#include "comm/Loops.h"
+#include "comm/Write.h"
 #include "event.h"
 #include "SquidTime.h"
 #include "Store.h"
-#include "comm.h"
-#include "comm/Write.h"
 #include "fde.h"
 #include "ip/tools.h"
 #include "MemBuf.h"
@@ -60,7 +59,7 @@
    using external DNS process.
  */
 #if !USE_DNSSERVERS
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
 #include "squid_windows.h"
 #define REG_TCPIP_PARA_INTERFACES "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"
 #define REG_TCPIP_PARA "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"
@@ -227,7 +226,7 @@ static void idnsParseNameservers(void);
 #ifndef _SQUID_MSWIN_
 static void idnsParseResolvConf(void);
 #endif
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
 static void idnsParseWIN32Registry(void);
 static void idnsParseWIN32SearchList(const char *);
 #endif
@@ -278,7 +277,7 @@ idnsAddNameserver(const char *buf)
         nameservers = (ns *)xcalloc(nns_alloc, sizeof(*nameservers));
 
         if (oldptr && oldalloc)
-            xmemcpy(nameservers, oldptr, oldalloc * sizeof(*nameservers));
+            memcpy(nameservers, oldptr, oldalloc * sizeof(*nameservers));
 
         if (oldptr)
             safe_free(oldptr);
@@ -310,7 +309,7 @@ idnsAddPathComponent(const char *buf)
         searchpath = (sp *)xcalloc(npc_alloc, sizeof(*searchpath));
 
         if (oldptr && oldalloc)
-            xmemcpy(searchpath, oldptr, oldalloc * sizeof(*searchpath));
+            memcpy(searchpath, oldptr, oldalloc * sizeof(*searchpath));
 
         if (oldptr)
             safe_free(oldptr);
@@ -365,9 +364,8 @@ idnsParseResolvConf(void)
         return;
     }
 
-#if defined(_SQUID_CYGWIN_)
+#if _SQUID_CYGWIN_
     setmode(fileno(fp), O_TEXT);
-
 #endif
 
     while (fgets(buf, RESOLV_BUFSZ, fp)) {
@@ -435,7 +433,7 @@ idnsParseResolvConf(void)
 
 #endif
 
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
 static void
 idnsParseWIN32SearchList(const char * Separator)
 {
@@ -1238,7 +1236,7 @@ idnsRead(int fd, void *data)
 
     // Always keep reading. This stops (or at least makes harder) several
     // attacks on the DNS client.
-    commSetSelect(fd, COMM_SELECT_READ, idnsRead, NULL, 0);
+    Comm::SetSelect(fd, COMM_SELECT_READ, idnsRead, NULL, 0);
 
     /* BUG (UNRESOLVED)
      *  two code lines after returning from comm_udprecvfrom()
@@ -1496,12 +1494,12 @@ idnsInit(void)
         if (DnsSocketB >= 0) {
             port = comm_local_port(DnsSocketB);
             debugs(78, 1, "DNS Socket created at " << addrB << ", FD " << DnsSocketB);
-            commSetSelect(DnsSocketB, COMM_SELECT_READ, idnsRead, NULL, 0);
+            Comm::SetSelect(DnsSocketB, COMM_SELECT_READ, idnsRead, NULL, 0);
         }
         if (DnsSocketA >= 0) {
             port = comm_local_port(DnsSocketA);
             debugs(78, 1, "DNS Socket created at " << addrA << ", FD " << DnsSocketA);
-            commSetSelect(DnsSocketA, COMM_SELECT_READ, idnsRead, NULL, 0);
+            Comm::SetSelect(DnsSocketA, COMM_SELECT_READ, idnsRead, NULL, 0);
         }
     }
 
@@ -1513,20 +1511,16 @@ idnsInit(void)
         idnsParseResolvConf();
 
 #endif
-#ifdef _SQUID_WIN32_
-
+#if _SQUID_WINDOWS_
     if (0 == nns)
         idnsParseWIN32Registry();
-
 #endif
 
     if (0 == nns) {
         debugs(78, 1, "Warning: Could not find any nameservers. Trying to use localhost");
-#ifdef _SQUID_WIN32_
-
+#if _SQUID_WINDOWS_
         debugs(78, 1, "Please check your TCP-IP settings or /etc/resolv.conf file");
 #else
-
         debugs(78, 1, "Please check your /etc/resolv.conf file");
 #endif
 
index f5ee494b511c24bf9ef33c3b1d9563705b48cf1f..0e9a41113d9dcc1b295da40e4caff899581244b6 100644 (file)
@@ -100,6 +100,7 @@ typedef enum {
     CC_MAX_STALE,
     CC_MIN_FRESH,
     CC_ONLY_IF_CACHED,
+    CC_STALE_IF_ERROR,
     CC_OTHER,
     CC_ENUM_END
 } http_hdr_cc_type;
@@ -325,7 +326,7 @@ enum {
 
 
 /* CygWin & Windows NT Port */
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
 /*
  * Supported Windows OS types codes
  */
@@ -342,20 +343,7 @@ enum {
     _WIN_OS_WINLON,
     _WIN_OS_WIN7
 };
-
-#endif
-
-typedef enum {
-    CLF_UNKNOWN,
-    CLF_AUTO,
-    CLF_CUSTOM,
-    CLF_SQUID,
-    CLF_COMMON,
-#if ICAP_CLIENT
-    CLF_ICAP_SQUID,
 #endif
-    CLF_NONE
-} customlog_type;
 
 enum {
     DISABLE_PMTU_OFF,
index e683215c845468aab8e75d50c8822fb709fcae73..3246a2fb5d02d961a68432dc1bc097f5da1d6df9 100644 (file)
@@ -4,8 +4,9 @@
 typedef enum {
     ERR_DETAIL_NONE,
     ERR_DETAIL_START = 100000, // to avoid clashes with most OS error numbers
-    ERR_DETAIL_ICAP_REQMOD_ABORT = ERR_DETAIL_START, // transaction abort
-    ERR_DETAIL_ICAP_RESPMOD_CLT_SIDE_BODY, // client-side detected body abort
+    ERR_DETAIL_CLT_REQMOD_ABORT = ERR_DETAIL_START, // client-side detected transaction abort
+    ERR_DETAIL_CLT_REQMOD_REQ_BODY, // client-side detected REQMOD request body adaptation failure
+    ERR_DETAIL_CLT_REQMOD_RESP_BODY, // client-side detected REQMOD satisfaction reply body failure
     ERR_DETAIL_ICAP_RESPMOD_EARLY, // RESPMOD failed w/o store entry
     ERR_DETAIL_ICAP_RESPMOD_LATE,  // RESPMOD failed with a store entry
     ERR_DETAIL_ICAP_XACT_START, // transaction start failure
index fc131b3ce0bfeead2958fd9be9543da99736354a..e919310c108314684e366f0f7c481037e6d5a5c9 100644 (file)
@@ -52,6 +52,9 @@ typedef enum {
     /* ICAP Errors */
     ERR_ICAP_FAILURE,
 
+    /* Squid problem */
+    ERR_GATEWAY_FAILURE,
+
     /* Special Cases */
     ERR_DIR_LISTING,            /* Display of remote directory (FTP, Gopher) */
     ERR_SQUID_SIGNATURE,        /* not really an error */
index 65ccb49495a4fc74631add457ad4f1a2d5ee12bf..fc92e04565c8e9f58f0471afb794f5dbb141eda3 100644 (file)
@@ -76,6 +76,7 @@ CBDATA_CLASS_INIT(ErrorState);
 typedef struct {
     int id;
     char *page_name;
+    http_status page_redirect;
 } ErrorDynamicPageInfo;
 
 /* local constant and vars */
@@ -179,9 +180,13 @@ errorInitialize(void)
             ErrorDynamicPageInfo *info = ErrorDynamicPages.items[i - ERR_MAX];
             assert(info && info->id == i && info->page_name);
 
-            if (strchr(info->page_name, ':') == NULL) {
+            const char *pg = info->page_name;
+            if (info->page_redirect != HTTP_STATUS_NONE)
+                pg = info->page_name +4;
+
+            if (strchr(pg, ':') == NULL) {
                 /** But only if they are not redirection URL. */
-                error_text[i] = errorLoadText(info->page_name);
+                error_text[i] = errorLoadText(pg);
             }
         }
     }
@@ -325,6 +330,40 @@ errorDynamicPageInfoCreate(int id, const char *page_name)
     ErrorDynamicPageInfo *info = new ErrorDynamicPageInfo;
     info->id = id;
     info->page_name = xstrdup(page_name);
+    info->page_redirect = static_cast<http_status>(atoi(page_name));
+
+    /* WARNING on redirection status:
+     * 2xx are permitted, but not documented officially.
+     * - might be useful for serving static files (PAC etc) in special cases
+     * 3xx require a URL suitable for Location: header.
+     * - the current design does not allow for a Location: URI as well as a local file template
+     *   although this possibility is explicitly permitted in the specs.
+     * 4xx-5xx require a local file template.
+     * - sending Location: on these codes with no body is invalid by the specs.
+     * - current result is Squid crashing or XSS problems as dynamic deny_info load random disk files.
+     * - a future redesign of the file loading may result in loading remote objects sent inline as local body.
+     */
+    if (info->page_redirect == HTTP_STATUS_NONE)
+        ; // special case okay.
+    else if (info->page_redirect < 200 || info->page_redirect > 599) {
+        // out of range
+        debugs(0, DBG_CRITICAL, "FATAL: status " << info->page_redirect << " is not valid on '" << page_name << "'");
+        self_destruct();
+    } else if ( /* >= 200 && */ info->page_redirect < 300 && strchr(&(page_name[4]), ':')) {
+        // 2xx require a local template file
+        debugs(0, DBG_CRITICAL, "FATAL: status " << info->page_redirect << " is not valid on '" << page_name << "'");
+        self_destruct();
+    } else if (/* >= 300 && */ info->page_redirect <= 399 && !strchr(&(page_name[4]), ':')) {
+        // 3xx require an absolute URL
+        debugs(0, DBG_CRITICAL, "FATAL: status " << info->page_redirect << " is not valid on '" << page_name << "'");
+        self_destruct();
+    } else if (info->page_redirect >= 400 /* && <= 599 */ && strchr(&(page_name[4]), ':')) {
+        // 4xx/5xx require a local template file
+        debugs(0, DBG_CRITICAL, "FATAL: status " << info->page_redirect << " is not valid on '" << page_name << "'");
+        self_destruct();
+    }
+    // else okay.
+
     return info;
 }
 
@@ -390,6 +429,8 @@ errorCon(err_type type, http_status status, HttpRequest * request)
     err->err_language = NULL;
     err->type = type;
     err->httpStatus = status;
+    if (err->page_id >= ERR_MAX && ErrorDynamicPages.items[err->page_id - ERR_MAX]->page_redirect != HTTP_STATUS_NONE)
+        err->httpStatus = ErrorDynamicPages.items[err->page_id - ERR_MAX]->page_redirect;
 
     if (request != NULL) {
         err->request = HTTPMSGLOCK(request);
@@ -513,6 +554,9 @@ errorStateFree(ErrorState * err)
     if (err->err_language != Config.errorDefaultLanguage)
 #endif
         safe_free(err->err_language);
+#if USE_SSL
+    delete err->detail;
+#endif
     cbdataFree(err);
 }
 
@@ -602,7 +646,7 @@ ErrorState::Dump(MemBuf * mb)
 #define CVT_BUF_SZ 512
 
 const char *
-ErrorState::Convert(char token, bool building_deny_info_url)
+ErrorState::Convert(char token, bool building_deny_info_url, bool allowRecursion)
 {
     static MemBuf mb;
     const char *p = NULL;      /* takes priority over mb if set */
@@ -631,6 +675,22 @@ ErrorState::Convert(char token, bool building_deny_info_url)
         p = errorPageName(type);
         break;
 
+    case 'D':
+        if (!allowRecursion)
+            p = "%D";  // if recursion is not allowed, do not convert
+#if USE_SSL
+        // currently only SSL error details implemented
+        else if (detail) {
+            const String &errDetail = detail->toString();
+            MemBuf *detail_mb  = ConvertText(errDetail.termedBuf(), false);
+            mb.append(detail_mb->content(), detail_mb->contentSize());
+            delete detail_mb;
+            do_quote = 0;
+        } else
+#endif
+            mb.Printf("[No Error Detail]");
+        break;
+
     case 'e':
         mb.Printf("%d", xerrno);
         break;
@@ -662,12 +722,12 @@ ErrorState::Convert(char token, bool building_deny_info_url)
 
     case 'g':
         if (building_deny_info_url) break;
-        /* FTP SERVER MESSAGE */
-        if (ftp.server_msg)
-            wordlistCat(ftp.server_msg, &mb);
-        else if (ftp.listing) {
+        /* FTP SERVER RESPONSE */
+        if (ftp.listing) {
             mb.append(ftp.listing->content(), ftp.listing->contentSize());
             do_quote = 0;
+        } else if (ftp.server_msg) {
+            wordlistCat(ftp.server_msg, &mb);
         }
         break;
 
@@ -804,7 +864,7 @@ ErrorState::Convert(char token, bool building_deny_info_url)
         break;
 
     case 't':
-        mb.Printf("%s", mkhttpdlogtime(&squid_curtime));
+        mb.Printf("%s", Time::FormatHttpd(squid_curtime));
         break;
 
     case 'T':
@@ -896,9 +956,12 @@ ErrorState::DenyInfoLocation(const char *name, HttpRequest *aRequest, MemBuf &re
     char const *p = m;
     char const *t;
 
+    if (m[0] == '3')
+        m += 4; // skip "3xx:"
+
     while ((p = strchr(m, '%'))) {
         result.append(m, p - m);       /* copy */
-        t = Convert(*++p, true);       /* convert */
+        t = Convert(*++p, true, true);       /* convert */
         result.Printf("%s", t);        /* copy */
         m = p + 1;                     /* advance */
     }
@@ -916,9 +979,19 @@ ErrorState::BuildHttpReply()
     const char *name = errorPageName(page_id);
     /* no LMT for error pages; error pages expire immediately */
 
-    if (strchr(name, ':')) {
+    if (name[0] == '3' || (name[0] != '4' && name[0] != '5' && strchr(name, ':'))) {
         /* Redirection */
-        rep->setHeaders(HTTP_MOVED_TEMPORARILY, NULL, "text/html", 0, 0, -1);
+        http_status status = HTTP_MOVED_TEMPORARILY;
+        // Use configured 3xx reply status if set.
+        if (name[0] == '3')
+            status = httpStatus;
+        else {
+            // Use 307 for HTTP/1.1 non-GET/HEAD requests.
+            if (request->method != METHOD_GET && request->method != METHOD_HEAD && request->http_ver >= HttpVersion(1,1))
+                status = HTTP_TEMPORARY_REDIRECT;
+        }
+
+        rep->setHeaders(status, NULL, "text/html", 0, 0, -1);
 
         if (request) {
             MemBuf redirect_location;
@@ -976,10 +1049,7 @@ ErrorState::BuildHttpReply()
 MemBuf *
 ErrorState::BuildContent()
 {
-    MemBuf *content = new MemBuf;
     const char *m = NULL;
-    const char *p;
-    const char *t;
 
     assert(page_id > ERR_NONE && page_id < error_page_count);
 
@@ -987,6 +1057,7 @@ ErrorState::BuildContent()
     String hdr;
     char dir[256];
     int l = 0;
+    const char *freePage = NULL;
 
     /** error_directory option in squid.conf overrides translations.
      * Custom errors are always found either in error_directory or the templates directory.
@@ -1060,6 +1131,7 @@ ErrorState::BuildContent()
                 if (m) {
                     /* store the language we found for the Content-Language reply header */
                     err_language = xstrdup(reset);
+                    freePage = m;
                     break;
                 } else if (Config.errorLogMissingLanguages) {
                     debugs(4, DBG_IMPORTANT, "WARNING: Error Pages Missing Language: " << reset);
@@ -1096,12 +1168,25 @@ ErrorState::BuildContent()
         debugs(4, 2, HERE << "No existing error page language negotiated for " << errorPageName(page_id) << ". Using default error file.");
     }
 
+    MemBuf *result = ConvertText(m, true);
+#if USE_ERR_LOCALES
+    safe_free(freePage);
+#endif
+
+    return result;
+}
+
+MemBuf *ErrorState::ConvertText(const char *text, bool allowRecursion)
+{
+    MemBuf *content = new MemBuf;
+    const char *p;
+    const char *m = text;
     assert(m);
     content->init();
 
     while ((p = strchr(m, '%'))) {
         content->append(m, p - m);     /* copy */
-        t = Convert(*++p, false);      /* convert */
+        const char *t = Convert(*++p, false, allowRecursion);  /* convert */
         content->Printf("%s", t);      /* copy */
         m = p + 1;                     /* advance */
     }
index 74a30b6efc504a8a3f44a1c57c47ad95763baf65..e3ea32cfa304febd03a282df3cb767ee13b1e081 100644 (file)
@@ -38,6 +38,9 @@
 #include "auth/UserRequest.h"
 #include "cbdata.h"
 #include "ip/Address.h"
+#if USE_SSL
+#include "ssl/ErrorDetail.h"
+#endif
 
 /**
  \defgroup ErrorPageAPI Error Pages API
@@ -49,6 +52,7 @@
    B - URL with FTP %2f hack                    x
    c - Squid error code                         x
    d - seconds elapsed since request received   x
+   D - Error details                            x
    e - errno                                    x
    E - strerror()                               x
    f - FTP request line                         x
@@ -98,6 +102,14 @@ private:
      */
     MemBuf *BuildContent(void);
 
+    /**
+     * Convert the given template string into textual output
+     *
+     * \param text            The string to be converted
+     * \param allowRecursion  Whether to convert codes which output may contain codes
+     */
+    MemBuf *ConvertText(const char *text, bool allowRecursion);
+
     /**
      * Generates the Location: header value for a deny_info error page
      * to be used for this error.
@@ -112,8 +124,9 @@ private:
      *
      * \param token                    The token following % which need to be converted
      * \param building_deny_info_url   Perform special deny_info actions, such as URL-encoding and token skipping.
+     * \ allowRecursion   True if the codes which do recursions should converted
      */
-    const char *Convert(char token, bool building_deny_info_url);
+    const char *Convert(char token, bool building_deny_info_url, bool allowRecursion);
 
     /**
      * CacheManager / Debug dump of the ErrorState object.
@@ -155,6 +168,9 @@ public:
     char *request_hdrs;
     char *err_msg; /* Preformatted error message from the cache */
 
+#if USE_SSL
+    Ssl::ErrorDetail *detail;
+#endif
 private:
     CBDATA_CLASS2(ErrorState);
 };
index 88e85884ad203c20c6be53be81efb5400b583746..7f0cceb10cf153d2c085bebfbfcf5196e0ea94e3 100644 (file)
@@ -640,7 +640,7 @@ ESIContext::send ()
     assert (len != 0 || rep != NULL);
 
     if (len) {
-        xmemcpy (next->readBuffer.data, &outbound->buf[outbound_offset], len);
+        memcpy(next->readBuffer.data, &outbound->buf[outbound_offset], len);
 
         if (len + outbound_offset == outbound->len) {
             ESISegment::Pointer temp = outbound->next;
@@ -798,7 +798,7 @@ esiProcessStream (clientStreamNode *thisNode, ClientHttpRequest *http, HttpReply
                    &context->incoming->buf[context->incoming->len] <<
                    " because our buffer was not used");
 
-            xmemcpy (&context->incoming->buf[context->incoming->len], receivedData.data, len);
+            memcpy(&context->incoming->buf[context->incoming->len], receivedData.data, len);
             context->incoming->len += len;
 
             if (context->incoming->len == HTTP_REQBUF_SZ) {
@@ -809,7 +809,7 @@ esiProcessStream (clientStreamNode *thisNode, ClientHttpRequest *http, HttpReply
 
             if (len != receivedData.length) {
                 /* capture the remnants */
-                xmemcpy (context->incoming->buf, &receivedData.data[len], receivedData.length - len);
+                memcpy(context->incoming->buf, &receivedData.data[len], receivedData.length - len);
                 context->incoming->len = receivedData.length - len;
             }
 
@@ -2296,7 +2296,7 @@ ElementList::pop_front (size_t const count)
     if (!count)
         return;
 
-    xmemmove (elements, &elements[count], (elementcount - count)  * sizeof (ESIElement::Pointer));
+    memmove(elements, &elements[count], (elementcount - count)  * sizeof (ESIElement::Pointer));
 
     elementcount -= count;
 }
index c92bfe873467149c7595646de811abc95ba6f203..b81b5e2d624f9cf5c5f34794470c41d08b81377b 100644 (file)
@@ -54,8 +54,8 @@
 
 typedef struct _stackmember stackmember;
 
-typedef int evaluate (stackmember * stack, int *depth, int whereAmI,
-                      stackmember * candidate);
+typedef int evaluate(stackmember * stack, int *depth, int whereAmI,
+                     stackmember * candidate);
 
 typedef enum {
     ESI_EXPR_INVALID,
@@ -94,27 +94,27 @@ struct _stackmember {
     int precedence;
 };
 
-static void cleanmember (stackmember *);
-static void stackpop (stackmember * s, int *depth);
+static void cleanmember(stackmember *);
+static void stackpop(stackmember * s, int *depth);
 
 void
-cleanmember (stackmember * s)
+cleanmember(stackmember * s)
 {
     if (s->valuetype == ESI_EXPR_LITERAL
             && s->valuestored == ESI_LITERAL_STRING) {
-        safe_free (s->value.string);
+        safe_free(s->value.string);
         s->value.string = NULL;
     }
 
 }
 
 void
-stackpop (stackmember * s, int *depth)
+stackpop(stackmember * s, int *depth)
 {
     if (!(*depth)--)
         return;
 
-    cleanmember (&s[*depth]);
+    cleanmember(&s[*depth]);
 }
 
 static evaluate evalnegate;
@@ -130,14 +130,14 @@ static evaluate evalnotequals;
 static evaluate evalstartexpr;
 static evaluate evalendexpr;
 static evaluate evalexpr;
-static void dumpstack (stackmember * stack, int depth);
-static int addmember (stackmember * stack, int *stackdepth,
-                      stackmember * candidate);
-static int membercompare (stackmember a, stackmember b);
-static char const *trim (char const *s);
-static stackmember getsymbol (const char *s, char const **endptr);
-static void printliteral (stackmember s);
-static void printmember (stackmember s);
+static void dumpstack(stackmember * stack, int depth);
+static int addmember(stackmember * stack, int *stackdepth,
+                     stackmember * candidate);
+static int membercompare(stackmember a, stackmember b);
+static char const *trim(char const *s);
+static stackmember getsymbol(const char *s, char const **endptr);
+static void printliteral(stackmember s);
+static void printmember(stackmember s);
 
 /* -2 = failed to compate
  * -1 = a less than b
@@ -145,7 +145,7 @@ static void printmember (stackmember s);
  * 2 - a more than b
  */
 int
-membercompare (stackmember a, stackmember b)
+membercompare(stackmember a, stackmember b)
 {
     /* we can compare: sub expressions to sub expressions ,
      * literals to literals
@@ -163,7 +163,7 @@ membercompare (stackmember a, stackmember b)
             return 1;
     } else if (a.valuestored == ESI_LITERAL_STRING) {
         if (b.valuestored == ESI_LITERAL_STRING) {
-            int i =strcmp (a.value.string, b.value.string);
+            int i =strcmp(a.value.string, b.value.string);
 
             if (i < 0)
                 return -1;
@@ -223,8 +223,8 @@ membercompare (stackmember a, stackmember b)
 }
 
 /* return 0 on success, 1 on failure */
-int evalnegate
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evalnegate(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
 {
     if (whereAmI != *depth - 2)
         /* invalid stack */
@@ -239,7 +239,7 @@ int evalnegate
 
     stack[whereAmI] = stack[(*depth)];
 
-    cleanmember (candidate);
+    cleanmember(candidate);
 
     if (stack[whereAmI].value.integral == 1)
         stack[whereAmI].value.integral = 0;
@@ -249,16 +249,16 @@ int evalnegate
     return 0;
 }
 
-int evalliteral
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evalliteral(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
 {
     debugs(86, 1, "attempt to evaluate a literal");
     /* literals can't be evaluated */
     return 1;
 }
 
-int evalexpr
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evalexpr(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
 {
     debugs(86, 1, "attempt to evaluate a sub-expression result");
     /* sub-scpr's can't be evaluated */
@@ -266,8 +266,8 @@ int evalexpr
 }
 
 
-int evalor
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evalor(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
 {
     int rv;
     stackmember srv;
@@ -291,11 +291,11 @@ int evalor
         /* invalid comparison */
         return 1;
 
-    stackpop (stack, depth);      /* arg rhs */
+    stackpop(stack, depth);      /* arg rhs */
 
-    stackpop (stack, depth);      /* me */
+    stackpop(stack, depth);      /* me */
 
-    stackpop (stack, depth);      /* arg lhs */
+    stackpop(stack, depth);      /* arg lhs */
 
     srv.valuetype = ESI_EXPR_EXPR;
 
@@ -310,15 +310,15 @@ int evalor
     stack[(*depth)++] = srv;
 
     /* we're out of way, try adding now */
-    if (!addmember (stack, depth, candidate))
+    if (!addmember(stack, depth, candidate))
         /* Something wrong upstream */
         return 1;
 
     return 0;
 }
 
-int evaland
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evaland(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
 {
     int rv;
     stackmember srv;
@@ -342,11 +342,11 @@ int evaland
         /* invalid comparison */
         return 1;
 
-    stackpop (stack, depth);      /* arg rhs */
+    stackpop(stack, depth);      /* arg rhs */
 
-    stackpop (stack, depth);      /* me */
+    stackpop(stack, depth);      /* me */
 
-    stackpop (stack, depth);      /* arg lhs */
+    stackpop(stack, depth);      /* arg lhs */
 
     srv.valuetype = ESI_EXPR_EXPR;
 
@@ -361,15 +361,15 @@ int evaland
     stack[(*depth)++] = srv;
 
     /* we're out of way, try adding now */
-    if (!addmember (stack, depth, candidate))
+    if (!addmember(stack, depth, candidate))
         /* Something wrong upstream */
         return 1;
 
     return 0;
 }
 
-int evallesseq
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evallesseq(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
 {
     int rv;
     stackmember srv;
@@ -382,17 +382,17 @@ int evallesseq
         /* invalid stack */
         return 1;
 
-    rv = membercompare (stack[whereAmI - 1], stack[whereAmI + 1]);
+    rv = membercompare(stack[whereAmI - 1], stack[whereAmI + 1]);
 
     if (rv == -2)
         /* invalid comparison */
         return 1;
 
-    stackpop (stack, depth);      /* arg rhs */
+    stackpop(stack, depth);      /* arg rhs */
 
-    stackpop (stack, depth);      /* me */
+    stackpop(stack, depth);      /* me */
 
-    stackpop (stack, depth);      /* arg lhs */
+    stackpop(stack, depth);      /* arg lhs */
 
     srv.valuetype = ESI_EXPR_EXPR;
 
@@ -407,7 +407,7 @@ int evallesseq
     stack[(*depth)++] = srv;
 
     /* we're out of way, try adding now */
-    if (!addmember (stack, depth, candidate))
+    if (!addmember(stack, depth, candidate))
         /* Something wrong upstream */
         return 1;
 
@@ -417,8 +417,8 @@ int evallesseq
 
 }
 
-int evallessthan
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evallessthan(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
 {
     int rv;
     stackmember srv;
@@ -431,17 +431,17 @@ int evallessthan
         /* invalid stack */
         return 1;
 
-    rv = membercompare (stack[whereAmI - 1], stack[whereAmI + 1]);
+    rv = membercompare(stack[whereAmI - 1], stack[whereAmI + 1]);
 
     if (rv == -2)
         /* invalid comparison */
         return 1;
 
-    stackpop (stack, depth);      /* arg rhs */
+    stackpop(stack, depth);      /* arg rhs */
 
-    stackpop (stack, depth);      /* me */
+    stackpop(stack, depth);      /* me */
 
-    stackpop (stack, depth);      /* arg lhs */
+    stackpop(stack, depth);      /* arg lhs */
 
     srv.valuetype = ESI_EXPR_EXPR;
 
@@ -456,7 +456,7 @@ int evallessthan
     stack[(*depth)++] = srv;
 
     /* we're out of way, try adding now */
-    if (!addmember (stack, depth, candidate))
+    if (!addmember(stack, depth, candidate))
         /* Something wrong upstream */
         return 1;
 
@@ -466,8 +466,8 @@ int evallessthan
 
 }
 
-int evalmoreeq
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evalmoreeq(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
 {
     int rv;
     stackmember srv;
@@ -480,17 +480,17 @@ int evalmoreeq
         /* invalid stack */
         return 1;
 
-    rv = membercompare (stack[whereAmI - 1], stack[whereAmI + 1]);
+    rv = membercompare(stack[whereAmI - 1], stack[whereAmI + 1]);
 
     if (rv == -2)
         /* invalid comparison */
         return 1;
 
-    stackpop (stack, depth);      /* arg rhs */
+    stackpop(stack, depth);      /* arg rhs */
 
-    stackpop (stack, depth);      /* me */
+    stackpop(stack, depth);      /* me */
 
-    stackpop (stack, depth);      /* arg lhs */
+    stackpop(stack, depth);      /* arg lhs */
 
     srv.valuetype = ESI_EXPR_EXPR;
 
@@ -505,7 +505,7 @@ int evalmoreeq
     stack[(*depth)++] = srv;
 
     /* we're out of way, try adding now */
-    if (!addmember (stack, depth, candidate))
+    if (!addmember(stack, depth, candidate))
         /* Something wrong upstream */
         return 1;
 
@@ -515,8 +515,8 @@ int evalmoreeq
 
 }
 
-int evalmorethan
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evalmorethan(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
 {
     int rv;
     stackmember srv;
@@ -529,17 +529,17 @@ int evalmorethan
         /* invalid stack */
         return 1;
 
-    rv = membercompare (stack[whereAmI - 1], stack[whereAmI + 1]);
+    rv = membercompare(stack[whereAmI - 1], stack[whereAmI + 1]);
 
     if (rv == -2)
         /* invalid comparison */
         return 1;
 
-    stackpop (stack, depth);   /* arg rhs */
+    stackpop(stack, depth);    /* arg rhs */
 
-    stackpop (stack, depth);   /* me */
+    stackpop(stack, depth);    /* me */
 
-    stackpop (stack, depth);   /* arg lhs */
+    stackpop(stack, depth);    /* arg lhs */
 
     srv.valuetype = ESI_EXPR_EXPR;
 
@@ -554,7 +554,7 @@ int evalmorethan
     stack[(*depth)++] = srv;
 
     /* we're out of way, try adding now */
-    if (!addmember (stack, depth, candidate))
+    if (!addmember(stack, depth, candidate))
         /* Something wrong upstream */
         return 1;
 
@@ -564,8 +564,8 @@ int evalmorethan
 }
 
 int
-evalequals (stackmember * stack, int *depth, int whereAmI,
-            stackmember * candidate)
+evalequals(stackmember * stack, int *depth, int whereAmI,
+           stackmember * candidate)
 {
     int rv;
     stackmember srv;
@@ -578,17 +578,17 @@ evalequals (stackmember * stack, int *depth, int whereAmI,
         /* invalid stack */
         return 1;
 
-    rv = membercompare (stack[whereAmI - 1], stack[whereAmI + 1]);
+    rv = membercompare(stack[whereAmI - 1], stack[whereAmI + 1]);
 
     if (rv == -2)
         /* invalid comparison */
         return 1;
 
-    stackpop (stack, depth);   /* arg rhs */
+    stackpop(stack, depth);    /* arg rhs */
 
-    stackpop (stack, depth);   /* me */
+    stackpop(stack, depth);    /* me */
 
-    stackpop (stack, depth);   /* arg lhs */
+    stackpop(stack, depth);    /* arg lhs */
 
     srv.valuetype = ESI_EXPR_EXPR;
 
@@ -603,7 +603,7 @@ evalequals (stackmember * stack, int *depth, int whereAmI,
     stack[(*depth)++] = srv;
 
     /* we're out of way, try adding now */
-    if (!addmember (stack, depth, candidate))
+    if (!addmember(stack, depth, candidate))
         /* Something wrong upstream */
         return 1;
 
@@ -611,8 +611,8 @@ evalequals (stackmember * stack, int *depth, int whereAmI,
     return 0;
 }
 
-int evalnotequals
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evalnotequals(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
 {
     int rv;
     stackmember srv;
@@ -625,17 +625,17 @@ int evalnotequals
         /* invalid stack */
         return 1;
 
-    rv = membercompare (stack[whereAmI - 1], stack[whereAmI + 1]);
+    rv = membercompare(stack[whereAmI - 1], stack[whereAmI + 1]);
 
     if (rv == -2)
         /* invalid comparison */
         return 1;
 
-    stackpop (stack, depth);   /* arg rhs */
+    stackpop(stack, depth);    /* arg rhs */
 
-    stackpop (stack, depth);   /* me */
+    stackpop(stack, depth);    /* me */
 
-    stackpop (stack, depth);   /* arg lhs */
+    stackpop(stack, depth);    /* arg lhs */
 
     srv.valuetype = ESI_EXPR_EXPR;
 
@@ -650,7 +650,7 @@ int evalnotequals
     stack[(*depth)++] = srv;
 
     /* we're out of way, try adding now */
-    if (!addmember (stack, depth, candidate))
+    if (!addmember(stack, depth, candidate))
         /* Something wrong upstream */
         return 1;
 
@@ -658,8 +658,8 @@ int evalnotequals
     return 0;
 }
 
-int evalstartexpr
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evalstartexpr(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
 {
     /* debugs(86, 1, "?("); */
 
@@ -675,20 +675,20 @@ int evalstartexpr
 
     stack[whereAmI] = stack[(*depth)];
 
-    cleanmember (candidate);
+    cleanmember(candidate);
 
     return 0;
 }
 
-int evalendexpr
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evalendexpr(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
 {
     /* Can't evaluate ) brackets */
     return 1;
 }
 
 char const *
-trim (char const *s)
+trim(char const *s)
 {
     while (*s == ' ')
         ++s;
@@ -697,33 +697,33 @@ trim (char const *s)
 }
 
 stackmember
-getsymbol (const char *s, char const **endptr)
+getsymbol(const char *s, char const **endptr)
 {
     stackmember rv;
     char *end;
     char const *origs = s;
     /* trim whitespace */
-    s = trim (s);
+    s = trim(s);
     rv.eval = NULL;            /* A literal */
     rv.valuetype = ESI_EXPR_INVALID;
     rv.valuestored = ESI_LITERAL_INVALID;
     rv.precedence = 1; /* A literal */
 
     if (('0' <= *s && *s <= '9') || *s == '-') {
-        size_t length = strspn (s, "0123456789.");
+        size_t length = strspn(s, "0123456789.");
         char const *point;
 
-        if ((point = strchr (s, '.')) && point - s < (ssize_t)length) {
+        if ((point = strchr(s, '.')) && point - s < (ssize_t)length) {
             /* floating point */
             errno=0; /* reset errno */
-            rv.value.floating = strtod (s, &end);
+            rv.value.floating = strtod(s, &end);
 
             if (s == end || errno) {
                 /* Couldn't convert to float */
                 debugs(86, 1, "failed to convert '" << s << "' to float ");
                 *endptr = origs;
             } else {
-                debugs (86,6, "found " << rv.value.floating << " of length " << end - s);
+                debugs(86,6, "found " << rv.value.floating << " of length " << end - s);
                 *endptr = end;
                 rv.eval = evalliteral;
                 rv.valuestored = ESI_LITERAL_FLOAT;
@@ -733,14 +733,14 @@ getsymbol (const char *s, char const **endptr)
         } else {
             /* INT */
             errno=0; /* reset errno */
-            rv.value.integral = strtol (s, &end, 0);
+            rv.value.integral = strtol(s, &end, 0);
 
             if (s == end || errno) {
                 /* Couldn't convert to int */
                 debugs(86, 1, "failed to convert '" << s << "' to int ");
                 *endptr = origs;
             } else {
-                debugs (86,6, "found " << rv.value.integral << " of length " << end - s);
+                debugs(86,6, "found " << rv.value.integral << " of length " << end - s);
                 *endptr = end;
                 rv.eval = evalliteral;
                 rv.valuestored = ESI_LITERAL_INT;
@@ -777,9 +777,9 @@ getsymbol (const char *s, char const **endptr)
             /* Special case for zero length strings */
 
             if (t - s - 1)
-                rv.value.string = xstrndup (s + 1, t - s - 1);
+                rv.value.string = xstrndup(s + 1, t - s - 1);
             else
-                rv.value.string = static_cast<char *>(xcalloc (1,1));
+                rv.value.string = static_cast<char *>(xcalloc(1,1));
 
             rv.eval = evalliteral;
 
@@ -854,7 +854,7 @@ getsymbol (const char *s, char const **endptr)
             rv.precedence = 5;
             rv.eval = evalmorethan;
         }
-    } else if (!strncmp (s, "false", 5)) {
+    } else if (!strncmp(s, "false", 5)) {
         debugs(86, 5, "getsymbol: found variable result 'false'");
         *endptr = s + 5;
         rv.valuetype = ESI_EXPR_EXPR;
@@ -862,7 +862,7 @@ getsymbol (const char *s, char const **endptr)
         rv.value.integral = 0;
         rv.precedence = 1;
         rv.eval = evalexpr;
-    } else if (!strncmp (s, "true", 4)) {
+    } else if (!strncmp(s, "true", 4)) {
         debugs(86, 5, "getsymbol: found variable result 'true'");
         *endptr = s + 4;
         rv.valuetype = ESI_EXPR_EXPR;
@@ -879,24 +879,24 @@ getsymbol (const char *s, char const **endptr)
 }
 
 void
-printliteral (stackmember s)
+printliteral(stackmember s)
 {
     switch (s.valuestored) {
 
     case ESI_LITERAL_INVALID:
-        old_debug(86, 1) ( " Invalid " );
+        old_debug(86, 1)( " Invalid " );
         break;
 
     case ESI_LITERAL_FLOAT:
-        old_debug(86,1) ("%f", s.value.floating);
+        old_debug(86,1)("%f", s.value.floating);
         break;
 
     case ESI_LITERAL_STRING:
-        old_debug(86,1) ("'%s'", s.value.string);
+        old_debug(86,1)("'%s'", s.value.string);
         break;
 
     case ESI_LITERAL_INT:
-        old_debug(86,1) ("%d", s.value.integral);
+        old_debug(86,1)("%d", s.value.integral);
         break;
 
     case ESI_LITERAL_BOOL:
@@ -905,82 +905,82 @@ printliteral (stackmember s)
 }
 
 void
-printmember (stackmember s)
+printmember(stackmember s)
 {
     switch (s.valuetype) {
 
     case ESI_EXPR_INVALID:
-        old_debug(86,1) (" Invalid ");
+        old_debug(86,1)(" Invalid ");
         break;
 
     case ESI_EXPR_LITERAL:
-        printliteral (s);
+        printliteral(s);
         break;
 
     case ESI_EXPR_EXPR:
-        old_debug(86,1) ("%s", s.value.integral ? "true" : "false");
+        old_debug(86,1)("%s", s.value.integral ? "true" : "false");
         break;
 
     case ESI_EXPR_OR:
-        old_debug(86,1) ("|");
+        old_debug(86,1)("|");
         break;
 
     case ESI_EXPR_AND:
-        old_debug(86,1) ("&");
+        old_debug(86,1)("&");
         break;
 
     case ESI_EXPR_NOT:
-        old_debug(86,1) ("!");
+        old_debug(86,1)("!");
         break;
 
     case ESI_EXPR_START:
-        old_debug(86,1) ("(");
+        old_debug(86,1)("(");
         break;
 
     case ESI_EXPR_END:
-        old_debug(86,1) (")");
+        old_debug(86,1)(")");
         break;
 
     case ESI_EXPR_EQ:
-        old_debug(86,1) ("==");
+        old_debug(86,1)("==");
         break;
 
     case ESI_EXPR_NOTEQ:
-        old_debug(86,1) ("!=");
+        old_debug(86,1)("!=");
         break;
 
     case ESI_EXPR_LESS:
-        old_debug(86,1) ("<");
+        old_debug(86,1)("<");
         break;
 
     case ESI_EXPR_LESSEQ:
-        old_debug(86,1) ("<=");
+        old_debug(86,1)("<=");
         break;
 
     case ESI_EXPR_MORE:
-        old_debug(86,1) (">");
+        old_debug(86,1)(">");
         break;
 
     case ESI_EXPR_MOREEQ:
-        old_debug(86,1) (">=");
+        old_debug(86,1)(">=");
         break;
     }
 }
 
 void
-dumpstack (stackmember * stack, int depth)
+dumpstack(stackmember * stack, int depth)
 {
     int i;
 
     for (i = 0; i < depth; ++i)
-        printmember (stack[i]);
+        printmember(stack[i]);
 
     if (depth)
-        old_debug(86,1) ("\n");
+        old_debug(86,1)("\n");
 }
 
 int
-addmember (stackmember * stack, int *stackdepth, stackmember * candidate)
+addmember(stackmember * stack, int *stackdepth, stackmember * candidate)
 {
     if (candidate->valuetype != ESI_EXPR_LITERAL && *stackdepth > 1) {
         /* !(!(a==b))) is why thats safe */
@@ -992,11 +992,11 @@ addmember (stackmember * stack, int *stackdepth, stackmember * candidate)
 
             if (stack[*stackdepth - 2].valuetype == ESI_EXPR_LITERAL ||
                     stack[*stackdepth - 2].valuetype == ESI_EXPR_INVALID ||
-                    stack[*stackdepth - 2].eval (stack, stackdepth,
-                                                 *stackdepth - 2, candidate)) {
+                    stack[*stackdepth - 2].eval(stack, stackdepth,
+                                                *stackdepth - 2, candidate)) {
                 /* cleanup candidate and stack */
-                dumpstack (stack, *stackdepth);
-                cleanmember (candidate);
+                dumpstack(stack, *stackdepth);
+                cleanmember(candidate);
                 debugs(86, 1, "invalid expression");
                 return 0;
             }
@@ -1010,7 +1010,7 @@ addmember (stackmember * stack, int *stackdepth, stackmember * candidate)
 }
 
 int
-ESIExpression::Evaluate (char const *s)
+ESIExpression::Evaluate(char const *s)
 {
     stackmember stack[20];
     int stackdepth = 0;
@@ -1018,12 +1018,12 @@ ESIExpression::Evaluate (char const *s)
     PROF_start(esiExpressionEval);
 
     while (*s) {
-        stackmember candidate = getsymbol (s, &end);
+        stackmember candidate = getsymbol(s, &end);
 
         if (candidate.valuetype != ESI_EXPR_INVALID) {
-            assert (s != end);
+            assert(s != end);
 
-            if (!addmember (stack, &stackdepth, &candidate)) {
+            if (!addmember(stack, &stackdepth, &candidate)) {
                 PROF_stop(esiExpressionEval);
                 return 0;
             }
@@ -1043,7 +1043,7 @@ ESIExpression::Evaluate (char const *s)
         rv.precedence = 0;
 
         if (stack[stackdepth - 2].
-                eval (stack, &stackdepth, stackdepth - 2, &rv)) {
+                eval(stack, &stackdepth, stackdepth - 2, &rv)) {
             /* special case - leading operator failed */
             debugs(86, 1, "invalid expression");
             PROF_stop(esiExpressionEval);
@@ -1058,9 +1058,9 @@ ESIExpression::Evaluate (char const *s)
     }
 
     /* if we hit here, we think we have a valid result */
-    assert (stackdepth == 1);
+    assert(stackdepth == 1);
 
-    assert (stack[0].valuetype == ESI_EXPR_EXPR);
+    assert(stack[0].valuetype == ESI_EXPR_EXPR);
 
     PROF_stop(esiExpressionEval);
 
index 797fbd3fdb2132ece6dc7d7d2788d856098b96f2..54880c534912fed6a54c3fe64e8b873f6fa928d0 100644 (file)
@@ -140,7 +140,7 @@ esiBufferRecipient (clientStreamNode *node, ClientHttpRequest *http, HttpReply *
 
             if (receivedData.data != esiStream->localbuffer->buf) {
                 /* But not the start of it */
-                xmemmove (esiStream->localbuffer->buf, receivedData.data, receivedData.length);
+                memmove(esiStream->localbuffer->buf, receivedData.data, receivedData.length);
             }
 
             esiStream->localbuffer->len = receivedData.length;
index a6f9df604d7ec915137ff1e53884d1516ee91026..8ed6ddc6a492f9db0013ce191f2d51b171ff5948 100644 (file)
@@ -114,7 +114,7 @@ ESISegment::listToChar() const
     size_t pos = 0;
 
     while (temp.getRaw()) {
-        xmemcpy (&rv[pos], temp->buf, temp->len);
+        memcpy(&rv[pos], temp->buf, temp->len);
         pos += temp->len;
         temp = temp->next;
     }
@@ -179,7 +179,7 @@ size_t
 ESISegment::append(char const *appendBuffer, size_t appendLength)
 {
     size_t toCopy = min(appendLength, space());
-    xmemcpy (&buf[len], appendBuffer, toCopy);
+    memcpy(&buf[len], appendBuffer, toCopy);
     len += toCopy;
     return toCopy;
 }
index 7e76de465626c53fa3a1a475b94a69f6f146f94f..b64cda26a9d76a95641429c5f9e8be99a8810709 100644 (file)
@@ -52,8 +52,7 @@
          and can be wrapped
  */
 
-#if _SQUID_WIN32_
-
+#if _SQUID_WINDOWS_
 struct arpreq {
 
     Ip::Address arp_pa;   /* protocol address */
@@ -160,9 +159,9 @@ bool
 Eui::Eui48::lookup(Ip::Address &c)
 {
     struct arpreq arpReq;
-#if !_SQUID_WIN32_
+#if !_SQUID_WINDOWS_
     struct sockaddr_in *sa = NULL;
-#endif /* !_SQUID_WIN32_ */
+#endif /* !_SQUID_WINDOWS_ */
 
     Ip::Address ipAddr = c;
     ipAddr.SetPort(0);
@@ -451,7 +450,7 @@ Eui::Eui48::lookup(Ip::Address &c)
     set(arpReq.arp_ha.sa_data, 6);
     return true;
 
-#elif _SQUID_WIN32_
+#elif _SQUID_WINDOWS_
 
     DWORD           dwNetTable = 0;
 
index 192948806b62bbe46f4ce96420a0935c8c0de438..aef254110139d993eeec3cf3c4f36d312db0a99f 100644 (file)
@@ -64,6 +64,9 @@
 #include "rfc1738.h"
 #include "URLScheme.h"
 #include "wordlist.h"
+#if USE_SSL
+#include "ssl/support.h"
+#endif
 
 #ifndef DEFAULT_EXTERNAL_ACL_TTL
 #define DEFAULT_EXTERNAL_ACL_TTL 1 * 60 * 60
@@ -91,8 +94,7 @@ class external_acl
 public:
     external_acl *next;
 
-    void add
-    (ExternalACLEntry *);
+    void add(ExternalACLEntry *);
 
     void trimCache();
 
@@ -625,9 +627,7 @@ find_externalAclHelper(const char *name)
 }
 
 void
-
-external_acl::add
-(ExternalACLEntry *anEntry)
+external_acl::add(ExternalACLEntry *anEntry)
 {
     trimCache();
     assert (anEntry->def == NULL);
@@ -1104,7 +1104,7 @@ external_acl_grace_expired(external_acl * def, external_acl_entry * entry)
     ttl = entry->result == 1 ? def->ttl : def->negative_ttl;
     ttl = (ttl * (100 - def->grace)) / 100;
 
-    if (entry->date + ttl < squid_curtime)
+    if (entry->date + ttl <= squid_curtime)
         return 1;
     else
         return 0;
@@ -1128,8 +1128,7 @@ external_acl_cache_add(external_acl * def, const char *key, ExternalACLEntryData
     entry->key = xstrdup(key);
     entry->update (data);
 
-    def->add
-    (entry);
+    def->add(entry);
 
     return entry;
 }
index e895d9c1f4b8820d4d7c41d2e6dbc8c404be8aa8..d3e685c63f12f401314954bfa3de6dbc817ce0aa 100644 (file)
--- a/src/fd.cc
+++ b/src/fd.cc
@@ -34,6 +34,7 @@
  */
 
 #include "squid.h"
+#include "comm/Loops.h"
 #include "fde.h"
 #include "SquidTime.h"
 #include "Debug.h"
@@ -110,8 +111,8 @@ fd_close(int fd)
     }
 
     debugs(51, 3, "fd_close FD " << fd << " " << F->desc);
-    commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
-    commSetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0);
+    Comm::SetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
+    Comm::SetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0);
     F->flags.open = 0;
     fdUpdateBiggest(fd, 0);
     Number_FD--;
index e7dcc6b034eafcb0f05efcf028bbfaa569182b89..d6d41ad1c937e003af614f5cd852c65ad528a0ca 100644 (file)
@@ -78,7 +78,7 @@ file_map_grow(fileMap * fm)
     debugs(8, 3, "file_map_grow: creating space for " << fm->max_n_files << " files");
     fm->file_map = (unsigned long *)xcalloc(fm->nwords, sizeof(*fm->file_map));
     debugs(8, 3, "copying " << old_sz << " old bytes");
-    xmemcpy(fm->file_map, old_map, old_sz);
+    memcpy(fm->file_map, old_map, old_sz);
     xfree(old_map);
     /* XXX account fm->file_map */
 }
index 3be71918389bb803723d4afaf61e195cf8a2f6e3..930a11062937c5e3b7ab64221d1bdde68d76e9e9 100644 (file)
@@ -36,6 +36,7 @@
 #include "acl/FilledChecklist.h"
 #include "acl/Gadgets.h"
 #include "CacheManager.h"
+#include "comm/Loops.h"
 #include "event.h"
 #include "errorpage.h"
 #include "fde.h"
 #include "ip/Intercept.h"
 #include "ip/tools.h"
 #include "mgr/Registration.h"
+#if USE_SSL
+#include "ssl/support.h"
+#include "ssl/ErrorDetail.h"
+#endif
 
 static PSC fwdStartCompleteWrapper;
 static PF fwdServerClosedWrapper;
@@ -67,11 +72,6 @@ static void fwdServerFree(FwdServer * fs);
 #define MAX_FWD_STATS_IDX 9
 static int FwdReplyCodes[MAX_FWD_STATS_IDX + 1][HTTP_INVALID_HEADER + 1];
 
-#if WIP_FWD_LOG
-static void fwdLog(FwdState * fwdState);
-static Logfile *logfile = NULL;
-#endif
-
 static PconnPool *fwdPconnPool = new PconnPool("server-side");
 CBDATA_CLASS_INIT(FwdState);
 
@@ -136,10 +136,6 @@ FwdState::completed()
 
     entry->mem_obj->checkUrlChecksum();
 #endif
-#if WIP_FWD_LOG
-
-    log();
-#endif
 
     if (entry->store_status == STORE_PENDING) {
         if (entry->isEmpty()) {
@@ -590,11 +586,11 @@ FwdState::negotiateSSL(int fd)
         switch (ssl_error) {
 
         case SSL_ERROR_WANT_READ:
-            commSetSelect(fd, COMM_SELECT_READ, fwdNegotiateSSLWrapper, this, 0);
+            Comm::SetSelect(fd, COMM_SELECT_READ, fwdNegotiateSSLWrapper, this, 0);
             return;
 
         case SSL_ERROR_WANT_WRITE:
-            commSetSelect(fd, COMM_SELECT_WRITE, fwdNegotiateSSLWrapper, this, 0);
+            Comm::SetSelect(fd, COMM_SELECT_WRITE, fwdNegotiateSSLWrapper, this, 0);
             return;
 
         default:
@@ -610,6 +606,14 @@ FwdState::negotiateSSL(int fd)
             anErr->xerrno = EACCES;
 #endif
 
+            Ssl::ErrorDetail *errFromFailure = (Ssl::ErrorDetail *)SSL_get_ex_data(ssl, ssl_ex_index_ssl_error_detail);
+            if (errFromFailure != NULL) {
+                // The errFromFailure is attached to the ssl object
+                // and will be released when ssl object destroyed.
+                // Copy errFromFailure to a new Ssl::ErrorDetail object
+                anErr->detail = new Ssl::ErrorDetail(*errFromFailure);
+            }
+
             fail(anErr);
 
             if (fs->_peer) {
@@ -1263,18 +1267,6 @@ void
 FwdState::initModule()
 {
     memDataInit(MEM_FWD_SERVER, "FwdServer", sizeof(FwdServer), 0);
-
-#if WIP_FWD_LOG
-
-    if (logfile)
-        (void) 0;
-    else if (NULL == Config.Log.forward)
-        (void) 0;
-    else
-        logfile = logfileOpen(Config.Log.forward, 0, 1);
-
-#endif
-
     RegisterWithCacheManager();
 }
 
@@ -1469,47 +1461,3 @@ GetNfmarkToServer(HttpRequest * request)
 
     return aclMapNfmark(Ip::Qos::TheConfig.nfmarkToServer, &ch);
 }
-
-
-/**** WIP_FWD_LOG *************************************************************/
-
-#if WIP_FWD_LOG
-void
-fwdUninit(void)
-{
-    if (NULL == logfile)
-        return;
-
-    logfileClose(logfile);
-
-    logfile = NULL;
-}
-
-void
-fwdLogRotate(void)
-{
-    if (logfile)
-        logfileRotate(logfile);
-}
-
-static void
-FwdState::log()
-{
-    if (NULL == logfile)
-        return;
-
-    logfilePrintf(logfile, "%9d.%03d %03d %s %s\n",
-                  (int) current_time.tv_sec,
-                  (int) current_time.tv_usec / 1000,
-                  last_status,
-                  RequestMethodStr(request->method),
-                  request->canonical);
-}
-
-void
-FwdState::status(http_status s)
-{
-    last_status = s;
-}
-
-#endif
index 5cf645bd410fc5824dd9764ec7735c40775b2768..0324c8f4d25e09241cafd15ffbcb05f2959718dd 100644 (file)
@@ -81,13 +81,6 @@ private:
     ErrorState *makeConnectingError(const err_type type) const;
     static void RegisterWithCacheManager(void);
 
-#if WIP_FWD_LOG
-
-    void uninit                /**DOCS_NOSEMI*/
-    static void logRotate      /**DOCS_NOSEMI*/
-    void status()              /**DOCS_NOSEMI*/
-#endif
-
 public:
     StoreEntry *entry;
     HttpRequest *request;
@@ -102,10 +95,6 @@ private:
     time_t start_t;
     int n_tries;
     int origin_tries;
-#if WIP_FWD_LOG
-
-    http_status last_status;
-#endif
 
     struct {
         unsigned int dont_retry:1;
index d3cc6108c85f0d6c734cd14dcf10f056187b0e21..ef75be1622bd839f8c5e86f0939075b00a8cac28 100644 (file)
@@ -152,6 +152,9 @@ static long fqdncache_low = 180;
 /// \ingroup FQDNCacheInternal
 static long fqdncache_high = 200;
 
+/// \ingroup FQDNCacheInternal
+inline int fqdncacheCount() { return fqdn_table ? fqdn_table->count : 0; }
+
 int
 fqdncache_entry::age() const
 {
@@ -229,7 +232,7 @@ fqdncache_purgelru(void *notused)
     eventAdd("fqdncache_purgelru", fqdncache_purgelru, NULL, 10.0, 1);
 
     for (m = lru_list.tail; m; m = prev) {
-        if (memInUse(MEM_FQDNCACHE_ENTRY) < fqdncache_low)
+        if (fqdncacheCount() < fqdncache_low)
             break;
 
         prev = m->prev;
@@ -698,9 +701,12 @@ fqdnStats(StoreEntry * sentry)
 
     storeAppendPrintf(sentry, "FQDN Cache Statistics:\n");
 
-    storeAppendPrintf(sentry, "FQDNcache Entries: %d\n",
+    storeAppendPrintf(sentry, "FQDNcache Entries In Use: %d\n",
                       memInUse(MEM_FQDNCACHE_ENTRY));
 
+    storeAppendPrintf(sentry, "FQDNcache Entries Cached: %d\n",
+                      fqdncacheCount());
+
     storeAppendPrintf(sentry, "FQDNcache Requests: %d\n",
                       FqdncacheStats.requests);
 
@@ -882,7 +888,7 @@ snmp_netFqdnFn(variable_list * Var, snint * ErrP)
 
     case FQDN_ENT:
         Answer = snmp_var_new_integer(Var->name, Var->name_length,
-                                      memInUse(MEM_FQDNCACHE_ENTRY),
+                                      fqdncacheCount(),
                                       SMI_GAUGE32);
         break;
 
index e3e2fe443c241cae56233cf8d9cb3112ff6c932b..025139c4018f4db8b54e3c6a73d44795d64966ce 100644 (file)
@@ -201,12 +201,12 @@ CossSwapDir::readCompleted(const char *buf, int len, int errflag, RefCount<ReadR
             cstate->readbuffer = (char *)xmalloc(cstate->st_size);
             p = storeCossMemPointerFromDiskOffset(storeCossFilenoToDiskOffset(sio->swap_filen),
                                                   NULL);
-            xmemcpy(cstate->readbuffer, p, cstate->st_size);
+            memcpy(cstate->readbuffer, p, cstate->st_size);
         }
 
         sio->offset_ += len;
-        xmemcpy(cstate->requestbuf, &cstate->readbuffer[cstate->requestoffset],
-                cstate->requestlen);
+        memcpy(cstate->requestbuf, &cstate->readbuffer[cstate->requestoffset],
+               cstate->requestlen);
         rlen = (size_t) cstate->requestlen;
     }
 
@@ -785,8 +785,8 @@ CossCleanLog::write(StoreEntry const &e)
     s.swap_file_sz = e.swap_file_sz;
     s.refcount = e.refcount;
     s.flags = e.flags;
-    xmemcpy(&s.key, e.key, SQUID_MD5_DIGEST_LENGTH);
-    xmemcpy(outbuf + outbuf_offset, &s, ss);
+    memcpy(&s.key, e.key, SQUID_MD5_DIGEST_LENGTH);
+    memcpy(outbuf + outbuf_offset, &s, ss);
     outbuf_offset += ss;
     /* buffered write */
 
@@ -836,10 +836,9 @@ CossSwapDir::writeCleanDone()
     /* rename */
 
     if (state->fd >= 0) {
-#if defined(_SQUID_OS2_) || defined(_SQUID_WIN32_)
+#if _SQUID_OS2_ || _SQUID_WINDOWS_
         file_close(state->fd);
         state->fd = -1;
-
 #endif
 
         xrename(state->newLog, state->cur);
@@ -890,7 +889,7 @@ CossSwapDir::logEntry(const StoreEntry & e, int op) const
     s->swap_file_sz = e.swap_file_sz;
     s->refcount = e.refcount;
     s->flags = e.flags;
-    xmemcpy(s->key, e.key, SQUID_MD5_DIGEST_LENGTH);
+    memcpy(s->key, e.key, SQUID_MD5_DIGEST_LENGTH);
     file_write(swaplog_fd,
                -1,
                s,
@@ -997,8 +996,8 @@ void
 CossSwapDir::statfs(StoreEntry & sentry) const
 {
     storeAppendPrintf(&sentry, "\n");
-    storeAppendPrintf(&sentry, "Maximum Size: %Zu KB\n", max_size);
-    storeAppendPrintf(&sentry, "Current Size: %Zu KB\n", cur_size);
+    storeAppendPrintf(&sentry, "Maximum Size: %lu KB\n", max_size);
+    storeAppendPrintf(&sentry, "Current Size: %lu KB\n", cur_size);
     storeAppendPrintf(&sentry, "Percent Used: %0.2f%%\n",
                       (100.0 * (double)cur_size / (double)max_size) );
     storeAppendPrintf(&sentry, "Number of object collisions: %d\n", (int) numcollisions);
@@ -1096,7 +1095,7 @@ CossSwapDir::reconfigure(int index, char *path)
 void
 CossSwapDir::dump(StoreEntry &entry)const
 {
-    storeAppendPrintf(&entry, " %Zu", (max_size >> 10));
+    storeAppendPrintf(&entry, " %lu", (max_size >> 10));
     dumpOptions(&entry);
 }
 
index b82d71c012d7be618a0a4899089bc67ab5de148e..659395d85a0db95c725412cd1813b44dd4382468 100644 (file)
@@ -221,7 +221,7 @@ CossSwapDir::openStoreIO(StoreEntry & e, StoreIOState::STFNCB * file_callback,
 
     if (p) {
         cstate->readbuffer = (char *)xmalloc(cstate->st_size);
-        xmemcpy(cstate->readbuffer, p, cstate->st_size);
+        memcpy(cstate->readbuffer, p, cstate->st_size);
         StoreFScoss::GetInstance().stats.open_mem_hits++;
     } else {
         /* Do the allocation */
@@ -344,7 +344,7 @@ CossState::write(char const *buf, size_t size, off_t offset, FREE * free_func)
     CossSwapDir *SD = (CossSwapDir *)INDEXSD(swap_dirn);
     dest = SD->storeCossMemPointerFromDiskOffset(diskoffset, &membuf);
     assert(dest != NULL);
-    xmemcpy(dest, buf, size);
+    memcpy(dest, buf, size);
     offset_ += size;
 
     if (free_func)
index cdd0259f561677ebeefb4658889d3dd0662b1f5f..09101df3f95d822aaad0262611bd87a54b6b7ab2 100644 (file)
@@ -312,8 +312,8 @@ UFSSwapDir::statfs(StoreEntry & sentry) const
     int x;
     storeAppendPrintf(&sentry, "First level subdirectories: %d\n", l1);
     storeAppendPrintf(&sentry, "Second level subdirectories: %d\n", l2);
-    storeAppendPrintf(&sentry, "Maximum Size: %Zu KB\n", max_size);
-    storeAppendPrintf(&sentry, "Current Size: %Zu KB\n", cur_size);
+    storeAppendPrintf(&sentry, "Maximum Size: %"PRIu64" KB\n", max_size);
+    storeAppendPrintf(&sentry, "Current Size: %"PRIu64" KB\n", cur_size);
     storeAppendPrintf(&sentry, "Percent Used: %0.2f%%\n",
                       (double)(100.0 * cur_size) / (double)max_size);
     storeAppendPrintf(&sentry, "Filemap bits in use: %d of %d (%d%%)\n",
@@ -882,7 +882,7 @@ UFSSwapDir::writeCleanStart()
     state->outbuf = (char *)xcalloc(CLEAN_BUF_SZ, 1);
     state->outbuf_offset = 0;
     /*copy the header */
-    xmemcpy(state->outbuf, &header, sizeof(StoreSwapLogHeader));
+    memcpy(state->outbuf, &header, sizeof(StoreSwapLogHeader));
     state->outbuf_offset += header.record_size;
 
     state->walker = repl->WalkInit(repl);
@@ -931,8 +931,8 @@ UFSCleanLog::write(StoreEntry const &e)
     s.swap_file_sz = e.swap_file_sz;
     s.refcount = e.refcount;
     s.flags = e.flags;
-    xmemcpy(&s.key, e.key, SQUID_MD5_DIGEST_LENGTH);
-    xmemcpy(outbuf + outbuf_offset, &s, ss);
+    memcpy(&s.key, e.key, SQUID_MD5_DIGEST_LENGTH);
+    memcpy(outbuf + outbuf_offset, &s, ss);
     outbuf_offset += ss;
     /* buffered write */
 
@@ -986,10 +986,9 @@ UFSSwapDir::writeCleanDone()
     /* rename */
 
     if (state->fd >= 0) {
-#if defined(_SQUID_OS2_) || defined (_SQUID_WIN32_)
+#if _SQUID_OS2_ || _SQUID_WINDOWS_
         file_close(state->fd);
         state->fd = -1;
-
 #endif
 
         xrename(state->newLog, state->cur);
@@ -1040,7 +1039,7 @@ UFSSwapDir::logEntry(const StoreEntry & e, int op) const
     s->swap_file_sz = e.swap_file_sz;
     s->refcount = e.refcount;
     s->flags = e.flags;
-    xmemcpy(s->key, e.key, SQUID_MD5_DIGEST_LENGTH);
+    memcpy(s->key, e.key, SQUID_MD5_DIGEST_LENGTH);
     file_write(swaplog_fd,
                -1,
                s,
@@ -1323,7 +1322,7 @@ UFSSwapDir::replacementRemove(StoreEntry * e)
 void
 UFSSwapDir::dump(StoreEntry & entry) const
 {
-    storeAppendPrintf(&entry, " %Zu %d %d", (max_size >> 10), l1, l2);
+    storeAppendPrintf(&entry, " %"PRIu64" %d %d", (max_size >> 10), l1, l2);
     dumpOptions(&entry);
 }
 
index fcfbab3d7a4db84c5d6a445afebcbe38d96ed256..5c89a1d2ee12c924f7009b5b46795b4bdc272321 100644 (file)
@@ -89,7 +89,7 @@ public:
         swapData.swap_file_sz = readData.swap_file_sz;
         swapData.refcount = readData.refcount;
         swapData.flags = readData.flags;
-        xmemcpy(swapData.key, readData.key, SQUID_MD5_DIGEST_LENGTH);
+        memcpy(swapData.key, readData.key, SQUID_MD5_DIGEST_LENGTH);
         return true;
     }
 };
@@ -137,7 +137,7 @@ public:
         swapData.swap_file_sz = readData.swap_file_sz;
         swapData.refcount = readData.refcount;
         swapData.flags = readData.flags;
-        xmemcpy(swapData.key, readData.key, SQUID_MD5_DIGEST_LENGTH);
+        memcpy(swapData.key, readData.key, SQUID_MD5_DIGEST_LENGTH);
         return true;
     }
 };
@@ -186,7 +186,7 @@ public:
         swapData.swap_file_sz = readData.swap_file_sz;
         swapData.refcount = readData.refcount;
         swapData.flags = readData.flags;
-        xmemcpy(swapData.key, readData.key, SQUID_MD5_DIGEST_LENGTH);
+        memcpy(swapData.key, readData.key, SQUID_MD5_DIGEST_LENGTH);
         return true;
     }
 };
@@ -370,7 +370,7 @@ struct InitStoreEntry : public unary_function<StoreMeta, void> {
 
         case STORE_META_KEY:
             assert(x.length == SQUID_MD5_DIGEST_LENGTH);
-            xmemcpy(index, x.value, SQUID_MD5_DIGEST_LENGTH);
+            memcpy(index, x.value, SQUID_MD5_DIGEST_LENGTH);
             break;
 
         case STORE_META_STD:
@@ -396,7 +396,7 @@ struct InitStoreEntry : public unary_function<StoreMeta, void> {
 
         case STORE_META_STD_LFS:
             assert(x.length == STORE_HDR_METASIZE);
-            xmemcpy(&what->timestamp, x.value, STORE_HDR_METASIZE);
+            memcpy(&what->timestamp, x.value, STORE_HDR_METASIZE);
             break;
 
         default:
index ed3f22dcebbba00e9ed4100745c1b37085eff9b3..752c2ebf60068f3886d7193cb38e9cb2ecc29de0 100644 (file)
@@ -34,8 +34,9 @@
 
 #include "squid.h"
 #include "comm.h"
+#include "CommCalls.h"
+#include "comm/TcpAcceptor.h"
 #include "comm/Write.h"
-#include "comm/ListenStateData.h"
 #include "compat/strtoll.h"
 #include "ConnectionDetail.h"
 #include "errorpage.h"
@@ -153,13 +154,11 @@ public:
 
     void clear(); /// just resets fd and close handler. does not close active connections.
 
-    int fd; /// channel descriptor; \todo: remove because the closer has it
+    int fd; /// channel descriptor
 
-    /** Current listening socket handler. delete on shutdown or abort.
-     * FTP stores a copy of the FD in the field fd above.
-     * Use close() to properly close the channel.
-     */
-    Comm::ListenStateData *listener;
+    Ip::Address local; ///< The local IP address:port this channel is using
+
+    int flags; ///< socket flags used when opening.
 
 private:
     AsyncCall::Pointer closer; /// Comm close handler callback
@@ -245,6 +244,12 @@ public:
     void completedListing(void);
     void dataComplete();
     void dataRead(const CommIoCbParams &io);
+
+    /// ignore timeout on CTRL channel. set read timeout on DATA channel.
+    void switchTimeoutToDataChannel();
+    /// create a data channel acceptor and start listening.
+    void listenForDataChannel(const int fd, const char *note);
+
     int checkAuth(const HttpHeader * req_hdr);
     void checkUrlpath();
     void buildTitleUrl();
@@ -443,6 +448,7 @@ FTPSM *FTP_SM_FUNCS[] = {
 void
 FtpStateData::ctrlClosed(const CommCloseCbParams &io)
 {
+    debugs(9, 4, HERE);
     ctrl.clear();
     deleteThis("FtpStateData::ctrlClosed");
 }
@@ -451,10 +457,10 @@ FtpStateData::ctrlClosed(const CommCloseCbParams &io)
 void
 FtpStateData::dataClosed(const CommCloseCbParams &io)
 {
-    if (data.listener) {
-        delete data.listener;
-        data.listener = NULL;
-        data.fd = -1;
+    debugs(9, 4, HERE);
+    if (data.fd >= 0) {
+        comm_close(data.fd);
+        // NP clear() does the: data.fd = -1;
     }
     data.clear();
     failed(ERR_FTP_FAILURE, 0);
@@ -605,6 +611,46 @@ FtpStateData::loginParser(const char *login, int escaped)
     debugs(9, 9, HERE << ": OUT: login='" << login << "', escaped=" << escaped << ", user=" << user << ", password=" << password);
 }
 
+void
+FtpStateData::switchTimeoutToDataChannel()
+{
+    commSetTimeout(ctrl.fd, -1, NULL, NULL);
+
+    typedef CommCbMemFunT<FtpStateData, CommTimeoutCbParams> TimeoutDialer;
+    AsyncCall::Pointer timeoutCall = JobCallback(9, 5, TimeoutDialer, this, FtpStateData::ftpTimeout);
+    commSetTimeout(data.fd, Config.Timeout.read, timeoutCall);
+}
+
+void
+FtpStateData::listenForDataChannel(const int fd, const char *note)
+{
+    assert(data.fd < 0);
+
+    typedef CommCbMemFunT<FtpStateData, CommAcceptCbParams> AcceptDialer;
+    typedef AsyncCallT<AcceptDialer> AcceptCall;
+    RefCount<AcceptCall> call = static_cast<AcceptCall*>(JobCallback(11, 5, AcceptDialer, this, FtpStateData::ftpAcceptDataConnection));
+    Subscription::Pointer sub = new CallSubscription<AcceptCall>(call);
+
+    /* open the conn if its not already open */
+    int newFd = fd;
+    if (newFd < 0) {
+        newFd = comm_open_listener(SOCK_STREAM, IPPROTO_TCP, data.local, data.flags, note);
+        if (newFd < 0) {
+            debugs(5, DBG_CRITICAL, HERE << "comm_open_listener failed:" << data.local << " error: " << errno);
+            return;
+        }
+        debugs(9, 3, HERE << "Unconnected data socket created on FD " << newFd << ", " << data.local);
+    }
+
+    assert(newFd >= 0);
+    Comm::TcpAcceptor *tmp = new Comm::TcpAcceptor(newFd, data.local, data.flags, note, sub);
+    AsyncJob::Start(tmp);
+
+    // Ensure we have a copy of the FD opened for listening and a close handler on it.
+    data.opened(newFd, dataCloser());
+    switchTimeoutToDataChannel();
+}
+
 void
 FtpStateData::ftpTimeout(const CommTimeoutCbParams &io)
 {
@@ -1066,10 +1112,16 @@ FtpStateData::parseListing()
 
     usable = end - sbuf;
 
-    debugs(9, 3, HERE << "usable = " << usable);
+    debugs(9, 3, HERE << "usable = " << usable << " of " << len << " bytes.");
 
     if (usable == 0) {
-        debugs(9, 3, HERE << "didn't find end for " << entry->url()  );
+        if (buf[0] == '\0' && len == 1) {
+            debugs(9, 3, HERE << "NIL ends data from " << entry->url() << " transfer problem?");
+            data.readBuf->consume(len);
+        } else {
+            debugs(9, 3, HERE << "didn't find end for " << entry->url());
+            debugs(9, 3, HERE << "buffer remains (" << len << " bytes) '" << rfc1738_do_escape(buf,0) << "'");
+        }
         xfree(sbuf);
         return;
     }
@@ -1138,7 +1190,14 @@ FtpStateData::dataComplete()
      * status code after the data command.  FtpStateData was being
      * deleted in the middle of dataRead().
      */
-    scheduleReadControlReply(0);
+    /* AYJ: 2011-01-13: Bug 2581.
+     * 226 status is possibly waiting in the ctrl buffer.
+     * The connection will hang if we DONT send buffered_ok.
+     * This happens on all transfers which can be completly sent by the
+     * server before the 150 started status message is read in by Squid.
+     * ie all transfers of about one packet hang.
+     */
+    scheduleReadControlReply(1);
 }
 
 void
@@ -1320,17 +1379,18 @@ FtpStateData::processReplyBody()
 int
 FtpStateData::checkAuth(const HttpHeader * req_hdr)
 {
-    const char *auth;
-
     /* default username */
     xstrncpy(user, "anonymous", MAX_URL);
 
+#if HAVE_AUTH_MODULE_BASIC
     /* Check HTTP Authorization: headers (better than defaults, but less than URL) */
+    const char *auth;
     if ( (auth = req_hdr->getAuth(HDR_AUTHORIZATION, "Basic")) ) {
         flags.authenticated = 1;
         loginParser(auth, FTP_LOGIN_NOT_ESCAPED);
     }
     /* we fail with authorization-required error later IFF the FTP server requests it */
+#endif
 
     /* Test URL login syntax. Overrides any headers received. */
     loginParser(request->login, FTP_LOGIN_ESCAPED);
@@ -1673,7 +1733,7 @@ FtpStateData::scheduleReadControlReply(int buffered_ok)
          * establish one on the control socket.
          */
 
-        if (data.fd > -1) {
+        if (data.fd >= 0) {
             AsyncCall::Pointer nullCall =  NULL;
             commSetTimeout(data.fd, -1, nullCall);
         }
@@ -1767,8 +1827,7 @@ FtpStateData::handleControlReply()
         /* Got some data past the complete reply */
         assert(bytes_used < ctrl.offset);
         ctrl.offset -= bytes_used;
-        xmemmove(ctrl.buf, ctrl.buf + bytes_used,
-                 ctrl.offset);
+        memmove(ctrl.buf, ctrl.buf + bytes_used, ctrl.offset);
     }
 
     /* Move the last line of the reply message to ctrl.last_reply */
@@ -1885,8 +1944,11 @@ FtpStateData::loginFailed()
 
     HttpReply *newrep = err->BuildHttpReply();
     errorStateFree(err);
+
+#if HAVE_AUTH_MODULE_BASIC
     /* add Authenticate header */
     newrep->header.putAuth("Basic", ftpRealm());
+#endif
 
     // add it to the store entry for response....
     entry->replaceHttpReply(newrep);
@@ -2719,27 +2781,24 @@ FtpStateData::ftpPasvCallback(int fd, const DnsLookupDetails &dns, comm_err_t st
 static int
 ftpOpenListenSocket(FtpStateData * ftpState, int fallback)
 {
-    int fd;
-    Ip::Address addr;
     struct addrinfo *AI = NULL;
-    int on = 1;
     int x = 0;
 
     /// Close old data channels, if any. We may open a new one below.
-    ftpState->data.close();
+    if ((ftpState->data.flags & COMM_REUSEADDR))
+        // NP: in fact it points to the control channel. just clear it.
+        ftpState->data.clear();
+    else
+        ftpState->data.close();
 
     /*
      * Set up a listen socket on the same local address as the
      * control connection.
      */
-
-    addr.InitAddrInfo(AI);
-
+    ftpState->data.local.InitAddrInfo(AI);
     x = getsockname(ftpState->ctrl.fd, AI->ai_addr, &AI->ai_addrlen);
-
-    addr = *AI;
-
-    addr.FreeAddrInfo(AI);
+    ftpState->data.local = *AI;
+    ftpState->data.local.FreeAddrInfo(AI);
 
     if (x) {
         debugs(9, DBG_CRITICAL, HERE << "getsockname(" << ftpState->ctrl.fd << ",..): " << xstrerror());
@@ -2751,38 +2810,18 @@ ftpOpenListenSocket(FtpStateData * ftpState, int fallback)
      * used for both control and data.
      */
     if (fallback) {
+        int on = 1;
         setsockopt(ftpState->ctrl.fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on));
+        ftpState->ctrl.flags |= COMM_REUSEADDR;
+        ftpState->data.flags |= COMM_REUSEADDR;
     } else {
         /* if not running in fallback mode a new port needs to be retrieved */
-        addr.SetPort(0);
+        ftpState->data.local.SetPort(0);
+        ftpState->data.flags = COMM_NONBLOCKING;
     }
 
-    fd = comm_open(SOCK_STREAM,
-                   IPPROTO_TCP,
-                   addr,
-                   COMM_NONBLOCKING | (fallback ? COMM_REUSEADDR : 0),
-                   ftpState->entry->url());
-    debugs(9, 3, HERE << "Unconnected data socket created on FD " << fd  );
-
-    if (fd < 0) {
-        debugs(9, DBG_CRITICAL, HERE << "comm_open failed");
-        return -1;
-    }
-
-    typedef CommCbMemFunT<FtpStateData, CommAcceptCbParams> acceptDialer;
-    AsyncCall::Pointer acceptCall = JobCallback(11, 5,
-                                    acceptDialer, ftpState, FtpStateData::ftpAcceptDataConnection);
-    ftpState->data.listener = new Comm::ListenStateData(fd, acceptCall, false);
-
-    if (!ftpState->data.listener || ftpState->data.listener->errcode != 0) {
-        comm_close(fd);
-        return -1;
-    }
-
-    ftpState->data.opened(fd, ftpState->dataCloser());
-    ftpState->data.port = comm_local_port(fd);
-    ftpState->data.host = NULL;
-    return fd;
+    ftpState->listenForDataChannel((fallback?ftpState->ctrl.fd:-1), ftpState->entry->url());
+    return ftpState->data.fd;
 }
 
 /// \ingroup ServerProtocolFTPInternal
@@ -2858,19 +2897,27 @@ ftpReadPORT(FtpStateData * ftpState)
 static void
 ftpSendEPRT(FtpStateData * ftpState)
 {
-    int fd;
-    Ip::Address addr;
-    struct addrinfo *AI = NULL;
-    char buf[MAX_IPSTRLEN];
-
     if (Config.Ftp.epsv_all && ftpState->flags.epsv_all_sent) {
         debugs(9, DBG_IMPORTANT, "FTP does not allow EPRT method after 'EPSV ALL' has been sent.");
         return;
     }
 
+    if (!Config.Ftp.eprt) {
+        /* Disabled. Switch immediately to attempting old PORT command. */
+        debugs(9, 3, "EPRT disabled by local administrator");
+        ftpSendPORT(ftpState);
+        return;
+    }
+
+    int fd;
+    Ip::Address addr;
+    struct addrinfo *AI = NULL;
+    char buf[MAX_IPSTRLEN];
+
     debugs(9, 3, HERE);
     ftpState->flags.pasv_supported = 0;
     fd = ftpOpenListenSocket(ftpState, 0);
+    debugs(9, 3, "Listening for FTP data connection with FD " << fd);
 
     Ip::Address::InitAddrInfo(AI);
 
@@ -2923,77 +2970,68 @@ ftpReadEPRT(FtpStateData * ftpState)
  */
 void FtpStateData::ftpAcceptDataConnection(const CommAcceptCbParams &io)
 {
-    char ntoapeer[MAX_IPSTRLEN];
-    debugs(9, 3, "ftpAcceptDataConnection");
-
-    // one connection accepted. the handler has stopped listening. drop our local pointer to it.
-    data.listener = NULL;
+    debugs(9, 3, HERE);
 
     if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
         abortTransaction("entry aborted when accepting data conn");
         return;
     }
 
+    if (io.flag != COMM_OK) {
+        data.close();
+        debugs(9, DBG_IMPORTANT, "FTP AcceptDataConnection: FD " << io.fd << ": " << xstrerr(io.xerrno));
+        /** \todo Need to send error message on control channel*/
+        ftpFail(this);
+        return;
+    }
+
+    /* data listening conn is no longer even open. abort. */
+    if (data.fd <= 0 || fd_table[data.fd].flags.open == 0) {
+        data.clear(); // ensure that it's cleared and not just closed.
+        return;
+    }
+
     /** \par
      * When squid.conf ftp_sanitycheck is enabled, check the new connection is actually being
      * made by the remote client which is connected to the FTP control socket.
+     * Or the one which we were told to listen for by control channel messages (may differ under NAT).
      * This prevents third-party hacks, but also third-party load balancing handshakes.
      */
     if (Config.Ftp.sanitycheck) {
+        char ntoapeer[MAX_IPSTRLEN];
         io.details.peer.NtoA(ntoapeer,MAX_IPSTRLEN);
 
-        if (strcmp(fd_table[ctrl.fd].ipaddr, ntoapeer) != 0) {
+        if (strcmp(fd_table[ctrl.fd].ipaddr, ntoapeer) != 0 &&
+                strcmp(fd_table[data.fd].ipaddr, ntoapeer) != 0) {
             debugs(9, DBG_IMPORTANT,
                    "FTP data connection from unexpected server (" <<
                    io.details.peer << "), expecting " <<
-                   fd_table[ctrl.fd].ipaddr);
+                   fd_table[ctrl.fd].ipaddr << " or " << fd_table[data.fd].ipaddr);
 
-            /* close the bad soures connection down ASAP. */
+            /* close the bad sources connection down ASAP. */
             comm_close(io.nfd);
 
-            /* we are ony accepting once, so need to re-open the listener socket. */
-            typedef CommCbMemFunT<FtpStateData, CommAcceptCbParams> acceptDialer;
-            AsyncCall::Pointer acceptCall = JobCallback(11, 5,
-                                            acceptDialer, this, FtpStateData::ftpAcceptDataConnection);
-            data.listener = new Comm::ListenStateData(data.fd, acceptCall, false);
+            /* drop the bad connection (io) by ignoring the attempt. */
             return;
         }
     }
 
-    if (io.flag != COMM_OK) {
-        debugs(9, DBG_IMPORTANT, "ftpHandleDataAccept: FD " << io.nfd << ": " << xstrerr(io.xerrno));
-        /** \todo XXX Need to set error message */
-        ftpFail(this);
-        return;
-    }
-
     /**\par
-     * Replace the Listen socket with the accepted data socket */
+     * Replace the Listening socket with the accepted data socket */
     data.close();
     data.opened(io.nfd, dataCloser());
     data.port = io.details.peer.GetPort();
-    io.details.peer.NtoA(data.host,SQUIDHOSTNAMELEN);
+    data.host = xstrdup(fd_table[io.nfd].ipaddr);
 
     debugs(9, 3, "ftpAcceptDataConnection: Connected data socket on " <<
            "FD " << io.nfd << " to " << io.details.peer << " FD table says: " <<
            "ctrl-peer= " << fd_table[ctrl.fd].ipaddr << ", " <<
            "data-peer= " << fd_table[data.fd].ipaddr);
 
+    assert(haveControlChannel("ftpAcceptDataConnection"));
+    assert(ctrl.message == NULL);
 
-    AsyncCall::Pointer nullCall = NULL;
-    commSetTimeout(ctrl.fd, -1, nullCall);
-
-    typedef CommCbMemFunT<FtpStateData, CommTimeoutCbParams> TimeoutDialer;
-    AsyncCall::Pointer timeoutCall =  JobCallback(9, 5,
-                                      TimeoutDialer, this, FtpStateData::ftpTimeout);
-    commSetTimeout(data.fd, Config.Timeout.read, timeoutCall);
-
-    /*\todo XXX We should have a flag to track connect state...
-     *    host NULL -> not connected, port == local port
-     *    host set  -> connected, port == remote port
-     */
-    /* Restart state (SENT_NLST/LIST/RETR) */
-    FTP_SM_FUNCS[state] (this);
+    // Ctrl channel operations will determine what happens to this data connection
 }
 
 /// \ingroup ServerProtocolFTPInternal
@@ -3065,34 +3103,17 @@ void FtpStateData::readStor()
             return;
         }
 
-        /*\par
-         * When client status is 125, or 150 without a hostname, Begin data transfer. */
+        /* When client status is 125, or 150 without a hostname, Begin data transfer. */
         debugs(9, 3, HERE << "starting data transfer");
+        switchTimeoutToDataChannel();
         sendMoreRequestBody();
-        /** \par
-         * Cancel the timeout on the Control socket and
-         * establish one on the data socket.
-         */
-        AsyncCall::Pointer nullCall = NULL;
-        commSetTimeout(ctrl.fd, -1, nullCall);
-
-        typedef CommCbMemFunT<FtpStateData, CommTimeoutCbParams> TimeoutDialer;
-        AsyncCall::Pointer timeoutCall =  JobCallback(9, 5,
-                                          TimeoutDialer, this, FtpStateData::ftpTimeout);
-
-        commSetTimeout(data.fd, Config.Timeout.read, timeoutCall);
-
         state = WRITING_DATA;
         debugs(9, 3, HERE << "writing data channel");
     } else if (code == 150) {
         /*\par
-         * When client code is 150 with a hostname, Accept data channel. */
+         * When client code is 150 without a hostname, Accept data channel. */
         debugs(9, 3, "ftpReadStor: accepting data channel");
-        typedef CommCbMemFunT<FtpStateData, CommAcceptCbParams> acceptDialer;
-        AsyncCall::Pointer acceptCall = JobCallback(11, 5,
-                                        acceptDialer, this, FtpStateData::ftpAcceptDataConnection);
-
-        data.listener = new Comm::ListenStateData(data.fd, acceptCall, false);
+        listenForDataChannel(data.fd, data.host);
     } else {
         debugs(9, DBG_IMPORTANT, HERE << "Unexpected reply code "<< std::setfill('0') << std::setw(3) << code);
         ftpFail(this);
@@ -3212,34 +3233,15 @@ ftpReadList(FtpStateData * ftpState)
 
     if (code == 125 || (code == 150 && ftpState->data.host)) {
         /* Begin data transfer */
-        /* XXX what about Config.Timeout.read? */
+        debugs(9, 3, HERE << "begin data transfer from " << ftpState->data.host << " (" << ftpState->data.local << ")");
+        ftpState->switchTimeoutToDataChannel();
         ftpState->maybeReadVirginBody();
         ftpState->state = READING_DATA;
-        /*
-         * Cancel the timeout on the Control socket and establish one
-         * on the data socket
-         */
-        AsyncCall::Pointer nullCall = NULL;
-        commSetTimeout(ftpState->ctrl.fd, -1, nullCall);
         return;
     } else if (code == 150) {
         /* Accept data channel */
-        typedef CommCbMemFunT<FtpStateData, CommAcceptCbParams> acceptDialer;
-        AsyncCall::Pointer acceptCall = JobCallback(11, 5,
-                                        acceptDialer, ftpState, FtpStateData::ftpAcceptDataConnection);
-
-        ftpState->data.listener = new Comm::ListenStateData(ftpState->data.fd, acceptCall, false);
-        /*
-         * Cancel the timeout on the Control socket and establish one
-         * on the data socket
-         */
-        AsyncCall::Pointer nullCall = NULL;
-        commSetTimeout(ftpState->ctrl.fd, -1, nullCall);
-
-        typedef CommCbMemFunT<FtpStateData, CommTimeoutCbParams> TimeoutDialer;
-        AsyncCall::Pointer timeoutCall =  JobCallback(9, 5,
-                                          TimeoutDialer, ftpState,FtpStateData::ftpTimeout);
-        commSetTimeout(ftpState->data.fd, Config.Timeout.read, timeoutCall);
+        debugs(9, 3, HERE << "accept data channel from " << ftpState->data.host << " (" << ftpState->data.local << ")");
+        ftpState->listenForDataChannel(ftpState->data.fd, ftpState->data.host);
         return;
     } else if (!ftpState->flags.tried_nlst && code > 300) {
         ftpSendNlst(ftpState);
@@ -3275,32 +3277,12 @@ ftpReadRetr(FtpStateData * ftpState)
     if (code == 125 || (code == 150 && ftpState->data.host)) {
         /* Begin data transfer */
         debugs(9, 3, HERE << "reading data channel");
-        /* XXX what about Config.Timeout.read? */
+        ftpState->switchTimeoutToDataChannel();
         ftpState->maybeReadVirginBody();
         ftpState->state = READING_DATA;
-        /*
-         * Cancel the timeout on the Control socket and establish one
-         * on the data socket
-         */
-        AsyncCall::Pointer nullCall = NULL;
-        commSetTimeout(ftpState->ctrl.fd, -1, nullCall);
     } else if (code == 150) {
         /* Accept data channel */
-        typedef CommCbMemFunT<FtpStateData, CommAcceptCbParams> acceptDialer;
-        AsyncCall::Pointer acceptCall = JobCallback(11, 5,
-                                        acceptDialer, ftpState, FtpStateData::ftpAcceptDataConnection);
-        ftpState->data.listener = new Comm::ListenStateData(ftpState->data.fd, acceptCall, false);
-        /*
-         * Cancel the timeout on the Control socket and establish one
-         * on the data socket
-         */
-        AsyncCall::Pointer nullCall = NULL;
-        commSetTimeout(ftpState->ctrl.fd, -1, nullCall);
-
-        typedef CommCbMemFunT<FtpStateData, CommTimeoutCbParams> TimeoutDialer;
-        AsyncCall::Pointer timeoutCall =  JobCallback(9, 5,
-                                          TimeoutDialer, ftpState,FtpStateData::ftpTimeout);
-        commSetTimeout(ftpState->data.fd, Config.Timeout.read, timeoutCall);
+        ftpState->listenForDataChannel(ftpState->data.fd, ftpState->data.host);
     } else if (code >= 300) {
         if (!ftpState->flags.try_slash_hack) {
             /* Try this as a directory missing trailing slash... */
@@ -3767,8 +3749,10 @@ FtpStateData::ftpAuthRequired(HttpRequest * request, const char *realm)
     ErrorState *err = errorCon(ERR_CACHE_ACCESS_DENIED, HTTP_UNAUTHORIZED, request);
     HttpReply *newrep = err->BuildHttpReply();
     errorStateFree(err);
+#if HAVE_AUTH_MODULE_BASIC
     /* add Authenticate header */
     newrep->header.putAuth("Basic", realm);
+#endif
     return newrep;
 }
 
@@ -3953,6 +3937,13 @@ FtpChannel::opened(int aFd, const AsyncCall::Pointer &aCloser)
     fd = aFd;
     closer = aCloser;
     comm_add_close_handler(fd, closer);
+
+    // grab the local IP address:port details for this connection
+    struct addrinfo *AI = NULL;
+    local.InitAddrInfo(AI);
+    getsockname(aFd, AI->ai_addr, &AI->ai_addrlen);
+    local = *AI;
+    local.FreeAddrInfo(AI);
 }
 
 /// planned close: removes the close handler and calls comm_close
@@ -3960,15 +3951,11 @@ void
 FtpChannel::close()
 {
     // channels with active listeners will be closed when the listener handler dies.
-    if (listener) {
-        delete listener;
-        listener = NULL;
-        comm_remove_close_handler(fd, closer);
-        closer = NULL;
-        fd = -1;
-    } else if (fd >= 0) {
-        comm_remove_close_handler(fd, closer);
-        closer = NULL;
+    if (fd >= 0) {
+        if (closer != NULL) {
+            comm_remove_close_handler(fd, closer);
+            closer = NULL;
+        }
         comm_close(fd); // we do not expect to be called back
         fd = -1;
     }
index a110e2d6159f93f8d851511a503f7cb5c231ab79..d2195f7a2b08f9c7a2f3c727c136833bacc03b98 100644 (file)
@@ -54,7 +54,6 @@ extern "C" {
 //MOVED:structs.h    extern SquidConfig2 Config2;
     extern char *ConfigFile;   /* NULL */
     extern char *IcpOpcodeStr[];
-    extern const char *log_tags[];
     extern char tmp_error_buf[ERROR_BUF_SZ];
     extern char ThisCache[RFC2181_MAXHOSTNAMELEN << 1];
     extern char ThisCache2[RFC2181_MAXHOSTNAMELEN << 1];
@@ -149,8 +148,7 @@ extern "C" {
 
     extern unsigned int WIN32_Socks_initialized;       /* 0 */
 #endif
-#ifdef _SQUID_WIN32_
-
+#if _SQUID_WINDOWS_
     extern unsigned int WIN32_OS_version;      /* 0 */
     extern char *WIN32_OS_string;           /* NULL */
     extern char *WIN32_Service_name;        /* NULL */
@@ -166,6 +164,7 @@ extern "C" {
     extern int ssl_ex_index_server;    /* -1 */
     extern int ssl_ctx_ex_index_dont_verify_domain; /* -1 */
     extern int ssl_ex_index_cert_error_check;  /* -1 */
+    extern int ssl_ex_index_ssl_error_detail;      /* -1 */
 
     extern const char *external_acl_message;      /* NULL */
     extern int opt_send_signal;        /* -1 */
index 5b31f3a3956da0b9d8aaf6b627cfff4cad689f01..5204526241a17c369b51efb05ab738ea2002287c 100644 (file)
@@ -467,7 +467,7 @@ gopherToHTML(GopherStateData * gopherState, char *inbuf, int len)
                     len = TEMP_BUF_SIZE - gopherState->len;
                 }
 
-                xmemcpy(gopherState->buf + gopherState->len, inbuf, len);
+                memcpy(gopherState->buf + gopherState->len, inbuf, len);
                 gopherState->len += len;
                 return;
             }
@@ -498,7 +498,7 @@ gopherToHTML(GopherStateData * gopherState, char *inbuf, int len)
                 }
 
                 if (len > (pos - inbuf)) {
-                    xmemcpy(gopherState->buf, pos, len - (pos - inbuf));
+                    memcpy(gopherState->buf, pos, len - (pos - inbuf));
                     gopherState->len = len - (pos - inbuf);
                 }
 
index e0a69984602fb2bd4002faaba530ffe4ff936652..6c313cbd1e967792ee4e944acfb9b5c1031cd622 100644 (file)
@@ -35,6 +35,7 @@
 #include "squid.h"
 #include "comm/Write.h"
 #include "helper.h"
+#include "log/Gadgets.h"
 #include "SquidMath.h"
 #include "SquidTime.h"
 #include "Store.h"
@@ -441,7 +442,7 @@ helperStats(StoreEntry * sentry, helper * hlp, const char *label)
                           srv->flags.shutdown ? 'S' : ' ',
                           tt < 0.0 ? 0.0 : tt,
                           (int) srv->roffset,
-                          srv->requests[0] ? log_quote(srv->requests[0]->buf) : "(none)");
+                          srv->requests[0] ? Log::QuoteMimeBlob(srv->requests[0]->buf) : "(none)");
     }
 
     storeAppendPrintf(sentry, "\nFlags key:\n\n");
@@ -495,7 +496,7 @@ helperStatefulStats(StoreEntry * sentry, statefulhelper * hlp, const char *label
                           srv->request ? (srv->request->placeholder ? 'P' : ' ') : ' ',
                                   tt < 0.0 ? 0.0 : tt,
                                   (int) srv->roffset,
-                                  srv->request ? log_quote(srv->request->buf) : "(none)");
+                                  srv->request ? Log::QuoteMimeBlob(srv->request->buf) : "(none)");
     }
 
     storeAppendPrintf(sentry, "\nFlags key:\n\n");
index 898189b763a0708d3c8e71558553c59588511ca0..0f6b30719737135a86bc68effaa0564feecfa434 100644 (file)
  */
 
 #include "squid.h"
-#include "htcp.h"
+#include "AccessLogEntry.h"
 #include "acl/FilledChecklist.h"
 #include "acl/Acl.h"
-#include "ip/tools.h"
-#include "SquidTime.h"
-#include "Store.h"
-#include "StoreClient.h"
-#include "HttpRequest.h"
 #include "comm.h"
-#include "MemBuf.h"
+#include "comm/Loops.h"
+#include "htcp.h"
 #include "http.h"
+#include "HttpRequest.h"
 #include "icmp/net_db.h"
-#include "AccessLogEntry.h"
 #include "ipc/StartListening.h"
+#include "ip/tools.h"
+#include "MemBuf.h"
+#include "SquidTime.h"
+#include "Store.h"
+#include "StoreClient.h"
 
 /// dials htcpIncomingConnectionOpened call
 class HtcpListeningStartedDialer: public CallDialer,
@@ -332,7 +333,7 @@ htcpBuildAuth(char *buf, size_t buflen)
     copy_sz += 2;
     if (buflen < copy_sz)
         return -1;
-    xmemcpy(buf, &auth, copy_sz);
+    memcpy(buf, &auth, copy_sz);
     return copy_sz;
 }
 
@@ -357,7 +358,7 @@ htcpBuildCountstr(char *buf, size_t buflen, const char *s)
 
     length = htons((uint16_t) len);
 
-    xmemcpy(buf + off, &length, 2);
+    memcpy(buf + off, &length, 2);
 
     off += 2;
 
@@ -365,7 +366,7 @@ htcpBuildCountstr(char *buf, size_t buflen, const char *s)
         return -1;
 
     if (len)
-        xmemcpy(buf + off, s, len);
+        memcpy(buf + off, s, len);
 
     off += len;
 
@@ -473,7 +474,7 @@ htcpBuildClrOpData(char *buf, size_t buflen, htcpStuff * stuff)
     case RR_REQUEST:
         debugs(31, 3, "htcpBuildClrOpData: RR_REQUEST");
         reason = htons((u_short)stuff->reason);
-        xmemcpy(buf, &reason, 2);
+        memcpy(buf, &reason, 2);
         return htcpBuildSpecifier(buf + 2, buflen - 2, stuff) + 2;
     case RR_RESPONSE:
         break;
@@ -548,7 +549,7 @@ htcpBuildData(char *buf, size_t buflen, htcpStuff * stuff)
     hdr.msg_id = htonl(hdr.msg_id);
 
     if (!old_squid_format) {
-        xmemcpy(buf, &hdr, hdr_sz);
+        memcpy(buf, &hdr, hdr_sz);
     } else {
         htcpDataHeaderSquid hdrSquid;
         memset(&hdrSquid, 0, sizeof(hdrSquid));
@@ -557,7 +558,7 @@ htcpBuildData(char *buf, size_t buflen, htcpStuff * stuff)
         hdrSquid.response = hdr.response;
         hdrSquid.F1 = hdr.F1;
         hdrSquid.RR = hdr.RR;
-        xmemcpy(buf, &hdrSquid, hdr_sz);
+        memcpy(buf, &hdrSquid, hdr_sz);
     }
 
     debugs(31, 3, "htcpBuildData: size " << off);
@@ -605,7 +606,7 @@ htcpBuildPacket(char *buf, size_t buflen, htcpStuff * stuff)
     else
         hdr.minor = 1;
 
-    xmemcpy(buf, &hdr, hdr_sz);
+    memcpy(buf, &hdr, hdr_sz);
 
     debugs(31, 3, "htcpBuildPacket: size " << off);
 
@@ -1365,7 +1366,7 @@ htcpHandleMsg(char *buf, int sz, Ip::Address &from)
     }
 
     htcpHexdump("htcpHandle", buf, sz);
-    xmemcpy(&htcpHdr, buf, sizeof(htcpHeader));
+    memcpy(&htcpHdr, buf, sizeof(htcpHeader));
     htcpHdr.length = ntohs(htcpHdr.length);
 
     if (htcpHdr.minor == 0)
@@ -1399,10 +1400,10 @@ htcpHandleMsg(char *buf, int sz, Ip::Address &from)
     }
 
     if (!old_squid_format) {
-        xmemcpy(&hdr, hbuf, sizeof(hdr));
+        memcpy(&hdr, hbuf, sizeof(hdr));
     } else {
         htcpDataHeaderSquid hdrSquid;
-        xmemcpy(&hdrSquid, hbuf, sizeof(hdrSquid));
+        memcpy(&hdrSquid, hbuf, sizeof(hdrSquid));
         hdr.length = hdrSquid.length;
         hdr.opcode = hdrSquid.opcode;
         hdr.response = hdrSquid.response;
@@ -1484,7 +1485,7 @@ htcpRecv(int fd, void *data)
 
     htcpHandleMsg(buf, len, from);
 
-    commSetSelect(fd, COMM_SELECT_READ, htcpRecv, NULL, 0);
+    Comm::SetSelect(fd, COMM_SELECT_READ, htcpRecv, NULL, 0);
 }
 
 /*
@@ -1547,7 +1548,7 @@ htcpInit(void)
         if (htcpOutSocket < 0)
             fatal("Cannot open Outgoing HTCP Socket");
 
-        commSetSelect(htcpOutSocket, COMM_SELECT_READ, htcpRecv, NULL, 0);
+        Comm::SetSelect(htcpOutSocket, COMM_SELECT_READ, htcpRecv, NULL, 0);
 
         debugs(31, 1, "Outgoing HTCP messages on port " << Config.Port.htcp << ", FD " << htcpOutSocket << ".");
 
@@ -1567,7 +1568,7 @@ htcpIncomingConnectionOpened(int fd, int errNo)
     if (htcpInSocket < 0)
         fatal("Cannot open HTCP Socket");
 
-    commSetSelect(htcpInSocket, COMM_SELECT_READ, htcpRecv, NULL, 0);
+    Comm::SetSelect(htcpInSocket, COMM_SELECT_READ, htcpRecv, NULL, 0);
 
     debugs(31, 1, "Accepting HTCP messages on port " << Config.Port.htcp << ", FD " << htcpInSocket << ".");
 
@@ -1733,7 +1734,7 @@ htcpSocketShutdown(void)
      */
     assert(htcpOutSocket > -1);
 
-    commSetSelect(htcpOutSocket, COMM_SELECT_READ, NULL, NULL, 0);
+    Comm::SetSelect(htcpOutSocket, COMM_SELECT_READ, NULL, NULL, 0);
 }
 
 void
index c162f2d878ae7d2bf1dbfa1387e2033d623f8fbc..3b5997f9abba231d81dd0b9a59a928dbf6cbf81a 100644 (file)
@@ -906,10 +906,6 @@ HttpStateData::haveParsedReplyHeaders()
         entry->mem_obj->vary_headers = xstrdup(vary);
     }
 
-#if WIP_FWD_LOG
-    fwdStatus(fwd, s);
-
-#endif
     /*
      * If its not a reply that we will re-forward, then
      * allow the client to get it.
@@ -1009,18 +1005,16 @@ HttpStateData::ConnectionStatus
 HttpStateData::persistentConnStatus() const
 {
     debugs(11, 3, "persistentConnStatus: FD " << fd << " eof=" << eof);
-    const HttpReply *vrep = virginReply();
-    debugs(11, 5, "persistentConnStatus: content_length=" << vrep->content_length);
-
-    /* If we haven't seen the end of reply headers, we are not done */
-    debugs(11, 5, "persistentConnStatus: flags.headers_parsed=" << flags.headers_parsed);
-
-    if (!flags.headers_parsed)
-        return INCOMPLETE_MSG;
-
     if (eof) // already reached EOF
         return COMPLETE_NONPERSISTENT_MSG;
 
+    /* If server fd is closing (but we have not been notified yet), stop Comm
+       I/O to avoid assertions. TODO: Change Comm API to handle callers that
+       want more I/O after async closing (usually initiated by others). */
+    // XXX: add canReceive or s/canSend/canTalkToServer/
+    if (!canSend(fd))
+        return COMPLETE_NONPERSISTENT_MSG;
+
     /** \par
      * In chunked response we do not know the content length but we are absolutely
      * sure about the end of response, so we are calling the statusIfComplete to
@@ -1029,6 +1023,9 @@ HttpStateData::persistentConnStatus() const
     if (lastChunk && flags.chunked)
         return statusIfComplete();
 
+    const HttpReply *vrep = virginReply();
+    debugs(11, 5, "persistentConnStatus: content_length=" << vrep->content_length);
+
     const int64_t clen = vrep->bodySize(request->method);
 
     debugs(11, 5, "persistentConnStatus: clen=" << clen);
@@ -1152,7 +1149,7 @@ HttpStateData::readReply(const CommIoCbParams &io)
         /* Skip whitespace between replies */
 
         while (len > 0 && xisspace(*buf))
-            xmemmove(buf, buf + 1, len--);
+            memmove(buf, buf + 1, len--);
 
         if (len == 0) {
             /* Continue to read... */
index ce221f9e7ed9a189a2f2582fd943e9f306adc5f8..e2edfc8a13258a6f62cad0085c011a312759af0b 100644 (file)
@@ -130,7 +130,7 @@ Icmp4::SendEcho(Ip::Address &to, int opcode, const char *payload, int len)
         if (len > MAX_PAYLOAD)
             len = MAX_PAYLOAD;
 
-        xmemcpy(echo->payload, payload, len);
+        memcpy(echo->payload, payload, len);
 
         icmp_pktsize += len;
     }
index daa34f3d3e819de1963f0bac114bca8b59b627e5..10c869f6ba17331b6e892cd7c1a0659744228ed1 100644 (file)
 #include <netinet/ip_icmp.h>
 #endif
 
-#ifndef _SQUID_LINUX_
-#ifndef _SQUID_CYGWIN_
-#ifndef _SQUID_MSWIN_
+#if !_SQUID_LINUX_ && !_SQUID_WINDOWS_
 #define icmphdr icmp
 #define iphdr ip
 #endif
-#endif
-#endif
 
 /* Linux uses its own field names. */
 #if defined (_SQUID_LINUX_)
@@ -87,8 +83,7 @@
    to use the native Windows port definitions.
  */
 
-#ifdef _SQUID_WIN32_
-
+#if _SQUID_WINDOWS_
 #include "fde.h"
 
 #ifdef _SQUID_MSWIN_
index e604754571adc1c3bbbd1e826a6aa5a5e008f5ae..21dc01feddec2b03dd854526e9e9fa1fa7de9686 100644 (file)
@@ -174,7 +174,7 @@ Icmp6::SendEcho(Ip::Address &to, int opcode, const char *payload, int len)
         if (len > MAX_PAYLOAD)
             len = MAX_PAYLOAD;
 
-        xmemcpy(echo->payload, payload, len);
+        memcpy(echo->payload, payload, len);
 
         icmp6_pktsize += len;
     }
index 88398b4d542fe44c7288d10f023316bbd36aab78..35758b4907d95217324d6c1d05a1d4a66d15fc6b 100644 (file)
@@ -93,7 +93,7 @@ IcmpPinger::Open(void)
         return -1;
     }
 
-    xmemcpy(&wpi, buf, sizeof(wpi));
+    memcpy(&wpi, buf, sizeof(wpi));
 
     write(1, "OK\n", 3);
     x = read(0, buf, sizeof(PS));
@@ -105,7 +105,7 @@ IcmpPinger::Open(void)
         return -1;
     }
 
-    xmemcpy(&PS, buf, sizeof(PS));
+    memcpy(&PS, buf, sizeof(PS));
 
     icmp_sock = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, &wpi, 0, 0);
 
index f2b4899905e1e03044b62ddb7e33fdcaad12e304..d530553164703d1d373b7b9d41b63f2d85b2b3b9 100644 (file)
  */
 
 #include "squid.h"
+#include "comm.h"
+#include "comm/Loops.h"
 #include "icmp/IcmpSquid.h"
 #include "icmp/net_db.h"
 #include "ip/tools.h"
-#include "comm.h"
 #include "SquidTime.h"
 
 // Instance global to be available in main() and elsewhere.
@@ -105,7 +106,7 @@ IcmpSquid::SendEcho(Ip::Address &to, int opcode, const char *payload, int len)
     pecho.psize = len;
 
     if (len > 0)
-        xmemcpy(pecho.payload, payload, len);
+        memcpy(pecho.payload, payload, len);
 
     slen = sizeof(pingerEchoData) - PINGER_PAYLOAD_SZ + pecho.psize;
 
@@ -144,7 +145,7 @@ IcmpSquid::Recv()
     pingerReplyData preply;
     static Ip::Address F;
 
-    commSetSelect(icmp_sock, COMM_SELECT_READ, icmpSquidRecv, NULL, 0);
+    Comm::SetSelect(icmp_sock, COMM_SELECT_READ, icmpSquidRecv, NULL, 0);
     memset(&preply, '\0', sizeof(pingerReplyData));
     n = comm_udp_recv(icmp_sock,
                       (char *) &preply,
@@ -247,7 +248,7 @@ IcmpSquid::Open(void)
 
     fd_note(icmp_sock, "pinger");
 
-    commSetSelect(icmp_sock, COMM_SELECT_READ, icmpSquidRecv, NULL, 0);
+    Comm::SetSelect(icmp_sock, COMM_SELECT_READ, icmpSquidRecv, NULL, 0);
 
     commSetTimeout(icmp_sock, -1, NULL, NULL);
 
index 016800d80761c45b90af3a7350e414e0e3ffb16f..5bb0e499ca52354b052bb1f0620832edca3ea7a4 100644 (file)
@@ -620,7 +620,7 @@ netdbReloadState(void)
 
         n = (netdbEntry *)memAllocate(MEM_NETDBENTRY);
 
-        xmemcpy(n, &N, sizeof(netdbEntry));
+        memcpy(n, &N, sizeof(netdbEntry));
 
         netdbHashInsert(n, addr);
 
@@ -778,21 +778,21 @@ netdbExchangeHandleReply(void *data, StoreIOBuffer receivedData)
             case NETDB_EX_NETWORK:
                 o++;
                 /* FIXME INET6 : NetDB can still ony send IPv4 */
-                xmemcpy(&line_addr, p + o, sizeof(struct in_addr));
+                memcpy(&line_addr, p + o, sizeof(struct in_addr));
                 addr = line_addr;
                 o += sizeof(struct in_addr);
                 break;
 
             case NETDB_EX_RTT:
                 o++;
-                xmemcpy(&j, p + o, sizeof(int));
+                memcpy(&j, p + o, sizeof(int));
                 o += sizeof(int);
                 rtt = (double) ntohl(j) / 1000.0;
                 break;
 
             case NETDB_EX_HOPS:
                 o++;
-                xmemcpy(&j, p + o, sizeof(int));
+                memcpy(&j, p + o, sizeof(int));
                 o += sizeof(int);
                 hops = (double) ntohl(j) / 1000.0;
                 break;
@@ -1247,7 +1247,7 @@ netdbBinaryExchange(StoreEntry * s)
         buf[i++] = (char) NETDB_EX_NETWORK;
 
         addr.GetInAddr(line_addr);
-        xmemcpy(&buf[i], &line_addr, sizeof(struct in_addr));
+        memcpy(&buf[i], &line_addr, sizeof(struct in_addr));
 
         i += sizeof(struct in_addr);
 
@@ -1255,7 +1255,7 @@ netdbBinaryExchange(StoreEntry * s)
 
         j = htonl((int) (n->rtt * 1000));
 
-        xmemcpy(&buf[i], &j, sizeof(int));
+        memcpy(&buf[i], &j, sizeof(int));
 
         i += sizeof(int);
 
@@ -1263,7 +1263,7 @@ netdbBinaryExchange(StoreEntry * s)
 
         j = htonl((int) (n->hops * 1000));
 
-        xmemcpy(&buf[i], &j, sizeof(int));
+        memcpy(&buf[i], &j, sizeof(int));
 
         i += sizeof(int);
 
index 87b2a8369ad05826d8044f62c250770de2e61049..2f1d326517a0d1c700e387477b62ac048591c44f 100644 (file)
@@ -38,6 +38,7 @@
 #include "squid.h"
 #include "Store.h"
 #include "comm.h"
+#include "comm/Loops.h"
 #include "ICP.h"
 #include "HttpRequest.h"
 #include "acl/FilledChecklist.h"
@@ -112,7 +113,7 @@ _icp_common_t::_icp_common_t(char *buf, unsigned int len)
         return;
     }
 
-    xmemcpy(this, buf, sizeof(icp_common_t));
+    memcpy(this, buf, sizeof(icp_common_t));
     /*
      * Convert network order sensitive fields
      */
@@ -291,7 +292,7 @@ _icp_common_t::createMessage(
     if (opcode == ICP_QUERY)
         urloffset += sizeof(uint32_t);
 
-    xmemcpy(urloffset, url, strlen(url));
+    memcpy(urloffset, url, strlen(url));
 
     return (icp_common_t *)buf;
 }
@@ -337,7 +338,7 @@ icpUdpSend(int fd,
             IcpQueueTail = queue;
         }
 
-        commSetSelect(fd, COMM_SELECT_WRITE, icpUdpSendQueue, NULL, 0);
+        Comm::SetSelect(fd, COMM_SELECT_WRITE, icpUdpSendQueue, NULL, 0);
         statCounter.icp.replies_queued++;
     } else {
         /* don't queue it */
@@ -616,7 +617,7 @@ icpHandleUdp(int sock, void *data)
     int len;
     int icp_version;
     int max = INCOMING_ICP_MAX;
-    commSetSelect(sock, COMM_SELECT_READ, icpHandleUdp, NULL, 0);
+    Comm::SetSelect(sock, COMM_SELECT_READ, icpHandleUdp, NULL, 0);
 
     while (max--) {
         len = comm_udp_recvfrom(sock,
@@ -729,11 +730,7 @@ icpConnectionsOpen(void)
         if (theOutIcpConnection < 0)
             fatal("Cannot open Outgoing ICP Port");
 
-        commSetSelect(theOutIcpConnection,
-                      COMM_SELECT_READ,
-                      icpHandleUdp,
-                      NULL,
-                      0);
+        Comm::SetSelect(theOutIcpConnection, COMM_SELECT_READ, icpHandleUdp, NULL, 0);
 
         debugs(12, 1, "Outgoing ICP messages on port " << addr.GetPort() << ", FD " << theOutIcpConnection << ".");
 
@@ -765,11 +762,7 @@ icpIncomingConnectionOpened(int fd, int errNo, Ip::Address& addr)
     if (theInIcpConnection < 0)
         fatal("Cannot open ICP Port");
 
-    commSetSelect(theInIcpConnection,
-                  COMM_SELECT_READ,
-                  icpHandleUdp,
-                  NULL,
-                  0);
+    Comm::SetSelect(theInIcpConnection, COMM_SELECT_READ, icpHandleUdp, NULL, 0);
 
     for (const wordlist *s = Config.mcast_group_list; s; s = s->next)
         ipcache_nbgethostbyname(s->key, mcastJoinGroups, NULL);
@@ -815,7 +808,7 @@ icpConnectionShutdown(void)
      */
     assert(theOutIcpConnection > -1);
 
-    commSetSelect(theOutIcpConnection, COMM_SELECT_READ, NULL, NULL, 0);
+    Comm::SetSelect(theOutIcpConnection, COMM_SELECT_READ, NULL, NULL, 0);
 }
 
 void
index bf53eae57f0830b107290431ee4f26ecead080a1..bfee8064521b885b2963c7c1966e3dd64fad669b 100644 (file)
@@ -116,7 +116,7 @@ Ip::Address::GetCIDR() const
     return len;
 }
 
-const int
+int
 Ip::Address::ApplyMask(Ip::Address const &mask_addr)
 {
     uint32_t *p1 = (uint32_t*)(&m_SocketAddr.sin6_addr);
index 55254522c64d3e2463563f354b59dec1a9ec8136..3665de500807f769492f65adb8c1f4e0cc3e84eb 100644 (file)
@@ -228,7 +228,7 @@ public:
     /** Apply a mask to the stored address.
      \param mask Netmask format to be bit-mask-AND'd over the stored address.
      */
-    const int ApplyMask(const Address &mask);
+    int ApplyMask(const Address &mask);
 
     /** Apply a mask to the stored address.
      *  CIDR will be converted appropriate to map the stored content.
index d7f341949680a85164f5f784faf0b9cb3bba6b74..02656fee3ded565fa7c8438e98a56a87a82d9a30 100644 (file)
 #include "CacheManager.h"
 #include "comm.h"
 #include "ipc/Coordinator.h"
-#include "ipc/FdNotes.h"
 #include "ipc/SharedListen.h"
 #include "mgr/Inquirer.h"
 #include "mgr/Request.h"
 #include "mgr/Response.h"
-#include "mgr/StoreToCommWriter.h"
-
+#if SQUID_SNMP
+#include "snmp/Inquirer.h"
+#include "snmp/Request.h"
+#include "snmp/Response.h"
+#endif
 
 CBDATA_NAMESPACED_CLASS_INIT(Ipc, Coordinator);
 Ipc::Coordinator* Ipc::Coordinator::TheInstance = NULL;
@@ -64,15 +66,35 @@ void Ipc::Coordinator::receive(const TypedMsgHdr& message)
         handleSharedListenRequest(SharedListenRequest(message));
         break;
 
-    case mtCacheMgrRequest:
+    case mtCacheMgrRequest: {
         debugs(54, 6, HERE << "Cache manager request");
-        handleCacheMgrRequest(Mgr::Request(message));
-        break;
+        const Mgr::Request req(message);
+        handleCacheMgrRequest(req);
+    }
+    break;
 
-    case mtCacheMgrResponse:
+    case mtCacheMgrResponse: {
         debugs(54, 6, HERE << "Cache manager response");
-        handleCacheMgrResponse(Mgr::Response(message));
-        break;
+        const Mgr::Response resp(message);
+        handleCacheMgrResponse(resp);
+    }
+    break;
+
+#if SQUID_SNMP
+    case mtSnmpRequest: {
+        debugs(54, 6, HERE << "SNMP request");
+        const Snmp::Request req(message);
+        handleSnmpRequest(req);
+    }
+    break;
+
+    case mtSnmpResponse: {
+        debugs(54, 6, HERE << "SNMP response");
+        const Snmp::Response resp(message);
+        handleSnmpResponse(resp);
+    }
+    break;
+#endif
 
     default:
         debugs(54, 1, HERE << "Unhandled message type: " << message.type());
@@ -123,8 +145,7 @@ Ipc::Coordinator::handleCacheMgrRequest(const Mgr::Request& request)
 
     Mgr::Action::Pointer action =
         CacheManager::GetInstance()->createRequestedAction(request.params);
-    AsyncJob::Start(new Mgr::Inquirer(action,
-                                      Mgr::ImportHttpFdIntoComm(request.fd), request, strands_));
+    AsyncJob::Start(new Mgr::Inquirer(action, request, strands_));
 }
 
 void
@@ -133,6 +154,28 @@ Ipc::Coordinator::handleCacheMgrResponse(const Mgr::Response& response)
     Mgr::Inquirer::HandleRemoteAck(response);
 }
 
+#if SQUID_SNMP
+void
+Ipc::Coordinator::handleSnmpRequest(const Snmp::Request& request)
+{
+    debugs(54, 4, HERE);
+
+    Snmp::Response response(request.requestId);
+    TypedMsgHdr message;
+    response.pack(message);
+    SendMessage(MakeAddr(strandAddrPfx, request.requestorId), message);
+
+    AsyncJob::Start(new Snmp::Inquirer(request, strands_));
+}
+
+void
+Ipc::Coordinator::handleSnmpResponse(const Snmp::Response& response)
+{
+    debugs(54, 4, HERE);
+    Snmp::Inquirer::HandleRemoteAck(response);
+}
+#endif
+
 int
 Ipc::Coordinator::openListenSocket(const SharedListenRequest& request,
                                    int &errNo)
index 11856b1d3e2d0f7a0ca956668bab6d4c988e7682..bc0d8fd765de6c647101ee28d374aab725f38f24 100644 (file)
@@ -15,7 +15,9 @@
 #include "ipc/SharedListen.h"
 #include "ipc/StrandCoords.h"
 #include "mgr/forward.h"
-
+#if SQUID_SNMP
+#include "snmp/forward.h"
+#endif
 #include <map>
 
 namespace Ipc
@@ -46,7 +48,10 @@ protected:
     void handleSharedListenRequest(const SharedListenRequest& request);
     void handleCacheMgrRequest(const Mgr::Request& request);
     void handleCacheMgrResponse(const Mgr::Response& response);
-
+#if SQUID_SNMP
+    void handleSnmpRequest(const Snmp::Request& request);
+    void handleSnmpResponse(const Snmp::Response& response);
+#endif
     /// calls comm_open_listener()
     int openListenSocket(const SharedListenRequest& request, int &errNo);
 
index 9eb3328f33e1e85c83e551defd9182d20bdaa8ff..f7ea3cf73f67e7052b3314f32c94a680436bf520 100644 (file)
@@ -17,8 +17,10 @@ Ipc::FdNote(int fdNoteId)
         "None", // fdnNone
         "HTTP Socket", // fdnHttpSocket
         "HTTPS Socket", // fdnHttpsSocket
+#if SQUID_SNMP
         "Incoming SNMP Socket", // fdnInSnmpSocket
         "Outgoing SNMP Socket", // fdnOutSnmpSocket
+#endif
         "Incoming ICP Socket", // fdnInIcpSocket
         "Incoming HTCP Socket" // fdnInHtcpSocket
     };
index 91409d0e72a94db3302d9c6493167f41a20ef098..20978ea2c890392d56acbaed1d305bd429d5154e 100644 (file)
@@ -15,7 +15,9 @@ namespace Ipc
 
 /// fd_note() label ID
 typedef enum { fdnNone, fdnHttpSocket, fdnHttpsSocket,
+#if SQUID_SNMP
                fdnInSnmpSocket, fdnOutSnmpSocket,
+#endif
                fdnInIcpSocket, fdnInHtcpSocket, fdnEnd
              } FdNoteId;
 
diff --git a/src/ipc/Forwarder.cc b/src/ipc/Forwarder.cc
new file mode 100644 (file)
index 0000000..3650229
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 54    Interprocess Communication
+ *
+ */
+
+#include "config.h"
+#include "base/AsyncJobCalls.h"
+#include "base/TextException.h"
+#include "ipc/Forwarder.h"
+#include "ipc/Port.h"
+#include "ipc/TypedMsgHdr.h"
+
+
+CBDATA_NAMESPACED_CLASS_INIT(Ipc, Forwarder);
+
+Ipc::Forwarder::RequestsMap Ipc::Forwarder::TheRequestsMap;
+unsigned int Ipc::Forwarder::LastRequestId = 0;
+
+Ipc::Forwarder::Forwarder(Request::Pointer aRequest, double aTimeout):
+        AsyncJob("Ipc::Forwarder"),
+        request(aRequest), timeout(aTimeout)
+{
+    debugs(54, 5, HERE);
+}
+
+Ipc::Forwarder::~Forwarder()
+{
+    debugs(54, 5, HERE);
+    Must(request->requestId == 0);
+    cleanup();
+}
+
+/// perform cleanup actions
+void
+Ipc::Forwarder::cleanup()
+{
+}
+
+void
+Ipc::Forwarder::start()
+{
+    debugs(54, 3, HERE);
+
+    typedef NullaryMemFunT<Forwarder> Dialer;
+    AsyncCall::Pointer callback = JobCallback(54, 5, Dialer, this, Forwarder::handleRemoteAck);
+    if (++LastRequestId == 0) // don't use zero value as request->requestId
+        ++LastRequestId;
+    request->requestId = LastRequestId;
+    TheRequestsMap[request->requestId] = callback;
+    TypedMsgHdr message;
+
+    try {
+        request->pack(message);
+    } catch (...) {
+        // assume the pack() call failed because the message did not fit
+        // TODO: add a more specific exception?
+        handleError();
+    }
+
+    SendMessage(coordinatorAddr, message);
+    eventAdd("Ipc::Forwarder::requestTimedOut", &Forwarder::RequestTimedOut,
+             this, timeout, 0, false);
+}
+
+void
+Ipc::Forwarder::swanSong()
+{
+    debugs(54, 5, HERE);
+    removeTimeoutEvent();
+    if (request->requestId > 0) {
+        DequeueRequest(request->requestId);
+        request->requestId = 0;
+    }
+    cleanup();
+}
+
+bool
+Ipc::Forwarder::doneAll() const
+{
+    debugs(54, 5, HERE);
+    return request->requestId == 0;
+}
+
+/// called when Coordinator starts processing the request
+void
+Ipc::Forwarder::handleRemoteAck()
+{
+    debugs(54, 3, HERE);
+    request->requestId = 0;
+}
+
+/// Ipc::Forwarder::requestTimedOut wrapper
+void
+Ipc::Forwarder::RequestTimedOut(void* param)
+{
+    debugs(54, 3, HERE);
+    Must(param != NULL);
+    Forwarder* fwdr = static_cast<Forwarder*>(param);
+    // use async call to enable job call protection that time events lack
+    CallJobHere(54, 5, fwdr, Forwarder, requestTimedOut);
+}
+
+/// called when Coordinator fails to start processing the request [in time]
+void
+Ipc::Forwarder::requestTimedOut()
+{
+    debugs(54, 3, HERE);
+    handleTimeout();
+}
+
+void
+Ipc::Forwarder::handleError()
+{
+    mustStop("error");
+}
+
+void
+Ipc::Forwarder::handleTimeout()
+{
+    mustStop("timeout");
+}
+
+/// terminate with an error
+void
+Ipc::Forwarder::handleException(const std::exception& e)
+{
+    debugs(54, 3, HERE << e.what());
+    mustStop("exception");
+}
+
+void
+Ipc::Forwarder::callException(const std::exception& e)
+{
+    try {
+        handleException(e);
+    } catch (const std::exception& ex) {
+        debugs(54, DBG_CRITICAL, HERE << ex.what());
+    }
+    AsyncJob::callException(e);
+}
+
+/// returns and forgets the right Forwarder callback for the request
+AsyncCall::Pointer
+Ipc::Forwarder::DequeueRequest(unsigned int requestId)
+{
+    debugs(54, 3, HERE);
+    Must(requestId != 0);
+    AsyncCall::Pointer call;
+    RequestsMap::iterator request = TheRequestsMap.find(requestId);
+    if (request != TheRequestsMap.end()) {
+        call = request->second;
+        Must(call != NULL);
+        TheRequestsMap.erase(request);
+    }
+    return call;
+}
+
+/// called when we are no longer waiting for Coordinator to respond
+void
+Ipc::Forwarder::removeTimeoutEvent()
+{
+    if (eventFind(&Forwarder::RequestTimedOut, this))
+        eventDelete(&Forwarder::RequestTimedOut, this);
+}
+
+void
+Ipc::Forwarder::HandleRemoteAck(unsigned int requestId)
+{
+    debugs(54, 3, HERE);
+    Must(requestId != 0);
+
+    AsyncCall::Pointer call = DequeueRequest(requestId);
+    if (call != NULL)
+        ScheduleCallHere(call);
+}
diff --git a/src/ipc/Forwarder.h b/src/ipc/Forwarder.h
new file mode 100644 (file)
index 0000000..25b115b
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 54    Interprocess Communication
+ *
+ */
+
+#ifndef SQUID_IPC_FORWARDER_H
+#define SQUID_IPC_FORWARDER_H
+
+#include "base/AsyncJob.h"
+#include "ipc/Request.h"
+#include <map>
+
+
+namespace Ipc
+{
+
+/** Forwards a worker request to coordinator.
+ * Waits for an ACK from Coordinator
+ * Send the data unit with an error response if forwarding fails.
+ */
+class Forwarder: public AsyncJob
+{
+public:
+    Forwarder(Request::Pointer aRequest, double aTimeout);
+    virtual ~Forwarder();
+
+    /// finds and calls the right Forwarder upon Coordinator's response
+    static void HandleRemoteAck(unsigned int requestId);
+
+    /* has-to-be-public AsyncJob API */
+    virtual void callException(const std::exception& e);
+
+protected:
+    /* AsyncJob API */
+    virtual void start();
+    virtual void swanSong();
+    virtual bool doneAll() const;
+
+    virtual void cleanup(); ///< perform cleanup actions
+    virtual void handleError();
+    virtual void handleTimeout();
+    virtual void handleException(const std::exception& e);
+    virtual void handleRemoteAck();
+
+private:
+    static void RequestTimedOut(void* param);
+    void requestTimedOut();
+    void removeTimeoutEvent();
+    static AsyncCall::Pointer DequeueRequest(unsigned int requestId);
+
+protected:
+    Request::Pointer request;
+    const double timeout; ///< response wait timeout in seconds
+
+    /// maps request->id to Forwarder::handleRemoteAck callback
+    typedef std::map<unsigned int, AsyncCall::Pointer> RequestsMap;
+    static RequestsMap TheRequestsMap; ///< pending Coordinator requests
+
+    static unsigned int LastRequestId; ///< last requestId used
+
+    CBDATA_CLASS2(Forwarder);
+};
+
+} // namespace Ipc
+
+#endif /* SQUID_IPC_FORWARDER_H */
diff --git a/src/ipc/Inquirer.cc b/src/ipc/Inquirer.cc
new file mode 100644 (file)
index 0000000..d80dce5
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 54    Interprocess Communication
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "comm/Write.h"
+#include "ipc/Inquirer.h"
+#include "ipc/Port.h"
+#include "ipc/TypedMsgHdr.h"
+#include "MemBuf.h"
+#include <algorithm>
+
+
+CBDATA_NAMESPACED_CLASS_INIT(Ipc, Inquirer);
+
+Ipc::Inquirer::RequestsMap Ipc::Inquirer::TheRequestsMap;
+unsigned int Ipc::Inquirer::LastRequestId = 0;
+
+/// compare Ipc::StrandCoord using kidId, for std::sort() below
+static bool
+LesserStrandByKidId(const Ipc::StrandCoord &c1, const Ipc::StrandCoord &c2)
+{
+    return c1.kidId < c2.kidId;
+}
+
+Ipc::Inquirer::Inquirer(Request::Pointer aRequest, const StrandCoords& coords,
+                        double aTimeout):
+        AsyncJob("Ipc::Inquirer"),
+        request(aRequest), strands(coords), pos(strands.begin()), timeout(aTimeout)
+{
+    debugs(54, 5, HERE);
+
+    // order by ascending kid IDs; useful for non-aggregatable stats
+    std::sort(strands.begin(), strands.end(), LesserStrandByKidId);
+}
+
+Ipc::Inquirer::~Inquirer()
+{
+    debugs(54, 5, HERE);
+    cleanup();
+}
+
+void
+Ipc::Inquirer::cleanup()
+{
+}
+
+void
+Ipc::Inquirer::start()
+{
+    request->requestId = 0;
+}
+
+void
+Ipc::Inquirer::inquire()
+{
+    if (pos == strands.end()) {
+        Must(done());
+        return;
+    }
+
+    Must(request->requestId == 0);
+    AsyncCall::Pointer callback = asyncCall(54, 5, "Mgr::Inquirer::handleRemoteAck",
+                                            HandleAckDialer(this, &Inquirer::handleRemoteAck, NULL));
+    if (++LastRequestId == 0) // don't use zero value as request->requestId
+        ++LastRequestId;
+    request->requestId = LastRequestId;
+    const int kidId = pos->kidId;
+    debugs(54, 4, HERE << "inquire kid: " << kidId << status());
+    TheRequestsMap[request->requestId] = callback;
+    TypedMsgHdr message;
+    request->pack(message);
+    SendMessage(Port::MakeAddr(strandAddrPfx, kidId), message);
+    eventAdd("Ipc::Inquirer::requestTimedOut", &Inquirer::RequestTimedOut,
+             this, timeout, 0, false);
+}
+
+/// called when a strand is done writing its output
+void
+Ipc::Inquirer::handleRemoteAck(Response::Pointer response)
+{
+    debugs(54, 4, HERE << status());
+    request->requestId = 0;
+    removeTimeoutEvent();
+    if (aggregate(response)) {
+        Must(!done()); // or we should not be called
+        ++pos; // advance after a successful inquiry
+        inquire();
+    } else {
+        mustStop("error");
+    }
+}
+
+void
+Ipc::Inquirer::swanSong()
+{
+    debugs(54, 5, HERE);
+    removeTimeoutEvent();
+    if (request->requestId > 0) {
+        DequeueRequest(request->requestId);
+        request->requestId = 0;
+    }
+    sendResponse();
+    cleanup();
+}
+
+bool
+Ipc::Inquirer::doneAll() const
+{
+    return pos == strands.end();
+}
+
+void
+Ipc::Inquirer::handleException(const std::exception& e)
+{
+    debugs(54, 3, HERE << e.what());
+    mustStop("exception");
+}
+
+void
+Ipc::Inquirer::callException(const std::exception& e)
+{
+    debugs(54, 3, HERE);
+    try {
+        handleException(e);
+    } catch (const std::exception& ex) {
+        debugs(54, DBG_CRITICAL, HERE << ex.what());
+    }
+    AsyncJob::callException(e);
+}
+
+/// returns and forgets the right Inquirer callback for strand request
+AsyncCall::Pointer
+Ipc::Inquirer::DequeueRequest(unsigned int requestId)
+{
+    debugs(54, 3, HERE << " requestId " << requestId);
+    Must(requestId != 0);
+    AsyncCall::Pointer call;
+    RequestsMap::iterator request = TheRequestsMap.find(requestId);
+    if (request != TheRequestsMap.end()) {
+        call = request->second;
+        Must(call != NULL);
+        TheRequestsMap.erase(request);
+    }
+    return call;
+}
+
+void
+Ipc::Inquirer::HandleRemoteAck(const Response& response)
+{
+    Must(response.requestId != 0);
+    AsyncCall::Pointer call = DequeueRequest(response.requestId);
+    if (call != NULL) {
+        HandleAckDialer* dialer = dynamic_cast<HandleAckDialer*>(call->getDialer());
+        Must(dialer);
+        dialer->arg1 = response.clone();
+        ScheduleCallHere(call);
+    }
+}
+
+/// called when we are no longer waiting for the strand to respond
+void
+Ipc::Inquirer::removeTimeoutEvent()
+{
+    if (eventFind(&Inquirer::RequestTimedOut, this))
+        eventDelete(&Inquirer::RequestTimedOut, this);
+}
+
+/// Ipc::Inquirer::requestTimedOut wrapper
+void
+Ipc::Inquirer::RequestTimedOut(void* param)
+{
+    debugs(54, 3, HERE);
+    Must(param != NULL);
+    Inquirer* cmi = static_cast<Inquirer*>(param);
+    // use async call to enable job call protection that time events lack
+    CallJobHere(54, 5, cmi, Inquirer, requestTimedOut);
+}
+
+/// called when the strand failed to respond (or finish responding) in time
+void
+Ipc::Inquirer::requestTimedOut()
+{
+    debugs(54, 3, HERE);
+    if (request->requestId != 0) {
+        DequeueRequest(request->requestId);
+        request->requestId = 0;
+        Must(!done()); // or we should not be called
+        ++pos; // advance after a failed inquiry
+        inquire();
+    }
+}
+
+const char*
+Ipc::Inquirer::status() const
+{
+    static MemBuf buf;
+    buf.reset();
+    buf.Printf(" [request->requestId %u]", request->requestId);
+    buf.terminate();
+    return buf.content();
+}
diff --git a/src/ipc/Inquirer.h b/src/ipc/Inquirer.h
new file mode 100644 (file)
index 0000000..6341528
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 54    Interprocess Communication
+ *
+ */
+
+#ifndef SQUID_IPC_INQUIRER_H
+#define SQUID_IPC_INQUIRER_H
+
+#include "base/AsyncJobCalls.h"
+#include "base/AsyncJob.h"
+#include "ipc/forward.h"
+#include "ipc/Request.h"
+#include "ipc/Response.h"
+#include "ipc/StrandCoords.h"
+#include <map>
+
+
+namespace Ipc
+{
+
+/// Coordinator's job that sends a cache manage request to each strand,
+/// aggregating individual strand responses and dumping the result if needed
+class Inquirer: public AsyncJob
+{
+public:
+    Inquirer(Request::Pointer aRequest, const Ipc::StrandCoords& coords, double aTimeout);
+    virtual ~Inquirer();
+
+    /// finds and calls the right Inquirer upon strand's response
+    static void HandleRemoteAck(const Response& response);
+
+    /* has-to-be-public AsyncJob API */
+    virtual void callException(const std::exception& e);
+
+protected:
+    /* AsyncJob API */
+    virtual void start();
+    virtual void swanSong();
+    virtual bool doneAll() const;
+    virtual const char *status() const;
+
+    /// inquire the next strand
+    virtual void inquire();
+    /// perform cleanup actions on completion of job
+    virtual void cleanup();
+    /// do specific exception handling
+    virtual void handleException(const std::exception& e);
+    /// send response to client
+    virtual void sendResponse() = 0;
+    /// perform aggregating of responses and returns true if need to continue
+    virtual bool aggregate(Response::Pointer aResponse) = 0;
+
+private:
+    typedef UnaryMemFunT<Inquirer, Response::Pointer, Response::Pointer> HandleAckDialer;
+
+    void handleRemoteAck(Response::Pointer response);
+
+    static AsyncCall::Pointer DequeueRequest(unsigned int requestId);
+
+    static void RequestTimedOut(void* param);
+    void requestTimedOut();
+    void removeTimeoutEvent();
+
+protected:
+    Request::Pointer request; ///< cache manager request received from client
+
+    Ipc::StrandCoords strands; ///< all strands we want to query, in order
+    Ipc::StrandCoords::const_iterator pos; ///< strand we should query now
+
+    const double timeout; ///< number of seconds to wait for strand response
+
+    /// maps request->id to Inquirer::handleRemoteAck callback
+    typedef std::map<unsigned int, AsyncCall::Pointer> RequestsMap;
+    static RequestsMap TheRequestsMap; ///< pending strand requests
+
+    static unsigned int LastRequestId; ///< last requestId used
+
+    CBDATA_CLASS2(Inquirer);
+};
+
+} // namespace Ipc
+
+#endif /* SQUID_IPC_INQUIRER_H */
index e2d13504d9dc99754ad79ca8a6c9c9fea4a93635..4cda3bba0a4a21a35dace70d7beb48b3444c48f7 100644 (file)
@@ -28,7 +28,12 @@ libipc_la_SOURCES = \
        Port.h \
        Strand.cc \
        Strand.h \
-       \
-       forward.h
+       forward.h \
+       Forwarder.cc \
+       Forwarder.h \
+       Inquirer.cc \
+       Inquirer.h \
+       Request.h \
+       Response.h
 
 DEFS += -DDEFAULT_PREFIX=\"$(prefix)\"
index 57ae03632d05cc325c6048052a83f5f7fb8f0a25..b358f1b9812ba015a485c419922d268d68c580b1 100644 (file)
@@ -8,10 +8,7 @@
 #ifndef SQUID_IPC_MESSAGES_H
 #define SQUID_IPC_MESSAGES_H
 
-#include "ipc/forward.h"
-#include <sys/types.h>
-
-/** Declarations used by varios IPC messages */
+/** Declarations used by various IPC messages */
 
 namespace Ipc
 {
@@ -19,7 +16,10 @@ namespace Ipc
 /// message class identifier
 typedef enum { mtNone = 0, mtRegistration,
                mtSharedListenRequest, mtSharedListenResponse,
-               mtCacheMgrRequest, mtCacheMgrResponse
+               mtCacheMgrRequest, mtCacheMgrResponse,
+#if SQUID_SNMP
+               mtSnmpRequest, mtSnmpResponse
+#endif
              } MessageType;
 
 } // namespace Ipc;
diff --git a/src/ipc/Request.h b/src/ipc/Request.h
new file mode 100644 (file)
index 0000000..f56aad3
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 54    Interprocess Communication
+ *
+ */
+
+#ifndef SQUID_IPC_REQUEST_H
+#define SQUID_IPC_REQUEST_H
+
+#include "ipc/forward.h"
+#include "RefCount.h"
+
+
+namespace Ipc
+{
+
+/// IPC request
+class Request: public RefCountable
+{
+public:
+    typedef RefCount<Request> Pointer;
+
+public:
+    Request(int aRequestorId, unsigned int aRequestId):
+            requestorId(aRequestorId), requestId(aRequestId) {}
+
+    virtual void pack(TypedMsgHdr& msg) const = 0; ///< prepare for sendmsg()
+    virtual Pointer clone() const = 0; ///< returns a copy of this
+
+private:
+    Request(const Request&); // not implemented
+    Request& operator= (const Request&); // not implemented
+
+public:
+    int requestorId; ///< kidId of the requestor; used for response destination
+    unsigned int requestId; ///< unique for sender; matches request w/ response
+};
+
+
+} // namespace Ipc
+
+#endif /* SQUID_IPC_REQUEST_H */
diff --git a/src/ipc/Response.h b/src/ipc/Response.h
new file mode 100644 (file)
index 0000000..1ae2f8a
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 54    Interprocess Communication
+ *
+ */
+
+#ifndef SQUID_IPC_RESPONSE_H
+#define SQUID_IPC_RESPONSE_H
+
+#include "ipc/forward.h"
+#include "RefCount.h"
+
+
+namespace Ipc
+{
+
+/// A response to Ipc::Request.
+class Response: public RefCountable
+{
+public:
+    typedef RefCount<Response> Pointer;
+
+public:
+    explicit Response(unsigned int aRequestId):
+            requestId(aRequestId) {}
+
+    virtual void pack(TypedMsgHdr& msg) const = 0; ///< prepare for sendmsg()
+    virtual Pointer clone() const = 0; ///< returns a copy of this
+
+private:
+    Response(const Response&); // not implemented
+    Response& operator= (const Response&); // not implemented
+
+public:
+    unsigned int requestId; ///< ID of request we are responding to
+};
+
+inline
+std::ostream& operator << (std::ostream &os, const Response& response)
+{
+    os << "[response.requestId %u]" << response.requestId << '}';
+    return os;
+}
+
+
+} // namespace Ipc
+
+#endif /* SQUID_IPC_RESPONSE_H */
index 77fa86f778e6cdaa1b1cd8a330a2d531c12fee98..8e146f8272569b0d44c2823270745119c1d404c5 100644 (file)
@@ -6,8 +6,8 @@
  */
 
 #include "config.h"
-#include "comm.h"
 #include "base/TextException.h"
+#include "comm.h"
 #include "ipc/SharedListen.h"
 #include "ipc/StartListening.h"
 
@@ -25,34 +25,29 @@ std::ostream &Ipc::StartListeningCb::startPrint(std::ostream &os) const
     return os << "(FD " << fd << ", err=" << errNo;
 }
 
-
-void Ipc::StartListening(int sock_type, int proto, Ip::Address &addr,
-                         int flags, FdNoteId fdNote, AsyncCall::Pointer &callback)
+void
+Ipc::StartListening(int sock_type, int proto, Ip::Address &addr, int flags,
+                    FdNoteId fdNote, AsyncCall::Pointer &callback)
 {
-    OpenListenerParams p;
-    p.sock_type = sock_type;
-    p.proto = proto;
-    p.addr = addr;
-    p.flags = flags;
-    p.fdNote = fdNote;
-
     if (UsingSmp()) { // if SMP is on, share
+        OpenListenerParams p;
+        p.sock_type = sock_type;
+        p.proto = proto;
+        p.addr = addr;
+        p.flags = flags;
+        p.fdNote = fdNote;
         Ipc::JoinSharedListen(p, callback);
         return; // wait for the call back
     }
 
+    StartListeningCb *cbd = dynamic_cast<StartListeningCb*>(callback->getDialer());
+    Must(cbd);
+
     enter_suid();
-    const int sock = comm_open_listener(p.sock_type, p.proto, p.addr, p.flags,
-                                        FdNote(p.fdNote));
-    const int errNo = (sock >= 0) ? 0 : errno;
+    cbd->fd = comm_open_listener(sock_type, proto, addr, flags, FdNote(fdNote));
+    cbd->errNo = cbd->fd >= 0 ? 0 : errno;
     leave_suid();
 
-    debugs(54, 3, HERE << "opened listen FD " << sock << " for " << p.addr);
-
-    StartListeningCb *cbd =
-        dynamic_cast<StartListeningCb*>(callback->getDialer());
-    Must(cbd);
-    cbd->fd = sock;
-    cbd->errNo = errNo;
+    debugs(54, 3, HERE << "opened listen FD " << cbd->fd << " on " << addr);
     ScheduleCallHere(callback);
 }
index a1e9f59c5dc69b54b451de1fc031185c18a57cb7..4d7bf6def351bff5ef29c1befaa0b31f9ca5bd3f 100644 (file)
 #include "mgr/Response.h"
 #include "mgr/Forwarder.h"
 #include "CacheManager.h"
-
+#if SQUID_SNMP
+#include "snmp/Forwarder.h"
+#include "snmp/Request.h"
+#include "snmp/Response.h"
+#endif
 
 CBDATA_NAMESPACED_CLASS_INIT(Ipc, Strand);
 
@@ -56,13 +60,31 @@ void Ipc::Strand::receive(const TypedMsgHdr &message)
         SharedListenJoined(SharedListenResponse(message));
         break;
 
-    case mtCacheMgrRequest:
-        handleCacheMgrRequest(Mgr::Request(message));
-        break;
+    case mtCacheMgrRequest: {
+        const Mgr::Request req(message);
+        handleCacheMgrRequest(req);
+    }
+    break;
 
-    case mtCacheMgrResponse:
-        handleCacheMgrResponse(Mgr::Response(message));
-        break;
+    case mtCacheMgrResponse: {
+        const Mgr::Response resp(message);
+        handleCacheMgrResponse(resp);
+    }
+    break;
+
+#if SQUID_SNMP
+    case mtSnmpRequest: {
+        const Snmp::Request req(message);
+        handleSnmpRequest(req);
+    }
+    break;
+
+    case mtSnmpResponse: {
+        const Snmp::Response resp(message);
+        handleSnmpResponse(resp);
+    }
+    break;
+#endif
 
     default:
         debugs(54, 1, HERE << "Unhandled message type: " << message.type());
@@ -95,6 +117,20 @@ void Ipc::Strand::handleCacheMgrResponse(const Mgr::Response& response)
     Mgr::Forwarder::HandleRemoteAck(response.requestId);
 }
 
+#if SQUID_SNMP
+void Ipc::Strand::handleSnmpRequest(const Snmp::Request& request)
+{
+    debugs(54, 6, HERE);
+    Snmp::SendResponse(request.requestId, request.pdu);
+}
+
+void Ipc::Strand::handleSnmpResponse(const Snmp::Response& response)
+{
+    debugs(54, 6, HERE);
+    Snmp::Forwarder::HandleRemoteAck(response.requestId);
+}
+#endif
+
 void Ipc::Strand::timedout()
 {
     debugs(54, 6, HERE << isRegistered);
index d01cf2b7f29d7aab08a0c48f615637765e0dd179..e574b7bd0d3017de56f6eeee279df4ffe384df9a 100644 (file)
@@ -10,7 +10,9 @@
 
 #include "ipc/Port.h"
 #include "mgr/forward.h"
-
+#if SQUID_SNMP
+#include "snmp/forward.h"
+#endif
 
 namespace Ipc
 {
@@ -34,6 +36,10 @@ private:
     void handleRegistrationResponse(const StrandCoord &strand);
     void handleCacheMgrRequest(const Mgr::Request& request);
     void handleCacheMgrResponse(const Mgr::Response& response);
+#if SQUID_SNMP
+    void handleSnmpRequest(const Snmp::Request& request);
+    void handleSnmpResponse(const Snmp::Response& response);
+#endif
 
 private:
     bool isRegistered; ///< whether Coordinator ACKed registration (unused)
index a49527e5fdd3a7d800fbbee3e5e56bed3af68812..0f2116cc72d3e105ae4ccf86d491544e6aa06fb1 100644 (file)
@@ -20,14 +20,14 @@ Ipc::TypedMsgHdr::TypedMsgHdr()
 
 Ipc::TypedMsgHdr::TypedMsgHdr(const TypedMsgHdr &tmh)
 {
-    xmemcpy(this, &tmh, sizeof(*this));
+    memcpy(this, &tmh, sizeof(*this));
     sync();
 }
 
 Ipc::TypedMsgHdr &Ipc::TypedMsgHdr::operator =(const TypedMsgHdr &tmh)
 {
     if (this != &tmh) { // skip assignment to self
-        xmemcpy(this, &tmh, sizeof(*this));
+        memcpy(this, &tmh, sizeof(*this));
         sync();
     }
     return *this;
@@ -156,7 +156,7 @@ Ipc::TypedMsgHdr::getRaw(void *raw, size_t size) const
     Must(size >= 0);
     if (size > 0) {
         Must(size <= data.size - offset);
-        xmemcpy(raw, data.raw + offset, size);
+        memcpy(raw, data.raw + offset, size);
         offset += size;
     }
 }
@@ -168,7 +168,7 @@ Ipc::TypedMsgHdr::putRaw(const void *raw, size_t size)
     Must(size >= 0);
     if (size > 0) {
         Must(size <= sizeof(data.raw) - data.size);
-        xmemcpy(data.raw + data.size, raw, size);
+        memcpy(data.raw + data.size, raw, size);
         data.size += size;
     }
 }
@@ -187,7 +187,7 @@ Ipc::TypedMsgHdr::putFd(int fd)
     cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fdCount);
 
     int *fdStore = reinterpret_cast<int*>(CMSG_DATA(cmsg));
-    xmemcpy(fdStore, &fd, fdCount * sizeof(int));
+    memcpy(fdStore, &fd, fdCount * sizeof(int));
     msg_controllen = cmsg->cmsg_len;
 }
 
@@ -203,7 +203,7 @@ Ipc::TypedMsgHdr::getFd() const
     const int fdCount = 1;
     const int *fdStore = reinterpret_cast<const int*>(CMSG_DATA(cmsg));
     int fd = -1;
-    xmemcpy(&fd, fdStore, fdCount * sizeof(int));
+    memcpy(&fd, fdStore, fdCount * sizeof(int));
     return fd;
 }
 
index 873450574a8b0b667851cba9e1d675b2254379d2..af7edc2b7333acc74650e526b43e3a6c7e3c5c60 100644 (file)
@@ -113,7 +113,7 @@ void Ipc::UdsSender::write()
 
 void Ipc::UdsSender::wrote(const CommIoCbParams& params)
 {
-    debugs(54, 5, HERE << "FD " << params.fd << " flag " << params.flag << " [" << this << ']');
+    debugs(54, 5, HERE << "FD " << params.fd << " flag " << params.flag << " retries " << retries << " [" << this << ']');
     writing = false;
     if (params.flag != COMM_OK && retries-- > 0) {
         sleep(1); // do not spend all tries at once; XXX: use an async timed event instead of blocking here; store the time when we started writing so that we do not sleep if not needed?
@@ -132,3 +132,23 @@ void Ipc::SendMessage(const String& toAddress, const TypedMsgHdr &message)
 {
     AsyncJob::Start(new UdsSender(toAddress, message));
 }
+
+int Ipc::ImportFdIntoComm(int fd, int socktype, int protocol, Ipc::FdNoteId noteId)
+{
+    struct sockaddr_in addr;
+    socklen_t len = sizeof(addr);
+    if (getsockname(fd, reinterpret_cast<sockaddr*>(&addr), &len) == 0) {
+        Ip::Address ipAddr(addr);
+        struct addrinfo* addr_info = NULL;
+        ipAddr.GetAddrInfo(addr_info);
+        addr_info->ai_socktype = socktype;
+        addr_info->ai_protocol = protocol;
+        comm_import_opened(fd, ipAddr, COMM_NONBLOCKING, Ipc::FdNote(noteId), addr_info);
+        ipAddr.FreeAddrInfo(addr_info);
+    } else {
+        debugs(54, DBG_CRITICAL, HERE << "ERROR: FD " << fd << ' ' << xstrerror());
+        ::close(fd);
+        fd = -1;
+    }
+    return fd;
+}
index 0187a4e3ee33404be3de9f373f7a9bb10135854c..bea34d3a6e6015f65edab9d495b8ba6ce6aabd5c 100644 (file)
@@ -12,6 +12,7 @@
 #include "SquidString.h"
 #include "base/AsyncJob.h"
 #include "ipc/TypedMsgHdr.h"
+#include "ipc/FdNotes.h"
 
 class CommTimeoutCbParams;
 class CommIoCbParams;
@@ -90,6 +91,8 @@ private:
 
 
 void SendMessage(const String& toAddress, const TypedMsgHdr& message);
+/// import socket fd from another strand into our Comm state
+int ImportFdIntoComm(int fd, int socktype, int protocol, FdNoteId noteId);
 
 
 }
index 7325abb6bc68c91982783669ce19fa581ebb5464..f4ddf4cb0caeec111b66084ccfcab05b4bda875c 100644 (file)
@@ -13,6 +13,10 @@ namespace Ipc
 
 class TypedMsgHdr;
 class StrandCoord;
+class Forwarder;
+class Inquirer;
+class Request;
+class Response;
 
 } // namespace Ipc
 
index 8969edae4bae3f3ce074765b1433b85d68c8ec31..9aacdabc2da8b185a52145e9b0a7636dc3753f1f 100644 (file)
@@ -690,8 +690,7 @@ ipc_thread_1(void *in_params)
     else
         thread_params.rfd = prfd_ipc;
 
-    thread =
-        (HANDLE) _beginthreadex(NULL, 0, ipc_thread_2, &thread_params, 0, NULL);
+    thread = (HANDLE)_beginthreadex(NULL, 0, ipc_thread_2, &thread_params, 0, NULL);
 
     if (!thread) {
         debugs(54, 0, "ipcCreate: CHILD: _beginthreadex: " << xstrerror());
index 45e7fc1620cdb9b2d56d6e2c311de71580549dcb..b4a1f725a65cf7784d8989ad6aff686d21ad9d4c 100644 (file)
@@ -161,6 +161,9 @@ static long ipcache_high = 200;
 extern int _dns_ttl_;
 #endif
 
+/// \ingroup IPCacheInternal
+inline int ipcacheCount() { return ip_table ? ip_table->count : 0; }
+
 int
 ipcache_entry::age() const
 {
@@ -235,7 +238,7 @@ ipcache_purgelru(void *voidnotused)
     eventAdd("ipcache_purgelru", ipcache_purgelru, NULL, 10.0, 1);
 
     for (m = lru_list.tail; m; m = prev) {
-        if (memInUse(MEM_IPCACHE_ENTRY) < ipcache_low)
+        if (ipcacheCount() < ipcache_low)
             break;
 
         prev = m->prev;
@@ -535,7 +538,7 @@ ipcacheParse(ipcache_entry *i, rfc1035_rr * answers, int nr, const char *error_m
                 continue;
 
             struct in_addr temp;
-            xmemcpy(&temp, answers[k].rdata, sizeof(struct in_addr));
+            memcpy(&temp, answers[k].rdata, sizeof(struct in_addr));
             i->addrs.in_addrs[j] = temp;
 
             debugs(14, 3, "ipcacheParse: " << name << " #" << j << " " << i->addrs.in_addrs[j]);
@@ -546,7 +549,7 @@ ipcacheParse(ipcache_entry *i, rfc1035_rr * answers, int nr, const char *error_m
                 continue;
 
             struct in6_addr temp;
-            xmemcpy(&temp, answers[k].rdata, sizeof(struct in6_addr));
+            memcpy(&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] );
@@ -855,8 +858,10 @@ stat_ipcache_get(StoreEntry * sentry)
     dlink_node *m;
     assert(ip_table != NULL);
     storeAppendPrintf(sentry, "IP Cache Statistics:\n");
-    storeAppendPrintf(sentry, "IPcache Entries:  %d\n",
+    storeAppendPrintf(sentry, "IPcache Entries In Use:  %d\n",
                       memInUse(MEM_IPCACHE_ENTRY));
+    storeAppendPrintf(sentry, "IPcache Entries Cached:  %d\n",
+                      ipcacheCount());
     storeAppendPrintf(sentry, "IPcache Requests: %d\n",
                       IpcacheStats.requests);
     storeAppendPrintf(sentry, "IPcache Hits:            %d\n",
@@ -1231,7 +1236,7 @@ snmp_netIpFn(variable_list * Var, snint * ErrP)
 
     case IP_ENT:
         Answer = snmp_var_new_integer(Var->name, Var->name_length,
-                                      memInUse(MEM_IPCACHE_ENTRY),
+                                      ipcacheCount(),
                                       SMI_GAUGE32);
         break;
 
index 2360212d4905facb0ad004dd493585cda096a38f..fd9a148eaf4485ad946c16cf48c6ed8b23c0910f 100644 (file)
@@ -1,4 +1,33 @@
 #include "config.h"
 #include "log/Config.h"
+#include "log/Tokens.h"
+#include "protos.h"
 
 Log::LogConfig Log::TheConfig;
+
+void
+Log::LogConfig::parseFormats()
+{
+    char *name, *def;
+
+    if ((name = strtok(NULL, w_space)) == NULL)
+        self_destruct();
+
+    if ((def = strtok(NULL, "\r\n")) == NULL) {
+        self_destruct();
+        return;
+    }
+
+    debugs(3, 2, "Logformat for '" << name << "' is '" << def << "'");
+
+    logformat *nlf = new logformat(name);
+
+    if (!accessLogParseLogFormat(&nlf->format, def)) {
+        self_destruct();
+        return;
+    }
+
+    // add to global config list
+    nlf->next = logformats;
+    logformats = nlf;
+}
index 4a74a26568f9c43bff1ebd25e80c3ecc139e8c97..f46d4654d0b721b6ddd96edab69a81b50d8a9500 100644 (file)
@@ -1,17 +1,35 @@
 #ifndef SQUID_SRC_LOG_CONFIG_H
 #define SQUID_SRC_LOG_CONFIG_H
 
+#include "log/Tokens.h"
+
+class StoreEntry;
+
 namespace Log
 {
 
 class LogConfig
 {
 public:
+    void parseFormats();
+    void dumpFormats(StoreEntry *e, const char *name) {
+        accessLogDumpLogFormat(e, name, logformats);
+    }
+
+    /// File path to logging daemon executable
     char *logfile_daemon;
+
+    /// Linked list of custom log formats
+    logformat *logformats;
 };
 
 extern LogConfig TheConfig;
 
 } // namespace Log
 
+// Legacy parsing wrappers
+#define parse_logformat(X)  (X)->parseFormats()
+#define free_logformat(X)   do{ delete (*X).logformats; (*X).logformats=NULL; }while(false)
+#define dump_logformat(E,N,D) (D).dumpFormats((E),(N))
+
 #endif
diff --git a/src/log/FormatHttpdCombined.cc b/src/log/FormatHttpdCombined.cc
new file mode 100644 (file)
index 0000000..1679be3
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 46    Access Log - Apache combined format
+ * 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; 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 "config.h"
+#include "AccessLogEntry.h"
+#include "HttpRequest.h"
+#include "log/File.h"
+#include "log/Formats.h"
+#include "log/Gadgets.h"
+#include "log/Tokens.h"
+#include "SquidTime.h"
+
+void
+Log::Format::HttpdCombined(AccessLogEntry * al, Logfile * logfile)
+{
+    char clientip[MAX_IPSTRLEN];
+
+    const char *user_ident = FormatName(al->cache.rfc931);
+
+    const char *user_auth = FormatName(al->cache.authuser);
+
+    const char *referer = al->request->header.getStr(HDR_REFERER);
+    if (!referer || *referer == '\0')
+        referer = "-";
+
+    const char *agent = al->request->header.getStr(HDR_USER_AGENT);
+    if (!agent || *agent == '\0')
+        agent = "-";
+
+    logfilePrintf(logfile, "%s %s %s [%s] \"%s %s HTTP/%d.%d\" %d %"PRId64" \"%s\" \"%s\" %s%s:%s%s",
+                  al->cache.caddr.NtoA(clientip,MAX_IPSTRLEN),
+                  user_ident ? user_ident : dash_str,
+                  user_auth ? user_auth : dash_str,
+                  Time::FormatHttpd(squid_curtime),
+                  al->_private.method_str,
+                  al->url,
+                  al->http.version.major, al->http.version.minor,
+                  al->http.code,
+                  al->cache.replySize,
+                  referer,
+                  agent,
+                  log_tags[al->cache.code],
+                  al->http.statusSfx(),
+                  hier_code_str[al->hier.code],
+                  (Config.onoff.log_mime_hdrs?"":"\n"));
+
+    safe_free(user_ident);
+    safe_free(user_auth);
+
+    if (Config.onoff.log_mime_hdrs) {
+        char *ereq = QuoteMimeBlob(al->headers.request);
+        char *erep = QuoteMimeBlob(al->headers.reply);
+        logfilePrintf(logfile, " [%s] [%s]\n", ereq, erep);
+        safe_free(ereq);
+        safe_free(erep);
+    }
+}
similarity index 50%
rename from src/useragent.cc
rename to src/log/FormatHttpdCommon.cc
index 996b7f87000c296352033dceb2b92d32571b0500..7bfa35a5e68670d8af028f0b534f398f43c44754 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * $Id$
  *
- * DEBUG: section 40    User-Agent Logging
- * AUTHOR: Joe Ramey <ramey@csc.ti.com>
+ * DEBUG: section 46    Access Log - Apache common format
+ * AUTHOR: Duane Wessels
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
  * ----------------------------------------------------------
  *
  */
 
-#include "squid.h"
+#include "config.h"
+#include "AccessLogEntry.h"
 #include "log/File.h"
+#include "log/Formats.h"
+#include "log/Gadgets.h"
+#include "log/Tokens.h"
 #include "SquidTime.h"
 
-#if USE_USERAGENT_LOG
-static Logfile *useragentlog = NULL;
-#endif
-
-void
-useragentOpenLog(void)
-{
-#if USE_USERAGENT_LOG
-    assert(NULL == useragentlog);
-
-    if (!Config.Log.useragent || (0 == strcmp(Config.Log.useragent, "none"))) {
-        debugs(40, 1, "User-Agent logging is disabled.");
-        return;
-    }
-
-    useragentlog = logfileOpen(Config.Log.useragent, 0, 1);
-#endif
-}
-
-void
-useragentRotateLog(void)
-{
-#if USE_USERAGENT_LOG
-
-    if (NULL == useragentlog)
-        return;
-
-    logfileRotate(useragentlog);
-
-#endif
-}
-
 void
-logUserAgent(const char *client, const char *agent)
+Log::Format::HttpdCommon(AccessLogEntry * al, Logfile * logfile)
 {
-#if USE_USERAGENT_LOG
-    static time_t last_time = 0;
-    static char time_str[128];
-    const char *s;
-
-    if (NULL == useragentlog)
-        return;
-
-    if (squid_curtime != last_time) {
-        s = mkhttpdlogtime(&squid_curtime);
-        strcpy(time_str, s);
-        last_time = squid_curtime;
+    char clientip[MAX_IPSTRLEN];
+    const char *user_auth = FormatName(al->cache.authuser);
+    const char *user_ident = FormatName(al->cache.rfc931);
+
+    logfilePrintf(logfile, "%s %s %s [%s] \"%s %s HTTP/%d.%d\" %d %"PRId64" %s%s:%s%s",
+                  al->cache.caddr.NtoA(clientip,MAX_IPSTRLEN),
+                  user_ident ? user_ident : dash_str,
+                  user_auth ? user_auth : dash_str,
+                  Time::FormatHttpd(squid_curtime),
+                  al->_private.method_str,
+                  al->url,
+                  al->http.version.major, al->http.version.minor,
+                  al->http.code,
+                  al->cache.replySize,
+                  log_tags[al->cache.code],
+                  al->http.statusSfx(),
+                  hier_code_str[al->hier.code],
+                  (Config.onoff.log_mime_hdrs?"":"\n"));
+
+    safe_free(user_auth);
+    safe_free(user_ident);
+
+    if (Config.onoff.log_mime_hdrs) {
+        char *ereq = QuoteMimeBlob(al->headers.request);
+        char *erep = QuoteMimeBlob(al->headers.reply);
+        logfilePrintf(logfile, " [%s] [%s]\n", ereq, erep);
+        safe_free(ereq);
+        safe_free(erep);
     }
-
-    logfilePrintf(useragentlog, "%s [%s] \"%s\"\n",
-                  client,
-                  time_str,
-                  agent);
-#endif
-}
-
-void
-useragentLogClose(void)
-{
-#if USE_USERAGENT_LOG
-
-    if (NULL == useragentlog)
-        return;
-
-    logfileClose(useragentlog);
-
-    useragentlog = NULL;
-
-#endif
 }
diff --git a/src/log/FormatSquidCustom.cc b/src/log/FormatSquidCustom.cc
new file mode 100644 (file)
index 0000000..f1a031c
--- /dev/null
@@ -0,0 +1,818 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 46    Access Log - Squid Custom format
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "AccessLogEntry.h"
+#include "log/File.h"
+#include "log/Formats.h"
+#include "log/Gadgets.h"
+#include "log/Tokens.h"
+#include "SquidTime.h"
+
+#include "MemBuf.h"
+#include "HttpRequest.h"
+#include "rfc1738.h"
+#include "err_detail_type.h"
+#include "errorpage.h"
+
+static void
+log_quoted_string(const char *str, char *out)
+{
+    char *p = out;
+
+    while (*str) {
+        int l = strcspn(str, "\"\\\r\n\t");
+        memcpy(p, str, l);
+        str += l;
+        p += l;
+
+        switch (*str) {
+
+        case '\0':
+            break;
+
+        case '\r':
+            *p++ = '\\';
+            *p++ = 'r';
+            str++;
+            break;
+
+        case '\n':
+            *p++ = '\\';
+            *p++ = 'n';
+            str++;
+            break;
+
+        case '\t':
+            *p++ = '\\';
+            *p++ = 't';
+            str++;
+            break;
+
+        default:
+            *p++ = '\\';
+            *p++ = *str;
+            str++;
+            break;
+        }
+    }
+
+    *p++ = '\0';
+}
+
+void
+Log::Format::SquidCustom(AccessLogEntry * al, customlog * log)
+{
+    logformat *lf;
+    Logfile *logfile;
+    logformat_token *fmt;
+    static MemBuf mb;
+    char tmp[1024];
+    String sb;
+
+    mb.reset();
+
+    lf = log->logFormat;
+    logfile = log->logfile;
+
+    for (fmt = lf->format; fmt != NULL; fmt = fmt->next) {     /* for each token */
+        const char *out = NULL;
+        int quote = 0;
+        long int outint = 0;
+        int doint = 0;
+        int dofree = 0;
+        int64_t outoff = 0;
+        int dooff = 0;
+
+        switch (fmt->type) {
+
+        case LFT_NONE:
+            out = "";
+            break;
+
+        case LFT_STRING:
+            out = fmt->data.string;
+            break;
+
+        case LFT_CLIENT_IP_ADDRESS:
+            if (al->cache.caddr.IsNoAddr()) // e.g., ICAP OPTIONS lack client
+                out = "-";
+            else
+                out = al->cache.caddr.NtoA(tmp,1024);
+            break;
+
+        case LFT_CLIENT_FQDN:
+            if (al->cache.caddr.IsAnyAddr()) // e.g., ICAP OPTIONS lack client
+                out = "-";
+            else
+                out = fqdncache_gethostbyaddr(al->cache.caddr, FQDN_LOOKUP_IF_MISS);
+            if (!out) {
+                out = al->cache.caddr.NtoA(tmp,1024);
+            }
+
+            break;
+
+        case LFT_CLIENT_PORT:
+            if (al->request) {
+                outint = al->request->client_addr.GetPort();
+                doint = 1;
+            }
+            break;
+
+#if USE_SQUID_EUI
+        case LFT_CLIENT_EUI:
+            if (al->request) {
+                if (al->cache.caddr.IsIPv4())
+                    al->request->client_eui48.encode(tmp, 1024);
+                else
+                    al->request->client_eui64.encode(tmp, 1024);
+                out = tmp;
+            }
+            break;
+#endif
+
+            /* case LFT_SERVER_IP_ADDRESS: */
+
+        case LFT_SERVER_IP_OR_PEER_NAME:
+            out = al->hier.host;
+
+            break;
+
+            /* case LFT_SERVER_PORT: */
+
+        case LFT_LOCAL_IP:
+            if (al->request) {
+                out = al->request->my_addr.NtoA(tmp,1024);
+            }
+
+            break;
+
+        case LFT_LOCAL_PORT:
+            if (al->request) {
+                outint = al->request->my_addr.GetPort();
+                doint = 1;
+            }
+
+            break;
+
+        case LFT_PEER_LOCAL_PORT:
+            if (al->hier.peer_local_port) {
+                outint = al->hier.peer_local_port;
+                doint = 1;
+            }
+
+            break;
+
+        case LFT_TIME_SECONDS_SINCE_EPOCH:
+            // some platforms store time in 32-bit, some 64-bit...
+            outoff = static_cast<int64_t>(current_time.tv_sec);
+            dooff = 1;
+            break;
+
+        case LFT_TIME_SUBSECOND:
+            outint = current_time.tv_usec / fmt->divisor;
+            doint = 1;
+            break;
+
+
+        case LFT_TIME_LOCALTIME:
+
+        case LFT_TIME_GMT: {
+            const char *spec;
+
+            struct tm *t;
+            spec = fmt->data.timespec;
+
+            if (fmt->type == LFT_TIME_LOCALTIME) {
+                if (!spec)
+                    spec = "%d/%b/%Y:%H:%M:%S %z";
+                t = localtime(&squid_curtime);
+            } else {
+                if (!spec)
+                    spec = "%d/%b/%Y:%H:%M:%S";
+
+                t = gmtime(&squid_curtime);
+            }
+
+            strftime(tmp, sizeof(tmp), spec, t);
+
+            out = tmp;
+        }
+
+        break;
+
+        case LFT_TIME_TO_HANDLE_REQUEST:
+            outint = al->cache.msec;
+            doint = 1;
+            break;
+
+        case LFT_PEER_RESPONSE_TIME:
+            if (al->hier.peer_response_time < 0) {
+                out = "-";
+            } else {
+                outoff = al->hier.peer_response_time;
+                dooff = 1;
+            }
+            break;
+
+        case LFT_TOTAL_SERVER_SIDE_RESPONSE_TIME:
+            if (al->hier.total_response_time < 0) {
+                out = "-";
+            } else {
+                outoff = al->hier.total_response_time;
+                dooff = 1;
+            }
+            break;
+
+        case LFT_DNS_WAIT_TIME:
+            if (al->request && al->request->dnsWait >= 0) {
+                outint = al->request->dnsWait;
+                doint = 1;
+            }
+            break;
+
+        case LFT_REQUEST_HEADER:
+
+            if (al->request)
+                sb = al->request->header.getByName(fmt->data.header.header);
+
+            out = sb.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_ADAPTED_REQUEST_HEADER:
+
+            if (al->request)
+                sb = al->adapted_request->header.getByName(fmt->data.header.header);
+
+            out = sb.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_REPLY_HEADER:
+            if (al->reply)
+                sb = al->reply->header.getByName(fmt->data.header.header);
+
+            out = sb.termedBuf();
+
+            quote = 1;
+
+            break;
+
+#if USE_ADAPTATION
+        case LTF_ADAPTATION_SUM_XACT_TIMES:
+            if (al->request) {
+                Adaptation::History::Pointer ah = al->request->adaptHistory();
+                if (ah != NULL)
+                    ah->sumLogString(fmt->data.string, sb);
+                out = sb.termedBuf();
+            }
+            break;
+
+        case LTF_ADAPTATION_ALL_XACT_TIMES:
+            if (al->request) {
+                Adaptation::History::Pointer ah = al->request->adaptHistory();
+                if (ah != NULL)
+                    ah->allLogString(fmt->data.string, sb);
+                out = sb.termedBuf();
+            }
+            break;
+#endif
+
+#if ICAP_CLIENT
+        case LFT_ICAP_LAST_MATCHED_HEADER:
+            if (al->request) {
+                Adaptation::Icap::History::Pointer ih = al->request->icapHistory();
+                if (ih != NULL)
+                    sb = ih->mergeOfIcapHeaders.getByName(fmt->data.header.header);
+            }
+
+            out = sb.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_ICAP_LAST_MATCHED_HEADER_ELEM:
+            if (al->request) {
+                Adaptation::Icap::History::Pointer ih = al->request->icapHistory();
+                if (ih != NULL)
+                    sb = ih->mergeOfIcapHeaders.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
+            }
+
+            out = sb.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_ICAP_LAST_MATCHED_ALL_HEADERS:
+            out = al->headers.icap;
+
+            quote = 1;
+
+            break;
+
+        case LFT_ICAP_ADDR:
+            if (!out)
+                out = al->icap.hostAddr.NtoA(tmp,1024);
+            break;
+
+        case LFT_ICAP_SERV_NAME:
+            out = al->icap.serviceName.termedBuf();
+            break;
+
+        case LFT_ICAP_REQUEST_URI:
+            out = al->icap.reqUri.termedBuf();
+            break;
+
+        case LFT_ICAP_REQUEST_METHOD:
+            out = Adaptation::Icap::ICAP::methodStr(al->icap.reqMethod);
+            break;
+
+        case LFT_ICAP_BYTES_SENT:
+            outoff = al->icap.bytesSent;
+            dooff = 1;
+            break;
+
+        case LFT_ICAP_BYTES_READ:
+            outoff = al->icap.bytesRead;
+            dooff = 1;
+            break;
+
+        case LFT_ICAP_BODY_BYTES_READ:
+            if (al->icap.bodyBytesRead >= 0) {
+                outoff = al->icap.bodyBytesRead;
+                dooff = 1;
+            }
+            // else if icap.bodyBytesRead < 0, we do not have any http data,
+            // so just print a "-" (204 responses etc)
+            break;
+
+        case LFT_ICAP_REQ_HEADER:
+            if (NULL != al->icap.request) {
+                sb = al->icap.request->header.getByName(fmt->data.header.header);
+                out = sb.termedBuf();
+                quote = 1;
+            }
+            break;
+
+        case LFT_ICAP_REQ_HEADER_ELEM:
+            if (al->request)
+                sb = al->icap.request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
+
+            out = sb.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_ICAP_REQ_ALL_HEADERS:
+            if (al->icap.request) {
+                HttpHeaderPos pos = HttpHeaderInitPos;
+                while (const HttpHeaderEntry *e = al->icap.request->header.getEntry(&pos)) {
+                    sb.append(e->name);
+                    sb.append(": ");
+                    sb.append(e->value);
+                    sb.append("\r\n");
+                }
+                out = sb.termedBuf();
+                quote = 1;
+            }
+            break;
+
+        case LFT_ICAP_REP_HEADER:
+            if (NULL != al->icap.reply) {
+                sb = al->icap.reply->header.getByName(fmt->data.header.header);
+                out = sb.termedBuf();
+                quote = 1;
+            }
+            break;
+
+        case LFT_ICAP_REP_HEADER_ELEM:
+            if (NULL != al->icap.reply)
+                sb = al->icap.reply->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
+
+            out = sb.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_ICAP_REP_ALL_HEADERS:
+            if (al->icap.reply) {
+                HttpHeaderPos pos = HttpHeaderInitPos;
+                while (const HttpHeaderEntry *e = al->icap.reply->header.getEntry(&pos)) {
+                    sb.append(e->name);
+                    sb.append(": ");
+                    sb.append(e->value);
+                    sb.append("\r\n");
+                }
+                out = sb.termedBuf();
+                quote = 1;
+            }
+            break;
+
+        case LFT_ICAP_TR_RESPONSE_TIME:
+            outint = al->icap.trTime;
+            doint = 1;
+            break;
+
+        case LFT_ICAP_IO_TIME:
+            outint = al->icap.ioTime;
+            doint = 1;
+            break;
+
+        case LFT_ICAP_STATUS_CODE:
+            outint = al->icap.resStatus;
+            doint  = 1;
+            break;
+
+        case LFT_ICAP_OUTCOME:
+            out = al->icap.outcome;
+            break;
+
+        case LFT_ICAP_TOTAL_TIME:
+            outint = al->icap.processingTime;
+            doint = 1;
+            break;
+#endif
+        case LFT_REQUEST_HEADER_ELEM:
+            if (al->request)
+                sb = al->request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
+
+            out = sb.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_ADAPTED_REQUEST_HEADER_ELEM:
+            if (al->adapted_request)
+                sb = al->adapted_request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
+
+            out = sb.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_REPLY_HEADER_ELEM:
+            if (al->reply)
+                sb = al->reply->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
+
+            out = sb.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_REQUEST_ALL_HEADERS:
+            out = al->headers.request;
+
+            quote = 1;
+
+            break;
+
+        case LFT_ADAPTED_REQUEST_ALL_HEADERS:
+            out = al->headers.adapted_request;
+
+            quote = 1;
+
+            break;
+
+        case LFT_REPLY_ALL_HEADERS:
+            out = al->headers.reply;
+
+            quote = 1;
+
+            break;
+
+        case LFT_USER_NAME:
+            out = Log::FormatName(al->cache.authuser);
+
+            if (!out)
+                out = Log::FormatName(al->cache.extuser);
+
+#if USE_SSL
+
+            if (!out)
+                out = Log::FormatName(al->cache.ssluser);
+
+#endif
+
+            if (!out)
+                out = Log::FormatName(al->cache.rfc931);
+
+            dofree = 1;
+
+            break;
+
+        case LFT_USER_LOGIN:
+            out = Log::FormatName(al->cache.authuser);
+
+            dofree = 1;
+
+            break;
+
+        case LFT_USER_IDENT:
+            out = Log::FormatName(al->cache.rfc931);
+
+            dofree = 1;
+
+            break;
+
+        case LFT_USER_EXTERNAL:
+            out = Log::FormatName(al->cache.extuser);
+
+            dofree = 1;
+
+            break;
+
+            /* case LFT_USER_REALM: */
+            /* case LFT_USER_SCHEME: */
+
+            // the fmt->type can not be LFT_HTTP_SENT_STATUS_CODE_OLD_30
+            // but compiler complains if ommited
+        case LFT_HTTP_SENT_STATUS_CODE_OLD_30:
+        case LFT_HTTP_SENT_STATUS_CODE:
+            outint = al->http.code;
+
+            doint = 1;
+
+            break;
+
+        case LFT_HTTP_RECEIVED_STATUS_CODE:
+            if (al->hier.peer_reply_status == HTTP_STATUS_NONE) {
+                out = "-";
+            } else {
+                outint = al->hier.peer_reply_status;
+                doint = 1;
+            }
+            break;
+            /* case LFT_HTTP_STATUS:
+             *           out = statusline->text;
+             *     quote = 1;
+             *     break;
+             */
+        case LFT_HTTP_BODY_BYTES_READ:
+            if (al->hier.bodyBytesRead >= 0) {
+                outoff = al->hier.bodyBytesRead;
+                dooff = 1;
+            }
+            // else if hier.bodyBytesRead < 0 we did not have any data exchange with
+            // a peer server so just print a "-" (eg requests served from cache,
+            // or internal error messages).
+            break;
+
+        case LFT_SQUID_STATUS:
+            if (al->http.timedout || al->http.aborted) {
+                snprintf(tmp, sizeof(tmp), "%s%s", log_tags[al->cache.code],
+                         al->http.statusSfx());
+                out = tmp;
+            } else {
+                out = log_tags[al->cache.code];
+            }
+
+            break;
+
+        case LFT_SQUID_ERROR:
+            if (al->request && al->request->errType != ERR_NONE)
+                out = errorPageName(al->request->errType);
+            break;
+
+        case LFT_SQUID_ERROR_DETAIL:
+            if (al->request && al->request->errDetail != ERR_DETAIL_NONE) {
+                if (al->request->errDetail > ERR_DETAIL_START  &&
+                        al->request->errDetail < ERR_DETAIL_MAX)
+                    out = errorDetailName(al->request->errDetail);
+                else {
+                    if (al->request->errDetail >= ERR_DETAIL_EXCEPTION_START)
+                        snprintf(tmp, sizeof(tmp), "%s=0x%X",
+                                 errorDetailName(al->request->errDetail), (uint32_t) al->request->errDetail);
+                    else
+                        snprintf(tmp, sizeof(tmp), "%s=%d",
+                                 errorDetailName(al->request->errDetail), al->request->errDetail);
+                    out = tmp;
+                }
+            }
+            break;
+
+        case LFT_SQUID_HIERARCHY:
+            if (al->hier.ping.timedout)
+                mb.append("TIMEOUT_", 8);
+
+            out = hier_code_str[al->hier.code];
+
+            break;
+
+        case LFT_MIME_TYPE:
+            out = al->http.content_type;
+
+            break;
+
+        case LFT_REQUEST_METHOD:
+            out = al->_private.method_str;
+
+            break;
+
+        case LFT_REQUEST_URI:
+            out = al->url;
+
+            break;
+
+        case LFT_REQUEST_URLPATH:
+            if (al->request) {
+                out = al->request->urlpath.termedBuf();
+                quote = 1;
+            }
+            break;
+
+        case LFT_REQUEST_VERSION:
+            snprintf(tmp, sizeof(tmp), "%d.%d", (int) al->http.version.major, (int) al->http.version.minor);
+            out = tmp;
+            break;
+
+        case LFT_REQUEST_SIZE_TOTAL:
+            outoff = al->cache.requestSize;
+            dooff = 1;
+            break;
+
+            /*case LFT_REQUEST_SIZE_LINE: */
+        case LFT_REQUEST_SIZE_HEADERS:
+            outoff = al->cache.requestHeadersSize;
+            dooff =1;
+            break;
+            /*case LFT_REQUEST_SIZE_BODY: */
+            /*case LFT_REQUEST_SIZE_BODY_NO_TE: */
+
+        case LFT_REPLY_SIZE_TOTAL:
+            outoff = al->cache.replySize;
+            dooff = 1;
+            break;
+
+        case LFT_REPLY_HIGHOFFSET:
+            outoff = al->cache.highOffset;
+
+            dooff = 1;
+
+            break;
+
+        case LFT_REPLY_OBJECTSIZE:
+            outoff = al->cache.objectSize;
+
+            dooff = 1;
+
+            break;
+
+            /*case LFT_REPLY_SIZE_LINE: */
+        case LFT_REPLY_SIZE_HEADERS:
+            outint = al->cache.replyHeadersSize;
+            doint = 1;
+            break;
+            /*case LFT_REPLY_SIZE_BODY: */
+            /*case LFT_REPLY_SIZE_BODY_NO_TE: */
+
+        case LFT_TAG:
+            if (al->request)
+                out = al->request->tag.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_IO_SIZE_TOTAL:
+            outint = al->cache.requestSize + al->cache.replySize;
+            doint = 1;
+            break;
+
+        case LFT_EXT_LOG:
+            if (al->request)
+                out = al->request->extacl_log.termedBuf();
+
+            quote = 1;
+
+            break;
+
+        case LFT_SEQUENCE_NUMBER:
+            outoff = logfile->sequence_number;
+            dooff = 1;
+            break;
+
+        case LFT_PERCENT:
+            out = "%";
+
+            break;
+        }
+
+        if (dooff) {
+            snprintf(tmp, sizeof(tmp), "%0*" PRId64, fmt->zero ? (int) fmt->width : 0, outoff);
+            out = tmp;
+
+        } else if (doint) {
+            snprintf(tmp, sizeof(tmp), "%0*ld", fmt->zero ? (int) fmt->width : 0, outint);
+            out = tmp;
+        }
+
+        if (out && *out) {
+            if (quote || fmt->quote != LOG_QUOTE_NONE) {
+                char *newout = NULL;
+                int newfree = 0;
+
+                switch (fmt->quote) {
+
+                case LOG_QUOTE_NONE:
+                    newout = rfc1738_escape_unescaped(out);
+                    break;
+
+                case LOG_QUOTE_QUOTES: {
+                    size_t out_len = static_cast<size_t>(strlen(out)) * 2 + 1;
+                    if (out_len >= sizeof(tmp)) {
+                        newout = (char *)xmalloc(out_len);
+                        newfree = 1;
+                    } else
+                        newout = tmp;
+                    log_quoted_string(out, newout);
+                }
+                break;
+
+                case LOG_QUOTE_MIMEBLOB:
+                    newout = Log::QuoteMimeBlob(out);
+                    newfree = 1;
+                    break;
+
+                case LOG_QUOTE_URL:
+                    newout = rfc1738_escape(out);
+                    break;
+
+                case LOG_QUOTE_RAW:
+                    break;
+                }
+
+                if (newout) {
+                    if (dofree)
+                        safe_free(out);
+
+                    out = newout;
+
+                    dofree = newfree;
+                }
+            }
+
+            if (fmt->width) {
+                if (fmt->left)
+                    mb.Printf("%-*s", (int) fmt->width, out);
+                else
+                    mb.Printf("%*s", (int) fmt->width, out);
+            } else
+                mb.append(out, strlen(out));
+        } else {
+            mb.append("-", 1);
+        }
+
+        if (fmt->space)
+            mb.append(" ", 1);
+
+        sb.clean();
+
+        if (dofree)
+            safe_free(out);
+    }
+
+    logfilePrintf(logfile, "%s\n", mb.buf);
+}
similarity index 50%
rename from src/referer.cc
rename to src/log/FormatSquidIcap.cc
index 7a1eb5d398fc309b97c774e7a7fa8fb13152cbaf..5fccc88f9eb5ee8661df4f5ff14402560af23104 100644 (file)
@@ -1,9 +1,8 @@
 /*
  * $Id$
  *
- * DEBUG: section 40    Referer Logging
- * AUTHOR: Joe Ramey <ramey@csc.ti.com> (useragent)
- *         Jens-S. Vöckler <voeckler@rvs.uni-hannover.de> (mod 4 referer)
+ * DEBUG: section 46    Access Log - Squid ICAP Logging
+ * AUTHOR: Alex Rousskov
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
  * ----------------------------------------------------------
  *
  */
 
-#include "squid.h"
+#include "config.h"
+
+#if ICAP_CLIENT
+
+#include "AccessLogEntry.h"
+#include "HttpRequest.h"
 #include "log/File.h"
+#include "log/Formats.h"
+#include "log/Gadgets.h"
 #include "SquidTime.h"
 
-#if USE_REFERER_LOG
-static Logfile *refererlog = NULL;
-#endif
-
 void
-refererOpenLog(void)
+Log::Format::SquidIcap(AccessLogEntry * al, Logfile * logfile)
 {
-#if USE_REFERER_LOG
-    assert(NULL == refererlog);
-
-    if (!Config.Log.referer || (0 == strcmp(Config.Log.referer, "none"))) {
-        debugs(40, 1, "Referer logging is disabled.");
-        return;
+    const char *client = NULL;
+    const char *user = NULL;
+    char tmp[MAX_IPSTRLEN], clientbuf[MAX_IPSTRLEN];
+
+    if (al->cache.caddr.IsAnyAddr()) { // ICAP OPTIONS xactions lack client
+        client = "-";
+    } else {
+        if (Config.onoff.log_fqdn)
+            client = fqdncache_gethostbyaddr(al->cache.caddr, FQDN_LOOKUP_IF_MISS);
+        if (!client)
+            client = al->cache.caddr.NtoA(clientbuf, MAX_IPSTRLEN);
     }
 
-    refererlog = logfileOpen(Config.Log.referer, 0, 1);
-#endif
-}
-
-void
-refererRotateLog(void)
-{
-#if USE_REFERER_LOG
-
-    if (NULL == refererlog)
-        return;
+    user = Log::FormatName(al->cache.authuser);
 
-    logfileRotate(refererlog);
+    if (!user)
+        user = Log::FormatName(al->cache.extuser);
 
+#if USE_SSL
+    if (!user)
+        user = Log::FormatName(al->cache.ssluser);
 #endif
-}
 
-void
-logReferer(const char *client, const char *referer, const char *uri)
-{
-#if USE_REFERER_LOG
+    if (!user)
+        user = Log::FormatName(al->cache.rfc931);
 
-    if (NULL == refererlog)
-        return;
+    if (user && !*user)
+        safe_free(user);
 
-    logfilePrintf(refererlog, "%9d.%03d %s %s %s\n",
-                  (int) current_time.tv_sec,
+    logfilePrintf(logfile, "%9ld.%03d %6d %s -/%03d %"PRId64" %s %s %s -/%s -\n",
+                  (long int) current_time.tv_sec,
                   (int) current_time.tv_usec / 1000,
+                  al->icap.trTime,
                   client,
-                  referer,
-                  uri ? uri : "-");
-
-#endif
+                  al->icap.resStatus,
+                  al->icap.bytesRead,
+                  Adaptation::Icap::ICAP::methodStr(al->icap.reqMethod),
+                  al->icap.reqUri.termedBuf(),
+                  user ? user : "-",
+                  al->icap.hostAddr.NtoA(tmp, MAX_IPSTRLEN));
+    safe_free(user);
 }
-
-void
-refererCloseLog(void)
-{
-#if USE_REFERER_LOG
-
-    if (NULL == refererlog)
-        return;
-
-    logfileClose(refererlog);
-
-    refererlog = NULL;
-
 #endif
-}
diff --git a/src/log/FormatSquidNative.cc b/src/log/FormatSquidNative.cc
new file mode 100644 (file)
index 0000000..d523c57
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 46    Access Log - Squid format
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "AccessLogEntry.h"
+#include "log/File.h"
+#include "log/Formats.h"
+#include "log/Gadgets.h"
+#include "log/Tokens.h"
+#include "SquidTime.h"
+
+void
+Log::Format::SquidNative(AccessLogEntry * al, Logfile * logfile)
+{
+    const char *user = NULL;
+    char clientip[MAX_IPSTRLEN];
+
+    user = FormatName(al->cache.authuser);
+
+    if (!user)
+        user = FormatName(al->cache.extuser);
+
+#if USE_SSL
+    if (!user)
+        user = FormatName(al->cache.ssluser);
+#endif
+
+    if (!user)
+        user = FormatName(al->cache.rfc931);
+
+    if (user && !*user)
+        safe_free(user);
+
+    logfilePrintf(logfile, "%9ld.%03d %6d %s %s%s/%03d %"PRId64" %s %s %s %s%s/%s %s%s",
+                  (long int) current_time.tv_sec,
+                  (int) current_time.tv_usec / 1000,
+                  al->cache.msec,
+                  al->cache.caddr.NtoA(clientip, MAX_IPSTRLEN),
+                  log_tags[al->cache.code],
+                  al->http.statusSfx(),
+                  al->http.code,
+                  al->cache.replySize,
+                  al->_private.method_str,
+                  al->url,
+                  user ? user : dash_str,
+                  al->hier.ping.timedout ? "TIMEOUT_" : "",
+                  hier_code_str[al->hier.code],
+                  al->hier.host,
+                  al->http.content_type,
+                  (Config.onoff.log_mime_hdrs?"":"\n"));
+
+    safe_free(user);
+
+    if (Config.onoff.log_mime_hdrs) {
+        char *ereq = QuoteMimeBlob(al->headers.request);
+        char *erep = QuoteMimeBlob(al->headers.reply);
+        logfilePrintf(logfile, " [%s] [%s]\n", ereq, erep);
+        safe_free(ereq);
+        safe_free(erep);
+    }
+}
similarity index 60%
rename from src/comm_epoll.h
rename to src/log/FormatSquidReferer.cc
index 90c10a46ee885873832007f8de716647c4fe32b5..585187dd654b8f205c41696505de52e1600cb2bf 100644 (file)
@@ -1,7 +1,9 @@
-
 /*
  * $Id$
  *
+ * DEBUG: section 46    Access Log - Squid referer format
+ * AUTHOR: Joe Ramey <ramey@csc.ti.com> (useragent)
+ *         Jens-S. V?ckler <voeckler@rvs.uni-hannover.de> (mod 4 referer)
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
  * ----------------------------------------------------------
  *
  */
 
-#ifndef SQUID_COMM_EPOLL_H
-#define SQUID_COMM_EPOLL_H
+#include "config.h"
+#include "AccessLogEntry.h"
+#include "HttpRequest.h"
+#include "log/File.h"
+#include "log/Formats.h"
+#include "SquidTime.h"
+
+void
+Log::Format::SquidReferer(AccessLogEntry *al, Logfile *logfile)
+{
+    const char *referer = al->request->header.getStr(HDR_REFERER);
+
+    // do not log unless there is something to be displayed
+    if (!referer || *referer == '\0')
+        return;
+
+    char clientip[MAX_IPSTRLEN];
 
-#endif /* SQUID_COMM_EPOLL_H */
+    logfilePrintf(logfile, "%9ld.%03d %s %s %s\n",
+                  (long int) current_time.tv_sec,
+                  (int) current_time.tv_usec / 1000,
+                  al->cache.caddr.NtoA(clientip, MAX_IPSTRLEN),
+                  referer,
+                  al->url ? al->url : "-");
+}
similarity index 63%
rename from src/comm_select.h
rename to src/log/FormatSquidUseragent.cc
index 9365f83e8368707521f9055826cb2ba2d8b0180f..ce9f676a1a74323b309057be4cbaa74bbf1bd539 100644 (file)
@@ -1,7 +1,9 @@
-
 /*
  * $Id$
  *
+ * DEBUG: section 46    Access Log - Squid useragent format
+ * AUTHOR: Joe Ramey <ramey@csc.ti.com>
+ * AUTHOR: Amos Jeffries <amosjeffries@squid-cache.org>
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
  * ----------------------------------------------------------
  *
  */
 
-#ifndef SQUID_COMM_SELECT_H
-#define SQUID_COMM_SELECT_H
+#include "config.h"
+#include "AccessLogEntry.h"
+#include "HttpRequest.h"
+#include "log/File.h"
+#include "log/Formats.h"
+#include "SquidTime.h"
+
+void
+Log::Format::SquidUserAgent(AccessLogEntry * al, Logfile * logfile)
+{
+    char clientip[MAX_IPSTRLEN];
+
+    const char *agent = al->request->header.getStr(HDR_USER_AGENT);
 
+    // do not log unless there is something to be displayed.
+    if (!agent || *agent == '\0')
+        return;
 
-#endif /* SQUID_COMM_SELECT_H */
+    logfilePrintf(logfile, "%s [%s] \"%s\"\n",
+                  al->cache.caddr.NtoA(clientip,MAX_IPSTRLEN),
+                  Time::FormatHttpd(squid_curtime),
+                  agent);
+}
diff --git a/src/log/Formats.h b/src/log/Formats.h
new file mode 100644 (file)
index 0000000..97ac52c
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef _SQUID_LOG_FORMATS_H
+#define _SQUID_LOG_FORMATS_H
+
+class AccessLogEntry;
+class Logfile;
+
+namespace Log
+{
+
+namespace Format
+{
+
+typedef enum {
+    CLF_UNKNOWN,
+    CLF_COMBINED,
+    CLF_COMMON,
+    CLF_CUSTOM,
+#if ICAP_CLIENT
+    CLF_ICAP_SQUID,
+#endif
+    CLF_REFERER,
+    CLF_SQUID,
+    CLF_USERAGENT,
+    CLF_NONE
+} log_type;
+
+/// Native Squid Format Display
+void SquidNative(AccessLogEntry * al, Logfile * logfile);
+
+/// Display log details in Squid ICAP format.
+void SquidIcap(AccessLogEntry * al, Logfile * logfile);
+
+/// Display log details in useragent format.
+void SquidUserAgent(AccessLogEntry * al, Logfile * logfile);
+
+/// Display log details in Squid old refererlog format.
+void SquidReferer(AccessLogEntry * al, Logfile * logfile);
+
+/// Log with a local custom format
+void SquidCustom(AccessLogEntry * al, customlog * log);
+
+/// Log with Apache httpd common format
+void HttpdCommon(AccessLogEntry * al, Logfile * logfile);
+
+/// Log with Apache httpd combined format
+void HttpdCombined(AccessLogEntry * al, Logfile * logfile);
+
+}; // namespace Format
+}; // namespace Log
+
+#endif /* _SQUID_LOG_FORMATS_H */
diff --git a/src/log/Gadgets.cc b/src/log/Gadgets.cc
new file mode 100644 (file)
index 0000000..f188f81
--- /dev/null
@@ -0,0 +1,156 @@
+#include "config.h"
+#include "log/Gadgets.h"
+
+static const char c2x[] =
+    "000102030405060708090a0b0c0d0e0f"
+    "101112131415161718191a1b1c1d1e1f"
+    "202122232425262728292a2b2c2d2e2f"
+    "303132333435363738393a3b3c3d3e3f"
+    "404142434445464748494a4b4c4d4e4f"
+    "505152535455565758595a5b5c5d5e5f"
+    "606162636465666768696a6b6c6d6e6f"
+    "707172737475767778797a7b7c7d7e7f"
+    "808182838485868788898a8b8c8d8e8f"
+    "909192939495969798999a9b9c9d9e9f"
+    "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
+    "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
+    "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
+    "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
+    "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
+    "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
+
+#if DEAD_USING_QUOTEMIMEBLOB
+/** copy of Log::QuoteMimeBlob. Bugs there will be found here.
+ * This omits [] characters but is otherwise identical to Log::QuoteMimeBlob when OLD_LOG_MIME = 1
+ */
+static char *
+username_quote(const char *header)
+{
+    int c;
+    int i;
+    char *buf;
+    char *buf_cursor;
+
+    if (header == NULL) {
+        buf = static_cast<char *>(xcalloc(1, 1));
+        *buf = '\0';
+        return buf;
+    }
+
+    buf = static_cast<char *>(xcalloc(1, (strlen(header) * 3) + 1));
+    buf_cursor = buf;
+    /*
+     * We escape: space \x00-\x1F and space (0x40) and \x7F-\xFF
+     * to prevent garbage in the logs. CR and LF are also there just in case.
+     */
+
+    while ((c = *(const unsigned char *) header++) != '\0') {
+        if (c == '\r') {
+            *buf_cursor++ = '\\';
+            *buf_cursor++ = 'r';
+        } else if (c == '\n') {
+            *buf_cursor++ = '\\';
+            *buf_cursor++ = 'n';
+        } else if (c <= 0x1F
+                   || c >= 0x7F
+                   || c == '%'
+                   || c == ' ') {
+            *buf_cursor++ = '%';
+            i = c * 2;
+            *buf_cursor++ = c2x[i];
+            *buf_cursor++ = c2x[i + 1];
+        } else {
+            *buf_cursor++ = (char) c;
+        }
+    }
+
+    *buf_cursor = '\0';
+    return buf;
+}
+#endif // DEAD
+
+char *
+Log::FormatName(const char *name)
+{
+    if (NULL == name)
+        return NULL;
+
+    if (name[0] == '\0')
+        return NULL;
+
+    return QuoteMimeBlob(name);
+//    return username_quote(name);
+}
+
+char *
+Log::QuoteMimeBlob(const char *header)
+{
+    int c;
+    int i;
+    char *buf;
+    char *buf_cursor;
+
+    if (header == NULL) {
+        buf = static_cast<char *>(xcalloc(1, 1));
+        *buf = '\0';
+        return buf;
+    }
+
+    buf = static_cast<char *>(xcalloc(1, (strlen(header) * 3) + 1));
+    buf_cursor = buf;
+    /**
+     * Whe OLD_LOG_MIME is defined we escape: \x00-\x1F"#%;<>?{}|\\\\^~`\[\]\x7F-\xFF
+     * which is the default escape list for the CPAN Perl5 URI module
+     * modulo the inclusion of space (x40) to make the raw logs a bit
+     * more readable.
+     */
+
+    while ((c = *(const unsigned char *) header++) != '\0') {
+#if !OLD_LOG_MIME
+        if (c == '\r') {
+            *buf_cursor++ = '\\';
+            *buf_cursor++ = 'r';
+        } else if (c == '\n') {
+            *buf_cursor++ = '\\';
+            *buf_cursor++ = 'n';
+        } else
+#endif
+            if (c <= 0x1F
+                    || c >= 0x7F
+                    || c == '%'
+#if OLD_LOG_MIME
+                    || c == '"'
+                    || c == '#'
+                    || c == ';'
+                    || c == '<'
+                    || c == '>'
+                    || c == '?'
+                    || c == '{'
+                    || c == '}'
+                    || c == '|'
+                    || c == '\\'
+                    || c == '^'
+                    || c == '~'
+                    || c == '`'
+#endif
+                    || c == '['
+                    || c == ']') {
+                *buf_cursor++ = '%';
+                i = c * 2;
+                *buf_cursor++ = c2x[i];
+                *buf_cursor++ = c2x[i + 1];
+#if !OLD_LOG_MIME
+
+            } else if (c == '\\') {
+                *buf_cursor++ = '\\';
+                *buf_cursor++ = '\\';
+#endif
+
+            } else {
+                *buf_cursor++ = (char) c;
+            }
+    }
+
+    *buf_cursor = '\0';
+    return buf;
+}
diff --git a/src/log/Gadgets.h b/src/log/Gadgets.h
new file mode 100644 (file)
index 0000000..9e5e1dd
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef _SQUID_LOG_GADGETS_H
+#define _SQUID_LOG_GADGETS_H
+
+namespace Log
+{
+
+/// Safely URL-encode a username.
+/// Accepts NULL or empty strings.
+char * FormatName(const char *name);
+
+/** URL-style encoding on a MIME headers blob.
+ * May accept NULL or empty strings.
+ * \return A dynamically allocated string. recipient is responsible for free()'ing
+ */
+char *QuoteMimeBlob(const char *header);
+
+}; // namespace Log
+
+#endif /* _SQUID_LOG_GADGETS_H */
index 82ffb7484646bc545bd689b917f4d53c1079e634..cab6f055809dba18d8e6df7bfeb8d1f48f1ab6b8 100644 (file)
@@ -9,6 +9,16 @@ liblog_la_SOURCES = \
        Config.h \
        File.cc \
        File.h \
+       FormatHttpdCombined.cc \
+       FormatHttpdCommon.cc \
+       Formats.h \
+       FormatSquidCustom.cc \
+       FormatSquidIcap.cc \
+       FormatSquidNative.cc \
+       FormatSquidReferer.cc \
+       FormatSquidUseragent.cc \
+       Gadgets.cc \
+       Gadgets.h \
        ModDaemon.cc \
        ModDaemon.h \
        ModStdio.cc \
@@ -18,4 +28,7 @@ liblog_la_SOURCES = \
        ModTcp.cc \
        ModTcp.h \
        ModUdp.cc \
-       ModUdp.h
+       ModUdp.h \
+       Tokens.cc \
+       Tokens.h
+
index b987d950925c6b1db7b41ee4f9e3975dad051729..59bf69b761b93d65633ce552ece020cc3cabe4c3 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "squid.h"
 #include "cbdata.h"
+#include "comm/Loops.h"
 #include "fde.h"
 #include "log/Config.h"
 #include "log/File.h"
@@ -151,7 +152,7 @@ logfileHandleWrite(int fd, void *data)
     /* there is, so schedule more */
 
 reschedule:
-    commSetSelect(ll->wfd, COMM_SELECT_WRITE, logfileHandleWrite, lf, 0);
+    Comm::SetSelect(ll->wfd, COMM_SELECT_WRITE, logfileHandleWrite, lf, 0);
     ll->flush_pending = 1;
 finish:
     return;
@@ -171,7 +172,7 @@ logfileQueueWrite(Logfile * lf)
             logfile_mod_daemon_append(lf, "F\n", 2);
     }
     /* Ok, schedule a write-event */
-    commSetSelect(ll->wfd, COMM_SELECT_WRITE, logfileHandleWrite, lf, 0);
+    Comm::SetSelect(ll->wfd, COMM_SELECT_WRITE, logfileHandleWrite, lf, 0);
 }
 
 static void
@@ -191,7 +192,7 @@ logfile_mod_daemon_append(Logfile * lf, const char *buf, int len)
         b = static_cast<logfile_buffer_t*>(ll->bufs.tail->data);
         debugs(50, 3, "logfile_mod_daemon_append: current buffer has " << b->len << " of " << b->size << " bytes before append");
         s = min(len, (b->size - b->len));
-        xmemcpy(b->buf + b->len, buf, s);
+        memcpy(b->buf + b->len, buf, s);
         len = len - s;
         buf = buf + s;
         b->len = b->len + s;
index 7a009140c7cf8308dc0b24e30a741b4c7b2f911d..e9d704b68cde7caac9b2d4296c22c4d75af97be1 100644 (file)
@@ -82,7 +82,7 @@ logfile_mod_stdio_writeline(Logfile * lf, const char *buf, size_t len)
         return;
     }
     /* buffer it */
-    xmemcpy(ll->buf + ll->offset, buf, len);
+    memcpy(ll->buf + ll->offset, buf, len);
 
     ll->offset += len;
 
index 816760b91aac51fd7ac8b08842199a4bf74f847a..4f5275c8745f8f896e8e8a3710622d633805e0bf 100644 (file)
@@ -101,7 +101,7 @@ logfile_mod_tcp_writeline(Logfile * lf, const char *buf, size_t len)
         return;
     }
     /* buffer it */
-    xmemcpy(ll->buf + ll->offset, buf, len);
+    memcpy(ll->buf + ll->offset, buf, len);
 
     ll->offset += len;
 
index b33e38fc0a4998439e453960034b60440cc7863c..ce373c83fe31c3a17cd3271736b08b9bee40921e 100644 (file)
@@ -99,7 +99,7 @@ logfile_mod_udp_writeline(Logfile * lf, const char *buf, size_t len)
         return;
     }
     /* buffer it */
-    xmemcpy(ll->buf + ll->offset, buf, len);
+    memcpy(ll->buf + ll->offset, buf, len);
 
     ll->offset += len;
 
diff --git a/src/log/Tokens.cc b/src/log/Tokens.cc
new file mode 100644 (file)
index 0000000..4afb57b
--- /dev/null
@@ -0,0 +1,690 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 46    Access Log Format Tokens
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "log/Tokens.h"
+#include "Store.h"
+
+const char *log_tags[] = {
+    "NONE",
+    "TCP_HIT",
+    "TCP_MISS",
+    "TCP_REFRESH_UNMODIFIED",
+    "TCP_REFRESH_FAIL", // same tag logged for LOG_TCP_REFRESH_FAIL_OLD and
+    "TCP_REFRESH_FAIL", // LOG_TCP_REFRESH_FAIL_ERR for backward-compatibility
+    "TCP_REFRESH_MODIFIED",
+    "TCP_CLIENT_REFRESH_MISS",
+    "TCP_IMS_HIT",
+    "TCP_SWAPFAIL_MISS",
+    "TCP_NEGATIVE_HIT",
+    "TCP_MEM_HIT",
+    "TCP_DENIED",
+    "TCP_DENIED_REPLY",
+    "TCP_OFFLINE_HIT",
+#if LOG_TCP_REDIRECTS
+    "TCP_REDIRECT",
+#endif
+    "UDP_HIT",
+    "UDP_MISS",
+    "UDP_DENIED",
+    "UDP_INVALID",
+    "UDP_MISS_NOFETCH",
+    "ICP_QUERY",
+    "LOG_TYPE_MAX"
+};
+
+#if USE_ADAPTATION
+bool alLogformatHasAdaptToken = false;
+#endif
+
+#if ICAP_CLIENT
+bool alLogformatHasIcapToken = false;
+#endif
+
+struct logformat_token_table_entry logformat_token_table[] = {
+
+    {">a", LFT_CLIENT_IP_ADDRESS},
+    {">p", LFT_CLIENT_PORT},
+    {">A", LFT_CLIENT_FQDN},
+#if USE_SQUID_EUI
+    {">eui", LFT_CLIENT_EUI},
+#endif
+
+    /*{ "<a", LFT_SERVER_IP_ADDRESS }, */
+    /*{ "<p", LFT_SERVER_PORT }, */
+    {"<A", LFT_SERVER_IP_OR_PEER_NAME},
+
+    /* {"oa", LFT_OUTGOING_IP}, */
+    /* {"ot", LFT_OUTGOING_TOS}, */
+
+    {"la", LFT_LOCAL_IP},
+    {"lp", LFT_LOCAL_PORT},
+    /*{ "lA", LFT_LOCAL_NAME }, */
+    {"<lp", LFT_PEER_LOCAL_PORT},
+
+    {"ts", LFT_TIME_SECONDS_SINCE_EPOCH},
+    {"tu", LFT_TIME_SUBSECOND},
+    {"tl", LFT_TIME_LOCALTIME},
+    {"tg", LFT_TIME_GMT},
+    {"tr", LFT_TIME_TO_HANDLE_REQUEST},
+
+    {"<pt", LFT_PEER_RESPONSE_TIME},
+    {"<tt", LFT_TOTAL_SERVER_SIDE_RESPONSE_TIME},
+    {"dt", LFT_DNS_WAIT_TIME},
+
+    {">ha", LFT_ADAPTED_REQUEST_HEADER},
+    {">ha", LFT_ADAPTED_REQUEST_ALL_HEADERS},
+    {">h", LFT_REQUEST_HEADER},
+    {">h", LFT_REQUEST_ALL_HEADERS},
+    {"<h", LFT_REPLY_HEADER},
+    {"<h", LFT_REPLY_ALL_HEADERS},
+
+    {"un", LFT_USER_NAME},
+    {"ul", LFT_USER_LOGIN},
+    /*{ "ur", LFT_USER_REALM }, */
+    /*{ "us", LFT_USER_SCHEME }, */
+    {"ui", LFT_USER_IDENT},
+    {"ue", LFT_USER_EXTERNAL},
+
+    {"Hs", LFT_HTTP_SENT_STATUS_CODE_OLD_30},
+    {">Hs", LFT_HTTP_SENT_STATUS_CODE},
+    {"<Hs", LFT_HTTP_RECEIVED_STATUS_CODE},
+    /*{ "Ht", LFT_HTTP_STATUS }, */
+    {"<bs", LFT_HTTP_BODY_BYTES_READ},
+
+    {"Ss", LFT_SQUID_STATUS},
+    { "err_code", LFT_SQUID_ERROR },
+    { "err_detail", LFT_SQUID_ERROR_DETAIL },
+    {"Sh", LFT_SQUID_HIERARCHY},
+
+    {"mt", LFT_MIME_TYPE},
+
+    {"rm", LFT_REQUEST_METHOD},
+    {"ru", LFT_REQUEST_URI},   /* doesn't include the query-string */
+    {"rp", LFT_REQUEST_URLPATH},       /* doesn't include the host */
+    /* { "rq", LFT_REQUEST_QUERY }, * /     / * the query-string, INCLUDING the leading ? */
+    {">v", LFT_REQUEST_VERSION},
+    {"rv", LFT_REQUEST_VERSION},
+
+    { ">st", LFT_REQUEST_SIZE_TOTAL },
+    /*{ ">sl", LFT_REQUEST_SIZE_LINE }, * / / * the request line "GET ... " */
+    { ">sh", LFT_REQUEST_SIZE_HEADERS },
+    /*{ ">sb", LFT_REQUEST_SIZE_BODY }, */
+    /*{ ">sB", LFT_REQUEST_SIZE_BODY_NO_TE }, */
+
+    {"<st", LFT_REPLY_SIZE_TOTAL},
+    {"<sH", LFT_REPLY_HIGHOFFSET},
+    {"<sS", LFT_REPLY_OBJECTSIZE},
+    /*{ "<sl", LFT_REPLY_SIZE_LINE }, * /   / * the reply line (protocol, code, text) */
+    { "<sh", LFT_REPLY_SIZE_HEADERS },
+    /*{ "<sb", LFT_REPLY_SIZE_BODY }, */
+    /*{ "<sB", LFT_REPLY_SIZE_BODY_NO_TE }, */
+
+    {"et", LFT_TAG},
+    {"st", LFT_IO_SIZE_TOTAL},
+    {"ea", LFT_EXT_LOG},
+    {"sn", LFT_SEQUENCE_NUMBER},
+
+    {"%", LFT_PERCENT},
+
+#if USE_ADAPTATION
+    {"adapt::all_trs", LTF_ADAPTATION_ALL_XACT_TIMES},
+    {"adapt::sum_trs", LTF_ADAPTATION_SUM_XACT_TIMES},
+#endif
+
+#if ICAP_CLIENT
+    {"icap::tt", LFT_ICAP_TOTAL_TIME},
+    {"icap::<last_h", LFT_ICAP_LAST_MATCHED_HEADER},
+
+    {"icap::<A",  LFT_ICAP_ADDR},
+    {"icap::<service_name",  LFT_ICAP_SERV_NAME},
+    {"icap::ru",  LFT_ICAP_REQUEST_URI},
+    {"icap::rm",  LFT_ICAP_REQUEST_METHOD},
+    {"icap::>st",  LFT_ICAP_BYTES_SENT},
+    {"icap::<st",  LFT_ICAP_BYTES_READ},
+    {"icap::<bs", LFT_ICAP_BODY_BYTES_READ},
+
+    {"icap::>h",  LFT_ICAP_REQ_HEADER},
+    {"icap::<h",  LFT_ICAP_REP_HEADER},
+
+    {"icap::tr",  LFT_ICAP_TR_RESPONSE_TIME},
+    {"icap::tio",  LFT_ICAP_IO_TIME},
+    {"icap::to",  LFT_ICAP_OUTCOME},
+    {"icap::Hs",  LFT_ICAP_STATUS_CODE},
+#endif
+
+    {NULL, LFT_NONE}           /* this must be last */
+};
+
+/* parses a single token. Returns the token length in characters,
+ * and fills in the lt item with the token information.
+ * def is for sure null-terminated
+ */
+int
+accessLogGetNewLogFormatToken(logformat_token * lt, char *def, enum log_quote *quote)
+{
+    char *cur = def;
+
+    struct logformat_token_table_entry *lte;
+    int l;
+
+    memset(lt, 0, sizeof(*lt));
+    l = strcspn(cur, "%");
+
+    if (l > 0) {
+        char *cp;
+        /* it's a string for sure, until \0 or the next % */
+        cp = (char *)xmalloc(l + 1);
+        xstrncpy(cp, cur, l + 1);
+        lt->type = LFT_STRING;
+        lt->data.string = cp;
+
+        while (l > 0) {
+            switch (*cur) {
+
+            case '"':
+
+                if (*quote == LOG_QUOTE_NONE)
+                    *quote = LOG_QUOTE_QUOTES;
+                else if (*quote == LOG_QUOTE_QUOTES)
+                    *quote = LOG_QUOTE_NONE;
+
+                break;
+
+            case '[':
+                if (*quote == LOG_QUOTE_NONE)
+                    *quote = LOG_QUOTE_MIMEBLOB;
+
+                break;
+
+            case ']':
+                if (*quote == LOG_QUOTE_MIMEBLOB)
+                    *quote = LOG_QUOTE_NONE;
+
+                break;
+            }
+
+            cur++;
+            l--;
+        }
+
+        goto done;
+    }
+
+    if (!*cur)
+        goto done;
+
+    cur++;
+
+    switch (*cur) {
+
+    case '"':
+        lt->quote = LOG_QUOTE_QUOTES;
+        cur++;
+        break;
+
+    case '\'':
+        lt->quote = LOG_QUOTE_RAW;
+        cur++;
+        break;
+
+    case '[':
+        lt->quote = LOG_QUOTE_MIMEBLOB;
+        cur++;
+        break;
+
+    case '#':
+        lt->quote = LOG_QUOTE_URL;
+        cur++;
+        break;
+
+    default:
+        lt->quote = *quote;
+        break;
+    }
+
+    if (*cur == '-') {
+        lt->left = 1;
+        cur++;
+    }
+
+    if (*cur == '0') {
+        lt->zero = 1;
+        cur++;
+    }
+
+    if (xisdigit(*cur))
+        lt->width = strtol(cur, &cur, 10);
+
+    if (*cur == '.')
+        lt->precision = strtol(cur + 1, &cur, 10);
+
+    if (*cur == '{') {
+        char *cp;
+        cur++;
+        l = strcspn(cur, "}");
+        cp = (char *)xmalloc(l + 1);
+        xstrncpy(cp, cur, l + 1);
+        lt->data.string = cp;
+        cur += l;
+
+        if (*cur == '}')
+            cur++;
+    }
+
+    // For upward compatibility, assume "http::" prefix as default prefix
+    // for all log access formating codes, except those starting
+    // from "icap::", "adapt::" and "%"
+    if (strncmp(cur,"http::", 6) == 0 &&
+            strncmp(cur+6, "icap::", 6) != 0  &&
+            strncmp(cur+6, "adapt::", 12) != 0 && *(cur+6) != '%' ) {
+        cur += 6;
+    }
+
+    lt->type = LFT_NONE;
+
+    for (lte = logformat_token_table; lte->config != NULL; lte++) {
+        if (strncmp(lte->config, cur, strlen(lte->config)) == 0) {
+            lt->type = lte->token_type;
+            cur += strlen(lte->config);
+            break;
+        }
+    }
+
+    if (lt->type == LFT_NONE) {
+        fatalf("Can't parse configuration token: '%s'\n",
+               def);
+    }
+
+    if (*cur == ' ') {
+        lt->space = 1;
+        cur++;
+    }
+
+done:
+
+    switch (lt->type) {
+
+#if ICAP_CLIENT
+    case LFT_ICAP_LAST_MATCHED_HEADER:
+
+    case LFT_ICAP_REQ_HEADER:
+
+    case LFT_ICAP_REP_HEADER:
+#endif
+
+    case LFT_ADAPTED_REQUEST_HEADER:
+
+    case LFT_REQUEST_HEADER:
+
+    case LFT_REPLY_HEADER:
+
+        if (lt->data.string) {
+            char *header = lt->data.string;
+            char *cp = strchr(header, ':');
+
+            if (cp) {
+                *cp++ = '\0';
+
+                if (*cp == ',' || *cp == ';' || *cp == ':')
+                    lt->data.header.separator = *cp++;
+                else
+                    lt->data.header.separator = ',';
+
+                lt->data.header.element = cp;
+
+                switch (lt->type) {
+                case LFT_REQUEST_HEADER:
+                    lt->type = LFT_REQUEST_HEADER_ELEM;
+                    break;
+
+                case LFT_ADAPTED_REQUEST_HEADER:
+                    lt->type = LFT_ADAPTED_REQUEST_HEADER_ELEM;
+                    break;
+
+                case LFT_REPLY_HEADER:
+                    lt->type = LFT_REPLY_HEADER_ELEM;
+                    break;
+#if ICAP_CLIENT
+                case LFT_ICAP_LAST_MATCHED_HEADER:
+                    lt->type = LFT_ICAP_LAST_MATCHED_HEADER_ELEM;
+                    break;
+                case LFT_ICAP_REQ_HEADER:
+                    lt->type = LFT_ICAP_REQ_HEADER_ELEM;
+                    break;
+                case LFT_ICAP_REP_HEADER:
+                    lt->type = LFT_ICAP_REP_HEADER_ELEM;
+                    break;
+#endif
+                default:
+                    break;
+                }
+            }
+
+            lt->data.header.header = header;
+        } else {
+            switch (lt->type) {
+            case LFT_REQUEST_HEADER:
+                lt->type = LFT_REQUEST_ALL_HEADERS;
+                break;
+
+            case LFT_ADAPTED_REQUEST_HEADER:
+                lt->type = LFT_ADAPTED_REQUEST_ALL_HEADERS;
+                break;
+
+            case LFT_REPLY_HEADER:
+                lt->type = LFT_REPLY_ALL_HEADERS;
+                break;
+#if ICAP_CLIENT
+            case LFT_ICAP_LAST_MATCHED_HEADER:
+                lt->type = LFT_ICAP_LAST_MATCHED_ALL_HEADERS;
+                break;
+            case LFT_ICAP_REQ_HEADER:
+                lt->type = LFT_ICAP_REQ_ALL_HEADERS;
+                break;
+            case LFT_ICAP_REP_HEADER:
+                lt->type = LFT_ICAP_REP_ALL_HEADERS;
+                break;
+#endif
+            default:
+                break;
+            }
+            Config.onoff.log_mime_hdrs = 1;
+        }
+
+        break;
+
+    case LFT_CLIENT_FQDN:
+        Config.onoff.log_fqdn = 1;
+        break;
+
+    case LFT_TIME_SUBSECOND:
+        lt->divisor = 1000;
+
+        if (lt->precision) {
+            int i;
+            lt->divisor = 1000000;
+
+            for (i = lt->precision; i > 1; i--)
+                lt->divisor /= 10;
+
+            if (!lt->divisor)
+                lt->divisor = 0;
+        }
+
+        break;
+
+    case LFT_HTTP_SENT_STATUS_CODE_OLD_30:
+        debugs(46, 0, "WARNING: the \"Hs\" formating code is deprecated use the \">Hs\" instead");
+        lt->type = LFT_HTTP_SENT_STATUS_CODE;
+        break;
+    default:
+        break;
+    }
+
+    return (cur - def);
+}
+
+int
+accessLogParseLogFormat(logformat_token ** fmt, char *def)
+{
+    char *cur, *eos;
+    logformat_token *new_lt, *last_lt;
+    enum log_quote quote = LOG_QUOTE_NONE;
+
+    debugs(46, 2, "accessLogParseLogFormat: got definition '" << def << "'");
+
+    /* very inefficent parser, but who cares, this needs to be simple */
+    /* First off, let's tokenize, we'll optimize in a second pass.
+     * A token can either be a %-prefixed sequence (usually a dynamic
+     * token but it can be an escaped sequence), or a string. */
+    cur = def;
+    eos = def + strlen(def);
+    *fmt = new_lt = last_lt = (logformat_token *)xmalloc(sizeof(logformat_token));
+    cur += accessLogGetNewLogFormatToken(new_lt, cur, &quote);
+
+    while (cur < eos) {
+        new_lt = (logformat_token *)xmalloc(sizeof(logformat_token));
+        last_lt->next = new_lt;
+        last_lt = new_lt;
+        cur += accessLogGetNewLogFormatToken(new_lt, cur, &quote);
+    }
+
+    return 1;
+}
+
+void
+accessLogDumpLogFormat(StoreEntry * entry, const char *name, logformat * definitions)
+{
+    logformat_token *t;
+    logformat *format;
+
+    struct logformat_token_table_entry *te;
+    debugs(46, 4, "accessLogDumpLogFormat called");
+
+    for (format = definitions; format; format = format->next) {
+        debugs(46, 3, "Dumping logformat definition for " << format->name);
+        storeAppendPrintf(entry, "logformat %s ", format->name);
+
+        for (t = format->format; t; t = t->next) {
+            if (t->type == LFT_STRING)
+                storeAppendPrintf(entry, "%s", t->data.string);
+            else {
+                char argbuf[256];
+                char *arg = NULL;
+                logformat_bcode_t type = t->type;
+
+                switch (type) {
+                    /* special cases */
+
+                case LFT_STRING:
+                    break;
+#if ICAP_CLIENT
+                case LFT_ICAP_LAST_MATCHED_HEADER_ELEM:
+                case LFT_ICAP_REQ_HEADER_ELEM:
+                case LFT_ICAP_REP_HEADER_ELEM:
+#endif
+                case LFT_REQUEST_HEADER_ELEM:
+                case LFT_ADAPTED_REQUEST_HEADER_ELEM:
+                case LFT_REPLY_HEADER_ELEM:
+
+                    if (t->data.header.separator != ',')
+                        snprintf(argbuf, sizeof(argbuf), "%s:%c%s", t->data.header.header, t->data.header.separator, t->data.header.element);
+                    else
+                        snprintf(argbuf, sizeof(argbuf), "%s:%s", t->data.header.header, t->data.header.element);
+
+                    arg = argbuf;
+
+                    switch (type) {
+                    case LFT_REQUEST_HEADER_ELEM:
+                        type = LFT_REQUEST_HEADER_ELEM;
+                        break;
+                    case LFT_ADAPTED_REQUEST_HEADER_ELEM:
+                        type = LFT_ADAPTED_REQUEST_HEADER_ELEM;
+                        break;
+                    case LFT_REPLY_HEADER_ELEM:
+                        type = LFT_REPLY_HEADER_ELEM;
+                        break;
+#if ICAP_CLIENT
+                    case LFT_ICAP_LAST_MATCHED_HEADER_ELEM:
+                        type = LFT_ICAP_LAST_MATCHED_HEADER;
+                        break;
+                    case LFT_ICAP_REQ_HEADER_ELEM:
+                        type = LFT_ICAP_REQ_HEADER;
+                        break;
+                    case LFT_ICAP_REP_HEADER_ELEM:
+                        type = LFT_ICAP_REP_HEADER;
+                        break;
+#endif
+                    default:
+                        break;
+                    }
+
+                    break;
+
+                case LFT_REQUEST_ALL_HEADERS:
+                case LFT_ADAPTED_REQUEST_ALL_HEADERS:
+                case LFT_REPLY_ALL_HEADERS:
+
+#if ICAP_CLIENT
+                case LFT_ICAP_LAST_MATCHED_ALL_HEADERS:
+                case LFT_ICAP_REQ_ALL_HEADERS:
+                case LFT_ICAP_REP_ALL_HEADERS:
+#endif
+
+                    switch (type) {
+                    case LFT_REQUEST_ALL_HEADERS:
+                        type = LFT_REQUEST_HEADER;
+                        break;
+                    case LFT_ADAPTED_REQUEST_ALL_HEADERS:
+                        type = LFT_ADAPTED_REQUEST_HEADER;
+                        break;
+                    case LFT_REPLY_ALL_HEADERS:
+                        type = LFT_REPLY_HEADER;
+                        break;
+#if ICAP_CLIENT
+                    case LFT_ICAP_LAST_MATCHED_ALL_HEADERS:
+                        type = LFT_ICAP_LAST_MATCHED_HEADER;
+                        break;
+                    case LFT_ICAP_REQ_ALL_HEADERS:
+                        type = LFT_ICAP_REQ_HEADER;
+                        break;
+                    case LFT_ICAP_REP_ALL_HEADERS:
+                        type = LFT_ICAP_REP_HEADER;
+                        break;
+#endif
+                    default:
+                        break;
+                    }
+
+                    break;
+
+                default:
+                    if (t->data.string)
+                        arg = t->data.string;
+
+                    break;
+                }
+
+                entry->append("%", 1);
+
+                switch (t->quote) {
+
+                case LOG_QUOTE_QUOTES:
+                    entry->append("\"", 1);
+                    break;
+
+                case LOG_QUOTE_MIMEBLOB:
+                    entry->append("[", 1);
+                    break;
+
+                case LOG_QUOTE_URL:
+                    entry->append("#", 1);
+                    break;
+
+                case LOG_QUOTE_RAW:
+                    entry->append("'", 1);
+                    break;
+
+                case LOG_QUOTE_NONE:
+                    break;
+                }
+
+                if (t->left)
+                    entry->append("-", 1);
+
+                if (t->zero)
+                    entry->append("0", 1);
+
+                if (t->width)
+                    storeAppendPrintf(entry, "%d", (int) t->width);
+
+                if (t->precision)
+                    storeAppendPrintf(entry, ".%d", (int) t->precision);
+
+                if (arg)
+                    storeAppendPrintf(entry, "{%s}", arg);
+
+                for (te = logformat_token_table; te->config != NULL; te++) {
+                    if (te->token_type == type) {
+                        storeAppendPrintf(entry, "%s", te->config);
+                        break;
+                    }
+                }
+
+                if (t->space)
+                    entry->append(" ", 1);
+
+                assert(te->config != NULL);
+            }
+        }
+
+        entry->append("\n", 1);
+    }
+
+}
+
+void
+accessLogFreeLogFormat(logformat_token ** tokens)
+{
+    while (*tokens) {
+        logformat_token *token = *tokens;
+        *tokens = token->next;
+        safe_free(token->data.string);
+        xfree(token);
+    }
+}
+
+logformat::logformat(const char *n) :
+        format(NULL),
+        next(NULL)
+{
+    name = xstrdup(n);
+}
+
+logformat::~logformat()
+{
+    // erase the list without consuming stack space
+    while (next) {
+        // unlink the next entry for deletion
+        logformat *temp = next;
+        next = temp->next;
+        temp->next = NULL;
+        delete temp;
+    }
+
+    // remove locals
+    xfree(name);
+    accessLogFreeLogFormat(&format);
+}
diff --git a/src/log/Tokens.h b/src/log/Tokens.h
new file mode 100644 (file)
index 0000000..36316d4
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 46    Access Log
+ * 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.
+ *
+ */
+#ifndef _SQUID_LOG_TOKENS_H
+#define _SQUID_LOG_TOKENS_H
+
+class StoreEntry;
+
+#define LOG_BUF_SZ (MAX_URL<<2)
+
+/*
+ * Bytecodes for the configureable logformat stuff
+ */
+typedef enum {
+    LFT_NONE,                  /* dummy */
+    LFT_STRING,
+
+    LFT_CLIENT_IP_ADDRESS,
+    LFT_CLIENT_FQDN,
+    LFT_CLIENT_PORT,
+#if USE_SQUID_EUI
+    LFT_CLIENT_EUI,
+#endif
+
+    /*LFT_SERVER_IP_ADDRESS, */
+    LFT_SERVER_IP_OR_PEER_NAME,
+    /*LFT_SERVER_PORT, */
+
+    LFT_LOCAL_IP,
+    LFT_LOCAL_PORT,
+    /*LFT_LOCAL_NAME, */
+    LFT_PEER_LOCAL_PORT,
+
+    LFT_TIME_SECONDS_SINCE_EPOCH,
+    LFT_TIME_SUBSECOND,
+    LFT_TIME_LOCALTIME,
+    LFT_TIME_GMT,
+    LFT_TIME_TO_HANDLE_REQUEST,
+
+    LFT_PEER_RESPONSE_TIME,
+    LFT_TOTAL_SERVER_SIDE_RESPONSE_TIME,
+    LFT_DNS_WAIT_TIME,
+
+    LFT_REQUEST_HEADER,
+    LFT_REQUEST_HEADER_ELEM,
+    LFT_REQUEST_ALL_HEADERS,
+
+    LFT_ADAPTED_REQUEST_HEADER,
+    LFT_ADAPTED_REQUEST_HEADER_ELEM,
+    LFT_ADAPTED_REQUEST_ALL_HEADERS,
+
+    LFT_REPLY_HEADER,
+    LFT_REPLY_HEADER_ELEM,
+    LFT_REPLY_ALL_HEADERS,
+
+    LFT_USER_NAME,
+    LFT_USER_LOGIN,
+    LFT_USER_IDENT,
+    /*LFT_USER_REALM, */
+    /*LFT_USER_SCHEME, */
+    LFT_USER_EXTERNAL,
+
+    LFT_HTTP_SENT_STATUS_CODE_OLD_30,
+    LFT_HTTP_SENT_STATUS_CODE,
+    LFT_HTTP_RECEIVED_STATUS_CODE,
+    /*LFT_HTTP_STATUS, */
+    LFT_HTTP_BODY_BYTES_READ,
+
+    LFT_SQUID_STATUS,
+    LFT_SQUID_ERROR,
+    LFT_SQUID_ERROR_DETAIL,
+    LFT_SQUID_HIERARCHY,
+
+    LFT_MIME_TYPE,
+
+    LFT_REQUEST_METHOD,
+    LFT_REQUEST_URI,
+    LFT_REQUEST_URLPATH,
+    /*LFT_REQUEST_QUERY, * // * this is not needed. see strip_query_terms */
+    LFT_REQUEST_VERSION,
+
+    LFT_REQUEST_SIZE_TOTAL,
+    /*LFT_REQUEST_SIZE_LINE, */
+    LFT_REQUEST_SIZE_HEADERS,
+    /*LFT_REQUEST_SIZE_BODY, */
+    /*LFT_REQUEST_SIZE_BODY_NO_TE, */
+
+    LFT_REPLY_SIZE_TOTAL,
+    LFT_REPLY_HIGHOFFSET,
+    LFT_REPLY_OBJECTSIZE,
+    /*LFT_REPLY_SIZE_LINE, */
+    LFT_REPLY_SIZE_HEADERS,
+    /*LFT_REPLY_SIZE_BODY, */
+    /*LFT_REPLY_SIZE_BODY_NO_TE, */
+
+    LFT_TAG,
+    LFT_IO_SIZE_TOTAL,
+    LFT_EXT_LOG,
+
+    LFT_SEQUENCE_NUMBER,
+
+#if USE_ADAPTATION
+    LTF_ADAPTATION_SUM_XACT_TIMES,
+    LTF_ADAPTATION_ALL_XACT_TIMES,
+#endif
+
+#if ICAP_CLIENT
+
+    LFT_ICAP_TOTAL_TIME,
+    LFT_ICAP_LAST_MATCHED_HEADER,
+    LFT_ICAP_LAST_MATCHED_HEADER_ELEM,
+    LFT_ICAP_LAST_MATCHED_ALL_HEADERS,
+
+    LFT_ICAP_ADDR,
+    LFT_ICAP_SERV_NAME,
+    LFT_ICAP_REQUEST_URI,
+    LFT_ICAP_REQUEST_METHOD,
+    LFT_ICAP_BYTES_SENT,
+    LFT_ICAP_BYTES_READ,
+    LFT_ICAP_BODY_BYTES_READ,
+
+    LFT_ICAP_REQ_HEADER,
+    LFT_ICAP_REQ_HEADER_ELEM,
+    LFT_ICAP_REQ_ALL_HEADERS,
+
+    LFT_ICAP_REP_HEADER,
+    LFT_ICAP_REP_HEADER_ELEM,
+    LFT_ICAP_REP_ALL_HEADERS,
+
+    LFT_ICAP_TR_RESPONSE_TIME,
+    LFT_ICAP_IO_TIME,
+    LFT_ICAP_OUTCOME,
+    LFT_ICAP_STATUS_CODE,
+#endif
+
+    LFT_PERCENT                        /* special string cases for escaped chars */
+} logformat_bcode_t;
+
+enum log_quote {
+    LOG_QUOTE_NONE = 0,
+    LOG_QUOTE_QUOTES,
+    LOG_QUOTE_MIMEBLOB,
+    LOG_QUOTE_URL,
+    LOG_QUOTE_RAW
+};
+
+/* FIXME: public class so we can pre-define its type. */
+class logformat_token
+{
+public:
+    logformat_bcode_t type;
+    union {
+        char *string;
+
+        struct {
+            char *header;
+            char *element;
+            char separator;
+        } header;
+        char *timespec;
+    } data;
+    unsigned char width;
+    unsigned char precision;
+    enum log_quote quote;
+    unsigned int left:1;
+    unsigned int space:1;
+    unsigned int zero:1;
+    int divisor;
+    logformat_token *next;     /* todo: move from linked list to array */
+};
+
+struct logformat_token_table_entry {
+    const char *config;
+    logformat_bcode_t token_type;
+    int options;
+};
+
+class logformat
+{
+public:
+    logformat(const char *name);
+    ~logformat();
+
+    char *name;
+    logformat_token *format;
+    logformat *next;
+};
+
+extern const char *log_tags[];
+extern struct logformat_token_table_entry logformat_token_table[];
+
+#if USE_ADAPTATION
+extern bool alLogformatHasAdaptToken;
+#endif
+
+#if ICAP_CLIENT
+extern bool alLogformatHasIcapToken;
+#endif
+
+/* parses a single token. Returns the token length in characters,
+ * and fills in the lt item with the token information.
+ * def is for sure null-terminated
+ */
+int accessLogGetNewLogFormatToken(logformat_token * lt, char *def, enum log_quote *quote);
+
+/* very inefficent parser, but who cares, this needs to be simple */
+/* First off, let's tokenize, we'll optimize in a second pass.
+ * A token can either be a %-prefixed sequence (usually a dynamic
+ * token but it can be an escaped sequence), or a string. */
+int accessLogParseLogFormat(logformat_token ** fmt, char *def);
+
+void accessLogDumpLogFormat(StoreEntry * entry, const char *name, logformat * definitions);
+
+void accessLogFreeLogFormat(logformat_token ** tokens);
+
+#endif /* _SQUID_LOG_TOKENS_H */
index da729f6a0baaf3664c472daab05b102dcc3d1bb6..8d73765a392da99f04b2753ddff8c682c4c5fdd8 100644 (file)
 #include "HttpReply.h"
 #include "HttpRequest.h"
 #include "log/File.h"
+#include "log/Formats.h"
+#include "log/Gadgets.h"
+#include "log/Tokens.h"
 #include "MemBuf.h"
 #include "mgr/Registration.h"
 #include "rfc1738.h"
 #include "SquidTime.h"
 
-static void accessLogSquid(AccessLogEntry * al, Logfile * logfile);
-static void accessLogCommon(AccessLogEntry * al, Logfile * logfile);
-static void accessLogCustom(AccessLogEntry * al, customlog * log);
 #if HEADERS_LOG
 static Logfile *headerslog = NULL;
 #endif
@@ -70,1919 +70,25 @@ static struct sockaddr_in mcast_miss_to;
 static void mcast_encode(unsigned int *, size_t, const unsigned int *);
 #endif
 
-const char *log_tags[] = {
-    "NONE",
-    "TCP_HIT",
-    "TCP_MISS",
-    "TCP_REFRESH_UNMODIFIED",
-    "TCP_REFRESH_FAIL", // same tag logged for LOG_TCP_REFRESH_FAIL_OLD and
-    "TCP_REFRESH_FAIL", // LOG_TCP_REFRESH_FAIL_ERR for backward-compatibility
-    "TCP_REFRESH_MODIFIED",
-    "TCP_CLIENT_REFRESH_MISS",
-    "TCP_IMS_HIT",
-    "TCP_SWAPFAIL_MISS",
-    "TCP_NEGATIVE_HIT",
-    "TCP_MEM_HIT",
-    "TCP_DENIED",
-    "TCP_DENIED_REPLY",
-    "TCP_OFFLINE_HIT",
-#if LOG_TCP_REDIRECTS
-    "TCP_REDIRECT",
-#endif
-    "UDP_HIT",
-    "UDP_MISS",
-    "UDP_DENIED",
-    "UDP_INVALID",
-    "UDP_MISS_NOFETCH",
-    "ICP_QUERY",
-    "LOG_TYPE_MAX"
-};
-
-#if USE_FORW_VIA_DB
-
-typedef struct {
-    hash_link hash;
-    int n;
-} fvdb_entry;
-static hash_table *via_table = NULL;
-static hash_table *forw_table = NULL;
-static void fvdbInit();
-static void fvdbDumpTable(StoreEntry * e, hash_table * hash);
-static void fvdbCount(hash_table * hash, const char *key);
-static OBJH fvdbDumpVia;
-static OBJH fvdbDumpForw;
-static FREE fvdbFreeEntry;
-static void fvdbClear(void);
-static void fvdbRegisterWithCacheManager();
-#endif
-
-int LogfileStatus = LOG_DISABLE;
-
-#if USE_ADAPTATION
-bool alLogformatHasAdaptToken = false;
-#endif
-
-#if ICAP_CLIENT
-bool alLogformatHasIcapToken = false;
-#endif
-
-#define LOG_BUF_SZ (MAX_URL<<2)
-
-static const char c2x[] =
-    "000102030405060708090a0b0c0d0e0f"
-    "101112131415161718191a1b1c1d1e1f"
-    "202122232425262728292a2b2c2d2e2f"
-    "303132333435363738393a3b3c3d3e3f"
-    "404142434445464748494a4b4c4d4e4f"
-    "505152535455565758595a5b5c5d5e5f"
-    "606162636465666768696a6b6c6d6e6f"
-    "707172737475767778797a7b7c7d7e7f"
-    "808182838485868788898a8b8c8d8e8f"
-    "909192939495969798999a9b9c9d9e9f"
-    "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
-    "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
-    "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
-    "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
-    "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
-    "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
-
-/* log_quote -- URL-style encoding on MIME headers. */
-
-char *
-log_quote(const char *header)
-{
-    int c;
-    int i;
-    char *buf;
-    char *buf_cursor;
-
-    if (header == NULL) {
-        buf = static_cast<char *>(xcalloc(1, 1));
-        *buf = '\0';
-        return buf;
-    }
-
-    buf = static_cast<char *>(xcalloc(1, (strlen(header) * 3) + 1));
-    buf_cursor = buf;
-    /*
-     * We escape: \x00-\x1F"#%;<>?{}|\\\\^~`\[\]\x7F-\xFF
-     * which is the default escape list for the CPAN Perl5 URI module
-     * modulo the inclusion of space (x40) to make the raw logs a bit
-     * more readable.
-     */
-
-    while ((c = *(const unsigned char *) header++) != '\0') {
-#if !OLD_LOG_MIME
-
-        if (c == '\r') {
-            *buf_cursor++ = '\\';
-            *buf_cursor++ = 'r';
-        } else if (c == '\n') {
-            *buf_cursor++ = '\\';
-            *buf_cursor++ = 'n';
-        } else
-#endif
-            if (c <= 0x1F
-                    || c >= 0x7F
-                    || c == '%'
-#if OLD_LOG_MIME
-                    || c == '"'
-                    || c == '#'
-                    || c == ';'
-                    || c == '<'
-                    || c == '>'
-                    || c == '?'
-                    || c == '{'
-                    || c == '}'
-                    || c == '|'
-                    || c == '\\'
-                    || c == '^'
-                    || c == '~'
-                    || c == '`'
-#endif
-                    || c == '['
-                    || c == ']') {
-                *buf_cursor++ = '%';
-                i = c * 2;
-                *buf_cursor++ = c2x[i];
-                *buf_cursor++ = c2x[i + 1];
-#if !OLD_LOG_MIME
-
-            } else if (c == '\\') {
-                *buf_cursor++ = '\\';
-                *buf_cursor++ = '\\';
-#endif
-
-            } else {
-                *buf_cursor++ = (char) c;
-            }
-    }
-
-    *buf_cursor = '\0';
-    return buf;
-}
-
-static char *
-username_quote(const char *header)
-/* copy of log_quote. Bugs there will be found here */
-{
-    int c;
-    int i;
-    char *buf;
-    char *buf_cursor;
-
-    if (header == NULL) {
-        buf = static_cast<char *>(xcalloc(1, 1));
-        *buf = '\0';
-        return buf;
-    }
-
-    buf = static_cast<char *>(xcalloc(1, (strlen(header) * 3) + 1));
-    buf_cursor = buf;
-    /*
-     * We escape: space \x00-\x1F and space (0x40) and \x7F-\xFF
-     * to prevent garbage in the logs. CR and LF are also there just in case.
-     */
-
-    while ((c = *(const unsigned char *) header++) != '\0') {
-        if (c == '\r') {
-            *buf_cursor++ = '\\';
-            *buf_cursor++ = 'r';
-        } else if (c == '\n') {
-            *buf_cursor++ = '\\';
-            *buf_cursor++ = 'n';
-        } else if (c <= 0x1F
-                   || c >= 0x7F
-                   || c == '%'
-                   || c == ' ') {
-            *buf_cursor++ = '%';
-            i = c * 2;
-            *buf_cursor++ = c2x[i];
-            *buf_cursor++ = c2x[i + 1];
-        } else {
-            *buf_cursor++ = (char) c;
-        }
-    }
-
-    *buf_cursor = '\0';
-    return buf;
-}
-
-static char *
-accessLogFormatName(const char *name)
-{
-    if (NULL == name)
-        return NULL;
-
-    if (name[0] == '\0')
-        return NULL;
-
-    return username_quote(name);
-}
-
-static char *
-log_quoted_string(const char *str)
-{
-    char *out = (char *)xmalloc(strlen(str) * 2 + 1);
-    char *p = out;
-
-    while (*str) {
-        int l = strcspn(str, "\"\\\r\n\t");
-        memcpy(p, str, l);
-        str += l;
-        p += l;
-
-        switch (*str) {
-
-        case '\0':
-            break;
-
-        case '\r':
-            *p++ = '\\';
-            *p++ = 'r';
-            str++;
-            break;
-
-        case '\n':
-            *p++ = '\\';
-            *p++ = 'n';
-            str++;
-            break;
-
-        case '\t':
-            *p++ = '\\';
-            *p++ = 't';
-            str++;
-            break;
-
-        default:
-            *p++ = '\\';
-            *p++ = *str;
-            str++;
-            break;
-        }
-    }
-
-    *p++ = '\0';
-    return out;
-}
-
-/*
- * Bytecodes for the configureable logformat stuff
- */
-typedef enum {
-    LFT_NONE,                  /* dummy */
-    LFT_STRING,
-
-    LFT_CLIENT_IP_ADDRESS,
-    LFT_CLIENT_FQDN,
-    LFT_CLIENT_PORT,
-#if USE_SQUID_EUI
-    LFT_CLIENT_EUI,
-#endif
-
-    /*LFT_SERVER_IP_ADDRESS, */
-    LFT_SERVER_IP_OR_PEER_NAME,
-    /*LFT_SERVER_PORT, */
-
-    LFT_LOCAL_IP,
-    LFT_LOCAL_PORT,
-    /*LFT_LOCAL_NAME, */
-    LFT_PEER_LOCAL_PORT,
-
-    LFT_TIME_SECONDS_SINCE_EPOCH,
-    LFT_TIME_SUBSECOND,
-    LFT_TIME_LOCALTIME,
-    LFT_TIME_GMT,
-    LFT_TIME_TO_HANDLE_REQUEST,
-
-    LFT_PEER_RESPONSE_TIME,
-    LFT_TOTAL_SERVER_SIDE_RESPONSE_TIME,
-    LFT_DNS_WAIT_TIME,
-
-    LFT_REQUEST_HEADER,
-    LFT_REQUEST_HEADER_ELEM,
-    LFT_REQUEST_ALL_HEADERS,
-
-    LFT_ADAPTED_REQUEST_HEADER,
-    LFT_ADAPTED_REQUEST_HEADER_ELEM,
-    LFT_ADAPTED_REQUEST_ALL_HEADERS,
-
-    LFT_REPLY_HEADER,
-    LFT_REPLY_HEADER_ELEM,
-    LFT_REPLY_ALL_HEADERS,
-
-    LFT_USER_NAME,
-    LFT_USER_LOGIN,
-    LFT_USER_IDENT,
-    /*LFT_USER_REALM, */
-    /*LFT_USER_SCHEME, */
-    LFT_USER_EXTERNAL,
-
-    LFT_HTTP_SENT_STATUS_CODE_OLD_30,
-    LFT_HTTP_SENT_STATUS_CODE,
-    LFT_HTTP_RECEIVED_STATUS_CODE,
-    /*LFT_HTTP_STATUS, */
-    LFT_HTTP_BODY_BYTES_READ,
-
-    LFT_SQUID_STATUS,
-    LFT_SQUID_ERROR,
-    LFT_SQUID_ERROR_DETAIL,
-    LFT_SQUID_HIERARCHY,
-
-    LFT_MIME_TYPE,
-
-    LFT_REQUEST_METHOD,
-    LFT_REQUEST_URI,
-    LFT_REQUEST_URLPATH,
-    /*LFT_REQUEST_QUERY, * // * this is not needed. see strip_query_terms */
-    LFT_REQUEST_VERSION,
-
-    LFT_REQUEST_SIZE_TOTAL,
-    /*LFT_REQUEST_SIZE_LINE, */
-    LFT_REQUEST_SIZE_HEADERS,
-    /*LFT_REQUEST_SIZE_BODY, */
-    /*LFT_REQUEST_SIZE_BODY_NO_TE, */
-
-    LFT_REPLY_SIZE_TOTAL,
-    LFT_REPLY_HIGHOFFSET,
-    LFT_REPLY_OBJECTSIZE,
-    /*LFT_REPLY_SIZE_LINE, */
-    LFT_REPLY_SIZE_HEADERS,
-    /*LFT_REPLY_SIZE_BODY, */
-    /*LFT_REPLY_SIZE_BODY_NO_TE, */
-
-    LFT_TAG,
-    LFT_IO_SIZE_TOTAL,
-    LFT_EXT_LOG,
-
-    LFT_SEQUENCE_NUMBER,
-
-#if USE_ADAPTATION
-    LTF_ADAPTATION_SUM_XACT_TIMES,
-    LTF_ADAPTATION_ALL_XACT_TIMES,
-#endif
-
-#if ICAP_CLIENT
-
-    LFT_ICAP_TOTAL_TIME,
-    LFT_ICAP_LAST_MATCHED_HEADER,
-    LFT_ICAP_LAST_MATCHED_HEADER_ELEM,
-    LFT_ICAP_LAST_MATCHED_ALL_HEADERS,
-
-    LFT_ICAP_ADDR,
-    LFT_ICAP_SERV_NAME,
-    LFT_ICAP_REQUEST_URI,
-    LFT_ICAP_REQUEST_METHOD,
-    LFT_ICAP_BYTES_SENT,
-    LFT_ICAP_BYTES_READ,
-    LFT_ICAP_BODY_BYTES_READ,
-
-    LFT_ICAP_REQ_HEADER,
-    LFT_ICAP_REQ_HEADER_ELEM,
-    LFT_ICAP_REQ_ALL_HEADERS,
-
-    LFT_ICAP_REP_HEADER,
-    LFT_ICAP_REP_HEADER_ELEM,
-    LFT_ICAP_REP_ALL_HEADERS,
-
-    LFT_ICAP_TR_RESPONSE_TIME,
-    LFT_ICAP_IO_TIME,
-    LFT_ICAP_OUTCOME,
-    LFT_ICAP_STATUS_CODE,
-#endif
-
-    LFT_PERCENT                        /* special string cases for escaped chars */
-} logformat_bcode_t;
-
-enum log_quote {
-    LOG_QUOTE_NONE = 0,
-    LOG_QUOTE_QUOTES,
-    LOG_QUOTE_BRAKETS,
-    LOG_QUOTE_URL,
-    LOG_QUOTE_RAW
-};
-
-/* FIXME: public class so we can pre-define its type. */
-class logformat_token
-{
-public:
-    logformat_bcode_t type;
-    union {
-        char *string;
-
-        struct {
-            char *header;
-            char *element;
-            char separator;
-        } header;
-        char *timespec;
-    } data;
-    unsigned char width;
-    unsigned char precision;
-    enum log_quote quote;
-    unsigned int left:1;
-    unsigned int space:1;
-    unsigned int zero:1;
-    int divisor;
-    logformat_token *next;     /* todo: move from linked list to array */
-};
-
-struct logformat_token_table_entry {
-    const char *config;
-    logformat_bcode_t token_type;
-    int options;
-};
-
-struct logformat_token_table_entry logformat_token_table[] = {
-
-    {">a", LFT_CLIENT_IP_ADDRESS},
-    {">p", LFT_CLIENT_PORT},
-    {">A", LFT_CLIENT_FQDN},
-#if USE_SQUID_EUI
-    {">eui", LFT_CLIENT_EUI},
-#endif
-
-    /*{ "<a", LFT_SERVER_IP_ADDRESS }, */
-    /*{ "<p", LFT_SERVER_PORT }, */
-    {"<A", LFT_SERVER_IP_OR_PEER_NAME},
-
-    /* {"oa", LFT_OUTGOING_IP}, */
-    /* {"ot", LFT_OUTGOING_TOS}, */
-
-    {"la", LFT_LOCAL_IP},
-    {"lp", LFT_LOCAL_PORT},
-    /*{ "lA", LFT_LOCAL_NAME }, */
-    {"<lp", LFT_PEER_LOCAL_PORT},
-
-    {"ts", LFT_TIME_SECONDS_SINCE_EPOCH},
-    {"tu", LFT_TIME_SUBSECOND},
-    {"tl", LFT_TIME_LOCALTIME},
-    {"tg", LFT_TIME_GMT},
-    {"tr", LFT_TIME_TO_HANDLE_REQUEST},
-
-    {"<pt", LFT_PEER_RESPONSE_TIME},
-    {"<tt", LFT_TOTAL_SERVER_SIDE_RESPONSE_TIME},
-    {"dt", LFT_DNS_WAIT_TIME},
-
-    {">ha", LFT_ADAPTED_REQUEST_HEADER},
-    {">ha", LFT_ADAPTED_REQUEST_ALL_HEADERS},
-    {">h", LFT_REQUEST_HEADER},
-    {">h", LFT_REQUEST_ALL_HEADERS},
-    {"<h", LFT_REPLY_HEADER},
-    {"<h", LFT_REPLY_ALL_HEADERS},
-
-    {"un", LFT_USER_NAME},
-    {"ul", LFT_USER_LOGIN},
-    /*{ "ur", LFT_USER_REALM }, */
-    /*{ "us", LFT_USER_SCHEME }, */
-    {"ui", LFT_USER_IDENT},
-    {"ue", LFT_USER_EXTERNAL},
-
-    {"Hs", LFT_HTTP_SENT_STATUS_CODE_OLD_30},
-    {">Hs", LFT_HTTP_SENT_STATUS_CODE},
-    {"<Hs", LFT_HTTP_RECEIVED_STATUS_CODE},
-    /*{ "Ht", LFT_HTTP_STATUS }, */
-    {"<bs", LFT_HTTP_BODY_BYTES_READ},
-
-    {"Ss", LFT_SQUID_STATUS},
-    { "err_code", LFT_SQUID_ERROR },
-    { "err_detail", LFT_SQUID_ERROR_DETAIL },
-    {"Sh", LFT_SQUID_HIERARCHY},
-
-    {"mt", LFT_MIME_TYPE},
-
-    {"rm", LFT_REQUEST_METHOD},
-    {"ru", LFT_REQUEST_URI},   /* doesn't include the query-string */
-    {"rp", LFT_REQUEST_URLPATH},       /* doesn't include the host */
-    /* { "rq", LFT_REQUEST_QUERY }, * /     / * the query-string, INCLUDING the leading ? */
-    {">v", LFT_REQUEST_VERSION},
-    {"rv", LFT_REQUEST_VERSION},
-
-    { ">st", LFT_REQUEST_SIZE_TOTAL },
-    /*{ ">sl", LFT_REQUEST_SIZE_LINE }, * / / * the request line "GET ... " */
-    { ">sh", LFT_REQUEST_SIZE_HEADERS },
-    /*{ ">sb", LFT_REQUEST_SIZE_BODY }, */
-    /*{ ">sB", LFT_REQUEST_SIZE_BODY_NO_TE }, */
-
-    {"<st", LFT_REPLY_SIZE_TOTAL},
-    {"<sH", LFT_REPLY_HIGHOFFSET},
-    {"<sS", LFT_REPLY_OBJECTSIZE},
-    /*{ "<sl", LFT_REPLY_SIZE_LINE }, * /   / * the reply line (protocol, code, text) */
-    { "<sh", LFT_REPLY_SIZE_HEADERS },
-    /*{ "<sb", LFT_REPLY_SIZE_BODY }, */
-    /*{ "<sB", LFT_REPLY_SIZE_BODY_NO_TE }, */
-
-    {"et", LFT_TAG},
-    {"st", LFT_IO_SIZE_TOTAL},
-    {"ea", LFT_EXT_LOG},
-    {"sn", LFT_SEQUENCE_NUMBER},
-
-    {"%", LFT_PERCENT},
-
-#if USE_ADAPTATION
-    {"adapt::all_trs", LTF_ADAPTATION_ALL_XACT_TIMES},
-    {"adapt::sum_trs", LTF_ADAPTATION_SUM_XACT_TIMES},
-#endif
-
-#if ICAP_CLIENT
-    {"icap::tt", LFT_ICAP_TOTAL_TIME},
-    {"icap::<last_h", LFT_ICAP_LAST_MATCHED_HEADER},
-
-    {"icap::<A",  LFT_ICAP_ADDR},
-    {"icap::<service_name",  LFT_ICAP_SERV_NAME},
-    {"icap::ru",  LFT_ICAP_REQUEST_URI},
-    {"icap::rm",  LFT_ICAP_REQUEST_METHOD},
-    {"icap::>st",  LFT_ICAP_BYTES_SENT},
-    {"icap::<st",  LFT_ICAP_BYTES_READ},
-    {"icap::<bs", LFT_ICAP_BODY_BYTES_READ},
-
-    {"icap::>h",  LFT_ICAP_REQ_HEADER},
-    {"icap::<h",  LFT_ICAP_REP_HEADER},
-
-    {"icap::tr",  LFT_ICAP_TR_RESPONSE_TIME},
-    {"icap::tio",  LFT_ICAP_IO_TIME},
-    {"icap::to",  LFT_ICAP_OUTCOME},
-    {"icap::Hs",  LFT_ICAP_STATUS_CODE},
-#endif
-
-    {NULL, LFT_NONE}           /* this must be last */
-};
-
-static void
-accessLogCustom(AccessLogEntry * al, customlog * log)
-{
-    logformat *lf;
-    Logfile *logfile;
-    logformat_token *fmt;
-    static MemBuf mb;
-    char tmp[1024];
-    String sb;
-
-    mb.reset();
-
-    lf = log->logFormat;
-    logfile = log->logfile;
-
-    for (fmt = lf->format; fmt != NULL; fmt = fmt->next) {     /* for each token */
-        const char *out = NULL;
-        int quote = 0;
-        long int outint = 0;
-        int doint = 0;
-        int dofree = 0;
-        int64_t outoff = 0;
-        int dooff = 0;
-
-        switch (fmt->type) {
-
-        case LFT_NONE:
-            out = "";
-            break;
-
-        case LFT_STRING:
-            out = fmt->data.string;
-            break;
-
-        case LFT_CLIENT_IP_ADDRESS:
-            if (al->cache.caddr.IsNoAddr()) // e.g., ICAP OPTIONS lack client
-                out = "-";
-            else
-                out = al->cache.caddr.NtoA(tmp,1024);
-            break;
-
-        case LFT_CLIENT_FQDN:
-            if (al->cache.caddr.IsAnyAddr()) // e.g., ICAP OPTIONS lack client
-                out = "-";
-            else
-                out = fqdncache_gethostbyaddr(al->cache.caddr, FQDN_LOOKUP_IF_MISS);
-            if (!out) {
-                out = al->cache.caddr.NtoA(tmp,1024);
-            }
-
-            break;
-
-        case LFT_CLIENT_PORT:
-            if (al->request) {
-                outint = al->request->client_addr.GetPort();
-                doint = 1;
-            }
-            break;
-
-#if USE_SQUID_EUI
-        case LFT_CLIENT_EUI:
-            if (al->request) {
-                if (al->cache.caddr.IsIPv4())
-                    al->request->client_eui48.encode(tmp, 1024);
-                else
-                    al->request->client_eui64.encode(tmp, 1024);
-                out = tmp;
-            }
-            break;
-#endif
-
-            /* case LFT_SERVER_IP_ADDRESS: */
-
-        case LFT_SERVER_IP_OR_PEER_NAME:
-            out = al->hier.host;
-
-            break;
-
-            /* case LFT_SERVER_PORT: */
-
-        case LFT_LOCAL_IP:
-            if (al->request) {
-                out = al->request->my_addr.NtoA(tmp,1024);
-            }
-
-            break;
-
-        case LFT_LOCAL_PORT:
-            if (al->request) {
-                outint = al->request->my_addr.GetPort();
-                doint = 1;
-            }
-
-            break;
-
-        case LFT_PEER_LOCAL_PORT:
-            if (al->hier.peer_local_port) {
-                outint = al->hier.peer_local_port;
-                doint = 1;
-            }
-
-            break;
-
-        case LFT_TIME_SECONDS_SINCE_EPOCH:
-            // some platforms store time in 32-bit, some 64-bit...
-            outoff = static_cast<int64_t>(current_time.tv_sec);
-            dooff = 1;
-            break;
-
-        case LFT_TIME_SUBSECOND:
-            outint = current_time.tv_usec / fmt->divisor;
-            doint = 1;
-            break;
-
-
-        case LFT_TIME_LOCALTIME:
-
-        case LFT_TIME_GMT: {
-            const char *spec;
-
-            struct tm *t;
-            spec = fmt->data.timespec;
-
-            if (fmt->type == LFT_TIME_LOCALTIME) {
-                if (!spec)
-                    spec = "%d/%b/%Y:%H:%M:%S %z";
-                t = localtime(&squid_curtime);
-            } else {
-                if (!spec)
-                    spec = "%d/%b/%Y:%H:%M:%S";
-
-                t = gmtime(&squid_curtime);
-            }
-
-            strftime(tmp, sizeof(tmp), spec, t);
-
-            out = tmp;
-        }
-
-        break;
-
-        case LFT_TIME_TO_HANDLE_REQUEST:
-            outint = al->cache.msec;
-            doint = 1;
-            break;
-
-        case LFT_PEER_RESPONSE_TIME:
-            if (al->hier.peer_response_time < 0) {
-                out = "-";
-            } else {
-                outoff = al->hier.peer_response_time;
-                dooff = 1;
-            }
-            break;
-
-        case LFT_TOTAL_SERVER_SIDE_RESPONSE_TIME:
-            if (al->hier.total_response_time < 0) {
-                out = "-";
-            } else {
-                outoff = al->hier.total_response_time;
-                dooff = 1;
-            }
-            break;
-
-        case LFT_DNS_WAIT_TIME:
-            if (al->request && al->request->dnsWait >= 0) {
-                outint = al->request->dnsWait;
-                doint = 1;
-            }
-            break;
-
-        case LFT_REQUEST_HEADER:
-
-            if (al->request)
-                sb = al->request->header.getByName(fmt->data.header.header);
-
-            out = sb.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_ADAPTED_REQUEST_HEADER:
-
-            if (al->request)
-                sb = al->adapted_request->header.getByName(fmt->data.header.header);
-
-            out = sb.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_REPLY_HEADER:
-            if (al->reply)
-                sb = al->reply->header.getByName(fmt->data.header.header);
-
-            out = sb.termedBuf();
-
-            quote = 1;
-
-            break;
-
-#if USE_ADAPTATION
-        case LTF_ADAPTATION_SUM_XACT_TIMES:
-            if (al->request) {
-                Adaptation::History::Pointer ah = al->request->adaptHistory();
-                if (ah != NULL)
-                    ah->sumLogString(fmt->data.string, sb);
-                out = sb.termedBuf();
-            }
-            break;
-
-        case LTF_ADAPTATION_ALL_XACT_TIMES:
-            if (al->request) {
-                Adaptation::History::Pointer ah = al->request->adaptHistory();
-                if (ah != NULL)
-                    ah->allLogString(fmt->data.string, sb);
-                out = sb.termedBuf();
-            }
-            break;
-#endif
-
-#if ICAP_CLIENT
-        case LFT_ICAP_LAST_MATCHED_HEADER:
-            if (al->request) {
-                Adaptation::Icap::History::Pointer ih = al->request->icapHistory();
-                if (ih != NULL)
-                    sb = ih->mergeOfIcapHeaders.getByName(fmt->data.header.header);
-            }
-
-            out = sb.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_ICAP_LAST_MATCHED_HEADER_ELEM:
-            if (al->request) {
-                Adaptation::Icap::History::Pointer ih = al->request->icapHistory();
-                if (ih != NULL)
-                    sb = ih->mergeOfIcapHeaders.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
-            }
-
-            out = sb.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_ICAP_LAST_MATCHED_ALL_HEADERS:
-            out = al->headers.icap;
-
-            quote = 1;
-
-            break;
-
-        case LFT_ICAP_ADDR:
-            if (!out)
-                out = al->icap.hostAddr.NtoA(tmp,1024);
-            break;
-
-        case LFT_ICAP_SERV_NAME:
-            out = al->icap.serviceName.termedBuf();
-            break;
-
-        case LFT_ICAP_REQUEST_URI:
-            out = al->icap.reqUri.termedBuf();
-            break;
-
-        case LFT_ICAP_REQUEST_METHOD:
-            out = Adaptation::Icap::ICAP::methodStr(al->icap.reqMethod);
-            break;
-
-        case LFT_ICAP_BYTES_SENT:
-            outoff = al->icap.bytesSent;
-            dooff = 1;
-            break;
-
-        case LFT_ICAP_BYTES_READ:
-            outoff = al->icap.bytesRead;
-            dooff = 1;
-            break;
-
-        case LFT_ICAP_BODY_BYTES_READ:
-            if (al->icap.bodyBytesRead >= 0) {
-                outoff = al->icap.bodyBytesRead;
-                dooff = 1;
-            }
-            // else if icap.bodyBytesRead < 0, we do not have any http data,
-            // so just print a "-" (204 responses etc)
-            break;
-
-        case LFT_ICAP_REQ_HEADER:
-            if (NULL != al->icap.request) {
-                sb = al->icap.request->header.getByName(fmt->data.header.header);
-                out = sb.termedBuf();
-                quote = 1;
-            }
-            break;
-
-        case LFT_ICAP_REQ_HEADER_ELEM:
-            if (al->request)
-                sb = al->icap.request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
-
-            out = sb.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_ICAP_REQ_ALL_HEADERS:
-            if (al->icap.request) {
-                HttpHeaderPos pos = HttpHeaderInitPos;
-                while (const HttpHeaderEntry *e = al->icap.request->header.getEntry(&pos)) {
-                    sb.append(e->name);
-                    sb.append(": ");
-                    sb.append(e->value);
-                    sb.append("\r\n");
-                }
-                out = sb.termedBuf();
-                quote = 1;
-            }
-            break;
-
-        case LFT_ICAP_REP_HEADER:
-            if (NULL != al->icap.reply) {
-                sb = al->icap.reply->header.getByName(fmt->data.header.header);
-                out = sb.termedBuf();
-                quote = 1;
-            }
-            break;
-
-        case LFT_ICAP_REP_HEADER_ELEM:
-            if (NULL != al->icap.reply)
-                sb = al->icap.reply->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
-
-            out = sb.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_ICAP_REP_ALL_HEADERS:
-            if (al->icap.reply) {
-                HttpHeaderPos pos = HttpHeaderInitPos;
-                while (const HttpHeaderEntry *e = al->icap.reply->header.getEntry(&pos)) {
-                    sb.append(e->name);
-                    sb.append(": ");
-                    sb.append(e->value);
-                    sb.append("\r\n");
-                }
-                out = sb.termedBuf();
-                quote = 1;
-            }
-            break;
-
-        case LFT_ICAP_TR_RESPONSE_TIME:
-            outint = al->icap.trTime;
-            doint = 1;
-            break;
-
-        case LFT_ICAP_IO_TIME:
-            outint = al->icap.ioTime;
-            doint = 1;
-            break;
-
-        case LFT_ICAP_STATUS_CODE:
-            outint = al->icap.resStatus;
-            doint  = 1;
-            break;
-
-        case LFT_ICAP_OUTCOME:
-            out = al->icap.outcome;
-            break;
-
-        case LFT_ICAP_TOTAL_TIME:
-            outint = al->icap.processingTime;
-            doint = 1;
-            break;
-#endif
-        case LFT_REQUEST_HEADER_ELEM:
-            if (al->request)
-                sb = al->request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
-
-            out = sb.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_ADAPTED_REQUEST_HEADER_ELEM:
-            if (al->adapted_request)
-                sb = al->adapted_request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
-
-            out = sb.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_REPLY_HEADER_ELEM:
-            if (al->reply)
-                sb = al->reply->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
-
-            out = sb.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_REQUEST_ALL_HEADERS:
-            out = al->headers.request;
-
-            quote = 1;
-
-            break;
-
-        case LFT_ADAPTED_REQUEST_ALL_HEADERS:
-            out = al->headers.adapted_request;
-
-            quote = 1;
-
-            break;
-
-        case LFT_REPLY_ALL_HEADERS:
-            out = al->headers.reply;
-
-            quote = 1;
-
-            break;
-
-        case LFT_USER_NAME:
-            out = accessLogFormatName(al->cache.authuser);
-
-            if (!out)
-                out = accessLogFormatName(al->cache.extuser);
-
-#if USE_SSL
-
-            if (!out)
-                out = accessLogFormatName(al->cache.ssluser);
-
-#endif
-
-            if (!out)
-                out = accessLogFormatName(al->cache.rfc931);
-
-            dofree = 1;
-
-            break;
-
-        case LFT_USER_LOGIN:
-            out = accessLogFormatName(al->cache.authuser);
-
-            dofree = 1;
-
-            break;
-
-        case LFT_USER_IDENT:
-            out = accessLogFormatName(al->cache.rfc931);
-
-            dofree = 1;
-
-            break;
-
-        case LFT_USER_EXTERNAL:
-            out = accessLogFormatName(al->cache.extuser);
-
-            dofree = 1;
-
-            break;
-
-            /* case LFT_USER_REALM: */
-            /* case LFT_USER_SCHEME: */
-
-            // the fmt->type can not be LFT_HTTP_SENT_STATUS_CODE_OLD_30
-            // but compiler complains if ommited
-        case LFT_HTTP_SENT_STATUS_CODE_OLD_30:
-        case LFT_HTTP_SENT_STATUS_CODE:
-            outint = al->http.code;
-
-            doint = 1;
-
-            break;
-
-        case LFT_HTTP_RECEIVED_STATUS_CODE:
-            if (al->hier.peer_reply_status == HTTP_STATUS_NONE) {
-                out = "-";
-            } else {
-                outint = al->hier.peer_reply_status;
-                doint = 1;
-            }
-            break;
-            /* case LFT_HTTP_STATUS:
-             *           out = statusline->text;
-             *     quote = 1;
-             *     break;
-             */
-        case LFT_HTTP_BODY_BYTES_READ:
-            if (al->hier.bodyBytesRead >= 0) {
-                outoff = al->hier.bodyBytesRead;
-                dooff = 1;
-            }
-            // else if hier.bodyBytesRead < 0 we did not have any data exchange with
-            // a peer server so just print a "-" (eg requests served from cache,
-            // or internal error messages).
-            break;
-
-        case LFT_SQUID_STATUS:
-            if (al->http.timedout || al->http.aborted) {
-                snprintf(tmp, sizeof(tmp), "%s%s", log_tags[al->cache.code],
-                         al->http.statusSfx());
-                out = tmp;
-            } else {
-                out = log_tags[al->cache.code];
-            }
-
-            break;
-
-        case LFT_SQUID_ERROR:
-            if (al->request && al->request->errType != ERR_NONE)
-                out = errorPageName(al->request->errType);
-            break;
-
-        case LFT_SQUID_ERROR_DETAIL:
-            if (al->request && al->request->errDetail != ERR_DETAIL_NONE) {
-                if (al->request->errDetail > ERR_DETAIL_START  &&
-                        al->request->errDetail < ERR_DETAIL_MAX)
-                    out = errorDetailName(al->request->errDetail);
-                else {
-                    if (al->request->errDetail >= ERR_DETAIL_EXCEPTION_START)
-                        snprintf(tmp, sizeof(tmp), "%s=0x%X",
-                                 errorDetailName(al->request->errDetail), (uint32_t) al->request->errDetail);
-                    else
-                        snprintf(tmp, sizeof(tmp), "%s=%d",
-                                 errorDetailName(al->request->errDetail), al->request->errDetail);
-                    out = tmp;
-                }
-            }
-            break;
-
-        case LFT_SQUID_HIERARCHY:
-            if (al->hier.ping.timedout)
-                mb.append("TIMEOUT_", 8);
-
-            out = hier_code_str[al->hier.code];
-
-            break;
-
-        case LFT_MIME_TYPE:
-            out = al->http.content_type;
-
-            break;
-
-        case LFT_REQUEST_METHOD:
-            out = al->_private.method_str;
-
-            break;
-
-        case LFT_REQUEST_URI:
-            out = al->url;
-
-            break;
-
-        case LFT_REQUEST_URLPATH:
-            if (al->request) {
-                out = al->request->urlpath.termedBuf();
-                quote = 1;
-            }
-            break;
-
-        case LFT_REQUEST_VERSION:
-            snprintf(tmp, sizeof(tmp), "%d.%d", (int) al->http.version.major, (int) al->http.version.minor);
-            out = tmp;
-            break;
-
-        case LFT_REQUEST_SIZE_TOTAL:
-            outoff = al->cache.requestSize;
-            dooff = 1;
-            break;
-
-            /*case LFT_REQUEST_SIZE_LINE: */
-        case LFT_REQUEST_SIZE_HEADERS:
-            outoff = al->cache.requestHeadersSize;
-            dooff =1;
-            break;
-            /*case LFT_REQUEST_SIZE_BODY: */
-            /*case LFT_REQUEST_SIZE_BODY_NO_TE: */
-
-        case LFT_REPLY_SIZE_TOTAL:
-            outoff = al->cache.replySize;
-            dooff = 1;
-            break;
-
-        case LFT_REPLY_HIGHOFFSET:
-            outoff = al->cache.highOffset;
-
-            dooff = 1;
-
-            break;
-
-        case LFT_REPLY_OBJECTSIZE:
-            outoff = al->cache.objectSize;
-
-            dooff = 1;
-
-            break;
-
-            /*case LFT_REPLY_SIZE_LINE: */
-        case LFT_REPLY_SIZE_HEADERS:
-            outint = al->cache.replyHeadersSize;
-            doint = 1;
-            break;
-            /*case LFT_REPLY_SIZE_BODY: */
-            /*case LFT_REPLY_SIZE_BODY_NO_TE: */
-
-        case LFT_TAG:
-            if (al->request)
-                out = al->request->tag.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_IO_SIZE_TOTAL:
-            outint = al->cache.requestSize + al->cache.replySize;
-            doint = 1;
-            break;
-
-        case LFT_EXT_LOG:
-            if (al->request)
-                out = al->request->extacl_log.termedBuf();
-
-            quote = 1;
-
-            break;
-
-        case LFT_SEQUENCE_NUMBER:
-            outoff = logfile->sequence_number;
-            dooff = 1;
-            break;
-
-        case LFT_PERCENT:
-            out = "%";
-
-            break;
-        }
-
-        if (dooff) {
-            snprintf(tmp, sizeof(tmp), "%0*" PRId64, fmt->zero ? (int) fmt->width : 0, outoff);
-            out = tmp;
-
-        } else if (doint) {
-            snprintf(tmp, sizeof(tmp), "%0*ld", fmt->zero ? (int) fmt->width : 0, outint);
-            out = tmp;
-        }
-
-        if (out && *out) {
-            if (quote || fmt->quote != LOG_QUOTE_NONE) {
-                char *newout = NULL;
-                int newfree = 0;
-
-                switch (fmt->quote) {
-
-                case LOG_QUOTE_NONE:
-                    newout = rfc1738_escape_unescaped(out);
-                    break;
-
-                case LOG_QUOTE_QUOTES:
-                    newout = log_quoted_string(out);
-                    newfree = 1;
-                    break;
-
-                case LOG_QUOTE_BRAKETS:
-                    newout = log_quote(out);
-                    newfree = 1;
-                    break;
-
-                case LOG_QUOTE_URL:
-                    newout = rfc1738_escape(out);
-                    break;
-
-                case LOG_QUOTE_RAW:
-                    break;
-                }
-
-                if (newout) {
-                    if (dofree)
-                        safe_free(out);
-
-                    out = newout;
-
-                    dofree = newfree;
-                }
-            }
-
-            if (fmt->width) {
-                if (fmt->left)
-                    mb.Printf("%-*s", (int) fmt->width, out);
-                else
-                    mb.Printf("%*s", (int) fmt->width, out);
-            } else
-                mb.append(out, strlen(out));
-        } else {
-            mb.append("-", 1);
-        }
-
-        if (fmt->space)
-            mb.append(" ", 1);
-
-        sb.clean();
-
-        if (dofree)
-            safe_free(out);
-    }
-
-    logfilePrintf(logfile, "%s\n", mb.buf);
-}
-
-/* parses a single token. Returns the token length in characters,
- * and fills in the lt item with the token information.
- * def is for sure null-terminated
- */
-static int
-accessLogGetNewLogFormatToken(logformat_token * lt, char *def, enum log_quote *quote)
-{
-    char *cur = def;
-
-    struct logformat_token_table_entry *lte;
-    int l;
-
-    memset(lt, 0, sizeof(*lt));
-    l = strcspn(cur, "%");
-
-    if (l > 0) {
-        char *cp;
-        /* it's a string for sure, until \0 or the next % */
-        cp = (char *)xmalloc(l + 1);
-        xstrncpy(cp, cur, l + 1);
-        lt->type = LFT_STRING;
-        lt->data.string = cp;
-
-        while (l > 0) {
-            switch (*cur) {
-
-            case '"':
-
-                if (*quote == LOG_QUOTE_NONE)
-                    *quote = LOG_QUOTE_QUOTES;
-                else if (*quote == LOG_QUOTE_QUOTES)
-                    *quote = LOG_QUOTE_NONE;
-
-                break;
-
-            case '[':
-                if (*quote == LOG_QUOTE_NONE)
-                    *quote = LOG_QUOTE_BRAKETS;
-
-                break;
-
-            case ']':
-                if (*quote == LOG_QUOTE_BRAKETS)
-                    *quote = LOG_QUOTE_NONE;
-
-                break;
-            }
-
-            cur++;
-            l--;
-        }
-
-        goto done;
-    }
-
-    if (!*cur)
-        goto done;
-
-    cur++;
-
-    switch (*cur) {
-
-    case '"':
-        lt->quote = LOG_QUOTE_QUOTES;
-        cur++;
-        break;
-
-    case '\'':
-        lt->quote = LOG_QUOTE_RAW;
-        cur++;
-        break;
-
-    case '[':
-        lt->quote = LOG_QUOTE_BRAKETS;
-        cur++;
-        break;
-
-    case '#':
-        lt->quote = LOG_QUOTE_URL;
-        cur++;
-        break;
-
-    default:
-        lt->quote = *quote;
-        break;
-    }
-
-    if (*cur == '-') {
-        lt->left = 1;
-        cur++;
-    }
-
-    if (*cur == '0') {
-        lt->zero = 1;
-        cur++;
-    }
-
-    if (xisdigit(*cur))
-        lt->width = strtol(cur, &cur, 10);
-
-    if (*cur == '.')
-        lt->precision = strtol(cur + 1, &cur, 10);
-
-    if (*cur == '{') {
-        char *cp;
-        cur++;
-        l = strcspn(cur, "}");
-        cp = (char *)xmalloc(l + 1);
-        xstrncpy(cp, cur, l + 1);
-        lt->data.string = cp;
-        cur += l;
-
-        if (*cur == '}')
-            cur++;
-    }
-
-    // For upward compatibility, assume "http::" prefix as default prefix
-    // for all log access formating codes, except those starting
-    // from "icap::", "adapt::" and "%"
-    if (strncmp(cur,"http::", 6) == 0 &&
-            strncmp(cur+6, "icap::", 6) != 0  &&
-            strncmp(cur+6, "adapt::", 12) != 0 && *(cur+6) != '%' ) {
-        cur += 6;
-    }
-
-    lt->type = LFT_NONE;
-
-    for (lte = logformat_token_table; lte->config != NULL; lte++) {
-        if (strncmp(lte->config, cur, strlen(lte->config)) == 0) {
-            lt->type = lte->token_type;
-            cur += strlen(lte->config);
-            break;
-        }
-    }
-
-    if (lt->type == LFT_NONE) {
-        fatalf("Can't parse configuration token: '%s'\n",
-               def);
-    }
-
-    if (*cur == ' ') {
-        lt->space = 1;
-        cur++;
-    }
-
-done:
-
-    switch (lt->type) {
-
-#if ICAP_CLIENT
-    case LFT_ICAP_LAST_MATCHED_HEADER:
-
-    case LFT_ICAP_REQ_HEADER:
-
-    case LFT_ICAP_REP_HEADER:
-#endif
-
-    case LFT_ADAPTED_REQUEST_HEADER:
-
-    case LFT_REQUEST_HEADER:
-
-    case LFT_REPLY_HEADER:
-
-        if (lt->data.string) {
-            char *header = lt->data.string;
-            char *cp = strchr(header, ':');
-
-            if (cp) {
-                *cp++ = '\0';
-
-                if (*cp == ',' || *cp == ';' || *cp == ':')
-                    lt->data.header.separator = *cp++;
-                else
-                    lt->data.header.separator = ',';
-
-                lt->data.header.element = cp;
-
-                switch (lt->type) {
-                case LFT_REQUEST_HEADER:
-                    lt->type = LFT_REQUEST_HEADER_ELEM;
-                    break;
-
-                case LFT_ADAPTED_REQUEST_HEADER:
-                    lt->type = LFT_ADAPTED_REQUEST_HEADER_ELEM;
-                    break;
-
-                case LFT_REPLY_HEADER:
-                    lt->type = LFT_REPLY_HEADER_ELEM;
-                    break;
-#if ICAP_CLIENT
-                case LFT_ICAP_LAST_MATCHED_HEADER:
-                    lt->type = LFT_ICAP_LAST_MATCHED_HEADER_ELEM;
-                    break;
-                case LFT_ICAP_REQ_HEADER:
-                    lt->type = LFT_ICAP_REQ_HEADER_ELEM;
-                    break;
-                case LFT_ICAP_REP_HEADER:
-                    lt->type = LFT_ICAP_REP_HEADER_ELEM;
-                    break;
-#endif
-                default:
-                    break;
-                }
-            }
-
-            lt->data.header.header = header;
-        } else {
-            switch (lt->type) {
-            case LFT_REQUEST_HEADER:
-                lt->type = LFT_REQUEST_ALL_HEADERS;
-                break;
-
-            case LFT_ADAPTED_REQUEST_HEADER:
-                lt->type = LFT_ADAPTED_REQUEST_ALL_HEADERS;
-                break;
-
-            case LFT_REPLY_HEADER:
-                lt->type = LFT_REPLY_ALL_HEADERS;
-                break;
-#if ICAP_CLIENT
-            case LFT_ICAP_LAST_MATCHED_HEADER:
-                lt->type = LFT_ICAP_LAST_MATCHED_ALL_HEADERS;
-                break;
-            case LFT_ICAP_REQ_HEADER:
-                lt->type = LFT_ICAP_REQ_ALL_HEADERS;
-                break;
-            case LFT_ICAP_REP_HEADER:
-                lt->type = LFT_ICAP_REP_ALL_HEADERS;
-                break;
-#endif
-            default:
-                break;
-            }
-            Config.onoff.log_mime_hdrs = 1;
-        }
-
-        break;
-
-    case LFT_CLIENT_FQDN:
-        Config.onoff.log_fqdn = 1;
-        break;
-
-    case LFT_TIME_SUBSECOND:
-        lt->divisor = 1000;
-
-        if (lt->precision) {
-            int i;
-            lt->divisor = 1000000;
-
-            for (i = lt->precision; i > 1; i--)
-                lt->divisor /= 10;
-
-            if (!lt->divisor)
-                lt->divisor = 0;
-        }
-
-        break;
-
-    case LFT_HTTP_SENT_STATUS_CODE_OLD_30:
-        debugs(46, 0, "WARNING: the \"Hs\" formating code is deprecated use the \">Hs\" instead");
-        lt->type = LFT_HTTP_SENT_STATUS_CODE;
-        break;
-    default:
-        break;
-    }
-
-    return (cur - def);
-}
-
-int
-accessLogParseLogFormat(logformat_token ** fmt, char *def)
-{
-    char *cur, *eos;
-    logformat_token *new_lt, *last_lt;
-    enum log_quote quote = LOG_QUOTE_NONE;
-
-    debugs(46, 2, "accessLogParseLogFormat: got definition '" << def << "'");
-
-    /* very inefficent parser, but who cares, this needs to be simple */
-    /* First off, let's tokenize, we'll optimize in a second pass.
-     * A token can either be a %-prefixed sequence (usually a dynamic
-     * token but it can be an escaped sequence), or a string. */
-    cur = def;
-    eos = def + strlen(def);
-    *fmt = new_lt = last_lt = (logformat_token *)xmalloc(sizeof(logformat_token));
-    cur += accessLogGetNewLogFormatToken(new_lt, cur, &quote);
-
-    while (cur < eos) {
-        new_lt = (logformat_token *)xmalloc(sizeof(logformat_token));
-        last_lt->next = new_lt;
-        last_lt = new_lt;
-        cur += accessLogGetNewLogFormatToken(new_lt, cur, &quote);
-    }
-
-    return 1;
-}
-
-void
-accessLogDumpLogFormat(StoreEntry * entry, const char *name, logformat * definitions)
-{
-    logformat_token *t;
-    logformat *format;
-
-    struct logformat_token_table_entry *te;
-    debugs(46, 4, "accessLogDumpLogFormat called");
-
-    for (format = definitions; format; format = format->next) {
-        debugs(46, 3, "Dumping logformat definition for " << format->name);
-        storeAppendPrintf(entry, "logformat %s ", format->name);
-
-        for (t = format->format; t; t = t->next) {
-            if (t->type == LFT_STRING)
-                storeAppendPrintf(entry, "%s", t->data.string);
-            else {
-                char argbuf[256];
-                char *arg = NULL;
-                logformat_bcode_t type = t->type;
-
-                switch (type) {
-                    /* special cases */
-
-                case LFT_STRING:
-                    break;
-#if ICAP_CLIENT
-                case LFT_ICAP_LAST_MATCHED_HEADER_ELEM:
-                case LFT_ICAP_REQ_HEADER_ELEM:
-                case LFT_ICAP_REP_HEADER_ELEM:
-#endif
-                case LFT_REQUEST_HEADER_ELEM:
-                case LFT_ADAPTED_REQUEST_HEADER_ELEM:
-                case LFT_REPLY_HEADER_ELEM:
-
-                    if (t->data.header.separator != ',')
-                        snprintf(argbuf, sizeof(argbuf), "%s:%c%s", t->data.header.header, t->data.header.separator, t->data.header.element);
-                    else
-                        snprintf(argbuf, sizeof(argbuf), "%s:%s", t->data.header.header, t->data.header.element);
-
-                    arg = argbuf;
-
-                    switch (type) {
-                    case LFT_REQUEST_HEADER_ELEM:
-                        type = LFT_REQUEST_HEADER_ELEM;
-                        break;
-                    case LFT_ADAPTED_REQUEST_HEADER_ELEM:
-                        type = LFT_ADAPTED_REQUEST_HEADER_ELEM;
-                        break;
-                    case LFT_REPLY_HEADER_ELEM:
-                        type = LFT_REPLY_HEADER_ELEM;
-                        break;
-#if ICAP_CLIENT
-                    case LFT_ICAP_LAST_MATCHED_HEADER_ELEM:
-                        type = LFT_ICAP_LAST_MATCHED_HEADER;
-                        break;
-                    case LFT_ICAP_REQ_HEADER_ELEM:
-                        type = LFT_ICAP_REQ_HEADER;
-                        break;
-                    case LFT_ICAP_REP_HEADER_ELEM:
-                        type = LFT_ICAP_REP_HEADER;
-                        break;
-#endif
-                    default:
-                        break;
-                    }
-
-                    break;
-
-                case LFT_REQUEST_ALL_HEADERS:
-                case LFT_ADAPTED_REQUEST_ALL_HEADERS:
-                case LFT_REPLY_ALL_HEADERS:
-
-#if ICAP_CLIENT
-                case LFT_ICAP_LAST_MATCHED_ALL_HEADERS:
-                case LFT_ICAP_REQ_ALL_HEADERS:
-                case LFT_ICAP_REP_ALL_HEADERS:
-#endif
-
-                    switch (type) {
-                    case LFT_REQUEST_ALL_HEADERS:
-                        type = LFT_REQUEST_HEADER;
-                        break;
-                    case LFT_ADAPTED_REQUEST_ALL_HEADERS:
-                        type = LFT_ADAPTED_REQUEST_HEADER;
-                        break;
-                    case LFT_REPLY_ALL_HEADERS:
-                        type = LFT_REPLY_HEADER;
-                        break;
-#if ICAP_CLIENT
-                    case LFT_ICAP_LAST_MATCHED_ALL_HEADERS:
-                        type = LFT_ICAP_LAST_MATCHED_HEADER;
-                        break;
-                    case LFT_ICAP_REQ_ALL_HEADERS:
-                        type = LFT_ICAP_REQ_HEADER;
-                        break;
-                    case LFT_ICAP_REP_ALL_HEADERS:
-                        type = LFT_ICAP_REP_HEADER;
-                        break;
-#endif
-                    default:
-                        break;
-                    }
-
-                    break;
-
-                default:
-                    if (t->data.string)
-                        arg = t->data.string;
-
-                    break;
-                }
-
-                entry->append("%", 1);
-
-                switch (t->quote) {
-
-                case LOG_QUOTE_QUOTES:
-                    entry->append("\"", 1);
-                    break;
-
-                case LOG_QUOTE_BRAKETS:
-                    entry->append("[", 1);
-                    break;
-
-                case LOG_QUOTE_URL:
-                    entry->append("#", 1);
-                    break;
-
-                case LOG_QUOTE_RAW:
-                    entry->append("'", 1);
-                    break;
-
-                case LOG_QUOTE_NONE:
-                    break;
-                }
-
-                if (t->left)
-                    entry->append("-", 1);
-
-                if (t->zero)
-                    entry->append("0", 1);
-
-                if (t->width)
-                    storeAppendPrintf(entry, "%d", (int) t->width);
-
-                if (t->precision)
-                    storeAppendPrintf(entry, ".%d", (int) t->precision);
-
-                if (arg)
-                    storeAppendPrintf(entry, "{%s}", arg);
-
-                for (te = logformat_token_table; te->config != NULL; te++) {
-                    if (te->token_type == type) {
-                        storeAppendPrintf(entry, "%s", te->config);
-                        break;
-                    }
-                }
-
-                if (t->space)
-                    entry->append(" ", 1);
-
-                assert(te->config != NULL);
-            }
-        }
-
-        entry->append("\n", 1);
-    }
-
-}
-
-void
-accessLogFreeLogFormat(logformat_token ** tokens)
-{
-    while (*tokens) {
-        logformat_token *token = *tokens;
-        *tokens = token->next;
-        safe_free(token->data.string);
-        xfree(token);
-    }
-}
-
-static void
-accessLogSquid(AccessLogEntry * al, Logfile * logfile)
-{
-    const char *client = NULL;
-    const char *user = NULL;
-    char buf[MAX_IPSTRLEN];
-
-    if (Config.onoff.log_fqdn) {
-        client = fqdncache_gethostbyaddr(al->cache.caddr, FQDN_LOOKUP_IF_MISS);
-    }
-
-    if (client == NULL) {
-        client = al->cache.caddr.NtoA(buf,MAX_IPSTRLEN);
-    }
-
-    user = accessLogFormatName(al->cache.authuser);
-
-    if (!user)
-        user = accessLogFormatName(al->cache.extuser);
-
-#if USE_SSL
-
-    if (!user)
-        user = accessLogFormatName(al->cache.ssluser);
-
-#endif
-
-    if (!user)
-        user = accessLogFormatName(al->cache.rfc931);
-
-    if (user && !*user)
-        safe_free(user);
-
-    if (!Config.onoff.log_mime_hdrs) {
-        logfilePrintf(logfile, "%9ld.%03d %6d %s %s%s/%03d %"PRId64" %s %s %s %s%s/%s %s\n",
-                      (long int) current_time.tv_sec,
-                      (int) current_time.tv_usec / 1000,
-                      al->cache.msec,
-                      client,
-                      log_tags[al->cache.code],
-                      al->http.statusSfx(),
-                      al->http.code,
-                      al->cache.replySize,
-                      al->_private.method_str,
-                      al->url,
-                      user ? user : dash_str,
-                      al->hier.ping.timedout ? "TIMEOUT_" : "",
-                      hier_code_str[al->hier.code],
-                      al->hier.host,
-                      al->http.content_type);
-    } else {
-        char *ereq = log_quote(al->headers.request);
-        char *erep = log_quote(al->headers.reply);
-        logfilePrintf(logfile, "%9ld.%03d %6d %s %s%s/%03d %"PRId64" %s %s %s %s%s/%s %s [%s] [%s]\n",
-                      (long int) current_time.tv_sec,
-                      (int) current_time.tv_usec / 1000,
-                      al->cache.msec,
-                      client,
-                      log_tags[al->cache.code],
-                      al->http.statusSfx(),
-                      al->http.code,
-                      al->cache.replySize,
-                      al->_private.method_str,
-                      al->url,
-                      user ? user : dash_str,
-                      al->hier.ping.timedout ? "TIMEOUT_" : "",
-                      hier_code_str[al->hier.code],
-                      al->hier.host,
-                      al->http.content_type,
-                      ereq,
-                      erep);
-        safe_free(ereq);
-        safe_free(erep);
-    }
-    safe_free(user);
-}
-
-static void
-accessLogCommon(AccessLogEntry * al, Logfile * logfile)
-{
-    const char *client = NULL;
-    char *user1 = NULL, *user2 = NULL;
-    char buf[MAX_IPSTRLEN];
-
-    if (Config.onoff.log_fqdn) {
-        client = fqdncache_gethostbyaddr(al->cache.caddr, 0);
-    }
-
-    if (client == NULL) {
-        client = al->cache.caddr.NtoA(buf,MAX_IPSTRLEN);
-    }
-
-    user1 = accessLogFormatName(al->cache.authuser);
-
-    user2 = accessLogFormatName(al->cache.rfc931);
-
-    logfilePrintf(logfile, "%s %s %s [%s] \"%s %s HTTP/%d.%d\" %d %"PRId64" %s%s:%s%s",
-                  client,
-                  user2 ? user2 : dash_str,
-                  user1 ? user1 : dash_str,
-                  mkhttpdlogtime(&squid_curtime),
-                  al->_private.method_str,
-                  al->url,
-                  al->http.version.major, al->http.version.minor,
-                  al->http.code,
-                  al->cache.replySize,
-                  log_tags[al->cache.code],
-                  al->http.statusSfx(),
-                  hier_code_str[al->hier.code],
-                  (Config.onoff.log_mime_hdrs?"":"\n"));
-
-    safe_free(user1);
-
-    safe_free(user2);
-
-    if (Config.onoff.log_mime_hdrs) {
-        char *ereq = log_quote(al->headers.request);
-        char *erep = log_quote(al->headers.reply);
-        logfilePrintf(logfile, " [%s] [%s]\n", ereq, erep);
-        safe_free(ereq);
-        safe_free(erep);
-    }
-}
-
-#if ICAP_CLIENT
-static void
-accessLogICAPSquid(AccessLogEntry * al, Logfile * logfile)
-{
-    const char *client = NULL;
-    const char *user = NULL;
-    char tmp[MAX_IPSTRLEN], clientbuf[MAX_IPSTRLEN];
-
-    if (al->cache.caddr.IsAnyAddr()) { // ICAP OPTIONS xactions lack client
-        client = "-";
-    } else {
-        if (Config.onoff.log_fqdn)
-            client = fqdncache_gethostbyaddr(al->cache.caddr, FQDN_LOOKUP_IF_MISS);
-        if (!client)
-            client = al->cache.caddr.NtoA(clientbuf, MAX_IPSTRLEN);
-    }
-
-    user = accessLogFormatName(al->cache.authuser);
-
-    if (!user)
-        user = accessLogFormatName(al->cache.extuser);
-
-#if USE_SSL
-
-    if (!user)
-        user = accessLogFormatName(al->cache.ssluser);
+#if USE_FORW_VIA_DB
 
+typedef struct {
+    hash_link hash;
+    int n;
+} fvdb_entry;
+static hash_table *via_table = NULL;
+static hash_table *forw_table = NULL;
+static void fvdbInit();
+static void fvdbDumpTable(StoreEntry * e, hash_table * hash);
+static void fvdbCount(hash_table * hash, const char *key);
+static OBJH fvdbDumpVia;
+static OBJH fvdbDumpForw;
+static FREE fvdbFreeEntry;
+static void fvdbClear(void);
+static void fvdbRegisterWithCacheManager();
 #endif
 
-    if (!user)
-        user = accessLogFormatName(al->cache.rfc931);
-
-    if (user && !*user)
-        safe_free(user);
-
-    logfilePrintf(logfile, "%9ld.%03d %6d %s -/%03d %"PRId64" %s %s %s -/%s -\n",
-                  (long int) current_time.tv_sec,
-                  (int) current_time.tv_usec / 1000,
-
-                  al->icap.trTime,
-                  client,
-
-                  al->icap.resStatus,
-                  al->icap.bytesRead,
-                  Adaptation::Icap::ICAP::methodStr(al->icap.reqMethod),
-                  al->icap.reqUri.termedBuf(),
-                  user ? user : dash_str,
-                  al->icap.hostAddr.NtoA(tmp, MAX_IPSTRLEN));
-    safe_free(user);
-}
-#endif
+int LogfileStatus = LOG_DISABLE;
 
 void
 accessLogLogTo(customlog* log, AccessLogEntry * al, ACLChecklist * checklist)
@@ -2013,32 +119,37 @@ accessLogLogTo(customlog* log, AccessLogEntry * al, ACLChecklist * checklist)
 
             switch (log->type) {
 
-            case CLF_AUTO:
-                if (Config.onoff.common_log)
-                    accessLogCommon(al, log->logfile);
-                else
-                    accessLogSquid(al, log->logfile);
+            case Log::Format::CLF_SQUID:
+                Log::Format::SquidNative(al, log->logfile);
+                break;
+
+            case Log::Format::CLF_COMBINED:
+                Log::Format::HttpdCombined(al, log->logfile);
+                break;
+
+            case Log::Format::CLF_COMMON:
+                Log::Format::HttpdCommon(al, log->logfile);
                 break;
 
-            case CLF_SQUID:
-                accessLogSquid(al, log->logfile);
+            case Log::Format::CLF_REFERER:
+                Log::Format::SquidReferer(al, log->logfile);
                 break;
 
-            case CLF_COMMON:
-                accessLogCommon(al, log->logfile);
+            case Log::Format::CLF_USERAGENT:
+                Log::Format::SquidUserAgent(al, log->logfile);
                 break;
 
-            case CLF_CUSTOM:
-                accessLogCustom(al, log);
+            case Log::Format::CLF_CUSTOM:
+                Log::Format::SquidCustom(al, log);
                 break;
 
 #if ICAP_CLIENT
-            case CLF_ICAP_SQUID:
-                accessLogICAPSquid(al, log->logfile);
+            case Log::Format::CLF_ICAP_SQUID:
+                Log::Format::SquidIcap(al, log->logfile);
                 break;
 #endif
 
-            case CLF_NONE:
+            case Log::Format::CLF_NONE:
                 return; // abort!
 
             default:
@@ -2185,8 +296,6 @@ accessLogInit(void)
 
     accessLogRegisterWithCacheManager();
 
-    assert(sizeof(log_tags) == (LOG_TYPE_MAX + 1) * sizeof(char *));
-
 #if USE_ADAPTATION
     alLogformatHasAdaptToken = false;
 #endif
@@ -2195,7 +304,7 @@ accessLogInit(void)
 #endif
 
     for (log = Config.Log.accesslogs; log; log = log->next) {
-        if (log->type == CLF_NONE)
+        if (log->type == Log::Format::CLF_NONE)
             continue;
 
         log->logfile = logfileOpen(log->filename, MAX_URL << 2, 1);
@@ -2261,24 +370,6 @@ accessLogInit(void)
 #endif
 }
 
-const char *
-accessLogTime(time_t t)
-{
-
-    struct tm *tm;
-    static char buf[128];
-    static time_t last_t = 0;
-
-    if (t != last_t) {
-        tm = localtime(&t);
-        strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm);
-        last_t = t;
-    }
-
-    return buf;
-}
-
-
 #if USE_FORW_VIA_DB
 
 static void
index 4ac574d01ad928ad87d16e323a24db33904b54fa..e29b7b69a20b0c8f6a3b3f70a70d6d64b5616f93 100644 (file)
@@ -42,6 +42,7 @@
 #if USE_DELAY_POOLS
 #include "ClientDelayConfig.h"
 #endif
+#include "comm.h"
 #include "ConfigParser.h"
 #include "CpuAffinity.h"
 #if USE_DELAY_POOLS
 #include "htcp.h"
 #include "StoreFileSystem.h"
 #include "DiskIO/DiskIOModule.h"
-#include "comm.h"
 #include "ipc/Kids.h"
 #include "ipc/Coordinator.h"
 #include "ipc/Strand.h"
 #include "ip/tools.h"
-#if USE_EPOLL
-#include "comm_epoll.h"
-#endif
-#if USE_KQUEUE
-#include "comm_kqueue.h"
-#endif
-#if USE_POLL
-#include "comm_poll.h"
-#endif
-#if defined(USE_SELECT) || defined(USE_SELECT_WIN32)
-#include "comm_select.h"
-#endif
 #include "SquidTime.h"
 #include "SwapDir.h"
 #include "forward.h"
@@ -756,8 +744,6 @@ mainReconfigureStart(void)
 #if ICAP_CLIENT
     icapLogClose();
 #endif
-    useragentLogClose();
-    refererCloseLog();
 
     eventAdd("mainReconfigureFinish", &mainReconfigureFinish, NULL, 0, 1,
              false);
@@ -823,8 +809,6 @@ mainReconfigureFinish(void *)
     icapLogOpen();
 #endif
     storeLogOpen();
-    useragentOpenLog();
-    refererOpenLog();
 #if USE_DNSSERVERS
 
     dnsInit();
@@ -893,15 +877,9 @@ mainRotate(void)
     storeDirWriteCleanLogs(1);
     storeLogRotate();          /* store.log */
     accessLogRotate();         /* access.log */
-    useragentRotateLog();      /* useragent.log */
-    refererRotateLog();                /* referer.log */
 #if ICAP_CLIENT
     icapLogRotate();               /*icap.log*/
 #endif
-#if WIP_FWD_LOG
-    fwdLogRotate();
-#endif
-
     icmpEngine.Open();
 #if USE_DNSSERVERS
     dnsInit();
@@ -988,14 +966,12 @@ mainInitialize(void)
 
     debugs(1, 0, "Starting Squid Cache version " << version_string << " for " << CONFIG_HOST_TYPE << "...");
 
-#ifdef _SQUID_WIN32_
-
+#if _SQUID_WINDOWS_
     if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
         debugs(1, 0, "Running as " << WIN32_Service_name << " Windows System Service on " << WIN32_OS_string);
         debugs(1, 0, "Service command line is: " << WIN32_Service_Command_Line);
     } else
         debugs(1, 0, "Running on " << WIN32_OS_string);
-
 #endif
 
     debugs(1, 1, "Process ID " << getpid());
@@ -1040,10 +1016,6 @@ mainInitialize(void)
 
     externalAclInit();
 
-    useragentOpenLog();
-
-    refererOpenLog();
-
     httpHeaderInitModule();    /* must go before any header processing (e.g. the one in errorInitialize) */
 
     httpReplyInitModule();     /* must go before accepting replies */
@@ -1266,8 +1238,7 @@ SquidMain(int argc, char **argv)
 {
     ConfigureCurrentKid(argv[0]);
 
-#ifdef _SQUID_WIN32_
-
+#if _SQUID_WINDOWS_
     int WIN32_init_err;
 #endif
 
@@ -1286,11 +1257,9 @@ SquidMain(int argc, char **argv)
 
 #endif
 
-#ifdef _SQUID_WIN32_
-
+#if _SQUID_WINDOWS_
     if ((WIN32_init_err = WIN32_Subsystem_Init(&argc, &argv)))
         return WIN32_init_err;
-
 #endif
 
     /* call mallopt() before anything else */
@@ -1397,8 +1366,6 @@ SquidMain(int argc, char **argv)
 
     comm_init();
 
-    comm_select_init();
-
     mainInitialize();
 
     test_access();
@@ -1450,8 +1417,6 @@ SquidMain(int argc, char **argv)
     /* init comm module */
     comm_init();
 
-    comm_select_init();
-
     if (opt_no_daemon) {
         /* we have to init fdstat here. */
         fd_open(0, FD_LOG, "stdin");
@@ -1875,13 +1840,6 @@ SquidShutdown()
     Store::Root().sync();              /* Flush log writes */
     storeLogClose();
     accessLogClose();
-    useragentLogClose();
-    refererCloseLog();
-#if WIP_FWD_LOG
-
-    fwdUninit();
-#endif
-
     Store::Root().sync();              /* Flush log close */
     StoreFileSystem::FreeAllFs();
     DiskIOModule::FreeAllModules();
index 2d908978cf8c9c4f20efc49539a31fdaf33f5d4b..4ea3f8d34ea9b1f31738d9ec12c1c97c2e3c3ab7 100644 (file)
 
 CBDATA_NAMESPACED_CLASS_INIT(Mgr, Forwarder);
 
-Mgr::Forwarder::RequestsMap Mgr::Forwarder::TheRequestsMap;
-unsigned int Mgr::Forwarder::LastRequestId = 0;
 
 Mgr::Forwarder::Forwarder(int aFd, const ActionParams &aParams,
                           HttpRequest* aRequest, StoreEntry* anEntry):
-        AsyncJob("Mgr::Forwarder"),
-        params(aParams),
-        request(aRequest), entry(anEntry), fd(aFd), requestId(0), closer(NULL)
+        Ipc::Forwarder(new Request(KidIdentifier, 0, aFd, aParams), 10),
+        httpRequest(aRequest), entry(anEntry), fd(aFd)
 {
-    debugs(16, 5, HERE << "FD " << aFd);
+    debugs(16, 5, HERE << "FD " << fd);
     Must(fd >= 0);
-    Must(request != NULL);
+    Must(httpRequest != NULL);
     Must(entry != NULL);
 
-    HTTPMSGLOCK(request);
+    HTTPMSGLOCK(httpRequest);
     entry->lock();
     EBIT_SET(entry->flags, ENTRY_FWD_HDR_WAIT);
 
@@ -47,19 +44,18 @@ Mgr::Forwarder::Forwarder(int aFd, const ActionParams &aParams,
 Mgr::Forwarder::~Forwarder()
 {
     debugs(16, 5, HERE);
-    Must(request != NULL);
+    Must(httpRequest != NULL);
     Must(entry != NULL);
-    Must(requestId == 0);
 
-    HTTPMSGUNLOCK(request);
+    HTTPMSGUNLOCK(httpRequest);
     entry->unregisterAbort();
     entry->unlock();
-    close();
+    cleanup();
 }
 
 /// closes our copy of the client HTTP connection socket
 void
-Mgr::Forwarder::close()
+Mgr::Forwarder::cleanup()
 {
     if (fd >= 0) {
         if (closer != NULL) {
@@ -72,61 +68,34 @@ Mgr::Forwarder::close()
 }
 
 void
-Mgr::Forwarder::start()
+Mgr::Forwarder::handleError()
 {
-    debugs(16, 3, HERE);
-    entry->registerAbort(&Forwarder::Abort, this);
-
-    typedef NullaryMemFunT<Mgr::Forwarder> Dialer;
-    AsyncCall::Pointer callback = JobCallback(16, 5, Dialer, this,
-                                  Forwarder::handleRemoteAck);
-    if (++LastRequestId == 0) // don't use zero value as requestId
-        ++LastRequestId;
-    requestId = LastRequestId;
-    TheRequestsMap[requestId] = callback;
-    Request mgrRequest(KidIdentifier, requestId, fd, params);
-    Ipc::TypedMsgHdr message;
-
-    try {
-        mgrRequest.pack(message);
-    } catch (...) {
-        // assume the pack() call failed because the message did not fit
-        // TODO: add a more specific exception?
-        debugs(16, DBG_CRITICAL, "ERROR: uri " << entry->url() << " exceeds buffer size");
-        quitOnError("long URI", errorCon(ERR_INVALID_URL, HTTP_REQUEST_URI_TOO_LARGE, request));
-    }
-
-    Ipc::SendMessage(Ipc::coordinatorAddr, message);
-    const double timeout = 10; // in seconds
-    eventAdd("Mgr::Forwarder::requestTimedOut", &Forwarder::RequestTimedOut,
-             this, timeout, 0, false);
+    debugs(16, DBG_CRITICAL, "ERROR: uri " << entry->url() << " exceeds buffer size");
+    sendError(errorCon(ERR_INVALID_URL, HTTP_REQUEST_URI_TOO_LARGE, httpRequest));
+    mustStop("long URI");
 }
 
 void
-Mgr::Forwarder::swanSong()
+Mgr::Forwarder::handleTimeout()
 {
-    debugs(16, 5, HERE);
-    removeTimeoutEvent();
-    if (requestId > 0) {
-        DequeueRequest(requestId);
-        requestId = 0;
-    }
-    close();
+    sendError(errorCon(ERR_LIFETIME_EXP, HTTP_REQUEST_TIMEOUT, httpRequest));
+    Ipc::Forwarder::handleTimeout();
 }
 
-bool
-Mgr::Forwarder::doneAll() const
+void
+Mgr::Forwarder::handleException(const std::exception& e)
 {
-    debugs(16, 5, HERE);
-    return requestId == 0;
+    if (entry != NULL && httpRequest != NULL && fd >= 0)
+        sendError(errorCon(ERR_INVALID_RESP, HTTP_INTERNAL_SERVER_ERROR, httpRequest));
+    Ipc::Forwarder::handleException(e);
 }
 
 /// called when the client socket gets closed by some external force
 void
-Mgr::Forwarder::noteCommClosed(const CommCloseCbParams &io)
+Mgr::Forwarder::noteCommClosed(const CommCloseCbParams& params)
 {
     debugs(16, 5, HERE);
-    Must(fd == io.fd);
+    Must(fd == params.fd);
     fd = -1;
     mustStop("commClosed");
 }
@@ -135,42 +104,21 @@ Mgr::Forwarder::noteCommClosed(const CommCloseCbParams &io)
 void
 Mgr::Forwarder::handleRemoteAck()
 {
-    debugs(16, 3, HERE);
-    Must(entry != NULL);
+    Ipc::Forwarder::handleRemoteAck();
 
-    requestId = 0;
+    Must(entry != NULL);
     EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT);
     entry->complete();
 }
 
-/// Mgr::Forwarder::requestTimedOut wrapper
+/// send error page
 void
-Mgr::Forwarder::RequestTimedOut(void* param)
+Mgr::Forwarder::sendError(ErrorState *error)
 {
     debugs(16, 3, HERE);
-    Must(param != NULL);
-    Forwarder* mgrFwdr = static_cast<Forwarder*>(param);
-    // use async call to enable job call protection that time events lack
-    CallJobHere(16, 5, mgrFwdr, Mgr::Forwarder, requestTimedOut);
-}
-
-/// called when Coordinator fails to start processing the request [in time]
-void
-Mgr::Forwarder::requestTimedOut()
-{
-    debugs(16, 3, HERE);
-    quitOnError("timeout", errorCon(ERR_LIFETIME_EXP, HTTP_REQUEST_TIMEOUT, request));
-}
-
-/// terminate with an error
-void
-Mgr::Forwarder::quitOnError(const char *reason, ErrorState *error)
-{
-    debugs(16, 3, HERE);
-    Must(reason != NULL);
     Must(error != NULL);
     Must(entry != NULL);
-    Must(request != NULL);
+    Must(httpRequest != NULL);
 
     EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT);
     entry->buffer();
@@ -179,62 +127,4 @@ Mgr::Forwarder::quitOnError(const char *reason, ErrorState *error)
     errorStateFree(error);
     entry->flush();
     entry->complete();
-
-    mustStop(reason);
-}
-
-void
-Mgr::Forwarder::callException(const std::exception& e)
-{
-    try {
-        if (entry != NULL && request != NULL && fd >= 0)
-            quitOnError("exception", errorCon(ERR_INVALID_RESP, HTTP_INTERNAL_SERVER_ERROR, request));
-    } catch (const std::exception& ex) {
-        debugs(16, DBG_CRITICAL, HERE << ex.what());
-    }
-    AsyncJob::callException(e);
-}
-
-/// returns and forgets the right Forwarder callback for the request
-AsyncCall::Pointer
-Mgr::Forwarder::DequeueRequest(unsigned int requestId)
-{
-    debugs(16, 3, HERE);
-    Must(requestId != 0);
-    AsyncCall::Pointer call;
-    RequestsMap::iterator request = TheRequestsMap.find(requestId);
-    if (request != TheRequestsMap.end()) {
-        call = request->second;
-        Must(call != NULL);
-        TheRequestsMap.erase(request);
-    }
-    return call;
-}
-
-/// called when we are no longer waiting for Coordinator to respond
-void
-Mgr::Forwarder::removeTimeoutEvent()
-{
-    if (eventFind(&Forwarder::RequestTimedOut, this))
-        eventDelete(&Forwarder::RequestTimedOut, this);
-}
-
-void
-Mgr::Forwarder::HandleRemoteAck(unsigned int requestId)
-{
-    debugs(16, 3, HERE);
-    Must(requestId != 0);
-
-    AsyncCall::Pointer call = DequeueRequest(requestId);
-    if (call != NULL)
-        ScheduleCallHere(call);
-}
-
-/// called when something goes wrong with the Store entry
-void
-Mgr::Forwarder::Abort(void* param)
-{
-    Forwarder* mgrFwdr = static_cast<Forwarder*>(param);
-    if (mgrFwdr->fd >= 0)
-        comm_close(mgrFwdr->fd);
 }
index 470a1a3fc7f42423a99e0b60385bba297051d7e4..1c8b9e84f556eda7d46f68188e86194b29b334e9 100644 (file)
@@ -8,9 +8,8 @@
 #ifndef SQUID_MGR_FORWARDER_H
 #define SQUID_MGR_FORWARDER_H
 
-#include "base/AsyncJob.h"
+#include "ipc/Forwarder.h"
 #include "mgr/ActionParams.h"
-#include <map>
 
 
 class CommCloseCbParams;
@@ -25,50 +24,31 @@ namespace Mgr
  * Waits for an ACK from Coordinator while holding the Store entry.
  * Fills the store entry with an error response if forwarding fails.
  */
-class Forwarder: public AsyncJob
+class Forwarder: public Ipc::Forwarder
 {
 public:
     Forwarder(int aFd, const ActionParams &aParams, HttpRequest* aRequest,
               StoreEntry* anEntry);
     virtual ~Forwarder();
 
-    /// finds and calls the right Forwarder upon Coordinator's response
-    static void HandleRemoteAck(unsigned int requestId);
-
-    /* has-to-be-public AsyncJob API */
-    virtual void callException(const std::exception& e);
-
 protected:
-    /* AsyncJob API */
-    virtual void start();
-    virtual void swanSong();
-    virtual bool doneAll() const;
+    /* Ipc::Forwarder API */
+    virtual void cleanup(); ///< perform cleanup actions
+    virtual void handleError();
+    virtual void handleTimeout();
+    virtual void handleException(const std::exception& e);
+    virtual void handleRemoteAck();
 
 private:
-    void handleRemoteAck();
-    static void RequestTimedOut(void* param);
-    void requestTimedOut();
-    void quitOnError(const char *reason, ErrorState *error);
     void noteCommClosed(const CommCloseCbParams& params);
-    void removeTimeoutEvent();
-    static AsyncCall::Pointer DequeueRequest(unsigned int requestId);
-    static void Abort(void* param);
-    void close();
+    void sendError(ErrorState* error);
 
 private:
-    ActionParams params; ///< action parameters to pass to the other side
-    HttpRequest* request; ///< HTTP client request for detailing errors
+    HttpRequest* httpRequest; ///< HTTP client request for detailing errors
     StoreEntry* entry; ///< Store entry expecting the response
     int fd; ///< HTTP client connection descriptor
-    unsigned int requestId; ///< request id
     AsyncCall::Pointer closer; ///< comm_close handler for the HTTP connection
 
-    /// maps requestId to Forwarder::handleRemoteAck callback
-    typedef std::map<unsigned int, AsyncCall::Pointer> RequestsMap;
-    static RequestsMap TheRequestsMap; ///< pending Coordinator requests
-
-    static unsigned int LastRequestId; ///< last requestId used
-
     CBDATA_CLASS2(Forwarder);
 };
 
index 4e7bc4927048114ce0ab4a5893bd5527076e1b65..6fd0f97c1a4140c747f49aff832b08f886de0501 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "config.h"
 #include "base/TextException.h"
+#include "ipc/UdsOp.h"
 #include "mgr/Command.h"
 #include "mgr/Filler.h"
 #include "mgr/FunAction.h"
@@ -31,7 +32,7 @@ void
 Mgr::FunAction::respond(const Request& request)
 {
     debugs(16, 5, HERE);
-    const int fd = ImportHttpFdIntoComm(request.fd);
+    const int fd = Ipc::ImportFdIntoComm(request.fd, SOCK_STREAM, IPPROTO_TCP, Ipc::fdnHttpSocket);
     Must(fd >= 0);
     Must(request.requestId != 0);
     AsyncJob::Start(new Mgr::Filler(this, fd, request.requestId));
index 27adf22ec872ce02a3fb6f78e9ab2df706c24c54..eb5760ba0b86236bc867a0d2a74444a2e15c35ac 100644 (file)
@@ -9,6 +9,7 @@
 #include "base/TextException.h"
 #include "HttpReply.h"
 #include "ipc/Messages.h"
+#include "ipc/UdsOp.h"
 #include "ipc/TypedMsgHdr.h"
 #include "mgr/Filler.h"
 #include "mgr/InfoAction.h"
@@ -155,7 +156,7 @@ void
 Mgr::InfoAction::respond(const Request& request)
 {
     debugs(16, 5, HERE);
-    int fd = ImportHttpFdIntoComm(request.fd);
+    int fd = Ipc::ImportFdIntoComm(request.fd, SOCK_STREAM, IPPROTO_TCP, Ipc::fdnHttpSocket);
     Must(fd >= 0);
     Must(request.requestId != 0);
     AsyncJob::Start(new Mgr::Filler(this, fd, request.requestId));
index d249c3a9136948cf1987ab7ad4dd416fc39667c2..411904519361e515b64c3dec96288862c9e80eb2 100644 (file)
 #include "comm/Write.h"
 #include "CommCalls.h"
 #include "HttpReply.h"
-#include "ipc/Coordinator.h"
+#include "ipc/UdsOp.h"
 #include "mgr/ActionWriter.h"
-#include "mgr/Command.h"
 #include "mgr/Inquirer.h"
 #include "mgr/Request.h"
 #include "mgr/Response.h"
 #include "SquidTime.h"
 #include <memory>
-#include <algorithm>
 
 
 CBDATA_NAMESPACED_CLASS_INIT(Mgr, Inquirer);
 
-Mgr::Inquirer::RequestsMap Mgr::Inquirer::TheRequestsMap;
-unsigned int Mgr::Inquirer::LastRequestId = 0;
 
-/// compare Ipc::StrandCoord using kidId, for std::sort() below
-static bool
-LesserStrandByKidId(const Ipc::StrandCoord &c1, const Ipc::StrandCoord &c2)
-{
-    return c1.kidId < c2.kidId;
-}
-
-Mgr::Inquirer::Inquirer(Action::Pointer anAction, int aFd,
+Mgr::Inquirer::Inquirer(Action::Pointer anAction,
                         const Request &aCause, const Ipc::StrandCoords &coords):
-        AsyncJob("Mgr::Inquirer"),
+        Ipc::Inquirer(aCause.clone(), coords, anAction->atomic() ? 10 : 100),
         aggrAction(anAction),
-        cause(aCause),
-        fd(aFd),
-        strands(coords), pos(strands.begin()),
-        requestId(0), closer(NULL), timeout(aggrAction->atomic() ? 10 : 100)
+        fd(Ipc::ImportFdIntoComm(aCause.fd, SOCK_STREAM, IPPROTO_TCP, Ipc::fdnHttpSocket))
 {
-    debugs(16, 5, HERE << "FD " << aFd << " action: " << aggrAction);
-
-    // order by ascending kid IDs; useful for non-aggregatable stats
-    std::sort(strands.begin(), strands.end(), LesserStrandByKidId);
+    debugs(16, 5, HERE << "FD " << fd << " action: " << aggrAction);
 
     closer = asyncCall(16, 5, "Mgr::Inquirer::noteCommClosed",
                        CommCbMemFunT<Inquirer, CommCloseCbParams>(this, &Inquirer::noteCommClosed));
     comm_add_close_handler(fd, closer);
 }
 
-Mgr::Inquirer::~Inquirer()
-{
-    debugs(16, 5, HERE);
-    close();
-}
-
 /// closes our copy of the client HTTP connection socket
 void
-Mgr::Inquirer::close()
+Mgr::Inquirer::cleanup()
 {
     if (fd >= 0) {
         removeCloseHandler();
@@ -82,6 +59,7 @@ void
 Mgr::Inquirer::start()
 {
     debugs(16, 5, HERE);
+    Ipc::Inquirer::start();
     Must(fd >= 0);
     Must(aggrAction != NULL);
 
@@ -107,46 +85,6 @@ Mgr::Inquirer::noteWroteHeader(const CommIoCbParams& params)
     inquire();
 }
 
-void
-Mgr::Inquirer::inquire()
-{
-    if (pos == strands.end()) {
-        Must(done());
-        return;
-    }
-
-    Must(requestId == 0);
-    AsyncCall::Pointer callback = asyncCall(16, 5, "Mgr::Inquirer::handleRemoteAck",
-                                            HandleAckDialer(this, &Inquirer::handleRemoteAck, Response()));
-    if (++LastRequestId == 0) // don't use zero value as requestId
-        ++LastRequestId;
-    requestId = LastRequestId;
-    const int kidId = pos->kidId;
-    debugs(16, 4, HERE << "inquire kid: " << kidId << status());
-    TheRequestsMap[requestId] = callback;
-    Request mgrRequest(KidIdentifier, requestId, fd,
-                       aggrAction->command().params);
-    Ipc::TypedMsgHdr message;
-    mgrRequest.pack(message);
-    Ipc::SendMessage(Ipc::Port::MakeAddr(Ipc::strandAddrPfx, kidId), message);
-    eventAdd("Mgr::Inquirer::requestTimedOut", &Inquirer::RequestTimedOut,
-             this, timeout, 0, false);
-}
-
-/// called when a strand is done writing its output
-void
-Mgr::Inquirer::handleRemoteAck(const Response& response)
-{
-    debugs(16, 4, HERE << status());
-    requestId = 0;
-    removeTimeoutEvent();
-    if (response.hasAction())
-        aggrAction->add(response.getAction());
-    Must(!done()); // or we should not be called
-    ++pos; // advance after a successful inquiry
-    inquire();
-}
-
 /// called when the HTTP client or some external force closed our socket
 void
 Mgr::Inquirer::noteCommClosed(const CommCloseCbParams& params)
@@ -157,97 +95,27 @@ Mgr::Inquirer::noteCommClosed(const CommCloseCbParams& params)
     mustStop("commClosed");
 }
 
+bool
+Mgr::Inquirer::aggregate(Ipc::Response::Pointer aResponse)
+{
+    Mgr::Response& response = static_cast<Response&>(*aResponse);
+    if (response.hasAction())
+        aggrAction->add(response.getAction());
+    return true;
+}
+
 void
-Mgr::Inquirer::swanSong()
+Mgr::Inquirer::sendResponse()
 {
-    debugs(16, 5, HERE);
-    removeTimeoutEvent();
-    if (requestId > 0) {
-        DequeueRequest(requestId);
-        requestId = 0;
-    }
     if (aggrAction->aggregatable()) {
         removeCloseHandler();
         AsyncJob::Start(new ActionWriter(aggrAction, fd));
         fd = -1; // should not close fd because we passed it to ActionWriter
     }
-    close();
 }
 
 bool
 Mgr::Inquirer::doneAll() const
 {
-    return !writer && pos == strands.end();
-}
-
-/// returns and forgets the right Inquirer callback for strand request
-AsyncCall::Pointer
-Mgr::Inquirer::DequeueRequest(unsigned int requestId)
-{
-    debugs(16, 3, HERE << " requestId " << requestId);
-    Must(requestId != 0);
-    AsyncCall::Pointer call;
-    RequestsMap::iterator request = TheRequestsMap.find(requestId);
-    if (request != TheRequestsMap.end()) {
-        call = request->second;
-        Must(call != NULL);
-        TheRequestsMap.erase(request);
-    }
-    return call;
-}
-
-void
-Mgr::Inquirer::HandleRemoteAck(const Mgr::Response& response)
-{
-    Must(response.requestId != 0);
-    AsyncCall::Pointer call = DequeueRequest(response.requestId);
-    if (call != NULL) {
-        HandleAckDialer* dialer = dynamic_cast<HandleAckDialer*>(call->getDialer());
-        Must(dialer);
-        dialer->arg1 = response;
-        ScheduleCallHere(call);
-    }
-}
-
-/// called when we are no longer waiting for the strand to respond
-void
-Mgr::Inquirer::removeTimeoutEvent()
-{
-    if (eventFind(&Inquirer::RequestTimedOut, this))
-        eventDelete(&Inquirer::RequestTimedOut, this);
-}
-
-/// Mgr::Inquirer::requestTimedOut wrapper
-void
-Mgr::Inquirer::RequestTimedOut(void* param)
-{
-    debugs(16, 3, HERE);
-    Must(param != NULL);
-    Inquirer* cmi = static_cast<Inquirer*>(param);
-    // use async call to enable job call protection that time events lack
-    CallJobHere(16, 5, cmi, Mgr::Inquirer, requestTimedOut);
-}
-
-/// called when the strand failed to respond (or finish responding) in time
-void
-Mgr::Inquirer::requestTimedOut()
-{
-    debugs(16, 3, HERE);
-    if (requestId != 0) {
-        DequeueRequest(requestId);
-        requestId = 0;
-        Must(!done()); // or we should not be called
-        ++pos; // advance after a failed inquiry
-        inquire();
-    }
-}
-
-const char*
-Mgr::Inquirer::status() const
-{
-    static MemBuf buf;
-    buf.reset();
-    buf.Printf(" [FD %d, requestId %u]", fd, requestId);
-    buf.terminate();
-    return buf.content();
+    return !writer && Ipc::Inquirer::doneAll();
 }
index 7059daa2b3945a2c72e12e2b13dc9fc63f40a9c2..03d7efeda1ed1c6919c35ee1f6c17b5bfe293fa5 100644 (file)
@@ -8,13 +8,8 @@
 #ifndef SQUID_MGR_INQUIRER_H
 #define SQUID_MGR_INQUIRER_H
 
-#include "base/AsyncJobCalls.h"
-#include "base/AsyncJob.h"
-#include "ipc/StrandCoords.h"
-#include "MemBuf.h"
+#include "ipc/Inquirer.h"
 #include "mgr/Action.h"
-#include "mgr/Request.h"
-#include <map>
 
 class CommIoCbParams;
 class CommCloseCbParams;
@@ -24,60 +19,34 @@ namespace Mgr
 
 /// Coordinator's job that sends a cache manage request to each strand,
 /// aggregating individual strand responses and dumping the result if needed
-class Inquirer: public AsyncJob
+class Inquirer: public Ipc::Inquirer
 {
 public:
-    Inquirer(Action::Pointer anAction, int aFd, const Request &aCause,
+    Inquirer(Action::Pointer anAction, const Request &aCause,
              const Ipc::StrandCoords &coords);
-    virtual ~Inquirer();
-
-    /// finds and calls the right Inquirer upon strand's response
-    static void HandleRemoteAck(const Mgr::Response& response);
 
 protected:
     /* AsyncJob API */
     virtual void start();
-    virtual void swanSong();
     virtual bool doneAll() const;
-    virtual const char *status() const;
 
-private:
-    typedef UnaryMemFunT<Inquirer, Response, const Response&> HandleAckDialer;
+    /* Ipc::Inquirer API */
+    virtual void cleanup();
+    virtual void sendResponse();
+    virtual bool aggregate(Ipc::Response::Pointer aResponse);
 
-    void inquire();
+private:
     void noteWroteHeader(const CommIoCbParams& params);
     void noteCommClosed(const CommCloseCbParams& params);
-
-    void handleRemoteAck(const Response& response);
-
-    static AsyncCall::Pointer DequeueRequest(unsigned int requestId);
-
-    static void RequestTimedOut(void* param);
-    void requestTimedOut();
-    void removeTimeoutEvent();
-
-    void close();
     void removeCloseHandler();
 
 private:
     Action::Pointer aggrAction; //< action to aggregate
 
-    Request cause; ///< cache manager request received from HTTP client
     int fd; ///< HTTP client socket descriptor
 
-    Ipc::StrandCoords strands; ///< all strands we want to query, in order
-    Ipc::StrandCoords::const_iterator pos; ///< strand we should query now
-
-    unsigned int requestId; ///< ID of our outstanding request to strand
     AsyncCall::Pointer writer; ///< comm_write callback
     AsyncCall::Pointer closer; ///< comm_close handler
-    const double timeout; ///< number of seconds to wait for strand response
-
-    /// maps requestId to Inquirer::handleRemoteAck callback
-    typedef std::map<unsigned int, AsyncCall::Pointer> RequestsMap;
-    static RequestsMap TheRequestsMap; ///< pending strand requests
-
-    static unsigned int LastRequestId; ///< last requestId used
 
     CBDATA_CLASS2(Inquirer);
 };
index a0f4014cdd19b5f40040a56ed239624048cbb76b..9e6f76e83477be681347735d9a1935e79d91b9ca 100644 (file)
@@ -8,20 +8,27 @@
 #include "config.h"
 #include "base/TextException.h"
 #include "ipc/Messages.h"
+#include "ipc/TypedMsgHdr.h"
 #include "mgr/ActionParams.h"
 #include "mgr/Request.h"
 
 
 Mgr::Request::Request(int aRequestorId, unsigned int aRequestId, int aFd,
                       const ActionParams &aParams):
-        requestorId(aRequestorId), requestId(aRequestId),
+        Ipc::Request(aRequestorId, aRequestId),
         fd(aFd), params(aParams)
 {
     Must(requestorId > 0);
-    Must(requestId != 0);
 }
 
-Mgr::Request::Request(const Ipc::TypedMsgHdr& msg)
+Mgr::Request::Request(const Request& request):
+        Ipc::Request(request.requestorId, request.requestId),
+        fd(request.fd), params(request.params)
+{
+}
+
+Mgr::Request::Request(const Ipc::TypedMsgHdr& msg):
+        Ipc::Request(0, 0)
 {
     msg.checkType(Ipc::mtCacheMgrRequest);
     msg.getPod(requestorId);
@@ -41,3 +48,9 @@ Mgr::Request::pack(Ipc::TypedMsgHdr& msg) const
 
     msg.putFd(fd);
 }
+
+Ipc::Request::Pointer
+Mgr::Request::clone() const
+{
+    return new Request(*this);
+}
index 89924f683713d666a4de190957ab4de0341d95ee..50b29d7016c13688ade20886a8e809b75b57dbcf 100644 (file)
@@ -8,7 +8,8 @@
 #ifndef SQUID_MGR_REQUEST_H
 #define SQUID_MGR_REQUEST_H
 
-#include "ipc/TypedMsgHdr.h"
+#include "ipc/forward.h"
+#include "ipc/Request.h"
 #include "mgr/ActionParams.h"
 
 
@@ -16,18 +17,21 @@ namespace Mgr
 {
 
 /// cache manager request
-class Request
+class Request: public Ipc::Request
 {
 public:
     Request(int aRequestorId, unsigned int aRequestId, int aFd,
             const ActionParams &aParams);
 
     explicit Request(const Ipc::TypedMsgHdr& msg); ///< from recvmsg()
-    void pack(Ipc::TypedMsgHdr& msg) const; ///< prepare for sendmsg()
+    /* Ipc::Request API */
+    virtual void pack(Ipc::TypedMsgHdr& msg) const;
+    virtual Pointer clone() const;
+
+private:
+    Request(const Request& request);
 
 public:
-    int requestorId; ///< kidId of the requestor; used for response destination
-    unsigned int requestId; ///< unique for sender; matches request w/ response
     int fd; ///< HTTP client connection descriptor
 
     ActionParams params; ///< action name and parameters
index e3204f814f15bb3048c5e6158ea7adce9b6c756e..38d48865b1783425b2023958ea047010618e41b1 100644 (file)
 #include "mgr/Response.h"
 
 
-std::ostream& Mgr::operator << (std::ostream &os, const Response& response)
+Mgr::Response::Response(unsigned int aRequestId, Action::Pointer anAction):
+        Ipc::Response(aRequestId), action(anAction)
 {
-    os << "response: {requestId: " << response.requestId << '}';
-    return os;
+    Must(!action || action->name()); // if there is an action, it must be named
 }
 
-Mgr::Response::Response(unsigned int aRequestId, Action::Pointer anAction):
-        requestId(aRequestId), action(anAction)
+Mgr::Response::Response(const Response& response):
+        Ipc::Response(response.requestId), action(response.action)
 {
-    Must(!action || action->name()); // if there is an action, it must be named
 }
 
-Mgr::Response::Response(const Ipc::TypedMsgHdr& msg)
+Mgr::Response::Response(const Ipc::TypedMsgHdr& msg):
+        Ipc::Response(0)
 {
     msg.checkType(Ipc::mtCacheMgrResponse);
     msg.getPod(requestId);
@@ -54,6 +54,12 @@ Mgr::Response::pack(Ipc::TypedMsgHdr& msg) const
     }
 }
 
+Ipc::Response::Pointer
+Mgr::Response::clone() const
+{
+    return new Response(*this);
+}
+
 bool
 Mgr::Response::hasAction() const
 {
index 7b759926eb7e35b33082ea854bbd0634767dab95..38f5f08e7ee2349fde084280946cf081dd915178 100644 (file)
@@ -8,6 +8,8 @@
 #ifndef SQUID_MGR_RESPONSE_H
 #define SQUID_MGR_RESPONSE_H
 
+#include "ipc/forward.h"
+#include "ipc/Response.h"
 #include "mgr/Action.h"
 
 
@@ -16,23 +18,27 @@ namespace Mgr
 
 /// A response to Mgr::Request.
 /// May carry strand action data to be aggregated with data from other strands.
-class Response
+class Response: public Ipc::Response
 {
 public:
-    Response(unsigned int aRequestId = 0, Action::Pointer anAction = NULL);
+    Response(unsigned int aRequestId, Action::Pointer anAction = NULL);
 
     explicit Response(const Ipc::TypedMsgHdr& msg); ///< from recvmsg()
-    void pack(Ipc::TypedMsgHdr& msg) const; ///< prepare for sendmsg()
+
+    /* Ipc::Response API */
+    virtual void pack(Ipc::TypedMsgHdr& msg) const;
+    virtual Ipc::Response::Pointer clone() const;
+
     bool hasAction() const; ///< whether response contain action object
     const Action& getAction() const; ///< returns action object
 
+private:
+    Response(const Response& response);
+
 public:
-    unsigned int requestId; ///< ID of request we are responding to
     Action::Pointer action; ///< action relating to response
 };
 
-extern std::ostream& operator <<(std::ostream &os, const Response &response);
-
 } // namespace Mgr
 
 #endif /* SQUID_MGR_RESPONSE_H */
index 12273337687ad01d0f444cf740792beda67e4aed..52aed325d8e738043bfdf5346de658611704dbec 100644 (file)
@@ -164,25 +164,3 @@ Mgr::StoreToCommWriter::Abort(void* param)
     if (mgrWriter->fd >= 0)
         comm_close(mgrWriter->fd);
 }
-
-
-int
-Mgr::ImportHttpFdIntoComm(int fd)
-{
-    struct sockaddr_in addr;
-    socklen_t len = sizeof(addr);
-    if (getsockname(fd, reinterpret_cast<sockaddr*>(&addr), &len) == 0) {
-        Ip::Address ipAddr(addr);
-        struct addrinfo* addr_info = NULL;
-        ipAddr.GetAddrInfo(addr_info);
-        addr_info->ai_socktype = SOCK_STREAM;
-        addr_info->ai_protocol = IPPROTO_TCP;
-        comm_import_opened(fd, ipAddr, COMM_NONBLOCKING, Ipc::FdNote(Ipc::fdnHttpSocket), addr_info);
-        ipAddr.FreeAddrInfo(addr_info);
-    } else {
-        debugs(16, DBG_CRITICAL, HERE << "ERROR: FD " << fd << ' ' << xstrerror());
-        ::close(fd);
-        fd = -1;
-    }
-    return fd;
-}
index 116ffdba51dceeec9daacbb32f89ffa3606ff03b..43678a3207cf24ff043d920ba9e14a39ec912f83 100644 (file)
@@ -65,9 +65,6 @@ protected:
     CBDATA_CLASS2(StoreToCommWriter);
 };
 
-/// import HTTP socket fd from another strand into our Comm state
-extern int ImportHttpFdIntoComm(int fd);
-
 } // namespace Mgr
 
 #endif /* SQUID_MGR_STORE_TO_COMM_WRITER_H */
index c4113f7e73e824044707c18adf54e39d089ba4c8..a55801022bbb30e4949e7fbe78507036ca619b1a 100644 (file)
@@ -49,6 +49,7 @@ class MimeIcon : public StoreClient
 
 public:
     MimeIcon ();
+    ~MimeIcon ();
     void setName (char const *);
     char const * getName () const;
     void _free();
@@ -137,6 +138,11 @@ mimeGetEntry(const char *fn, int skip_encodings)
 MimeIcon::MimeIcon () : icon (NULL), url (NULL)
 {}
 
+MimeIcon::~MimeIcon ()
+{
+    _free();
+}
+
 void
 MimeIcon::setName (char const *aString)
 {
@@ -273,9 +279,8 @@ mimeInit(char *filename)
         return;
     }
 
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
     setmode(fileno(fp), O_TEXT);
-
 #endif
 
     mimeFreeMemory();
index d4b5ec37518cbe76da0a069dbfcf905345a9e70a..42133a3f5cecd1089c4c41a4b43e67966a6996e6 100644 (file)
@@ -14,9 +14,17 @@ BEGIN {
        print "/*"
        print " * Auto-Generated File. Changes will be destroyed."
        print " */"
-       print "#include \"squid.h\""
+       print "#include \"config.h\""
         codeSkip = 1
         e = 0
+        nspath = ""
+}
+
+# when namespace is encountered store it
+/^namespace [a-zA-Z]+/ {
+       nspath = tolower($2) "/"                # nested folder
+       namespace = $2                          # code namespace reconstruct
+       next
 }
 
 # Skip all lines outside of typedef {}
@@ -34,11 +42,17 @@ codeSkip == 1               { next }
        type = t[1]
         codeSkip = 1
 
-       print "#include \"" type ".h\""
+       print "#include \"" nspath type ".h\""
+
+       # if namesapce is not empty ??
+       if (namespace) print "namespace " namespace
+       if (namespace) print "{"
+
        print "\nconst char *" type "_str[] = {"
        for ( i = 1; i < e; ++i)
                print "\t\"" Element[i] "\","
        print "\t\"" Element[i] "\""
        print "};"
+       if (namespace) print "}; // namespace " namespace
        next
 }
index 4402bd107792dc08db4f993d6d46b07023355257..3490db232987472bb2f565787294201ce2478140 100644 (file)
@@ -1755,7 +1755,7 @@ dump_peers(StoreEntry * sentry, peer * peers)
 
         if (e->stats.last_connect_failure) {
             storeAppendPrintf(sentry, "Last failed connect() at: %s\n",
-                              mkhttpdlogtime(&(e->stats.last_connect_failure)));
+                              Time::FormatHttpd(e->stats.last_connect_failure));
         }
 
         if (e->peer_domain != NULL) {
index e2fcad7cbb1f36b862adc38c59f2b0ac5193d53e..99bf06a9e9a9147b6cee6ef12665afee69245735 100644 (file)
@@ -115,7 +115,7 @@ IdleConnList::push(int fd)
         nfds_alloc <<= 1;
         int *old = fds;
         fds = (int *)xmalloc(nfds_alloc * sizeof(int));
-        xmemcpy(fds, old, nfds * sizeof(int));
+        memcpy(fds, old, nfds * sizeof(int));
 
         if (nfds == PCONN_FDS_SZ)
             pconn_fds_pool->freeOne(old);
@@ -367,9 +367,7 @@ PconnModule::registerWithCacheManager(void)
 }
 
 void
-
-PconnModule::add
-(PconnPool *aPool)
+PconnModule::add(PconnPool *aPool)
 {
     assert(poolCount < MAX_NUM_PCONN_POOLS);
     *(pools+poolCount) = aPool;
index 4f009ec93e592296c73dadd1388a13cf9d1154c4..d20525293e53912c2235c2fd7b0f40b0e99ed022 100644 (file)
@@ -491,7 +491,7 @@ peerDigestHandleReply(void *data, StoreIOBuffer receivedData)
          */
         newsize = fetch->bufofs - retsize;
 
-        xmemmove(fetch->buf, fetch->buf + retsize, fetch->bufofs - newsize);
+        memmove(fetch->buf, fetch->buf + retsize, fetch->bufofs - newsize);
 
         fetch->bufofs = newsize;
 
@@ -713,7 +713,7 @@ peerDigestSwapInMask(void *data, char *buf, ssize_t size)
      * NOTENOTENOTENOTENOTE: buf doesn't point to pd->cd->mask anymore!
      * we need to do the copy ourselves!
      */
-    xmemcpy(pd->cd->mask + fetch->mask_offset, buf, size);
+    memcpy(pd->cd->mask + fetch->mask_offset, buf, size);
 
     /* NOTE! buf points to the middle of pd->cd->mask! */
 
@@ -988,7 +988,7 @@ peerDigestSetCBlock(PeerDigest * pd, const char *buf)
     int freed_size = 0;
     const char *host = pd->host.termedBuf();
 
-    xmemcpy(&cblock, buf, sizeof(cblock));
+    memcpy(&cblock, buf, sizeof(cblock));
     /* network -> host conversions */
     cblock.ver.current = ntohs(cblock.ver.current);
     cblock.ver.required = ntohs(cblock.ver.required);
index 863c8bd4931bed8822726505751626683d0d807d..1d5ada7acd304b0bce5e3fab8dbbd27b3c370e06 100644 (file)
@@ -25,8 +25,9 @@
  * Hosted at http://sourceforge.net/projects/squidkerbauth
  */
 
-#include "squid.h"
+#include "config.h"
 #include "base64.h"
+#include "Debug.h"
 
 #if HAVE_KRB5 && HAVE_GSSAPI
 #ifdef __cplusplus
index beb25ecd120eff185bec377bf2ac972e830e68cb..599a9aa31146df60282d57e5884c74fa648a8440 100644 (file)
@@ -57,7 +57,6 @@ SQUIDCEXTERN void fvdbCountForw(const char *key);
 #if HEADERS_LOG
 SQUIDCEXTERN void headersLog(int cs, int pq, const HttpRequestMethod& m, void *data);
 #endif
-SQUIDCEXTERN char *log_quote(const char *header);
 SQUIDCEXTERN int logTypeIsATcpHit(log_type);
 
 /*
@@ -294,21 +293,21 @@ SQUIDCEXTERN void addr2oid(Ip::Address &addr, oid *Dest);
 SQUIDCEXTERN void oid2addr(oid *Dest, Ip::Address &addr, u_int code);
 
 SQUIDCEXTERN Ip::Address *client_entry(Ip::Address *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 *);
-SQUIDCEXTERN variable_list *snmp_prfSysFn(variable_list *, snint *);
-SQUIDCEXTERN variable_list *snmp_prfProtoFn(variable_list *, snint *);
-SQUIDCEXTERN variable_list *snmp_prfPeerFn(variable_list *, snint *);
-SQUIDCEXTERN variable_list *snmp_netIpFn(variable_list *, snint *);
-SQUIDCEXTERN variable_list *snmp_netFqdnFn(variable_list *, snint *);
+extern variable_list *snmp_basicFn(variable_list *, snint *);
+extern variable_list *snmp_confFn(variable_list *, snint *);
+extern variable_list *snmp_sysFn(variable_list *, snint *);
+extern variable_list *snmp_prfSysFn(variable_list *, snint *);
+extern variable_list *snmp_prfProtoFn(variable_list *, snint *);
+extern variable_list *snmp_prfPeerFn(variable_list *, snint *);
+extern variable_list *snmp_netIpFn(variable_list *, snint *);
+extern variable_list *snmp_netFqdnFn(variable_list *, snint *);
 #if USE_DNSSERVERS
-SQUIDCEXTERN variable_list *snmp_netDnsFn(variable_list *, snint *);
+extern variable_list *snmp_netDnsFn(variable_list *, snint *);
 #else
-SQUIDCEXTERN variable_list *snmp_netIdnsFn(variable_list *, snint *);
+extern variable_list *snmp_netIdnsFn(variable_list *, snint *);
 #endif /* USE_DNSSERVERS */
-SQUIDCEXTERN variable_list *snmp_meshPtblFn(variable_list *, snint *);
-SQUIDCEXTERN variable_list *snmp_meshCtblFn(variable_list *, snint *);
+extern variable_list *snmp_meshPtblFn(variable_list *, snint *);
+extern variable_list *snmp_meshCtblFn(variable_list *, snint *);
 #endif /* SQUID_SNMP */
 
 #if USE_WCCP
@@ -526,7 +525,7 @@ SQUIDCEXTERN void storeDigestInit(void);
 SQUIDCEXTERN void storeDigestNoteStoreReady(void);
 SQUIDCEXTERN void storeDigestScheduleRebuild(void);
 SQUIDCEXTERN void storeDigestDel(const StoreEntry * entry);
-SQUIDCEXTERN void storeDigestReport(StoreEntry *);
+extern void storeDigestReport(StoreEntry *);
 
 /*
  * store_rebuild.c
@@ -556,10 +555,9 @@ SQUIDCEXTERN int storeClientIsThisAClient(store_client * sc, void *someClient);
 SQUIDCEXTERN const char *getMyHostname(void);
 SQUIDCEXTERN const char *uniqueHostname(void);
 SQUIDCEXTERN void safeunlink(const char *path, int quiet);
+
+#include "fatal.h"
 void death(int sig);
-SQUIDCEXTERN void fatal(const char *message);
-SQUIDCEXTERN void fatalf(const char *fmt,...) PRINTF_FORMAT_ARG1;
-SQUIDCEXTERN void fatal_dump(const char *message);
 void sigusr2_handle(int sig);
 void sig_child(int sig);
 SQUIDCEXTERN void leave_suid(void);
@@ -569,7 +567,7 @@ SQUIDCEXTERN void writePidFile(void);
 SQUIDCEXTERN void setSocketShutdownLifetimes(int);
 SQUIDCEXTERN void setMaxFD(void);
 SQUIDCEXTERN void setSystemLimits(void);
-SQUIDCEXTERN void squid_signal(int sig, SIGHDLR *, int flags);
+extern void squid_signal(int sig, SIGHDLR *, int flags);
 SQUIDCEXTERN pid_t readPidFile(void);
 SQUIDCEXTERN void keepCapabilities(void);
 SQUIDCEXTERN void BroadcastSignalIfAny(int& sig);
@@ -632,14 +630,6 @@ SQUIDCEXTERN int urlDefaultPort(protocol_t p);
 SQUIDCEXTERN char *urlHostname(const char *url);
 SQUIDCEXTERN void urlExtMethodConfigure(void);
 
-SQUIDCEXTERN void useragentOpenLog(void);
-SQUIDCEXTERN void useragentRotateLog(void);
-SQUIDCEXTERN void logUserAgent(const char *, const char *);
-SQUIDCEXTERN void useragentLogClose(void);
-SQUIDCEXTERN void refererOpenLog(void);
-SQUIDCEXTERN void refererRotateLog(void);
-SQUIDCEXTERN void logReferer(const char *, const char *, const char *);
-SQUIDCEXTERN void refererCloseLog(void);
 SQUIDCEXTERN peer_t parseNeighborType(const char *s);
 
 /* tools.c */
@@ -742,7 +732,7 @@ SQUIDCEXTERN int varyEvaluateMatch(StoreEntry * entry, HttpRequest * req);
 
 /* CygWin & Windows NT Port */
 /* win32.c */
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
 SQUIDCEXTERN int WIN32_Subsystem_Init(int *, char ***);
 SQUIDCEXTERN void WIN32_sendSignal(int);
 SQUIDCEXTERN void WIN32_Abort(int);
@@ -751,7 +741,7 @@ SQUIDCEXTERN void WIN32_SetServiceCommandLine(void);
 SQUIDCEXTERN void WIN32_InstallService(void);
 SQUIDCEXTERN void WIN32_RemoveService(void);
 SQUIDCEXTERN int SquidMain(int, char **);
-#endif /* _SQUID_WIN32_ */
+#endif /* _SQUID_WINDOWS_ */
 #ifdef _SQUID_MSWIN_
 
 SQUIDCEXTERN int WIN32_pipe(int[2]);
index 9a7fdcb767351a98793ec3922a55f070cfc49e13..a57fb4e4432515ceed9ae0d9dfe25031de705e85 100644 (file)
@@ -121,7 +121,7 @@ main(int argc, char *argv[])
             exit(2);
         }
 
-        xmemcpy(ip, &R.sin_addr.s_addr, 4);
+        memcpy(ip, &R.sin_addr.s_addr, 4);
         hp = gethostbyaddr(ip, 4, AF_INET);
         ipa = R.sin_addr;
         printf("==============================================================================\n");
index 999474b5350d44bbc468eca273c02e4c4ad63829..ea777bc1f0a972d6287ac0c905238f0cd5695a3d 100644 (file)
 #include "acl/Checklist.h"
 #include "HttpRequest.h"
 #include "client_side.h"
+#include "client_side_reply.h"
 #include "helper.h"
 #include "rfc1738.h"
+#if USE_SSL
+#include "ssl/support.h"
+#endif
+
+/// url maximum lengh + extra informations passed to redirector
+#define MAX_REDIRECTOR_REQUEST_STRLEN (MAX_URL + 1024)
 
 typedef struct {
     void *data;
@@ -114,7 +121,9 @@ redirectStart(ClientHttpRequest * http, RH * handler, void *data)
     ConnStateData * conn = http->getConn();
     redirectStateData *r = NULL;
     const char *fqdn;
-    char buf[8192];
+    char buf[MAX_REDIRECTOR_REQUEST_STRLEN];
+    int sz;
+    http_status status;
     char claddr[MAX_IPSTRLEN];
     char myaddr[MAX_IPSTRLEN];
     assert(http);
@@ -164,14 +173,41 @@ redirectStart(ClientHttpRequest * http, RH * handler, void *data)
     if ((fqdn = fqdncache_gethostbyaddr(r->client_addr, 0)) == NULL)
         fqdn = dash_str;
 
-    snprintf(buf, 8192, "%s %s/%s %s %s myip=%s myport=%d\n",
-             r->orig_url,
-             r->client_addr.NtoA(claddr,MAX_IPSTRLEN),
-             fqdn,
-             r->client_ident[0] ? rfc1738_escape(r->client_ident) : dash_str,
-             r->method_s,
-             http->request->my_addr.NtoA(myaddr,MAX_IPSTRLEN),
-             http->request->my_addr.GetPort());
+    sz = snprintf(buf, MAX_REDIRECTOR_REQUEST_STRLEN, "%s %s/%s %s %s myip=%s myport=%d\n",
+                  r->orig_url,
+                  r->client_addr.NtoA(claddr,MAX_IPSTRLEN),
+                  fqdn,
+                  r->client_ident[0] ? rfc1738_escape(r->client_ident) : dash_str,
+                  r->method_s,
+                  http->request->my_addr.NtoA(myaddr,MAX_IPSTRLEN),
+                  http->request->my_addr.GetPort());
+
+    if ((sz<=0) || (sz>=MAX_REDIRECTOR_REQUEST_STRLEN)) {
+        if (sz<=0) {
+            status = HTTP_INTERNAL_SERVER_ERROR;
+            debugs(61, DBG_CRITICAL, "ERROR: Gateway Failure. Can not build request to be passed to redirector. Request ABORTED.");
+        } else {
+            status = HTTP_REQUEST_URI_TOO_LARGE;
+            debugs(61, DBG_CRITICAL, "ERROR: Gateway Failure. Request passed to redirector exceeds MAX_REDIRECTOR_REQUEST_STRLEN (" << MAX_REDIRECTOR_REQUEST_STRLEN << "). Request ABORTED.");
+        }
+
+        clientStreamNode *node = (clientStreamNode *)http->client_stream.tail->prev->data;
+        clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
+        assert (repContext);
+        Ip::Address tmpnoaddr;
+        tmpnoaddr.SetNoAddr();
+        repContext->setReplyToError(ERR_GATEWAY_FAILURE, status,
+                                    http->request->method, NULL,
+                                    http->getConn() != NULL ? http->getConn()->peer : tmpnoaddr,
+                                    http->request,
+                                    NULL,
+                                    http->getConn() != NULL && http->getConn()->auth_user_request != NULL ?
+                                    http->getConn()->auth_user_request : http->request->auth_user_request);
+
+        node = (clientStreamNode *)http->client_stream.tail->data;
+        clientStreamRead(node, http, node->readBuffer);
+        return;
+    }
 
     helperSubmit(redirectors, buf, redirectHandleReply, r);
 }
index 17b97ef1c0f45d72ac26fe295744480240cc1a4a..4617102a8e30750df539ae643d5cc3430ff0a602 100644 (file)
@@ -86,6 +86,7 @@ enum {
     STALE_EXPIRES,
     STALE_MAX_RULE,
     STALE_LMFACTOR_RULE,
+    STALE_MAX_STALE,
     STALE_DEFAULT = 299
 };
 
@@ -283,6 +284,15 @@ refreshCheck(const StoreEntry * entry, HttpRequest * request, time_t delta)
 
     debugs(22, 3, "Staleness = " << staleness);
 
+    // stale-if-error requires any failure be passed thru when its period is over.
+    if (request && entry->mem_obj && entry->mem_obj->getReply() && entry->mem_obj->getReply()->cache_control &&
+            EBIT_TEST(entry->mem_obj->getReply()->cache_control->mask, CC_STALE_IF_ERROR) &&
+            entry->mem_obj->getReply()->cache_control->stale_if_error < staleness) {
+
+        debugs(22, 3, "refreshCheck: stale-if-error period expired.");
+        request->flags.fail_on_validation_err = 1;
+    }
+
     if (EBIT_TEST(entry->flags, ENTRY_REVALIDATE) && staleness > -1
 #if USE_HTTP_VIOLATIONS
             && !R->flags.ignore_must_revalidate
@@ -379,7 +389,16 @@ refreshCheck(const StoreEntry * entry, HttpRequest * request, time_t delta)
     /*
      * At this point the response is stale, unless one of
      * the override options kicks in.
+     * NOTE: max-stale config blocks the overrides.
      */
+    int max_stale = (R->max_stale >= 0 ? R->max_stale : Config.maxStale);
+    if ( max_stale >= 0 && staleness < max_stale) {
+        debugs(22, 3, "refreshCheck: YES: max-stale limit");
+        if (request)
+            request->flags.fail_on_validation_err = 1;
+        return STALE_MAX_STALE;
+    }
+
     if (sf.expires) {
 #if USE_HTTP_VIOLATIONS
 
index 04bba820cde98201059fdb40997301537fb8a04d..773cceaf865cef87c6589b18195274a28363c9a6 100644 (file)
@@ -92,7 +92,7 @@ send_announce(const ipcache_addrs *ia, const DnsLookupDetails &, void *junk)
 
     snprintf(tbuf, 256, "generated %d [%s]\n",
              (int) squid_curtime,
-             mkhttpdlogtime(&squid_curtime));
+             Time::FormatHttpd(squid_curtime));
     strcat(sndbuf, tbuf);
     l = strlen(sndbuf);
 
diff --git a/src/snmp/Forwarder.cc b/src/snmp/Forwarder.cc
new file mode 100644 (file)
index 0000000..66f6f71
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 49    SNMP Interface
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "CommCalls.h"
+#include "ipc/Port.h"
+#include "snmp_core.h"
+#include "snmp/Forwarder.h"
+#include "snmp/Request.h"
+#include "snmp/Response.h"
+
+
+CBDATA_NAMESPACED_CLASS_INIT(Snmp, Forwarder);
+
+
+Snmp::Forwarder::Forwarder(const Pdu& aPdu, const Session& aSession, int aFd,
+                           const Ip::Address& anAddress):
+        Ipc::Forwarder(new Request(KidIdentifier, 0, aPdu, aSession, aFd, anAddress), 2),
+        fd(aFd)
+{
+    debugs(49, 5, HERE << "FD " << aFd);
+    Must(fd >= 0);
+    closer = asyncCall(49, 5, "Snmp::Forwarder::noteCommClosed",
+                       CommCbMemFunT<Forwarder, CommCloseCbParams>(this, &Forwarder::noteCommClosed));
+    comm_add_close_handler(fd, closer);
+}
+
+/// removes our cleanup handler of the client connection socket
+void
+Snmp::Forwarder::cleanup()
+{
+    if (fd >= 0) {
+        if (closer != NULL) {
+            comm_remove_close_handler(fd, closer);
+            closer = NULL;
+        }
+        fd = -1;
+    }
+}
+
+/// called when the client socket gets closed by some external force
+void
+Snmp::Forwarder::noteCommClosed(const CommCloseCbParams& params)
+{
+    debugs(49, 5, HERE);
+    Must(fd == params.fd);
+    fd = -1;
+    mustStop("commClosed");
+}
+
+void
+Snmp::Forwarder::handleTimeout()
+{
+    sendError(SNMP_ERR_RESOURCEUNAVAILABLE);
+    Ipc::Forwarder::handleTimeout();
+}
+
+void
+Snmp::Forwarder::handleException(const std::exception& e)
+{
+    debugs(49, 3, HERE << e.what());
+    if (fd >= 0)
+        sendError(SNMP_ERR_GENERR);
+    Ipc::Forwarder::handleException(e);
+}
+
+/// send error SNMP response
+void
+Snmp::Forwarder::sendError(int error)
+{
+    debugs(49, 3, HERE);
+    Snmp::Request& req = static_cast<Snmp::Request&>(*request);
+    req.pdu.command = SNMP_PDU_RESPONSE;
+    req.pdu.errstat = error;
+    u_char buffer[SNMP_REQUEST_SIZE];
+    int len = sizeof(buffer);
+    snmp_build(&req.session, &req.pdu, buffer, &len);
+    comm_udp_sendto(fd, req.address, buffer, len);
+}
+
+void
+Snmp::SendResponse(unsigned int requestId, const Pdu& pdu)
+{
+    debugs(49, 5, HERE);
+    // snmpAgentResponse() can modify arg
+    Pdu tmp = pdu;
+    Snmp::Response response(requestId);
+    snmp_pdu* response_pdu = NULL;
+    try {
+        response_pdu = snmpAgentResponse(&tmp);
+        Must(response_pdu != NULL);
+        response.pdu = static_cast<Pdu&>(*response_pdu);
+        snmp_free_pdu(response_pdu);
+    } catch (const std::exception& e) {
+        debugs(49, DBG_CRITICAL, HERE << e.what());
+        response.pdu.command = SNMP_PDU_RESPONSE;
+        response.pdu.errstat = SNMP_ERR_GENERR;
+    }
+    Ipc::TypedMsgHdr message;
+    response.pack(message);
+    Ipc::SendMessage(Ipc::coordinatorAddr, message);
+}
diff --git a/src/snmp/Forwarder.h b/src/snmp/Forwarder.h
new file mode 100644 (file)
index 0000000..aba0b17
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 49    SNMP Interface
+ *
+ */
+
+#ifndef SQUID_SNMPX_FORWARDER_H
+#define SQUID_SNMPX_FORWARDER_H
+
+#include "ipc/Forwarder.h"
+#include "snmp/Pdu.h"
+#include "snmp/Session.h"
+
+
+class CommCloseCbParams;
+
+namespace Snmp
+{
+
+/** Forwards a single client SNMP request to Coordinator.
+ * Waits for an ACK from Coordinator
+ * Send the data unit with an error response if forwarding fails.
+ */
+class Forwarder: public Ipc::Forwarder
+{
+public:
+    Forwarder(const Pdu& aPdu, const Session& aSession, int aFd,
+              const Ip::Address& anAddress);
+
+protected:
+    /* Ipc::Forwarder API */
+    virtual void cleanup(); ///< perform cleanup actions
+    virtual void handleTimeout();
+    virtual void handleException(const std::exception& e);
+
+private:
+    void noteCommClosed(const CommCloseCbParams& params);
+    void sendError(int error);
+
+private:
+    int fd; ///< client connection descriptor
+    AsyncCall::Pointer closer; ///< comm_close handler for the connection
+
+    CBDATA_CLASS2(Forwarder);
+};
+
+extern void SendResponse(unsigned int requestId, const Pdu& pdu);
+
+} // namespace Snmp
+
+#endif /* SQUID_SNMPX_FORWARDER_H */
diff --git a/src/snmp/Inquirer.cc b/src/snmp/Inquirer.cc
new file mode 100644 (file)
index 0000000..6d748b0
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 49    SNMP Interface
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "CommCalls.h"
+#include "ipc/UdsOp.h"
+#include "snmp_core.h"
+#include "snmp/Inquirer.h"
+#include "snmp/Response.h"
+#include "snmp/Request.h"
+
+
+CBDATA_NAMESPACED_CLASS_INIT(Snmp, Inquirer);
+
+
+Snmp::Inquirer::Inquirer(const Request& aRequest, const Ipc::StrandCoords& coords):
+        Ipc::Inquirer(aRequest.clone(), coords, 2),
+        aggrPdu(aRequest.pdu),
+        fd(ImportFdIntoComm(aRequest.fd, SOCK_DGRAM, IPPROTO_UDP, Ipc::fdnInSnmpSocket))
+{
+    debugs(49, 5, HERE);
+    closer = asyncCall(49, 5, "Snmp::Inquirer::noteCommClosed",
+                       CommCbMemFunT<Inquirer, CommCloseCbParams>(this, &Inquirer::noteCommClosed));
+    comm_add_close_handler(fd, closer);
+}
+
+/// closes our copy of the client connection socket
+void
+Snmp::Inquirer::cleanup()
+{
+    if (fd >= 0) {
+        if (closer != NULL) {
+            comm_remove_close_handler(fd, closer);
+            closer = NULL;
+        }
+        comm_close(fd);
+        fd = -1;
+    }
+}
+
+void
+Snmp::Inquirer::start()
+{
+    debugs(49, 5, HERE);
+    Ipc::Inquirer::start();
+    Must(fd >= 0);
+    inquire();
+}
+
+void
+Snmp::Inquirer::handleException(const std::exception& e)
+{
+    aggrPdu.errstat = SNMP_ERR_GENERR;
+    Ipc::Inquirer::handleException(e);
+}
+
+bool
+Snmp::Inquirer::aggregate(Response::Pointer aResponse)
+{
+    Snmp::Response& response = static_cast<Snmp::Response&>(*aResponse);
+    bool error = response.pdu.errstat != SNMP_ERR_NOERROR;
+    if (error) {
+        aggrPdu = response.pdu;
+    } else {
+        aggrPdu.aggregate(response.pdu);
+    }
+    return !error;
+}
+
+/// called when the some external force closed our socket
+void
+Snmp::Inquirer::noteCommClosed(const CommCloseCbParams& params)
+{
+    debugs(49, 5, HERE);
+    Must(fd < 0 || fd == params.fd);
+    fd = -1;
+    mustStop("commClosed");
+}
+
+bool
+Snmp::Inquirer::doneAll() const
+{
+    return !writer && Ipc::Inquirer::doneAll();
+}
+
+void
+Snmp::Inquirer::sendResponse()
+{
+    debugs(49, 5, HERE);
+    aggrPdu.fixAggregate();
+    aggrPdu.command = SNMP_PDU_RESPONSE;
+    u_char buffer[SNMP_REQUEST_SIZE];
+    int len = sizeof(buffer);
+    Snmp::Request& req = static_cast<Snmp::Request&>(*request);
+    snmp_build(&req.session, &aggrPdu, buffer, &len);
+    comm_udp_sendto(fd, req.address, buffer, len);
+}
diff --git a/src/snmp/Inquirer.h b/src/snmp/Inquirer.h
new file mode 100644 (file)
index 0000000..5efcdcf
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 49    SNMP Interface
+ *
+ */
+
+#ifndef SQUID_SNMPX_INQUIRER_H
+#define SQUID_SNMPX_INQUIRER_H
+
+#include "ipc/Inquirer.h"
+#include "snmp/forward.h"
+#include "snmp/Pdu.h"
+
+
+class CommCloseCbParams;
+
+namespace Snmp
+{
+
+/// Coordinator's job that sends a PDU request to each strand,
+/// aggregates strand responses and send back the result to client
+class Inquirer: public Ipc::Inquirer
+{
+public:
+    Inquirer(const Request& aRequest, const Ipc::StrandCoords& coords);
+
+protected:
+    /* AsyncJob API */
+    virtual void start();
+    virtual bool doneAll() const;
+
+    /* Ipc::Inquirer API */
+    virtual void cleanup();
+    virtual void handleException(const std::exception& e);
+    virtual void sendResponse();
+    virtual bool aggregate(Ipc::Response::Pointer aResponse);
+
+private:
+    void noteCommClosed(const CommCloseCbParams& params);
+
+private:
+    Pdu aggrPdu; ///< aggregated pdu
+    int fd; ///< client connection descriptor
+
+    AsyncCall::Pointer writer; ///< comm_write callback
+    AsyncCall::Pointer closer; ///< comm_close handler
+
+    CBDATA_CLASS2(Inquirer);
+};
+
+} // namespace Snmp
+
+#endif /* SQUID_SNMPX_INQUIRER_H */
diff --git a/src/snmp/Makefile.am b/src/snmp/Makefile.am
new file mode 100644 (file)
index 0000000..39d6036
--- /dev/null
@@ -0,0 +1,24 @@
+include $(top_srcdir)/src/Common.am
+include $(top_srcdir)/src/TestHeaders.am
+
+
+noinst_LTLIBRARIES = libsnmp.la
+
+libsnmp_la_SOURCES = \
+       Forwarder.cc \
+       Forwarder.h \
+       forward.h \
+       Inquirer.cc \
+       Inquirer.h \
+       Pdu.cc \
+       Pdu.h \
+       Request.cc \
+       Request.h \
+       Response.cc \
+       Response.h \
+       Session.cc \
+       Session.h \
+       Var.cc \
+       Var.h
+
+DEFS += -DDEFAULT_PREFIX=\"$(prefix)\"
diff --git a/src/snmp/Pdu.cc b/src/snmp/Pdu.cc
new file mode 100644 (file)
index 0000000..db1af89
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 49    SNMP Interface
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "ipc/TypedMsgHdr.h"
+#include "protos.h"
+#include "snmp_core.h"
+#include "snmp/Pdu.h"
+#include "snmp/Var.h"
+
+
+Snmp::Pdu::Pdu()
+{
+    init();
+}
+
+Snmp::Pdu::Pdu(const Pdu& pdu)
+{
+    init();
+    assign(pdu);
+}
+
+Snmp::Pdu::~Pdu()
+{
+    clear();
+}
+
+Snmp::Pdu&
+Snmp::Pdu::operator = (const Pdu& pdu)
+{
+    clear();
+    assign(pdu);
+    return *this;
+}
+
+void
+Snmp::Pdu::init()
+{
+    xmemset(this, 0, sizeof(*this));
+    errstat = SNMP_DEFAULT_ERRSTAT;
+    errindex = SNMP_DEFAULT_ERRINDEX;
+}
+
+void
+Snmp::Pdu::aggregate(const Pdu& pdu)
+{
+    Must(varCount() == pdu.varCount());
+    aggrCount++;
+    for (variable_list* p_aggr = variables, *p_var = pdu.variables; p_var != NULL;
+            p_aggr = p_aggr->next_variable, p_var = p_var->next_variable) {
+        Must(p_aggr != NULL);
+        Var& aggr = static_cast<Var&>(*p_aggr);
+        Var& var = static_cast<Var&>(*p_var);
+        if (aggr.isNull()) {
+            aggr.setName(var.getName());
+            aggr.copyValue(var);
+        } else {
+            switch (snmpAggrType(aggr.name, aggr.name_length)) {
+            case atSum:
+            case atAverage:
+                // The mean-average division is done later
+                // when the Snmp::Pdu::fixAggregate() called
+                aggr += var;
+                break;
+            case atMax:
+                if (var > aggr)
+                    aggr.copyValue(var);
+                break;
+            case atMin:
+                if (var < aggr)
+                    aggr.copyValue(var);
+                break;
+            default:
+                break;
+            }
+        }
+    }
+}
+
+void
+Snmp::Pdu::clear()
+{
+    clearSystemOid();
+    clearVars();
+    init();
+}
+
+void
+Snmp::Pdu::assign(const Pdu& pdu)
+{
+    command = pdu.command;
+    address.sin_addr.s_addr = pdu.address.sin_addr.s_addr;
+    reqid = pdu.reqid;
+    errstat = pdu.errstat;
+    errindex = pdu.errindex;
+    non_repeaters = pdu.non_repeaters;
+    max_repetitions = pdu.max_repetitions;
+    agent_addr.sin_addr.s_addr = pdu.agent_addr.sin_addr.s_addr;
+    trap_type = pdu.trap_type;
+    specific_type = pdu.specific_type;
+    time = pdu.time;
+    aggrCount = pdu.aggrCount;
+    setSystemOid(pdu.getSystemOid());
+    setVars(pdu.variables);
+}
+
+void
+Snmp::Pdu::clearVars()
+{
+    variable_list* var = variables;
+    while (var != NULL) {
+        variable_list* tmp = var;
+        var = var->next_variable;
+        snmp_var_free(tmp);
+    }
+    variables = NULL;
+}
+
+void
+Snmp::Pdu::setVars(variable_list* vars)
+{
+    clearVars();
+    for (variable_list** p_var = &variables; vars != NULL;
+            vars = vars->next_variable, p_var = &(*p_var)->next_variable) {
+        *p_var = new Var(static_cast<Var&>(*vars));
+    }
+}
+
+void
+Snmp::Pdu::clearSystemOid()
+{
+    if (enterprise != NULL) {
+        xfree(enterprise);
+        enterprise = NULL;
+    }
+    enterprise_length = 0;
+}
+
+Range<const oid*>
+Snmp::Pdu::getSystemOid() const
+{
+    return Range<const oid*>(enterprise, enterprise + enterprise_length);
+}
+
+void
+Snmp::Pdu::setSystemOid(const Range<const oid*>& systemOid)
+{
+    clearSystemOid();
+    if (systemOid.start != NULL && systemOid.size() != 0) {
+        enterprise_length = systemOid.size();
+        enterprise = static_cast<oid*>(xmalloc(enterprise_length * sizeof(oid)));
+        std::copy(systemOid.start, systemOid.end, enterprise);
+    }
+}
+
+void
+Snmp::Pdu::pack(Ipc::TypedMsgHdr& msg) const
+{
+    msg.putPod(command);
+    msg.putPod(address);
+    msg.putPod(reqid);
+    msg.putPod(errstat);
+    msg.putPod(errindex);
+    msg.putPod(non_repeaters);
+    msg.putPod(max_repetitions);
+    msg.putInt(enterprise_length);
+    if (enterprise_length > 0) {
+        Must(enterprise != NULL);
+        msg.putFixed(enterprise, enterprise_length * sizeof(oid));
+    }
+    msg.putPod(agent_addr);
+    msg.putPod(trap_type);
+    msg.putPod(specific_type);
+    msg.putPod(time);
+    msg.putInt(varCount());
+    for (variable_list* var = variables; var != NULL; var = var->next_variable)
+        static_cast<Var*>(var)->pack(msg);
+}
+
+void
+Snmp::Pdu::unpack(const Ipc::TypedMsgHdr& msg)
+{
+    clear();
+    msg.getPod(command);
+    msg.getPod(address);
+    msg.getPod(reqid);
+    msg.getPod(errstat);
+    msg.getPod(errindex);
+    msg.getPod(non_repeaters);
+    msg.getPod(max_repetitions);
+    enterprise_length = msg.getInt();
+    if (enterprise_length > 0) {
+        enterprise = static_cast<oid*>(xmalloc(enterprise_length * sizeof(oid)));
+        msg.getFixed(enterprise, enterprise_length * sizeof(oid));
+    }
+    msg.getPod(agent_addr);
+    msg.getPod(trap_type);
+    msg.getPod(specific_type);
+    msg.getPod(time);
+    int count = msg.getInt();
+    for (variable_list** p_var = &variables; count > 0;
+            p_var = &(*p_var)->next_variable, --count) {
+        Var* var = new Var();
+        var->unpack(msg);
+        *p_var = var;
+    }
+}
+
+int
+Snmp::Pdu::varCount() const
+{
+    int count = 0;
+    for (variable_list* var = variables; var != NULL; var = var->next_variable)
+        ++count;
+    return count;
+}
+
+void
+Snmp::Pdu::fixAggregate()
+{
+    if (aggrCount < 2)
+        return;
+    for (variable_list* p_aggr = variables; p_aggr != NULL; p_aggr = p_aggr->next_variable) {
+        Var& aggr = static_cast<Var&>(*p_aggr);
+        if (snmpAggrType(aggr.name, aggr.name_length) == atAverage) {
+            aggr /= aggrCount;
+        }
+    }
+    aggrCount = 0;
+}
diff --git a/src/snmp/Pdu.h b/src/snmp/Pdu.h
new file mode 100644 (file)
index 0000000..2069539
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 49    SNMP Interface
+ *
+ */
+
+#ifndef SQUID_SNMPX_PDU_H
+#define SQUID_SNMPX_PDU_H
+
+#include "config.h"
+#include "ipc/forward.h"
+#include "Range.h"
+#include "snmp.h"
+
+
+namespace Snmp
+{
+
+/// snmp_pdu wrapper introduce the feature
+/// to aggregate variables and to pack/unpack message
+class Pdu: public snmp_pdu
+{
+public:
+    Pdu();
+    Pdu(const Pdu& pdu);
+    Pdu& operator = (const Pdu& pdu);
+    ~Pdu();
+
+    void aggregate(const Pdu& pdu);
+    void fixAggregate();
+    void pack(Ipc::TypedMsgHdr& msg) const; ///< prepare for sendmsg()
+    void unpack(const Ipc::TypedMsgHdr& msg); ///< restore struct from the message
+    int  varCount() const; ///< size of variables list
+    void clear();  ///< clear all internal members
+    void setVars(variable_list* vars); ///< perform assignment of variables list
+    void clearVars(); ///< clear variables list
+    Range<const oid*> getSystemOid() const;
+    void setSystemOid(const Range<const oid*>& systemOid);
+    void clearSystemOid();
+
+private:
+    void init(); ///< initialize members
+    void assign(const Pdu& pdu); ///< perform full assignment
+    unsigned int aggrCount;  ///< The number of other Pdus merged into
+};
+
+} // namespace Snmp
+
+#endif /* SQUID_SNMPX_PDU_H */
diff --git a/src/snmp/Request.cc b/src/snmp/Request.cc
new file mode 100644 (file)
index 0000000..b204f8c
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 49    SNMP Interface
+ *
+ */
+
+#include "config.h"
+#include "ipc/Messages.h"
+#include "ipc/TypedMsgHdr.h"
+#include "snmp/Request.h"
+
+
+Snmp::Request::Request(int aRequestorId, unsigned int aRequestId,
+                       const Pdu& aPdu, const Session& aSession,
+                       int aFd, const Ip::Address& anAddress):
+        Ipc::Request(aRequestorId, aRequestId),
+        pdu(aPdu), session(aSession), fd(aFd), address(anAddress)
+{
+}
+
+Snmp::Request::Request(const Request& request):
+        Ipc::Request(request.requestorId, request.requestId),
+        pdu(request.pdu), session(request.session),
+        fd(request.fd), address(request.address)
+{
+}
+
+Snmp::Request::Request(const Ipc::TypedMsgHdr& msg):
+        Ipc::Request(0, 0)
+{
+    msg.checkType(Ipc::mtSnmpRequest);
+    msg.getPod(requestorId);
+    msg.getPod(requestId);
+    pdu.unpack(msg);
+    session.unpack(msg);
+    msg.getPod(address);
+
+    fd = msg.getFd();
+}
+
+void
+Snmp::Request::pack(Ipc::TypedMsgHdr& msg) const
+{
+    msg.setType(Ipc::mtSnmpRequest);
+    msg.putPod(requestorId);
+    msg.putPod(requestId);
+    pdu.pack(msg);
+    session.pack(msg);
+    msg.putPod(address);
+
+    msg.putFd(fd);
+}
+
+Ipc::Request::Pointer
+Snmp::Request::clone() const
+{
+    return new Request(*this);
+}
diff --git a/src/snmp/Request.h b/src/snmp/Request.h
new file mode 100644 (file)
index 0000000..f515b0b
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 49    SNMP Interface
+ *
+ */
+
+#ifndef SQUID_SNMPX_REQUEST_H
+#define SQUID_SNMPX_REQUEST_H
+
+#include "ip/Address.h"
+#include "ipc/forward.h"
+#include "ipc/Request.h"
+#include "snmp/Pdu.h"
+#include "snmp/Session.h"
+
+
+namespace Snmp
+{
+
+/// SNMP request
+class Request: public Ipc::Request
+{
+public:
+    Request(int aRequestorId, unsigned int aRequestId, const Pdu& aPdu,
+            const Session& aSession, int aFd, const Ip::Address& anAddress);
+
+    explicit Request(const Ipc::TypedMsgHdr& msg); ///< from recvmsg()
+    /* Ipc::Request API */
+    virtual void pack(Ipc::TypedMsgHdr& msg) const;
+    virtual Pointer clone() const;
+
+private:
+    Request(const Request& request);
+
+public:
+    Pdu pdu; ///< SNMP protocol data unit
+    Session session; ///< SNMP session
+    int fd; ///< client connection descriptor
+    Ip::Address address; ///< client address
+};
+
+
+} // namespace Snmp
+
+#endif /* SQUID_SNMPX_REQUEST_H */
diff --git a/src/snmp/Response.cc b/src/snmp/Response.cc
new file mode 100644 (file)
index 0000000..0128f16
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 49    SNMP Interface
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "ipc/Messages.h"
+#include "ipc/TypedMsgHdr.h"
+#include "snmp/Response.h"
+
+
+std::ostream& Snmp::operator << (std::ostream& os, const Response& response)
+{
+    os << "response: {requestId: " << response.requestId << '}';
+    return os;
+}
+
+Snmp::Response::Response(unsigned int aRequestId):
+        Ipc::Response(aRequestId), pdu()
+{
+}
+
+Snmp::Response::Response(const Response& response):
+        Ipc::Response(response.requestId), pdu(response.pdu)
+{
+}
+
+Snmp::Response::Response(const Ipc::TypedMsgHdr& msg):
+        Ipc::Response(0)
+{
+    msg.checkType(Ipc::mtSnmpResponse);
+    msg.getPod(requestId);
+    pdu.unpack(msg);
+}
+
+void
+Snmp::Response::pack(Ipc::TypedMsgHdr& msg) const
+{
+    msg.setType(Ipc::mtSnmpResponse);
+    msg.putPod(requestId);
+    pdu.pack(msg);
+}
+
+Ipc::Response::Pointer
+Snmp::Response::clone() const
+{
+    return new Response(*this);
+}
diff --git a/src/snmp/Response.h b/src/snmp/Response.h
new file mode 100644 (file)
index 0000000..b2bf360
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 49    SNMP Interface
+ *
+ */
+
+#ifndef SQUID_SNMPX_RESPONSE_H
+#define SQUID_SNMPX_RESPONSE_H
+
+#include "ipc/forward.h"
+#include "ipc/Response.h"
+#include "snmp/Pdu.h"
+#include <ostream>
+
+namespace Snmp
+{
+
+///
+class Response: public Ipc::Response
+{
+public:
+    Response(unsigned int aRequestId);
+    explicit Response(const Ipc::TypedMsgHdr& msg); ///< from recvmsg()
+    /* Ipc::Response API */
+    virtual void pack(Ipc::TypedMsgHdr& msg) const;
+    virtual Ipc::Response::Pointer clone() const;
+
+private:
+    Response(const Response& response);
+
+public:
+    Pdu pdu; ///< SNMP protocol data unit
+};
+
+extern std::ostream& operator << (std::ostream& os, const Response& response);
+
+} // namespace Snmp
+
+#endif /* SQUID_SNMPX_RESPONSE_H */
diff --git a/src/snmp/Session.cc b/src/snmp/Session.cc
new file mode 100644 (file)
index 0000000..566ec96
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 49    SNMP Interface
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "ipc/TypedMsgHdr.h"
+#include "protos.h"
+#include "snmp/Session.h"
+
+
+Snmp::Session::Session()
+{
+    clear();
+}
+
+Snmp::Session::Session(const Session& session)
+{
+    assign(session);
+}
+
+Snmp::Session::~Session()
+{
+    free();
+}
+
+Snmp::Session&
+Snmp::Session::operator = (const Session& session)
+{
+    free();
+    assign(session);
+    return *this;
+}
+
+void
+Snmp::Session::clear()
+{
+    xmemset(this, 0, sizeof(*this));
+}
+
+void
+Snmp::Session::free()
+{
+    if (community_len > 0) {
+        Must(community != NULL);
+        xfree(community);
+    }
+    if (peername != NULL)
+        xfree(peername);
+    clear();
+}
+
+void
+Snmp::Session::assign(const Session& session)
+{
+    memcpy(this, &session, sizeof(*this));
+    if (session.community != NULL) {
+        community = (u_char*)xstrdup((char*)session.community);
+        Must(community != NULL);
+    }
+    if (session.peername != NULL) {
+        peername = xstrdup(session.peername);
+        Must(peername != NULL);
+    }
+}
+
+void
+Snmp::Session::pack(Ipc::TypedMsgHdr& msg) const
+{
+    msg.putPod(Version);
+    msg.putInt(community_len);
+    if (community_len > 0) {
+        Must(community != NULL);
+        msg.putFixed(community, community_len);
+    }
+    msg.putPod(retries);
+    msg.putPod(timeout);
+    int len = peername != NULL ? strlen(peername) : 0;
+    msg.putInt(len);
+    if (len > 0)
+        msg.putFixed(peername, len);
+    msg.putPod(remote_port);
+    msg.putPod(local_port);
+}
+
+void
+Snmp::Session::unpack(const Ipc::TypedMsgHdr& msg)
+{
+    free();
+    msg.getPod(Version);
+    community_len = msg.getInt();
+    if (community_len > 0) {
+        community = static_cast<u_char*>(xmalloc(community_len + 1));
+        Must(community != NULL);
+        msg.getFixed(community, community_len);
+        community[community_len] = 0;
+    }
+    msg.getPod(retries);
+    msg.getPod(timeout);
+    int len = msg.getInt();
+    if (len > 0) {
+        peername = static_cast<char*>(xmalloc(len + 1));
+        Must(peername != NULL);
+        msg.getFixed(peername, len);
+        peername[len] = 0;
+    }
+    msg.getPod(remote_port);
+    msg.getPod(local_port);
+}
diff --git a/src/snmp/Session.h b/src/snmp/Session.h
new file mode 100644 (file)
index 0000000..6e93f81
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 49    SNMP Interface
+ *
+ */
+
+#ifndef SQUID_SNMPX_SESSION_H
+#define SQUID_SNMPX_SESSION_H
+
+#include "config.h"
+#include "ipc/forward.h"
+#include "snmp.h"
+#include "snmp_session.h"
+
+
+namespace Snmp
+{
+
+/// snmp_session wrapper add pack/unpack feature
+class Session: public snmp_session
+{
+public:
+    Session();
+    Session(const Session& session);
+    Session& operator = (const Session& session);
+    ~Session();
+
+    void pack(Ipc::TypedMsgHdr& msg) const; ///< prepare for sendmsg()
+    void unpack(const Ipc::TypedMsgHdr& msg); ///< restore struct from the message
+    void clear(); ///< clear internal members
+
+private:
+    void free();  ///< free internal members
+    void assign(const Session& session); ///< perform full assignment
+};
+
+} // namespace Snmp
+
+#endif /* SQUID_SNMPX_SESSION_H */
diff --git a/src/snmp/Var.cc b/src/snmp/Var.cc
new file mode 100644 (file)
index 0000000..3a6a6b9
--- /dev/null
@@ -0,0 +1,356 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 49    SNMP Interface
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "ipc/TypedMsgHdr.h"
+#include "protos.h"
+#include "snmp/Var.h"
+
+
+Snmp::Var::Var()
+{
+    init();
+}
+
+Snmp::Var::Var(const Var& var)
+{
+    init();
+    assign(var);
+}
+
+Snmp::Var::~Var()
+{
+    clear();
+}
+
+Snmp::Var&
+Snmp::Var::operator = (const Var& var)
+{
+    clear();
+    assign(var);
+    return *this;
+}
+
+void
+Snmp::Var::init()
+{
+    xmemset(this, 0, sizeof(*this));
+}
+
+Snmp::Var&
+Snmp::Var::operator += (const Var& var)
+{
+    switch (type) {
+    case SMI_INTEGER:
+        setInt(asInt() + var.asInt());
+        break;
+    case SMI_GAUGE32:
+        setGauge(asGauge() + var.asGauge());
+        break;
+    case SMI_COUNTER32:
+        setCounter(asCounter() + var.asCounter());
+        break;
+    case SMI_COUNTER64:
+        setCounter64(asCounter64() + var.asCounter64());
+        break;
+    case SMI_TIMETICKS:
+        setTimeTicks(asTimeTicks() + var.asTimeTicks());
+        break;
+    default:
+        debugs(49, DBG_CRITICAL, HERE << "Unsupported type: " << type);
+        throw TexcHere("Unsupported type");
+        break;
+    }
+    return *this;
+}
+
+Snmp::Var&
+Snmp::Var::operator /= (int num)
+{
+    Must(num != 0);
+    switch (type) {
+    case SMI_INTEGER:
+        setInt(asInt() / num);
+        break;
+    case SMI_GAUGE32:
+        setGauge(asGauge() / num);
+        break;
+    case SMI_COUNTER32:
+        setCounter(asCounter() / num);
+        break;
+    case SMI_COUNTER64:
+        setCounter64(asCounter64() / num);
+        break;
+    case SMI_TIMETICKS:
+        setTimeTicks(asTimeTicks() / num);
+        break;
+    default:
+        debugs(49, DBG_CRITICAL, HERE << "Unsupported type: " << type);
+        throw TexcHere("Unsupported type");
+        break;
+    }
+    return *this;
+}
+
+bool
+Snmp::Var::operator < (const Var& var) const
+{
+    switch (type) {
+    case SMI_INTEGER:
+        return asInt() < var.asInt();
+    case SMI_GAUGE32:
+        return asGauge() < var.asGauge();
+    case SMI_COUNTER32:
+        return asCounter() < var.asCounter();
+    case SMI_COUNTER64:
+        return asCounter64() < var.asCounter64();
+    case SMI_TIMETICKS:
+        return asTimeTicks() < var.asTimeTicks();
+    default:
+        debugs(49, DBG_CRITICAL, HERE << "Unsupported type: " << type);
+        throw TexcHere("Unsupported type");
+        break;
+    }
+    return false; // unreachable
+}
+
+bool
+Snmp::Var::operator > (const Var& var) const
+{
+    switch (type) {
+    case SMI_INTEGER:
+        return asInt() > var.asInt();
+    case SMI_GAUGE32:
+        return asGauge() > var.asGauge();
+    case SMI_COUNTER32:
+        return asCounter() > var.asCounter();
+    case SMI_COUNTER64:
+        return asCounter64() > var.asCounter64();
+    case SMI_TIMETICKS:
+        return asTimeTicks() > var.asTimeTicks();
+    default:
+        debugs(49, DBG_CRITICAL, HERE << "Unsupported type: " << type);
+        throw TexcHere("Unsupported type");
+        break;
+    }
+    return false; // unreachable
+}
+
+void
+Snmp::Var::assign(const Var& var)
+{
+    setName(var.getName());
+    copyValue(var);
+}
+
+void
+Snmp::Var::clearName()
+{
+    if (name != NULL) {
+        xfree(name);
+        name = NULL;
+    }
+    name_length = 0;
+}
+
+Range<const oid*>
+Snmp::Var::getName() const
+{
+    return Range<const oid*>(name, name + name_length);
+}
+
+void
+Snmp::Var::setName(const Range<const oid*>& aName)
+{
+    clearName();
+    if (aName.start != NULL && aName.size() != 0) {
+        name_length = aName.size();
+        name = static_cast<oid*>(xmalloc(name_length * sizeof(oid)));
+        std::copy(aName.start, aName.end, name);
+    }
+}
+
+void
+Snmp::Var::clearValue()
+{
+    if (val.string != NULL) {
+        xfree(val.string);
+        val.string = NULL;
+    }
+    val_len = 0;
+    type = 0;
+}
+
+bool
+Snmp::Var::isNull() const
+{
+    return type == SMI_NULLOBJ;
+}
+
+int
+Snmp::Var::asInt() const
+{
+    Must(type == SMI_INTEGER);
+    Must(val.integer != NULL && val_len == sizeof(int));
+    return *val.integer;
+}
+
+unsigned int
+Snmp::Var::asGauge() const
+{
+    Must(type == SMI_GAUGE32);
+    Must(val.integer != NULL && val_len == 4);
+    return *reinterpret_cast<unsigned int*>(val.integer);
+}
+
+int
+Snmp::Var::asCounter() const
+{
+    Must(type == SMI_COUNTER32);
+    Must(val.integer != NULL && val_len == 4);
+    return *reinterpret_cast<int*>(val.integer);
+}
+
+long long int
+Snmp::Var::asCounter64() const
+{
+    Must(type == SMI_COUNTER64);
+    Must(val.integer != NULL && val_len == 8);
+    return *reinterpret_cast<long long int*>(val.integer);
+}
+
+unsigned int
+Snmp::Var::asTimeTicks() const
+{
+    Must(type == SMI_TIMETICKS);
+    Must(val.integer != NULL && val_len == sizeof(unsigned int));
+    return *reinterpret_cast<unsigned int*>(val.integer);
+}
+
+Range<const oid*>
+Snmp::Var::asObject() const
+{
+    Must(type == SMI_OBJID);
+    Must(val_len % sizeof(oid) == 0);
+    int length = val_len / sizeof(oid);
+    Must(val.objid != NULL && length > 0);
+    return Range<const oid*>(val.objid, val.objid + length);
+}
+
+Range<const u_char*>
+Snmp::Var::asString() const
+{
+    Must(type == SMI_STRING);
+    Must(val.string != NULL && val_len > 0);
+    return Range<const u_char*>(val.string, val.string + val_len);
+}
+
+void
+Snmp::Var::setInt(int value)
+{
+    setValue(&value, sizeof(value), SMI_INTEGER);
+}
+
+void
+Snmp::Var::setCounter(int value)
+{
+    setValue(&value, sizeof(value), SMI_COUNTER32);
+}
+
+void
+Snmp::Var::setGauge(unsigned int value)
+{
+    setValue(&value, sizeof(value), SMI_GAUGE32);
+}
+
+void
+Snmp::Var::setString(const Range<const u_char*>& string)
+{
+    setValue(string.start, string.size(), SMI_STRING);
+}
+
+void
+Snmp::Var::setObject(const Range<const oid*>& object)
+{
+    setValue(object.start, object.size() * sizeof(oid), SMI_OBJID);
+}
+
+void
+Snmp::Var::setCounter64(long long int counter)
+{
+    setValue(&counter, sizeof(counter), SMI_COUNTER64);
+}
+
+void
+Snmp::Var::setTimeTicks(unsigned int ticks)
+{
+    setValue(&ticks, sizeof(ticks), SMI_TIMETICKS);
+}
+
+void
+Snmp::Var::copyValue(const Var& var)
+{
+    setValue(var.val.string, var.val_len, var.type);
+}
+
+void
+Snmp::Var::setValue(const void* value, int length, int aType)
+{
+    clearValue();
+    if (value != NULL) {
+        Must(length > 0 && aType > 0);
+        val.string = static_cast<u_char*>(xmalloc(length));
+        memcpy(val.string, value, length);
+    }
+    val_len = length;
+    type = aType;
+}
+
+void
+Snmp::Var::clear()
+{
+    clearName();
+    clearValue();
+    init();
+}
+
+void
+Snmp::Var::pack(Ipc::TypedMsgHdr& msg) const
+{
+    msg.putInt(name_length);
+    if (name_length > 0) {
+        Must(name != NULL);
+        msg.putFixed(name, name_length * sizeof(oid));
+    }
+    msg.putPod(type);
+    msg.putPod(val_len);
+    if (val_len > 0) {
+        Must(val.string != NULL);
+        msg.putFixed(val.string, val_len);
+    }
+}
+
+void
+Snmp::Var::unpack(const Ipc::TypedMsgHdr& msg)
+{
+    clearName();
+    clearValue();
+    name_length = msg.getInt();
+    Must(name_length >= 0);
+    if (name_length > 0) {
+        name = static_cast<oid*>(xmalloc(name_length * sizeof(oid)));
+        msg.getFixed(name, name_length * sizeof(oid));
+    }
+    msg.getPod(type);
+    val_len = msg.getInt();
+    Must(val_len >= 0);
+    if (val_len > 0) {
+        val.string = static_cast<u_char*>(xmalloc(val_len));
+        msg.getFixed(val.string, val_len);
+    }
+}
diff --git a/src/snmp/Var.h b/src/snmp/Var.h
new file mode 100644 (file)
index 0000000..bd0adb2
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 49    SNMP Interface
+ *
+ */
+
+#ifndef SQUID_SNMPX_VAR_H
+#define SQUID_SNMPX_VAR_H
+
+#include "config.h"
+#include "ipc/forward.h"
+#include "Range.h"
+#include "snmp_vars.h"
+
+
+namespace Snmp
+{
+
+/// variable_list wrapper implement the feature to change
+/// the name/value of variable and to pack/unpack message
+class Var: public variable_list
+{
+public:
+    Var();
+    Var(const Var& var);
+    Var& operator = (const Var& var);
+    ~Var();
+
+    Var& operator += (const Var& var);
+    Var& operator /= (int num);
+    bool operator < (const Var& var) const;
+    bool operator > (const Var& var) const;
+
+    void pack(Ipc::TypedMsgHdr& msg) const; ///< prepare for sendmsg()
+    void unpack(const Ipc::TypedMsgHdr& msg); ///< restore struct from the message
+
+    Range<const oid*> getName() const; ///< returns variable name
+    void setName(const Range<const oid*>& aName); ///< set new variable name
+    void clearName(); ///< clear variable name
+
+    bool isNull() const;
+
+    int asInt() const; ///< returns variable value as integer
+    unsigned int asGauge() const; ///< returns variable value as unsigned int
+    int asCounter() const; ///< returns variable value as Counter32
+    long long int asCounter64() const; ///< returns variable value as Counter64
+    unsigned int asTimeTicks() const; ///< returns variable value as time ticks
+    Range<const oid*> asObject() const; ///< returns variable value as object oid
+    Range<const u_char*> asString() const; ///< returns variable value as chars string
+
+    void setInt(int value); ///< assign int value to variable
+    void setCounter(int value); ///< assign Counter32 value to variable
+    void setGauge(unsigned int value); ///< assign unsigned int value to variable
+    void setString(const Range<const u_char*>& string); ///< assign string to variable
+    void setObject(const Range<const oid*>& object); ///< assign object oid to variable
+    void setTimeTicks(unsigned int ticks); ///<assign unsigned int (time) value to variable
+    void setCounter64(long long int counter); ///< assign Counter64 value to variable
+
+    void copyValue(const Var& var); ///< copy variable from another one
+    void clearValue(); ///< clear .val member
+    void clear();  ///< clear all internal members
+
+private:
+    void init(); ///< initialize members
+    void assign(const Var& var); ///< perform full assignment
+    void setValue(const void* value, int length, int aType); ///< set new variable value
+};
+
+} // namespace Snmp
+
+#endif /* SQUID_SNMPX_VAR_H */
diff --git a/src/snmp/forward.h b/src/snmp/forward.h
new file mode 100644 (file)
index 0000000..5f02316
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 49    SNMP Interface
+ *
+ */
+
+#ifndef SQUID_SNMPX_FORWARD_H
+#define SQUID_SNMPX_FORWARD_H
+
+#include "config.h"
+
+namespace Snmp
+{
+
+class Pdu;
+class Request;
+class Response;
+class Session;
+class Var;
+
+} // namespace Snmp
+
+#endif /* SQUID_SNMPX_FORWARD_H */
index 25d4d80a1cf1671e4755fba17319c57939c2c1c4..fb300d2ed23deca2dea069529cb6123506dbac55 100644 (file)
  */
 #include "squid.h"
 #include "acl/FilledChecklist.h"
-#include "cache_snmp.h"
+#include "base/CbcPointer.h"
 #include "comm.h"
+#include "comm/Loops.h"
 #include "ipc/StartListening.h"
 #include "ip/Address.h"
 #include "ip/tools.h"
+#include "snmp_core.h"
+#include "snmp/Forwarder.h"
 
-#define SNMP_REQUEST_SIZE 4096
-#define MAX_PROTOSTAT 5
 
 /// dials snmpConnectionOpened call
 class SnmpListeningStartedDialer: public CallDialer,
@@ -60,29 +61,14 @@ public:
 
 Ip::Address theOutSNMPAddr;
 
-typedef struct _mib_tree_entry mib_tree_entry;
-typedef oid *(instance_Fn) (oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn);
-
-struct _mib_tree_entry {
-    oid *name;
-    int len;
-    oid_ParseFn *parsefunction;
-    instance_Fn *instancefunction;
-    int children;
-
-    struct _mib_tree_entry **leaves;
-
-    struct _mib_tree_entry *parent;
-};
-
 mib_tree_entry *mib_tree_head;
 mib_tree_entry *mib_tree_last;
 
 static void snmpIncomingConnectionOpened(int fd, int errNo);
 static void snmpOutgoingConnectionOpened(int fd, int errNo);
 
-static mib_tree_entry * snmpAddNodeStr(const char *base_str, int o, oid_ParseFn * parsefunction, instance_Fn * instancefunction);
-static mib_tree_entry *snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, instance_Fn * instancefunction, int children,...);
+static mib_tree_entry * snmpAddNodeStr(const char *base_str, int o, oid_ParseFn * parsefunction, instance_Fn * instancefunction, AggrType aggrType = atNone);
+static mib_tree_entry *snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, instance_Fn * instancefunction, AggrType aggrType, int children,...);
 static oid *snmpCreateOid(int length,...);
 mib_tree_entry * snmpLookupNodeStr(mib_tree_entry *entry, const char *str);
 int snmpCreateOidFromStr(const char *str, oid **name, int *nl);
@@ -94,12 +80,11 @@ static oid *client_Inst(oid * name, snint * len, mib_tree_entry * current, oid_P
 static void snmpDecodePacket(snmp_request_t * rq);
 static void snmpConstructReponse(snmp_request_t * rq);
 
-static struct snmp_pdu *snmpAgentResponse(struct snmp_pdu *PDU);
 static oid_ParseFn *snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen);
 static oid_ParseFn *snmpTreeGet(oid * Current, snint CurrentLen);
 static mib_tree_entry *snmpTreeEntry(oid entry, snint len, mib_tree_entry * current);
 static mib_tree_entry *snmpTreeSiblingEntry(oid entry, snint len, mib_tree_entry * current);
-static void snmpSnmplibDebug(int lvl, char *buf);
+extern "C" void snmpSnmplibDebug(int lvl, char *buf);
 
 /*
  * The functions used during startup:
@@ -124,7 +109,7 @@ snmpInit(void)
      * without having a "search" function. A search function should be written
      * to make this and the other code much less evil.
      */
-    mib_tree_head = snmpAddNode(snmpCreateOid(1, 1), 1, NULL, NULL, 0);
+    mib_tree_head = snmpAddNode(snmpCreateOid(1, 1), 1, NULL, NULL, atNone, 0);
 
     assert(mib_tree_head);
     debugs(49, 5, "snmpInit: root is " << mib_tree_head);
@@ -143,9 +128,9 @@ snmpInit(void)
 
     /* SQ_SYS - 1.3.6.1.4.1.3495.1.1 */
     snmpAddNodeStr("1.3.6.1.4.1.3495.1", 1, NULL, NULL);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.1", SYSVMSIZ, snmp_sysFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.1", SYSSTOR, snmp_sysFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.1", SYS_UPTIME, snmp_sysFn, static_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.1", SYSVMSIZ, snmp_sysFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.1", SYSSTOR, snmp_sysFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.1", SYS_UPTIME, snmp_sysFn, static_Inst, atMax);
 
     /* SQ_CONF - 1.3.6.1.4.1.3495.1.2 */
     snmpAddNodeStr("1.3.6.1.4.1.3495.1", 2, NULL, NULL);
@@ -156,10 +141,10 @@ snmpInit(void)
 
     /* SQ_CONF + CONF_STORAGE - 1.3.6.1.4.1.3495.1.5 */
     snmpAddNodeStr("1.3.6.1.4.1.3495.1.2", CONF_STORAGE, NULL, NULL);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.2.5", CONF_ST_MMAXSZ, snmp_confFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.2.5", CONF_ST_SWMAXSZ, snmp_confFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.2.5", CONF_ST_SWHIWM, snmp_confFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.2.5", CONF_ST_SWLOWM, snmp_confFn, static_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.2.5", CONF_ST_MMAXSZ, snmp_confFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.2.5", CONF_ST_SWMAXSZ, snmp_confFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.2.5", CONF_ST_SWHIWM, snmp_confFn, static_Inst, atMin);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.2.5", CONF_ST_SWLOWM, snmp_confFn, static_Inst, atMin);
 
     snmpAddNodeStr("1.3.6.1.4.1.3495.1.2", CONF_UNIQNAME, snmp_confFn, static_Inst);
 
@@ -168,38 +153,46 @@ snmpInit(void)
 
     /* PERF_SYS - 1.3.6.1.4.1.3495.1.3.1 */
     snmpAddNodeStr("1.3.6.1.4.1.3495.1.3", PERF_SYS, NULL, NULL);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_PF, snmp_prfSysFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_NUMR, snmp_prfSysFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_MEMUSAGE, snmp_prfSysFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CPUTIME, snmp_prfSysFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CPUUSAGE, snmp_prfSysFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_MAXRESSZ, snmp_prfSysFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_NUMOBJCNT, snmp_prfSysFn, static_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_PF, snmp_prfSysFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_NUMR, snmp_prfSysFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_MEMUSAGE, snmp_prfSysFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CPUTIME, snmp_prfSysFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CPUUSAGE, snmp_prfSysFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_MAXRESSZ, snmp_prfSysFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_NUMOBJCNT, snmp_prfSysFn, static_Inst, atSum);
+    /*
+      Amos comments:
+      The meaning of LRU is "oldest timestamped object in cache,  if LRU algorithm is
+      used"...
+      What this SMP support needs to do is aggregate via a special filter equivalent to
+      min() to retain the semantic oldest-object meaning. A special one is needed that
+      works as unsigned and ignores '0' values.
+     */
     snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURLRUEXP, snmp_prfSysFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURUNLREQ, snmp_prfSysFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURUNUSED_FD, snmp_prfSysFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURRESERVED_FD, snmp_prfSysFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURUSED_FD, snmp_prfSysFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURMAX_FD, snmp_prfSysFn, static_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURUNLREQ, snmp_prfSysFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURUNUSED_FD, snmp_prfSysFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURRESERVED_FD, snmp_prfSysFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURUSED_FD, snmp_prfSysFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.1", PERF_SYS_CURMAX_FD, snmp_prfSysFn, static_Inst, atMax);
 
     /* PERF_PROTO - 1.3.6.1.4.1.3495.1.3.2 */
     snmpAddNodeStr("1.3.6.1.4.1.3495.1.3", PERF_PROTO, NULL, NULL);
     snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2", PERF_PROTOSTAT_AGGR, NULL, NULL);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_HTTP_REQ, snmp_prfProtoFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_HTTP_HITS, snmp_prfProtoFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_HTTP_ERRORS, snmp_prfProtoFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_HTTP_KBYTES_IN, snmp_prfProtoFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_HTTP_KBYTES_OUT, snmp_prfProtoFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_ICP_S, snmp_prfProtoFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_ICP_R, snmp_prfProtoFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_ICP_SKB, snmp_prfProtoFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_ICP_RKB, snmp_prfProtoFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_REQ, snmp_prfProtoFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_ERRORS, snmp_prfProtoFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_KBYTES_IN, snmp_prfProtoFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_KBYTES_OUT, snmp_prfProtoFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_CURSWAP, snmp_prfProtoFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_CLIENTS, snmp_prfProtoFn, static_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_HTTP_REQ, snmp_prfProtoFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_HTTP_HITS, snmp_prfProtoFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_HTTP_ERRORS, snmp_prfProtoFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_HTTP_KBYTES_IN, snmp_prfProtoFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_HTTP_KBYTES_OUT, snmp_prfProtoFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_ICP_S, snmp_prfProtoFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_ICP_R, snmp_prfProtoFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_ICP_SKB, snmp_prfProtoFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_ICP_RKB, snmp_prfProtoFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_REQ, snmp_prfProtoFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_ERRORS, snmp_prfProtoFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_KBYTES_IN, snmp_prfProtoFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_KBYTES_OUT, snmp_prfProtoFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_CURSWAP, snmp_prfProtoFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.1", PERF_PROTOSTAT_AGGR_CLIENTS, snmp_prfProtoFn, static_Inst, atSum);
 
     /* Note this is time-series rather than 'static' */
     /* cacheMedianSvcTable */
@@ -207,49 +200,49 @@ snmpInit(void)
 
     /* cacheMedianSvcEntry */
     snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2", 1, NULL, NULL);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_TIME, snmp_prfProtoFn, time_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_HTTP_ALL, snmp_prfProtoFn, time_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_HTTP_MISS, snmp_prfProtoFn, time_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_HTTP_NM, snmp_prfProtoFn, time_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_HTTP_HIT, snmp_prfProtoFn, time_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_ICP_QUERY, snmp_prfProtoFn, time_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_ICP_REPLY, snmp_prfProtoFn, time_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_DNS, snmp_prfProtoFn, time_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_RHR, snmp_prfProtoFn, time_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_BHR, snmp_prfProtoFn, time_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_HTTP_NH, snmp_prfProtoFn, time_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_TIME, snmp_prfProtoFn, time_Inst, atAverage);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_HTTP_ALL, snmp_prfProtoFn, time_Inst, atAverage);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_HTTP_MISS, snmp_prfProtoFn, time_Inst, atAverage);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_HTTP_NM, snmp_prfProtoFn, time_Inst, atAverage);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_HTTP_HIT, snmp_prfProtoFn, time_Inst, atAverage);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_ICP_QUERY, snmp_prfProtoFn, time_Inst, atAverage);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_ICP_REPLY, snmp_prfProtoFn, time_Inst, atAverage);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_DNS, snmp_prfProtoFn, time_Inst, atAverage);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_RHR, snmp_prfProtoFn, time_Inst, atAverage);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_BHR, snmp_prfProtoFn, time_Inst, atAverage);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.3.2.2.1", PERF_MEDIAN_HTTP_NH, snmp_prfProtoFn, time_Inst, atAverage);
 
     /* SQ_NET - 1.3.6.1.4.1.3495.1.4 */
     snmpAddNodeStr("1.3.6.1.4.1.3495.1", 4, NULL, NULL);
 
     snmpAddNodeStr("1.3.6.1.4.1.3495.1.4", NET_IP_CACHE, NULL, NULL);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_ENT, snmp_netIpFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_REQ, snmp_netIpFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_HITS, snmp_netIpFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_PENDHIT, snmp_netIpFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_NEGHIT, snmp_netIpFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_MISS, snmp_netIpFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_GHBN, snmp_netIpFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_LOC, snmp_netIpFn, static_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_ENT, snmp_netIpFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_REQ, snmp_netIpFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_HITS, snmp_netIpFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_PENDHIT, snmp_netIpFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_NEGHIT, snmp_netIpFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_MISS, snmp_netIpFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_GHBN, snmp_netIpFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.1", IP_LOC, snmp_netIpFn, static_Inst, atSum);
 
     snmpAddNodeStr("1.3.6.1.4.1.3495.1.4", NET_FQDN_CACHE, NULL, NULL);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_ENT, snmp_netFqdnFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_REQ, snmp_netFqdnFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_HITS, snmp_netFqdnFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_PENDHIT, snmp_netFqdnFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_NEGHIT, snmp_netFqdnFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_MISS, snmp_netFqdnFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_GHBN, snmp_netFqdnFn, static_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_ENT, snmp_netFqdnFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_REQ, snmp_netFqdnFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_HITS, snmp_netFqdnFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_PENDHIT, snmp_netFqdnFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_NEGHIT, snmp_netFqdnFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_MISS, snmp_netFqdnFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.2", FQDN_GHBN, snmp_netFqdnFn, static_Inst, atSum);
 
     snmpAddNodeStr("1.3.6.1.4.1.3495.1.4", NET_DNS_CACHE, NULL, NULL);
 #if USE_DNSSERVERS
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.3", DNS_REQ, snmp_netDnsFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.3", DNS_REP, snmp_netDnsFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.3", DNS_SERVERS, snmp_netDnsFn, static_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.3", DNS_REQ, snmp_netDnsFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.3", DNS_REP, snmp_netDnsFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.3", DNS_SERVERS, snmp_netDnsFn, static_Inst, atSum);
 #else
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.3", DNS_REQ, snmp_netIdnsFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.3", DNS_REP, snmp_netIdnsFn, static_Inst);
-    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.3", DNS_SERVERS, snmp_netIdnsFn, static_Inst);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.3", DNS_REQ, snmp_netIdnsFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.3", DNS_REP, snmp_netIdnsFn, static_Inst, atSum);
+    snmpAddNodeStr("1.3.6.1.4.1.3495.1.4.3", DNS_SERVERS, snmp_netIdnsFn, static_Inst, atSum);
 #endif
 
     /* SQ_MESH - 1.3.6.1.4.1.3495.1.5 */
@@ -356,8 +349,7 @@ snmpIncomingConnectionOpened(int fd, int errNo)
     if (theInSnmpConnection < 0)
         fatal("Cannot open Incoming SNMP Port");
 
-    commSetSelect(theInSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL,
-                  0);
+    Comm::SetSelect(theInSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
 
     debugs(1, 1, "Accepting SNMP messages on " << Config.Addrs.snmp_incoming <<
            ", FD " << theInSnmpConnection << ".");
@@ -373,8 +365,7 @@ snmpOutgoingConnectionOpened(int fd, int errNo)
     if (theOutSnmpConnection < 0)
         fatal("Cannot open Outgoing SNMP Port");
 
-    commSetSelect(theOutSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL,
-                  0);
+    Comm::SetSelect(theOutSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
 
     debugs(1, 1, "Outgoing SNMP messages on " << Config.Addrs.snmp_outgoing <<
            ", FD " << theOutSnmpConnection << ".");
@@ -426,7 +417,7 @@ snmpConnectionShutdown(void)
      */
     assert(theOutSnmpConnection > -1);
 
-    commSetSelect(theOutSnmpConnection, COMM_SELECT_READ, NULL, NULL, 0);
+    Comm::SetSelect(theOutSnmpConnection, COMM_SELECT_READ, NULL, NULL, 0);
 }
 
 void
@@ -459,7 +450,7 @@ snmpHandleUdp(int sock, void *not_used)
 
     debugs(49, 5, "snmpHandleUdp: Called.");
 
-    commSetSelect(sock, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
+    Comm::SetSelect(sock, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
 
     memset(buf, '\0', SNMP_REQUEST_SIZE);
 
@@ -538,6 +529,14 @@ snmpConstructReponse(snmp_request_t * rq)
     struct snmp_pdu *RespPDU;
 
     debugs(49, 5, "snmpConstructReponse: Called.");
+
+    if (UsingSmp() && IamWorkerProcess()) {
+        AsyncJob::Start(new Snmp::Forwarder(static_cast<Snmp::Pdu&>(*rq->PDU),
+                                            static_cast<Snmp::Session&>(rq->session), rq->sock, rq->from));
+        snmp_free_pdu(rq->PDU);
+        return;
+    }
+
     RespPDU = snmpAgentResponse(rq->PDU);
     snmp_free_pdu(rq->PDU);
 
@@ -553,7 +552,7 @@ snmpConstructReponse(snmp_request_t * rq)
  * return the response to the requester.
  */
 
-static struct snmp_pdu *
+struct snmp_pdu *
 snmpAgentResponse(struct snmp_pdu *PDU) {
 
     struct snmp_pdu *Answer = NULL;
@@ -666,6 +665,29 @@ snmpTreeGet(oid * Current, snint CurrentLen)
     return (Fn);
 }
 
+AggrType
+snmpAggrType(oid* Current, snint CurrentLen)
+{
+    debugs(49, 5, HERE);
+
+    mib_tree_entry* mibTreeEntry = mib_tree_head;
+    AggrType type = atNone;
+    int count = 0;
+
+    if (Current[count] == mibTreeEntry->name[count]) {
+        count++;
+
+        while (mibTreeEntry != NULL && count < CurrentLen) {
+            mibTreeEntry = snmpTreeEntry(Current[count], count, mibTreeEntry);
+            if (mibTreeEntry != NULL)
+                type = mibTreeEntry->aggrType;
+            count++;
+        }
+    }
+
+    return type;
+}
+
 static oid_ParseFn *
 snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen)
 {
@@ -763,7 +785,7 @@ 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));
+        memcpy(instance, name, (sizeof(name) * *len));
         instance[*len] = 0;
         *len += 1;
     }
@@ -780,7 +802,7 @@ time_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
 
     if (*len <= current->len) {
         instance = (oid *)xmalloc(sizeof(name) * (*len + 1));
-        xmemcpy(instance, name, (sizeof(name) * *len));
+        memcpy(instance, name, (sizeof(name) * *len));
         instance[*len] = *index;
         *len += 1;
     } else {
@@ -791,7 +813,7 @@ time_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
 
         if (loop < (TIME_INDEX_LEN - 1)) {
             instance = (oid *)xmalloc(sizeof(name) * (*len));
-            xmemcpy(instance, name, (sizeof(name) * *len));
+            memcpy(instance, name, (sizeof(name) * *len));
             instance[*len - 1] = index[++loop];
         }
     }
@@ -817,7 +839,7 @@ peer_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
     } else if (*len <= current->len) {
         debugs(49, 6, "snmp peer_Inst: *len <= current->len ???");
         instance = (oid *)xmalloc(sizeof(name) * ( *len + 1));
-        xmemcpy(instance, name, (sizeof(name) * *len));
+        memcpy(instance, name, (sizeof(name) * *len));
         instance[*len] = 1 ;
         *len += 1;
     } else {
@@ -829,7 +851,7 @@ peer_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn)
         if (peers) {
             debugs(49, 6, "snmp peer_Inst: Encode peer #" << i);
             instance = (oid *)xmalloc(sizeof(name) * (current->len + 1 ));
-            xmemcpy(instance, name, (sizeof(name) * current->len ));
+            memcpy(instance, name, (sizeof(name) * current->len ));
             instance[current->len] = no + 1 ; // i.e. the next index on cache_peeer table.
         } else {
             debugs(49, 6, "snmp peer_Inst: We have " << i << " peers. Can't find #" << no);
@@ -864,7 +886,7 @@ client_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn
         debugs(49, 6, HERE << "len" << *len << ", current-len" << current->len << ", addr=" << laddr << ", size=" << size);
 
         instance = (oid *)xmalloc(sizeof(name) * (*len + size ));
-        xmemcpy(instance, name, (sizeof(name) * (*len)));
+        memcpy(instance, name, (sizeof(name) * (*len)));
 
         if ( !laddr.IsAnyAddr() ) {
             addr2oid(laddr, &instance[ *len]);  // the addr
@@ -888,7 +910,7 @@ client_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn
             debugs(49, 6, HERE << "len" << *len << ", current-len" << current->len << ", addr=" << laddr << ", newshift=" << newshift);
 
             instance = (oid *)xmalloc(sizeof(name) * (current->len +  newshift));
-            xmemcpy(instance, name, (sizeof(name) * (current->len)));
+            memcpy(instance, name, (sizeof(name) * (current->len)));
             addr2oid(laddr, &instance[current->len]);  // the addr.
             *len = current->len + newshift ;
         }
@@ -1033,7 +1055,7 @@ snmpCreateOidFromStr(const char *str, oid **name, int *nl)
  * on failure.
  */
 static mib_tree_entry *
-snmpAddNodeStr(const char *base_str, int o, oid_ParseFn * parsefunction, instance_Fn * instancefunction)
+snmpAddNodeStr(const char *base_str, int o, oid_ParseFn * parsefunction, instance_Fn * instancefunction, AggrType aggrType)
 {
     mib_tree_entry *m, *b;
     oid *n;
@@ -1052,7 +1074,7 @@ snmpAddNodeStr(const char *base_str, int o, oid_ParseFn * parsefunction, instanc
         return NULL;
 
     /* Create a node */
-    m = snmpAddNode(n, nl, parsefunction, instancefunction, 0);
+    m = snmpAddNode(n, nl, parsefunction, instancefunction, aggrType, 0);
 
     /* Link it into the existing tree */
     snmpAddNodeChild(b, m);
@@ -1066,7 +1088,7 @@ snmpAddNodeStr(const char *base_str, int o, oid_ParseFn * parsefunction, instanc
  * Adds a node to the MIB tree structure and adds the appropriate children
  */
 static mib_tree_entry *
-snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, instance_Fn * instancefunction, int children,...)
+snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, instance_Fn * instancefunction, AggrType aggrType, int children,...)
 {
     va_list args;
     int loop;
@@ -1084,6 +1106,7 @@ snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, instance_Fn * inst
     entry->instancefunction = instancefunction;
     entry->children = children;
     entry->leaves = NULL;
+    entry->aggrType = aggrType;
 
     if (children > 0) {
         entry->leaves = (mib_tree_entry **)xmalloc(sizeof(mib_tree_entry *) * children);
@@ -1138,7 +1161,7 @@ snmpDebugOid(oid * Name, snint Len, MemBuf &outbuf)
     return outbuf.content();
 }
 
-static void
+void
 snmpSnmplibDebug(int lvl, char *buf)
 {
     debugs(49, lvl, buf);
diff --git a/src/snmp_core.h b/src/snmp_core.h
new file mode 100644 (file)
index 0000000..284902e
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 49    SNMP Interface
+ *
+ */
+
+#ifndef SQUID_SNMP_CORE_H
+#define SQUID_SNMP_CORE_H
+
+#include "config.h"
+#include "cache_snmp.h"
+
+#define SNMP_REQUEST_SIZE 4096
+#define MAX_PROTOSTAT 5
+
+
+typedef struct _mib_tree_entry mib_tree_entry;
+typedef oid *(instance_Fn) (oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn);
+typedef enum {atNone = 0, atSum, atAverage, atMax, atMin} AggrType;
+
+struct _mib_tree_entry {
+    oid *name;
+    int len;
+    oid_ParseFn *parsefunction;
+    instance_Fn *instancefunction;
+    int children;
+
+    struct _mib_tree_entry **leaves;
+
+    struct _mib_tree_entry *parent;
+    AggrType aggrType;
+};
+
+extern struct snmp_pdu* snmpAgentResponse(struct snmp_pdu* PDU);
+extern AggrType snmpAggrType(oid* Current, snint CurrentLen);
+
+#endif /* SQUID_SNMP_CORE_H */
index 2c05e4b325966d6d950249abf888890d5e52369c..b6298c75d0a8a181d4e17c0535ed1fb893fa08fb 100644 (file)
@@ -126,7 +126,7 @@ using namespace Squid;
 #if HAVE_LIMITS_H
 #include <limits.h>
 #endif
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
 #include <io.h>
 #endif
 #if HAVE_SYS_MOUNT_H
@@ -154,9 +154,6 @@ using namespace Squid;
 #endif
 
 #include "md5.h"
-#if USE_SSL
-#include "ssl/support.h"
-#endif
 #if SQUID_SNMP
 #include "cache_snmp.h"
 #endif
diff --git a/src/ssl/ErrorDetail.cc b/src/ssl/ErrorDetail.cc
new file mode 100644 (file)
index 0000000..a7f8f38
--- /dev/null
@@ -0,0 +1,261 @@
+#include "squid.h"
+#include "ssl/ErrorDetail.h"
+
+struct SslErrorDetailEntry {
+    Ssl::ssl_error_t value;
+    const char *name;
+    const char *detail;
+};
+
+// TODO: optimize by replacing with std::map or similar
+static SslErrorDetailEntry TheSslDetailMap[] = {
+    {  SQUID_X509_V_ERR_DOMAIN_MISMATCH,
+        "SQUID_X509_V_ERR_DOMAIN_MISMATCH",
+        "%err_name: The hostname you are connecting to (%H),  does not match any of the Certificate valid names: %ssl_cn"},
+    { X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT,
+      "X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT",
+      "%err_name: SSL Certficate error: certificate issuer (CA) not known: %ssl_ca_name" },
+    { X509_V_ERR_CERT_NOT_YET_VALID,
+      "X509_V_ERR_CERT_NOT_YET_VALID",
+      "%err_name: SSL Certficate is not valid before: %ssl_notbefore" },
+    { X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD,
+      "X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD",
+      "%err_name: SSL Certificate has invalid start date (the 'not before' field): %subject" },
+    { X509_V_ERR_CERT_HAS_EXPIRED,
+      "X509_V_ERR_CERT_HAS_EXPIRED",
+      "%err_name: SSL Certificate expired on %ssl_notafter" },
+    { X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD,
+      "X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD",
+      "%err_name: SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject" },
+    {X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT,
+     "X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT",
+     "%err_name: Self-signed SSL Certificate: %ssl_subject"},
+    { X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY,
+      "X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY",
+      "%err_name: SSL Certficate error: certificate issuer (CA) not known: %ssl_ca_name" },
+    { SSL_ERROR_NONE, "SSL_ERROR_NONE", "%err_name: No error" },
+    {SSL_ERROR_NONE, NULL, NULL }
+};
+
+Ssl::ssl_error_t
+Ssl::parseErrorString(const char *name)
+{
+    assert(name);
+
+    for (int i = 0; TheSslDetailMap[i].name; ++i) {
+        if (strcmp(name, TheSslDetailMap[i].name) == 0)
+            return TheSslDetailMap[i].value;
+    }
+
+    if (xisdigit(*name)) {
+        const long int value = strtol(name, NULL, 0);
+        if (SQUID_SSL_ERROR_MIN <= value && value <= SQUID_SSL_ERROR_MAX)
+            return value;
+        fatalf("Too small or too bug SSL error code '%s'", name);
+    }
+
+    fatalf("Unknown SSL error name '%s'", name);
+    return SSL_ERROR_SSL; // not reached
+}
+
+const char *
+Ssl::getErrorName(Ssl::ssl_error_t value)
+{
+
+    for (int i = 0; TheSslDetailMap[i].name; ++i) {
+        if (TheSslDetailMap[i].value == value)
+            return TheSslDetailMap[i].name;
+    }
+
+    return NULL;
+}
+
+static const char *getErrorDetail(Ssl::ssl_error_t value)
+{
+    for (int i = 0; TheSslDetailMap[i].name; ++i) {
+        if (TheSslDetailMap[i].value == value)
+            return TheSslDetailMap[i].detail;
+    }
+
+    return NULL;
+}
+
+Ssl::ErrorDetail::err_frm_code Ssl::ErrorDetail::ErrorFormatingCodes[] = {
+    {"ssl_subject", &Ssl::ErrorDetail::subject},
+    {"ssl_ca_name", &Ssl::ErrorDetail::ca_name},
+    {"ssl_cn", &Ssl::ErrorDetail::cn},
+    {"ssl_notbefore", &Ssl::ErrorDetail::notbefore},
+    {"ssl_notafter", &Ssl::ErrorDetail::notafter},
+    {"err_name", &Ssl::ErrorDetail::err_code},
+    {NULL,NULL}
+};
+
+/**
+ * The subject of the current certification in text form
+ */
+const char  *Ssl::ErrorDetail::subject() const
+{
+    if (!peer_cert)
+        return "[Not available]";
+
+    static char tmpBuffer[256]; // A temporary buffer
+    X509_NAME_oneline(X509_get_subject_name(peer_cert.get()), tmpBuffer,
+                      sizeof(tmpBuffer));
+    return tmpBuffer;
+}
+
+// helper function to be used with Ssl::matchX509CommonNames
+static int copy_cn(void *check_data,  ASN1_STRING *cn_data)
+{
+    String *str = (String *)check_data;
+    if (!str) // no data? abort
+        return 0;
+    if (str->defined())
+        str->append(", ");
+    str->append((const char *)cn_data->data, cn_data->length);
+    return 1;
+}
+
+/**
+ * The list with certificates cn and alternate names
+ */
+const char *Ssl::ErrorDetail::cn() const
+{
+    if (!peer_cert)
+        return "[Not available]";
+
+    static String tmpStr;  ///< A temporary string buffer
+    tmpStr.clean();
+    Ssl::matchX509CommonNames(peer_cert.get(), &tmpStr, copy_cn);
+    return tmpStr.termedBuf();
+}
+
+/**
+ * The issuer name
+ */
+const char *Ssl::ErrorDetail::ca_name() const
+{
+    if (!peer_cert)
+        return "[Not available]";
+
+    static char tmpBuffer[256]; // A temporary buffer
+    X509_NAME_oneline(X509_get_issuer_name(peer_cert.get()), tmpBuffer, sizeof(tmpBuffer));
+    return tmpBuffer;
+}
+
+/**
+ * The certificate "not before" field
+ */
+const char *Ssl::ErrorDetail::notbefore() const
+{
+    if (!peer_cert)
+        return "[Not available]";
+
+    static char tmpBuffer[256]; // A temporary buffer
+    ASN1_UTCTIME * tm = X509_get_notBefore(peer_cert.get());
+    Ssl::asn1timeToString(tm, tmpBuffer, sizeof(tmpBuffer));
+    return tmpBuffer;
+}
+
+/**
+ * The certificate "not after" field
+ */
+const char *Ssl::ErrorDetail::notafter() const
+{
+    if (!peer_cert)
+        return "[Not available]";
+
+    static char tmpBuffer[256]; // A temporary buffer
+    ASN1_UTCTIME * tm = X509_get_notAfter(peer_cert.get());
+    Ssl::asn1timeToString(tm, tmpBuffer, sizeof(tmpBuffer));
+    return tmpBuffer;
+}
+
+/**
+ * The string representation of the error_no
+ */
+const char *Ssl::ErrorDetail::err_code() const
+{
+    const char *err = getErrorName(error_no);
+    if (!err)
+        return "[Not available]";
+    return err;
+}
+
+/**
+ * It converts the code to a string value. Currently the following
+ * formating codes are supported:
+ * %err_name: The name of the SSL error
+ * %ssl_cn: The comma-separated list of common and alternate names
+ * %ssl_subject: The certificate subject
+ * %ssl_ca_name: The certificate issuer name
+ * %ssl_notbefore: The certificate "not before" field
+ * %ssl_notafter: The certificate "not after" field
+ \retval  the length of the code (the number of characters will be replaced by value)
+*/
+int Ssl::ErrorDetail::convert(const char *code, const char **value) const
+{
+    *value = "-";
+    for (int i=0; ErrorFormatingCodes[i].code!=NULL; i++) {
+        const int len = strlen(ErrorFormatingCodes[i].code);
+        if (strncmp(code,ErrorFormatingCodes[i].code, len)==0) {
+            ErrorDetail::fmt_action_t action  = ErrorFormatingCodes[i].fmt_action;
+            *value = (this->*action)();
+            return len;
+        }
+    }
+    return 0;
+}
+
+/**
+ * It uses the convert method to build the string errDetailStr using
+ * a template message for the current SSL error. The template messages
+ * can also contain normal error pages formating codes.
+ * Currently the error template messages are hard-coded
+ */
+void Ssl::ErrorDetail::buildDetail() const
+{
+    char const *s = getErrorDetail(error_no);
+    char const *p;
+    char const *t;
+    int code_len = 0;
+
+    if (!s)  //May be add a default detail string?
+        return;
+
+    while ((p = strchr(s, '%'))) {
+        errDetailStr.append(s, p - s);
+        code_len = convert(++p, &t);
+        if (code_len)
+            errDetailStr.append(t);
+        else
+            errDetailStr.append("%");
+        s = p + code_len;
+    }
+    errDetailStr.append(s, strlen(s));
+}
+
+const String &Ssl::ErrorDetail::toString() const
+{
+    if (!errDetailStr.defined())
+        buildDetail();
+    return errDetailStr;
+}
+
+/* We may do not want to use X509_dup but instead
+   internal SSL locking:
+   CRYPTO_add(&(cert->references),1,CRYPTO_LOCK_X509);
+   peer_cert.reset(cert);
+*/
+Ssl::ErrorDetail::ErrorDetail( Ssl::ssl_error_t err_no, X509 *cert): error_no (err_no)
+{
+    peer_cert.reset(X509_dup(cert));
+}
+
+Ssl::ErrorDetail::ErrorDetail(Ssl::ErrorDetail const &anErrDetail)
+{
+    error_no = anErrDetail.error_no;
+    if (anErrDetail.peer_cert.get()) {
+        peer_cert.reset(X509_dup(anErrDetail.peer_cert.get()));
+    }
+}
diff --git a/src/ssl/ErrorDetail.h b/src/ssl/ErrorDetail.h
new file mode 100644 (file)
index 0000000..c1e0815
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef _SQUID_SSL_ERROR_DETAIL_H
+#define _SQUID_SSL_ERROR_DETAIL_H
+
+#include "err_detail_type.h"
+#include "ssl/support.h"
+#include "ssl/gadgets.h"
+
+#if HAVE_OPENSSL_SSL_H
+#include <openssl/ssl.h>
+#endif
+
+// Custom SSL errors; assumes all official errors are positive
+#define SQUID_X509_V_ERR_DOMAIN_MISMATCH -1
+// All SSL errors range: from smallest (negative) custom to largest SSL error
+#define SQUID_SSL_ERROR_MIN SQUID_X509_V_ERR_DOMAIN_MISMATCH
+#define SQUID_SSL_ERROR_MAX INT_MAX
+
+namespace Ssl
+{
+/// Squid defined error code (<0),  an error code returned by SSL X509 api, or SSL_ERROR_NONE
+typedef int ssl_error_t;
+
+/**
+   \ingroup ServerProtocolSSLAPI
+ * The ssl_error_t representation of the error described by "name".
+ */
+ssl_error_t parseErrorString(const char *name);
+
+/**
+   \ingroup ServerProtocolSSLAPI
+ * The string representation of the SSL error "value"
+ */
+const char *getErrorName(ssl_error_t value);
+
+/**
+   \ingroup ServerProtocolSSLAPI
+ * Used to pass SSL error details to the error pages returned to the
+ * end user.
+ */
+class ErrorDetail
+{
+public:
+    ErrorDetail(ssl_error_t err_no, X509 *cert);
+    ErrorDetail(ErrorDetail const &);
+    const String &toString() const;  ///< An error detail string to embed in squid error pages
+
+private:
+    typedef const char * (ErrorDetail::*fmt_action_t)() const;
+    /**
+     * Holds a formating code and its conversion method
+     */
+    class err_frm_code
+    {
+    public:
+        const char *code;             ///< The formating code
+        fmt_action_t fmt_action; ///< A pointer to the conversion method
+    };
+    static err_frm_code  ErrorFormatingCodes[]; ///< The supported formating codes
+
+    const char *subject() const;
+    const char *ca_name() const;
+    const char *cn() const;
+    const char *notbefore() const;
+    const char *notafter() const;
+    const char *err_code() const;
+
+    int convert(const char *code, const char **value) const;
+    void buildDetail() const;
+
+    mutable String errDetailStr; ///< Caches the error detail message
+    ssl_error_t error_no;   ///< The error code
+    X509_Pointer peer_cert; ///< A pointer to the peer certificate
+};
+
+}//namespace Ssl
+#endif
index 8aad6f469846a267f782bcc0514868acc52d05f3..6eb6756a662206a6c36af504fe79512c457d7a5d 100644 (file)
@@ -20,11 +20,13 @@ libsslsquid_la_SOURCES = \
        context_storage.cc \
        context_storage.h \
        Config.cc \
-       Config.h
+       Config.h \
+       ErrorDetail.cc \
+       ErrorDetail.h \
+       support.cc \
+       support.h
 
 libsslutil_la_SOURCES = \
-       support.cc \
-       support.h \
        gadgets.cc \
        gadgets.h \
        crtd_message.cc \
index c837926c7e13d5aedaebf1da5148088bedfe6d5e..21b85e2b3d946d0b8aac7ff31153a3731a8bb0b1 100644 (file)
@@ -170,7 +170,7 @@ void Ssl::CrtdMessage::composeBody(CrtdMessage::BodyParams const & map, std::str
         body += i->first + "=" + i->second;
     }
     if (!other_part.empty())
-        body += other_part;
+        body += '\n' + other_part;
 }
 
 const std::string Ssl::CrtdMessage::code_new_certificate("new_certificate");
index a18aee573487ee3309b3311035523203cf5c9c28..057d3c766cbdaa0296e89a16759ce511fede27a9 100644 (file)
@@ -14,7 +14,11 @@ static bool addCnToRequest(Ssl::X509_REQ_Pointer & request, char const * cn)
     Ssl::X509_NAME_Pointer name(X509_REQ_get_subject_name(request.get()));
     if (!name)
         return false;
-    if (!X509_NAME_add_entry_by_txt(name.get(), "CN", MBSTRING_ASC, (unsigned char *)cn, -1, -1, 0))
+
+    // The second argument of the X509_NAME_add_entry_by_txt declared as
+    // "char *" on some OS. Use cn_name to avoid compile warnings.
+    static char cn_name[3] = "CN";
+    if (!X509_NAME_add_entry_by_txt(name.get(), cn_name, MBSTRING_ASC, (unsigned char *)cn, -1, -1, 0))
         return false;
     name.release();
     return true;
@@ -37,11 +41,6 @@ static bool makeRequest(Ssl::X509_REQ_Pointer & request, Ssl::EVP_PKEY_Pointer c
     return true;
 }
 
-void Ssl::BIO_free_wrapper(BIO * bio)
-{
-    BIO_free(bio);
-}
-
 EVP_PKEY * Ssl::createSslPrivateKey()
 {
     Ssl::EVP_PKEY_Pointer pkey(EVP_PKEY_new());
index 12f8f6d71f4a16310f11bdd7e4a29e2e5d81cc07..11f2286307ab6c5bd191c3d50323581257f74b36 100644 (file)
@@ -25,27 +25,49 @@ namespace Ssl
  because they are used by ssl_crtd.
  */
 
-/**
- \ingroup SslCrtdSslAPI
- * Function for BIO delete for Deleter template.
-*/
-void BIO_free_wrapper(BIO * bio);
+// Macro to be used to define the C++ equivalent function of an extern "C"
+// function. The C++ function suffixed with the _cpp extension
+#define CtoCpp1(function, argument) \
+        extern "C++" inline void function ## _cpp(argument a) { \
+            function(a); \
+        }
 
 /**
  \ingroup SslCrtdSslAPI
  * TidyPointer typedefs for  common SSL objects
  */
-typedef TidyPointer<X509, X509_free> X509_Pointer;
-typedef TidyPointer<EVP_PKEY, EVP_PKEY_free> EVP_PKEY_Pointer;
-typedef TidyPointer<BIGNUM, BN_free> BIGNUM_Pointer;
-typedef TidyPointer<BIO, BIO_free_wrapper> BIO_Pointer;
-typedef TidyPointer<ASN1_INTEGER, ASN1_INTEGER_free> ASN1_INT_Pointer;
-typedef TidyPointer<TXT_DB, TXT_DB_free> TXT_DB_Pointer;
-typedef TidyPointer<X509_NAME, X509_NAME_free> X509_NAME_Pointer;
-typedef TidyPointer<RSA, RSA_free> RSA_Pointer;
-typedef TidyPointer<X509_REQ, X509_REQ_free> X509_REQ_Pointer;
-typedef TidyPointer<SSL_CTX, SSL_CTX_free> SSL_CTX_Pointer;
-typedef  TidyPointer<SSL, SSL_free> SSL_Pointer;
+CtoCpp1(X509_free, X509 *)
+typedef TidyPointer<X509, X509_free_cpp> X509_Pointer;
+
+CtoCpp1(EVP_PKEY_free, EVP_PKEY *)
+typedef TidyPointer<EVP_PKEY, EVP_PKEY_free_cpp> EVP_PKEY_Pointer;
+
+CtoCpp1(BN_free, BIGNUM *)
+typedef TidyPointer<BIGNUM, BN_free_cpp> BIGNUM_Pointer;
+
+CtoCpp1(BIO_free, BIO *)
+typedef TidyPointer<BIO, BIO_free_cpp> BIO_Pointer;
+
+CtoCpp1(ASN1_INTEGER_free, ASN1_INTEGER *)
+typedef TidyPointer<ASN1_INTEGER, ASN1_INTEGER_free_cpp> ASN1_INT_Pointer;
+
+CtoCpp1(TXT_DB_free, TXT_DB *)
+typedef TidyPointer<TXT_DB, TXT_DB_free_cpp> TXT_DB_Pointer;
+
+CtoCpp1(X509_NAME_free, X509_NAME *)
+typedef TidyPointer<X509_NAME, X509_NAME_free_cpp> X509_NAME_Pointer;
+
+CtoCpp1(RSA_free, RSA *)
+typedef TidyPointer<RSA, RSA_free_cpp> RSA_Pointer;
+
+CtoCpp1(X509_REQ_free, X509_REQ *)
+typedef TidyPointer<X509_REQ, X509_REQ_free_cpp> X509_REQ_Pointer;
+
+CtoCpp1(SSL_CTX_free, SSL_CTX *)
+typedef TidyPointer<SSL_CTX, SSL_CTX_free_cpp> SSL_CTX_Pointer;
+
+CtoCpp1(SSL_free, SSL *)
+typedef TidyPointer<SSL, SSL_free_cpp> SSL_Pointer;
 
 
 /**
index a86afd0fcf0d71a47e4a8a19788cb7b4d98723fe..e68774aeb396e49032c0641892585243848b0be9 100644 (file)
@@ -42,6 +42,8 @@
 
 #include "fde.h"
 #include "acl/FilledChecklist.h"
+#include "ssl/ErrorDetail.h"
+#include "ssl/support.h"
 #include "ssl/gadgets.h"
 
 /**
@@ -136,6 +138,68 @@ ssl_temp_rsa_cb(SSL * ssl, int anInt, int keylen)
     return rsa;
 }
 
+int Ssl::asn1timeToString(ASN1_TIME *tm, char *buf, int len)
+{
+    BIO *bio;
+    int write = 0;
+    bio = BIO_new(BIO_s_mem());
+    if (bio) {
+        if (ASN1_TIME_print(bio, tm))
+            write = BIO_read(bio, buf, len-1);
+        BIO_free(bio);
+    }
+    buf[write]='\0';
+    return write;
+}
+
+int Ssl::matchX509CommonNames(X509 *peer_cert, void *check_data, int (*check_func)(void *check_data,  ASN1_STRING *cn_data))
+{
+    assert(peer_cert);
+
+    X509_NAME *name = X509_get_subject_name(peer_cert);
+
+    for (int i = X509_NAME_get_index_by_NID(name, NID_commonName, -1); i >= 0; i = X509_NAME_get_index_by_NID(name, NID_commonName, i)) {
+
+        ASN1_STRING *cn_data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
+
+        if ( (*check_func)(check_data, cn_data) == 0)
+            return 1;
+    }
+
+    STACK_OF(GENERAL_NAME) * altnames;
+    altnames = (STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(peer_cert, NID_subject_alt_name, NULL, NULL);
+
+    if (altnames) {
+        int numalts = sk_GENERAL_NAME_num(altnames);
+        for (int i = 0; i < numalts; i++) {
+            const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i);
+            if (check->type != GEN_DNS) {
+                continue;
+            }
+            ASN1_STRING *cn_data = check->d.dNSName;
+
+            if ( (*check_func)(check_data, cn_data) == 0)
+                return 1;
+        }
+        sk_GENERAL_NAME_pop_free(altnames, GENERAL_NAME_free);
+    }
+    return 0;
+}
+
+static int check_domain( void *check_data, ASN1_STRING *cn_data)
+{
+    char cn[1024];
+    const char *server = (const char *)check_data;
+
+    if (cn_data->length > (int)sizeof(cn) - 1) {
+        return 1; //if does not fit our buffer just ignore
+    }
+    memcpy(cn, cn_data->data, cn_data->length);
+    cn[cn_data->length] = '\0';
+    debugs(83, 4, "Verifying server domain " << server << " to certificate name/subjectAltName " << cn);
+    return matchDomainName(server, cn[0] == '*' ? cn + 1 : cn);
+}
+
 /// \ingroup ServerProtocolSSLInternal
 static int
 ssl_verify_cb(int ok, X509_STORE_CTX * ctx)
@@ -147,6 +211,7 @@ ssl_verify_cb(int ok, X509_STORE_CTX * ctx)
     void *dont_verify_domain = SSL_CTX_get_ex_data(sslctx, ssl_ctx_ex_index_dont_verify_domain);
     ACLChecklist *check = (ACLChecklist*)SSL_get_ex_data(ssl, ssl_ex_index_cert_error_check);
     X509 *peer_cert = ctx->cert;
+    Ssl::ssl_error_t error_no = SSL_ERROR_NONE;
 
     X509_NAME_oneline(X509_get_subject_name(peer_cert), buffer,
                       sizeof(buffer));
@@ -155,65 +220,22 @@ ssl_verify_cb(int ok, X509_STORE_CTX * ctx)
         debugs(83, 5, "SSL Certificate signature OK: " << buffer);
 
         if (server) {
-            int i;
-            int found = 0;
-            char cn[1024];
-
-            STACK_OF(GENERAL_NAME) * altnames;
-            altnames = (STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(peer_cert, NID_subject_alt_name, NULL, NULL);
-            if (altnames) {
-                int numalts = sk_GENERAL_NAME_num(altnames);
-                debugs(83, 3, "Verifying server domain " << server << " to certificate subjectAltName");
-                for (i = 0; i < numalts; i++) {
-                    const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i);
-                    if (check->type != GEN_DNS) {
-                        continue;
-                    }
-                    ASN1_STRING *data = check->d.dNSName;
-                    if (data->length > (int)sizeof(cn) - 1) {
-                        continue;
-                    }
-                    memcpy(cn, data->data, data->length);
-                    cn[data->length] = '\0';
-                    debugs(83, 4, "Verifying server domain " << server << " to certificate name " << cn);
-                    if (matchDomainName(server, cn[0] == '*' ? cn + 1 : cn) == 0) {
-                        found = 1;
-                        break;
-                    }
-                }
-            }
-
-            X509_NAME *name = X509_get_subject_name(peer_cert);
-            debugs(83, 3, "Verifying server domain " << server << " to certificate dn " << buffer);
-
-            for (i = X509_NAME_get_index_by_NID(name, NID_commonName, -1); i >= 0; i = X509_NAME_get_index_by_NID(name, NID_commonName, i)) {
-                ASN1_STRING *data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
-
-                if (data->length > (int)sizeof(cn) - 1)
-                    continue;
-
-                memcpy(cn, data->data, data->length);
-
-                cn[data->length] = '\0';
-
-                debugs(83, 4, "Verifying server domain " << server << " to certificate cn " << cn);
-
-                if (matchDomainName(server, cn[0] == '*' ? cn + 1 : cn) == 0) {
-                    found = 1;
-                    break;
-                }
-            }
+            int found = Ssl::matchX509CommonNames(peer_cert, (void *)server, check_domain);
 
             if (!found) {
                 debugs(83, 2, "SQUID_X509_V_ERR_DOMAIN_MISMATCH: Certificate " << buffer << " does not match domainname " << server);
                 ok = 0;
+                error_no = SQUID_X509_V_ERR_DOMAIN_MISMATCH;
+
                 if (check)
                     Filled(check)->ssl_error = SQUID_X509_V_ERR_DOMAIN_MISMATCH;
             }
         }
     } else {
+        error_no = ctx->error;
         switch (ctx->error) {
 
+        case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
             debugs(83, 5, "SSL Certficate error: CA not known: " << buffer);
             break;
@@ -236,6 +258,10 @@ ssl_verify_cb(int ok, X509_STORE_CTX * ctx)
             debugs(83, 5, "SSL Certificate has invalid \'not after\' field: " << buffer);
             break;
 
+        case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+            debugs(83, 5, "SSL Certificate is self signed: " << buffer);
+            break;
+
         default:
             debugs(83, 1, "SSL unknown certificate error " << ctx->error << " in " << buffer);
             break;
@@ -256,6 +282,14 @@ ssl_verify_cb(int ok, X509_STORE_CTX * ctx)
 
     if (!dont_verify_domain && server) {}
 
+    if (error_no != SSL_ERROR_NONE && !SSL_get_ex_data(ssl, ssl_ex_index_ssl_error_detail) ) {
+        Ssl::ErrorDetail *errDetail = new Ssl::ErrorDetail(error_no, peer_cert);
+        if (!SSL_set_ex_data(ssl, ssl_ex_index_ssl_error_detail,  errDetail)) {
+            debugs(83, 2, "Failed to set Ssl::ErrorDetail in ssl_verify_cb: Certificate " << buffer);
+            delete errDetail;
+        }
+    }
+
     return ok;
 }
 
@@ -525,55 +559,6 @@ ssl_parse_flags(const char *flags)
     return fl;
 }
 
-struct SslErrorMapEntry {
-    const char *name;
-    ssl_error_t value;
-};
-
-static SslErrorMapEntry TheSslErrorMap[] = {
-    { "SQUID_X509_V_ERR_DOMAIN_MISMATCH", SQUID_X509_V_ERR_DOMAIN_MISMATCH },
-    { "X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT", X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT },
-    { "X509_V_ERR_CERT_NOT_YET_VALID", X509_V_ERR_CERT_NOT_YET_VALID },
-    { "X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD", X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD },
-    { "X509_V_ERR_CERT_HAS_EXPIRED", X509_V_ERR_CERT_HAS_EXPIRED },
-    { "X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD", X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD },
-    { "X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY", X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY },
-    { "SSL_ERROR_NONE", SSL_ERROR_NONE },
-    { NULL, SSL_ERROR_NONE }
-};
-
-ssl_error_t
-sslParseErrorString(const char *name)
-{
-    assert(name);
-
-    for (int i = 0; TheSslErrorMap[i].name; ++i) {
-        if (strcmp(name, TheSslErrorMap[i].name) == 0)
-            return TheSslErrorMap[i].value;
-    }
-
-    if (xisdigit(*name)) {
-        const long int value = strtol(name, NULL, 0);
-        if (SQUID_SSL_ERROR_MIN <= value && value <= SQUID_SSL_ERROR_MAX)
-            return value;
-        fatalf("Too small or too bug SSL error code '%s'", name);
-    }
-
-    fatalf("Unknown SSL error name '%s'", name);
-    return SSL_ERROR_SSL; // not reached
-}
-
-const char *
-sslFindErrorString(ssl_error_t value)
-{
-    for (int i = 0; TheSslErrorMap[i].name; ++i) {
-        if (TheSslErrorMap[i].value == value)
-            return TheSslErrorMap[i].name;
-    }
-
-    return NULL;
-}
-
 // "dup" function for SSL_get_ex_new_index("cert_err_check")
 static int
 ssl_dupAclChecklist(CRYPTO_EX_DATA *, CRYPTO_EX_DATA *, void *,
@@ -593,6 +578,15 @@ ssl_freeAclChecklist(void *, void *ptr, CRYPTO_EX_DATA *,
     delete static_cast<ACLChecklist *>(ptr); // may be NULL
 }
 
+// "free" function for SSL_get_ex_new_index("ssl_error_detail")
+static void
+ssl_free_ErrorDetail(void *, void *ptr, CRYPTO_EX_DATA *,
+                     int, long, void *)
+{
+    Ssl::ErrorDetail  *errDetail = static_cast <Ssl::ErrorDetail *>(ptr);
+    delete errDetail;
+}
+
 /// \ingroup ServerProtocolSSLInternal
 static void
 ssl_initialize(void)
@@ -631,6 +625,7 @@ ssl_initialize(void)
     ssl_ex_index_server = SSL_get_ex_new_index(0, (void *) "server", NULL, NULL, NULL);
     ssl_ctx_ex_index_dont_verify_domain = SSL_CTX_get_ex_new_index(0, (void *) "dont_verify_domain", NULL, NULL, NULL);
     ssl_ex_index_cert_error_check = SSL_get_ex_new_index(0, (void *) "cert_error_check", NULL, &ssl_dupAclChecklist, &ssl_freeAclChecklist);
+    ssl_ex_index_ssl_error_detail = SSL_get_ex_new_index(0, (void *) "ssl_error_detail", NULL, NULL, &ssl_free_ErrorDetail);
 }
 
 /// \ingroup ServerProtocolSSLInternal
index 84bdaa661fb4950b0a0a9dda0a0dabd7b7324a71..2e83dd791be6882dbc3f90d7ae83895a704ce8e1 100644 (file)
@@ -89,10 +89,6 @@ const char *sslGetUserCertificatePEM(SSL *ssl);
 /// \ingroup ServerProtocolSSLAPI
 const char *sslGetUserCertificateChainPEM(SSL *ssl);
 
-typedef int ssl_error_t;
-ssl_error_t sslParseErrorString(const char *name);
-const char *sslFindErrorString(ssl_error_t value);
-
 namespace Ssl
 {
 /**
@@ -115,13 +111,28 @@ bool verifySslCertificateDate(SSL_CTX * sslContext);
  */
 SSL_CTX * generateSslContextUsingPkeyAndCertFromMemory(const char * data);
 
-} //namespace Ssl
+/**
+   \ingroup ServerProtocolSSLAPI
+   * Iterates over the X509 common and alternate names and to see if  matches with given data
+   * using the check_func.
+   \param peer_cert  The X509 cert to check
+   \param check_data The data with which the X509 CNs compared
+   \param check_func The function used to match X509 CNs. The CN data passed as ASN1_STRING data
+   \return   1 if any of the certificate CN matches, 0 if none matches.
+ */
+int matchX509CommonNames(X509 *peer_cert, void *check_data, int (*check_func)(void *check_data,  ASN1_STRING *cn_data));
 
-// Custom SSL errors; assumes all official errors are positive
-#define SQUID_X509_V_ERR_DOMAIN_MISMATCH -1
-// All SSL errors range: from smallest (negative) custom to largest SSL error
-#define SQUID_SSL_ERROR_MIN SQUID_X509_V_ERR_DOMAIN_MISMATCH
-#define SQUID_SSL_ERROR_MAX INT_MAX
+/**
+   \ingroup ServerProtocolSSLAPI
+   * Convert a given ASN1_TIME to a string form.
+   \param tm the time in ASN1_TIME form
+   \param buf the buffer to write the output
+   \param len write at most len bytes
+   \return The number of bytes written
+ */
+int asn1timeToString(ASN1_TIME *tm, char *buf, int len);
+
+} //namespace Ssl
 
 #ifdef _SQUID_MSWIN_
 
index 47143b288243ab7e34a9ac0da8304b5f8a53d456..5d767cf78b03bba9565f8bb6aa2c59ea26b3e67b 100644 (file)
@@ -39,6 +39,7 @@
 #include "mgr/Registration.h"
 #include "Store.h"
 #include "HttpRequest.h"
+#include "log/Tokens.h"
 #include "MemObject.h"
 #include "fde.h"
 #include "mem_node.h"
@@ -56,6 +57,9 @@
 #include "mgr/IntervalAction.h"
 #include "mgr/IoAction.h"
 #include "mgr/ServiceTimesAction.h"
+#if USE_SSL
+#include "ssl/support.h"
+#endif
 
 /* these are included because they expose stats calls */
 /* TODO: provide a self registration mechanism for those classes
@@ -645,7 +649,7 @@ GetInfo(Mgr::InfoActionData& stats)
         stats.mem_pool_allocated = mp_stats.TheMeter->alloc.level;
 #endif
 
-        stats.gb_freed_count = mp_stats.TheMeter->gb_saved.count;
+        stats.gb_saved_count = mp_stats.TheMeter->gb_saved.count;
         stats.gb_freed_count = mp_stats.TheMeter->gb_freed.count;
     }
 
@@ -669,15 +673,13 @@ DumpInfo(Mgr::InfoActionData& stats, StoreEntry* sentry)
     storeAppendPrintf(sentry, "Squid Object Cache: Version %s\n",
                       version_string);
 
-#if _SQUID_WIN32_
-
+#if _SQUID_WINDOWS_
     if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
         storeAppendPrintf(sentry,"\nRunning as %s Windows System Service on %s\n",
                           WIN32_Service_name, WIN32_OS_string);
         storeAppendPrintf(sentry,"Service command line is: %s\n", WIN32_Service_Command_Line);
     } else
         storeAppendPrintf(sentry,"Running on %s\n",WIN32_OS_string);
-
 #endif
 
     storeAppendPrintf(sentry, "Start Time:\t%s\n",
@@ -718,10 +720,10 @@ DumpInfo(Mgr::InfoActionData& stats, StoreEntry* sentry)
                       stats.request_failure_ratio / fct);
 
     storeAppendPrintf(sentry, "\tAverage HTTP requests per minute since start:\t%.1f\n",
-                      stats.avg_client_http_requests / fct);
+                      stats.avg_client_http_requests);
 
     storeAppendPrintf(sentry, "\tAverage ICP messages per minute since start:\t%.1f\n",
-                      stats.avg_icp_messages / fct);
+                      stats.avg_icp_messages);
 
     storeAppendPrintf(sentry, "\tSelect loop called: %.0f times, %0.3f ms avg\n",
                       stats.select_loops, stats.avg_loop_time / fct);
@@ -745,7 +747,7 @@ DumpInfo(Mgr::InfoActionData& stats, StoreEntry* sentry)
                       stats.request_hit_disk_ratio60 / fct);
 
     storeAppendPrintf(sentry, "\tStorage Swap size:\t%.0f KB\n",
-                      stats.store_swap_size / 1024);
+                      stats.store_swap_size);
 
     storeAppendPrintf(sentry, "\tStorage Swap capacity:\t%4.1f%% used, %4.1f%% free\n",
                       Math::doublePercent(stats.store_swap_size, stats.store_swap_max_size),
@@ -1421,7 +1423,7 @@ statAvgTick(void *notused)
     c->timestamp = current_time;
     /* even if NCountHist is small, we already Init()ed the tail */
     statCountersClean(CountHist + N_COUNT_HIST - 1);
-    xmemmove(p, t, (N_COUNT_HIST - 1) * sizeof(StatCounters));
+    memmove(p, t, (N_COUNT_HIST - 1) * sizeof(StatCounters));
     statCountersCopy(t, c);
     NCountHist++;
 
@@ -1431,7 +1433,7 @@ statAvgTick(void *notused)
         StatCounters *p2 = &CountHourHist[1];
         StatCounters *c2 = &CountHist[N_COUNT_HIST - 1];
         statCountersClean(CountHourHist + N_COUNT_HOUR_HIST - 1);
-        xmemmove(p2, t2, (N_COUNT_HOUR_HIST - 1) * sizeof(StatCounters));
+        memmove(p2, t2, (N_COUNT_HOUR_HIST - 1) * sizeof(StatCounters));
         statCountersCopy(t2, c2);
         NCountHourHist++;
     }
@@ -1541,7 +1543,7 @@ statCountersCopy(StatCounters * dest, const StatCounters * orig)
 {
     assert(dest && orig);
     /* this should take care of all the fields, but "special" ones */
-    xmemcpy(dest, orig, sizeof(*dest));
+    memcpy(dest, orig, sizeof(*dest));
     /* prepare space where to copy special entries */
     statCountersInitSpecial(dest);
     /* now handle special cases */
index b264138f69565c596c9daa97c4a41bf1e08bfdda..95257d6eb0653a11d7dfddc62145a7fb5ddc419c 100644 (file)
@@ -142,7 +142,7 @@ mem_hdr::writeAvailable(mem_node *aNode, int64_t location, size_t amount, char c
     assert (location - aNode->nodeBuffer.offset == (int64_t)aNode->nodeBuffer.length);
     size_t copyLen = min(amount, aNode->space());
 
-    xmemcpy(aNode->nodeBuffer.data + aNode->nodeBuffer.length, source, copyLen);
+    memcpy(aNode->nodeBuffer.data + aNode->nodeBuffer.length, source, copyLen);
 
     if (inmem_hi <= location)
         inmem_hi = location + copyLen;
@@ -218,7 +218,7 @@ mem_hdr::copyAvailable(mem_node *aNode, int64_t location, size_t amount, char *t
 
     size_t copyLen = min(amount, aNode->nodeBuffer.length - copyOffset);
 
-    xmemcpy(target, aNode->nodeBuffer.data + copyOffset, copyLen);
+    memcpy(target, aNode->nodeBuffer.data + copyOffset, copyLen);
 
     return copyLen;
 }
index 50ac793d0bdbc463c363fa1440edb736fa852a75..fd9b3dd344a6f23c6d8facd9db3d9af01d5912fa 100644 (file)
@@ -622,7 +622,7 @@ store_client::readHeader(char const *buf, ssize_t len)
          */
         size_t copy_sz = min(copyInto.length, body_sz);
         debugs(90, 3, "storeClientReadHeader: copying " << copy_sz << " bytes of body");
-        xmemmove(copyInto.data, copyInto.data + mem->swap_hdr_sz, copy_sz);
+        memmove(copyInto.data, copyInto.data + mem->swap_hdr_sz, copy_sz);
 
         readBody(copyInto.data, copy_sz);
 
index a6d220dbd42fe06ecf2c9bbdafc9271d3f3989ed..a7c90008fbe157bfe249e15991219e68f5eec170 100644 (file)
@@ -146,35 +146,30 @@ StoreController::create()
 #endif
 }
 
-/*
+/**
  * Determine whether the given directory can handle this object
  * size
  *
  * Note: if the object size is -1, then the only swapdirs that
- * will return true here are ones that have max_obj_size = -1,
+ * will return true here are ones that have min and max unset,
  * ie any-sized-object swapdirs. This is a good thing.
  */
 bool
 SwapDir::objectSizeIsAcceptable(int64_t objsize) const
 {
-    /*
-     * If the swapdir's max_obj_size is -1, then it definitely can
-     */
-
-    if (max_objsize == -1)
+    // If the swapdir has no range limits, then it definitely can
+    if (min_objsize <= 0 && max_objsize == -1)
         return true;
 
     /*
-     * If the object size is -1, then if the storedir isn't -1 we
-     * can't store it
+     * If the object size is -1 and the storedir has limits we
+     * can't store it there.
      */
-    if ((objsize == -1) && (max_objsize != -1))
+    if (objsize == -1)
         return false;
 
-    /*
-     * Else, make sure that the max object size is larger than objsize
-     */
-    return max_objsize > objsize;
+    // Else, make sure that the object size will fit.
+    return min_objsize <= objsize && max_objsize > objsize;
 }
 
 
@@ -361,14 +356,13 @@ StoreController::stat(StoreEntry &output) const
     storeAppendPrintf(&output, "Store Directory Statistics:\n");
     storeAppendPrintf(&output, "Store Entries          : %lu\n",
                       (unsigned long int)StoreEntry::inUseCount());
-    storeAppendPrintf(&output, "Maximum Swap Size      : %8ld KB\n",
-                      (long int) maxSize());
+    storeAppendPrintf(&output, "Maximum Swap Size      : %"PRIu64" KB\n",
+                      maxSize());
     storeAppendPrintf(&output, "Current Store Swap Size: %8lu KB\n",
                       store_swap_size);
-    // XXX : below capacity display calculation breaks with int overflow on 64-bit systems
-    storeAppendPrintf(&output, "Current Capacity       : %d%% used, %d%% free\n",
-                      Math::intPercent((int) store_swap_size, (int) maxSize()),
-                      Math::intPercent((int) (maxSize() - store_swap_size), (int) maxSize()));
+    storeAppendPrintf(&output, "Current Capacity       : %"PRId64"%% used, %"PRId64"%% free\n",
+                      Math::int64Percent(store_swap_size, maxSize()),
+                      Math::int64Percent((maxSize() - store_swap_size), maxSize()));
     /* FIXME Here we should output memory statistics */
 
     /* now the swapDir */
@@ -376,14 +370,14 @@ StoreController::stat(StoreEntry &output) const
 }
 
 /* if needed, this could be taught to cache the result */
-size_t
+uint64_t
 StoreController::maxSize() const
 {
     /* TODO: include memory cache ? */
     return swapDir->maxSize();
 }
 
-size_t
+uint64_t
 StoreController::minSize() const
 {
     /* TODO: include memory cache ? */
@@ -630,7 +624,7 @@ allocate_new_swapdir(SquidConfig::_cacheSwap * swap)
         StorePointer *tmp;
         swap->n_allocated <<= 1;
         tmp = static_cast<StorePointer *>(xcalloc(swap->n_allocated, sizeof(StorePointer)));
-        xmemcpy(tmp, swap->swapDirs, swap->n_configured * sizeof(SwapDir *));
+        memcpy(tmp, swap->swapDirs, swap->n_configured * sizeof(SwapDir *));
         xfree(swap->swapDirs);
         swap->swapDirs = tmp;
     }
@@ -695,19 +689,14 @@ StoreController::dereference(StoreEntry & e)
 }
 
 StoreEntry *
-
-StoreController::get
-(const cache_key *key)
+StoreController::get(const cache_key *key)
 {
 
-    return swapDir->get
-           (key);
+    return swapDir->get(key);
 }
 
 void
-
-StoreController::get
-(String const key, STOREGETCLIENT aCallback, void *aCallbackData)
+StoreController::get(String const key, STOREGETCLIENT aCallback, void *aCallbackData)
 {
     fatal("not implemented");
 }
@@ -770,9 +759,7 @@ StoreHashIndex::create()
 /* Lookup an object in the cache.
  * return just a reference to object, don't start swapping in yet. */
 StoreEntry *
-
-StoreHashIndex::get
-(const cache_key *key)
+StoreHashIndex::get(const cache_key *key)
 {
     PROF_start(storeGet);
     debugs(20, 3, "storeGet: looking up " << storeKeyText(key));
@@ -782,9 +769,7 @@ StoreHashIndex::get
 }
 
 void
-
-StoreHashIndex::get
-(String const key, STOREGETCLIENT aCallback, void *aCallbackData)
+StoreHashIndex::get(String const key, STOREGETCLIENT aCallback, void *aCallbackData)
 {
     fatal("not implemented");
 }
@@ -829,22 +814,21 @@ StoreHashIndex::init()
     }
 }
 
-size_t
+uint64_t
 StoreHashIndex::maxSize() const
 {
-    int i;
-    size_t result = 0;
+    uint64_t result = 0;
 
-    for (i = 0; i < Config.cacheSwap.n_configured; i++)
+    for (int i = 0; i < Config.cacheSwap.n_configured; i++)
         result += store(i)->maxSize();
 
     return result;
 }
 
-size_t
+uint64_t
 StoreHashIndex::minSize() const
 {
-    size_t result = 0;
+    uint64_t result = 0;
 
     for (int i = 0; i < Config.cacheSwap.n_configured; i++)
         result += store(i)->minSize();
index be83ca0a8237047a6a96382b089d447f406ebdef..06f1377a4ab10e75692b4e116eecf200b52d5e43 100644 (file)
@@ -155,14 +155,14 @@ cache_key *
 storeKeyDup(const cache_key * key)
 {
     cache_key *dup = (cache_key *)memAllocate(MEM_MD5_DIGEST);
-    xmemcpy(dup, key, SQUID_MD5_DIGEST_LENGTH);
+    memcpy(dup, key, SQUID_MD5_DIGEST_LENGTH);
     return dup;
 }
 
 cache_key *
 storeKeyCopy(cache_key * dst, const cache_key * src)
 {
-    xmemcpy(dst, src, SQUID_MD5_DIGEST_LENGTH);
+    memcpy(dst, src, SQUID_MD5_DIGEST_LENGTH);
     return dst;
 }
 
index d1113226453deb8995836ed561fcaefe04f3b9bd..56bbcec8c2343f78753db0f0fbc3c414d3c92ad3 100644 (file)
@@ -35,6 +35,7 @@
 #include "squid.h"
 #include "HttpReply.h"
 #include "log/File.h"
+#include "log/Tokens.h"
 #include "MemObject.h"
 #include "mgr/Registration.h"
 #include "Store.h"
index 0fa50acaf48f080afda4a751027ca25a2cd044d1..ed17af445a2b2357b2cf1021fa6c742ff17662f0 100644 (file)
@@ -135,15 +135,15 @@ storeSwapMetaPack(tlv * tlv_list, int *length)
 
     buf[j++] = (char) STORE_META_OK;
 
-    xmemcpy(&buf[j], &buflen, sizeof(int));
+    memcpy(&buf[j], &buflen, sizeof(int));
 
     j += sizeof(int);
 
     for (t = tlv_list; t; t = t->next) {
         buf[j++] = t->getType();
-        xmemcpy(&buf[j], &t->length, sizeof(int));
+        memcpy(&buf[j], &t->length, sizeof(int));
         j += sizeof(int);
-        xmemcpy(&buf[j], t->value, t->length);
+        memcpy(&buf[j], t->value, t->length);
         j += t->length;
     }
 
index d9b98952f6a11d6b64b29fd98d97c9ef056b7832..f0ac547c9b08068e5fbfcdfdcd5559adc2424f75 100644 (file)
@@ -47,6 +47,12 @@ static void storeSwapOutStart(StoreEntry * e);
 static StoreIOState::STIOCB storeSwapOutFileClosed;
 static StoreIOState::STFNCB storeSwapOutFileNotify;
 
+// wrapper to cross C/C++ ABI boundary. xfree is extern "C" for libraries.
+static void xfree_cppwrapper(void *x)
+{
+    xfree(x);
+}
+
 /* start swapping object to disk */
 static void
 storeSwapOutStart(StoreEntry * e)
@@ -96,7 +102,7 @@ storeSwapOutStart(StoreEntry * e)
     e->swap_dirn = mem->swapout.sio->swap_dirn;
 
     /* write out the swap metadata */
-    storeIOWrite(mem->swapout.sio, buf, mem->swap_hdr_sz, 0, xfree);
+    storeIOWrite(mem->swapout.sio, buf, mem->swap_hdr_sz, 0, xfree_cppwrapper);
 }
 
 static void
index 86ba3965538471bc39bbbc141691dded3b03a8b7..2f70ffe98b4b27b88b6e156e6ffbd53294065d7d 100644 (file)
 /* for ICP_END */
 #include "icp_opcode.h"
 
+#if USE_SSL
+#include <openssl/ssl.h>
+#endif
+
 #define PEER_MULTICAST_SIBLINGS 1
 
 struct acl_name_list {
@@ -163,6 +167,7 @@ struct SquidConfig {
 #if USE_HTTP_VIOLATIONS
     time_t negativeTtl;
 #endif
+    time_t maxStale;
     time_t negativeDnsTtl;
     time_t positiveDnsTtl;
     time_t shutdownLifetime;
@@ -195,6 +200,7 @@ struct SquidConfig {
     size_t maxRequestHeaderSize;
     int64_t maxRequestBodySize;
     int64_t maxChunkedRequestBodySize;
+    size_t maxRequestBufferSize;
     size_t maxReplyHeaderSize;
     acl_size_t *ReplyBodySize;
 
@@ -256,27 +262,10 @@ struct SquidConfig {
     struct {
         char *store;
         char *swap;
-#if USE_USERAGENT_LOG
-
-        char *useragent;
-#endif
-#if USE_REFERER_LOG
-
-        char *referer;
-#endif
-#if WIP_FWD_LOG
-
-        char *forward;
-#endif
-
-        logformat *logformats;
-
         customlog *accesslogs;
-
 #if ICAP_CLIENT
         customlog *icaplogs;
 #endif
-
         int rotateNumber;
     } Log;
     char *adminEmail;
@@ -498,6 +487,7 @@ struct SquidConfig {
         int passive;
         int epsv_all;
         int epsv;
+        int eprt;
         int sanitycheck;
         int telnet;
     } Ftp;
@@ -726,6 +716,7 @@ public:
     int max_age;
     int s_maxage;
     int max_stale;
+    int stale_if_error;
     int min_fresh;
     String other;
 };
@@ -1118,6 +1109,7 @@ struct _refresh_t {
         unsigned int ignore_auth:1;
 #endif
     } flags;
+    int max_stale;
 };
 
 /*
@@ -1310,23 +1302,17 @@ struct _store_rebuild_data {
     int zero_object_sz;
 };
 
-class logformat_token;
-
-struct _logformat {
-    char *name;
-    logformat_token *format;
-    logformat *next;
-};
-
 class Logfile;
+class logformat;
 
+#include "log/Formats.h"
 struct _customlog {
     char *filename;
     ACLList *aclList;
     logformat *logFormat;
     Logfile *logfile;
     customlog *next;
-    customlog_type type;
+    Log::Format::log_type type;
 };
 
 #endif /* SQUID_STRUCTS_H */
index 489896500d3ace1654b395cbc9d240cb1f36913a..30ae1dbf0989a6b7c1ba841f6cd7cd249a3060ed 100644 (file)
@@ -225,7 +225,7 @@ cacheEntryCreate(const storeSwapLogData * s)
     CacheEntry *e = (CacheEntry *)xcalloc(1, sizeof(CacheEntry));
     assert(s);
     /* e->s = *s; */
-    xmemcpy(e->key_arr, s->key, SQUID_MD5_DIGEST_LENGTH);
+    memcpy(e->key_arr, s->key, SQUID_MD5_DIGEST_LENGTH);
     e->key = &e->key_arr[0];
     return e;
 }
@@ -491,7 +491,7 @@ accessLogReader(FileIterator * fi)
      * strcmp(hier, "SSL_PARENT_MISS") &&
      * strcmp(hier, "DEFAULT_PARENT");
      */
-    xmemcpy(entry->key, storeKeyPublic(url, method_id), sizeof(entry->key));
+    memcpy(entry->key, storeKeyPublic(url, method_id), sizeof(entry->key));
 
     /*fprintf(stdout, "%s:%d: %s %s %s %s\n",
      * fname, count, method, storeKeyText(entry->key), url, hier); */
index c24fb83ad418f72c6c03b24da64f15f8fb44845d..0ca06d32e22c2a5086b051b40df3ff2def668d4b 100644 (file)
@@ -3,7 +3,7 @@
 #include "squid.h"
 #include "TestSwapDir.h"
 
-size_t
+uint64_t
 TestSwapDir::maxSize() const
 {
     return 3;
index d93fcd6dbcaf529eb138bebdef4b5780ad2bb374..d58c4ace643e9fb1d643586ea43d2fff3b57767c 100644 (file)
@@ -12,7 +12,7 @@ public:
 
     bool statsCalled;
 
-    virtual size_t maxSize() const;
+    virtual uint64_t maxSize() const;
     virtual void stat(StoreEntry &) const; /* output stats to the provided store entry */
 
     virtual void reconfigure(int, char*);
index adb10851cccf8ca4147ee0bc50e6e0da13bba3bd..6c2eb1bc0346c12133c2f9cdffe6cebf1f75c07c 100644 (file)
@@ -23,7 +23,7 @@ HelperChildConfig::operator =(const HelperChildConfig &rhs)
     return *this;
 }
 
-const int
+int
 HelperChildConfig::needNew() const
 {
     /* during the startup and reconfigure use our special amount... */
index b744abc637d6146caab67dd1ca2e902e71f69169..c7ee10f135daf19baacafabf169d03cc653ef2c4 100644 (file)
@@ -36,7 +36,7 @@
 Mgr::Action::Pointer
 CacheManager::createNamedAction(char const* action)
 {
-    fatal ("Not implemented");
+    fatal("Not implemented");
     return NULL;
 }
 
@@ -46,12 +46,12 @@ CacheManager::Start(int fd, HttpRequest * request, StoreEntry * entry)
     return;
 }
 
+CacheManager* CacheManager::instance=0;
+
 CacheManager*
-CacheManager::GetInstance(void)
+CacheManager::GetInstance()
 {
-    static CacheManager *instance = 0;
-    if (!instance)
-        instance = new CacheManager();
+    fatal("Not implemented");
     return instance;
 }
 
index 45f8a8b906fce2da268ade94e9a680a219560682..a2007ae53819be29d9202261a4dc6be6b259edfe 100644 (file)
@@ -34,6 +34,7 @@
 
 #include "squid.h"
 #include "comm.h"
+#include "comm/Loops.h"
 #include "CommRead.h"
 #include "fde.h"
 
@@ -90,14 +91,13 @@ commSetCloseOnExec(int fd)
 }
 
 void
-commSetSelect(int fd, unsigned int type, PF * handler, void *client_data,
-              time_t timeout)
+Comm::SetSelect(int fd, unsigned int type, PF * handler, void *client_data, time_t timeout)
 {
     /* all test code runs synchronously at the moment */
 }
 
 void
-comm_quick_poll_required()
+Comm::QuickPollRequired()
 {
     /* for tests ... ignore */
 }
diff --git a/src/tests/stub_ipc_Forwarder.cc b/src/tests/stub_ipc_Forwarder.cc
new file mode 100644 (file)
index 0000000..03234df
--- /dev/null
@@ -0,0 +1,8 @@
+#include "config.h"
+#include "ipc/Forwarder.h"
+
+//Avoid linker errors about Ipc::Forwarder
+void foo_stub_ipc_forwarder()
+{
+    Ipc::Forwarder foo(NULL,1.0);
+}
index ec8407daa44bd97502ac83780b6b419cd513b04f..9832a53f9f2114c78ebc41ac1f36b70bb40361b7 100644 (file)
@@ -43,7 +43,7 @@ storeAppendPrintf(StoreEntry * e, const char *fmt,...)
     fatal("storeAppendPrintf: Not implemented");
 }
 
-extern "C" void
+void
 storeAppendVPrintf(StoreEntry * e, const char *fmt, va_list vargs)
 {
     fatal("storeAppendVPrintf: Not implemented");
index 6be5f03067704c5401e52f0f95f1fcbe7a1d0bb7..6e76cf159c29a36df0c5a39d1e31ae76c4fd5fbc 100644 (file)
@@ -13,17 +13,13 @@ TestStore::callback()
 }
 
 StoreEntry*
-
-TestStore::get
-(const cache_key*)
+TestStore::get(const cache_key*)
 {
     return NULL;
 }
 
 void
-
-TestStore::get
-(String, void (*)(StoreEntry*, void*), void*)
+TestStore::get(String, void (*)(StoreEntry*, void*), void*)
 {}
 
 void
@@ -31,13 +27,13 @@ void
 TestStore::init()
 {}
 
-size_t
+uint64_t
 TestStore::maxSize() const
 {
     return 3;
 }
 
-size_t
+uint64_t
 TestStore::minSize() const
 {
     return 1;
@@ -58,7 +54,7 @@ TestStore::search(String const url, HttpRequest *)
 void
 testStore::testSetRoot()
 {
-    StorePointer aStore (new TestStore);
+    StorePointer aStore(new TestStore);
     Store::Root(aStore);
 
     CPPUNIT_ASSERT(&Store::Root() == aStore.getRaw());
@@ -68,8 +64,8 @@ testStore::testSetRoot()
 void
 testStore::testUnsetRoot()
 {
-    StorePointer aStore (new TestStore);
-    StorePointer aStore2 (new TestStore);
+    StorePointer aStore(new TestStore);
+    StorePointer aStore2(new TestStore);
     Store::Root(aStore);
     Store::Root(aStore2);
     CPPUNIT_ASSERT(&Store::Root() == aStore2.getRaw());
@@ -79,7 +75,7 @@ testStore::testUnsetRoot()
 void
 testStore::testStats()
 {
-    TestStorePointer aStore (new TestStore);
+    TestStorePointer aStore(new TestStore);
     Store::Root(aStore.getRaw());
     CPPUNIT_ASSERT(aStore->statsCalled == false);
     Store::Stats(NullStoreEntry::getInstance());
@@ -90,7 +86,7 @@ testStore::testStats()
 void
 testStore::testMaxSize()
 {
-    StorePointer aStore (new TestStore);
+    StorePointer aStore(new TestStore);
     Store::Root(aStore.getRaw());
     CPPUNIT_ASSERT(aStore->maxSize() == 3);
     Store::Root(NULL);
index 804a92f44dc82c30f2e926a4e7ae2deee6797721..fbdf7e0b4106b0e7742c2c61776b55c91ea7f4db 100644 (file)
@@ -55,9 +55,9 @@ public:
 
     virtual void maintain() {};
 
-    virtual size_t maxSize() const;
+    virtual uint64_t maxSize() const;
 
-    virtual size_t minSize() const;
+    virtual uint64_t minSize() const;
 
     virtual void stat(StoreEntry &) const; /* output stats to the provided store entry */
 
index f1ef387be413f4029e2d4a7c637741607e2bbea0..bb0bbdd9c81d5aa7eeac390fb993456477660ddd 100644 (file)
@@ -68,3 +68,66 @@ TimeEngine::tick()
 {
     getCurrentTime();
 }
+
+const char *
+Time::FormatStrf(time_t t)
+{
+    struct tm *tm;
+    static char buf[128];
+    static time_t last_t = 0;
+
+    if (t != last_t) {
+        tm = localtime(&t);
+        strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm);
+        last_t = t;
+    }
+
+    return buf;
+}
+
+const char *
+Time::FormatHttpd(time_t t)
+{
+    static char buf[128];
+    static time_t last_t = 0;
+
+    if (t != last_t) {
+        struct tm *gmt = gmtime(&t);
+
+#if !USE_GMT
+        int gmt_min, gmt_hour, gmt_yday, day_offset;
+        size_t len;
+        struct tm *lt;
+        int min_offset;
+
+        /* localtime & gmtime may use the same static data */
+        gmt_min = gmt->tm_min;
+        gmt_hour = gmt->tm_hour;
+        gmt_yday = gmt->tm_yday;
+
+        lt = localtime(&t);
+
+        day_offset = lt->tm_yday - gmt_yday;
+        /* wrap round on end of year */
+        if (day_offset > 1)
+            day_offset = -1;
+        else if (day_offset < -1)
+            day_offset = 1;
+
+        min_offset = day_offset * 1440 + (lt->tm_hour - gmt_hour) * 60
+                     + (lt->tm_min - gmt_min);
+
+        len = strftime(buf, 127 - 5, "%d/%b/%Y:%H:%M:%S ", lt);
+        snprintf(buf + len, 128 - len, "%+03d%02d",
+                 (min_offset / 60) % 24,
+                 min_offset % 60);
+#else /* USE_GMT */
+        buf[0] = '\0';
+        strftime(buf, 127, "%d/%b/%Y:%H:%M:%S -000", gmt);
+#endif /* USE_GMT */
+
+        last_t = t;
+    }
+
+    return buf;
+}
index f3118949e9d0be8ccb059e4e1132c43bfd3e39ef..64af91020afc3b0e7a444a9f0b627c49ce3b8e97 100644 (file)
@@ -240,13 +240,13 @@ squid_getrusage(struct rusage *r)
 
     memset(r, '\0', sizeof(struct rusage));
 #if HAVE_GETRUSAGE && defined(RUSAGE_SELF)
-#ifdef _SQUID_SOLARIS_
+#if _SQUID_SOLARIS_
     /* Solaris 2.5 has getrusage() permission bug -- Arjan de Vet */
     enter_suid();
 #endif
 
     getrusage(RUSAGE_SELF, r);
-#ifdef _SQUID_SOLARIS_
+#if _SQUID_SOLARIS_
 
     leave_suid();
 #endif
@@ -997,7 +997,7 @@ setMaxFD(void)
 void
 setSystemLimits(void)
 {
-#if HAVE_SETRLIMIT && defined(RLIMIT_NOFILE) && !defined(_SQUID_CYGWIN_)
+#if HAVE_SETRLIMIT && defined(RLIMIT_NOFILE) && !_SQUID_CYGWIN_
     /* limit system filedescriptors to our own limit */
     struct rlimit rl;
     if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
@@ -1149,9 +1149,8 @@ parseEtcHosts(void)
         return;
     }
 
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
     setmode(fileno(fp), O_TEXT);
-
 #endif
 
     while (fgets(buf, 1024, fp)) {     /* for each line */
index 9186321b1be5a94cf54c99cae9c26c2e1b096549..dcd614a9b0d0be4e091e7f9f65d418c4b0cb95d7 100644 (file)
@@ -47,12 +47,6 @@ typedef struct {
     size_t kb;
 } kb_t;
 
-//UNUSED               typedef struct _acl_time_data acl_time_data;
-//UNUSED               typedef struct _acl_name_list acl_name_list;
-//UNUSED               typedef struct _acl_deny_info_list acl_deny_info_list;
-//UNUSED               typedef class AuthUser auth_user_t;
-
-
 /// \ingroup AuthAPI
 /// \deprecated Use AuthUserHashPointer instead.
 typedef struct AuthUserHashPointer auth_user_hash_pointer;
@@ -63,21 +57,9 @@ typedef struct AuthUserHashPointer auth_user_hash_pointer;
 class AuthConfig;
 typedef Vector<AuthConfig *> authConfig;
 
-//UNUSED               typedef struct _acl_snmp_comm acl_snmp_comm;
-//UNUSED               typedef class ACLList acl_list;
-//UNUSED               typedef struct _acl_address acl_address;
-//UNUSED               typedef struct _acl_tos acl_tos;
-//UNUSED               typedef struct _acl_size_t acl_size_t;
-//UNUSED               class ACLChecklist;
-//UNUSED               typedef struct _ushortlist ushortlist;
-//UNUSED               typedef struct _relist relist;
-
 struct http_port_list;
 struct https_port_list;
 
-//UNUSED       typedef struct _SquidConfig SquidConfig;
-//UNUSED       typedef struct _SquidConfig2 SquidConfig2;
-
 typedef struct _close_handler close_handler;
 
 typedef struct _dread_ctrl dread_ctrl;
@@ -86,26 +68,16 @@ typedef struct _dwrite_q dwrite_q;
 
 typedef struct _ETag ETag;
 
-//UNUSED               class fde;
-
 typedef struct _fileMap fileMap;
 
 typedef struct _HttpHeaderFieldAttrs HttpHeaderFieldAttrs;
 
-//UNUSED               class HttpHeaderFieldInfo;
-//UNUSED               class HttpHeader;
-//UNUSED               class HttpHdrCc;
-
 typedef struct _TimeOrTag TimeOrTag;
 
-//UNUSED               class HttpHeaderFieldStat;
-
 typedef struct _HttpHeaderStat HttpHeaderStat;
 
 typedef struct _HttpBody HttpBody;
 
-//UNUSED               class HttpReply;
-
 typedef struct _ConnCloseHelperData ConnCloseHelperData;
 
 typedef struct _ipcache_addrs ipcache_addrs;
@@ -118,10 +90,6 @@ typedef struct _DynPool DynPool;
 
 typedef struct _DigestFetchState DigestFetchState;
 
-//UNUSED               class PeerDigest;
-
-//UNUSED typedef struct _peer peer;
-
 typedef struct _net_db_name net_db_name;
 
 typedef struct _net_db_peer net_db_peer;
@@ -134,20 +102,12 @@ typedef struct _Meta_data Meta_data;
 
 typedef struct _iostats iostats;
 
-//UNUSED               class MemBuf;
-
-//UNUSED               class store_client;
-
-//UNUSED               class SwapDir;
-
 typedef struct _http_state_flags http_state_flags;
 
 typedef struct _header_mangler header_mangler;
 
 typedef struct _body_size body_size;
 
-//UNUSED               class HttpRequest;
-
 typedef struct _cachemgr_passwd cachemgr_passwd;
 
 typedef struct _refresh_t refresh_t;
@@ -156,7 +116,6 @@ typedef struct _CommWriteStateData CommWriteStateData;
 
 typedef struct _StatCounters StatCounters;
 
-/// \todo DROP: deprecated and no longer used.
 typedef struct _storeSwapLogData storeSwapLogData;
 
 typedef struct _StatHist StatHist;
@@ -169,8 +128,6 @@ typedef struct _Version Version;
 
 typedef struct _link_list link_list;
 
-typedef struct _logformat logformat;
-
 typedef struct _customlog customlog;
 
 #if SQUID_SNMP
index 0e5d688cb8b4f6cd4c33de28c0e387d38b67f266..24d635412d39930b546440ca9a9c19d3118c891e 100644 (file)
@@ -934,7 +934,7 @@ URLHostName::trimAuth()
 
     if ((t = strrchr(Host, '@'))) {
         t++;
-        xmemmove(Host, t, strlen(t) + 1);
+        memmove(Host, t, strlen(t) + 1);
     }
 }
 
index e96f2ad1df998e37d5375463833f9c4300f5ed79..8e1c4ad7145bf5009ec876ca79c37e6228a2feac 100644 (file)
@@ -482,7 +482,7 @@ urnParseReply(const char *inbuf, const HttpRequestMethod& m)
             old = list;
             n <<= 2;
             list = (url_entry *)xcalloc(n + 1, sizeof(*list));
-            xmemcpy(list, old, i * sizeof(*list));
+            memcpy(list, old, i * sizeof(*list));
             safe_free(old);
         }
 
index 9f0f5147987feac0137ea8f5eb3a19abf80b5138..fdad1a0a8229df7c5c5e374d73a071eb46bee60d 100644 (file)
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
  *
  */
+#include "config.h"
+
+#if USE_WCCP
+
 #include "squid.h"
 #include "comm.h"
+#include "comm/Loops.h"
 #include "event.h"
 
-#if USE_WCCP
-
 #define WCCP_PORT 2048
 #define WCCP_REVISION 0
 #define WCCP_ACTIVE_CACHES 32
@@ -157,11 +160,7 @@ wccpConnectionOpen(void)
     if (theWccpConnection < 0)
         fatal("Cannot open WCCP Port");
 
-    commSetSelect(theWccpConnection,
-                  COMM_SELECT_READ,
-                  wccpHandleUdp,
-                  NULL,
-                  0);
+    Comm::SetSelect(theWccpConnection, COMM_SELECT_READ, wccpHandleUdp, NULL, 0);
 
     debugs(80, 1, "Accepting WCCPv1 messages on " << Config.Wccp.address << ", FD " << theWccpConnection << ".");
 
@@ -208,7 +207,7 @@ wccpHandleUdp(int sock, void *not_used)
 
     debugs(80, 6, "wccpHandleUdp: Called.");
 
-    commSetSelect(sock, COMM_SELECT_READ, wccpHandleUdp, NULL, 0);
+    Comm::SetSelect(sock, COMM_SELECT_READ, wccpHandleUdp, NULL, 0);
 
     memset(&wccp_i_see_you, '\0', sizeof(wccp_i_see_you));
 
@@ -354,9 +353,9 @@ wccpAssignBuckets(void)
 
     for (loop = 0; loop < number_caches; loop++) {
         int i;
-        xmemcpy(&caches[loop],
-                &wccp_i_see_you.wccp_cache_entry[loop].ip_addr,
-                sizeof(*caches));
+        memcpy(&caches[loop],
+               &wccp_i_see_you.wccp_cache_entry[loop].ip_addr,
+               sizeof(*caches));
 
         for (i = 0; i < buckets_per_cache; i++) {
             assert(bucket < WCCP_BUCKETS);
index f9af664b1632336f90e9de95f3e7cd9d2cbda59e..6e8cb568fde70c921e065469bbed9208e4f21239 100644 (file)
@@ -35,6 +35,7 @@
 #if USE_WCCPv2
 
 #include "comm.h"
+#include "comm/Loops.h"
 #include "compat/strsep.h"
 #include "event.h"
 #include "ip/Address.h"
@@ -744,13 +745,11 @@ wccp2Init(void)
         service_list_ptr->security_info = (struct wccp2_security_md5_t *) ptr;
 
         if (service_list_ptr->wccp2_security_type == WCCP2_MD5_SECURITY) {
-
-            xmemcpy(ptr, &wccp2_security_md5, sizeof(struct wccp2_security_md5_t));
-
+            memcpy(ptr, &wccp2_security_md5, sizeof(struct wccp2_security_md5_t));
             ptr += sizeof(struct wccp2_security_md5_t);
         } else {
             /* assume NONE, and XXX I hate magic length numbers */
-            xmemcpy(ptr, &wccp2_security_md5, 8);
+            memcpy(ptr, &wccp2_security_md5, 8);
             ptr += 8;
         }
 
@@ -760,7 +759,7 @@ wccp2Init(void)
 
         assert(wccp2_here_i_am_header.length <= WCCP_RESPONSE_SIZE);
 
-        xmemcpy(ptr, &service_list_ptr->info, sizeof(struct wccp2_service_info_t));
+        memcpy(ptr, &service_list_ptr->info, sizeof(struct wccp2_service_info_t));
 
         service_list_ptr->service_info = (struct wccp2_service_info_t *) ptr;
 
@@ -783,7 +782,7 @@ wccp2Init(void)
             wccp2_identity_info.cache_identity.weight = htons(Config.Wccp2.weight);
             memset(&wccp2_identity_info.cache_identity.status, '\0', sizeof(wccp2_identity_info.cache_identity.status));
 
-            xmemcpy(ptr, &wccp2_identity_info, sizeof(struct wccp2_identity_info_t));
+            memcpy(ptr, &wccp2_identity_info, sizeof(struct wccp2_identity_info_t));
             service_list_ptr->wccp2_identity_info_ptr = ptr;
 
             ptr += sizeof(struct wccp2_identity_info_t);
@@ -817,7 +816,7 @@ wccp2Init(void)
             wccp2_mask_identity_info.cache_identity.weight = 0;
             wccp2_mask_identity_info.cache_identity.status = 0;
 
-            xmemcpy(ptr, &wccp2_mask_identity_info, sizeof(struct wccp2_mask_identity_info_t));
+            memcpy(ptr, &wccp2_mask_identity_info, sizeof(struct wccp2_mask_identity_info_t));
             service_list_ptr->wccp2_identity_info_ptr = ptr;
 
             ptr += sizeof(struct wccp2_mask_identity_info_t);
@@ -839,7 +838,7 @@ wccp2Init(void)
 
         wccp2_cache_view_header.cache_view_version = htonl(1);
 
-        xmemcpy(ptr, &wccp2_cache_view_header, sizeof(wccp2_cache_view_header));
+        memcpy(ptr, &wccp2_cache_view_header, sizeof(wccp2_cache_view_header));
 
         ptr += sizeof(wccp2_cache_view_header);
 
@@ -850,7 +849,7 @@ wccp2Init(void)
 
         service_list_ptr->num_routers = htonl(wccp2_numrouters);
 
-        xmemcpy(ptr, &service_list_ptr->num_routers, sizeof(service_list_ptr->num_routers));
+        memcpy(ptr, &service_list_ptr->num_routers, sizeof(service_list_ptr->num_routers));
 
         ptr += sizeof(service_list_ptr->num_routers);
 
@@ -890,7 +889,7 @@ wccp2Init(void)
 
         wccp2_cache_view_info.num_caches = htonl(0);
 
-        xmemcpy(ptr, &wccp2_cache_view_info.num_caches, sizeof(wccp2_cache_view_info.num_caches));
+        memcpy(ptr, &wccp2_cache_view_info.num_caches, sizeof(wccp2_cache_view_info.num_caches));
 
         ptr += sizeof(wccp2_cache_view_info.num_caches);
 
@@ -903,7 +902,7 @@ wccp2Init(void)
 
         wccp2_capability_info_header.capability_info_length = htons(3 * sizeof(wccp2_capability_element));
 
-        xmemcpy(ptr, &wccp2_capability_info_header, sizeof(wccp2_capability_info_header));
+        memcpy(ptr, &wccp2_capability_info_header, sizeof(wccp2_capability_info_header));
 
         ptr += sizeof(wccp2_capability_info_header);
 
@@ -918,7 +917,7 @@ wccp2Init(void)
 
         wccp2_capability_element.capability_value = htonl(Config.Wccp2.forwarding_method);
 
-        xmemcpy(ptr, &wccp2_capability_element, sizeof(wccp2_capability_element));
+        memcpy(ptr, &wccp2_capability_element, sizeof(wccp2_capability_element));
 
         ptr += sizeof(wccp2_capability_element);
 
@@ -933,7 +932,7 @@ wccp2Init(void)
 
         wccp2_capability_element.capability_value = htonl(Config.Wccp2.assignment_method);
 
-        xmemcpy(ptr, &wccp2_capability_element, sizeof(wccp2_capability_element));
+        memcpy(ptr, &wccp2_capability_element, sizeof(wccp2_capability_element));
 
         ptr += sizeof(wccp2_capability_element);
 
@@ -948,7 +947,7 @@ wccp2Init(void)
 
         wccp2_capability_element.capability_value = htonl(Config.Wccp2.return_method);
 
-        xmemcpy(ptr, &wccp2_capability_element, sizeof(wccp2_capability_element));
+        memcpy(ptr, &wccp2_capability_element, sizeof(wccp2_capability_element));
 
         ptr += sizeof(wccp2_capability_element);
 
@@ -1011,11 +1010,7 @@ wccp2ConnectionOpen(void)
     }
 
 #endif
-    commSetSelect(theWccp2Connection,
-                  COMM_SELECT_READ,
-                  wccp2HandleUdp,
-                  NULL,
-                  0);
+    Comm::SetSelect(theWccp2Connection, COMM_SELECT_READ, wccp2HandleUdp, NULL, 0);
 
     debugs(80, 1, "Accepting WCCPv2 messages on port " << WCCP_PORT << ", FD " << theWccp2Connection << ".");
     debugs(80, 1, "Initialising all WCCPv2 lists");
@@ -1176,7 +1171,7 @@ wccp2HandleUdp(int sock, void *not_used)
 
     debugs(80, 6, "wccp2HandleUdp: Called.");
 
-    commSetSelect(sock, COMM_SELECT_READ, wccp2HandleUdp, NULL, 0);
+    Comm::SetSelect(sock, COMM_SELECT_READ, wccp2HandleUdp, NULL, 0);
 
     /* FIXME INET6 : drop conversion boundary */
     Ip::Address from_tmp;
@@ -1766,7 +1761,7 @@ wccp2AssignBuckets(void *voidnotused)
         offset += sizeof(struct assignment_key_t);
 
         /* Number of routers */
-        xmemcpy(&wccp_packet[offset], &service_list_ptr->num_routers, sizeof(service_list_ptr->num_routers));
+        memcpy(&wccp_packet[offset], &service_list_ptr->num_routers, sizeof(service_list_ptr->num_routers));
 
         offset += sizeof(service_list_ptr->num_routers);
 
@@ -1795,7 +1790,7 @@ wccp2AssignBuckets(void *voidnotused)
 
             case WCCP2_ASSIGNMENT_METHOD_HASH:
                 /* Number of caches */
-                xmemcpy(&wccp_packet[offset], &router_list_ptr->num_caches, sizeof(router_list_ptr->num_caches));
+                memcpy(&wccp_packet[offset], &router_list_ptr->num_caches, sizeof(router_list_ptr->num_caches));
                 offset += sizeof(router_list_ptr->num_caches);
 
                 if (num_caches) {
@@ -1806,7 +1801,7 @@ wccp2AssignBuckets(void *voidnotused)
 
                         cache_address = (struct in_addr *) &wccp_packet[offset];
 
-                        xmemcpy(cache_address, &cache_list_ptr->cache_ip, sizeof(struct in_addr));
+                        memcpy(cache_address, &cache_list_ptr->cache_ip, sizeof(struct in_addr));
                         total_weight += cache_list_ptr->weight << 12;
                         weight[cache] = cache_list_ptr->weight << 12;
 
@@ -1865,7 +1860,7 @@ wccp2AssignBuckets(void *voidnotused)
 
             case WCCP2_ASSIGNMENT_METHOD_MASK:
                 num_maskval = htonl(1);
-                xmemcpy(&wccp_packet[offset], &num_maskval, sizeof(int));
+                memcpy(&wccp_packet[offset], &num_maskval, sizeof(int));
                 offset += sizeof(int);
 
                 mask_element = (struct wccp2_mask_element_t *) &wccp_packet[offset];
index 5f16136198d5d6f2b340cc29542e07bb4d1ea9b3..64cee2670772c567c909826caa8292817260fa29 100755 (executable)
@@ -53,7 +53,7 @@ fi
 # do not build any of the install's ...
 #
 # eval is need to correctly handle quoted arguments
-       eval "$base/../configure ${SQUID_CONFIGURE_FLAGS} ${configcache}" \
+       eval "$base/../configure ${DISTCHECK_CONFIGURE_FLAGS} ${configcache}" \
                2>&1 && \
        make ${pjobs} ${MAKETEST} 2>&1
 
index 46c1ab4ea627993088490970cdb78084c88c180f..3e9096c75a8d56ec6efaeccc19013b26aeceed0a 100644 (file)
@@ -9,11 +9,11 @@
 MAKETEST="distcheck"
 #
 #
-# The options for this level can be easily generated semi-automatically from configure.in by:
-#      grep -E "^AC_ARG_ENABLE" ./configure.in | grep -o -E "[0-9a-z\-]+[,]" | grep -o -E "[^,]+" >disable.opts
+# The options for this level can be easily generated semi-automatically from configure.ac by:
+#      grep -E "^AC_ARG_ENABLE" ./configure.ac | grep -o -E "[0-9a-z\-]+[,]" | grep -o -E "[^,]+" >disable.opts
 # followed by insertion of '   --disable-' and '\' strings
 #
-#      grep -E "^AC_ARG_WITH" ./configure.in | grep -o -E "[0-9a-z\-]+[,]" | grep -o -E "[^,]+" >without.opts
+#      grep -E "^AC_ARG_WITH" ./configure.ac | grep -o -E "[0-9a-z\-]+[,]" | grep -o -E "[^,]+" >without.opts
 # followed by insertion of '   --without-' and ' \' strings
 #
 # sometimes it's just too automatic.. Following options should be just stripped
index 675b53a4539c5250c3f445d950914ab85c19c0da..c7360d6fbd8b5da3263162121e5dfba381d76156 100644 (file)
@@ -9,11 +9,11 @@
 MAKETEST="distcheck"
 #
 #
-# The options for this level can be easily generated semi-automatically from configure.in by:
-#      grep -E "^AC_ARG_ENABLE" ./configure.in | grep -o -E "[0-9a-z\-]+[,]" | grep -o -E "[^,]+" >disable.opts
+# The options for this level can be easily generated semi-automatically from configure.ac by:
+#      grep -E "^AC_ARG_ENABLE" ./configure.ac | grep -o -E "[0-9a-z\-]+[,]" | grep -o -E "[^,]+" >disable.opts
 # followed by insertion of '   --enable-' and '\' strings
 #
-#      grep -E "^AC_ARG_WITH" ./configure.in | grep -o -E "[0-9a-z\-]+[,]" | grep -o -E "[^,]+" >without.opts
+#      grep -E "^AC_ARG_WITH" ./configure.ac | grep -o -E "[0-9a-z\-]+[,]" | grep -o -E "[^,]+" >without.opts
 # followed by insertion of '   --with-' and ' \' strings
 #
 # sometimes it's just too automatic..
@@ -39,6 +39,8 @@ MAKETEST="distcheck"
 #   --enable-win32-service \
 #   --with-valgrind-debug \
 #
+#   --enable-cpu-profiling \  Requires CPU support.
+#
 #
 # NP: DISTCHECK_CONFIGURE_FLAGS is a magic automake macro for the 
 #     distcheck target recursive tests beteen scripted runs.
@@ -89,7 +91,6 @@ DISTCHECK_CONFIGURE_FLAGS=" \
        --enable-mempools \
        --enable-unlinkd \
        --enable-stacktraces \
-       --enable-cpu-profiling \
        --enable-vary \
        --enable-x-accelerator-vary \
        --enable-ipv6 \
index 6f0b135c37633c4c7c28987caecef30383fd49f0..6bb8ebf997ef2a98c727f92512ba1712966d8576 100644 (file)
@@ -312,7 +312,7 @@ handle_read(char *inbuf, int len)
         return -1;
     }
     total_bytes_read += len;
-    xmemcpy(buf, inbuf, len);
+    memcpy(buf, inbuf, len);
     if (len == 0) {
         fprintf(stderr, "WARNING: %s, server closed socket after %d+%d bytes\n", r->url, r->hdr_offset, r->bytes_read);
         /* XXX, If no data was received and it isn't the first request on this
@@ -331,12 +331,12 @@ handle_read(char *inbuf, int len)
         /* Build headers */
         if (r->hdr_length == 0) {
             hlen = min(len, REPLY_HDR_SZ - r->hdr_offset - 1);
-            xmemcpy(r->reply_hdrs + r->hdr_offset, buf, hlen);
+            memcpy(r->reply_hdrs + r->hdr_offset, buf, hlen);
             r->hdr_offset += hlen;
             r->reply_hdrs[r->hdr_offset] = '\0';
             len -= hlen;
             /* Save any remaining read data */
-            xmemmove(buf, buf + hlen, len);
+            memmove(buf, buf + hlen, len);
         }
         /* Process headers */
         if (r->hdr_length == 0 && (end = mime_headers_end(r->reply_hdrs)) != NULL) {
@@ -352,8 +352,8 @@ handle_read(char *inbuf, int len)
             blen = r->hdr_offset - r->hdr_length;
             assert(blen >= 0);
             if (blen > 0) {
-                xmemmove(buf + blen, buf, len);
-                xmemcpy(buf, r->reply_hdrs + r->hdr_length, blen);
+                memmove(buf + blen, buf, len);
+                memcpy(buf, r->reply_hdrs + r->hdr_length, blen);
                 len += blen;
             }
             r->reply_hdrs[r->hdr_length] = '\0';       /* Null terminate headers */
@@ -398,7 +398,7 @@ handle_read(char *inbuf, int len)
             } else if (r->content_length > -1) {
                 assert(r->bytes_read < r->content_length);
             }
-            xmemmove(buf, buf + bytes_used, len);
+            memmove(buf, buf + bytes_used, len);
         }
     }
     return 0;
index cb0144a95373b069c07d03e1fb42b7044c424a02..58b21d5b1ca24ffe71feb3ee3d48a570c59a83c7 100755 (executable)
@@ -24,6 +24,7 @@ for f in $@; do
     if [ ! -f "$t.o" -o $f -nt "$t.o" ]; then
         echo >$t.cc <<EOF
 /* This file is AUTOMATICALLY GENERATED. DO NOT ALTER IT */
+#include "config.h"
 #include "${f}"
 int main( int argc, char* argv[] ) { return 0; }
 EOF
index 8763081bdd50664de9e046e766846febdaef981c..a22e37b397df3fed863ad535ada1e6c37b8e07f3 100644 (file)
@@ -17,8 +17,6 @@ man_MANS =
 DISTCLEANFILES = 
 
 LDADD = \
-       $(top_builddir)/src/tests/stub_debug.o \
-       $(top_builddir)/src/time.o \
        $(top_builddir)/src/ip/libip.la \
        $(top_builddir)/lib/libmiscencoding.la \
        $(top_builddir)/lib/libmiscutil.la \
@@ -28,15 +26,23 @@ LDADD = \
 
 include $(top_srcdir)/doc/manuals/Substitute.am
 
+## Several files need to be shared but we cannot depend on the other
+## directories to be built.
 test_tools.cc: $(top_srcdir)/test-suite/test_tools.cc
        cp $(top_srcdir)/test-suite/test_tools.cc .
 
+stub_debug.cc: $(top_srcdir)/src/tests/stub_debug.cc
+       cp $(top_srcdir)/src/tests/stub_debug.cc .
+
+time.cc: $(top_srcdir)/src/time.cc
+       cp $(top_srcdir)/src/time.cc .
+
 # stock tools for unit tests - library independent versions of dlink_list
 # etc.
 # globals.cc is needed by test_tools.cc.
 # Neither of these should be disted from here.
 TESTSOURCES= test_tools.cc
-CLEANFILES += test_tools.cc
+CLEANFILES += test_tools.cc stub_debug.cc time.cc
 
 ## ##### helper-mux #####
 
@@ -51,7 +57,9 @@ EXTRA_DIST += helper-ok-dying.pl helper-ok.pl
 bin_PROGRAMS = squidclient
 
 squidclient_SOURCES = squidclient.cc \
-       test_tools.cc
+       stub_debug.cc \
+       test_tools.cc \
+       time.cc
 
 EXTRA_DIST += squidclient.1
 man_MANS += squidclient.1
@@ -65,7 +73,9 @@ DEFAULT_CACHEMGR_CONFIG = $(sysconfdir)/cachemgr.conf
 libexec_PROGRAMS = cachemgr$(CGIEXT)
 
 cachemgr__CGIEXT__SOURCES = cachemgr.cc \
-       test_tools.cc
+       stub_debug.cc \
+       test_tools.cc \
+       time.cc
 
 cachemgr__CGIEXT__CXXFLAGS = -DDEFAULT_CACHEMGR_CONFIG=\"$(DEFAULT_CACHEMGR_CONFIG)\" $(AM_CXXFLAGS)
 
index 07b6371c635c6958c7e5fb6a9a6bb38d97c61a7c..f70ed716641b44285675b6913c5a07ce3bb06138 100644 (file)
@@ -44,7 +44,7 @@ using namespace Squid;
 /** \endcond */
 #endif
 
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
 #include <io.h>
 #endif
 #if HAVE_STDIO_H
@@ -86,16 +86,18 @@ using namespace Squid;
 #include <gssapi/gssapi.h>
 #elif HAVE_GSSAPI_H
 #include <gssapi.h>
-#endif                          /* HAVE_GSSAPI_H */
-#if HAVE_GSSAPI_GSSAPI_EXT_H
-#include <gssapi/gssapi_ext.h>
-#endif                          /* HAVE_GSSAPI_GSSAPI_EXT_H */
+#endif /* HAVE_GSSAPI_GSSAPI_H/HAVE_GSSAPI_H */
+#if !HAVE_HEIMDAL_KERBEROS
 #if HAVE_GSSAPI_GSSAPI_KRB5_H
 #include <gssapi/gssapi_krb5.h>
-#endif                          /* HAVE_GSSAPI_GSSAPI_KRB5_H */
+#endif
 #if HAVE_GSSAPI_GSSAPI_GENERIC_H
 #include <gssapi/gssapi_generic.h>
-#endif                          /* HAVE_GSSAPI_GSSAPI_GENERIC_H */
+#endif
+#if HAVE_GSSAPI_GSSAPI_EXT_H
+#include <gssapi/gssapi_ext.h>
+#endif
+#endif
 
 #ifndef gss_nt_service_name
 #define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
@@ -126,8 +128,8 @@ static int client_comm_connect(int, const Ip::Address &, struct timeval *);
 static void usage(const char *progname);
 
 static int Now(struct timeval *);
-static SIGHDLR catchSignal;
-static SIGHDLR pipe_handler;
+SIGHDLR catchSignal;
+SIGHDLR pipe_handler;
 static void set_our_signal(void);
 static ssize_t myread(int fd, void *buf, size_t len);
 static ssize_t mywrite(int fd, void *buf, size_t len);
@@ -398,9 +400,8 @@ main(int argc, char *argv[])
                     xstrerror());
             exit(-1);
         }
-#ifdef _SQUID_WIN32_
+#if _SQUID_WINDOWS_
         setmode(put_fd, O_BINARY);
-
 #endif
 
         fstat(put_fd, &sb);
@@ -758,14 +759,14 @@ Now(struct timeval *tp)
 #endif
 }                              /* ARGSUSED */
 
-static void
+void
 catchSignal(int sig)
 {
     interrupted = 1;
     fprintf(stderr, "Interrupted.\n");
 }
 
-static void
+void
 pipe_handler(int sig)
 {
     fprintf(stderr, "SIGPIPE received.\n");