Skip to content

Commit

Permalink
add more check for siprec request
Browse files Browse the repository at this point in the history
  • Loading branch information
sorooshm78 committed Nov 18, 2024
1 parent 4a8fd1c commit 2232f57
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 20 deletions.
13 changes: 12 additions & 1 deletion pjsip/include/pjsip-ua/sip_siprec.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ PJ_DECL(pj_status_t) pjsip_siprec_init_module(pjsip_endpoint *endpt);
PJ_DEF(pjmedia_sdp_attr*) pjmedia_sdp_attr_get_label(pjmedia_sdp_media *answer);


PJ_DEF(pj_status_t) pjsip_siprec_verify_require_hdr(pjsip_require_hdr *req_hdr);


PJ_DEF(pj_status_t) pjsip_siprec_verify_sdp_attr_label(pjmedia_sdp_session *sdp);


/**
* Verifies that the incoming request has the siprec value in the Require header.
* This function checks whether the incoming request is a siprec request or not."
Expand All @@ -56,7 +62,12 @@ PJ_DEF(pjmedia_sdp_attr*) pjmedia_sdp_attr_get_label(pjmedia_sdp_media *answer);
* - If the request contains siprec in Require header, the
* function returns PJ_TRUE
*/
PJ_DEF(pj_status_t) pjsip_siprec_verify_request(pjsip_rx_data *rdata);
PJ_DEF(pj_status_t) pjsip_siprec_verify_request(pjsip_rx_data *rdata,
pjmedia_sdp_session *sdp_offer,
unsigned *options,
pjsip_dialog *dlg,
pjsip_endpoint *endpt,
pjsip_tx_data **p_tdata);



Expand Down
137 changes: 124 additions & 13 deletions pjsip/src/pjsip-ua/sip_siprec.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,36 +58,147 @@ PJ_DEF(pj_status_t) pjsip_siprec_init_module(pjsip_endpoint *endpt)
/**
* Returns the label attribute in the SDP offer
*/
PJ_DEF(pjmedia_sdp_attr*) pjmedia_sdp_attr_get_label(pjmedia_sdp_media *answer)
PJ_DEF(pjmedia_sdp_attr*) pjmedia_sdp_attr_get_label(pjmedia_sdp_media *sdp_media)
{
pjmedia_sdp_attr *attr;
attr = pjmedia_sdp_media_find_attr(answer, &STR_LABEL, NULL);
attr = pjmedia_sdp_media_find_attr(sdp_media, &STR_LABEL, NULL);
return attr;
}


PJ_DEF(pj_status_t) pjsip_siprec_verify_sdp_attr_label(pjmedia_sdp_session *sdp)
{
for (unsigned mi=0; mi<sdp->media_count; ++mi) {
if(!pjmedia_sdp_attr_get_label(sdp->media[mi]))
return PJ_FALSE;
}
return PJ_TRUE;
}


PJ_DEF(pj_status_t) pjsip_siprec_verify_require_hdr(pjsip_require_hdr *req_hdr)
{
for (int i=0; i<req_hdr->count; ++i) {
/* Check request has the siprec value in the Require header.*/
if (pj_stricmp(&req_hdr->values[i], &STR_SIPREC)==0)
{
return PJ_TRUE;
}
}
return PJ_FALSE;
}


/**
* Verifies that the incoming request has the siprec value in the Require header.
*/
PJ_DEF(pj_status_t) pjsip_siprec_verify_request(pjsip_rx_data *rdata)
PJ_DEF(pj_status_t) pjsip_siprec_verify_request(pjsip_rx_data *rdata,
pjmedia_sdp_session *sdp_offer,
unsigned *options,
pjsip_dialog *dlg,
pjsip_endpoint *endpt,
pjsip_tx_data **p_tdata)
{
pjsip_require_hdr *req_hdr;
pjsip_contact_hdr *conatct_hdr;
const pj_str_t str_require = {"Require", 7};
const pj_str_t str_src = {"+sip.src", 8};
int code = 200;
pj_status_t status = PJ_SUCCESS;
const char *warn_text = NULL;
pjsip_hdr res_hdr_list;
pjsip_param *param;

/* Init return arguments. */
if (p_tdata) *p_tdata = NULL;

/* Init response header list */
pj_list_init(&res_hdr_list);

/* Find Require header */
req_hdr = (pjsip_require_hdr*) pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_require, NULL);

if(req_hdr)
{
for (int i=0; i<req_hdr->count; ++i) {
/* Check request has the siprec value in the Require header.*/
if (pj_stricmp(&req_hdr->values[i], &STR_SIPREC)==0)
{
return PJ_TRUE;
}
if(!req_hdr || (pjsip_siprec_verify_require_hdr(req_hdr) == PJ_FALSE)){
return PJ_SUCCESS;
}

/* Find Conatct header */
conatct_hdr = (pjsip_contact_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL);

if(!conatct_hdr || !conatct_hdr->uri){
code = PJSIP_SC_BAD_REQUEST;
warn_text = "Bad/missing Contact header";
goto on_return;
}

if(!pjsip_param_find(&conatct_hdr->other_param, &str_src)){
return PJ_SUCCESS;
}

if(!sdp_offer){
return PJ_SUCCESS;
}

if(pjsip_siprec_verify_sdp_attr_label(sdp_offer) == PJ_FALSE){
code = PJSIP_SC_BAD_REQUEST;
warn_text = "SDP media has label attr";
goto on_return;
}

*options |= PJSIP_INV_REQUIRE_SIPREC;
return status;

on_return:

/* Create response if necessary */
if (code != 200) {
pjsip_tx_data *tdata;
const pjsip_hdr *h;

if (dlg) {
status = pjsip_dlg_create_response(dlg, rdata, code, NULL,
&tdata);
} else {
status = pjsip_endpt_create_response(endpt, rdata, code, NULL,
&tdata);
}

if (status != PJ_SUCCESS)
return status;

/* Add response headers. */
h = res_hdr_list.next;
while (h != &res_hdr_list) {
pjsip_hdr *cloned;

cloned = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, h);
PJ_ASSERT_RETURN(cloned, PJ_ENOMEM);

pjsip_msg_add_hdr(tdata->msg, cloned);

h = h->next;
}

/* Add warn text, if any */
if (warn_text) {
pjsip_warning_hdr *warn_hdr;
pj_str_t warn_value = pj_str((char*)warn_text);

warn_hdr=pjsip_warning_hdr_create(tdata->pool, 399,
pjsip_endpt_name(endpt),
&warn_value);
pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)warn_hdr);
}

*p_tdata = tdata;

/* Can not return PJ_SUCCESS when response message is produced.
* Ref: PROTOS test ~#2490
*/
if (status == PJ_SUCCESS)
status = PJSIP_ERRNO_FROM_SIP_STATUS(code);

}

/* No Require header or not exist siprec value in Require header */
return PJ_FALSE;
return status;
}
28 changes: 22 additions & 6 deletions pjsip/src/pjsua-lib/pjsua_call.c
Original file line number Diff line number Diff line change
Expand Up @@ -1808,13 +1808,29 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata)
* If siprec is present, this function returns the value PJ_TRUE
* if not, it returns PJ_FALSE
*/
status = pjsip_siprec_verify_request(rdata);
status = pjsip_siprec_verify_request(rdata, offer, &options, NULL, pjsua_var.endpt, &response);

/* Check if the siprec value is present in the INVITE request
* in that case, it must be able to support multiple media in the SDP.
*/
if(status == PJ_TRUE){
options |= PJSIP_INV_REQUIRE_SIPREC;
if(status != PJ_SUCCESS){
/*
* No we can't handle the incoming INVITE request.
*/
if (response) {
pjsip_response_addr res_addr;
ret_st_code = response->msg->line.status.code;

pjsip_get_response_addr(response->pool, rdata, &res_addr);
status = pjsip_endpt_send_response(pjsua_var.endpt, &res_addr,
response, NULL, NULL);
if (status != PJ_SUCCESS) pjsip_tx_data_dec_ref(response);

} else {
/* Respond with 500 (Internal Server Error) */
ret_st_code = PJSIP_SC_INTERNAL_SERVER_ERROR;
pjsip_endpt_respond(pjsua_var.endpt, NULL, rdata, ret_st_code,
NULL, NULL, NULL, NULL);
}

goto on_return;
}

/* Check if request supports PJSIP_INV_REQUIRE_SIPREC. If so
Expand Down

0 comments on commit 2232f57

Please sign in to comment.