diff options
author | Benny Prijono <bennylp@teluu.com> | 2006-07-02 14:53:05 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2006-07-02 14:53:05 +0000 |
commit | 4de1d93c777da624a6044aa572f3c87842b0b401 (patch) | |
tree | dcc46c8b5c6ec816687d40b8f42e623579fbd99d /pjsip/src | |
parent | 01b2e0b27f8b5aa65a58617cfbf22844d31c1ecf (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.c | 80 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_dialog.c | 32 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_parser.c | 20 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transport.c | 6 |
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; |