From d764c464f75a3c0e83e01222a414b8a1cde1d117 Mon Sep 17 00:00:00 2001 From: Stefan Kieszkowski <85728496+stefankiesz@users.noreply.github.com> Date: Mon, 14 Apr 2025 17:06:40 -0700 Subject: [PATCH 01/10] Viewer peer can have either IPv4-only or Dual-Stack (using Ipv6) STUN servers to make successful connection not that C master does both v4 & v6 --- .../Dependencies/libwebsockets-CMakeLists.txt | 1 + samples/Common.c | 10 ++-- src/source/Ice/IceAgent.c | 59 +++++++++++++------ src/source/Ice/IceUtils.c | 34 ++++++++--- src/source/Ice/IceUtils.h | 2 +- src/source/Ice/NatBehaviorDiscovery.c | 16 ++--- src/source/Ice/Network.c | 37 +++++++----- src/source/Ice/Network.h | 2 +- src/source/Ice/TurnConnection.c | 10 ++-- src/source/Ice/TurnConnectionStateMachine.c | 6 +- src/source/Include_i.h | 8 ++- src/source/PeerConnection/PeerConnection.c | 42 +++++++++---- src/source/PeerConnection/PeerConnection.h | 2 +- 13 files changed, 153 insertions(+), 76 deletions(-) diff --git a/CMake/Dependencies/libwebsockets-CMakeLists.txt b/CMake/Dependencies/libwebsockets-CMakeLists.txt index ebb4b390b5..01b61dbd5c 100644 --- a/CMake/Dependencies/libwebsockets-CMakeLists.txt +++ b/CMake/Dependencies/libwebsockets-CMakeLists.txt @@ -64,6 +64,7 @@ ExternalProject_Add(project_libwebsockets -DLWS_EXT_PTHREAD_LIBRARIES=${LWS_EXT_PTHREAD_LIBRARIES} -DLWS_OPENSSL_INCLUDE_DIRS=${LWS_OPENSSL_INCLUDE_DIRS} -DLWS_OPENSSL_LIBRARIES=${LWS_OPENSSL_LIBRARIES} + -DLWS_IPV6=1 BUILD_ALWAYS TRUE TEST_COMMAND "" ) diff --git a/samples/Common.c b/samples/Common.c index b371f30779..f30beadfd5 100644 --- a/samples/Common.c +++ b/samples/Common.c @@ -375,8 +375,10 @@ STATUS initializePeerConnection(PSampleConfiguration pSampleConfiguration, PRtcP if (STRSTR(pSampleConfiguration->channelInfo.pRegion, "cn-")) { pKinesisVideoStunUrlPostFix = KINESIS_VIDEO_STUN_URL_POSTFIX_CN; } - SNPRINTF(configuration.iceServers[0].urls, MAX_ICE_CONFIG_URI_LEN, KINESIS_VIDEO_STUN_URL, pSampleConfiguration->channelInfo.pRegion, - pKinesisVideoStunUrlPostFix); + // SNPRINTF(configuration.iceServers[0].urls, MAX_ICE_CONFIG_URI_LEN, KINESIS_VIDEO_STUN_URL, pSampleConfiguration->channelInfo.pRegion, + // pKinesisVideoStunUrlPostFix); + SNPRINTF(configuration.iceServers[0].urls, MAX_ICE_CONFIG_URI_LEN, "stun:stun.l.google.com:19302"); + DLOGI("STUN server URL: %s", configuration.iceServers[0].urls); if (pSampleConfiguration->useTurn) { // Set the URIs from the configuration @@ -507,7 +509,7 @@ STATUS createSampleStreamingSession(PSampleConfiguration pSampleConfiguration, P // Flag to enable/disable SDK calculations of selected ice server, local, remote and candidate pair stats. // Note: enableIceStats only has an effect if compiler flag ENABLE_STATS_CALCULATION_CONTROL is defined. - pSampleConfiguration->enableIceStats = FALSE; + pSampleConfiguration->enableIceStats = TRUE; CHK_STATUS(initializePeerConnection(pSampleConfiguration, &pSampleStreamingSession->pPeerConnection)); CHK_STATUS(peerConnectionOnIceCandidate(pSampleStreamingSession->pPeerConnection, (UINT64) pSampleStreamingSession, onIceCandidateHandler)); @@ -887,7 +889,7 @@ STATUS createSampleConfiguration(PCHAR channelName, SIGNALING_CHANNEL_ROLE_TYPE pSampleConfiguration->channelInfo.pTags = NULL; pSampleConfiguration->channelInfo.channelType = SIGNALING_CHANNEL_TYPE_SINGLE_MASTER; pSampleConfiguration->channelInfo.channelRoleType = roleType; - pSampleConfiguration->channelInfo.cachingPolicy = SIGNALING_API_CALL_CACHE_TYPE_FILE; + pSampleConfiguration->channelInfo.cachingPolicy = SIGNALING_API_CALL_CACHE_TYPE_NONE; pSampleConfiguration->channelInfo.cachingPeriod = SIGNALING_API_CALL_CACHE_TTL_SENTINEL_VALUE; pSampleConfiguration->channelInfo.asyncIceServerConfig = TRUE; // has no effect pSampleConfiguration->channelInfo.retry = TRUE; diff --git a/src/source/Ice/IceAgent.c b/src/source/Ice/IceAgent.c index a9d3a066a8..4a40b54dac 100644 --- a/src/source/Ice/IceAgent.c +++ b/src/source/Ice/IceAgent.c @@ -116,7 +116,7 @@ STATUS createIceAgent(PCHAR username, PCHAR password, PIceAgentCallbacks pIceAge if (doStatCalcs) { CHK(NULL != (pIceAgent->pRtcIceServerDiagnostics[i] = (PRtcIceServerDiagnostics) MEMCALLOC(1, SIZEOF(RtcIceServerDiagnostics))), STATUS_NOT_ENOUGH_MEMORY); - pIceAgent->pRtcIceServerDiagnostics[i]->port = (INT32) getInt16(pIceAgent->iceServers[i].ipAddress.port); + pIceAgent->pRtcIceServerDiagnostics[i]->port = (INT32) getInt16(pIceAgent->iceServers[i].ipAddresses.ipv4Address.port); switch (pIceAgent->iceServers[pIceAgent->iceServersCount].transport) { case KVS_SOCKET_PROTOCOL_UDP: STRCPY(pIceAgent->pRtcIceServerDiagnostics[i]->protocol, ICE_TRANSPORT_TYPE_UDP); @@ -639,8 +639,9 @@ STATUS iceAgentStartGathering(PIceAgent pIceAgent) "Srflx candidates setup time"); } - PROFILE_CALL_WITH_T_OBJ(CHK_STATUS(iceAgentInitRelayCandidates(pIceAgent)), pIceAgent->iceAgentProfileDiagnostics.relayCandidateSetUpTime, - "Relay candidates setup time"); + // Disable relay candidate gathering for STUN testing. + // PROFILE_CALL_WITH_T_OBJ(CHK_STATUS(iceAgentInitRelayCandidates(pIceAgent)), pIceAgent->iceAgentProfileDiagnostics.relayCandidateSetUpTime, + // "Relay candidates setup time"); // start listening for incoming data CHK_STATUS(connectionListenerStart(pIceAgent->pConnectionListener)); @@ -1105,6 +1106,11 @@ STATUS createIceCandidatePairs(PIceAgent pIceAgent, PIceCandidate pIceCandidate, pCurrentIceCandidate = (PIceCandidate) data; pCurNode = pCurNode->pNext; + // Skip forming pairs with local host candidates for STUN testing. + if (isRemoteCandidate && pCurrentIceCandidate->iceCandidateType == ICE_CANDIDATE_TYPE_HOST) { + continue; + } + // https://tools.ietf.org/html/rfc8445#section-6.1.2.2 // pair local and remote candidates with the same family if (pCurrentIceCandidate->state == ICE_CANDIDATE_STATE_VALID && pCurrentIceCandidate->ipAddress.family == pIceCandidate->ipAddress.family) { @@ -1458,14 +1464,32 @@ STATUS iceAgentSendSrflxCandidateRequest(PIceAgent pIceAgent) switch (pCandidate->iceCandidateType) { case ICE_CANDIDATE_TYPE_SERVER_REFLEXIVE: pIceServer = &(pIceAgent->iceServers[pCandidate->iceServerIndex]); - if (pIceServer->ipAddress.family == pCandidate->ipAddress.family) { + if (pIceServer->ipAddresses.ipv4Address.family == pCandidate->ipAddress.family) { // update transactionId CHK_STATUS( iceUtilsGenerateTransactionId(pBindingRequest->header.transactionId, ARRAY_SIZE(pBindingRequest->header.transactionId))); transactionIdStoreInsert(pIceAgent->pStunBindingRequestTransactionIdStore, pBindingRequest->header.transactionId); checkSum = COMPUTE_CRC32(pBindingRequest->header.transactionId, ARRAY_SIZE(pBindingRequest->header.transactionId)); - CHK_STATUS(iceAgentSendStunPacket(pBindingRequest, NULL, 0, pIceAgent, pCandidate, &pIceServer->ipAddress)); + + DLOGD("[TEST] Sending STUN binding request to IPv4 STUN server: %u:%u", pIceServer->ipAddresses.ipv4Address.address, pIceServer->ipAddresses.ipv4Address.port); + + CHK_STATUS(iceAgentSendStunPacket(pBindingRequest, NULL, 0, pIceAgent, pCandidate, &pIceServer->ipAddresses.ipv4Address)); + if (pIceAgent->pRtcIceServerDiagnostics[pCandidate->iceServerIndex] != NULL) { + pIceAgent->pRtcIceServerDiagnostics[pCandidate->iceServerIndex]->totalRequestsSent++; + CHK_STATUS(hashTableUpsert(pIceAgent->requestTimestampDiagnostics, checkSum, GETTIME())); + } + } else if (pIceServer->ipAddresses.ipv6Address.family == pCandidate->ipAddress.family) { + // update transactionId + CHK_STATUS( + iceUtilsGenerateTransactionId(pBindingRequest->header.transactionId, ARRAY_SIZE(pBindingRequest->header.transactionId))); + + transactionIdStoreInsert(pIceAgent->pStunBindingRequestTransactionIdStore, pBindingRequest->header.transactionId); + checkSum = COMPUTE_CRC32(pBindingRequest->header.transactionId, ARRAY_SIZE(pBindingRequest->header.transactionId)); + + DLOGD("[TEST] Sending STUN binding request to IPv6 STUN server: %u:%u", pIceServer->ipAddresses.ipv6Address.address, pIceServer->ipAddresses.ipv6Address.port); + + CHK_STATUS(iceAgentSendStunPacket(pBindingRequest, NULL, 0, pIceAgent, pCandidate, &pIceServer->ipAddresses.ipv6Address)); if (pIceAgent->pRtcIceServerDiagnostics[pCandidate->iceServerIndex] != NULL) { pIceAgent->pRtcIceServerDiagnostics[pCandidate->iceServerIndex]->totalRequestsSent++; CHK_STATUS(hashTableUpsert(pIceAgent->requestTimestampDiagnostics, checkSum, GETTIME())); @@ -1762,7 +1786,7 @@ STATUS iceAgentInitSrflxCandidate(PIceAgent pIceAgent) if (pCandidate->iceCandidateType == ICE_CANDIDATE_TYPE_HOST) { for (j = 0; j < pIceAgent->iceServersCount; j++) { pIceServer = &pIceAgent->iceServers[j]; - if (!pIceServer->isTurn && pIceServer->ipAddress.family == pCandidate->ipAddress.family) { + if (!pIceServer->isTurn && (pIceServer->ipAddresses.ipv4Address.family == pCandidate->ipAddress.family || pIceServer->ipAddresses.ipv6Address.family == pCandidate->ipAddress.family)) { CHK((pNewCandidate = (PIceCandidate) MEMCALLOC(1, SIZEOF(IceCandidate))) != NULL, STATUS_NOT_ENOUGH_MEMORY); generateJSONSafeString(pNewCandidate->id, ARRAY_SIZE(pNewCandidate->id)); pNewCandidate->isRemote = FALSE; @@ -1794,18 +1818,19 @@ STATUS iceAgentInitSrflxCandidate(PIceAgent pIceAgent) pCandidate = srflxCandidates[j]; // TODO: IPv6 STUN is not supported at the moment. Remove this check if the support is added in the future if (IS_IPV4_ADDR(&(pCandidate->ipAddress))) { - // open up a new socket at host candidate's ip address for server reflex candidate. - // the new port will be stored in pNewCandidate->ipAddress.port. And the Ip address will later be updated - // with the correct ip address once the STUN response is received. - CHK_STATUS(createSocketConnection(pCandidate->ipAddress.family, KVS_SOCKET_PROTOCOL_UDP, &pCandidate->ipAddress, NULL, (UINT64) pIceAgent, - incomingDataHandler, pIceAgent->kvsRtcConfiguration.sendBufSize, &pCandidate->pSocketConnection)); - ATOMIC_STORE_BOOL(&pCandidate->pSocketConnection->receiveData, TRUE); - // connectionListener will free the pSocketConnection at the end. - CHK_STATUS(connectionListenerAddConnection(pIceAgent->pConnectionListener, pCandidate->pSocketConnection)); - + DLOGW("[TEST] IPv4 STUN candidate detected ...."); } else { - DLOGW("IPv6 candidate detected, ignoring...."); + DLOGW("[TEST] IPv6 STUN candidate detected ...."); } + + // open up a new socket at host candidate's ip address for server reflex candidate. + // the new port will be stored in pNewCandidate->ipAddress.port. And the Ip address will later be updated + // with the correct ip address once the STUN response is received. + CHK_STATUS(createSocketConnection(pCandidate->ipAddress.family, KVS_SOCKET_PROTOCOL_UDP, &pCandidate->ipAddress, NULL, (UINT64) pIceAgent, + incomingDataHandler, pIceAgent->kvsRtcConfiguration.sendBufSize, &pCandidate->pSocketConnection)); + ATOMIC_STORE_BOOL(&pCandidate->pSocketConnection->receiveData, TRUE); + // connectionListener will free the pSocketConnection at the end. + CHK_STATUS(connectionListenerAddConnection(pIceAgent->pConnectionListener, pCandidate->pSocketConnection)); } CleanUp: @@ -1898,7 +1923,7 @@ STATUS iceAgentInitRelayCandidate(PIceAgent pIceAgent, UINT32 iceServerIndex, KV // open up a new socket without binding to any host address. The candidate Ip address will later be updated // with the correct relay ip address once the Allocation success response is received. Relay candidate's socket is managed // by TurnConnection struct. - CHK_STATUS(createSocketConnection(KVS_IP_FAMILY_TYPE_IPV4, protocol, NULL, &pIceAgent->iceServers[iceServerIndex].ipAddress, + CHK_STATUS(createSocketConnection(KVS_IP_FAMILY_TYPE_IPV4, protocol, NULL, &pIceAgent->iceServers[iceServerIndex].ipAddresses.ipv4Address, (UINT64) pNewCandidate, incomingRelayedDataHandler, pIceAgent->kvsRtcConfiguration.sendBufSize, &pNewCandidate->pSocketConnection)); // connectionListener will free the pSocketConnection at the end. diff --git a/src/source/Ice/IceUtils.c b/src/source/Ice/IceUtils.c index 444d2d025a..f83ce24624 100644 --- a/src/source/Ice/IceUtils.c +++ b/src/source/Ice/IceUtils.c @@ -168,16 +168,25 @@ STATUS iceUtilsSendStunPacket(PStunPacket pStunPacket, PBYTE password, UINT32 pa UINT32 stunPacketSize = STUN_PACKET_ALLOCATION_SIZE; BYTE stunPacketBuffer[STUN_PACKET_ALLOCATION_SIZE]; + CHAR ipAddrStr[KVS_IP_ADDRESS_STRING_BUFFER_LEN]; + + getIpAddrStr(pDest, ipAddrStr, ARRAY_SIZE(ipAddrStr)); + CHK_STATUS(iceUtilsPackageStunPacket(pStunPacket, password, passwordLen, stunPacketBuffer, &stunPacketSize)); CHK(pDest != NULL, STATUS_NULL_ARG); switch (pStunPacket->header.stunMessageType) { case STUN_PACKET_TYPE_BINDING_REQUEST: - DLOGD("Sending BINDING_REQUEST to ip:%u.%u.%u.%u, port:%u", pDest->address[0], pDest->address[1], pDest->address[2], pDest->address[3], - (UINT16) getInt16(pDest->port)); + // Need to format properly for IPv6. + // DLOGD("Sending BINDING_REQUEST to ip:%u.%u.%u.%u, port:%u", pDest->address[0], pDest->address[1], pDest->address[2], pDest->address[3], + // (UINT16) getInt16(pDest->port)); + DLOGD("Sending BINDING_REQUEST to ip:%s, port:%u",ipAddrStr,(UINT16) getInt16(pDest->port)); + break; case STUN_PACKET_TYPE_BINDING_RESPONSE_SUCCESS: - DLOGD("Sending BINDING_RESPONSE_SUCCESS to ip:%u.%u.%u.%u, port:%u", pDest->address[0], pDest->address[1], pDest->address[2], - pDest->address[3], (UINT16) getInt16(pDest->port)); + // DLOGD("Sending BINDING_RESPONSE_SUCCESS to ip:%u.%u.%u.%u, port:%u", pDest->address[0], pDest->address[1], pDest->address[2], + // pDest->address[3], (UINT16) getInt16(pDest->port)); + DLOGD("Sending BINDING_RESPONSE_SUCCESS to ip:%s, port:%u",ipAddrStr,(UINT16) getInt16(pDest->port)); + break; default: break; @@ -222,6 +231,7 @@ STATUS parseIceServer(PIceServer pIceServer, PCHAR url, PCHAR username, PCHAR cr PCHAR separator = NULL, urlNoPrefix = NULL, paramStart = NULL; UINT32 port = ICE_STUN_DEFAULT_PORT; CHAR addressResolved[KVS_IP_ADDRESS_STRING_BUFFER_LEN + 1] = {'\0'}; + CHAR addressResolved2[KVS_IP_ADDRESS_STRING_BUFFER_LEN + 1] = {'\0'}; // username and credential is only mandatory for turn server CHK(url != NULL && pIceServer != NULL, STATUS_NULL_ARG); @@ -264,7 +274,7 @@ STATUS parseIceServer(PIceServer pIceServer, PCHAR url, PCHAR username, PCHAR cr } if (pIceServer->setIpFn != NULL) { - retStatus = pIceServer->setIpFn(0, pIceServer->url, &pIceServer->ipAddress); + retStatus = pIceServer->setIpFn(0, pIceServer->url, &pIceServer->ipAddresses); } // Adding a NULL_ARG check specifically to cover for the case where early STUN @@ -274,12 +284,18 @@ STATUS parseIceServer(PIceServer pIceServer, PCHAR url, PCHAR username, PCHAR cr // Reset the retStatus to ensure the appropriate status code is returned from // getIpWithHostName retStatus = STATUS_SUCCESS; - CHK_STATUS(getIpWithHostName(pIceServer->url, &pIceServer->ipAddress)); + CHK_STATUS(getIpWithHostName(pIceServer->url, &pIceServer->ipAddresses)); } - pIceServer->ipAddress.port = (UINT16) getInt16((INT16) port); - getIpAddrStr(&pIceServer->ipAddress, addressResolved, ARRAY_SIZE(addressResolved)); - DLOGP("ICE Server address for %s: %s", pIceServer->url, addressResolved); + DLOGD("Setting port to %u", port); + pIceServer->ipAddresses.ipv4Address.port = (UINT16) getInt16((INT16) port); + getIpAddrStr(&pIceServer->ipAddresses.ipv4Address, addressResolved, ARRAY_SIZE(addressResolved)); + DLOGP("ICE Server IPv4 address for %s: %s", pIceServer->url, addressResolved); + + pIceServer->ipAddresses.ipv6Address.port = (UINT16) getInt16((INT16) port); + getIpAddrStr(&pIceServer->ipAddresses.ipv6Address, addressResolved2, ARRAY_SIZE(addressResolved)); + DLOGP("ICE Server IPv6 address for %s: %s", pIceServer->url, addressResolved2); + CleanUp: diff --git a/src/source/Ice/IceUtils.h b/src/source/Ice/IceUtils.h index c03b1f1d19..a9a18bfc1f 100644 --- a/src/source/Ice/IceUtils.h +++ b/src/source/Ice/IceUtils.h @@ -54,7 +54,7 @@ typedef struct { BOOL isTurn; BOOL isSecure; CHAR url[MAX_ICE_CONFIG_URI_LEN + 1]; - KvsIpAddress ipAddress; + DualKvsIpAddresses ipAddresses; CHAR username[MAX_ICE_CONFIG_USER_NAME_LEN + 1]; CHAR credential[MAX_ICE_CONFIG_CREDENTIAL_LEN + 1]; KVS_SOCKET_PROTOCOL transport; diff --git a/src/source/Ice/NatBehaviorDiscovery.c b/src/source/Ice/NatBehaviorDiscovery.c index a0b70e4721..9d664a6830 100644 --- a/src/source/Ice/NatBehaviorDiscovery.c +++ b/src/source/Ice/NatBehaviorDiscovery.c @@ -123,7 +123,7 @@ STATUS discoverNatMappingBehavior(PIceServer pStunServer, PNatTestData data, PSo /* execute test I */ DLOGD("Running mapping behavior test I. Send binding request"); - CHK_STATUS(executeNatTest(bindingRequest, &pStunServer->ipAddress, pSocketConnection, testIndex++, data, &bindingResponse)); + CHK_STATUS(executeNatTest(bindingRequest, &pStunServer->ipAddresses.ipv4Address, pSocketConnection, testIndex++, data, &bindingResponse)); if (bindingResponse == NULL) { natMappingBehavior = NAT_BEHAVIOR_NO_UDP_CONNECTIVITY; @@ -144,7 +144,7 @@ STATUS discoverNatMappingBehavior(PIceServer pStunServer, PNatTestData data, PSo /* execute test II */ DLOGD("Running mapping behavior test II. Send binding request to alternate address but primary port"); testDestAddress = otherAddress; - testDestAddress.port = pStunServer->ipAddress.port; + testDestAddress.port = pStunServer->ipAddresses.ipv4Address.port; CHK_STATUS(executeNatTest(bindingRequest, &testDestAddress, pSocketConnection, testIndex++, data, &bindingResponse)); CHK_ERR(bindingResponse != NULL, retStatus, "Expect to receive binding response"); @@ -208,7 +208,7 @@ STATUS discoverNatFilteringBehavior(PIceServer pStunServer, PNatTestData data, P /* execute test I */ DLOGD("Running filtering behavior test I. Send binding request"); - CHK_STATUS(executeNatTest(bindingRequest, &pStunServer->ipAddress, pSocketConnection, testIndex++, data, &bindingResponse)); + CHK_STATUS(executeNatTest(bindingRequest, &pStunServer->ipAddresses.ipv4Address, pSocketConnection, testIndex++, data, &bindingResponse)); if (bindingResponse == NULL) { natFilteringBehavior = NAT_BEHAVIOR_NO_UDP_CONNECTIVITY; CHK(FALSE, retStatus); @@ -219,7 +219,7 @@ STATUS discoverNatFilteringBehavior(PIceServer pStunServer, PNatTestData data, P CHK_STATUS(appendStunChangeRequestAttribute(bindingRequest, STUN_ATTRIBUTE_CHANGE_REQUEST_FLAG_CHANGE_IP | STUN_ATTRIBUTE_CHANGE_REQUEST_FLAG_CHANGE_PORT)); - CHK_STATUS(executeNatTest(bindingRequest, &pStunServer->ipAddress, pSocketConnection, testIndex++, data, &bindingResponse)); + CHK_STATUS(executeNatTest(bindingRequest, &pStunServer->ipAddresses.ipv4Address, pSocketConnection, testIndex++, data, &bindingResponse)); if (bindingResponse != NULL) { natFilteringBehavior = NAT_BEHAVIOR_ENDPOINT_INDEPENDENT; CHK(FALSE, retStatus); @@ -230,7 +230,7 @@ STATUS discoverNatFilteringBehavior(PIceServer pStunServer, PNatTestData data, P CHK_STATUS(getStunAttribute(bindingRequest, STUN_ATTRIBUTE_TYPE_CHANGE_REQUEST, (PStunAttributeHeader*) &pStunAttributeChangeRequest)); pStunAttributeChangeRequest->changeFlag = STUN_ATTRIBUTE_CHANGE_REQUEST_FLAG_CHANGE_PORT; - CHK_STATUS(executeNatTest(bindingRequest, &pStunServer->ipAddress, pSocketConnection, testIndex++, data, &bindingResponse)); + CHK_STATUS(executeNatTest(bindingRequest, &pStunServer->ipAddresses.ipv4Address, pSocketConnection, testIndex++, data, &bindingResponse)); if (bindingResponse != NULL) { natFilteringBehavior = NAT_BEHAVIOR_ADDRESS_DEPENDENT; @@ -291,14 +291,14 @@ STATUS discoverNatBehavior(PCHAR stunServer, NAT_BEHAVIOR* pNatMappingBehavior, /* use the first usable local interface to create socket */ for (i = 0; i < localNetworkInterfaceCount; ++i) { - if (localNetworkInterfaces[i].family == iceServerStun.ipAddress.family) { + if (localNetworkInterfaces[i].family == iceServerStun.ipAddresses.ipv4Address.family) { pSelectedLocalInterface = &localNetworkInterfaces[i]; break; } } CHK_WARN(pSelectedLocalInterface != NULL, retStatus, "No usable local interface"); - CHK_STATUS(createSocketConnection(iceServerStun.ipAddress.family, KVS_SOCKET_PROTOCOL_UDP, pSelectedLocalInterface, NULL, (UINT64) &customData, + CHK_STATUS(createSocketConnection(iceServerStun.ipAddresses.ipv4Address.family, KVS_SOCKET_PROTOCOL_UDP, pSelectedLocalInterface, NULL, (UINT64) &customData, natTestIncomingDataHandler, 0, &pSocketConnection)); ATOMIC_STORE_BOOL(&pSocketConnection->receiveData, TRUE); @@ -322,7 +322,7 @@ STATUS discoverNatBehavior(PCHAR stunServer, NAT_BEHAVIOR* pNatMappingBehavior, CHK_STATUS(connectionListenerRemoveAllConnection(pConnectionListener)); freeSocketConnection(&pSocketConnection); - CHK_STATUS(createSocketConnection(iceServerStun.ipAddress.family, KVS_SOCKET_PROTOCOL_UDP, pSelectedLocalInterface, NULL, (UINT64) &customData, + CHK_STATUS(createSocketConnection(iceServerStun.ipAddresses.ipv4Address.family, KVS_SOCKET_PROTOCOL_UDP, pSelectedLocalInterface, NULL, (UINT64) &customData, natTestIncomingDataHandler, 0, &pSocketConnection)); ATOMIC_STORE_BOOL(&pSocketConnection->receiveData, TRUE); CHK_STATUS(connectionListenerAddConnection(pConnectionListener, pSocketConnection)); diff --git a/src/source/Ice/Network.c b/src/source/Ice/Network.c index b5568bb97b..199b1b64ac 100644 --- a/src/source/Ice/Network.c +++ b/src/source/Ice/Network.c @@ -393,14 +393,15 @@ STATUS getIpAddrFromDnsHostname(PCHAR hostname, PCHAR address, UINT16 lengthSrc, return retStatus; } -STATUS getIpWithHostName(PCHAR hostname, PKvsIpAddress destIp) +STATUS getIpWithHostName(PCHAR hostname, PDualKvsIpAddresses destIps) { STATUS retStatus = STATUS_SUCCESS; INT32 errCode; UINT16 hostnameLen, addrLen; PCHAR errStr; struct addrinfo *res, *rp; - BOOL resolved = FALSE; + BOOL ipv4Resolved = FALSE; + BOOL ipv6Resolved = FALSE; struct sockaddr_in* ipv4Addr; struct sockaddr_in6* ipv6Addr; struct in_addr inaddr; @@ -430,27 +431,33 @@ STATUS getIpWithHostName(PCHAR hostname, PKvsIpAddress destIp) errStr = errCode == EAI_SYSTEM ? (strerror(errno)) : ((PCHAR) gai_strerror(errCode)); CHK_ERR(FALSE, STATUS_RESOLVE_HOSTNAME_FAILED, "getaddrinfo() with errno %s", errStr); } - for (rp = res; rp != NULL && !resolved; rp = rp->ai_next) { + for (rp = res; rp != NULL && !(ipv4Resolved && ipv6Resolved); rp = rp->ai_next) { if (rp->ai_family == AF_INET) { + DLOGD("Found an IPv4 ICE server addresss"); ipv4Addr = (struct sockaddr_in*) rp->ai_addr; - destIp->family = KVS_IP_FAMILY_TYPE_IPV4; - MEMCPY(destIp->address, &ipv4Addr->sin_addr, IPV4_ADDRESS_LENGTH); - resolved = TRUE; + destIps->ipv4Address.family = KVS_IP_FAMILY_TYPE_IPV4; + // TODO: Should also init port to 0, or no (we do in the threadpool-enabled version of this call for STUN)? + MEMCPY(destIps->ipv4Address.address, &ipv4Addr->sin_addr, IPV4_ADDRESS_LENGTH); + ipv4Resolved = TRUE; + // ipv6Resolved = TRUE; } else if (rp->ai_family == AF_INET6) { + DLOGD("Found an IPv6 ICE server addresss"); ipv6Addr = (struct sockaddr_in6*) rp->ai_addr; - destIp->family = KVS_IP_FAMILY_TYPE_IPV6; - MEMCPY(destIp->address, &ipv6Addr->sin6_addr, IPV6_ADDRESS_LENGTH); - resolved = TRUE; + destIps->ipv6Address.family = KVS_IP_FAMILY_TYPE_IPV6; + MEMCPY(destIps->ipv6Address.address, &ipv6Addr->sin6_addr, IPV6_ADDRESS_LENGTH); + ipv6Resolved = TRUE; + // ipv4Resolved = TRUE; + } else { + DLOGD("Found an invalid ICE server addresss family type - must be IPv4 or IPv6."); } } freeaddrinfo(res); - CHK_ERR(resolved, STATUS_HOSTNAME_NOT_FOUND, "Could not find network address of %s", hostname); - } - - else { + CHK_ERR(ipv4Resolved || ipv6Resolved, STATUS_HOSTNAME_NOT_FOUND, "Could not find network address of %s", hostname); + } else { + // TODO: The below is for TURN case, will need to do this based on IP family too... inet_pton(AF_INET, addr, &inaddr); - destIp->family = KVS_IP_FAMILY_TYPE_IPV4; - MEMCPY(destIp->address, &inaddr, IPV4_ADDRESS_LENGTH); + destIps->ipv4Address.family = KVS_IP_FAMILY_TYPE_IPV4; + MEMCPY(destIps->ipv4Address.address, &inaddr, IPV4_ADDRESS_LENGTH); } CleanUp: diff --git a/src/source/Ice/Network.h b/src/source/Ice/Network.h index 80fb745160..9a05e7a251 100644 --- a/src/source/Ice/Network.h +++ b/src/source/Ice/Network.h @@ -122,7 +122,7 @@ STATUS socketWrite(INT32, const void*, SIZE_T); * * @return - STATUS status of execution */ -STATUS getIpWithHostName(PCHAR, PKvsIpAddress); +STATUS getIpWithHostName(PCHAR, PDualKvsIpAddresses); /** * @param - PCHAR - IN - IP address string to verify if it is IPv4 or IPv6 format diff --git a/src/source/Ice/TurnConnection.c b/src/source/Ice/TurnConnection.c index 86dc365747..d2dc24ef17 100644 --- a/src/source/Ice/TurnConnection.c +++ b/src/source/Ice/TurnConnection.c @@ -674,7 +674,7 @@ STATUS turnConnectionAddPeer(PTurnConnection pTurnConnection, PKvsIpAddress pPee BOOL locked = FALSE; CHK(pTurnConnection != NULL && pPeerAddress != NULL, STATUS_NULL_ARG); - CHK(pTurnConnection->turnServer.ipAddress.family == pPeerAddress->family, STATUS_INVALID_ARG); + CHK(pTurnConnection->turnServer.ipAddresses.ipv4Address.family == pPeerAddress->family, STATUS_INVALID_ARG); CHK_WARN(IS_IPV4_ADDR(pPeerAddress), retStatus, "Drop IPv6 turn peer because only IPv4 turn peer is supported right now"); MUTEX_LOCK(pTurnConnection->lock); @@ -770,7 +770,7 @@ STATUS turnConnectionSendData(PTurnConnection pTurnConnection, PBYTE pBuf, UINT3 putInt16((PINT16) (pTurnConnection->sendDataBuffer + 2), (UINT16) bufLen); MEMCPY(pTurnConnection->sendDataBuffer + TURN_DATA_CHANNEL_SEND_OVERHEAD, pBuf, bufLen); - retStatus = iceUtilsSendData(pTurnConnection->sendDataBuffer, paddedDataLen, &pTurnConnection->turnServer.ipAddress, + retStatus = iceUtilsSendData(pTurnConnection->sendDataBuffer, paddedDataLen, &pTurnConnection->turnServer.ipAddresses.ipv4Address, pTurnConnection->pControlChannel, NULL, FALSE); if (STATUS_FAILED(retStatus)) { @@ -858,7 +858,7 @@ STATUS turnConnectionRefreshAllocation(PTurnConnection pTurnConnection) pStunAttributeLifetime->lifetime = DEFAULT_TURN_ALLOCATION_LIFETIME_SECONDS; CHK_STATUS(iceUtilsSendStunPacket(pTurnConnection->pTurnAllocationRefreshPacket, pTurnConnection->longTermKey, - ARRAY_SIZE(pTurnConnection->longTermKey), &pTurnConnection->turnServer.ipAddress, + ARRAY_SIZE(pTurnConnection->longTermKey), &pTurnConnection->turnServer.ipAddresses.ipv4Address, pTurnConnection->pControlChannel, NULL, FALSE)); pTurnConnection->nextAllocationRefreshTime = currTime + DEFAULT_TURN_SEND_REFRESH_INVERVAL; @@ -1056,7 +1056,7 @@ STATUS checkTurnPeerConnections(PTurnConnection pTurnConnection) CHK(pTurnPeer->pTransactionIdStore != NULL, STATUS_INVALID_OPERATION); transactionIdStoreInsert(pTurnPeer->pTransactionIdStore, pTurnConnection->pTurnCreatePermissionPacket->header.transactionId); sendStatus = iceUtilsSendStunPacket(pTurnConnection->pTurnCreatePermissionPacket, pTurnConnection->longTermKey, - ARRAY_SIZE(pTurnConnection->longTermKey), &pTurnConnection->turnServer.ipAddress, + ARRAY_SIZE(pTurnConnection->longTermKey), &pTurnConnection->turnServer.ipAddresses.ipv4Address, pTurnConnection->pControlChannel, NULL, FALSE); } else if (pTurnPeer->connectionState == TURN_PEER_CONN_STATE_BIND_CHANNEL) { @@ -1082,7 +1082,7 @@ STATUS checkTurnPeerConnections(PTurnConnection pTurnConnection) CHK(pTurnPeer->pTransactionIdStore != NULL, STATUS_INVALID_OPERATION); transactionIdStoreInsert(pTurnPeer->pTransactionIdStore, pTurnConnection->pTurnChannelBindPacket->header.transactionId); sendStatus = iceUtilsSendStunPacket(pTurnConnection->pTurnChannelBindPacket, pTurnConnection->longTermKey, - ARRAY_SIZE(pTurnConnection->longTermKey), &pTurnConnection->turnServer.ipAddress, + ARRAY_SIZE(pTurnConnection->longTermKey), &pTurnConnection->turnServer.ipAddresses.ipv4Address, pTurnConnection->pControlChannel, NULL, FALSE); } } diff --git a/src/source/Ice/TurnConnectionStateMachine.c b/src/source/Ice/TurnConnectionStateMachine.c index 6b7ba5775c..75aa37da8c 100644 --- a/src/source/Ice/TurnConnectionStateMachine.c +++ b/src/source/Ice/TurnConnectionStateMachine.c @@ -278,7 +278,7 @@ STATUS executeGetCredentialsTurnState(UINT64 customData, UINT64 time) } else { CHK(currentTime <= pTurnConnection->stateTimeoutTime, STATUS_TURN_CONNECTION_GET_CREDENTIALS_FAILED); } - CHK_STATUS(iceUtilsSendStunPacket(pTurnConnection->pTurnPacket, NULL, 0, &pTurnConnection->turnServer.ipAddress, pTurnConnection->pControlChannel, + CHK_STATUS(iceUtilsSendStunPacket(pTurnConnection->pTurnPacket, NULL, 0, &pTurnConnection->turnServer.ipAddresses.ipv4Address, pTurnConnection->pControlChannel, NULL, FALSE)); CleanUp: @@ -348,7 +348,7 @@ STATUS executeAllocationTurnState(UINT64 customData, UINT64 time) CHK(currentTime <= pTurnConnection->stateTimeoutTime, STATUS_TURN_CONNECTION_ALLOCATION_FAILED); } CHK_STATUS(iceUtilsSendStunPacket(pTurnConnection->pTurnPacket, pTurnConnection->longTermKey, ARRAY_SIZE(pTurnConnection->longTermKey), - &pTurnConnection->turnServer.ipAddress, pTurnConnection->pControlChannel, NULL, FALSE)); + &pTurnConnection->turnServer.ipAddresses.ipv4Address, pTurnConnection->pControlChannel, NULL, FALSE)); CleanUp: @@ -679,7 +679,7 @@ STATUS executeCleanUpTurnState(UINT64 customData, UINT64 time) CHK(pStunAttributeLifetime != NULL, STATUS_INTERNAL_ERROR); pStunAttributeLifetime->lifetime = 0; CHK_STATUS(iceUtilsSendStunPacket(pTurnConnection->pTurnAllocationRefreshPacket, pTurnConnection->longTermKey, - ARRAY_SIZE(pTurnConnection->longTermKey), &pTurnConnection->turnServer.ipAddress, + ARRAY_SIZE(pTurnConnection->longTermKey), &pTurnConnection->turnServer.ipAddresses.ipv4Address, pTurnConnection->pControlChannel, NULL, FALSE)); pTurnConnection->deallocatePacketSent = TRUE; } diff --git a/src/source/Include_i.h b/src/source/Include_i.h index b606165d8c..716c5c0f5f 100644 --- a/src/source/Include_i.h +++ b/src/source/Include_i.h @@ -103,12 +103,18 @@ typedef struct { BOOL isPointToPoint; } KvsIpAddress, *PKvsIpAddress; +// This structure stores both an IPv4 and IPv6 address (if applicable) for a peer/server. +typedef struct { + KvsIpAddress ipv4Address; + KvsIpAddress ipv6Address; +} DualKvsIpAddresses, *PDualKvsIpAddresses; + #define IS_IPV4_ADDR(pAddress) ((pAddress)->family == KVS_IP_FAMILY_TYPE_IPV4) // Used for ensuring alignment #define ALIGN_UP_TO_MACHINE_WORD(x) ROUND_UP((x), SIZEOF(SIZE_T)) -typedef STATUS (*IceServerSetIpFunc)(UINT64, PCHAR, PKvsIpAddress); +typedef STATUS (*IceServerSetIpFunc)(UINT64, PCHAR, PDualKvsIpAddresses); STATUS getIpAddrStr(PKvsIpAddress pKvsIpAddress, PCHAR pBuffer, UINT32 bufferLen); //////////////////////////////////////////////////// diff --git a/src/source/PeerConnection/PeerConnection.c b/src/source/PeerConnection/PeerConnection.c index d25101cb38..bbfde2a6e8 100644 --- a/src/source/PeerConnection/PeerConnection.c +++ b/src/source/PeerConnection/PeerConnection.c @@ -806,34 +806,54 @@ STATUS getStunAddr(PStunIpAddrContext pStunIpAddrCtx) STATUS retStatus = STATUS_SUCCESS; struct addrinfo *rp, *res; struct sockaddr_in* ipv4Addr; - BOOL resolved = FALSE; + struct sockaddr_in6* ipv6Addr; + BOOL ipv4Resolved = FALSE; + BOOL ipv6Resolved = FALSE; + + // To speed up connection for non-dual stack candidates,ignore IPv6. + // # if not defined (USE_DUAL_STACK_CANDIDATES) + // ipv6Resolved = TRUE; + + DLOGD("Resolving STUN address..."); + errCode = getaddrinfo(pStunIpAddrCtx->hostname, NULL, NULL, &res); if (errCode != 0) { DLOGI("Failed to resolve hostname with errcode: %d", errCode); retStatus = STATUS_RESOLVE_HOSTNAME_FAILED; } else { - for (rp = res; rp != NULL && !resolved; rp = rp->ai_next) { - if (rp->ai_family == AF_INET) { + for (rp = res; rp != NULL && !(ipv4Resolved && ipv6Resolved); rp = rp->ai_next) { + if (!ipv4Resolved && rp->ai_family == AF_INET) { + DLOGD("Found an IPv4 STUN addresss"); ipv4Addr = (struct sockaddr_in*) rp->ai_addr; - pStunIpAddrCtx->kvsIpAddr.family = KVS_IP_FAMILY_TYPE_IPV4; - pStunIpAddrCtx->kvsIpAddr.port = 0; - MEMCPY(pStunIpAddrCtx->kvsIpAddr.address, &ipv4Addr->sin_addr, IPV4_ADDRESS_LENGTH); - resolved = TRUE; + pStunIpAddrCtx->kvsIpAddresses.ipv4Address.family = KVS_IP_FAMILY_TYPE_IPV4; + pStunIpAddrCtx->kvsIpAddresses.ipv4Address.port = 0; + MEMCPY(pStunIpAddrCtx->kvsIpAddresses.ipv4Address.address, &ipv4Addr->sin_addr, IPV4_ADDRESS_LENGTH); + ipv4Resolved = TRUE; + } else if (!ipv6Resolved && rp->ai_family == AF_INET6) { + DLOGD("Found an IPv6 STUN addresss"); + ipv6Addr = (struct sockaddr_in6*) rp->ai_addr; + pStunIpAddrCtx->kvsIpAddresses.ipv6Address.family = KVS_IP_FAMILY_TYPE_IPV6; + pStunIpAddrCtx->kvsIpAddresses.ipv6Address.port = 0; + MEMCPY(pStunIpAddrCtx->kvsIpAddresses.ipv6Address.address, &ipv6Addr->sin6_addr, IPV6_ADDRESS_LENGTH); + ipv6Resolved = TRUE; + } else { + DLOGD("Invalid family STUN addresss"); } } freeaddrinfo(res); } - if (!resolved) { + if (!(ipv4Resolved || ipv6Resolved)) { retStatus = STATUS_RESOLVE_HOSTNAME_FAILED; } CHK_LOG_ERR(retStatus); LEAVES(); return retStatus; + } -STATUS onSetStunServerIp(UINT64 customData, PCHAR url, PKvsIpAddress pIpAddr) +STATUS onSetStunServerIp(UINT64 customData, PCHAR url, PDualKvsIpAddresses pIpAddresses) { ENTERS(); UNUSED_PARAM(customData); @@ -863,7 +883,7 @@ STATUS onSetStunServerIp(UINT64 customData, PCHAR url, PKvsIpAddress pIpAddr) pWebRtcClientContext->pStunIpAddrCtx->startTime = 0; CHK_ERR(getStunAddr(pWebRtcClientContext->pStunIpAddrCtx) == STATUS_SUCCESS, retStatus, "Failed to resolve after cache expiry"); } - MEMCPY(pIpAddr, &pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddr, SIZEOF(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddr)); + MEMCPY(pIpAddresses, &pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address, SIZEOF(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address)); } else { DLOGE("Initialization failed"); } @@ -912,7 +932,7 @@ PVOID resolveStunIceServerIp(PVOID args) KINESIS_VIDEO_STUN_URL_WITHOUT_PORT, pRegion, pHostnamePostfix); stunDnsResolutionStartTime = GETTIME(); if (getStunAddr(pWebRtcClientContext->pStunIpAddrCtx) == STATUS_SUCCESS) { - getIpAddrStr(&pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddr, addressResolved, ARRAY_SIZE(addressResolved)); + getIpAddrStr(&pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address, addressResolved, ARRAY_SIZE(addressResolved)); DLOGI("ICE Server address for %s with getaddrinfo: %s", pWebRtcClientContext->pStunIpAddrCtx->hostname, addressResolved); pWebRtcClientContext->pStunIpAddrCtx->isIpInitialized = TRUE; } else { diff --git a/src/source/PeerConnection/PeerConnection.h b/src/source/PeerConnection/PeerConnection.h index 7311ec9794..20cec6e078 100644 --- a/src/source/PeerConnection/PeerConnection.h +++ b/src/source/PeerConnection/PeerConnection.h @@ -158,7 +158,7 @@ typedef struct { typedef struct { CHAR hostname[MAX_ICE_CONFIG_URI_LEN + 1]; - KvsIpAddress kvsIpAddr; + DualKvsIpAddresses kvsIpAddresses; BOOL isIpInitialized; UINT64 startTime; UINT64 stunDnsResolutionTime; From 79ca218b112e48a6181da38de2a603c6fe300513 Mon Sep 17 00:00:00 2001 From: Stefan Kieszkowski <85728496+stefankiesz@users.noreply.github.com> Date: Fri, 25 Apr 2025 10:26:42 -0700 Subject: [PATCH 02/10] Cleanup --- samples/Common.c | 10 +++----- src/source/Ice/IceAgent.c | 15 +++-------- src/source/Ice/IceUtils.c | 19 +++++--------- src/source/Ice/Network.c | 2 -- src/source/Include_i.h | 2 +- src/source/PeerConnection/PeerConnection.c | 30 +++++++++++++++------- 6 files changed, 36 insertions(+), 42 deletions(-) diff --git a/samples/Common.c b/samples/Common.c index f30beadfd5..b371f30779 100644 --- a/samples/Common.c +++ b/samples/Common.c @@ -375,10 +375,8 @@ STATUS initializePeerConnection(PSampleConfiguration pSampleConfiguration, PRtcP if (STRSTR(pSampleConfiguration->channelInfo.pRegion, "cn-")) { pKinesisVideoStunUrlPostFix = KINESIS_VIDEO_STUN_URL_POSTFIX_CN; } - // SNPRINTF(configuration.iceServers[0].urls, MAX_ICE_CONFIG_URI_LEN, KINESIS_VIDEO_STUN_URL, pSampleConfiguration->channelInfo.pRegion, - // pKinesisVideoStunUrlPostFix); - SNPRINTF(configuration.iceServers[0].urls, MAX_ICE_CONFIG_URI_LEN, "stun:stun.l.google.com:19302"); - DLOGI("STUN server URL: %s", configuration.iceServers[0].urls); + SNPRINTF(configuration.iceServers[0].urls, MAX_ICE_CONFIG_URI_LEN, KINESIS_VIDEO_STUN_URL, pSampleConfiguration->channelInfo.pRegion, + pKinesisVideoStunUrlPostFix); if (pSampleConfiguration->useTurn) { // Set the URIs from the configuration @@ -509,7 +507,7 @@ STATUS createSampleStreamingSession(PSampleConfiguration pSampleConfiguration, P // Flag to enable/disable SDK calculations of selected ice server, local, remote and candidate pair stats. // Note: enableIceStats only has an effect if compiler flag ENABLE_STATS_CALCULATION_CONTROL is defined. - pSampleConfiguration->enableIceStats = TRUE; + pSampleConfiguration->enableIceStats = FALSE; CHK_STATUS(initializePeerConnection(pSampleConfiguration, &pSampleStreamingSession->pPeerConnection)); CHK_STATUS(peerConnectionOnIceCandidate(pSampleStreamingSession->pPeerConnection, (UINT64) pSampleStreamingSession, onIceCandidateHandler)); @@ -889,7 +887,7 @@ STATUS createSampleConfiguration(PCHAR channelName, SIGNALING_CHANNEL_ROLE_TYPE pSampleConfiguration->channelInfo.pTags = NULL; pSampleConfiguration->channelInfo.channelType = SIGNALING_CHANNEL_TYPE_SINGLE_MASTER; pSampleConfiguration->channelInfo.channelRoleType = roleType; - pSampleConfiguration->channelInfo.cachingPolicy = SIGNALING_API_CALL_CACHE_TYPE_NONE; + pSampleConfiguration->channelInfo.cachingPolicy = SIGNALING_API_CALL_CACHE_TYPE_FILE; pSampleConfiguration->channelInfo.cachingPeriod = SIGNALING_API_CALL_CACHE_TTL_SENTINEL_VALUE; pSampleConfiguration->channelInfo.asyncIceServerConfig = TRUE; // has no effect pSampleConfiguration->channelInfo.retry = TRUE; diff --git a/src/source/Ice/IceAgent.c b/src/source/Ice/IceAgent.c index 4a40b54dac..6b8632b473 100644 --- a/src/source/Ice/IceAgent.c +++ b/src/source/Ice/IceAgent.c @@ -639,9 +639,8 @@ STATUS iceAgentStartGathering(PIceAgent pIceAgent) "Srflx candidates setup time"); } - // Disable relay candidate gathering for STUN testing. - // PROFILE_CALL_WITH_T_OBJ(CHK_STATUS(iceAgentInitRelayCandidates(pIceAgent)), pIceAgent->iceAgentProfileDiagnostics.relayCandidateSetUpTime, - // "Relay candidates setup time"); + PROFILE_CALL_WITH_T_OBJ(CHK_STATUS(iceAgentInitRelayCandidates(pIceAgent)), pIceAgent->iceAgentProfileDiagnostics.relayCandidateSetUpTime, + "Relay candidates setup time"); // start listening for incoming data CHK_STATUS(connectionListenerStart(pIceAgent->pConnectionListener)); @@ -1106,11 +1105,6 @@ STATUS createIceCandidatePairs(PIceAgent pIceAgent, PIceCandidate pIceCandidate, pCurrentIceCandidate = (PIceCandidate) data; pCurNode = pCurNode->pNext; - // Skip forming pairs with local host candidates for STUN testing. - if (isRemoteCandidate && pCurrentIceCandidate->iceCandidateType == ICE_CANDIDATE_TYPE_HOST) { - continue; - } - // https://tools.ietf.org/html/rfc8445#section-6.1.2.2 // pair local and remote candidates with the same family if (pCurrentIceCandidate->state == ICE_CANDIDATE_STATE_VALID && pCurrentIceCandidate->ipAddress.family == pIceCandidate->ipAddress.family) { @@ -1816,11 +1810,10 @@ STATUS iceAgentInitSrflxCandidate(PIceAgent pIceAgent) // Create and start the connection listener outside of the locks for (j = 0; j < srflxCount; j++) { pCandidate = srflxCandidates[j]; - // TODO: IPv6 STUN is not supported at the moment. Remove this check if the support is added in the future if (IS_IPV4_ADDR(&(pCandidate->ipAddress))) { - DLOGW("[TEST] IPv4 STUN candidate detected ...."); + DLOGI("Initializing an IPv4 STUN candidate..."); } else { - DLOGW("[TEST] IPv6 STUN candidate detected ...."); + DLOGI("Initializing an IPv6 STUN candidate..."); } // open up a new socket at host candidate's ip address for server reflex candidate. diff --git a/src/source/Ice/IceUtils.c b/src/source/Ice/IceUtils.c index f83ce24624..514f08af1e 100644 --- a/src/source/Ice/IceUtils.c +++ b/src/source/Ice/IceUtils.c @@ -176,17 +176,10 @@ STATUS iceUtilsSendStunPacket(PStunPacket pStunPacket, PBYTE password, UINT32 pa CHK(pDest != NULL, STATUS_NULL_ARG); switch (pStunPacket->header.stunMessageType) { case STUN_PACKET_TYPE_BINDING_REQUEST: - // Need to format properly for IPv6. - // DLOGD("Sending BINDING_REQUEST to ip:%u.%u.%u.%u, port:%u", pDest->address[0], pDest->address[1], pDest->address[2], pDest->address[3], - // (UINT16) getInt16(pDest->port)); DLOGD("Sending BINDING_REQUEST to ip:%s, port:%u",ipAddrStr,(UINT16) getInt16(pDest->port)); - break; case STUN_PACKET_TYPE_BINDING_RESPONSE_SUCCESS: - // DLOGD("Sending BINDING_RESPONSE_SUCCESS to ip:%u.%u.%u.%u, port:%u", pDest->address[0], pDest->address[1], pDest->address[2], - // pDest->address[3], (UINT16) getInt16(pDest->port)); DLOGD("Sending BINDING_RESPONSE_SUCCESS to ip:%s, port:%u",ipAddrStr,(UINT16) getInt16(pDest->port)); - break; default: break; @@ -230,8 +223,8 @@ STATUS parseIceServer(PIceServer pIceServer, PCHAR url, PCHAR username, PCHAR cr STATUS retStatus = STATUS_SUCCESS; PCHAR separator = NULL, urlNoPrefix = NULL, paramStart = NULL; UINT32 port = ICE_STUN_DEFAULT_PORT; - CHAR addressResolved[KVS_IP_ADDRESS_STRING_BUFFER_LEN + 1] = {'\0'}; - CHAR addressResolved2[KVS_IP_ADDRESS_STRING_BUFFER_LEN + 1] = {'\0'}; + CHAR addressResolvedIPv4[KVS_IP_ADDRESS_STRING_BUFFER_LEN + 1] = {'\0'}; + CHAR addressResolvedIPv6[KVS_IP_ADDRESS_STRING_BUFFER_LEN + 1] = {'\0'}; // username and credential is only mandatory for turn server CHK(url != NULL && pIceServer != NULL, STATUS_NULL_ARG); @@ -289,12 +282,12 @@ STATUS parseIceServer(PIceServer pIceServer, PCHAR url, PCHAR username, PCHAR cr DLOGD("Setting port to %u", port); pIceServer->ipAddresses.ipv4Address.port = (UINT16) getInt16((INT16) port); - getIpAddrStr(&pIceServer->ipAddresses.ipv4Address, addressResolved, ARRAY_SIZE(addressResolved)); - DLOGP("ICE Server IPv4 address for %s: %s", pIceServer->url, addressResolved); + getIpAddrStr(&pIceServer->ipAddresses.ipv4Address, addressResolvedIPv4, ARRAY_SIZE(addressResolvedIPv4)); + DLOGP("ICE Server IPv4 address for %s: %s", pIceServer->url, addressResolvedIPv4); pIceServer->ipAddresses.ipv6Address.port = (UINT16) getInt16((INT16) port); - getIpAddrStr(&pIceServer->ipAddresses.ipv6Address, addressResolved2, ARRAY_SIZE(addressResolved)); - DLOGP("ICE Server IPv6 address for %s: %s", pIceServer->url, addressResolved2); + getIpAddrStr(&pIceServer->ipAddresses.ipv6Address, addressResolvedIPv6, ARRAY_SIZE(addressResolvedIPv6)); + DLOGP("ICE Server IPv6 address for %s: %s", pIceServer->url, addressResolvedIPv6); CleanUp: diff --git a/src/source/Ice/Network.c b/src/source/Ice/Network.c index 199b1b64ac..83c718249b 100644 --- a/src/source/Ice/Network.c +++ b/src/source/Ice/Network.c @@ -439,14 +439,12 @@ STATUS getIpWithHostName(PCHAR hostname, PDualKvsIpAddresses destIps) // TODO: Should also init port to 0, or no (we do in the threadpool-enabled version of this call for STUN)? MEMCPY(destIps->ipv4Address.address, &ipv4Addr->sin_addr, IPV4_ADDRESS_LENGTH); ipv4Resolved = TRUE; - // ipv6Resolved = TRUE; } else if (rp->ai_family == AF_INET6) { DLOGD("Found an IPv6 ICE server addresss"); ipv6Addr = (struct sockaddr_in6*) rp->ai_addr; destIps->ipv6Address.family = KVS_IP_FAMILY_TYPE_IPV6; MEMCPY(destIps->ipv6Address.address, &ipv6Addr->sin6_addr, IPV6_ADDRESS_LENGTH); ipv6Resolved = TRUE; - // ipv4Resolved = TRUE; } else { DLOGD("Found an invalid ICE server addresss family type - must be IPv4 or IPv6."); } diff --git a/src/source/Include_i.h b/src/source/Include_i.h index 716c5c0f5f..0cc540461d 100644 --- a/src/source/Include_i.h +++ b/src/source/Include_i.h @@ -103,7 +103,7 @@ typedef struct { BOOL isPointToPoint; } KvsIpAddress, *PKvsIpAddress; -// This structure stores both an IPv4 and IPv6 address (if applicable) for a peer/server. +// This structure stores both an IPv4 and IPv6 address (if applicable). typedef struct { KvsIpAddress ipv4Address; KvsIpAddress ipv6Address; diff --git a/src/source/PeerConnection/PeerConnection.c b/src/source/PeerConnection/PeerConnection.c index bbfde2a6e8..8e249f525e 100644 --- a/src/source/PeerConnection/PeerConnection.c +++ b/src/source/PeerConnection/PeerConnection.c @@ -814,8 +814,7 @@ STATUS getStunAddr(PStunIpAddrContext pStunIpAddrCtx) // # if not defined (USE_DUAL_STACK_CANDIDATES) // ipv6Resolved = TRUE; - DLOGD("Resolving STUN address..."); - + DLOGD("Resolving STUN server address for hostname: %s", pStunIpAddrCtx->hostname); errCode = getaddrinfo(pStunIpAddrCtx->hostname, NULL, NULL, &res); if (errCode != 0) { @@ -824,21 +823,21 @@ STATUS getStunAddr(PStunIpAddrContext pStunIpAddrCtx) } else { for (rp = res; rp != NULL && !(ipv4Resolved && ipv6Resolved); rp = rp->ai_next) { if (!ipv4Resolved && rp->ai_family == AF_INET) { - DLOGD("Found an IPv4 STUN addresss"); + DLOGD("Found an IPv4 STUN addresss for hostname: %s", pStunIpAddrCtx->hostname); ipv4Addr = (struct sockaddr_in*) rp->ai_addr; pStunIpAddrCtx->kvsIpAddresses.ipv4Address.family = KVS_IP_FAMILY_TYPE_IPV4; pStunIpAddrCtx->kvsIpAddresses.ipv4Address.port = 0; MEMCPY(pStunIpAddrCtx->kvsIpAddresses.ipv4Address.address, &ipv4Addr->sin_addr, IPV4_ADDRESS_LENGTH); ipv4Resolved = TRUE; } else if (!ipv6Resolved && rp->ai_family == AF_INET6) { - DLOGD("Found an IPv6 STUN addresss"); + DLOGD("Found an IPv6 STUN addresss for hostname: %s", pStunIpAddrCtx->hostname); ipv6Addr = (struct sockaddr_in6*) rp->ai_addr; pStunIpAddrCtx->kvsIpAddresses.ipv6Address.family = KVS_IP_FAMILY_TYPE_IPV6; pStunIpAddrCtx->kvsIpAddresses.ipv6Address.port = 0; MEMCPY(pStunIpAddrCtx->kvsIpAddresses.ipv6Address.address, &ipv6Addr->sin6_addr, IPV6_ADDRESS_LENGTH); ipv6Resolved = TRUE; } else { - DLOGD("Invalid family STUN addresss"); + DLOGD("Invalid family STUN addresss for hostname: %s", pStunIpAddrCtx->hostname); } } freeaddrinfo(res); @@ -884,6 +883,7 @@ STATUS onSetStunServerIp(UINT64 customData, PCHAR url, PDualKvsIpAddresses pIpAd CHK_ERR(getStunAddr(pWebRtcClientContext->pStunIpAddrCtx) == STATUS_SUCCESS, retStatus, "Failed to resolve after cache expiry"); } MEMCPY(pIpAddresses, &pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address, SIZEOF(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address)); + MEMCPY(pIpAddresses, &pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address, SIZEOF(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address)); } else { DLOGE("Initialization failed"); } @@ -906,7 +906,8 @@ PVOID resolveStunIceServerIp(PVOID args) UNUSED_PARAM(args); PWebRtcClientContext pWebRtcClientContext = getWebRtcClientInstance(); BOOL locked = FALSE; - CHAR addressResolved[KVS_IP_ADDRESS_STRING_BUFFER_LEN + 1] = {'\0'}; + CHAR addressResolvedIPv4[KVS_IP_ADDRESS_STRING_BUFFER_LEN + 1] = {'\0'}; + CHAR addressResolvedIPv6[KVS_IP_ADDRESS_STRING_BUFFER_LEN + 1] = {'\0'}; PCHAR pRegion; PCHAR pHostnamePostfix; UINT64 stunDnsResolutionStartTime = 0; @@ -932,9 +933,20 @@ PVOID resolveStunIceServerIp(PVOID args) KINESIS_VIDEO_STUN_URL_WITHOUT_PORT, pRegion, pHostnamePostfix); stunDnsResolutionStartTime = GETTIME(); if (getStunAddr(pWebRtcClientContext->pStunIpAddrCtx) == STATUS_SUCCESS) { - getIpAddrStr(&pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address, addressResolved, ARRAY_SIZE(addressResolved)); - DLOGI("ICE Server address for %s with getaddrinfo: %s", pWebRtcClientContext->pStunIpAddrCtx->hostname, addressResolved); - pWebRtcClientContext->pStunIpAddrCtx->isIpInitialized = TRUE; + if(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address.family == KVS_IP_FAMILY_TYPE_IPV4) { + // If IP family is set, then there must have been an IPv4 address resolved. + getIpAddrStr(&pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address, addressResolvedIPv4, ARRAY_SIZE(addressResolvedIPv4)); + DLOGI("ICE Server address for %s with getaddrinfo: %s", pWebRtcClientContext->pStunIpAddrCtx->hostname, addressResolvedIPv4); + pWebRtcClientContext->pStunIpAddrCtx->isIpInitialized = TRUE; + } + if(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address.family == KVS_IP_FAMILY_TYPE_IPV4) { + // If IP family is set, then there must have been an IPv6 address resolved. + getIpAddrStr(&pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address, addressResolvedIPv6, ARRAY_SIZE(addressResolvedIPv6)); + DLOGI("ICE Server address for %s with getaddrinfo: %s", pWebRtcClientContext->pStunIpAddrCtx->hostname, addressResolvedIPv6); + pWebRtcClientContext->pStunIpAddrCtx->isIpInitialized = TRUE; + + } + } else { DLOGE("Failed to resolve %s", pWebRtcClientContext->pStunIpAddrCtx->hostname); } From bb1a9307f315dd2cfd7469f00e17705a8b34bca0 Mon Sep 17 00:00:00 2001 From: Stefan Kieszkowski <85728496+stefankiesz@users.noreply.github.com> Date: Tue, 29 Apr 2025 06:27:25 -0700 Subject: [PATCH 03/10] Fixup unit tests --- tst/IceFunctionalityTest.cpp | 2 +- tst/NetworkApiTest.cpp | 16 ++++++++-------- tst/TurnConnectionFunctionalityTest.cpp | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tst/IceFunctionalityTest.cpp b/tst/IceFunctionalityTest.cpp index 3a27b6324b..1c9d5fc8cf 100644 --- a/tst/IceFunctionalityTest.cpp +++ b/tst/IceFunctionalityTest.cpp @@ -305,7 +305,7 @@ TEST_F(IceFunctionalityTest, IceAgentIceAgentAddIceServerUnitTest) EXPECT_EQ(STATUS_SUCCESS, parseIceServer(&iceServer, (PCHAR) "turn:54.202.170.151:443?transport=udp", (PCHAR) "username", (PCHAR) "password")); EXPECT_TRUE(!iceServer.isSecure); EXPECT_EQ(iceServer.transport, KVS_SOCKET_PROTOCOL_UDP); - EXPECT_EQ(443, (UINT16) getInt16(iceServer.ipAddress.port)); + EXPECT_EQ(443, (UINT16) getInt16(iceServer.ipAddresses.ipv4Address.port)); /* we are not doing full validation. Only parsing out what we know */ EXPECT_EQ(STATUS_SUCCESS, parseIceServer(&iceServer, (PCHAR) "turn:54.202.170.151:443?randomstuff", (PCHAR) "username", (PCHAR) "password")); diff --git a/tst/NetworkApiTest.cpp b/tst/NetworkApiTest.cpp index c5702a61c6..01697f3b3d 100644 --- a/tst/NetworkApiTest.cpp +++ b/tst/NetworkApiTest.cpp @@ -11,14 +11,14 @@ class NetworkApiTest : public WebRtcClientTestBase { TEST_F(NetworkApiTest, GetIpWithHostNameTest) { - KvsIpAddress ipAddress; - EXPECT_EQ(STATUS_NULL_ARG, getIpWithHostName(NULL, &ipAddress)); - EXPECT_EQ(STATUS_RESOLVE_HOSTNAME_FAILED, getIpWithHostName((PCHAR) "stun:stun.test.net:3478", &ipAddress)); - EXPECT_EQ(STATUS_SUCCESS, getIpWithHostName((PCHAR) "35-90-63-38.t-ae7dd61a.kinesisvideo.us-west-2.amazonaws.com", &ipAddress)); - EXPECT_EQ(STATUS_SUCCESS, getIpWithHostName((PCHAR) "12.34.45.40", &ipAddress)); - EXPECT_EQ(STATUS_SUCCESS, getIpWithHostName((PCHAR) "2001:0db8:85a3:0000:0000:8a2e:0370:7334", &ipAddress)); - EXPECT_EQ(STATUS_RESOLVE_HOSTNAME_FAILED, getIpWithHostName((PCHAR) ".12.34.45.40", &ipAddress)); - EXPECT_EQ(STATUS_RESOLVE_HOSTNAME_FAILED, getIpWithHostName((PCHAR) "...........", &ipAddress)); + DualKvsIpAddresses ipAddresses; + EXPECT_EQ(STATUS_NULL_ARG, getIpWithHostName(NULL, &ipAddresses)); + EXPECT_EQ(STATUS_RESOLVE_HOSTNAME_FAILED, getIpWithHostName((PCHAR) "stun:stun.test.net:3478", &ipAddresses)); + EXPECT_EQ(STATUS_SUCCESS, getIpWithHostName((PCHAR) "35-90-63-38.t-ae7dd61a.kinesisvideo.us-west-2.amazonaws.com", &ipAddresses)); + EXPECT_EQ(STATUS_SUCCESS, getIpWithHostName((PCHAR) "12.34.45.40", &ipAddresses)); + EXPECT_EQ(STATUS_SUCCESS, getIpWithHostName((PCHAR) "2001:0db8:85a3:0000:0000:8a2e:0370:7334", &ipAddresses)); + EXPECT_EQ(STATUS_RESOLVE_HOSTNAME_FAILED, getIpWithHostName((PCHAR) ".12.34.45.40", &ipAddresses)); + EXPECT_EQ(STATUS_RESOLVE_HOSTNAME_FAILED, getIpWithHostName((PCHAR) "...........", &ipAddresses)); } TEST_F(NetworkApiTest, ipIpAddrTest) diff --git a/tst/TurnConnectionFunctionalityTest.cpp b/tst/TurnConnectionFunctionalityTest.cpp index da2914cd63..42a158b42a 100644 --- a/tst/TurnConnectionFunctionalityTest.cpp +++ b/tst/TurnConnectionFunctionalityTest.cpp @@ -52,7 +52,7 @@ class TurnConnectionFunctionalityTest : public WebRtcClientTestBase { EXPECT_EQ(STATUS_SUCCESS, getLocalhostIpAddresses(localIpInterfaces, &localIpInterfaceCount, NULL, 0)); for (i = 0; i < localIpInterfaceCount; ++i) { - if (localIpInterfaces[i].family == pTurnServer->ipAddress.family && (pTurnSocketAddr == NULL || localIpInterfaces[i].isPointToPoint)) { + if (localIpInterfaces[i].family == pTurnServer->ipAddresses.ipv4Address.family && (pTurnSocketAddr == NULL || localIpInterfaces[i].isPointToPoint)) { pTurnSocketAddr = &localIpInterfaces[i]; } } @@ -69,8 +69,8 @@ class TurnConnectionFunctionalityTest : public WebRtcClientTestBase { return STATUS_SUCCESS; }; EXPECT_EQ(STATUS_SUCCESS, - createSocketConnection((KVS_IP_FAMILY_TYPE) pTurnServer->ipAddress.family, KVS_ICE_DEFAULT_TURN_PROTOCOL, NULL, - &pTurnServer->ipAddress, (UINT64) this, onDataHandler, 0, &pTurnSocket)); + createSocketConnection((KVS_IP_FAMILY_TYPE) pTurnServer->ipAddresses.ipv4Address.family, KVS_ICE_DEFAULT_TURN_PROTOCOL, NULL, + &pTurnServer->ipAddresses.ipv4Address, (UINT64) this, onDataHandler, 0, &pTurnSocket)); EXPECT_EQ(STATUS_SUCCESS, connectionListenerAddConnection(pConnectionListener, pTurnSocket)); ASSERT_EQ(STATUS_SUCCESS, createTurnConnection(pTurnServer, timerQueueHandle, TURN_CONNECTION_DATA_TRANSFER_MODE_DATA_CHANNEL, KVS_ICE_DEFAULT_TURN_PROTOCOL, From da0811f42baf8059681b218bbaa906c353cffa7f Mon Sep 17 00:00:00 2001 From: Stefan Kieszkowski <85728496+stefankiesz@users.noreply.github.com> Date: Tue, 29 Apr 2025 06:52:25 -0700 Subject: [PATCH 04/10] Cleanup --- src/source/Ice/IceAgent.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/source/Ice/IceAgent.c b/src/source/Ice/IceAgent.c index 6b8632b473..25b84b0826 100644 --- a/src/source/Ice/IceAgent.c +++ b/src/source/Ice/IceAgent.c @@ -1466,7 +1466,7 @@ STATUS iceAgentSendSrflxCandidateRequest(PIceAgent pIceAgent) transactionIdStoreInsert(pIceAgent->pStunBindingRequestTransactionIdStore, pBindingRequest->header.transactionId); checkSum = COMPUTE_CRC32(pBindingRequest->header.transactionId, ARRAY_SIZE(pBindingRequest->header.transactionId)); - DLOGD("[TEST] Sending STUN binding request to IPv4 STUN server: %u:%u", pIceServer->ipAddresses.ipv4Address.address, pIceServer->ipAddresses.ipv4Address.port); + DLOGD("Sending STUN binding request to IPv4 STUN server: %u:%u", pIceServer->ipAddresses.ipv4Address.address, pIceServer->ipAddresses.ipv4Address.port); CHK_STATUS(iceAgentSendStunPacket(pBindingRequest, NULL, 0, pIceAgent, pCandidate, &pIceServer->ipAddresses.ipv4Address)); if (pIceAgent->pRtcIceServerDiagnostics[pCandidate->iceServerIndex] != NULL) { @@ -1481,7 +1481,7 @@ STATUS iceAgentSendSrflxCandidateRequest(PIceAgent pIceAgent) transactionIdStoreInsert(pIceAgent->pStunBindingRequestTransactionIdStore, pBindingRequest->header.transactionId); checkSum = COMPUTE_CRC32(pBindingRequest->header.transactionId, ARRAY_SIZE(pBindingRequest->header.transactionId)); - DLOGD("[TEST] Sending STUN binding request to IPv6 STUN server: %u:%u", pIceServer->ipAddresses.ipv6Address.address, pIceServer->ipAddresses.ipv6Address.port); + DLOGD("Sending STUN binding request to IPv6 STUN server: %u:%u", pIceServer->ipAddresses.ipv6Address.address, pIceServer->ipAddresses.ipv6Address.port); CHK_STATUS(iceAgentSendStunPacket(pBindingRequest, NULL, 0, pIceAgent, pCandidate, &pIceServer->ipAddresses.ipv6Address)); if (pIceAgent->pRtcIceServerDiagnostics[pCandidate->iceServerIndex] != NULL) { From f1d60ad75e76068b89b0f43ef40b38274570db85 Mon Sep 17 00:00:00 2001 From: Stefan Kieszkowski <85728496+stefankiesz@users.noreply.github.com> Date: Wed, 30 Apr 2025 13:33:41 -0700 Subject: [PATCH 05/10] Address some comments --- src/source/Ice/IceUtils.c | 2 +- src/source/Ice/Network.c | 14 ++++++++++++-- src/source/Include_i.h | 1 + src/source/PeerConnection/PeerConnection.c | 17 +++++++++++------ 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/source/Ice/IceUtils.c b/src/source/Ice/IceUtils.c index 514f08af1e..4d51ac79e1 100644 --- a/src/source/Ice/IceUtils.c +++ b/src/source/Ice/IceUtils.c @@ -170,7 +170,7 @@ STATUS iceUtilsSendStunPacket(PStunPacket pStunPacket, PBYTE password, UINT32 pa CHAR ipAddrStr[KVS_IP_ADDRESS_STRING_BUFFER_LEN]; - getIpAddrStr(pDest, ipAddrStr, ARRAY_SIZE(ipAddrStr)); + CHK_STATUS(getIpAddrStr(pDest, ipAddrStr, ARRAY_SIZE(ipAddrStr))); CHK_STATUS(iceUtilsPackageStunPacket(pStunPacket, password, passwordLen, stunPacketBuffer, &stunPacketSize)); CHK(pDest != NULL, STATUS_NULL_ARG); diff --git a/src/source/Ice/Network.c b/src/source/Ice/Network.c index 83c718249b..cdab06ef98 100644 --- a/src/source/Ice/Network.c +++ b/src/source/Ice/Network.c @@ -405,6 +405,8 @@ STATUS getIpWithHostName(PCHAR hostname, PDualKvsIpAddresses destIps) struct sockaddr_in* ipv4Addr; struct sockaddr_in6* ipv6Addr; struct in_addr inaddr; + CHAR ipv4AddrStr[KVS_IP_ADDRESS_STRING_BUFFER_LEN]; + CHAR ipv6AddrStr[KVS_IP_ADDRESS_STRING_BUFFER_LEN]; CHAR addr[KVS_IP_ADDRESS_STRING_BUFFER_LEN + 1] = {'\0'}; @@ -433,18 +435,26 @@ STATUS getIpWithHostName(PCHAR hostname, PDualKvsIpAddresses destIps) } for (rp = res; rp != NULL && !(ipv4Resolved && ipv6Resolved); rp = rp->ai_next) { if (rp->ai_family == AF_INET) { - DLOGD("Found an IPv4 ICE server addresss"); ipv4Addr = (struct sockaddr_in*) rp->ai_addr; destIps->ipv4Address.family = KVS_IP_FAMILY_TYPE_IPV4; // TODO: Should also init port to 0, or no (we do in the threadpool-enabled version of this call for STUN)? MEMCPY(destIps->ipv4Address.address, &ipv4Addr->sin_addr, IPV4_ADDRESS_LENGTH); + + CHK_STATUS(getIpAddrStr(&(destIps->ipv4Address), ipv4AddrStr, ARRAY_SIZE(ipv4AddrStr))); + DLOGD("Found an IPv4 ICE server addresss: %s", ipv4AddrStr); + ipv4Resolved = TRUE; + } else if (rp->ai_family == AF_INET6) { - DLOGD("Found an IPv6 ICE server addresss"); ipv6Addr = (struct sockaddr_in6*) rp->ai_addr; destIps->ipv6Address.family = KVS_IP_FAMILY_TYPE_IPV6; MEMCPY(destIps->ipv6Address.address, &ipv6Addr->sin6_addr, IPV6_ADDRESS_LENGTH); + + CHK_STATUS(getIpAddrStr(&(destIps->ipv6Address), ipv6AddrStr, ARRAY_SIZE(ipv6AddrStr))); + DLOGD("Found an IPv6 ICE server addresss: %s", ipv6AddrStr); + ipv6Resolved = TRUE; + } else { DLOGD("Found an invalid ICE server addresss family type - must be IPv4 or IPv6."); } diff --git a/src/source/Include_i.h b/src/source/Include_i.h index 0cc540461d..f704d7b991 100644 --- a/src/source/Include_i.h +++ b/src/source/Include_i.h @@ -92,6 +92,7 @@ extern "C" { #define MAX_UDP_PACKET_SIZE 65507 typedef enum { + KVS_IP_FAMILY_TYPE_UNKNOWN = (UINT16) 0x0000, KVS_IP_FAMILY_TYPE_IPV4 = (UINT16) 0x0001, KVS_IP_FAMILY_TYPE_IPV6 = (UINT16) 0x0002, } KVS_IP_FAMILY_TYPE; diff --git a/src/source/PeerConnection/PeerConnection.c b/src/source/PeerConnection/PeerConnection.c index 8e249f525e..bde27c6310 100644 --- a/src/source/PeerConnection/PeerConnection.c +++ b/src/source/PeerConnection/PeerConnection.c @@ -814,6 +814,13 @@ STATUS getStunAddr(PStunIpAddrContext pStunIpAddrCtx) // # if not defined (USE_DUAL_STACK_CANDIDATES) // ipv6Resolved = TRUE; + // Initialize IP address families to a sentinel value + // to indicate that they are not set. + pStunIpAddrCtx->kvsIpAddresses.ipv4Address.family = KVS_IP_FAMILY_TYPE_UNKNOWN; + pStunIpAddrCtx->kvsIpAddresses.ipv6Address.family = KVS_IP_FAMILY_TYPE_UNKNOWN; + pStunIpAddrCtx->kvsIpAddresses.ipv4Address.port = 0; + pStunIpAddrCtx->kvsIpAddresses.ipv6Address.port = 0; + DLOGD("Resolving STUN server address for hostname: %s", pStunIpAddrCtx->hostname); errCode = getaddrinfo(pStunIpAddrCtx->hostname, NULL, NULL, &res); @@ -826,14 +833,12 @@ STATUS getStunAddr(PStunIpAddrContext pStunIpAddrCtx) DLOGD("Found an IPv4 STUN addresss for hostname: %s", pStunIpAddrCtx->hostname); ipv4Addr = (struct sockaddr_in*) rp->ai_addr; pStunIpAddrCtx->kvsIpAddresses.ipv4Address.family = KVS_IP_FAMILY_TYPE_IPV4; - pStunIpAddrCtx->kvsIpAddresses.ipv4Address.port = 0; MEMCPY(pStunIpAddrCtx->kvsIpAddresses.ipv4Address.address, &ipv4Addr->sin_addr, IPV4_ADDRESS_LENGTH); ipv4Resolved = TRUE; } else if (!ipv6Resolved && rp->ai_family == AF_INET6) { DLOGD("Found an IPv6 STUN addresss for hostname: %s", pStunIpAddrCtx->hostname); ipv6Addr = (struct sockaddr_in6*) rp->ai_addr; pStunIpAddrCtx->kvsIpAddresses.ipv6Address.family = KVS_IP_FAMILY_TYPE_IPV6; - pStunIpAddrCtx->kvsIpAddresses.ipv6Address.port = 0; MEMCPY(pStunIpAddrCtx->kvsIpAddresses.ipv6Address.address, &ipv6Addr->sin6_addr, IPV6_ADDRESS_LENGTH); ipv6Resolved = TRUE; } else { @@ -933,14 +938,14 @@ PVOID resolveStunIceServerIp(PVOID args) KINESIS_VIDEO_STUN_URL_WITHOUT_PORT, pRegion, pHostnamePostfix); stunDnsResolutionStartTime = GETTIME(); if (getStunAddr(pWebRtcClientContext->pStunIpAddrCtx) == STATUS_SUCCESS) { - if(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address.family == KVS_IP_FAMILY_TYPE_IPV4) { - // If IP family is set, then there must have been an IPv4 address resolved. + if(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address.family != KVS_IP_FAMILY_TYPE_UNKNOWN) { + // If the IPv4 family is set, then there must have been an IPv4 address resolved. getIpAddrStr(&pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address, addressResolvedIPv4, ARRAY_SIZE(addressResolvedIPv4)); DLOGI("ICE Server address for %s with getaddrinfo: %s", pWebRtcClientContext->pStunIpAddrCtx->hostname, addressResolvedIPv4); pWebRtcClientContext->pStunIpAddrCtx->isIpInitialized = TRUE; } - if(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address.family == KVS_IP_FAMILY_TYPE_IPV4) { - // If IP family is set, then there must have been an IPv6 address resolved. + if(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address.family != KVS_IP_FAMILY_TYPE_UNKNOWN) { + // If the IPv6 family is set, then there must have been an IPv6 address resolved. getIpAddrStr(&pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address, addressResolvedIPv6, ARRAY_SIZE(addressResolvedIPv6)); DLOGI("ICE Server address for %s with getaddrinfo: %s", pWebRtcClientContext->pStunIpAddrCtx->hostname, addressResolvedIPv6); pWebRtcClientContext->pStunIpAddrCtx->isIpInitialized = TRUE; From 4db0874df12213078567732a56ef3e9686ba0f8d Mon Sep 17 00:00:00 2001 From: Stefan Kieszkowski <85728496+stefankiesz@users.noreply.github.com> Date: Wed, 30 Apr 2025 13:37:23 -0700 Subject: [PATCH 06/10] Update IP family sentinel value name --- src/source/Include_i.h | 6 +++--- src/source/PeerConnection/PeerConnection.c | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/source/Include_i.h b/src/source/Include_i.h index f704d7b991..cfc7d84ce1 100644 --- a/src/source/Include_i.h +++ b/src/source/Include_i.h @@ -92,9 +92,9 @@ extern "C" { #define MAX_UDP_PACKET_SIZE 65507 typedef enum { - KVS_IP_FAMILY_TYPE_UNKNOWN = (UINT16) 0x0000, - KVS_IP_FAMILY_TYPE_IPV4 = (UINT16) 0x0001, - KVS_IP_FAMILY_TYPE_IPV6 = (UINT16) 0x0002, + KVS_IP_FAMILY_TYPE_NOT_SET = (UINT16) 0x0000, // Sentinel value for not yet set IP address. + KVS_IP_FAMILY_TYPE_IPV4 = (UINT16) 0x0001, + KVS_IP_FAMILY_TYPE_IPV6 = (UINT16) 0x0002, } KVS_IP_FAMILY_TYPE; typedef struct { diff --git a/src/source/PeerConnection/PeerConnection.c b/src/source/PeerConnection/PeerConnection.c index bde27c6310..ff0b9ff5ab 100644 --- a/src/source/PeerConnection/PeerConnection.c +++ b/src/source/PeerConnection/PeerConnection.c @@ -816,8 +816,8 @@ STATUS getStunAddr(PStunIpAddrContext pStunIpAddrCtx) // Initialize IP address families to a sentinel value // to indicate that they are not set. - pStunIpAddrCtx->kvsIpAddresses.ipv4Address.family = KVS_IP_FAMILY_TYPE_UNKNOWN; - pStunIpAddrCtx->kvsIpAddresses.ipv6Address.family = KVS_IP_FAMILY_TYPE_UNKNOWN; + pStunIpAddrCtx->kvsIpAddresses.ipv4Address.family = KVS_IP_FAMILY_TYPE_NOT_SET; + pStunIpAddrCtx->kvsIpAddresses.ipv6Address.family = KVS_IP_FAMILY_TYPE_NOT_SET; pStunIpAddrCtx->kvsIpAddresses.ipv4Address.port = 0; pStunIpAddrCtx->kvsIpAddresses.ipv6Address.port = 0; @@ -938,13 +938,13 @@ PVOID resolveStunIceServerIp(PVOID args) KINESIS_VIDEO_STUN_URL_WITHOUT_PORT, pRegion, pHostnamePostfix); stunDnsResolutionStartTime = GETTIME(); if (getStunAddr(pWebRtcClientContext->pStunIpAddrCtx) == STATUS_SUCCESS) { - if(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address.family != KVS_IP_FAMILY_TYPE_UNKNOWN) { + if(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address.family != KVS_IP_FAMILY_TYPE_NOT_SET) { // If the IPv4 family is set, then there must have been an IPv4 address resolved. getIpAddrStr(&pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address, addressResolvedIPv4, ARRAY_SIZE(addressResolvedIPv4)); DLOGI("ICE Server address for %s with getaddrinfo: %s", pWebRtcClientContext->pStunIpAddrCtx->hostname, addressResolvedIPv4); pWebRtcClientContext->pStunIpAddrCtx->isIpInitialized = TRUE; } - if(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address.family != KVS_IP_FAMILY_TYPE_UNKNOWN) { + if(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address.family != KVS_IP_FAMILY_TYPE_NOT_SET) { // If the IPv6 family is set, then there must have been an IPv6 address resolved. getIpAddrStr(&pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address, addressResolvedIPv6, ARRAY_SIZE(addressResolvedIPv6)); DLOGI("ICE Server address for %s with getaddrinfo: %s", pWebRtcClientContext->pStunIpAddrCtx->hostname, addressResolvedIPv6); From f3c48a2bbd4f0407abbcfcd091e659495ce8c3d1 Mon Sep 17 00:00:00 2001 From: Stefan Kieszkowski <85728496+stefankiesz@users.noreply.github.com> Date: Wed, 30 Apr 2025 19:37:36 -0700 Subject: [PATCH 07/10] Fix typoed memcopy --- src/source/PeerConnection/PeerConnection.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/source/PeerConnection/PeerConnection.c b/src/source/PeerConnection/PeerConnection.c index ff0b9ff5ab..ace49ad5ca 100644 --- a/src/source/PeerConnection/PeerConnection.c +++ b/src/source/PeerConnection/PeerConnection.c @@ -887,8 +887,8 @@ STATUS onSetStunServerIp(UINT64 customData, PCHAR url, PDualKvsIpAddresses pIpAd pWebRtcClientContext->pStunIpAddrCtx->startTime = 0; CHK_ERR(getStunAddr(pWebRtcClientContext->pStunIpAddrCtx) == STATUS_SUCCESS, retStatus, "Failed to resolve after cache expiry"); } - MEMCPY(pIpAddresses, &pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address, SIZEOF(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address)); - MEMCPY(pIpAddresses, &pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address, SIZEOF(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address)); + MEMCPY(pIpAddresses->ipv4Address.address, &pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address, SIZEOF(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address)); + MEMCPY(pIpAddresses->ipv6Address.address, &pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address, SIZEOF(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address)); } else { DLOGE("Initialization failed"); } From 59d3bc6f2befe3d2e380453b62b941c8e68423d3 Mon Sep 17 00:00:00 2001 From: Stefan Kieszkowski <85728496+stefankiesz@users.noreply.github.com> Date: Wed, 30 Apr 2025 20:13:50 -0700 Subject: [PATCH 08/10] Don't log non-resolved IP addresses, cleanup comments --- src/source/Ice/IceUtils.c | 22 +++++++++++++--------- src/source/PeerConnection/PeerConnection.c | 4 ---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/source/Ice/IceUtils.c b/src/source/Ice/IceUtils.c index 4d51ac79e1..8b5a1ee946 100644 --- a/src/source/Ice/IceUtils.c +++ b/src/source/Ice/IceUtils.c @@ -280,15 +280,19 @@ STATUS parseIceServer(PIceServer pIceServer, PCHAR url, PCHAR username, PCHAR cr CHK_STATUS(getIpWithHostName(pIceServer->url, &pIceServer->ipAddresses)); } - DLOGD("Setting port to %u", port); - pIceServer->ipAddresses.ipv4Address.port = (UINT16) getInt16((INT16) port); - getIpAddrStr(&pIceServer->ipAddresses.ipv4Address, addressResolvedIPv4, ARRAY_SIZE(addressResolvedIPv4)); - DLOGP("ICE Server IPv4 address for %s: %s", pIceServer->url, addressResolvedIPv4); - - pIceServer->ipAddresses.ipv6Address.port = (UINT16) getInt16((INT16) port); - getIpAddrStr(&pIceServer->ipAddresses.ipv6Address, addressResolvedIPv6, ARRAY_SIZE(addressResolvedIPv6)); - DLOGP("ICE Server IPv6 address for %s: %s", pIceServer->url, addressResolvedIPv6); - + if(pIceServer->ipAddresses.ipv4Address.family != KVS_IP_FAMILY_TYPE_NOT_SET) { + pIceServer->ipAddresses.ipv4Address.port = (UINT16) getInt16((INT16) port); + getIpAddrStr(&pIceServer->ipAddresses.ipv4Address, addressResolvedIPv4, ARRAY_SIZE(addressResolvedIPv4)); + DLOGP("Resolved ICE Server IPv4 address for %s: %s", pIceServer->url, addressResolvedIPv4); + DLOGP("...with port: %u", pIceServer->ipAddresses.ipv4Address.port); + } + + if (pIceServer->ipAddresses.ipv6Address.family != KVS_IP_FAMILY_TYPE_NOT_SET) { + pIceServer->ipAddresses.ipv6Address.port = (UINT16) getInt16((INT16) port); + getIpAddrStr(&pIceServer->ipAddresses.ipv6Address, addressResolvedIPv6, ARRAY_SIZE(addressResolvedIPv6)); + DLOGP("Resolved ICE Server IPv6 address for %s: %s", pIceServer->url, addressResolvedIPv6); + DLOGP("...with port: %u", pIceServer->ipAddresses.ipv6Address.port); + } CleanUp: diff --git a/src/source/PeerConnection/PeerConnection.c b/src/source/PeerConnection/PeerConnection.c index ace49ad5ca..afad341160 100644 --- a/src/source/PeerConnection/PeerConnection.c +++ b/src/source/PeerConnection/PeerConnection.c @@ -810,10 +810,6 @@ STATUS getStunAddr(PStunIpAddrContext pStunIpAddrCtx) BOOL ipv4Resolved = FALSE; BOOL ipv6Resolved = FALSE; - // To speed up connection for non-dual stack candidates,ignore IPv6. - // # if not defined (USE_DUAL_STACK_CANDIDATES) - // ipv6Resolved = TRUE; - // Initialize IP address families to a sentinel value // to indicate that they are not set. pStunIpAddrCtx->kvsIpAddresses.ipv4Address.family = KVS_IP_FAMILY_TYPE_NOT_SET; From c0c5b16740d8601a970d46641f3e7cc3577ac96c Mon Sep 17 00:00:00 2001 From: Stefan Kieszkowski <85728496+stefankiesz@users.noreply.github.com> Date: Wed, 30 Apr 2025 20:15:35 -0700 Subject: [PATCH 09/10] Clang format, remove a comment --- src/source/Ice/IceAgent.c | 12 ++++++++---- src/source/Ice/IceUtils.c | 8 ++++---- src/source/Ice/NatBehaviorDiscovery.c | 8 ++++---- src/source/Ice/Network.c | 5 ++--- src/source/Ice/TurnConnectionStateMachine.c | 4 ++-- src/source/Include_i.h | 4 ++-- src/source/PeerConnection/PeerConnection.c | 18 ++++++++++-------- 7 files changed, 32 insertions(+), 27 deletions(-) diff --git a/src/source/Ice/IceAgent.c b/src/source/Ice/IceAgent.c index 25b84b0826..0628bf1602 100644 --- a/src/source/Ice/IceAgent.c +++ b/src/source/Ice/IceAgent.c @@ -1466,7 +1466,8 @@ STATUS iceAgentSendSrflxCandidateRequest(PIceAgent pIceAgent) transactionIdStoreInsert(pIceAgent->pStunBindingRequestTransactionIdStore, pBindingRequest->header.transactionId); checkSum = COMPUTE_CRC32(pBindingRequest->header.transactionId, ARRAY_SIZE(pBindingRequest->header.transactionId)); - DLOGD("Sending STUN binding request to IPv4 STUN server: %u:%u", pIceServer->ipAddresses.ipv4Address.address, pIceServer->ipAddresses.ipv4Address.port); + DLOGD("Sending STUN binding request to IPv4 STUN server: %u:%u", pIceServer->ipAddresses.ipv4Address.address, + pIceServer->ipAddresses.ipv4Address.port); CHK_STATUS(iceAgentSendStunPacket(pBindingRequest, NULL, 0, pIceAgent, pCandidate, &pIceServer->ipAddresses.ipv4Address)); if (pIceAgent->pRtcIceServerDiagnostics[pCandidate->iceServerIndex] != NULL) { @@ -1481,7 +1482,8 @@ STATUS iceAgentSendSrflxCandidateRequest(PIceAgent pIceAgent) transactionIdStoreInsert(pIceAgent->pStunBindingRequestTransactionIdStore, pBindingRequest->header.transactionId); checkSum = COMPUTE_CRC32(pBindingRequest->header.transactionId, ARRAY_SIZE(pBindingRequest->header.transactionId)); - DLOGD("Sending STUN binding request to IPv6 STUN server: %u:%u", pIceServer->ipAddresses.ipv6Address.address, pIceServer->ipAddresses.ipv6Address.port); + DLOGD("Sending STUN binding request to IPv6 STUN server: %u:%u", pIceServer->ipAddresses.ipv6Address.address, + pIceServer->ipAddresses.ipv6Address.port); CHK_STATUS(iceAgentSendStunPacket(pBindingRequest, NULL, 0, pIceAgent, pCandidate, &pIceServer->ipAddresses.ipv6Address)); if (pIceAgent->pRtcIceServerDiagnostics[pCandidate->iceServerIndex] != NULL) { @@ -1780,7 +1782,9 @@ STATUS iceAgentInitSrflxCandidate(PIceAgent pIceAgent) if (pCandidate->iceCandidateType == ICE_CANDIDATE_TYPE_HOST) { for (j = 0; j < pIceAgent->iceServersCount; j++) { pIceServer = &pIceAgent->iceServers[j]; - if (!pIceServer->isTurn && (pIceServer->ipAddresses.ipv4Address.family == pCandidate->ipAddress.family || pIceServer->ipAddresses.ipv6Address.family == pCandidate->ipAddress.family)) { + if (!pIceServer->isTurn && + (pIceServer->ipAddresses.ipv4Address.family == pCandidate->ipAddress.family || + pIceServer->ipAddresses.ipv6Address.family == pCandidate->ipAddress.family)) { CHK((pNewCandidate = (PIceCandidate) MEMCALLOC(1, SIZEOF(IceCandidate))) != NULL, STATUS_NOT_ENOUGH_MEMORY); generateJSONSafeString(pNewCandidate->id, ARRAY_SIZE(pNewCandidate->id)); pNewCandidate->isRemote = FALSE; @@ -1820,7 +1824,7 @@ STATUS iceAgentInitSrflxCandidate(PIceAgent pIceAgent) // the new port will be stored in pNewCandidate->ipAddress.port. And the Ip address will later be updated // with the correct ip address once the STUN response is received. CHK_STATUS(createSocketConnection(pCandidate->ipAddress.family, KVS_SOCKET_PROTOCOL_UDP, &pCandidate->ipAddress, NULL, (UINT64) pIceAgent, - incomingDataHandler, pIceAgent->kvsRtcConfiguration.sendBufSize, &pCandidate->pSocketConnection)); + incomingDataHandler, pIceAgent->kvsRtcConfiguration.sendBufSize, &pCandidate->pSocketConnection)); ATOMIC_STORE_BOOL(&pCandidate->pSocketConnection->receiveData, TRUE); // connectionListener will free the pSocketConnection at the end. CHK_STATUS(connectionListenerAddConnection(pIceAgent->pConnectionListener, pCandidate->pSocketConnection)); diff --git a/src/source/Ice/IceUtils.c b/src/source/Ice/IceUtils.c index 8b5a1ee946..ee0abfd0ec 100644 --- a/src/source/Ice/IceUtils.c +++ b/src/source/Ice/IceUtils.c @@ -176,10 +176,10 @@ STATUS iceUtilsSendStunPacket(PStunPacket pStunPacket, PBYTE password, UINT32 pa CHK(pDest != NULL, STATUS_NULL_ARG); switch (pStunPacket->header.stunMessageType) { case STUN_PACKET_TYPE_BINDING_REQUEST: - DLOGD("Sending BINDING_REQUEST to ip:%s, port:%u",ipAddrStr,(UINT16) getInt16(pDest->port)); + DLOGD("Sending BINDING_REQUEST to ip:%s, port:%u", ipAddrStr, (UINT16) getInt16(pDest->port)); break; case STUN_PACKET_TYPE_BINDING_RESPONSE_SUCCESS: - DLOGD("Sending BINDING_RESPONSE_SUCCESS to ip:%s, port:%u",ipAddrStr,(UINT16) getInt16(pDest->port)); + DLOGD("Sending BINDING_RESPONSE_SUCCESS to ip:%s, port:%u", ipAddrStr, (UINT16) getInt16(pDest->port)); break; default: break; @@ -280,12 +280,12 @@ STATUS parseIceServer(PIceServer pIceServer, PCHAR url, PCHAR username, PCHAR cr CHK_STATUS(getIpWithHostName(pIceServer->url, &pIceServer->ipAddresses)); } - if(pIceServer->ipAddresses.ipv4Address.family != KVS_IP_FAMILY_TYPE_NOT_SET) { + if (pIceServer->ipAddresses.ipv4Address.family != KVS_IP_FAMILY_TYPE_NOT_SET) { pIceServer->ipAddresses.ipv4Address.port = (UINT16) getInt16((INT16) port); getIpAddrStr(&pIceServer->ipAddresses.ipv4Address, addressResolvedIPv4, ARRAY_SIZE(addressResolvedIPv4)); DLOGP("Resolved ICE Server IPv4 address for %s: %s", pIceServer->url, addressResolvedIPv4); DLOGP("...with port: %u", pIceServer->ipAddresses.ipv4Address.port); - } + } if (pIceServer->ipAddresses.ipv6Address.family != KVS_IP_FAMILY_TYPE_NOT_SET) { pIceServer->ipAddresses.ipv6Address.port = (UINT16) getInt16((INT16) port); diff --git a/src/source/Ice/NatBehaviorDiscovery.c b/src/source/Ice/NatBehaviorDiscovery.c index 9d664a6830..b48d8dee3a 100644 --- a/src/source/Ice/NatBehaviorDiscovery.c +++ b/src/source/Ice/NatBehaviorDiscovery.c @@ -298,8 +298,8 @@ STATUS discoverNatBehavior(PCHAR stunServer, NAT_BEHAVIOR* pNatMappingBehavior, } CHK_WARN(pSelectedLocalInterface != NULL, retStatus, "No usable local interface"); - CHK_STATUS(createSocketConnection(iceServerStun.ipAddresses.ipv4Address.family, KVS_SOCKET_PROTOCOL_UDP, pSelectedLocalInterface, NULL, (UINT64) &customData, - natTestIncomingDataHandler, 0, &pSocketConnection)); + CHK_STATUS(createSocketConnection(iceServerStun.ipAddresses.ipv4Address.family, KVS_SOCKET_PROTOCOL_UDP, pSelectedLocalInterface, NULL, + (UINT64) &customData, natTestIncomingDataHandler, 0, &pSocketConnection)); ATOMIC_STORE_BOOL(&pSocketConnection->receiveData, TRUE); CHK_STATUS(createConnectionListener(&pConnectionListener)); @@ -322,8 +322,8 @@ STATUS discoverNatBehavior(PCHAR stunServer, NAT_BEHAVIOR* pNatMappingBehavior, CHK_STATUS(connectionListenerRemoveAllConnection(pConnectionListener)); freeSocketConnection(&pSocketConnection); - CHK_STATUS(createSocketConnection(iceServerStun.ipAddresses.ipv4Address.family, KVS_SOCKET_PROTOCOL_UDP, pSelectedLocalInterface, NULL, (UINT64) &customData, - natTestIncomingDataHandler, 0, &pSocketConnection)); + CHK_STATUS(createSocketConnection(iceServerStun.ipAddresses.ipv4Address.family, KVS_SOCKET_PROTOCOL_UDP, pSelectedLocalInterface, NULL, + (UINT64) &customData, natTestIncomingDataHandler, 0, &pSocketConnection)); ATOMIC_STORE_BOOL(&pSocketConnection->receiveData, TRUE); CHK_STATUS(connectionListenerAddConnection(pConnectionListener, pSocketConnection)); diff --git a/src/source/Ice/Network.c b/src/source/Ice/Network.c index cdab06ef98..d900a9245f 100644 --- a/src/source/Ice/Network.c +++ b/src/source/Ice/Network.c @@ -437,12 +437,11 @@ STATUS getIpWithHostName(PCHAR hostname, PDualKvsIpAddresses destIps) if (rp->ai_family == AF_INET) { ipv4Addr = (struct sockaddr_in*) rp->ai_addr; destIps->ipv4Address.family = KVS_IP_FAMILY_TYPE_IPV4; - // TODO: Should also init port to 0, or no (we do in the threadpool-enabled version of this call for STUN)? MEMCPY(destIps->ipv4Address.address, &ipv4Addr->sin_addr, IPV4_ADDRESS_LENGTH); CHK_STATUS(getIpAddrStr(&(destIps->ipv4Address), ipv4AddrStr, ARRAY_SIZE(ipv4AddrStr))); DLOGD("Found an IPv4 ICE server addresss: %s", ipv4AddrStr); - + ipv4Resolved = TRUE; } else if (rp->ai_family == AF_INET6) { @@ -454,7 +453,7 @@ STATUS getIpWithHostName(PCHAR hostname, PDualKvsIpAddresses destIps) DLOGD("Found an IPv6 ICE server addresss: %s", ipv6AddrStr); ipv6Resolved = TRUE; - + } else { DLOGD("Found an invalid ICE server addresss family type - must be IPv4 or IPv6."); } diff --git a/src/source/Ice/TurnConnectionStateMachine.c b/src/source/Ice/TurnConnectionStateMachine.c index 75aa37da8c..2963a9d36b 100644 --- a/src/source/Ice/TurnConnectionStateMachine.c +++ b/src/source/Ice/TurnConnectionStateMachine.c @@ -278,8 +278,8 @@ STATUS executeGetCredentialsTurnState(UINT64 customData, UINT64 time) } else { CHK(currentTime <= pTurnConnection->stateTimeoutTime, STATUS_TURN_CONNECTION_GET_CREDENTIALS_FAILED); } - CHK_STATUS(iceUtilsSendStunPacket(pTurnConnection->pTurnPacket, NULL, 0, &pTurnConnection->turnServer.ipAddresses.ipv4Address, pTurnConnection->pControlChannel, - NULL, FALSE)); + CHK_STATUS(iceUtilsSendStunPacket(pTurnConnection->pTurnPacket, NULL, 0, &pTurnConnection->turnServer.ipAddresses.ipv4Address, + pTurnConnection->pControlChannel, NULL, FALSE)); CleanUp: diff --git a/src/source/Include_i.h b/src/source/Include_i.h index cfc7d84ce1..ffbd328dd2 100644 --- a/src/source/Include_i.h +++ b/src/source/Include_i.h @@ -93,8 +93,8 @@ extern "C" { typedef enum { KVS_IP_FAMILY_TYPE_NOT_SET = (UINT16) 0x0000, // Sentinel value for not yet set IP address. - KVS_IP_FAMILY_TYPE_IPV4 = (UINT16) 0x0001, - KVS_IP_FAMILY_TYPE_IPV6 = (UINT16) 0x0002, + KVS_IP_FAMILY_TYPE_IPV4 = (UINT16) 0x0001, + KVS_IP_FAMILY_TYPE_IPV6 = (UINT16) 0x0002, } KVS_IP_FAMILY_TYPE; typedef struct { diff --git a/src/source/PeerConnection/PeerConnection.c b/src/source/PeerConnection/PeerConnection.c index afad341160..1ade8d9a25 100644 --- a/src/source/PeerConnection/PeerConnection.c +++ b/src/source/PeerConnection/PeerConnection.c @@ -850,7 +850,6 @@ STATUS getStunAddr(PStunIpAddrContext pStunIpAddrCtx) CHK_LOG_ERR(retStatus); LEAVES(); return retStatus; - } STATUS onSetStunServerIp(UINT64 customData, PCHAR url, PDualKvsIpAddresses pIpAddresses) @@ -883,8 +882,10 @@ STATUS onSetStunServerIp(UINT64 customData, PCHAR url, PDualKvsIpAddresses pIpAd pWebRtcClientContext->pStunIpAddrCtx->startTime = 0; CHK_ERR(getStunAddr(pWebRtcClientContext->pStunIpAddrCtx) == STATUS_SUCCESS, retStatus, "Failed to resolve after cache expiry"); } - MEMCPY(pIpAddresses->ipv4Address.address, &pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address, SIZEOF(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address)); - MEMCPY(pIpAddresses->ipv6Address.address, &pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address, SIZEOF(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address)); + MEMCPY(pIpAddresses->ipv4Address.address, &pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address, + SIZEOF(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address)); + MEMCPY(pIpAddresses->ipv6Address.address, &pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address, + SIZEOF(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address)); } else { DLOGE("Initialization failed"); } @@ -934,18 +935,19 @@ PVOID resolveStunIceServerIp(PVOID args) KINESIS_VIDEO_STUN_URL_WITHOUT_PORT, pRegion, pHostnamePostfix); stunDnsResolutionStartTime = GETTIME(); if (getStunAddr(pWebRtcClientContext->pStunIpAddrCtx) == STATUS_SUCCESS) { - if(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address.family != KVS_IP_FAMILY_TYPE_NOT_SET) { + if (pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address.family != KVS_IP_FAMILY_TYPE_NOT_SET) { // If the IPv4 family is set, then there must have been an IPv4 address resolved. - getIpAddrStr(&pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address, addressResolvedIPv4, ARRAY_SIZE(addressResolvedIPv4)); + getIpAddrStr(&pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv4Address, addressResolvedIPv4, + ARRAY_SIZE(addressResolvedIPv4)); DLOGI("ICE Server address for %s with getaddrinfo: %s", pWebRtcClientContext->pStunIpAddrCtx->hostname, addressResolvedIPv4); pWebRtcClientContext->pStunIpAddrCtx->isIpInitialized = TRUE; } - if(pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address.family != KVS_IP_FAMILY_TYPE_NOT_SET) { + if (pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address.family != KVS_IP_FAMILY_TYPE_NOT_SET) { // If the IPv6 family is set, then there must have been an IPv6 address resolved. - getIpAddrStr(&pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address, addressResolvedIPv6, ARRAY_SIZE(addressResolvedIPv6)); + getIpAddrStr(&pWebRtcClientContext->pStunIpAddrCtx->kvsIpAddresses.ipv6Address, addressResolvedIPv6, + ARRAY_SIZE(addressResolvedIPv6)); DLOGI("ICE Server address for %s with getaddrinfo: %s", pWebRtcClientContext->pStunIpAddrCtx->hostname, addressResolvedIPv6); pWebRtcClientContext->pStunIpAddrCtx->isIpInitialized = TRUE; - } } else { From 1e7d6e9bd6e4a5d0c8ea466a0852ca2b3db7a2f2 Mon Sep 17 00:00:00 2001 From: Stefan Kieszkowski <85728496+stefankiesz@users.noreply.github.com> Date: Thu, 1 May 2025 16:08:47 -0700 Subject: [PATCH 10/10] Address comment --- src/source/Ice/IceUtils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/source/Ice/IceUtils.c b/src/source/Ice/IceUtils.c index ee0abfd0ec..9209639aec 100644 --- a/src/source/Ice/IceUtils.c +++ b/src/source/Ice/IceUtils.c @@ -282,14 +282,14 @@ STATUS parseIceServer(PIceServer pIceServer, PCHAR url, PCHAR username, PCHAR cr if (pIceServer->ipAddresses.ipv4Address.family != KVS_IP_FAMILY_TYPE_NOT_SET) { pIceServer->ipAddresses.ipv4Address.port = (UINT16) getInt16((INT16) port); - getIpAddrStr(&pIceServer->ipAddresses.ipv4Address, addressResolvedIPv4, ARRAY_SIZE(addressResolvedIPv4)); + CHK_STATUS(getIpAddrStr(&pIceServer->ipAddresses.ipv4Address, addressResolvedIPv4, ARRAY_SIZE(addressResolvedIPv4))); DLOGP("Resolved ICE Server IPv4 address for %s: %s", pIceServer->url, addressResolvedIPv4); DLOGP("...with port: %u", pIceServer->ipAddresses.ipv4Address.port); } if (pIceServer->ipAddresses.ipv6Address.family != KVS_IP_FAMILY_TYPE_NOT_SET) { pIceServer->ipAddresses.ipv6Address.port = (UINT16) getInt16((INT16) port); - getIpAddrStr(&pIceServer->ipAddresses.ipv6Address, addressResolvedIPv6, ARRAY_SIZE(addressResolvedIPv6)); + CHK_STATUS(getIpAddrStr(&pIceServer->ipAddresses.ipv6Address, addressResolvedIPv6, ARRAY_SIZE(addressResolvedIPv6))); DLOGP("Resolved ICE Server IPv6 address for %s: %s", pIceServer->url, addressResolvedIPv6); DLOGP("...with port: %u", pIceServer->ipAddresses.ipv6Address.port); }