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 [2/2] - in /trafficserver/traffic/trunk/proxy/wccp:
Wccp.h WccpEndPoint.cc WccpLocal.h WccpMsg.cc WccpStatic.cc WccpUtil.h
Modified: trafficserver/traffic/trunk/proxy/wccp/WccpMsg.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/wccp/WccpMsg.cc?rev=1067578&r1=1067577&r2=1067578&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/wccp/WccpMsg.cc (original)
+++ trafficserver/traffic/trunk/proxy/wccp/WccpMsg.cc Sun Feb 6 02:57:11 2011
@@ -60,8 +60,8 @@ ServiceGroup::operator == (self const& t
}
// ------------------------------------------------------
// ------------------------------------------------------
-CacheIdElt&
-CacheIdElt::setBucket(int idx, bool state) {
+CacheHashIdElt&
+CacheHashIdElt::setBucket(int idx, bool state) {
uint8_t& bucket = m_buckets[idx>>3];
uint8_t mask = 1 << (idx & 7);
if (state) bucket |= mask;
@@ -69,11 +69,98 @@ CacheIdElt::setBucket(int idx, bool stat
return *this;
}
-CacheIdElt&
-CacheIdElt::setBuckets(bool state) {
+CacheHashIdElt&
+CacheHashIdElt::setBuckets(bool state) {
memset(m_buckets, state ? 0xFF : 0, sizeof(m_buckets));
return *this;
}
+
+CacheIdBox::CacheIdBox()
+ : m_base(0)
+ , m_count(0)
+ , m_size(0)
+{
+}
+
+size_t CacheIdBox::getSize() const { return m_count; }
+
+CacheIdBox&
+CacheIdBox::require(size_t n) {
+ if (m_size < n) {
+ if (m_base && m_size) free(m_base);
+ m_base = static_cast<CacheIdElt*>(malloc(n));
+ m_size = n;
+ }
+ memset(m_base, 0, m_size);
+ m_count = 0;
+ return *this;
+}
+
+CacheIdBox&
+CacheIdBox::initDefaultHash(uint32_t addr) {
+ this->require(sizeof(CacheHashIdElt));
+ m_count = sizeof(CacheHashIdElt);
+ m_base->initHashRev().setUnassigned(true).setMask(false).setAddr(addr);
+ return *this;
+}
+CacheIdBox&
+CacheIdBox::initDefaultMask(uint32_t addr) {
+ this->require(sizeof(CacheMaskIdElt));
+ CacheMaskIdElt* mid = static_cast<CacheMaskIdElt*>(m_base);
+ mid->initHashRev().setUnassigned(true).setMask(true).setAddr(addr);
+ mid->m_assign.init(0,0,0,0)->addValue(addr, 0, 0, 0, 0);
+ m_count = mid->getSize();
+ return *this;
+}
+
+CacheIdBox&
+CacheIdBox::fill(self const& src) {
+ size_t n = src.getSize();
+ this->require(src.getSize());
+ memcpy(m_base, src.m_base, n);
+ return *this;
+}
+
+CacheIdBox&
+CacheIdBox::fill(void* base, self const& src) {
+ m_count = src.getSize();
+ m_size = 0;
+ m_base = static_cast<CacheIdElt*>(base);
+ memcpy(m_base, src.m_base, m_count);
+ return *this;
+}
+
+int
+CacheIdBox::parse(MsgBuffer base) {
+ int zret = PARSE_SUCCESS;
+ CacheIdElt* ptr = reinterpret_cast<CacheIdElt*>(base.getTail());
+ size_t n = base.getSpace();
+ m_size = 0;
+ if (ptr->isMask()) {
+ CacheMaskIdElt* mptr = static_cast<CacheMaskIdElt*>(ptr);
+ size_t size = sizeof(CacheMaskIdElt);
+ // Sanity check - verify enough room for empty elements.
+ if (n < size
+ || n < size + MaskValueSetElt::calcSize(0) * mptr->getCount()) {
+ zret = PARSE_BUFFER_TOO_SMALL;
+ } else {
+ m_count = mptr->getSize();
+ if (n < m_count) {
+ zret = PARSE_BUFFER_TOO_SMALL;
+ logf(LVL_DEBUG, "I_SEE_YOU Cache Mask ID too small: %lu < %lu", n, m_count);
+ }
+ }
+ } else {
+ if (n < sizeof(CacheHashIdElt)) {
+ zret = PARSE_BUFFER_TOO_SMALL;
+ logf(LVL_DEBUG, "I_SEE_YOU Cache Hash ID too small: %lu < %lu", n, sizeof(CacheHashIdElt));
+ } else {
+ m_count = sizeof(CacheHashIdElt);
+ }
+ }
+ if (PARSE_SUCCESS == zret) m_base = ptr;
+ return zret;
+}
// ------------------------------------------------------
inline CapabilityElt::Type
CapabilityElt::getCapType() const {
@@ -107,50 +194,6 @@ CapabilityElt::CapabilityElt(Type cap, u
}
// ------------------------------------------------------
inline uint32_t
-MaskElt::getf_src_addr_mask() const {
- return ntohl(m_src_addr_mask);
-}
-
-inline MaskElt&
-MaskElt::setf_src_addr_mask(uint32_t mask) {
- m_src_addr_mask = htonl(mask);
- return *this;
-}
-
-inline uint32_t
-MaskElt::getf_dst_addr_mask() const {
- return ntohl(m_dst_addr_mask);
-}
-
-inline MaskElt&
-MaskElt::setf_dst_addr_mask(uint32_t mask) {
- m_dst_addr_mask = htonl(mask);
- return *this;
-}
-
-inline uint16_t
-MaskElt::getf_src_port_mask() const {
- return ntohs(m_src_port_mask);
-}
-
-inline MaskElt&
-MaskElt::setf_src_port_mask(uint16_t mask) {
- m_src_port_mask = htons(mask);
- return *this;
-}
-
-inline uint16_t
-MaskElt::getf_dst_port_mask() const {
- return ntohs(m_dst_port_mask);
-}
-
-inline MaskElt&
-MaskElt::setf_dst_port_mask(uint16_t mask) {
- m_dst_port_mask = htons(mask);
- return *this;
-}
-// ------------------------------------------------------
-inline uint32_t
ValueElt::getf_src_addr() const {
return ntohl(m_src_addr);
}
@@ -162,7 +205,7 @@ ValueElt::setf_src_addr(uint32_t addr) {
}
inline uint32_t
-ValueElt::getf_dst_addr() const {
+ValueElt::getDstAddr() const {
return ntohl(m_dst_addr);
}
@@ -184,7 +227,7 @@ ValueElt::setf_src_port(uint16_t port) {
}
inline uint16_t
-ValueElt::getf_dst_port() const {
+ValueElt::getDstPort() const {
return ntohs(m_dst_port);
}
@@ -205,69 +248,69 @@ ValueElt::setCacheAddr(uint32_t addr) {
return *this;
}
// ------------------------------------------------------
-MaskValueSetElt::MaskValueSetElt() {
-}
-
-MaskValueSetElt::MaskValueSetElt(uint32_t count)
- : m_count(count) {
-}
-
-inline size_t
-MaskValueSetElt::calcSize() const {
- return sizeof(self) + ntohl(m_count) * sizeof(ValueElt);
-}
-
-inline MaskElt&
-MaskValueSetElt::atf_mask() {
- return m_mask;
-}
-
-inline uint32_t
-MaskValueSetElt::getf_count() const {
- return ntohl(m_count);
-}
-
-inline uint32_t
-MaskValueSetElt::getf_src_addr_mask() const {
- return m_mask.getf_src_addr_mask();
-}
-
-inline MaskValueSetElt&
-MaskValueSetElt::setf_src_addr_mask(uint32_t mask) {
- m_mask.setf_src_addr_mask(mask);
- return *this;
-}
-
-inline uint32_t
-MaskValueSetElt::getf_dst_addr_mask() const {
- return m_mask.getf_dst_addr_mask();
-}
-
-inline MaskValueSetElt&
-MaskValueSetElt::setf_dst_addr_mask(uint32_t mask) {
- m_mask.setf_dst_addr_mask(mask);
+MaskValueSetElt&
+MaskValueSetElt::addValue(
+ uint32_t cacheAddr,
+ uint32_t srcAddr,
+ uint32_t dstAddr,
+ uint16_t srcPort,
+ uint16_t dstPort
+) {
+ uint32_t idx = ntohl(m_count);
+ new (this->values() + idx) ValueElt(cacheAddr, srcAddr, dstAddr, srcPort, dstPort);
+ m_count = htonl(idx + 1);
return *this;
}
-inline uint16_t
-MaskValueSetElt::getf_src_port_mask() const {
- return m_mask.getf_src_port_mask();
+size_t
+MaskAssignElt::getVarSize() const {
+ size_t zret = 0;
+ int n = this->getCount();
+
+ // Special case - if the count is zero, the rest of the data is just
+ // the target IP address.
+ if (0 == n) return sizeof(uint32_t);
+
+ MaskValueSetElt const* set = reinterpret_cast<MaskValueSetElt const*>(this+1);
+ while (n--) {
+ size_t k = set->getSize();
+ zret += k;
+ set = reinterpret_cast<MaskValueSetElt const*>(
+ reinterpret_cast<char const*>(set) + k
+ );
+ }
+ return zret;
}
-inline MaskValueSetElt&
-MaskValueSetElt::setf_src_port_mask(uint16_t mask) {
- m_mask.setf_src_port_mask(mask);
+HashAssignElt&
+HashAssignElt::round_robin_assign() {
+ uint32_t v_caches = this->getCount();
+ Bucket* buckets = this->getBucketBase();
+ if (1 == v_caches) memset(buckets, 0, sizeof(Bucket) * N_BUCKETS);
+ else { // Assign round robin.
+ size_t x = 0;
+ for ( Bucket *spot = buckets, *limit = spot + N_BUCKETS;
+ spot < limit;
+ ++spot
+ ) {
+ spot->m_idx = x;
+ spot->m_alt = 0;
+ x = ( x + 1 ) % v_caches;
+ }
+ }
return *this;
}
-inline uint16_t
-MaskValueSetElt::getf_dst_port_mask() const {
- return m_mask.getf_dst_port_mask();
-}
-
-inline MaskValueSetElt&
-MaskValueSetElt::setf_dst_port_mask(uint16_t mask) {
- m_mask.setf_dst_port_mask(mask);
+RouterAssignListElt&
+RouterAssignListElt::updateRouterId(uint32_t addr, uint32_t rcvid, uint32_t cno) {
+ uint32_t n = this->getCount();
+ RouterAssignElt* elt = access_array<RouterAssignElt>(this+1);
+ for ( uint32_t i = 0 ; i < n ; ++i, ++elt ) {
+ if (addr == elt->getAddr()) {
+ elt->setChangeNumber(cno).setRecvId(rcvid);
+ break;
+ }
+ }
return *this;
}
// ------------------------------------------------------
@@ -654,12 +697,12 @@ RouterIdComp::parse(MsgBuffer& buffer) {
}
// ------------------------------------------------------
AssignmentKeyElt&
-RouterViewComp::key_elt() {
+RouterViewComp::keyElt() {
return access_field(&raw_t::m_key, m_base);
}
AssignmentKeyElt const&
-RouterViewComp::key_elt() const {
+RouterViewComp::keyElt() const {
return access_field(&raw_t::m_key, m_base);
}
@@ -684,9 +727,9 @@ RouterViewComp::getRouterCount() const {
return get_field(&raw_t::m_router_count, m_base);
}
-CacheIdElt&
-RouterViewComp::cacheElt(int idx) {
- return reinterpret_cast<CacheIdElt*>(m_cache_count+1)[idx];
+CacheIdBox&
+RouterViewComp::cacheId(int idx) {
+ return m_cache_ids[idx];
}
uint32_t
@@ -700,14 +743,6 @@ RouterViewComp::setRouterAddr(int idx, u
return *this;
}
-size_t
-RouterViewComp::calcSize(int n_routers, int n_caches) {
- return sizeof(raw_t)
- + n_routers * sizeof(uint32_t)
- + sizeof(uint32_t) + n_caches * sizeof(CacheIdElt)
- ;
-}
-
uint32_t*
RouterViewComp::calc_cache_count_ptr() {
return reinterpret_cast<uint32_t*>(
@@ -722,7 +757,10 @@ RouterViewComp::fill(
int n_routers,
int n_caches
) {
- size_t comp_size = this->calcSize(n_routers, n_caches);
+ // TBD: This isn't right since the upgrade to mask support
+ // because the size isn't a static function of the router and
+ // cache count anymore.
+ size_t comp_size = sizeof(raw_t);
if (buffer.getSpace() < comp_size)
throw ts::Exception(BUFFER_TOO_SMALL_FOR_COMP_TEXT);
@@ -738,7 +776,7 @@ RouterViewComp::fill(
// No setf, go direct.
*m_cache_count = htonl(n_caches);
- this->setLength(comp_size - sizeof(super::raw_t));
+ this->setLength(comp_size - HEADER_SIZE);
buffer.use(comp_size);
return *this;
@@ -753,36 +791,46 @@ RouterViewComp::parse(MsgBuffer& buffer)
m_base = buffer.getTail();
zret = this->checkHeader(buffer, COMP_TYPE);
if (PARSE_SUCCESS == zret ) {
- size_t comp_size;
- m_cache_count = this->calc_cache_count_ptr();
- // If the cache count is past the end of the buffer, or
- // the size doesn't match, it's ill formed.
- if ((static_cast<void*>(m_cache_count) >= static_cast<void*>(buffer.getBase() + buffer.getSize()))
- || (this->getLength() != (comp_size =
- this->calcSize(
- this->getRouterCount(),
- this->getCacheCount()
- ))
- - sizeof(super::raw_t)
- ))
- zret = PARSE_COMP_WRONG_SIZE;
- else
- buffer.use(comp_size);
+ uint32_t ncaches; // # of caches.
+ if (this->getRouterCount() > MAX_ROUTERS) zret = PARSE_MSG_INVALID;
+ // check if cache count is past end of buffer
+ else if (static_cast<void*>(m_cache_count = this->calc_cache_count_ptr())
+ >= static_cast<void*>(buffer.getBase() + buffer.getSize())
+ )
+ zret = PARSE_COMP_WRONG_SIZE, log(LVL_DEBUG, "I_SEE_YOU: cache counter past end of buffer");
+ else if ((ncaches = this->getCacheCount()) > MAX_CACHES)
+ zret = PARSE_MSG_INVALID;
+ else {
+ size_t comp_size = reinterpret_cast<char*>(m_cache_count+1) - m_base;
+ // Walk the cache ID elements.
+ MsgBuffer spot(buffer);
+ CacheIdBox* box = m_cache_ids;
+ uint32_t idx = 0;
+ spot.use(comp_size);
+ while ( idx < ncaches && PARSE_SUCCESS == (zret = box->parse(spot))) {
+ size_t k = box->getSize();
+ spot.use(k);
+ comp_size += k;
+ ++box;
+ ++idx;
+ }
+ if (PARSE_SUCCESS == zret) buffer.use(comp_size);
+ }
}
}
return zret;
}
// ------------------------------------------------------
CacheIdComp&
-CacheIdComp::fill(MsgBuffer& base, CacheIdElt const& src) {
- size_t comp_size = this->calcSize();
+CacheIdComp::fill(MsgBuffer& base, CacheIdBox const& src) {
+ size_t comp_size = src.getSize() + HEADER_SIZE;
if (base.getSpace() < comp_size)
throw ts::Exception(BUFFER_TOO_SMALL_FOR_COMP_TEXT);
m_base = base.getTail();
- this->setType(COMP_TYPE).setLength(comp_size - sizeof(super::raw_t));
- access_field(&raw_t::m_id, m_base) = src;
+ this->setType(COMP_TYPE).setLength(comp_size - HEADER_SIZE);
+ m_box.fill(&(access_field(&raw_t::m_id, m_base)), src);
base.use(comp_size);
return *this;
}
@@ -793,14 +841,19 @@ CacheIdComp::parse(MsgBuffer& buffer) {
if (buffer.getSpace() < sizeof(raw_t))
zret = PARSE_BUFFER_TOO_SMALL;
else {
- size_t comp_size = this->calcSize();
m_base = buffer.getTail();
zret = this->checkHeader(buffer, COMP_TYPE);
if (PARSE_SUCCESS == zret ) {
- if (this->getLength() != comp_size - sizeof(super::raw_t))
- zret = PARSE_COMP_WRONG_SIZE;
- else
- buffer.use(comp_size);
+ MsgBuffer tmp(buffer);
+ tmp.use(reinterpret_cast<char*>(&(access_field(&raw_t::m_id, m_base))) - m_base);
+ zret = m_box.parse(tmp);
+ if (PARSE_SUCCESS == zret) {
+ size_t comp_size = HEADER_SIZE + m_box.getSize();
+ if (this->getLength() != comp_size - HEADER_SIZE)
+ zret = PARSE_COMP_WRONG_SIZE;
+ else
+ buffer.use(comp_size);
+ }
}
}
return zret;
@@ -871,10 +924,11 @@ CacheViewComp::calcSize(int n_routers, i
CacheViewComp&
CacheViewComp::fill(
MsgBuffer& buffer,
- uint32_t change_number,
- int n_routers,
- int n_caches
+ detail::cache::GroupData const& group
) {
+ int i;
+ size_t n_routers = group.m_routers.size();
+ size_t n_caches = group.m_caches.size();
size_t comp_size = this->calcSize(n_routers, n_caches);
if (buffer.getSpace() < comp_size)
@@ -882,16 +936,38 @@ CacheViewComp::fill(
m_base = buffer.getTail();
- this->setType(COMP_TYPE).setChangeNumber(change_number);
+ this->setType(COMP_TYPE).setChangeNumber(group.m_generation);
set_field(&raw_t::m_router_count, m_base, n_routers);
-// reinterpret_cast<raw_t*>(m_base)->m_router_count = htonl(n_routers);
// Set the pointer to the count of caches.
m_cache_count = reinterpret_cast<uint32_t*>(
m_base + sizeof(raw_t) + n_routers * sizeof(RouterIdElt)
);
*m_cache_count = htonl(n_caches); // set the actual count.
+ // Fill routers.
+ i = 0;
+ for ( detail::cache::RouterBag::const_iterator spot = group.m_routers.begin(),
+ limit = group.m_routers.end();
+ spot != limit;
+ ++spot, ++i
+ ) {
+ this->routerElt(i)
+ .setAddr(spot->m_addr)
+ .setRecvId(spot->m_recv.m_sn)
+ ;
+ }
+
+ // fill caches.
+ i = 0;
+ for ( detail::cache::CacheBag::const_iterator spot = group.m_caches.begin(),
+ limit = group.m_caches.end();
+ spot != limit;
+ ++spot, ++i
+ ) {
+ this->setCacheAddr(i, spot->idAddr());
+ }
+
this->setLength(comp_size - sizeof(super::raw_t));
buffer.use(comp_size);
return *this;
@@ -954,12 +1030,12 @@ AssignInfoComp::setKeyAddr(uint32_t addr
uint32_t
AssignInfoComp::getRouterCount() const {
- return get_field(&raw_t::m_router_count, m_base);
+ return access_field(&raw_t::m_routers, m_base).getCount();
}
-RouterAssignmentElt&
+RouterAssignElt&
AssignInfoComp::routerElt(int idx) {
- return access_array<RouterAssignmentElt>(m_base + sizeof(raw_t))[idx];
+ return access_field(&raw_t::m_routers, m_base).elt(idx);
}
uint32_t
@@ -981,15 +1057,17 @@ AssignInfoComp::setCacheAddr(int idx, ui
size_t
AssignInfoComp::calcSize(int n_routers, int n_caches) {
return sizeof(raw_t)
- + n_routers * sizeof(RouterAssignmentElt)
- + (1 + n_caches) * sizeof(uint32_t)
- + sizeof(Bucket) * N_BUCKETS
+ + RouterAssignListElt::calcVarSize(n_routers)
+ + HashAssignElt::calcSize(n_caches)
;
}
uint32_t*
AssignInfoComp::calcCacheCountPtr() {
- return reinterpret_cast<uint32_t*>(m_base + sizeof(raw_t) + this->getRouterCount() * sizeof(RouterAssignmentElt));
+ return reinterpret_cast<uint32_t*>(
+ m_base + sizeof(raw_t)
+ + access_field(&raw_t::m_routers, m_base).getVarSize()
+ );
}
AssignInfoComp::Bucket*
@@ -1000,11 +1078,12 @@ AssignInfoComp::calcBucketPtr() {
AssignInfoComp&
AssignInfoComp::fill(
MsgBuffer& buffer,
- AssignmentKeyElt const& key,
- int n_routers,
- int n_caches,
- Bucket const* buckets
+ detail::Assignment const& assign
) {
+ RouterAssignListElt const* ralist = assign.getRouterList();
+ HashAssignElt const* ha = assign.getHash();
+ size_t n_routers = ralist->getCount();
+ size_t n_caches = ha->getCount();
size_t comp_size = this->calcSize(n_routers, n_caches);
if (buffer.getSpace() < comp_size)
@@ -1013,42 +1092,114 @@ AssignInfoComp::fill(
m_base = buffer.getTail();
this->setType(COMP_TYPE);
- this->keyElt() = key;
-
- // Write the router count.
- set_field(&raw_t::m_router_count, m_base, n_routers);
+ this->keyElt() = *(assign.getKey());
+ memcpy(&(access_field(&raw_t::m_routers, m_base)), ralist, ralist->getSize());
// Set the pointer to the count of caches and write the count.
m_cache_count = this->calcCacheCountPtr();
- *m_cache_count = htonl(n_caches);
+ memcpy(m_cache_count, ha, ha->getSize());
- // Get the bucket pointer.
- m_buckets = this->calcBucketPtr();
- memcpy(m_buckets, buckets, sizeof(Bucket) * N_BUCKETS);
-
- this->setLength(comp_size - sizeof(super::raw_t));
+ this->setLength(comp_size - HEADER_SIZE);
buffer.use(comp_size);
return *this;
}
-AssignInfoComp&
-AssignInfoComp::fill(MsgBuffer& buffer, self const& that) {
- size_t comp_size = that.getLength() + sizeof(super::raw_t);
+int
+AssignInfoComp::parse(MsgBuffer& buffer) {
+ int zret = PARSE_SUCCESS;
+ if (buffer.getSpace() < HEADER_SIZE)
+ zret = PARSE_BUFFER_TOO_SMALL;
+ else {
+ m_base = buffer.getTail();
+ zret = this->checkHeader(buffer, COMP_TYPE);
+ if (PARSE_SUCCESS == zret ) {
+ int n_routers = this->getRouterCount();
+ int n_caches;
+ m_cache_count = this->calcCacheCountPtr();
+ n_caches = this->getCacheCount();
+ m_buckets = this->calcBucketPtr();
+ size_t comp_size = this->calcSize(n_routers, n_caches);
+ if (this->getLength() != comp_size - HEADER_SIZE)
+ zret = PARSE_COMP_WRONG_SIZE;
+ else
+ buffer.use(comp_size);
+ }
+ }
+ if (PARSE_SUCCESS != zret) m_base = 0;
+ return zret;
+}
+
+AssignmentKeyElt&
+AltAssignComp::keyElt() {
+ return access_field(&raw_t::m_key, m_base);
+}
+
+AssignmentKeyElt const&
+AltAssignComp::keyElt() const {
+ return access_field(&raw_t::m_key, m_base);
+}
+
+void*
+AltAssignComp::calcVarPtr() {
+ return reinterpret_cast<void*>(
+ m_base + sizeof(raw_t)
+ + access_field(&raw_t::m_routers, m_base).getVarSize()
+ );
+}
+
+uint32_t
+AltAssignComp::getRouterCount() const {
+ return access_field(&raw_t::m_routers, m_base).getCount();
+}
+
+uint32_t
+AltHashAssignComp::getCacheCount() const {
+ return ntohl(*m_cache_count);
+}
+
+
+size_t
+AltHashAssignComp::calcSize(int n_routers, int n_caches) {
+ return sizeof(raw_t)
+ + RouterAssignListElt::calcVarSize(n_routers)
+ + HashAssignElt::calcSize(n_caches)
+ ;
+}
+
+AltHashAssignComp&
+AltHashAssignComp::fill(
+ MsgBuffer& buffer,
+ detail::Assignment const& assign
+) {
+ RouterAssignListElt const* ralist = assign.getRouterList();
+ HashAssignElt const* ha = assign.getHash();
+ size_t n_routers = ralist->getCount();
+ size_t n_caches = ha->getCount();
+ size_t comp_size = this->calcSize(n_routers, n_caches);
if (buffer.getSpace() < comp_size)
throw ts::Exception(BUFFER_TOO_SMALL_FOR_COMP_TEXT);
m_base = buffer.getTail();
- memcpy(m_base, that.m_base, comp_size);
- // Set the pointer to the count of caches.
- m_cache_count = this->calcCacheCountPtr();
- m_buckets = this->calcBucketPtr();
+
+ this->setType(COMP_TYPE)
+ .setLength(comp_size - HEADER_SIZE)
+ .setAssignType(ALT_HASH_ASSIGNMENT)
+ .setAssignLength(comp_size - HEADER_SIZE - sizeof(local_header_t))
+ ;
+ this->keyElt() = *(assign.getKey());
+ memcpy(&(access_field(&raw_t::m_routers, m_base)), ralist, ralist->getSize());
+ // Set the pointer to the count of caches and write the count.
+ m_cache_count = static_cast<uint32_t*>(this->calcVarPtr());
+ memcpy(m_cache_count, ha, ha->getSize());
+
buffer.use(comp_size);
+
return *this;
}
int
-AssignInfoComp::parse(MsgBuffer& buffer) {
+AltHashAssignComp::parse(MsgBuffer& buffer) {
int zret = PARSE_SUCCESS;
if (buffer.getSpace() < sizeof(raw_t))
zret = PARSE_BUFFER_TOO_SMALL;
@@ -1058,11 +1209,62 @@ AssignInfoComp::parse(MsgBuffer& buffer)
if (PARSE_SUCCESS == zret ) {
int n_routers = this->getRouterCount();
int n_caches;
- m_cache_count = this->calcCacheCountPtr();
+ m_cache_count = static_cast<uint32_t*>(this->calcVarPtr());
n_caches = this->getCacheCount();
- m_buckets = this->calcBucketPtr();
size_t comp_size = this->calcSize(n_routers, n_caches);
- if (this->getLength() != comp_size - sizeof(super::raw_t))
+ if (this->getLength() != comp_size - HEADER_SIZE)
+ zret = PARSE_COMP_WRONG_SIZE;
+ else
+ buffer.use(comp_size);
+ }
+ }
+ if (PARSE_SUCCESS != zret) m_base = 0;
+ return zret;
+}
+
+AltMaskAssignComp&
+AltMaskAssignComp::fill(
+ MsgBuffer& buffer,
+ detail::Assignment const& assign
+) {
+ RouterAssignListElt const* ralist = assign.getRouterList();
+ MaskAssignElt const* ma = assign.getMask();
+ size_t comp_size = sizeof(raw_t) + ralist->getVarSize() + ma->getSize();
+
+ if (buffer.getSpace() < comp_size)
+ throw ts::Exception(BUFFER_TOO_SMALL_FOR_COMP_TEXT);
+
+ m_base = buffer.getTail();
+
+ this->setType(COMP_TYPE)
+ .setLength(comp_size - HEADER_SIZE)
+ .setAssignType(ALT_MASK_ASSIGNMENT)
+ .setAssignLength(comp_size - HEADER_SIZE - sizeof(local_header_t))
+ ;
+ this->keyElt() = *(assign.getKey());
+
+ memcpy(&(access_field(&raw_t::m_routers, m_base)), ralist, ralist->getSize());
+ m_mask_elt = static_cast<MaskAssignElt*>(this->calcVarPtr());
+ memcpy(m_mask_elt, ma, ma->getSize());
+
+ buffer.use(comp_size);
+
+ return *this;
+}
+
+int
+AltMaskAssignComp::parse(MsgBuffer& buffer) {
+ int zret = PARSE_SUCCESS;
+ if (buffer.getSpace() < sizeof(raw_t))
+ zret = PARSE_BUFFER_TOO_SMALL;
+ else {
+ m_base = buffer.getTail();
+ zret = this->checkHeader(buffer, COMP_TYPE);
+ if (PARSE_SUCCESS == zret ) {
+ RouterAssignListElt* ralist = &(access_field(&raw_t::m_routers, m_base));
+ m_mask_elt = static_cast<MaskAssignElt*>(this->calcVarPtr());
+ size_t comp_size = sizeof(raw_t) + ralist->getVarSize() + m_mask_elt->getSize();
+ if (this->getLength() != comp_size - HEADER_SIZE)
zret = PARSE_COMP_WRONG_SIZE;
else
buffer.use(comp_size);
@@ -1229,34 +1431,29 @@ QueryComp::parse(MsgBuffer& buffer) {
return zret;
}
// ------------------------------------------------------
-MaskValueSetElt&
-AssignMapComp::elt(int idx) {
- return access_array<MaskValueSetElt>(m_base + sizeof(raw_t))[idx];
-}
-
uint32_t
-AssignMapComp::getEltCount() const {
- return get_field(&raw_t::m_count, m_base);
-}
-
-inline size_t
-AssignMapComp::calcSize(int n) {
- return sizeof(raw_t) + n * sizeof(MaskValueSetElt);
+AssignMapComp::getCount() const {
+ return access_field(&raw_t::m_assign, m_base).getCount();
}
AssignMapComp&
-AssignMapComp::fill(MsgBuffer& buffer, int n) {
- size_t comp_size = this->calcSize(n);
-
- if (buffer.getSpace() < comp_size)
+AssignMapComp::fill(MsgBuffer& buffer, detail::Assignment const& assign) {
+ size_t comp_size = sizeof(raw_t);
+ MaskAssignElt const* ma = assign.getMask();
+ size_t ma_size = ma->getSize(); // Not constant time.
+
+ // Can't be precise, but we need at least one mask/value set with
+ // at least one value. If we don't have that it's a clear fail.
+ if (buffer.getSpace() < comp_size + sizeof(MaskValueSetElt::calcSize(1)))
throw ts::Exception(BUFFER_TOO_SMALL_FOR_COMP_TEXT);
m_base = buffer.getTail();
+ memcpy(&(access_field(&raw_t::m_assign, m_base)), ma, ma_size);
+ comp_size += ma_size - sizeof(*ma);
this->setType(COMP_TYPE)
- .setLength(comp_size - sizeof(super::raw_t))
+ .setLength(comp_size - HEADER_SIZE)
;
- set_field(&raw_t::m_count, m_base, n);
buffer.use(comp_size);
return *this;
@@ -1265,17 +1462,14 @@ AssignMapComp::fill(MsgBuffer& buffer, i
int
AssignMapComp::parse(MsgBuffer& buffer) {
int zret = PARSE_SUCCESS;
- if (buffer.getSpace() < sizeof(raw_t))
+ if (buffer.getSpace() < HEADER_SIZE)
zret = PARSE_BUFFER_TOO_SMALL;
else {
m_base = buffer.getTail();
zret = this->checkHeader(buffer, COMP_TYPE);
if (PARSE_SUCCESS == zret ) {
- size_t comp_size = this->calcSize(this->getEltCount());
- if (this->getLength() != comp_size - sizeof(super::raw_t))
- zret = PARSE_COMP_WRONG_SIZE;
- else
- buffer.use(comp_size);
+ // TBD - Actually check the mask/value set data !!
+ buffer.use(this->getLength() + HEADER_SIZE);
}
}
if (PARSE_SUCCESS != zret) m_base = 0;
@@ -1285,51 +1479,9 @@ AssignMapComp::parse(MsgBuffer& buffer)
detail::Assignment::Assignment()
: m_key(0,0)
, m_active(false)
- , m_dirty(true) {
- memset(m_buckets, UNASSIGNED_BUCKET, sizeof(m_buckets));
-}
-
-void
-detail::Assignment::generate() const {
- int i;
- size_t size = AssignInfoComp::calcSize(m_router_keys.size(), m_cache_addrs.size());
-
- // Resize buffer if needed.
- if (m_buffer.getSize() < size) {
- free(m_buffer.getBase());
- m_buffer.set(malloc(size), size);
- }
- m_buffer.reset();
-
- // Load basic layout.
- m_comp.fill(m_buffer, m_key, m_router_keys.size(), m_cache_addrs.size(), m_buckets);
-
- i = 0;
- for ( RouterKeys::const_iterator
- spot = m_router_keys.begin(),
- limit = m_router_keys.end();
- spot != limit;
- ++spot, ++i
- ) {
- m_comp.routerElt(i) = *spot;
- }
-
- i = 0;
- for ( CacheAddrs::const_iterator
- spot = m_cache_addrs.begin(),
- limit = m_cache_addrs.end();
- spot != limit;
- ++spot, ++i
- ) {
- m_comp.setCacheAddr(i, *spot);
- }
- m_dirty = false;
-}
-
-void
-detail::Assignment::pour(MsgBuffer& base, AssignInfoComp& comp) const {
- if (m_dirty) this->generate();
- comp.fill(base, m_comp);
+ , m_router_list(0)
+ , m_hash_assign(0)
+ , m_mask_assign(0) {
}
bool
@@ -1342,9 +1494,6 @@ detail::Assignment::fill(cache::GroupDat
// are purged.
size_t n_routers = group.m_routers.size(); // routers in group
size_t n_caches = group.m_caches.size(); // caches in group
- size_t v_caches = 0; // valid caches
-
- this->m_dirty = true;
// We need both routers and caches to do something useful.
if (! (n_routers && n_caches)) return false;
@@ -1359,17 +1508,34 @@ detail::Assignment::fill(cache::GroupDat
cend = group.m_caches.end();
size_t nr[n_caches]; // validity check counts.
+ memset(nr, 0, sizeof(nr)); // Set counts to zero.
+
+ // Guess at size of serialization buffer. For the router list and
+ // the hash assignment, we can compute reasonable upper bounds and so
+ // we don't have to do space checks when those get filled out.
+ // The mask assignment is more difficult. We just guess generously and
+ // try to recover if we go over.
+ size_t size = RouterAssignListElt::calcSize(n_routers)
+ + HashAssignElt::calcSize(n_caches)
+ + 4096;
+ if (m_buffer.getSize() < size) {
+ free(m_buffer.getBase());
+ m_buffer.set(malloc(size), size);
+ }
+ m_buffer.reset();
// Set assignment key
m_key.setAddr(addr).setChangeNumber(group.m_generation);
- memset(nr, 0, sizeof(nr)); // Set counts to zero.
- m_router_keys.resize(n_routers);
- // For each router, run over the caches and bump the nr count
- // if that cache was included in the most recent packet.
+ m_router_list = reinterpret_cast<RouterAssignListElt*>(m_buffer.getBase());
+ new (m_router_list) RouterAssignListElt(n_routers);
+
+ // For each router, update the assignment and run over the caches
+ // and bump the nr count if that cache was included in the most
+ // recent packet.
for ( rdx = 0, rspot = rbegin ; rspot != rend ; ++rspot, ++rdx ) {
- // Update router key.
- m_router_keys[rdx]
+ // Update router assignment.
+ m_router_list->elt(rdx)
.setChangeNumber(rspot->m_generation)
.setAddr(rspot->m_addr)
.setRecvId(rspot->m_recv.m_sn)
@@ -1380,32 +1546,38 @@ detail::Assignment::fill(cache::GroupDat
++(nr[cdx]);
}
}
+
+ size_t k = m_router_list->getSize();
+ m_buffer.use(k);
+ m_hash_assign = reinterpret_cast<HashAssignElt*>(m_buffer.getTail());
+
// If the nr value is 0, then the cache was not included in any
// last packet, so it should be discarded. A cache is valid if
// nr is n_routers, indicating that every router mentioned it.
- m_cache_addrs.clear();
- m_cache_addrs.reserve(n_caches);
+ int v_caches = 0; // valid caches
for ( cdx = 0, cspot = cbegin ; cspot != cend ; ++cspot, ++cdx )
- if (nr[cdx] == n_routers) m_cache_addrs.push_back(cspot->idAddr());
- v_caches = m_cache_addrs.size();
+ if (nr[cdx] == n_routers) {
+ m_hash_assign->setAddr(cdx, cspot->idAddr());
+ ++v_caches;
+ }
if (! v_caches) { // no valid caches.
- log(LVL_INFO, "Assignment requested but no valid caches were found.");
+ log(LVL_INFO, "Attempted to generate cache assignment but no valid caches were found.");
return false;
}
+ // Just sets the cache count.
+ new (m_hash_assign) HashAssignElt(v_caches);
+ m_hash_assign->round_robin_assign();
+ m_buffer.use(m_hash_assign->getSize());
+
+ m_mask_assign = reinterpret_cast<MaskAssignElt*>(m_buffer.getTail());
+ new (m_mask_assign) MaskAssignElt;
+
+ // For now, hardwire everything to first cache.
+ // We have plenty of space, but will need to check if we do something
+ // more complex here.
+ m_mask_assign->init(0,0,0,0)->addValue(m_hash_assign->getAddr(0),0,0,0,0);
- if (1 == v_caches) memset(m_buckets, 0, sizeof(m_buckets));
- else { // Assign round robin.
- size_t x = 0;
- for ( Bucket *spot = m_buckets, *limit = m_buckets + N_BUCKETS;
- spot < limit;
- ++spot
- ) {
- spot->m_idx = x;
- spot->m_alt = 0;
- x = ( x + 1 ) % v_caches;
- }
- }
logf(LVL_INFO, "Generated assignment for group %d with %d routers, %d valid caches.", group.m_svc.getSvcId(), n_routers, v_caches);
return true;
@@ -1430,15 +1602,13 @@ BaseMsg::validateSecurity() const {
void
HereIAmMsg::fill(
detail::cache::GroupData const& group,
- SecurityOption sec_opt,
- int n_routers,
- int n_caches
+ SecurityOption sec_opt
) {
m_header.fill(m_buffer, HERE_I_AM);
m_security.fill(m_buffer, sec_opt);
m_service.fill(m_buffer, group.m_svc);
m_cache_id.fill(m_buffer, group.m_id);
- m_cache_view.fill(m_buffer, group.m_generation, n_routers, n_caches);
+ m_cache_view.fill(m_buffer, group);
}
void
@@ -1450,9 +1620,9 @@ HereIAmMsg::fill_caps(
m_capabilities.elt(0) =
CapabilityElt(CapabilityElt::PACKET_FORWARD_METHOD, router.m_packet_forward);
m_capabilities.elt(1) =
- CapabilityElt(CapabilityElt::PACKET_RETURN_METHOD, router.m_packet_return);
- m_capabilities.elt(2) =
CapabilityElt(CapabilityElt::CACHE_ASSIGNMENT_METHOD, router.m_cache_assign);
+ m_capabilities.elt(2) =
+ CapabilityElt(CapabilityElt::PACKET_RETURN_METHOD, router.m_packet_return);
}
}
@@ -1488,15 +1658,22 @@ HereIAmMsg::parse(ts::Buffer const& buff
void
RedirectAssignMsg::fill(
detail::cache::GroupData const& group,
- SecurityOption sec_opt,
- AssignmentKeyElt const& key,
- int n_routers,
- int n_caches
+ SecurityOption sec_opt
) {
m_header.fill(m_buffer, REDIRECT_ASSIGN);
m_security.fill(m_buffer, sec_opt);
m_service.fill(m_buffer, group.m_svc);
- group.m_assign_info.pour(m_buffer, m_assign);
+ switch (group.m_cache_assign) {
+ case ServiceGroup::HASH_ONLY:
+ m_hash_assign.fill(m_buffer, group.m_assign_info);
+ break;
+ case ServiceGroup::MASK_ONLY:
+ m_alt_mask_assign.fill(m_buffer, group.m_assign_info);
+ break;
+ default:
+ logf(LVL_WARN, "Bad assignment type [%d] for REDIRECT_ASSIGN", group.m_cache_assign);
+ break;
+ }
}
// ------------------------------------------------------
void
@@ -1514,7 +1691,6 @@ ISeeYouMsg::fill(
m_service.fill(m_buffer, group.m_svc);
m_router_id.fill(m_buffer, to_caches);
m_router_view.fill(m_buffer, n_routers, n_caches);
- if (assign.isActive()) assign.pour(m_buffer, m_assignment);
}
int
@@ -1534,10 +1710,10 @@ ISeeYouMsg::parse(ts::Buffer const& buff
if (PARSE_SUCCESS != zret) return zret;
zret = m_router_id.parse(m_buffer);
- if (PARSE_SUCCESS != zret) return zret;
+ if (PARSE_SUCCESS != zret) { logf(LVL_DEBUG, "I_SEE_YOU: Invalid %d router id", zret); return zret; }
zret = m_router_view.parse(m_buffer);
- if (PARSE_SUCCESS != zret) return zret;
+ if (PARSE_SUCCESS != zret) { logf(LVL_DEBUG, "I_SEE_YOU: Invalid %d router view", zret); return zret; }
// Optional components.
@@ -1551,7 +1727,9 @@ ISeeYouMsg::parse(ts::Buffer const& buff
m_capabilities.parse(m_buffer);
m_command.parse(m_buffer);
- return m_buffer.getSpace() ? PARSE_DATA_OVERRUN : PARSE_SUCCESS;
+ if (m_buffer.getSpace()) { zret = PARSE_DATA_OVERRUN; logf(LVL_DEBUG, "I_SEE_YOU: Data overrun %lu", m_buffer.getSpace()); }
+
+ return zret;
}
// ------------------------------------------------------
int
Modified: trafficserver/traffic/trunk/proxy/wccp/WccpStatic.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/wccp/WccpStatic.cc?rev=1067578&r1=1067577&r2=1067578&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/wccp/WccpStatic.cc (original)
+++ trafficserver/traffic/trunk/proxy/wccp/WccpStatic.cc Sun Feb 6 02:57:11 2011
@@ -35,6 +35,7 @@ struct CompileTimeChecks {
ts::TEST_IF_TRUE< BUCKET_SIZE == UINT8_SIZE > m_check_bucket_size;
};
+ts::Errata::Code LVL_TMP = 1; ///< Temporary message.
ts::Errata::Code LVL_FATAL = 3; ///< Fatal, cannot continue.
ts::Errata::Code LVL_WARN = 2; ///< Significant, should be fixed.
ts::Errata::Code LVL_INFO = 1; /// Interesting, not necessarily a problem.
Modified: trafficserver/traffic/trunk/proxy/wccp/WccpUtil.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/wccp/WccpUtil.h?rev=1067578&r1=1067577&r2=1067578&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/wccp/WccpUtil.h (original)
+++ trafficserver/traffic/trunk/proxy/wccp/WccpUtil.h Sun Feb 6 02:57:11 2011
@@ -29,6 +29,8 @@ extern ts::Errata::Code LVL_FATAL; ///<
extern ts::Errata::Code LVL_WARN; ///< Significant, function degraded.
extern ts::Errata::Code LVL_INFO; ///< Interesting, not necessarily a problem.
extern ts::Errata::Code LVL_DEBUG; ///< Debugging information.
+extern ts::Errata::Code LVL_TMP; ///< For temporary debugging only.
+// Handy so that temporary debugging messages can be located by grep.
//@}
/** Logging / reporting support.
@@ -151,6 +153,7 @@ void set_field(uint32_t R::*M, char* buf
// IP address fields are kept locally in network order so
// we need variants without re-ordering.
+// Also required for member structures.
template < typename R, typename T >
T& access_field(T R::*M, void* buffer) {
return reinterpret_cast<R*>(buffer)->*M;
@@ -158,12 +161,12 @@ T& access_field(T R::*M, void* buffer) {
// Access an array @a T starting at @a buffer.
template < typename T>
-T* access_array(char* buffer) {
+T* access_array(void* buffer) {
return reinterpret_cast<T*>(buffer);
}
// Access an array of @a T starting at @a buffer.
template < typename T >
-T const* access_array(char const* buffer) {
+T const* access_array(void const* buffer) {
return reinterpret_cast<T const*>(buffer);
}