CTEST(stunserver, Encode_decode) { StunMessage stunMsg; StunMessage stunResponse; StunMsgId stunId; uint8_t stunBuff[STUN_MAX_PACKET_SIZE]; stunlib_createId(&stunId); sockaddr_initFromString( (struct sockaddr*)&mappedAddr, "193.200.93.152:3478" ); CreateConnectivityBindingResp(&stunMsg, stunId, (struct sockaddr *)&mappedAddr, 1, 1, STUN_MSG_BindResponseMsg, 200, NULL); int len = stunlib_encodeMessage(&stunMsg, (uint8_t*)stunBuff, STUN_MAX_PACKET_SIZE, (unsigned char *) passwd, strlen(passwd), NULL); ASSERT_TRUE(len == 72); ASSERT_TRUE( stunlib_DecodeMessage(stunBuff, len, &stunResponse, NULL, NULL /*stdout for debug*/)); }
uint32_t StunClient_startSTUNTrace(STUN_CLIENT_DATA* clientData, void* userCtx, const struct sockaddr* serverAddr, const struct sockaddr* baseAddr, bool useRelay, const char* ufrag, const char* password, uint8_t ttl, StunMsgId transactionId, uint32_t sockhandle, STUN_SENDFUNC sendFunc, STUNCB stunCbFunc, DiscussData* discussData) /*NULL if * none*/ { StunBindReqStruct m; STUN_TRANSACTION_DATA trans; StunMessage stunMsg; uint8_t stunBuff[STUN_MAX_PACKET_SIZE]; uint32_t len; memset( &m, 0, sizeof(m) ); m.userCtx = userCtx; sockaddr_copy( (struct sockaddr*)&m.serverAddr, serverAddr ); sockaddr_copy( (struct sockaddr*)&m.baseAddr, baseAddr ); m.useRelay = useRelay; strncpy(m.ufrag, ufrag, sizeof(m.ufrag) - 1); strncpy(m.password, password, sizeof(m.password) - 1); m.ttl = ttl; m.transactionId = transactionId; m.sockhandle = sockhandle; m.sendFunc = sendFunc; m.discussData = discussData; m.addSoftware = false; /* callback and data (owned by caller) */ m.stunCbFunc = stunCbFunc; m.stuntrace = true; StoreStunBindReq(&trans, &m); BuildStunBindReq(&trans, &stunMsg); StunClientMain(clientData, STUNCLIENT_CTX_UNKNOWN, STUN_SIGNAL_BindReq, (uint8_t*)&m); len = stunlib_encodeMessage(&stunMsg, (uint8_t*)stunBuff, STUN_MAX_PACKET_SIZE, (unsigned char*)password, /* md5key */ password ? strlen(password) : 0, /* keyLen */ NULL); return len; }
END_TEST START_TEST (response_encode_IPv6) { StunMessage stunMsg; unsigned char stunBuf[120]; struct sockaddr_storage b; sockaddr_initFromString((struct sockaddr*)&b, "[2001:db8:1234:5678:11:2233:4455:6677]:32853"); memset(&stunMsg, 0, sizeof(StunMessage)); stunMsg.msgHdr.msgType = STUN_MSG_BindResponseMsg; /*id*/ memcpy(&stunMsg.msgHdr.id.octet,&idOctet,12); /*Server*/ stunMsg.hasSoftware = true; memcpy( stunMsg.software.value, software, strlen(software)); stunMsg.software.sizeValue = strlen(software); /*Mapped Address*/ stunMsg.hasXorMappedAddress = true; stunlib_setIP6Address(&stunMsg.xorMappedAddress, ((struct sockaddr_in6 *)&b)->sin6_addr.s6_addr, port); fail_unless( stunlib_addSoftware(&stunMsg, software_resp, '\x20') ); fail_unless( stunlib_encodeMessage(&stunMsg, stunBuf, 96, (unsigned char*)password, strlen(password), NULL)); fail_unless( memcmp(stunBuf, respv6, 92) == 0 ); }
static bool SendConnectivityBindResponse(STUN_CLIENT_DATA* clientData, int32_t globalSocketId, StunMessage* stunRespMsg, const char* password, const struct sockaddr* dstAddr, void* userData, STUN_SENDFUNC sendFunc, int proto, bool useRelay) { uint8_t stunBuff[STUN_MAX_PACKET_SIZE]; int stunLen; (void) userData; /* encode bind Response */ stunLen = stunlib_encodeMessage(stunRespMsg, (uint8_t*)stunBuff, STUN_MAX_PACKET_SIZE, (unsigned char*)password, /* md5key **/ password ? strlen(password) : 0, /* keyLen **/ NULL); if (!stunLen) { StunPrint(clientData->logUserData, clientData->Log_cb, StunInfoCategory_Error, "<STUNCLIENT> Failed to encode Binding request response\n"); return false; } /* send */ /* sendFunc(globalSocketId, stunBuff, stunLen, dstAddr, useRelay, 0); */ sendFunc(clientData->userCtx, globalSocketId, stunBuff, stunLen, dstAddr, proto, useRelay, 0); clientData->stats.BindRespSent++; return true; }
END_TEST START_TEST( error_encode_decode ) { StunMessage stunMsg; unsigned char stunBuf[STUN_MAX_PACKET_SIZE]; const char *testStr[MAX_STRING_TEST] = {"a", "ab", "acb", "abcd", "abcde" }; int i; for (i=0; i < MAX_STRING_TEST; i++) { int encLen; memset(&stunMsg, 0, sizeof(StunMessage)); stunMsg.msgHdr.msgType = STUN_MSG_AllocateRequestMsg; memcpy(&stunMsg.msgHdr.id.octet,&idOctet,12); stunlib_addError(&stunMsg, testStr[i], 400+i, ' '); encLen = stunlib_encodeMessage(&stunMsg, stunBuf, STUN_MAX_PACKET_SIZE, (unsigned char*)password, strlen(password), NULL); fail_unless( stunlib_DecodeMessage(stunBuf, encLen, &stunMsg, NULL, NULL)); fail_unless( stunlib_checkIntegrity(stunBuf, encLen, &stunMsg, password, sizeof(password)) ); fail_unless( (stunMsg.errorCode.errorClass == 4) && (stunMsg.errorCode.number == i) && (stunMsg.errorCode.reserved == 0) && (strncmp(stunMsg.errorCode.reason, testStr[i], strlen(testStr[i])) == 0) ); } }
END_TEST START_TEST (response_encode) { StunMessage stunMsg; unsigned char stunBuf[120]; memset(&stunMsg, 0, sizeof(StunMessage)); stunMsg.msgHdr.msgType = STUN_MSG_BindResponseMsg; /*id*/ memcpy(&stunMsg.msgHdr.id.octet,&idOctet,12); /*Server*/ stunMsg.hasSoftware = true; memcpy( stunMsg.software.value, software_resp, strlen(software_resp)); stunMsg.software.sizeValue = strlen(software_resp); /*Mapped Address*/ stunMsg.hasXorMappedAddress = true; stunMsg.xorMappedAddress.familyType = STUN_ADDR_IPv4Family; stunMsg.xorMappedAddress.addr.v4.addr = xorMapped; stunMsg.xorMappedAddress.addr.v4.port = port; fail_unless( stunlib_addSoftware(&stunMsg, software_resp, '\x20') ); fail_unless( stunlib_encodeMessage(&stunMsg, stunBuf, 80, (unsigned char*)password, strlen(password), NULL)); fail_unless( memcmp(stunBuf, respv4, 80)==0 ); }
END_TEST START_TEST (string_realm_encode_decode) { uint8_t stunBuf[STUN_MAX_PACKET_SIZE]; const char *testStr[MAX_STRING_TEST] = {"a", "ab", "acb", "abcd", "abcde" }; StunMessage stunMsg; int i; for (i=0; i < MAX_STRING_TEST; i++) { int encLen; memset(&stunMsg, 0, sizeof(StunMessage)); stunMsg.msgHdr.msgType = STUN_MSG_AllocateRequestMsg; /*id*/ memcpy(&stunMsg.msgHdr.id.octet,&idOctet,12); stunlib_addRealm(&stunMsg, testStr[i], STUN_DFLT_PAD); encLen = stunlib_encodeMessage(&stunMsg, stunBuf, sizeof(stunBuf), (unsigned char*)password, strlen(password), NULL); fail_unless( stunlib_DecodeMessage(stunBuf, encLen, &stunMsg, NULL, NULL) ); fail_unless( stunlib_checkIntegrity(stunBuf, encLen, &stunMsg, password, sizeof(password)) ); fail_unless(stunMsg.realm.sizeValue == strlen(testStr[i])); fail_unless(strcmp(stunMsg.realm.value, testStr[i]) == 0); } }
END_TEST START_TEST( channel_encode_decode ) { StunMessage stunMsg; unsigned char stunBuf[STUN_MAX_PACKET_SIZE]; uint16_t chan; for (chan = STUN_MIN_CHANNEL_ID; chan <= STUN_MAX_CHANNEL_ID; chan += 0x100) { memset(&stunMsg, 0, sizeof(StunMessage)); stunMsg.msgHdr.msgType = STUN_MSG_AllocateRequestMsg; /*id*/ memcpy(&stunMsg.msgHdr.id.octet,&idOctet,12); stunlib_addChannelNumber(&stunMsg, chan); stunlib_encodeMessage(&stunMsg, stunBuf, sizeof(stunBuf), (unsigned char*)password, strlen(password), NULL); fail_unless( stunlib_DecodeMessage(stunBuf, sizeof(stunBuf), &stunMsg, NULL, NULL) ); fail_unless( stunlib_checkIntegrity(stunBuf, sizeof(stunBuf), &stunMsg, password, sizeof(password)) ); fail_unless(( stunMsg.channelNumber.channelNumber == chan) && (stunMsg.channelNumber.rffu == 0)); } }
END_TEST START_TEST (transport_encode_decode) { StunMessage stunMsg; unsigned char stunBuf[STUN_MAX_PACKET_SIZE]; memset(&stunMsg, 0, sizeof(StunMessage)); stunMsg.msgHdr.msgType = STUN_MSG_AllocateRequestMsg; memcpy(&stunMsg.msgHdr.id.octet,&idOctet,12); stunlib_addRequestedTransport(&stunMsg, STUN_REQ_TRANSPORT_UDP); stunlib_encodeMessage(&stunMsg, stunBuf, sizeof(stunBuf), (unsigned char*)password, strlen(password), NULL); fail_unless( stunlib_DecodeMessage(stunBuf, sizeof(stunBuf), &stunMsg, NULL, NULL)); fail_unless( stunlib_checkIntegrity(stunBuf, sizeof(stunBuf), &stunMsg, password, sizeof(password)) ); fail_unless(( stunMsg.requestedTransport.protocol == STUN_REQ_TRANSPORT_UDP) && (stunMsg.requestedTransport.rffu[0] == 0) && (stunMsg.requestedTransport.rffu[1] == 0) && (stunMsg.requestedTransport.rffu[2] == 0) ); }
END_TEST START_TEST (request_encode) { StunMessage stunMsg; unsigned char stunBuf[120]; memset(&stunMsg, 0, sizeof(StunMessage)); stunMsg.msgHdr.msgType = STUN_MSG_BindRequestMsg; memcpy(&stunMsg.msgHdr.id.octet,&idOctet,12); fail_unless( stunlib_addUserName(&stunMsg, username, '\x20') ); fail_unless( stunlib_addSoftware(&stunMsg, software, '\x20') ); stunMsg.hasPriority = true; stunMsg.priority.value = priority; stunMsg.hasControlled = true; stunMsg.controlled.value = tieBreaker; fail_unless( stunlib_encodeMessage(&stunMsg, stunBuf, 120, (unsigned char*)password, strlen(password), NULL)); fail_unless( memcmp(stunBuf, req, 108 ) == 0 ); }
END_TEST START_TEST (discuss_encode_decode) { StunMessage stunMsg; unsigned char stunBuf[STUN_MAX_PACKET_SIZE]; DiscussData discussData; discussData.streamType=0x004; discussData.interactivity=0x01; discussData.networkStatus_flags = 0; discussData.networkStatus_nodeCnt = 0; discussData.networkStatus_tbd = 0; discussData.networkStatus_upMaxBandwidth = 0; discussData.networkStatus_downMaxBandwidth = 0; memset(&stunMsg, 0, sizeof(StunMessage)); stunMsg.msgHdr.msgType = STUN_MSG_AllocateRequestMsg; memcpy(&stunMsg.msgHdr.id.octet,&idOctet,12); stunMsg.hasStreamType = true; stunMsg.streamType.type = discussData.streamType; stunMsg.streamType.interactivity = discussData.interactivity; stunMsg.hasNetworkStatus = true; stunMsg.networkStatus.flags = 0; stunMsg.networkStatus.nodeCnt = 0; stunMsg.networkStatus.upMaxBandwidth = 0; stunMsg.networkStatus.downMaxBandwidth = 0; stunMsg.hasNetworkStatusResp = true; stunMsg.networkStatusResp.flags = discussData.networkStatusResp_flags; stunMsg.networkStatusResp.nodeCnt = discussData.networkStatusResp_nodeCnt; stunMsg.networkStatusResp.upMaxBandwidth = discussData.networkStatusResp_upMaxBandwidth; stunMsg.networkStatusResp.downMaxBandwidth = discussData.networkStatusResp_downMaxBandwidth; stunlib_encodeMessage(&stunMsg, stunBuf, sizeof(stunBuf), (unsigned char*)password, strlen(password), NULL); fail_unless( stunlib_DecodeMessage(stunBuf, sizeof(stunBuf), &stunMsg, NULL, NULL)); fail_unless( stunlib_checkIntegrity(stunBuf, sizeof(stunBuf), &stunMsg, password, sizeof(password)) ); fail_unless( stunMsg.streamType.type == discussData.streamType); fail_unless( stunMsg.streamType.interactivity == discussData.interactivity); fail_unless( stunMsg.networkStatusResp.flags == discussData.networkStatusResp_flags); fail_unless( stunMsg.networkStatusResp.nodeCnt == discussData.networkStatusResp_nodeCnt); fail_unless( stunMsg.networkStatusResp.upMaxBandwidth == discussData.networkStatusResp_upMaxBandwidth); fail_unless( stunMsg.networkStatusResp.downMaxBandwidth == discussData.networkStatusResp_downMaxBandwidth); }
END_TEST START_TEST( xor_encode_decode ) { StunMessage stunMsg; unsigned char stunBuf[STUN_MAX_PACKET_SIZE]; int encLen; uint8_t ip6Addr[] = {0x20, 0x1, 0x4, 0x70, 0xdc, 0x88, 0x0, 0x2, 0x2, 0x26, 0x18, 0xff, 0xfe, 0x92, 0x6d, 0x53}; memset(&stunMsg, 0, sizeof(StunMessage)); stunMsg.msgHdr.msgType = STUN_MSG_AllocateRequestMsg; memcpy(&stunMsg.msgHdr.id.octet,&idOctet,12); /* ip4 test */ stunlib_setIP4Address(&stunMsg.xorMappedAddress, 0x12345678, 4355); stunMsg.hasXorMappedAddress = true; encLen = stunlib_encodeMessage(&stunMsg, stunBuf, sizeof(stunBuf), (unsigned char*)password, strlen(password), NULL); fail_unless( stunlib_DecodeMessage(stunBuf, encLen, &stunMsg, NULL, NULL) ); fail_unless( stunlib_checkIntegrity(stunBuf, encLen, &stunMsg, password, sizeof(password)) ); fail_unless( (stunMsg.xorMappedAddress.familyType == STUN_ADDR_IPv4Family) && (stunMsg.xorMappedAddress.addr.v4.port == 4355) && (stunMsg.xorMappedAddress.addr.v4.addr == 0x12345678)); /* ip6 */ stunlib_setIP6Address(&stunMsg.xorMappedAddress, ip6Addr, 4685); memcpy(stunMsg.xorMappedAddress.addr.v6.addr, ip6Addr, sizeof(ip6Addr)); stunMsg.hasXorMappedAddress = true; encLen = stunlib_encodeMessage(&stunMsg, stunBuf, sizeof(stunBuf), (unsigned char*)password, strlen(password), NULL); fail_unless( stunlib_DecodeMessage(stunBuf, encLen, &stunMsg, NULL, NULL)); fail_unless( stunlib_checkIntegrity(stunBuf, encLen, &stunMsg, password, sizeof(password)) ); fail_unless( (stunMsg.xorMappedAddress.familyType == STUN_ADDR_IPv6Family) && (stunMsg.xorMappedAddress.addr.v6.port == 4685) && (memcmp(stunMsg.xorMappedAddress.addr.v6.addr, ip6Addr, sizeof(ip6Addr)) == 0)); }
ICELIB_Result sendConnectivityResp(void* pUserData, uint32_t userValue1, uint32_t userValue2, uint32_t componentId, int sockfd, int proto, const struct sockaddr* source, const struct sockaddr* destination, const struct sockaddr* MappedAddress, uint16_t errorResponse, StunMsgId transactionId, bool useRelay, const char* pPasswd) { (void)userValue1; (void)userValue2; (void)componentId; (void)source; (void)destination; StunMessage stunMsg; CreateConnectivityBindingResp(&stunMsg, transactionId, MappedAddress, 0, 0, 0, 0, 0, 0, (errorResponse == 200) ? STUN_MSG_BindResponseMsg : STUN_MSG_BindErrorResponseMsg, errorResponse); /* encode */ uint8_t stunBuff[STUN_MAX_PACKET_SIZE]; int stunLen = stunlib_encodeMessage(&stunMsg, (uint8_t*)stunBuff, STUN_MAX_PACKET_SIZE, (unsigned char*)pPasswd, /* md5key **/ pPasswd ? strlen(pPasswd) : 0, /* * keyLen **/ NULL); if (!stunLen) { printf("Failed to encode STUN msg\n"); exit(1); } sendPacket(pUserData, sockfd, stunBuff, stunLen, destination, proto, useRelay, 0); return 0; }
/* encode and send */ static bool SendStunReq(STUN_TRANSACTION_DATA* trans, StunMessage* stunReqMsg) { STUN_CLIENT_DATA* client = trans->client; /* encode the BindReq */ if (strlen(trans->stunBindReq.password) > 0) { trans->stunReqMsgBufLen = stunlib_encodeMessage(stunReqMsg, (unsigned char*) (trans-> stunReqMsgBuf), STUN_MAX_PACKET_SIZE, (unsigned char*)&trans->stunBindReq.password, /* key */ strlen(trans->stunBindReq. password), /* keyLen * */ NULL); } else { trans->stunReqMsgBufLen = stunlib_encodeMessage(stunReqMsg, (unsigned char*) (trans-> stunReqMsgBuf), STUN_MAX_PACKET_SIZE, NULL, /* key */ 0, /* keyLen */ NULL); } if (!trans->stunReqMsgBufLen) { StunPrint(client->logUserData, client->Log_cb, StunInfoCategory_Error, "<STUNCLIENT:%02d> SendStunReq(BindReq), failed encode", trans->inst); return false; } /*Store Time so we can messure RTT */ gettimeofday(&trans->start[trans->retransmits], NULL); if (trans->stunBindReq.sendFunc != NULL) { trans->stunBindReq.sendFunc(trans->client->userCtx, trans->stunBindReq.sockhandle, trans->stunReqMsgBuf, trans->stunReqMsgBufLen, (struct sockaddr*)&trans->stunBindReq.serverAddr, trans->stunBindReq.proto, trans->stunBindReq.useRelay, trans->stunBindReq.ttl); } trans->stats.BindReqSent++; return true; }