Merge "chan_sip: Enable Session-Timers for SIP over TCP (and TLS)." into 13

This commit is contained in:
zuul
2016-07-22 16:55:13 -05:00
committed by Gerrit Code Review
2 changed files with 30 additions and 32 deletions

10
CHANGES
View File

@@ -18,6 +18,16 @@ chan_dahdi
The option determines how many seconds into a call before faxdetect The option determines how many seconds into a call before faxdetect
is disabled for the call. Setting the value to zero disables the timeout. is disabled for the call. Setting the value to zero disables the timeout.
chan_sip
------------------
* 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.
res_pjsip res_pjsip
------------------ ------------------
* Added "fax_detect_timeout" to endpoint. * Added "fax_detect_timeout" to endpoint.

View File

@@ -4200,19 +4200,6 @@ static enum sip_result __sip_reliable_xmit(struct sip_pvt *p, uint32_t seqno, in
p->pendinginvite = seqno; 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); pkt = ao2_alloc_options(sizeof(*pkt), sip_pkt_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK);
if (!pkt) { if (!pkt) {
return AST_FAILURE; return AST_FAILURE;
@@ -4249,6 +4236,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->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 */ 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 */ /* Schedule retransmission */
ao2_t_ref(pkt, +1, "Schedule packet retransmission"); ao2_t_ref(pkt, +1, "Schedule packet retransmission");
pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1);
@@ -24592,6 +24583,7 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
char *c_copy = ast_strdupa(c); char *c_copy = ast_strdupa(c);
/* Skip the Cseq and its subsequent spaces */ /* Skip the Cseq and its subsequent spaces */
const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy)); const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy));
int ack_res = FALSE;
if (!msg) if (!msg)
msg = ""; msg = "";
@@ -24620,28 +24612,24 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
ast_channel_hangupcause_set(owner, hangup_sip2cause(resp)); ast_channel_hangupcause_set(owner, hangup_sip2cause(resp));
} }
if (p->socket.type == AST_TRANSPORT_UDP) { /* Acknowledge whatever it is destined for */
int ack_res = FALSE; 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 (ack_res == FALSE) {
if ((resp >= 100) && (resp <= 199)) { /* RFC 3261 13.2.2.4 and 17.1.1.2 - We must re-send ACKs to re-transmitted final responses */
/* NON-INVITE messages do not ack a 1XX response. RFC 3261 section 17.1.2.2 */ if (sipmethod == SIP_INVITE && resp >= 200) {
if (sipmethod == SIP_INVITE) { transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, resp < 300 ? TRUE: FALSE);
ack_res = __sip_semi_ack(p, seqno, 0, sipmethod);
}
} else {
ack_res = __sip_ack(p, seqno, 0, sipmethod);
} }
if (ack_res == FALSE) { append_history(p, "Ignore", "Ignoring this retransmit\n");
/* RFC 3261 13.2.2.4 and 17.1.1.2 - We must re-send ACKs to re-transmitted final responses */ return;
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 */ /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */