Commit c32eb6f8 authored by Benjamin REIS's avatar Benjamin REIS

add background task to transaction and handle IOS10 socket error

parent 5bb7c82f
......@@ -661,6 +661,7 @@ struct belle_sip_transaction{
unsigned char is_internal;
unsigned char timed_out;
unsigned char sent_by_dialog_queue;
unsigned long bg_task_id;
};
......
......@@ -670,6 +670,7 @@ static int belle_sip_channel_process_read_data(belle_sip_channel_t *obj){
} else if (num == 0) {
/*before closing the channel, check if there was a pending message to receive, whose body acquisition is to be finished.*/
belle_sip_channel_process_stream(obj,TRUE);
obj->closed_by_remote = TRUE;
channel_set_state(obj,BELLE_SIP_CHANNEL_DISCONNECTED);
ret=BELLE_SIP_STOP;
} else if (belle_sip_error_code_is_would_block(-num)){
......
......@@ -123,6 +123,7 @@ struct belle_sip_channel{
unsigned char srv_overrides_port; /*set when this channel was connected to destination port provided by SRV resolution*/
unsigned char soft_error; /*set when this channel enters ERROR state because of error detected in upper layer */
int stop_logging_buffer; /*log buffer content only if this is non binary data, and stop it at the first occurence*/
bool_t closed_by_remote; /*If the channel has been remotely closed*/
};
#define BELLE_SIP_CHANNEL(obj) BELLE_SIP_CAST(obj,belle_sip_channel_t)
......
......@@ -55,7 +55,28 @@ BELLESIP_EXPORT const char *belle_sip_transaction_get_method(const belle_sip_tra
return belle_sip_request_get_method(t->request);
}
static void transaction_end_background_task(belle_sip_transaction_t *obj){
if (obj->bg_task_id){
belle_sip_message("channel [%p]: ending transaction background task with id=[%lx].",obj,obj->bg_task_id);
belle_sip_end_background_task(obj->bg_task_id);
obj->bg_task_id=0;
}
}
static void transaction_background_task_ended(belle_sip_transaction_t *obj){
belle_sip_warning("channel [%p]: transaction background task has to be ended now, but work isn't finished.",obj);
transaction_end_background_task(obj);
}
static void transaction_begin_background_task(belle_sip_transaction_t *obj){
if (obj->bg_task_id==0){
obj->bg_task_id=belle_sip_begin_background_task("belle-sip transaction",(void (*)(void*))transaction_background_task_ended, obj);
if (obj->bg_task_id) belle_sip_message("channel [%p]: starting transaction background task with id=[%lx].",obj,obj->bg_task_id);
}
}
static void belle_sip_transaction_init(belle_sip_transaction_t *t, belle_sip_provider_t *prov, belle_sip_request_t *req){
transaction_begin_background_task(t);
t->request=(belle_sip_request_t*)belle_sip_object_ref(req);
t->provider=prov;
}
......@@ -217,6 +238,7 @@ int belle_sip_transaction_state_is_transient(const belle_sip_transaction_state_t
}
void belle_sip_transaction_terminate(belle_sip_transaction_t *t){
belle_sip_object_ref(t);
if (t->call_repair_timer) {
belle_sip_transaction_stop_timer(t, t->call_repair_timer);
belle_sip_object_unref(t->call_repair_timer);
......@@ -236,6 +258,8 @@ void belle_sip_transaction_terminate(belle_sip_transaction_t *t){
BELLE_SIP_OBJECT_VPTR(t,belle_sip_transaction_t)->on_terminate(t);
belle_sip_provider_set_transaction_terminated(t->provider,t);
}
belle_sip_object_unref(t);
transaction_end_background_task(t);
}
belle_sip_request_t *belle_sip_transaction_get_request(const belle_sip_transaction_t *t){
......
......@@ -54,6 +54,13 @@ int stream_channel_send(belle_sip_stream_channel_t *obj, const void *buf, size_t
int stream_channel_recv(belle_sip_stream_channel_t *obj, void *buf, size_t buflen){
belle_sip_socket_t sock = belle_sip_source_get_socket((belle_sip_source_t*)obj);
int err=bctbx_recv(sock,buf,buflen,0);
if (strcmp(belle_sip_get_socket_error_string(), "Socket is not connected") == 0) { //Do NOT treat it as an error
belle_sip_message("Socket is not connected because of IOS10 background policy");
obj->base.closed_by_remote = TRUE;
return 0;
}
if (err==(belle_sip_socket_t)-1){
int errnum=get_socket_error();
if (!belle_sip_error_code_is_would_block(errnum)){
......
......@@ -353,7 +353,7 @@ struct belle_sip_tls_channel{
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) {
if (sock!=-1 && belle_sip_channel_get_state((belle_sip_channel_t*)obj)!=BELLE_SIP_CHANNEL_ERROR && !obj->base.base.closed_by_remote) {
if (obj->sslctx) bctbx_ssl_close_notify(obj->sslctx);
}
stream_channel_close((belle_sip_stream_channel_t*)obj);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment