void StunClient_HandleICMP(STUN_CLIENT_DATA* clientData, const struct sockaddr* srcAddr, uint32_t ICMPtype) { if (clientData == NULL) { return; } /* Todo: Test if this is for me.. */ StunPrint(clientData->logUserData, clientData->Log_cb, StunInfoCategory_Trace, "<STUNTRACE> StunClient_HandleICMP: Got ICMP type: %i\n ", ICMPtype); if ( isTimeExceeded(ICMPtype, srcAddr->sa_family) || isDstUnreachable(ICMPtype,srcAddr->sa_family) ) { for (int i = 0; i < MAX_STUN_TRANSACTIONS; i++) { 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; } } } else { StunPrint(clientData->logUserData, clientData->Log_cb, StunInfoCategory_Trace, "<STUNTRACE> StunClient_HandleICMP: Ignoring ICMP Type, nothing to do\n ", ICMPtype); } }
CTEST(stuntrace, isTimeExceeded) { ASSERT_TRUE( isTimeExceeded(11, AF_INET) ); ASSERT_FALSE( isTimeExceeded(3, AF_INET) ); ASSERT_FALSE( isTimeExceeded(5, AF_INET) ); ASSERT_TRUE( isTimeExceeded(3, AF_INET6) ); ASSERT_FALSE( isTimeExceeded(11, AF_INET6) ); ASSERT_FALSE( isTimeExceeded(5, AF_INET6) ); }
void handleStunRespIcmp(struct hiutResult* result, int ICMPtype, int ttl, struct sockaddr* srcAddr, int rtt, int retransmits) { if ( (ttl == MAX_TTL) && isDstUnreachable(ICMPtype, srcAddr->sa_family) ) { /* Part of far end alive test */ result->remoteAlive = true; result->currentTTL = 1; stunlib_createId(&result->currStunMsgId); 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 - 1) { result->currentTTL++; while (result->pathElement[result->currentTTL].inactive && result->currentTTL < result->path_max_ttl) { result->currentTTL++; } if (result->currentTTL <= result->path_max_ttl) { sendCallback(result, srcAddr, ttl, rtt, retransmits, false, false); stunlib_createId(&result->currStunMsgId); 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; } } bool done = result->num_traces < result->max_recuring ? false : true; sendCallback(result, srcAddr, ttl, rtt, retransmits, true, done); resartIfNotDone(result); } else if ( isDstUnreachable(ICMPtype,srcAddr->sa_family) ) { bool done = result->num_traces < result->max_recuring ? false : true; if (result->path_max_ttl >= ttl) { result->path_max_ttl = ttl; sendCallback(result, srcAddr, ttl, rtt, retransmits, true, done); resartIfNotDone(result); } } }