forked from mirrors/linphone-iphone
fix crash when receiving an invalid 200Ok for INVITE
This commit is contained in:
parent
a4b116d4e4
commit
aa7adfdac7
2 changed files with 46 additions and 17 deletions
|
|
@ -32,8 +32,9 @@ static void call_set_released(SalOp* op){
|
|||
}
|
||||
}
|
||||
|
||||
static void call_set_error(SalOp* op,belle_sip_response_t* response){
|
||||
static void call_set_error(SalOp* op,belle_sip_response_t* response, bool_t fatal){
|
||||
sal_op_set_error_info_from_response(op,response);
|
||||
if (fatal) op->state = SalOpStateTerminating;
|
||||
op->base.root->callbacks.call_failure(op);
|
||||
}
|
||||
static void set_addr_to_0000(char value[]) {
|
||||
|
|
@ -149,6 +150,7 @@ static void call_process_io_error(void *user_ctx, const belle_sip_io_error_event
|
|||
/*call terminated very early*/
|
||||
sal_error_info_set(&op->error_info,SalReasonIOError,503,"IO error",NULL);
|
||||
op->base.root->callbacks.call_failure(op);
|
||||
op->state = SalOpStateTerminating;
|
||||
call_set_released(op);
|
||||
} else {
|
||||
/*dialog will terminated shortly, nothing to do*/
|
||||
|
|
@ -162,6 +164,14 @@ static void process_dialog_terminated(void *ctx, const belle_sip_dialog_terminat
|
|||
ms_message("Dialog [%p] terminated for op [%p]",belle_sip_dialog_terminated_event_get_dialog(event),op);
|
||||
|
||||
switch(belle_sip_dialog_get_previous_state(op->dialog)) {
|
||||
case BELLE_SIP_DIALOG_EARLY:
|
||||
case BELLE_SIP_DIALOG_NULL:
|
||||
if (op->state!=SalOpStateTerminated && op->state!=SalOpStateTerminating) {
|
||||
/*this is an early termination due to incorrect response received*/
|
||||
op->base.root->callbacks.call_failure(op);
|
||||
op->state=SalOpStateTerminating;
|
||||
}
|
||||
break;
|
||||
case BELLE_SIP_DIALOG_CONFIRMED:
|
||||
if (op->state!=SalOpStateTerminated && op->state!=SalOpStateTerminating) {
|
||||
/*this is probably a normal termination from a BYE*/
|
||||
|
|
@ -201,7 +211,23 @@ static void cancelling_invite(SalOp* op ){
|
|||
belle_sip_request_t* cancel;
|
||||
ms_message("Cancelling INVITE request from [%s] to [%s] ",sal_op_get_from(op), sal_op_get_to(op));
|
||||
cancel = belle_sip_client_transaction_create_cancel(op->pending_client_trans);
|
||||
sal_op_send_request(op,cancel);
|
||||
if (cancel){
|
||||
sal_op_send_request(op,cancel);
|
||||
}else if (op->dialog){
|
||||
belle_sip_dialog_state_t state = belle_sip_dialog_get_state(op->dialog);;
|
||||
/*case where the response received is invalid (could not establish a dialog), but the transaction is not cancellable
|
||||
* because already terminated*/
|
||||
switch(state){
|
||||
case BELLE_SIP_DIALOG_EARLY:
|
||||
case BELLE_SIP_DIALOG_NULL:
|
||||
/*force kill the dialog*/
|
||||
ms_warning("op [%p]: force kill of dialog [%p]", op, op->dialog);
|
||||
belle_sip_dialog_delete(op->dialog);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
op->state=SalOpStateTerminating;
|
||||
}
|
||||
|
||||
|
|
@ -263,7 +289,7 @@ static void call_process_response(void *op_base, const belle_sip_response_event_
|
|||
}
|
||||
belle_sip_object_data_set(BELLE_SIP_OBJECT(dialog),"early_response",belle_sip_object_ref(response),belle_sip_object_unref);
|
||||
} else if (code>=300){
|
||||
call_set_error(op,response);
|
||||
call_set_error(op, response, TRUE);
|
||||
if (op->dialog==NULL) call_set_released(op);
|
||||
}
|
||||
} else if (code >=200
|
||||
|
|
@ -295,7 +321,7 @@ static void call_process_response(void *op_base, const belle_sip_response_event_
|
|||
op->base.root->callbacks.call_accepted(op); /*INVITE*/
|
||||
op->state=SalOpStateActive;
|
||||
}else if (code >= 300){
|
||||
call_set_error(op,response);
|
||||
call_set_error(op,response, FALSE);
|
||||
}
|
||||
}else if (strcmp("INFO",method)==0){
|
||||
if (code == 491
|
||||
|
|
@ -324,7 +350,7 @@ static void call_process_response(void *op_base, const belle_sip_response_event_
|
|||
break;
|
||||
case BELLE_SIP_DIALOG_TERMINATED: {
|
||||
if (strcmp("INVITE",method)==0 && code >= 300){
|
||||
call_set_error(op,response);
|
||||
call_set_error(op,response, TRUE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -345,6 +371,7 @@ static void call_process_timeout(void *user_ctx, const belle_sip_timeout_event_t
|
|||
/*call terminated very early*/
|
||||
sal_error_info_set(&op->error_info,SalReasonRequestTimeout,408,"Request timeout",NULL);
|
||||
op->base.root->callbacks.call_failure(op);
|
||||
op->state = SalOpStateTerminating;
|
||||
call_set_released(op);
|
||||
} else {
|
||||
/*dialog will terminated shortly, nothing to do*/
|
||||
|
|
@ -378,6 +405,7 @@ static void call_process_transaction_terminated(void *user_ctx, const belle_sip_
|
|||
}else if (op->state == SalOpStateEarly && code < 200){
|
||||
/*call terminated early*/
|
||||
sal_error_info_set(&op->error_info,SalReasonIOError,503,"I/O error",NULL);
|
||||
op->state = SalOpStateTerminating;
|
||||
op->base.root->callbacks.call_failure(op);
|
||||
release_call=TRUE;
|
||||
}
|
||||
|
|
@ -396,6 +424,7 @@ static void call_process_transaction_terminated(void *user_ctx, const belle_sip_
|
|||
|
||||
static void call_terminated(SalOp* op,belle_sip_server_transaction_t* server_transaction, belle_sip_request_t* request,int status_code) {
|
||||
belle_sip_response_t* resp;
|
||||
op->state = SalOpStateTerminating;
|
||||
op->base.root->callbacks.call_terminated(op,op->dir==SalOpDirIncoming?sal_op_get_from(op):sal_op_get_to(op));
|
||||
resp=sal_op_create_response_from_request(op,request,status_code);
|
||||
belle_sip_server_transaction_send_response(server_transaction,resp);
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ static FILE *sip_start(const char *senario, const char* dest_username, LinphoneA
|
|||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
static FILE *sip_start_recv(const char *senario) {
|
||||
#if HAVE_SIPP
|
||||
char *command;
|
||||
|
|
@ -88,7 +88,7 @@ static FILE *sip_start_recv(const char *senario) {
|
|||
return NULL;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*static void dest_server_server_resolved(void *data, const char *name, struct addrinfo *ai_list) {
|
||||
*(struct addrinfo **)data =ai_list;
|
||||
|
|
@ -306,7 +306,7 @@ static void call_with_multiple_video_mline_in_sdp() {
|
|||
linphone_core_manager_destroy(mgr);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
static void call_invite_200ok_without_contact_header() {
|
||||
LinphoneCoreManager *mgr;
|
||||
char *identity_char;
|
||||
|
|
@ -333,16 +333,18 @@ static void call_invite_200ok_without_contact_header() {
|
|||
BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallOutgoingInit, 1));
|
||||
BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallOutgoingProgress, 1));
|
||||
BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallOutgoingRinging, 1));
|
||||
if (call) {
|
||||
BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallStreamsRunning, 1));
|
||||
check_rtcp(call);
|
||||
linphone_core_terminate_call(mgr->lc, call);
|
||||
}
|
||||
/*assert that the call never gets connected nor terminated*/
|
||||
BC_ASSERT_FALSE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallConnected, 1));
|
||||
BC_ASSERT_EQUAL(mgr->stat.number_of_LinphoneCallEnd, 0, int, "%d");
|
||||
BC_ASSERT_EQUAL(mgr->stat.number_of_LinphoneCallError, 0, int, "%d");
|
||||
linphone_core_terminate_call(mgr->lc, call);
|
||||
BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallEnd, 1));
|
||||
BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallReleased, 1));
|
||||
pclose(sipp_out);
|
||||
}
|
||||
linphone_core_manager_destroy(mgr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static test_t tests[] = {
|
||||
{ "SIP UPDATE within incoming reinvite without sdp", sip_update_within_icoming_reinvite_with_no_sdp },
|
||||
|
|
@ -350,9 +352,7 @@ static test_t tests[] = {
|
|||
{ "Call with video mline before audio in sdp", call_with_video_mline_before_audio_in_sdp },
|
||||
{ "Call with multiple audio mline in sdp", call_with_multiple_audio_mline_in_sdp },
|
||||
{ "Call with multiple video mline in sdp", call_with_multiple_video_mline_in_sdp },
|
||||
#if 0
|
||||
{ "Call invite 200ok without contact header", call_invite_200ok_without_contact_header },
|
||||
#endif
|
||||
{ "Call invite 200ok without contact header", call_invite_200ok_without_contact_header }
|
||||
};
|
||||
|
||||
test_suite_t complex_sip_call_test_suite = {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue