Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 80129) +++ channels/chan_sip.c (working copy) @@ -198,8 +198,8 @@ #define DEFAULT_RETRANS 1000 /*!< How frequently to retransmit Default: 2 * 500 ms in RFC 3261 */ #define MAX_RETRANS 6 /*!< Try only 6 times for retransmissions, a total of 7 transmissions */ -#define SIP_TIMER_T1 500 /* SIP timer T1 (according to RFC 3261) */ -#define SIP_TRANS_TIMEOUT 32000 /*!< SIP request timeout (rfc 3261) 64*T1 +#define SIP_TIMER_T1 500 /* SIP timer T1 (according to RFC 3261) */ +#define SIP_TRANS_TIMEOUT 64 * SIP_TIMER_T1/*!< SIP request timeout (rfc 3261) 64*T1 \todo Use known T1 for timeout (peerpoke) */ #define DEFAULT_TRANS_TIMEOUT -1 /* Use default SIP transaction timeout */ @@ -616,7 +616,9 @@ static char global_useragent[AST_MAX_EXTENSION]; /*!< Useragent for the SIP channel */ static int allow_external_domains; /*!< Accept calls to external SIP domains? */ static int global_callevents; /*!< Whether we send manager events or not */ +static int global_t1; /*!< T1 time */ static int global_t1min; /*!< T1 roundtrip time minimum */ +static int global_timer_b; /*!< Timer B - RFC 3261 Section 17.1.1.2 */ static int global_regextenonqualify; /*!< Whether to add/remove regexten when qualifying peers */ static int global_autoframing; /*!< Turn autoframing on or off. */ static enum transfermodes global_allowtransfer; /*!< SIP Refer restriction scheme */ @@ -1052,6 +1054,7 @@ char notext; /*!< Text not supported (?) */ int timer_t1; /*!< SIP timer T1, ms rtt */ + int timer_b; /*!< SIP timer B, ms */ unsigned int sipoptions; /*!< Supported SIP options on the other end */ struct ast_codec_pref prefs; /*!< codec prefs */ int capability; /*!< Special capability (codec) */ @@ -1309,6 +1312,8 @@ struct ast_variable *chanvars; /*!< Variables to set for channel created by user */ struct sip_pvt *mwipvt; /*!< Subscription for MWI */ int autoframing; + int timer_t1; /*!< The maximum T1 value for the peer */ + int timer_b; /*!< The maximum timer B (transaction timeouts) */ }; @@ -2441,8 +2446,10 @@ static void sip_scheddestroy(struct sip_pvt *p, int ms) { if (ms < 0) { - if (p->timer_t1 == 0) - p->timer_t1 = SIP_TIMER_T1; /* Set timer T1 if not set (RFC 3261) */ + if (p->timer_t1 == 0) { + p->timer_t1 = global_t1; /* Set timer T1 if not set (RFC 3261) */ + p->timer_b = global_timer_b; /* Set timer B if not set (RFC 3261) */ + } ms = p->timer_t1 * 64; } if (sip_debug_test_pvt(p)) @@ -3371,10 +3378,19 @@ dialog->callgroup = peer->callgroup; dialog->pickupgroup = peer->pickupgroup; dialog->allowtransfer = peer->allowtransfer; - /* Set timer T1 to RTT for this peer (if known by qualify=) */ - /* Minimum is settable or default to 100 ms */ + /* If there is a maxms and lastms from a qualify use that over a manual T1 + value. Otherwise, use the peer's T1 value. */ if (peer->maxms && peer->lastms) dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; + else + dialog->timer_t1 = peer->timer_t1; + + /* Set timer B to control transaction timeouts */ + if (peer->timer_b) + dialog->timer_b = peer->timer_b; + else + dialog->timer_b = 64 * dialog->timer_t1; + if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) dialog->noncodeccapability |= AST_RTP_DTMF; @@ -3408,7 +3424,8 @@ if (port) *port++ = '\0'; dialog->sa.sin_family = AF_INET; - dialog->timer_t1 = SIP_TIMER_T1; /* Default SIP retransmission timer T1 (RFC 3261) */ + dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */ + dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */ peer = find_peer(peername, NULL, 1); if (peer) { @@ -3560,7 +3577,7 @@ p->invitestate = INV_CALLING; /* Initialize auto-congest time */ - p->initid = ast_sched_replace(p->initid, sched, SIP_TRANS_TIMEOUT, + p->initid = ast_sched_replace(p->initid, sched, p->timer_b, auto_congest, dialog_ref(p)); } @@ -4971,8 +4988,10 @@ p->stateid = -1; p->prefs = default_prefs; /* Set default codecs for this call */ - if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ - p->timer_t1 = SIP_TIMER_T1; /* Default SIP retransmission timer T1 (RFC 3261) */ + if (intended_method != SIP_OPTIONS) { /* Peerpoke has it's own system */ + p->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */ + p->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */ + } if (!sin) p->ourip = internip; @@ -10195,6 +10214,15 @@ p->callingpres = peer->callingpres; if (peer->maxms && peer->lastms) p->timer_t1 = peer->lastms; + else + p->timer_t1 = peer->timer_t1; + + /* Set timer B to control transaction timeouts */ + if (peer->timer_b) + p->timer_b = peer->timer_b; + else + p->timer_b = 64 * p->timer_t1; + if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { /* Pretend there is no required authentication */ ast_string_field_free(p, peersecret); @@ -11231,6 +11259,8 @@ /* - is enumerated */ ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); + ast_cli(fd, " Timer T1 : %d\n", peer->timer_t1); + ast_cli(fd, " Timer B : %d\n", peer->timer_b); ast_cli(fd, " ToHost : %s\n", peer->tohost); ast_cli(fd, " Addr->IP : %s Port %d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port)); ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); @@ -11576,7 +11606,9 @@ ast_cli(fd, " Codec Order: "); print_codec_to_cli(fd, &default_prefs); ast_cli(fd, "\n"); + ast_cli(fd, " Timer T1: %d\n", global_t1); ast_cli(fd, " T1 minimum: %d\n", global_t1min); + ast_cli(fd, " Timer B: %d\n", global_timer_b); ast_cli(fd, " Relax DTMF: %s\n", cli_yesno(global_relaxdtmf)); ast_cli(fd, " Compact SIP headers: %s\n", cli_yesno(compactheaders)); ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); @@ -17281,6 +17313,8 @@ peer->pickupgroup = 0; peer->maxms = default_qualify; peer->prefs = default_prefs; + peer->timer_t1 = global_t1; + peer->timer_b = global_timer_b; clear_peer_mailboxes(peer); } @@ -17552,6 +17586,16 @@ ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); peer->rtpkeepalive = global_rtpkeepalive; } + } else if (!strcasecmp(v->name, "timert1")) { + if ((sscanf(v->value, "%d", &peer->timer_t1) != 1) || (peer->timer_t1 < 0)) { + ast_log(LOG_WARNING, "'%s' is not a valid T1 time at line %d. Using default.\n", v->value, v->lineno); + peer->timer_t1 = global_t1; + } + } else if (!strcasecmp(v->name, "timerb")) { + if ((sscanf(v->value, "%d", &peer->timer_b) != 1) || (peer->timer_b < 0)) { + ast_log(LOG_WARNING, "'%s' is not a valid Timer B time at line %d. Using default.\n", v->value, v->lineno); + peer->timer_b = global_timer_b; + } } else if (!strcasecmp(v->name, "setvar")) { peer->chanvars = add_var(v->value, peer->chanvars); } else if (!strcasecmp(v->name, "qualify")) { @@ -17768,6 +17812,8 @@ /* Misc settings for the channel */ global_relaxdtmf = FALSE; global_callevents = FALSE; + global_t1 = SIP_TIMER_T1; + global_timer_b = 64 * SIP_TIMER_T1; global_t1min = DEFAULT_T1MIN; global_matchexterniplocally = FALSE; Index: configs/sip.conf.sample =================================================================== --- configs/sip.conf.sample (revision 80129) +++ configs/sip.conf.sample (working copy) @@ -74,6 +74,11 @@ ;defaultexpiry=120 ; Default length of incoming/outgoing registration ;t1min=100 ; Minimum roundtrip time for messages to monitored hosts ; Defaults to 100 ms +;timert1=500 ; Default T1 timer + ; Defaults to 500 ms +;timerb=32000 ; Call setup timer. If a provisional response is not received + ; in this amount of time, the call will autocongest + ; Defaults to 64*timert1 ;notifymimetype=text/plain ; Allow overriding of mime type in MWI NOTIFY ;buggymwi=no ; Cisco SIP firmware doesn't support the MWI RFC ; fully. Enable this option to not get error messages @@ -585,6 +590,8 @@ ; outboundproxy ; rfc2833compensate ; callbackextension +; timert1 +; timerb ;[sip_proxy] ; For incoming calls only. Example: FWD (Free World Dialup)