def test_process_route_info_loose_routing(): def check_rroute_fun(uri): return Uri(this_proxy_uri) == uri bob_uri = 'sip:[email protected]' this_proxy_uri = 'sip:this.proxy.org' next_proxy_uri = 'sip:next.proxy.org' msg = 'INVITE ' + bob_uri + ' SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nVia: SIP/2.0/UDP bigbox3.site3.atlanta.com' + \ '\r\nMax-Forwards: 70' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nContact: <sip:[email protected]>' + \ '\r\nRoute: <' + this_proxy_uri + '>' + \ '\r\nRoute: <' + next_proxy_uri + '>' + \ '\r\nContent-Type: application/sdp' + \ '\r\nContent-Length: 4' + \ '\r\n\r\nTest' options = ValidationOptions(proxy=ProxyOptionsDetails(check_rroute_function=check_rroute_fun)) sip_msg = process_route_info(raw_message(msg), options) sip_msg_rebuilt = rebuild_sip_msg(sip_msg) assert sip_msg_rebuilt.ruri == Uri(bob_uri) expected_route_hdr = RouteHeader(next_proxy_uri) assert expected_route_hdr == sip_msg_rebuilt.get(ROUTE_HEADER)
def test_stateless_proxy_forward_to_ua(): def check_rroute_fun(uri): return uri == Uri(this_proxy_uri) bob_uri = 'sip:[email protected]' this_proxy_uri = 'sip:this.proxy.org' msg = 'INVITE ' + bob_uri + ' SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nVia: SIP/2.0/UDP bigbox3.site3.atlanta.com' + \ '\r\nMax-Forwards: 70' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nContact: <sip:[email protected]>' + \ '\r\nRoute: <' + this_proxy_uri + '>' + \ '\r\nContent-Type: application/sdp' + \ '\r\nContent-Length: 4' + \ '\r\n\r\nTest' proxy_opts = ProxyOptionsDetails(check_rroute_function=check_rroute_fun) options = ValidationOptions(proxy=proxy_opts) sip_msg = process_route_info(raw_message(msg), options) target = Uri(bob_uri) sip_msg, opts = CommonProxy.forward_request(target, sip_msg, proxy_opts) assert target == opts.nexthop assert isinstance(sip_msg.find(ROUTE_HEADER), NotFound)
def test_request_validation_proxy_require_cannot_reply(): msg = 'INVITE sip:[email protected] SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nVia: SIP/2.0/UDP bigbox3.site3.atlanta.com' + \ '\r\nMax-Forwards: 70' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nProxy-Require: gin' + \ '\r\n\r\n' with pytest.raises(SipHeaderError): CommonProxy.validate_request(raw_message(msg), ValidationOptions())
def test_request_validation_success_no_maxforwards(): msg = 'INVITE sip:[email protected] SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nVia: SIP/2.0/UDP bigbox3.site3.atlanta.com' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nContact: <sip:[email protected]>' + \ '\r\nContent-Type: application/sdp' + \ '\r\nContent-Length: 4' + \ '\r\n\r\nTest' CommonProxy.validate_request(raw_message(msg), ValidationOptions())
def test_request_validation_maxforwards_is_zero_options(): msg = 'OPTIONS sip:[email protected] SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nVia: SIP/2.0/UDP bigbox3.site3.atlanta.com' + \ '\r\nMax-Forwards: 0' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 OPTIONS' + \ '\r\n\r\n' sip_msg = CommonProxy.validate_request(raw_message(msg), ValidationOptions()) assert sip_msg.status == 483 assert 'too many hops' == sip_msg.reason.lower()
def test_request_validation_maxforwards_is_zero_options_reply_no_allow(): msg = 'OPTIONS sip:[email protected] SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nVia: SIP/2.0/UDP bigbox3.site3.atlanta.com' + \ '\r\nMax-Forwards: 0' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 OPTIONS\r\n\r\n' options = ValidationOptions(validate=ValidationOptionsDetails(reply_on_options=True)) response = CommonProxy.validate_request(raw_message(msg), options) assert response.status == 200 resp_raw_message = raw_message(response.serialize()) assert resp_raw_message.get(ALLOW_HEADER) == Header(ALLOW_HEADER)
def test_request_validation_no_resp_from(): # Invalid message: invalid maxforwards and no From header msg = 'INVITE sip:[email protected] SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nVia: SIP/2.0/UDP bigbox3.site3.atlanta.com' + \ '\r\nMax-Forwards: xyz' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nContact: <sip:[email protected]>' + \ '\r\nContent-Type: application/sdp' + \ '\r\nContent-Length: 4' + \ '\r\n\r\nTest' with pytest.raises(SipHeaderError): CommonProxy.validate_request(raw_message(msg), ValidationOptions())
def test_proxy_params_check_no_validate(): msg = 'INVITE sip:[email protected] SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nVia: SIP/2.0/UDP bigbox3.site3.atlanta.com' + \ '\r\nMax-Forwards: 70' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nContact: <sip:[email protected]>' + \ '\r\nContent-Type: application/sdp' + \ '\r\nContent-Length: 4' + \ '\r\n\r\nTest' this_proxy_uri = Uri('sip:this.proxy.org') options = ValidationOptions(proxy=ProxyOptionsDetails(record_route_uri=this_proxy_uri, no_validate=True)) # No exceptions raised: process_route_info(raw_message(msg), options)
def test_request_validation_proxy_require_all_supported(): msg = 'INVITE sip:[email protected] SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nVia: SIP/2.0/UDP bigbox3.site3.atlanta.com' + \ '\r\nMax-Forwards: 70' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nProxy-Require: gin' + \ '\r\n\r\n' supported = OptTagListHeader.from_list([OptionTag('gin')]) options = ValidationOptions(proxy=ProxyOptionsDetails(supported=supported)) # no errors while validating: response = CommonProxy.validate_request(raw_message(msg), options) assert isinstance(response, SipMessage)
def test_request_validation_bad_maxforwards(): msg = 'INVITE sip:[email protected] SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nVia: SIP/2.0/UDP bigbox3.site3.atlanta.com' + \ '\r\nMax-Forwards: xyz' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nContact: <sip:[email protected]>' + \ '\r\nContent-Type: application/sdp' + \ '\r\nContent-Length: 4' + \ '\r\n\r\nTest' sip_msg = CommonProxy.validate_request(raw_message(msg), ValidationOptions()) assert sip_msg.status == 400 assert 'max-forwards' in sip_msg.reason.lower()
def test_request_validation_unsupported_scheme_cannot_reply(): # Invalid message: no To header def scheme_validation_function(value): return False msg = 'INVITE sip:[email protected] SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nVia: SIP/2.0/UDP bigbox3.site3.atlanta.com' + \ '\r\nMax-Forwards: 70' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nContact: <sip:[email protected]>' + \ '\r\nContent-Type: application/sdp' + \ '\r\nContent-Length: 4' + \ '\r\n\r\nTest' with pytest.raises(SipHeaderError): CommonProxy.validate_request(raw_message(msg), ValidationOptions(validate=ValidationOptionsDetails(scheme_validation_function=scheme_validation_function)))
def test_request_validation_proxy_require(): msg = 'INVITE sip:[email protected] SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nVia: SIP/2.0/UDP bigbox3.site3.atlanta.com' + \ '\r\nMax-Forwards: 70' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nProxy-Require: gin' + \ '\r\n\r\n' unsupported = OptTagListHeader.from_list([OptionTag('gin')]) response = CommonProxy.validate_request(raw_message(msg), ValidationOptions()) assert response.status == 420 assert response.reason.lower() == 'bad extension' resp_raw_message = raw_message(response.serialize()) sip_response = SipMessage.parse(resp_raw_message, [UNSUPPORTED_HEADER]) assert sip_response.get(UNSUPPORTED_HEADER) == unsupported
def test_process_route_info_no_routes_strict_route(): bob_uri = 'sip:[email protected]' msg = 'INVITE ' + bob_uri + ' SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nVia: SIP/2.0/UDP bigbox3.site3.atlanta.com' + \ '\r\nMax-Forwards: 70' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nContact: <sip:[email protected]>' + \ '\r\nContent-Type: application/sdp' + \ '\r\nContent-Length: 4' + \ '\r\n\r\nTest' options = ValidationOptions(proxy=ProxyOptionsDetails(check_rroute_function=lambda x: True)) sip_msg = process_route_info(raw_message(msg), options) sip_msg = rebuild_sip_msg(sip_msg) assert sip_msg.ruri == Uri(bob_uri) assert isinstance(sip_msg.find(ROUTE_HEADER), NotFound)
def test_request_validation_unsupported_scheme(): def scheme_validation_function(value): return False msg = 'INVITE sip:[email protected] SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nVia: SIP/2.0/UDP bigbox3.site3.atlanta.com' + \ '\r\nMax-Forwards: 70' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nContact: <sip:[email protected]>' + \ '\r\nContent-Type: application/sdp' + \ '\r\nContent-Length: 4' + \ '\r\n\r\nTest' sip_msg = CommonProxy.validate_request(raw_message(msg), ValidationOptions(validate=ValidationOptionsDetails(scheme_validation_function=scheme_validation_function))) assert sip_msg.status == 416 assert 'unsupported' in sip_msg.reason.lower() and 'uri' in sip_msg.reason.lower() and \ 'scheme' in sip_msg.reason.lower()
def test_request_validation_maxforwards_is_zero_options_reply(): msg = 'OPTIONS sip:[email protected] SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nVia: SIP/2.0/UDP bigbox3.site3.atlanta.com' + \ '\r\nMax-Forwards: 0' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 OPTIONS' + \ '\r\n\r\n' allow_methods = AllowHeader(MethodSet([INVITE, ACK, OPTIONS, CANCEL, BYE])) supported_list = OptTagListHeader.from_list([OptionTag('100rel'), OptionTag('timers')]) options = ValidationOptions(validate=ValidationOptionsDetails(reply_on_options=True), proxy=ProxyOptionsDetails(supported=supported_list, allow=allow_methods)) response = CommonProxy.validate_request(raw_message(msg), options) assert response.status == 200 assert response.reason == 'OK' resp_raw_message = raw_message(response.serialize()) sip_response = SipMessage.parse(resp_raw_message, [ALLOW_HEADER, SUPPORTED_HEADER]) assert allow_methods == sip_response.get(ALLOW_HEADER) assert sip_response.get(SUPPORTED_HEADER) == supported_list
def test_process_route_info_no_rr_checker(): bob_uri = 'sip:[email protected]' this_proxy_uri = 'sip:this.proxy.org' next_proxy_uri = 'sip:next.proxy.org' msg = 'INVITE ' + bob_uri + ' SIP/2.0' + \ '\r\nVia: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds' + \ '\r\nVia: SIP/2.0/UDP bigbox3.site3.atlanta.com' + \ '\r\nMax-Forwards: 70' + \ '\r\nTo: Bob <sip:[email protected]>' + \ '\r\nFrom: Alice <sip:[email protected]>;tag=1928301774' + \ '\r\nCall-ID: [email protected]' + \ '\r\nCSeq: 314159 INVITE' + \ '\r\nContact: <sip:[email protected]>' + \ '\r\nRoute: <' + this_proxy_uri + '>' + \ '\r\nRoute: <' + next_proxy_uri + '>' + \ '\r\nContent-Type: application/sdp' + \ '\r\nContent-Length: 4' + \ '\r\n\r\nTest' sip_msg = process_route_info(raw_message(msg), ValidationOptions()) sip_msg = rebuild_sip_msg(sip_msg) assert sip_msg.ruri == Uri(bob_uri) assert sip_msg.get(ROUTE_HEADER) == RouteHeader.make(f'<{this_proxy_uri}>,<{next_proxy_uri}>')
def forward_request(target, raw_msg, opts): sip_msg = CommonProxy.validate_request(raw_msg, ValidationOptions(proxy=opts)) return CommonProxy.forward_request(Uri(target), sip_msg, opts)