31#define WCCP_RESPONSE_SIZE 12448
32#define WCCP_BUCKETS 256
43#define WCCP2_HASH_ASSIGNMENT 0x00
44#define WCCP2_MASK_ASSIGNMENT 0x01
46#define WCCP2_NONE_SECURITY_LEN 0
47#define WCCP2_MD5_SECURITY_LEN SQUID_MD5_DIGEST_LENGTH
50#define WCCP2_NUMPORTS 8
51#define WCCP2_PASSWORD_LEN 8 + 1
65#define WCCP2_SECURITY_INFO 0
66#define WCCP2_SERVICE_INFO 1
67#define WCCP2_ROUTER_ID_INFO 2
68#define WCCP2_WC_ID_INFO 3
69#define WCCP2_RTR_VIEW_INFO 4
70#define WCCP2_WC_VIEW_INFO 5
71#define WCCP2_REDIRECT_ASSIGNMENT 6
72#define WCCP2_QUERY_INFO 7
73#define WCCP2_CAPABILITY_INFO 8
74#define WCCP2_ALT_ASSIGNMENT 13
75#define WCCP2_ASSIGN_MAP 14
76#define WCCP2_COMMAND_EXTENSION 15
84#define WCCP2_VERSION 0x200
91#define WCCP2_HERE_I_AM 10
92#define WCCP2_I_SEE_YOU 11
93#define WCCP2_REDIRECT_ASSIGN 12
94#define WCCP2_REMOVAL_QUERY 13
108#define WCCP2_NO_SECURITY 0
109#define WCCP2_MD5_SECURITY 1
147#define WCCP2_SERVICE_STANDARD 0
148#define WCCP2_SERVICE_DYNAMIC 1
151#define WCCP2_SERVICE_ID_HTTP 0x00
154#define WCCP2_SERVICE_SRC_IP_HASH 0x1
155#define WCCP2_SERVICE_DST_IP_HASH 0x2
156#define WCCP2_SERVICE_SRC_PORT_HASH 0x4
157#define WCCP2_SERVICE_DST_PORT_HASH 0x8
158#define WCCP2_SERVICE_PORTS_DEFINED 0x10
159#define WCCP2_SERVICE_PORTS_SOURCE 0x20
160#define WCCP2_SERVICE_SRC_IP_ALT_HASH 0x100
161#define WCCP2_SERVICE_DST_IP_ALT_HASH 0x200
162#define WCCP2_SERVICE_SRC_PORT_ALT_HASH 0x400
163#define WCCP2_SERVICE_DST_PORT_ALT_HASH 0x800
217#define WCCP2_MASK_ASSIGNMENT_DATA (0x2)
303#define WCCP2_CAPABILITY_FORWARDING_METHOD 0x01
304#define WCCP2_CAPABILITY_ASSIGNMENT_METHOD 0x02
305#define WCCP2_CAPABILITY_RETURN_METHOD 0x03
310#define WCCP2_METHOD_GRE 0x00000001
311#define WCCP2_METHOD_L2 0x00000002
313#define WCCP2_FORWARDING_METHOD_GRE WCCP2_METHOD_GRE
314#define WCCP2_FORWARDING_METHOD_L2 WCCP2_METHOD_L2
316#define WCCP2_ASSIGNMENT_METHOD_HASH 0x00000001
317#define WCCP2_ASSIGNMENT_METHOD_MASK 0x00000002
319#define WCCP2_PACKET_RETURN_METHOD_GRE WCCP2_METHOD_GRE
320#define WCCP2_PACKET_RETURN_METHOD_L2 WCCP2_METHOD_L2
464 int service_proto,
int service_flags,
int ports[],
int security_type,
char *password);
477 debugs(80, 5,
"wccp2InitServices: called");
482 int service_id,
int service_priority,
int service_proto,
int service_flags,
503 int service_proto,
int service_flags,
int ports[],
int security_type,
511 debugs(80, 5,
"wccp2_add_service_list: added service id " << service_id);
519 service_priority, service_proto, service_flags, ports);
535 while (p !=
nullptr) {
560 debugs(80, 5,
"wccp2_update_md5_security: called");
563 memset(pwd, 0,
sizeof(pwd));
564 xstrncpy(pwd, password,
sizeof(pwd));
571 debugs(80, 5,
"wccp2_update_md5_security: this service ain't md5'ing, abort");
586 static_assert(
sizeof(pwd) - 1 == 8,
"WCCP2 password has exactly 8 (padded) octets, excluding storage-terminating NUL");
616 debugs(80,
DBG_IMPORTANT,
"wccp2_check_security: received packet has the wrong security option");
632 memset(pwd, 0,
sizeof(pwd));
642 static_assert(
sizeof(pwd) - 1 == 8,
"WCCP2 password has exactly 8 (padded) octets, excluding storage-terminating NUL");
661 uint32_t service_flags;
667 debugs(80, 5,
"wccp2Init: Called");
687 memset(&wccp2_security_md5, 0,
sizeof(wccp2_security_md5));
694 while (service_list_ptr !=
nullptr) {
716 fatalf(
"Bad WCCP2 security type\n");
730 memcpy(ptr, &wccp2_security_md5, 8);
791 fatalf(
"Unknown service hash method\n");
804 fatalf(
"Unknown Wccp2 assignment method\n");
854 router_list_ptr = router_list_ptr->
next;
855 router_list_ptr->
next =
nullptr;
945 debugs(80,3,
"wccp2Init: skip duplicate 'HERE_I_AM'.");
948 service_list_ptr = service_list_ptr->
next;
958 struct sockaddr_in router, local, null;
965 debugs(80, 5,
"wccp2ConnectionOpen: Called");
968 debugs(80, 2,
"WCCPv2 Disabled. No IPv4 Router(s) configured.");
985 fatal(
"Cannot open WCCP Port");
987#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
989 int i = IP_PMTUDISC_DONT;
1003 memset(&null, 0,
sizeof(null));
1005 null.sin_family = AF_UNSPEC;
1009 while (service_list_ptr !=
nullptr) {
1010 for (router_list_ptr = &service_list_ptr->
router_list_head; router_list_ptr->
next !=
nullptr; router_list_ptr = router_list_ptr->
next) {
1011 router_len =
sizeof(router);
1012 memset(&router,
'\0', router_len);
1013 router.sin_family = AF_INET;
1018 fatal(
"Unable to connect WCCP out socket");
1020 local_len =
sizeof(local);
1022 memset(&local,
'\0', local_len);
1025 fatal(
"Unable to getsockname on WCCP out socket");
1027 router_list_ptr->
local_ip = local.sin_addr;
1037 service_list_ptr = service_list_ptr->
next;
1079 while (service_list_ptr !=
nullptr) {
1080 for (router_list_ptr = &service_list_ptr->
router_list_head; router_list_ptr !=
nullptr; router_list_ptr = router_list_next) {
1081 for (cache_list_ptr = &router_list_ptr->
cache_list_head; cache_list_ptr; cache_list_ptr = cache_list_ptr_next) {
1082 cache_list_ptr_next = cache_list_ptr->
next;
1085 xfree(cache_list_ptr);
1092 router_list_next = router_list_ptr->
next;
1095 xfree(router_list_ptr);
1102 service_list_ptr_next = service_list_ptr->
next;
1103 xfree(service_list_ptr);
1104 service_list_ptr = service_list_ptr_next;
1131CheckSectionLength(
const void *sectionStart,
const size_t sectionLength,
const void *wholeStart,
const size_t wholeSize,
const char *
error)
1136 const auto wholeEnd =
static_cast<const char*
>(wholeStart) + wholeSize;
1137 assert(sectionStart >= wholeStart &&
"we never go backwards");
1138 assert(sectionStart <= wholeEnd &&
"we never go beyond our whole (but zero-sized fields are OK)");
1139 static_assert(
sizeof(
wccp2_i_see_you_t) <= PTRDIFF_MAX,
"paranoid: no UB when subtracting in-whole pointers");
1141 const auto remainderDiff = wholeEnd -
static_cast<const char*
>(sectionStart);
1144 assert(remainderDiff >= 0);
1145 const auto remainderSize =
static_cast<size_t>(remainderDiff);
1147 if (sectionLength <= remainderSize)
1156template<
class FieldHeader>
1161 const auto dataStart =
reinterpret_cast<const char*
>(header) +
sizeof(header);
1163 return sizeof(header) + dataLength;
1173template<
class Field>
1175SetField(Field *&field,
const void *fieldStart,
const void *areaStart,
const size_t areaSize,
const char *
error)
1178 field =
static_cast<Field*
>(
const_cast<void*
>(fieldStart));
1212 char *router_capability_data_start =
nullptr;
1216 struct sockaddr_in from;
1218 struct in_addr cache_address;
1223 debugs(80, 6,
"wccp2HandleUdp: Called.");
1235 const auto len =
static_cast<size_t>(lenOrError);
1240 Must3(len >= message_header_size,
"incomplete WCCP message header",
Here());
1251 Must3(data_length <= len - message_header_size,
1252 "malformed packet claiming it's bigger than received data",
Here());
1263 data, data_length,
"truncated record");
1267 switch (ntohs(itemHeader->type)) {
1270 Must3(!security_info,
"duplicate security definition",
Here());
1271 SetField(security_info, itemHeader, itemHeader, itemSize,
1272 "security definition truncated");
1276 Must3(!service_info,
"duplicate service_info definition",
Here());
1277 SetField(service_info, itemHeader, itemHeader, itemSize,
1278 "service_info definition truncated");
1282 Must3(!router_identity_info,
"duplicate router_identity_info definition",
Here());
1283 SetField(router_identity_info, itemHeader, itemHeader, itemSize,
1284 "router_identity_info definition truncated");
1288 Must3(!router_view_header,
"duplicate router_view definition",
Here());
1289 SetField(router_view_header, itemHeader, itemHeader, itemSize,
1290 "router_view definition truncated");
1294 Must3(!router_capability_header,
"duplicate router_capability definition",
Here());
1295 SetField(router_capability_header, itemHeader, itemHeader, itemSize,
1296 "router_capability definition truncated");
1299 itemHeader, itemSize,
"capability info truncated");
1300 router_capability_data_start =
reinterpret_cast<char*
>(router_capability_header) +
1301 sizeof(*router_capability_header);
1312 debugs(80,
DBG_IMPORTANT,
"ERROR: Unknown record type in WCCPv2 Packet (" << ntohs(itemHeader->type) <<
").");
1316 assert(offset <= data_length &&
"CheckFieldDataLength(itemHeader...) established that");
1319 Must3(security_info,
"packet missing security definition",
Here());
1320 Must3(service_info,
"packet missing service_info definition",
Here());
1321 Must3(router_identity_info,
"packet missing router_identity_info definition",
Here());
1322 Must3(router_view_header,
"packet missing router_view definition",
Here());
1324 debugs(80, 5,
"Complete packet received");
1329 while (service_list_ptr !=
nullptr) {
1334 service_list_ptr = service_list_ptr->
next;
1337 if (service_list_ptr ==
nullptr) {
1353 for (router_list_ptr = &service_list_ptr->
router_list_head; router_list_ptr->
next !=
nullptr; router_list_ptr = router_list_ptr->
next) {
1358 Must3(router_list_ptr->
next,
"packet received from unknown router",
Here());
1370 if (router_capability_header ==
nullptr) {
1372 debugs(80,
DBG_IMPORTANT,
"ERROR: wccp2HandleUdp: fatal error - A WCCP router does not support the forwarding method specified, only GRE supported");
1379 assert(router_capability_data_start);
1380 const auto router_capability_data_end = router_capability_data_start +
1381 router_capability_data_length;
1382 for (
auto router_capability_data_current = router_capability_data_start;
1383 router_capability_data_current < router_capability_data_end;) {
1385 SetField(router_capability_element, router_capability_data_current,
1386 router_capability_data_start, router_capability_data_length,
1387 "capability element header truncated");
1390 router_capability_data_start, router_capability_data_length,
1391 "capability element truncated");
1433 router_capability_data_current += elementSize;
1437 debugs(80, 5,
"Cleaning out cache list");
1440 for (cache_list_ptr = &router_list_ptr->
cache_list_head; cache_list_ptr; cache_list_ptr = cache_list_ptr_next) {
1441 cache_list_ptr_next = cache_list_ptr->
next;
1444 xfree(cache_list_ptr);
1458 ptr = (
char *) (router_view_header) +
sizeof(
struct router_view_t);
1459 const auto router_view_size =
sizeof(
struct router_view_t) +
1460 ntohs(router_view_header->
header.length);
1463 const uint32_t *routerCountRaw =
nullptr;
1464 SetField(routerCountRaw, ptr, router_view_header, router_view_size,
1465 "malformed packet (truncated router view info w/o number of routers)");
1468 ptr +=
sizeof(*routerCountRaw);
1469 const auto ipCount = ntohl(*routerCountRaw);
1470 const auto ipsSize = ipCount *
sizeof(
struct in_addr);
1471 Must3(ipsSize /
sizeof(
struct in_addr) == ipCount,
"huge IP address count",
Here());
1472 CheckSectionLength(ptr, ipsSize, router_view_header, router_view_size,
"invalid IP address count");
1476 const uint32_t *cacheCountRaw =
nullptr;
1477 SetField(cacheCountRaw, ptr, router_view_header, router_view_size,
1478 "malformed packet (truncated router view info w/o cache count)");
1479 memcpy(&tmp, cacheCountRaw,
sizeof(tmp));
1482 if (ntohl(tmp) != 0) {
1485 for (num_caches = 0; num_caches < (
int) ntohl(tmp); ++num_caches) {
1487 memset(&cache_address, 0,
sizeof(cache_address));
1493 SetField(cache_identity, ptr, router_view_header, router_view_size,
1494 "malformed packet (truncated router view info cache w/o assignment hash)");
1498 memcpy(&cache_address, &cache_identity->
addr,
sizeof(
struct in_addr));
1500 cache_list_ptr->
weight = ntohs(cache_identity->
weight);
1505 SetField(cache_mask_info, ptr, router_view_header, router_view_size,
1506 "malformed packet (truncated router view info cache w/o assignment mask)");
1510 if (ntohl(cache_mask_info->
num1) == 3) {
1512 SetField(cache_mask_identity, ptr, router_view_header, router_view_size,
1513 "malformed packet (truncated router view info cache w/o assignment mask identity)");
1517 memcpy(&cache_address, &cache_mask_identity->
addr,
sizeof(
struct in_addr));
1522 memcpy(&cache_address, &cache_mask_info->
addr,
sizeof(
struct in_addr));
1525 cache_list_ptr->
weight = 0;
1529 fatalf(
"Unknown Wccp2 assignment method\n");
1533 cache_list_ptr->
cache_ip = cache_address;
1537 cache_list_ptr = cache_list_ptr->
next;
1539 cache_list_ptr->
next =
nullptr;
1541 debugs (80, 5,
"checking cache list: (" << std::hex << cache_address.s_addr <<
":" << router_list_ptr->
local_ip.s_addr <<
")");
1544 found = found || (cache_address.s_addr == router_list_ptr->
local_ip.s_addr);
1546 if (cache_address.s_addr < router_list_ptr->
local_ip.s_addr) {
1551 debugs(80, 5,
"Adding ourselves as the only cache");
1557 cache_list_ptr = cache_list_ptr->
next;
1558 cache_list_ptr->
next =
nullptr;
1567 router_list_ptr->
num_caches = htonl(num_caches);
1569 if (found && (service_list_ptr->
lowest_ip == 1)) {
1571 debugs(80, 4,
"Change detected - queueing up new assignment");
1580 debugs(80, 5,
"I am not the lowest ip cache - not assigning buckets");
1601 debugs(80, 6,
"wccp2HereIam: Called");
1619 while (service_list_ptr !=
nullptr) {
1622 for (router_list_ptr = &service_list_ptr->
router_list_head; router_list_ptr->
next !=
nullptr; router_list_ptr = router_list_ptr->
next) {
1642 fatalf(
"Unknown Wccp2 assignment method\n");
1662 debugs(80, 2,
"ERROR: failed to send WCCPv2 HERE_I_AM packet to " << router <<
" : " <<
xstrerr(xerrno));
1667 service_list_ptr = service_list_ptr->
next;
1682 short int offset, saved_offset, assignment_offset, alt_assignment_offset;
1684 struct sockaddr_in router;
1687 uint32_t service_flags;
1705 struct in_addr *cache_address;
1712 int valuecounter, value;
1715 assignment_offset = alt_assignment_offset = 0;
1717 router_len =
sizeof(router);
1718 memset(&router,
'\0', router_len);
1719 router.sin_family = AF_INET;
1729 debugs(80, 2,
"Running wccp2AssignBuckets");
1732 while (service_list_ptr !=
nullptr) {
1737 service_list_ptr = service_list_ptr->
next;
1768 fatalf(
"Unknown Wccp2 security type\n");
1787 assignment_offset = offset;
1794 assignment_offset = offset;
1802 alt_assignment_offset = offset;
1807 fatalf(
"Unknown Wccp2 assignment method\n");
1824 for (router_list_ptr = &service_list_ptr->
router_list_head; router_list_ptr->
next !=
nullptr; router_list_ptr = router_list_ptr->
next) {
1836 saved_offset = offset;
1838 for (router_list_ptr = &service_list_ptr->
router_list_head; router_list_ptr->
next !=
nullptr; router_list_ptr = router_list_ptr->
next) {
1839 unsigned long *weight = (
unsigned long *)
xcalloc(
sizeof(*weight), ntohl(router_list_ptr->
num_caches));
1840 unsigned long total_weight = 0;
1841 int num_caches = ntohl(router_list_ptr->
num_caches);
1843 offset = saved_offset;
1849 memcpy(&wccp_packet[offset], &router_list_ptr->
num_caches,
sizeof(router_list_ptr->
num_caches));
1850 offset +=
sizeof(router_list_ptr->
num_caches);
1855 for (cache = 0, cache_list_ptr = &router_list_ptr->
cache_list_head; cache_list_ptr->
next; cache_list_ptr = cache_list_ptr->
next, ++cache) {
1858 cache_address = (
struct in_addr *) &wccp_packet[offset];
1860 memcpy(cache_address, &cache_list_ptr->
cache_ip,
sizeof(
struct in_addr));
1861 total_weight += cache_list_ptr->
weight << 12;
1862 weight[cache] = cache_list_ptr->
weight << 12;
1864 offset +=
sizeof(
struct in_addr);
1869 buckets = (
char *) &wccp_packet[offset];
1873 if (num_caches != 0) {
1874 if (total_weight == 0) {
1875 for (bucket_counter = 0; bucket_counter <
WCCP_BUCKETS; ++bucket_counter) {
1876 buckets[bucket_counter] = (char) (bucket_counter % num_caches);
1879 unsigned long *assigned = (
unsigned long *)
xcalloc(
sizeof(*assigned), num_caches);
1880 unsigned long done = 0;
1882 unsigned long per_bucket = total_weight /
WCCP_BUCKETS;
1884 for (bucket_counter = 0; bucket_counter <
WCCP_BUCKETS; ++bucket_counter) {
1888 for (n = num_caches; n; --n) {
1891 if (cache >= num_caches)
1894 if (!weight[cache]) {
1899 if (assigned[cache] <= done)
1903 buckets[bucket_counter] = (char) cache;
1904 step = per_bucket * total_weight / weight[cache];
1905 assigned[cache] += step;
1918 num_maskval = htonl(1);
1919 memcpy(&wccp_packet[offset], &num_maskval,
sizeof(
int));
1920 offset +=
sizeof(
int);
1946 fatalf(
"Unknown service hash method\n");
1956 for (valuecounter = 0; valuecounter < 64; ++valuecounter) {
1962 for (; (value & 0x1741) != value; ++value) {
1987 fatalf(
"Unknown service hash method\n");
1997 if ((cache_list_ptr->
next) && (cache_list_ptr->
next->
next))
1998 cache_list_ptr = cache_list_ptr->
next;
2004 alt_assignment_type_header->
length = htons(offset - alt_assignment_offset);
2009 fatalf(
"Unknown Wccp2 assignment method\n");
2014 assignment_header->
length = htons(offset - assignment_offset);
2046 debugs(80, 2,
"ERROR: failed to send WCCPv2 HERE_I_AM packet to " << tmp_rtr <<
" : " <<
xstrerr(xerrno));
2053 service_list_ptr = service_list_ptr->
next;
2079 if (strcmp(t,
"gre") == 0 || strcmp(t,
"1") == 0) {
2081 }
else if (strcmp(t,
"l2") == 0 || strcmp(t,
"2") == 0) {
2100 debugs(80,
DBG_CRITICAL,
"FATAL: WCCPv2 configured method (" << v <<
") is not valid.");
2127 if (strcmp(t,
"hash") == 0 || strcmp(t,
"1") == 0) {
2129 }
else if (strcmp(t,
"mask") == 0 || strcmp(t,
"2") == 0) {
2132 debugs(80,
DBG_CRITICAL,
"ERROR: wccp2_assignment_method: unknown setting, got " << t );
2148 debugs(80,
DBG_CRITICAL,
"FATAL: WCCPv2 configured " << label <<
" (" << v <<
") is not valid.");
2172 debugs(80,
DBG_IMPORTANT,
"WCCPv2: Somehow reparsing the configuration without having shut down WCCP! Try reloading squid again.");
2178 debugs(80,
DBG_CRITICAL,
"ERROR: wccp2ParseServiceInfo: missing service info type (standard|dynamic)");
2183 if (strcmp(t,
"standard") == 0) {
2185 }
else if (strcmp(t,
"dynamic") == 0) {
2188 debugs(80,
DBG_CRITICAL,
"ERROR: wccp2ParseServiceInfo: bad service info type (expected standard|dynamic, got " << t <<
")");
2196 if (service_id < 0 || service_id > 255) {
2197 debugs(80,
DBG_CRITICAL,
"ERROR: invalid WCCP service id " << service_id <<
" (must be between 0 .. 255)");
2202 memset(wccp_password, 0,
sizeof(wccp_password));
2206 if (strncmp(t,
"password=", 9) == 0) {
2208 xstrncpy(wccp_password, t + 9,
sizeof(wccp_password));
2222 while (srv !=
nullptr) {
2273 while (
size_t len = strcspn(flag,
",")) {
2275 if (strncmp(flag,
"src_ip_hash", len) == 0) {
2277 }
else if (strncmp(flag,
"dst_ip_hash", len) == 0) {
2279 }
else if (strncmp(flag,
"source_port_hash", len) == 0) {
2281 }
else if (strncmp(flag,
"dst_port_hash", len) == 0) {
2283 }
else if (strncmp(flag,
"ports_source", len) == 0) {
2285 }
else if (strncmp(flag,
"src_ip_alt_hash", len) == 0) {
2287 }
else if (strncmp(flag,
"dst_ip_alt_hash", len) == 0) {
2289 }
else if (strncmp(flag,
"src_port_alt_hash", len) == 0) {
2291 }
else if (strncmp(flag,
"dst_port_alt_hash", len) == 0) {
2295 fatalf(
"Unknown wccp2 service flag: %s\n", flag);
2298 if (flag[len] ==
'\0')
2315 char *tmp = options;
2316 static char copy[10];
2318 while (
size_t len = strcspn(tmp,
",")) {
2320 fatalf(
"parse_wccp2_service_ports: too many ports (maximum: 8) in list '%s'\n", options);
2323 fatalf(
"parse_wccp2_service_ports: port value '%s' isn't valid (1..65535)\n", tmp);
2326 memcpy(copy, tmp, len);
2328 int p =
xatoi(copy);
2330 if (p < 1 || p > 65535) {
2331 fatalf(
"parse_wccp2_service_ports: port value '%s' isn't valid (1..65535)\n", tmp);
2336 if (tmp[len] ==
'\0')
2355 debugs(80,
DBG_IMPORTANT,
"WCCPv2: Somehow reparsing the configuration without having shut down WCCP! Try reloading squid again.");
2359 debugs(80, 5,
"parse_wccp2_service_info: called");
2360 memset(portlist, 0,
sizeof(portlist));
2364 if (service_id < 0 || service_id > 255) {
2365 debugs(80,
DBG_CRITICAL,
"ERROR: invalid WCCP service id " << service_id <<
" (must be between 0 .. 255)");
2373 if (srv ==
nullptr) {
2374 fatalf(
"parse_wccp2_service_info: unknown dynamic service id %d: you need to define it using wccp2_service (and make sure you wish to configure it as a dynamic service.)\n", service_id);
2379 if (strncmp(t,
"flags=", 6) == 0) {
2382 }
else if (strncmp(t,
"ports=", 6) == 0) {
2385 }
else if (strncmp(t,
"protocol=tcp", 12) == 0) {
2386 protocol = IPPROTO_TCP;
2387 }
else if (strncmp(t,
"protocol=udp", 12) == 0) {
2388 protocol = IPPROTO_UDP;
2389 }
else if (strncmp(t,
"protocol=", 9) == 0) {
2390 fatalf(
"parse_wccp2_service_info: id %d: unknown protocol (%s) - must be tcp or udp!\n", service_id, t);
2391 }
else if (strncmp(t,
"priority=", 9) == 0) {
2392 priority = strtol(t + 9, &end, 0);
2394 if (priority < 0 || priority > 255) {
2395 fatalf(
"parse_wccp2_service_info: id %d: %s out of range (0..255)!\n", service_id, t);
2398 fatalf(
"parse_wccp2_service_info: id %d: unknown option '%s'\n", service_id, t);
2403 if (priority == -1) {
2404 fatalf(
"parse_wccp2_service_info: service %d: no priority defined (valid: 0..255)!\n", service_id);
2407 if (protocol == -1) {
2408 fatalf(
"parse_wccp2_service_info: service %d: no protocol defined (valid: tcp or udp)!\n", service_id);
2412 fatalf(
"parse_wccp2_service_info: service %d: no ports defined!\n", service_id);
2417 protocol, flags, portlist);
2429 while (srv !=
nullptr) {
2435 debugs(80, 3,
"dump_wccp2_service_info: id " << srv->
info.
service_id <<
": standard service, not dumping info");
2567 for (this_item =
head; this_item->
next; this_item = this_item->
next) {
2569 next_lowest = this_item;
2571 for (find_item = this_item; find_item->
next; find_item = find_item->
next) {
2573 next_lowest = find_item;
2577 if (next_lowest != this_item) {
2583 next_lowest->
next = this_item->
next;
#define Here()
source code location of the caller
int xatoi(const char *token)
#define DefineRunnerRegistrator(ClassName)
std::ostream & CurrentException(std::ostream &os)
prints active (i.e., thrown but not yet handled) exception
#define Must3(condition, description, location)
void error(char *format,...)
squidaio_request_t * head
static char * NextToken()
void getSockAddr(struct sockaddr_storage &addr, const int family) const
bool getInAddr(struct in_addr &) const
unsigned short port() const
struct SquidConfig::@81 Wccp2
static int store_dirs_rebuilding
the number of cache_dirs being rebuilt; TODO: move to Disks::Rebuilding
an std::runtime_error with thrower location info
void startShutdown() override
void startReconfigure() override
void useConfig() override
void syncConfig() override
int comm_udp_sendto(int fd, const Ip::Address &to_addr, const void *buf, int len)
void comm_open_listener(int sock_type, int proto, Comm::ConnectionPointer &conn, const char *note)
int comm_udp_recvfrom(int fd, void *buf, size_t len, int flags, Ip::Address &from)
#define debugs(SECTION, LEVEL, CONTENT)
int eventFind(EVH *func, void *arg)
void eventDelete(EVH *func, void *arg)
void eventAdd(const char *name, EVH *func, void *arg, double when, int weight, bool cbdata)
void fatal(const char *message)
void fatalf(const char *fmt,...)
SQUIDCEXTERN void SquidMD5Init(struct SquidMD5Context *context)
#define SQUID_MD5_DIGEST_LENGTH
SQUIDCEXTERN void SquidMD5Update(struct SquidMD5Context *context, const void *buf, unsigned len)
SQUIDCEXTERN void SquidMD5Final(uint8_t digest[16], struct SquidMD5Context *context)
void SetSelect(int, unsigned int, PF *, void *, time_t)
Mark an FD to be watched for its IO status.
static struct tok * buckets[HASHSIZE]
ssize_t xsend(int socketFd, const void *buf, size_t bufLength, int flags)
POSIX send(2) equivalent.
int xgetsockname(int socketFd, struct sockaddr *sa, socklen_t *saLength)
POSIX getsockname(2) equivalent.
int xsetsockopt(int socketFd, int level, int option, const void *value, socklen_t valueLength)
POSIX setsockopt(2) equivalent.
int xconnect(int socketFd, const struct sockaddr *sa, socklen_t saLength)
POSIX connect(2) equivalent.
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)
struct wccp2_router_id_element_t router_id_element
struct in_addr router_address
struct wccp2_item_header_t header
struct wccp2_item_header_t header
struct assignment_key_t assignment_key
struct wccp2_cache_list_t * next
uint32_t mask_element_count
struct wccp2_mask_element_t mask
uint32_t capability_value
uint16_t capability_length
char data[WCCP_RESPONSE_SIZE]
uint16_t cache_identity_length
struct wccp2_cache_identity_info_t cache_identity
uint16_t cache_identity_type
uint16_t source_port_mask
struct wccp2_cache_mask_identity_info_t cache_identity
uint16_t cache_identity_length
uint16_t cache_identity_type
struct in_addr router_address
struct in_addr router_address
struct wccp2_router_id_element_t * info
struct wccp2_router_list_t * next
struct wccp2_cache_list_t cache_list_head
struct in_addr router_sendto_address
uint8_t security_implementation[WCCP2_MD5_SECURITY_LEN]
struct wccp2_service_info_t info
struct wccp2_router_list_t router_list_head
char wccp_password[WCCP2_PASSWORD_LEN]
uint32_t wccp2_security_type
struct wccp2_service_list_t * next
struct wccp2_service_info_t * service_info
struct wccp2_security_md5_t * security_info
char * wccp2_identity_info_ptr
char wccp_packet[WCCP_RESPONSE_SIZE]
uint16_t source_port_value
#define WCCP2_ASSIGNMENT_METHOD_MASK
static struct wccp2_cache_view_header_t wccp2_cache_view_header
void parse_wccp2_service(void *)
#define WCCP2_SERVICE_SRC_IP_ALT_HASH
static char wccp2_update_md5_security(char *password, char *ptr, char *packet, int len)
#define WCCP2_SERVICE_DST_PORT_ALT_HASH
void parse_wccp2_method(int *method)
static EVH wccp2AssignBuckets
static void wccp2InitServices(void)
static struct wccp2_message_header_t wccp2_here_i_am_header
#define WCCP2_REDIRECT_ASSIGNMENT
void free_wccp2_amethod(int *)
#define WCCP2_PASSWORD_LEN
void free_wccp2_service_info(void *)
#define WCCP2_ROUTER_ID_INFO
#define WCCP2_SERVICE_PORTS_DEFINED
#define WCCP2_SERVICE_DST_IP_HASH
static struct wccp2_capability_element_t wccp2_capability_element
static void wccp2SortCacheList(struct wccp2_cache_list_t *head)
#define WCCP2_NO_SECURITY
#define WCCP2_MD5_SECURITY
#define WCCP2_MASK_ASSIGNMENT_DATA
#define WCCP2_SERVICE_DYNAMIC
int check_null_wccp2_service(void *)
static struct wccp2_capability_info_header_t wccp2_capability_info_header
#define WCCP2_PACKET_RETURN_METHOD_GRE
void dump_wccp2_amethod(StoreEntry *e, const char *label, int v)
#define WCCP2_CAPABILITY_FORWARDING_METHOD
static void wccp2ConnectionClose(void)
static int theWccp2Connection
#define WCCP2_CAPABILITY_RETURN_METHOD
void dump_wccp2_method(StoreEntry *e, const char *label, int v)
static int wccp2_connected
#define WCCP2_SERVICE_STANDARD
#define WCCP2_FORWARDING_METHOD_GRE
#define WCCP2_REDIRECT_ASSIGN
static int wccp2_numrouters
static void parse_wccp2_service_ports(char *options, int portlist[])
void parse_wccp2_service_info(void *)
#define WCCP2_CAPABILITY_INFO
#define WCCP2_SERVICE_INFO
#define WCCP2_CAPABILITY_ASSIGNMENT_METHOD
#define WCCP2_SERVICE_PORTS_SOURCE
static void wccp2Init(void)
#define WCCP2_RTR_VIEW_INFO
int empty_portlist[WCCP2_NUMPORTS]
static size_t CheckFieldDataLength(const FieldHeader *header, const size_t dataLength, const void *areaStart, const size_t areaSize, const char *error)
static void wccp2_update_service(struct wccp2_service_list_t *srv, int service, int service_id, int service_priority, int service_proto, int service_flags, int ports[])
void dump_wccp2_service_info(StoreEntry *e, const char *label, void *)
static int parse_wccp2_service_flags(char *flags)
#define WCCP2_SERVICE_SRC_IP_HASH
static struct wccp2_service_list_t * wccp2_get_service_by_id(int service, int service_id)
#define WCCP_RESPONSE_SIZE
static struct wccp2_identity_info_t wccp2_identity_info
static void wccp2ConnectionOpen(void)
static struct wccp2_service_list_t * wccp2_service_list_head
#define WCCP2_SERVICE_DST_PORT_HASH
static struct wccp2_i_see_you_t wccp2_i_see_you
#define WCCP2_SERVICE_SRC_PORT_HASH
#define WCCP2_MD5_SECURITY_LEN
static struct wccp2_mask_identity_info_t wccp2_mask_identity_info
#define WCCP2_ASSIGNMENT_METHOD_HASH
#define WCCP2_MASK_ASSIGNMENT
#define WCCP2_ALT_ASSIGNMENT
static void wccp2_add_service_list(int service, int service_id, int service_priority, int service_proto, int service_flags, int ports[], int security_type, char *password)
void free_wccp2_service(void *)
static void CheckSectionLength(const void *sectionStart, const size_t sectionLength, const void *wholeStart, const size_t wholeSize, const char *error)
#define WCCP2_SERVICE_DST_IP_ALT_HASH
void free_wccp2_method(int *)
static struct wccp2_cache_view_info_t wccp2_cache_view_info
static char wccp2_check_security(struct wccp2_service_list_t *srv, char *security, char *packet, int len)
#define WCCP2_WC_VIEW_INFO
#define WCCP2_SERVICE_SRC_PORT_ALT_HASH
#define WCCP2_SECURITY_INFO
void dump_wccp2_service(StoreEntry *e, const char *label, void *)
static void SetField(Field *&field, const void *fieldStart, const void *areaStart, const size_t areaSize, const char *error)
void parse_wccp2_amethod(int *method)
void * xcalloc(size_t n, size_t sz)
const char * xstrerr(int error)
char * xstrncpy(char *dst, const char *src, size_t n)