diff --git a/CHANGES b/CHANGES index 9caa524226a0684de41add73fe4e7b342c03a7b4..6d7cb4c4238c98f6027d99c4230dee8a0fa2fa13 100644 --- a/CHANGES +++ b/CHANGES @@ -177,6 +177,14 @@ chan_sip NOTE: This is again separated by an exclamation mark, so the To: header may not contain one of those. + * Session-Timers (RFC 4028) work for TCP (and TLS) transports as well now. + Previously Asterisk dropped calls only with UDP transports. However with + longer international calls via TCP, the SIP channel might break, because + all hops on the Internet route must stay online (have not a single power + outage, for example). Therefore with Session-Timers enabled (which are + enabled at default), you might see additional dropped calls. Consequently + please, consider to go for session-timers=refuse in your sip.conf. + chan_pjsip ------------------ * New 'user_eq_phone' endpoint setting. This adds a 'user=phone' parameter diff --git a/channels/chan_sip.c b/channels/chan_sip.c index b2522b6db79e193fc9985b8cf53881f0221ce1df..9098c14e58ae45a4ec91dbaabe6f20c8cc9e0689 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -4204,19 +4204,6 @@ static enum sip_result __sip_reliable_xmit(struct sip_pvt *p, uint32_t seqno, in p->pendinginvite = seqno; } - /* If the transport is something reliable (TCP or TLS) then don't really send this reliably */ - /* I removed the code from retrans_pkt that does the same thing so it doesn't get loaded into the scheduler */ - /*! \todo According to the RFC some packets need to be retransmitted even if its TCP, so this needs to get revisited */ - if (!(p->socket.type & AST_TRANSPORT_UDP)) { - xmitres = __sip_xmit(p, data); /* Send packet */ - if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ - append_history(p, "XmitErr", "%s", fatal ? "(Critical)" : "(Non-critical)"); - return AST_FAILURE; - } else { - return AST_SUCCESS; - } - } - pkt = ao2_alloc_options(sizeof(*pkt), sip_pkt_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK); if (!pkt) { return AST_FAILURE; @@ -4253,6 +4240,10 @@ static enum sip_result __sip_reliable_xmit(struct sip_pvt *p, uint32_t seqno, in pkt->time_sent = ast_tvnow(); /* time packet was sent */ pkt->retrans_stop_time = 64 * (pkt->timer_t1 ? pkt->timer_t1 : DEFAULT_TIMER_T1); /* time in ms after pkt->time_sent to stop retransmission */ + if (!(p->socket.type & AST_TRANSPORT_UDP)) { + pkt->retrans_stop = 1; + } + /* Schedule retransmission */ ao2_t_ref(pkt, +1, "Schedule packet retransmission"); pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); @@ -24629,6 +24620,7 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc char *c_copy = ast_strdupa(c); /* Skip the Cseq and its subsequent spaces */ const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy)); + int ack_res = FALSE; if (!msg) msg = ""; @@ -24643,28 +24635,24 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc } } - if (p->socket.type == AST_TRANSPORT_UDP) { - int ack_res = FALSE; - - /* Acknowledge whatever it is destined for */ - if ((resp >= 100) && (resp <= 199)) { - /* NON-INVITE messages do not ack a 1XX response. RFC 3261 section 17.1.2.2 */ - if (sipmethod == SIP_INVITE) { - ack_res = __sip_semi_ack(p, seqno, 0, sipmethod); - } - } else { - ack_res = __sip_ack(p, seqno, 0, sipmethod); + /* Acknowledge whatever it is destined for */ + if ((resp >= 100) && (resp <= 199)) { + /* NON-INVITE messages do not ack a 1XX response. RFC 3261 section 17.1.2.2 */ + if (sipmethod == SIP_INVITE) { + ack_res = __sip_semi_ack(p, seqno, 0, sipmethod); } + } else { + ack_res = __sip_ack(p, seqno, 0, sipmethod); + } - if (ack_res == FALSE) { - /* RFC 3261 13.2.2.4 and 17.1.1.2 - We must re-send ACKs to re-transmitted final responses */ - if (sipmethod == SIP_INVITE && resp >= 200) { - transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, resp < 300 ? TRUE: FALSE); - } - - append_history(p, "Ignore", "Ignoring this retransmit\n"); - return; + if (ack_res == FALSE) { + /* RFC 3261 13.2.2.4 and 17.1.1.2 - We must re-send ACKs to re-transmitted final responses */ + if (sipmethod == SIP_INVITE && resp >= 200) { + transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, resp < 300 ? TRUE: FALSE); } + + append_history(p, "Ignore", "Ignoring this retransmit\n"); + return; } /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */