reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
Tuple.cxx
Go to the documentation of this file.
1#if defined(HAVE_CONFIG_H)
2#include "config.h"
3#endif
4
6#include "rutil/compat.hxx"
7
8#include <iostream>
9#include <string.h>
10#include <sys/types.h>
11#include "rutil/ResipAssert.h"
12
13#if !defined (WIN32)
14#include <arpa/inet.h>
15#include <netinet/in.h>
16#if defined(__APPLE__) && !defined(s6_addr16)
17#define s6_addr16 __u6_addr.__u6_addr16
18#endif
19#endif
20
21#include "rutil/Data.hxx"
22#include "rutil/DnsUtil.hxx"
24#include "rutil/HashMap.hxx"
26#include "rutil/Logger.hxx"
27#ifdef USE_NETNS
28# include "rutil/NetNs.hxx"
29#endif
30
31using namespace resip;
32
33#define RESIPROCATE_SUBSYSTEM Subsystem::DNS
34
36 mFlowKey(0),
37 mTransportKey(0),
38 onlyUseExistingConnection(false),
39 mTransportType(UNKNOWN_TRANSPORT)
40{
41 sockaddr_in* addr4 = (sockaddr_in*)&mSockaddr;
42 memset(addr4, 0, sizeof(sockaddr_in));
43 mSockaddr.sa_family = AF_INET;
44}
45
46Tuple::Tuple(const GenericIPAddress& genericAddress, TransportType type,
47 const Data& targetDomain) :
48 mFlowKey(0),
49 mTransportKey(0),
50 onlyUseExistingConnection(false),
51 mTransportType(type),
52 mTargetDomain(targetDomain)
53{
54 setSockaddr(genericAddress);
55}
56
57
58Tuple::Tuple(const Data& printableAddr,
59 int port,
60 IpVersion ipVer,
61 TransportType type,
62 const Data& targetDomain,
63 const Data& netNs) :
64 mFlowKey(0),
65 mTransportKey(0),
66 onlyUseExistingConnection(false),
67 mTransportType(type),
68 mTargetDomain(targetDomain),
69 mNetNs(netNs)
70{
71 if (ipVer == V4)
72 {
73 memset(&m_anonv4, 0, sizeof(m_anonv4));
74 m_anonv4.sin_family = AF_INET;
75 m_anonv4.sin_port = htons(port);
76
77 if (printableAddr.empty())
78 {
79 m_anonv4.sin_addr.s_addr = htonl(INADDR_ANY);
80 }
81 else
82 {
83 DnsUtil::inet_pton( printableAddr, m_anonv4.sin_addr);
84 }
85 }
86 else
87 {
88#ifdef USE_IPV6
89 memset(&m_anonv6, 0, sizeof(m_anonv6));
90 m_anonv6.sin6_family = AF_INET6;
91 m_anonv6.sin6_port = htons(port);
92 if (printableAddr.empty())
93 {
94 m_anonv6.sin6_addr = in6addr_any;
95 }
96 else
97 {
98 DnsUtil::inet_pton( printableAddr, m_anonv6.sin6_addr);
99 }
100#else
101 // avoid asserts since Tuples created via printableAddr can be created from items
102 // received from the wire or from configuration settings. Just create an IPV4 inaddr_any tuple.
103 //assert(0);
104 memset(&m_anonv4, 0, sizeof(m_anonv4));
105 m_anonv4.sin_family = AF_INET;
106 m_anonv4.sin_port = htons(port);
107 m_anonv4.sin_addr.s_addr = htonl(INADDR_ANY);
108#endif
109 }
110}
111
112Tuple::Tuple(const Data& printableAddr,
113 int port,
114 TransportType ptype,
115 const Data& targetDomain,
116 const Data& netNs) :
117 mFlowKey(0),
118 mTransportKey(0),
119 onlyUseExistingConnection(false),
120 mTransportType(ptype),
121 mTargetDomain(targetDomain),
122 mNetNs(netNs)
123{
124 if (DnsUtil::isIpV4Address(printableAddr))
125 {
126 memset(&m_anonv4, 0, sizeof(m_anonv4));
127
128 DnsUtil::inet_pton( printableAddr, m_anonv4.sin_addr);
129 m_anonv4.sin_family = AF_INET;
130 m_anonv4.sin_port = htons(port);
131 }
132#ifdef USE_IPV6
133 else if(DnsUtil::isIpV6Address(printableAddr))
134 {
135 memset(&m_anonv6, 0, sizeof(m_anonv6));
136 DnsUtil::inet_pton( printableAddr, m_anonv6.sin6_addr);
137 m_anonv6.sin6_family = AF_INET6;
138 m_anonv6.sin6_port = htons(port);
139 }
140#endif
141 else
142 {
143 // avoid asserts since Tuples created via printableAddr can be created from items
144 // received from the wire or from configuration settings. Just create an IPV4 inaddr_any tuple.
145 // assert(0);
146 memset(&m_anonv4, 0, sizeof(m_anonv4));
147 m_anonv4.sin_family = AF_INET;
148 m_anonv4.sin_port = htons(port);
149 m_anonv4.sin_addr.s_addr = htonl(INADDR_ANY);
150 }
151}
152
153Tuple::Tuple(const in_addr& ipv4,
154 int port,
155 TransportType ptype,
156 const Data& targetDomain,
157 const Data& netNs)
158 :mFlowKey(0),
159 mTransportKey(0),
160 onlyUseExistingConnection(false),
161 mTransportType(ptype),
162 mTargetDomain(targetDomain),
163 mNetNs(netNs)
164{
165 memset(&m_anonv4, 0, sizeof(sockaddr_in));
166 m_anonv4.sin_addr = ipv4;
167 m_anonv4.sin_port = htons(port);
168 m_anonv4.sin_family = AF_INET;
169}
170
171#ifdef USE_IPV6
172Tuple::Tuple(const in6_addr& ipv6,
173 int port,
174 TransportType ptype,
175 const Data& targetDomaina,
176 const Data& netNs)
177 :mFlowKey(0),
178 mTransportKey(0),
179 onlyUseExistingConnection(false),
180 mTransportType(ptype),
181 mTargetDomain(targetDomaina),
182 mNetNs(netNs)
183{
184 memset(&m_anonv6, 0, sizeof(sockaddr_in6));
185 m_anonv6.sin6_addr = ipv6;
186 m_anonv6.sin6_port = htons(port);
187 m_anonv6.sin6_family = AF_INET6;
188}
189#endif
190
191Tuple::Tuple(const struct sockaddr& addr,
192 TransportType ptype,
193 const Data& targetDomain) :
194 mFlowKey(0),
195 mTransportKey(0),
196 onlyUseExistingConnection(false),
197 mSockaddr(addr),
198 mTransportType(ptype),
199 mTargetDomain(targetDomain)
200{
201 if (addr.sa_family == AF_INET)
202 {
203 m_anonv4 = (sockaddr_in&)(addr);
204 }
205#ifdef USE_IPV6
206 else if (addr.sa_family == AF_INET6)
207 {
208 m_anonv6 = (sockaddr_in6&)(addr);
209 }
210#endif
211 else
212 {
213 resip_assert(0);
214 }
215}
216
217void
219{
220 memcpy(sa, &mSockaddr, length());
221 // zero the port number
222 if (sa->sa_family == AF_INET)
223 {
224 ((sockaddr_in*)sa)->sin_port = 0;
225 }
226#ifdef USE_IPV6
227 else if (sa->sa_family == AF_INET6)
228 {
229 ((sockaddr_in6*)sa)->sin6_port = 0;
230 }
231#endif
232 else
233 {
234 resip_assert(0);
235 }
236}
237
238void
240{
241 if (addr.isVersion4())
242 {
243 m_anonv4 = addr.v4Address;
244 }
245 else
246#ifdef USE_IPV6
247 {
248 m_anonv6 = addr.v6Address;
249 }
250#else
251 {
252 resip_assert(0);
253 }
254#endif
255}
256
257#ifdef USE_NETNS
258# define TOKEN_SIZE 8
259# define TOKEN_IP_ADDRESS_OFFSET 4
260#else
261# define TOKEN_SIZE 7
262# define TOKEN_IP_ADDRESS_OFFSET 3
263#endif
264
265void
266Tuple::writeBinaryToken(const resip::Tuple& tuple, resip::Data& container, const Data& salt)
267{
268 // .bwc. Maybe should just write the raw sockaddr into a buffer, and tack
269 // on the flowid and onlyUseExistingConnection flag. Would require 10 extra
270 // bytes for V6, and 14 extra bytes for V4.
271 // V6: sin6_len(1), sin6_flowinfo(4), flowId(4), onlyUseExistingConnection(1)
272 // V4: sin_family(2 instead of 1), sin_zero(8), flowId(4), onlyUseExistingConnection(1)
273 uint32_t rawToken[TOKEN_SIZE];
274 memset(&rawToken, 0, TOKEN_SIZE * 4);
275
276 rawToken[0] = tuple.mFlowKey;
277
278 rawToken[1] = tuple.mTransportKey;
279
280 // 0xXXXX0000
281 rawToken[2] += (tuple.getPort() << 16);
282
283 // 0x0000XX00
284 rawToken[2] += (tuple.getType() << 8);
285
286 // 0x000000X0
288 {
289 rawToken[2] += 0x00000010;
290 }
291
292#ifdef USE_NETNS
293 rawToken[3] = NetNs::getNetNsId(tuple.getNetNs());
294#endif
295
296#ifdef USE_IPV6
297 if(tuple.ipVersion()==V6)
298 {
299 // 0x0000000X
300 rawToken[2] += 0x00000001;
301 in6_addr address = reinterpret_cast<const sockaddr_in6&>(tuple.getSockaddr()).sin6_addr;
302 resip_assert(sizeof(address)==16);
303 memcpy(&rawToken[TOKEN_IP_ADDRESS_OFFSET],&address,16);
304 }
305 else
306#endif
307 {
308 in_addr address = reinterpret_cast<const sockaddr_in&>(tuple.getSockaddr()).sin_addr;
309 resip_assert(sizeof(address)==4);
310 memcpy(&rawToken[TOKEN_IP_ADDRESS_OFFSET],&address,4);
311 }
312
313 container.clear();
314 container.reserve(((tuple.ipVersion()==V6) ? TOKEN_SIZE*4 : (TOKEN_SIZE-3)*4) + (salt.empty() ? 0 : 32));
315 container.append((char*)&rawToken[0],(tuple.ipVersion()==V6) ? TOKEN_SIZE*4 : (TOKEN_SIZE-3)*4);
316
317 if(!salt.empty())
318 {
319 // TODO - potentially use SHA1 HMAC for stronger encryption
320 DigestStream ms;
321 ms << container << salt;
322 container += ms.getHex();
323 }
324}
325
326
327Tuple
328Tuple::makeTupleFromBinaryToken(const resip::Data& binaryFlowToken, const Data& salt)
329{
330 // To check if size is valid, we first need the IP version, so make sure the token is at least
331 // the size of an IPv4 token
332 if(binaryFlowToken.size()<16)
333 {
334 // !bwc! Should not assert here, since this sort of thing
335 // can come off the wire easily.
336 // TODO Throw an exception here?
337 DebugLog(<<"binary flow token was too small: " << binaryFlowToken.size());
338 return Tuple();
339 }
340
341 const uint32_t* rawToken=reinterpret_cast<const uint32_t*>(binaryFlowToken.data());
342
343 FlowKey mFlowKey=rawToken[0];
344 TransportKey transportKey=rawToken[1];
345
346 IpVersion version = (rawToken[2] & 0x00000001 ? V6 : V4);
347
348 bool isRealFlow = (rawToken[2] & 0x00000010 ? true : false);
349
350 uint8_t temp = (TransportType)((rawToken[2] & 0x00000F00) >> 8);
351 if(temp >= MAX_TRANSPORT)
352 {
353 DebugLog(<<"Garbage transport type in flow token: " << temp );
354 return Tuple();
355 }
356 TransportType type = (TransportType)temp;
357
358 uint16_t port= (rawToken[2] >> 16);
359
360 // Now that we have the version we can do a more accurate check on the size
361 if(!((version==V4 && salt.empty() && binaryFlowToken.size()==(TOKEN_SIZE-3)*4) ||
362 (version==V4 && !salt.empty() && binaryFlowToken.size()==(TOKEN_SIZE-3)*4 + 32) ||
363 (version==V6 && salt.empty() && binaryFlowToken.size()==TOKEN_SIZE*4) ||
364 (version==V6 && !salt.empty() && binaryFlowToken.size()==TOKEN_SIZE*4 + 32)))
365 {
366 DebugLog(<<"Binary flow token is the wrong size for its IP version.");
367 return Tuple();
368 }
369
370 // If salt is specified, validate HMAC
371 if(!salt.empty())
372 {
373 unsigned int tokenSizeLessHMAC = version == V4 ? (TOKEN_SIZE-3)*4 : TOKEN_SIZE*4;
374 Data flowTokenLessHMAC(Data::Share, binaryFlowToken.data(), tokenSizeLessHMAC);
375 Data flowTokenHMAC(Data::Share, binaryFlowToken.data()+tokenSizeLessHMAC, 32);
376 DigestStream ms;
377 ms << flowTokenLessHMAC << salt;
378 if(ms.getHex() != flowTokenHMAC)
379 {
380 DebugLog(<<"Binary flow token has invalid HMAC, not our token");
381 return Tuple();
382 }
383 }
384
385 Data netNs("");
386#ifdef USE_NETNS
387 int netNsId = rawToken[3];
388 try
389 {
390 netNs = NetNs::getNetNsName(netNsId);
391 }
392 catch (const NetNs::Exception& e)
393 {
394 ErrLog(<< "Tuple binary token contained netns id: " << netNsId << "which does not exist."
395 << e);
396 }
397#endif
398
399 if(version==V6)
400 {
401#ifdef USE_IPV6
402 in6_addr address;
403 resip_assert(sizeof(address)==16);
404 memcpy(&address,&rawToken[TOKEN_IP_ADDRESS_OFFSET],16);
405 Tuple result(address, port, type, Data::Empty, netNs);
406#else
407 Tuple result(resip::Data::Empty, port, type, Data::Empty, netNs);
408#endif
409 result.mFlowKey=(FlowKey)mFlowKey;
410 result.mTransportKey = (TransportKey)transportKey;
411 result.onlyUseExistingConnection=isRealFlow;
412 return result;
413 }
414
415 in_addr address;
416 resip_assert(sizeof(address)==4);
417 memcpy(&address,&rawToken[TOKEN_IP_ADDRESS_OFFSET],4);
418 Tuple result(address, port, type, Data::Empty, netNs);
419 result.mFlowKey=(FlowKey)mFlowKey;
420 result.mTransportKey = (TransportKey)transportKey;
421 result.onlyUseExistingConnection=isRealFlow;
422 return result;
423}
424
425Data
427{
428#ifdef USE_IPV6
429 if (isV4())
430 {
431 return Tuple::inet_ntop(*this);
432 }
433 else if (IN6_IS_ADDR_V4MAPPED(&m_anonv6.sin6_addr))
434 {
435 return DnsUtil::inet_ntop(*(reinterpret_cast<const in_addr*>(
436 (reinterpret_cast<const unsigned char*>(&m_anonv6.sin6_addr) + 12))));
437 }
438 else
439 {
440 return Tuple::inet_ntop(*this);
441 }
442#else
443 return Tuple::inet_ntop(*this);
444#endif
445
446}
447
448void
450{
451 if (mSockaddr.sa_family == AF_INET) // v4
452 {
453 m_anonv4.sin_port = htons(port);
454 }
455 else
456 {
457#ifdef USE_IPV6
458 m_anonv6.sin6_port = htons(port);
459#else
460 resip_assert(0);
461#endif
462 }
463}
464
465int
467{
468 if (mSockaddr.sa_family == AF_INET) // v4
469 {
470 return ntohs(m_anonv4.sin_port);
471 }
472 else
473 {
474#ifdef USE_IPV6
475 return ntohs(m_anonv6.sin6_port);
476#else
477 resip_assert(0);
478#endif
479 }
480
481 return -1;
482}
483
484bool
486{
487 if (isV4())
488 {
489 return m_anonv4.sin_addr.s_addr == htonl(INADDR_ANY);
490 }
491#if defined (USE_IPV6)
492 else
493 {
494 return memcmp(&m_anonv6.sin6_addr, &in6addr_any, sizeof(in6_addr)) == 0;
495 }
496#else
497 return false;
498#endif
499}
500
501static Tuple loopbackv4("127.0.0.1",0,UNKNOWN_TRANSPORT);
502bool
504{
505 if(ipVersion()==V4)
506 {
507 return isEqualWithMask(loopbackv4,8,true,true);
508 }
509 else if (ipVersion()==V6)
510 {
511#ifdef USE_IPV6
512#if defined(__linux__) || defined(__APPLE__) || defined(WIN32)
513 return IN6_IS_ADDR_LOOPBACK(&(m_anonv6.sin6_addr)) != 0;
514#else
515 return ((*(const __uint32_t *)(const void *)(&(m_anonv6.sin6_addr.s6_addr[0])) == 0) &&
516 (*(const __uint32_t *)(const void *)(&(m_anonv6.sin6_addr.s6_addr[4])) == 0) &&
517 (*(const __uint32_t *)(const void *)(&(m_anonv6.sin6_addr.s6_addr[8])) == 0) &&
518 (*(const __uint32_t *)(const void *)(&(m_anonv6.sin6_addr.s6_addr[12])) == ntohl(1)));
519#endif
520#endif
521 }
522 else
523 {
524 resip_assert(0);
525 }
526
527 return false;
528}
529
530bool
532{
533 return mSockaddr.sa_family == AF_INET;
534}
535
538{
539 return mSockaddr.sa_family == AF_INET ? V4 : V6;
540}
541
546
547#ifdef USE_IPV6
549#endif
550
551bool
553{
554 if(ipVersion()==V4)
555 {
556 // RFC 1918 & RFC 6598
557 return isEqualWithMask(v4privateaddrbase1,8,true,true) || // 10.0.0.0 - 10.255.255.255 (10/8 prefix)
558 isEqualWithMask(v4privateaddrbase2,12,true,true) || // 172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
559 isEqualWithMask(v4privateaddrbase3,16,true,true) || // 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
560 isEqualWithMask(v4sharedaddrbase1,10,true,true) || // 100.64.0.0 - 100.127.255.255 (100.64/110 prefix)
561 isLoopback();
562 }
563#ifdef USE_IPV6
564 else if (ipVersion()==V6)
565 {
566 // RFC 4193
567 // ?slg? should we look specifically for ipv4 mapped/compatible address and apply V4 rules to them?
568 return isEqualWithMask(v6privateaddrbase,7,true,true) || // fc00::/7
569 isLoopback();
570 }
571#endif
572 else
573 {
574 resip_assert(0);
575 }
576
577 return false;
578}
579
581static Tuple v4llinklocal("169.254.0.0", 0, UNKNOWN_TRANSPORT);
582static Tuple v4ietfprotocol("192.0.0.0", 0, UNKNOWN_TRANSPORT);
584static Tuple v4documentation2("198.51.100.0", 0, UNKNOWN_TRANSPORT);
585static Tuple v4documentation3("203.0.113.0", 0, UNKNOWN_TRANSPORT);
587static Tuple v4benchmarking("198.18.0.0", 0, UNKNOWN_TRANSPORT);
588static Tuple v4reserved("240.0.0.0", 0, UNKNOWN_TRANSPORT);
589static Tuple v4broadcast("255.255.255.255", 0, UNKNOWN_TRANSPORT);
590static Tuple v4multicast("224.0.0.0", 0, UNKNOWN_TRANSPORT);
591
592#ifdef USE_IPV6
599static Tuple v6documentation("2001:db8::", 0, UNKNOWN_TRANSPORT);
600static Tuple v6orchid("2001:10::", 0, UNKNOWN_TRANSPORT);
601static Tuple v66to4("2002::", 0, UNKNOWN_TRANSPORT);
605#endif
606
607// Returns true if this is an address that is specified as a special address in RFC 6890, which includes:
608// private addresses, loopback addresses, link-local addresses, and multicast addresses. These are all
609// address types that are not expected to be routable on the public internet.
610bool
612{
613 if (isPrivateAddress()) return true; // Covers loopback
614
615 if (ipVersion() == V4)
616 {
617 return isEqualWithMask(v4thishostonthisnetwork, 8, true, true) || // "This host on this network"
618 isEqualWithMask(v4llinklocal, 16, true, true) || // Link Local
619 isEqualWithMask(v4ietfprotocol, 24, true, true) || // IETF Protocol assignments, also covers DS-Lite (192.0.0.0/29)
620 isEqualWithMask(v4documentation1, 24, true, true) || // Documentation (TEST-NET-1)
621 isEqualWithMask(v4documentation2, 24, true, true) || // Documentation (TEST-NET-2)
622 isEqualWithMask(v4documentation3, 24, true, true) || // Documentation (TEST-NET-3)
623 isEqualWithMask(v46to5relayanycast, 24, true, true) || // 6to4 Relay Anycast
624 isEqualWithMask(v4benchmarking, 15, true, true) || // Benchmarking
625 isEqualWithMask(v4reserved, 4, true, true) || // Reserved
626 isEqualWithMask(v4broadcast, 32, true, true) || // Limited Broadcast
627 isEqualWithMask(v4multicast, 4, true, true); // Multicast
628 }
629#ifdef USE_IPV6
630 else if (ipVersion() == V6)
631 {
632 return isEqualWithMask(v6unspecified, 128, true, true) || // Unspecified address
633 isEqualWithMask(v64to6translation, 96, true, true) || // IPv4-IPv6 translation
634 isEqualWithMask(v6v4mappedaddress, 96, true, true) || // IPv4-mapped address
635 isEqualWithMask(v6discardonly, 64, true, true) || // Discard-only address
636 isEqualWithMask(v6ietfprotocol, 23, true, true) || // IETF Protocol assignments, also covers TEREDO (2001::/32)
637 isEqualWithMask(v6benchmarking, 48, true, true) || // Benchmarking
638 isEqualWithMask(v6documentation, 32, true, true) || // Documentation
639 isEqualWithMask(v6orchid, 28, true, true) || // ORCHID
640 isEqualWithMask(v66to4, 16, true, true) || // 6to4
641 isEqualWithMask(v6uniquelocal, 7, true, true) || // Unique local address
642 isEqualWithMask(v6linkedscopedunicast, 10, true, true) || // Link-Scoped Unicast
643 isEqualWithMask(v6multicast, 8, true, true); // Multicast
644 }
645#endif
646 else
647 {
648 resip_assert(0);
649 }
650
651 return false;
652}
653
654socklen_t
656{
657 if (mSockaddr.sa_family == AF_INET) // v4
658 {
659 return sizeof(sockaddr_in);
660 }
661#ifdef USE_IPV6
662 else if (mSockaddr.sa_family == AF_INET6) // v6
663 {
664 return sizeof(sockaddr_in6);
665 }
666#endif
667
668 resip_assert(0);
669 return 0;
670}
671
672
673bool
674Tuple::operator==(const Tuple& rhs) const
675{
676 return isEqual(rhs);
677}
678
679bool
680Tuple::isEqual(const Tuple& compare, bool ignorePort, bool ignoreTransport) const
681{
682 if (ignoreTransport || getType() == compare.getType()) // check if transport type matches
683 {
684 if (mSockaddr.sa_family == compare.mSockaddr.sa_family)
685 {
686 if (mSockaddr.sa_family == AF_INET) // v4
687 {
688 return ((ignorePort || m_anonv4.sin_port == compare.m_anonv4.sin_port) &&
689 memcmp(&m_anonv4.sin_addr, &compare.m_anonv4.sin_addr, sizeof(in_addr)) == 0 &&
690 compare.mNetNs == mNetNs);
691 }
692 else // v6
693 {
694#ifdef USE_IPV6
695 return ((ignorePort || m_anonv6.sin6_port == compare.m_anonv6.sin6_port) &&
696 memcmp(&m_anonv6.sin6_addr, &compare.m_anonv6.sin6_addr, sizeof(in6_addr)) == 0 &&
697 compare.mNetNs == mNetNs);
698#else
699 resip_assert(0);
700#endif
701 }
702 }
703 }
704
705 // !dlb! don't include connection
706
707 return false;
708}
709
710bool
711Tuple::operator<(const Tuple& rhs) const
712{
713 if (mTransportType < rhs.mTransportType)
714 {
715 return true;
716 }
717 else if (mTransportType > rhs.mTransportType)
718 {
719 return false;
720 }
721
722#ifdef USE_NETNS
723 // netns needs to be checked before port and address as the port/address
724 // comparison bails out in equal case. Ideally netns comparison should
725 // be last as its the most expensive comparison. For now putting it here
726 // for minimal code change
727 else if(mNetNs < rhs.mNetNs)
728 {
729 return(true);
730 }
731 else if(mNetNs > rhs.mNetNs)
732 {
733 return(false);
734 }
735#endif
736
737 else if (mSockaddr.sa_family == AF_INET && rhs.mSockaddr.sa_family == AF_INET)
738 {
739 int c=memcmp(&m_anonv4.sin_addr,
740 &rhs.m_anonv4.sin_addr,
741 sizeof(in_addr));
742
743 if (c < 0)
744 {
745 return true;
746 }
747 else if (c > 0)
748 {
749 return false;
750 }
751 else if (m_anonv4.sin_port < rhs.m_anonv4.sin_port)
752 {
753 return true;
754 }
755 else
756 {
757 return false;
758 }
759 }
760#ifdef USE_IPV6
761 else if (mSockaddr.sa_family == AF_INET6 &&
762 rhs.mSockaddr.sa_family == AF_INET6)
763 {
764 int c = memcmp(&m_anonv6.sin6_addr,
765 &rhs.m_anonv6.sin6_addr,
766 sizeof(in6_addr));
767 if (c < 0)
768 {
769 return true;
770 }
771 else if (c > 0)
772 {
773 return false;
774 }
775 else if (m_anonv6.sin6_port < rhs.m_anonv6.sin6_port)
776 {
777 return true;
778 }
779 else
780 {
781 return false;
782 }
783 }
784 else if (mSockaddr.sa_family == AF_INET6 &&
785 rhs.mSockaddr.sa_family == AF_INET)
786 {
787 return true;
788 }
789 else if (mSockaddr.sa_family == AF_INET &&
790 rhs.mSockaddr.sa_family == AF_INET6)
791 {
792 return false;
793 }
794#endif
795
796 else
797 {
798 //assert(0);
799 return false;
800 }
801}
802
804resip::operator<<(EncodeStream& ostrm, const Tuple& tuple)
805{
806 ostrm << "[ " ;
807
808#ifdef USE_IPV6
809 if (tuple.mSockaddr.sa_family == AF_INET6)
810 {
811 ostrm << "V6 " << DnsUtil::inet_ntop(tuple.m_anonv6.sin6_addr) << " port=" << tuple.getPort();
812 }
813 else
814#endif
815 if (tuple.mSockaddr.sa_family == AF_INET)
816 {
817 ostrm << "V4 " << Tuple::inet_ntop(tuple) << ":" << tuple.getPort();
818 }
819 else
820 {
821 resip_assert(0);
822 }
823
824 ostrm << " " << Tuple::toData(tuple.mTransportType);
825
826 if (!tuple.mTargetDomain.empty())
827 {
828 ostrm << " targetDomain=" << tuple.mTargetDomain;
829 }
830
831 if(tuple.mFlowKey != 0)
832 {
833 ostrm << " flowKey=" << tuple.mFlowKey;
834 }
835
836 if(tuple.mTransportKey != 0)
837 {
838 ostrm << " transportKey=" << tuple.mTransportKey;
839 }
840
841#ifdef USE_NETNS
842 ostrm << " mNetNs=" << tuple.mNetNs;
843#endif
844
845 ostrm << " ]";
846
847 return ostrm;
848}
849
851resip::operator<<(EncodeStream& ostrm, const AddressMask& addressMask)
852{
853 ostrm << addressMask.mAddress << "/" << addressMask.mMaskBits;
854 return ostrm;
855}
856
857bool
858Tuple::isAddressAllowed(const std::vector<AddressMask>& allowed,
859 const std::vector<AddressMask>& denied) const
860{
861 // Deny wins.
862 for (const AddressMask& entry : denied)
863 {
864 if (entry.mAddress.isEqualWithMask(*this, entry.mMaskBits, true /*ignorePort*/, true /*ignoreTransport*/))
865 {
866 return false;
867 }
868 }
869
870 // If an allow list is configured, this address must match one of its entries.
871 if (!allowed.empty())
872 {
873 for (const AddressMask& entry : allowed)
874 {
875 if (entry.mAddress.isEqualWithMask(*this, entry.mMaskBits, true /*ignorePort*/, true /*ignoreTransport*/))
876 {
877 return true;
878 }
879 }
880 return false;
881 }
882
883 return true;
884}
885
886size_t
888{
889 // !dlb! do not include the connection
890#ifdef USE_IPV6
891 if (mSockaddr.sa_family == AF_INET6)
892 {
893 const sockaddr_in6& in6 =
894 reinterpret_cast<const sockaddr_in6&>(mSockaddr);
895
896 return size_t(Data(Data::Share, (const char *)&in6.sin6_addr.s6_addr, sizeof(in6.sin6_addr.s6_addr)).hash() +
897#ifdef USE_NETNS
898 mNetNs.hash() +
899#endif
900 5*in6.sin6_port +
901 25*mTransportType);
902 }
903 else
904#endif
905 {
906 const sockaddr_in& in4 =
907 reinterpret_cast<const sockaddr_in&>(mSockaddr);
908
909 return size_t(in4.sin_addr.s_addr +
910#ifdef USE_NETNS
911 mNetNs.hash() +
912#endif
913 5*in4.sin_port +
914 25*mTransportType);
915 }
916}
917
919
921Tuple::toTransport(const Data& transportName)
922{
923 return resip::toTransportType(transportName); // TransportTypes.hxx
924};
925
926const Data&
928{
929 return resip::toData(type); // TransportTypes.hxx
930}
931
932const Data&
934{
935 return resip::toDataLower(type); // TransportTypes.hxx
936}
937
938Data
940{
941#ifdef USE_IPV6
942 if (!tuple.isV4())
943 {
944 const sockaddr_in6& addr = reinterpret_cast<const sockaddr_in6&>(tuple.getSockaddr());
945 return DnsUtil::inet_ntop(addr.sin6_addr);
946 }
947 else
948#endif
949 {
950 const sockaddr_in& addr = reinterpret_cast<const sockaddr_in&>(tuple.getSockaddr());
951 return DnsUtil::inet_ntop(addr.sin_addr);
952 }
953}
954
955bool
956Tuple::isEqualWithMask(const Tuple& compare, short mask, bool ignorePort, bool ignoreTransport) const
957{
958 if(ignoreTransport || getType() == compare.getType()) // check if transport type matches
959 {
960 if (mSockaddr.sa_family == compare.getSockaddr().sa_family && mSockaddr.sa_family == AF_INET) // v4
961 {
962 sockaddr_in* addr1 = (sockaddr_in*)&mSockaddr;
963 sockaddr_in* addr2 = (sockaddr_in*)&compare.getSockaddr();
964
965 return ((ignorePort || addr1->sin_port == addr2->sin_port) &&
966 (addr1->sin_addr.s_addr & htonl((0xFFFFFFFF << (32 - mask)))) ==
967 (addr2->sin_addr.s_addr & htonl((0xFFFFFFFF << (32 - mask)))));
968 }
969#ifdef USE_IPV6
970 else if (mSockaddr.sa_family == compare.getSockaddr().sa_family && mSockaddr.sa_family == AF_INET6) // v6
971 {
972 sockaddr_in6* addr1 = (sockaddr_in6*)&mSockaddr;
973 sockaddr_in6* addr2 = (sockaddr_in6*)&compare.getSockaddr();
974
975 if(ignorePort || addr1->sin6_port == addr2->sin6_port)
976 {
977 uint32_t mask6part;
978 uint32_t temp;
979 bool match=true;
980 for(int i = 3; i >= 0; i--)
981 {
982 if(mask <= 32*i)
983 {
984 mask6part = 0;
985 }
986 else
987 {
988 temp = mask - 32*i;
989 if(temp >= 32)
990 {
991 mask6part = 0xffffffff;
992 }
993 else
994 {
995 mask6part = 0xffffffff << (32 - temp);
996 }
997 }
998#ifdef WIN32
999 if((*((unsigned long*)&addr1->sin6_addr.u.Word[i*2]) & htonl(mask6part)) !=
1000 (*((unsigned long*)&addr2->sin6_addr.u.Word[i*2]) & htonl(mask6part)))
1001#elif defined(sun)
1002 // sun has no s6_addr16
1003 if((*((unsigned long*)&addr1->sin6_addr._S6_un._S6_u32[i]) & htonl(mask6part)) !=
1004 (*((unsigned long*)&addr2->sin6_addr._S6_un._S6_u32[i]) & htonl(mask6part)))
1005#elif defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__)
1006 // bsd has no s6_addr16
1007 if((*((unsigned long*)&addr1->sin6_addr.__u6_addr.__u6_addr32[i]) & htonl(mask6part)) !=
1008 (*((unsigned long*)&addr2->sin6_addr.__u6_addr.__u6_addr32[i]) & htonl(mask6part)))
1009#else
1010 if((*((uint32_t*)&addr1->sin6_addr.s6_addr16[i*2]) & htonl(mask6part)) !=
1011 (*((uint32_t*)&addr2->sin6_addr.s6_addr16[i*2]) & htonl(mask6part)))
1012#endif
1013 {
1014 match=false;
1015 break;
1016 }
1017 }
1018 if(match)
1019 {
1020 return true;
1021 }
1022 }
1023 }
1024#endif
1025 }
1026 return false;
1027}
1028
1029// special comparitors
1030bool
1032 const Tuple& rhs) const
1033{
1034 if (lhs.mTransportType < rhs.mTransportType)
1035 {
1036 return true;
1037 }
1038 else if (lhs.mTransportType > rhs.mTransportType)
1039 {
1040 return false;
1041 }
1042 else if (lhs.mSockaddr.sa_family == AF_INET && rhs.mSockaddr.sa_family == AF_INET)
1043 {
1044 if (lhs.m_anonv4.sin_port < rhs.m_anonv4.sin_port)
1045 {
1046 return true;
1047 }
1048 else
1049 {
1050 return false;
1051 }
1052 }
1053#ifdef USE_IPV6
1054 else if (lhs.mSockaddr.sa_family == AF_INET6 &&
1055 rhs.mSockaddr.sa_family == AF_INET6)
1056 {
1057 if (lhs.m_anonv6.sin6_port < rhs.m_anonv6.sin6_port)
1058 {
1059 return true;
1060 }
1061 else
1062 {
1063 return false;
1064 }
1065 }
1066 else if (lhs.mSockaddr.sa_family == AF_INET6 &&
1067 rhs.mSockaddr.sa_family == AF_INET)
1068 {
1069 return true;
1070 }
1071 else if (lhs.mSockaddr.sa_family == AF_INET &&
1072 rhs.mSockaddr.sa_family == AF_INET6)
1073 {
1074 return false;
1075 }
1076#endif
1077 else
1078 {
1079 return false;
1080 }
1081};
1082
1083bool
1085 const Tuple& rhs) const
1086{
1087 if (lhs.mTransportType < rhs.mTransportType)
1088 {
1089 return true;
1090 }
1091 else if (lhs.mTransportType > rhs.mTransportType)
1092 {
1093 return false;
1094 }
1095
1096 // transport types equal, so compare addresses
1097 if (lhs.mSockaddr.sa_family == AF_INET && rhs.mSockaddr.sa_family == AF_INET)
1098 {
1099 int c = memcmp(&lhs.m_anonv4.sin_addr,
1100 &rhs.m_anonv4.sin_addr,
1101 sizeof(in_addr));
1102
1103 if (c < 0)
1104 {
1105 return true;
1106 }
1107 else if (c > 0)
1108 {
1109 return false;
1110 }
1111 }
1112#ifdef USE_IPV6
1113 else if (lhs.mSockaddr.sa_family == AF_INET6 &&
1114 rhs.mSockaddr.sa_family == AF_INET6)
1115 {
1116 int c = memcmp(&lhs.m_anonv6.sin6_addr,
1117 &rhs.m_anonv6.sin6_addr,
1118 sizeof(in6_addr));
1119 if (c < 0)
1120 {
1121 return true;
1122 }
1123 else if (c > 0)
1124 {
1125 return false;
1126 }
1127 }
1128 else if (lhs.mSockaddr.sa_family == AF_INET6 &&
1129 rhs.mSockaddr.sa_family == AF_INET)
1130 {
1131 return true;
1132 }
1133 else if (lhs.mSockaddr.sa_family == AF_INET &&
1134 rhs.mSockaddr.sa_family == AF_INET6)
1135 {
1136 return false;
1137 }
1138#endif
1139#ifdef USE_NETNS
1140 // transport type and addresses are equal, so compare netns
1141 if(lhs.mNetNs < rhs.mNetNs)
1142 {
1143 //DebugLog(<< "AnyPortCompare netns less than (l=" << lhs.mNetNs << ", r=" << rhs.mNetNs);
1144 return(true);
1145 }
1146 else if(rhs.mNetNs < lhs.mNetNs)
1147 {
1148 //DebugLog(<< "AnyPortCompare netns greater than (l=" << lhs.mNetNs << ", r=" << rhs.mNetNs);
1149 return(false);
1150 }
1151 //DebugLog(<< "AnyPortCompare netns equal to (l=\"" << lhs.mNetNs << "\", r=\"" << rhs.mNetNs << "\"");
1152#endif
1153
1154 return false;
1155}
1156
1157bool
1159 const Tuple& rhs) const
1160{
1161 if (lhs == rhs)
1162 {
1163 return lhs.mFlowKey < rhs.mFlowKey;
1164 }
1165 return lhs < rhs;
1166};
1167
1170{
1171 if (isV4())
1172 {
1173 return GenericIPAddress(m_anonv4);
1174 }
1175 else
1176#ifdef USE_IPV6
1177 {
1178 return GenericIPAddress(m_anonv6);
1179 }
1180#else
1181 {
1182 resip_assert(0);
1183 return m_anonv4; //bogus
1184 }
1185#endif
1186}
1187
1188bool
1190 const Tuple& rhs) const
1191{
1192 if (lhs.mTransportType < rhs.mTransportType)
1193 {
1194 return true;
1195 }
1196 else if (lhs.mTransportType > rhs.mTransportType)
1197 {
1198 return false;
1199 }
1200#ifdef USE_IPV6
1201 else if (lhs.mSockaddr.sa_family == AF_INET6 &&
1202 rhs.mSockaddr.sa_family == AF_INET)
1203 {
1204 return true;
1205 }
1206 else if (lhs.mSockaddr.sa_family == AF_INET &&
1207 rhs.mSockaddr.sa_family == AF_INET6)
1208 {
1209 return false;
1210 }
1211#endif
1212 else
1213 {
1214 return false;
1215 }
1216};
1217
1218/* ====================================================================
1219 * The Vovida Software License, Version 1.0
1220 *
1221 * Copyright (c) 2026 SIP Spectrum, Inc. https://www.sipspectrum.com
1222 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
1223 *
1224 * Redistribution and use in source and binary forms, with or without
1225 * modification, are permitted provided that the following conditions
1226 * are met:
1227 *
1228 * 1. Redistributions of source code must retain the above copyright
1229 * notice, this list of conditions and the following disclaimer.
1230 *
1231 * 2. Redistributions in binary form must reproduce the above copyright
1232 * notice, this list of conditions and the following disclaimer in
1233 * the documentation and/or other materials provided with the
1234 * distribution.
1235 *
1236 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
1237 * and "Vovida Open Communication Application Library (VOCAL)" must
1238 * not be used to endorse or promote products derived from this
1239 * software without prior written permission. For written
1240 * permission, please contact vocal@vovida.org.
1241 *
1242 * 4. Products derived from this software may not be called "VOCAL", nor
1243 * may "VOCAL" appear in their name, without prior written
1244 * permission of Vovida Networks, Inc.
1245 *
1246 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
1247 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1248 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
1249 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
1250 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
1251 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
1252 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1253 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
1254 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
1255 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1256 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
1257 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1258 * DAMAGE.
1259 *
1260 * ====================================================================
1261 *
1262 * This software consists of voluntary contributions made by Vovida
1263 * Networks, Inc. and many individuals on behalf of Vovida Networks,
1264 * Inc. For more information on Vovida Networks, Inc., please see
1265 * <http://www.vovida.org/>.
1266 *
1267 */
Wraps your platform's implementation of hash_map, hash_multimap, and hash_set.
#define HashValueImp(type, ret)
Definition HashMap.hxx:24
#define DebugLog(args_)
Definition Logger.hxx:128
#define ErrLog(args_)
Definition Logger.hxx:137
#define resip_assert(x)
This file needs to work for both C and C++ code.
static Tuple v4documentation1("192.0.2.0", 0, UNKNOWN_TRANSPORT)
static Tuple v6linkedscopedunicast("fe80::", 0, UNKNOWN_TRANSPORT)
static Tuple v4documentation2("198.51.100.0", 0, UNKNOWN_TRANSPORT)
static Tuple v66to4("2002::", 0, UNKNOWN_TRANSPORT)
static Tuple v4multicast("224.0.0.0", 0, UNKNOWN_TRANSPORT)
static Tuple v4broadcast("255.255.255.255", 0, UNKNOWN_TRANSPORT)
static Tuple v4benchmarking("198.18.0.0", 0, UNKNOWN_TRANSPORT)
static Tuple v4privateaddrbase1("10.0.0.0", 0, UNKNOWN_TRANSPORT)
static Tuple v6privateaddrbase("fc00::", 0, UNKNOWN_TRANSPORT)
static Tuple v4privateaddrbase2("172.16.0.0", 0, UNKNOWN_TRANSPORT)
static Tuple v6multicast("ff00::", 0, UNKNOWN_TRANSPORT)
static Tuple v6discardonly("100::", 0, UNKNOWN_TRANSPORT)
static Tuple v4sharedaddrbase1("100.64.0.0", 0, UNKNOWN_TRANSPORT)
static Tuple v4ietfprotocol("192.0.0.0", 0, UNKNOWN_TRANSPORT)
static Tuple v4privateaddrbase3("192.168.0.0", 0, UNKNOWN_TRANSPORT)
static Tuple v4documentation3("203.0.113.0", 0, UNKNOWN_TRANSPORT)
#define TOKEN_SIZE
Definition Tuple.cxx:261
static Tuple v4llinklocal("169.254.0.0", 0, UNKNOWN_TRANSPORT)
#define TOKEN_IP_ADDRESS_OFFSET
Definition Tuple.cxx:262
static Tuple v6documentation("2001:db8::", 0, UNKNOWN_TRANSPORT)
static Tuple v6v4mappedaddress("::ffff:0:0", 0, UNKNOWN_TRANSPORT)
static Tuple v46to5relayanycast("192.88.99.0", 0, UNKNOWN_TRANSPORT)
static Tuple v6orchid("2001:10::", 0, UNKNOWN_TRANSPORT)
static Tuple v6benchmarking("2001:2::", 0, UNKNOWN_TRANSPORT)
static Tuple v64to6translation("64:ff9b::", 0, UNKNOWN_TRANSPORT)
static Tuple v6uniquelocal("fc00::", 0, UNKNOWN_TRANSPORT)
static Tuple loopbackv4("127.0.0.1", 0, UNKNOWN_TRANSPORT)
static Tuple v6unspecified("::", 0, UNKNOWN_TRANSPORT)
static Tuple v4thishostonthisnetwork("0.0.0.0", 0, UNKNOWN_TRANSPORT)
static Tuple v6ietfprotocol("2001::", 0, UNKNOWN_TRANSPORT)
static Tuple v4reserved("240.0.0.0", 0, UNKNOWN_TRANSPORT)
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
static const Data Empty
Constant that represents a zero-length data.
Definition Data.hxx:882
@ Share
The Data instance will use the buffer in a read-only mode.
Definition Data.hxx:266
Data & append(const char *str, size_type len)
Appends the specified number of bytes to the end of this Data.
Definition Data.cxx:1058
bool empty() const noexcept
Checks whether the Data is empty.
Definition Data.hxx:591
size_type size() const noexcept
Returns the number of bytes in this Data.
Definition Data.hxx:599
size_t hash() const
Creates a 32-bit hash based on the contents of this Data.
Definition Data.cxx:2355
Data & clear()
Clears the contents of this Data.
Definition Data.hxx:800
const char * data() const noexcept
Returns a pointer to the contents of this Data.
Definition Data.hxx:608
void reserve(size_type capacity)
Guarantees that the underlying buffer used by the Data is at least the number of bytes specified.
Definition Data.cxx:1049
Used to accumlate data written to the stream in a DigestBuffer and convert the data to Digest.
Data getHex()
Calls flush() on itself and returns the Digest data in hex format.
static bool isIpV6Address(const Data &ipAddress)
Definition DnsUtil.cxx:386
static int inet_pton(const Data &printableIp, struct in_addr &dst)
Convert from the presentation format of the IPv4 address to struct in_addr.
Definition DnsUtil.cxx:275
static Data inet_ntop(const struct in_addr &addr)
Converts from the network format to presentation format.
Definition DnsUtil.cxx:240
static bool isIpV4Address(const Data &ipAddress)
Definition DnsUtil.cxx:290
bool operator()(const Tuple &x, const Tuple &y) const
Definition Tuple.cxx:1031
bool operator()(const Tuple &x, const Tuple &y) const
Definition Tuple.cxx:1189
bool operator()(const Tuple &x, const Tuple &y) const
Definition Tuple.cxx:1084
bool operator()(const Tuple &x, const Tuple &y) const
Definition Tuple.cxx:1158
Represents a network address.
Definition Tuple.hxx:59
IpVersion ipVersion() const
Returns V4 or V6 as appropriate.
Definition Tuple.cxx:537
Data presentationFormat() const
Wrapper around the inet_top() method.
Definition Tuple.cxx:426
static Tuple makeTupleFromBinaryToken(const Data &binaryToken, const Data &salt=Data::Empty)
Definition Tuple.cxx:328
size_t hash() const
Creates a 32-bit hash based on the contents of this Tuple.
Definition Tuple.cxx:887
void setPort(int port)
Definition Tuple.cxx:449
static const Data & toData(TransportType)
Converts the TransportType to a string representation of the transport type, e.g.
Definition Tuple.cxx:927
bool isLoopback() const
Definition Tuple.cxx:503
bool operator==(const Tuple &rhs) const
Compares TransportType, the binary address, port, and address family of the Tuple.
Definition Tuple.cxx:674
const Data & getNetNs() const
Get the netns for this Tuple.
Definition Tuple.hxx:271
GenericIPAddress toGenericIPAddress() const
Definition Tuple.cxx:1169
bool isAnyInterface() const
TRUE if this address is equal to the "INADDR_ANY" value for this address family.
Definition Tuple.cxx:485
bool onlyUseExistingConnection
Definition Tuple.hxx:192
bool isPrivateAddress() const
Definition Tuple.cxx:552
FlowKey mFlowKey
This is a (largely) opaque key that subclasses of Transport will use to help record/find flows.
Definition Tuple.hxx:189
sockaddr_in m_anonv4
Definition Tuple.hxx:285
bool isAddressAllowed(const std::vector< AddressMask > &allowed, const std::vector< AddressMask > &denied) const
Tests whether this address is permitted by the supplied allow/deny address lists.
Definition Tuple.cxx:858
static const Data & toDataLower(TransportType type)
Definition Tuple.cxx:933
static void writeBinaryToken(const Tuple &tuple, Data &container, const Data &salt=Data::Empty)
Definition Tuple.cxx:266
bool isEqual(const Tuple &tuple, bool ignorePort=false, bool ignoreTransport=false) const
compares this tuple with the one passed in for family, port and address equality.
Definition Tuple.cxx:680
sockaddr mSockaddr
Definition Tuple.hxx:284
void copySockaddrAnyPort(sockaddr *sa)
Get a copy of the socket address including the interface and not the port number.
Definition Tuple.cxx:218
socklen_t length() const
Definition Tuple.cxx:655
bool isEqualWithMask(const Tuple &tuple, short mask, bool ignorePort=false, bool ignoreTransport=false) const
compares this tuple with the one passed in for family, port and address equality using the passed in ...
Definition Tuple.cxx:956
bool isV4() const
Definition Tuple.cxx:531
int getPort() const
Definition Tuple.cxx:466
TransportType getType() const
Definition Tuple.hxx:122
static Data inet_ntop(const Tuple &tuple)
Converts the binary socket address to presentation format, via the DnsUtil::inet_ntop() method.
Definition Tuple.cxx:939
const sockaddr & getSockaddr() const
Retrieve a const binary representation of the socket address for this tuple.
Definition Tuple.hxx:109
static TransportType toTransport(const Data &)
Converts a string representation of transport type, i.e.
Definition Tuple.cxx:921
bool isSpecialPurposeAddress() const
Definition Tuple.cxx:611
void setSockaddr(const GenericIPAddress &)
Set the internal binary representation of the socket address from the GenericIPAddress.
Definition Tuple.cxx:239
TransportKey mTransportKey
Definition Tuple.hxx:190
bool operator<(const Tuple &rhs) const
Compares TransportType, the binary address, port, and address family of the Tuple.
Definition Tuple.cxx:711
This file is used to handle compatibility fixes/tweaks so reSIProcate can function on multiple platfo...
dcm! – add UnusedChecking(_enum) below;
const resip::Data & toData(const TransportType typeEnum)
unsigned long FlowKey
Definition Tuple.hxx:37
TransportType toTransportType(const resip::Data &transportName)
unsigned short uint16_t
Definition Stun.hxx:30
const resip::Data & toDataLower(const TransportType typeEnum)
unsigned long TransportKey
Definition Tuple.hxx:38
unsigned int uint32_t
Definition Stun.hxx:34
TransportType
An enumeration of transport protocols.
@ UNKNOWN_TRANSPORT
IpVersion
An enumeration of IP versions.
EncodeStream & operator<<(EncodeStream &strm, const BaseException &e)
unsigned char uint8_t
Definition Stun.hxx:29
#define EncodeStream
An IP address paired with a CIDR prefix length (number of mask bits), for use in address-based access...
Definition Tuple.hxx:314
Represents an IP-address and port (V4 or V6).