View | Details | Raw Unified | Return to bug 15006
Collapse All | Expand All

(-)a/C4/SIP/SIPServer.pm (-5 / +7 lines)
Lines 15-20 use C4::SIP::Sip::Constants qw(:all); Link Here
15
use C4::SIP::Sip::Configuration;
15
use C4::SIP::Sip::Configuration;
16
use C4::SIP::Sip::Checksum qw(checksum verify_cksum);
16
use C4::SIP::Sip::Checksum qw(checksum verify_cksum);
17
use C4::SIP::Sip::MsgType qw( handle login_core );
17
use C4::SIP::Sip::MsgType qw( handle login_core );
18
use C4::SIP::Sip qw( get_timeout );
18
19
19
use base qw(Net::Server::PreFork);
20
use base qw(Net::Server::PreFork);
20
21
Lines 135-142 sub raw_transport { Link Here
135
    # Timeout the while loop if we get stuck in it
136
    # Timeout the while loop if we get stuck in it
136
    # In practice it should only iterate once but be prepared
137
    # In practice it should only iterate once but be prepared
137
    local $SIG{ALRM} = sub { die 'raw transport Timed Out!' };
138
    local $SIG{ALRM} = sub { die 'raw transport Timed Out!' };
138
    syslog('LOG_DEBUG', "raw_transport: timeout is $service->{timeout}");
139
    my $timeout = get_timeout( $self, { transport => 1 } );
139
    alarm $service->{timeout};
140
    syslog('LOG_DEBUG', "raw_transport: timeout is $timeout");
141
    alarm $timeout;
140
    while (!$self->{account}) {
142
    while (!$self->{account}) {
141
        $input = read_request();
143
        $input = read_request();
142
        if (!$input) {
144
        if (!$input) {
Lines 193-200 sub telnet_transport { Link Here
193
    my $account = undef;
195
    my $account = undef;
194
    my $input;
196
    my $input;
195
    my $config  = $self->{config};
197
    my $config  = $self->{config};
196
	my $timeout = $self->{service}->{timeout} || $config->{timeout} || 30;
198
    my $timeout = get_timeout( $self, { transport => 1 } );
197
	syslog("LOG_DEBUG", "telnet_transport: timeout is %s", $timeout);
199
	syslog("LOG_DEBUG", "telnet_transport: timeout is $timeout");
198
200
199
    eval {
201
    eval {
200
	local $SIG{ALRM} = sub { die "telnet_transport: Timed Out ($timeout seconds)!\n"; };
202
	local $SIG{ALRM} = sub { die "telnet_transport: Timed Out ($timeout seconds)!\n"; };
Lines 256-262 sub sip_protocol_loop { Link Here
256
    my $self = shift;
258
    my $self = shift;
257
    my $service = $self->{service};
259
    my $service = $self->{service};
258
    my $config  = $self->{config};
260
    my $config  = $self->{config};
259
    my $timeout = $self->{service}->{timeout} || $config->{timeout} || 30;
261
    my $timeout = get_timeout( $self, { client => 1 } );
260
262
261
    # The spec says the first message will be:
263
    # The spec says the first message will be:
262
    #     SIP v1: SC_STATUS
264
    #     SIP v1: SC_STATUS
(-)a/C4/SIP/Sip.pm (-1 / +45 lines)
Lines 22-38 BEGIN { Link Here
22
	@ISA = qw(Exporter);
22
	@ISA = qw(Exporter);
23
23
24
	@EXPORT_OK = qw(y_or_n timestamp add_field maybe_add add_count
24
	@EXPORT_OK = qw(y_or_n timestamp add_field maybe_add add_count
25
		    denied sipbool boolspace write_msg
25
		    denied sipbool boolspace write_msg get_timeout
26
		    $error_detection $protocol_version $field_delimiter
26
		    $error_detection $protocol_version $field_delimiter
27
		    $last_response);
27
		    $last_response);
28
28
29
	%EXPORT_TAGS = (
29
	%EXPORT_TAGS = (
30
		    all => [qw(y_or_n timestamp add_field maybe_add
30
		    all => [qw(y_or_n timestamp add_field maybe_add
31
			       add_count denied sipbool boolspace write_msg
31
			       add_count denied sipbool boolspace write_msg
32
                   get_timeout
32
			       $error_detection $protocol_version
33
			       $error_detection $protocol_version
33
			       $field_delimiter $last_response)]);
34
			       $field_delimiter $last_response)]);
34
}
35
}
35
36
37
36
our $error_detection = 0;
38
our $error_detection = 0;
37
our $protocol_version = 1;
39
our $protocol_version = 1;
38
our $field_delimiter = '|'; # Protocol Default
40
our $field_delimiter = '|'; # Protocol Default
Lines 197-200 sub write_msg { Link Here
197
    $last_response = $msg;
199
    $last_response = $msg;
198
}
200
}
199
201
202
# get_timeout( $server, { $type => 1, fallback => $fallback } );
203
#     where $type is transport | client | policy
204
#
205
# Centralizes all timeout logic.
206
# Transport refers to login process, client to active connections.
207
# Policy timeout is transaction timeout (used in ACS status message).
208
#
209
# Fallback is optional. If you do not pass transport, client or policy,
210
# you will get fallback or hardcoded default.
211
212
sub get_timeout {
213
    my ( $server, $params ) = @_;
214
    my $fallback = $params->{fallback} || 30;
215
    my $service = $server->{service} // {};
216
    my $config = $server->{config} // {};
217
218
    if( $params->{transport} ||
219
        ( $params->{client} && !exists $service->{client_timeout} )) {
220
        # We do not allow zero values here.
221
        # Note: config/timeout seems to be deprecated.
222
        return $service->{timeout} || $config->{timeout} || $fallback;
223
224
    } elsif( $params->{client} ) {
225
        # We know that client_timeout exists now.
226
        # We do allow zero values here to indicate no timeout.
227
        return 0 if $service->{client_timeout} =~ /^0+$|\D/;
228
        return $service->{client_timeout};
229
230
    } elsif( $params->{policy} ) {
231
        my $policy = $server->{policy} // {};
232
        my $rv = sprintf( "%03d", $policy->{timeout} // 0 );
233
        if( length($rv) != 3 ) {
234
            syslog( "LOG_ERR", "Policy timeout has wrong size: '%s'", $rv );
235
            return '000';
236
        }
237
        return $rv;
238
239
    } else {
240
        return $fallback;
241
    }
242
}
243
200
1;
244
1;
(-)a/C4/SIP/Sip/MsgType.pm (-6 / +1 lines)
Lines 1505-1518 sub send_acs_status { Link Here
1505
    $ACS_renewal_policy = sipbool( $policy->{renewal} );
1505
    $ACS_renewal_policy = sipbool( $policy->{renewal} );
1506
    $status_update_ok   = sipbool( $ils->status_update_ok );
1506
    $status_update_ok   = sipbool( $ils->status_update_ok );
1507
    $offline_ok         = sipbool( $ils->offline_ok );
1507
    $offline_ok         = sipbool( $ils->offline_ok );
1508
    $timeout            = sprintf( "%03d", $policy->{timeout} );
1508
    $timeout            = get_timeout( $server, { policy => 1 } );
1509
    $retries            = sprintf( "%03d", $policy->{retries} );
1509
    $retries            = sprintf( "%03d", $policy->{retries} );
1510
1510
1511
    if ( length($timeout) != 3 ) {
1512
        syslog( "LOG_ERR", "handle_acs_status: timeout field wrong size: '%s'", $timeout );
1513
        $timeout = '000';
1514
    }
1515
1516
    if ( length($retries) != 3 ) {
1511
    if ( length($retries) != 3 ) {
1517
        syslog( "LOG_ERR", "handle_acs_status: retries field wrong size: '%s'", $retries );
1512
        syslog( "LOG_ERR", "handle_acs_status: retries field wrong size: '%s'", $retries );
1518
        $retries = '000';
1513
        $retries = '000';
(-)a/etc/SIPconfig.xml (+8 lines)
Lines 32-38 Link Here
32
      port="127.0.0.1:6001/tcp"
32
      port="127.0.0.1:6001/tcp"
33
      transport="RAW" 
33
      transport="RAW" 
34
      protocol="SIP/2.00"
34
      protocol="SIP/2.00"
35
      client_timeout="0"
35
      timeout="60" />
36
      timeout="60" />
37
<!--- client_timeout times out active connections which have not received
38
     input from the client. Many persistent connections will send a status request
39
     every 5-7 mins so setting this to less than that will add instability to the connection
40
     if explicitly set to zero, no timeout is applied to the connection.
41
     NB the parameter timeout applies to the login process only and should be set to a lower value
42
     to time out failed connections
43
-->
36
  </listeners>
44
  </listeners>
37
45
38
  <accounts>
46
  <accounts>
(-)a/t/SIP_Sip.t (-25 / +66 lines)
Lines 17-58 Link Here
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Test::More tests => 9;
20
use Test::More tests => 3;
21
use Test::Warn;
21
use Test::Warn;
22
22
23
BEGIN {
23
BEGIN {
24
        use_ok('C4::SIP::Sip');
24
        use_ok('C4::SIP::Sip', qw|get_timeout| );
25
}
25
}
26
26
27
my $date_time = C4::SIP::Sip::timestamp();
27
subtest 'Timestamp' => sub {
28
like( $date_time, qr/^\d{8}    \d{6}$/, 'Timestamp format no param');
28
    plan tests => 8;
29
    test_timestamp();
30
};
31
subtest 'Get_timeout' => sub {
32
    plan tests => 11;
33
    test_get_timeout();
34
};
29
35
30
my $t = time();
36
sub test_timestamp {
37
    my $date_time = C4::SIP::Sip::timestamp();
38
    like( $date_time, qr/^\d{8}    \d{6}$/, 'Timestamp format no param');
31
39
32
$date_time = C4::SIP::Sip::timestamp($t);
40
    my $t = time();
33
like( $date_time, qr/^\d{8}    \d{6}$/, 'Timestamp format secs');
34
41
35
$date_time = C4::SIP::Sip::timestamp('2011-01-12');
42
    $date_time = C4::SIP::Sip::timestamp($t);
36
ok( $date_time eq '20110112    235900', 'Timestamp iso date string');
43
    like( $date_time, qr/^\d{8}    \d{6}$/, 'Timestamp format secs');
37
44
38
my $myChecksum = C4::SIP::Sip::Checksum::checksum("12345");
45
    $date_time = C4::SIP::Sip::timestamp('2011-01-12');
39
my $checker = 65281;
46
    ok( $date_time eq '20110112    235900', 'Timestamp iso date string');
40
my $stringChecksum = C4::SIP::Sip::Checksum::checksum("teststring");
41
my $stringChecker = 64425;
42
47
43
is( $myChecksum, $checker, "Checksum: $myChecksum matches expected output");
48
    my $myChecksum = C4::SIP::Sip::Checksum::checksum("12345");
44
is( $stringChecksum, $stringChecker, "Checksum: $stringChecksum matches expected output");
49
    my $checker = 65281;
50
    my $stringChecksum = C4::SIP::Sip::Checksum::checksum("teststring");
51
    my $stringChecker = 64425;
45
52
46
my $testdata = "abcdAZ";
53
    is( $myChecksum, $checker, "Checksum: $myChecksum matches expected output");
47
my $something = C4::SIP::Sip::Checksum::checksum($testdata);
54
    is( $stringChecksum, $stringChecker, "Checksum: $stringChecksum matches expected output");
48
55
49
$something =  sprintf("%4X", $something);
56
    my $testdata = "abcdAZ";
50
ok( C4::SIP::Sip::Checksum::verify_cksum($testdata.$something), "Checksum: $something is valid.");
57
    my $something = C4::SIP::Sip::Checksum::checksum($testdata);
51
58
52
my $invalidTest;
59
    $something =  sprintf("%4X", $something);
53
warning_is { $invalidTest = C4::SIP::Sip::Checksum::verify_cksum("1234567") }
60
    ok( C4::SIP::Sip::Checksum::verify_cksum($testdata.$something), "Checksum: $something is valid.");
54
            'verify_cksum: no sum detected',
61
55
            'verify_cksum prints the expected warning for an invalid checksum';
62
    my $invalidTest;
56
is($invalidTest, 0, "Checksum: 1234567 is invalid as expected");
63
    warning_is { $invalidTest = C4::SIP::Sip::Checksum::verify_cksum("1234567") }
64
                'verify_cksum: no sum detected',
65
                'verify_cksum prints the expected warning for an invalid checksum';
66
    is($invalidTest, 0, "Checksum: 1234567 is invalid as expected");
67
}
68
69
sub test_get_timeout {
70
    my $server = { policy => { timeout => 1 },
71
                   config => { timeout => 2 },
72
                   service => {
73
                       timeout => 3,
74
                       client_timeout => 4,
75
                   },
76
    };
77
78
    is( get_timeout(), 30, "Default fallback" );
79
    is( get_timeout( undef, { fallback => 25 } ), 25, "Fallback parameter" );
80
    is( get_timeout( $server, { transport => 1 } ), 3, "Transport value" );
81
    is( get_timeout( $server, { client => 1 } ), 4, "Client value" );
82
    is( get_timeout( $server, { policy => 1 } ), '001', "Policy value" );
83
84
    delete $server->{policy}->{timeout};
85
    is( get_timeout( $server, { policy => 1 } ), '000', "No policy" );
86
87
    $server->{service}->{client_timeout} = '0';
88
    is( get_timeout( $server, { client => 1 } ), 0, "Client zero" );
89
    $server->{service}->{client_timeout} = 'no';
90
    is( get_timeout( $server, { client => 1 } ), 0, "Client no" );
91
    delete $server->{service}->{client_timeout};
92
    is( get_timeout( $server, { client => 1 } ), 3, "Fallback to service" );
93
94
    delete $server->{service}->{timeout};
95
    is( get_timeout( $server, { transport => 1 } ), 2, "Back to old config" );
96
    delete $server->{config}->{timeout};
97
    is( get_timeout( $server, { transport => 1 } ), 30, "Fallback again" );
98
}
57
99
58
1;
100
1;
59
- 

Return to bug 15006