23#include <sys/socket.h>
29#include <netinet/in.h>
32#include <arpa/nameser.h>
38#if defined (__SUNPRO_CC) || defined (__sun__)
39#include <sys/sockio.h>
71 memcpy(&nport, body, 2); body += 2;
75 memcpy(&naddr, body, 4); body += 4;
101 memcpy(&tmp, body, 4);
119 memcpy(&result.
value, body, 4);
128 if (hdrLen >= (
sizeof(result) -
sizeof(result.
sizeReason)))
139 memcpy(&result.
pad, body, 2); body += 2;
140 result.
pad = ntohs(result.
pad);
154 if (hdrLen >=
sizeof(result))
160 if (hdrLen % 4 != 0)
return false;
164 memcpy(&result.
attrType[i], body, 2); body += 2;
192 memcpy(&result.
value, body, hdrLen);
193 result.
value[hdrLen] = 0;
208 memcpy(&result, body, 4);
209 result = ntohl(result);
225 memcpy(&result.
hash, body, hdrLen);
235 if (verbose) clog <<
"Received stun message: " << bufLen <<
" bytes" << endl;
239 clog <<
"Bad message" << endl;
249 clog <<
"Message header length doesn't match message size: " << msg.
msgHdr.
msgLength <<
" - " << bufLen << endl;
256 if (verbose) clog <<
"bytes after header = " << size << endl;
267 unsigned int attrLen = ntohs(attr->
length);
270 unsigned int attrLenPad = attrLen % 4 == 0 ? 0 : 4 - (attrLen % 4);
272 int atrType = ntohs(attr->
type);
274 if (verbose) clog <<
"Found attribute type=" << atrType <<
" length=" << attrLen << endl;
275 if (attrLen + attrLenPad + 4 > size)
277 clog <<
"claims attribute is larger than size of message " <<
"(attribute type=" << atrType <<
")" << endl;
290 clog <<
"problem parsing MappedAddress" << endl;
304 if (verbose) clog <<
"problem parsing ResponseAddress" << endl;
317 if (verbose) clog <<
"problem parsing ChangeRequest" << endl;
330 if (verbose) clog <<
"problem parsing SourceAddress" << endl;
343 if (verbose) clog <<
"problem parsing ChangedAddress" << endl;
356 if (verbose) clog <<
"problem parsing Username" << endl;
361 if (verbose) clog <<
"Username = " << msg.
username.
value << endl;
370 if (verbose) clog <<
"problem parsing Password" << endl;
375 if (verbose) clog <<
"Password = " << msg.
password.
value << endl;
387 if (verbose) clog <<
"problem parsing MessageIntegrity" << endl;
400 if (verbose) clog <<
"problem parsing ErrorCode" << endl;
416 if (verbose) clog <<
"problem parsing UnknownAttribute" << endl;
425 if (verbose) clog <<
"problem parsing ReflectedFrom" << endl;
435 if (verbose) clog <<
"Realm length=" << attrLen <<
" is longer than max allowed=" <<
MAX_REALM_BYTES << endl;
440 if (verbose) clog <<
"Realm = " << *msg.
realm << endl;
444 if (verbose) clog <<
"Duplicate Realm in message - ignoring." << endl;
453 if (verbose) clog <<
"Nonce length=" << attrLen <<
" is longer than max allowed=" <<
MAX_NONCE_BYTES << endl;
458 if (verbose) clog <<
"Nonce = " << *msg.
nonce << endl;
462 if (verbose) clog <<
"Duplicate Nonce in message - ignoring." << endl;
471 if (verbose) clog <<
"problem parsing XorMappedAddress" << endl;
484 if (verbose) clog <<
"xorOnly = true" << endl;
493 if (verbose) clog <<
"problem parsing ServerName" << endl;
498 if (verbose) clog <<
"ServerName = " << msg.
software.
value << endl;
508 if (verbose) clog <<
"problem parsing AlternateServer" << endl;
515 if (verbose) clog <<
"Duplicate AlternateServer in message - ignoring." << endl;
525 if (verbose) clog <<
"problem parsing Fingerprint" << endl;
528 if (verbose) clog <<
"Fingerprint = " << msg.
fingerprint;
532 if (verbose) clog <<
"Duplicate Fingerprint in message - ignoring." << endl;
541 if (verbose) clog <<
"problem parsing secondaryAddress" << endl;
613 if (verbose) clog <<
"Unknown attribute: " << atrType << endl;
614 if (atrType <= 0x7FFF)
620 body += attrLen + attrLenPad;
621 size -= attrLen + attrLenPad;
631 memcpy(buf,
reinterpret_cast<void*
>(&ndata),
sizeof(
uint16_t));
639 memcpy(buf,
reinterpret_cast<void*
>(&ndata),
sizeof(
uint32_t));
645 encode(
char* buf,
const char* data,
unsigned int length)
647 memcpy(buf, data, length);
656 memcpy(ptr, td->
data(), td->
size());
769 if (verbose) clog <<
"Encoding stun message: " << endl;
778 if (verbose) clog <<
"Encoding TurnMagicCookie: " << msg.
turnMagicCookie << endl;
788 if (verbose) clog <<
"Encoding MappedAddress: " << msg.
mappedAddress.
ipv4 << endl;
808 if (verbose) clog <<
"Encoding SourceAddress: " << msg.
sourceAddress.
ipv4 << endl;
818 if (verbose) clog <<
"Encoding Username: " << msg.
username.
value << endl;
823 if (verbose) clog <<
"Encoding Password: " << msg.
password.
value << endl;
828 if (verbose) clog <<
"Encoding ErrorCode: class="
839 if (verbose) clog <<
"Encoding UnknownAttribute: ???" << endl;
844 if (verbose) clog <<
"Encoding ReflectedFrom: " << msg.
reflectedFrom.
ipv4 << endl;
854 if (verbose) clog <<
"Encoding xorOnly: " << endl;
859 if (verbose) clog <<
"Encoding Software: " << msg.
software.
value << endl;
869 if (verbose) clog <<
"Encoding Turn Lifetime: " << msg.
turnLifetime << endl;
874 if (verbose) clog <<
"Encoding Turn Bandwidth: " << msg.
turnBandwidth << endl;
879 if (verbose) clog <<
"Encoding TurnData (not shown)" << endl;
884 if (verbose) clog <<
"HMAC with password: " << password.
value << endl;
887 char* ptrMessageIntegrity = ptr;
897 int len = int(ptrMessageIntegrity - buf);
902 if (verbose) clog << endl;
904 return int(ptr - buf);
940#include <openssl/hmac.h>
943 computeHmac(
char* hmac,
const char* input,
int length,
const char* key,
int sizeKey)
945 unsigned int resultSize = 0;
948 reinterpret_cast<const unsigned char*
>(input), length,
949 reinterpret_cast<unsigned char*
>(hmac), &resultSize);
954 computeHmac(
char* hmac,
const char* input,
int length,
const char* key,
int sizeKey)
958 const int blockSize = 64;
960 unsigned char paddedKey[blockSize];
961 memset(paddedKey, 0,
sizeof(paddedKey));
962 if (sizeKey > blockSize)
966 keyHash.update(std::string(key, sizeKey));
967 const Data hashedKey = keyHash.finalBin();
968 memcpy(paddedKey, hashedKey.data(),
969 hashedKey.size() <
static_cast<size_t>(blockSize) ? hashedKey.size() : blockSize);
971 else if (sizeKey > 0)
973 memcpy(paddedKey, key, sizeKey);
976 unsigned char ipad[blockSize];
977 unsigned char opad[blockSize];
978 for (
int i = 0; i < blockSize; ++i)
980 ipad[i] = paddedKey[i] ^ 0x36;
981 opad[i] = paddedKey[i] ^ 0x5c;
986 inner.update(std::string(
reinterpret_cast<const char*
>(ipad), blockSize));
987 inner.update(std::string(input, length));
988 const Data innerDigest = inner.finalBin();
992 outer.update(std::string(
reinterpret_cast<const char*
>(opad), blockSize));
993 outer.update(std::string(innerDigest.data(), innerDigest.size()));
994 const Data outerDigest = outer.finalBin();
997 memcpy(hmac, outerDigest.data(), 20);
1004 unsigned int bufLen,
1017 miOffset + 4 + 20 > bufLen ||
1030 memcpy(hashInput, buf, miOffset);
1031 const uint16_t adjustedLength = htons(
static_cast<uint16_t>(miOffset + 4));
1032 memcpy(hashInput + 2, &adjustedLength,
sizeof(adjustedLength));
1034 char computed[20] = { 0 };
1035 computeHmac(computed, hashInput,
static_cast<int>(miOffset),
1039 unsigned char diff = 0;
1040 for (
int i = 0; i < 20; ++i)
1042 diff |=
static_cast<unsigned char>(computed[i]) ^
1050 toHex(
const char* buffer,
int bufferSize,
char* output)
1052 static char hexmap[] =
"0123456789abcdef";
1054 const char* p = buffer;
1056 for (
int i = 0; i < bufferSize; i++)
1058 unsigned char temp = *p++;
1060 int hi = (temp & 0xf0) >> 4;
1061 int low = (temp & 0xf);
1073 time -= (time % 20 * 60);
1075 uint64_t lotime = time & 0xFFFFFFFF;
1077 constexpr size_t bufferSize = 256;
1078 char buffer[bufferSize];
1079 int expectedSize = std::snprintf(buffer,
1085 resip_assert(expectedSize > 0 &&
static_cast<size_t>(expectedSize) < bufferSize);
1089 char hmac[20] = { 0 };
1090 char key[] =
"Jason";
1091 computeHmac(hmac, buffer, (
int)strlen(buffer), key, (
int)strlen(key));
1092 char hmacHex[41] = { 0 };
1093 toHex(hmac, 20, hmacHex);
1096 snprintf(buffer + expectedSize, bufferSize - expectedSize,
"%s", hmacHex);
1098 int l = (int)strlen(buffer);
1103 memcpy(username->
value, buffer, l);
1104 username->
value[l] = 0;
1112 char hmac[20] = { 0 };
1113 char key[] =
"Fluffy";
1118 password->
value[40] = 0;
1132 time = (t.wHour * 60 + t.wMinute) * 60 + t.wSecond;
1135 gettimeofday(&now, NULL);
1145 strm << int(r.
octet[0]);
1146 for (
int i = 1; i < 16; i++)
1148 strm <<
':' << int(r.
octet[i]);
1158 strm << ((int)(ip >> 24) & 0xFF) <<
".";
1159 strm << ((int)(ip >> 16) & 0xFF) <<
".";
1160 strm << ((int)(ip >> 8) & 0xFF) <<
".";
1161 strm << ((int)(ip >> 0) & 0xFF);
1163 strm <<
":" << addr.
port;
1174 os <<
"BindingRequest";
1177 os <<
"BindingResponse";
1180 os <<
"BindingErrorResponse";
1183 os <<
"TurnAllocateRequest";
1186 os <<
"TurnAllocateResponse";
1189 os <<
"TurnAllocateErrorResponse";
1192 os <<
"TurnSendRequest";
1195 os <<
"TurnSendResponse";
1198 os <<
"TurnSendErrorResponse";
1201 os <<
"TurnDataIndication";
1204 os <<
"TurnSetActiveDestinationRequest";
1207 os <<
"TurnSetActiveDestinationResponse";
1210 os <<
"TurnSetActiveDestinationErrorResponse";
1217 for (
unsigned int i = 0; i <
sizeof(
UInt128); i++) {
1218 os << static_cast<int>(h.
id.
octet[i]);
1236 snprintf(host,
sizeof(host),
"%s", peerName);
1237 host[512 - 1] =
'\0';
1240 int portNum = defaultPort;
1243 char*
sep = strchr(host,
':');
1247 portNum = defaultPort;
1255 char* endPtr = NULL;
1257 portNum = strtol(port, &endPtr, 10);
1261 if (*endPtr !=
'\0')
1263 portNum = defaultPort;
1268 if (portNum < 1024)
return false;
1269 if (portNum >= 0xFFFF)
return false;
1274 if (isdigit(
static_cast<unsigned char>(host[0])))
1277 unsigned long a = 0;
1278 inet_pton(AF_INET, host, &a);
1286 struct addrinfo hints = {};
1287 struct addrinfo* res = NULL;
1288 hints.ai_family = AF_INET;
1289 hints.ai_socktype = SOCK_STREAM;
1291 int err = getaddrinfo(host, NULL, &hints, &res);
1292 if (err != 0 || res == NULL)
1294 std::cerr <<
"getaddrinfo error: " << gai_strerror(err) << std::endl;
1298 ip = ntohl(0x7F000001L);
1302 sin_addr = ((
struct sockaddr_in*)res->ai_addr)->sin_addr;
1303 ip = ntohl(sin_addr.s_addr);
1340 stunCreateSharedSecretErrorResponse(StunMessage& response,
int cl,
int number,
const char* msg)
1343 response.hasErrorCode =
true;
1344 response.errorCode.errorClass = cl;
1345 response.errorCode.number = number;
1346 strcpy(response.errorCode.reason, msg);
1369 unsigned int bufLen,
1382 *changePort =
false;
1389 if (verbose) clog <<
"Request did not parse" << endl;
1392 if (verbose) clog <<
"Request parsed ok" << endl;
1401 if (verbose) clog <<
"Received SharedSecretRequestMsg on udp. send error 433." << endl;
1410 if (verbose) clog <<
"BindRequest does not contain MessageIntegrity" << endl;
1414 if (verbose) clog <<
"Received BindRequest with no MessageIntegrity. Sending 401." << endl;
1423 if (verbose) clog <<
"No UserName. Send 432." << endl;
1429 if (verbose) clog <<
"Validating username: " << req.
username.
value << endl;
1447 if (verbose) clog <<
"MessageIntegrity is bad. Sending 431." << endl;
1452 if (verbose) clog <<
"MessageIntegrity validated" << endl;
1467 if (respondTo.
port == 0) respondTo = from;
1468 if (mapped.
port == 0) mapped = from;
1475 clog <<
"Request is valid:" << endl;
1476 clog <<
"\t flags=" <<
flags << endl;
1477 clog <<
"\t changeIp=" << *changeIp << endl;
1478 clog <<
"\t changePort=" << *changePort << endl;
1479 clog <<
"\t from = " << from << endl;
1480 clog <<
"\t respond to = " << respondTo << endl;
1481 clog <<
"\t mapped = " << mapped << endl;
1486 for (
int i = 0; i < 16; i++)
1519 if (secondary.
port != 0)
1566 destination->
port = respondTo.
port;
1567 destination->
addr = respondTo.
addr;
1572 if (verbose) clog <<
"Unknown or unsupported request " << endl;
1582 const StunAddress4& altAddr,
int startMediaPort,
bool verbose)
1598 if (startMediaPort > 0)
1617 if (verbose) clog <<
"Can't open " << myAddr << endl;
1626 if (verbose) clog <<
"Can't open " << myAddr << endl;
1634 if (altAddr.
addr != 0)
1638 if (verbose) clog <<
"Can't open " << altAddr << endl;
1646 if (altAddr.
addr != 0)
1650 if (verbose) clog <<
"Can't open " << altAddr << endl;
1686 int msgLen =
sizeof(msg);
1689 bool recvAltIp =
false;
1690 bool recvAltPort =
false;
1696 FD_SET(info.
myFd, &fdSet);
1697 if (info.
myFd >= maxFd) maxFd = info.
myFd + 1;
1719 FD_SET(relay->
fd, &fdSet);
1722 maxFd = relay->
fd + 1;
1743 int e = (int)select((
int)maxFd, &fdSet, NULL, NULL, &tv);
1747 if (verbose) clog <<
"Error on select: " <<
strError(err) << endl;
1756 time_t now = time(0);
1762 if (FD_ISSET(relay->
fd, &fdSet))
1765 int msgLen =
sizeof(msg);
1773 if (verbose) clog <<
"Relay packet on "
1775 <<
" from " << rtpFrom
1790 if (FD_ISSET(info.
myFd, &fdSet))
1792 if (verbose) clog <<
"received on A1:P1" << endl;
1794 recvAltPort =
false;
1797 else if (FD_ISSET(info.
altPortFd, &fdSet))
1799 if (verbose) clog <<
"received on A1:P2" << endl;
1806 if (verbose) clog <<
"received on A2:P1" << endl;
1808 recvAltPort =
false;
1813 if (verbose) clog <<
"received on A2:P2" << endl;
1845 if (verbose) clog <<
"Open relay port " << relay->
relayPort << endl;
1860 if (verbose) clog <<
"Get message did not return a valid message" << endl;
1864 if (verbose) clog <<
"Got a request (len=" << msgLen <<
") from " << from << endl;
1871 bool changePort =
false;
1872 bool changeIp =
false;
1883 if (info.
relay && relayPort)
1888 from.
port = relayPort;
1903 if (verbose) clog <<
"Failed to parse message" << endl;
1908 int len =
sizeof(buf);
1912 if (dest.
addr == 0) ok =
false;
1913 if (dest.
port == 0) ok =
false;
1922 bool sendAltIp = recvAltIp;
1923 bool sendAltPort = recvAltPort;
1925 if (changeIp) sendAltIp = !sendAltIp;
1926 if (changePort) sendAltPort = !sendAltPort;
1964#if defined(WIN32) || defined(__sparc__)
1969 int s = socket(AF_INET, SOCK_DGRAM, 0);
1970 const int len = 100 *
sizeof(
struct ifreq);
1977 int e = ioctl(s, SIOCGIFCONF, &ifc);
1979 int tl = ifc.ifc_len;
1982 while ((tl > 0) && (count < maxRet))
1984 struct ifreq* ifr = (
struct ifreq*)ptr;
1986 int si =
sizeof(ifr->ifr_name) +
sizeof(
struct sockaddr);
1995 e = ioctl(s, SIOCGIFADDR, &ifr2);
2003 struct sockaddr a = ifr2.ifr_addr;
2004 struct sockaddr_in* addr = (
struct sockaddr_in*)&a;
2006 uint32_t ai = ntohl(addr->sin_addr.s_addr);
2007 if (
int((ai >> 24) & 0xFF) != 127)
2009 addresses[count++] = ai;
2013 cerr <<
"Detected interface "
2014 << int((ai >> 24) & 0xFF) <<
"."
2015 << int((ai >> 16) & 0xFF) <<
"."
2016 << int((ai >> 8) & 0xFF) <<
"."
2017 << int((ai) & 0xFF) << endl;
2031 bool changePort,
bool changeIp,
unsigned int id)
2037 for (
int i = 0; i < 16; i = i + 4)
2070 int testNum,
bool verbose)
2075 bool changePort =
false;
2076 bool changeIP =
false;
2096 cerr <<
"Test " << testNum <<
" is unknown\n";
2102 changePort, changeIP,
2112 clog <<
"About to send msg of len " << len <<
" to " << dest << endl;
2142 interfaceIp = sAddr->
addr;
2143 if (sAddr->
port != 0)
2172 stunSendTest(myFd, dest, username, password, testNum, verbose);
2194 if (verbose) clog <<
"Got a response" << endl;
2201 clog <<
"\t ok=" << ok << endl;
2202 clog <<
"\t id=" << resp.
msgHdr.
id << endl;
2243 interfaceIp = sAddr->
addr;
2252 cerr <<
"Some problem opening port/interface to send on" << endl;
2259 bool respTestI =
false;
2262 bool respTestI2 =
false;
2263 bool mappedIpSame =
true;
2266 bool respTestII =
false;
2267 bool respTestIII =
false;
2269 bool respTestHairpin =
false;
2270 bool respTestPreservePort =
false;
2272 memset(&testImappedAddr, 0,
sizeof(testImappedAddr));
2290 typedef unsigned int FdSetSize;
2292 typedef int FdSetSize;
2294 FdSetSize fdSetSize;
2295 FD_ZERO(&fdSet); fdSetSize = 0;
2296 FD_SET(myFd1, &fdSet); fdSetSize = ((FdSetSize)myFd1 + 1 > fdSetSize) ? (FdSetSize)myFd1 + 1 : fdSetSize;
2297 FD_SET(myFd2, &fdSet); fdSetSize = ((FdSetSize)myFd2 + 1 > fdSetSize) ? (FdSetSize)myFd2 + 1 : fdSetSize;
2299 tv.tv_usec = 150 * 1000;
2300 if (count == 0) tv.tv_usec = 0;
2302 int err = select(fdSetSize, &fdSet, NULL, NULL, &tv);
2309 cerr <<
"Error " << e <<
" " <<
strError(e) <<
" in select" << endl;
2319 stunSendTest(myFd1, dest, username, password, 1, verbose);
2322 if ((!respTestI2) && respTestI)
2325 if ((testI2dest.
addr != 0) &&
2326 (testI2dest.
port != 0))
2328 stunSendTest(myFd1, testI2dest, username, password, 10, verbose);
2334 stunSendTest(myFd2, dest, username, password, 2, verbose);
2339 stunSendTest(myFd2, dest, username, password, 3, verbose);
2342 if (respTestI && (!respTestHairpin))
2344 if ((testImappedAddr.
addr != 0) &&
2345 (testImappedAddr.
port != 0))
2347 stunSendTest(myFd1, testImappedAddr, username, password, 11, verbose);
2357 for (
int i = 0; i < 2; i++)
2371 if (FD_ISSET(myFd, &fdSet))
2374 int msgLen =
sizeof(msg);
2404 respTestPreservePort = (testImappedAddr.
port == port);
2407 *preservePort = respTestPreservePort;
2414 sAddr->
port = testImappedAddr.
port;
2415 sAddr->
addr = testImappedAddr.
addr;
2440 mappedIpSame =
false;
2441 if ((testI2mappedAddr.
addr == testImappedAddr.
addr) &&
2442 (testI2mappedAddr.
port == testImappedAddr.
port))
2444 mappedIpSame =
true;
2459 respTestHairpin =
true;
2489 clog <<
"test I = " << respTestI << endl;
2490 clog <<
"test II = " << respTestII << endl;
2491 clog <<
"test III = " << respTestIII << endl;
2492 clog <<
"test I(2) = " << respTestI2 << endl;
2493 clog <<
"is nat = " << isNat << endl;
2494 clog <<
"mapped IP same = " << mappedIpSame << endl;
2495 clog <<
"hairpin = " << respTestHairpin << endl;
2496 clog <<
"preserver port = " << respTestPreservePort << endl;
2507 return StunTypeConeNat;
2515 return StunTypeRestrictedNat;
2519 return StunTypePortRestrictedNat;
2524 return StunTypeSymNat;
2536 return StunTypeSymFirewall;
2607 unsigned int interfaceIp = 0;
2610 interfaceIp = srcAddr->
addr;
2620 int msgLen =
sizeof(msg);
2653 *mapAddr = mappedAddr;
2680 int msgLen =
sizeof(msg);
2686 unsigned int interfaceIp = 0;
2689 interfaceIp = srcAddr->
addr;
2692 for (i = 0; i < NUM; i++)
2694 fd[i] = (int)
openPort((port == 0) ? 0 : (port + i),
2695 interfaceIp, verbose);
2716 for (i = 0; i < NUM; i++)
2718 stunSendTest(fd[i], dest, username, password, 1, verbose);
2722 for (i = 0; i < NUM; i++)
2724 msgLen =
sizeof(msg) /
sizeof(*msg);
2729 &from.
port, verbose);
2743 clog <<
"--- stunOpenSocketPair --- " << endl;
2744 for (i = 0; i < NUM; i++)
2746 clog <<
"\t mappedAddr=" << mappedAddr[i] << endl;
2750 if (mappedAddr[0].port % 2 == 0)
2752 if (mappedAddr[0].port + 1 == mappedAddr[1].port)
2754 *mapAddr = mappedAddr[0];
2763 if ((mappedAddr[1].port % 2 == 0)
2764 && (mappedAddr[1].port + 1 == mappedAddr[2].port))
2766 *mapAddr = mappedAddr[1];
2775 for (i = 0; i < NUM; i++)
2786 return memcmp(&lhs, &rhs,
sizeof(lhs)) < 0;
2791 return memcmp(&lhs, &rhs,
sizeof(lhs)) == 0;
2797 return lhs.
id < rhs.
id;
static const char hexmap[]
static const Data cookie("z9hG4bK")
static const Data sep("[]")
#define resip_assert(x)
This file needs to work for both C and C++ code.
Handles cross-platform sockets compatibility.
#define WSANOTINITIALISED
#define STUN_MAX_MESSAGE_SIZE
#define MEDIA_RELAY_TIMEOUT
resip::Socket openPort(unsigned short port, unsigned int interfaceIp, bool verbose)
Open a UDP socket to receive on the given port - if port is 0, pick a a port, if interfaceIp!...
bool getMessage(resip::Socket fd, char *buf, int *len, uint32_t *srcIp, unsigned short *srcPort, bool verbose)
recive a UDP message
bool sendMessage(resip::Socket fd, char *buf, int l, unsigned int dstIp, unsigned short dstPort, bool verbose)
send a UDP message
static const struct nv flags[]
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
@ Share
The Data instance will use the buffer in a read-only mode.
size_type size() const noexcept
Returns the number of bytes in this Data.
const char * data() const noexcept
Returns a pointer to the contents of this Data.
Object-oriented wrapper for your platform's file-descriptor set.
int selectMilliSeconds(unsigned long ms)
static int getRandom()
Returns a postive integer (31 bits) of randomness.
static int getCryptoRandom()
dcm! – add UnusedChecking(_enum) below;
const uint16_t TurnSendResponse
static void stunSendTest(resip::Socket myFd, StunAddress4 &dest, const StunAtrString &username, const StunAtrString &password, int testNum, bool verbose)
bool stunParseServerName(char *name, StunAddress4 &addr)
find the IP address of a the specified stun server - return false is fails parse
void stunCreateUserName(const StunAddress4 &source, StunAtrString *username)
const uint16_t TurnSetActiveDestinationRequest
bool stunInitServer(StunServerInfo &info, const StunAddress4 &myAddr, const StunAddress4 &altAddr, int startMediaPort, bool verbose)
return true if all is OK Create a media relay and do the STERN thing if startMediaPort is non-zero
static bool stunParseAtrChangeRequest(char *body, unsigned int hdrLen, StunAtrChangeRequest &result)
void computeHmac(char *hmac, const char *input, int length, const char *key, int sizeKey)
static bool stunParseAtrIntegrity(char *body, unsigned int hdrLen, StunAtrIntegrity &result)
const uint16_t TurnLifetime
static const uint16_t Username
static char * encodeAtrUnknown(char *ptr, const StunAtrUnknown &atr)
static const uint16_t AlternateServer
const uint16_t SharedSecretErrorResponseMsg
static char * encodeAtrString(char *ptr, uint16_t type, const StunAtrString &atr)
static char * encodeAtrError(char *ptr, const StunAtrError &atr)
NatType stunNatType(StunAddress4 &dest, bool verbose, bool *preservePort, bool *hairpin, int port, StunAddress4 *sAddr)
const uint16_t TurnSendErrorResponse
const uint16_t TurnMagicCookie
static char * encodeAtrAddress4(char *ptr, uint16_t type, const StunAtrAddress4 &atr)
void stunCreatePassword(const StunAtrString &username, StunAtrString *password)
static const uint16_t XorMappedAddress
static char * encodeTurnData(char *ptr, const resip::Data *td)
static bool stunParseAtrUnknown(char *body, unsigned int hdrLen, StunAtrUnknown &result)
const uint8_t IPv4Family
define a structure to hold a stun address
const uint16_t TurnDestinationAddress
static const uint16_t ChangedAddress
int stunFindLocalInterfaces(uint32_t *addresses, int maxRet)
returns number of address found - take array or addres
static void toHex(const char *buffer, int bufferSize, char *output)
bool stunServerProcessMsg(char *buf, unsigned int bufLen, StunAddress4 &from, StunAddress4 &secondary, StunAddress4 &myAddr, StunAddress4 &altAddr, StunMessage *resp, StunAddress4 *destination, StunAtrString *hmacPassword, bool *changePort, bool *changeIp, bool verbose)
static bool stunParseAtrString(char *body, unsigned int hdrLen, StunAtrString &result)
static bool stunParseAtrError(char *body, unsigned int hdrLen, StunAtrError &result)
static void stunCreateErrorResponse(StunMessage &response, int cl, int number, const char *msg)
static const uint16_t Software
static char * encode16(char *buf, uint16_t data)
const uint16_t BindResponseMsg
static char * encodeAtrChangeRequest(char *ptr, const StunAtrChangeRequest &atr)
static bool stunParseAtrAddress(char *body, unsigned int hdrLen, StunAtrAddress4 &result)
static const uint16_t Realm
const uint16_t TurnRemoteAddress
static void stunCreateSharedSecretResponse(const StunMessage &request, const StunAddress4 &source, StunMessage &response)
const uint16_t TurnSetActiveDestinationErrorResponse
@ StunTypeIndependentFilter
@ StunTypeDependentMapping
@ StunTypePortDependedFilter
@ StunTypeDependentFilter
static const uint16_t SourceAddress
static const uint16_t XorMappedAddress_old
const uint16_t TurnSetActiveDestinationResponse
static const uint16_t ResponseAddress
static const uint16_t Fingerprint
const uint32_t ChangePortFlag
int stunOpenSocket(StunAddress4 &dest, StunAddress4 *mapAddr, int port, StunAddress4 *srcAddr, bool verbose)
unsigned long long uint64_t
static const uint16_t Nonce
bool stunVerifyMessageIntegrity(const char *buf, unsigned int bufLen, const StunMessage &message, const StunAtrString &password)
Verify the MESSAGE-INTEGRITY attribute of a parsed message against the supplied short-term credential...
const uint16_t TurnAllocateRequest
void stunBuildReqSimple(StunMessage *msg, const StunAtrString &username, bool changePort, bool changeIp, unsigned int id)
bool operator<(const Data &lhs, const Data &rhs)
const uint16_t TurnSendRequest
bool stunParseHostName(char *peerName, uint32_t &ip, uint16_t &portVal, uint16_t defaultPort)
int closeSocket(Socket fd)
const uint32_t ChangeIpFlag
static const uint16_t ErrorCode
static const uint16_t SecondaryAddress
static const uint16_t MappedAddress
static char * encodeAtrUInt32(char *ptr, uint16_t type, uint32_t value)
const uint16_t BindErrorResponseMsg
void stunStopServer(StunServerInfo &info)
const uint16_t TurnAllocateErrorResponse
static char * encodeMagicCookie(char *ptr, const uint32_t &cookie)
const uint16_t SharedSecretResponseMsg
static const uint16_t XorOnly
static const uint16_t ReflectedFrom
void stunGetUserNameAndPassword(const StunAddress4 &dest, StunAtrString *username, StunAtrString *password)
bool stunParseMessage(char *buf, unsigned int bufLen, StunMessage &msg, bool verbose)
std::string strError(int err)
static char * encode32(char *buf, uint32_t data)
static const uint16_t Password
static char * encode(char *buf, const char *data, unsigned int length)
const uint16_t TurnAlternateServer
static const uint16_t MessageIntegrity
static const uint16_t UnknownAttribute
bool stunServerProcess(StunServerInfo &info, bool verbose)
return true if all is OK
const uint16_t BindRequestMsg
bool makeSocketNonBlocking(Socket fd)
uint64_t stunGetSystemTimeSecs()
int stunRandomPort()
return a random number to use as a port
const uint16_t TurnAllocateResponse
const uint16_t TurnBandwidth
const uint16_t SharedSecretRequestMsg
static bool stunParseAtrUInt32(char *body, unsigned int hdrLen, uint32_t &result)
EncodeStream & operator<<(EncodeStream &strm, const BaseException &e)
static char * encodeXorOnly(char *ptr)
bool stunTest(StunAddress4 &dest, int testNum, bool verbose, StunAddress4 *sAddr, unsigned long timeoutMs)
bool operator==(const char *lhs, const Data &rhs)
static char * encodeAtrIntegrity(char *ptr, const StunAtrIntegrity &atr)
static const uint16_t ChangeRequest
bool stunOpenSocketPair(StunAddress4 &dest, StunAddress4 *mapAddr, int *fd1, int *fd2, int port, StunAddress4 *srcAddr, bool verbose)
static bool stunParseUInt32(char *body, unsigned int hdrLen, uint32_t &result)
unsigned int stunEncodeMessage(const StunMessage &msg, char *buf, unsigned int bufLen, const StunAtrString &password, bool verbose)
const uint16_t TurnDataIndication
unsigned __int64 uint64_t
char reason[STUN_MAX_STRING]
char value[STUN_MAX_STRING]
uint16_t attrType[STUN_MAX_UNKNOWN_ATTRIBUTES]
bool hasUnknownAttributes
StunAtrAddress4 reflectedFrom
StunAtrAddress4 secondaryAddress
bool hasTurnAlternateServer
StunAtrAddress4 turnRemoteAddress
unsigned int messageIntegrityOffset
StunAtrAddress4 changedAddress
StunAtrChangeRequest changeRequest
StunAtrAddress4 sourceAddress
StunAtrAddress4 alternateServer
StunAtrAddress4 turnDestinationAddress
StunAtrUnknown unknownAttributes
StunAtrAddress4 xorMappedAddress
bool hasTurnDestinationAddress
StunAtrAddress4 turnAlternateServer
bool hasTurnRemoteAddress
StunAtrAddress4 mappedAddress
StunAtrAddress4 responseAddress
StunAtrIntegrity messageIntegrity
resip::Socket altIpPortFd
StunMediaRelay relays[MAX_MEDIA_RELAYS]