summaryrefslogtreecommitdiff
path: root/pjsip/src
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-07-02 14:53:05 +0000
committerBenny Prijono <bennylp@teluu.com>2006-07-02 14:53:05 +0000
commit4de1d93c777da624a6044aa572f3c87842b0b401 (patch)
treedcc46c8b5c6ec816687d40b8f42e623579fbd99d /pjsip/src
parent01b2e0b27f8b5aa65a58617cfbf22844d31c1ecf (diff)
Final changeset from the PROTOS testing, fixed misc. crashes. See
mailing list archive for the details git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@576 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip/src')
-rw-r--r--pjsip/src/pjsip-ua/sip_inv.c80
-rw-r--r--pjsip/src/pjsip/sip_dialog.c32
-rw-r--r--pjsip/src/pjsip/sip_parser.c20
-rw-r--r--pjsip/src/pjsip/sip_transport.c6
4 files changed, 123 insertions, 15 deletions
diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c
index 4efb9177..d3176862 100644
--- a/pjsip/src/pjsip-ua/sip_inv.c
+++ b/pjsip/src/pjsip-ua/sip_inv.c
@@ -232,10 +232,17 @@ static pj_bool_t mod_inv_on_rx_request(pjsip_rx_data *rdata)
*/
method = &rdata->msg_info.msg->line.req.method;
- if (method->id == PJSIP_INVITE_METHOD ||
- method->id == PJSIP_CANCEL_METHOD ||
- method->id == PJSIP_BYE_METHOD)
+ if (method->id == PJSIP_INVITE_METHOD) {
+ return PJ_TRUE;
+ }
+
+ /* BYE and CANCEL must have existing invite session */
+ if (method->id == PJSIP_BYE_METHOD ||
+ method->id == PJSIP_CANCEL_METHOD)
{
+ if (inv == NULL)
+ return PJ_FALSE;
+
return PJ_TRUE;
}
@@ -780,6 +787,13 @@ on_return:
}
*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);
+
}
return status;
@@ -2204,7 +2218,26 @@ static void inv_on_state_connecting( pjsip_inv_session *inv, pjsip_event *e)
inv_handle_bye_response( inv, tsx, e->body.tsx_state.src.rdata, e);
}
+ else if (tsx->method.id == PJSIP_CANCEL_METHOD &&
+ tsx->role == PJSIP_ROLE_UAS &&
+ tsx->status_code < 200 &&
+ e->body.tsx_state.type == PJSIP_EVENT_RX_MSG)
+ {
+
+ /*
+ * Handle strandled incoming CANCEL.
+ */
+ pjsip_rx_data *rdata = e->body.tsx_state.src.rdata;
+ pjsip_tx_data *tdata;
+ pj_status_t status;
+
+ status = pjsip_dlg_create_response(dlg, rdata, 200, NULL, &tdata);
+ if (status != PJ_SUCCESS) return;
+
+ status = pjsip_dlg_send_response(dlg, tsx, tdata);
+ if (status != PJ_SUCCESS) return;
+ }
}
/*
@@ -2244,6 +2277,26 @@ static void inv_on_state_confirmed( pjsip_inv_session *inv, pjsip_event *e)
inv_respond_incoming_bye( inv, tsx, e->body.tsx_state.src.rdata, e );
}
+ else if (tsx->method.id == PJSIP_CANCEL_METHOD &&
+ tsx->role == PJSIP_ROLE_UAS &&
+ tsx->status_code < 200 &&
+ e->body.tsx_state.type == PJSIP_EVENT_RX_MSG)
+ {
+
+ /*
+ * Handle strandled incoming CANCEL.
+ */
+ pjsip_rx_data *rdata = e->body.tsx_state.src.rdata;
+ pjsip_tx_data *tdata;
+ pj_status_t status;
+
+ status = pjsip_dlg_create_response(dlg, rdata, 200, NULL, &tdata);
+ if (status != PJ_SUCCESS) return;
+
+ status = pjsip_dlg_send_response(dlg, tsx, tdata);
+ if (status != PJ_SUCCESS) return;
+
+ }
else if (tsx->method.id == PJSIP_INVITE_METHOD &&
tsx->role == PJSIP_ROLE_UAS)
{
@@ -2377,18 +2430,31 @@ static void inv_on_state_disconnected( pjsip_inv_session *inv, pjsip_event *e)
PJ_ASSERT_ON_FAIL(tsx && dlg, return);
- if (tsx->method.id == PJSIP_BYE_METHOD &&
- tsx->role == PJSIP_ROLE_UAS &&
+ if (tsx->role == PJSIP_ROLE_UAS &&
tsx->status_code < 200 &&
e->body.tsx_state.type == PJSIP_EVENT_RX_MSG)
{
+ pjsip_rx_data *rdata = e->body.tsx_state.src.rdata;
/*
- * Be nice, handle incoming BYE.
+ * Respond BYE with 200/OK
*/
+ if (tsx->method.id == PJSIP_BYE_METHOD) {
+ inv_respond_incoming_bye( inv, tsx, rdata, e );
+ } else if (tsx->method.id == PJSIP_CANCEL_METHOD) {
+ /*
+ * Respond CANCEL with 200/OK too.
+ */
+ pjsip_tx_data *tdata;
+ pj_status_t status;
- inv_respond_incoming_bye( inv, tsx, e->body.tsx_state.src.rdata, e );
+ status = pjsip_dlg_create_response(dlg, rdata, 200, NULL, &tdata);
+ if (status != PJ_SUCCESS) return;
+ status = pjsip_dlg_send_response(dlg, tsx, tdata);
+ if (status != PJ_SUCCESS) return;
+
+ }
}
}
diff --git a/pjsip/src/pjsip/sip_dialog.c b/pjsip/src/pjsip/sip_dialog.c
index dfa60495..9b59d258 100644
--- a/pjsip/src/pjsip/sip_dialog.c
+++ b/pjsip/src/pjsip/sip_dialog.c
@@ -702,9 +702,11 @@ PJ_DEF(void) pjsip_dlg_dec_lock(pjsip_dialog *dlg)
pj_assert(dlg->sess_count > 0);
--dlg->sess_count;
- if (dlg->sess_count==0 && dlg->tsx_count==0)
+ if (dlg->sess_count==0 && dlg->tsx_count==0) {
+ pj_mutex_unlock(dlg->mutex);
+ pj_mutex_lock(dlg->mutex);
unregister_and_destroy_dialog(dlg);
- else {
+ } else {
pj_mutex_unlock(dlg->mutex);
}
}
@@ -971,6 +973,8 @@ PJ_DEF(pj_status_t) pjsip_dlg_send_request( pjsip_dialog *dlg,
* The transaction user is the user agent module.
*/
if (msg->line.req.method.id != PJSIP_ACK_METHOD) {
+ int tsx_count;
+
status = pjsip_tsx_create_uac(dlg->ua, tdata, &tsx);
if (status != PJ_SUCCESS)
goto on_error;
@@ -985,12 +989,13 @@ PJ_DEF(pj_status_t) pjsip_dlg_send_request( pjsip_dialog *dlg,
tsx->mod_data[mod_data_id] = mod_data;
/* Increment transaction counter. */
- ++dlg->tsx_count;
+ tsx_count = ++dlg->tsx_count;
/* Send the message. */
status = pjsip_tsx_send_msg(tsx, tdata);
if (status != PJ_SUCCESS) {
- pjsip_tsx_terminate(tsx, tsx->status_code);
+ if (dlg->tsx_count == tsx_count)
+ pjsip_tsx_terminate(tsx, tsx->status_code);
goto on_error;
}
@@ -1259,6 +1264,7 @@ void pjsip_dlg_on_rx_request( pjsip_dialog *dlg, pjsip_rx_data *rdata )
{
pj_status_t status;
pjsip_transaction *tsx = NULL;
+ pj_bool_t processed = PJ_FALSE;
unsigned i;
PJ_LOG(5,(dlg->obj_name, "Received %s",
@@ -1316,7 +1322,6 @@ void pjsip_dlg_on_rx_request( pjsip_dialog *dlg, pjsip_rx_data *rdata )
/* Report the request to dialog usages. */
for (i=0; i<dlg->usage_cnt; ++i) {
- pj_bool_t processed;
if (!dlg->usage[i]->on_rx_request)
continue;
@@ -1331,6 +1336,23 @@ void pjsip_dlg_on_rx_request( pjsip_dialog *dlg, pjsip_rx_data *rdata )
if (tsx)
pjsip_tsx_recv_msg(tsx, rdata);
+ /* If no dialog usages has claimed the processing of the transaction,
+ * and if transaction has not sent final response, respond with
+ * 500/Internal Server Error.
+ */
+ if (!processed && tsx && tsx->status_code < 200) {
+ pjsip_tx_data *tdata;
+ const pj_str_t reason = { "No session found", 16};
+
+ PJ_LOG(4,(tsx->obj_name, "Incoming request was unhandled by "
+ "dialog usages, sending 500 response"));
+
+ status = pjsip_dlg_create_response(dlg, rdata, 500, &reason, &tdata);
+ if (status == PJ_SUCCESS) {
+ status = pjsip_dlg_send_response(dlg, tsx, tdata);
+ }
+ }
+
on_return:
/* Unlock dialog and dec session, may destroy dialog. */
pjsip_dlg_dec_lock(dlg);
diff --git a/pjsip/src/pjsip/sip_parser.c b/pjsip/src/pjsip/sip_parser.c
index 41be6926..ab6144fd 100644
--- a/pjsip/src/pjsip/sip_parser.c
+++ b/pjsip/src/pjsip/sip_parser.c
@@ -478,6 +478,7 @@ static pj_status_t int_register_parser( const char *name,
rec.handler = fptr;
rec.hname_len = strlen(name);
if (rec.hname_len >= sizeof(rec.hname)) {
+ pj_assert(!"Header name is too long!");
return PJ_ENAMETOOLONG;
}
/* Name is copied in lowercase. */
@@ -545,7 +546,7 @@ static pjsip_parse_hdr_func * find_handler(const pj_str_t *hname)
unsigned n;
if (hname->slen >= PJSIP_MAX_HNAME_LEN) {
- pj_assert(!"Header name is too long!");
+ /* Guaranteed not to be able to find handler. */
return NULL;
}
@@ -831,6 +832,11 @@ parse_headers:
do {
pjsip_parse_hdr_func * handler;
pjsip_hdr *hdr = NULL;
+
+ /* Init hname just in case parsing fails.
+ * Ref: PROTOS #2412
+ */
+ hname.slen = 0;
/* Get hname. */
pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &hname);
@@ -913,6 +919,10 @@ parse_headers:
err_info->col = pj_scan_get_col(scanner) + 1;
if (parsing_headers)
err_info->hname = hname;
+ else if (msg && msg->type == PJSIP_REQUEST_MSG)
+ err_info->hname = pj_str("Request Line");
+ else if (msg && msg->type == PJSIP_RESPONSE_MSG)
+ err_info->hname = pj_str("Status Line");
else
err_info->hname.slen = 0;
@@ -1125,9 +1135,14 @@ static pjsip_uri *int_parse_uri_or_name_addr( pj_scanner *scanner, pj_pool_t *po
static pjsip_uri *int_parse_uri(pj_scanner *scanner, pj_pool_t *pool,
pj_bool_t parse_params)
{
+ /* Bug:
+ * This function should not call back int_parse_name_addr() because
+ * it is called by that function. This would cause stack overflow
+ * with PROTOS test #1223.
if (*scanner->curptr=='"' || *scanner->curptr=='<') {
return (pjsip_uri*)int_parse_name_addr( scanner, pool );
} else {
+ */
pj_str_t scheme;
int colon;
pjsip_parse_uri_func *func;
@@ -1147,7 +1162,10 @@ static pjsip_uri *int_parse_uri(pj_scanner *scanner, pj_pool_t *pool,
PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
UNREACHED({ return NULL; /* Not reached. */ })
}
+
+ /*
}
+ */
}
/* Parse "sip:" and "sips:" URI.
diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c
index 1e9a4f05..204eff12 100644
--- a/pjsip/src/pjsip/sip_transport.c
+++ b/pjsip/src/pjsip/sip_transport.c
@@ -983,12 +983,14 @@ PJ_DEF(pj_ssize_t) pjsip_tpmgr_receive_packet( pjsip_tpmgr *mgr,
}
PJ_LOG(1, (THIS_FILE,
- "Error processing packet from %s:%d %.*s:\n"
- "%s\n"
+ "Error processing %d bytes packet from %s:%d %.*s:\n"
+ "%.*s\n"
"-- end of packet.",
+ msg_fragment_size,
rdata->pkt_info.src_name,
rdata->pkt_info.src_port,
(int)tmp.slen, tmp.ptr,
+ (int)msg_fragment_size,
rdata->msg_info.msg_buf));
goto finish_process_fragment;