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