FreeBSD Bugzilla – Attachment 59348 Details for
Bug 89329
Add WCCPv2 support to squid
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
squid_wccpv2.patch
squid_wccpv2.patch (text/plain), 34.53 KB, created by
Rauf Kuliyev
on 2005-11-24 03:02:32 UTC
(
hide
)
Description:
squid_wccpv2.patch
Filename:
MIME Type:
Creator:
Rauf Kuliyev
Created:
2005-11-24 03:02:32 UTC
Size:
34.53 KB
patch
obsolete
>diff -crN /usr/ports/www/squid.orig/Makefile /usr/ports/www/squid/Makefile >*** /usr/ports/www/squid.orig/Makefile Tue Nov 1 18:05:59 2005 >--- /usr/ports/www/squid/Makefile Mon Nov 21 01:30:41 2005 >*************** >*** 111,116 **** >--- 111,117 ---- > SQUID_VIA_DB "Enable forward/via database" off \ > SQUID_CACHE_DIGESTS "Enable cache digests" off \ > SQUID_WCCP "Enable Web Cache Coordination Protocol" on \ >+ SQUID_WCCPV2 "Enable WCCP version 2" off \ > SQUID_UNDERSCORES "Allow underscores in hostnames" on \ > SQUID_CHECK_HOSTNAME "Do hostname checking" on \ > SQUID_STRICT_HTTP "Be strictly HTTP compliant" off \ >*************** >*** 250,255 **** >--- 251,259 ---- > .endif > .if defined(WITHOUT_SQUID_WCCP) > CONFIGURE_ARGS+= --disable-wccp >+ .endif >+ .if defined(WITH_SQUID_WCCPV2) >+ CONFIGURE_ARGS+= --enable-wccpv2 > .endif > .if !defined(WITHOUT_SQUID_UNDERSCORES) > CONFIGURE_ARGS+= --enable-underscores >diff -crN /usr/ports/www/squid.orig/files/patch-wccpv2 /usr/ports/www/squid/files/patch-wccpv2 >*** /usr/ports/www/squid.orig/files/patch-wccpv2 Thu Jan 1 04:00:00 1970 >--- /usr/ports/www/squid/files/patch-wccpv2 Mon Nov 21 01:30:41 2005 >*************** >*** 0 **** >--- 1,1045 ---- >+ diff -Nur acconfig.h.orig acconfig.h >+ --- acconfig.horig Mon Jul 1 11:55:11 2002 >+ +++ 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 configure.orig configure >+ --- configure.orig Mon Sep 15 03:37:04 2003 >+ +++ 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 configure.in.orig configure.in >+ --- configure.in.orig Mon Sep 15 03:37:04 2003 >+ +++ 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 include/autoconf.h.in.orig include/autoconf.h.in >+ --- include/autoconf.h.in.orig Sat Jan 18 03:46:33 2003 >+ +++ 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 src/cf.data.pre.orig src/cf.data.pre >+ --- src/cf.data.pre.orig Tue Sep 2 10:49:32 2003 >+ +++ 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 src/cf_gen_defines.orig src/cf_gen_defines >+ --- src/cf_gen_defines.orig Mon Dec 3 10:01:53 2001 >+ +++ 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 src/main.c.orig src/main.c >+ --- src/main.c.orig Mon Jun 9 02:28:46 2003 >+ +++ 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 src/protos.h.orig src/protos.h >+ --- src/protos.h.orig Mon Aug 11 00:04:47 2003 >+ +++ 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 src/structs.h.orig src/structs.h >+ --- src/structs.h.orig Fri Sep 12 23:30:16 2003 >+ +++ 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 src/wccpv2.c.orig src/wccpv2.c >+ --- src/wccpv2.c.orig Thu Jan 1 03:00:00 1970 >+ +++ 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/Makefile.in.orig Thu Sep 29 01:57:21 2005 >+ +++ src/Makefile.in Fri Nov 18 13:37:24 2005 >+ @@ -136,6 +136,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 >+ @@ -202,6 +205,7 @@ >+ unlinkd.c \ >+ ssl_support.c \ >+ ssl_support.h \ >+ + wccpv2.c \ >+ win32.c >+ >+ >+ @@ -303,6 +307,7 @@ >+ useragent.c \ >+ wais.c \ >+ wccp.c \ >+ + $(WCCPv2_SOURCE) \ >+ whois.c \ >+ $(WIN32SOURCE) >+ >+ @@ -514,8 +519,8 @@ >+ store_rebuild.$(OBJEXT) store_swapin.$(OBJEXT) \ >+ 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) >+ + useragent.$(OBJEXT) wais.$(OBJEXT) wccp.$(OBJEXT) wccpv2.$(OBJEXT) \ >+ + $(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) >+ @@ -591,7 +596,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) >+ @@ -827,6 +832,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@ >+
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 89329
:
59347
| 59348