Example #1
0
static void tls_channel_close(belle_sip_tls_channel_t *obj){
	belle_sip_socket_t sock = belle_sip_source_get_socket((belle_sip_source_t*)obj);
	if (sock!=-1 && belle_sip_channel_get_state((belle_sip_channel_t*)obj)!=BELLE_SIP_CHANNEL_ERROR)
		ssl_close_notify(&obj->sslctx);
	stream_channel_close((belle_sip_stream_channel_t*)obj);
	ssl_session_reset(&obj->sslctx);
	obj->socket_connected=0;
}
Example #2
0
static void process_io_error(belle_sip_listener_t *user_ctx, const belle_sip_io_error_event_t *event){
	belle_sip_refresher_t* refresher=(belle_sip_refresher_t*)user_ctx;
	belle_sip_client_transaction_t*client_transaction;
	if (refresher->on_io_error==1) {
		return; /*refresher already on error*/
	}
	if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(belle_sip_io_error_event_get_source(event),belle_sip_client_transaction_t)) {
		client_transaction=BELLE_SIP_CLIENT_TRANSACTION(belle_sip_io_error_event_get_source(event));
		if (!refresher || (refresher && ((refresher->state==stopped
			&& belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(refresher->transaction)) != BELLE_SIP_TRANSACTION_TRYING
			&& belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(refresher->transaction)) != BELLE_SIP_TRANSACTION_INIT /*to cover dns or certificate error*/)
			|| client_transaction !=refresher->transaction )))
				return; /*not for me or no longuer involved*/

		if (refresher->target_expires==0
				&& belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(refresher->transaction)) != BELLE_SIP_TRANSACTION_TRYING
				&& belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(refresher->transaction)) != BELLE_SIP_TRANSACTION_INIT ) {
			return; /*not for me or no longuer involved because expire=0*/
		}
		if (refresher->state==started) retry_later_on_io_error(refresher);
		if (refresher->listener) refresher->listener(refresher,refresher->user_data,503, "io error");

		return;
	} else if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(belle_sip_io_error_event_get_source(event),belle_sip_provider_t)) {
		/*something went wrong on this provider, checking if my channel is still up*/
		if (refresher->state==started  /*refresher started or trying to refresh */
				&& belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(refresher->transaction)) == BELLE_SIP_TRANSACTION_TERMINATED /*else we are notified by transaction error*/
				&& refresher->transaction->base.channel /*transaction may not have any channel*/
				&&	(belle_sip_channel_get_state(refresher->transaction->base.channel) == BELLE_SIP_CHANNEL_DISCONNECTED
								||belle_sip_channel_get_state(refresher->transaction->base.channel) == BELLE_SIP_CHANNEL_ERROR)) {
			belle_sip_message("refresher [%p] has channel [%p] in state [%s], reporting error"
								,refresher
								,refresher->transaction->base.channel
								,belle_sip_channel_state_to_string(belle_sip_channel_get_state(refresher->transaction->base.channel)));
			if (refresher->state==started) retry_later_on_io_error(refresher);
			if (refresher->listener) refresher->listener(refresher,refresher->user_data,503, "io error");
			refresher->on_io_error=1;
		}
		return;
	}else {
		/*belle_sip_error("Refresher process_io_error not implemented yet for non transaction/provider source");*/
		/*nop, because already handle at transaction layer*/
	}
}
Example #3
0
int belle_sip_client_transaction_send_request_to(belle_sip_client_transaction_t *t,belle_sip_uri_t* outbound_proxy) {
	belle_sip_channel_t *chan;
	belle_sip_provider_t *prov=t->base.provider;
	belle_sip_dialog_t *dialog=t->base.dialog;
	belle_sip_request_t *req=t->base.request;
	int result=-1;

	if (t->base.state!=BELLE_SIP_TRANSACTION_INIT){
		belle_sip_error("belle_sip_client_transaction_send_request: bad state.");
		return -1;
	}

	/*check uris components compliance*/
	if (!belle_sip_request_check_uris_components(t->base.request)) {
		belle_sip_error("belle_sip_client_transaction_send_request: bad request for transaction [%p]",t);
		return -1;
	}
	/*store preset route for future use by refresher*/
	if (outbound_proxy){
		t->preset_route=outbound_proxy;
		belle_sip_object_ref(t->preset_route);
	}

	if (t->base.sent_by_dialog_queue){
		
		/*it can be sent immediately, so update the request with latest cseq and route_set */
		/*update route and contact just in case they changed*/
		belle_sip_dialog_update_request(dialog,req);
	} else if (t->base.request->dialog_queued){
		/*this request was created by belle_sip_dialog_create_queued_request().*/
		if (belle_sip_dialog_request_pending(dialog) || dialog->queued_ct!=NULL){
			/*it cannot be sent immediately, queue the transaction into dialog*/
			belle_sip_message("belle_sip_client_transaction_send_request(): transaction [%p], cannot send request now because dialog is busy"
			" or other transactions are queued, so queuing into dialog.",t);
			belle_sip_dialog_queue_client_transaction(dialog,t);
			return 0;
		}
		belle_sip_dialog_update_request(dialog,req);
	}

	if (dialog){
		belle_sip_dialog_update(dialog,(belle_sip_transaction_t*)t,BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_server_transaction_t));
	}

	if (!t->next_hop) {
		if (t->preset_route) {
			t->next_hop=belle_sip_hop_new_from_uri(t->preset_route);
		} else {
			t->next_hop = belle_sip_stack_get_next_hop(prov->stack,t->base.request);
		}
		belle_sip_object_ref(t->next_hop);
	} else {
		/*next hop already preset, probably in case of CANCEL*/
	}
	belle_sip_provider_add_client_transaction(t->base.provider,t); /*add it in any case*/
	chan=belle_sip_provider_get_channel(prov,t->next_hop);
	if (chan){
		belle_sip_object_ref(chan);
		belle_sip_channel_add_listener(chan,BELLE_SIP_CHANNEL_LISTENER(t));
		t->base.channel=chan;
		if (belle_sip_channel_get_state(chan)==BELLE_SIP_CHANNEL_INIT){
			belle_sip_message("belle_sip_client_transaction_send_request(): waiting channel to be ready");
			belle_sip_channel_prepare(chan);
			/*the channel will notify us when it is ready*/
		} else if (belle_sip_channel_get_state(chan)==BELLE_SIP_CHANNEL_READY){
			/*otherwise we can send immediately*/
			BELLE_SIP_OBJECT_VPTR(t,belle_sip_client_transaction_t)->send_request(t);
		}
		result=0;
	}else {
		belle_sip_error("belle_sip_client_transaction_send_request(): no channel available");
		belle_sip_transaction_terminate(BELLE_SIP_TRANSACTION(t));
		result=-1;
	}
	return result;
}