File Coverage

blib/lib/Net/Server/Proto/TCP.pm
Criterion Covered Total %
statement 76 104 73.0
branch 34 54 62.9
condition 6 15 40.0
subroutine 17 20 85.0
pod 9 14 64.2
total 142 207 68.6


line stmt bran cond sub pod time code
1             # -*- perl -*-
2             #
3             # Net::Server::Proto::TCP - Net::Server Protocol module
4             #
5             # Copyright (C) 2001-2022
6             #
7             # Paul Seamons
8             #
9             # This package may be distributed under the terms of either the
10             # GNU General Public License
11             # or the
12             # Perl Artistic License
13             #
14             # All rights reserved.
15             #
16             ################################################################
17              
18             package Net::Server::Proto::TCP;
19              
20 25     25   189 use strict;
  25         56  
  25         1743  
21 25     25   187 use warnings;
  25         48  
  25         4921  
22 25     25   183 use Carp qw(croak);
  25         73  
  25         15971  
23 25     25   256 use IO::Socket::INET ();
  25         65  
  25         1304  
24 25     25   214 use Net::Server::Proto qw(SOMAXCONN AF_INET AF_INET6 AF_UNSPEC);
  25         46  
  25         1011  
25 25     25   517 use base qw(Net::Server::IP); # Can safely handle IPv4 or IPv6 on the fly
  25         58  
  25         56636  
26              
27 159     159 0 853 sub NS_proto { 'TCP' }
28 294 100   294 0 864 sub NS_port { my $sock = shift; ${*$sock}{'NS_port'} = shift if @_; return ${*$sock}{'NS_port'} }
  294         823  
  145         529  
  294         446  
  294         1001  
29 243 100   243 0 602 sub NS_host { my $sock = shift; ${*$sock}{'NS_host'} = shift if @_; return ${*$sock}{'NS_host'} }
  243         643  
  119         359  
  243         401  
  243         2247  
30 243 100   243 0 634 sub NS_ipv { my $sock = shift; ${*$sock}{'NS_ipv'} = shift if @_; return ${*$sock}{'NS_ipv'} }
  243         548  
  119         1037  
  243         382  
  243         1560  
31 148 100   148 0 298 sub NS_listen { my $sock = shift; ${*$sock}{'NS_listen'} = shift if @_; return ${*$sock}{'NS_listen'} }
  148         477  
  108         611  
  148         305  
  148         335  
32              
33             sub object {
34 108     108 1 303 my ($class, $info, $server) = @_;
35              
36 108         1933 my $sock = $class->new;
37 108         18338 $sock->NS_host($info->{'host'});
38 108         357 $sock->NS_port($info->{'port'});
39 108         383 $sock->NS_ipv( $info->{'ipv'} );
40             $sock->NS_listen(defined($info->{'listen'}) ? $info->{'listen'}
41 108 100       1084 : defined($server->{'server'}->{'listen'}) ? $server->{'server'}->{'listen'}
    100          
42             : SOMAXCONN);
43 108 50       388 ${*$sock}{'NS_orig_port'} = $info->{'orig_port'} if defined $info->{'orig_port'};
  0         0  
44 108         25147 return $sock;
45             }
46              
47             sub log_connect {
48 31     31 1 94 my ($sock, $server) = @_;
49 31         105 $server->log(2, "Binding to ".$sock->NS_proto." port ".$sock->NS_port." on host ".$sock->NS_host." with IPv".$sock->NS_ipv);
50             }
51              
52             sub connect {
53 30     30 1 98 my ($sock, $server) = @_;
54 30         90 my $host = $sock->NS_host;
55 30         102 my $port = $sock->NS_port;
56 30         90 my $ipv = $sock->NS_ipv;
57 30         86 my $lstn = $sock->NS_listen;
58              
59 30 100       1842 $sock->configure({
    100          
    100          
    100          
    100          
    50          
60             LocalPort => $port,
61             Proto => 'tcp',
62             Listen => $lstn,
63             ReuseAddr => 1,
64             Reuse => 1,
65             LocalAddr => ($host eq '*' ? undef : $host), # undef means listen on all interfaces
66             Family => ($ipv eq '6' ? AF_INET6 : $ipv eq '4' ? AF_INET : AF_UNSPEC),
67             ($ipv =~ /[6*]/ ? (V6Only => $ipv eq '*' ? 0 : 1) : ()),
68             }) or $server->fatal("Cannot bind and listen to TCP port $port on $host [$!]");
69              
70 30 50 33     6114 if ($port eq '0' and $port = $sock->sockport) {
    50 33        
71 0         0 $server->log(2, " Bound to auto-assigned port $port");
72 0         0 ${*$sock}{'NS_orig_port'} = $sock->NS_port;
  0         0  
73 0         0 $sock->NS_port($port);
74             } elsif ($port =~ /\D/ and $port = $sock->sockport) {
75 0         0 $server->log(2, " Bound to service port ".$sock->NS_port()."($port)");
76 0         0 ${*$sock}{'NS_orig_port'} = $sock->NS_port;
  0         0  
77 0         0 $sock->NS_port($port);
78             }
79             }
80              
81             sub reconnect { # after a sig HUP
82 0     0 1 0 my ($sock, $fd, $server, $port) = @_;
83 0         0 $server->log(3,"Reassociating file descriptor $fd with ".$sock->NS_proto." on [".$sock->NS_host."]:".$sock->NS_port.", using IPv".$sock->NS_ipv);
84 0 0       0 $sock->fdopen($fd, 'w') or $server->fatal("Error opening to file descriptor ($fd) [$!]");
85              
86 0         0 my $ipv = $sock->NS_ipv;
87 0 0       0 ${*$sock}{'io_socket_domain'} = $ipv eq '6' ? AF_INET6 : $ipv eq '4' ? AF_INET : AF_UNSPEC;
  0 0       0  
88              
89 0 0       0 if ($port ne $sock->NS_port) {
90 0         0 $server->log(2, " Re-bound to previously assigned port $port");
91 0         0 ${*$sock}{'NS_orig_port'} = $sock->NS_port;
  0         0  
92 0         0 $sock->NS_port($port);
93             }
94             }
95              
96             sub accept {
97 26     26 1 89 my ($sock, $class) = (@_);
98 26         75 my ($client, $peername);
99 26 50       126 if (wantarray) {
100 0         0 ($client, $peername) = $sock->SUPER::accept($class);
101             } else {
102 26         385 $client = $sock->SUPER::accept($class);
103             }
104 26 50       162709 if (defined $client) {
105 26         323 $client->NS_port($sock->NS_port);
106             }
107 26 50       621 return wantarray ? ($client, $peername) : $client;
108             }
109              
110             sub poll_cb { # implemented for psgi compatibility - TODO - should poll appropriately for Multipex
111 0     0 1 0 my ($self, $cb) = @_;
112 0         0 return $cb->($self);
113             }
114              
115             ###----------------------------------------------------------------###
116              
117             sub read_until { # only sips the data - but it allows for compatibility with SSLEAY
118 2     2 1 6 my ($client, $bytes, $end_qr) = @_;
119 2 0 33     11 croak "read_until: One of bytes or end_qr should be defined" if !defined($bytes) && !defined($end_qr);
120 2         3 my $content = '';
121 2         2 my $ok = 0;
122 2         4 while (1) {
123 109         232 $client->read($content, 1, length($content));
124 109 50 33     4788 if (defined($bytes) && length($content) >= $bytes) {
    100 66        
125 0         0 $ok = 2;
126 0         0 last;
127             } elsif (defined($end_qr) && $content =~ $end_qr) {
128 2         3 $ok = 1;
129 2         12 last;
130             }
131             }
132 2 50       16 return wantarray ? ($ok, $content) : $content;
133             }
134              
135             ###----------------------------------------------------------------###
136              
137             ### a string containing any information necessary for restarting the server
138             ### via a -HUP signal
139             ### a newline is not allowed
140             ### the hup_string must be a unique identifier based on configuration info
141             sub hup_string {
142 48     48 1 11602 my $sock = shift;
143 48 50       178 return join "|", $sock->NS_host, $sock->NS_port, $sock->NS_proto, 'ipv'.$sock->NS_ipv, (defined(${*$sock}{'NS_orig_port'}) ? ${*$sock}{'NS_orig_port'} : ());
  48         345  
  0            
144             }
145              
146             sub show {
147 0     0 1   my $sock = shift;
148 0           return "Ref = \"".ref($sock). "\" (".$sock->hup_string.")\n";
149             }
150              
151             1;
152              
153             __END__