The OpenNET Project / Index page

[ новости/++ | форум | wiki | теги ]

WCCPv2 для squid на FreeBSD (eng) (eccp squid transparent proxy freebsd patch)


<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>
Ключевые слова: eccp, squid, transparent, proxy, freebsd, patch,  (найти похожие документы)
From: Sinyuk Roman <roman@univ.kiev.ua.> Date: Mon, 20 Jan 2005 18:21:07 +0000 (UTC) Subject: WCCPv2 для squid на FreeBSD (eng) Оригинал: http://www.univ.kiev.ua/~roman/wccpv2/ WCCPv2 for squid on FreeBSD howto Requirements: * Tested on FreeBSD 4.8R and FreeBSD-Stable. * Squid-2.5.STABLE4 * Cisco IOS with wccp support (ip plus or enterprise plus) Note: WCCPv1 and WCCPv2 have different encapsulation formats, and are not compatible. GRE frames with WCCPv2 encapsulated packets has extra 4 bytes in GRE header, and kernel code modification required. * Step 1. Modify /usr/src/sys/net/if_gre.h. Add in to struct gre_h 4 bytes field: struct gre_h { u_int16_t flags; /* GRE flags */ u_int16_t ptype; /* protocol type of payload typically Ether protocol type*/ u_int32_t xxx; /* Add it for WCCPv2 support */ ... * Step 2. Add "pseudo-device gre" to kernel configuration file, recompile kernel and reboot computer # cd /usr/src/sys/i386/conf # vi KERNEL_CONF # config -r KERNEL_CONF # cd ../../compile/KERNEL_CONF # make depend # make # make install # shutdown -r now * Step 3.a For installing squid from sources apply wccpv2 patch (modified version of Visolve patch) to squid sources before building: # fetch http://www.univ.kiev.ua/~roman/wccpv2/wccpv2.patch # tar -xzvf squid-2.5.STABLE4.tar.gz # cd squid-2.5.STABLE4 # patch -p1 < ../wccpv2.patch # ./configure --enable-wccpv2 ... # make # make install * Step 3.b For building squid from FreeBSD port (autoconf-2.* and automake-1.5* must be installed before): # fetch http://www.univ.kiev.ua/~roman/wccpv2/squid-2.5-wccpv2.tar.gz # tar -xzvf squid-2.5-wccpv2.tar.gz # cd squid-2.5-wccpv2 If you want to install squid with other then default prefix define PREFIX va riable: # export PREFIX=/usr/local/squid Add extra CONFIGURE_ARGS in Makefile.local (for example delay-pools, cache-d igests, ...) # vi Makefile.local Build and install port: # make # make install * Step 5. Create GRE tunnel to your Cisco router # ifconfig gre0 create # ifconfig gre0 link0 tunnel squid_host_IP router_IP up where: router_IP is IP address of routers physical interface (not loopback interface) * Step 7. Configure Cisco router # configure terminal # ip wccp 97 password abc123 # interface loopback 0 # ip address 192.168.0.1 255.255.255.255 # interface Serial 0 # ip wccp 97 redirect out # end where: 97 is wccp2_service_id parameter and abc123 is wccp2_password, both defined in squid.conf Interface loopback IP used by WCCPv2 as router-id. Interface Serial 0 is external interface. * Step 8. Configure IPFW # ipfw add fwd 127.0.0.1,3128 ip from any to any via gre0 in # ipfw add permit ip from any to any * Step 9. Configure squid. Edit squid.conf file and set: wccp2_router 192.168.0.1 wccp2_password abc123 wccp2_service_id 97 wccp2_redirect_port1 80 wccp2_redirect_port2 81 wccp2_redirect_port3 8000 wccp2_redirect_port4 8080 wccp2_redirect_port5 3128 wccp2_redirect_port6 8900 wccp2_redirect_port7 0 wccp2_redirect_port8 0 httpd_accel_host virtual httpd_accel_port 0 httpd_accel_with_proxy on httpd_accel_uses_host_header on * Step 10. Start squid.
wccpv2.patch diff -Nur squid-2.5.STABLE4/acconfig.h squid-2.5.STABLE4_wccpv2/acconfig.h --- squid-2.5.STABLE4/acconfig.h Mon Jul 1 11:55:11 2002 +++ squid-2.5.STABLE4_wccpv2/acconfig.h Sun Jan 25 04:31:20 2004 @@ -112,9 +112,14 @@ #undef SQUID_SNMP /* - * Define to enable WCCP + * Define to enable WCCPv1 */ #define USE_WCCP 1 + +/* + * Define to enable WCCP V2 + */ +#undef USE_WCCPv2 /* * Squid frequently calls gettimeofday() for accurate timestamping. diff -Nur squid-2.5.STABLE4/configure squid-2.5.STABLE4_wccpv2/configure --- squid-2.5.STABLE4/configure Mon Sep 15 03:37:04 2003 +++ squid-2.5.STABLE4_wccpv2/configure Sun Jan 25 04:31:20 2004 @@ -70,7 +70,9 @@ ac_help="$ac_help --enable-referer-log Enable logging of Referer header" ac_help="$ac_help - --disable-wccp Disable Web Cache Coordination Protocol" + --disable-wccp Disable Web Cache Coordination V1 Protocol" +ac_help="$ac_help + --enable-wccpv2 Enable Web Cache Coordination V2 Protocol" ac_help="$ac_help --enable-kill-parent-hack Kill parent on shutdown" @@ -2133,7 +2135,7 @@ if test "${enable_wccp+set}" = set; then enableval="$enable_wccp" if test "$enableval" = "no" ; then - echo "Web Cache Coordination Protocol disabled" + echo "Web Cache Coordination V1 Protocol disabled" cat >> confdefs.h <<\EOF #define USE_WCCP 0 EOF @@ -2161,6 +2163,35 @@ fi +if false; then + USE_WCCPv2_TRUE= + USE_WCCPv2_FALSE='#' +else + USE_WCCPv2_TRUE='#' + USE_WCCPv2_FALSE= +fi +# Check whether --enable-wccpv2 or --disable-wccpv2 was given. +if test "${enable_wccpv2+set}" = set; then + enableval="$enable_wccpv2" + if test "$enableval" = "yes"; then + echo "Web Cache Coordination V2 Protocol Enabled" + cat >> confdefs.h <<\EOF +#define USE_WCCPv2 1 +EOF + + + +if true; then + USE_WCCPv2_TRUE= + USE_WCCPv2_FALSE='#' +else + USE_WCCPv2_TRUE='#' + USE_WCCPv2_FALSE= +fi + fi + +fi + @@ -8594,6 +8625,8 @@ s%@ENABLE_PINGER_FALSE@%$ENABLE_PINGER_FALSE%g s%@USE_DELAY_POOLS_TRUE@%$USE_DELAY_POOLS_TRUE%g s%@USE_DELAY_POOLS_FALSE@%$USE_DELAY_POOLS_FALSE%g +s%@USE_WCCPv2_TRUE@%$USE_WCCPv2_TRUE%g +s%@USE_WCCPv2_FALSE@%$USE_WCCPv2_FALSE%g s%@USE_SNMP_TRUE@%$USE_SNMP_TRUE%g s%@USE_SNMP_FALSE@%$USE_SNMP_FALSE%g s%@SNMPLIB@%$SNMPLIB%g diff -Nur squid-2.5.STABLE4/configure.in squid-2.5.STABLE4_wccpv2/configure.in --- squid-2.5.STABLE4/configure.in Mon Sep 15 03:37:04 2003 +++ squid-2.5.STABLE4_wccpv2/configure.in Sun Jan 25 04:31:20 2004 @@ -459,15 +459,26 @@ fi ]) -AC_ARG_ENABLE(wccp, -[ --disable-wccp Disable Web Cache Coordination Protocol], +AC_ARG_ENABLE(wccp, +[ --disable-wccp Disable Web Cache Coordination V1 Protocol], [ if test "$enableval" = "no" ; then - echo "Web Cache Coordination Protocol disabled" + echo "Web Cache Coordination V1 Protocol disabled" AC_DEFINE(USE_WCCP, 0) else AC_DEFINE(USE_WCCP, 1) fi -]) +]) + +AM_CONDITIONAL(USE_WCCPv2, false) +AC_ARG_ENABLE(wccpv2, +[ --enable-wccpv2 Enable Web Cache Coordination V2 Protocol], +[ if test "$enableval" = "yes" ; then + echo "Web Cache Coordination V2 Protocol enabled" + AC_DEFINE(USE_WCCPv2, 1) + AM_CONDITIONAL(USE_WCCPv2, true) + fi +]) + AC_ARG_ENABLE(kill-parent-hack, [ --enable-kill-parent-hack diff -Nur squid-2.5.STABLE4/include/autoconf.h.in squid-2.5.STABLE4_wccpv2/include/autoconf.h.in --- squid-2.5.STABLE4/include/autoconf.h.in Sat Jan 18 03:46:33 2003 +++ squid-2.5.STABLE4_wccpv2/include/autoconf.h.in Sun Jan 25 04:31:20 2004 @@ -149,9 +149,14 @@ #undef SQUID_SNMP /* - * Define to enable WCCP + * Define to enable WCCP V1 */ #define USE_WCCP 1 + +/* + * Define to enable WCCP V2 + */ +#undef USE_WCCPv2 /* * Define this to include code which lets you specify access control diff -Nur squid-2.5.STABLE4/src/Makefile.in squid-2.5.STABLE4_wccpv2/src/Makefile.in --- squid-2.5.STABLE4/src/Makefile.in Wed Feb 12 04:03:14 2003 +++ squid-2.5.STABLE4_wccpv2/src/Makefile.in Sun Jan 25 04:31:20 2004 @@ -131,6 +131,9 @@ @USE_DELAY_POOLS_TRUE@DELAY_POOL_SOURCE = delay_pools.c @USE_DELAY_POOLS_FALSE@DELAY_POOL_SOURCE = +@USE_WCCPv2_TRUE@WCCPv2_SOURCE = wccpv2.c +@USE_WCCPv2_FALSE@WCCPv2_SOURCE = + @ENABLE_HTCP_TRUE@HTCPSOURCE = htcp.c @MAKE_LEAKFINDER_TRUE@LEAKFINDERSOURCE = leakfinder.c @@ -196,6 +199,7 @@ unlinkd.c \ ssl_support.c \ ssl_support.h \ + wccpv2.c \ win32.c @@ -297,6 +301,7 @@ useragent.c \ wais.c \ wccp.c \ + $(WCCPv2_SOURCE) \ whois.c \ $(WIN32SOURCE) @@ -471,8 +476,10 @@ @ENABLE_SSL_TRUE@am__objects_8 = ssl_support.$(OBJEXT) @ENABLE_UNLINKD_TRUE@am__objects_9 = unlinkd.$(OBJEXT) @ENABLE_UNLINKD_FALSE@am__objects_9 = -@ENABLE_WIN32SPECIFIC_FALSE@am__objects_10 = -@ENABLE_WIN32SPECIFIC_TRUE@am__objects_10 = win32.$(OBJEXT) +@USE_WCCPv2_FALSE@am__objects_10 = +@USE_WCCPv2_TRUE@am__objects_10 = wccpv2.$(OBJEXT) +@ENABLE_WIN32SPECIFIC_FALSE@am__objects_11 = +@ENABLE_WIN32SPECIFIC_TRUE@am__objects_11 = win32.$(OBJEXT) am_squid_OBJECTS = access_log.$(OBJEXT) acl.$(OBJEXT) asn.$(OBJEXT) \ authenticate.$(OBJEXT) cache_cf.$(OBJEXT) CacheDigest.$(OBJEXT) \ cache_manager.$(OBJEXT) carp.$(OBJEXT) cbdata.$(OBJEXT) \ @@ -505,7 +512,7 @@ store_swapmeta.$(OBJEXT) store_swapout.$(OBJEXT) \ tools.$(OBJEXT) $(am__objects_9) url.$(OBJEXT) urn.$(OBJEXT) \ useragent.$(OBJEXT) wais.$(OBJEXT) wccp.$(OBJEXT) \ - whois.$(OBJEXT) $(am__objects_10) + $(am__objects_10) whois.$(OBJEXT) $(am__objects_11) nodist_squid_OBJECTS = repl_modules.$(OBJEXT) auth_modules.$(OBJEXT) \ store_modules.$(OBJEXT) globals.$(OBJEXT) \ string_arrays.$(OBJEXT) @@ -580,7 +587,7 @@ @AMDEP_TRUE@ $(DEPDIR)/unlinkd.Po $(DEPDIR)/url.Po \ @AMDEP_TRUE@ $(DEPDIR)/urn.Po $(DEPDIR)/useragent.Po \ @AMDEP_TRUE@ $(DEPDIR)/wais.Po $(DEPDIR)/wccp.Po \ -@AMDEP_TRUE@ $(DEPDIR)/whois.Po $(DEPDIR)/win32.Po +@AMDEP_TRUE@ $(DEPDIR)/wccpv2.Po $(DEPDIR)/whois.Po $(DEPDIR)/win32.Po COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) @@ -815,6 +822,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/useragent.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/wais.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/wccp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/wccpv2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/whois.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/win32.Po@am__quote@ diff -Nur squid-2.5.STABLE4/src/cf.data.pre squid-2.5.STABLE4_wccpv2/src/cf.data.pre --- squid-2.5.STABLE4/src/cf.data.pre Tue Sep 2 10:49:32 2003 +++ squid-2.5.STABLE4_wccpv2/src/cf.data.pre Sun Jan 25 04:32:18 2004 @@ -3194,17 +3194,125 @@ LOC: Config.Wccp.router DEFAULT: 0.0.0.0 IFDEF: USE_WCCP +DOC_NONE +NAME: wccp2_router +TYPE: address +LOC: Config.Wccp2.router +DEFAULT: 0.0.0.0 +IFDEF: USE_WCCPv2 DOC_START Use this option to define your WCCP ``home'' router for Squid. Setting the 'wccp_router' to 0.0.0.0 (the default) disables WCCP. DOC_END +NAME: wccp2_password +TYPE: string +LOC: Config.Wccp2.password +DEFAULT: xxx123 +IFDEF: USE_WCCPv2 +DOC_START + Password for WCCP service. Password is mandatory, first eight + characters are significant. +DOC_END + +NAME: wccp2_service_id +TYPE: int +LOC: Config.Wccp2.service_id +DEFAULT: 97 +IFDEF: USE_WCCPv2 +DOC_START + WCCP service group number. Numbers from 90 to 97 are user + configurable. Set the same service group number on router. + For example, if service group number is 97 and password is + xxx123, make global and interface router settings: + "ip wccp 97 password xxx123", "ip wccp 97 redirect out|in" +DOC_END + +NAME: wccp2_redirect_port1 +TYPE: ushort +LOC: Config.Wccp2.redirect_port1 +DEFAULT: 80 +IFDEF: USE_WCCPv2 +DOC_START + First redirected TCP port number. Single service group allows + up to 8 ports redirect. Set to zero for unused ports. +DOC_END + +NAME: wccp2_redirect_port2 +TYPE: ushort +LOC: Config.Wccp2.redirect_port2 +DEFAULT: 8080 +IFDEF: USE_WCCPv2 +DOC_START + Second redirected port number. +DOC_END + +NAME: wccp2_redirect_port3 +TYPE: ushort +LOC: Config.Wccp2.redirect_port3 +DEFAULT: 8000 +IFDEF: USE_WCCPv2 +DOC_START + Thirs redirected port number. +DOC_END + +NAME: wccp2_redirect_port4 +TYPE: ushort +LOC: Config.Wccp2.redirect_port4 +DEFAULT: 0 +IFDEF: USE_WCCPv2 +DOC_START + Fours redirected port number. (unused by default) +DOC_END + +NAME: wccp2_redirect_port5 +TYPE: ushort +LOC: Config.Wccp2.redirect_port5 +DEFAULT: 0 +IFDEF: USE_WCCPv2 +DOC_START + Fifth redirected port number. (unused by default) +DOC_END + +NAME: wccp2_redirect_port6 +TYPE: ushort +LOC: Config.Wccp2.redirect_port6 +DEFAULT: 0 +IFDEF: USE_WCCPv2 +DOC_START + Sixth redirected port number. (unused by default) +DOC_END + +NAME: wccp2_redirect_port7 +TYPE: ushort +LOC: Config.Wccp2.redirect_port7 +DEFAULT: 0 +IFDEF: USE_WCCPv2 +DOC_START + Seventh redirected port number. (unused by default) +DOC_END + +NAME: wccp2_redirect_port8 +TYPE: ushort +LOC: Config.Wccp2.redirect_port8 +DEFAULT: 0 +IFDEF: USE_WCCPv2 +DOC_START + Eighth redirected port number. (unused by default) +DOC_END + NAME: wccp_version TYPE: int LOC: Config.Wccp.version DEFAULT: 4 IFDEF: USE_WCCP +DOC_NONE +NAME: wccp2_version +TYPE: int +LOC: Config.Wccp2.version +DEFAULT: 4 +IFDEF: USE_WCCPv2 DOC_START According to some users, Cisco IOS 11.2 only supports WCCP version 3. If you're using that version of IOS, change @@ -3222,6 +3330,18 @@ LOC: Config.Wccp.outgoing DEFAULT: 255.255.255.255 IFDEF: USE_WCCP +DOC_NONE +NAME: wccp2_incoming_address +TYPE: address +LOC: Config.Wccp2.incoming +DEFAULT: 0.0.0.0 +IFDEF: USE_WCCPv2 +DOC_NONE +NAME: wccp2_outgoing_address +TYPE: address +LOC: Config.Wccp2.outgoing +DEFAULT: 255.255.255.255 +IFDEF: USE_WCCPv2 DOC_START wccp_incoming_address Use this option if you require WCCP messages to be received on only one diff -Nur squid-2.5.STABLE4/src/cf_gen_defines squid-2.5.STABLE4_wccpv2/src/cf_gen_defines --- squid-2.5.STABLE4/src/cf_gen_defines Mon Dec 3 10:01:53 2001 +++ squid-2.5.STABLE4_wccpv2/src/cf_gen_defines Sun Jan 25 04:31:20 2004 @@ -18,6 +18,7 @@ define["USE_UNLINKD"]="--enable-unlinkd" define["USE_USERAGENT_LOG"]="--enable-useragent-log" define["USE_WCCP"]="--enable-wccp" + define["USE_WCCPv2"]="--enable-wccpv2" } /^IFDEF:/ { if (define[$2] != "") diff -Nur squid-2.5.STABLE4/src/main.c squid-2.5.STABLE4_wccpv2/src/main.c --- squid-2.5.STABLE4/src/main.c Mon Jun 9 02:28:46 2003 +++ squid-2.5.STABLE4_wccpv2/src/main.c Sun Jan 25 04:31:20 2004 @@ -297,6 +297,9 @@ #if USE_WCCP wccpConnectionOpen(); #endif +#if USE_WCCPv2 + wccp2ConnectionOpen(); +#endif clientdbInit(); icmpOpen(); netdbInit(); @@ -323,6 +326,9 @@ #if USE_WCCP wccpConnectionShutdown(); #endif +#if USE_WCCPv2 + wccp2ConnectionShutdown(); +#endif asnFreeMemory(); } @@ -343,6 +349,9 @@ #if USE_WCCP wccpConnectionClose(); #endif +#if USE_WCCPv2 + wccp2ConnectionClose(); +#endif #if USE_DNSSERVERS dnsShutdown(); #else @@ -381,6 +390,9 @@ #if USE_WCCP wccpInit(); #endif +#if USE_WCCPv2 + wccp2Init(); +#endif serverConnectionsOpen(); if (theOutIcpConnection >= 0) { if (!Config2.Accel.on || Config.onoff.accel_with_proxy) @@ -544,6 +556,9 @@ #if USE_WCCP wccpInit(); #endif +#if USE_WCCPv2 + wccp2Init(); +#endif serverConnectionsOpen(); if (theOutIcpConnection >= 0) { if (!Config2.Accel.on || Config.onoff.accel_with_proxy) @@ -969,6 +984,9 @@ #endif #if USE_WCCP wccpConnectionClose(); +#endif +#if USE_WCCPv2 + wccp2ConnectionClose(); #endif releaseServerSockets(); commCloseAllSockets(); diff -Nur squid-2.5.STABLE4/src/protos.h squid-2.5.STABLE4_wccpv2/src/protos.h --- squid-2.5.STABLE4/src/protos.h Mon Aug 11 00:04:47 2003 +++ squid-2.5.STABLE4_wccpv2/src/protos.h Sun Jan 25 04:31:20 2004 @@ -570,6 +570,13 @@ extern void wccpConnectionClose(void); #endif /* USE_WCCP */ +#if USE_WCCPv2 +extern void wccp2Init(void); +extern void wccp2ConnectionOpen(void); +extern void wccp2ConnectionShutdown(void); +extern void wccp2ConnectionClose(void); +#endif /* USE_WCCPv2 */ + extern void icpHandleIcpV3(int, struct sockaddr_in, char *, int); extern int icpCheckUdpHit(StoreEntry *, request_t * request); extern void icpConnectionsOpen(void); diff -Nur squid-2.5.STABLE4/src/structs.h squid-2.5.STABLE4_wccpv2/src/structs.h --- squid-2.5.STABLE4/src/structs.h Fri Sep 12 23:30:16 2003 +++ squid-2.5.STABLE4_wccpv2/src/structs.h Sun Jan 25 04:31:39 2004 @@ -450,6 +450,24 @@ int version; } Wccp; #endif +#if USE_WCCPv2 + struct { + struct in_addr router; + struct in_addr incoming; + struct in_addr outgoing; + int version; + char *password; + int service_id; + uint16_t redirect_port1; + uint16_t redirect_port2; + uint16_t redirect_port3; + uint16_t redirect_port4; + uint16_t redirect_port5; + uint16_t redirect_port6; + uint16_t redirect_port7; + uint16_t redirect_port8; + } Wccp2; +#endif char *as_whois_server; struct { char *log; diff -Nur squid-2.5.STABLE4/src/wccpv2.c squid-2.5.STABLE4_wccpv2/src/wccpv2.c --- squid-2.5.STABLE4/src/wccpv2.c Thu Jan 1 03:00:00 1970 +++ squid-2.5.STABLE4_wccpv2/src/wccpv2.c Sun Jan 25 04:32:03 2004 @@ -0,0 +1,578 @@ +/* + * $Id$ + * + * DEBUG: section 80 WCCP Support + * AUTHOR: Glenn Chisholm + * + * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from the + * Internet community. Development is led by Duane Wessels of the + * National Laboratory for Applied Network Research and funded by the + * National Science Foundation. Squid is Copyrighted (C) 1998 by + * Duane Wessels and the University of California San Diego. Please + * see the COPYRIGHT file for full details. Squid incorporates + * software developed and/or copyrighted by other sources. Please 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 "squid.h" +#include <netdb.h> + +#include <md5.h> +MD5_CTX context; + +#if USE_WCCPv2 + +char wccp_password[8]; + +#define WCCP_PORT 2048 +#define WCCP_VERSION 4 +#define WCCP_REVISION 0 +#define WCCP_RESPONSE_SIZE 12448 +#define WCCP_ACTIVE_CACHES 32 +#define WCCP_HASH_SIZE 32 +#define WCCP_BUCKETS 256 + +#define WCCP_HERE_I_AM 7 +#define WCCP_I_SEE_YOU 8 +#define WCCP_ASSIGN_BUCKET 9 + +static int theInWccpConnection = -1; +static int theOutWccpConnection = -1; +static int change; +static struct in_addr local_ip; + +static PF wccp2HandleUdp; +static int wccp2LowestIP(void); +static EVH wccp2HereIam; +static EVH wccp2AssignBuckets; + +/* KDW WCCP V2 */ +#define WCCP2_HERE_I_AM 10 +#define WCCP2_I_SEE_YOU 11 +#define WCCP2_REDIRECT_ASSIGN 12 +#define WCCP2_REMOVAL_QUERY 13 +#define WCCP2_VERSION 0x200 + +#define WCCP2_SECURITY_INFO 0 +#define WCCP2_NO_SECURITY 0 +#define WCCP2_MD5_SECURITY 1 + +#define WCCP2_SERVICE_INFO 1 +#define WCCP2_SERVICE_STANDARD 0 +#define WCCP2_SERVICE_DYNAMIC 1 +#define WCCP2_SERVICE_ID_HTTP 0x00 + +#define WCCP2_ROUTER_ID_INFO 2 + +#define WCCP2_WC_ID_INFO 3 + +#define WCCP2_RTR_VIEW_INFO 4 + +#define WCCP2_WC_VIEW_INFO 5 + +#define WCCP2_REDIRECT_ASSIGNMENT 6 + +#define WCCP2_QUERY_INFO 7 + +#define WCCP2_CAPABILTIY_INFO 8 + +struct wccp2_here_i_am_t { + uint32_t type; + uint16_t version; + uint16_t length; + uint16_t security_type; + uint16_t security_length; + uint32_t security_option; + unsigned char security_implementation[16]; + uint16_t service_type; + uint16_t service_length; + uint8_t service; + uint8_t serviceid; + uint8_t priority; + uint8_t protocol; + uint32_t service_flags; + uint16_t ports[8]; + uint16_t cache_identity_type; + uint16_t cache_identity_length; + struct in_addr cache_identity_addr; + char cache_identity_filler[40]; + uint16_t cache_view_type; + uint16_t cache_view_length; + uint32_t cache_view_version; + uint32_t cache_view_num_routers; + struct in_addr cache_view_rtr1_addr; + uint32_t cache_view_rtr1_receive_id; + uint32_t cache_view_num_caches; + int id; +}; + +static struct wccp2_here_i_am_t wccp2_here_i_am; + +struct wccp2_i_see_you_t { + uint32_t type; + uint16_t version; + uint16_t length; + char data[WCCP_RESPONSE_SIZE]; + int id; +}; + +static struct wccp2_i_see_you_t wccp2_i_see_you; + +struct wccp2_item_header_t { + uint16_t type; + uint16_t length; +}; + +static struct wccp2_item_header_t wccp2_item_header; + +struct wccp2_router_id_element_t { + uint16_t type; + uint16_t length; + struct in_addr router_addr; + uint32_t received_id; +}; + +static struct wccp2_router_id_element_t wccp2_router_id_element; + +struct wccp2_router_info_t { + uint16_t type; + uint16_t length; + uint32_t member_change; +}; + +static struct wccp2_router_info_t wccp2_router_info; + +struct wccp2_redirect_assign_t { + uint32_t type; + uint16_t version; + uint16_t length; + uint16_t security_type; + uint16_t security_length; + uint32_t security_option; + unsigned char security_implementation[16]; + uint16_t service_type; + uint16_t service_length; + uint8_t service; + uint8_t serviceid; + uint8_t priority; + uint8_t protocol; + uint32_t service_flags; + uint16_t ports[8]; + uint16_t assignment_type; + uint16_t assignment_length; + struct in_addr assignment_key; + uint32_t assignment_key_change; + uint32_t assignment_num_routers; + struct in_addr assignment_router1_addr; + uint32_t assignment_router1_receive_id; + uint32_t assignment_router1_change_number; + uint32_t assignment_num_caches; + struct in_addr assignment_cache1_addr; + char buckets[WCCP_BUCKETS]; +}; + +static struct wccp2_redirect_assign_t wccp2_redirect_assign; + +struct wccp2_assign_bucket_t { + int type; + int id; + int number; +}; + +static uint32_t wccp2_received_id; +static struct in_addr wccp2_router_addr; + + +/* END WCCP V2 */ + +/* + * The functions used during startup: + * wccp2Init + * wccp2ConnectionOpen + * wccp2ConnectionShutdown + * wccp2ConnectionClose + */ + +void +wccp2Init(void) +{ + debug(80, 5) ("wccp2Init: Called\n"); + + if (Config.Wccp2.service_id < 90 || Config.Wccp2.service_id > 97) + { + debug(3, 0) ("WARNING: resetting 'wccp2_service_id' to 97\n"); + Config.Wccp2.service_id = 97; + } + + if (eventFind(wccp2HereIam, NULL)) + return; + + change = 1; + wccp2_here_i_am.type = htonl(WCCP2_HERE_I_AM); + wccp2_here_i_am.version = htons(WCCP2_VERSION); + wccp2_here_i_am.length = htons(sizeof(wccp2_here_i_am)-8); + wccp2_here_i_am.security_type = htons(WCCP2_SECURITY_INFO); + wccp2_here_i_am.security_length = htons(sizeof(wccp2_here_i_am.security_option)+16); + wccp2_here_i_am.security_option = htonl(WCCP2_MD5_SECURITY); + wccp2_here_i_am.service_type = htons(WCCP2_SERVICE_INFO); + wccp2_here_i_am.service_length = htons(sizeof(wccp2_here_i_am.service) + + sizeof(wccp2_here_i_am.serviceid) + + sizeof(wccp2_here_i_am.priority) + + sizeof(wccp2_here_i_am.protocol) + + sizeof(wccp2_here_i_am.service_flags) + + sizeof(wccp2_here_i_am.ports)); + wccp2_here_i_am.service = WCCP2_SERVICE_DYNAMIC; + wccp2_here_i_am.serviceid = Config.Wccp2.service_id; + wccp2_here_i_am.priority = 0; + wccp2_here_i_am.protocol = 6; /* TCP */ + wccp2_here_i_am.service_flags = htonl(0x0010); /* Ports Defined */ + wccp2_here_i_am.ports[0] = htons(Config.Wccp2.redirect_port1); + wccp2_here_i_am.ports[1] = htons(Config.Wccp2.redirect_port2); + wccp2_here_i_am.ports[2] = htons(Config.Wccp2.redirect_port3); + wccp2_here_i_am.ports[3] = htons(Config.Wccp2.redirect_port4); + wccp2_here_i_am.ports[4] = htons(Config.Wccp2.redirect_port5); + wccp2_here_i_am.ports[5] = htons(Config.Wccp2.redirect_port6); + wccp2_here_i_am.ports[6] = htons(Config.Wccp2.redirect_port7); + wccp2_here_i_am.ports[7] = htons(Config.Wccp2.redirect_port8); + + wccp2_here_i_am.cache_identity_type = htons(WCCP2_WC_ID_INFO); + wccp2_here_i_am.cache_identity_length = + htons(sizeof(wccp2_here_i_am.cache_identity_addr) + + sizeof(wccp2_here_i_am.cache_identity_filler)); + memset(&wccp2_here_i_am.cache_identity_filler, '\0', + sizeof(wccp2_here_i_am.cache_identity_filler)); + wccp2_here_i_am.cache_view_type = htons(WCCP2_WC_VIEW_INFO); + wccp2_here_i_am.cache_view_length = htons(sizeof(wccp2_here_i_am.cache_view_version) + + sizeof(wccp2_here_i_am.cache_view_num_routers)+ + sizeof(wccp2_here_i_am.cache_view_num_caches) + + sizeof(wccp2_here_i_am.cache_view_rtr1_addr) + + sizeof(wccp2_here_i_am.cache_view_rtr1_receive_id)); + wccp2_here_i_am.cache_view_version = htonl(1); + wccp2_here_i_am.cache_view_num_routers = htonl(1); + wccp2_here_i_am.cache_view_rtr1_addr = Config.Wccp2.router; + wccp2_here_i_am.cache_view_rtr1_receive_id = wccp2_router_id_element.received_id; + wccp2_here_i_am.cache_view_num_caches = htonl(0); + + if (Config.Wccp2.router.s_addr != any_addr.s_addr) + if (!eventFind(wccp2HereIam, NULL)) + eventAdd("wccp2HereIam", wccp2HereIam, NULL, 10.0, 1); +} + +void +wccp2ConnectionOpen(void) +{ + u_short port = WCCP_PORT; + struct sockaddr_in router, local; + int local_len, router_len; + debug(80, 5) ("wccp2ConnectionOpen: Called\n"); + if (Config.Wccp2.router.s_addr == any_addr.s_addr) { + debug(1, 1) ("WCCP Disabled.\n"); + return; + } + theInWccpConnection = comm_open(SOCK_DGRAM, + 0, + Config.Wccp2.incoming, + port, + COMM_NONBLOCKING, + "WCCP Socket"); + if (theInWccpConnection < 0) + fatal("Cannot open WCCP Port"); + commSetSelect(theInWccpConnection, + COMM_SELECT_READ, + wccp2HandleUdp, + NULL, + 0); + debug(1, 1) ("Accepting WCCP v2 messages on port %d, FD %d.\n", + (int) port, theInWccpConnection); + if (Config.Wccp2.outgoing.s_addr != no_addr.s_addr) { + theOutWccpConnection = comm_open(SOCK_DGRAM, + 0, + Config.Wccp2.outgoing, + port, + COMM_NONBLOCKING, + "WCCP Socket"); + if (theOutWccpConnection < 0) + fatal("Cannot open Outgoing WCCP Port"); + commSetSelect(theOutWccpConnection, + COMM_SELECT_READ, + wccp2HandleUdp, + NULL, 0); + debug(1, 1) ("Outgoing WCCP v2 messages on port %d, FD %d.\n", + (int) port, theOutWccpConnection); + fd_note(theOutWccpConnection, "Outgoing WCCP socket"); + fd_note(theInWccpConnection, "Incoming WCCP socket"); + } else { + theOutWccpConnection = theInWccpConnection; + } + router_len = sizeof(router); + memset(&router, '\0', router_len); + router.sin_family = AF_INET; + router.sin_port = htons(port); + router.sin_addr = Config.Wccp2.router; + if (connect(theOutWccpConnection, (struct sockaddr *) &router, router_len)) + fatal("Unable to connect WCCP out socket"); + local_len = sizeof(local); + memset(&local, '\0', local_len); + if (getsockname(theOutWccpConnection, (struct sockaddr *) &local, &local_len)) + fatal("Unable to getsockname on WCCP out socket"); + local_ip.s_addr = local.sin_addr.s_addr; +} + +void +wccp2ConnectionShutdown(void) +{ + if (theInWccpConnection < 0) + return; + if (theInWccpConnection != theOutWccpConnection) { + debug(80, 1) ("FD %d Closing WCCP socket\n", theInWccpConnection); + comm_close(theInWccpConnection); + } + assert(theOutWccpConnection > -1); + commSetSelect(theOutWccpConnection, COMM_SELECT_READ, NULL, NULL, 0); +} + +void +wccp2ConnectionClose(void) +{ + wccp2ConnectionShutdown(); + if (theOutWccpConnection > -1) { + debug(80, 1) ("FD %d Closing WCCP socket\n", theOutWccpConnection); + comm_close(theOutWccpConnection); + } +} + +/* + * Functions for handling the requests. + */ + +/* + * Accept the UDP packet + */ +static void +wccp2HandleUdp(int sock, void *not_used) +{ + struct sockaddr_in from; + socklen_t from_len; + int len, offset; + uint32_t tmp; + + debug(80, 6) ("wccp2HandleUdp: Called.\n"); + + commSetSelect(sock, COMM_SELECT_READ, wccp2HandleUdp, NULL, 0); + from_len = sizeof(struct sockaddr_in); + memset(&from, '\0', from_len); + memset(&wccp2_i_see_you, '\0', sizeof(wccp2_i_see_you)); + + statCounter.syscalls.sock.recvfroms++; + + len = recvfrom(sock, + &wccp2_i_see_you, + WCCP_RESPONSE_SIZE, + 0, + (struct sockaddr *) &from, + &from_len); + + if (len < 0) + return; + if (Config.Wccp2.router.s_addr != from.sin_addr.s_addr) + return; + if (ntohs(wccp2_i_see_you.version) != WCCP2_VERSION) + return; + if (ntohl(wccp2_i_see_you.type) != WCCP2_I_SEE_YOU) + return; + + debug(80, 1) ("Incoming WCCP v2 I_SEE_YOU length %d.\n", + ntohs(wccp2_i_see_you.length)); + memcpy(&wccp2_item_header, &wccp2_i_see_you.data[0], sizeof(wccp2_item_header)); + if (ntohs(wccp2_item_header.type) != WCCP2_SECURITY_INFO) { + debug(80,1) ("WCCP2_I_SEE_YOU missing WCCP2_SECURITY_INFO\n"); + return; + } + + offset = ntohs(wccp2_item_header.length) + 4; + memcpy(&wccp2_item_header, &wccp2_i_see_you.data[offset], sizeof(wccp2_item_header)); + if (ntohs(wccp2_item_header.type) != WCCP2_SERVICE_INFO) { + debug(80,1) ("WCCP2_I_SEE_YOU missing WCCP2_SERVICE_INFO offset %d\n", offset); + return; + } + offset += ntohs(wccp2_item_header.length) + 4; /* Skip WCCP2_SERVICE_INFO */ + memcpy(&wccp2_item_header, &wccp2_i_see_you.data[offset], sizeof(wccp2_item_header)); + if (ntohs(wccp2_item_header.type) != WCCP2_ROUTER_ID_INFO) { + debug(80,1) ("WCCP2_I_SEE_YOU missing WCCP2_ROUTER_ID_INFO\n"); + return; + } + memcpy(&wccp2_router_id_element, &wccp2_i_see_you.data[offset], sizeof(wccp2_router_id_element)); + debug(80, 1) ("Incoming WCCP2_I_SEE_YOU received id = %d.\n", + ntohl(wccp2_router_id_element.received_id)); + + wccp2_router_addr = wccp2_router_id_element.router_addr; + wccp2_received_id = wccp2_router_id_element.received_id; + + offset += ntohs(wccp2_router_id_element.length) + 4; + memcpy (&wccp2_router_info, &wccp2_i_see_you.data[offset], sizeof(wccp2_router_info)); + + debug(80, 1) ("Incoming WCCP2_I_SEE_YOU member change = %d tmp=%d.\n", + change,ntohl(wccp2_router_info.member_change)); + + if (!change) { + change = ntohl(wccp2_router_info.member_change); + debug(80, 1) ("Incoming WCCP2_I_SEE_YOU member change = %d.\n", change); + return; + } + if (change != ntohl(wccp2_router_info.member_change)) { + change = ntohl(wccp2_router_info.member_change); + if (wccp2LowestIP()) + if (!eventFind(wccp2AssignBuckets, NULL)) + eventAdd("wccp2AssignBuckets", wccp2AssignBuckets, NULL, 25.0, 1); + } +} + +static int +wccp2LowestIP(void) +{ +/* Force Election for now + int loop; + for (loop = 0; loop < ntohl(wccp2_i_see_you.number); loop++) { + if (wccp2_i_see_you.wccp2_cache_entry[loop].ip_addr.s_addr < local_ip.s_addr) + return 0; + } +*/ + return 1; +} + +static void +wccp2HereIam(void *voidnotused) +{ + debug(80, 6) ("wccp2HereIam: Called\n"); + + wccp2_here_i_am.cache_identity_addr = local_ip; + wccp2_here_i_am.id = wccp2_i_see_you.id; + wccp2_here_i_am.cache_view_rtr1_receive_id = wccp2_received_id; + wccp2_here_i_am.cache_view_rtr1_addr = wccp2_router_addr; + + bzero (&wccp2_here_i_am.security_implementation, 16); + bzero (wccp_password, 8); + strncpy (wccp_password, Config.Wccp2.password, 8); + + MD5Init (&context); + MD5Update (&context, wccp_password, 8); + MD5Update (&context, &wccp2_here_i_am, sizeof (wccp2_here_i_am)); + MD5Final (wccp2_here_i_am.security_implementation, &context); + + send(theOutWccpConnection, + &wccp2_here_i_am, + sizeof(wccp2_here_i_am), + 0); + + if (!eventFind(wccp2HereIam, NULL)) + eventAdd("wccp2HereIam", wccp2HereIam, NULL, 10.0, 1); +} + +static void +wccp2AssignBuckets(void *voidnotused) +{ + struct wccp2_assign_bucket_t wccp2_assign_bucket; + int buckets_per_cache; + int loop; + int number_caches; + int bucket = 0; + int *caches; + int offset; + char buckets[WCCP_BUCKETS]; + + if (Config.Wccp2.service_id < 90 || Config.Wccp2.service_id > 97) + { + debug(3, 0) ("WARNING: resetting 'wccp2_service_id' to 97\n"); + Config.Wccp2.service_id = 97; + } + + debug(80, 6) ("wccp2AssignBuckets: Called\n"); + debug(80, 1) ("WCCP2 Assigning Redirect\n"); + memset(&wccp2_redirect_assign.buckets, '\0', sizeof(wccp2_redirect_assign.buckets)); + memset(&wccp2_redirect_assign.buckets, 0xFF, WCCP_BUCKETS); + for (bucket = 0; bucket < WCCP_BUCKETS; bucket++) { + wccp2_redirect_assign.buckets[bucket] = 0; + } + wccp2_redirect_assign.type = htonl(WCCP2_REDIRECT_ASSIGN); + wccp2_redirect_assign.version = htons(WCCP2_VERSION); + wccp2_redirect_assign.length = htons(sizeof(wccp2_redirect_assign)-8); + wccp2_redirect_assign.security_type = htons(WCCP2_SECURITY_INFO); + wccp2_redirect_assign.security_length = htons(sizeof(wccp2_redirect_assign.security_option)+16); + wccp2_redirect_assign.security_option = htonl(WCCP2_MD5_SECURITY); + wccp2_redirect_assign.service_type = htons(WCCP2_SERVICE_INFO); + wccp2_redirect_assign.service_length = htons(sizeof(wccp2_redirect_assign.service) + + sizeof(wccp2_redirect_assign.serviceid) + + sizeof(wccp2_redirect_assign.priority) + + sizeof(wccp2_redirect_assign.protocol) + + sizeof(wccp2_redirect_assign.service_flags) + + sizeof(wccp2_redirect_assign.ports)); + + wccp2_redirect_assign.service = WCCP2_SERVICE_DYNAMIC; + wccp2_redirect_assign.serviceid = Config.Wccp2.service_id; + wccp2_redirect_assign.priority = 0; + wccp2_redirect_assign.protocol = 6; /* TCP */ + wccp2_redirect_assign.service_flags = htonl(0x0010); /* Ports Defined */ + wccp2_redirect_assign.ports[0] = htons(Config.Wccp2.redirect_port1); + wccp2_redirect_assign.ports[1] = htons(Config.Wccp2.redirect_port2); + wccp2_redirect_assign.ports[2] = htons(Config.Wccp2.redirect_port3); + wccp2_redirect_assign.ports[3] = htons(Config.Wccp2.redirect_port4); + wccp2_redirect_assign.ports[4] = htons(Config.Wccp2.redirect_port5); + wccp2_redirect_assign.ports[5] = htons(Config.Wccp2.redirect_port6); + wccp2_redirect_assign.ports[6] = htons(Config.Wccp2.redirect_port7); + wccp2_redirect_assign.ports[7] = htons(Config.Wccp2.redirect_port8); + + wccp2_redirect_assign.assignment_type = htons(WCCP2_REDIRECT_ASSIGNMENT); + wccp2_redirect_assign.assignment_length = + htons(sizeof(wccp2_redirect_assign.assignment_key) + + sizeof(wccp2_redirect_assign.assignment_key_change) + + sizeof(wccp2_redirect_assign.assignment_num_routers) + + sizeof(wccp2_redirect_assign.assignment_router1_addr) + + sizeof(wccp2_redirect_assign.assignment_router1_receive_id) + + sizeof(wccp2_redirect_assign.assignment_router1_change_number) + + sizeof(wccp2_redirect_assign.assignment_num_caches) + + sizeof(wccp2_redirect_assign.assignment_cache1_addr) + + sizeof(wccp2_redirect_assign.buckets)); + wccp2_redirect_assign.assignment_key = wccp2_here_i_am.cache_identity_addr; + wccp2_redirect_assign.assignment_key_change = htonl(change); + wccp2_redirect_assign.assignment_num_routers = htonl(1); + wccp2_redirect_assign.assignment_router1_addr = wccp2_router_addr; + wccp2_redirect_assign.assignment_router1_receive_id = wccp2_received_id; + wccp2_redirect_assign.assignment_router1_change_number = htonl(change); + wccp2_redirect_assign.assignment_num_caches = htonl(1); + wccp2_redirect_assign.assignment_cache1_addr = wccp2_here_i_am.cache_identity_addr; + + bzero (&wccp2_redirect_assign.security_implementation, 16); + bzero (wccp_password, 8); + strncpy (wccp_password, Config.Wccp2.password, 8); + + MD5Init (&context); + MD5Update (&context, wccp_password, 8); + MD5Update (&context, &wccp2_redirect_assign, sizeof(wccp2_redirect_assign)); + MD5Final (wccp2_redirect_assign.security_implementation, &context); + + send(theOutWccpConnection, + &wccp2_redirect_assign, + sizeof(wccp2_redirect_assign), + 0); + change = 0; +} + +#endif /* USE_WCCPv2 */ +

<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>

Ваш комментарий
Имя:         
E-Mail:      
Заголовок:
Текст:





  Закладки на сайте
  Проследить за страницей
Created 1996-2017 by Maxim Chirkov  
ДобавитьРекламаВебмастеруГИД  
Hosting by Ihor