Re #1788: Add support to allow INVITE/reINVITE with unknown body.

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@4924 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
Riza Sulistyo 2014-09-17 12:11:45 +00:00
parent 5ee3d807c8
commit e90ea2f3d8
3 changed files with 96 additions and 38 deletions

View File

@ -1208,6 +1208,18 @@ PJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void)
# define PJSIP_HAS_TX_DATA_LIST 0
#endif
/**
* Specify whether to accept INVITE/re-INVITE with unknown content type,
* by default the stack will reject this type of message as specified in
* RFC3261 section 8.2.3.
* Application that wishes to process the body could set this to PJ_TRUE,
* be informed that SDP offer/answer will still be present.
*
* Default: PJ_FALSE
*/
#ifndef PJSIP_INV_ACCEPT_UNKNOWN_BODY
# define PJSIP_INV_ACCEPT_UNKNOWN_BODY PJ_FALSE
#endif
PJ_END_DECL

View File

@ -4737,36 +4737,53 @@ static void inv_on_state_confirmed( pjsip_inv_session *inv, pjsip_event *e)
}
if (status != PJ_SUCCESS) {
pj_bool_t reject_message = PJ_TRUE;
/* Not Acceptable */
const pjsip_hdr *accept;
/* The incoming SDP is unacceptable. If the SDP negotiator
* state has just been changed, i.e: DONE -> REMOTE_OFFER,
* revert it back.
*/
if (pjmedia_sdp_neg_get_state(inv->neg) ==
PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER)
if (status == PJMEDIA_SDP_EINSDP)
{
pjmedia_sdp_neg_cancel_offer(inv->neg);
sdp_info = pjsip_rdata_get_sdp_info(rdata);
if (sdp_info->body.ptr == NULL &&
PJSIP_INV_ACCEPT_UNKNOWN_BODY)
{
/* Message body is not "application/sdp" */
reject_message = PJ_FALSE;
}
}
status = pjsip_dlg_create_response(inv->dlg, rdata,
488, NULL, &tdata);
if (status != PJ_SUCCESS)
if (reject_message) {
/* Not Acceptable */
const pjsip_hdr *accept;
/* The incoming SDP is unacceptable. If the SDP negotiator
* state has just been changed, i.e: DONE -> REMOTE_OFFER,
* revert it back.
*/
if (pjmedia_sdp_neg_get_state(inv->neg) ==
PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER)
{
pjmedia_sdp_neg_cancel_offer(inv->neg);
}
status = pjsip_dlg_create_response(inv->dlg, rdata,
(status == PJMEDIA_SDP_EINSDP)?415:488,
NULL, &tdata);
if (status != PJ_SUCCESS)
return;
accept = pjsip_endpt_get_capability(dlg->endpt,
PJSIP_H_ACCEPT,
NULL);
if (accept) {
pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)
pjsip_hdr_clone(tdata->pool, accept));
}
status = pjsip_dlg_send_response(dlg, tsx, tdata);
return;
accept = pjsip_endpt_get_capability(dlg->endpt, PJSIP_H_ACCEPT,
NULL);
if (accept) {
pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)
pjsip_hdr_clone(tdata->pool, accept));
}
status = pjsip_dlg_send_response(dlg, tsx, tdata);
return;
}
/* Create 2xx ANSWER */

View File

@ -1199,32 +1199,61 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata)
offer = sdp_info->sdp;
status = sdp_info->sdp_err;
if (status==PJ_SUCCESS && sdp_info->sdp==NULL)
status = PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE);
if (status==PJ_SUCCESS && sdp_info->sdp==NULL &&
!PJSIP_INV_ACCEPT_UNKNOWN_BODY)
{
if (sdp_info->body.ptr == NULL) {
status = PJSIP_ERRNO_FROM_SIP_STATUS(
PJSIP_SC_UNSUPPORTED_MEDIA_TYPE);
} else {
status = PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE);
}
}
if (status != PJ_SUCCESS) {
const pj_str_t reason = pj_str("Bad SDP");
pjsip_hdr hdr_list;
pjsip_warning_hdr *w;
pjsua_perror(THIS_FILE, "Bad SDP in incoming INVITE",
status);
/* Check if body really contains SDP. */
if (sdp_info->body.ptr == NULL) {
/* Couldn't find "application/sdp" */
pjsip_accept_hdr *acc;
w = pjsip_warning_hdr_create_from_status(rdata->tp_info.pool,
pjsip_endpt_name(pjsua_var.endpt),
status);
pj_list_init(&hdr_list);
pj_list_push_back(&hdr_list, w);
pjsua_perror(THIS_FILE, "Unknown Content-Type in incoming "\
"INVITE", status);
pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 400,
&reason, &hdr_list, NULL, NULL);
/* Add Accept header to response */
acc = pjsip_accept_hdr_create(rdata->tp_info.pool);
PJ_ASSERT_RETURN(acc, PJ_ENOMEM);
acc->values[acc->count++] = pj_str("application/sdp");
pj_list_init(&hdr_list);
pj_list_push_back(&hdr_list, acc);
pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata,
PJSIP_SC_UNSUPPORTED_MEDIA_TYPE,
NULL, &hdr_list, NULL, NULL);
} else {
const pj_str_t reason = pj_str("Bad SDP");
pjsip_warning_hdr *w;
pjsua_perror(THIS_FILE, "Bad SDP in incoming INVITE",
status);
w = pjsip_warning_hdr_create_from_status(rdata->tp_info.pool,
pjsip_endpt_name(pjsua_var.endpt),
status);
pj_list_init(&hdr_list);
pj_list_push_back(&hdr_list, w);
pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 400,
&reason, &hdr_list, NULL, NULL);
}
goto on_return;
}
/* Do quick checks on SDP before passing it to transports. More elabore
* checks will be done in pjsip_inv_verify_request2() below.
*/
if (offer->media_count==0) {
if ((offer) && (offer->media_count==0)) {
const pj_str_t reason = pj_str("Missing media in SDP");
pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, 400, &reason,
NULL, NULL, NULL);