static void test_extract_source(void) { const char * invite_1="INVITE sip:[email protected]:50343;transport=tcp;line=f18e0009dd6cc43 SIP/2.0\r\n" "Via: SIP/2.0/TCP 37.59.129.73;branch=z9hG4bK.SKvK9U327e8mU68XUv5rt144pg\r\n" "Via: SIP/2.0/UDP 192.168.1.12:15060;rport=15060;branch=z9hG4bK1596944937;received=81.56.113.2\r\n" "Record-Route: <sip:37.59.129.73;lr;transport=tcp>\r\n" "Record-Route: <sip:37.59.129.73;lr>\r\n" "Max-Forwards: 70\r\n" "From: <sip:[email protected]>;tag=711138653\r\n" "To: <sip:[email protected]>\r\n" "Call-ID: 977107319\r\n" "CSeq: 21 INVITE\r\n" "Contact: <sip:[email protected]:15060>\r\n" "Subject: Phone call\r\n" "User-Agent: Linphone/3.5.2 (eXosip2/3.6.0)\r\n" "Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO\r\n" "Content-Type: application/sdp\r\n"\ "Content-Length: 230\r\n\r\n"; const char * invite_2="INVITE sip:[email protected]:50343;transport=tcp;line=f18e0009dd6cc43 SIP/2.0\r\n" "Via: SIP/2.0/UDP 192.168.1.12:15060;rport=15060;branch=z9hG4bK1596944937;received=81.56.113.2\r\n" "Via: SIP/2.0/TCP 37.59.129.73;branch=z9hG4bK.SKvK9U327e8mU68XUv5rt144pg\r\n" "Record-Route: <sip:37.59.129.73;lr;transport=tcp>\r\n" "Record-Route: <sip:37.59.129.73;lr>\r\n" "Max-Forwards: 70\r\n" "From: <sip:[email protected]>;tag=711138653\r\n" "To: <sip:[email protected]>\r\n" "Call-ID: 977107319\r\n" "CSeq: 21 INVITE\r\n" "Contact: <sip:[email protected]:15060>\r\n" "Subject: Phone call\r\n" "User-Agent: Linphone/3.5.2 (eXosip2/3.6.0)\r\n" "Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO\r\n" "Content-Length: 0\r\n\r\n"; belle_sip_message_t* message = belle_sip_message_parse(invite_1); belle_sip_request_t* request = BELLE_SIP_REQUEST(message); belle_sip_uri_t* source =belle_sip_request_extract_origin(request); CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"Content-type")); CU_ASSERT_PTR_NOT_NULL(source); CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(source),"37.59.129.73"); CU_ASSERT_EQUAL(belle_sip_uri_get_port(source),0); CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_transport_param(source),"tcp"); belle_sip_object_unref(message); message = belle_sip_message_parse(invite_2); request = BELLE_SIP_REQUEST(message); source =belle_sip_request_extract_origin(request); CU_ASSERT_PTR_NOT_NULL(source); CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(source),"81.56.113.2"); CU_ASSERT_EQUAL(belle_sip_uri_get_port(source),15060); CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_transport_param(source),"udp"); belle_sip_object_unref(message); }
const char* sal_address_get_transport_name(const SalAddress* addr){ belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr); belle_sip_uri_t* uri = belle_sip_header_address_get_uri(header_addr); if (uri) { return belle_sip_uri_get_transport_param(uri); } return NULL; }
int belle_sip_uri_get_listening_port(const belle_sip_uri_t *uri){ int port=belle_sip_uri_get_port(uri); const char *transport=belle_sip_uri_get_transport_param(uri); if (!transport) { transport=belle_sip_uri_is_secure(uri)?"tls":"udp"; } if (port==0) port=belle_sip_listening_point_get_well_known_port(transport); return port; }
static void testCOMPLEXURI(void) { belle_sip_uri_t* L_tmp; belle_sip_uri_t * L_uri = belle_sip_uri_parse("sip:[email protected]:5060;transport=tcp"); char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri)); belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri)); L_tmp = belle_sip_uri_parse(l_raw_uri); L_uri = BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp))); belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp)); belle_sip_free(l_raw_uri); CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_user(L_uri), "toto"); CU_ASSERT_EQUAL(belle_sip_uri_get_port(L_uri), 5060); CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(L_uri), "titi.com"); CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_transport_param(L_uri), "tcp"); belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri)); }
static void testSIMPLEURI(void) { belle_sip_uri_t* L_tmp; belle_sip_uri_t* L_uri = belle_sip_uri_parse("sip:sip.titi.com"); char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri)); belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri)); L_tmp = belle_sip_uri_parse(l_raw_uri); L_uri = BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp))); belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp)); belle_sip_free(l_raw_uri); CU_ASSERT_PTR_NULL(belle_sip_uri_get_user(L_uri)); CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(L_uri), "sip.titi.com"); CU_ASSERT_PTR_NULL(belle_sip_uri_get_transport_param(L_uri)); belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri)); }
belle_sip_hop_t* belle_sip_hop_new_from_uri(const belle_sip_uri_t *uri){ const char *host; const char *cname=NULL; const char * transport=belle_sip_uri_get_transport_param(uri); if (!transport) { transport=belle_sip_uri_is_secure(uri)?"tls":"udp"; } host=belle_sip_uri_get_maddr_param(uri); if (!host) host=belle_sip_uri_get_host(uri); else cname=belle_sip_uri_get_host(uri); return belle_sip_hop_new( transport, cname, host, belle_sip_uri_get_listening_port(uri)); }
static void testIPV6URI_base(const char* ip6) { belle_sip_uri_t* L_tmp; belle_sip_uri_t * L_uri; char* l_raw_uri; char uri[256]; snprintf(uri,sizeof(uri),"sip:toto@[%s]:5060;transport=tcp",ip6); L_uri = belle_sip_uri_parse(uri); l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri)); belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri)); L_tmp = belle_sip_uri_parse(l_raw_uri); L_uri = BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp))); belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp)); belle_sip_free(l_raw_uri); CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_user(L_uri), "toto"); CU_ASSERT_EQUAL(belle_sip_uri_get_port(L_uri), 5060); CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(L_uri),ip6); CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_transport_param(L_uri), "tcp"); belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri)); }
static void test_uri_parameters (void) { char* l_raw_uri; belle_sip_uri_t* L_tmp; belle_sip_uri_t * L_uri = belle_sip_uri_parse("sip:192.168.0.1;ttl=12"); belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri)); L_uri = belle_sip_uri_parse("sip:[email protected];lr;maddr=192.168.0.1;user=ip;ttl=140;transport=sctp;method=INVITE;rport=5060"); l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri)); belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri)); L_tmp = belle_sip_uri_parse(l_raw_uri); L_uri = BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp))); belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp)); belle_sip_free(l_raw_uri); CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_maddr_param(L_uri), "192.168.0.1"); CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_user_param(L_uri), "ip"); CU_ASSERT_EQUAL(belle_sip_uri_get_ttl_param(L_uri),140); CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_transport_param(L_uri), "sctp"); CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_method_param(L_uri), "INVITE"); belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri)); }
static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* request, bool_t add_contact) { belle_sip_client_transaction_t* client_transaction; belle_sip_provider_t* prov=op->base.root->prov; belle_sip_uri_t* outbound_proxy=NULL; belle_sip_header_contact_t* contact; int result =-1; belle_sip_uri_t *next_hop_uri=NULL; if (add_contact && !belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(request),belle_sip_header_contact_t)) { contact = sal_op_create_contact(op); belle_sip_message_set_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(contact)); } /*keep existing*/ _sal_op_add_custom_headers(op, (belle_sip_message_t*)request); if (!op->dialog || belle_sip_dialog_get_state(op->dialog) == BELLE_SIP_DIALOG_NULL) { /*don't put route header if dialog is in confirmed state*/ const MSList *elem=sal_op_get_route_addresses(op); const char *transport; const char *method=belle_sip_request_get_method(request); belle_sip_listening_point_t *udplp=belle_sip_provider_get_listening_point(prov,"UDP"); if (elem) { outbound_proxy=belle_sip_header_address_get_uri((belle_sip_header_address_t*)elem->data); next_hop_uri=outbound_proxy; }else{ next_hop_uri=(belle_sip_uri_t*)belle_sip_object_clone((belle_sip_object_t*)belle_sip_request_get_uri(request)); } transport=belle_sip_uri_get_transport_param(next_hop_uri); if (transport==NULL){ /*compatibility mode: by default it should be udp as not explicitely set and if no udp listening point is available, then use * the first available transport*/ if (!belle_sip_uri_is_secure(next_hop_uri)){ if (udplp==NULL){ if (belle_sip_provider_get_listening_point(prov,"TCP")!=NULL){ transport="tcp"; }else if (belle_sip_provider_get_listening_point(prov,"TLS")!=NULL ){ transport="tls"; } } if (transport){ belle_sip_message("Transport is not specified, using %s because UDP is not available.",transport); belle_sip_uri_set_transport_param(next_hop_uri,transport); } } }else{ #ifdef TUNNEL_ENABLED if (udplp && BELLE_SIP_OBJECT_IS_INSTANCE_OF(udplp,belle_sip_tunnel_listening_point_t)){ /* our tunnel mode only supports UDP. Force transport to be set to UDP */ belle_sip_uri_set_transport_param(next_hop_uri,"udp"); } #endif } if ((strcmp(method,"REGISTER")==0 || strcmp(method,"SUBSCRIBE")==0) && transport && (strcasecmp(transport,"TCP")==0 || strcasecmp(transport,"TLS")==0)){ /*RFC 5923: add 'alias' parameter to tell the server that we want it to keep the connection for future requests*/ belle_sip_header_via_t *via=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(request),belle_sip_header_via_t); belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(via),"alias",NULL); } } client_transaction = belle_sip_provider_create_client_transaction(prov,request); belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(client_transaction),sal_op_ref(op)); if (op->pending_client_trans) belle_sip_object_unref(op->pending_client_trans); op->pending_client_trans=client_transaction; /*update pending inv for being able to cancel*/ belle_sip_object_ref(op->pending_client_trans); if (belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(request),belle_sip_header_user_agent_t)==NULL) belle_sip_message_add_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(op->base.root->user_agent)); if (!belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_AUTHORIZATION) && !belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_PROXY_AUTHORIZATION)) { /*hmm just in case we already have authentication param in cache*/ belle_sip_provider_add_authorization(op->base.root->prov,request,NULL,NULL,NULL,op->base.realm); } result = belle_sip_client_transaction_send_request_to(client_transaction,next_hop_uri/*might be null*/); /*update call id if not set yet for this OP*/ if (result == 0 && !op->base.call_id) { op->base.call_id=ms_strdup(belle_sip_header_call_id_get_call_id(BELLE_SIP_HEADER_CALL_ID(belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(request), belle_sip_header_call_id_t)))); } return result; }
const char *belle_sip_listening_point_get_transport(const belle_sip_listening_point_t *lp){ return belle_sip_uri_get_transport_param(lp->listening_uri); }
static void process_response_event(void *user_ctx, const belle_sip_response_event_t *event){ belle_sip_client_transaction_t* client_transaction = belle_sip_response_event_get_client_transaction(event); belle_sip_response_t* response = belle_sip_response_event_get_response(event); int response_code = belle_sip_response_get_status_code(response); if (!client_transaction) { ms_warning("Discarding stateless response [%i]",response_code); return; } else { SalOp* op = (SalOp*)belle_sip_transaction_get_application_data(BELLE_SIP_TRANSACTION(client_transaction)); belle_sip_request_t* request=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction)); belle_sip_header_contact_t* original_contact; belle_sip_header_address_t* contact_address=NULL; belle_sip_header_via_t* via_header; belle_sip_uri_t* contact_uri; unsigned int contact_port; const char* received; int rport; bool_t contact_updated=FALSE; char* new_contact; if (op->state == SalOpStateTerminated) { belle_sip_message("Op is terminated, nothing to do with this [%i]",response_code); return; } if (!op->base.remote_ua) { sal_op_set_remote_ua(op,BELLE_SIP_MESSAGE(response)); } if (!op->base.call_id) { op->base.call_id=ms_strdup(belle_sip_header_call_id_get_call_id(BELLE_SIP_HEADER_CALL_ID(belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(response), belle_sip_header_call_id_t)))); } sal_op_assign_recv_headers(op,(belle_sip_message_t*)response); if (op->callbacks.process_response_event) { if (op->base.root->nat_helper_enabled) { /*Fix contact if needed*/ via_header= (belle_sip_header_via_t*)belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_VIA); received = belle_sip_header_via_get_received(via_header); rport = belle_sip_header_via_get_rport(via_header); if ((original_contact=belle_sip_message_get_header_by_type(request,belle_sip_header_contact_t))) { /*update contact with sent values in any cases*/ contact_address=belle_sip_header_address_create(NULL,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(original_contact))); sal_op_set_contact_address(op,(const SalAddress *)contact_address); belle_sip_object_unref(contact_address); } if (sal_op_get_contact(op)){ if (received!=NULL || rport>0) { contact_address = BELLE_SIP_HEADER_ADDRESS(sal_address_clone(sal_op_get_contact_address(op))); contact_uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(contact_address)); if (received && strcmp(received,belle_sip_uri_get_host(contact_uri))!=0) { /*need to update host*/ belle_sip_uri_set_host(contact_uri,received); contact_updated=TRUE; } contact_port = belle_sip_uri_get_port(contact_uri); if (rport>0 && rport!=contact_port && (contact_port+rport)!=5060) { /*need to update port*/ belle_sip_uri_set_port(contact_uri,rport); contact_updated=TRUE; } /*try to fix transport if needed (very unlikely)*/ if (strcasecmp(belle_sip_header_via_get_transport(via_header),"UDP")!=0) { if (!belle_sip_uri_get_transport_param(contact_uri) ||strcasecmp(belle_sip_uri_get_transport_param(contact_uri),belle_sip_header_via_get_transport(via_header))!=0) { belle_sip_uri_set_transport_param(contact_uri,belle_sip_header_via_get_transport_lowercase(via_header)); contact_updated=TRUE; } } else { if (belle_sip_uri_get_transport_param(contact_uri)) { contact_updated=TRUE; belle_sip_uri_set_transport_param(contact_uri,NULL); } } if (contact_updated) { char* old_contact=belle_sip_object_to_string(BELLE_SIP_OBJECT(sal_op_get_contact_address(op))); new_contact=belle_sip_object_to_string(BELLE_SIP_OBJECT(contact_address)); ms_message("Updating contact from [%s] to [%s] for [%p]",old_contact,new_contact,op); sal_op_set_contact_address(op,(const SalAddress *)contact_address); belle_sip_free(new_contact); belle_sip_free(old_contact); } if (contact_address)belle_sip_object_unref(contact_address); } } } /*handle authorization*/ switch (response_code) { case 200: { break; } case 401: case 407:{ /*belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(client_transaction),NULL);*//*remove op from trans*/ if (op->state == SalOpStateTerminating && strcmp("BYE",belle_sip_request_get_method(request))!=0) { /*only bye are completed*/ belle_sip_message("Op is in state terminating, nothing else to do "); } else { if (op->pending_auth_transaction){ belle_sip_object_unref(op->pending_auth_transaction); op->pending_auth_transaction=NULL; } op->pending_auth_transaction=(belle_sip_client_transaction_t*)belle_sip_object_ref(client_transaction); sal_process_authentication(op); return; } } } op->callbacks.process_response_event(op,event); } else { ms_error("Unhandled event response [%p]",event); } } }