diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c index 2f9a80f69..92a15e19e 100644 --- a/pjsip/src/pjsip/sip_transaction.c +++ b/pjsip/src/pjsip/sip_transaction.c @@ -2195,11 +2195,12 @@ static void send_msg_callback( pjsip_send_state *send_state, else sc = PJSIP_SC_TSX_TRANSPORT_ERROR; - /* We terminate the transaction for 502 error. For 503, - * we will retry it. - * See https://github.com/pjsip/pjproject/pull/3805 + /* For UAC tsx, we directly terminate the transaction. + * For UAS tsx, we terminate the transaction for 502 error, + * 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_DESTROYED) { @@ -2274,7 +2275,16 @@ static void transport_callback(void *token, pjsip_tx_data *tdata, pj_grp_lock_acquire(tsx->grp_lock); 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? */ if (tsx->transport_flag & TSX_HAS_PENDING_DESTROY) { 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); - if (sent < 0) { + if (sent < 0 && tsx->role == PJSIP_ROLE_UAC) { pj_time_val delay = {0, 0}; 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. * 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]; pj_str_t err; diff --git a/pjsip/src/test/tsx_bench.c b/pjsip/src/test/tsx_bench.c index dd8c1971a..30b2aa220 100644 --- a/pjsip/src/test/tsx_bench.c +++ b/pjsip/src/test/tsx_bench.c @@ -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.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.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; pj_sockaddr_in_init(&remote, 0, 0); diff --git a/pjsip/src/test/tsx_uas_test.c b/pjsip/src/test/tsx_uas_test.c index f2460fcfb..815cbe069 100644 --- a/pjsip/src/test/tsx_uas_test.c +++ b/pjsip/src/test/tsx_uas_test.c @@ -710,10 +710,11 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e) if (!test_complete) 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" " (expecting %d, got %d)", - PJSIP_SC_TSX_TRANSPORT_ERROR, + PJSIP_SC_REQUEST_TIMEOUT, + // PJSIP_SC_TSX_TRANSPORT_ERROR, tsx->status_code)); test_complete = -170; } @@ -726,12 +727,13 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e) if (!test_complete) 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) { PJ_LOG(3,(THIS_FILE," error: incorrect status code" " (expecting %d, got %d)", - PJSIP_SC_TSX_TRANSPORT_ERROR, + PJSIP_SC_REQUEST_TIMEOUT, + // PJSIP_SC_TSX_TRANSPORT_ERROR, tsx->status_code)); test_complete = -170; } @@ -1199,9 +1201,11 @@ static int perform_test( char *target_uri, char *from_uri, int sent_cnt; pj_status_t status; - PJ_LOG(3,(THIS_FILE, - " please standby, this will take at most %d seconds..", - test_time)); + if (test_time > 0) { + PJ_LOG(3,(THIS_FILE, + " please standby, this will take at most %d seconds..", + test_time)); + } /* Reset test. */ recv_count = 0; @@ -1481,24 +1485,29 @@ int tsx_transport_failure_test(void) { struct test_desc { + int result; int transport_delay; int fail_delay; char *branch_id; char *title; } tests[] = { - { 0, 10, TEST10_BRANCH_ID, "test10: failed transport in TRYING state (no delay)" }, - { 50, 10, TEST10_BRANCH_ID, "test10: failed transport in TRYING state (50 ms delay)" }, - { 0, 1500, TEST11_BRANCH_ID, "test11: failed transport in PROCEEDING state (no delay)" }, - // After ticket #2076, transport error will be ignored if tsx is in COMPLETED state, note that - // tsx state will be shifted to COMPLETED state once 200 response is sent due to transport delay. - //{ 50, 1500, TEST11_BRANCH_ID, "test11: failed transport in PROCEEDING state (50 ms delay)" }, - { 0, 2500, TEST12_BRANCH_ID, "test12: failed transport in COMPLETED state (no delay)" }, - //Not applicable (maybe) - //This test may expect transport failure notification in COMPLETED state. This may not be - //possible because the loop transport can only notify failure when it has something to send, - //while in this case, there is nothing to send because UAS already sends 200/OK - //{ 50, 2500, TEST12_BRANCH_ID, "test12: failed transport in COMPLETED state (50 ms delay)" }, + // After #3805 and #3806, transport error will be ignored and + // the tests will time out. + // All tests are valid, but it will take too long to complete, + // so we disable some of the similar ones. + { 0, 0, 10, TEST10_BRANCH_ID, + "test10: failed transport in TRYING state (no delay)" }, + //{ 0, 50, 10, TEST10_BRANCH_ID, + // "test10: failed transport in TRYING state (50 ms delay)" }, + //{ 1, 0, 1500, TEST11_BRANCH_ID, + // "test11: failed transport in PROCEEDING state (no delay)" }, + { 1, 50, 1500, TEST11_BRANCH_ID, + "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; @@ -1532,7 +1541,7 @@ int tsx_transport_failure_test(void) PJ_LOG(5,(THIS_FILE, " transport loop fail mode set")); end_test = now; - end_test.sec += 5; + end_test.sec += 33; do { pj_time_val interval = { 0, 1 }; @@ -1540,13 +1549,10 @@ int tsx_transport_failure_test(void) pjsip_endpt_handle_events(endpt, &interval); } while (!test_complete && PJ_TIME_VAL_LT(now, end_test)); - if (test_complete == 0) { - PJ_LOG(3,(THIS_FILE, " error: test has timed out")); + if (test_complete != tests[i].result) { + PJ_LOG(3,(THIS_FILE, " error: expecting timeout")); return -41; } - - if (test_complete != 1) - return test_complete; } return 0;