You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by am...@apache.org on 2011/02/06 03:57:11 UTC
svn commit: r1067578 [1/2] - in /trafficserver/traffic/trunk/proxy/wccp:
Wccp.h WccpEndPoint.cc WccpLocal.h WccpMsg.cc WccpStatic.cc WccpUtil.h
Author: amc
Date: Sun Feb 6 02:57:11 2011
New Revision: 1067578
URL: http://svn.apache.org/viewvc?rev=1067578&view=rev
Log:
TS-663
Modified:
trafficserver/traffic/trunk/proxy/wccp/Wccp.h
trafficserver/traffic/trunk/proxy/wccp/WccpEndPoint.cc
trafficserver/traffic/trunk/proxy/wccp/WccpLocal.h
trafficserver/traffic/trunk/proxy/wccp/WccpMsg.cc
trafficserver/traffic/trunk/proxy/wccp/WccpStatic.cc
trafficserver/traffic/trunk/proxy/wccp/WccpUtil.h
Modified: trafficserver/traffic/trunk/proxy/wccp/Wccp.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/wccp/Wccp.h?rev=1067578&r1=1067577&r2=1067578&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/wccp/Wccp.h (original)
+++ trafficserver/traffic/trunk/proxy/wccp/Wccp.h Sun Feb 6 02:57:11 2011
@@ -134,6 +134,11 @@ public:
static uint32_t const SRC_PORT_ALT_HASH = 1<<10;
/// Alternate destination port hash
static uint32_t const DST_PORT_ALT_HASH = 1<<11;
+ /// All hash related flags.
+ static uint32_t const HASH_FLAGS =
+ SRC_IP_HASH | DST_IP_HASH | SRC_PORT_HASH | DST_PORT_HASH
+ | SRC_IP_ALT_HASH | DST_IP_ALT_HASH | SRC_PORT_ALT_HASH | DST_PORT_ALT_HASH
+ ;
//@}
/// Default constructor - no member initialization.
Modified: trafficserver/traffic/trunk/proxy/wccp/WccpEndPoint.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/wccp/WccpEndPoint.cc?rev=1067578&r1=1067577&r2=1067578&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/wccp/WccpEndPoint.cc (original)
+++ trafficserver/traffic/trunk/proxy/wccp/WccpEndPoint.cc Sun Feb 6 02:57:11 2011
@@ -341,9 +341,7 @@ CacheImpl::defineServiceGroup(
group = &(m_groups[svc_id]);
group->m_svc = svc;
memset(&group->m_id, 0, sizeof(group->m_id));
- group->m_id.setAddr(m_addr);
- group->m_id.setUnassigned(true);
- group->m_id.setBuckets(false);
+ group->m_id.initDefaultHash(m_addr);
zret = ServiceGroup::DEFINED;
} else {
group = &spot->second;
@@ -483,7 +481,7 @@ CacheImpl::generateHereIAm(
HereIAmMsg& msg,
GroupData& group
) {
- msg.fill(group, this->setSecurity(msg, group), 0, 0);
+ msg.fill(group, this->setSecurity(msg, group));
msg.finalize();
}
@@ -493,36 +491,8 @@ CacheImpl::generateHereIAm(
GroupData& group,
RouterData& router
) {
- int i;
- size_t n_routers = group.m_routers.size();
- size_t n_caches = group.m_caches.size();
-
- msg.fill(group, this->setSecurity(msg, group), n_routers, n_caches);
+ msg.fill(group, this->setSecurity(msg, group));
msg.fill_caps(router);
-
- // Fill routers.
- i = 0;
- for ( RouterBag::iterator spot = group.m_routers.begin(),
- limit = group.m_routers.end();
- spot != limit;
- ++spot, ++i
- ) {
- msg.m_cache_view.routerElt(i)
- .setAddr(spot->m_addr)
- .setRecvId(spot->m_recv.m_sn)
- ;
- }
-
- // fill caches.
- i = 0;
- for ( CacheBag::iterator spot = group.m_caches.begin(),
- limit = group.m_caches.end();
- spot != limit;
- ++spot, ++i
- ) {
- msg.m_cache_view.setCacheAddr(i, spot->idAddr());
- }
-
msg.finalize();
}
@@ -531,37 +501,7 @@ CacheImpl::generateRedirectAssign(
RedirectAssignMsg& msg,
GroupData& group
) {
- int i;
- size_t n_caches = group.m_caches.size();
- size_t n_routers = group.m_caches.size();
- AssignmentKeyElt key(m_addr, group.m_generation);
-
- msg.fill(group, this->setSecurity(msg, group), key, n_routers, n_caches);
-
- // Fill routers.
- i = 0;
- for ( RouterBag::iterator spot = group.m_routers.begin(),
- limit = group.m_routers.end();
- spot != limit;
- ++spot, ++i
- ) {
- msg.m_assign.routerElt(i)
- .setChangeNumber(spot->m_generation)
- .setAddr(spot->m_addr)
- .setRecvId(spot->m_recv.m_sn)
- ;
- }
-
- // fill caches.
- i = 0;
- for ( CacheBag::iterator spot = group.m_caches.begin(),
- limit = group.m_caches.end();
- spot != limit;
- ++spot, ++i
- ) {
- msg.m_assign.setCacheAddr(i, spot->idAddr());
- }
-
+ msg.fill(group, this->setSecurity(msg, group));
msg.finalize();
}
@@ -572,16 +512,27 @@ CacheImpl::checkRouterAssignment(
) const {
// If group doesn't have an active assignment, always match w/o checking.
bool zret = ! group.m_assign_info.isActive();
- if (! zret && ! comp.isEmpty()) { // invalid component doesn't match.
- uint32_t nc = comp.getCacheCount();
+ if (! zret
+ && ! comp.isEmpty()
+ && ServiceGroup::HASH_ONLY == group.m_cache_assign
+ ) {
+// uint32_t nc = comp.getCacheCount();
+// HashAssignElt const& ha = *(group.m_assign_info.getHash());
// Nothing for it but simple brute force - iterate over every bucket
// in the assignment and verify the corresponding bucket in the
// cache bit array is set.
zret = true;
+ // TBD: FIX THIS TO CHECK HASH BUCKETS!
+ // Need to fix up RouterViewComp extensively to make this work.
+# if 0
for ( size_t b = 0 ; zret && b < N_BUCKETS ; ++b ) {
- unsigned int c = group.m_assign_info[b].m_idx;
+ unsigned int c = ha[b].m_idx;
if (c >= nc || ! comp.cacheElt(c).getBucket(b)) zret = false;
}
+# endif
+ } else {
+ // TBD: Validate mask assignments. For now, always OK.
+ zret = true;
}
return zret;
}
@@ -681,10 +632,10 @@ CacheImpl::housekeeping() {
zret = sendto(m_fd, msg_data, here_i_am.getCount(), 0,
addr_ptr, sizeof(dst_addr));
if (0 <= zret) {
- logf(LVL_DEBUG, "Sent HERE_I_AM for SG %d to seed router %s [#%d,%lu].",
+ logf(LVL_DEBUG, "Sent HERE_I_AM for SG %d to seed router %s [gen=#%d,t=%lu,n=%lu].",
group.m_svc.getSvcId(),
ip_addr_to_str(sspot->m_addr),
- group.m_generation, now
+ group.m_generation, now, here_i_am.getCount()
);
sspot->m_xmit = now;
sspot->m_count += 1;
@@ -741,20 +692,25 @@ CacheImpl::handleISeeYou(IpHeader const&
int router_idx; // index in active routers.
std::vector< SeedRouter >::iterator seed_spot;
+ CapComp& caps = msg.m_capabilities;
// Handle the router that sent us this.
ar_spot = find_by_member(group.m_routers, &RouterData::m_addr, router_addr);
if (ar_spot == group.m_routers.end()) {
+ // This is a new router that's replied to one of our pings.
+ // Need to do various setup and reply things to get the connection
+ // established.
+
// Remove this from the seed routers and copy the last packet
// sent time.
RouterData r(router_addr); // accumulate state before we commit it.
r.m_xmit.m_time = group.removeSeedRouter(to_addr);
// Validate capabilities.
- CapComp& caps = msg.m_capabilities;
ServiceGroup::PacketStyle ps;
ServiceGroup::CacheAssignmentStyle as;
char const* caps_tag = caps.isEmpty() ? "default" : "router";
+ // No caps -> use GRE forwarding.
ps = caps.isEmpty() ? ServiceGroup::GRE : caps.getPacketForwardStyle();
if (ServiceGroup::GRE & ps & group.m_packet_forward)
r.m_packet_forward = ServiceGroup::GRE;
@@ -763,6 +719,7 @@ CacheImpl::handleISeeYou(IpHeader const&
else
logf(zret, LVL_WARN, "Packet forwarding (config=%d, %s=%d) did not match.", group.m_packet_forward, caps_tag, ps);
+ // No caps -> use GRE return.
ps = caps.isEmpty() ? ServiceGroup::GRE : caps.getPacketReturnStyle();
if (ServiceGroup::GRE & ps & group.m_packet_return)
r.m_packet_return = ServiceGroup::GRE;
@@ -771,16 +728,16 @@ CacheImpl::handleISeeYou(IpHeader const&
else
logf(zret, LVL_WARN, "Packet return (local=%d, %s=%d) did not match.", group.m_packet_return, caps_tag, ps);
+ // No caps -> use HASH assignment.
as = caps.isEmpty() ? ServiceGroup::HASH_ONLY : caps.getCacheAssignmentStyle();
if (ServiceGroup::HASH_ONLY & as & group.m_cache_assign)
r.m_cache_assign = ServiceGroup::HASH_ONLY;
- else if (ServiceGroup::MASK_ONLY & as & group.m_cache_assign)
+ else if (ServiceGroup::MASK_ONLY & as & group.m_cache_assign) {
r.m_cache_assign = ServiceGroup::MASK_ONLY;
- else
+ group.m_id.initDefaultMask(m_addr); // switch to MASK style ID.
+ } else
logf(zret, LVL_WARN, "Cache assignment (local=%d, %s=%d) did not match.", group.m_cache_assign, caps_tag, as);
- r.m_send_caps = ! caps.isEmpty();
-
if (!zret) {
// cancel out, can't use this packet because we reject the router.
return logf(zret, LVL_WARN, "Router %s rejected because of capabilities mismatch.", ip_addr_to_str(router_addr));
@@ -791,8 +748,9 @@ CacheImpl::handleISeeYou(IpHeader const&
view_changed = true;
logf(LVL_INFO, "Added source router %s to view %d", ip_addr_to_str(router_addr), group.m_svc.getSvcId());
} else {
- // Existing router. If we have a valid assignment, check it and
- // send again if this router hasn't updated.
+ // Existing router. Update the receive ID in the assignment object.
+ group.m_assign_info.updateRouterId(router_addr, recv_id, msg.m_router_view.getChangeNumber());
+ // Check the assignment to see if we need to send it again.
if (!this->checkRouterAssignment(group, msg.m_router_view)) {
ar_spot->m_assign = true; // schedule an assignment message.
logf(LVL_INFO, "Router assignment reported from "
@@ -805,6 +763,11 @@ CacheImpl::handleISeeYou(IpHeader const&
ar_spot->m_recv.set(now, recv_id);
ar_spot->m_generation = msg.m_router_view.getChangeNumber();
router_idx = ar_spot - group.m_routers.begin();
+ // Reply with our own capability options iff the router sent one to us.
+ // This is a violation of the spec but it's what we have to do in practice
+ // for mask assignment.
+ ar_spot->m_send_caps = ! caps.isEmpty();
+
// For all the other listed routers, seed them if they're not
// already active.
@@ -821,7 +784,7 @@ CacheImpl::handleISeeYou(IpHeader const&
group.resizeCacheSources();
uint32_t nc = msg.m_router_view.getCacheCount();
for ( uint32_t idx = 0 ; idx < nc ; ++idx ) {
- CacheIdElt& cache = msg.m_router_view.cacheElt(idx);
+ CacheIdBox& cache = msg.m_router_view.cacheId(idx);
CacheBag::iterator ac_spot = group.findCache(cache.getAddr());
if (group.m_caches.end() == ac_spot) {
group.m_caches.push_back(CacheData());
@@ -830,7 +793,7 @@ CacheImpl::handleISeeYou(IpHeader const&
logf(LVL_INFO, "Added cache %s to view %d", ip_addr_to_str(cache.getAddr()), group.m_svc.getSvcId());
view_changed = true;
}
- ac_spot->m_id = cache;
+ ac_spot->m_id.fill(cache);
ac_spot->m_src[router_idx].set(now, recv_id);
}
@@ -986,7 +949,7 @@ RouterImpl::handleHereIAm(IpHeader const
cache_gen = msg.m_cache_view.getChangeNumber();
cache_idx = cache - group.m_caches.begin();
- cache->m_id = msg.m_cache_id.idElt();
+ cache->m_id.fill(msg.m_cache_id.cacheId());
cache->m_recv.set(now, cache_gen);
cache->m_pending = true;
cache->m_to_addr = ip_hdr.m_dst;
@@ -1048,7 +1011,9 @@ RouterImpl::generateISeeYou(
spot != limit;
++spot, ++i
) {
- msg.m_router_view.cacheElt(i) = spot->m_id;
+ // TBD: This needs to track memory because cache ID elements
+ // turn out to be variable sized.
+// msg.m_router_view.cacheId(i) = spot->m_id;
}
msg.finalize();
Modified: trafficserver/traffic/trunk/proxy/wccp/WccpLocal.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/wccp/WccpLocal.h?rev=1067578&r1=1067577&r2=1067578&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/wccp/WccpLocal.h (original)
+++ trafficserver/traffic/trunk/proxy/wccp/WccpLocal.h Sun Feb 6 02:57:11 2011
@@ -35,7 +35,13 @@ static const int NO_FD = -1;
namespace wccp {
-namespace detail { namespace cache { class RouterData; } }
+// Forward declares
+namespace detail {
+ class Assignment;
+ namespace cache {
+ class RouterData;
+ }
+}
/// Default port used by the protocol.
static unsigned int const DEFAULT_PORT = 2048;
@@ -45,6 +51,10 @@ static unsigned int const N_BUCKETS = 25
static uint8_t const UNASSIGNED_BUCKET = 0xFF;
/// Size of group password in octets.
static unsigned int const GROUP_PASSWORD_SIZE = 8;
+/// Maximum # of caches
+static uint32_t const MAX_CACHES = 32;
+/// Maximum # of routers
+static uint32_t const MAX_ROUTERS = 32;
/// Our version of the protocol.
static unsigned int const VERSION = 0x200;
@@ -150,9 +160,9 @@ enum CompType {
SECURITY_INFO = 0,
SERVICE_INFO = 1,
ROUTER_ID_INFO = 2,
- WC_ID_INFO = 3,
+ CACHE_ID_INFO = 3,
RTR_VIEW_INFO = 4,
- WC_VIEW_INFO = 5,
+ CACHE_VIEW_INFO = 5,
REDIRECT_ASSIGNMENT = 6,
QUERY_INFO = 7,
CAPABILITY_INFO = 8,
@@ -212,67 +222,6 @@ public:
self& operator = (super const& that);
};
-/// Sect 5.7.2: Web-Cache Identity.
-struct CacheId {
- typedef CacheId self; ///< Self reference type.
- /// Container for hash assignment.
- typedef uint8_t HashBuckets[N_BUCKETS >> 3];
- /// Hash revision (protocol required).
- static uint16_t const HASH_REVISION = 0;
-
- uint32_t m_addr; ///< Identifying cache IP address.
- uint16_t m_hash_rev; ///< Hash revision.
- unsigned int m_reserved_0:7; ///< Reserved bits.
- /** Cache not assigned.
- If set the cache does not have an assignment in the redirection
- hash table and the data in @a m_buckets is historical. This allows
- a cache that was removed to be added back in the same buckets.
- */
- unsigned int m_unassigned:1;
- unsigned int m_reserved_1:8; ///< Reserved (unused).
- /// Bit vector of buckets assigned to this cache.
- HashBuckets m_buckets;
- uint16_t m_weight; ///< Assignment weight.
- uint16_t m_status; ///< Cache status.
-};
-
-/** Sect 5.7.2: Web-Cache Identity Element
- This is maps directly on to message content. It is effectively
- a @c CacheId with accessors to guarantee correctly serialized layout.
-*/
-class CacheIdElt : protected CacheId {
-protected:
- typedef CacheId super; ///< Parent type.
-public:
- typedef CacheIdElt self; ///< Self reference type.
-
- typedef super::HashBuckets HashBuckets; ///< Expose type.
-
- /// Hash revision (protocol required).
- static uint16_t const HASH_REVISION = super::HASH_REVISION;
-
- /// @name Accessors
- //@{
- uint32_t getAddr() const; ///< Get address field.
- self& setAddr(uint32_t addr); ///< Set address field to @a addr.
- uint16_t getHashRev() const; ///< Get hash revision field.
- self& setHashRev(uint16_t rev); ///< Set hash revision field to @a rev.
- bool getUnassigned() const; ///< Get unassigned field.
- self& setUnassigned(bool state); ///< Set unassigned field to @a state.
- uint16_t getWeight() const; ///< Get weight field.
- self& setWeight(uint16_t w); ///< Set weight field to @a w.
- uint16_t getStatus() const; ///< Get status field.
- self& setStatus(uint16_t s); ///< Set status field to @a s.
-
- bool getBucket(int idx) const; ///< Get bucket state at index @a idx.
- /// Set bucket at index @a idx to @a state.
- self& setBucket(int idx, bool state);
- self& setBuckets(bool state); ///< Set all buckets to @a state.
-
- self& clearReserved(); ///< Set reserved bits to zero.
- //@}
-};
-
/// Sect 5.7.3: Assignment Key Element
/// @note This maps directly on to message content.
/// @internal: At top level because it is used in more than one component.
@@ -302,15 +251,15 @@ protected:
/// Sect 5.7.4: Router Assignment Element
/// @note This maps directly on to message content.
/// @internal: At top level because it is used in more than one component.
-class RouterAssignmentElt : public RouterIdElt {
+class RouterAssignElt : public RouterIdElt {
public:
- typedef RouterAssignmentElt self; ///< Self reference type.
+ typedef RouterAssignElt self; ///< Self reference type.
typedef RouterIdElt super; ///< Parent type.
/// Default constructor, members zero initialized.
- RouterAssignmentElt();
+ RouterAssignElt();
/// Construct from address and sequence number.
- RouterAssignmentElt(
+ RouterAssignElt(
uint32_t addr, ///< Router address.
uint32_t recv_id, ///< Receive ID (sequence number).
uint32_t change_number ///< Change number (sequence number).
@@ -325,6 +274,60 @@ protected:
uint32_t m_change_number; ///< Change number (sequence #).
};
+/** List of @c RouterAssignElt
+ @note Not explicitly part of the spec, but it shows up in multiple
+ places.
+ */
+class RouterAssignListElt {
+public:
+ typedef RouterAssignListElt self; ///< Self reference type.
+
+ /// Default constructor - @b no initialization.
+ RouterAssignListElt();
+ /// Construct with @n elements.
+ RouterAssignListElt(
+ int n ///< Number of elements.
+ );
+
+ /// @name Accessors
+ //@{
+ /// Access element.
+ RouterAssignElt& elt(
+ int idx ///< Index of target element.
+ );
+ /// Access const element.
+ RouterAssignElt const& elt(
+ int idx ///< Index of target element.
+ ) const;
+ /// Get the number of elements.
+ uint32_t getCount() const;
+ //@}
+
+ /// Update ID for a router.
+ self& updateRouterId(
+ uint32_t addr, ///< Identifying IP address of router.
+ uint32_t rcvid, ///< New receive ID value.
+ uint32_t cno ///< New change number.
+ );
+
+ /// Get size in bytes of this structure.
+ size_t getSize() const;
+ /// Get the size of the variable part only.
+ /// This is useful for classes that put this element in their
+ /// stub structure.
+ size_t getVarSize() const;
+ /// Calculate size in bytes for @a n elements.
+ static size_t calcSize(
+ int n ///< Number of elements.
+ );
+ /// Calculate size of variable data in bytes for @a n elements.
+ static size_t calcVarSize(
+ int n ///< Number of elements.
+ );
+protected:
+ uint32_t m_count; ///< # of elements (network order).
+};
+
/// Sect 5.7.5: Capability Element
/// @note This maps directly on to message content.
class CapabilityElt {
@@ -369,31 +372,41 @@ class MaskElt {
public:
typedef MaskElt self; ///< Self reference type.
+ /// Default constructor - @b no initialization.
+ MaskElt();
+ /// Construct with specific values.
+ MaskElt(
+ uint32_t srcAddr, ///< Mask for source address.
+ uint32_t dstAddr, ///< Mask for destination address.
+ uint16_t srcPort, ///< Mask for source port.
+ uint16_t dstPort ///< Mask for destination port.
+ );
+
/// @name Accessors
//@{
/// Get source address mask field.
- uint32_t getf_src_addr_mask() const;
+ uint32_t getSrcAddr() const;
/// Set source address mask field to @a mask.
- self& setf_src_addr_mask(uint32_t mask);
+ self& setSrcAddr(uint32_t mask);
/// Get destination address field.
- uint32_t getf_dst_addr_mask() const;
+ uint32_t getDstAddr() const;
/// Set destination address field to @a mask.
- self& setf_dst_addr_mask(uint32_t mask);
+ self& setDstAddr(uint32_t mask);
/// Get source port mask field.
- uint16_t getf_src_port_mask() const;
+ uint16_t getSrcPort() const;
/// Set source port mask field to @a mask.
- self& setf_src_port_mask(uint16_t mask);
+ self& setSrcPort(uint16_t mask);
/// Get destination port mask field.
- uint16_t getf_dst_port_mask() const;
+ uint16_t getDstPort() const;
/// Set destination port mask field to @a mask.
- self& setf_dst_port_mask(uint16_t mask);
+ self& setDstPort(uint16_t mask);
//@}
protected:
- uint32_t m_src_addr_mask; ///< Source address mask.
- uint32_t m_dst_addr_mask; ///< Destination address mask.
- uint16_t m_src_port_mask; ///< Source port mask.
- uint16_t m_dst_port_mask; ///< Destination port mask.
+ uint32_t m_src_addr; ///< Source address mask.
+ uint32_t m_dst_addr; ///< Destination address mask.
+ uint16_t m_src_port; ///< Source port mask.
+ uint16_t m_dst_port; ///< Destination port mask.
};
/// Sect 5.7.8: Value element.
@@ -401,15 +414,26 @@ class ValueElt {
public:
typedef ValueElt self; ///< Self reference type.
+ /// Default constructor - @b no initialization.
+ ValueElt();
+ /// Construct a specific value.
+ ValueElt(
+ uint32_t cacheAddr, ///< Address of cache for this value.
+ uint32_t srcAddr, ///< Value for source address.
+ uint32_t dstAddr, ///< Value for destination address.
+ uint16_t srcPort, ///< Value for source port.
+ uint16_t dstPort ///< Value for destination port.
+ );
+
/// @name Accessors
//@{
uint32_t getf_src_addr() const; ///< Get source address field.
self& setf_src_addr(uint32_t addr); ///< Set source address field to @a addr.
- uint32_t getf_dst_addr() const; ///< Get destination address field.
+ uint32_t getDstAddr() const; ///< Get destination address field.
self& setf_dst_addr(uint32_t addr); ///< Set destination address field to @a addr.
uint16_t getf_src_port() const; ///< Get source port field.
self& setf_src_port(uint16_t port); ///< Set source port field to @a port.
- uint16_t getf_dst_port() const; ///< Get destination port field.
+ uint16_t getDstPort() const; ///< Get destination port field.
self& setf_dst_port(uint16_t port); ///< Set destination port field to @a port.
uint32_t getCacheAddr() const; ///< Get cache address field.
self& setCacheAddr(uint32_t addr); ///< Set cache address field to @a addr
@@ -439,38 +463,398 @@ public:
/// @name Accessors
//@{
/// Directly access contained mask element.
- MaskElt& atf_mask();
+ MaskElt& maskElt();
/// Get source address mask field.
- uint32_t getf_src_addr_mask() const;
+ uint32_t getSrcAddrMask() const;
/// Set source address mask field to @a mask.
- self& setf_src_addr_mask(uint32_t mask);
+ self& setSrcAddrMask(uint32_t mask);
/// Get destination address field.
- uint32_t getf_dst_addr_mask() const;
+ uint32_t getDstAddrMask() const;
/// Set destination address field to @a mask.
- self& setf_dst_addr_mask(uint32_t mask);
+ self& setDstAddrMask(uint32_t mask);
/// Get source port mask field.
- uint16_t getf_src_port_mask() const;
+ uint16_t getSrcPortMask() const;
/// Set source port mask field to @a mask.
- self& setf_src_port_mask(uint16_t mask);
+ self& setSrcPortMask(uint16_t mask);
/// Get destination port mask field.
- uint16_t getf_dst_port_mask() const;
+ uint16_t getDstPortMask() const;
/// Set destination port mask field to @a mask.
- self& setf_dst_port_mask(uint16_t mask);
+ self& setDstPortMask(uint16_t mask);
+
+ /// Append a value to this set.
+ self& addValue(
+ uint32_t cacheAddr, ///< Address of cache for this value.
+ uint32_t srcAddr, ///< Value for source address.
+ uint32_t dstAddr, ///< Value for destination address.
+ uint16_t srcPort, ///< Value for source port.
+ uint16_t dstPort ///< Value for destination port.
+ );
/// Get the value count.
- /// @note No corresponding @c setf_ because this cannot be safely changed.
- uint32_t getf_count() const;
+ /// @note No corresponding @c set because this cannot be directly changed.
+ uint32_t getCount() const;
/// Access value element.
ValueElt& operator [] (
int idx ///< Index of target element.
);
//@}
- /// Get the total size of this element.
- size_t calcSize() const;
+ /// Calcuate the size of an element with @a n values.
+ static size_t calcSize(
+ uint32_t n ///< Number of values.
+ );
+ /// Get the size (length) of this element.
+ size_t getSize() const;
protected:
+ // All members are kept in network order.
MaskElt m_mask; ///< Base mask element.
uint32_t m_count; ///< Number of value elements.
+
+ /// Get base address of Value elements.
+ ValueElt* values();
+ /// Get base address of Value elements.
+ ValueElt const* values() const;
+};
+
+/// Assignment of caches by hash.
+/// Not in specification.
+class HashAssignElt {
+public:
+ typedef HashAssignElt self; ///< Self reference type.
+
+ /// Hash assignment bucket.
+ struct Bucket {
+ unsigned int m_idx:7; ///< Cache index.
+ unsigned int m_alt:1; ///< Alternate hash flag.
+
+ /// Test for unassigned value in bucket.
+ bool is_unassigned() const;
+ } __attribute__((aligned(1),packed));
+
+ /// Default constructor - @b no initialization.
+ HashAssignElt();
+ /// Construct with @n elements.
+ HashAssignElt(
+ int n ///< Number of elements.
+ );
+
+ /// @name Accessors
+ //@{
+ /// Get the number of caches.
+ uint32_t getCount() const;
+ /// Get a cache address.
+ uint32_t getAddr(
+ int idx ///< Index of target address.
+ ) const;
+ /// Set a cache address.
+ self& setAddr(
+ int idx, ///< Index of target address.
+ uint32_t addr ///< Address value to set.
+ );
+ /// Access a bucket.
+ Bucket& operator [] (
+ size_t idx ///< Bucket index (0..N_BUCKETS-1)
+ );
+ /// Access a const bucket.
+ Bucket const& operator [] (
+ size_t idx ///< Bucket index (0..N_BUCKETS-1)
+ ) const;
+ //@}
+
+ /** Do a round robin assignment.
+ The buckets are assigned round robin, starting with 0, up to the
+ index of the last cache.
+ @return @c this.
+ */
+ self& round_robin_assign();
+
+ /// Get size in bytes of this structure.
+ size_t getSize() const;
+ /// Calculate size in bytes for @a n caches.
+ static size_t calcSize(
+ int n ///< Number of caches.
+ );
+protected:
+ uint32_t m_count; ///< # of caches (network order).
+
+ Bucket* getBucketBase();
+};
+
+/** Assignment of caches by mask.
+ @note Not in specification.
+
+ @internal Because this is an element, it must correspond exactly
+ to the serialized layout. Therefore we can't keep extra accounting
+ data around to make manipulation easier. We need a helper class
+ for that, which functions in a manner similar to an iterator.
+
+ @internal As a shorthand, a mask assignment of everything to a
+ single web cache can be represented by an mask/value set count of
+ 0 followed by the IP address of the target web cache. I don't know
+ if this works went sent to a router, but I observe it being
+ returned by routers in Cache Identity elements. I have verified
+ that a single count of zero with no other data is rejected by
+ at least one type of router.
+ */
+
+class MaskAssignElt {
+public:
+ typedef MaskAssignElt self; ///< Self reference type.
+
+ /// Default constructor - @b no initialization.
+ MaskAssignElt();
+
+ /** A minimalist insert iterator.
+ */
+ struct appender {
+ typedef appender self; ///< Self reference type.
+ /// Get pointer to current set.
+ MaskValueSetElt* operator -> ();
+ /// Append a new mask/value set.
+ /// @return A pointer to the new set.
+ MaskValueSetElt* mask(
+ uint32_t srcAddr, ///< Mask for source address.
+ uint32_t dstAddr, ///< Mask for destination address.
+ uint16_t srcPort, ///< Mask for source port.
+ uint16_t dstPort ///< Mask for destination port.
+ );
+ /// Initialize the current set to empty with specific mask values.
+ /// @return A pointer to the new set.
+ MaskValueSetElt* initSet(
+ uint32_t srcAddr, ///< Mask for source address.
+ uint32_t dstAddr, ///< Mask for destination address.
+ uint16_t srcPort, ///< Mask for source port.
+ uint16_t dstPort ///< Mask for destination port.
+ );
+ MaskValueSetElt* m_set; ///< Current set.
+ MaskAssignElt* m_elt; ///< Parent element.
+ };
+
+ /// @name Accessors
+ //@{
+ /// Get the number of mask/value sets.
+ uint32_t getCount() const;
+ //@}
+
+ appender init(
+ uint32_t srcAddr, ///< Mask for source address.
+ uint32_t dstAddr, ///< Mask for destination address.
+ uint16_t srcPort, ///< Mask for source port.
+ uint16_t dstPort ///< Mask for destination port.
+ );
+
+ /// Get size in bytes of this structure.
+ /// @note This is not constant time. The mask/value sets must be traversed
+ /// to get the total size.
+ size_t getSize() const;
+ /// Get the size in bytes of the variable part of this structure.
+ /// @note This is not constant time. The mask/value sets must be traversed
+ /// to get the total size.
+ size_t getVarSize() const;
+protected:
+ uint32_t m_count; ///< # of sets (network order).
+
+ friend struct appender;
+};
+
+class CacheIdBox;
+
+/** Sect 5.7.2: Web-Cache Identity Element
+ According to the specification, this is a fixed structure with
+ hash data. However, in practice there is an undocumented variant for
+ mask assignment where it contains mask data instead of hash data.
+
+ This class provides basic control. Two subclasses specialize for the
+ two variants. Use @c isMask to detect which variant is present.
+
+ @see CacheHashIdElt
+ @see CacheMaskIdElt
+*/
+class CacheIdElt {
+ friend class CacheIdBox;
+public:
+ typedef CacheIdElt self; ///< Self reference type.
+
+ /// Hash revision (protocol required).
+ static uint16_t const HASH_REVISION = 0;
+
+ /// @name Accessors
+ //@{
+ uint32_t getAddr() const; ///< Get address field.
+ self& setAddr(uint32_t addr); ///< Set address field to @a addr.
+ uint16_t getHashRev() const; ///< Get hash revision field.
+ self& setHashRev(uint16_t rev); ///< Set hash revision field to @a rev.
+ self& initHashRev(); ///< Set hash revision to default value.
+ bool getUnassigned() const; ///< Get unassigned field.
+ self& setUnassigned(bool state); ///< Set unassigned field to @a state.
+ bool isMask() const; ///< @return @c true if this is a mask assignment.
+ /** Set the maskiness of this structure.
+ Be very careful with this, as different values change the
+ memory layout of the object.
+ */
+ self& setMask(
+ bool state ///< @c true to be mask, @c false to be hash.
+ );
+
+ self& clearReserved(); ///< Set reserved bits to zero.
+ //@}
+
+protected:
+ uint32_t m_addr; ///< Identifying cache IP address.
+ uint16_t m_hash_rev; ///< Hash revision.
+ unsigned int m_reserved_0:7; ///< Reserved bits.
+ /** Cache not assigned.
+ If set the cache does not have an assignment in the redirection
+ hash table and the data in @a m_buckets is historical. This allows
+ a cache that was removed to be added back in the same buckets.
+ */
+ unsigned int m_unassigned:1;
+ unsigned int m_reserved_1:1; ///< Reserved (unused).
+ unsigned int m_is_mask:1; ///< Set -> mask, Clear -> hash.
+ unsigned int m_reserved_2:6; ///< Reserved (unused).
+ // Unfortunately, although @c weight and @c status are common, they are
+ // after the variable data and so can't be put in the base class.
+};
+
+/** Cache ID for Hash assignment.
+ */
+class CacheHashIdElt : public CacheIdElt {
+ friend class CacheIdBox;
+public:
+ typedef CacheHashIdElt self; ///< Self reference type.
+ typedef CacheIdElt super; ///< Parent type.
+ /// Container for hash assignment.
+ typedef uint8_t HashBuckets[N_BUCKETS >> 3];
+ /// @name Accessors
+ //@{
+ bool getBucket(int idx) const; ///< Get bucket state at index @a idx.
+ /// Set bucket at index @a idx to @a state.
+ self& setBucket(int idx, bool state);
+ self& setBuckets(bool state); ///< Set all buckets to @a state.
+ uint16_t getWeight() const; ///< Get weight field.
+ self& setWeight(uint16_t w); ///< Set weight field to @a w.
+ uint16_t getStatus() const; ///< Get status field.
+ self& setStatus(uint16_t s); ///< Set status field to @a s.
+ //@}
+ /// Get object size in bytes.
+ size_t getSize() const;
+protected:
+ /// Bit vector of buckets assigned to this cache.
+ HashBuckets m_buckets;
+ uint16_t m_weight; ///< Assignment weight.
+ uint16_t m_status; ///< Cache status.
+};
+
+/** Cache ID for Mask assignment.
+ Be a little careful with this object. Because it's an element and
+ must copy the serialized data layout, almost all of the methods are
+ not constant time but require walking internal data structures.
+
+ @internal Experimentally,
+ - A mask assign element count of zero does not work. It fails
+ with the wrongly descriptive message "incompatible assignment data".
+ - A single mask assign element with a mask set with one value seems to
+ work.
+ */
+class CacheMaskIdElt : public CacheIdElt {
+ friend class CacheIdBox;
+public:
+ typedef CacheMaskIdElt self; ///< Self reference type.
+ typedef CacheIdElt super; ///< Parent type.
+ /// @name Accessors
+ //@{
+ uint16_t getWeight() const; ///< Get weight field.
+ self& setWeight(uint16_t w); ///< Set weight field to @a w.
+ uint16_t getStatus() const; ///< Get status field.
+ self& setStatus(uint16_t s); ///< Set status field to @a s.
+ /// Get the number of mask/value sets.
+ uint32_t getCount() const;
+ //@}
+ /// Get object size in bytes.
+ size_t getSize() const;
+protected:
+ MaskAssignElt m_assign;
+ // m_assign is variable sized so we can't layout the weight and status.
+};
+
+/** Holder for a @c CacheIdElt.
+ This class is needed because of the restrictions on element classes and
+ because a @c CacheIdElt is a variable sized element yet we need to store
+ instances of it in other classes. This box both holds an instance and
+ handles some of the memory allocation issues involved.
+ */
+class CacheIdBox {
+public:
+ typedef CacheIdBox self; ///< Self reference type.
+
+ /// Default constructor.
+ CacheIdBox();
+
+ /// @name Accessors
+ //@{
+ /// Get the identifying cache address.
+ uint32_t getAddr() const;
+ /// Set the identifying cache address.
+ self& setAddr(
+ uint32_t ///< Identifying IP address.
+ );
+ uint16_t getHashRev() const; ///< Get hash revision field.
+ self& setHashRev(uint16_t rev); ///< Set hash revision field to @a rev.
+ self& initHashRev(); ///< Set hash revision to default value.
+ bool getUnassigned() const; ///< Get unassigned field.
+ self& setUnassigned(bool state); ///< Set unassigned field to @a state.
+ bool isMask() const; ///< @return @c true if this is a mask assignment.
+ /** Set the maskiness of this structure.
+ Be very careful with this, as different values change the
+ memory layout of the object.
+ */
+ self& setMask(
+ bool state ///< @c true to be mask, @c false to be hash.
+ );
+
+ self& clearReserved(); ///< Set reserved bits to zero.
+ //@}
+ /// Initialize to unassigned hash.
+ /// The cache address is set to @a addr.
+ self& initDefaultHash(
+ uint32_t addr ///< Identifying cache address.
+ );
+ /// Initialize to unassigned mask
+ /// The cache address is set to @a addr.
+ self& initDefaultMask(
+ uint32_t addr ///< Identifying cache address.
+ );
+ /** Fill in element from source copy.
+ Internal memory is allocated and the @a src copied.
+ */
+ self& fill(
+ self const& src ///< Original source element
+ );
+ /** Fill in element from source copy.
+ This is used to write the element to memory that is allocated
+ independently of the box.
+ @note Caller is expected to have verified sufficient buffer space.
+ */
+ self& fill(
+ void* base, ///< Target buffer.
+ self const& src ///< Original source element
+ );
+ /// Initialize box from an existing element in memory.
+ int parse(
+ MsgBuffer base ///< Source memory.
+ );
+
+ /// Get the size in bytes of the contained element.
+ size_t getSize() const;
+protected:
+ /// Force buffer to be at least @a n bytes
+ self& require(
+ size_t n ///< Minimum buffer size required.
+ );
+
+ CacheIdElt* m_base; ///< Base address of memory for element.
+ size_t m_count; ///< Size of element.
+ size_t m_size; ///< Size of allocated memory. Zero if external memory.
};
/** Base class for all components.
@@ -571,6 +955,11 @@ struct CompWithHeader : public Component
uint16_t m_type; ///< Serialized @ref CompType.
uint16_t m_length; ///< length of rest of component (not including header).
};
+ /** Size of header.
+ This is needed by all subclasses because the value in the length field
+ excludes this structure.
+ */
+ static size_t const HEADER_SIZE = sizeof(raw_t);
/// @name Accessors
//@{
@@ -872,10 +1261,6 @@ public:
};
/** Sect 5.6.4: Web-Cache Identity Info Component
-
- Although we could have just passed back the contained
- CacheIdElt, since there was only one and it's the only
- data in this component, we provide forwarding methods.
*/
class CacheIdComp
: public CompWithHeader<CacheIdComp> {
@@ -885,20 +1270,20 @@ public:
typedef CompWithHeader<self> super; ///< Parent type.
/// Component type ID for this component.
- static CompType const COMP_TYPE = WC_ID_INFO;
+ static CompType const COMP_TYPE = CACHE_ID_INFO;
/// Serialized format.
struct raw_t : public super::raw_t {
- typedef CacheIdElt::HashBuckets HashBuckets; ///< Promote.
- CacheIdElt m_id; ///< Identity element.
+ CacheIdElt m_id; ///< Identity element stub.
};
/// @name Accessors
//@{
/// Direct access to the cache ID element.
- CacheIdElt& idElt();
- CacheIdElt const& idElt() const;
+ CacheIdBox& cacheId();
+ CacheIdBox const& cacheId() const;
+ // Only forward the common ones.
uint32_t getAddr() const; ///< Get address field.
self& setAddr(uint32_t addr); ///< Set address field to @a addr.
uint16_t getHashRev() const; ///< Get hash revision field.
@@ -909,11 +1294,6 @@ public:
self& setWeight(uint16_t w); ///< Set weight field to @a w.
uint16_t getStatus() const; ///< Get status field.
self& setStatus(uint16_t s); ///< Set status field to @a s.
-
- bool getBucket(int idx) const; ///< Get bucket state at index @a idx.
- /// Set bucket at index @a idx to @a state.
- self& setBucket(int idx, bool state);
- self& setBuckets(bool state); ///< Set all buckets to @a state.
//@}
/** Write serialization data.
@@ -922,7 +1302,7 @@ public:
*/
self& fill(
MsgBuffer& base, ///< Target storage.
- CacheIdElt const& src ///< Cache descriptor
+ CacheIdBox const& src ///< Cache descriptor
);
/// Validate an existing structure.
@@ -930,7 +1310,10 @@ public:
int parse(MsgBuffer& buffer);
/// Compute the memory size of the component.
- static size_t calcSize();
+ /// Cannot be reliably computed statically.
+ size_t getSize();
+protected:
+ CacheIdBox m_box; ///< Wrapper for cache id element.
};
/** Sect 5.6.5: Router View Info Component
@@ -953,12 +1336,14 @@ public:
uint32_t m_router_count; ///< # of router elements.
};
+ RouterViewComp();
+
/// @name Accessors
//@{
/// Directly access assignment key.
- AssignmentKeyElt& key_elt();
+ AssignmentKeyElt& keyElt();
/// Directly access assignment key.
- AssignmentKeyElt const& key_elt() const;
+ AssignmentKeyElt const& keyElt() const;
/// Get address in assignment key.
uint32_t getKeyAddr() const;
/// Set address in assignment key.
@@ -976,11 +1361,11 @@ public:
/// @see fill
uint32_t getCacheCount() const;
/// Access cache element.
- CacheIdElt& cacheElt(
+ CacheIdBox& cacheId(
int idx ///< Index of target element.
);
/// Access cache element.
- CacheIdElt const& cacheElt(
+ CacheIdBox const& cacheId(
int idx ///< Index of target element.
) const;
/// Get router count field.
@@ -1013,16 +1398,13 @@ public:
/// @return Parse result.
int parse(MsgBuffer& buffer);
- /// Compute the total size of the component.
- static size_t calcSize(
- int n_routers, ///< Number of routers in view.
- int n_caches ///< Number of caches in view.
- );
-
protected:
/// Serialized count of cache addresses.
/// The actual addresses start immediate after this.
uint32_t* m_cache_count;
+ /// Wrappers for cache identity elements.
+ /// These are variably sized in the general case.
+ CacheIdBox m_cache_ids[MAX_CACHES];
/// Compute the address of the cache count field.
/// Assumes the router count field is set.
@@ -1039,7 +1421,7 @@ public:
typedef CompWithHeader<self> super; ///< Parent type.
/// Component type ID for this component.
- static CompType const COMP_TYPE = WC_VIEW_INFO;
+ static CompType const COMP_TYPE = CACHE_VIEW_INFO;
/// Stub of the serialized data.
/// There is more variable sized data that must be handled specially.
@@ -1090,9 +1472,7 @@ public:
*/
self& fill(
MsgBuffer& buffer, ///< Target storage.
- uint32_t change_number, ///< Change number.
- int n_routers, ///< Number of routers in view.
- int n_caches ///< Number of caches in view.
+ detail::cache::GroupData const& group ///< Service group information.
);
/// Validate an existing structure.
@@ -1130,16 +1510,9 @@ public:
/// There is more variable sized data that must be handled specially.
struct raw_t : public super::raw_t {
AssignmentKeyElt m_key; ///< Assignment key data.
- uint32_t m_router_count; ///< # of router assignment elements.
+ RouterAssignListElt m_routers; ///< Routers.
};
- /// Redirection bucket.
- struct Bucket {
- unsigned int m_idx:7; ///< Cache index.
- unsigned int m_alt:1; ///< Alternate hash flag.
-
- /// Test for unassigned value in bucket.
- bool is_unassigned() const;
- } __attribute__((aligned(1),packed));
+ typedef HashAssignElt::Bucket Bucket; ///< Import type.
/// @name Accessors
//@{
@@ -1161,7 +1534,7 @@ public:
/// @see fill
uint32_t getRouterCount() const;
/// Access a router assignment element.
- RouterAssignmentElt& routerElt(
+ RouterAssignElt& routerElt(
int idx ///< Index of target element.
);
/// Get cache count field.
@@ -1193,31 +1566,10 @@ public:
) const;
//@}
- /** Write serialization data.
-
- Things left undone by this method -
- - Filling in the
- - router elements
- - cache elements
-
- A client @b must call this method before updating these fields.
- */
+ /// Fill out the component from an @c Assignment.
self& fill(
MsgBuffer& buffer, ///< Target storage.
- AssignmentKeyElt const& key, ///< Assignment key.
- int n_routers, ///< Number of routers in view.
- int n_caches, ///< Number of caches in view.
- Bucket const* buckets ///< Bucket array @c N_BUCKETS long.
- );
-
- /** Copy serialization data.
- This copies the serialized data in @a that to the buffer @a base and
- updates its internal state to reference @a base. This allows constructing
- the component elsewhere and then copying it to a message buffer.
- */
- self& fill(
- MsgBuffer& base, ///< Target storage
- self const& that ///< Original to copy.
+ detail::Assignment const& assign ///< Assignment data.
);
/// Validate an existing structure.
@@ -1321,6 +1673,142 @@ protected:
mutable ServiceGroup::CacheAssignmentStyle m_cache_assign;
};
+/** Sect 5.6.10: Alternate Assignment Component
+ This is an abstract base class. It is specialized for each alternate.
+ */
+class AltAssignComp
+ : public CompWithHeader<AltAssignComp> {
+
+public:
+ typedef AltAssignComp self; ///< Self reference type.
+ typedef CompWithHeader<self> super; ///< Parent type.
+
+ /// Component type ID for this component.
+ static CompType const COMP_TYPE = ALT_ASSIGNMENT;
+ /// Alternate is hash.
+ static uint16_t const ALT_HASH_ASSIGNMENT = 0;
+ /// Alternate is mask.
+ static uint16_t const ALT_MASK_ASSIGNMENT = 1;
+
+ /// Component secondary header.
+ /// @internal Split out because we need to compute its size.
+ struct local_header_t {
+ uint16_t m_assign_type; ///< Assignment body type.
+ uint16_t m_assign_length; ///< Assignment body length.
+ };
+ /// Stub of the serialized data.
+ /// There is more variable sized data that must be handled specially.
+ struct raw_t : public super::raw_t, public local_header_t {
+ // These are the same in all current subclasses.
+ AssignmentKeyElt m_key; ///< Assignment key data.
+ RouterAssignListElt m_routers; ///< Routers.
+ };
+
+ /// @name Accessors
+ //@{
+ /// Get the assignment type.
+ uint16_t getAssignType() const;
+ /// Set the assignment type.
+ self& setAssignType(
+ uint16_t t ///< Assignment type.
+ );
+ /// Get the assignment length.
+ uint16_t getAssignLength() const;
+ /// Set the assignment length.
+ self& setAssignLength(
+ uint16_t length ///< Length in bytes.
+ );
+ /// Get router count field.
+ /// @note No @c setf method because this cannot be changed independently.
+ /// @see fill
+ uint32_t getRouterCount() const;
+ /// Directly access assignment key.
+ AssignmentKeyElt& keyElt();
+ /// Directly access assignment key.
+ AssignmentKeyElt const& keyElt() const;
+ //@}
+
+ /// Fill out the component from an @c Assignment.
+ virtual self& fill(
+ MsgBuffer& buffer, ///< Target storage.
+ detail::Assignment const& assign ///< Assignment data.
+ ) = 0;
+
+ /// Validate an existing structure.
+ /// @return Parse result.
+ virtual int parse(MsgBuffer& buffer) = 0;
+
+protected:
+ /// Calculate the first byte past the end of the variable data.
+ void* calcVarPtr();
+};
+
+/** Sect 5.6.10: Alternate Assignment Component
+ This is the hash based version.
+ */
+class AltHashAssignComp
+ : public AltAssignComp {
+
+public:
+ typedef AltHashAssignComp self; ///< Self reference type.
+ typedef AltAssignComp super; ///< Parent type.
+
+ /// @name Accessors
+ //@{
+ /// Get cache count field.
+ /// @note No @c setf method because this cannot be changed independently.
+ /// @see fill
+ uint32_t getCacheCount() const;
+ //@}
+
+ /// Fill out the component from an @c Assignment.
+ virtual self& fill(
+ MsgBuffer& buffer, ///< Target storage.
+ detail::Assignment const& assign ///< Assignment data.
+ );
+
+ /// Validate an existing structure.
+ /// @return Parse result.
+ virtual int parse(MsgBuffer& buffer);
+
+ /// Compute the total size of the component.
+ static size_t calcSize(
+ int n_routers, ///< Number of routers in view.
+ int n_caches ///< Number of caches in view.
+ );
+
+protected:
+ /// Serialized count of cache addresses.
+ /// The actual addresses start immediate after this.
+ uint32_t* m_cache_count;
+ /// Calculate the address of the cache count.
+ uint32_t* calcCacheCountPtr();
+};
+
+/** Sect 5.6.10: Alternate Assignment Component
+ This is the mask based version.
+ */
+class AltMaskAssignComp
+ : public AltAssignComp {
+
+public:
+ typedef AltMaskAssignComp self; ///< Self reference type.
+ typedef AltAssignComp super; ///< Parent type.
+
+ /// Fill out the component from an @c Assignment.
+ virtual self& fill(
+ MsgBuffer& buffer, ///< Target storage.
+ detail::Assignment const& assign ///< Assignment data.
+ );
+
+ /// Validate an existing structure.
+ /// @return Parse result.
+ virtual int parse(MsgBuffer& buffer);
+
+protected:
+ MaskAssignElt* m_mask_elt; ///< Address of the mask assign element.
+};
+
/** Sect 5.6.12: Command Info Component
*/
class CmdComp
@@ -1387,36 +1875,27 @@ public:
/// Serialized layout structure.
/// Not complete, only a stub.
struct raw_t : public super::raw_t {
- uint32_t m_count; ///< # of mask/value set elements.
+ MaskAssignElt m_assign;
};
+ /// Default constructor.
+ AssignMapComp();
+
/// @name Accessors.
//@{
- /// Directly access mask value element.
- MaskValueSetElt& elt(
- int idx ///< Index of target element.
- );
/// Get the element count.
- /// @note No corresponding @c setf_ because that cannot be changed once set.
- /// @see fill
- uint32_t getEltCount() const;
+ uint32_t getCount() const;
//@}
- /// Write basic serialization data.
- /// Elements must be filled in seperately and after invoking this method.
+ /// Fill from assignment data.
self& fill(
MsgBuffer& buffer, ///< Component storage.
- int n ///< Number of elements.
+ detail::Assignment const& assign ///< Assignment data.
);
/// Validate an existing structure.
/// @return Parse result.
int parse(MsgBuffer& buffer);
-
- /// Compute the total size of the component.
- static size_t calcSize(
- int n ///< Number of elements.
- );
};
/// Sect 5.6.8: Router Query Info Component.
@@ -1498,7 +1977,6 @@ namespace detail {
public:
typedef Assignment self; ///< Self reference type.
typedef AssignmentKeyElt Key; ///< Import assignment key type.
- typedef RouterAssignmentElt RouterKey; ///< Import type for router data.
/// Import assignment bucket definition.
/// @internal Just one byte, no serialization issues.
typedef AssignInfoComp::Bucket Bucket;
@@ -1529,48 +2007,38 @@ namespace detail {
cache::GroupData& group, ///< Service group data.
uint32_t addr ///< Identifying IP address of designated cache.
);
-
- /// Fill in a component from the data in this object.
- /// In effect, copy the serialized from this instance
- /// to a component.
- void pour(
- MsgBuffer& base, ///< Target storage.
- AssignInfoComp& comp ///< Component to fill.
- ) const;
-
- /** Test this assignment against a component.
- @return @c true if the assignments are the same, @c false otherwise.
- */
- bool compare(AssignInfoComp const& comp) const;
-
- /// Access a bucket.
- Bucket& operator [] (
- size_t idx ///< Bucket index (0..N_BUCKETS-1)
+ /// Update the receive ID for a router.
+ self& updateRouterId(
+ uint32_t addr, ///< Identifying IP address of router.
+ uint32_t rcvid, ///< New receive ID.
+ uint32_t cno ///< New change number.
);
- /// Access a bucket.
- Bucket const& operator [] (
- size_t idx ///< Bucket index (0..N_BUCKETS-1)
- ) const;
+
+ /// Get the assignment key.
+ AssignmentKeyElt const* getKey() const;
+ /// Get the router assignment list.
+ RouterAssignListElt const* getRouterList() const;
+ /// Get the hash assignment.
+ HashAssignElt const* getHash() const;
+ /// Get the mask assignment.
+ MaskAssignElt const* getMask() const;
protected:
Key m_key; ///< Assignment key.
bool m_active; ///< Active state.
- mutable bool m_dirty; ///< Cache dirty flag.
- typedef std::vector<RouterKey> RouterKeys; ///< Group of router keys.
- RouterKeys m_router_keys; ///< Routers participating in assignment.
- typedef std::vector<uint32_t> CacheAddrs; ///< Vector of cache IP addresses.
- CacheAddrs m_cache_addrs; ///< Caches participating in assignment.
- /// Assignment buckets. Values are indices to @a m_caches.
- Bucket m_buckets[N_BUCKETS];
+ // These store the serialized assignment chunks which are assembled
+ // in to the components as needed. Each points in to the serialization
+ // buffer, or is @c NULL if that assignment data isn't valid.
+ /// Router assignments.
+ RouterAssignListElt *m_router_list;
+ /// Hash assignment.
+ HashAssignElt *m_hash_assign;
+ /// Mask assignment.
+ MaskAssignElt *m_mask_assign;
- /// Cached serialization.
- mutable AssignInfoComp m_comp;
/// Buffer for serialization.
- mutable MsgBuffer m_buffer;
-
- /// Discard current serialized cache and regenerate it.
- void generate() const;
+ MsgBuffer m_buffer;
};
namespace endpoint {
@@ -1655,9 +2123,7 @@ public:
*/
void fill(
detail::cache::GroupData const& group, ///< Service group for message.
- SecurityOption sec_opt, ///< Security option to use.
- int n_routers, ///< Number of routers expected.
- int n_caches ///< Number of caches expected.
+ SecurityOption sec_opt ///< Security option to use.
);
/** Fill in optional capabilities.
The capabilities component is added only if the @a router
@@ -1727,10 +2193,7 @@ public:
*/
void fill(
detail::cache::GroupData const& group, ///< Service group for message.
- SecurityOption sec_opt, ///< Security option to use.
- AssignmentKeyElt const& key, ///< Assignment key.
- int n_routers, ///< Number of routers expected.
- int n_caches ///< Number of caches expected.
+ SecurityOption sec_opt ///< Security option to use.
);
/// Parse message data, presumed to be of this type.
@@ -1739,8 +2202,9 @@ public:
);
// Only one of these should be present in an instance.
- AssignInfoComp m_assign; ///< Primary assignment data.
- AssignMapComp m_alt_assign; ///< Alternate assignment data.
+ AssignInfoComp m_hash_assign; ///< Primary (hash) assignment.
+ AltHashAssignComp m_alt_hash_assign; ///< Alternate (hash) assignment.
+ AltMaskAssignComp m_alt_mask_assign; ///< Alternate (mask) assignment.
};
/// Sect 5.4: @c WCCP_REMOVAL_QUERY
@@ -1901,7 +2365,7 @@ namespace detail {
/// Get the identifying IP address for this cache.
uint32_t idAddr() const;
/// Cache identity data.
- CacheIdElt m_id;
+ CacheIdBox m_id;
/// Last time this cache was mentioned by the routers.
/// Indexed in parallel to the routers.
std::vector<PacketStamp> m_src;
@@ -1976,7 +2440,7 @@ namespace detail {
typedef endpoint::GroupData super; ///< Parent type.
/// Cache identity of this cache.
- CacheIdElt m_id;
+ CacheIdBox m_id;
/// Packet forwarding methods supported.
ServiceGroup::PacketStyle m_packet_forward;
@@ -2135,7 +2599,6 @@ protected:
RedirectAssignMsg& msg, ///< Message with allocated buffer.
GroupData& group ///< Group with data for message.
);
-
/// Process HERE_I_AM message.
virtual ts::Errata handleISeeYou(
IpHeader const& header, ///< IP packet data.
@@ -2180,7 +2643,7 @@ namespace detail {
//// Stamp for last packet received from this cache.
PacketStamp m_recv;
- CacheIdElt m_id; ///< Transmitted cache descriptor.
+ CacheIdBox m_id; ///< Transmitted cache descriptor.
uint32_t m_target_addr; ///< Target address of last packet.
};
@@ -2309,15 +2772,104 @@ RouterIdElt::operator = (super const& th
return this->setAddr(that.m_addr).setRecvId(that.m_recv_id);
}
-inline SecurityComp::SecurityComp() : m_local_key(false) { }
-inline void SecurityComp::setDefaultOption(Option opt) {
- m_default_opt = opt;
+inline MaskElt::MaskElt() { }
+
+inline MaskElt::MaskElt(
+ uint32_t srcAddr,
+ uint32_t dstAddr,
+ uint16_t srcPort,
+ uint16_t dstPort
+) : m_src_addr(srcAddr)
+ , m_dst_addr(dstAddr)
+ , m_src_port(srcPort)
+ , m_dst_port(dstPort) {
+}
+
+inline uint32_t MaskElt::getSrcAddr() const { return ntohl(m_src_addr); }
+inline MaskElt& MaskElt::setSrcAddr(uint32_t mask) { m_src_addr = htonl(mask); return *this; }
+inline uint32_t MaskElt::getDstAddr() const { return ntohl(m_dst_addr); }
+inline MaskElt& MaskElt::setDstAddr(uint32_t mask) { m_dst_addr = htonl(mask); return *this; }
+inline uint16_t MaskElt::getSrcPort() const { return ntohs(m_src_port); }
+inline MaskElt& MaskElt::setSrcPort(uint16_t mask) { m_src_port = htons(mask); return *this; }
+inline uint16_t MaskElt::getDstPort() const { return ntohs(m_dst_port);}
+inline MaskElt& MaskElt::setDstPort(uint16_t mask) { m_dst_port = htons(mask); return *this; }
+
+inline ValueElt::ValueElt() { }
+
+inline ValueElt::ValueElt(
+ uint32_t cacheAddr,
+ uint32_t srcAddr,
+ uint32_t dstAddr,
+ uint16_t srcPort,
+ uint16_t dstPort
+) : m_src_addr(srcAddr)
+ , m_dst_addr(dstAddr)
+ , m_src_port(srcPort)
+ , m_dst_port(dstPort)
+ , m_cache_addr(cacheAddr) {
+}
+
+inline MaskValueSetElt::MaskValueSetElt() { }
+inline MaskValueSetElt::MaskValueSetElt(uint32_t count) : m_count(count) { }
+inline MaskElt& MaskValueSetElt::maskElt() { return m_mask; }
+inline uint32_t MaskValueSetElt::getCount() const { return ntohl(m_count); }
+
+inline uint32_t
+MaskValueSetElt::getSrcAddrMask() const {
+ return m_mask.getSrcAddr();
+}
+inline MaskValueSetElt&
+MaskValueSetElt::setSrcAddrMask(uint32_t mask) {
+ m_mask.setSrcAddr(mask);
+ return *this;
+}
+inline uint32_t
+MaskValueSetElt::getDstAddrMask() const {
+ return m_mask.getDstAddr();
+}
+inline MaskValueSetElt&
+MaskValueSetElt::setDstAddrMask(uint32_t mask) {
+ m_mask.setDstAddr(mask);
+ return *this;
+}
+inline uint16_t
+MaskValueSetElt::getSrcPortMask() const {
+ return m_mask.getSrcPort();
+}
+inline MaskValueSetElt&
+MaskValueSetElt::setSrcPortMask(uint16_t mask) {
+ m_mask.setSrcPort(mask);
+ return *this;
+}
+inline uint16_t
+MaskValueSetElt::getDstPortMask() const {
+ return m_mask.getDstPort();
+}
+inline MaskValueSetElt&
+MaskValueSetElt::setDstPortMask(uint16_t mask) {
+ m_mask.setDstPort(mask);
+ return *this;
+}
+inline ValueElt*
+MaskValueSetElt::values() {
+ return reinterpret_cast<ValueElt*>(this+1);
+}
+inline ValueElt const*
+MaskValueSetElt::values() const {
+ return const_cast<self*>(this)->values();
}
inline size_t
-SecurityComp::calcSize(Option opt) {
- return SECURITY_NONE == opt ? sizeof(RawNone) : sizeof(RawMD5);
+MaskValueSetElt::calcSize(uint32_t n) {
+ return sizeof(self) + n * sizeof(ValueElt);
+}
+inline size_t
+MaskValueSetElt::getSize() const {
+ return self::calcSize(ntohl(m_count));
}
+inline size_t
+MaskAssignElt::getSize() const { return sizeof(self) + this->getVarSize(); }
+
inline uint32_t CacheIdElt::getAddr() const { return m_addr; }
inline CacheIdElt&
CacheIdElt::setAddr(uint32_t addr) {
@@ -2330,12 +2882,32 @@ CacheIdElt::setHashRev(uint16_t addr) {
m_hash_rev = htons(addr);
return *this;
}
+inline CacheIdElt&
+CacheIdElt::initHashRev() {
+ this->setHashRev(HASH_REVISION);
+ return *this;
+}
inline bool CacheIdElt::getUnassigned() const { return 1 == m_unassigned; }
inline CacheIdElt&
CacheIdElt::setUnassigned(bool state) {
m_unassigned = state ? 1 : 0;
return *this;
}
+inline CacheIdElt&
+CacheIdElt::clearReserved() {
+ m_reserved_0 = 0;
+ m_reserved_1 = 0;
+ m_reserved_2 = 0;
+ return *this;
+}
+inline bool CacheIdElt::isMask() const { return 1 == m_is_mask; }
+inline CacheIdElt&
+CacheIdElt::setMask(bool state) {
+ m_is_mask = state ? 1 : 0;
+ return *this;
+}
+
+# if 0
inline uint16_t CacheIdElt::getWeight() const { return ntohs(m_weight); }
inline CacheIdElt&
CacheIdElt::setWeight(uint16_t w) {
@@ -2348,14 +2920,33 @@ CacheIdElt::setStatus(uint16_t s) {
m_status = htons(s);
return *this;
}
+# endif
+
+# if 0
inline bool
-CacheIdElt::getBucket(int idx) const {
+CacheHashIdElt::getBucket(int idx) const {
return 0 != (m_buckets[idx>>3] & (1<<(idx & 7)));
}
-inline CacheIdElt&
-CacheIdElt::clearReserved() {
- m_reserved_0 = 0;
- m_reserved_1 = 0;
+# endif
+
+inline uint32_t
+CacheMaskIdElt::getCount() const {
+ return m_assign.getCount();
+}
+
+inline size_t
+CacheMaskIdElt::getSize() const {
+ return sizeof(self) + m_assign.getVarSize();
+}
+
+inline uint32_t
+CacheIdBox::getAddr() const {
+ return m_base->getAddr();
+}
+
+inline CacheIdBox&
+CacheIdBox::setAddr(uint32_t addr) {
+ m_base->setAddr(addr);
return *this;
}
@@ -2382,7 +2973,7 @@ AssignmentKeyElt::setChangeNumber(uint32
return *this;
}
-inline RouterAssignmentElt::RouterAssignmentElt(
+inline RouterAssignElt::RouterAssignElt(
uint32_t addr,
uint32_t recv_id,
uint32_t change_number
@@ -2391,15 +2982,24 @@ inline RouterAssignmentElt::RouterAssign
, m_change_number(htonl(change_number)) {
}
inline uint32_t
-RouterAssignmentElt::getChangeNumber() const {
+RouterAssignElt::getChangeNumber() const {
return ntohl(m_change_number);
}
-inline RouterAssignmentElt&
-RouterAssignmentElt::setChangeNumber(uint32_t n) {
+inline RouterAssignElt&
+RouterAssignElt::setChangeNumber(uint32_t n) {
m_change_number = htonl(n);
return *this;
}
+inline SecurityComp::SecurityComp() : m_local_key(false) { }
+inline void SecurityComp::setDefaultOption(Option opt) {
+ m_default_opt = opt;
+}
+inline size_t
+SecurityComp::calcSize(Option opt) {
+ return SECURITY_NONE == opt ? sizeof(RawNone) : sizeof(RawMD5);
+}
+
inline ServiceComp::ServiceComp () : m_port_count(0) { }
inline ServiceComp::raw_t*
ServiceComp::access() {
@@ -2481,62 +3081,57 @@ RouterIdComp::calcSize(int n) {
inline uint32_t
RouterViewComp::getKeyAddr() const {
- return this->key_elt().getAddr();
+ return this->keyElt().getAddr();
}
inline RouterViewComp&
RouterViewComp::setKeyAddr(uint32_t addr) {
- this->key_elt().setAddr(addr);
+ this->keyElt().setAddr(addr);
return *this;
}
inline uint32_t
RouterViewComp::getKeyChangeNumber() const {
- return this->key_elt().getChangeNumber();
+ return this->keyElt().getChangeNumber();
}
inline RouterViewComp&
RouterViewComp::setKeyChangeNumber(uint32_t change_number) {
- this->key_elt().setChangeNumber(change_number);
+ this->keyElt().setChangeNumber(change_number);
return *this;
}
-inline CacheIdElt const&
-RouterViewComp::cacheElt(int idx) const {
- return const_cast<self*>(this)->cacheElt(idx);
+inline CacheIdBox const&
+RouterViewComp::cacheId(int idx) const {
+ return const_cast<self*>(this)->cacheId(idx);
}
-inline CacheIdElt&
-CacheIdComp::idElt() {
- return access_field(&raw_t::m_id, m_base);
-}
-inline CacheIdElt const&
-CacheIdComp::idElt() const {
- return access_field(&raw_t::m_id, m_base);
-}
+inline CacheIdBox& CacheIdComp::cacheId() { return m_box; }
+inline CacheIdBox const& CacheIdComp::cacheId() const { return m_box; }
inline uint32_t
CacheIdComp::getAddr() const {
- return this->idElt().getAddr();
+ return this->cacheId().getAddr();
}
inline CacheIdComp&
CacheIdComp::setAddr(uint32_t addr) {
- this->idElt().setAddr(addr);
+ this->cacheId().setAddr(addr);
return *this;
}
inline uint16_t
CacheIdComp::getHashRev() const {
- return this->idElt().getHashRev();
+ return this->cacheId().getHashRev();
}
inline CacheIdComp&
CacheIdComp::setHashRev(uint16_t rev) {
- this->idElt().setHashRev(rev);
+ this->cacheId().setHashRev(rev);
return *this;
}
inline bool
CacheIdComp::getUnassigned() const {
- return this->idElt().getUnassigned();
+ return this->cacheId().getUnassigned();
}
inline CacheIdComp&
CacheIdComp::setUnassigned(bool state) {
- this->idElt().setUnassigned(state);
+ this->cacheId().setUnassigned(state);
return *this;
}
+# if 0
inline uint16_t
CacheIdComp::getWeight() const {
return this->idElt().getWeight();
@@ -2570,6 +3165,7 @@ CacheIdComp::setBuckets(bool state) {
return *this;
}
inline size_t CacheIdComp::calcSize() { return sizeof(raw_t); }
+# endif
inline bool detail::Assignment::isActive() const { return m_active; }
inline detail::Assignment&
@@ -2577,14 +3173,27 @@ detail::Assignment::setActive(bool state
m_active = state;
return *this;
}
-inline bool detail::Assignment::compare(AssignInfoComp const& comp) const {
- return comp.compare(m_buckets);
-}
-inline detail::Assignment::Bucket& detail::Assignment::operator[] (size_t idx) {
- return m_buckets[idx];
+inline detail::Assignment&
+detail::Assignment::updateRouterId(uint32_t addr, uint32_t rcvid, uint32_t cno) {
+ if (m_router_list) m_router_list->updateRouterId(addr, rcvid, cno);
+ return *this;
}
-inline detail::Assignment::Bucket const& detail::Assignment::operator[] (size_t idx) const {
- return m_buckets[idx];
+inline AssignmentKeyElt::AssignmentKeyElt() { }
+inline AssignmentKeyElt const*
+detail::Assignment::getKey() const {
+ return &m_key;
+}
+inline RouterAssignListElt const*
+detail::Assignment::getRouterList() const {
+ return m_router_list;
+}
+inline HashAssignElt const*
+detail::Assignment::getHash() const {
+ return m_hash_assign;
+}
+inline MaskAssignElt const*
+detail::Assignment::getMask() const {
+ return m_mask_assign;
}
inline MsgBuffer::MsgBuffer() : super(0,0), _count(0) { }
@@ -2640,7 +3249,115 @@ inline ServiceGroup::ServiceGroup() {
}
inline RouterIdElt::RouterIdElt() { }
-inline RouterAssignmentElt::RouterAssignmentElt() : m_change_number(0) { }
+inline RouterAssignElt::RouterAssignElt() : m_change_number(0) { }
+
+inline RouterAssignListElt::RouterAssignListElt() {}
+inline RouterAssignListElt::RouterAssignListElt(int n) : m_count(htonl(n)) {}
+inline RouterAssignElt&
+RouterAssignListElt::elt(int n) {
+ return access_array<RouterAssignElt>(this + 1)[n];
+}
+inline RouterAssignElt const&
+RouterAssignListElt::elt(int n) const {
+ return const_cast<self*>(this)->elt(n);
+}
+inline size_t
+RouterAssignListElt::calcVarSize(int n) {
+ return n * sizeof(RouterAssignElt);
+}
+inline size_t
+RouterAssignListElt::calcSize(int n) {
+ return sizeof(self) + self::calcVarSize(n);
+}
+inline size_t
+RouterAssignListElt::getSize() const {
+ return this->calcSize(this->getCount());
+}
+inline size_t
+RouterAssignListElt::getVarSize() const {
+ return this->getSize() - sizeof(self);
+}
+inline uint32_t RouterAssignListElt::getCount() const { return ntohl(m_count); }
+
+inline HashAssignElt::HashAssignElt () { }
+inline HashAssignElt::HashAssignElt (int n) : m_count(htonl(n)) { }
+inline uint32_t HashAssignElt::getCount() const { return ntohl(m_count); }
+inline size_t
+HashAssignElt::calcSize(int n) {
+ return sizeof(self) + n * sizeof(uint32_t) + sizeof(Bucket) * N_BUCKETS;
+}
+inline size_t
+HashAssignElt::getSize() const {
+ return self::calcSize(this->getCount());
+}
+inline uint32_t
+HashAssignElt::getAddr(int idx) const {
+ return (&m_count)[idx+1];
+}
+inline HashAssignElt&
+HashAssignElt::setAddr(int idx, uint32_t addr) {
+ (&m_count)[idx+1] = addr;
+ return *this;
+}
+inline HashAssignElt::Bucket*
+HashAssignElt::getBucketBase() {
+ return reinterpret_cast<Bucket*>((&m_count + 1 + this->getCount()));
+}
+inline HashAssignElt::Bucket&
+HashAssignElt::operator [] (size_t idx) {
+ return this->getBucketBase()[idx];
+}
+inline HashAssignElt::Bucket const&
+HashAssignElt::operator [] (size_t idx) const {
+ return (*(const_cast<self*>(this)))[idx];
+}
+
+inline MaskAssignElt::MaskAssignElt() {}
+inline uint32_t MaskAssignElt::getCount() const { return ntohl(m_count); }
+inline MaskValueSetElt* MaskAssignElt::appender::operator -> () {
+ return m_set;
+}
+inline MaskValueSetElt* MaskAssignElt::appender::initSet(
+ uint32_t srcAddr,
+ uint32_t dstAddr,
+ uint16_t srcPort,
+ uint16_t dstPort
+) {
+ (*(new (m_set) MaskValueSetElt(0)))
+ .setSrcAddrMask(srcAddr)
+ .setDstAddrMask(dstAddr)
+ .setSrcPortMask(srcPort)
+ .setDstPortMask(dstPort)
+ ;
+ return m_set;
+}
+inline MaskValueSetElt* MaskAssignElt::appender::mask(
+ uint32_t srcAddr,
+ uint32_t dstAddr,
+ uint16_t srcPort,
+ uint16_t dstPort
+) {
+ m_set = reinterpret_cast<MaskValueSetElt*>(
+ reinterpret_cast<char*>(m_set) + m_set->getSize()
+ );
+ m_elt->m_count = htonl(1 + m_elt->getCount()); // bump set count.
+ this->initSet(srcAddr, dstAddr, srcPort, dstPort);
+ return m_set;
+}
+inline MaskAssignElt::appender
+MaskAssignElt::init(
+ uint32_t srcAddr,
+ uint32_t dstAddr,
+ uint16_t srcPort,
+ uint16_t dstPort
+) {
+ appender zret;
+ m_count = htonl(1);
+ zret.m_set = reinterpret_cast<MaskValueSetElt*>(this+1);
+ zret.m_elt = this;
+ zret.initSet(srcAddr, dstAddr, srcPort, dstPort);
+ return zret;
+}
inline ComponentBase::ComponentBase() : m_base(0) { }
inline bool ComponentBase::isEmpty() const { return 0 == m_base; }
@@ -2700,6 +3417,11 @@ inline bool AssignInfoComp::compare(Buck
return 0 == memcmp(buckets, m_buckets, sizeof(buckets));
}
+inline RouterViewComp::RouterViewComp()
+ : m_cache_count(0) {
+ memset(m_cache_ids, 0, sizeof(m_cache_ids));
+}
+
inline CapComp::CapComp() : m_count(0), m_cached(false) { }
inline CapComp& CapComp::invalidate() { m_cached = false; return *this; }
inline uint32_t CapComp::getEltCount() const { return this->m_count; }
@@ -2720,6 +3442,37 @@ CapComp::getCacheAssignmentStyle() const
return m_cache_assign;
}
+inline AssignMapComp::AssignMapComp() { }
+
+/* Implementation note: Due to a bug in gcc, we have to be
+ careful with these fields. If we use the field access templates
+ directly, we get bad results because the pointer to member matching
+ is done incorrectly (it uses a super type, not @c raw_t). We work
+ around this by putting the pointer to member in a static variable.
+*/
+inline uint16_t
+AltAssignComp::getAssignType() const {
+ static uint16_t raw_t::*mptr = &raw_t::m_assign_type;
+ return get_field(mptr, m_base);
+}
+inline AltAssignComp&
+AltAssignComp::setAssignType(uint16_t t) {
+ static uint16_t raw_t::*mptr = &raw_t::m_assign_type;
+ set_field(mptr, m_base, t);
+ return *this;
+}
+inline uint16_t
+AltAssignComp::getAssignLength() const {
+ static uint16_t raw_t::*mptr = &raw_t::m_assign_length;
+ return get_field(mptr, m_base);
+}
+inline AltAssignComp&
+AltAssignComp::setAssignLength(uint16_t length) {
+ static uint16_t raw_t::*mptr = &raw_t::m_assign_length;
+ set_field(mptr, m_base, length);
+ return *this;
+}
+
inline uint32_t QueryComp::getRouterAddr() const {
return access_field(&raw_t::m_router_addr, m_base);
}