diff --git a/shoot.c b/shoot.c index 2e5d5b4..1d89fe4 100644 --- a/shoot.c +++ b/shoot.c @@ -183,7 +183,7 @@ void trace_reply() printf("(%.3f ms) ", deltaT(&(timers.sendtime), &(timers.recvtime))); print_message_line(rec); } - delays.retryAfter = SIP_T2; + delays.retryAfter = timer_t2; cdata.dontsend=1; return; } @@ -235,10 +235,10 @@ void handle_default() " waiting for a final response\n"); } if (inv_trans) { - delays.retryAfter = inv_final; + delays.retryAfter = timer_final; } else { - delays.retryAfter = SIP_T2; + delays.retryAfter = timer_t2; } cdata.dontsend = 1; return; @@ -273,7 +273,7 @@ void handle_default() else { counters.run++; new_transaction(req); - delays.retryAfter = SIP_T1; + delays.retryAfter = timer_t1; } } if (timing == 0) { @@ -340,10 +340,10 @@ void handle_usrloc() printf("ignoring provisional response\n\n"); } if (inv_trans) { - delays.retryAfter = inv_final; + delays.retryAfter = timer_final; } else { - delays.retryAfter = SIP_T2; + delays.retryAfter = timer_t2; } cdata.dontsend = 1; } @@ -794,10 +794,10 @@ void shoot(char *buf, int buff_size) /* delays.retryAfter = DEFAULT_TIMEOUT; */ if (transport == SIP_UDP_TRANSPORT) { - delays.retryAfter = SIP_T1; + delays.retryAfter = timer_t1; } else { - delays.retryAfter = inv_final; + delays.retryAfter = timer_final; } inv_trans = 0; cseq_counter = 1; @@ -1009,7 +1009,7 @@ void shoot(char *buf, int buff_size) } counters.run++; new_transaction(req); - delays.retryAfter = SIP_T1; + delays.retryAfter = timer_t1; continue; } fprintf(stderr, "%s\nerror: received 40[17] but cannot " diff --git a/sipsak.1 b/sipsak.1 index d65ba0e..7c359cb 100644 --- a/sipsak.1 +++ b/sipsak.1 @@ -526,6 +526,12 @@ per cent of the bindings will be removed, is determined by the USRLOC_REMOVE_PERCENT define within the code (set it before compilation). Multiple removing of bindings is possible, and cannot be prevented. +.IP "-Z, --timer-t1" +Sets the amount of milliseconds for the SIP timer T1. It determines the +length of the gaps between two retransmissions of a request on a unreliable +transport. Default value is 500 if not changed via the configure option +--enable-timeout. + .SH RETURN VALUES The return value 0 means that a 200 was received. 1 means something else then 1xx or 2xx was received. diff --git a/sipsak.c b/sipsak.c index 81fafa4..ba7ca6a 100644 --- a/sipsak.c +++ b/sipsak.c @@ -153,9 +153,11 @@ void print_long_help() { " --from=SIPURI use the given uri as From in MESSAGE\n" " --timeout-factor=NUMBER timeout multiplier for INVITE transactions\n" " on non-reliable transports (default: 64)\n" + " --timer-t1=NUMBER timeout T1 in ms (default: %i)\n" " --transport=STRING specify transport to be used\n" " --headers=STRING adds additional headers to the request\n" " --authhash=STRING ha1 hash for authentication instead of password\n" + , DEFAULT_TIMEOUT ); exit_code(0); } @@ -225,9 +227,11 @@ void print_help() { " -c SIPURI use the given uri as From in MESSAGE\n" " -D NUMBER timeout multiplier for INVITE transactions\n" " on non-reliable transports (default: 64)\n" + " -Z NUMBER timeout T1 in ms (default: %i)\n" " -E STRING specify transport to be used\n" " -j STRING adds additional headers to the request\n" " -J STRING ha1 hash for authentication instead of password\n" + , DEFAULT_TIMEOUT ); exit_code(0); } @@ -288,6 +292,7 @@ int main(int argc, char *argv[]) {"symmetric", 0, 0, 'S'}, {"from", 1, 0, 'c'}, {"timeout-factor", 1, 0, 'D'}, + {"timer-t1", 1, 0, 'Z'}, {"transport", 1, 0, 'E'}, {"headers", 1, 0, 'j'}, {"authhash", 1, 0, 'J'}, @@ -316,7 +321,9 @@ int main(int argc, char *argv[]) transport=tsp = 0; rport = port = 0; expires_t = USRLOC_EXP_DEF; - inv_final = 64 * SIP_T1; + timer_t1 = SIP_T1; + timer_t2 = 8; + timer_final = 64; memset(buff, 0, BUFSIZE); memset(fqdn, 0, FQDN_SIZE); #ifdef WITH_TLS_TRANSP @@ -338,9 +345,9 @@ int main(int argc, char *argv[]) /* lots of command line switches to handle*/ #ifdef HAVE_GETOPT_LONG - while ((c=getopt_long(argc, argv, "a:A:b:B:c:C:dD:e:E:f:Fg:GhH:iIj:J:l:Lm:MnNo:O:p:P:q:r:Rs:St:Tu:UvVwW:x:Xz:", l_opts, &option_index)) != EOF){ + while ((c=getopt_long(argc, argv, "a:A:b:B:c:C:dD:e:E:f:Fg:GhH:iIj:J:l:Lm:MnNo:O:p:P:q:r:Rs:St:Tu:UvVwW:x:Xz:Z:", l_opts, &option_index)) != EOF){ #else - while ((c=getopt(argc, argv, "a:A:b:B:c:C:dD:e:E:f:Fg:GhH:iIj:J:l:Lm:MnNo:O:p:P:q:r:Rs:St:Tu:UvVwW:x:z:")) != EOF){ + while ((c=getopt(argc, argv, "a:A:b:B:c:C:dD:e:E:f:Fg:GhH:iIj:J:l:Lm:MnNo:O:p:P:q:r:Rs:St:Tu:UvVwW:x:z:Z:")) != EOF){ #endif switch(c){ case 'a': @@ -426,7 +433,11 @@ int main(int argc, char *argv[]) redirects=0; break; case 'D': - inv_final = str_to_int(0, optarg) * SIP_T1; + timer_final = str_to_int(0, optarg); + if (timer_final <= 0) { + fprintf(stderr, "error: option D has to be above 0\n"); + exit_code(2); + } break; case 'e': nameend=str_to_int(0, optarg); @@ -771,6 +782,13 @@ int main(int argc, char *argv[]) exit_code(2); } break; + case 'Z': + timer_t1 = str_to_int(0, optarg); + if (timer_t1 <= 0) { + fprintf(stderr, "error: Z option must be above 0\n"); + exit_code(2); + } + break; default: fprintf(stderr, "error: unknown parameter %c\n", c); exit_code(2); @@ -789,6 +807,9 @@ int main(int argc, char *argv[]) transport = SIP_UDP_TRANSPORT; } + timer_t2 = timer_t2 * timer_t1; + timer_final = timer_final * timer_t1; + /* replace LF with CRLF if we read from a file */ if ((file_b) && (fix_crlf)) { insert_cr(buff); diff --git a/sipsak.h b/sipsak.h index 9c94a8f..ae49823 100644 --- a/sipsak.h +++ b/sipsak.h @@ -325,7 +325,8 @@ int sleep_ms, processes, cseq_counter; int verbose, nameend, namebeg, expires_t, flood, warning_ext, invite, message; int maxforw, lport, rport, randtrash, trashchar, numeric, symmetric; int file_b, uri_b, trace, via_ins, usrloc, redirects, rand_rem, replace_b; -int empty_contact, nagios_warn, fix_crlf, timing, outbound_proxy, inv_final; +int empty_contact, nagios_warn, fix_crlf, timing, outbound_proxy; +int timer_t1, timer_t2, timer_final; char *username, *domainname, *password, *replace_str, *hostname, *contact_uri; char *mes_body, *con_dis, *auth_username, *from_uri, *headers, *authhash; char fqdn[FQDN_SIZE]; diff --git a/transport.c b/transport.c index 5c3c86c..734ee2a 100644 --- a/transport.c +++ b/transport.c @@ -766,7 +766,7 @@ int check_for_message(char *recv, int size, struct sipsak_con_data *cd, if (count->send_counter==1) { memcpy(&(srt->firstsendt), &(srt->sendtime), sizeof(struct timeval)); } - if (sd->retryAfter == SIP_T1) { + if (sd->retryAfter == timer_t1) { memcpy(&(srt->starttime), &(srt->sendtime), sizeof(struct timeval)); } if (ret == 0) @@ -805,7 +805,7 @@ int check_for_message(char *recv, int size, struct sipsak_con_data *cd, } } senddiff = deltaT(&(srt->starttime), &(srt->recvtime)); - if (senddiff > (float)inv_final) { + if (senddiff > (float)timer_final) { if (timing == 0) { if (verbose>0) printf("*** giving up, no final response after %.3f ms\n", senddiff); @@ -817,7 +817,7 @@ int check_for_message(char *recv, int size, struct sipsak_con_data *cd, sd->all_delay += senddiff; sd->big_delay = senddiff; new_transaction(req); - sd->retryAfter = SIP_T1; + sd->retryAfter = timer_t1; if (timing == 0) { printf("%.3f/%.3f/%.3f ms\n", sd->small_delay, sd->all_delay / count->run, sd->big_delay); exit_code(3); @@ -826,11 +826,11 @@ int check_for_message(char *recv, int size, struct sipsak_con_data *cd, } else { /* set retry time according to RFC3261 */ - if ((inv_trans) || (sd->retryAfter *2 < SIP_T2)) { + if ((inv_trans) || (sd->retryAfter *2 < timer_t2)) { sd->retryAfter = sd->retryAfter * 2; } else { - sd->retryAfter = SIP_T2; + sd->retryAfter = timer_t2; } } (count->retrans_s_c)++; @@ -1070,7 +1070,7 @@ int recv_message(char *buf, int size, int inv_trans, printf(":\n"); #endif // HAVE_INET_NTOP if (!inv_trans && ret > 0 && (regexec(&(reg->proexp), buf, 0, 0, 0) != REG_NOERROR)) { - sd->retryAfter = SIP_T1; + sd->retryAfter = timer_t1; } } else {