1 /** @file
2 WCCP (v2) support for Apache Traffic Server.
3
4 @section license License
5
6 Licensed to the Apache Software Foundation (ASF) under one
7 or more contributor license agreements. See the NOTICE file
8 distributed with this work for additional information
9 regarding copyright ownership. The ASF licenses this file
10 to you under the Apache License, Version 2.0 (the
11 "License"); you may not use this file except in compliance
12 with the License. You may obtain a copy of the License at
13
14 http://www.apache.org/licenses/LICENSE-2.0
15
16 Unless required by applicable law or agreed to in writing, software
17 distributed under the License is distributed on an "AS IS" BASIS,
18 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 See the License for the specific language governing permissions and
20 limitations under the License.
21 */
22
23 #pragma once
24
25 #include "wccp/Wccp.h"
26 #include "WccpUtil.h"
27 #include "ts/apidefs.h"
28 #include "tscore/Errata.h"
29 // Needed for template use of byte ordering functions.
30 #include <netinet/in.h>
31 #include <memory.h>
32 #include <map>
33 #include <string_view>
34
35 namespace YAML
36 {
37 class Node;
38 };
39
40 namespace wccp
41 {
42 // Forward declares
43 namespace detail
44 {
45 class Assignment;
46 namespace cache
47 {
48 struct RouterData;
49 }
50 } // namespace detail
51
52 /// Default port used by the protocol.
53 static unsigned int const DEFAULT_PORT = 2048;
54 /// Number of buckets in WCCP hash allocation.
55 static unsigned int const N_BUCKETS = 256;
56 /// Unassigned bucket value (defined by protocol).
57 static uint8_t const UNASSIGNED_BUCKET = 0xFF;
58 /// Size of group password in octets.
59 static unsigned int const GROUP_PASSWORD_SIZE = 8;
60 /// Maximum # of caches
61 static uint32_t const MAX_CACHES = 32;
62 /// Maximum # of routers
63 static uint32_t const MAX_ROUTERS = 32;
64
65 /// Our version of the protocol.
66 static unsigned int const VERSION = 0x200;
67
68 /// @name Parse results.
69 /// @note Internal values are positive. System errors are reported as
70 /// the negative of errno.
71 //@{
72 /// Successful parse (message is well formatted)
73 static int const PARSE_SUCCESS = 0;
74 /// Component is the wrong type but looks like a valid type.
75 static int const PARSE_COMP_OTHER_TYPE = 1;
76 /// Component has a bogus type (cannot be valid).
77 static int const PARSE_COMP_TYPE_INVALID = 2;
78 /// Length in message is larger than actual message data.
79 static int const PARSE_MSG_TOO_BIG = 3;
80 /// Message header has invalid data.
81 static int const PARSE_MSG_INVALID = 5;
82 /// Component is malformed.
83 static int const PARSE_COMP_INVALID = 4;
84 /// Message is not the expected type.
85 static int const PARSE_MSG_WRONG_TYPE = 6;
86 /// Variable data for component can't fit in remaining data.
87 static int const PARSE_COMP_TOO_BIG = 7;
88 /// Fixed data for component can't fit in remaining data.
89 static int const PARSE_BUFFER_TOO_SMALL = 8;
90 /// Stored component size doesn't agree with locally computed size.
91 static int const PARSE_COMP_WRONG_SIZE = 9;
92 /// More data in message than can be accounted for.
93 static int const PARSE_DATA_OVERRUN = 10;
94 //@}
95
96 /** Buffer for serialized data.
97 Takes the basic ATS buffer and adds a count field to track
98 the amount of buffer in use.
99 */
100 class MsgBuffer : protected ts::Buffer
101 {
102 public:
103 typedef MsgBuffer self; ///< Self reference type.
104 typedef ts::Buffer super; ///< Parent type.
105
106 MsgBuffer(); ///< Default construct empty buffer.
107 /// Construct from ATS buffer.
108 MsgBuffer(super const &that ///< Instance to copy.
109 );
110 /// Construct from pointer and size.
111 MsgBuffer(void *ptr, ///< Pointer to buffer.
112 size_t n ///< Size of buffer.
113 );
114 /// Assign a buffer.
115 MsgBuffer &set(void *ptr, ///< Pointer to buffer.
116 size_t n ///< Size of buffer.
117 );
118
119 /// Get the buffer size.
120 size_t getSize() const;
121 /// Get the content size (use count).
122 size_t getCount() const;
123 /// Get address of first unused byte.
124 char *getTail();
125 /// Get address of first byte.
126 char *getBase();
127 /// Get address of first byte.
128 const char *getBase() const;
129 /// Get the remaining space in the buffer.
130 size_t getSpace() const;
131 /// Mark additional space in use.
132 self &use(size_t n ///< Additional space to mark in use.
133 );
134 /// Mark all space as unused.
135 self &reset();
136
137 /// Reset and zero the buffer.
138 self &zero();
139
140 size_t _count; ///< Number of bytes in use.
141 };
142
143 /// Sect 4.4: Cache assignment method.
144 enum CacheAssignmentType {
145 ASSIGNMENT_BY_HASH = 0,
146 ASSIGNMENT_BY_MASK = 1,
147 };
148
149 /// Top level message types.
150 enum message_type_t {
151 INVALID_MSG_TYPE = 0,
152 HERE_I_AM = 10,
153 I_SEE_YOU = 11,
154 REDIRECT_ASSIGN = 12,
155 REMOVAL_QUERY = 13,
156 };
157
158 /// Message component type.
159 /// See Sect 5.1 - 5.4
160 enum CompType {
161 SECURITY_INFO = 0,
162 SERVICE_INFO = 1,
163 ROUTER_ID_INFO = 2,
164 CACHE_ID_INFO = 3,
165 RTR_VIEW_INFO = 4,
166 CACHE_VIEW_INFO = 5,
167 REDIRECT_ASSIGNMENT = 6,
168 QUERY_INFO = 7,
169 CAPABILITY_INFO = 8,
170 ALT_ASSIGNMENT = 13,
171 ASSIGN_MAP = 14,
172 COMMAND_EXTENSION = 15,
173 COMP_TYPE_MIN = SECURITY_INFO,
174 COMP_TYPE_MAX = COMMAND_EXTENSION
175 };
176
177 /// Router Identity.
178 /// Data is stored in host order. This structure is not used publicly.
179 struct RouterId {
180 typedef RouterId self; ///< Self reference type.
181
182 RouterId(); ///< Default constructor.
183 /// Construct from address and sequence number.
184 RouterId(uint32_t addr, ///< Router address.
185 uint32_t recv_id ///< Receive ID (sequence number).
186 );
187
188 uint32_t m_addr; ///< Identifying router IP address.
189 uint32_t m_recv_id; ///< Receive ID (sequence #).
190 };
191
192 /** Sect 5.7.1: Router Identity Element.
193
194 This maps directly on to message content.
195
196 @internal A @c RouterId with accessors to guarantee correct memory
197 layout.
198 */
199 class RouterIdElt : protected RouterId
200 {
201 protected:
202 typedef RouterId super; ///< Parent type.
203 public:
204 typedef RouterIdElt self; ///< Self reference type.
205
206 /// Default constructor, members zero initialized.
207 RouterIdElt();
208 /// Construct from address and sequence number.
209 RouterIdElt(uint32_t addr, ///< Router address.
210 uint32_t recv_id ///< Receive ID (sequence number).
211 );
212
213 /// @name Accessors
214 //@{
215 uint32_t getAddr() const; ///< Get the address field.
216 self &setAddr(uint32_t addr); ///< Set the address field to @a addr.
217 uint32_t getRecvId() const; ///< Get the receive ID field.
218 self &setRecvId(uint32_t id); ///< Set the receive ID field to @a id.
219 //@}
220
221 /// Assign from non-serialized variant.
222 self &operator=(super const &that);
223 };
224
225 /// Sect 5.7.3: Assignment Key Element
226 /// @note This maps directly on to message content.
227 /// @internal: At top level because it is used in more than one component.
228 class AssignmentKeyElt
229 {
230 public:
231 typedef AssignmentKeyElt self; ///< Self reference type.
232
233 AssignmentKeyElt(); ///< Default constructor. No member initialization.
234 /// Construct from address and sequence number.
235 AssignmentKeyElt(uint32_t addr, ///< Key address.
236 uint32_t generation ///< Change number.
237 );
238
239 /// @name Accessors
240 //@{
241 uint32_t getAddr() const; ///< Get the address field.
242 self &setAddr(uint32_t addr); ///< Set the address field to @a addr.
243 uint32_t getChangeNumber() const; ///< Get change number field.
244 self &setChangeNumber(uint32_t n); ///< Set change number field to @a n.
245 //@}
246 protected:
247 uint32_t m_addr; ///< Identifying router IP address.
248 uint32_t m_change_number; ///< Change number (sequence #).
249 };
250
251 /// Sect 5.7.4: Router Assignment Element
252 /// @note This maps directly on to message content.
253 /// @internal: At top level because it is used in more than one component.
254 class RouterAssignElt : public RouterIdElt
255 {
256 public:
257 typedef RouterAssignElt self; ///< Self reference type.
258 typedef RouterIdElt super; ///< Parent type.
259
260 /// Default constructor, members zero initialized.
261 RouterAssignElt();
262 /// Construct from address and sequence number.
263 RouterAssignElt(uint32_t addr, ///< Router address.
264 uint32_t recv_id, ///< Receive ID (sequence number).
265 uint32_t change_number ///< Change number (sequence number).
266 );
267
268 /// @name Accessors
269 //@{
270 uint32_t getChangeNumber() const; ///< Get change number field.
271 self &setChangeNumber(uint32_t n); ///< Set change number field to @a n.
272 //@}
273 protected:
274 uint32_t m_change_number; ///< Change number (sequence #).
275 };
276
277 /** List of @c RouterAssignElt
278 @note Not explicitly part of the spec, but it shows up in multiple
279 places.
280 */
281 class RouterAssignListElt
282 {
283 public:
284 typedef RouterAssignListElt self; ///< Self reference type.
285
286 /// Default constructor - @b no initialization.
287 RouterAssignListElt();
288 /// Construct with @n elements.
289 RouterAssignListElt(int n ///< Number of elements.
290 );
291
292 /// @name Accessors
293 //@{
294 /// Access element.
295 RouterAssignElt &elt(int idx ///< Index of target element.
296 );
297 /// Access const element.
298 RouterAssignElt const &elt(int idx ///< Index of target element.
299 ) const;
300 /// Get the number of elements.
301 uint32_t getCount() const;
302 //@}
303
304 /// Update ID for a router.
305 self &updateRouterId(uint32_t addr, ///< Identifying IP address of router.
306 uint32_t rcvid, ///< New receive ID value.
307 uint32_t cno ///< New change number.
308 );
309
310 /// Get size in bytes of this structure.
311 size_t getSize() const;
312 /// Get the size of the variable part only.
313 /// This is useful for classes that put this element in their
314 /// stub structure.
315 size_t getVarSize() const;
316 /// Calculate size in bytes for @a n elements.
317 static size_t calcSize(int n ///< Number of elements.
318 );
319 /// Calculate size of variable data in bytes for @a n elements.
320 static size_t calcVarSize(int n ///< Number of elements.
321 );
322
323 protected:
324 uint32_t m_count; ///< # of elements (network order).
325 };
326
327 /// Sect 5.7.5: Capability Element
328 /// @note This maps directly on to message content.
329 class CapabilityElt
330 {
331 public:
332 typedef CapabilityElt self; ///< Self reference type.
333
334 /// Capability types.
335 enum Type : uint16_t {
336 NO_METHOD = 0, ///< Method not set.
337 PACKET_FORWARD_METHOD = 1, ///< Packet forwarding methods.
338 CACHE_ASSIGNMENT_METHOD = 2, ///< Cache assignment methods.
339 PACKET_RETURN_METHOD = 3 ///< Packet return methods.
340 };
341
342 CapabilityElt(); ///< Default constructor.
343 /// Construct from address and sequence number.
344 CapabilityElt(Type type, ///< Capability type.
345 uint32_t data ///< Capability data.
346 );
347
348 /// @name Accessors
349 //@{
350 Type getCapType() const; ///< Get the capability type.
351 /// Set capability type.
352 self &setCapType(Type cap ///< Capability type.
353 );
354 uint32_t getCapData() const; ///< Get capability data.
355 /// Set capability data.
356 self &setCapData(uint32_t data ///< Data value.
357 );
358 //@}
359 protected:
360 enum Type m_cap_type = NO_METHOD; ///< Capability type.
361 uint16_t m_cap_length = 0; ///< Length of capability data.
362 uint32_t m_cap_data = 0; ///< Capability data.
363 };
364
365 /// Sect 5.7.7: Mask element
366 class MaskElt
367 {
368 public:
369 typedef MaskElt self; ///< Self reference type.
370
371 /// Default constructor - @b no initialization.
372 MaskElt();
373 /// Construct with specific values.
374 MaskElt(uint32_t srcAddr, ///< Mask for source address.
375 uint32_t dstAddr, ///< Mask for destination address.
376 uint16_t srcPort, ///< Mask for source port.
377 uint16_t dstPort ///< Mask for destination port.
378 );
379
380 /// @name Accessors
381 //@{
382 /// Get source address mask field.
383 uint32_t getSrcAddr() const;
384 /// Set source address mask field to @a mask.
385 self &setSrcAddr(uint32_t mask);
386 /// Get destination address field.
387 uint32_t getDstAddr() const;
388 /// Set destination address field to @a mask.
389 self &setDstAddr(uint32_t mask);
390 /// Get source port mask field.
391 uint16_t getSrcPort() const;
392 /// Set source port mask field to @a mask.
393 self &setSrcPort(uint16_t mask);
394 /// Get destination port mask field.
395 uint16_t getDstPort() const;
396 /// Set destination port mask field to @a mask.
397 self &setDstPort(uint16_t mask);
398 //@}
399
400 protected:
401 uint32_t m_src_addr = INADDR_ANY; ///< Source address mask.
402 uint32_t m_dst_addr = INADDR_ANY; ///< Destination address mask.
403 uint16_t m_src_port = 0; ///< Source port mask.
404 uint16_t m_dst_port = 0; ///< Destination port mask.
405 };
406
407 /// Sect 5.7.8: Value element.
408 class ValueElt
409 {
410 public:
411 typedef ValueElt self; ///< Self reference type.
412
413 /// Default constructor - @b no initialization.
414 ValueElt();
415 /// Construct a specific value.
416 ValueElt(uint32_t cacheAddr, ///< Address of cache for this value.
417 uint32_t srcAddr, ///< Value for source address.
418 uint32_t dstAddr, ///< Value for destination address.
419 uint16_t srcPort, ///< Value for source port.
420 uint16_t dstPort ///< Value for destination port.
421 );
422
423 /// @name Accessors
424 //@{
425 uint32_t getf_src_addr() const; ///< Get source address field.
426 self &setf_src_addr(uint32_t addr); ///< Set source address field to @a addr.
427 uint32_t getDstAddr() const; ///< Get destination address field.
428 self &setf_dst_addr(uint32_t addr); ///< Set destination address field to @a addr.
429 uint16_t getf_src_port() const; ///< Get source port field.
430 self &setf_src_port(uint16_t port); ///< Set source port field to @a port.
431 uint16_t getDstPort() const; ///< Get destination port field.
432 self &setf_dst_port(uint16_t port); ///< Set destination port field to @a port.
433 uint32_t getCacheAddr() const; ///< Get cache address field.
434 self &setCacheAddr(uint32_t addr); ///< Set cache address field to @a addr
435 //@}
436
437 protected:
438 uint32_t m_src_addr; ///< Source address.
439 uint32_t m_dst_addr; ///< Destination address.
440 uint16_t m_src_port; ///< Source port.
441 uint16_t m_dst_port; ///< Destination port.
442 uint32_t m_cache_addr; ///< Cache address.
443 };
444
445 /** Sect 5.7.6: Mask/Value Set Element
446 This is a variable sized element.
447 */
448 class MaskValueSetElt
449 {
450 public:
451 typedef MaskValueSetElt self; ///< Self reference type.
452
453 MaskValueSetElt(); ///< Default constructor.
454 /// Construct from address and sequence number.
455 MaskValueSetElt(uint32_t n ///< Value count.
456 );
457
458 /// @name Accessors
459 //@{
460 /// Directly access contained mask element.
461 MaskElt &maskElt();
462
463 /// Get source address mask field.
464 uint32_t getSrcAddrMask() const;
465 /// Set source address mask field to @a mask.
466 self &setSrcAddrMask(uint32_t mask);
467 /// Get destination address field.
468 uint32_t getDstAddrMask() const;
469 /// Set destination address field to @a mask.
470 self &setDstAddrMask(uint32_t mask);
471 /// Get source port mask field.
472 uint16_t getSrcPortMask() const;
473 /// Set source port mask field to @a mask.
474 self &setSrcPortMask(uint16_t mask);
475 /// Get destination port mask field.
476 uint16_t getDstPortMask() const;
477 /// Set destination port mask field to @a mask.
478 self &setDstPortMask(uint16_t mask);
479
480 /// Append a value to this set.
481 self &addValue(uint32_t cacheAddr, ///< Address of cache for this value.
482 uint32_t srcAddr, ///< Value for source address.
483 uint32_t dstAddr, ///< Value for destination address.
484 uint16_t srcPort, ///< Value for source port.
485 uint16_t dstPort ///< Value for destination port.
486 );
487
488 /// Get the value count.
489 /// @note No corresponding @c set because this cannot be directly changed.
490 uint32_t getCount() const;
491 /// Access value element.
492 ValueElt &operator[](int idx ///< Index of target element.
493 );
494 //@}
495 /// Calculate the size of an element with @a n values.
496 static size_t calcSize(uint32_t n ///< Number of values.
497 );
498 /// Get the size (length) of this element.
499 size_t getSize() const;
500
501 protected:
502 // All members are kept in network order.
503 MaskElt m_mask; ///< Base mask element.
504 uint32_t m_count; ///< Number of value elements.
505
506 /// Get base address of Value elements.
507 ValueElt *values();
508 /// Get base address of Value elements.
509 ValueElt const *values() const;
510 };
511
512 /// Assignment of caches by hash.
513 /// Not in specification.
514 class HashAssignElt
515 {
516 public:
517 typedef HashAssignElt self; ///< Self reference type.
518
519 /// Hash assignment bucket.
520 struct Bucket {
521 unsigned int m_idx : 7; ///< Cache index.
522 unsigned int m_alt : 1; ///< Alternate hash flag.
523
524 /// Test for unassigned value in bucket.
525 bool is_unassigned() const;
526 } __attribute__((aligned(1), packed));
527
528 /// Default constructor - @b no initialization.
529 HashAssignElt();
530 /// Construct with @n elements.
531 HashAssignElt(int n ///< Number of elements.
532 );
533
534 /// @name Accessors
535 //@{
536 /// Get the number of caches.
537 uint32_t getCount() const;
538 /// Get a cache address.
539 uint32_t getAddr(int idx ///< Index of target address.
540 ) const;
541 /// Set a cache address.
542 self &setAddr(int idx, ///< Index of target address.
543 uint32_t addr ///< Address value to set.
544 );
545 /// Access a bucket.
546 Bucket &operator[](size_t idx ///< Bucket index (0..N_BUCKETS-1)
547 );
548 /// Access a const bucket.
549 Bucket const &operator[](size_t idx ///< Bucket index (0..N_BUCKETS-1)
550 ) const;
551 //@}
552
553 /** Do a round robin assignment.
554 The buckets are assigned round robin, starting with 0, up to the
555 index of the last cache.
556 @return @c this.
557 */
558 self &round_robin_assign();
559
560 /// Get size in bytes of this structure.
561 size_t getSize() const;
562 /// Calculate size in bytes for @a n caches.
563 static size_t calcSize(int n ///< Number of caches.
564 );
565
566 protected:
567 uint32_t m_count; ///< # of caches (network order).
568
569 Bucket *getBucketBase();
570 };
571
572 /** Assignment of caches by mask.
573 @note Not in specification.
574
575 @internal Because this is an element, it must correspond exactly
576 to the serialized layout. Therefore we can't keep extra accounting
577 data around to make manipulation easier. We need a helper class
578 for that, which functions in a manner similar to an iterator.
579 */
580
581 class MaskAssignElt
582 {
583 public:
584 typedef MaskAssignElt self; ///< Self reference type.
585
586 /** A minimalist insert iterator.
587 */
588 struct appender {
589 typedef appender self; ///< Self reference type.
590 /// Get pointer to current set.
591 MaskValueSetElt *operator->();
592 /// Append a new mask/value set.
593 /// @return A pointer to the new set.
594 MaskValueSetElt *mask(uint32_t srcAddr, ///< Mask for source address.
595 uint32_t dstAddr, ///< Mask for destination address.
596 uint16_t srcPort, ///< Mask for source port.
597 uint16_t dstPort ///< Mask for destination port.
598 );
599 /// Initialize the current set to empty with specific mask values.
600 /// @return A pointer to the new set.
601 MaskValueSetElt *initSet(uint32_t srcAddr, ///< Mask for source address.
602 uint32_t dstAddr, ///< Mask for destination address.
603 uint16_t srcPort, ///< Mask for source port.
604 uint16_t dstPort ///< Mask for destination port.
605 );
606 MaskValueSetElt *m_set; ///< Current set.
607 MaskAssignElt *m_elt; ///< Parent element.
608 };
609
610 /// @name Accessors
611 //@{
612 /// Get the number of mask/value sets.
613 uint32_t getCount() const;
614 //@}
615
616 appender init(uint32_t srcAddr, ///< Mask for source address.
617 uint32_t dstAddr, ///< Mask for destination address.
618 uint16_t srcPort, ///< Mask for source port.
619 uint16_t dstPort ///< Mask for destination port.
620 );
621
622 /// Get size in bytes of this structure.
623 /// @note This is not constant time. The mask/value sets must be traversed
624 /// to get the total size.
625 size_t getSize() const;
626 /// Get the size in bytes of the variable part of this structure.
627 /// @note This is not constant time. The mask/value sets must be traversed
628 /// to get the total size.
629 size_t getVarSize() const;
630
631 protected:
632 uint32_t m_count = 0; ///< # of sets (network order).
633
634 friend struct appender;
635 };
636
637 class CacheIdBox;
638
639 /** Sect 5.7.2: Web-Cache Identity Element
640 According to the specification, this is a fixed structure with
641 hash data. However, in practice there is an undocumented variant for
642 mask assignment where it contains mask data instead of hash data.
643
644 This class provides basic control. Two subclasses specialize for the
645 two variants. Use @c isMask to detect which variant is present.
646
647 @note Do not add virtual methods, as reasonable as that seems because
648 this is a serialized object and the memory layout correspond to the
649 protocol definition.
650
651 @see CacheHashIdElt
652 @see CacheMaskIdElt
653 */
654 class CacheIdElt
655 {
656 friend class CacheIdBox;
657
658 public:
659 typedef CacheIdElt self; ///< Self reference type.
660
661 /// Hash revision (protocol required).
662 static uint16_t const HASH_REVISION = 0;
663
664 /// @name Accessors
665 //@{
666 uint32_t getAddr() const; ///< Get address field.
667 self &setAddr(uint32_t addr); ///< Set address field to @a addr.
668 uint16_t getHashRev() const; ///< Get hash revision field.
669 self &setHashRev(uint16_t rev); ///< Set hash revision field to @a rev.
670 self &initHashRev(); ///< Set hash revision to default value.
671 bool getUnassigned() const; ///< Get unassigned field.
672 self &setUnassigned(bool state); ///< Set unassigned field to @a state.
673 bool isMask() const; ///< @return @c true if this is a mask assignment.
674 /** Set the maskiness of this structure.
675 Be very careful with this, as different values change the
676 memory layout of the object.
677 */
678 self &setMask(bool state ///< @c true to be mask, @c false to be hash.
679 );
680
681 self &clearReserved(); ///< Set reserved bits to zero.
682 //@}
683
684 protected:
685 uint32_t m_addr; ///< Identifying cache IP address.
686 uint16_t m_hash_rev; ///< Hash revision.
687 unsigned int m_reserved_0 : 7; ///< Reserved bits.
688 /** Cache not assigned.
689 If set the cache does not have an assignment in the redirection
690 hash table and the data in @a m_buckets is historical. This allows
691 a cache that was removed to be added back in the same buckets.
692 */
693 unsigned int m_unassigned : 1;
694 unsigned int m_reserved_1 : 1; ///< Reserved (unused).
695 unsigned int m_is_mask : 1; ///< Set -> mask, Clear -> hash.
696 unsigned int m_reserved_2 : 6; ///< Reserved (unused).
697 /** Trailing elements common to all cache ID variants.
698 Unfortunately, although @c weight and @c status are common, they are
699 after the variable data and so can't be put in the base class.
700 Best we can do is declare a struct for them for later convenience.
701 */
702 struct Tail {
703 uint16_t m_weight; ///< Weight of assignment.
704 uint16_t m_status; ///< Cache status.
705 };
706 };
707
708 /** Cache ID for Hash assignment.
709 */
710 class CacheHashIdElt : public CacheIdElt
711 {
712 friend class CacheIdBox;
713
714 public:
715 typedef CacheHashIdElt self; ///< Self reference type.
716 typedef CacheIdElt super; ///< Parent type.
717 /// Container for hash assignment.
718 typedef uint8_t HashBuckets[N_BUCKETS >> 3];
719 /// @name Accessors
720 //@{
721 bool getBucket(int idx) const; ///< Get bucket state at index @a idx.
722 /// Set bucket at index @a idx to @a state.
723 self &setBucket(int idx, bool state);
724 self &setBuckets(bool state); ///< Set all buckets to @a state.
725 uint16_t getWeight() const; ///< Get weight field.
726 self &setWeight(uint16_t w); ///< Set weight field to @a w.
727 uint16_t getStatus() const; ///< Get status field.
728 self &setStatus(uint16_t s); ///< Set status field to @a s.
729 //@}
730 /// Get object size in bytes.
731 size_t getSize() const;
732
733 protected:
734 /// Bit vector of buckets assigned to this cache.
735 HashBuckets m_buckets;
736 Tail m_tail; /// Trailing values in element.
737
738 /// Get the address of the tail elements.
739 Tail *getTailPtr();
740 };
741
742 /** Cache ID for Mask assignment.
743 Be a little careful with this object. Because it's an element and
744 must copy the serialized data layout, almost all of the methods are
745 not constant time but require walking internal data structures.
746
747 @internal Experimentally,
748 - A mask assign element count of zero does not work. It fails
749 with the wrongly descriptive message "incompatible assignment data".
750 - A single mask assign element with a mask set with one value seems to
751 work.
752 */
753 class CacheMaskIdElt : public CacheIdElt
754 {
755 friend class CacheIdBox;
756
757 public:
758 typedef CacheMaskIdElt self; ///< Self reference type.
759 typedef CacheIdElt super; ///< Parent type.
760 /// @name Accessors
761 //@{
762 uint16_t getWeight() const; ///< Get weight field.
763 self &setWeight(uint16_t w); ///< Set weight field to @a w.
764 uint16_t getStatus() const; ///< Get status field.
765 self &setStatus(uint16_t s); ///< Set status field to @a s.
766 /// Get the number of mask/value sets.
767 uint32_t getCount() const;
768 //@}
769 /// Get object size in bytes.
770 size_t getSize() const;
771
772 protected:
773 /// Mask assignment data.
774 MaskAssignElt m_assign;
775 /// Get a pointer to where the tail data is.
776 /// Presumes the assignment is filled out.
777 Tail *getTailPtr();
778 };
779
780 /** Holder for a @c CacheIdElt.
781 This class is needed because of the restrictions on element classes and
782 because a @c CacheIdElt is a variable sized element yet we need to store
783 instances of it in other classes. This box both holds an instance and
784 handles some of the memory allocation issues involved.
785 */
786 class CacheIdBox
787 {
788 public:
789 typedef CacheIdBox self; ///< Self reference type.
790
791 /// Default constructor.
792 CacheIdBox() = default;
793
794 /// @name Accessors
795 //@{
796 /// Get the identifying cache address.
797 uint32_t getAddr() const;
798 /// Set the identifying cache address.
799 self &setAddr(uint32_t ///< Identifying IP address.
800 );
801 uint16_t getHashRev() const; ///< Get hash revision field.
802 self &setHashRev(uint16_t rev); ///< Set hash revision field to @a rev.
803 self &initHashRev(); ///< Set hash revision to default value.
804 bool getUnassigned() const; ///< Get unassigned field.
805 self &setUnassigned(bool state); ///< Set unassigned field to @a state.
806 bool isMask() const; ///< @return @c true if this is a mask assignment.
807 /** Set the maskiness of this structure.
808 Be very careful with this, as different values change the
809 memory layout of the object.
810 */
811 self &setMask(bool state ///< @c true to be mask, @c false to be hash.
812 );
813
814 self &clearReserved(); ///< Set reserved bits to zero.
815 //@}
816 /// Initialize to unassigned hash.
817 /// The cache address is set to @a addr.
818 self &initDefaultHash(uint32_t addr ///< Identifying cache address.
819 );
820 /// Initialize to unassigned mask
821 /// The cache address is set to @a addr.
822 self &initDefaultMask(uint32_t addr ///< Identifying cache address.
823 );
824 /** Fill in element from source copy.
825 Internal memory is allocated and the @a src copied.
826 */
827 self &fill(self const &src ///< Original source element
828 );
829 /** Fill in element from source copy.
830 This is used to write the element to memory that is allocated
831 independently of the box.
832 @note Caller is expected to have verified sufficient buffer space.
833 */
834 self &fill(void *base, ///< Target buffer.
835 self const &src ///< Original source element
836 );
837 /// Initialize box from an existing element in memory.
838 int parse(MsgBuffer base ///< Source memory.
839 );
840
841 /// Get the size in bytes of the contained element.
842 size_t getSize() const;
843
844 protected:
845 /// Force buffer to be at least @a n bytes
846 self &require(size_t n ///< Minimum buffer size required.
847 );
848
849 CacheIdElt *m_base = nullptr; ///< Base address of memory for element.
850 CacheIdElt::Tail *m_tail = nullptr; ///< Base address of trailing data elements.
851 size_t m_size = 0; ///< Size of element (valid data in buffer);
852 size_t m_cap = 0; ///< Size of allocated memory. Zero if external memory.
853 };
854
855 /** Base class for all components.
856
857 Each component is a fixed sized object that represents a
858 component in the WCCP message. The component instance points at
859 its corresponding data in the message. Values in the message are
860 accessed through accessor methods which have the form @c
861 getNAME and @c setNAME for "get field" and "set field". The
862 @c set methods return a reference to the component so that
863 they can be chained.
864
865 Most components will have an internal typedef @c raw_t which is a
866 structure with the exact memory layout of the
867 component. Components without this typedef cannot be directed
868 represented by a C++ structure (which is why we need this
869 indirection in the first place).
870 */
871 class ComponentBase
872 {
873 public:
874 typedef ComponentBase self; ///< Self reference type.
875 /// Default constructor.
876 ComponentBase() = default;
877 /// Check for not present.
878 bool isEmpty() const;
879
880 protected:
881 /// Base of component in message data.
882 /// If this is @c NULL then the component is not in the message.
883 char *m_base = nullptr;
884 };
885
886 /// Synthetic component to represent the overall message header.
887 class MsgHeaderComp : public ComponentBase
888 {
889 public:
890 typedef MsgHeaderComp self; ///< Self reference type.
891 typedef ComponentBase super; ///< Parent type.
892
893 /// Sect 5.5: Message Header
894 /// Serialized layout of message header.
895 struct raw_t {
896 uint32_t m_type; ///< @c message_type_t
897 uint16_t m_version; ///< Implementation version of sender
898 uint16_t m_length; ///< Message body length (excluding header)
899 };
900
901 /// Default constructor.
MsgHeaderComp()902 MsgHeaderComp() {}
903 /// @name Accessors
904 //@{
905 message_type_t getType(); ///< Get message type field.
906 uint16_t getVersion(); ///< Get message version field.
907 uint16_t getLength(); ///< Get message length field.
908 self &setType(message_type_t type); ///< Set message type field to @a type.
909 self &setVersion(uint16_t version); ///< Set version field to @a version.
910 self &setLength(uint16_t length); ///< Set length field to @a length.
911 //@}
912
913 /// Write initial values to message data.
914 /// @a base is updated to account for this component.
915 self &fill(MsgBuffer &base, ///< [in,out] Buffer for component storage.
916 message_type_t t ///< Message type.
917 );
918
919 /// Validate component for existing data.
920 /// @a base is updated to account for this component.
921 int parse(MsgBuffer &base ///< [in,out] Base address for component data.
922 );
923
924 /// Compute size of a component of this type.
925 static size_t calcSize();
926
927 /// Convert to a top level message type.
928 /// @return The converted type if valid, @c INVALID_MSG_TYPE if not.
929 static message_type_t toMsgType(int t);
930 };
931
932 /** Intermediate base class for components with the standard component header.
933
934 @note That's all of them except the message header itself.
935
936 @internal This saves some work getting around C++ co-variance issues
937 with return values.
938 */
939 template <typename T ///< Child class (CRT pattern)
940 >
941 struct CompWithHeader : public ComponentBase {
942 /** Serialized layout of per component header.
943 All components except the message header start with this structure.
944 Provided for ease of use by child classes, which should
945 subclass this for their own @c raw_t.
946 */
947 struct raw_t {
948 uint16_t m_type; ///< Serialized @ref CompType.
949 uint16_t m_length; ///< length of rest of component (not including header).
950 };
951 /** Size of header.
952 This is needed by all subclasses because the value in the length field
953 excludes this structure.
954 */
955 static size_t const HEADER_SIZE = sizeof(raw_t);
956
957 /// @name Accessors
958 //@{
959 CompType getType() const; ///< Get component type field.
960 uint16_t getLength() const; ///< Get component length field.
961 T &setType(CompType type); ///< Set component type field to @a type.
962 T &setLength(uint16_t length); ///< Set length field to @a length.
963 //@}
964
965 /** Check the component header for type and length sanity.
966 This requires the (subclass) client to
967 - Do a size check to verify enough space for the component header.
968 - Set @a m_base
969
970 This method
971 - Checks the component type against the expected type (@a ect)
972 - Checks stored component length against the buffer size.
973
974 @return A parse result.
975 */
976 int checkHeader(MsgBuffer const &buffer, ///< Message buffer.
977 CompType t ///< Expected component type.
978 );
979 };
980
981 /** Sect 5.6.1: Security Info Component
982 This is used for both security options. Clients should check
983 the @c m_option to see if the @a m_impl member is valid.
984 */
985 class SecurityComp : public CompWithHeader<SecurityComp>
986 {
987 public:
988 typedef SecurityComp self; ///< Self reference type.
989 typedef CompWithHeader<self> super; ///< Parent type.
990 /// Specify the type for this component.
991 static CompType const COMP_TYPE = SECURITY_INFO;
992
993 /// Import security option type.
994 typedef SecurityOption Option;
995
996 static size_t const KEY_SIZE = 8;
997 typedef char Key[KEY_SIZE];
998
999 /// Raw memory layout, no security.
1000 struct RawNone : public super::raw_t {
1001 uint32_t m_option; ///< @c Option
1002 };
1003
1004 /// Raw memory layout, with MD5.
1005 struct RawMD5 : public RawNone {
1006 /// Size of MD5 hash (in bytes).
1007 static size_t const HASH_SIZE = 16;
1008 /// Storage for MD5 hash.
1009 typedef uint8_t HashData[HASH_SIZE];
1010 /// MD5 hash value.
1011 HashData m_data;
1012 };
1013
1014 /// Default constructor.
1015 SecurityComp();
1016
1017 /// @name Accessors
1018 //@{
1019 Option getOption() const; ///< Get security option field.
1020 self &setOption(Option opt); ///< Set security option field to @a opt.
1021 //@}
1022
1023 /// Write default values to the serialization buffer.
1024 self &fill(MsgBuffer &buffer, Option opt = m_default_opt);
1025 /// Validate an existing structure.
1026 int parse(MsgBuffer &buffer);
1027
1028 /// Compute the memory size of the component.
1029 static size_t calcSize(Option opt);
1030
1031 /// Set the global / default security key.
1032 /// This is used for the security hash unless the local key is set.
1033 /// @a key is copied to a global buffer and clipped to @c KEY_SIZE bytes.
1034 static void setDefaultKey(const char *key ///< Shared key.
1035 );
1036 static void setDefaultOption(Option opt ///< Type of security.
1037 );
1038
1039 /// Set message local security key.
1040 self &setKey(const char *key ///< Shared key.
1041 );
1042
1043 /// Compute and set the security data.
1044 /// @a msg must be a buffer that covers exactly the entire message.
1045 self &secure(MsgBuffer const &msg ///< Message data.
1046 );
1047
1048 bool validate(MsgBuffer const &msg ///< Message data.
1049 ) const;
1050
1051 protected:
1052 /// Local to this message shared key / password.
1053 Key m_key;
1054 /// Use local key.
1055 bool m_local_key;
1056 /// Global (static) shared key / password.
1057 static Key m_default_key;
1058 /// Default security option.
1059 static Option m_default_opt;
1060 };
1061
1062 /// Sect 5.6.2: Service Info Component
1063 class ServiceComp : public CompWithHeader<ServiceComp>
1064 {
1065 public:
1066 typedef ServiceComp self; ///< Self reference type.
1067 typedef CompWithHeader<self> super; ///< Parent type.
1068
1069 /// Specify the type for this component.
1070 static CompType const COMP_TYPE = SERVICE_INFO;
1071
1072 /// Serialized format for component.
1073 struct raw_t : public super::raw_t, public ServiceGroup {
1074 };
1075
1076 ServiceComp(); ///< Default constructor, no member initialization.
1077
1078 /// @name Accessors
1079 //@{
1080 ServiceGroup::Type getSvcType() const; ///< Get service type field.
1081 /** Set the service type.
1082 If @a svc is @c SERVICE_STANDARD then all fields except the
1083 component header and service id are set to zero as required
1084 by the protocol.
1085 */
1086 self &setSvcType(ServiceGroup::Type svc);
1087
1088 uint8_t getSvcId() const; ///< Get service ID field.
1089 self &setSvcId(uint8_t id); ///< Set service ID field to @a id.
1090
1091 uint8_t getPriority() const; ///< Get priority field.
1092 self &setPriority(uint8_t pri); ///< Set priority field to @a p.
1093
1094 uint8_t getProtocol() const; ///< Get protocol field.
1095 self &setProtocol(uint8_t p); ///< Set protocol field to @a p.
1096
1097 uint32_t getFlags() const; ///< Get flags field.
1098 self &setFlags(uint32_t f); ///< Set the flags flags in field to @a f.
1099 /// Set the flags in the flag field that are set in @a f.
1100 /// Other flags are unchanged.
1101 self &enableFlags(uint32_t f);
1102 /// Clear the flags in the flag field that are set in @a f.
1103 /// Other flags are unchanged.
1104 self &disableFlags(uint32_t f);
1105
1106 /// Get a port value.
1107 uint16_t getPort(int idx ///< Index of target port.
1108 ) const;
1109 /// Set a port value.
1110 self &setPort(int idx, ///< Index of port.
1111 uint16_t port ///< Value for port.
1112 );
1113 /// Zero (clear) all ports.
1114 self &clearPorts();
1115 /** Add a port to the service.
1116 The first port which has not been set is set to @a port. It is an error
1117 to add more than @c N_PORTS ports.
1118 */
1119 self &addPort(uint16_t port ///< Port value.
1120 );
1121 //@}
1122
1123 /// Raw access to ServiceGroup.
1124 operator ServiceGroup const &() const;
1125
1126 /** Fill from a service group definition.
1127 */
1128 self &fill(MsgBuffer &base, ///< Target storage.
1129 ServiceGroup const &svc ///< Service group definition.
1130 );
1131
1132 /// Validate an existing structure.
1133 /// @return Parse result.
1134 int parse(MsgBuffer &buffer);
1135
1136 /// Compute the memory size of the component.
1137 static size_t calcSize();
1138
1139 protected:
1140 int m_port_count; ///< Number of ports in use.
1141
1142 /// Cast raw internal pointer to data type.
1143 raw_t *access();
1144 /// Cast raw internal pointer to data type.
1145 raw_t const *access() const;
1146 };
1147
1148 /// Sect 5.6.3: RouterIdentity Info Component
1149 /// @note An instance of this struct is followed by @a m_count
1150 /// IP addresses.
1151 class RouterIdComp : public CompWithHeader<RouterIdComp>
1152 {
1153 public:
1154 typedef RouterIdComp self; ///< Self reference type.
1155 typedef CompWithHeader<self> super; ///< Parent type.
1156
1157 /// Specify the type for this component.
1158 static CompType const COMP_TYPE = ROUTER_ID_INFO;
1159
1160 /// Stub of serialized layout.
1161 struct raw_t : public super::raw_t {
1162 RouterIdElt m_id; ///< Router ID element.
1163 /// Source address.
1164 /// For response messages, this is the address to which the
1165 /// original message was sent.
1166 uint32_t m_to_addr;
1167 /// # of target cache addresses.
1168 uint32_t m_from_count;
1169 // Addresses follow here.
1170 };
1171
1172 /// @name Accessors
1173 //@{
1174 /// Directly access router ID element.
1175 RouterIdElt &idElt();
1176 /// Directly access router ID element.
1177 RouterIdElt const &idElt() const;
1178 /// Set the fields in the router ID element.
1179 self &setIdElt(uint32_t addr, ///< Identifying IP address for router.
1180 uint32_t recv_id ///< Receive count for router to target cache.
1181 );
1182 uint32_t getAddr() const; ///< Get the address field in the ID element.
1183 self &setAddr(uint32_t addr); ///< Set the address field in the ID element.
1184 uint32_t getRecvId() const; ///< Get the receive ID field in the ID element.
1185 self &setRecvId(uint32_t id); ///< Set the receive ID field in the ID element.
1186
1187 /// Get the sent to address.
1188 uint32_t getToAddr() const;
1189 /// Set the sent to address.
1190 self &setToAddr(uint32_t addr ///< Address value.
1191 );
1192 /// Get router count field.
1193 /// @note No @c setf method because this cannot be changed independently.
1194 /// @see fill
1195 uint32_t getFromCount() const;
1196 /// Get received from address.
1197 uint32_t getFromAddr(int idx ///< Index of address.
1198 ) const;
1199 /// Set received from address.
1200 self &setFromAddr(int idx, ///< Index of address.
1201 uint32_t addr ///< Address value.
1202 );
1203 //@}
1204 /// Find an address in the from list.
1205 /// @return The index of the address, or -1 if not found.
1206 int findFromAddr(uint32_t addr ///< Search value.
1207 );
1208
1209 /** Write serialization data for single cache target.
1210 This completely fills the component.
1211 */
1212 self &fillSingleton(MsgBuffer &base, ///< Target storage.
1213 uint32_t addr, ///< Identifying IP address.
1214 uint32_t recv_count, ///< Receive count for target cache.
1215 uint32_t to_addr, ///< Destination address in initial packet.
1216 uint32_t from_addr ///< Identifying IP address of target cache.
1217 );
1218
1219 /** Write basic message structure.
1220 The router and cache data must be filled in separately.
1221 */
1222 self &fill(MsgBuffer &base, ///< Target storage.
1223 size_t n_caches ///< Number of caches (fromAddr).
1224 );
1225
1226 /// Validate an existing structure.
1227 /// @return Parse result.
1228 int parse(MsgBuffer &buffer);
1229
1230 /// Compute the memory size of the component.
1231 static size_t calcSize(int n ///< Receive address count
1232 );
1233 };
1234
1235 /** Sect 5.6.4: Web-Cache Identity Info Component
1236 */
1237 class CacheIdComp : public CompWithHeader<CacheIdComp>
1238 {
1239 public:
1240 typedef CacheIdComp self; ///< Self reference type.
1241 typedef CompWithHeader<self> super; ///< Parent type.
1242
1243 /// Component type ID for this component.
1244 static CompType const COMP_TYPE = CACHE_ID_INFO;
1245
1246 /// Serialized format.
1247 struct raw_t : public super::raw_t {
1248 CacheIdElt m_id; ///< Identity element stub.
1249 };
1250
1251 /// @name Accessors
1252 //@{
1253 /// Direct access to the cache ID element.
1254 CacheIdBox &cacheId();
1255 CacheIdBox const &cacheId() const;
1256
1257 // Only forward the common ones.
1258 uint32_t getAddr() const; ///< Get address field.
1259 self &setAddr(uint32_t addr); ///< Set address field to @a addr.
1260 uint16_t getHashRev() const; ///< Get hash revision field.
1261 self &setHashRev(uint16_t rev); ///< Set hash revision field to @a rev.
1262 bool getUnassigned() const; ///< Get unassigned field.
1263 self &setUnassigned(bool state); ///< Set unassigned field to @a state.
1264 uint16_t getWeight() const; ///< Get weight field.
1265 self &setWeight(uint16_t w); ///< Set weight field to @a w.
1266 uint16_t getStatus() const; ///< Get status field.
1267 self &setStatus(uint16_t s); ///< Set status field to @a s.
1268 //@}
1269
1270 /** Write serialization data.
1271 - Sets required header fields for the component.
1272 - Copies the data from @a src.
1273 */
1274 self &fill(MsgBuffer &base, ///< Target storage.
1275 CacheIdBox const &src ///< Cache descriptor
1276 );
1277
1278 /// Validate an existing structure.
1279 /// @return Parse result.
1280 int parse(MsgBuffer &buffer);
1281
1282 /// Compute the memory size of the component.
1283 /// Cannot be reliably computed statically.
1284 size_t getSize();
1285
1286 protected:
1287 CacheIdBox m_box; ///< Wrapper for cache id element.
1288 };
1289
1290 /** Sect 5.6.5: Router View Info Component
1291 */
1292 class RouterViewComp : public CompWithHeader<RouterViewComp>
1293 {
1294 public:
1295 typedef RouterViewComp self; ///< Self reference type.
1296 typedef CompWithHeader<self> super; ///< Parent type.
1297
1298 /// Component type ID for this component.
1299 static CompType const COMP_TYPE = RTR_VIEW_INFO;
1300
1301 /// Stub of the serialized data.
1302 /// There is more variable sized data that must be handled specially.
1303 struct raw_t : public super::raw_t {
1304 uint32_t m_change_number; ///< Sequence number.
1305 AssignmentKeyElt m_key; ///< Assignment data.
1306 uint32_t m_router_count; ///< # of router elements.
1307 };
1308
1309 RouterViewComp();
1310
1311 /// @name Accessors
1312 //@{
1313 /// Directly access assignment key.
1314 AssignmentKeyElt &keyElt();
1315 /// Directly access assignment key.
1316 AssignmentKeyElt const &keyElt() const;
1317 /// Get address in assignment key.
1318 uint32_t getKeyAddr() const;
1319 /// Set address in assignment key.
1320 self &setKeyAddr(uint32_t addr);
1321 /// Get change number in assignment key.
1322 uint32_t getKeyChangeNumber() const;
1323 /// Set change number in assignment key.
1324 self &setKeyChangeNumber(uint32_t n);
1325
1326 uint32_t getChangeNumber() const; ///< Get change number field.
1327 self &setChangeNumber(uint32_t n); ///< Set change number field to @a n
1328
1329 /// Get cache count field.
1330 /// @note No @c setf method because this cannot be changed independently.
1331 /// @see fill
1332 uint32_t getCacheCount() const;
1333 /// Access cache element.
1334 CacheIdBox &cacheId(int idx ///< Index of target element.
1335 );
1336 /// Access cache element.
1337 CacheIdBox const &cacheId(int idx ///< Index of target element.
1338 ) const;
1339 /// Get router count field.
1340 /// @note No @c setf method because this cannot be changed independently.
1341 /// @see fill
1342 uint32_t getRouterCount() const;
1343 /// Get router address.
1344 uint32_t getRouterAddr(int idx ///< Index of router.
1345 ) const;
1346 /// Set router address.
1347 self &setRouterAddr(int idx, ///< Index of router.
1348 uint32_t addr ///< Address value.
1349 );
1350 //@}
1351
1352 /** Write serialization data.
1353
1354 A client @b must call this method before writing any fields directly.
1355 After invocation the client must fill in the router and cache elements.
1356 */
1357 self &fill(MsgBuffer &base, ///< Target storage.
1358 int n_routers, ///< Number of routers in view.
1359 int n_caches ///< Number of caches in view.
1360 );
1361
1362 /// Validate an existing structure.
1363 /// @return Parse result.
1364 int parse(MsgBuffer &buffer);
1365
1366 protected:
1367 /// Serialized count of cache addresses.
1368 /// The actual addresses start immediate after this.
1369 uint32_t *m_cache_count;
1370 /// Wrappers for cache identity elements.
1371 /// These are variably sized in the general case.
1372 CacheIdBox m_cache_ids[MAX_CACHES];
1373
1374 /// Compute the address of the cache count field.
1375 /// Assumes the router count field is set.
1376 uint32_t *calc_cache_count_ptr();
1377 };
1378
1379 /** Sect 5.6.6: Web-Cache View Info Component
1380 */
1381 class CacheViewComp : public CompWithHeader<CacheViewComp>
1382 {
1383 public:
1384 typedef CacheViewComp self; ///< Self reference type.
1385 typedef CompWithHeader<self> super; ///< Parent type.
1386
1387 /// Component type ID for this component.
1388 static CompType const COMP_TYPE = CACHE_VIEW_INFO;
1389
1390 /// Stub of the serialized data.
1391 /// There is more variable sized data that must be handled specially.
1392 struct raw_t : public super::raw_t {
1393 uint32_t m_change_number; ///< Sequence number.
1394 uint32_t m_router_count; ///< # of router ID elements.
1395 };
1396
1397 /// @name Accessors
1398 //@{
1399 uint32_t getChangeNumber() const; ///< Get change number field.
1400 self &setChangeNumber(uint32_t n); ///< Set change number field to @a n
1401
1402 /// Get router count field.
1403 /// @note No @c setf method because this cannot be changed independently.
1404 /// @see fill
1405 uint32_t getRouterCount() const;
1406 /// Access a router ID element.
1407 RouterIdElt &routerElt(int idx ///< Index of target element.
1408 );
1409 /** Find a router element by router IP address.
1410 @return A pointer to the router element or @c NULL
1411 if no router is identified by @a addr.
1412 */
1413 RouterIdElt *findf_router_elt(uint32_t addr ///< Router IP address.
1414 );
1415 /// Get cache count field.
1416 /// @note No @c setf method because this cannot be changed independently.
1417 /// @see fill
1418 uint32_t getCacheCount() const;
1419 /// Get a cache address.
1420 uint32_t getCacheAddr(int idx ///< Index of target address.
1421 ) const;
1422 /// Set a cache address.
1423 self &setCacheAddr(int idx, ///< Index of target address.
1424 uint32_t addr ///< Address value to set.
1425 );
1426 //@}
1427
1428 /** Write serialization data.
1429
1430 A client @b must call this method before writing any fields directly.
1431 After invocation the client must fill in the router and cache elements.
1432 */
1433 self &fill(MsgBuffer &buffer, ///< Target storage.
1434 detail::cache::GroupData const &group ///< Service group information.
1435 );
1436
1437 /// Validate an existing structure.
1438 /// @return Parse result.
1439 int parse(MsgBuffer &buffer);
1440
1441 /// Compute the total size of the component.
1442 static size_t calcSize(int n_routers, ///< Number of routers in view.
1443 int n_caches ///< Number of caches in view.
1444 );
1445
1446 protected:
1447 /// Get router element array.
1448 /// @return A pointer to the first router element.
1449 RouterIdElt *atf_router_array();
1450 /// Serialized count of cache addresses.
1451 /// The actual addresses start immediate after this.
1452 uint32_t *m_cache_count;
1453 };
1454
1455 /** Sect 5.6.7: Assignment Info Component
1456 */
1457 class AssignInfoComp : public CompWithHeader<AssignInfoComp>
1458 {
1459 public:
1460 typedef AssignInfoComp self; ///< Self reference type.
1461 typedef CompWithHeader<self> super; ///< Parent type.
1462
1463 /// Component type ID for this component.
1464 static CompType const COMP_TYPE = REDIRECT_ASSIGNMENT;
1465
1466 /// Stub of the serialized data.
1467 /// There is more variable sized data that must be handled specially.
1468 struct raw_t : public super::raw_t {
1469 AssignmentKeyElt m_key; ///< Assignment key data.
1470 RouterAssignListElt m_routers; ///< Routers.
1471 };
1472 typedef HashAssignElt::Bucket Bucket; ///< Import type.
1473
1474 /// @name Accessors
1475 //@{
1476 /// Directly access assignment key.
1477 AssignmentKeyElt &keyElt();
1478 /// Directly access assignment key.
1479 AssignmentKeyElt const &keyElt() const;
1480 /// Get address in assignment key.
1481 uint32_t getKeyAddr() const;
1482 /// Set address in assignment key.
1483 self &setKeyAddr(uint32_t addr);
1484 /// Get change number in assignment key.
1485 uint32_t getKeyChangeNumber() const;
1486 /// Set change number in assignment key.
1487 self &setKeyChangeNumber(uint32_t n);
1488
1489 /// Get router count field.
1490 /// @note No @c setf method because this cannot be changed independently.
1491 /// @see fill
1492 uint32_t getRouterCount() const;
1493 /// Access a router assignment element.
1494 RouterAssignElt &routerElt(int idx ///< Index of target element.
1495 );
1496 /// Get cache count field.
1497 /// @note No @c setf method because this cannot be changed independently.
1498 /// @see fill
1499 uint32_t getCacheCount() const;
1500 /// Get a cache address.
1501 uint32_t getCacheAddr(int idx ///< Index of target address.
1502 ) const;
1503 /// Set a cache address.
1504 self &setCacheAddr(int idx, ///< Index of target address.
1505 uint32_t addr ///< Address value to set.
1506 );
1507 /// Access a bucket.
1508 Bucket &bucket(int idx ///< Index of target bucket.
1509 );
1510 /// Access a bucket.
1511 Bucket const &bucket(int idx ///< Index of target bucket.
1512 ) const;
1513 //@}
1514
1515 /// Fill out the component from an @c Assignment.
1516 self &fill(MsgBuffer &buffer, ///< Target storage.
1517 detail::Assignment const &assign ///< Assignment data.
1518 );
1519
1520 /// Validate an existing structure.
1521 /// @return Parse result.
1522 int parse(MsgBuffer &buffer);
1523
1524 /// Compute the total size of the component.
1525 static size_t calcSize(int n_routers, ///< Number of routers in view.
1526 int n_caches ///< Number of caches in view.
1527 );
1528
1529 protected:
1530 /// Serialized count of cache addresses.
1531 /// The actual addresses start immediate after this.
1532 uint32_t *m_cache_count;
1533 /// Serialized bucket data.
1534 Bucket *m_buckets;
1535 /// Calculate the address of the cache count.
1536 uint32_t *calcCacheCountPtr();
1537 /// Calculate the address of the bucket array.
1538 Bucket *calcBucketPtr();
1539 };
1540
1541 /** Sect 5.6.9: Capabilities Info Component
1542 */
1543 class CapComp : public CompWithHeader<CapComp>
1544 {
1545 public:
1546 typedef CapComp self; ///< Self reference type.
1547 typedef CompWithHeader<self> super; ///< Parent type.
1548
1549 /// Component type ID for this component.
1550 static CompType const COMP_TYPE = CAPABILITY_INFO;
1551
1552 // Not even a stub for this component, just an array of elements.
1553
1554 /// Default constructor.
1555 CapComp();
1556
1557 /// @name Accessors.
1558 //@{
1559 /// Directly access mask value element.
1560 CapabilityElt &elt(int idx ///< Index of target element.
1561 );
1562 CapabilityElt const &elt(int idx ///< Index of target element.
1563 ) const;
1564 /// Get the element count.
1565 /// @note No corresponding @c setf_ because that cannot be changed once set.
1566 /// @see fill
1567 uint32_t getEltCount() const;
1568 //@}
1569
1570 /** Write serialization data.
1571
1572 The capability elements must be filled @b after invoking this method.
1573 And, of course, do not fill more than @a n of them.
1574 */
1575 self &fill(MsgBuffer &buffer, ///< Target storage.
1576 int n ///< Number of capabilities.
1577 );
1578
1579 /// Validate an existing structure.
1580 /// @return Parse result.
1581 int parse(MsgBuffer &buffer);
1582
1583 /// Compute the total size of the component.
1584 static size_t calcSize(int n ///< Number of capabilities.
1585 );
1586
1587 /// Find value for Cache Assignment.
1588 ServiceGroup::CacheAssignmentStyle getCacheAssignmentStyle() const;
1589 /// Find value for packet forwarding.
1590 ServiceGroup::PacketStyle getPacketForwardStyle() const;
1591 /// Find value for packet return.
1592 ServiceGroup::PacketStyle getPacketReturnStyle() const;
1593 /// Invalidate cached values.
1594 /// Needed after modifying elements via the @c elt method.
1595 self &invalidate();
1596
1597 protected:
1598 /// Fill the cached values.
1599 void cache() const;
1600
1601 int m_count = 0; ///< # of elements.
1602 /** Whether the style values are valid.
1603 We load all the values on the first request because we have to walk
1604 all the capabilities anyway, and cache them.
1605 */
1606 mutable bool m_cached = false;
1607 /// Style used to forward packets to cache.
1608 mutable ServiceGroup::PacketStyle m_packet_forward = ServiceGroup::PacketStyle::NO_PACKET_STYLE;
1609 /// Style used to return packets to the router.
1610 mutable ServiceGroup::PacketStyle m_packet_return = ServiceGroup::PacketStyle::NO_PACKET_STYLE;
1611 /// Style used to make cache assignments.
1612 mutable ServiceGroup::CacheAssignmentStyle m_cache_assign = ServiceGroup::CacheAssignmentStyle::NO_CACHE_ASSIGN_STYLE;
1613 };
1614
1615 /** Sect 5.6.10: Alternate Assignment Component
1616 This is an abstract base class. It is specialized for each alternate.
1617 */
1618 class AltAssignComp : public CompWithHeader<AltAssignComp>
1619 {
1620 public:
1621 typedef AltAssignComp self; ///< Self reference type.
1622 typedef CompWithHeader<self> super; ///< Parent type.
1623
1624 /// Component type ID for this component.
1625 static CompType const COMP_TYPE = ALT_ASSIGNMENT;
1626 /// Alternate is hash.
1627 static uint16_t const ALT_HASH_ASSIGNMENT = 0;
1628 /// Alternate is mask.
1629 static uint16_t const ALT_MASK_ASSIGNMENT = 1;
1630
1631 /// Component secondary header.
1632 /// @internal Split out because we need to compute its size.
1633 struct local_header_t {
1634 uint16_t m_assign_type; ///< Assignment body type.
1635 uint16_t m_assign_length; ///< Assignment body length.
1636 };
1637 /// Stub of the serialized data.
1638 /// There is more variable sized data that must be handled specially.
1639 struct raw_t : public super::raw_t, public local_header_t {
1640 // These are the same in all current subclasses.
1641 AssignmentKeyElt m_key; ///< Assignment key data.
1642 RouterAssignListElt m_routers; ///< Routers.
1643 };
1644
1645 /// Force virtual destructor.
~AltAssignComp()1646 virtual ~AltAssignComp() {}
1647 /// @name Accessors
1648 //@{
1649 /// Get the assignment type.
1650 uint16_t getAssignType() const;
1651 /// Set the assignment type.
1652 self &setAssignType(uint16_t t ///< Assignment type.
1653 );
1654 /// Get the assignment length.
1655 uint16_t getAssignLength() const;
1656 /// Set the assignment length.
1657 self &setAssignLength(uint16_t length ///< Length in bytes.
1658 );
1659 /// Get router count field.
1660 /// @note No @c setf method because this cannot be changed independently.
1661 /// @see fill
1662 uint32_t getRouterCount() const;
1663 /// Directly access assignment key.
1664 AssignmentKeyElt &keyElt();
1665 /// Directly access assignment key.
1666 AssignmentKeyElt const &keyElt() const;
1667 //@}
1668
1669 /// Fill out the component from an @c Assignment.
1670 virtual self &fill(MsgBuffer &buffer, ///< Target storage.
1671 detail::Assignment const &assign ///< Assignment data.
1672 ) = 0;
1673
1674 /// Validate an existing structure.
1675 /// @return Parse result.
1676 virtual int parse(MsgBuffer &buffer) = 0;
1677
1678 protected:
1679 /// Calculate the first byte past the end of the variable data.
1680 void *calcVarPtr();
1681 };
1682
1683 /** Sect 5.6.10: Alternate Assignment Component
1684 This is the hash based version.
1685 */
1686 class AltHashAssignComp : public AltAssignComp
1687 {
1688 public:
1689 typedef AltHashAssignComp self; ///< Self reference type.
1690 typedef AltAssignComp super; ///< Parent type.
1691
1692 /// @name Accessors
1693 //@{
1694 /// Get cache count field.
1695 /// @note No @c setf method because this cannot be changed independently.
1696 /// @see fill
1697 uint32_t getCacheCount() const;
1698 //@}
1699
1700 /// Force virtual destructor.
~AltHashAssignComp()1701 virtual ~AltHashAssignComp() {}
1702 /// Fill out the component from an @c Assignment.
1703 virtual self &fill(MsgBuffer &buffer, ///< Target storage.
1704 detail::Assignment const &assign ///< Assignment data.
1705 );
1706
1707 /// Validate an existing structure.
1708 /// @return Parse result.
1709 virtual int parse(MsgBuffer &buffer);
1710
1711 /// Compute the total size of the component.
1712 static size_t calcSize(int n_routers, ///< Number of routers in view.
1713 int n_caches ///< Number of caches in view.
1714 );
1715
1716 protected:
1717 /// Serialized count of cache addresses.
1718 /// The actual addresses start immediate after this.
1719 uint32_t *m_cache_count;
1720 /// Calculate the address of the cache count.
1721 uint32_t *calcCacheCountPtr();
1722 };
1723
1724 /** Sect 5.6.10: Alternate Assignment Component
1725 This is the mask based version.
1726 */
1727 class AltMaskAssignComp : public AltAssignComp
1728 {
1729 public:
1730 typedef AltMaskAssignComp self; ///< Self reference type.
1731 typedef AltAssignComp super; ///< Parent type.
1732
1733 /// Force virtual destructor.
~AltMaskAssignComp()1734 virtual ~AltMaskAssignComp() {}
1735 /// Fill out the component from an @c Assignment.
1736 virtual self &fill(MsgBuffer &buffer, ///< Target storage.
1737 detail::Assignment const &assign ///< Assignment data.
1738 );
1739
1740 /// Validate an existing structure.
1741 /// @return Parse result.
1742 virtual int parse(MsgBuffer &buffer);
1743
1744 protected:
1745 MaskAssignElt *m_mask_elt; ///< Address of the mask assign element.
1746 };
1747
1748 /** Sect 5.6.12: Command Info Component
1749 */
1750 class CmdComp : public CompWithHeader<CmdComp>
1751 {
1752 public:
1753 typedef CmdComp self; ///< Self reference type.
1754 typedef CompWithHeader<self> super; ///< Parent type.
1755
1756 /// Component type ID for this component.
1757 static CompType const COMP_TYPE = COMMAND_EXTENSION;
1758
1759 /// Command types.
1760 enum cmd_t {
1761 SHUTDOWN = 1, ///< Cache is shutting down.
1762 SHUTDOWN_RESPONSE = 2 ///< SHUTDOWN ack.
1763 };
1764
1765 /// Serialized data layout.
1766 /// @internal Technically the command data is variable, but all currently
1767 /// defined commands have the same 32 bit data element.
1768 struct raw_t : public super::raw_t {
1769 uint16_t m_cmd; ///< Command type / code.
1770 uint16_t m_cmd_length; ///< Length of command data.
1771 uint32_t m_cmd_data; ///< Command data.
1772 };
1773
1774 /// @name Accessors.
1775 //@{
1776 /// Directly access mask value element.
1777 cmd_t getCmd() const; ///< Get command type.
1778 self &setCmd(cmd_t cmd); ///< Set command type.
1779 uint32_t getCmdData() const; ///< Get command data.
1780 self &setCmdData(uint32_t data); ///< Set command @a data.
1781 //@}
1782
1783 /// Write basic serialization data.
1784 /// Elements must be filled in separately and after invoking this method.
1785 self &fill(MsgBuffer &buffer, ///< Component storage.
1786 cmd_t cmd, ///< Command type.
1787 uint32_t data ///< Command data.
1788 );
1789
1790 /// Validate an existing structure.
1791 /// @return Parse result.
1792 int parse(MsgBuffer &buffer);
1793
1794 /// Compute the total size of the component.
1795 static size_t calcSize();
1796 };
1797
1798 /// Sect 5.6.11: Assignment Map Component
1799 class AssignMapComp : public CompWithHeader<AssignMapComp>
1800 {
1801 public:
1802 typedef AssignMapComp self; ///< Self reference type.
1803 typedef CompWithHeader<self> super; ///< Parent type.
1804
1805 /// Component type ID for this component.
1806 static CompType const COMP_TYPE = ASSIGN_MAP;
1807
1808 /// Serialized layout structure.
1809 /// Not complete, only a stub.
1810 struct raw_t : public super::raw_t {
1811 MaskAssignElt m_assign;
1812 };
1813
1814 /// Default constructor.
1815 AssignMapComp();
1816
1817 /// @name Accessors.
1818 //@{
1819 /// Get the element count.
1820 uint32_t getCount() const;
1821 //@}
1822
1823 /// Fill from assignment data.
1824 self &fill(MsgBuffer &buffer, ///< Component storage.
1825 detail::Assignment const &assign ///< Assignment data.
1826 );
1827
1828 /// Validate an existing structure.
1829 /// @return Parse result.
1830 int parse(MsgBuffer &buffer);
1831 };
1832
1833 /// Sect 5.6.8: Router Query Info Component.
1834 class QueryComp : public CompWithHeader<QueryComp>
1835 {
1836 public:
1837 typedef QueryComp self; ///< Self reference type.
1838 typedef CompWithHeader<self> super; ///< Parent type.
1839
1840 /// Component type ID for this component.
1841 static CompType const COMP_TYPE = QUERY_INFO;
1842
1843 /// Internal layout.
1844 struct raw_t : public super::raw_t {
1845 uint32_t m_router_addr; ///< Identifying router address.
1846 uint32_t m_recv_id; ///< Receive ID router expects in reply.
1847 uint32_t m_to_addr; ///< Destination address of query.
1848 uint32_t m_cache_addr; ///< Identifying address of cache.
1849 };
1850
1851 /// @name Accessors.
1852 //@{
1853 /// Directly access mask value element.
1854 uint32_t getRouterAddr() const; ///< Get identifying router address.
1855 self &setRouterAddr(uint32_t addr); ///< Set identifying router address.
1856 uint32_t getToAddr() const; ///< Get target address.
1857 self &setToAddr(uint32_t addr); ///< Set target address.
1858 uint32_t getCacheAddr() const; ///< Get identifying cache address.
1859 self &setCacheAddr(uint32_t addr); ///< Set identifying cache address.
1860 uint32_t getRecvId() const; ///< Get receive ID.
1861 self &setRecvId(uint32_t data); ///< Set receive ID.
1862 //@}
1863
1864 /// Write serialization data.
1865 /// This fills in all fields.
1866 self &fill(MsgBuffer &buffer, ///< Component storage.
1867 uint32_t routerAddr, ///< Router identifying address.
1868 uint32_t toAddr, ///< Destination address.
1869 uint32_t cacheAddr, ///< Cache identifying address.
1870 uint32_t recvId ///< Receive ID.
1871 );
1872
1873 /// Validate an existing structure.
1874 /// @return Parse result.
1875 int parse(MsgBuffer &buffer);
1876
1877 /// Compute the total size of the component.
1878 static size_t calcSize();
1879 };
1880
1881 /// Cache assignment hash function.
1882 inline uint8_t
assignment_hash(uint32_t key)1883 assignment_hash(uint32_t key ///< Key to hash.
1884 )
1885 {
1886 key ^= key >> 16;
1887 key ^= key >> 8;
1888 return key & 0xFF;
1889 }
1890
1891 /// IP header information for a receive message.
1892 struct IpHeader {
1893 uint32_t m_src; ///< Source address.
1894 uint32_t m_dst; ///< Destination address.
1895 };
1896
1897 // Various static values.
1898 const char *const BUFFER_TOO_SMALL_FOR_COMP_TEXT = "Unable to write component -- buffer too small";
1899
1900 // ------------------------------------------------------
1901 namespace detail
1902 {
1903 /** Local storage for cache assignment data.
1904 The maintenance of this data is sufficiently complex that it is better
1905 to have a standard class to hold it, rather than updating a serialized
1906 form.
1907 */
1908 class Assignment
1909 {
1910 public:
1911 typedef Assignment self; ///< Self reference type.
1912 typedef AssignmentKeyElt Key; ///< Import assignment key type.
1913 /// Import assignment bucket definition.
1914 /// @internal Just one byte, no serialization issues.
1915 typedef AssignInfoComp::Bucket Bucket;
1916
1917 /// Default constructor. Initialization to empty state.
1918 Assignment();
1919
1920 /** Check for active assignment.
1921
1922 An assignment is active if it is is current. This means either it
1923 was successfully generated on the cache side, or a valid assignment
1924 was received on the router side and has not expired.
1925
1926 @return The current active state.
1927 */
1928 bool isActive() const;
1929 /// Control active flag.
1930 self &setActive(bool state ///< New active state.
1931 );
1932
1933 /** Fill the assignment from cache service group data.
1934 Caches that are obsolete are purged from the data.
1935 @return @c true if a valid assignment was generated,
1936 @c false otherwise.
1937 */
1938 bool fill(cache::GroupData &group, ///< Service group data.
1939 uint32_t addr ///< Identifying IP address of designated cache.
1940 );
1941 /// Update the receive ID for a router.
1942 self &updateRouterId(uint32_t addr, ///< Identifying IP address of router.
1943 uint32_t rcvid, ///< New receive ID.
1944 uint32_t cno ///< New change number.
1945 );
1946
1947 /// Get the assignment key.
1948 AssignmentKeyElt const &getKey() const;
1949 /// Get the router assignment list.
1950 RouterAssignListElt const &getRouterList() const;
1951 /// Get the hash assignment.
1952 HashAssignElt const &getHash() const;
1953 /// Get the mask assignment.
1954 MaskAssignElt const &getMask() const;
1955
1956 protected:
1957 Key m_key; ///< Assignment key.
1958 bool m_active; ///< Active state.
1959
1960 // These store the serialized assignment chunks which are assembled
1961 // in to the components as needed. Each points in to the serialization
1962 // buffer, or is @c NULL if that assignment data isn't valid.
1963 /// Router assignments.
1964 RouterAssignListElt *m_router_list;
1965 /// Hash assignment.
1966 HashAssignElt *m_hash_assign;
1967 /// Mask assignment.
1968 MaskAssignElt *m_mask_assign;
1969
1970 /// Buffer for serialization.
1971 MsgBuffer m_buffer;
1972 };
1973
1974 namespace endpoint
1975 {
1976 /// Common service group data.
1977 struct GroupData {
1978 typedef GroupData self; ///< Self reference type.
1979
1980 ServiceGroup m_svc; ///< The service definition.
1981 uint32_t m_generation = 0; ///< Generation value (change number).
1982 time_t m_generation_time = 0; ///< Time of last view change.
1983
1984 bool m_use_security_opt = false; ///< Use group local security.
1985 SecurityComp::Option m_security_opt = SECURITY_NONE; ///< Type of security.
1986 bool m_use_security_key = false; ///< Use group local key.
1987 SecurityComp::Key m_security_key; ///< MD5 key.
1988
1989 /** Group assignment data.
1990 This is used as a place to generate an assignment or
1991 store one received from an extern source.
1992 */
1993 detail::Assignment m_assign_info;
1994
1995 /// Default constructor.
1996 GroupData() = default;
1997 /// Use @a key instead of global default.
1998 self &setKey(const char *key ///< Shared key.
1999 );
2000 /// Use security @a style instead of global default.
2001 self &setSecurity(SecurityOption style ///< Security style to use.
2002 );
2003 };
2004 } // namespace endpoint
2005 } // namespace detail
2006 // ------------------------------------------------------
2007 /** Base class for all messages.
2008 */
2009 class BaseMsg
2010 {
2011 public:
2012 /// Default constructor.
2013 BaseMsg();
2014 /// Destructor.
~BaseMsg()2015 virtual ~BaseMsg() {}
2016 /// Set the message @a buffer.
2017 void setBuffer(MsgBuffer const &buffer ///< Storage for message.
2018 );
2019 /// Get the current buffer.
2020 MsgBuffer const &buffer() const;
2021 /// Invoke once all components have been filled.
2022 /// Sets the length and updates security data if needed.
2023 virtual void finalize();
2024 /// Get available buffer space.
2025 size_t getSpace() const;
2026 /// Get the message size.
2027 size_t getCount() const;
2028
2029 /// Validate security option.
2030 /// @note This presumes a subclass has already successfully parsed.
2031 bool validateSecurity() const;
2032
2033 // Common starting components for all messages.
2034 MsgHeaderComp m_header; ///< Message header.
2035 SecurityComp m_security; ///< Security component.
2036 ServiceComp m_service; ///< Service provided.
2037
2038 protected:
2039 MsgBuffer m_buffer; ///< Raw storage for message data.
2040 };
2041
2042 /// Sect 5.1: Layout and control for @c WCCP2_HERE_I_AM
2043 class HereIAmMsg : public BaseMsg
2044 {
2045 public:
2046 typedef HereIAmMsg self; ///< Self reference type.
2047
2048 /** Fill in the basic message structure.
2049 This expects @c setBuffer to have already been called
2050 with an appropriate buffer.
2051 The actual router and cache data must be filled in
2052 after this call, which will allocate the appropriate spaces
2053 in the message layou.
2054 */
2055 void fill(detail::cache::GroupData const &group, ///< Service group for message.
2056 CacheIdBox const &cache_id, ///< ID to use for this cache.
2057 SecurityOption sec_opt ///< Security option to use.
2058 );
2059 /** Fill in optional capabilities.
2060 The capabilities component is added only if the @a router
2061 is set to send them.
2062 */
2063 void fill_caps(detail::cache::RouterData const &router ///< Target router.
2064 );
2065 /// Parse message data, presumed to be of this type.
2066 int parse(ts::Buffer const &buffer ///< Raw message data.
2067 );
2068
2069 CacheIdComp m_cache_id; ///< Web cache identity info.
2070 CacheViewComp m_cache_view; ///< Web cache view.
2071 CapComp m_capabilities; ///< Capabilities data.
2072 CmdComp m_command; ///< Command extension.
2073 };
2074
2075 /// Sect 5.2: 'I See You' Message
2076 class ISeeYouMsg : public BaseMsg
2077 {
2078 public:
2079 typedef ISeeYouMsg self; ///< Self reference type.
2080
2081 /// Fill out message structure.
2082 /// Router ID and view data must be filled in separately.
2083 void fill(detail::router::GroupData const &group, ///< Service groupc context.
2084 SecurityOption sec_opt, ///< Security option.
2085 detail::Assignment &assign, ///< Cache assignment data.
2086 size_t to_caches, ///< # of target caches for message.
2087 size_t n_routers, ///< Routers in view.
2088 size_t n_caches, ///< Caches in view.
2089 bool send_capabilities = false ///< Send capabilities.
2090 );
2091
2092 /// Parse message data, presumed to be of this type.
2093 int parse(ts::Buffer const &buffer ///< Raw message data.
2094 );
2095
2096 RouterIdComp m_router_id; ///< Router ID.
2097 RouterViewComp m_router_view; ///< Router view data.
2098 // The rest of these are optional. The spec says we should get
2099 // an assignment or map, but in practice that doesn't happen with
2100 // actual Cisco routers in the hash case. Perhaps it happens with
2101 // a map.
2102 AssignInfoComp m_assignment; ///< Assignment data.
2103 AssignMapComp m_map; ///< Assignment map.
2104 CapComp m_capabilities; ///< Capabilities data.
2105 CmdComp m_command; ///< Command extension.
2106 };
2107
2108 /// Sect 5.1: Layout and control for @c WCCP2_REDIRECT_ASSIGN
2109 class RedirectAssignMsg : public BaseMsg
2110 {
2111 public:
2112 typedef RedirectAssignMsg self; ///< Self reference type.
2113
2114 /** Fill in the basic message structure.
2115 This expects @c setBuffer to have already been called
2116 with an appropriate buffer.
2117 The actual router and cache data must be filled in
2118 after this call, which will allocate the appropriate spaces
2119 in the message layou.
2120 */
2121 void fill(detail::cache::GroupData const &group, ///< Service group for message.
2122 SecurityOption sec_opt ///< Security option to use.
2123 );
2124
2125 /// Parse message data, presumed to be of this type.
2126 int parse(ts::Buffer const &buffer ///< Raw message data.
2127 );
2128
2129 // Only one of these should be present in an instance.
2130 AssignInfoComp m_hash_assign; ///< Primary (hash) assignment.
2131 AltHashAssignComp m_alt_hash_assign; ///< Alternate (hash) assignment.
2132 AltMaskAssignComp m_alt_mask_assign; ///< Alternate (mask) assignment.
2133 };
2134
2135 /// Sect 5.4: @c WCCP_REMOVAL_QUERY
2136 class RemovalQueryMsg : public BaseMsg
2137 {
2138 public:
2139 typedef RemovalQueryMsg self; ///< Self reference type.
2140
2141 /** Fill in the basic message structure.
2142 This expects @c setBuffer to have already been called
2143 with an appropriate buffer.
2144 The actual router and cache data must be filled in
2145 after this call, which will allocate the appropriate spaces
2146 in the message layou.
2147 */
2148 void fill(detail::cache::GroupData const &group, ///< Service group for message.
2149 SecurityOption sec_opt, ///< Security option to use.
2150 AssignmentKeyElt const &key, ///< Assignment key.
2151 int n_routers, ///< Number of routers expected.
2152 int n_caches ///< Number of caches expected.
2153 );
2154
2155 /// Parse message data, presumed to be of this type.
2156 int parse(ts::Buffer const &buffer ///< Raw message data.
2157 );
2158
2159 QueryComp m_query; ///< Router Removal Query component.
2160 };
2161
2162 // ------------------------------------------------------
2163 /// Last packet information.
2164 struct PacketStamp {
2165 typedef PacketStamp self; ///< Self reference type.
2166
2167 PacketStamp(); ///< Default constructor (zero elements).
2168 /// Set the @a time and @a generation.
2169 self &set(time_t time, uint32_t generation);
2170
2171 time_t m_time; ///< Time when packet was sent/received.
2172 uint32_t m_sn; ///< Sequence # of packet.
2173 };
2174
2175 /** Implementation class for EndPoint.
2176 All of the WCCP structures are defined in this class.
2177
2178 A note on the component classes - these are designed to reside in
2179 a side buffer which then points in to the actual message
2180 buffer. This is done because the WCCP designers were not too
2181 bright. Rather than packing the fixed sized elements in front and
2182 using offsets to point at variables sized data, it's intermixed,
2183 so it's not possible to declare C++ structures that map on to the
2184 actual message data in all cases. And because mixed styles are
2185 worse than a consistent mediocre style, we go with the latter and
2186 put all the message structures on the side. This also means having
2187 to use accessor methods.
2188 */
2189 class Impl : public ts::IntrusivePtrCounter
2190 {
2191 friend class EndPoint;
2192
2193 public:
2194 typedef Impl self; ///< Self reference type.
2195
2196 /// Import detail struct.
2197 typedef detail::endpoint::GroupData GroupData;
2198
2199 /// Default constructor.
2200 Impl() = default;
2201 /** Set the local address used for this endpoint.
2202 If not set, an arbitrary local address will be
2203 @note This can only be called once, and must be called before
2204 @c open.
2205 */
2206 /// Force virtual destructor.
2207 virtual ~Impl();
2208
2209 /// Open a socket for communications.
2210 /// @return 0 on success, -ERRNO on failure.
2211 virtual int open(uint32_t addr ///< Local IP address.
2212 );
2213
2214 /// Use MD5 security.
2215 void useMD5Security(std::string_view const key ///< Shared key.
2216 );
2217
2218 /// Perform all scheduled housekeeping functions.
2219 /// @return 0 for success, -errno on error.
2220 virtual int housekeeping() = 0;
2221
2222 /// Receive and process a message.
2223 /// @return 0 for success, -ERRNO on system error.
2224 virtual ts::Rv<int> handleMessage();
2225
2226 /// Check if endpoint is configured.
2227 /// @return @c true if ready to operate, @c false otherwise.
2228 virtual bool isConfigured() const = 0;
2229
2230 /* These handlers simply generate an error message and return. The
2231 base @c handleMessage will read the data from the socket and
2232 validate the message header. It then calls the appropriate one of
2233 these specialized message handlers. Subclasses should override
2234 to process relevant messages.
2235 */
2236 /// Process HERE_I_AM message.
2237 virtual ts::Errata handleHereIAm(IpHeader const &header, ///< IP packet data.
2238 ts::Buffer const &data ///< Buffer with message data.
2239 );
2240 /// Process I_SEE_YOU message.
2241 virtual ts::Errata handleISeeYou(IpHeader const &header, ///< IP packet data.
2242 ts::Buffer const &data ///< Buffer with message data.
2243 );
2244 /// Process REDIRECT_ASSIGN message.
2245 virtual ts::Errata handleRedirectAssign(IpHeader const &header, ///< IP packet data.
2246 ts::Buffer const &data ///< Buffer with message data.
2247 );
2248 /// Process REMOVAL_QUERY message.
2249 virtual ts::Errata handleRemovalQuery(IpHeader const &header, ///< IP packet data.
2250 ts::Buffer const &data ///< Buffer with message data.
2251 );
2252
2253 protected:
2254 /** Local address for this end point.
2255 This is set only when the socket is open.
2256 */
2257 uint32_t m_addr = INADDR_ANY;
2258 int m_fd = ts::NO_FD; ///< Our socket.
2259
2260 bool m_use_security_opt = false; ///< Use group local security.
2261 SecurityComp::Option m_security_opt = SECURITY_NONE; ///< Type of security.
2262 bool m_use_security_key = false; ///< Use group local key.
2263 SecurityComp::Key m_security_key; ///< MD5 key.
2264
2265 /// Close the socket.
2266 void close();
2267 /// Set security options in a message.
2268 /// @return Security option to use during message fill.
2269 SecurityOption setSecurity(BaseMsg &msg, ///< Message.
2270 GroupData const &group ///< Group data used to control fill.
2271 ) const;
2272 /// Validate a security component.
2273 bool validateSecurity(BaseMsg &msg, ///< Message data (including security component).
2274 GroupData const &group ///< Group data for message.
2275 );
2276 };
2277 // ------------------------------------------------------
2278 namespace detail
2279 {
2280 namespace cache
2281 {
2282 /// Caches's view of caches.
2283 struct CacheData {
2284 /// Get the identifying IP address for this cache.
2285 uint32_t idAddr() const;
2286 /// Cache identity data.
2287 CacheIdBox m_id;
2288 /// Last time this cache was mentioned by the routers.
2289 /// Indexed in parallel to the routers.
2290 std::vector<PacketStamp> m_src;
2291 };
2292
2293 /// Cache's view of routers.
2294 struct RouterData {
2295 /// Default constructor, no member initialization.
2296 RouterData();
2297 /// Construct with address.
2298 RouterData(uint32_t addr ///< Router identifying address.
2299 );
2300
2301 /// Time until next packet.
2302 /// @return Seconds until a packet should be sent.
2303 time_t waitTime(time_t now ///< Current time.
2304 ) const;
2305 /// Time till next ping.
2306 /// @return Seconds until a HERE_I_AM should be sent.
2307 time_t pingTime(time_t now ///< Current time.
2308 ) const;
2309
2310 uint32_t m_addr; ///< Router identifying IP address.
2311 uint32_t m_generation; ///< Router's view change number.
2312 /** Most recent packet received from router.
2313 * The sequence number @a m_sn is the receive ID of the router.
2314 */
2315 PacketStamp m_recv;
2316 /** Most recent packet sent to router.
2317 * The sequence number @a m_sn is the view generation of this cache.
2318 */
2319 PacketStamp m_xmit;
2320 /// Cache ID of this cache as reflected by this router.
2321 CacheIdBox m_local_cache_id;
2322 int m_rapid; ///< Rapid replies to send.
2323 bool m_assign; ///< Send a REDIRECT_ASSIGN.
2324 bool m_send_caps; ///< Send capabilities.
2325 /// Packet forwarding method selected.
2326 ServiceGroup::PacketStyle m_packet_forward = ServiceConstants::NO_PACKET_STYLE;
2327 /// Packet return method selected.
2328 ServiceGroup::PacketStyle m_packet_return = ServiceConstants::NO_PACKET_STYLE;
2329 /// Cache assignment method selected.
2330 ServiceGroup::CacheAssignmentStyle m_cache_assign = ServiceConstants::NO_CACHE_ASSIGN_STYLE;
2331 };
2332
2333 /// Data for a seeded router.
2334 struct SeedRouter {
2335 SeedRouter(); ///< Default constructor, no member initialization.
2336 /// Construct with address @a addr.
2337 /// Other members are zero initialized.
2338 SeedRouter(uint32_t addr);
2339 uint32_t m_addr; ///< Address of router.
2340 uint32_t m_count; ///< # of packets sent w/o response.
2341 time_t m_xmit; ///< Time of last packet sent.
2342 };
2343
2344 /// Storage type for known caches.
2345 typedef std::vector<CacheData> CacheBag;
2346 /// Storage type for known routers.
2347 typedef std::vector<RouterData> RouterBag;
2348
2349 /** Cache's view of a service group.
2350 This stores the internal accounting information, it is not the
2351 serialized form.
2352 */
2353 struct GroupData : public endpoint::GroupData {
2354 typedef GroupData self; ///< Self reference type.
2355 typedef endpoint::GroupData super; ///< Parent type.
2356
2357 /// Cache identity of this cache.
2358 CacheIdBox m_id;
2359
2360 /// Packet forwarding methods supported.
2361 ServiceGroup::PacketStyle m_packet_forward = ServiceConstants::NO_PACKET_STYLE;
2362 /// Packet return methods supported.
2363 ServiceGroup::PacketStyle m_packet_return = ServiceConstants::NO_PACKET_STYLE;
2364 /// Cache assignment methods supported.
2365 ServiceGroup::CacheAssignmentStyle m_cache_assign = ServiceConstants::NO_CACHE_ASSIGN_STYLE;
2366
2367 /// Known caches.
2368 CacheBag m_caches;
2369 /// Known routers.
2370 RouterBag m_routers;
2371 char *m_proc_name;
2372
2373 /// Set if there an assignment should be computed and sent.
2374 /// This is before checking for being a designated cache
2375 /// (that check is part of the assignment generation).
2376 bool m_assignment_pending;
2377
2378 /// Seed routers.
2379 std::vector<SeedRouter> m_seed_routers;
2380
2381 GroupData(); ///< Default constructor.
2382
2383 void setProcName(const std::string_view name);
2384 const char *getProcName();
2385
2386 /// Find a router by IP @a addr.
2387 /// @return A pointer to the router, or @c NULL if not found.
2388 RouterBag::iterator findRouter(uint32_t addr ///< IP address of cache.
2389 );
2390
2391 /// Set an initial router for a service group.
2392 self &seedRouter(uint32_t addr ///< IP address for router.
2393 );
2394 /// Remove a seed router.
2395 /// @return The last time a packet was sent to the router.
2396 time_t removeSeedRouter(uint32_t addr ///< Identifying router address.
2397 );
2398
2399 /// Find a cache by IP @a addr.
2400 /// @return An iterator to the cache, or @c NULL if not found.
2401 CacheBag::iterator findCache(uint32_t addr ///< IP address of cache.
2402 );
2403 /// Adjust packet stamp vectors to track routers.
2404 void resizeCacheSources();
2405
2406 /// Time until next event.
2407 /// @return The number of seconds until the next event of interest.
2408 time_t waitTime(time_t now ///< Current time.
2409 ) const;
2410
2411 /** Cull routers.
2412 Routers that have not replied recently are moved from the
2413 active router list to the seed router list.
2414
2415 @return @c true if any routers were culled, @c false otherwise.
2416 */
2417 bool cullRouters(time_t now ///< Current time.
2418 );
2419
2420 /** Check to see if the process associated with service is up
2421 */
2422 bool processUp();
2423
2424 /// Update state to reflect a view change.
2425 self &viewChanged(time_t now);
2426
2427 /// Use @a key instead of global default.
2428 self &setKey(const char *key ///< Shared key.
2429 );
2430 /// Use security @a style instead of global default.
2431 self &setSecurity(SecurityOption style ///< Security style to use.
2432 );
2433 };
2434 inline const char *
getProcName()2435 GroupData::getProcName()
2436 {
2437 return m_proc_name;
2438 }
2439 inline void
setProcName(const std::string_view name)2440 GroupData::setProcName(const std::string_view name)
2441 {
2442 m_proc_name = ats_strndup(name.data(), name.size());
2443 }
2444 } // namespace cache
2445 } // namespace detail
2446
2447 /** Implementation class for Cache Endpoint.
2448 */
2449 class CacheImpl : public Impl
2450 {
2451 public:
2452 typedef CacheImpl self; ///< Self reference type.
2453 typedef Impl super; ///< Parent type.
2454
2455 // Import details
2456 typedef detail::cache::SeedRouter SeedRouter;
2457 typedef detail::cache::CacheData CacheData;
2458 typedef detail::cache::RouterData RouterData;
2459 typedef detail::cache::GroupData GroupData;
2460 typedef detail::cache::CacheBag CacheBag;
2461 typedef detail::cache::RouterBag RouterBag;
2462
2463 /** Define a service group.
2464 If no service is defined for the ID in @a svc, it is created.
2465 If @a result is not @c NULL then it is set to
2466 - @c ServiceGroup::DEFINED if the service was created.
2467 - @c ServiceGroup::EXISTS if the service matches the existing service.
2468 - @c ServiceGroup::CONFLICT if the service doesn't match the existing service.
2469
2470 @return The data for the service group.
2471 */
2472 virtual GroupData &defineServiceGroup(ServiceGroup const &svc, ///< [in] Service to define.
2473 ServiceGroup::Result *result = 0 ///< [out] Result for service creation.
2474 );
2475
2476 /** Set an initial router for a service group.
2477 This is needed to bootstrap the protocol.
2478 If the router is already seeded, this call is silently ignored.
2479 */
2480 self &seedRouter(uint8_t id, ///< Service group ID.
2481 uint32_t addr ///< IP address for router.
2482 );
2483
2484 /// Define services from a configuration file.
2485 ts::Errata loadServicesFromFile(const char *path ///< Path to file.
2486 );
2487
2488 /// Override.
2489 int open(uint32_t addr);
2490
2491 /// Time until next scheduled event.
2492 time_t waitTime() const;
2493
2494 /// Check for configuration.
2495 bool isConfigured() const;
2496
2497 /// Perform all scheduled housekeeping functions.
2498 /// @return 0 for success, -errno on error.
2499 virtual int housekeeping();
2500
2501 /** Check cache assignment reported by a router against internal assign.
2502 @return @c true if they are the same, @c false otherwise.
2503 */
2504 virtual ts::Errata checkRouterAssignment(GroupData const &group, ///< Group with assignment.
2505 RouterViewComp const &comp ///< Assignment reported by router.
2506 ) const;
2507
2508 protected:
2509 /// Generate contents in HERE_I_AM @a msg for seed router.
2510 void generateHereIAm(HereIAmMsg &msg, ///< Message with allocated buffer.
2511 GroupData &group ///< Group with data for message.
2512 );
2513 /// Generate contents in HERE_I_AM @a msg for active @a router.
2514 void generateHereIAm(HereIAmMsg &msg, ///< Message with allocated buffer.
2515 GroupData &group, ///< Group with data for message.
2516 RouterData &router ///< Target router.
2517 );
2518 /// Generate contents in REDIRECT_ASSIGN @a msg for a service @a group.
2519 void generateRedirectAssign(RedirectAssignMsg &msg, ///< Message with allocated buffer.
2520 GroupData &group ///< Group with data for message.
2521 );
2522 /// Process HERE_I_AM message.
2523 virtual ts::Errata handleISeeYou(IpHeader const &header, ///< IP packet data.
2524 ts::Buffer const &data ///< Buffer with message data.
2525 );
2526 /// Process REMOVAL_QUERY message.
2527 virtual ts::Errata handleRemovalQuery(IpHeader const &header, ///< IP packet data.
2528 ts::Buffer const &data ///< Message data.
2529 );
2530
2531 /// Map Service Group ID to Service Group Data.
2532 typedef std::map<uint8_t, GroupData> GroupMap;
2533 /// Active service groups.
2534 GroupMap m_groups;
2535
2536 private:
2537 ts::Errata loader(const YAML::Node &node);
2538 };
2539
2540 // ------------------------------------------------------
2541 namespace detail
2542 {
2543 namespace router
2544 {
2545 /** Router's view of a cache.
2546 @a m_count tracks the number of packets received from this particular
2547 cache. The RFC is unclear but it looks like this should be tracked
2548 independently for each target address (which can be different than
2549 caches if multicasting). A response is pending if @a m_count is
2550 different than @ m_xmit.m_gen which is the received count last time
2551 this router sent this cache a response.
2552 */
2553 struct CacheData {
2554 /// Get the identifying IP address for this cache.
2555 uint32_t idAddr() const;
2556
2557 /// Received count for this cache.
2558 uint32_t m_recv_count;
2559 /// Change number of last received message.
2560 uint32_t m_generation;
2561 /// Need to send a response to this cache.
2562 bool m_pending;
2563 /// Address used by cache to send to this router.
2564 uint32_t m_to_addr;
2565 /// Stamp for last pack transmitted to this cache.
2566 PacketStamp m_xmit;
2567 //// Stamp for last packet received from this cache.
2568 PacketStamp m_recv;
2569
2570 CacheIdBox m_id; ///< Transmitted cache descriptor.
2571 uint32_t m_target_addr; ///< Target address of last packet.
2572 };
2573
2574 /// Router's view of other routers.
2575 struct RouterData {
2576 typedef RouterData self; ///< Self reference type.
2577
2578 /// Identifying IP address of router.
2579 uint32_t m_addr;
2580 /** Stamp for last mention of this router from a cache.
2581 Indexed in parallel with the Caches.
2582 The sequence number @a m_sn is the cache's change #.
2583 */
2584 std::vector<PacketStamp> m_src;
2585 /// Resize the packet stamp vector.
2586 self &resize(size_t);
2587 };
2588
2589 /// Storage type for known caches.
2590 typedef std::vector<CacheData> CacheBag;
2591 /// Storage type for known routers.
2592 typedef std::vector<RouterData> RouterBag;
2593
2594 /** A router's view of a service group.
2595
2596 This stores the internal accounting information, it is not the
2597 serialized form.
2598 */
2599 struct GroupData : public detail::endpoint::GroupData {
2600 typedef GroupData self; ///< Self reference type.
2601 typedef detail::endpoint::GroupData super; ///< Parent type.
2602
2603 GroupData(); ///< Default constructor.
2604
2605 /// Known caches.
2606 CacheBag m_caches;
2607 /// Known (other) routers.
2608 RouterBag m_routers;
2609
2610 /// Find a cache by IP @a addr.
2611 /// @return An iterator to the cache, or @c NULL if not found.
2612 CacheBag::iterator findCache(uint32_t addr ///< IP address of cache.
2613 );
2614 /// Adjust packet stamp vectors to track caches.
2615 void resizeRouterSources();
2616 };
2617 } // namespace router
2618 } // namespace detail
2619
2620 /** Implementation class for Router Endpoint.
2621 */
2622 class RouterImpl : public Impl
2623 {
2624 public:
2625 typedef RouterImpl self; ///< Self reference type.
2626 typedef Impl super; ///< Parent type.
2627 // Import details
2628 typedef detail::router::CacheData CacheData;
2629 typedef detail::router::RouterData RouterData;
2630 typedef detail::router::GroupData GroupData;
2631 typedef detail::router::CacheBag CacheBag;
2632 typedef detail::router::RouterBag RouterBag;
2633
2634 /// Process HERE_I_AM message.
2635 virtual ts::Errata handleHereIAm(IpHeader const &header, ///< IP packet data.
2636 ts::Buffer const &data ///< Buffer with message data.
2637 );
2638 /// Perform all scheduled housekeeping functions.
2639 int housekeeping();
2640 /// Send pending I_SEE_YOU messages.
2641 int xmitISeeYou();
2642 /// Check for configuration.
2643 bool isConfigured() const;
2644
2645 protected:
2646 /** Find or create a service group record.
2647 If no service is defined for the ID, it is created.
2648 If @a result is not @c NULL then it is set to
2649 - @c ServiceGroup::DEFINED if the service was created.
2650 - @c ServiceGroup::EXISTS if the service matches the existing service.
2651 - @c ServiceGroup::CONFLICT if the service doesn't match the existing service.
2652
2653 @return The data for the service group.
2654 */
2655 GroupData &defineServiceGroup(ServiceGroup const &svc, ServiceGroup::Result *result);
2656 /// Fill out message data.
2657 void generateISeeYou(ISeeYouMsg &msg, ///< Message structure to fill.
2658 GroupData &group, ///< Group data for message.
2659 CacheData &cache ///< Target cache.
2660 );
2661
2662 /// Map Service Group ID to Service Group Data.
2663 typedef std::map<uint8_t, GroupData> GroupMap;
2664 /// Active service groups.
2665 GroupMap m_groups;
2666 };
2667 // ------------------------------------------------------
RouterId()2668 inline RouterId::RouterId() : m_addr(0), m_recv_id(0) {}
RouterId(uint32_t addr,uint32_t recv_id)2669 inline RouterId::RouterId(uint32_t addr, uint32_t recv_id) : m_addr(addr), m_recv_id(recv_id) {}
2670
RouterIdElt(uint32_t addr,uint32_t recv_id)2671 inline RouterIdElt::RouterIdElt(uint32_t addr, uint32_t recv_id) : super(addr, htonl(recv_id)) {}
2672 inline uint32_t
getAddr()2673 RouterIdElt::getAddr() const
2674 {
2675 return m_addr;
2676 }
2677 inline RouterIdElt &
setAddr(uint32_t addr)2678 RouterIdElt::setAddr(uint32_t addr)
2679 {
2680 m_addr = addr;
2681 return *this;
2682 }
2683 inline uint32_t
getRecvId()2684 RouterIdElt::getRecvId() const
2685 {
2686 return ntohl(m_recv_id);
2687 }
2688 inline RouterIdElt &
setRecvId(uint32_t recv_id)2689 RouterIdElt::setRecvId(uint32_t recv_id)
2690 {
2691 m_recv_id = htonl(recv_id);
2692 return *this;
2693 }
2694 inline RouterIdElt &
2695 RouterIdElt::operator=(super const &that)
2696 {
2697 return this->setAddr(that.m_addr).setRecvId(that.m_recv_id);
2698 }
2699
MaskElt()2700 inline MaskElt::MaskElt() {}
2701
MaskElt(uint32_t srcAddr,uint32_t dstAddr,uint16_t srcPort,uint16_t dstPort)2702 inline MaskElt::MaskElt(uint32_t srcAddr, uint32_t dstAddr, uint16_t srcPort, uint16_t dstPort)
2703 : m_src_addr(srcAddr), m_dst_addr(dstAddr), m_src_port(srcPort), m_dst_port(dstPort)
2704 {
2705 }
2706
2707 inline uint32_t
getSrcAddr()2708 MaskElt::getSrcAddr() const
2709 {
2710 return ntohl(m_src_addr);
2711 }
2712 inline MaskElt &
setSrcAddr(uint32_t mask)2713 MaskElt::setSrcAddr(uint32_t mask)
2714 {
2715 m_src_addr = htonl(mask);
2716 return *this;
2717 }
2718 inline uint32_t
getDstAddr()2719 MaskElt::getDstAddr() const
2720 {
2721 return ntohl(m_dst_addr);
2722 }
2723 inline MaskElt &
setDstAddr(uint32_t mask)2724 MaskElt::setDstAddr(uint32_t mask)
2725 {
2726 m_dst_addr = htonl(mask);
2727 return *this;
2728 }
2729 inline uint16_t
getSrcPort()2730 MaskElt::getSrcPort() const
2731 {
2732 return ntohs(m_src_port);
2733 }
2734 inline MaskElt &
setSrcPort(uint16_t mask)2735 MaskElt::setSrcPort(uint16_t mask)
2736 {
2737 m_src_port = htons(mask);
2738 return *this;
2739 }
2740 inline uint16_t
getDstPort()2741 MaskElt::getDstPort() const
2742 {
2743 return ntohs(m_dst_port);
2744 }
2745 inline MaskElt &
setDstPort(uint16_t mask)2746 MaskElt::setDstPort(uint16_t mask)
2747 {
2748 m_dst_port = htons(mask);
2749 return *this;
2750 }
2751
ValueElt()2752 inline ValueElt::ValueElt() {}
2753
ValueElt(uint32_t cacheAddr,uint32_t srcAddr,uint32_t dstAddr,uint16_t srcPort,uint16_t dstPort)2754 inline ValueElt::ValueElt(uint32_t cacheAddr, uint32_t srcAddr, uint32_t dstAddr, uint16_t srcPort, uint16_t dstPort)
2755 : m_src_addr(srcAddr), m_dst_addr(dstAddr), m_src_port(srcPort), m_dst_port(dstPort), m_cache_addr(cacheAddr)
2756 {
2757 }
2758
MaskValueSetElt()2759 inline MaskValueSetElt::MaskValueSetElt() {}
MaskValueSetElt(uint32_t count)2760 inline MaskValueSetElt::MaskValueSetElt(uint32_t count) : m_count(count) {}
2761 inline MaskElt &
maskElt()2762 MaskValueSetElt::maskElt()
2763 {
2764 return m_mask;
2765 }
2766 inline uint32_t
getCount()2767 MaskValueSetElt::getCount() const
2768 {
2769 return ntohl(m_count);
2770 }
2771
2772 inline uint32_t
getSrcAddrMask()2773 MaskValueSetElt::getSrcAddrMask() const
2774 {
2775 return m_mask.getSrcAddr();
2776 }
2777 inline MaskValueSetElt &
setSrcAddrMask(uint32_t mask)2778 MaskValueSetElt::setSrcAddrMask(uint32_t mask)
2779 {
2780 m_mask.setSrcAddr(mask);
2781 return *this;
2782 }
2783 inline uint32_t
getDstAddrMask()2784 MaskValueSetElt::getDstAddrMask() const
2785 {
2786 return m_mask.getDstAddr();
2787 }
2788 inline MaskValueSetElt &
setDstAddrMask(uint32_t mask)2789 MaskValueSetElt::setDstAddrMask(uint32_t mask)
2790 {
2791 m_mask.setDstAddr(mask);
2792 return *this;
2793 }
2794 inline uint16_t
getSrcPortMask()2795 MaskValueSetElt::getSrcPortMask() const
2796 {
2797 return m_mask.getSrcPort();
2798 }
2799 inline MaskValueSetElt &
setSrcPortMask(uint16_t mask)2800 MaskValueSetElt::setSrcPortMask(uint16_t mask)
2801 {
2802 m_mask.setSrcPort(mask);
2803 return *this;
2804 }
2805 inline uint16_t
getDstPortMask()2806 MaskValueSetElt::getDstPortMask() const
2807 {
2808 return m_mask.getDstPort();
2809 }
2810 inline MaskValueSetElt &
setDstPortMask(uint16_t mask)2811 MaskValueSetElt::setDstPortMask(uint16_t mask)
2812 {
2813 m_mask.setDstPort(mask);
2814 return *this;
2815 }
2816 inline ValueElt *
values()2817 MaskValueSetElt::values()
2818 {
2819 return reinterpret_cast<ValueElt *>(this + 1);
2820 }
2821 inline ValueElt const *
values()2822 MaskValueSetElt::values() const
2823 {
2824 return const_cast<self *>(this)->values();
2825 }
2826 inline size_t
calcSize(uint32_t n)2827 MaskValueSetElt::calcSize(uint32_t n)
2828 {
2829 return sizeof(self) + n * sizeof(ValueElt);
2830 }
2831 inline size_t
getSize()2832 MaskValueSetElt::getSize() const
2833 {
2834 return self::calcSize(ntohl(m_count));
2835 }
2836
2837 inline size_t
getSize()2838 MaskAssignElt::getSize() const
2839 {
2840 return sizeof(self) + this->getVarSize();
2841 }
2842
2843 inline uint32_t
getAddr()2844 CacheIdElt::getAddr() const
2845 {
2846 return m_addr;
2847 }
2848 inline CacheIdElt &
setAddr(uint32_t addr)2849 CacheIdElt::setAddr(uint32_t addr)
2850 {
2851 m_addr = addr;
2852 return *this;
2853 }
2854 inline uint16_t
getHashRev()2855 CacheIdElt::getHashRev() const
2856 {
2857 return ntohs(m_hash_rev);
2858 }
2859 inline CacheIdElt &
setHashRev(uint16_t addr)2860 CacheIdElt::setHashRev(uint16_t addr)
2861 {
2862 m_hash_rev = htons(addr);
2863 return *this;
2864 }
2865 inline CacheIdElt &
initHashRev()2866 CacheIdElt::initHashRev()
2867 {
2868 this->setHashRev(HASH_REVISION);
2869 return *this;
2870 }
2871 inline bool
getUnassigned()2872 CacheIdElt::getUnassigned() const
2873 {
2874 return 1 == m_unassigned;
2875 }
2876 inline CacheIdElt &
setUnassigned(bool state)2877 CacheIdElt::setUnassigned(bool state)
2878 {
2879 m_unassigned = state ? 1 : 0;
2880 return *this;
2881 }
2882 inline CacheIdElt &
clearReserved()2883 CacheIdElt::clearReserved()
2884 {
2885 m_reserved_0 = 0;
2886 m_reserved_1 = 0;
2887 m_reserved_2 = 0;
2888 return *this;
2889 }
2890 inline bool
isMask()2891 CacheIdElt::isMask() const
2892 {
2893 return 1 == m_is_mask;
2894 }
2895 inline CacheIdElt &
setMask(bool state)2896 CacheIdElt::setMask(bool state)
2897 {
2898 m_is_mask = state ? 1 : 0;
2899 return *this;
2900 }
2901
2902 inline CacheIdElt::Tail *
getTailPtr()2903 CacheHashIdElt::getTailPtr()
2904 {
2905 return &m_tail;
2906 }
2907
2908 inline uint32_t
getCount()2909 CacheMaskIdElt::getCount() const
2910 {
2911 return m_assign.getCount();
2912 }
2913
2914 inline size_t
getSize()2915 CacheMaskIdElt::getSize() const
2916 {
2917 return sizeof(self) + sizeof(Tail) + m_assign.getVarSize();
2918 }
2919
2920 inline CacheIdElt::Tail *
getTailPtr()2921 CacheMaskIdElt::getTailPtr()
2922 {
2923 return reinterpret_cast<Tail *>(reinterpret_cast<char *>(this) + sizeof(self) + m_assign.getVarSize());
2924 }
2925
2926 inline uint32_t
getAddr()2927 CacheIdBox::getAddr() const
2928 {
2929 return m_base->getAddr();
2930 }
2931
2932 inline CacheIdBox &
setAddr(uint32_t addr)2933 CacheIdBox::setAddr(uint32_t addr)
2934 {
2935 m_base->setAddr(addr);
2936 return *this;
2937 }
2938
2939 inline CacheIdBox &
setUnassigned(bool state)2940 CacheIdBox::setUnassigned(bool state)
2941 {
2942 m_base->setUnassigned(state);
2943 return *this;
2944 }
2945
AssignmentKeyElt(uint32_t addr,uint32_t n)2946 inline AssignmentKeyElt::AssignmentKeyElt(uint32_t addr, uint32_t n) : m_addr(addr), m_change_number(htonl(n)) {}
2947 inline uint32_t
getAddr()2948 AssignmentKeyElt::getAddr() const
2949 {
2950 return m_addr;
2951 }
2952 inline AssignmentKeyElt &
setAddr(uint32_t addr)2953 AssignmentKeyElt::setAddr(uint32_t addr)
2954 {
2955 m_addr = addr;
2956 return *this;
2957 }
2958 inline uint32_t
getChangeNumber()2959 AssignmentKeyElt::getChangeNumber() const
2960 {
2961 return ntohl(m_change_number);
2962 }
2963 inline AssignmentKeyElt &
setChangeNumber(uint32_t n)2964 AssignmentKeyElt::setChangeNumber(uint32_t n)
2965 {
2966 m_change_number = htonl(n);
2967 return *this;
2968 }
2969
RouterAssignElt(uint32_t addr,uint32_t recv_id,uint32_t change_number)2970 inline RouterAssignElt::RouterAssignElt(uint32_t addr, uint32_t recv_id, uint32_t change_number)
2971 : super(addr, recv_id), m_change_number(htonl(change_number))
2972 {
2973 }
2974 inline uint32_t
getChangeNumber()2975 RouterAssignElt::getChangeNumber() const
2976 {
2977 return ntohl(m_change_number);
2978 }
2979 inline RouterAssignElt &
setChangeNumber(uint32_t n)2980 RouterAssignElt::setChangeNumber(uint32_t n)
2981 {
2982 m_change_number = htonl(n);
2983 return *this;
2984 }
2985
SecurityComp()2986 inline SecurityComp::SecurityComp() : m_local_key(false) {}
2987 inline void
setDefaultOption(Option opt)2988 SecurityComp::setDefaultOption(Option opt)
2989 {
2990 m_default_opt = opt;
2991 }
2992 inline size_t
calcSize(Option opt)2993 SecurityComp::calcSize(Option opt)
2994 {
2995 return SECURITY_NONE == opt ? sizeof(RawNone) : sizeof(RawMD5);
2996 }
2997
ServiceComp()2998 inline ServiceComp::ServiceComp() : m_port_count(0) {}
2999 inline ServiceComp::raw_t *
access()3000 ServiceComp::access()
3001 {
3002 return reinterpret_cast<raw_t *>(m_base);
3003 }
3004 inline ServiceComp::raw_t const *
access()3005 ServiceComp::access() const
3006 {
3007 return reinterpret_cast<raw_t const *>(m_base);
3008 }
3009 inline ServiceGroup::Type
getSvcType()3010 ServiceComp::getSvcType() const
3011 {
3012 return this->access()->getSvcType();
3013 }
3014 inline ServiceComp &
setSvcType(ServiceGroup::Type t)3015 ServiceComp::setSvcType(ServiceGroup::Type t)
3016 {
3017 this->access()->setSvcType(t);
3018 return *this;
3019 }
3020 inline uint8_t
getSvcId()3021 ServiceComp::getSvcId() const
3022 {
3023 return this->access()->getSvcId();
3024 }
3025 inline ServiceComp &
setSvcId(uint8_t id)3026 ServiceComp::setSvcId(uint8_t id)
3027 {
3028 this->access()->setSvcId(id);
3029 return *this;
3030 }
3031 inline uint8_t
getPriority()3032 ServiceComp::getPriority() const
3033 {
3034 return this->access()->getPriority();
3035 }
3036 inline ServiceComp &
setPriority(uint8_t pri)3037 ServiceComp::setPriority(uint8_t pri)
3038 {
3039 this->access()->setPriority(pri);
3040 return *this;
3041 }
3042 inline uint8_t
getProtocol()3043 ServiceComp::getProtocol() const
3044 {
3045 return this->access()->getProtocol();
3046 }
3047 inline ServiceComp &
setProtocol(uint8_t proto)3048 ServiceComp::setProtocol(uint8_t proto)
3049 {
3050 this->access()->setProtocol(proto);
3051 return *this;
3052 }
3053 inline uint32_t
getFlags()3054 ServiceComp::getFlags() const
3055 {
3056 return this->access()->getFlags();
3057 }
3058 inline ServiceComp &
setFlags(uint32_t flags)3059 ServiceComp::setFlags(uint32_t flags)
3060 {
3061 this->access()->setFlags(flags);
3062 return *this;
3063 }
3064 inline ServiceComp &
enableFlags(uint32_t flags)3065 ServiceComp::enableFlags(uint32_t flags)
3066 {
3067 this->access()->enableFlags(flags);
3068 return *this;
3069 }
3070 inline ServiceComp &
disableFlags(uint32_t flags)3071 ServiceComp::disableFlags(uint32_t flags)
3072 {
3073 this->access()->disableFlags(flags);
3074 return *this;
3075 }
3076 inline uint16_t
getPort(int idx)3077 ServiceComp::getPort(int idx) const
3078 {
3079 return this->access()->getPort(idx);
3080 }
3081 inline size_t
calcSize()3082 ServiceComp::calcSize()
3083 {
3084 return sizeof(raw_t);
3085 }
3086 inline ServiceComp::operator ServiceGroup const &() const
3087 {
3088 return *static_cast<ServiceGroup const *>(this->access());
3089 }
3090
3091 inline size_t
calcSize(int n)3092 RouterIdComp::calcSize(int n)
3093 {
3094 return sizeof(raw_t) + n * sizeof(uint32_t);
3095 }
3096
3097 inline uint32_t
getKeyAddr()3098 RouterViewComp::getKeyAddr() const
3099 {
3100 return this->keyElt().getAddr();
3101 }
3102 inline RouterViewComp &
setKeyAddr(uint32_t addr)3103 RouterViewComp::setKeyAddr(uint32_t addr)
3104 {
3105 this->keyElt().setAddr(addr);
3106 return *this;
3107 }
3108 inline uint32_t
getKeyChangeNumber()3109 RouterViewComp::getKeyChangeNumber() const
3110 {
3111 return this->keyElt().getChangeNumber();
3112 }
3113 inline RouterViewComp &
setKeyChangeNumber(uint32_t change_number)3114 RouterViewComp::setKeyChangeNumber(uint32_t change_number)
3115 {
3116 this->keyElt().setChangeNumber(change_number);
3117 return *this;
3118 }
3119 inline CacheIdBox const &
cacheId(int idx)3120 RouterViewComp::cacheId(int idx) const
3121 {
3122 return const_cast<self *>(this)->cacheId(idx);
3123 }
3124
3125 inline CacheIdBox &
cacheId()3126 CacheIdComp::cacheId()
3127 {
3128 return m_box;
3129 }
3130 inline CacheIdBox const &
cacheId()3131 CacheIdComp::cacheId() const
3132 {
3133 return m_box;
3134 }
3135 inline uint32_t
getAddr()3136 CacheIdComp::getAddr() const
3137 {
3138 return this->cacheId().getAddr();
3139 }
3140 inline CacheIdComp &
setAddr(uint32_t addr)3141 CacheIdComp::setAddr(uint32_t addr)
3142 {
3143 this->cacheId().setAddr(addr);
3144 return *this;
3145 }
3146 inline uint16_t
getHashRev()3147 CacheIdComp::getHashRev() const
3148 {
3149 return this->cacheId().getHashRev();
3150 }
3151 inline CacheIdComp &
setHashRev(uint16_t rev)3152 CacheIdComp::setHashRev(uint16_t rev)
3153 {
3154 this->cacheId().setHashRev(rev);
3155 return *this;
3156 }
3157 inline bool
getUnassigned()3158 CacheIdComp::getUnassigned() const
3159 {
3160 return this->cacheId().getUnassigned();
3161 }
3162 inline CacheIdComp &
setUnassigned(bool state)3163 CacheIdComp::setUnassigned(bool state)
3164 {
3165 this->cacheId().setUnassigned(state);
3166 return *this;
3167 }
3168
3169 inline bool
isActive()3170 detail::Assignment::isActive() const
3171 {
3172 return m_active;
3173 }
3174 inline detail::Assignment &
setActive(bool state)3175 detail::Assignment::setActive(bool state)
3176 {
3177 m_active = state;
3178 return *this;
3179 }
3180 inline detail::Assignment &
updateRouterId(uint32_t addr,uint32_t rcvid,uint32_t cno)3181 detail::Assignment::updateRouterId(uint32_t addr, uint32_t rcvid, uint32_t cno)
3182 {
3183 if (m_router_list)
3184 m_router_list->updateRouterId(addr, rcvid, cno);
3185 return *this;
3186 }
AssignmentKeyElt()3187 inline AssignmentKeyElt::AssignmentKeyElt() {}
3188 inline AssignmentKeyElt const &
getKey()3189 detail::Assignment::getKey() const
3190 {
3191 return m_key;
3192 }
3193 inline RouterAssignListElt const &
getRouterList()3194 detail::Assignment::getRouterList() const
3195 {
3196 assert(m_router_list);
3197 return *m_router_list;
3198 }
3199 inline HashAssignElt const &
getHash()3200 detail::Assignment::getHash() const
3201 {
3202 assert(m_hash_assign);
3203 return *m_hash_assign;
3204 }
3205 inline MaskAssignElt const &
getMask()3206 detail::Assignment::getMask() const
3207 {
3208 assert(m_mask_assign);
3209 return *m_mask_assign;
3210 }
3211
MsgBuffer()3212 inline MsgBuffer::MsgBuffer() : super(), _count(0) {}
MsgBuffer(super const & that)3213 inline MsgBuffer::MsgBuffer(super const &that) : super(that), _count(0) {}
MsgBuffer(void * p,size_t n)3214 inline MsgBuffer::MsgBuffer(void *p, size_t n) : super(static_cast<char *>(p), n), _count(0) {}
3215
3216 inline size_t
getSize()3217 MsgBuffer::getSize() const
3218 {
3219 return _size;
3220 }
3221 inline size_t
getCount()3222 MsgBuffer::getCount() const
3223 {
3224 return _count;
3225 }
3226 inline char *
getBase()3227 MsgBuffer::getBase()
3228 {
3229 return _ptr;
3230 }
3231 inline const char *
getBase()3232 MsgBuffer::getBase() const
3233 {
3234 return _ptr;
3235 }
3236 inline char *
getTail()3237 MsgBuffer::getTail()
3238 {
3239 return _ptr + _count;
3240 }
3241 inline size_t
getSpace()3242 MsgBuffer::getSpace() const
3243 {
3244 return _size - _count;
3245 }
3246 inline MsgBuffer &
reset()3247 MsgBuffer::reset()
3248 {
3249 _count = 0;
3250 return *this;
3251 }
3252
3253 inline MsgBuffer &
set(void * ptr,size_t n)3254 MsgBuffer::set(void *ptr, size_t n)
3255 {
3256 _ptr = static_cast<char *>(ptr);
3257 _size = n;
3258 _count = 0;
3259 return *this;
3260 }
3261
3262 inline MsgBuffer &
use(size_t n)3263 MsgBuffer::use(size_t n)
3264 {
3265 _count += std::min(n, this->getSpace());
3266 return *this;
3267 }
3268
3269 inline MsgBuffer &
zero()3270 MsgBuffer::zero()
3271 {
3272 memset(_ptr, 0, _size);
3273 _count = 0;
3274 return *this;
3275 }
3276
PacketStamp()3277 inline PacketStamp::PacketStamp() : m_time(0), m_sn(0) {}
3278
3279 inline PacketStamp &
set(time_t time,uint32_t sn)3280 PacketStamp::set(time_t time, uint32_t sn)
3281 {
3282 m_time = time;
3283 m_sn = sn;
3284 return *this;
3285 }
3286
ServiceGroup()3287 inline ServiceGroup::ServiceGroup() : m_svc_type(STANDARD), m_svc_id(0), m_priority(0), m_protocol(0), m_flags(0) {}
3288
RouterIdElt()3289 inline RouterIdElt::RouterIdElt() {}
RouterAssignElt()3290 inline RouterAssignElt::RouterAssignElt() : m_change_number(0) {}
3291
RouterAssignListElt()3292 inline RouterAssignListElt::RouterAssignListElt() {}
RouterAssignListElt(int n)3293 inline RouterAssignListElt::RouterAssignListElt(int n) : m_count(htonl(n)) {}
3294 inline RouterAssignElt &
elt(int n)3295 RouterAssignListElt::elt(int n)
3296 {
3297 return access_array<RouterAssignElt>(this + 1)[n];
3298 }
3299 inline RouterAssignElt const &
elt(int n)3300 RouterAssignListElt::elt(int n) const
3301 {
3302 return const_cast<self *>(this)->elt(n);
3303 }
3304 inline size_t
calcVarSize(int n)3305 RouterAssignListElt::calcVarSize(int n)
3306 {
3307 return n * sizeof(RouterAssignElt);
3308 }
3309 inline size_t
calcSize(int n)3310 RouterAssignListElt::calcSize(int n)
3311 {
3312 return sizeof(self) + self::calcVarSize(n);
3313 }
3314 inline size_t
getSize()3315 RouterAssignListElt::getSize() const
3316 {
3317 return this->calcSize(this->getCount());
3318 }
3319 inline size_t
getVarSize()3320 RouterAssignListElt::getVarSize() const
3321 {
3322 return this->getSize() - sizeof(self);
3323 }
3324 // This is untainted because an overall size check is done when the packet is read. If any of the
3325 // counts are bogus, that size check will fail.
3326 // coverity[ -tainted_data_return]
3327 inline uint32_t
getCount()3328 RouterAssignListElt::getCount() const
3329 {
3330 return ntohl(m_count);
3331 }
3332
HashAssignElt()3333 inline HashAssignElt::HashAssignElt() {}
HashAssignElt(int n)3334 inline HashAssignElt::HashAssignElt(int n) : m_count(htonl(n)) {}
3335 // This is untainted because an overall size check is done when the packet is read. If any of the
3336 // counts are bogus, that size check will fail.
3337 // coverity[ -tainted_data_return]
3338 inline uint32_t
getCount()3339 HashAssignElt::getCount() const
3340 {
3341 return ntohl(m_count);
3342 }
3343 inline size_t
calcSize(int n)3344 HashAssignElt::calcSize(int n)
3345 {
3346 return sizeof(self) + n * sizeof(uint32_t) + sizeof(Bucket) * N_BUCKETS;
3347 }
3348 inline size_t
getSize()3349 HashAssignElt::getSize() const
3350 {
3351 return self::calcSize(this->getCount());
3352 }
3353 inline uint32_t
getAddr(int idx)3354 HashAssignElt::getAddr(int idx) const
3355 {
3356 // coverity[ptr_arith]
3357 return (&m_count)[idx + 1];
3358 }
3359 inline HashAssignElt &
setAddr(int idx,uint32_t addr)3360 HashAssignElt::setAddr(int idx, uint32_t addr)
3361 {
3362 // coverity[ptr_arith]
3363 (&m_count)[idx + 1] = addr;
3364 return *this;
3365 }
3366 inline HashAssignElt::Bucket *
getBucketBase()3367 HashAssignElt::getBucketBase()
3368 {
3369 // coverity[ptr_arith]
3370 return reinterpret_cast<Bucket *>((&m_count + 1 + this->getCount()));
3371 }
3372 inline HashAssignElt::Bucket &
3373 HashAssignElt::operator[](size_t idx)
3374 {
3375 return this->getBucketBase()[idx];
3376 }
3377 inline HashAssignElt::Bucket const &
3378 HashAssignElt::operator[](size_t idx) const
3379 {
3380 return (*(const_cast<self *>(this)))[idx];
3381 }
3382
3383 // This is untainted because an overall size check is done when the packet is read. If any of the
3384 // counts are bogus, that size check will fail.
3385 // coverity[ -tainted_data_return]
3386 inline uint32_t
getCount()3387 MaskAssignElt::getCount() const
3388 {
3389 return ntohl(m_count);
3390 }
3391 inline MaskValueSetElt *
3392 MaskAssignElt::appender::operator->()
3393 {
3394 return m_set;
3395 }
3396 inline MaskValueSetElt *
initSet(uint32_t srcAddr,uint32_t dstAddr,uint16_t srcPort,uint16_t dstPort)3397 MaskAssignElt::appender::initSet(uint32_t srcAddr, uint32_t dstAddr, uint16_t srcPort, uint16_t dstPort)
3398 {
3399 (*(new (m_set) MaskValueSetElt(0)))
3400 .setSrcAddrMask(srcAddr)
3401 .setDstAddrMask(dstAddr)
3402 .setSrcPortMask(srcPort)
3403 .setDstPortMask(dstPort);
3404 return m_set;
3405 }
3406 inline MaskValueSetElt *
mask(uint32_t srcAddr,uint32_t dstAddr,uint16_t srcPort,uint16_t dstPort)3407 MaskAssignElt::appender::mask(uint32_t srcAddr, uint32_t dstAddr, uint16_t srcPort, uint16_t dstPort)
3408 {
3409 m_set = reinterpret_cast<MaskValueSetElt *>(reinterpret_cast<char *>(m_set) + m_set->getSize());
3410 m_elt->m_count = htonl(1 + m_elt->getCount()); // bump set count.
3411 this->initSet(srcAddr, dstAddr, srcPort, dstPort);
3412 return m_set;
3413 }
3414 inline MaskAssignElt::appender
init(uint32_t srcAddr,uint32_t dstAddr,uint16_t srcPort,uint16_t dstPort)3415 MaskAssignElt::init(uint32_t srcAddr, uint32_t dstAddr, uint16_t srcPort, uint16_t dstPort)
3416 {
3417 appender zret;
3418 m_count = htonl(1);
3419 zret.m_set = reinterpret_cast<MaskValueSetElt *>(this + 1);
3420 zret.m_elt = this;
3421 zret.initSet(srcAddr, dstAddr, srcPort, dstPort);
3422 return zret;
3423 }
3424
3425 inline bool
isEmpty()3426 ComponentBase::isEmpty() const
3427 {
3428 return 0 == m_base;
3429 }
3430
3431 inline message_type_t
toMsgType(int t)3432 MsgHeaderComp::toMsgType(int t)
3433 {
3434 return HERE_I_AM != t && I_SEE_YOU != t && REDIRECT_ASSIGN != t && REMOVAL_QUERY != t ? INVALID_MSG_TYPE :
3435 static_cast<message_type_t>(t);
3436 }
3437
3438 template <typename T>
3439 CompType
getType()3440 CompWithHeader<T>::getType() const
3441 {
3442 return static_cast<CompType>(ntohs(reinterpret_cast<raw_t const *>(m_base)->m_type));
3443 }
3444
3445 template <typename T>
3446 T &
setType(CompType t)3447 CompWithHeader<T>::setType(CompType t)
3448 {
3449 reinterpret_cast<raw_t *>(m_base)->m_type = htons(t);
3450 return static_cast<T &>(*this);
3451 }
3452
3453 template <typename T>
3454 uint16_t
getLength()3455 CompWithHeader<T>::getLength() const
3456 {
3457 return ntohs(reinterpret_cast<raw_t const *>(m_base)->m_length);
3458 }
3459
3460 template <typename T>
3461 T &
setLength(uint16_t length)3462 CompWithHeader<T>::setLength(uint16_t length)
3463 {
3464 reinterpret_cast<raw_t *>(m_base)->m_length = htons(length);
3465 return static_cast<T &>(*this);
3466 }
3467
3468 template <typename T>
3469 int
checkHeader(MsgBuffer const & buffer,CompType ect)3470 CompWithHeader<T>::checkHeader(MsgBuffer const &buffer, CompType ect)
3471 {
3472 CompType act = this->getType();
3473 if (act != ect)
3474 return (act < COMP_TYPE_MIN || COMP_TYPE_MAX < act) ? PARSE_COMP_TYPE_INVALID : PARSE_COMP_OTHER_TYPE;
3475 if (this->getLength() + sizeof(raw_t) > buffer.getSpace())
3476 return PARSE_COMP_TOO_BIG;
3477 return PARSE_SUCCESS;
3478 }
3479
3480 inline AssignInfoComp::Bucket &
bucket(int idx)3481 AssignInfoComp::bucket(int idx)
3482 {
3483 return m_buckets[idx];
3484 }
3485 inline AssignInfoComp::Bucket const &
bucket(int idx)3486 AssignInfoComp::bucket(int idx) const
3487 {
3488 return m_buckets[idx];
3489 }
RouterViewComp()3490 inline RouterViewComp::RouterViewComp() : m_cache_count(0)
3491 {
3492 ink_zero(m_cache_ids);
3493 }
3494
CapComp()3495 inline CapComp::CapComp() {}
3496 inline CapComp &
invalidate()3497 CapComp::invalidate()
3498 {
3499 m_cached = false;
3500 return *this;
3501 }
3502 inline uint32_t
getEltCount()3503 CapComp::getEltCount() const
3504 {
3505 return this->m_count;
3506 }
3507 inline size_t
calcSize(int n)3508 CapComp::calcSize(int n)
3509 {
3510 return sizeof(super::raw_t) + n * sizeof(CapabilityElt);
3511 }
3512 inline ServiceGroup::PacketStyle
getPacketForwardStyle()3513 CapComp::getPacketForwardStyle() const
3514 {
3515 if (!m_cached)
3516 this->cache();
3517 return m_packet_forward;
3518 }
3519 inline ServiceGroup::PacketStyle
getPacketReturnStyle()3520 CapComp::getPacketReturnStyle() const
3521 {
3522 if (!m_cached)
3523 this->cache();
3524 return m_packet_return;
3525 }
3526 inline ServiceGroup::CacheAssignmentStyle
getCacheAssignmentStyle()3527 CapComp::getCacheAssignmentStyle() const
3528 {
3529 if (!m_cached)
3530 this->cache();
3531 return m_cache_assign;
3532 }
3533
AssignMapComp()3534 inline AssignMapComp::AssignMapComp() {}
3535
3536 /* Implementation note: Due to a bug in gcc, we have to be
3537 careful with these fields. If we use the field access templates
3538 directly, we get bad results because the pointer to member matching
3539 is done incorrectly (it uses a super type, not @c raw_t). We work
3540 around this by putting the pointer to member in a static variable.
3541 */
3542 inline uint16_t
getAssignType()3543 AltAssignComp::getAssignType() const
3544 {
3545 static uint16_t raw_t::*mptr = &raw_t::m_assign_type;
3546 return get_field(mptr, m_base);
3547 }
3548 inline AltAssignComp &
setAssignType(uint16_t t)3549 AltAssignComp::setAssignType(uint16_t t)
3550 {
3551 static uint16_t raw_t::*mptr = &raw_t::m_assign_type;
3552 set_field(mptr, m_base, t);
3553 return *this;
3554 }
3555 inline uint16_t
getAssignLength()3556 AltAssignComp::getAssignLength() const
3557 {
3558 static uint16_t raw_t::*mptr = &raw_t::m_assign_length;
3559 return get_field(mptr, m_base);
3560 }
3561 inline AltAssignComp &
setAssignLength(uint16_t length)3562 AltAssignComp::setAssignLength(uint16_t length)
3563 {
3564 static uint16_t raw_t::*mptr = &raw_t::m_assign_length;
3565 set_field(mptr, m_base, length);
3566 return *this;
3567 }
3568
3569 inline uint32_t
getRouterAddr()3570 QueryComp::getRouterAddr() const
3571 {
3572 return access_field(&raw_t::m_router_addr, m_base);
3573 }
3574 inline QueryComp &
setRouterAddr(uint32_t addr)3575 QueryComp::setRouterAddr(uint32_t addr)
3576 {
3577 access_field(&raw_t::m_router_addr, m_base) = addr;
3578 return *this;
3579 }
3580 inline uint32_t
getToAddr()3581 QueryComp::getToAddr() const
3582 {
3583 return access_field(&raw_t::m_to_addr, m_base);
3584 }
3585 inline QueryComp &
setToAddr(uint32_t addr)3586 QueryComp::setToAddr(uint32_t addr)
3587 {
3588 access_field(&raw_t::m_to_addr, m_base) = addr;
3589 return *this;
3590 }
3591 inline uint32_t
getCacheAddr()3592 QueryComp::getCacheAddr() const
3593 {
3594 return access_field(&raw_t::m_cache_addr, m_base);
3595 }
3596 inline QueryComp &
setCacheAddr(uint32_t addr)3597 QueryComp::setCacheAddr(uint32_t addr)
3598 {
3599 access_field(&raw_t::m_cache_addr, m_base) = addr;
3600 return *this;
3601 }
3602 inline uint32_t
getRecvId()3603 QueryComp::getRecvId() const
3604 {
3605 return get_field(&raw_t::m_recv_id, m_base);
3606 }
3607 inline QueryComp &
setRecvId(uint32_t data)3608 QueryComp::setRecvId(uint32_t data)
3609 {
3610 set_field(&raw_t::m_recv_id, m_base, data);
3611 return *this;
3612 }
3613 inline size_t
calcSize()3614 QueryComp::calcSize()
3615 {
3616 return sizeof(raw_t);
3617 }
3618
SeedRouter()3619 inline detail::cache::SeedRouter::SeedRouter() {}
3620
SeedRouter(uint32_t addr)3621 inline detail::cache::SeedRouter::SeedRouter(uint32_t addr) : m_addr(addr), m_count(0), m_xmit(0) {}
3622
BaseMsg()3623 inline BaseMsg::BaseMsg() : m_buffer(0, 0) {}
3624 inline MsgBuffer const &
buffer()3625 BaseMsg::buffer() const
3626 {
3627 return m_buffer;
3628 }
3629 inline size_t
getSpace()3630 BaseMsg::getSpace() const
3631 {
3632 return m_buffer.getSpace();
3633 }
3634 inline size_t
getCount()3635 BaseMsg::getCount() const
3636 {
3637 return m_buffer.getCount();
3638 }
3639
3640 inline RouterImpl::RouterData &
resize(size_t n)3641 RouterImpl::RouterData::resize(size_t n)
3642 {
3643 m_src.resize(n);
3644 return *this;
3645 }
3646 // ------------------------------------------------------
3647
3648 } // namespace wccp
3649