Bugzilla – Attachment 169642 Details for
Bug 37087
Add support for TCP keepalive to SIP server
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 37087: Add TCP keepalive support to SIP server
Bug-37087-Add-TCP-keepalive-support-to-SIP-server.patch (text/plain), 7.71 KB, created by
Martin Renvoize (ashimema)
on 2024-07-26 07:11:18 UTC
(
hide
)
Description:
Bug 37087: Add TCP keepalive support to SIP server
Filename:
MIME Type:
Creator:
Martin Renvoize (ashimema)
Created:
2024-07-26 07:11:18 UTC
Size:
7.71 KB
patch
obsolete
>From 2ab72b13d122123bdf3f540f5e6521fc3dd9994f Mon Sep 17 00:00:00 2001 >From: David Cook <dcook@prosentient.com.au> >Date: Fri, 14 Jun 2024 04:34:47 +0000 >Subject: [PATCH] Bug 37087: Add TCP keepalive support to SIP server >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >This change adds the ability to enable and configure TCP keepalive >support for the SIP server using SIPconfig.xml. > >For the sake of backwards compatibility, it defaults to disabled >and additional parameters default match typical kernel defaults. > >Technical detail can be found in the perldoc for C4/SIP/SIPserver.pm > >Test plan: >0. Apply the patch >1. koha-sip --restart kohadev >2. apt-get update && apt-get install tcpdump >3. In one window, run "tcpdump -A -n -v -i any 'port 6001'" >4. In another window, run the following: >echo -e "9300CNterm1|COterm1|CPCPL|\r" | nc 127.0.0.1 6001 -v >5. Note in tcpdump output that after the initial flood of packets, >nothing more is received > >6. vi /etc/koha/sites/kohadev/SIPconfig.xml >7. In the "server-params" element, add attributes like the following: >custom_tcp_keepalive='1' >custom_tcp_keepalive_time='10' >custom_tcp_keepalive_intvl='5' >8. koha-sip --restart kohadev >9. In one window, run "tcpdump -A -n -v -i any 'port 6001'" >10. In another window, run the following: >echo -e "9300CNterm1|COterm1|CPCPL|\r" | nc 127.0.0.1 6001 -v >11. Note in tcpdump output that after the initial flood of packets, >ACK packets are sent out every 10+ seconds for the idle connection > >Signed-off-by: Tadeusz âtadzikâ SoÅnierz <tadeusz@sosnierz.com> >Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com> >--- > C4/SIP/SIPServer.pm | 122 ++++++++++++++++++++++++++++++++- > debian/templates/SIPconfig.xml | 3 + > etc/SIPconfig.xml | 3 + > 3 files changed, 127 insertions(+), 1 deletion(-) > >diff --git a/C4/SIP/SIPServer.pm b/C4/SIP/SIPServer.pm >index d26f5e25e6b..96c1809fbe1 100644 >--- a/C4/SIP/SIPServer.pm >+++ b/C4/SIP/SIPServer.pm >@@ -8,7 +8,7 @@ use FindBin qw($Bin); > use lib "$Bin"; > use Net::Server::PreFork; > use IO::Socket::INET; >-use Socket qw(:DEFAULT :crlf); >+use Socket qw(:DEFAULT :crlf TCP_KEEPIDLE TCP_KEEPINTVL IPPROTO_TCP); > use Scalar::Util qw(blessed); > require UNIVERSAL::require; > >@@ -90,6 +90,126 @@ push @parms, 'group=' . $>; > # This is the main event. > __PACKAGE__ ->run(@parms); > >+# >+# Server >+# >+ >+=head3 options >+ >+As per Net::Server documentation, override "options" to provide your own >+custom options to the Net::Server* object. This allows us to use the Net::Server >+infrastructure for configuration rather than hacking our own configuration into the >+object. >+ >+=cut >+ >+sub options { >+ my $self = shift; >+ my $prop = $self->{'server'}; >+ my $template = shift; >+ >+ # setup options in the parent classes >+ $self->SUPER::options($template); >+ >+ $prop->{'custom_tcp_keepalive'} ||= undef; >+ $template->{'custom_tcp_keepalive'} = \$prop->{'custom_tcp_keepalive'}; >+ >+ $prop->{'custom_tcp_keepalive_time'} ||= undef; >+ $template->{'custom_tcp_keepalive_time'} = \$prop->{'custom_tcp_keepalive_time'}; >+ >+ $prop->{'custom_tcp_keepalive_intvl'} ||= undef; >+ $template->{'custom_tcp_keepalive_intvl'} = \$prop->{'custom_tcp_keepalive_intvl'}; >+} >+ >+=head3 post_configure_hook >+ >+As per Net::Server documentation, this method validates our custom configuration. >+ >+=cut >+ >+sub post_configure_hook { >+ my $self = shift; >+ my $prop = $self->{'server'}; >+ if ( defined $prop->{'custom_tcp_keepalive'} && $prop->{'custom_tcp_keepalive'} ) { >+ >+ #NOTE: Any true value defined is forced to 1 just for the sake of predictability >+ $prop->{'custom_tcp_keepalive'} = 1; >+ } >+ >+ foreach my $key ( 'custom_tcp_keepalive_time', 'custom_tcp_keepalive_intvl' ) { >+ my $value = $prop->{$key}; >+ >+ #NOTE: A regex is used here to detect a positive integer, as int() returns integers but does not validate them >+ #NOTE: We do not allow zero as it can lead to problematic behaviour >+ if ( $value && $value =~ /^\d+$/ ) { >+ >+ #NOTE: Strictly, you must convert into an integer as a string will cause setsockopt to fail >+ $prop->{$key} = int($value); >+ } >+ } >+} >+ >+=head3 post_accept_hook >+ >+This hook occurs after the client connection socket is created, which gives >+us an opportunity to enable support for TCP keepalives using the SO_KEEPALIVE >+socket option. >+ >+By default, the kernel-level defaults (in seconds) are used. You can view these in the output of "sysctl -a": >+net.ipv4.tcp_keepalive_intvl = 75 >+net.ipv4.tcp_keepalive_time = 7200 >+ >+Alternatively, you can use "custom_tcp_keepalive_time" and "custom_tcp_keepalive_intvl" to define >+your own custom values for the socket. Note that these parameters are defined at the top server-level >+and not on the listener-level. >+ >+If you lower "custom_tcp_keepalive_time" below 75, you will also need to set "custom_tcp_keepalive_intvl". >+The "tcp_keepalive_time" is the initial time used for the keepalive timer, and the "tcp_keepalive_intvl" >+is the time used for subsequent keepalive timers. However, timers only send keepalive ACKs if the idle time >+elapsed is greater than "tcp_keepalive_time". >+ >+Thus, if "tcp_keepalive_time = 10" and "tcp_keepalive_intvl = 5", a keepalive ACK will be sent every 10 seconds >+of idle time. If "tcp_keepalive_intvl = 10" and "tcp_keepalive_time = 5", a keepalive ACK will be sent after 5 >+seconds of idle time, and the next keepalive ACK will be sent after 10 seconds of idle time. Generally speaking, >+it's best to set "tcp_keepalive_time" to be higher than "tcp_keepalive_intvl". >+ >+Reminder: once these settings are set on the socket, they are handled by the operating system kernel, and not >+by the SIP server application. If you are having trouble with your settings, monitor your TCP traffic using >+a tool such as "tcpdump" to review and refine how they work. >+ >+=cut >+ >+sub post_accept_hook { >+ my $self = shift; >+ my $prop = $self->{'server'}; >+ my $client = shift || $prop->{'client'}; >+ >+ my $tcp_keepalive = $prop->{custom_tcp_keepalive}; >+ my $tcp_keepalive_time = $prop->{custom_tcp_keepalive_time}; >+ my $tcp_keepalive_intvl = $prop->{custom_tcp_keepalive_intvl}; >+ >+ if ($tcp_keepalive) { >+ >+ #NOTE: set the SO_KEEPALIVE option to enable TCP keepalives >+ setsockopt( $client, SOL_SOCKET, SO_KEEPALIVE, 1 ) >+ or die "Unable to set SO_KEEPALIVE: $!"; >+ >+ if ($tcp_keepalive_time) { >+ >+ #NOTE: override "net.ipv4.tcp_keepalive_time" kernel parameter for this socket >+ setsockopt( $client, IPPROTO_TCP, TCP_KEEPIDLE, $tcp_keepalive_time ) >+ or die "Unable to set TCP_KEEPIDLE: $!"; >+ } >+ >+ if ($tcp_keepalive_intvl) { >+ >+ #NOTE: override "net.ipv4.tcp_keepalive_intvl" kernel parameter for this socket >+ setsockopt( $client, IPPROTO_TCP, TCP_KEEPINTVL, $tcp_keepalive_intvl ) >+ or die "Unable to set TCP_KEEPINTVL: $!"; >+ } >+ } >+} >+ > # > # Child > # >diff --git a/debian/templates/SIPconfig.xml b/debian/templates/SIPconfig.xml >index e79a2950b6c..f0a408c67b7 100644 >--- a/debian/templates/SIPconfig.xml >+++ b/debian/templates/SIPconfig.xml >@@ -10,6 +10,9 @@ > <server-params > min_servers='1' > min_spare_servers='0' >+ custom_tcp_keepalive='0' >+ custom_tcp_keepalive_time='7200' >+ custom_tcp_keepalive_intvl='75' > /> > > <listeners> >diff --git a/etc/SIPconfig.xml b/etc/SIPconfig.xml >index 1816b91a234..a1432b13f34 100644 >--- a/etc/SIPconfig.xml >+++ b/etc/SIPconfig.xml >@@ -19,6 +19,9 @@ > user='koha' > group='koha' > pid_file='/var/run/sipserver.pid' >+ custom_tcp_keepalive='0' >+ custom_tcp_keepalive_time='7200' >+ custom_tcp_keepalive_intvl='75' > /> > > <listeners> >-- >2.45.2
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 37087
:
167706
|
167713
| 169642