Commit 8b6ea1ad authored by Simon Morlat's avatar Simon Morlat
Browse files

fix crash in belle_sip_channel_t, when the inactive timeout timer triggers...

fix crash in belle_sip_channel_t, when the inactive timeout timer triggers just after the listening point has cleaned out all its channels (due to linphone_core_set_network_reachable(false)).
The main loop has only one reference when this removes, so when belle_sip_channel_close() removes the parent belle_sip_source_t from the main loop, the channel is destroyed.
The call to belle_sip_source_uninit() at the end of _close() then overwrites free memory.
parent 934612c9
......@@ -115,10 +115,10 @@ int belle_sip_auth_helper_compute_response(const char* ha1,const char* nonce, co
,strlen(nonce));
belle_sip_md5_append(&state,(const md5_byte_t *)":",1);
belle_sip_md5_append(&state,(const md5_byte_t *)ha2,strlen(ha2));
belle_sip_md5_finish(&state,out);
/*copy values*/
for (di = 0; di < 16; ++di)
sprintf(response + di * 2, "%02x", out[di]);
belle_sip_md5_finish(&state,out);
/*copy values*/
for (di = 0; di < 16; ++di)
sprintf(response + di * 2, "%02x", out[di]);
return 0;
}
......
......@@ -856,8 +856,11 @@ int belle_sip_channel_recv(belle_sip_channel_t *obj, void *buf, size_t buflen){
void belle_sip_channel_close(belle_sip_channel_t *obj){
if (BELLE_SIP_OBJECT_VPTR(obj,belle_sip_channel_t)->close)
BELLE_SIP_OBJECT_VPTR(obj,belle_sip_channel_t)->close(obj); /*udp channel doesn't have close function*/
belle_sip_object_ref(obj);
/*removing the source (our base class) will decrement the ref count, this why this code needs to be protected by ref/unref.*/
belle_sip_main_loop_remove_source(obj->stack->ml,(belle_sip_source_t*)obj);
belle_sip_source_uninit((belle_sip_source_t*)obj);
belle_sip_object_unref(obj);
}
const struct addrinfo * belle_sip_channel_get_peer(belle_sip_channel_t *obj){
......@@ -905,14 +908,23 @@ static void channel_end_recv_background_task(belle_sip_channel_t *obj){
}
static void channel_invoke_state_listener(belle_sip_channel_t *obj){
if (obj->state==BELLE_SIP_CHANNEL_DISCONNECTED || obj->state==BELLE_SIP_CHANNEL_ERROR){
int close = FALSE;
switch(obj->state){
case BELLE_SIP_CHANNEL_DISCONNECTED:
case BELLE_SIP_CHANNEL_ERROR:
/*the background tasks must be released "after" notifying the app of the disconnected or error state
By "after" it is means not before the main loop iteration that will notify the app*/
By "after" it is means not before the main loop iteration that will notify the app.
This is the reason why these calls are done here rather than in the channel_set_state() function.*/
channel_end_send_background_task(obj);
channel_end_recv_background_task(obj);
belle_sip_channel_close(obj);
close = TRUE;
break;
default:
break;
}
BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2(obj->listeners,belle_sip_channel_listener_t,on_state_changed,obj,obj->state);
/*since _close() removes the channel from the main loop (dropping the channel's reference count), it must be done at the end*/
if (close) belle_sip_channel_close(obj);
}
static void channel_invoke_state_listener_defered(belle_sip_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