belle_sip_uri_t *belle_sip_channel_create_routable_uri(belle_sip_channel_t *chan) { const char *transport = belle_sip_channel_get_transport_name_lower_case(chan); belle_sip_uri_t* uri = belle_sip_uri_new(); unsigned char natted = chan->public_ip && strcmp(chan->public_ip,chan->local_ip)!=0; if (natted) { belle_sip_uri_set_host(uri, chan->public_ip); belle_sip_uri_set_port(uri, chan->public_port); } else { belle_sip_uri_set_host(uri, chan->local_ip); // With streamed protocols listening port is what we want if (chan->lp) belle_sip_uri_set_port(uri, belle_sip_uri_get_port(chan->lp->listening_uri)); else belle_sip_uri_set_port(uri,chan->local_port); } belle_sip_uri_set_transport_param(uri, transport); belle_sip_uri_set_lr_param(uri, TRUE); return uri; }
void belle_sip_stream_listening_point_setup_server_socket(belle_sip_stream_listening_point_t *obj, belle_sip_source_func_t on_new_connection_cb ){ int port=belle_sip_uri_get_port(obj->base.listening_uri); obj->server_sock=create_server_socket(belle_sip_uri_get_host(obj->base.listening_uri), &port, &obj->base.ai_family); if (obj->server_sock==(belle_sip_socket_t)-1) return; belle_sip_uri_set_port(((belle_sip_listening_point_t*)obj)->listening_uri,port); if (obj->base.stack->dscp) belle_sip_socket_set_dscp(obj->server_sock,obj->base.ai_family,obj->base.stack->dscp); obj->source=belle_sip_socket_source_new(on_new_connection_cb,obj,obj->server_sock,BELLE_SIP_EVENT_READ,-1); belle_sip_main_loop_add_source(obj->base.stack->ml,obj->source); }
static int belle_sip_udp_listening_point_init_socket(belle_sip_udp_listening_point_t *lp){ int port=belle_sip_uri_get_listening_port(((belle_sip_listening_point_t*)lp)->listening_uri); lp->sock=create_udp_socket(belle_sip_uri_get_host(((belle_sip_listening_point_t*)lp)->listening_uri) ,&port,&lp->base.ai_family); if (lp->sock==(belle_sip_socket_t)-1){ return -1; } belle_sip_uri_set_port(((belle_sip_listening_point_t*)lp)->listening_uri,port); if (lp->base.stack->dscp) belle_sip_socket_set_dscp(lp->sock,lp->base.ai_family,lp->base.stack->dscp); lp->source=belle_sip_socket_source_new((belle_sip_source_func_t)on_udp_data,lp,lp->sock,BELLE_SIP_EVENT_READ,-1); belle_sip_main_loop_add_source(((belle_sip_listening_point_t*)lp)->stack->ml,lp->source); return 0; }
void belle_sip_listening_point_init(belle_sip_listening_point_t *lp, belle_sip_stack_t *s, const char *address, int port){ char *tmp; belle_sip_init_sockets(); lp->stack=s; lp->listening_uri=belle_sip_uri_create(NULL,address); belle_sip_object_ref(lp->listening_uri); belle_sip_uri_set_port(lp->listening_uri,port); belle_sip_uri_set_transport_param(lp->listening_uri,BELLE_SIP_OBJECT_VPTR(lp,belle_sip_listening_point_t)->transport); tmp=belle_sip_object_to_string((belle_sip_object_t*)BELLE_SIP_LISTENING_POINT(lp)->listening_uri); if (strchr(address,':')) { lp->ai_family=AF_INET6; } else { lp->ai_family=AF_INET; } belle_sip_message("Creating listening point [%p] on [%s]",lp, tmp); belle_sip_free(tmp); }
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); } } }