/[resiprocate]/main/resip/stack/Tuple.cxx
ViewVC logotype

Diff of /main/resip/stack/Tuple.cxx

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 11152 by sgodin, Sun Feb 23 21:29:34 2014 UTC revision 11153 by dpetrie, Wed Apr 23 17:25:02 2014 UTC
# Line 24  Line 24 
24  #include "rutil/HashMap.hxx"  #include "rutil/HashMap.hxx"
25  #include "rutil/MD5Stream.hxx"  #include "rutil/MD5Stream.hxx"
26  #include "rutil/Logger.hxx"  #include "rutil/Logger.hxx"
27    #ifdef USE_NETNS
28    #   include "rutil/NetNs.hxx"
29    #endif
30    
31  using std::auto_ptr;  using std::auto_ptr;
32  using namespace resip;  using namespace resip;
# Line 58  Line 60 
60               int port,               int port,
61               IpVersion ipVer,               IpVersion ipVer,
62               TransportType type,               TransportType type,
63               const Data& targetDomain) :               const Data& targetDomain,
64                 const Data& netNs) :
65     mFlowKey(0),     mFlowKey(0),
66     mTransportKey(0),     mTransportKey(0),
67     onlyUseExistingConnection(false),     onlyUseExistingConnection(false),
68     mTransportType(type),     mTransportType(type),
69     mTargetDomain(targetDomain)     mTargetDomain(targetDomain),
70       mNetNs(netNs)
71  {  {
72     if (ipVer == V4)     if (ipVer == V4)
73     {     {
# Line 109  Line 113 
113  Tuple::Tuple(const Data& printableAddr,  Tuple::Tuple(const Data& printableAddr,
114               int port,               int port,
115               TransportType ptype,               TransportType ptype,
116               const Data& targetDomain) :               const Data& targetDomain,
117                 const Data& netNs) :
118     mFlowKey(0),     mFlowKey(0),
119     mTransportKey(0),     mTransportKey(0),
120     onlyUseExistingConnection(false),     onlyUseExistingConnection(false),
121     mTransportType(ptype),     mTransportType(ptype),
122     mTargetDomain(targetDomain)     mTargetDomain(targetDomain),
123       mNetNs(netNs)
124  {  {
125     if (DnsUtil::isIpV4Address(printableAddr))     if (DnsUtil::isIpV4Address(printableAddr))
126     {     {
# Line 148  Line 154 
154  Tuple::Tuple(const in_addr& ipv4,  Tuple::Tuple(const in_addr& ipv4,
155               int port,               int port,
156               TransportType ptype,               TransportType ptype,
157               const Data& targetDomain)               const Data& targetDomain,
158                 const Data& netNs)
159       :mFlowKey(0),       :mFlowKey(0),
160       mTransportKey(0),       mTransportKey(0),
161       onlyUseExistingConnection(false),       onlyUseExistingConnection(false),
162       mTransportType(ptype),       mTransportType(ptype),
163       mTargetDomain(targetDomain)       mTargetDomain(targetDomain),
164         mNetNs(netNs)
165  {  {
166     memset(&m_anonv4, 0, sizeof(sockaddr_in));     memset(&m_anonv4, 0, sizeof(sockaddr_in));
167     m_anonv4.sin_addr = ipv4;     m_anonv4.sin_addr = ipv4;
# Line 165  Line 173 
173  Tuple::Tuple(const in6_addr& ipv6,  Tuple::Tuple(const in6_addr& ipv6,
174               int port,               int port,
175               TransportType ptype,               TransportType ptype,
176               const Data& targetDomaina)               const Data& targetDomaina,
177                 const Data& netNs)
178       :mFlowKey(0),       :mFlowKey(0),
179       mTransportKey(0),       mTransportKey(0),
180       onlyUseExistingConnection(false),       onlyUseExistingConnection(false),
181       mTransportType(ptype),       mTransportType(ptype),
182       mTargetDomain(targetDomaina)       mTargetDomain(targetDomaina),
183         mNetNs(netNs)
184  {  {
185     memset(&m_anonv6, 0, sizeof(sockaddr_in6));     memset(&m_anonv6, 0, sizeof(sockaddr_in6));
186     m_anonv6.sin6_addr = ipv6;     m_anonv6.sin6_addr = ipv6;
# Line 245  Line 255 
255  #endif  #endif
256  }  }
257    
258    #ifdef USE_NETNS
259    #   define TOKEN_SIZE 8
260    #   define TOKEN_IP_ADDRESS_OFFSET 4
261    #else
262    #   define TOKEN_SIZE 7
263    #   define TOKEN_IP_ADDRESS_OFFSET 3
264    #endif
265    
266  void  void
267  Tuple::writeBinaryToken(const resip::Tuple& tuple, resip::Data& container, const Data& salt)  Tuple::writeBinaryToken(const resip::Tuple& tuple, resip::Data& container, const Data& salt)
268  {  {
# Line 253  Line 271 
271     // bytes for V6, and 14 extra bytes for V4.     // bytes for V6, and 14 extra bytes for V4.
272     // V6: sin6_len(1), sin6_flowinfo(4), flowId(4), onlyUseExistingConnection(1)     // V6: sin6_len(1), sin6_flowinfo(4), flowId(4), onlyUseExistingConnection(1)
273     // V4: sin_family(2 instead of 1), sin_zero(8), flowId(4), onlyUseExistingConnection(1)     // V4: sin_family(2 instead of 1), sin_zero(8), flowId(4), onlyUseExistingConnection(1)
274     UInt32 rawToken[7];     UInt32 rawToken[TOKEN_SIZE];
275     memset(&rawToken, 0, 28);     memset(&rawToken, 0, TOKEN_SIZE * 4);
276    
277     rawToken[0] = tuple.mFlowKey;     rawToken[0] = tuple.mFlowKey;
278    
# Line 272  Line 290 
290        rawToken[2] += 0x00000010;        rawToken[2] += 0x00000010;
291     }     }
292    
293    #ifdef USE_NETNS
294       rawToken[3] = NetNs::getNetNsId(tuple.getNetNs());
295    #endif
296    
297  #ifdef USE_IPV6  #ifdef USE_IPV6
298     if(tuple.ipVersion()==V6)     if(tuple.ipVersion()==V6)
299     {     {
# Line 279  Line 301 
301        rawToken[2] += 0x00000001;        rawToken[2] += 0x00000001;
302        in6_addr address = reinterpret_cast<const sockaddr_in6&>(tuple.getSockaddr()).sin6_addr;        in6_addr address = reinterpret_cast<const sockaddr_in6&>(tuple.getSockaddr()).sin6_addr;
303        assert(sizeof(address)==16);        assert(sizeof(address)==16);
304        memcpy(&rawToken[3],&address,16);        memcpy(&rawToken[TOKEN_IP_ADDRESS_OFFSET],&address,16);
305     }     }
306     else     else
307  #endif  #endif
308     {     {
309        in_addr address = reinterpret_cast<const sockaddr_in&>(tuple.getSockaddr()).sin_addr;        in_addr address = reinterpret_cast<const sockaddr_in&>(tuple.getSockaddr()).sin_addr;
310        assert(sizeof(address)==4);        assert(sizeof(address)==4);
311        memcpy(&rawToken[3],&address,4);        memcpy(&rawToken[TOKEN_IP_ADDRESS_OFFSET],&address,4);
312     }     }
313        
314     container.clear();     container.clear();
315     container.reserve(((tuple.ipVersion()==V6) ? 28 : 16) + (salt.empty() ? 0 : 32));     container.reserve(((tuple.ipVersion()==V6) ? TOKEN_SIZE*4 : (TOKEN_SIZE-3)*4) + (salt.empty() ? 0 : 32));
316     container.append((char*)&rawToken[0],(tuple.ipVersion()==V6) ? 28 : 16);     container.append((char*)&rawToken[0],(tuple.ipVersion()==V6) ? TOKEN_SIZE*4 : (TOKEN_SIZE-3)*4);
317    
318     if(!salt.empty())     if(!salt.empty())
319     {     {
# Line 337  Line 359 
359     UInt16 port= (rawToken[2] >> 16);     UInt16 port= (rawToken[2] >> 16);
360    
361     // Now that we have the version we can do a more accurate check on the size     // Now that we have the version we can do a more accurate check on the size
362     if(!((version==V4 && salt.empty() && binaryFlowToken.size()==16) ||     if(!((version==V4 && salt.empty() && binaryFlowToken.size()==(TOKEN_SIZE-3)*4) ||
363          (version==V4 && !salt.empty() && binaryFlowToken.size()==48) ||          (version==V4 && !salt.empty() && binaryFlowToken.size()==(TOKEN_SIZE-3)*4 + 32) ||
364          (version==V6 && salt.empty() && binaryFlowToken.size()==28) ||          (version==V6 && salt.empty() && binaryFlowToken.size()==TOKEN_SIZE*4) ||
365          (version==V6 && !salt.empty() && binaryFlowToken.size()==60)))          (version==V6 && !salt.empty() && binaryFlowToken.size()==TOKEN_SIZE*4 + 32)))
366     {     {
367        DebugLog(<<"Binary flow token is the wrong size for its IP version.");        DebugLog(<<"Binary flow token is the wrong size for its IP version.");
368        return Tuple();        return Tuple();
# Line 349  Line 371 
371     // If salt is specified, validate HMAC     // If salt is specified, validate HMAC
372     if(!salt.empty())     if(!salt.empty())
373     {     {
374        unsigned int tokenSizeLessHMAC = version == V4 ? 16 : 28;        unsigned int tokenSizeLessHMAC = version == V4 ? (TOKEN_SIZE-3)*4 : TOKEN_SIZE*4;
375        Data flowTokenLessHMAC(Data::Share, binaryFlowToken.data(), tokenSizeLessHMAC);        Data flowTokenLessHMAC(Data::Share, binaryFlowToken.data(), tokenSizeLessHMAC);
376        Data flowTokenHMAC(Data::Share, binaryFlowToken.data()+tokenSizeLessHMAC, 32);        Data flowTokenHMAC(Data::Share, binaryFlowToken.data()+tokenSizeLessHMAC, 32);
377        MD5Stream ms;        MD5Stream ms;
# Line 361  Line 383 
383        }        }
384     }     }
385    
386       Data netNs("");
387    #ifdef USE_NETNS
388       int netNsId = rawToken[3];
389       try
390       {
391          netNs = NetNs::getNetNsName(netNsId);
392       }
393       catch(NetNs::Exception e)
394       {
395           ErrLog(<< "Tuple binary token contained netns id: " << netNsId << "which does not exist."
396                   << e);
397       }
398    #endif
399    
400     if(version==V6)     if(version==V6)
401     {     {
402  #ifdef USE_IPV6  #ifdef USE_IPV6
403        in6_addr address;        in6_addr address;
404        assert(sizeof(address)==16);        assert(sizeof(address)==16);
405        memcpy(&address,&rawToken[3],16);        memcpy(&address,&rawToken[TOKEN_IP_ADDRESS_OFFSET],16);
406        Tuple result(address,port,type);        Tuple result(address, port, type, Data::Empty, netNs);
407  #else  #else
408        Tuple result(resip::Data::Empty, port, type);        Tuple result(resip::Data::Empty, port, type, Data::Empty, netNs);
409  #endif  #endif
410        result.mFlowKey=(FlowKey)mFlowKey;        result.mFlowKey=(FlowKey)mFlowKey;
411        result.mTransportKey = (TransportKey)transportKey;        result.mTransportKey = (TransportKey)transportKey;
# Line 379  Line 415 
415    
416     in_addr address;     in_addr address;
417     assert(sizeof(address)==4);     assert(sizeof(address)==4);
418     memcpy(&address,&rawToken[3],4);     memcpy(&address,&rawToken[TOKEN_IP_ADDRESS_OFFSET],4);
419     Tuple result(address,port,type);     Tuple result(address, port, type, Data::Empty, netNs);
420     result.mFlowKey=(FlowKey)mFlowKey;     result.mFlowKey=(FlowKey)mFlowKey;
421     result.mTransportKey = (TransportKey)transportKey;     result.mTransportKey = (TransportKey)transportKey;
422     result.onlyUseExistingConnection=isRealFlow;     result.onlyUseExistingConnection=isRealFlow;
# Line 567  Line 603 
603        {        {
604           return (m_anonv4.sin_port == rhs.m_anonv4.sin_port &&           return (m_anonv4.sin_port == rhs.m_anonv4.sin_port &&
605                   mTransportType == rhs.mTransportType &&                   mTransportType == rhs.mTransportType &&
606                   memcmp(&m_anonv4.sin_addr, &rhs.m_anonv4.sin_addr, sizeof(in_addr)) == 0);                   memcmp(&m_anonv4.sin_addr, &rhs.m_anonv4.sin_addr, sizeof(in_addr)) == 0 &&
607                     rhs.mNetNs == mNetNs);
608        }        }
609        else // v6        else // v6
610        {        {
611  #ifdef USE_IPV6  #ifdef USE_IPV6
612           return (m_anonv6.sin6_port == rhs.m_anonv6.sin6_port &&           return (m_anonv6.sin6_port == rhs.m_anonv6.sin6_port &&
613                   mTransportType == rhs.mTransportType &&                   mTransportType == rhs.mTransportType &&
614                   memcmp(&m_anonv6.sin6_addr, &rhs.m_anonv6.sin6_addr, sizeof(in6_addr)) == 0);                   memcmp(&m_anonv6.sin6_addr, &rhs.m_anonv6.sin6_addr, sizeof(in6_addr)) == 0 &&
615                     rhs.mNetNs == mNetNs);
616  #else  #else
617           assert(0);           assert(0);
618           return false;           return false;
# Line 600  Line 638 
638     {     {
639        return false;        return false;
640     }     }
641    
642    #ifdef USE_NETNS
643       // netns needs to be checked before port and address as the port/address
644       // comparison bails out in equal case.  Ideally netns comparison should
645       // be last as its the most expensive comparison.  For now putting it here
646       // for minimal code change
647       else if(mNetNs < rhs.mNetNs)
648       {
649           return(true);
650       }
651       else if(mNetNs > rhs.mNetNs)
652       {
653           return(false);
654       }
655    #endif
656    
657     else if (mSockaddr.sa_family == AF_INET && rhs.mSockaddr.sa_family == AF_INET)     else if (mSockaddr.sa_family == AF_INET && rhs.mSockaddr.sa_family == AF_INET)
658     {     {
659        int c=memcmp(&m_anonv4.sin_addr,        int c=memcmp(&m_anonv4.sin_addr,
# Line 658  Line 712 
712        return false;        return false;
713     }     }
714  #endif  #endif
715    
716     else     else
717     {     {
718        //assert(0);        //assert(0);
# Line 703  Line 758 
758        ostrm << " transportKey=" << tuple.mTransportKey;        ostrm << " transportKey=" << tuple.mTransportKey;
759     }     }
760    
761    #ifdef USE_NETNS
762          ostrm << " mNetNs=" << tuple.mNetNs;
763    #endif
764    
765     ostrm << " ]";     ostrm << " ]";
766        
767     return ostrm;     return ostrm;
# Line 719  Line 778 
778           reinterpret_cast<const sockaddr_in6&>(mSockaddr);           reinterpret_cast<const sockaddr_in6&>(mSockaddr);
779    
780        return size_t(Data(Data::Share, (const char *)&in6.sin6_addr.s6_addr, sizeof(in6.sin6_addr.s6_addr)).hash() +        return size_t(Data(Data::Share, (const char *)&in6.sin6_addr.s6_addr, sizeof(in6.sin6_addr.s6_addr)).hash() +
781    #ifdef USE_NETNS
782                        mNetNs.hash() +
783    #endif
784                      5*in6.sin6_port +                      5*in6.sin6_port +
785                      25*mTransportType);                      25*mTransportType);
786     }     }
# Line 729  Line 791 
791           reinterpret_cast<const sockaddr_in&>(mSockaddr);           reinterpret_cast<const sockaddr_in&>(mSockaddr);
792                    
793        return size_t(in4.sin_addr.s_addr +        return size_t(in4.sin_addr.s_addr +
794    #ifdef USE_NETNS
795                        mNetNs.hash() +
796    #endif
797                      5*in4.sin_port +                      5*in4.sin_port +
798                      25*mTransportType);                      25*mTransportType);
799     }         }    
# Line 913  Line 978 
978     {     {
979        return false;        return false;
980     }     }
981     else if (lhs.mSockaddr.sa_family == AF_INET && rhs.mSockaddr.sa_family == AF_INET)  
982       // transport types equal, so compare addresses
983       if (lhs.mSockaddr.sa_family == AF_INET && rhs.mSockaddr.sa_family == AF_INET)
984     {     {
985        int c = memcmp(&lhs.m_anonv4.sin_addr,        int c = memcmp(&lhs.m_anonv4.sin_addr,
986                       &rhs.m_anonv4.sin_addr,                       &rhs.m_anonv4.sin_addr,
# Line 955  Line 1022 
1022        return false;        return false;
1023     }     }
1024  #endif  #endif
1025    #ifdef USE_NETNS
1026       // transport type and addresses are equal, so compare netns
1027       if(lhs.mNetNs < rhs.mNetNs)
1028       {
1029           //DebugLog(<< "AnyPortCompare netns less than (l=" << lhs.mNetNs << ", r=" << rhs.mNetNs);
1030           return(true);
1031       }
1032       else if(rhs.mNetNs < lhs.mNetNs)
1033       {
1034           //DebugLog(<< "AnyPortCompare netns greater than (l=" << lhs.mNetNs << ", r=" << rhs.mNetNs);
1035           return(false);
1036       }
1037       //DebugLog(<< "AnyPortCompare netns equal to (l=\"" << lhs.mNetNs << "\", r=\"" << rhs.mNetNs << "\"");
1038    #endif
1039    
1040     return false;     return false;
1041  }  }

Legend:
Removed from v.11152  
changed lines
  Added in v.11153

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27