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