Compare commits

...

4 Commits

Author SHA1 Message Date
sauwming ac39c675a3 Fixed UAS tsx tp error handling and PJSIP test 2024-01-02 12:08:26 +08:00
sauwming f396cd4788 Merge branch 'master' into tsx-tp-error 2024-01-02 12:05:40 +08:00
sauwming b5be1717cd Add doc 2023-12-18 12:00:55 +08:00
sauwming d931d78ffe Prevent immediate tsx termination upon transport error 2023-12-15 12:07:57 +08:00
3 changed files with 52 additions and 33 deletions

View File

@ -2195,11 +2195,12 @@ static void send_msg_callback( pjsip_send_state *send_state,
else else
sc = PJSIP_SC_TSX_TRANSPORT_ERROR; sc = PJSIP_SC_TSX_TRANSPORT_ERROR;
/* We terminate the transaction for 502 error. For 503, /* For UAC tsx, we directly terminate the transaction.
* we will retry it. * For UAS tsx, we terminate the transaction for 502 error,
* See https://github.com/pjsip/pjproject/pull/3805 * and will retry for 503.
* See #3805 and #3806.
*/ */
if (sc == PJSIP_SC_BAD_GATEWAY && if ((tsx->role == PJSIP_ROLE_UAC || sc == PJSIP_SC_BAD_GATEWAY) &&
tsx->state != PJSIP_TSX_STATE_TERMINATED && tsx->state != PJSIP_TSX_STATE_TERMINATED &&
tsx->state != PJSIP_TSX_STATE_DESTROYED) tsx->state != PJSIP_TSX_STATE_DESTROYED)
{ {
@ -2274,7 +2275,16 @@ static void transport_callback(void *token, pjsip_tx_data *tdata,
pj_grp_lock_acquire(tsx->grp_lock); pj_grp_lock_acquire(tsx->grp_lock);
tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT); tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT);
if (sent > 0) { if (sent > 0 || tsx->role == PJSIP_ROLE_UAS) {
if (sent < 0) {
/* For UAS transactions, we just print error log
* and continue as per normal.
*/
PJ_PERROR(2,(tsx->obj_name, (pj_status_t)-sent,
"Transport failed to send %s!",
pjsip_tx_data_get_info(tdata)));
}
/* Pending destroy? */ /* Pending destroy? */
if (tsx->transport_flag & TSX_HAS_PENDING_DESTROY) { if (tsx->transport_flag & TSX_HAS_PENDING_DESTROY) {
tsx_set_state( tsx, PJSIP_TSX_STATE_DESTROYED, tsx_set_state( tsx, PJSIP_TSX_STATE_DESTROYED,
@ -2307,7 +2317,7 @@ static void transport_callback(void *token, pjsip_tx_data *tdata,
} }
pj_grp_lock_release(tsx->grp_lock); pj_grp_lock_release(tsx->grp_lock);
if (sent < 0) { if (sent < 0 && tsx->role == PJSIP_ROLE_UAC) {
pj_time_val delay = {0, 0}; pj_time_val delay = {0, 0};
PJ_PERROR(2,(tsx->obj_name, (pj_status_t)-sent, PJ_PERROR(2,(tsx->obj_name, (pj_status_t)-sent,
@ -2442,8 +2452,11 @@ static pj_status_t tsx_send_msg( pjsip_transaction *tsx,
/* If we have resolved the server, we treat the error as permanent error. /* If we have resolved the server, we treat the error as permanent error.
* Terminate transaction with transport error failure. * Terminate transaction with transport error failure.
* Only applicable for UAC transactions.
*/ */
if (tsx->transport_flag & TSX_HAS_RESOLVED_SERVER) { if (tsx->role == PJSIP_ROLE_UAC &&
(tsx->transport_flag & TSX_HAS_RESOLVED_SERVER))
{
char errmsg[PJ_ERR_MSG_SIZE]; char errmsg[PJ_ERR_MSG_SIZE];
pj_str_t err; pj_str_t err;

View File

@ -138,7 +138,7 @@ static int uas_tsx_bench(unsigned working_set, pj_timestamp *p_elapsed)
rdata.msg_info.from = (pjsip_from_hdr*) pjsip_msg_find_hdr(request->msg, PJSIP_H_FROM, NULL); rdata.msg_info.from = (pjsip_from_hdr*) pjsip_msg_find_hdr(request->msg, PJSIP_H_FROM, NULL);
rdata.msg_info.to = (pjsip_to_hdr*) pjsip_msg_find_hdr(request->msg, PJSIP_H_TO, NULL); rdata.msg_info.to = (pjsip_to_hdr*) pjsip_msg_find_hdr(request->msg, PJSIP_H_TO, NULL);
rdata.msg_info.cseq = (pjsip_cseq_hdr*) pjsip_msg_find_hdr(request->msg, PJSIP_H_CSEQ, NULL); rdata.msg_info.cseq = (pjsip_cseq_hdr*) pjsip_msg_find_hdr(request->msg, PJSIP_H_CSEQ, NULL);
rdata.msg_info.cid = (pjsip_cid_hdr*) pjsip_msg_find_hdr(request->msg, PJSIP_H_FROM, NULL); rdata.msg_info.cid = (pjsip_cid_hdr*) pjsip_msg_find_hdr(request->msg, PJSIP_H_CALL_ID, NULL);
rdata.msg_info.via = via; rdata.msg_info.via = via;
pj_sockaddr_in_init(&remote, 0, 0); pj_sockaddr_in_init(&remote, 0, 0);

View File

@ -710,10 +710,11 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
if (!test_complete) if (!test_complete)
test_complete = 1; test_complete = 1;
if (tsx->status_code != PJSIP_SC_TSX_TRANSPORT_ERROR) { if (tsx->status_code != PJSIP_SC_REQUEST_TIMEOUT) {
PJ_LOG(3,(THIS_FILE," error: incorrect status code" PJ_LOG(3,(THIS_FILE," error: incorrect status code"
" (expecting %d, got %d)", " (expecting %d, got %d)",
PJSIP_SC_TSX_TRANSPORT_ERROR, PJSIP_SC_REQUEST_TIMEOUT,
// PJSIP_SC_TSX_TRANSPORT_ERROR,
tsx->status_code)); tsx->status_code));
test_complete = -170; test_complete = -170;
} }
@ -726,12 +727,13 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
if (!test_complete) if (!test_complete)
test_complete = 1; test_complete = 1;
if (tsx->status_code != PJSIP_SC_TSX_TRANSPORT_ERROR && if (tsx->status_code != PJSIP_SC_REQUEST_TIMEOUT &&
tsx->status_code != PJSIP_SC_OK) tsx->status_code != PJSIP_SC_OK)
{ {
PJ_LOG(3,(THIS_FILE," error: incorrect status code" PJ_LOG(3,(THIS_FILE," error: incorrect status code"
" (expecting %d, got %d)", " (expecting %d, got %d)",
PJSIP_SC_TSX_TRANSPORT_ERROR, PJSIP_SC_REQUEST_TIMEOUT,
// PJSIP_SC_TSX_TRANSPORT_ERROR,
tsx->status_code)); tsx->status_code));
test_complete = -170; test_complete = -170;
} }
@ -1199,9 +1201,11 @@ static int perform_test( char *target_uri, char *from_uri,
int sent_cnt; int sent_cnt;
pj_status_t status; pj_status_t status;
PJ_LOG(3,(THIS_FILE, if (test_time > 0) {
" please standby, this will take at most %d seconds..", PJ_LOG(3,(THIS_FILE,
test_time)); " please standby, this will take at most %d seconds..",
test_time));
}
/* Reset test. */ /* Reset test. */
recv_count = 0; recv_count = 0;
@ -1481,24 +1485,29 @@ int tsx_transport_failure_test(void)
{ {
struct test_desc struct test_desc
{ {
int result;
int transport_delay; int transport_delay;
int fail_delay; int fail_delay;
char *branch_id; char *branch_id;
char *title; char *title;
} tests[] = } tests[] =
{ {
{ 0, 10, TEST10_BRANCH_ID, "test10: failed transport in TRYING state (no delay)" }, // After #3805 and #3806, transport error will be ignored and
{ 50, 10, TEST10_BRANCH_ID, "test10: failed transport in TRYING state (50 ms delay)" }, // the tests will time out.
{ 0, 1500, TEST11_BRANCH_ID, "test11: failed transport in PROCEEDING state (no delay)" }, // All tests are valid, but it will take too long to complete,
// After ticket #2076, transport error will be ignored if tsx is in COMPLETED state, note that // so we disable some of the similar ones.
// tsx state will be shifted to COMPLETED state once 200 response is sent due to transport delay. { 0, 0, 10, TEST10_BRANCH_ID,
//{ 50, 1500, TEST11_BRANCH_ID, "test11: failed transport in PROCEEDING state (50 ms delay)" }, "test10: failed transport in TRYING state (no delay)" },
{ 0, 2500, TEST12_BRANCH_ID, "test12: failed transport in COMPLETED state (no delay)" }, //{ 0, 50, 10, TEST10_BRANCH_ID,
//Not applicable (maybe) // "test10: failed transport in TRYING state (50 ms delay)" },
//This test may expect transport failure notification in COMPLETED state. This may not be //{ 1, 0, 1500, TEST11_BRANCH_ID,
//possible because the loop transport can only notify failure when it has something to send, // "test11: failed transport in PROCEEDING state (no delay)" },
//while in this case, there is nothing to send because UAS already sends 200/OK { 1, 50, 1500, TEST11_BRANCH_ID,
//{ 50, 2500, TEST12_BRANCH_ID, "test12: failed transport in COMPLETED state (50 ms delay)" }, "test11: failed transport in PROCEEDING state (50 ms delay)" },
{ 1, 0, 2500, TEST12_BRANCH_ID,
"test12: failed transport in COMPLETED state (no delay)" },
//{ 1, 50, 2500, TEST12_BRANCH_ID,
// "test12: failed transport in COMPLETED state (50 ms delay)" },
}; };
int i, status; int i, status;
@ -1532,7 +1541,7 @@ int tsx_transport_failure_test(void)
PJ_LOG(5,(THIS_FILE, " transport loop fail mode set")); PJ_LOG(5,(THIS_FILE, " transport loop fail mode set"));
end_test = now; end_test = now;
end_test.sec += 5; end_test.sec += 33;
do { do {
pj_time_val interval = { 0, 1 }; pj_time_val interval = { 0, 1 };
@ -1540,13 +1549,10 @@ int tsx_transport_failure_test(void)
pjsip_endpt_handle_events(endpt, &interval); pjsip_endpt_handle_events(endpt, &interval);
} while (!test_complete && PJ_TIME_VAL_LT(now, end_test)); } while (!test_complete && PJ_TIME_VAL_LT(now, end_test));
if (test_complete == 0) { if (test_complete != tests[i].result) {
PJ_LOG(3,(THIS_FILE, " error: test has timed out")); PJ_LOG(3,(THIS_FILE, " error: expecting timeout"));
return -41; return -41;
} }
if (test_complete != 1)
return test_complete;
} }
return 0; return 0;