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 |
# |