void testMultiplePAIs_Match() { const char* message = "INVITE sip:[email protected]:5060;x-sipX-pubcontact=47.135.162.145%3A29544 SIP/2.0\r\n" "Record-Route: <sip:192.168.0.2:5060;lr>\r\n" "From: caller <sip:[email protected]>;tag=94bc25b8-c0a80165-13c4-3e635-37aa1989-3e635\r\n" "To: <sip:[email protected]>\r\n" "Call-Id: 94bb2520-c0a80165-13c4-3e635-3ccd2971-3e635@rjolyscs2.ca.nortel.com\r\n" "Cseq: 1 INVITE\r\n" "Max-Forwards: 19\r\n" "Supported: replaces\r\n" "Contact: <sip:[email protected]:5060;x-sipX-pubcontact=47.135.162.145%3A14956>\r\n" "P-Asserted-Identity: \"Some guy\" <sip:[email protected]>\r\n" "P-Asserted-Identity: \"Some other guy\" <sip:[email protected]>\r\n" "P-Asserted-Identity: \"yet another guy\" <sip:[email protected]>\r\n" "P-Asserted-Identity: \"you again\" <sip:[email protected]>\r\n" "Content-Length: 0\r\n" "\r\n"; SipMessage testMsg(message, strlen(message)); UtlSList noRemovedRoutes; UtlString routeName("mydomain.com"); RouteState routeState( testMsg, noRemovedRoutes, routeName ); UtlString rejectReason; CPPUNIT_ASSERT(AuthPlugin::CONTINUE == spLinter->authorizeAndModify(identity, requestUri, routeState, "INVITE", AuthPlugin::CONTINUE, testMsg, false, rejectReason )); // verify that PAIs are gone. CPPUNIT_ASSERT( !testMsg.getHeaderValue( 0, SipXauthIdentity::PAssertedIdentityHeaderName ) ); }
void testPAIForMatchingDomain_StillSpiraling() { const char* message = "INVITE sip:[email protected]:5060;x-sipX-pubcontact=47.135.162.145%3A29544 SIP/2.0\r\n" "Record-Route: <sip:192.168.0.2:5060;lr>\r\n" "From: caller <sip:[email protected]>;tag=94bc25b8-c0a80165-13c4-3e635-37aa1989-3e635\r\n" "To: <sip:[email protected]>\r\n" "Call-Id: 94bb2520-c0a80165-13c4-3e635-3ccd2971-3e635@rjolyscs2.ca.nortel.com\r\n" "Cseq: 1 INVITE\r\n" "Max-Forwards: 19\r\n" "Supported: replaces\r\n" "Contact: <sip:[email protected]:5060;x-sipX-pubcontact=47.135.162.145%3A14956>\r\n" "P-Asserted-Identity: \"Some guy\" <sip:[email protected]>\r\n" "Content-Length: 0\r\n" "\r\n"; SipMessage testMsg(message, strlen(message)); CPPUNIT_ASSERT( testMsg.getHeaderValue( 0, SipXauthIdentity::PAssertedIdentityHeaderName ) ); UtlSList noRemovedRoutes; UtlString routeName("mydomain.com"); RouteState routeState( testMsg, noRemovedRoutes, routeName ); UtlString rejectReason; CPPUNIT_ASSERT(AuthPlugin::CONTINUE == spLinter->authorizeAndModify(identity, requestUri, routeState, "INVITE", AuthPlugin::CONTINUE, testMsg, true, // request still spiraling rejectReason )); // verify that PAI is still there because request is still spiraling. const char* pPAI; CPPUNIT_ASSERT( ( pPAI = testMsg.getHeaderValue( 0, SipXauthIdentity::PAssertedIdentityHeaderName ) ) ); ASSERT_STR_EQUAL( "\"Some guy\" <sip:[email protected]>", pPAI ); }
void testPAIForOtherDomain() { const char* message = "INVITE sip:[email protected]:5060;x-sipX-pubcontact=47.135.162.145%3A29544 SIP/2.0\r\n" "Record-Route: <sip:192.168.0.2:5060;lr>\r\n" "From: caller <sip:[email protected]>;tag=94bc25b8-c0a80165-13c4-3e635-37aa1989-3e635\r\n" "To: <sip:[email protected]>\r\n" "Call-Id: 94bb2520-c0a80165-13c4-3e635-3ccd2971-3e635@rjolyscs2.ca.nortel.com\r\n" "Cseq: 1 INVITE\r\n" "Max-Forwards: 19\r\n" "Supported: replaces\r\n" "Contact: <sip:[email protected]:5060;x-sipX-pubcontact=47.135.162.145%3A14956>\r\n" "P-Asserted-Identity: \"Some guy\" <sip:[email protected]>\r\n" "Content-Length: 0\r\n" "\r\n"; SipMessage testMsg(message, strlen(message)); UtlSList noRemovedRoutes; UtlString routeName("mydomain.com"); RouteState routeState( testMsg, noRemovedRoutes, routeName ); UtlString rejectReason; CPPUNIT_ASSERT(AuthPlugin::CONTINUE == spLinter->authorizeAndModify(identity, requestUri, routeState, "INVITE", AuthPlugin::CONTINUE, testMsg, false, rejectReason )); ssize_t size; UtlString modifiedMessageText; testMsg.getBytes( &modifiedMessageText, &size ); ASSERT_STR_EQUAL( message, modifiedMessageText.data() ); }
void stalledMediaStreamDetectionTest_StreamStalled() { SetFakeReceptionOfPacketsFlag( false ); RouteState::setSecret("fixed"); const char* message = "INVITE sip:[email protected]:5060;x-sipX-pubcontact=47.135.162.145%3A29544 SIP/2.0\r\n" "Record-Route: <sip:192.168.0.2:5060;lr>\r\n" "From: \"L3\"<sip:[email protected]>;tag=94bb9480-c0a80065-13c4-50045-20c55bd3-50045\r\n" "To: <sip:[email protected]>\r\n" "Call-Id: 94bb55a0-c0a80065-13c4-50045-61a3ad3-50045@rjolyscs2.ca.nortel.com\r\n" "Cseq: 1 INVITE\r\n" "Via: SIP/2.0/UDP 192.168.0.2;branch=z9hG4bK-sipXecs-8130adee90e0277761fec4ee1c194a56838f~9d6590763d78764b93a42e94dbd6b75a\r\n" "Via: SIP/2.0/UDP 192.168.0.101:5060;branch=z9hG4bK-50045-13890e4e-4f17a229\r\n" "Max-Forwards: 19\r\n" "Supported: replaces\r\n" "User-Agent: LG-Nortel LIP 6812 v1.2.38sp SN/00405A183385\r\n" "Contact: <sip:[email protected]:5060;x-sipX-nonat>\r\n" "Content-Type: application/sdp\r\n" "Content-Length: 301\r\n" "Date: Fri, 13 Jun 2008 14:48:44 GMT\r\n" "\r\n" "\r\n" "v=0\r\n" "o=LGEIPP 14595 14595 IN IP4 192.168.0.101\r\n" "s=SIP Call\r\n" "c=IN IP4 192.168.0.101\r\n" "t=0 0\r\n" "m=audio 23016 RTP/AVP 18 4 0 8 101\r\n" "a=rtpmap:18 G729/8000\r\n" "a=rtpmap:4 G723/8000\r\n" "a=rtpmap:0 PCMU/8000\r\n" "a=rtpmap:8 PCMA/8000\r\n" "a=rtpmap:101 telephone-event/8000\r\n" "a=fmtp:18 annexb=no\r\n" "a=fmtp:101 0-11\r\n" "a=sendrecv\r\n"; SipMessage testMsg(message, strlen(message)); UtlString rejectReason; UtlSList emptyList; RouteState routeState( message, emptyList, "192.168.0.2:5060" ); AuthPlugin::AuthResult result; result = pNatTraversalAgent->authorizeAndModify( "id", //dummy Url("sip:[email protected]:5060"), //dummy routeState, "INVITE", AuthPlugin::CONTINUE, testMsg, false, rejectReason ); // check auth result CPPUNIT_ASSERT( result == AuthPlugin::CONTINUE ); routeState.update( &testMsg ); pNatTraversalAgent->handleOutputMessage( testMsg, "47.135.162.145", 29544 ); // Mow simulalate the reception of the response const char* response = "SIP/2.0 200 OK\r\n" "From: \"L3\"<sip:[email protected]>;tag=94bb9480-c0a80065-13c4-50045-20c55bd3-50045\r\n" "To: <sip:[email protected]>;tag=94bf81c0-c0a8010b-13c4-4fc07-650a9211-4fc07\r\n" "Call-Id: 94bb55a0-c0a80065-13c4-50045-61a3ad3-50045@rjolyscs2.ca.nortel.com\r\n" "Cseq: 1 INVITE\r\n" "Via: SIP/2.0/UDP 192.168.0.101:5060;branch=z9hG4bK-50045-13890e4e-4f17a229;id=1234-3\r\n" "Supported: replaces\r\n" "Contact: <sip:[email protected]:5060>\r\n" "Record-Route: <sip:47.135.162.140:5060;lr;sipXecs-rs=%2Afrom%7EOTRiYjk0ODAtYzBhODAwNjUtMTNjNC01MDA0NS0yMGM1NWJkMy01MDA0NQ%60%60.ntap%2ACeT%7ENDcuMTM1LjE2Mi4xNDU6Mjk1NDQ7dHJhbnNwb3J0PXVkcA%60%60.ntap%2Aid%7EMTIzNC0z%213d7b53562948991d1cf59dfe7fdaaf24>\r\n" "Content-Type: application/sdp\r\n" "Content-Length: 250\r\n" "Date: Fri, 13 Jun 2008 14:48:46 GMT\r\n" "\r\n" "\r\n" "v=0\r\n" "o=LGEIPP 12617 12617 IN IP4 192.168.1.11\r\n" "s=SIP Call\r\n" "c=IN IP4 192.168.1.11\r\n" "t=0 0\r\n" "m=audio 25038 RTP/AVP 4 101\r\n" "c=IN IP4 192.168.0.2\r\n" "a=rtpmap:4 G723/8000\r\n" "a=rtpmap:101 telephone-event/8000\r\n" "a=fmtp:101 0-11\r\n" "a=sendrecv\r\n" "a=x-sipx-ntap:192.168.0.2;3\r\n"; SipMessage okResp( response, strlen(response) ); pNatTraversalAgent->handleOutputMessage( okResp, "192.168.0.101", 5060 ); // Mow simulalate the reception of the ACK const char* ack = "ACK sip:[email protected]:5060;x-sipX-pubcontact=47.135.162.145%3A29544 SIP/2.0\r\n" "From: \"L3\"<sip:[email protected]>;tag=94bb9480-c0a80065-13c4-50045-20c55bd3-50045\r\n" "To: <sip:[email protected]>;tag=94bf81c0-c0a8010b-13c4-4fc07-650a9211-4fc07\r\n" "Call-Id: 94bb55a0-c0a80065-13c4-50045-61a3ad3-50045@rjolyscs2.ca.nortel.com\r\n" "Cseq: 1 ACK\r\n" "Via: SIP/2.0/UDP 192.168.0.2;branch=z9hG4bK-sipXecs-8130adee90e0277761fec4ee1c194a56838f~9d6590763d78764b93a42e94dbd6b75a\r\n" "Via: SIP/2.0/UDP 192.168.0.101:5060;branch=z9hG4bK-50045-13890e4e-4f17a229\r\n" "Max-Forwards: 19\r\n" "Supported: replaces\r\n" "User-Agent: LG-Nortel LIP 6812 v1.2.38sp SN/00405A183385\r\n" "Contact: <sip:[email protected]:5060;x-sipX-nonat>\r\n" "Content-Length: 0\r\n" "\r\n"; SipMessage ackRequest( ack, strlen(ack) ); UtlSList routeList; UtlString poppedRoute("<sip:47.135.162.140:5060;lr;sipXecs-rs=%2Afrom%7EOTRiYjk0ODAtYzBhODAwNjUtMTNjNC01MDA0NS0yMGM1NWJkMy01MDA0NQ%60%60.ntap%2ACeT%7ENDcuMTM1LjE2Mi4xNDU6Mjk1NDQ7dHJhbnNwb3J0PXVkcA%60%60.ntap%2Aid%7EMTIzNC0z%213d7b53562948991d1cf59dfe7fdaaf24>"); routeList.append( &poppedRoute ); RouteState newRouteState( message, routeList, "192.168.0.2:5060" ); result = pNatTraversalAgent->authorizeAndModify( "id", //dummy Url("sip:[email protected]:5060"), //dummy newRouteState, "ACK", AuthPlugin::CONTINUE, ackRequest, false, rejectReason ); // check auth result CPPUNIT_ASSERT( result == AuthPlugin::CONTINUE ); pNatTraversalAgent->handleOutputMessage( ackRequest, "47.135.162.145", 29544 ); // Check that the DialogTracker is still around after 10 seconds. CallTracker* pTracker; UtlString callId; testMsg.getCallIdField( &callId ); pTracker = pNatTraversalAgent->getCallTrackerFromCallId( callId ); CPPUNIT_ASSERT( pTracker != 0 ); CPPUNIT_ASSERT( pTracker->mSessionContextsMap.entries() == 1 ); sleep( MAX_TIMER_TICK_COUNTS_BEFORE_CALL_TRACKER_CLEAN_UP * CLEAN_UP_TIMER_IN_SECS * 2 /*safety margin*/ ); pTracker = pNatTraversalAgent->getCallTrackerFromCallId( callId ); CPPUNIT_ASSERT( pTracker == 0 ); }
void handleRemoteNATedToRemoteNATedCall() { const char* message = "INVITE sip:[email protected]:5060;x-sipX-pubcontact=47.135.162.145%3A29544 SIP/2.0\r\n" "Record-Route: <sip:192.168.0.2:5060;lr>\r\n" "From: caller <sip:[email protected]>;tag=94bc25b8-c0a80165-13c4-3e635-37aa1989-3e635\r\n" "To: <sip:[email protected]>\r\n" "Call-Id: 94bb2520-c0a80165-13c4-3e635-3ccd2971-3e635@rjolyscs2.ca.nortel.com\r\n" "Cseq: 1 INVITE\r\n" "Max-Forwards: 19\r\n" "Supported: replaces\r\n" "User-Agent: LG-Nortel LIP 6804 v1.2.38sp SN/00405A187376\r\n" "Contact: <sip:[email protected]:5060;x-sipX-pubcontact=47.135.162.145%3A14956>\r\n" "Content-Type: application/sdp\r\n" "Content-Length: 297\r\n" "Date: Thu, 12 Jun 2008 19:14:29 GMT\r\n" "Via: SIP/2.0/UDP 192.168.0.2;branch=z9hG4bK-sipXecs-01a17f9662b96b1d454a71775bbda1ec6bf6~9d6590763d78764b93a42e94dbd6b75a\r\n" "Via: SIP/2.0/UDP 192.168.1.101:5060;branch=z9hG4bK-3e635-f3b41fc-310ddca7;received=47.135.162.145;rport=14956\r\n" "\r\n" "\r\n" "v=0\r\n" "o=LGEIPP 874 874 IN IP4 192.168.1.101\r\n" "s=SIP Call\r\n" "c=IN IP4 192.168.1.101\r\n" "t=0 0\r\n" "m=audio 23000 RTP/AVP 18 0 8 4 101\r\n" "a=rtpmap:18 G729/8000\r\n" "a=rtpmap:0 PCMU/8000\r\n" "a=rtpmap:8 PCMA/8000\r\n" "a=rtpmap:4 G723/8000\r\n" "a=rtpmap:101 telephone-event/8000\r\n" "a=fmtp:18 annexb=no\r\n" "a=fmtp:101 0-11\r\n" "a=sendrecv\r\n"; SipMessage testMsg(message, strlen(message)); UtlString rejectReason; UtlSList emptyList; RouteState routeState( message, emptyList, "192.168.0.2:5060" ); AuthPlugin::AuthResult result; result = pNatTraversalAgent->authorizeAndModify( "id", //dummy Url("sip:[email protected]:5060"), //dummy routeState, "INVITE", AuthPlugin::CONTINUE, testMsg, false, rejectReason ); // check auth result CPPUNIT_ASSERT( result == AuthPlugin::CONTINUE ); // check that call tracker got created UtlString callId; CallTracker* pTracker; testMsg.getCallIdField( &callId ); pTracker = pNatTraversalAgent->getCallTrackerFromCallId( callId ); CPPUNIT_ASSERT( pTracker != 0 ); // check that public transport of caller got encoded in route state UtlString transportInfo; routeState.getParameter( pNatTraversalAgent->mInstanceName.data(), CALLER_PUBLIC_TRANSPORT_PARAM, transportInfo ); ASSERT_STR_EQUAL( "47.135.162.145:14956;transport=udp", transportInfo.data() ); // check that public transport of callee got encoded in route state routeState.getParameter( pNatTraversalAgent->mInstanceName.data(), CALLEE_PUBLIC_TRANSPORT_PARAM, transportInfo ); ASSERT_STR_EQUAL( "47.135.162.145:29544;transport=udp", transportInfo.data() ); // Check that sipX NAT route is set to reach the callee's public IP address UtlString natRoute; CPPUNIT_ASSERT( testMsg.getSipXNatRoute( &natRoute ) == true ); ASSERT_STR_EQUAL( "47.135.162.145:29544;transport=udp", natRoute.data() ); // Now present the message to the Output Processor and verify that it got processed correctly. routeState.update( &testMsg ); // uodate route state as it would normally be done by SipRouter. pNatTraversalAgent->handleOutputMessage( testMsg, "47.135.162.145", 29544 ); // verify that top via got adjusted to reflect our public IP address UtlString topmostVia; CPPUNIT_ASSERT( testMsg.getViaFieldSubField( &topmostVia, 0 ) ); ASSERT_STR_EQUAL( "SIP/2.0/UDP 47.135.162.140:5060;branch=z9hG4bK-sipXecs-01a17f9662b96b1d454a71775bbda1ec6bf6~9d6590763d78764b93a42e94dbd6b75a", topmostVia.data() ); // verify that top route got modfified to reflect our public address UtlString tmpRecordRoute; CPPUNIT_ASSERT( testMsg.getRecordRouteUri( 0, &tmpRecordRoute ) ); Url tmpRecordRouteUrl( tmpRecordRoute ); UtlString tmpRecordRouteHost; tmpRecordRouteUrl.getHostWithPort( tmpRecordRouteHost ); ASSERT_STR_EQUAL( "47.135.162.140:5060", tmpRecordRouteHost.data() ); // recall the call tracker based on message and compare with previous CallTracker* pTracker2; pTracker2 = pNatTraversalAgent->getCallTrackerForMessage( testMsg ); CPPUNIT_ASSERT( pTracker2 == pTracker ); // check that the SDP got changed properly to relay media const SdpBody* pSdpBody = testMsg.getSdpBody(); CPPUNIT_ASSERT( pSdpBody ); UtlString mediaType, mediaTransportType; int mediaPort, mediaPortPairs, numPayloadTypes, payloadTypes[10]; SdpDirectionality dir; CPPUNIT_ASSERT( pSdpBody->getMediaData( 0, &mediaType, &mediaPort, &mediaPortPairs, &mediaTransportType, 10, &numPayloadTypes, payloadTypes, &dir ) == TRUE ); CPPUNIT_ASSERT( mediaType == "audio" ); CPPUNIT_ASSERT( mediaPort == 10000 ); CPPUNIT_ASSERT( mediaPortPairs == 1 ); CPPUNIT_ASSERT( mediaTransportType == "RTP/AVP" ); CPPUNIT_ASSERT( numPayloadTypes == 5 ); CPPUNIT_ASSERT( payloadTypes[0] == 18 ); CPPUNIT_ASSERT( payloadTypes[1] == 0 ); CPPUNIT_ASSERT( payloadTypes[2] == 8 ); CPPUNIT_ASSERT( payloadTypes[3] == 4 ); CPPUNIT_ASSERT( payloadTypes[4] == 101 ); CPPUNIT_ASSERT( dir == sdpDirectionalitySendRecv ); // check that we are using the public IP address of the media relay UtlString mediaAddress; CPPUNIT_ASSERT( pSdpBody->getMediaAddress(0, &mediaAddress ) ); ASSERT_STR_EQUAL( pNatTraversalAgent->mNatTraversalRules.getMediaRelayPublicAddress(), mediaAddress ); // Mow simulalate the reception of the response const char* response = "SIP/2.0 200 OK\r\n" "From: \"R1_2 - 602\"<sip:[email protected]>;tag=94bc25b8-c0a80165-13c4-3e635-37aa1989-3e635\r\n" "To: <sip:[email protected]>;tag=94bf84d0-c0a8010b-13c4-3e8d1-496994c2-3e8d1\r\n" "Call-ID: 94bb2520-c0a80165-13c4-3e635-3ccd2971-3e635@rjolyscs2.ca.nortel.com\r\n" "CSeq: 1 INVITE\r\n" "Via: SIP/2.0/UDP 192.168.1.101:5060;received=47.135.162.145;rport=14956;branch=z9hG4bK-3e635-f3b41fc-310ddca7;id=1234-0\r\n" "Supported: replaces\r\n" "Contact: <sip:[email protected]:5060>\r\n" "Record-Route: <sip:47.135.162.140:5060;lr;sipXecs-rs=%2Afrom%7EOTRiYzI1YjgtYzBhODAxNjUtMTNjNC0zZTYzNS0zN2FhMTk4OS0zZTYzNQ%60%60.400_authrules%2Aauth%7E.900_ntap%2ACeT%7ENDcuMTM1LjE2Mi4xNDU6Mjk1NDQ7dHJhbnNwb3J0PXVkcA%60%60.900_ntap%2ACrT%7ENDcuMTM1LjE2Mi4xNDU6MTQ5NTY7dHJhbnNwb3J0PXVkcA%60%60.900_ntap%2Aid%7EMC0w%215d4c53f8d9c9ecd8d089e57ba7a59513>\r\n" "Content-Type: application/sdp\r\n" "Content-Length: 202\r\n" "\r\n" "\r\n" "v=0\r\n" "o=LGEIPP 5466 5466 IN IP4 192.168.1.11\r\n" "s=SIP Call\r\n" "c=IN IP4 192.168.1.11\r\n" "t=0 0\r\n" "m=audio 23020 RTP/AVP 0 101\r\n" "a=rtpmap:0 PCMU/8000\r\n" "a=rtpmap:101 telephone-event/8000\r\n" "a=fmtp:101 0-11\r\n" "a=sendrecv\r\n" "a=x-sipx-ntap:192.168.0.2;1\r\n"; SipMessage okResp( response, strlen(response) ); pNatTraversalAgent->handleOutputMessage( okResp, "47.135.162.145", 14956 ); // check that the record route still has our public IP address CPPUNIT_ASSERT( okResp.getRecordRouteUri( 0, &tmpRecordRoute ) ); Url tmpRecordRouteUrl2( tmpRecordRoute ); tmpRecordRouteUrl2.getHostWithPort( tmpRecordRouteHost ); ASSERT_STR_EQUAL( "47.135.162.140:5060", tmpRecordRouteHost.data() ); // check that the SDP got changed properly to relay media pSdpBody = okResp.getSdpBody(); CPPUNIT_ASSERT( pSdpBody ); CPPUNIT_ASSERT( pSdpBody->getMediaData( 0, &mediaType, &mediaPort, &mediaPortPairs, &mediaTransportType, 10, &numPayloadTypes, payloadTypes, &dir ) == TRUE ); CPPUNIT_ASSERT( mediaType == "audio" ); CPPUNIT_ASSERT( mediaPort == 11000 ); CPPUNIT_ASSERT( mediaPortPairs == 1 ); CPPUNIT_ASSERT( mediaTransportType == "RTP/AVP" ); CPPUNIT_ASSERT( numPayloadTypes == 2 ); CPPUNIT_ASSERT( payloadTypes[0] == 0); CPPUNIT_ASSERT( payloadTypes[1] == 101 ); CPPUNIT_ASSERT( dir == sdpDirectionalitySendRecv ); // check that we are using the public IP address of the media relay CPPUNIT_ASSERT( pSdpBody->getMediaAddress(0, &mediaAddress ) ); ASSERT_STR_EQUAL( pNatTraversalAgent->mNatTraversalRules.getMediaRelayPublicAddress(), mediaAddress ); }
void handleLocalNATedToRemoteNATedCall() { const char* message = "INVITE sip:[email protected]:5060;x-sipX-pubcontact=47.135.162.145%3A29544 SIP/2.0\r\n" "Record-Route: <sip:192.168.0.2:5060;lr>\r\n" "From: \"L3\"<sip:[email protected]>;tag=94bb9480-c0a80065-13c4-50045-20c55bd3-50045\r\n" "To: <sip:[email protected]>\r\n" "Call-Id: 94bb55a0-c0a80065-13c4-50045-61a3ad3-50045@rjolyscs2.ca.nortel.com\r\n" "Cseq: 1 INVITE\r\n" "Via: SIP/2.0/UDP 192.168.0.2;branch=z9hG4bK-sipXecs-8130adee90e0277761fec4ee1c194a56838f~9d6590763d78764b93a42e94dbd6b75a\r\n" "Via: SIP/2.0/UDP 192.168.0.101:5060;branch=z9hG4bK-50045-13890e4e-4f17a229\r\n" "Max-Forwards: 19\r\n" "Supported: replaces\r\n" "User-Agent: LG-Nortel LIP 6812 v1.2.38sp SN/00405A183385\r\n" "Contact: <sip:[email protected]:5060;x-sipX-nonat>\r\n" "Content-Type: application/sdp\r\n" "Content-Length: 301\r\n" "Date: Fri, 13 Jun 2008 14:48:44 GMT\r\n" "\r\n" "\r\n" "v=0\r\n" "o=LGEIPP 14595 14595 IN IP4 192.168.0.101\r\n" "s=SIP Call\r\n" "c=IN IP4 192.168.0.101\r\n" "t=0 0\r\n" "m=audio 23016 RTP/AVP 18 4 0 8 101\r\n" "a=rtpmap:18 G729/8000\r\n" "a=rtpmap:4 G723/8000\r\n" "a=rtpmap:0 PCMU/8000\r\n" "a=rtpmap:8 PCMA/8000\r\n" "a=rtpmap:101 telephone-event/8000\r\n" "a=fmtp:18 annexb=no\r\n" "a=fmtp:101 0-11\r\n" "a=sendrecv\r\n"; SipMessage testMsg(message, strlen(message)); UtlString rejectReason; UtlSList emptyList; RouteState routeState( message, emptyList, "192.168.0.2:5060" ); AuthPlugin::AuthResult result; result = pNatTraversalAgent->authorizeAndModify( "id", //dummy Url("sip:[email protected]:5060"), //dummy routeState, "INVITE", AuthPlugin::CONTINUE, testMsg, false, rejectReason ); // check auth result CPPUNIT_ASSERT( result == AuthPlugin::CONTINUE ); // check that call tracker got created UtlString callId; CallTracker* pTracker; testMsg.getCallIdField( &callId ); pTracker = pNatTraversalAgent->getCallTrackerFromCallId( callId ); CPPUNIT_ASSERT( pTracker != 0 ); // check that no public transport of caller got encoded in route state UtlString transportInfo; CPPUNIT_ASSERT( !routeState.getParameter( pNatTraversalAgent->mInstanceName.data(), CALLER_PUBLIC_TRANSPORT_PARAM, transportInfo ) ); // check that public transport of callee got encoded in route state routeState.getParameter( pNatTraversalAgent->mInstanceName.data(), CALLEE_PUBLIC_TRANSPORT_PARAM, transportInfo ); ASSERT_STR_EQUAL( "47.135.162.145:29544;transport=udp", transportInfo.data() ); // Check that sipX NAT route is set to reach the callee's public IP address UtlString natRoute; CPPUNIT_ASSERT( testMsg.getSipXNatRoute( &natRoute ) == true ); ASSERT_STR_EQUAL( "47.135.162.145:29544;transport=udp", natRoute.data() ); // Now present the message to the Output Processor and verify that it got processed correctly. routeState.update( &testMsg ); // uodate route state as it would normally be done by SipRouter. pNatTraversalAgent->handleOutputMessage( testMsg, "47.135.162.145", 29544 ); // verify that top via got adjusted to reflect our public IP address UtlString topmostVia; CPPUNIT_ASSERT( testMsg.getViaFieldSubField( &topmostVia, 0 ) ); ASSERT_STR_EQUAL( "SIP/2.0/UDP 47.135.162.140:5060;branch=z9hG4bK-sipXecs-8130adee90e0277761fec4ee1c194a56838f~9d6590763d78764b93a42e94dbd6b75a", topmostVia.data() ); // verify that top route got modfified to reflect our public address UtlString tmpRecordRoute; CPPUNIT_ASSERT( testMsg.getRecordRouteUri( 0, &tmpRecordRoute ) ); Url tmpRecordRouteUrl( tmpRecordRoute ); UtlString tmpRecordRouteHost; tmpRecordRouteUrl.getHostWithPort( tmpRecordRouteHost ); ASSERT_STR_EQUAL( "47.135.162.140:5060", tmpRecordRouteHost.data() ); // recall the call tracker based on message and compare with previous CallTracker* pTracker2; pTracker2 = pNatTraversalAgent->getCallTrackerForMessage( testMsg ); CPPUNIT_ASSERT( pTracker2 == pTracker ); // check that the SDP got changed properly to relay media const SdpBody* pSdpBody = testMsg.getSdpBody(); CPPUNIT_ASSERT( pSdpBody ); UtlString mediaType, mediaTransportType; int mediaPort, mediaPortPairs, numPayloadTypes, payloadTypes[10]; SdpDirectionality dir; CPPUNIT_ASSERT( pSdpBody->getMediaData( 0, &mediaType, &mediaPort, &mediaPortPairs, &mediaTransportType, 10, &numPayloadTypes, payloadTypes, &dir ) == TRUE ); CPPUNIT_ASSERT( mediaType == "audio" ); CPPUNIT_ASSERT( mediaPort == 10000 ); CPPUNIT_ASSERT( mediaPortPairs == 1 ); CPPUNIT_ASSERT( mediaTransportType == "RTP/AVP" ); CPPUNIT_ASSERT( numPayloadTypes == 5 ); CPPUNIT_ASSERT( payloadTypes[0] == 18 ); CPPUNIT_ASSERT( payloadTypes[1] == 4 ); CPPUNIT_ASSERT( payloadTypes[2] == 0 ); CPPUNIT_ASSERT( payloadTypes[3] == 8 ); CPPUNIT_ASSERT( payloadTypes[4] == 101 ); CPPUNIT_ASSERT( dir == sdpDirectionalitySendRecv ); // check that we are using the public IP address of the media relay UtlString mediaAddress; CPPUNIT_ASSERT( pSdpBody->getMediaAddress(0, &mediaAddress ) ); ASSERT_STR_EQUAL( pNatTraversalAgent->mNatTraversalRules.getMediaRelayPublicAddress(), mediaAddress ); // Mow simulalate the reception of the response const char* response = "SIP/2.0 200 OK\r\n" "From: \"L3\"<sip:[email protected]>;tag=94bb9480-c0a80065-13c4-50045-20c55bd3-50045\r\n" "To: <sip:[email protected]>;tag=94bf81c0-c0a8010b-13c4-4fc07-650a9211-4fc07\r\n" "Call-Id: 94bb55a0-c0a80065-13c4-50045-61a3ad3-50045@rjolyscs2.ca.nortel.com\r\n" "Cseq: 1 INVITE\r\n" "Via: SIP/2.0/UDP 192.168.0.101:5060;branch=z9hG4bK-50045-13890e4e-4f17a229;id=1234-1\r\n" "Supported: replaces\r\n" "Contact: <sip:[email protected]:5060>\r\n" "Record-Route: <sip:47.135.162.140:5060;lr;sipXecs-rs=%2Afrom%7EOTRiYjk0ODAtYzBhODAwNjUtMTNjNC01MDA0NS0yMGM1NWJkMy01MDA0NQ%60%60.400_authrules%2Aauth%7E.900_ntap%2ACeT%7ENDcuMTM1LjE2Mi4xNDU6Mjk1NDQ7dHJhbnNwb3J0PXVkcA%60%60.900_ntap%2Aid%7EMy0z%21641c6aa1807d3544000f310a64a5360a>\r\n" "Content-Type: application/sdp\r\n" "Content-Length: 250\r\n" "Date: Fri, 13 Jun 2008 14:48:46 GMT\r\n" "\r\n" "\r\n" "v=0\r\n" "o=LGEIPP 12617 12617 IN IP4 192.168.1.11\r\n" "s=SIP Call\r\n" "c=IN IP4 192.168.1.11\r\n" "t=0 0\r\n" "m=audio 25038 RTP/AVP 4 101\r\n" "c=IN IP4 192.168.0.2\r\n" "a=rtpmap:4 G723/8000\r\n" "a=rtpmap:101 telephone-event/8000\r\n" "a=fmtp:101 0-11\r\n" "a=sendrecv\r\n" "a=x-sipx-ntap:192.168.0.2;3\r\n"; SipMessage okResp( response, strlen(response) ); pNatTraversalAgent->handleOutputMessage( okResp, "192.168.0.101", 5060 ); // check that the record route has our private IP address CPPUNIT_ASSERT( okResp.getRecordRouteUri( 0, &tmpRecordRoute ) ); Url tmpRecordRouteUrl2( tmpRecordRoute ); tmpRecordRouteUrl2.getHostWithPort( tmpRecordRouteHost ); ASSERT_STR_EQUAL( "192.168.0.2:5060", tmpRecordRouteHost.data() ); // check that the SDP got changed properly to relay media pSdpBody = okResp.getSdpBody(); CPPUNIT_ASSERT( pSdpBody ); CPPUNIT_ASSERT( pSdpBody->getMediaData( 0, &mediaType, &mediaPort, &mediaPortPairs, &mediaTransportType, 10, &numPayloadTypes, payloadTypes, &dir ) == TRUE ); CPPUNIT_ASSERT( mediaType == "audio" ); CPPUNIT_ASSERT( mediaPort == 11000 ); CPPUNIT_ASSERT( mediaPortPairs == 1 ); CPPUNIT_ASSERT( mediaTransportType == "RTP/AVP" ); CPPUNIT_ASSERT( numPayloadTypes == 2 ); CPPUNIT_ASSERT( payloadTypes[0] == 4); CPPUNIT_ASSERT( payloadTypes[1] == 101 ); CPPUNIT_ASSERT( dir == sdpDirectionalitySendRecv ); // check that we are using the native IP address of the media relay CPPUNIT_ASSERT( pSdpBody->getMediaAddress(0, &mediaAddress ) ); ASSERT_STR_EQUAL( pNatTraversalAgent->mNatTraversalRules.getMediaRelayNativeAddress(), mediaAddress ); }
void testLotsaRoutes() { const char* message = "INVITE sip:example.com;lr SIP/2.0\r\n" "Route: " "<sip:internal.example.com;lr>, " "<sip:external.example.net;lr>, " "<sip:somewhere.else.net;lr>, " "<sip:some.other.net;lr>, " "<sip:somewhereelse.org;lr>, " "<sip:some-other.net;lr>, " "<sip:proxy.other.net;lr>, " "<sip:[email protected]>\r\n" "Via: SIP/2.0/TCP 10.1.1.3:33855\r\n" "To: sip:[email protected]\r\n" "From: Caller <sip:[email protected]>; tag=30543f3483e1cb11ecb40866edd3295b\r\n" "Call-Id: f88dfabce84b6a2787ef024a7dbe8749\r\n" "Cseq: 1 INVITE\r\n" "Max-Forwards: 20\r\n" "Contact: [email protected]\r\n" "Content-Length: 0\r\n" "\r\n"; SipMessage testMsg(message, strlen(message)); Url requestUri; UtlSList removedRoutes; testMsg.normalizeProxyRoutes(UserAgent, requestUri, &removedRoutes); UtlString normalizedMsg; int msgLen; testMsg.getBytes(&normalizedMsg, &msgLen); UtlString requestUriResult; requestUri.toString(requestUriResult); ASSERT_STR_EQUAL("sip:[email protected]", requestUriResult.data()); UtlString* removedRoute; CPPUNIT_ASSERT( removedRoute = static_cast<UtlString*>(removedRoutes.get())); ASSERT_STR_EQUAL("<sip:example.com;lr>", removedRoute->data()); delete removedRoute; CPPUNIT_ASSERT( removedRoute = static_cast<UtlString*>(removedRoutes.get())); ASSERT_STR_EQUAL("<sip:internal.example.com;lr>", removedRoute->data()); delete removedRoute; CPPUNIT_ASSERT( removedRoute = static_cast<UtlString*>(removedRoutes.get())); ASSERT_STR_EQUAL("<sip:external.example.net;lr>", removedRoute->data()); delete removedRoute; CPPUNIT_ASSERT(removedRoutes.isEmpty()); UtlString route; /* "Route: " * "<sip:somewhere.else.net;lr>, " * "<sip:some.other.net;lr>, " * "<sip:somewhereelse.org;lr>, " * "<sip:some-other.net;lr>, " * "<sip:proxy.other.net;lr>" */ CPPUNIT_ASSERT(getNormalRoute(testMsg, 0, route)); ASSERT_STR_EQUAL("<sip:somewhere.else.net;lr>", route.data()); CPPUNIT_ASSERT(getNormalRoute(testMsg, 1, route)); ASSERT_STR_EQUAL("<sip:some.other.net;lr>", route.data()); CPPUNIT_ASSERT(getNormalRoute(testMsg, 2, route)); ASSERT_STR_EQUAL("<sip:somewhereelse.org;lr>", route.data()); CPPUNIT_ASSERT(getNormalRoute(testMsg, 3, route)); ASSERT_STR_EQUAL("<sip:some-other.net;lr>", route.data()); CPPUNIT_ASSERT(getNormalRoute(testMsg, 4, route)); ASSERT_STR_EQUAL("<sip:proxy.other.net;lr>", route.data()); CPPUNIT_ASSERT(!getNormalRoute(testMsg, 5, route)); }
void testShutdownNonBlocking() { int myPID = OsProcess::getCurrentPID(); int startingThreads; // Stop TimerTask and NatAgentTask before counting threads. // Some tests do not bother stopping them, so they may come started. OsTimerTask::destroyTimerTask(); OsNatAgentTask::releaseInstance(); // Count number of threads now. startingThreads = getNumThreads(myPID); // Simple invite message from siptest/src/siptest/invite.txt const char* SimpleMessage = "INVITE sip:[email protected] SIP/2.0\r\n" "Route: <sip:[email protected]:5064;lr>\r\n" "From: <sip:[email protected];user=phone>;tag=bbb\r\n" "To: <sip:[email protected]:3000;user=phone>\r\n" "Call-Id: 8\r\n" "Cseq: 1 INVITE\r\n" "Content-Length: 0\r\n" "\r\n"; SipMessage testMsg( SimpleMessage, strlen( SimpleMessage ) ); for(int i = 0; i < SHUTDOWN_TEST_ITERATIONS; ++i) { // Limit life time of lineMgr and refreshMgr. They should be freed // before releasing OsNatAgentTask instance, or we will crash. { SipLineMgr lineMgr; SipRefreshMgr refreshMgr; lineMgr.StartLineMgr(); lineMgr.initializeRefreshMgr( &refreshMgr ); SipUserAgent sipUA( 5090 ,5090 ,5091 ,NULL // default publicAddress ,NULL // default defaultUser ,"127.0.0.1" // default defaultSipAddress ,NULL // default sipProxyServers ,NULL // default sipDirectoryServers ,NULL // default sipRegistryServers ,NULL // default authenticationScheme ,NULL // default authenicateRealm ,NULL // default authenticateDb ,NULL // default authorizeUserIds ,NULL // default authorizePasswords ,&lineMgr ); sipUA.start(); refreshMgr.init(&sipUA); sipUA.send(testMsg); // Wait long enough for some stack timeouts/retransmits to occur OsTask::delay(10000); // 10 seconds sipUA.shutdown(FALSE); lineMgr.requestShutdown(); refreshMgr.requestShutdown(); while(!sipUA.isShutdownDone()) { ; } CPPUNIT_ASSERT(sipUA.isShutdownDone()); } // Stop TimerTask and NatAgentTask again before counting threads. // They were started while testing. OsTimerTask::destroyTimerTask(); OsNatAgentTask::releaseInstance(); // Test to see that all the threads created by the above operations // get properly shut down. // Since the threads do not shut down synchronously with the above // calls, we have to wait before we know they will be cleared. OsTask::delay(1000); // 1 second int numThreads = getNumThreads(myPID); CPPUNIT_ASSERT_EQUAL(startingThreads,numThreads); } };
// Test that an out-of-dialog request gets a Record-Route, even if it does not // require authorization/authentication, and test that the Record-Route has no // extraneous parameters applied. void testNoPermNeededOut() { OsConfigDb configuration; configuration.set("RULES", TEST_DATA_DIR "/enforcerules.xml"); enforcer->readConfig(configuration); UtlString identity; // no authenticated identity Url requestUri("sip:911@emergency-gw"); const char* message = "INVITE sip:911@emergency-gw SIP/2.0\r\n" "Via: SIP/2.0/TCP 10.1.1.3:33855\r\n" "To: sip:911@emergency-gw\r\n" "From: Caller <sip:[email protected]>; tag=30543f3483e1cb11ecb40866edd3295b\r\n" "Call-Id: f88dfabce84b6a2787ef024a7dbe8749\r\n" "Cseq: 2 INVITE\r\n" "Max-Forwards: 20\r\n" "Contact: [email protected]\r\n" "Content-Length: 0\r\n" "\r\n"; SipMessage testMsg(message, strlen(message)); UtlSList noRemovedRoutes; UtlString routeName("example.com"); RouteState routeState( testMsg, noRemovedRoutes, routeName ); const char unmodifiedRejectReason[] = "unmodified"; UtlString rejectReason(unmodifiedRejectReason); UtlString method("INVITE"); const bool bSpiralingRequest = false; AuthPlugin::AuthResult priorResult = AuthPlugin::CONTINUE; CPPUNIT_ASSERT(AuthPlugin::ALLOW == enforcer->authorizeAndModify(identity, requestUri, routeState, method, priorResult, testMsg, bSpiralingRequest, rejectReason )); ASSERT_STR_EQUAL(unmodifiedRejectReason, rejectReason.data()); // No Record-Route header. routeState.update(&testMsg); UtlString recordRoute; CPPUNIT_ASSERT(!testMsg.getRecordRouteField(0, &recordRoute)); RouteState spiraledRouteState(testMsg, noRemovedRoutes, routeName); // now simulate a spiral with the same message CPPUNIT_ASSERT(AuthPlugin::ALLOW == enforcer->authorizeAndModify(identity, requestUri, spiraledRouteState, method, priorResult, testMsg, bSpiralingRequest, rejectReason )); ASSERT_STR_EQUAL(unmodifiedRejectReason, rejectReason.data()); // No Record-Route header. spiraledRouteState.update(&testMsg); CPPUNIT_ASSERT(!testMsg.getRecordRouteField(0, &recordRoute)); }
// Test that an ACK is not challenged and not RecordRouted void testNoPermAck() { OsConfigDb configuration; configuration.set("RULES", TEST_DATA_DIR "/enforcerules.xml"); enforcer->readConfig(configuration); UtlString identity; // no authenticated identity Url requestUri("sip:somewhere@forbidden"); const char* message = "ACK sip:somewhere@forbidden SIP/2.0\r\n" "Via: SIP/2.0/TCP 10.1.1.3:33855\r\n" "To: sip:somewhere@forbidden\r\n" "From: Caller <sip:[email protected]>; tag=99911983748\r\n" "Call-Id: b1373e736d7d359ead76fa5cd467d999\r\n" "Cseq: 2 ACK\r\n" "Max-Forwards: 20\r\n" "Contact: [email protected]\r\n" "Content-Length: 0\r\n" "\r\n"; SipMessage testMsg(message, strlen(message)); UtlSList noRemovedRoutes; UtlString routeName("example.com"); RouteState routeState( testMsg, noRemovedRoutes, routeName ); const char unmodifiedRejectReason[] = "unmodified"; UtlString rejectReason(unmodifiedRejectReason); UtlString method("ACK"); const bool bSpiralingRequest = false; AuthPlugin::AuthResult priorResult = AuthPlugin::ALLOW; CPPUNIT_ASSERT(AuthPlugin::CONTINUE == enforcer->authorizeAndModify(identity, requestUri, routeState, method, priorResult, testMsg, bSpiralingRequest, rejectReason )); ASSERT_STR_EQUAL(unmodifiedRejectReason, rejectReason.data()); routeState.update(&testMsg); UtlString recordRoute; CPPUNIT_ASSERT(!testMsg.getRecordRouteField(0, &recordRoute)); // now simulate a spiral with the same message CPPUNIT_ASSERT(AuthPlugin::CONTINUE == enforcer->authorizeAndModify(identity, requestUri, routeState, method, priorResult, testMsg, bSpiralingRequest, rejectReason )); ASSERT_STR_EQUAL(unmodifiedRejectReason, rejectReason.data()); routeState.update(&testMsg); CPPUNIT_ASSERT(!testMsg.getRecordRouteField(0, &recordRoute)); }
void testShutdownBlocking() { pid_t myPID = OsProcess::getCurrentPID(); int startingThreads = getNumThreads(myPID); // Simple invite message from siptest/src/siptest/invite.txt const char* SimpleMessage = "INVITE sip:[email protected] SIP/2.0\r\n" "Route: <sip:[email protected]:5064;lr>\r\n" "From: <sip:[email protected];user=phone>;tag=bbb\r\n" "To: <sip:[email protected]:3000;user=phone>\r\n" "Call-Id: 8\r\n" "Cseq: 1 INVITE\r\n" "Content-Length: 0\r\n" "\r\n"; SipMessage testMsg( SimpleMessage, strlen( SimpleMessage ) ); for(int i = 0; i < SHUTDOWN_TEST_ITERATIONS; ++i) { { SipLineMgr lineMgr; SipRefreshMgr refreshMgr; lineMgr.StartLineMgr(); lineMgr.initializeRefreshMgr( &refreshMgr ); SipUserAgent sipUA( 5090 ,5090 ,5091 ,NULL // default publicAddress ,NULL // default defaultUser ,"127.0.0.1" // default defaultSipAddress ,NULL // default sipProxyServers ,NULL // default sipDirectoryServers ,NULL // default sipRegistryServers ,NULL // default authenticationScheme ,NULL // default authenicateRealm ,NULL // default authenticateDb ,NULL // default authorizeUserIds ,NULL // default authorizePasswords ,&lineMgr ); sipUA.start(); refreshMgr.init(&sipUA); sipUA.send(testMsg); // Wait long enough for some stack timeouts/retansmits to occur OsTask::delay(10000); // 10 seconds // Shut down the tasks in reverse order. refreshMgr.requestShutdown(); sipUA.shutdown(TRUE); lineMgr.requestShutdown(); CPPUNIT_ASSERT(sipUA.isShutdownDone()); OsTimerTask::destroyTimerTask(); OsStunAgentTask::releaseInstance(); } // Test to see that all the threads created by the above operations // get properly shut down. int numThreads = getNumThreads(myPID); OsSysLog::add(FAC_SIP, PRI_NOTICE, "SipUserAgentTest::testShutdownBlocking " "numThreads=%d startingThreads=%d", numThreads, startingThreads); KNOWN_BUG("XECS-48", "Some threads are not cleaned up?"); CPPUNIT_ASSERT(numThreads <= startingThreads); } };