diff --git a/include/stun_intern.h b/include/stun_intern.h index cc533ca..9264769 100644 --- a/include/stun_intern.h +++ b/include/stun_intern.h @@ -97,15 +97,15 @@ struct StunClientStats typedef struct { - STUN_STATE state; - bool inUse; - uint32_t inst; + STUN_STATE state; + bool inUse; + uint32_t inst; StunBindReqStruct stunBindReq; uint8_t stunReqMsgBuf[STUN_MAX_PACKET_SIZE]; /* encoded STUN request * */ - int stunReqMsgBufLen; /* of encoded STUN - *request */ + int stunReqMsgBufLen; /* of encoded STUN + * request */ STUN_USER_CREDENTIALS userCredentials; bool authenticated; @@ -130,14 +130,14 @@ typedef struct DiscussData discussData; struct StunClientStats stats; - STUN_CLIENT_DATA* client; + STUN_CLIENT_DATA* client; } STUN_TRANSACTION_DATA; struct STUN_CLIENT_DATA { - void* userCtx; + void* userCtx; STUN_TRANSACTION_DATA data [MAX_STUN_TRANSACTIONS]; @@ -145,7 +145,7 @@ struct STUN_CLIENT_DATA STUN_INFO_FUNC_PTR Log_cb; void* logUserData; struct StunClientStats stats; - struct hiutResult traceResult; + struct hiutResult traceResult; }; diff --git a/include/stunclient.h b/include/stunclient.h index 696e3fe..2ed0be5 100644 --- a/include/stunclient.h +++ b/include/stunclient.h @@ -138,7 +138,7 @@ StunClient_RegisterLogger(STUN_CLIENT_DATA* clientData, * serverAddr - Address of TURN server in format "a.b.c.d:port" * baseAddr - Address of BASE in format "a.b.c.d:port" * proto - Optional context passed to sendFunc. eg. - *IPPROTO_UDP/TCP. + * IPPROTO_UDP/TCP. * useRelay - True to send via TURN server * uFrag - Combination of local and remote ufrag exchanged in * INVITE(LFRAG) / OK(RFRAG) in format : @@ -179,23 +179,7 @@ StunClient_startBindTransaction(STUN_CLIENT_DATA* clientData, uint32_t sockhandle, STUN_SENDFUNC sendFunc, STUNCB stunCbFunc, - DiscussData* discussData); /* - * - *nullptr - * - *if - * - *no - * - *malicedata - * - *should - * - *be - * - *sent. - **/ - + DiscussData* discussData); uint32_t StunClient_startSTUNTrace(STUN_CLIENT_DATA* clientData, void* userCtx, @@ -209,11 +193,7 @@ StunClient_startSTUNTrace(STUN_CLIENT_DATA* clientData, uint32_t sockhandle, STUN_SENDFUNC sendFunc, STUNCB stunCbFunc, - DiscussData* discussData); /*NULL - * if - * - *none*/ - + DiscussData* discussData); /* * This function must be called by the application every N msec. N must be same * as in StunClientBind_Init(instances, N) @@ -279,6 +259,13 @@ StunClient_dumpStats(STUN_CLIENT_DATA* clientData, STUN_INFO_FUNC_PTR logPtr, void* userData); +void +StunPrint(void* userData, + STUN_INFO_FUNC_PTR Log_cb, + StunInfoCategory_T category, + const char* fmt, + ...); + #ifdef __cplusplus } diff --git a/include/stuntrace.h b/include/stuntrace.h index 8f81007..366a941 100644 --- a/include/stuntrace.h +++ b/include/stuntrace.h @@ -1,6 +1,6 @@ #pragma once -#define MAX_TTL 64 +#define MAX_TTL 40 #define MAX_CONCECUTIVE_INACTIVE 4 #define STUNTRACE_MAX_RETRANSMITS 3 @@ -49,12 +49,12 @@ struct hiutResult { STUN_SENDFUNC sendFunc; - int32_t currentTTL; + int32_t currentTTL; StunMsgId currStunMsgId; - int32_t user_start_ttl; - int32_t user_max_ttl; - int32_t user_paralell_traces; - int32_t path_max_ttl; /*got port unreachable or STUN response + int32_t user_start_ttl; + int32_t user_max_ttl; + int32_t user_paralell_traces; + int32_t path_max_ttl; /*got port unreachable or STUN response **/ uint32_t wait_ms; struct sockaddr_storage localAddr; @@ -63,8 +63,9 @@ struct hiutResult { /* Initial Length of first STUN packet (TTL=1) */ uint32_t stunLen; - struct hiutPathElement pathElement[MAX_TTL]; - //struct hiutTTLinfo ttlInfo[MAX_TTL]; + struct hiutPathElement pathElement[MAX_TTL + 1]; + bool remoteAlive; + /* struct hiutTTLinfo ttlInfo[MAX_TTL]; */ /* struct npa_trace trace; */ /* Recurring traces*/ diff --git a/src/stunclient.c b/src/stunclient.c index cd52682..fab7a7c 100644 --- a/src/stunclient.c +++ b/src/stunclient.c @@ -54,12 +54,6 @@ StunClientMain(STUN_CLIENT_DATA* clientData, int ctx, STUN_SIGNAL sig, uint8_t* payload); -static void -StunPrint(void* userData, - STUN_INFO_FUNC_PTR Log_cb, - StunInfoCategory_T category, - const char* fmt, - ...); static void StunClientFsm(STUN_TRANSACTION_DATA* trans, @@ -99,7 +93,7 @@ TimerHasExpired(STUN_TRANSACTION_DATA* trans, * If the application has defined a callback function to handle the output * then this is called with the string and the severity. */ -static void +void StunPrint(void* userData, STUN_INFO_FUNC_PTR Log_cb, StunInfoCategory_T category, @@ -150,7 +144,7 @@ TransIdIsEqual(const StunMsgId* a, static void StoreStunBindReq(STUN_TRANSACTION_DATA* trans, - StunBindReqStruct* pMsgIn) + StunBindReqStruct* pMsgIn) { /* copy whole msg */ memcpy( &trans->stunBindReq, pMsgIn, sizeof(StunBindReqStruct) ); @@ -255,7 +249,7 @@ StunClient_Alloc(STUN_CLIENT_DATA** clientDataPtr) if (!clientDataPtr) { - return false; + return false; } clientData = malloc(sizeof *clientData); @@ -351,7 +345,7 @@ StunClient_startBindTransaction(STUN_CLIENT_DATA* clientData, if (clientData == NULL) { - return STUNCLIENT_CTX_UNKNOWN; + return STUNCLIENT_CTX_UNKNOWN; } memset( &m, 0, sizeof(m) ); @@ -398,7 +392,7 @@ StunClient_startSTUNTrace(STUN_CLIENT_DATA* clientData, * none*/ { - StunBindReqStruct m; + StunBindReqStruct m; STUN_TRANSACTION_DATA trans; StunMessage stunMsg; uint8_t stunBuff[STUN_MAX_PACKET_SIZE]; @@ -431,7 +425,6 @@ StunClient_startSTUNTrace(STUN_CLIENT_DATA* clientData, StoreStunBindReq(&trans, &m); BuildStunBindReq(&trans, &stunMsg); - StunClientMain(clientData, STUNCLIENT_CTX_UNKNOWN, STUN_SIGNAL_BindReq, (uint8_t*)&m); len = stunlib_encodeMessage(&stunMsg, @@ -486,33 +479,44 @@ StunClient_HandleICMP(STUN_CLIENT_DATA* clientData, return; } /* Todo: Test if this is fr me.. */ - (void)srcAddr; + StunPrint(clientData->logUserData, + clientData->Log_cb, + StunInfoCategory_Trace, + " StunClient_HandleICMP: Got ICMP type: %i\n ", ICMPtype); - for (int i = 0; i < MAX_STUN_TRANSACTIONS; i++) + if ( ( (ICMPtype == 11 || ICMPtype == 3) && (srcAddr->sa_family == AF_INET) ) || + ( (ICMPtype == 3 || ICMPtype == 1) && (srcAddr->sa_family == AF_INET6) ) ) { - STUN_TRANSACTION_DATA* trans = &clientData->data[i]; - if ( trans->inUse && - TransIdIsEqual(&clientData->traceResult.currStunMsgId, - &trans->stunBindReq.transactionId) ) + for (int i = 0; i < MAX_STUN_TRANSACTIONS; i++) { - StunRespStruct m; - gettimeofday(&trans->stop[trans->retransmits], NULL); - /* memcpy(&m.stunRespMessage, msg, sizeof(m.stunRespMessage)); */ - sockaddr_copy( (struct sockaddr*)&m.srcAddr, srcAddr ); - m.ICMPtype = ICMPtype; - m.ttl = clientData->traceResult.currentTTL; - StunClientMain(clientData, i, STUN_SIGNAL_ICMPResp, (void*)&m); - return; + STUN_TRANSACTION_DATA* trans = &clientData->data[i]; + if ( trans->inUse && + TransIdIsEqual(&clientData->traceResult.currStunMsgId, + &trans->stunBindReq.transactionId) ) + { + StunRespStruct m; + gettimeofday(&trans->stop[trans->retransmits], NULL); + /* memcpy(&m.stunRespMessage, msg, sizeof(m.stunRespMessage)); */ + sockaddr_copy( (struct sockaddr*)&m.srcAddr, srcAddr ); + m.ICMPtype = ICMPtype; + m.ttl = clientData->traceResult.currentTTL; + StunClientMain(clientData, i, STUN_SIGNAL_ICMPResp, (void*)&m); + return; + } } - } + StunPrint(clientData->logUserData, + clientData->Log_cb, + StunInfoCategory_Trace, + " no instance with transId, discarding, ICMP message\n "); + }else{ StunPrint(clientData->logUserData, clientData->Log_cb, StunInfoCategory_Trace, - " no instance with transId, discarding, ICMP message\n "); + " StunClient_HandleICMP: Ignoring ICMP Type, nothing to do\n ", ICMPtype); + } } - /* * Cancel a transaction with matching transaction id * transactionId - Transaction id. @@ -1144,7 +1148,7 @@ RetransmitLastReq(STUN_TRANSACTION_DATA* trans, trans->stunReqMsgBuf, trans->stunReqMsgBufLen, (struct sockaddr*)destAddr, - trans->stunBindReq.proto, + trans->stunBindReq.proto, trans->stunBindReq.useRelay, trans->stunBindReq.ttl); } @@ -1424,7 +1428,7 @@ StunState_Idle(STUN_TRANSACTION_DATA* trans, case STUN_SIGNAL_BindReq: { StunBindReqStruct* pMsgIn = (StunBindReqStruct*)payload; - StunMessage stunReqMsg; /* decoded */ + StunMessage stunReqMsg; /* decoded */ /* clear instance data */ InitInstData(trans); /* store msg */ diff --git a/src/stuntrace.c b/src/stuntrace.c index 19378bc..adfb772 100644 --- a/src/stuntrace.c +++ b/src/stuntrace.c @@ -12,6 +12,29 @@ void StunStatusCallBack(void* userCtx, StunCallBackData_T* stunCbData); +static bool +isDstUnreachable(int32_t ICMPtype, + u_int16_t addrFamily) +{ + if ( ( (ICMPtype == 3) && (addrFamily == AF_INET) ) || + ( (ICMPtype == 1) && (addrFamily == AF_INET6) ) ) + { + return true; + } + return false; +} + +static bool +isTimeExceeded(int32_t ICMPtype, + u_int16_t addrFamily) +{ + if ( ( (ICMPtype == 11) && (addrFamily == AF_INET) ) || + ( (ICMPtype == 3) && (addrFamily == AF_INET6) ) ) + { + return true; + } + return false; +} void @@ -96,12 +119,11 @@ handleStunNoAnswer(struct hiutResult* result) { result->pathElement[result->currentTTL].inactive = true; /* Hov many no answer in a row? */ - if (numConcecutiveInactiveNodes(result) >= MAX_CONCECUTIVE_INACTIVE) + if (numConcecutiveInactiveNodes(result) >= MAX_CONCECUTIVE_INACTIVE && + !result->remoteAlive) { bool done = result->num_traces < result->max_recuring ? false : true; - - result->path_max_ttl = result->currentTTL-MAX_CONCECUTIVE_INACTIVE; - + result->path_max_ttl = result->currentTTL - MAX_CONCECUTIVE_INACTIVE; sendCallback(result, NULL, result->currentTTL, @@ -111,7 +133,6 @@ handleStunNoAnswer(struct hiutResult* result) done); resartIfNotDone(result); return; - } sendCallback(result, @@ -122,18 +143,13 @@ handleStunNoAnswer(struct hiutResult* result) false, false); - if ( (result->currentTTL < result->user_max_ttl) && - (result->currentTTL < result->path_max_ttl) ) + if ( result->currentTTL < result->user_max_ttl ) { - // - //result->pathElement[result->currentTTL].inactive = true; - while (result->pathElement[result->currentTTL].inactive && result->currentTTL < result->path_max_ttl) { result->currentTTL++; } - stunlib_createId(&result->currStunMsgId, rand(), result->currentTTL); StunClient_startSTUNTrace( (STUN_CLIENT_DATA*)result->stunCtx, @@ -167,17 +183,34 @@ handleStunRespIcmp(struct hiutResult* result, int rtt, int retransmits) { - if (ttl >= result->user_max_ttl) + STUN_CLIENT_DATA* clientData = (STUN_CLIENT_DATA*) result->stunCtx; + + if ( (ttl == MAX_TTL) && + isDstUnreachable(ICMPtype, srcAddr->sa_family) ) { - /* - * stopAndExit(result); - */ - /* Do callback to user here.. */ - } + /* Part of far end alive test */ + result->remoteAlive = true; + result->currentTTL = 1; - /* printf("Type: %i\n", ICMPtype); */ - if ( ( (ICMPtype == 11) && (srcAddr->sa_family == AF_INET) ) || - ( (ICMPtype == 3) && (srcAddr->sa_family == AF_INET6) ) ) + stunlib_createId(&result->currStunMsgId, + rand(), result->currentTTL); + + StunClient_startSTUNTrace( (STUN_CLIENT_DATA*)result->stunCtx, + result, + (struct sockaddr*)&result->remoteAddr, + (struct sockaddr*)&result->localAddr, + false, + result->username, + result->password, + result->currentTTL, + result->currStunMsgId, + result->sockfd, + result->sendFunc, + StunStatusCallBack, + NULL ); + return; + } + if ( isTimeExceeded(ICMPtype, srcAddr->sa_family) ) { if (result->currentTTL < result->user_max_ttl) { @@ -187,7 +220,6 @@ handleStunRespIcmp(struct hiutResult* result, { result->currentTTL++; } - if (result->currentTTL <= result->path_max_ttl) { sendCallback(result, @@ -214,7 +246,9 @@ handleStunRespIcmp(struct hiutResult* result, result->sendFunc, StunStatusCallBack, NULL ); - }else{ + } + else + { bool done = result->num_traces < result->max_recuring ? false : true; sendCallback(result, srcAddr, @@ -225,13 +259,14 @@ handleStunRespIcmp(struct hiutResult* result, done); resartIfNotDone(result); } - }else{ - //do nothing + } + else + { + /* do nothing */ } } - else if ( (ICMPtype == 3) && (srcAddr->sa_family == AF_INET) ) + else if ( isDstUnreachable(ICMPtype,srcAddr->sa_family) ) { - /*Got port unreachable. We can stop now*/ bool done = result->num_traces < result->max_recuring ? false : true; if (result->path_max_ttl >= ttl) @@ -246,21 +281,17 @@ handleStunRespIcmp(struct hiutResult* result, true, done); - /* cancel any outstanding transactions */ - for (int i = ttl + 1; i <= result->currentTTL; i++) - { - printf("Canceling transaction (%i)\n", i); - StunClient_cancelBindingTransaction( (STUN_CLIENT_DATA*)result->stunCtx, - result->currStunMsgId ); - } resartIfNotDone(result); - - } } else { - printf(" Some sort of ICMP message. Ignoring\n"); + StunPrint(clientData->logUserData, + clientData->Log_cb, + StunInfoCategory_Trace, + " handleStunRespIcmp: Ignoring ICMP type: %i\n ", + ICMPtype); + } } @@ -274,41 +305,15 @@ handleStunRespSucsessfull(struct hiutResult* result, { /* char addr[SOCKADDR_MAX_STRLEN]; */ (void) rflxAddr; - (void) rtt; - (void) ttl; - (void)retransmits; - /* TODO do callback here */ - /* - * printResultLine(out_format, - * true, - * ttl, - * srcAddr, - * rtt, - * retransmits); - */ - /* printf(" RFLX addr: '%s'\n", */ - /* sockaddr_toString(rflxAddr, */ - /* addr, */ - /* sizeof(addr), */ - /* true)); */ - - /*Got STUN response. We can stop now*/ - if ( sockaddr_sameAddr( (struct sockaddr*)&result->remoteAddr,srcAddr ) ) - { - /* TODO do callback here */ - /* - * stopAndExit(0); - */ - } - if (result->currentTTL < result->user_max_ttl) + if (ttl == MAX_TTL) { - while (result->pathElement[result->currentTTL].inactive && - result->currentTTL < result->path_max_ttl) - { - result->currentTTL++; - } + /* Part of far end alive test */ + result->remoteAlive = true; + result->currentTTL = 1; + stunlib_createId(&result->currStunMsgId, rand(), result->currentTTL); + StunClient_startSTUNTrace( (STUN_CLIENT_DATA*)result->stunCtx, result, (struct sockaddr*)&result->remoteAddr, @@ -322,8 +327,27 @@ handleStunRespSucsessfull(struct hiutResult* result, result->sendFunc, StunStatusCallBack, NULL ); + return; } + bool done = result->num_traces < result->max_recuring ? false : true; + if ( sockaddr_sameAddr( (struct sockaddr*)&result->remoteAddr,srcAddr ) ) + { + if (result->path_max_ttl >= ttl) + { + result->path_max_ttl = ttl; + sendCallback(result, + srcAddr, + ttl, + rtt, + retransmits, + true, + done); + + resartIfNotDone(result); + return; + } + } } @@ -332,7 +356,6 @@ void StunStatusCallBack(void* userCtx, StunCallBackData_T* stunCbData) { - /* char addr[SOCKADDR_MAX_STRLEN]; */ struct hiutResult* result = (struct hiutResult*)userCtx; if (result->pathElement[stunCbData->ttl].gotAnswer) @@ -364,13 +387,10 @@ StunStatusCallBack(void* userCtx, handleStunNoAnswer( (struct hiutResult*)userCtx ); break; default: - printf("Should not happen (Probably a cancel OK)\n"); + return; } } - - - int StunTrace_startTrace(STUN_CLIENT_DATA* clientData, void* userCtx, @@ -388,7 +408,7 @@ StunTrace_startTrace(STUN_CLIENT_DATA* clientData, result = &clientData->traceResult; - result->currentTTL = 1; + result->currentTTL = MAX_TTL; result->userCtx = userCtx; stunlib_createId(&result->currStunMsgId, rand(), 1); result->stunCtx = clientData; diff --git a/test/stuntrace_test.c b/test/stuntrace_test.c index d7ab149..ec04ca1 100644 --- a/test/stuntrace_test.c +++ b/test/stuntrace_test.c @@ -12,9 +12,13 @@ static StunMsgId LastTransId; static struct sockaddr_storage LastAddress; static struct sockaddr_storage LastHopAddr; static int LastTTL; +static StunMsgId LastTransId; static bool Done; static bool EndOfTrace; +static const uint8_t StunCookie[] = STUN_MAGIC_COOKIE_ARRAY; +const uint64_t test_addr_ipv4 = 1009527574; /* "60.44.43.22"); */ +const uint32_t test_port_ipv4 = 43000; static void sendPacket(void* ctx, @@ -33,7 +37,7 @@ sendPacket(void* ctx, (void) useRelay; char addr_str[SOCKADDR_MAX_STRLEN]; /* find the transaction id so we can use this in the simulated resp */ - + memcpy(&LastTransId, &buf[8], STUN_MSG_ID_SIZE); memcpy(&LastTransId, &buf[8], STUN_MSG_ID_SIZE); sockaddr_copy( (struct sockaddr*)&LastAddress, addr ); @@ -89,17 +93,24 @@ CTEST(stuntrace, run_IPv4) 1, StunTraceCallBack, sendPacket); - ASSERT_TRUE(len == 68); - ASSERT_TRUE(LastTTL == 1); + /* First alive probe */ + ASSERT_TRUE(len == 224); + ASSERT_TRUE(LastTTL == 40); + + StunClient_HandleICMP(clientData, + (struct sockaddr*)&remoteAddr, + 3); + ASSERT_FALSE(Done); + ASSERT_FALSE(EndOfTrace); + + /* First hop.. */ + ASSERT_TRUE(LastTTL == 1); sockaddr_initFromString( (struct sockaddr*)&hop1Addr, "192.168.1.1:45674" ); StunClient_HandleICMP(clientData, (struct sockaddr*)&hop1Addr, 11); - ASSERT_FALSE(Done); - ASSERT_FALSE(EndOfTrace); - ASSERT_TRUE( sockaddr_alike( (struct sockaddr*)&LastHopAddr, (struct sockaddr*)&hop1Addr ) ); @@ -145,8 +156,12 @@ CTEST(stuntrace, recurring_IPv4) 2, StunTraceCallBack, sendPacket); - ASSERT_TRUE(len == 68); - ASSERT_TRUE(LastTTL == 1); + ASSERT_TRUE(len == 224); + ASSERT_TRUE(LastTTL == 40); + + StunClient_HandleICMP(clientData, + (struct sockaddr*)&remoteAddr, + 3); sockaddr_initFromString( (struct sockaddr*)&hop1Addr, "192.168.1.1:45674" ); @@ -218,7 +233,10 @@ CTEST(stuntrace, no_answer_IPv4) 1, StunTraceCallBack, sendPacket); - ASSERT_TRUE(len == 68); + ASSERT_TRUE(len == 224); + StunClient_HandleICMP(clientData, + (struct sockaddr*)&remoteAddr, + 3); /* HOP 1 Answer */ ASSERT_TRUE(LastTTL == 1); @@ -291,7 +309,11 @@ CTEST(stuntrace, no_answer_recurring_IPv4) 2, StunTraceCallBack, sendPacket); - ASSERT_TRUE(len == 68); + ASSERT_TRUE(len == 224); + + StunClient_HandleICMP(clientData, + (struct sockaddr*)&remoteAddr, + 3); /* HOP 1 Answer */ ASSERT_TRUE(LastTTL == 1); @@ -332,8 +354,8 @@ CTEST(stuntrace, no_answer_recurring_IPv4) ASSERT_TRUE( sockaddr_alike( (struct sockaddr*)&LastHopAddr, (struct sockaddr*)&hop2Addr ) ); - ASSERT_FALSE( Done); - ASSERT_TRUE( EndOfTrace); + ASSERT_FALSE(Done); + ASSERT_TRUE(EndOfTrace); /* HOP 1 Answer */ ASSERT_TRUE(LastTTL == 1); @@ -367,3 +389,138 @@ CTEST(stuntrace, no_answer_recurring_IPv4) ASSERT_TRUE( EndOfTrace); } + +CTEST(stuntrace, run_IPv4_Stunresp) +{ + int someData = 3; + STUN_CLIENT_DATA* clientData; + + struct sockaddr_storage localAddr, remoteAddr, hop1Addr, hop2Addr; + int sockfd = 4; + + sockaddr_initFromString( (struct sockaddr*)&remoteAddr, + "193.200.93.152:45674" ); + + sockaddr_initFromString( (struct sockaddr*)&localAddr, + "192.168.1.34:45674" ); + + StunClient_Alloc(&clientData); + + + int len = StunTrace_startTrace(clientData, + &someData, + (const struct sockaddr*)&remoteAddr, + (const struct sockaddr*)&localAddr, + sockfd, + "test", + "tset", + 1, + StunTraceCallBack, + sendPacket); + /* First alive probe */ + ASSERT_TRUE(len == 224); + ASSERT_TRUE(LastTTL == 40); + StunMessage m; + memset( &m, 0, sizeof(m) ); + memcpy( &m.msgHdr.id, &LastTransId, STUN_MSG_ID_SIZE); + memcpy( &m.msgHdr.cookie, StunCookie, sizeof(m.msgHdr.cookie) ); + m.msgHdr.msgType = STUN_MSG_BindResponseMsg; + m.hasXorMappedAddress = true; + m.xorMappedAddress.familyType = STUN_ADDR_IPv4Family; + m.xorMappedAddress.addr.v4.addr = test_addr_ipv4; + m.xorMappedAddress.addr.v4.port = test_port_ipv4; + + StunClient_HandleIncResp(clientData, + &m, + NULL); + + /* First hop.. */ + ASSERT_TRUE(LastTTL == 1); + sockaddr_initFromString( (struct sockaddr*)&hop1Addr, + "192.168.1.1:45674" ); + StunClient_HandleICMP(clientData, + (struct sockaddr*)&hop1Addr, + 11); + ASSERT_TRUE( sockaddr_alike( (struct sockaddr*)&LastHopAddr, + (struct sockaddr*)&hop1Addr ) ); + + ASSERT_TRUE( LastTTL == 2); + + sockaddr_initFromString( (struct sockaddr*)&hop2Addr, + "193.200.93.152:45674" ); + + StunClient_HandleICMP(clientData, + (struct sockaddr*)&hop2Addr, + 3); + ASSERT_TRUE( sockaddr_alike( (struct sockaddr*)&LastHopAddr, + (struct sockaddr*)&hop2Addr ) ); + ASSERT_TRUE( Done); + ASSERT_TRUE( EndOfTrace); + +} + +CTEST(stuntrace, run_IPv4_Stunresp_end) +{ + int someData = 3; + STUN_CLIENT_DATA* clientData; + + struct sockaddr_storage localAddr, remoteAddr, hop1Addr; + int sockfd = 4; + + sockaddr_initFromString( (struct sockaddr*)&remoteAddr, + "193.200.93.152:45674" ); + + sockaddr_initFromString( (struct sockaddr*)&localAddr, + "192.168.1.34:45674" ); + + StunClient_Alloc(&clientData); + + + int len = StunTrace_startTrace(clientData, + &someData, + (const struct sockaddr*)&remoteAddr, + (const struct sockaddr*)&localAddr, + sockfd, + "test", + "tset", + 1, + StunTraceCallBack, + sendPacket); + /* First alive probe */ + ASSERT_TRUE(len == 224); + ASSERT_TRUE(LastTTL == 40); + StunMessage m; + memset( &m, 0, sizeof(m) ); + memcpy( &m.msgHdr.id, &LastTransId, STUN_MSG_ID_SIZE); + memcpy( &m.msgHdr.cookie, StunCookie, sizeof(m.msgHdr.cookie) ); + m.msgHdr.msgType = STUN_MSG_BindResponseMsg; + m.hasXorMappedAddress = true; + m.xorMappedAddress.familyType = STUN_ADDR_IPv4Family; + m.xorMappedAddress.addr.v4.addr = test_addr_ipv4; + m.xorMappedAddress.addr.v4.port = test_port_ipv4; + + StunClient_HandleIncResp(clientData, + &m, + NULL); + + /* First hop.. */ + ASSERT_TRUE(LastTTL == 1); + sockaddr_initFromString( (struct sockaddr*)&hop1Addr, + "192.168.1.1:45674" ); + StunClient_HandleICMP(clientData, + (struct sockaddr*)&hop1Addr, + 11); + ASSERT_TRUE( sockaddr_alike( (struct sockaddr*)&LastHopAddr, + (struct sockaddr*)&hop1Addr ) ); + + ASSERT_TRUE( LastTTL == 2); + + memcpy( &m.msgHdr.id, &LastTransId, STUN_MSG_ID_SIZE); + StunClient_HandleIncResp(clientData, + &m, + (struct sockaddr*)&remoteAddr); + + ASSERT_TRUE( Done); + ASSERT_TRUE( EndOfTrace); + +}