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

(-)a/C4/SIP/SIPServer.pm (-1 / +121 lines)
Lines 8-14 use FindBin qw($Bin); Link Here
8
use lib "$Bin";
8
use lib "$Bin";
9
use Net::Server::PreFork;
9
use Net::Server::PreFork;
10
use IO::Socket::INET;
10
use IO::Socket::INET;
11
use Socket qw(:DEFAULT :crlf);
11
use Socket qw(:DEFAULT :crlf TCP_KEEPIDLE TCP_KEEPINTVL IPPROTO_TCP);
12
use Scalar::Util qw(blessed);
12
use Scalar::Util qw(blessed);
13
require UNIVERSAL::require;
13
require UNIVERSAL::require;
14
14
Lines 90-95 push @parms, 'group=' . $>; Link Here
90
# This is the main event.
90
# This is the main event.
91
__PACKAGE__ ->run(@parms);
91
__PACKAGE__ ->run(@parms);
92
92
93
#
94
# Server
95
#
96
97
=head3 options
98
99
As per Net::Server documentation, override "options" to provide your own
100
custom options to the Net::Server* object. This allows us to use the Net::Server
101
infrastructure for configuration rather than hacking our own configuration into the
102
object.
103
104
=cut
105
106
sub options {
107
    my $self     = shift;
108
    my $prop     = $self->{'server'};
109
    my $template = shift;
110
111
    # setup options in the parent classes
112
    $self->SUPER::options($template);
113
114
    $prop->{'custom_tcp_keepalive'} ||= undef;
115
    $template->{'custom_tcp_keepalive'} = \$prop->{'custom_tcp_keepalive'};
116
117
    $prop->{'custom_tcp_keepalive_time'} ||= undef;
118
    $template->{'custom_tcp_keepalive_time'} = \$prop->{'custom_tcp_keepalive_time'};
119
120
    $prop->{'custom_tcp_keepalive_intvl'} ||= undef;
121
    $template->{'custom_tcp_keepalive_intvl'} = \$prop->{'custom_tcp_keepalive_intvl'};
122
}
123
124
=head3 post_configure_hook
125
126
As per Net::Server documentation, this method validates our custom configuration.
127
128
=cut
129
130
sub post_configure_hook {
131
    my $self = shift;
132
    my $prop = $self->{'server'};
133
    if ( defined $prop->{'custom_tcp_keepalive'} && $prop->{'custom_tcp_keepalive'} ) {
134
135
        #NOTE: Any true value defined is forced to 1 just for the sake of predictability
136
        $prop->{'custom_tcp_keepalive'} = 1;
137
    }
138
139
    foreach my $key ( 'custom_tcp_keepalive_time', 'custom_tcp_keepalive_intvl' ) {
140
        my $value = $prop->{$key};
141
142
        #NOTE: A regex is used here to detect a positive integer, as int() returns integers but does not validate them
143
        #NOTE: We do not allow zero as it can lead to problematic behaviour
144
        if ( $value && $value =~ /^\d+$/ ) {
145
146
            #NOTE: Strictly, you must convert into an integer as a string will cause setsockopt to fail
147
            $prop->{$key} = int($value);
148
        }
149
    }
150
}
151
152
=head3 post_accept_hook 
153
154
This hook occurs after the client connection socket is created, which gives
155
us an opportunity to enable support for TCP keepalives using the SO_KEEPALIVE
156
socket option.
157
158
By default, the kernel-level defaults (in seconds) are used. You can view these in the output of "sysctl -a":
159
net.ipv4.tcp_keepalive_intvl = 75
160
net.ipv4.tcp_keepalive_time = 7200
161
162
Alternatively, you can use "custom_tcp_keepalive_time" and "custom_tcp_keepalive_intvl" to define
163
your own custom values for the socket. Note that these parameters are defined at the top server-level
164
and not on the listener-level.
165
166
If you lower "custom_tcp_keepalive_time" below 75, you will also need to set "custom_tcp_keepalive_intvl".
167
The "tcp_keepalive_time" is the initial time used for the keepalive timer, and the "tcp_keepalive_intvl"
168
is the time used for subsequent keepalive timers. However, timers only send keepalive ACKs if the idle time
169
elapsed is greater than "tcp_keepalive_time". 
170
171
Thus, if "tcp_keepalive_time = 10" and "tcp_keepalive_intvl = 5", a keepalive ACK will be sent every 10 seconds
172
of idle time. If "tcp_keepalive_intvl = 10" and "tcp_keepalive_time = 5", a keepalive ACK will be sent after 5
173
seconds of idle time, and the next keepalive ACK will be sent after 10 seconds of idle time. Generally speaking,
174
it's best to set "tcp_keepalive_time" to be higher than "tcp_keepalive_intvl". 
175
176
Reminder: once these settings are set on the socket, they are handled by the operating system kernel, and not
177
by the SIP server application. If you are having trouble with your settings, monitor your TCP traffic using
178
a tool such as "tcpdump" to review and refine how they work. 
179
180
=cut
181
182
sub post_accept_hook {
183
    my $self   = shift;
184
    my $prop   = $self->{'server'};
185
    my $client = shift || $prop->{'client'};
186
187
    my $tcp_keepalive       = $prop->{custom_tcp_keepalive};
188
    my $tcp_keepalive_time  = $prop->{custom_tcp_keepalive_time};
189
    my $tcp_keepalive_intvl = $prop->{custom_tcp_keepalive_intvl};
190
191
    if ($tcp_keepalive) {
192
193
        #NOTE: set the SO_KEEPALIVE option to enable TCP keepalives
194
        setsockopt( $client, SOL_SOCKET, SO_KEEPALIVE, 1 )
195
            or die "Unable to set SO_KEEPALIVE: $!";
196
197
        if ($tcp_keepalive_time) {
198
199
            #NOTE: override "net.ipv4.tcp_keepalive_time" kernel parameter for this socket
200
            setsockopt( $client, IPPROTO_TCP, TCP_KEEPIDLE, $tcp_keepalive_time )
201
                or die "Unable to set TCP_KEEPIDLE: $!";
202
        }
203
204
        if ($tcp_keepalive_intvl) {
205
206
            #NOTE: override "net.ipv4.tcp_keepalive_intvl" kernel parameter for this socket
207
            setsockopt( $client, IPPROTO_TCP, TCP_KEEPINTVL, $tcp_keepalive_intvl )
208
                or die "Unable to set TCP_KEEPINTVL: $!";
209
        }
210
    }
211
}
212
93
#
213
#
94
# Child
214
# Child
95
#
215
#
(-)a/debian/templates/SIPconfig.xml (+3 lines)
Lines 10-15 Link Here
10
  <server-params
10
  <server-params
11
    min_servers='1'
11
    min_servers='1'
12
    min_spare_servers='0'
12
    min_spare_servers='0'
13
    custom_tcp_keepalive='0'
14
    custom_tcp_keepalive_time='7200'
15
    custom_tcp_keepalive_intvl='75'
13
  />
16
  />
14
17
15
  <listeners>
18
  <listeners>
(-)a/etc/SIPconfig.xml (-1 / +3 lines)
Lines 19-24 Link Here
19
    user='koha'
19
    user='koha'
20
    group='koha'
20
    group='koha'
21
    pid_file='/var/run/sipserver.pid'
21
    pid_file='/var/run/sipserver.pid'
22
    custom_tcp_keepalive='0'
23
    custom_tcp_keepalive_time='7200'
24
    custom_tcp_keepalive_intvl='75'
22
  />
25
  />
23
26
24
  <listeners>
27
  <listeners>
25
- 

Return to bug 37087