00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 #ifndef _WIN32_WCE
00071 #include <errno.h>
00072 #endif
00073
00074 #include <assert.h>
00075
00076 #if defined(WIN32) || defined(_WIN32_WCE)
00077 #include <winsock2.h>
00078 #include <stdlib.h>
00079
00080 #include <time.h>
00081 #include <ctype.h>
00082 #else
00083
00084 #include <stdlib.h>
00085 #include <unistd.h>
00086 #include <string.h>
00087 #include <sys/ioctl.h>
00088 #include <sys/socket.h>
00089 #include <sys/time.h>
00090 #include <sys/types.h>
00091 #include <arpa/inet.h>
00092 #include <fcntl.h>
00093 #include <netdb.h>
00094 #include <netinet/in.h>
00095 #include <arpa/nameser.h>
00096 #include <resolv.h>
00097 #include <net/if.h>
00098
00099 #endif
00100
00101
00102 #define NOSSL
00103
00104
00105
00106
00107
00108
00109
00110 #include "ortp/stun_udp.h"
00111 #include "ortp/stun.h"
00112 #include "ortp/ortp.h"
00113
00114 static char *ipaddr(const StunAddress4 *addr)
00115 {
00116 static char tmp[512];
00117 struct in_addr inaddr;
00118 char *atmp;
00119 inaddr.s_addr = htonl(addr->addr);
00120 atmp = (char *)inet_ntoa(inaddr);
00121
00122 snprintf(tmp, 512, "%s:%i", atmp, addr->port);
00123 return tmp;
00124 }
00125
00126 static void
00127 computeHmac(char* hmac, const char* input, int length, const char* key, int keySize);
00128
00129 static bool_t
00130 stunParseAtrAddress( char* body, unsigned int hdrLen, StunAtrAddress4 *result )
00131 {
00132 if ( hdrLen != 8 )
00133 {
00134 ortp_error("stun: hdrLen wrong for Address\n");
00135 return FALSE;
00136 }
00137 result->pad = *body++;
00138 result->family = *body++;
00139 if (result->family == IPv4Family)
00140 {
00141 UInt16 nport;
00142 UInt32 naddr;
00143 memcpy(&nport, body, 2); body+=2;
00144 result->ipv4.port = ntohs(nport);
00145
00146 memcpy(&naddr, body, 4); body+=4;
00147 result->ipv4.addr = ntohl(naddr);
00148 return TRUE;
00149 }
00150 else if (result->family == IPv6Family)
00151 {
00152 ortp_error("stun: ipv6 not supported\n");
00153 }
00154 else
00155 {
00156 ortp_error("stun: bad address family: %i\n", result->family);
00157 }
00158
00159 return FALSE;
00160 }
00161
00162 static bool_t
00163 stunParseAtrChangeRequest( char* body, unsigned int hdrLen, StunAtrChangeRequest *result )
00164 {
00165 if ( hdrLen != 4 )
00166 {
00167
00168
00169 ortp_error("stun: Incorrect size for ChangeRequest");
00170 return FALSE;
00171 }
00172 else
00173 {
00174 memcpy(&result->value, body, 4);
00175 result->value = ntohl(result->value);
00176 return TRUE;
00177 }
00178 }
00179
00180 static bool_t
00181 stunParseAtrError( char* body, unsigned int hdrLen, StunAtrError *result )
00182 {
00183 if ( hdrLen >= sizeof(result) )
00184 {
00185 ortp_error("stun: head on Error too large");
00186 return FALSE;
00187 }
00188 else
00189 {
00190 memcpy(&result->pad, body, 2); body+=2;
00191 result->pad = ntohs(result->pad);
00192 result->errorClass = *body++;
00193 result->number = *body++;
00194
00195 result->sizeReason = hdrLen - 4;
00196 memcpy(&result->reason, body, result->sizeReason);
00197 result->reason[result->sizeReason] = 0;
00198 return TRUE;
00199 }
00200 }
00201
00202 static bool_t
00203 stunParseAtrUnknown( char* body, unsigned int hdrLen, StunAtrUnknown *result )
00204 {
00205 if ( hdrLen >= sizeof(result) )
00206 {
00207 return FALSE;
00208 }
00209 else
00210 {
00211 int i;
00212 if (hdrLen % 4 != 0) return FALSE;
00213 result->numAttributes = hdrLen / 4;
00214 for (i=0; i<result->numAttributes; i++)
00215 {
00216 memcpy(&result->attrType[i], body, 2); body+=2;
00217 result->attrType[i] = ntohs(result->attrType[i]);
00218 }
00219 return TRUE;
00220 }
00221 }
00222
00223
00224 static bool_t
00225 stunParseAtrString( char* body, unsigned int hdrLen, StunAtrString *result )
00226 {
00227 if ( hdrLen >= STUN_MAX_STRING )
00228 {
00229 ortp_error("stun: String is too large");
00230 return FALSE;
00231 }
00232 else
00233 {
00234 if (hdrLen % 4 != 0)
00235 {
00236 ortp_error("stun: Bad length string %i\n", hdrLen);
00237 return FALSE;
00238 }
00239
00240 result->sizeValue = hdrLen;
00241 memcpy(&result->value, body, hdrLen);
00242 result->value[hdrLen] = 0;
00243 return TRUE;
00244 }
00245 }
00246
00247
00248 static bool_t
00249 stunParseAtrIntegrity( char* body, unsigned int hdrLen, StunAtrIntegrity *result )
00250 {
00251 if ( hdrLen != 20)
00252 {
00253 ortp_error("stun: MessageIntegrity must be 20 bytes");
00254 return FALSE;
00255 }
00256 else
00257 {
00258 memcpy(&result->hash, body, hdrLen);
00259 return TRUE;
00260 }
00261 }
00262
00263
00264 bool_t
00265 stunParseMessage( char* buf, unsigned int bufLen, StunMessage *msg, bool_t verbose)
00266 {
00267 char* body;
00268 unsigned int size;
00269 if (verbose)
00270 ortp_message("stun: Received stun message: %i bytes\n", bufLen);
00271 memset(msg, 0, sizeof(msg));
00272
00273 if (sizeof(StunMsgHdr) > bufLen)
00274 {
00275 ortp_warning("stun: Bad message\n");
00276 return FALSE;
00277 }
00278
00279 memcpy(&msg->msgHdr, buf, sizeof(StunMsgHdr));
00280 msg->msgHdr.msgType = ntohs(msg->msgHdr.msgType);
00281 msg->msgHdr.msgLength = ntohs(msg->msgHdr.msgLength);
00282
00283 if (msg->msgHdr.msgLength + sizeof(StunMsgHdr) != bufLen)
00284 {
00285 ortp_warning("stun: Message header length doesn't match message size: %i - %i\n", msg->msgHdr.msgLength, bufLen);
00286 return FALSE;
00287 }
00288
00289 body = buf + sizeof(StunMsgHdr);
00290 size = msg->msgHdr.msgLength;
00291
00292
00293
00294 while ( size > 0 )
00295 {
00296
00297
00298 StunAtrHdr* attr = (StunAtrHdr*)body;
00299
00300 unsigned int attrLen = ntohs(attr->length);
00301 int atrType = ntohs(attr->type);
00302
00303
00304 if ( attrLen+4 > size )
00305 {
00306 ortp_error("stun: claims attribute is larger than size of message (attribute type=%i)\n", atrType);
00307 return FALSE;
00308 }
00309
00310 body += 4;
00311 size -= 4;
00312
00313 if (atrType == MappedAddress)
00314 {
00315 msg->hasMappedAddress = TRUE;
00316 if ( stunParseAtrAddress( body, attrLen, &msg->mappedAddress )== FALSE )
00317 {
00318 ortp_error("stun: problem parsing MappedAddress\n");
00319 return FALSE;
00320 }
00321 else
00322 {
00323 if (verbose)
00324 ortp_message("stun: MappedAddress = %s\n", ipaddr(&msg->mappedAddress.ipv4));
00325 }
00326
00327 }
00328 else if (atrType == ResponseAddress)
00329 {
00330 msg->hasResponseAddress = TRUE;
00331 if ( stunParseAtrAddress( body, attrLen, &msg->responseAddress )== FALSE )
00332 {
00333 ortp_error("stun: problem parsing ResponseAddress");
00334 return FALSE;
00335 }
00336 else
00337 {
00338 if (verbose)
00339 ortp_message("stun: ResponseAddress = %s\n", ipaddr(&msg->responseAddress.ipv4));
00340 }
00341 }
00342 else if (atrType == ChangeRequest)
00343 {
00344 msg->hasChangeRequest = TRUE;
00345 if (stunParseAtrChangeRequest( body, attrLen, &msg->changeRequest) == FALSE)
00346 {
00347 ortp_error("stun: problem parsing ChangeRequest\n");
00348 return FALSE;
00349 }
00350 else
00351 {
00352 if (verbose)
00353 ortp_message("stun: ChangeRequest = %i\n", msg->changeRequest.value);
00354 }
00355 }
00356 else if (atrType == SourceAddress)
00357 {
00358 msg->hasSourceAddress = TRUE;
00359 if ( stunParseAtrAddress( body, attrLen, &msg->sourceAddress )== FALSE )
00360 {
00361 ortp_error("stun: problem parsing SourceAddress\n");
00362 return FALSE;
00363 }
00364 else
00365 {
00366 if (verbose)
00367 ortp_message("stun: SourceAddress = %s\n", ipaddr(&msg->sourceAddress.ipv4) );
00368 }
00369 }
00370 else if (atrType == ChangedAddress)
00371 {
00372 msg->hasChangedAddress = TRUE;
00373 if ( stunParseAtrAddress( body, attrLen, &msg->changedAddress )== FALSE )
00374 {
00375 ortp_error("stun: problem parsing ChangedAddress\n");
00376 return FALSE;
00377 }
00378 else
00379 {
00380 if (verbose) ortp_message("stun: ChangedAddress = %s\n", ipaddr(&msg->changedAddress.ipv4));
00381 }
00382 }
00383 else if (atrType == Username)
00384 {
00385 msg->hasUsername = TRUE;
00386 if (stunParseAtrString( body, attrLen, &msg->username) == FALSE)
00387 {
00388 ortp_error("stun: problem parsing Username");
00389 return FALSE;
00390 }
00391 else
00392 {
00393 if (verbose)
00394 ortp_message("stun: Username = %s\n", msg->username.value );
00395 }
00396 }
00397 else if (atrType == Password)
00398 {
00399 msg->hasPassword = TRUE;
00400 if (stunParseAtrString( body, attrLen, &msg->password) == FALSE)
00401 {
00402 ortp_error("stun: problem parsing Password");
00403 return FALSE;
00404 }
00405 else
00406 {
00407 if (verbose)
00408 ortp_message("stun: Password = %s\n", msg->password.value );
00409 }
00410 }
00411 else if (atrType == MessageIntegrity)
00412 {
00413 msg->hasMessageIntegrity = TRUE;
00414 if (stunParseAtrIntegrity( body, attrLen, &msg->messageIntegrity) == FALSE)
00415 {
00416 ortp_error("stun: problem parsing MessageIntegrity");
00417 return FALSE;
00418 }
00419 else
00420 {
00421
00422 }
00423
00424
00425
00426
00427
00428 }
00429 else if (atrType == ErrorCode)
00430 {
00431 msg->hasErrorCode = TRUE;
00432 if (stunParseAtrError(body, attrLen, &msg->errorCode) == FALSE)
00433 {
00434 ortp_error("stun: problem parsing ErrorCode");
00435 return FALSE;
00436 }
00437 else
00438 {
00439 if (verbose)
00440 ortp_message("stun: ErrorCode = %i %i %s\n",
00441 msg->errorCode.errorClass ,
00442 msg->errorCode.number ,
00443 msg->errorCode.reason );
00444 }
00445
00446 }
00447 else if (atrType == UnknownAttribute)
00448 {
00449 msg->hasUnknownAttributes = TRUE;
00450 if (stunParseAtrUnknown(body, attrLen, &msg->unknownAttributes) == FALSE)
00451 {
00452 ortp_error("stun: problem parsing UnknownAttribute");
00453 return FALSE;
00454 }
00455 }
00456 else if (atrType == ReflectedFrom)
00457 {
00458 msg->hasReflectedFrom = TRUE;
00459 if ( stunParseAtrAddress( body, attrLen, &msg->reflectedFrom ) == FALSE )
00460 {
00461 ortp_error("stun: problem parsing ReflectedFrom");
00462 return FALSE;
00463 }
00464 }
00465 else if (atrType == XorMappedAddress)
00466 {
00467 msg->hasXorMappedAddress = TRUE;
00468 if ( stunParseAtrAddress( body, attrLen, &msg->xorMappedAddress ) == FALSE )
00469 {
00470 ortp_error("stun: problem parsing XorMappedAddress");
00471 return FALSE;
00472 }
00473 else
00474 {
00475 if (verbose)
00476 ortp_message("stun: XorMappedAddress = %s\n", ipaddr(&msg->mappedAddress.ipv4) );
00477 }
00478 }
00479 else if (atrType == XorOnly)
00480 {
00481 msg->xorOnly = TRUE;
00482 }
00483 else if (atrType == ServerName)
00484 {
00485 msg->hasServerName = TRUE;
00486 if (stunParseAtrString( body, attrLen, &msg->serverName) == FALSE)
00487 {
00488 ortp_error("stun: problem parsing ServerName");
00489 return FALSE;
00490 }
00491 else
00492 {
00493 if (verbose)
00494 ortp_message("stun: ServerName = %s\n", msg->serverName.value );
00495 }
00496 }
00497 else if (atrType == SecondaryAddress)
00498 {
00499 msg->hasSecondaryAddress = TRUE;
00500 if ( stunParseAtrAddress( body, attrLen, &msg->secondaryAddress ) == FALSE )
00501 {
00502 ortp_error("stun: problem parsing secondaryAddress");
00503 return FALSE;
00504 }
00505 else
00506 {
00507 if (verbose)
00508 ortp_message("stun: SecondaryAddress = %s\n", ipaddr(&msg->secondaryAddress.ipv4) );
00509 }
00510 }
00511 else
00512 {
00513 if (verbose)
00514 ortp_message("stun: Unknown attribute: %i\n", atrType );
00515 if ( atrType <= 0x7FFF )
00516 {
00517 return FALSE;
00518 }
00519 }
00520
00521 body += attrLen;
00522 size -= attrLen;
00523 }
00524
00525 return TRUE;
00526 }
00527
00528
00529 static char*
00530 encode16(char* buf, UInt16 data)
00531 {
00532 UInt16 ndata = htons(data);
00533
00534 memcpy(buf, &ndata, sizeof(UInt16));
00535 return buf + sizeof(UInt16);
00536 }
00537
00538 static char*
00539 encode32(char* buf, UInt32 data)
00540 {
00541 UInt32 ndata = htonl(data);
00542
00543 memcpy(buf, &ndata, sizeof(UInt32));
00544 return buf + sizeof(UInt32);
00545 }
00546
00547
00548 static char*
00549 encode(char* buf, const char* data, unsigned int length)
00550 {
00551 memcpy(buf, data, length);
00552 return buf + length;
00553 }
00554
00555
00556 static char*
00557 encodeAtrAddress4(char* ptr, UInt16 type, const StunAtrAddress4 *atr)
00558 {
00559 ptr = encode16(ptr, type);
00560 ptr = encode16(ptr, 8);
00561 *ptr++ = atr->pad;
00562 *ptr++ = IPv4Family;
00563 ptr = encode16(ptr, atr->ipv4.port);
00564 ptr = encode32(ptr, atr->ipv4.addr);
00565
00566 return ptr;
00567 }
00568
00569 static char*
00570 encodeAtrChangeRequest(char* ptr, const StunAtrChangeRequest *atr)
00571 {
00572 ptr = encode16(ptr, ChangeRequest);
00573 ptr = encode16(ptr, 4);
00574 ptr = encode32(ptr, atr->value);
00575 return ptr;
00576 }
00577
00578 static char*
00579 encodeAtrError(char* ptr, const StunAtrError *atr)
00580 {
00581 ptr = encode16(ptr, ErrorCode);
00582 ptr = encode16(ptr, 6 + atr->sizeReason);
00583 ptr = encode16(ptr, atr->pad);
00584 *ptr++ = atr->errorClass;
00585 *ptr++ = atr->number;
00586 ptr = encode(ptr, atr->reason, atr->sizeReason);
00587 return ptr;
00588 }
00589
00590
00591 static char*
00592 encodeAtrUnknown(char* ptr, const StunAtrUnknown *atr)
00593 {
00594 int i;
00595 ptr = encode16(ptr, UnknownAttribute);
00596 ptr = encode16(ptr, 2+2*atr->numAttributes);
00597 for (i=0; i<atr->numAttributes; i++)
00598 {
00599 ptr = encode16(ptr, atr->attrType[i]);
00600 }
00601 return ptr;
00602 }
00603
00604
00605 static char*
00606 encodeXorOnly(char* ptr)
00607 {
00608 ptr = encode16(ptr, XorOnly );
00609 return ptr;
00610 }
00611
00612
00613 static char*
00614 encodeAtrString(char* ptr, UInt16 type, const StunAtrString *atr)
00615 {
00616
00617
00618 ptr = encode16(ptr, type);
00619 ptr = encode16(ptr, atr->sizeValue);
00620 ptr = encode(ptr, atr->value, atr->sizeValue);
00621 return ptr;
00622 }
00623
00624
00625 static char*
00626 encodeAtrIntegrity(char* ptr, const StunAtrIntegrity *atr)
00627 {
00628 ptr = encode16(ptr, MessageIntegrity);
00629 ptr = encode16(ptr, 20);
00630 ptr = encode(ptr, atr->hash, sizeof(atr->hash));
00631 return ptr;
00632 }
00633
00634
00635 unsigned int
00636 stunEncodeMessage( const StunMessage *msg,
00637 char* buf,
00638 unsigned int bufLen,
00639 const StunAtrString *password,
00640 bool_t verbose)
00641 {
00642
00643 char* ptr = buf;
00644 char* lengthp;
00645 ptr = encode16(ptr, msg->msgHdr.msgType);
00646 lengthp = ptr;
00647 ptr = encode16(ptr, 0);
00648
00649 ptr = encode(ptr, (const char*)msg->msgHdr.id.octet, sizeof(msg->msgHdr.id));
00650
00651 if (verbose) ortp_message("stun: Encoding stun message: ");
00652 if (msg->hasMappedAddress)
00653 {
00654 if (verbose) ortp_message("stun: Encoding MappedAddress: %s\n", ipaddr(&msg->mappedAddress.ipv4) );
00655 ptr = encodeAtrAddress4 (ptr, MappedAddress, &msg->mappedAddress);
00656 }
00657 if (msg->hasResponseAddress)
00658 {
00659 if (verbose) ortp_message("stun: Encoding ResponseAddress: %s\n", ipaddr(&msg->responseAddress.ipv4) );
00660 ptr = encodeAtrAddress4(ptr, ResponseAddress, &msg->responseAddress);
00661 }
00662 if (msg->hasChangeRequest)
00663 {
00664 if (verbose) ortp_message("stun: Encoding ChangeRequest: %i\n", msg->changeRequest.value );
00665 ptr = encodeAtrChangeRequest(ptr, &msg->changeRequest);
00666 }
00667 if (msg->hasSourceAddress)
00668 {
00669 if (verbose) ortp_message("stun: Encoding SourceAddress: %s\n", ipaddr(&msg->sourceAddress.ipv4) );
00670 ptr = encodeAtrAddress4(ptr, SourceAddress, &msg->sourceAddress);
00671 }
00672 if (msg->hasChangedAddress)
00673 {
00674 if (verbose) ortp_message("stun: Encoding ChangedAddress: %s\n", ipaddr(&msg->changedAddress.ipv4) );
00675 ptr = encodeAtrAddress4(ptr, ChangedAddress, &msg->changedAddress);
00676 }
00677 if (msg->hasUsername)
00678 {
00679 if (verbose) ortp_message("stun: Encoding Username: %s\n", msg->username.value );
00680 ptr = encodeAtrString(ptr, Username, &msg->username);
00681 }
00682 if (msg->hasPassword)
00683 {
00684 if (verbose) ortp_message("stun: Encoding Password: %s\n", msg->password.value );
00685 ptr = encodeAtrString(ptr, Password, &msg->password);
00686 }
00687 if (msg->hasErrorCode)
00688 {
00689 if (verbose) ortp_message("stun: Encoding ErrorCode: class=%i number=%i reason=%s\n"
00690 , msg->errorCode.errorClass
00691 , msg->errorCode.number
00692 , msg->errorCode.reason );
00693
00694 ptr = encodeAtrError(ptr, &msg->errorCode);
00695 }
00696 if (msg->hasUnknownAttributes)
00697 {
00698 if (verbose) ortp_message("stun: Encoding UnknownAttribute: ???");
00699 ptr = encodeAtrUnknown(ptr, &msg->unknownAttributes);
00700 }
00701 if (msg->hasReflectedFrom)
00702 {
00703 if (verbose) ortp_message("stun: Encoding ReflectedFrom: %s\n", ipaddr(&msg->reflectedFrom.ipv4) );
00704 ptr = encodeAtrAddress4(ptr, ReflectedFrom, &msg->reflectedFrom);
00705 }
00706 if (msg->hasXorMappedAddress)
00707 {
00708 if (verbose) ortp_message("stun: Encoding XorMappedAddress: %s\n", ipaddr(&msg->xorMappedAddress.ipv4) );
00709 ptr = encodeAtrAddress4 (ptr, XorMappedAddress, &msg->xorMappedAddress);
00710 }
00711 if (msg->xorOnly)
00712 {
00713 if (verbose) ortp_message("stun: Encoding xorOnly: ");
00714 ptr = encodeXorOnly( ptr );
00715 }
00716 if (msg->hasServerName)
00717 {
00718 if (verbose) ortp_message("stun: Encoding ServerName: %s\n", msg->serverName.value );
00719 ptr = encodeAtrString(ptr, ServerName, &msg->serverName);
00720 }
00721 if (msg->hasSecondaryAddress)
00722 {
00723 if (verbose) ortp_message("stun: Encoding SecondaryAddress: %s\n", ipaddr(&msg->secondaryAddress.ipv4) );
00724 ptr = encodeAtrAddress4 (ptr, SecondaryAddress, &msg->secondaryAddress);
00725 }
00726
00727 if (password->sizeValue > 0)
00728 {
00729 StunAtrIntegrity integrity;
00730 if (verbose) ortp_message("stun: HMAC with password: %s\n", password->value );
00731
00732 computeHmac(integrity.hash, buf, (int)(ptr-buf) , password->value, password->sizeValue);
00733 ptr = encodeAtrIntegrity(ptr, &integrity);
00734 }
00735
00736 encode16(lengthp, (UInt16)(ptr - buf - sizeof(StunMsgHdr)));
00737 return (int)(ptr - buf);
00738 }
00739
00740 int
00741 stunRand(void)
00742 {
00743
00744
00745 static bool_t init=FALSE;
00746 if ( !init )
00747 {
00748 UInt64 tick;
00749 int seed;
00750 init = TRUE;
00751
00752 #if defined(_WIN32_WCE)
00753 tick = GetTickCount ();
00754 #elif defined(_MSC_VER)
00755 {
00756 volatile unsigned int lowtick=0,hightick=0;
00757 __asm
00758 {
00759 rdtsc
00760 mov lowtick, eax
00761 mov hightick, edx
00762 }
00763 tick = hightick;
00764 tick <<= 32;
00765 tick |= lowtick;
00766 }
00767 #elif defined(__GNUC__) && ( defined(__i686__) || defined(__i386__) )
00768 asm("rdtsc" : "=A" (tick));
00769 #elif defined(__GNUC__) && defined(__amd64__)
00770 asm("rdtsc" : "=A" (tick));
00771 #elif defined (__SUNPRO_CC) && defined( __sparc__ )
00772 tick = gethrtime();
00773 #elif defined(__MACH__)
00774 {
00775 int fd=open("/dev/random",O_RDONLY);
00776 read(fd,&tick,sizeof(tick));
00777 closesocket(fd);
00778 }
00779 #elif defined(__linux)
00780 {
00781 fd_set fdSet;
00782 int maxFd=0;
00783 struct timeval tv;
00784 int e;
00785
00786 int fd=open("/dev/random",O_RDONLY);
00787
00788 if (fd<0)
00789 {
00790 ortp_message("stun: Failed to open random device\n");
00791 return random();
00792 }
00793 FD_ZERO(&fdSet);
00794 FD_SET(fd,&fdSet);
00795 maxFd=fd+1;
00796
00797 tv.tv_sec = 0;
00798 tv.tv_usec = 500;
00799
00800 e = select( maxFd, &fdSet, NULL,NULL, &tv );
00801 if (e <= 0)
00802 {
00803 ortp_error("stun: Failed to get data from random device\n");
00804 closesocket(fd);
00805 return random();
00806 }
00807 read(fd,&tick,sizeof(tick));
00808 closesocket(fd);
00809 }
00810 #else
00811 # error Need some way to seed the random number generator
00812 #endif
00813 seed = (int)(tick);
00814 #if defined(_WIN32) || defined(_WIN32_WCE)
00815 srand(seed);
00816 #else
00817 srandom(seed);
00818 #endif
00819 }
00820
00821 #if defined(_WIN32) || defined(_WIN32_WCE)
00822
00823 {
00824 int r1 = rand();
00825 int r2 = rand();
00826 int ret = (r1<<16) + r2;
00827
00828 return ret;
00829 }
00830 #else
00831 return random();
00832 #endif
00833 }
00834
00835
00836
00837 static int
00838 randomPort()
00839 {
00840 int min=0x4000;
00841 int max=0x7FFF;
00842
00843 int ret = stunRand();
00844 ret = ret|min;
00845 ret = ret&max;
00846
00847 return ret;
00848 }
00849
00850
00851 #ifdef NOSSL
00852 static void
00853 computeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey)
00854 {
00855 strncpy(hmac,"hmac-not-implemented",20);
00856 }
00857 #else
00858 #include <openssl/hmac.h>
00859
00860 static void
00861 computeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey)
00862 {
00863 unsigned int resultSize=0;
00864 HMAC(EVP_sha1(),
00865 key, sizeKey,
00866 (const unsigned char*) input, length,
00867 (unsigned char*)hmac, &resultSize);
00868
00869
00870
00871
00872
00873
00874
00875 }
00876 #endif
00877
00878
00879 static void
00880 toHex(const char* buffer, int bufferSize, char* output)
00881 {
00882 int i;
00883 static char hexmap[] = "0123456789abcdef";
00884
00885 const char* p = buffer;
00886 char* r = output;
00887 for (i=0; i < bufferSize; i++)
00888 {
00889 unsigned char temp = *p++;
00890
00891 int hi = (temp & 0xf0)>>4;
00892 int low = (temp & 0xf);
00893
00894 *r++ = hexmap[hi];
00895 *r++ = hexmap[low];
00896 }
00897 *r = 0;
00898 }
00899
00900 void
00901 stunCreateUserName(const StunAddress4* source, StunAtrString* username)
00902 {
00903 UInt64 time = stunGetSystemTimeSecs();
00904 UInt64 lotime;
00905 char buffer[1024];
00906 char hmac[20];
00907 char key[] = "Jason";
00908 char hmacHex[41];
00909 int l;
00910
00911 time -= (time % 20*60);
00912
00913 lotime = time & 0xFFFFFFFF;
00914
00915 sprintf(buffer,
00916 "%08x:%08x:%08x:",
00917 (UInt32)(source->addr),
00918 (UInt32)(stunRand()),
00919 (UInt32)(lotime));
00920
00921
00922
00923
00924 computeHmac(hmac, buffer, strlen(buffer), key, strlen(key) );
00925 toHex(hmac, 20, hmacHex );
00926 hmacHex[40] =0;
00927
00928 strcat(buffer,hmacHex);
00929
00930 l = strlen(buffer);
00931
00932
00933
00934 username->sizeValue = l;
00935 memcpy(username->value,buffer,l);
00936 username->value[l]=0;
00937
00938
00939 }
00940
00941 void
00942 stunCreatePassword(const StunAtrString *username, StunAtrString* password)
00943 {
00944 char hmac[20];
00945 char key[] = "Fluffy";
00946
00947 computeHmac(hmac, username->value, strlen(username->value), key, strlen(key));
00948 toHex(hmac, 20, password->value);
00949 password->sizeValue = 40;
00950 password->value[40]=0;
00951
00952
00953 }
00954
00955
00956 UInt64
00957 stunGetSystemTimeSecs(void)
00958 {
00959 UInt64 time=0;
00960 #if defined(_WIN32) || defined(_WIN32_WCE)
00961 SYSTEMTIME t;
00962
00963 GetSystemTime( &t );
00964 time = (t.wHour*60+t.wMinute)*60+t.wSecond;
00965 #else
00966 struct timeval now;
00967 gettimeofday( &now , NULL );
00968
00969 time = now.tv_sec;
00970 #endif
00971 return time;
00972 }
00973
00974
00975
00976 bool_t
00977 stunParseHostName( char* peerName,
00978 UInt32* ip,
00979 UInt16* portVal,
00980 UInt16 defaultPort )
00981 {
00982 struct in_addr sin_addr;
00983
00984 char host[512];
00985 char* port = NULL;
00986 int portNum = defaultPort;
00987 char* sep;
00988 struct hostent* h;
00989
00990 strncpy(host,peerName,512);
00991 host[512-1]='\0';
00992
00993
00994 sep = strchr(host,':');
00995
00996 if ( sep == NULL )
00997 {
00998 portNum = defaultPort;
00999 }
01000 else
01001 {
01002 char* endPtr=NULL;
01003 *sep = '\0';
01004 port = sep + 1;
01005
01006
01007
01008 portNum = strtol(port,&endPtr,10);
01009
01010 if ( endPtr != NULL )
01011 {
01012 if ( *endPtr != '\0' )
01013 {
01014 portNum = defaultPort;
01015 }
01016 }
01017 }
01018
01019 if ( portNum < 1024 ) return FALSE;
01020 if ( portNum >= 0xFFFF ) return FALSE;
01021
01022
01023
01024 #if defined(_WIN32) || defined(_WIN32_WCE)
01025
01026 if ( isdigit( host[0] ) )
01027 {
01028
01029 unsigned long a = inet_addr(host);
01030
01031
01032 *ip = ntohl( a );
01033 }
01034 else
01035 {
01036
01037 h = gethostbyname( host );
01038
01039 if ( h == NULL )
01040 {
01041
01042
01043
01044
01045
01046
01047 *ip = ntohl( 0x7F000001L );
01048
01049 return FALSE;
01050 }
01051 else
01052 {
01053 sin_addr = *(struct in_addr*)h->h_addr;
01054 *ip = ntohl( sin_addr.s_addr );
01055 }
01056 }
01057
01058 #else
01059 h = gethostbyname( host );
01060 if ( h == NULL )
01061 {
01062
01063
01064
01065
01066 *ip = ntohl( 0x7F000001L );
01067 return FALSE;
01068 }
01069 else
01070 {
01071 sin_addr = *(struct in_addr*)h->h_addr;
01072 *ip = ntohl( sin_addr.s_addr );
01073 }
01074 #endif
01075
01076 *portVal = portNum;
01077
01078 return TRUE;
01079 }
01080
01081
01082 bool_t
01083 stunParseServerName( char* name, StunAddress4 *addr)
01084 {
01085
01086
01087
01088
01089 bool_t ret = stunParseHostName( name, &addr->addr, &addr->port, 3478);
01090 if ( ret != TRUE )
01091 {
01092 addr->port=0xFFFF;
01093 }
01094 return ret;
01095 }
01096
01097
01098 static void
01099 stunCreateErrorResponse(StunMessage *response, int cl, int number, const char* msg)
01100 {
01101 response->msgHdr.msgType = BindErrorResponseMsg;
01102 response->hasErrorCode = TRUE;
01103 response->errorCode.errorClass = cl;
01104 response->errorCode.number = number;
01105 strcpy(response->errorCode.reason, msg);
01106 }
01107
01108 #if 0
01109 static void
01110 stunCreateSharedSecretErrorResponse(StunMessage& response, int cl, int number, const char* msg)
01111 {
01112 response.msgHdr.msgType = SharedSecretErrorResponseMsg;
01113 response.hasErrorCode = TRUE;
01114 response.errorCode.errorClass = cl;
01115 response.errorCode.number = number;
01116 strcpy(response.errorCode.reason, msg);
01117 }
01118 #endif
01119
01120 static void
01121 stunCreateSharedSecretResponse(const StunMessage *request, const StunAddress4 *source, StunMessage *response)
01122 {
01123 response->msgHdr.msgType = SharedSecretResponseMsg;
01124 response->msgHdr.id = request->msgHdr.id;
01125
01126 response->hasUsername = TRUE;
01127 stunCreateUserName( source, &response->username);
01128
01129 response->hasPassword = TRUE;
01130 stunCreatePassword( &response->username, &response->password);
01131 }
01132
01133
01134
01135
01136
01137 bool_t
01138 stunServerProcessMsg( char* buf,
01139 unsigned int bufLen,
01140 StunAddress4 *from,
01141 StunAddress4 *secondary,
01142 StunAddress4 *myAddr,
01143 StunAddress4 *altAddr,
01144 StunMessage *resp,
01145 StunAddress4 *destination,
01146 StunAtrString *hmacPassword,
01147 bool_t* changePort,
01148 bool_t* changeIp,
01149 bool_t verbose)
01150 {
01151 int i;
01152 StunMessage req;
01153 StunAddress4 mapped;
01154 StunAddress4 respondTo;
01155 UInt32 flags;
01156 bool_t ok;
01157
01158
01159 memset( &req, 0 , sizeof(req) );
01160 memset( resp, 0 , sizeof(*resp) );
01161
01162 *changeIp = FALSE;
01163 *changePort = FALSE;
01164
01165 ok = stunParseMessage( buf,bufLen, &req, verbose);
01166
01167 if (!ok)
01168 {
01169 if (verbose) ortp_error("stun: Request did not parse");
01170 return FALSE;
01171 }
01172 if (verbose) ortp_message("stun: Request parsed ok");
01173
01174 mapped = req.mappedAddress.ipv4;
01175 respondTo = req.responseAddress.ipv4;
01176 flags = req.changeRequest.value;
01177
01178 if (req.msgHdr.msgType==SharedSecretRequestMsg)
01179 {
01180 if(verbose) ortp_message("stun: Received SharedSecretRequestMsg on udp. send error 433.");
01181
01182 stunCreateSharedSecretResponse(&req, from, resp);
01183
01184 return TRUE;
01185
01186 }
01187 else if (req.msgHdr.msgType==BindRequestMsg)
01188 {
01189 if (!req.hasMessageIntegrity)
01190 {
01191 if (verbose) ortp_message("stun: BindRequest does not contain MessageIntegrity");
01192
01193 if (0)
01194 {
01195 if(verbose) ortp_message("stun: Received BindRequest with no MessageIntegrity. Sending 401.");
01196 stunCreateErrorResponse(resp, 4, 1, "Missing MessageIntegrity");
01197 return TRUE;
01198 }
01199 }
01200 else
01201 {
01202 if (!req.hasUsername)
01203 {
01204 if (verbose) ortp_message("stun: No UserName. Send 432.");
01205 stunCreateErrorResponse(resp, 4, 32, "No UserName and contains MessageIntegrity");
01206 return TRUE;
01207 }
01208 else
01209 {
01210 if (verbose) ortp_message("stun: Validating username: %s", req.username.value );
01211
01212 if (strcmp(req.username.value, "test") == 0)
01213 {
01214 if (0)
01215 {
01216
01217 stunCreateErrorResponse(resp, 4, 30, "Stale credentials on BindRequest");
01218 return TRUE;
01219 }
01220 else
01221 {
01222 unsigned char hmac[20];
01223 if (verbose) ortp_message("stun: Validating MessageIntegrity");
01224
01225
01226 #ifndef NOSSL
01227 {
01228 unsigned int hmacSize=20;
01229
01230 HMAC(EVP_sha1(),
01231 "1234", 4,
01232 (const unsigned char*) buf, bufLen-20-4,
01233 hmac, &hmacSize);
01234
01235
01236
01237
01238
01239
01240 }
01241 #endif
01242
01243 if (memcmp(buf, hmac, 20) != 0)
01244 {
01245 if (verbose) ortp_warning("stun: MessageIntegrity is bad. Sending ");
01246 stunCreateErrorResponse(resp, 4, 3, "Unknown username. Try test with password 1234");
01247 return TRUE;
01248 }
01249
01250
01251 resp->hasMessageIntegrity = TRUE;
01252
01253 resp->hasUsername = TRUE;
01254 resp->username = req.username;
01255 }
01256 }
01257 else
01258 {
01259 if (verbose) ortp_message("stun: Invalid username: %s Send 430", req.username.value);
01260 }
01261 }
01262 }
01263
01264
01265
01266
01267 if ( respondTo.port == 0 )
01268 {
01269
01270 memcpy(&respondTo, from, sizeof(StunAddress4));
01271 }
01272 if ( mapped.port == 0 )
01273 {
01274
01275 memcpy(&mapped, from, sizeof(StunAddress4));
01276 }
01277
01278 *changeIp = ( flags & ChangeIpFlag )?TRUE:FALSE;
01279 *changePort = ( flags & ChangePortFlag )?TRUE:FALSE;
01280
01281 if (verbose)
01282 {
01283 ortp_message("stun: Request is valid:\n");
01284 ortp_message("stun: \t flags= %i\n", flags );
01285 ortp_message("stun: \t changeIp= %i\n", *changeIp );
01286 ortp_message("stun: \t changePort=%i\n", *changePort );
01287 ortp_message("stun: \t from= %i\n", from->addr );
01288 ortp_message("stun: \t respond to= %i\n", respondTo.addr );
01289 ortp_message("stun: \t mapped= %i\n", mapped.addr );
01290 }
01291
01292
01293 resp->msgHdr.msgType = BindResponseMsg;
01294 for (i=0; i<16; i++ )
01295 {
01296 resp->msgHdr.id.octet[i] = req.msgHdr.id.octet[i];
01297 }
01298
01299 if ( req.xorOnly == FALSE )
01300 {
01301 resp->hasMappedAddress = TRUE;
01302 resp->mappedAddress.ipv4.port = mapped.port;
01303 resp->mappedAddress.ipv4.addr = mapped.addr;
01304 }
01305
01306 if (1)
01307 {
01308 UInt16 id16;
01309 UInt32 id32;
01310 resp->hasXorMappedAddress = TRUE;
01311 id16 = req.msgHdr.id.octet[7]<<8
01312 | req.msgHdr.id.octet[6];
01313 id32 = req.msgHdr.id.octet[7]<<24
01314 | req.msgHdr.id.octet[6]<<16
01315 | req.msgHdr.id.octet[5]<<8
01316 | req.msgHdr.id.octet[4];
01317 resp->xorMappedAddress.ipv4.port = mapped.port^id16;
01318 resp->xorMappedAddress.ipv4.addr = mapped.addr^id32;
01319 }
01320
01321 resp->hasSourceAddress = TRUE;
01322 resp->sourceAddress.ipv4.port = (*changePort) ? altAddr->port : myAddr->port;
01323 resp->sourceAddress.ipv4.addr = (*changeIp) ? altAddr->addr : myAddr->addr;
01324
01325 resp->hasChangedAddress = TRUE;
01326 resp->changedAddress.ipv4.port = altAddr->port;
01327 resp->changedAddress.ipv4.addr = altAddr->addr;
01328
01329 if ( secondary->port != 0 )
01330 {
01331 resp->hasSecondaryAddress = TRUE;
01332 resp->secondaryAddress.ipv4.port = secondary->port;
01333 resp->secondaryAddress.ipv4.addr = secondary->addr;
01334 }
01335
01336 if ( req.hasUsername && req.username.sizeValue > 0 )
01337 {
01338
01339 resp->hasUsername = TRUE;
01340
01341
01342 memcpy( resp->username.value, req.username.value, req.username.sizeValue );
01343 resp->username.sizeValue = req.username.sizeValue;
01344 }
01345
01346 if (1)
01347 {
01348 const char serverName[] = "Vovida.org " STUN_VERSION;
01349 resp->hasServerName = TRUE;
01350
01351
01352
01353
01354 memcpy( resp->serverName.value, serverName, sizeof(serverName));
01355 resp->serverName.sizeValue = sizeof(serverName);
01356 }
01357
01358 if ( req.hasMessageIntegrity & req.hasUsername )
01359 {
01360
01361
01362 stunCreatePassword( &req.username, hmacPassword );
01363 }
01364
01365 if (req.hasUsername && (req.username.sizeValue > 64 ) )
01366 {
01367 UInt32 source;
01368
01369
01370 sscanf(req.username.value, "%x", &source);
01371 resp->hasReflectedFrom = TRUE;
01372 resp->reflectedFrom.ipv4.port = 0;
01373 resp->reflectedFrom.ipv4.addr = source;
01374 }
01375
01376 destination->port = respondTo.port;
01377 destination->addr = respondTo.addr;
01378
01379 return TRUE;
01380 }
01381 else
01382 {
01383 if (verbose) ortp_error("stun: Unknown or unsupported request ");
01384 return FALSE;
01385 }
01386
01387
01388 return FALSE;
01389 }
01390
01391 bool_t
01392 stunInitServer(StunServerInfo *info, const StunAddress4 *myAddr, const StunAddress4 *altAddr, int startMediaPort, bool_t verbose )
01393 {
01394
01395
01396
01397
01398
01399
01400 info->myAddr.port = myAddr->port;
01401 info->myAddr.addr = myAddr->addr;
01402
01403
01404 info->altAddr.port = altAddr->port;
01405 info->altAddr.addr = altAddr->addr;
01406
01407 info->myFd = INVALID_SOCKET;
01408 info->altPortFd = INVALID_SOCKET;
01409 info->altIpFd = INVALID_SOCKET;
01410 info->altIpPortFd = INVALID_SOCKET;
01411
01412 memset(info->relays, 0, sizeof(info->relays));
01413 if (startMediaPort > 0)
01414 {
01415 int i;
01416 info->relay = TRUE;
01417
01418 for (i=0; i<MAX_MEDIA_RELAYS; ++i)
01419 {
01420 StunMediaRelay* relay = &info->relays[i];
01421 relay->relayPort = startMediaPort+i;
01422 relay->fd = 0;
01423 relay->expireTime = 0;
01424 }
01425 }
01426 else
01427 {
01428 info->relay = FALSE;
01429 }
01430
01431 if ((info->myFd = openPort(myAddr->port, myAddr->addr,verbose)) == INVALID_SOCKET)
01432 {
01433 ortp_error("stun: Can't open %i\n", myAddr->addr );
01434 stunStopServer(info);
01435
01436 return FALSE;
01437 }
01438
01439
01440 if ((info->altPortFd = openPort(altAddr->port,myAddr->addr,verbose)) == INVALID_SOCKET)
01441 {
01442 ortp_error("stun: Can't open %i\n", myAddr->addr );
01443 stunStopServer(info);
01444 return FALSE;
01445 }
01446
01447
01448
01449 info->altIpFd = INVALID_SOCKET;
01450 if ( altAddr->addr != 0 )
01451 {
01452 if ((info->altIpFd = openPort( myAddr->port, altAddr->addr,verbose)) == INVALID_SOCKET)
01453 {
01454 ortp_error("stun: Can't open %i\n", altAddr->addr );
01455 stunStopServer(info);
01456 return FALSE;
01457 }
01458
01459 }
01460
01461 info->altIpPortFd = INVALID_SOCKET;
01462 if ( altAddr->addr != 0 )
01463 { if ((info->altIpPortFd = openPort(altAddr->port, altAddr->addr,verbose)) == INVALID_SOCKET)
01464 {
01465 ortp_error("stun: Can't open %i\n", altAddr->addr );
01466 stunStopServer(info);
01467 return FALSE;
01468 }
01469
01470 }
01471
01472 return TRUE;
01473 }
01474
01475 void
01476 stunStopServer(StunServerInfo *info)
01477 {
01478 if (info->myFd > 0) closesocket(info->myFd);
01479 if (info->altPortFd > 0) closesocket(info->altPortFd);
01480 if (info->altIpFd > 0) closesocket(info->altIpFd);
01481 if (info->altIpPortFd > 0) closesocket(info->altIpPortFd);
01482
01483 if (info->relay)
01484 {
01485 int i;
01486 for (i=0; i<MAX_MEDIA_RELAYS; ++i)
01487 {
01488 StunMediaRelay* relay = &info->relays[i];
01489 if (relay->fd)
01490 {
01491 closesocket(relay->fd);
01492 relay->fd = 0;
01493 }
01494 }
01495 }
01496 }
01497
01498 #if 0
01499
01500 bool_t
01501 stunServerProcess(StunServerInfo *info, bool_t verbose)
01502 {
01503 char msg[STUN_MAX_MESSAGE_SIZE];
01504 int msgLen = sizeof(msg);
01505
01506 bool_t ok = FALSE;
01507 bool_t recvAltIp =FALSE;
01508 bool_t recvAltPort = FALSE;
01509
01510 fd_set fdSet;
01511 #if defined(_WIN32) || defined(_WIN32_WCE)
01512 unsigned int maxFd=0;
01513 #else
01514 int maxFd=0;
01515 #endif
01516 struct timeval tv;
01517 int e;
01518
01519 FD_ZERO(&fdSet);
01520 FD_SET(info->myFd,&fdSet);
01521 if ( info->myFd >= maxFd ) maxFd=info->myFd+1;
01522 FD_SET(info->altPortFd,&fdSet);
01523 if ( info->altPortFd >= maxFd ) maxFd=info->altPortFd+1;
01524
01525 if ( info->altIpFd != INVALID_SOCKET )
01526 {
01527 FD_SET(info->altIpFd,&fdSet);
01528 if (info->altIpFd>=maxFd) maxFd=info->altIpFd+1;
01529 }
01530 if ( info->altIpPortFd != INVALID_SOCKET )
01531 {
01532 FD_SET(info->altIpPortFd,&fdSet);
01533 if (info->altIpPortFd>=maxFd) maxFd=info->altIpPortFd+1;
01534 }
01535
01536 if (info->relay)
01537 {
01538 int i;
01539 for (i=0; i<MAX_MEDIA_RELAYS; ++i)
01540 {
01541 StunMediaRelay* relay = &info->relays[i];
01542 if (relay->fd)
01543 {
01544 FD_SET(relay->fd, &fdSet);
01545 if (relay->fd >= maxFd) maxFd=relay->fd+1;
01546 }
01547 }
01548 }
01549
01550 if ( info->altIpFd != INVALID_SOCKET )
01551 {
01552 FD_SET(info->altIpFd,&fdSet);
01553 if (info->altIpFd>=maxFd) maxFd=info->altIpFd+1;
01554 }
01555 if ( info->altIpPortFd != INVALID_SOCKET )
01556 {
01557 FD_SET(info->altIpPortFd,&fdSet);
01558 if (info->altIpPortFd>=maxFd) maxFd=info->altIpPortFd+1;
01559 }
01560
01561 tv.tv_sec = 0;
01562 tv.tv_usec = 1000;
01563
01564 e = select( maxFd, &fdSet, NULL,NULL, &tv );
01565 if (e < 0)
01566 {
01567 int err = getErrno();
01568 #if !defined(_WIN32_WCE)
01569 ortp_error("stun: Error on select: %s\n", strerror(err) );
01570 #else
01571 ortp_error("stun: Error on select: %i\n", err );
01572 #endif
01573 }
01574 else if (e >= 0)
01575 {
01576 StunAddress4 from;
01577 int relayPort = 0;
01578
01579 bool_t changePort = FALSE;
01580 bool_t changeIp = FALSE;
01581
01582 StunMessage resp;
01583 StunAddress4 dest;
01584 StunAtrString hmacPassword;
01585
01586 StunAddress4 secondary;
01587
01588 char buf[STUN_MAX_MESSAGE_SIZE];
01589 int len = sizeof(buf);
01590
01591 hmacPassword.sizeValue = 0;
01592 secondary.port = 0;
01593 secondary.addr = 0;
01594
01595
01596 if (info->relay)
01597 {
01598 time_t now;
01599 int i;
01600 #if !defined(_WIN32_WCE)
01601 now = time(0);
01602 #else
01603 DWORD timemillis = GetTickCount();
01604 now = timemillis/1000;
01605 #endif
01606 for (i=0; i<MAX_MEDIA_RELAYS; ++i)
01607 {
01608 StunMediaRelay* relay = &info->relays[i];
01609 if (relay->fd)
01610 {
01611 if (FD_ISSET(relay->fd, &fdSet))
01612 {
01613 char msg[MAX_RTP_MSG_SIZE];
01614 int msgLen = sizeof(msg);
01615
01616 StunAddress4 rtpFrom;
01617 ok = getMessage( relay->fd, msg, &msgLen, &rtpFrom.addr, &rtpFrom.port ,verbose);
01618 if (ok)
01619 {
01620 sendMessage(info->myFd, msg, msgLen, relay->destination.addr, relay->destination.port, verbose);
01621 relay->expireTime = now + MEDIA_RELAY_TIMEOUT;
01622 if ( verbose ) ortp_message("stun: Relay packet on %i from %i -> %i",
01623 relay->fd,
01624 rtpFrom.addr,
01625 relay->destination.addr
01626 );
01627 }
01628 }
01629 else if (now > relay->expireTime)
01630 {
01631 closesocket(relay->fd);
01632 relay->fd = 0;
01633 }
01634 }
01635 }
01636 }
01637
01638
01639 if (FD_ISSET(info->myFd,&fdSet))
01640 {
01641 if (verbose) ortp_message("stun: received on A1:P1");
01642 recvAltIp = FALSE;
01643 recvAltPort = FALSE;
01644 ok = getMessage( info->myFd, msg, &msgLen, &from.addr, &from.port,verbose );
01645 }
01646 else if (FD_ISSET(info->altPortFd, &fdSet))
01647 {
01648 if (verbose) ortp_message("stun: received on A1:P2");
01649 recvAltIp = FALSE;
01650 recvAltPort = TRUE;
01651 ok = getMessage( info->altPortFd, msg, &msgLen, &from.addr, &from.port,verbose );
01652 }
01653 else if ( (info->altIpFd!=INVALID_SOCKET) && FD_ISSET(info->altIpFd,&fdSet))
01654 {
01655 if (verbose) ortp_message("stun: received on A2:P1");
01656 recvAltIp = TRUE;
01657 recvAltPort = FALSE;
01658 ok = getMessage( info->altIpFd, msg, &msgLen, &from.addr, &from.port ,verbose);
01659 }
01660 else if ( (info->altIpPortFd!=INVALID_SOCKET) && FD_ISSET(info->altIpPortFd, &fdSet))
01661 {
01662 if (verbose) ortp_message("stun: received on A2:P2");
01663 recvAltIp = TRUE;
01664 recvAltPort = TRUE;
01665 ok = getMessage( info->altIpPortFd, msg, &msgLen, &from.addr, &from.port,verbose );
01666 }
01667 else
01668 {
01669 return TRUE;
01670 }
01671
01672 if (info->relay)
01673 {
01674 int i;
01675 for (i=0; i<MAX_MEDIA_RELAYS; ++i)
01676 {
01677 StunMediaRelay* relay = &info->relays[i];
01678 if (relay->destination.addr == from.addr &&
01679 relay->destination.port == from.port)
01680 {
01681 relayPort = relay->relayPort;
01682 relay->expireTime = time(0) + MEDIA_RELAY_TIMEOUT;
01683 break;
01684 }
01685 }
01686
01687 if (relayPort == 0)
01688 {
01689 int i;
01690 for (i=0; i<MAX_MEDIA_RELAYS; ++i)
01691 {
01692 StunMediaRelay* relay = &info->relays[i];
01693 if (relay->fd == 0)
01694 {
01695 if ( verbose ) ortp_message("stun: Open relay port %i\n", relay->relayPort );
01696 relay->fd = openPort(relay->relayPort, info->myAddr.addr, verbose);
01697 relay->destination.addr = from.addr;
01698 relay->destination.port = from.port;
01699 relay->expireTime = time(0) + MEDIA_RELAY_TIMEOUT;
01700 relayPort = relay->relayPort;
01701 break;
01702 }
01703 }
01704 }
01705 }
01706
01707 if ( !ok )
01708 {
01709 if ( verbose ) ortp_message("stun: Get message did not return a valid message\n");
01710 return TRUE;
01711 }
01712
01713 if ( verbose ) ortp_message("stun: Got a request (len=%i) from %i", msgLen, from.addr);
01714
01715 if ( msgLen <= 0 )
01716 {
01717 return TRUE;
01718 }
01719
01720 if (info->relay && relayPort)
01721 {
01722 secondary = from;
01723
01724 from.addr = info->myAddr.addr;
01725 from.port = relayPort;
01726 }
01727
01728 ok = stunServerProcessMsg( msg, msgLen, &from, &secondary,
01729 recvAltIp ? &info->altAddr : &info->myAddr,
01730 recvAltIp ? &info->myAddr : &info->altAddr,
01731 &resp,
01732 &dest,
01733 &hmacPassword,
01734 &changePort,
01735 &changeIp,
01736 verbose );
01737
01738 if ( !ok )
01739 {
01740 if ( verbose ) ortp_error("stun: Failed to parse message");
01741 return TRUE;
01742 }
01743
01744 len = stunEncodeMessage( &resp, buf, len, &hmacPassword,verbose );
01745
01746 if ( dest.addr == 0 ) ok=FALSE;
01747 if ( dest.port == 0 ) ok=FALSE;
01748
01749 if ( ok )
01750 {
01751
01752
01753
01754 Socket sendFd;
01755
01756 bool_t sendAltIp = recvAltIp;
01757 bool_t sendAltPort = recvAltPort;
01758
01759 if ( changeIp ) sendAltIp = !sendAltIp;
01760 if ( changePort ) sendAltPort = !sendAltPort;
01761
01762 if ( !sendAltPort )
01763 {
01764 if ( !sendAltIp )
01765 {
01766 sendFd = info->myFd;
01767 }
01768 else
01769 {
01770 sendFd = info->altIpFd;
01771 }
01772 }
01773 else
01774 {
01775 if ( !sendAltIp )
01776 {
01777 sendFd = info->altPortFd;
01778 }
01779 else
01780 {
01781 sendFd = info->altIpPortFd;
01782 }
01783 }
01784
01785 if ( sendFd != INVALID_SOCKET )
01786 {
01787 sendMessage( sendFd, buf, len, dest.addr, dest.port, verbose );
01788 }
01789 }
01790 }
01791
01792 return TRUE;
01793 }
01794 #endif
01795
01796 int
01797 stunFindLocalInterfaces(UInt32* addresses,int maxRet)
01798 {
01799 #if defined(WIN32) || defined(_WIN32_WCE) || defined(__sparc__)
01800 return 0;
01801 #else
01802 struct ifconf ifc;
01803 int e;
01804
01805 int s = socket( AF_INET, SOCK_DGRAM, 0 );
01806 int len = 100 * sizeof(struct ifreq);
01807
01808 char buf[ 100 * sizeof(struct ifreq) ];
01809 char *ptr;
01810 int tl;
01811 int count=0;
01812
01813 ifc.ifc_len = len;
01814 ifc.ifc_buf = buf;
01815
01816 e = ioctl(s,SIOCGIFCONF,&ifc);
01817 ptr = buf;
01818 tl = ifc.ifc_len;
01819
01820 while ( (tl > 0) && ( count < maxRet) )
01821 {
01822 struct ifreq* ifr = (struct ifreq *)ptr;
01823 struct ifreq ifr2;
01824 struct sockaddr a;
01825 struct sockaddr_in* addr;
01826
01827 UInt32 ai;
01828 int si = sizeof(ifr->ifr_name) + sizeof(struct sockaddr);
01829 tl -= si;
01830 ptr += si;
01831
01832
01833
01834 ifr2 = *ifr;
01835
01836 e = ioctl(s,SIOCGIFADDR,&ifr2);
01837 if ( e == -1 )
01838 {
01839 break;
01840 }
01841
01842
01843
01844 a = ifr2.ifr_addr;
01845 addr = (struct sockaddr_in*) &a;
01846
01847 ai = ntohl( addr->sin_addr.s_addr );
01848 if ((int)((ai>>24)&0xFF) != 127)
01849 {
01850 addresses[count++] = ai;
01851 }
01852
01853 }
01854
01855 closesocket(s);
01856
01857 return count;
01858 #endif
01859 }
01860
01861
01862 void
01863 stunBuildReqSimple( StunMessage* msg,
01864 const StunAtrString *username,
01865 bool_t changePort, bool_t changeIp, unsigned int id )
01866 {
01867 int i;
01868
01869 memset( msg , 0 , sizeof(*msg) );
01870
01871 msg->msgHdr.msgType = BindRequestMsg;
01872
01873 for ( i=0; i<16; i=i+4 )
01874 {
01875
01876 int r = stunRand();
01877 msg->msgHdr.id.octet[i+0]= r>>0;
01878 msg->msgHdr.id.octet[i+1]= r>>8;
01879 msg->msgHdr.id.octet[i+2]= r>>16;
01880 msg->msgHdr.id.octet[i+3]= r>>24;
01881 }
01882
01883 if ( id != 0 )
01884 {
01885 msg->msgHdr.id.octet[0] = id;
01886 }
01887
01888 msg->hasChangeRequest = TRUE;
01889 msg->changeRequest.value =(changeIp?ChangeIpFlag:0) |
01890 (changePort?ChangePortFlag:0);
01891
01892 if ( username->sizeValue > 0 )
01893 {
01894 msg->hasUsername = TRUE;
01895
01896 memcpy(&msg->username, username, sizeof(StunAtrString));
01897 }
01898 }
01899
01900
01901 static void
01902 stunSendTest( Socket myFd, StunAddress4 *dest,
01903 const StunAtrString *username, const StunAtrString *password,
01904 int testNum, bool_t verbose )
01905 {
01906
01907
01908
01909 bool_t changePort=FALSE;
01910 bool_t changeIP=FALSE;
01911 bool_t discard=FALSE;
01912
01913 StunMessage req;
01914 char buf[STUN_MAX_MESSAGE_SIZE];
01915 int len = STUN_MAX_MESSAGE_SIZE;
01916
01917 switch (testNum)
01918 {
01919 case 1:
01920 case 10:
01921 case 11:
01922 break;
01923 case 2:
01924
01925 changeIP=TRUE;
01926 break;
01927 case 3:
01928 changePort=TRUE;
01929 break;
01930 case 4:
01931 changeIP=TRUE;
01932 break;
01933 case 5:
01934 discard=TRUE;
01935 break;
01936 default:
01937 ortp_error("stun: Test %i is unkown\n", testNum);
01938 return ;
01939 }
01940
01941 memset(&req, 0, sizeof(StunMessage));
01942
01943 stunBuildReqSimple( &req, username,
01944 changePort , changeIP ,
01945 testNum );
01946
01947 len = stunEncodeMessage( &req, buf, len, password,verbose );
01948
01949 if ( verbose )
01950 {
01951 ortp_message("stun: About to send msg of len %i to %s\n", len, ipaddr(dest) );
01952 }
01953
01954 sendMessage( myFd, buf, len, dest->addr, dest->port, verbose );
01955
01956
01957 #if defined(_WIN32_WCE)
01958 Sleep (10);
01959 #elif defined(WIN32)
01960 {
01961 clock_t now = clock();
01962
01963 while ( clock() <= now+10 ) { };
01964 }
01965 #else
01966 usleep(10*1000);
01967 #endif
01968
01969 }
01970
01971
01972 void
01973 stunGetUserNameAndPassword( const StunAddress4 *dest,
01974 StunAtrString* username,
01975 StunAtrString* password)
01976 {
01977
01978
01979 stunCreateUserName(dest, username);
01980 stunCreatePassword(username, password);
01981 }
01982
01983
01984 int
01985 stunTest( StunAddress4 *dest, int testNum, bool_t verbose, StunAddress4* sAddr , StunAddress4 *sMappedAddr, StunAddress4* sChangedAddr)
01986 {
01987
01988
01989
01990 int port = randomPort();
01991 UInt32 interfaceIp=0;
01992 Socket myFd;
01993 StunAtrString username;
01994 StunAtrString password;
01995 char msg[STUN_MAX_MESSAGE_SIZE];
01996 int msgLen = STUN_MAX_MESSAGE_SIZE;
01997 StunAddress4 from;
01998 StunMessage resp;
01999 bool_t ok;
02000
02001 if (sAddr)
02002 {
02003 interfaceIp = sAddr->addr;
02004 if ( sAddr->port != 0 )
02005 {
02006 port = sAddr->port;
02007 }
02008 }
02009 myFd = openPort(port,interfaceIp,verbose);
02010 if ( myFd == INVALID_SOCKET)
02011 return -1;
02012
02013 username.sizeValue = 0;
02014 password.sizeValue = 0;
02015
02016 #ifdef USE_TLS
02017 stunGetUserNameAndPassword( dest, &username, &password );
02018 #endif
02019
02020 stunSendTest( myFd, dest, &username, &password, testNum, verbose );
02021
02022 ok = getMessage( myFd,
02023 msg,
02024 &msgLen,
02025 &from.addr,
02026 &from.port,verbose );
02027 closesocket(myFd);
02028 if (!ok)
02029 return -1;
02030
02031 memset(&resp, 0, sizeof(StunMessage));
02032
02033 if ( verbose ) ortp_message("stun: Got a response");
02034 ok = stunParseMessage( msg,msgLen, &resp,verbose );
02035
02036 if ( verbose )
02037 {
02038 ortp_message("stun: \t ok=%i\n", ok );
02039 #if defined(WIN32) || defined(_WIN32_WCE)
02040 ortp_message("stun: \t id=%u\n", *(unsigned int*)&resp.msgHdr.id );
02041 #endif
02042 ortp_message("stun: \t mappedAddr=%i\n", resp.mappedAddress.ipv4.addr );
02043 ortp_message("stun: \t changedAddr=%i\n", resp.changedAddress.ipv4.addr );
02044 }
02045
02046 if (sAddr)
02047 {
02048 sAddr->port = port;
02049 }
02050
02051 if (sMappedAddr)
02052 {
02053 sMappedAddr->port = resp.mappedAddress.ipv4.port;
02054 sMappedAddr->addr = resp.mappedAddress.ipv4.addr;
02055 }
02056
02057 if (sChangedAddr)
02058 {
02059 sChangedAddr->port = resp.changedAddress.ipv4.port;
02060 sChangedAddr->addr = resp.changedAddress.ipv4.addr;
02061 }
02062
02063 if (ok)
02064 return 0;
02065 else
02066 return -1;
02067 }
02068
02069
02070 NatType
02071 stunNatType( StunAddress4 *dest,
02072 bool_t verbose,
02073 bool_t* preservePort,
02074 bool_t* hairpin,
02075 int port,
02076 StunAddress4* sAddr
02077 )
02078 {
02079
02080
02081 UInt32 interfaceIp=0;
02082 Socket myFd1;
02083 Socket myFd2;
02084
02085 bool_t respTestI=FALSE;
02086 bool_t isNat=TRUE;
02087 StunAddress4 testIchangedAddr;
02088 StunAddress4 testImappedAddr;
02089 bool_t respTestI2=FALSE;
02090 bool_t mappedIpSame = TRUE;
02091 StunAddress4 testI2mappedAddr;
02092
02093 StunAddress4 testI2dest;
02094 bool_t respTestII=FALSE;
02095 bool_t respTestIII=FALSE;
02096 bool_t respTestHairpin=FALSE;
02097 StunAtrString username;
02098 StunAtrString password;
02099 int count=0;
02100 UInt64 second_started;
02101 UInt64 second_elapsed;
02102 Socket s;
02103
02104 if ( hairpin )
02105 {
02106 *hairpin = FALSE;
02107 }
02108
02109 if ( port == 0 )
02110 {
02111 port = randomPort();
02112 }
02113
02114 if (sAddr)
02115 {
02116 interfaceIp = sAddr->addr;
02117 }
02118 myFd1 = openPort(port,interfaceIp,verbose);
02119 myFd2 = openPort(port+1,interfaceIp,verbose);
02120
02121 if ( ( myFd1 == INVALID_SOCKET) || ( myFd2 == INVALID_SOCKET) )
02122 {
02123 ortp_error("stun: Some problem opening port/interface to send on\n");
02124 return StunTypeFailure;
02125 }
02126
02127
02128
02129
02130 memcpy(&testI2dest, dest, sizeof(StunAddress4));
02131
02132 memset(&testImappedAddr,0,sizeof(testImappedAddr));
02133
02134 username.sizeValue = 0;
02135 password.sizeValue = 0;
02136
02137 #ifdef USE_TLS
02138 stunGetUserNameAndPassword( dest, username, password );
02139 #endif
02140
02141
02142
02143
02144 second_started = stunGetSystemTimeSecs();
02145 second_elapsed = 1;
02146
02147 while ( count < 7 && second_elapsed < 5)
02148 {
02149 struct timeval tv;
02150 fd_set fdSet;
02151 int err;
02152 int e;
02153
02154 #if defined(WIN32) || defined(_WIN32_WCE)
02155 unsigned int fdSetSize;
02156 #else
02157 int fdSetSize;
02158 #endif
02159
02160 second_elapsed = stunGetSystemTimeSecs() - second_started ;
02161
02162 FD_ZERO(&fdSet); fdSetSize=0;
02163 FD_SET(myFd1,&fdSet); fdSetSize = (myFd1+1>fdSetSize) ? myFd1+1 : fdSetSize;
02164 FD_SET(myFd2,&fdSet); fdSetSize = (myFd2+1>fdSetSize) ? myFd2+1 : fdSetSize;
02165 tv.tv_sec=0;
02166 tv.tv_usec=500*1000;
02167 if ( count == 0 ) tv.tv_usec=0;
02168
02169 err = select(fdSetSize, &fdSet, NULL, NULL, &tv);
02170 e = getErrno();
02171 if ( err == SOCKET_ERROR )
02172 {
02173
02174 #if !defined(_WIN32_WCE)
02175 ortp_error("stun: Error %i %s in select\n", e, strerror(e));
02176 #else
02177 ortp_error("stun: Error %i in select\n", e);
02178 #endif
02179 closesocket(myFd1);
02180 closesocket(myFd2);
02181 return StunTypeFailure;
02182 }
02183 else if ( err == 0 )
02184 {
02185
02186 count++;
02187
02188 if ( !respTestI )
02189 {
02190 stunSendTest( myFd1, dest, &username, &password, 1 ,verbose );
02191 }
02192
02193 if ( (!respTestI2) && respTestI )
02194 {
02195
02196 if ( ( testI2dest.addr != 0 ) &&
02197 ( testI2dest.port != 0 ) )
02198 {
02199 stunSendTest( myFd1, &testI2dest, &username, &password, 10 ,verbose);
02200 }
02201 }
02202
02203 if ( !respTestII )
02204 {
02205 stunSendTest( myFd2, dest, &username, &password, 2 ,verbose );
02206 }
02207
02208 if ( !respTestIII )
02209 {
02210 stunSendTest( myFd2, dest, &username, &password, 3 ,verbose );
02211 }
02212
02213 if ( respTestI && (!respTestHairpin) )
02214 {
02215 if ( ( testImappedAddr.addr != 0 ) &&
02216 ( testImappedAddr.port != 0 ) )
02217 {
02218 stunSendTest( myFd1, &testImappedAddr, &username, &password, 11 ,verbose );
02219 }
02220 }
02221 }
02222 else
02223 {
02224 int i;
02225
02226
02227
02228
02229 for ( i=0; i<2; i++)
02230 {
02231 Socket myFd;
02232 if ( i==0 )
02233 {
02234 myFd=myFd1;
02235 }
02236 else
02237 {
02238 myFd=myFd2;
02239 }
02240
02241 if ( myFd!=INVALID_SOCKET )
02242 {
02243 if ( FD_ISSET(myFd,&fdSet) )
02244 {
02245 char msg[STUN_MAX_MESSAGE_SIZE];
02246 int msgLen = sizeof(msg);
02247
02248 StunAddress4 from;
02249 StunMessage resp;
02250
02251 getMessage( myFd,
02252 msg,
02253 &msgLen,
02254 &from.addr,
02255 &from.port,verbose );
02256
02257 memset(&resp, 0, sizeof(StunMessage));
02258
02259 stunParseMessage( msg,msgLen, &resp,verbose );
02260
02261 if ( verbose )
02262 {
02263 ortp_message("stun: Received message of type %i id=%i\n",
02264 resp.msgHdr.msgType,
02265 (int)(resp.msgHdr.id.octet[0]) );
02266 }
02267
02268 switch( resp.msgHdr.id.octet[0] )
02269 {
02270 case 1:
02271 {
02272 if ( !respTestI )
02273 {
02274
02275 testIchangedAddr.addr = resp.changedAddress.ipv4.addr;
02276 testIchangedAddr.port = resp.changedAddress.ipv4.port;
02277 testImappedAddr.addr = resp.mappedAddress.ipv4.addr;
02278 testImappedAddr.port = resp.mappedAddress.ipv4.port;
02279
02280 if ( preservePort )
02281 {
02282 *preservePort = ( testImappedAddr.port == port );
02283 }
02284
02285 testI2dest.addr = resp.changedAddress.ipv4.addr;
02286
02287 if (sAddr)
02288 {
02289 sAddr->port = testImappedAddr.port;
02290 sAddr->addr = testImappedAddr.addr;
02291 }
02292
02293 count = 0;
02294 }
02295 respTestI=TRUE;
02296 }
02297 break;
02298 case 2:
02299 {
02300 respTestII=TRUE;
02301 }
02302 break;
02303 case 3:
02304 {
02305 respTestIII=TRUE;
02306 }
02307 break;
02308 case 10:
02309 {
02310 if ( !respTestI2 )
02311 {
02312 testI2mappedAddr.addr = resp.mappedAddress.ipv4.addr;
02313 testI2mappedAddr.port = resp.mappedAddress.ipv4.port;
02314
02315 mappedIpSame = FALSE;
02316 if ( (testI2mappedAddr.addr == testImappedAddr.addr ) &&
02317 (testI2mappedAddr.port == testImappedAddr.port ))
02318 {
02319 mappedIpSame = TRUE;
02320 }
02321
02322
02323 }
02324 respTestI2=TRUE;
02325 }
02326 break;
02327 case 11:
02328 {
02329
02330 if ( hairpin )
02331 {
02332 *hairpin = TRUE;
02333 }
02334 respTestHairpin = TRUE;
02335 }
02336 break;
02337 }
02338 }
02339 }
02340 }
02341 }
02342 }
02343
02344 closesocket(myFd1);
02345 closesocket(myFd2);
02346
02347
02348
02349 s = openPort( 0, testImappedAddr.addr, FALSE );
02350 if ( s != INVALID_SOCKET )
02351 {
02352 isNat = FALSE;
02353
02354 }
02355 else
02356 {
02357 isNat = TRUE;
02358
02359 }
02360
02361 closesocket(s);
02362
02363 if (verbose)
02364 {
02365 ortp_message("stun: test I = %i\n", respTestI );
02366 ortp_message("stun: test II = %i\n", respTestII );
02367 ortp_message("stun: test III = %i\n", respTestIII );
02368 ortp_message("stun: test I(2) = %i\n", respTestI2 );
02369 ortp_message("stun: is nat = %i\n", isNat);
02370 ortp_message("stun: mapped IP same = %i\n", mappedIpSame );
02371 }
02372
02373
02374 if ( respTestI )
02375 {
02376 if ( isNat )
02377 {
02378 if (respTestII)
02379 {
02380 return StunTypeConeNat;
02381 }
02382 else
02383 {
02384 if ( mappedIpSame )
02385 {
02386 if ( respTestIII )
02387 {
02388 return StunTypeRestrictedNat;
02389 }
02390 else
02391 {
02392 return StunTypePortRestrictedNat;
02393 }
02394 }
02395 else
02396 {
02397 return StunTypeSymNat;
02398 }
02399 }
02400 }
02401 else
02402 {
02403 if (respTestII)
02404 {
02405 return StunTypeOpen;
02406 }
02407 else
02408 {
02409 return StunTypeSymFirewall;
02410 }
02411 }
02412 }
02413 else
02414 {
02415 return StunTypeBlocked;
02416 }
02417
02418 return StunTypeUnknown;
02419 }
02420
02421 int
02422 stunOpenSocket( StunAddress4 *dest, StunAddress4* mapAddr,
02423 int port, StunAddress4* srcAddr,
02424 bool_t verbose )
02425 {
02426
02427
02428
02429 unsigned int interfaceIp = 0;
02430 Socket myFd;
02431 char msg[STUN_MAX_MESSAGE_SIZE];
02432 int msgLen = sizeof(msg);
02433
02434 StunAtrString username;
02435 StunAtrString password;
02436
02437 StunAddress4 from;
02438 StunMessage resp;
02439 bool_t ok;
02440 StunAddress4 mappedAddr;
02441
02442 if ( port == 0 )
02443 {
02444 port = randomPort();
02445 }
02446
02447 if ( srcAddr )
02448 {
02449 interfaceIp = srcAddr->addr;
02450 }
02451
02452 myFd = openPort(port,interfaceIp,verbose);
02453 if (myFd == INVALID_SOCKET)
02454 {
02455 return myFd;
02456 }
02457
02458 username.sizeValue = 0;
02459 password.sizeValue = 0;
02460
02461 #ifdef USE_TLS
02462 stunGetUserNameAndPassword( dest, username, password );
02463 #endif
02464
02465 stunSendTest(myFd, dest, &username, &password, 1, 0 );
02466
02467 getMessage( myFd, msg, &msgLen, &from.addr, &from.port,verbose );
02468
02469 memset(&resp, 0, sizeof(StunMessage));
02470
02471 ok = stunParseMessage( msg, msgLen, &resp,verbose );
02472 if (!ok)
02473 {
02474 closesocket(myFd);
02475 return -1;
02476 }
02477
02478 mappedAddr = resp.mappedAddress.ipv4;
02479
02480
02481
02482
02483
02484
02485
02486
02487 *mapAddr = mappedAddr;
02488
02489 return myFd;
02490 }
02491
02492
02493 bool_t
02494 stunOpenSocketPair(StunAddress4 *dest,
02495 StunAddress4* mapAddr_rtp,
02496 StunAddress4* mapAddr_rtcp,
02497 int* fd1, int* fd2,
02498 int port, StunAddress4* srcAddr,
02499 bool_t verbose )
02500 {
02501
02502
02503
02504
02505 const int NUM=2;
02506 char msg[STUN_MAX_MESSAGE_SIZE];
02507 int msgLen =sizeof(msg);
02508
02509 StunAddress4 from;
02510 int fd[2];
02511 int i;
02512
02513 unsigned int interfaceIp = 0;
02514
02515 StunAtrString username;
02516 StunAtrString password;
02517
02518 StunAddress4 mappedAddr[2];
02519
02520 if ( port == 0 )
02521 {
02522 port = randomPort();
02523 }
02524
02525 *fd1=-1;
02526 *fd2=-1;
02527
02528 if ( srcAddr )
02529 {
02530 interfaceIp = srcAddr->addr;
02531 }
02532
02533 for( i=0; i<NUM; i++)
02534 {
02535 fd[i] = openPort( (port == 0) ? 0 : (port + i),
02536 interfaceIp, verbose);
02537 if (fd[i] < 0)
02538 {
02539 while (i > 0)
02540 {
02541 closesocket(fd[--i]);
02542 }
02543 return FALSE;
02544 }
02545 }
02546
02547 username.sizeValue = 0;
02548 password.sizeValue = 0;
02549
02550 #ifdef USE_TLS
02551 stunGetUserNameAndPassword( dest, username, password );
02552 #endif
02553
02554 for( i=0; i<NUM; i++)
02555 {
02556 stunSendTest(fd[i], dest, &username, &password, 1, verbose );
02557 }
02558
02559 for( i=0; i<NUM; i++)
02560 {
02561 StunMessage resp;
02562 bool_t ok;
02563 msgLen = sizeof(msg)/sizeof(*msg);
02564 getMessage( fd[i],
02565 msg,
02566 &msgLen,
02567 &from.addr,
02568 &from.port ,verbose);
02569
02570 memset(&resp, 0, sizeof(StunMessage));
02571
02572 ok = stunParseMessage( msg, msgLen, &resp, verbose );
02573 if (!ok)
02574 {
02575 for( i=0; i<NUM; i++)
02576 {
02577 closesocket(fd[i]);
02578 }
02579 return FALSE;
02580 }
02581
02582 mappedAddr[i] = resp.mappedAddress.ipv4;
02583 }
02584
02585 if (verbose)
02586 {
02587 ortp_message("stun: --- stunOpenSocketPair --- \n");
02588 for( i=0; i<NUM; i++)
02589 {
02590 ortp_message("stun: \t mappedAddr=%s\n", ipaddr(&mappedAddr[i]) );
02591 }
02592 }
02593
02594 #if 0
02595 if ( mappedAddr[0].port %2 == 0 )
02596 {
02597 if ( mappedAddr[0].port+1 == mappedAddr[1].port )
02598 {
02599 *mapAddr = mappedAddr[0];
02600 *fd1 = fd[0];
02601 *fd2 = fd[1];
02602 closesocket( fd[2] );
02603 return TRUE;
02604 }
02605 }
02606 else
02607 {
02608 if (( mappedAddr[1].port %2 == 0 )
02609 && ( mappedAddr[1].port+1 == mappedAddr[2].port ))
02610 {
02611 *mapAddr = mappedAddr[1];
02612 *fd1 = fd[1];
02613 *fd2 = fd[2];
02614 closesocket( fd[0] );
02615 return TRUE;
02616 }
02617 }
02618 #else
02619 *mapAddr_rtp = mappedAddr[0];
02620 *mapAddr_rtcp = mappedAddr[1];
02621 *fd1 = fd[0];
02622 *fd2 = fd[1];
02623 #endif
02624
02625
02626 for( i=0; i<NUM; i++)
02627 {
02628 closesocket( fd[i] );
02629 }
02630
02631 return TRUE;
02632 }
02633
02634
02635
02636
02637
02638
02639
02640
02641