Fix some hashing bugs resulting from adaptation of new IPAddr class.

This commit is contained in:
Jon Siwek 2012-02-06 13:05:52 -06:00
parent 2e2f8f5d06
commit 1f58ac875b
6 changed files with 24 additions and 25 deletions

View file

@ -107,8 +107,6 @@ char* CompositeHash::SingleValHash(int type_check, char* kp0,
case TYPE_INTERNAL_ADDR: case TYPE_INTERNAL_ADDR:
{ {
// Use uint32 instead of int, because 'int' is not
// guaranteed to be 32-bit.
uint32* kp = AlignAndPadType<uint32>(kp0); uint32* kp = AlignAndPadType<uint32>(kp0);
uint32 bytes[4]; uint32 bytes[4];
v->AsAddr()->CopyIPv6(bytes); v->AsAddr()->CopyIPv6(bytes);

View file

@ -24,15 +24,15 @@ HashKey* ConnID::BuildConnKey() const
if ( is_one_way || if ( is_one_way ||
addr_port_canon_lt(src_addr, src_port, dst_addr, dst_port) ) addr_port_canon_lt(src_addr, src_port, dst_addr, dst_port) )
{ {
key.ip1 = src_addr; src_addr.CopyIPv6(key.ip1);
key.ip2 = dst_addr; dst_addr.CopyIPv6(key.ip2);
key.port1 = src_port; key.port1 = src_port;
key.port2 = dst_port; key.port2 = dst_port;
} }
else else
{ {
key.ip1 = dst_addr; dst_addr.CopyIPv6(key.ip1);
key.ip2 = src_addr; src_addr.CopyIPv6(key.ip2);
key.port1 = dst_port; key.port1 = dst_port;
key.port2 = src_port; key.port2 = src_port;
} }

View file

@ -50,8 +50,8 @@ struct ConnID {
// The structure used internally for hashing. // The structure used internally for hashing.
struct Key { struct Key {
IPAddr ip1; uint32 ip1[4];
IPAddr ip2; uint32 ip2[4];
uint16 port1; uint16 port1;
uint16 port2; uint16 port2;
}; };

View file

@ -235,7 +235,8 @@ Connection* ConnCompressor::NextPacket(double t, HashKey* key, const IP_Hdr* ip,
tc = FirstFromOrig(t, key, ip, tp); tc = FirstFromOrig(t, key, ip, tp);
} }
else if ( ip->SrcAddr() == SrcAddr(pending) && else if ( ip->SrcAddr() ==
IPAddr(IPAddr::IPv6, SrcAddr(pending), IPAddr::Network) &&
tp->th_sport == SrcPort(pending) ) tp->th_sport == SrcPort(pending) )
// Another packet from originator. // Another packet from originator.
tc = NextFromOrig(pending, t, key, ip, tp); tc = NextFromOrig(pending, t, key, ip, tp);
@ -507,8 +508,8 @@ Connection* ConnCompressor::Instantiate(HashKey* key, PendingConn* pending)
{ {
// Instantantiate a Connection. // Instantantiate a Connection.
ConnID conn_id; ConnID conn_id;
conn_id.src_addr = SrcAddr(pending); conn_id.src_addr = IPAddr(IPAddr::IPv6, SrcAddr(pending), IPAddr::Network);
conn_id.dst_addr = DstAddr(pending); conn_id.dst_addr = IPAddr(IPAddr::IPv6, DstAddr(pending), IPAddr::Network);
conn_id.src_port = SrcPort(pending); conn_id.src_port = SrcPort(pending);
conn_id.dst_port = DstPort(pending); conn_id.dst_port = DstPort(pending);
@ -607,7 +608,8 @@ void ConnCompressor::PktHdrToPendingConn(double time, const HashKey* key,
memcpy(&c->key, key->Key(), key->Size()); memcpy(&c->key, key->Key(), key->Size());
c->hash = key->Hash(); c->hash = key->Hash();
c->ip1_is_src = c->key.ip1 == ip->SrcAddr() && IPAddr ip1(IPAddr::IPv6, c->key.ip1, IPAddr::Network);
c->ip1_is_src = ip1 == ip->SrcAddr() &&
c->key.port1 == tp->th_sport; c->key.port1 == tp->th_sport;
c->time = time; c->time = time;
c->window = tp->th_win; c->window = tp->th_win;
@ -656,11 +658,10 @@ const IP_Hdr* ConnCompressor::PendingConnToPacket(const PendingConn* c)
tp->th_urp = 0; tp->th_urp = 0;
} }
// Note, do *not* use copy_addr() here. This is because we're IPAddr ip1(IPAddr::IPv6, c->key.ip1, IPAddr::Network);
// copying to an IPv4 header, which has room for exactly and IPAddr ip2(IPAddr::IPv6, c->key.ip2, IPAddr::Network);
// only an IPv4 address. if ( ip1.family() == IPAddr::IPv6 ||
if ( c->key.ip1.family() == IPAddr::IPv6 || ip2.family() == IPAddr::IPv6 )
c->key.ip2.family() == IPAddr::IPv6 )
reporter->InternalError("IPv6 snuck into connection compressor"); reporter->InternalError("IPv6 snuck into connection compressor");
else else
{ {
@ -668,13 +669,13 @@ const IP_Hdr* ConnCompressor::PendingConnToPacket(const PendingConn* c)
const uint32* dst_bytes; const uint32* dst_bytes;
if ( c->ip1_is_src ) if ( c->ip1_is_src )
{ {
c->key.ip1.GetBytes(&src_bytes); ip1.GetBytes(&src_bytes);
c->key.ip2.GetBytes(&dst_bytes); ip2.GetBytes(&dst_bytes);
} }
else else
{ {
c->key.ip2.GetBytes(&src_bytes); ip2.GetBytes(&src_bytes);
c->key.ip1.GetBytes(&dst_bytes); ip1.GetBytes(&dst_bytes);
} }
memcpy(&ip->ip_src, src_bytes, sizeof(ip->ip_src)); memcpy(&ip->ip_src, src_bytes, sizeof(ip->ip_src));
memcpy(&ip->ip_dst, dst_bytes, sizeof(ip->ip_dst)); memcpy(&ip->ip_dst, dst_bytes, sizeof(ip->ip_dst));

View file

@ -105,9 +105,9 @@ public:
private: private:
// Helpers to extract addrs/ports from PendingConn. // Helpers to extract addrs/ports from PendingConn.
const IPAddr& SrcAddr(const PendingConn* c) const uint32* SrcAddr(const PendingConn* c)
{ return c->ip1_is_src ? c->key.ip1 : c->key.ip2; } { return c->ip1_is_src ? c->key.ip1 : c->key.ip2; }
const IPAddr& DstAddr(const PendingConn* c) const uint32* DstAddr(const PendingConn* c)
{ return c->ip1_is_src ? c->key.ip2 : c->key.ip1; } { return c->ip1_is_src ? c->key.ip2 : c->key.ip1; }
uint16 SrcPort(const PendingConn* c) uint16 SrcPort(const PendingConn* c)

View file

@ -71,8 +71,8 @@ void TimerMgrExpireTimer::Dispatch(double t, int is_expire)
NetSessions::NetSessions() NetSessions::NetSessions()
{ {
TypeList* t = new TypeList(); TypeList* t = new TypeList();
t->Append(base_type(TYPE_COUNT)); // source IP address t->Append(base_type(TYPE_ADDR)); // source IP address
t->Append(base_type(TYPE_COUNT)); // dest IP address t->Append(base_type(TYPE_ADDR)); // dest IP address
t->Append(base_type(TYPE_COUNT)); // source and dest ports t->Append(base_type(TYPE_COUNT)); // source and dest ports
ch = new CompositeHash(t); ch = new CompositeHash(t);