line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# You may distribute under the terms of either the GNU General Public License |
2
|
|
|
|
|
|
|
# or the Artistic License (the same terms as Perl itself) |
3
|
|
|
|
|
|
|
# |
4
|
|
|
|
|
|
|
# (C) Paul Evans, 2010-2023 -- leonerd@leonerd.org.uk |
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
package IO::Socket::IP 0.42; |
7
|
|
|
|
|
|
|
|
8
|
22
|
|
|
22
|
|
1194396
|
use v5.14; |
|
22
|
|
|
|
|
246
|
|
9
|
22
|
|
|
22
|
|
98
|
use warnings; |
|
22
|
|
|
|
|
33
|
|
|
22
|
|
|
|
|
559
|
|
10
|
|
|
|
|
|
|
|
11
|
22
|
|
|
22
|
|
95
|
use base qw( IO::Socket ); |
|
22
|
|
|
|
|
33
|
|
|
22
|
|
|
|
|
10287
|
|
12
|
|
|
|
|
|
|
|
13
|
22
|
|
|
22
|
|
367471
|
use Carp; |
|
22
|
|
|
|
|
44
|
|
|
22
|
|
|
|
|
1248
|
|
14
|
|
|
|
|
|
|
|
15
|
22
|
|
|
|
|
4729
|
use Socket 1.97 qw( |
16
|
|
|
|
|
|
|
getaddrinfo getnameinfo |
17
|
|
|
|
|
|
|
sockaddr_family |
18
|
|
|
|
|
|
|
AF_INET |
19
|
|
|
|
|
|
|
AI_PASSIVE |
20
|
|
|
|
|
|
|
IPPROTO_TCP IPPROTO_UDP |
21
|
|
|
|
|
|
|
IPPROTO_IPV6 IPV6_V6ONLY |
22
|
|
|
|
|
|
|
NI_DGRAM NI_NUMERICHOST NI_NUMERICSERV NIx_NOHOST NIx_NOSERV |
23
|
|
|
|
|
|
|
SO_REUSEADDR SO_REUSEPORT SO_BROADCAST SO_ERROR |
24
|
|
|
|
|
|
|
SOCK_DGRAM SOCK_STREAM |
25
|
|
|
|
|
|
|
SOL_SOCKET |
26
|
22
|
|
|
22
|
|
110
|
); |
|
22
|
|
|
|
|
323
|
|
27
|
|
|
|
|
|
|
my $AF_INET6 = eval { Socket::AF_INET6() }; # may not be defined |
28
|
|
|
|
|
|
|
my $AI_ADDRCONFIG = eval { Socket::AI_ADDRCONFIG() } || 0; |
29
|
22
|
|
|
22
|
|
9267
|
use POSIX qw( dup2 ); |
|
22
|
|
|
|
|
116048
|
|
|
22
|
|
|
|
|
97
|
|
30
|
22
|
|
|
22
|
|
26394
|
use Errno qw( EINVAL EINPROGRESS EISCONN ENOTCONN ETIMEDOUT EWOULDBLOCK EOPNOTSUPP ); |
|
22
|
|
|
|
|
40
|
|
|
22
|
|
|
|
|
2593
|
|
31
|
|
|
|
|
|
|
|
32
|
22
|
|
|
22
|
|
137
|
use constant HAVE_MSWIN32 => ( $^O eq "MSWin32" ); |
|
22
|
|
|
|
|
33
|
|
|
22
|
|
|
|
|
2176
|
|
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# At least one OS (Android) is known not to have getprotobyname() |
35
|
22
|
|
|
22
|
|
122
|
use constant HAVE_GETPROTOBYNAME => defined eval { getprotobyname( "tcp" ) }; |
|
22
|
|
|
|
|
40
|
|
|
22
|
|
|
|
|
32
|
|
|
22
|
|
|
|
|
81315
|
|
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
my $IPv6_re = do { |
38
|
|
|
|
|
|
|
# translation of RFC 3986 3.2.2 ABNF to re |
39
|
|
|
|
|
|
|
my $IPv4address = do { |
40
|
|
|
|
|
|
|
my $dec_octet = q<(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])>; |
41
|
|
|
|
|
|
|
qq<$dec_octet(?: \\. $dec_octet){3}>; |
42
|
|
|
|
|
|
|
}; |
43
|
|
|
|
|
|
|
my $IPv6address = do { |
44
|
|
|
|
|
|
|
my $h16 = qq<[0-9A-Fa-f]{1,4}>; |
45
|
|
|
|
|
|
|
my $ls32 = qq<(?: $h16 : $h16 | $IPv4address)>; |
46
|
|
|
|
|
|
|
qq<(?: |
47
|
|
|
|
|
|
|
(?: $h16 : ){6} $ls32 |
48
|
|
|
|
|
|
|
| :: (?: $h16 : ){5} $ls32 |
49
|
|
|
|
|
|
|
| (?: $h16 )? :: (?: $h16 : ){4} $ls32 |
50
|
|
|
|
|
|
|
| (?: (?: $h16 : ){0,1} $h16 )? :: (?: $h16 : ){3} $ls32 |
51
|
|
|
|
|
|
|
| (?: (?: $h16 : ){0,2} $h16 )? :: (?: $h16 : ){2} $ls32 |
52
|
|
|
|
|
|
|
| (?: (?: $h16 : ){0,3} $h16 )? :: $h16 : $ls32 |
53
|
|
|
|
|
|
|
| (?: (?: $h16 : ){0,4} $h16 )? :: $ls32 |
54
|
|
|
|
|
|
|
| (?: (?: $h16 : ){0,5} $h16 )? :: $h16 |
55
|
|
|
|
|
|
|
| (?: (?: $h16 : ){0,6} $h16 )? :: |
56
|
|
|
|
|
|
|
)> |
57
|
|
|
|
|
|
|
}; |
58
|
|
|
|
|
|
|
qr<$IPv6address>xo; |
59
|
|
|
|
|
|
|
}; |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
=head1 NAME |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
C - Family-neutral IP socket supporting both IPv4 and IPv6 |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
=head1 SYNOPSIS |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
use IO::Socket::IP; |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
my $sock = IO::Socket::IP->new( |
70
|
|
|
|
|
|
|
PeerHost => "www.google.com", |
71
|
|
|
|
|
|
|
PeerPort => "http", |
72
|
|
|
|
|
|
|
Type => SOCK_STREAM, |
73
|
|
|
|
|
|
|
) or die "Cannot construct socket - $IO::Socket::errstr"; |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
my $familyname = ( $sock->sockdomain == PF_INET6 ) ? "IPv6" : |
76
|
|
|
|
|
|
|
( $sock->sockdomain == PF_INET ) ? "IPv4" : |
77
|
|
|
|
|
|
|
"unknown"; |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
printf "Connected to google via %s\n", $familyname; |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
=head1 DESCRIPTION |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
This module provides a protocol-independent way to use IPv4 and IPv6 sockets, |
84
|
|
|
|
|
|
|
intended as a replacement for L. Most constructor arguments |
85
|
|
|
|
|
|
|
and methods are provided in a backward-compatible way. For a list of known |
86
|
|
|
|
|
|
|
differences, see the C INCOMPATIBILITES section below. |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
It uses the C function to convert hostnames and service names |
89
|
|
|
|
|
|
|
or port numbers into sets of possible addresses to connect to or listen on. |
90
|
|
|
|
|
|
|
This allows it to work for IPv6 where the system supports it, while still |
91
|
|
|
|
|
|
|
falling back to IPv4-only on systems which don't. |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
=head1 REPLACING C DEFAULT BEHAVIOUR |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
By placing C<-register> in the import list to C, it will |
96
|
|
|
|
|
|
|
register itself with L as the class that handles C. It |
97
|
|
|
|
|
|
|
will also ask to handle C as well, provided that constant is |
98
|
|
|
|
|
|
|
available. |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
Changing C's default behaviour means that calling the |
101
|
|
|
|
|
|
|
C constructor with either C or C as the |
102
|
|
|
|
|
|
|
C parameter will yield an C object. |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
use IO::Socket::IP -register; |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
my $sock = IO::Socket->new( |
107
|
|
|
|
|
|
|
Domain => PF_INET6, |
108
|
|
|
|
|
|
|
LocalHost => "::1", |
109
|
|
|
|
|
|
|
Listen => 1, |
110
|
|
|
|
|
|
|
) or die "Cannot create socket - $IO::Socket::errstr\n"; |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
print "Created a socket of type " . ref($sock) . "\n"; |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
Note that C<-register> is a global setting that applies to the entire program; |
115
|
|
|
|
|
|
|
it cannot be applied only for certain callers, removed, or limited by lexical |
116
|
|
|
|
|
|
|
scope. |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
=cut |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
sub import |
121
|
|
|
|
|
|
|
{ |
122
|
22
|
|
|
22
|
|
163
|
my $pkg = shift; |
123
|
22
|
|
|
|
|
40
|
my @symbols; |
124
|
|
|
|
|
|
|
|
125
|
22
|
|
|
|
|
49
|
foreach ( @_ ) { |
126
|
1
|
50
|
|
|
|
4
|
if( $_ eq "-register" ) { |
127
|
1
|
|
|
|
|
8
|
IO::Socket::IP::_ForINET->register_domain( AF_INET ); |
128
|
1
|
50
|
|
|
|
10
|
IO::Socket::IP::_ForINET6->register_domain( $AF_INET6 ) if defined $AF_INET6; |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
else { |
131
|
0
|
|
|
|
|
0
|
push @symbols, $_; |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
|
135
|
22
|
|
|
|
|
58
|
@_ = ( $pkg, @symbols ); |
136
|
22
|
|
|
|
|
117
|
goto &IO::Socket::import; |
137
|
|
|
|
|
|
|
} |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
# Convenient capability test function |
140
|
|
|
|
|
|
|
{ |
141
|
|
|
|
|
|
|
my $can_disable_v6only; |
142
|
|
|
|
|
|
|
sub CAN_DISABLE_V6ONLY |
143
|
|
|
|
|
|
|
{ |
144
|
0
|
0
|
|
0
|
0
|
0
|
return $can_disable_v6only if defined $can_disable_v6only; |
145
|
|
|
|
|
|
|
|
146
|
0
|
0
|
|
|
|
0
|
socket my $testsock, Socket::PF_INET6(), SOCK_STREAM, 0 or |
147
|
|
|
|
|
|
|
die "Cannot socket(PF_INET6) - $!"; |
148
|
|
|
|
|
|
|
|
149
|
0
|
0
|
0
|
|
|
0
|
if( setsockopt $testsock, IPPROTO_IPV6, IPV6_V6ONLY, 0 ) { |
|
|
0
|
|
|
|
|
|
150
|
0
|
0
|
|
|
|
0
|
if( $^O eq "dragonfly") { |
151
|
|
|
|
|
|
|
# dragonflybsd 6.4 lies about successfully turning this off |
152
|
0
|
0
|
|
|
|
0
|
if( getsockopt $testsock, IPPROTO_IPV6, IPV6_V6ONLY ) { |
153
|
0
|
|
|
|
|
0
|
return $can_disable_v6only = 0; |
154
|
|
|
|
|
|
|
} |
155
|
|
|
|
|
|
|
} |
156
|
0
|
|
|
|
|
0
|
return $can_disable_v6only = 1; |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
elsif( $! == EINVAL || $! == EOPNOTSUPP ) { |
159
|
0
|
|
|
|
|
0
|
return $can_disable_v6only = 0; |
160
|
|
|
|
|
|
|
} |
161
|
|
|
|
|
|
|
else { |
162
|
0
|
|
|
|
|
0
|
die "Cannot setsockopt() - $!"; |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
=head1 CONSTRUCTORS |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
=cut |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
=head2 new |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
$sock = IO::Socket::IP->new( %args ) |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
Creates a new C object, containing a newly created socket |
176
|
|
|
|
|
|
|
handle according to the named arguments passed. The recognised arguments are: |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
=over 8 |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
=item PeerHost => STRING |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
=item PeerService => STRING |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
Hostname and service name for the peer to C to. The service name |
185
|
|
|
|
|
|
|
may be given as a port number, as a decimal string. |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
=item PeerAddr => STRING |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
=item PeerPort => STRING |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
For symmetry with the accessor methods and compatibility with |
192
|
|
|
|
|
|
|
C, these are accepted as synonyms for C and |
193
|
|
|
|
|
|
|
C respectively. |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=item PeerAddrInfo => ARRAY |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
Alternate form of specifying the peer to C to. This should be an |
198
|
|
|
|
|
|
|
array of the form returned by C. |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
This parameter takes precedence over the C, C, C and |
201
|
|
|
|
|
|
|
C arguments. |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=item LocalHost => STRING |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
=item LocalService => STRING |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
Hostname and service name for the local address to C to. |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
=item LocalAddr => STRING |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
=item LocalPort => STRING |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
For symmetry with the accessor methods and compatibility with |
214
|
|
|
|
|
|
|
C, these are accepted as synonyms for C and |
215
|
|
|
|
|
|
|
C respectively. |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
=item LocalAddrInfo => ARRAY |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
Alternate form of specifying the local address to C to. This should be |
220
|
|
|
|
|
|
|
an array of the form returned by C. |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
This parameter takes precedence over the C, C, C and |
223
|
|
|
|
|
|
|
C arguments. |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
=item Family => INT |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
The address family to pass to C (e.g. C, C). |
228
|
|
|
|
|
|
|
Normally this will be left undefined, and C will search using any |
229
|
|
|
|
|
|
|
address family supported by the system. |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
=item Type => INT |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
The socket type to pass to C (e.g. C, |
234
|
|
|
|
|
|
|
C). Normally defined by the caller; if left undefined |
235
|
|
|
|
|
|
|
C may attempt to infer the type from the service name. |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
=item Proto => STRING or INT |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
The IP protocol to use for the socket (e.g. C<'tcp'>, C, |
240
|
|
|
|
|
|
|
C<'udp'>,C). Normally this will be left undefined, and either |
241
|
|
|
|
|
|
|
C or the kernel will choose an appropriate value. May be given |
242
|
|
|
|
|
|
|
either in string name or numeric form. |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
=item GetAddrInfoFlags => INT |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
More flags to pass to the C function. If not supplied, a |
247
|
|
|
|
|
|
|
default of C will be used. |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
These flags will be combined with C if the C argument is |
250
|
|
|
|
|
|
|
given. For more information see the documentation about C in |
251
|
|
|
|
|
|
|
the L module. |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
=item Listen => INT |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
If defined, puts the socket into listening mode where new connections can be |
256
|
|
|
|
|
|
|
accepted using the C method. The value given is used as the |
257
|
|
|
|
|
|
|
C queue size. |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
=item ReuseAddr => BOOL |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
If true, set the C sockopt |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
=item ReusePort => BOOL |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
If true, set the C sockopt (not all OSes implement this sockopt) |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
=item Broadcast => BOOL |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
If true, set the C sockopt |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
=item Sockopts => ARRAY |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
An optional array of other socket options to apply after the three listed |
274
|
|
|
|
|
|
|
above. The value is an ARRAY containing 2- or 3-element ARRAYrefs. Each inner |
275
|
|
|
|
|
|
|
array relates to a single option, giving the level and option name, and an |
276
|
|
|
|
|
|
|
optional value. If the value element is missing, it will be given the value of |
277
|
|
|
|
|
|
|
a platform-sized integer 1 constant (i.e. suitable to enable most of the |
278
|
|
|
|
|
|
|
common boolean options). |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
For example, both options given below are equivalent to setting C. |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
Sockopts => [ |
283
|
|
|
|
|
|
|
[ SOL_SOCKET, SO_REUSEADDR ], |
284
|
|
|
|
|
|
|
[ SOL_SOCKET, SO_REUSEADDR, pack( "i", 1 ) ], |
285
|
|
|
|
|
|
|
] |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
=item V6Only => BOOL |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
If defined, set the C sockopt when creating C sockets |
290
|
|
|
|
|
|
|
to the given value. If true, a listening-mode socket will only listen on the |
291
|
|
|
|
|
|
|
C addresses; if false it will also accept connections from |
292
|
|
|
|
|
|
|
C addresses. |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
If not defined, the socket option will not be changed, and default value set |
295
|
|
|
|
|
|
|
by the operating system will apply. For repeatable behaviour across platforms |
296
|
|
|
|
|
|
|
it is recommended this value always be defined for listening-mode sockets. |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
Note that not all platforms support disabling this option. Some, at least |
299
|
|
|
|
|
|
|
OpenBSD and MirBSD, will fail with C if you attempt to disable it. |
300
|
|
|
|
|
|
|
To determine whether it is possible to disable, you may use the class method |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
if( IO::Socket::IP->CAN_DISABLE_V6ONLY ) { |
303
|
|
|
|
|
|
|
... |
304
|
|
|
|
|
|
|
} |
305
|
|
|
|
|
|
|
else { |
306
|
|
|
|
|
|
|
... |
307
|
|
|
|
|
|
|
} |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
If your platform does not support disabling this option but you still want to |
310
|
|
|
|
|
|
|
listen for both C and C connections you will have to create |
311
|
|
|
|
|
|
|
two listening sockets, one bound to each protocol. |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
=item MultiHomed |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
This C-style argument is ignored, except if it is defined |
316
|
|
|
|
|
|
|
but false. See the C INCOMPATIBILITES section below. |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
However, the behaviour it enables is always performed by C. |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
=item Blocking => BOOL |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
If defined but false, the socket will be set to non-blocking mode. Otherwise |
323
|
|
|
|
|
|
|
it will default to blocking mode. See the NON-BLOCKING section below for more |
324
|
|
|
|
|
|
|
detail. |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
=item Timeout => NUM |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
If defined, gives a maximum time in seconds to block per C call |
329
|
|
|
|
|
|
|
when in blocking mode. If missing, no timeout is applied other than that |
330
|
|
|
|
|
|
|
provided by the underlying operating system. When in non-blocking mode this |
331
|
|
|
|
|
|
|
parameter is ignored. |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
Note that if the hostname resolves to multiple address candidates, the same |
334
|
|
|
|
|
|
|
timeout will apply to each connection attempt individually, rather than to the |
335
|
|
|
|
|
|
|
operation as a whole. Further note that the timeout does not apply to the |
336
|
|
|
|
|
|
|
initial hostname resolve operation, if connecting by hostname. |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
This behaviour is copied inspired by C; for more fine |
339
|
|
|
|
|
|
|
grained control over connection timeouts, consider performing a nonblocking |
340
|
|
|
|
|
|
|
connect directly. |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
=back |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
If neither C nor C hints are provided, a default of |
345
|
|
|
|
|
|
|
C and C respectively will be set, to maintain |
346
|
|
|
|
|
|
|
compatibility with C. Other named arguments that are not |
347
|
|
|
|
|
|
|
recognised are ignored. |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
If neither C nor any hosts or addresses are passed, nor any |
350
|
|
|
|
|
|
|
C<*AddrInfo>, then the constructor has no information on which to decide a |
351
|
|
|
|
|
|
|
socket family to create. In this case, it performs a C call with |
352
|
|
|
|
|
|
|
the C flag, no host name, and a service name of C<"0">, and |
353
|
|
|
|
|
|
|
uses the family of the first returned result. |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
If the constructor fails, it will set C<$IO::Socket::errstr> and C<$@> to |
356
|
|
|
|
|
|
|
an appropriate error message; this may be from C<$!> or it may be some other |
357
|
|
|
|
|
|
|
string; not every failure necessarily has an associated C value. |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
=head2 new (one arg) |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
$sock = IO::Socket::IP->new( $peeraddr ) |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
As a special case, if the constructor is passed a single argument (as |
364
|
|
|
|
|
|
|
opposed to an even-sized list of key/value pairs), it is taken to be the value |
365
|
|
|
|
|
|
|
of the C parameter. This is parsed in the same way, according to the |
366
|
|
|
|
|
|
|
behaviour given in the C AND C PARSING section below. |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
=cut |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
sub new |
371
|
|
|
|
|
|
|
{ |
372
|
56
|
|
|
56
|
1
|
79248
|
my $class = shift; |
373
|
56
|
100
|
|
|
|
277
|
my %arg = (@_ == 1) ? (PeerHost => $_[0]) : @_; |
374
|
56
|
|
|
|
|
307
|
return $class->SUPER::new(%arg); |
375
|
|
|
|
|
|
|
} |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
# IO::Socket may call this one; neaten up the arguments from IO::Socket::INET |
378
|
|
|
|
|
|
|
# before calling our real _configure method |
379
|
|
|
|
|
|
|
sub configure |
380
|
|
|
|
|
|
|
{ |
381
|
51
|
|
|
51
|
0
|
3523
|
my $self = shift; |
382
|
51
|
|
|
|
|
85
|
my ( $arg ) = @_; |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
$arg->{PeerHost} = delete $arg->{PeerAddr} |
385
|
51
|
50
|
33
|
|
|
160
|
if exists $arg->{PeerAddr} && !exists $arg->{PeerHost}; |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
$arg->{PeerService} = delete $arg->{PeerPort} |
388
|
51
|
100
|
66
|
|
|
155
|
if exists $arg->{PeerPort} && !exists $arg->{PeerService}; |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
$arg->{LocalHost} = delete $arg->{LocalAddr} |
391
|
51
|
50
|
33
|
|
|
143
|
if exists $arg->{LocalAddr} && !exists $arg->{LocalHost}; |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
$arg->{LocalService} = delete $arg->{LocalPort} |
394
|
51
|
100
|
66
|
|
|
163
|
if exists $arg->{LocalPort} && !exists $arg->{LocalService}; |
395
|
|
|
|
|
|
|
|
396
|
51
|
|
|
|
|
101
|
for my $type (qw(Peer Local)) { |
397
|
102
|
|
|
|
|
181
|
my $host = $type . 'Host'; |
398
|
102
|
|
|
|
|
173
|
my $service = $type . 'Service'; |
399
|
|
|
|
|
|
|
|
400
|
102
|
100
|
|
|
|
229
|
if( defined $arg->{$host} ) { |
401
|
43
|
|
|
|
|
115
|
( $arg->{$host}, my $s ) = $self->split_addr( $arg->{$host} ); |
402
|
|
|
|
|
|
|
# IO::Socket::INET compat - *Host parsed port always takes precedence |
403
|
43
|
100
|
|
|
|
137
|
$arg->{$service} = $s if defined $s; |
404
|
|
|
|
|
|
|
} |
405
|
|
|
|
|
|
|
} |
406
|
|
|
|
|
|
|
|
407
|
51
|
|
|
|
|
148
|
$self->_io_socket_ip__configure( $arg ); |
408
|
|
|
|
|
|
|
} |
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
# Avoid simply calling it _configure, as some subclasses of IO::Socket::INET on CPAN already take that |
411
|
|
|
|
|
|
|
sub _io_socket_ip__configure |
412
|
|
|
|
|
|
|
{ |
413
|
35
|
|
|
35
|
|
70
|
my $self = shift; |
414
|
35
|
|
|
|
|
65
|
my ( $arg ) = @_; |
415
|
|
|
|
|
|
|
|
416
|
35
|
|
|
|
|
77
|
my %hints; |
417
|
|
|
|
|
|
|
my @localinfos; |
418
|
35
|
|
|
|
|
0
|
my @peerinfos; |
419
|
|
|
|
|
|
|
|
420
|
35
|
|
|
|
|
58
|
my $listenqueue = $arg->{Listen}; |
421
|
35
|
50
|
33
|
|
|
151
|
if( defined $listenqueue and |
|
|
|
66
|
|
|
|
|
422
|
|
|
|
|
|
|
( defined $arg->{PeerHost} || defined $arg->{PeerService} || defined $arg->{PeerAddrInfo} ) ) { |
423
|
0
|
|
|
|
|
0
|
croak "Cannot Listen with a peer address"; |
424
|
|
|
|
|
|
|
} |
425
|
|
|
|
|
|
|
|
426
|
35
|
100
|
|
|
|
86
|
if( defined $arg->{GetAddrInfoFlags} ) { |
427
|
2
|
|
|
|
|
6
|
$hints{flags} = $arg->{GetAddrInfoFlags}; |
428
|
|
|
|
|
|
|
} |
429
|
|
|
|
|
|
|
else { |
430
|
33
|
|
|
|
|
60
|
$hints{flags} = $AI_ADDRCONFIG; |
431
|
|
|
|
|
|
|
} |
432
|
|
|
|
|
|
|
|
433
|
35
|
100
|
|
|
|
89
|
if( defined( my $family = $arg->{Family} ) ) { |
434
|
3
|
|
|
|
|
6
|
$hints{family} = $family; |
435
|
|
|
|
|
|
|
} |
436
|
|
|
|
|
|
|
|
437
|
35
|
100
|
|
|
|
78
|
if( defined( my $type = $arg->{Type} ) ) { |
438
|
19
|
|
|
|
|
46
|
$hints{socktype} = $type; |
439
|
|
|
|
|
|
|
} |
440
|
|
|
|
|
|
|
|
441
|
35
|
50
|
|
|
|
84
|
if( defined( my $proto = $arg->{Proto} ) ) { |
442
|
0
|
0
|
|
|
|
0
|
unless( $proto =~ m/^\d+$/ ) { |
443
|
|
|
|
|
|
|
my $protonum = HAVE_GETPROTOBYNAME |
444
|
|
|
|
|
|
|
? getprotobyname( $proto ) |
445
|
0
|
|
|
|
|
0
|
: eval { Socket->${\"IPPROTO_\U$proto"}() }; |
446
|
0
|
0
|
|
|
|
0
|
defined $protonum or croak "Unrecognised protocol $proto"; |
447
|
0
|
|
|
|
|
0
|
$proto = $protonum; |
448
|
|
|
|
|
|
|
} |
449
|
|
|
|
|
|
|
|
450
|
0
|
|
|
|
|
0
|
$hints{protocol} = $proto; |
451
|
|
|
|
|
|
|
} |
452
|
|
|
|
|
|
|
|
453
|
|
|
|
|
|
|
# To maintain compatibility with IO::Socket::INET, imply a default of |
454
|
|
|
|
|
|
|
# SOCK_STREAM + IPPROTO_TCP if neither hint is given |
455
|
35
|
50
|
66
|
|
|
132
|
if( !defined $hints{socktype} and !defined $hints{protocol} ) { |
456
|
16
|
|
|
|
|
28
|
$hints{socktype} = SOCK_STREAM; |
457
|
16
|
|
|
|
|
26
|
$hints{protocol} = IPPROTO_TCP; |
458
|
|
|
|
|
|
|
} |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
# Some OSes (NetBSD) don't seem to like just a protocol hint without a |
461
|
|
|
|
|
|
|
# socktype hint as well. We'll set a couple of common ones |
462
|
35
|
50
|
33
|
|
|
128
|
if( !defined $hints{socktype} and defined $hints{protocol} ) { |
463
|
0
|
0
|
|
|
|
0
|
$hints{socktype} = SOCK_STREAM if $hints{protocol} == IPPROTO_TCP; |
464
|
0
|
0
|
|
|
|
0
|
$hints{socktype} = SOCK_DGRAM if $hints{protocol} == IPPROTO_UDP; |
465
|
|
|
|
|
|
|
} |
466
|
|
|
|
|
|
|
|
467
|
35
|
100
|
100
|
|
|
209
|
if( my $info = $arg->{LocalAddrInfo} ) { |
|
|
100
|
100
|
|
|
|
|
468
|
1
|
50
|
|
|
|
5
|
ref $info eq "ARRAY" or croak "Expected 'LocalAddrInfo' to be an ARRAY ref"; |
469
|
1
|
|
|
|
|
3
|
@localinfos = @$info; |
470
|
|
|
|
|
|
|
} |
471
|
|
|
|
|
|
|
elsif( defined $arg->{LocalHost} or |
472
|
|
|
|
|
|
|
defined $arg->{LocalService} or |
473
|
|
|
|
|
|
|
HAVE_MSWIN32 and $arg->{Listen} ) { |
474
|
|
|
|
|
|
|
# Either may be undef |
475
|
21
|
|
|
|
|
55
|
my $host = $arg->{LocalHost}; |
476
|
21
|
|
|
|
|
29
|
my $service = $arg->{LocalService}; |
477
|
|
|
|
|
|
|
|
478
|
21
|
50
|
66
|
|
|
79
|
unless ( defined $host or defined $service ) { |
479
|
0
|
|
|
|
|
0
|
$service = 0; |
480
|
|
|
|
|
|
|
} |
481
|
|
|
|
|
|
|
|
482
|
21
|
|
|
|
|
67
|
local $1; # Placate a taint-related bug; [perl #67962] |
483
|
21
|
100
|
100
|
|
|
132
|
defined $service and $service =~ s/\((\d+)\)$// and |
484
|
|
|
|
|
|
|
my $fallback_port = $1; |
485
|
|
|
|
|
|
|
|
486
|
21
|
|
|
|
|
99
|
my %localhints = %hints; |
487
|
21
|
|
|
|
|
53
|
$localhints{flags} |= AI_PASSIVE; |
488
|
21
|
|
|
|
|
1642
|
( my $err, @localinfos ) = getaddrinfo( $host, $service, \%localhints ); |
489
|
|
|
|
|
|
|
|
490
|
21
|
100
|
100
|
|
|
130
|
if( $err and defined $fallback_port ) { |
491
|
1
|
|
|
|
|
9
|
( $err, @localinfos ) = getaddrinfo( $host, $fallback_port, \%localhints ); |
492
|
|
|
|
|
|
|
} |
493
|
|
|
|
|
|
|
|
494
|
21
|
100
|
|
|
|
86
|
if( $err ) { |
495
|
5
|
|
|
|
|
14
|
$IO::Socket::errstr = $@ = "$err"; |
496
|
5
|
|
|
|
|
14
|
$! = EINVAL; |
497
|
5
|
|
|
|
|
74
|
return; |
498
|
|
|
|
|
|
|
} |
499
|
|
|
|
|
|
|
} |
500
|
|
|
|
|
|
|
|
501
|
30
|
100
|
66
|
|
|
208
|
if( my $info = $arg->{PeerAddrInfo} ) { |
|
|
100
|
|
|
|
|
|
502
|
1
|
50
|
|
|
|
7
|
ref $info eq "ARRAY" or croak "Expected 'PeerAddrInfo' to be an ARRAY ref"; |
503
|
1
|
|
|
|
|
3
|
@peerinfos = @$info; |
504
|
|
|
|
|
|
|
} |
505
|
|
|
|
|
|
|
elsif( defined $arg->{PeerHost} or defined $arg->{PeerService} ) { |
506
|
10
|
50
|
|
|
|
34
|
defined( my $host = $arg->{PeerHost} ) or |
507
|
|
|
|
|
|
|
croak "Expected 'PeerHost'"; |
508
|
10
|
50
|
|
|
|
26
|
defined( my $service = $arg->{PeerService} ) or |
509
|
|
|
|
|
|
|
croak "Expected 'PeerService'"; |
510
|
|
|
|
|
|
|
|
511
|
10
|
|
|
|
|
23
|
local $1; # Placate a taint-related bug; [perl #67962] |
512
|
10
|
50
|
33
|
|
|
74
|
defined $service and $service =~ s/\((\d+)\)$// and |
513
|
|
|
|
|
|
|
my $fallback_port = $1; |
514
|
|
|
|
|
|
|
|
515
|
10
|
|
|
|
|
3646
|
( my $err, @peerinfos ) = getaddrinfo( $host, $service, \%hints ); |
516
|
|
|
|
|
|
|
|
517
|
10
|
50
|
33
|
|
|
69
|
if( $err and defined $fallback_port ) { |
518
|
0
|
|
|
|
|
0
|
( $err, @peerinfos ) = getaddrinfo( $host, $fallback_port, \%hints ); |
519
|
|
|
|
|
|
|
} |
520
|
|
|
|
|
|
|
|
521
|
10
|
50
|
|
|
|
40
|
if( $err ) { |
522
|
0
|
|
|
|
|
0
|
$IO::Socket::errstr = $@ = "$err"; |
523
|
0
|
|
|
|
|
0
|
$! = EINVAL; |
524
|
0
|
|
|
|
|
0
|
return; |
525
|
|
|
|
|
|
|
} |
526
|
|
|
|
|
|
|
} |
527
|
|
|
|
|
|
|
|
528
|
30
|
|
|
|
|
67
|
my $INT_1 = pack "i", 1; |
529
|
|
|
|
|
|
|
|
530
|
30
|
|
|
|
|
43
|
my @sockopts_enabled; |
531
|
30
|
100
|
|
|
|
75
|
push @sockopts_enabled, [ SOL_SOCKET, SO_REUSEADDR, $INT_1 ] if $arg->{ReuseAddr}; |
532
|
30
|
100
|
|
|
|
77
|
push @sockopts_enabled, [ SOL_SOCKET, SO_REUSEPORT, $INT_1 ] if $arg->{ReusePort}; |
533
|
30
|
100
|
|
|
|
77
|
push @sockopts_enabled, [ SOL_SOCKET, SO_BROADCAST, $INT_1 ] if $arg->{Broadcast}; |
534
|
|
|
|
|
|
|
|
535
|
30
|
100
|
|
|
|
87
|
if( my $sockopts = $arg->{Sockopts} ) { |
536
|
1
|
50
|
|
|
|
4
|
ref $sockopts eq "ARRAY" or croak "Expected 'Sockopts' to be an ARRAY ref"; |
537
|
1
|
|
|
|
|
2
|
foreach ( @$sockopts ) { |
538
|
1
|
50
|
|
|
|
4
|
ref $_ eq "ARRAY" or croak "Bad Sockopts item - expected ARRAYref"; |
539
|
1
|
50
|
33
|
|
|
5
|
@$_ >= 2 and @$_ <= 3 or |
540
|
|
|
|
|
|
|
croak "Bad Sockopts item - expected 2 or 3 elements"; |
541
|
|
|
|
|
|
|
|
542
|
1
|
|
|
|
|
3
|
my ( $level, $optname, $value ) = @$_; |
543
|
|
|
|
|
|
|
# TODO: consider more sanity checking on argument values |
544
|
|
|
|
|
|
|
|
545
|
1
|
50
|
|
|
|
3
|
defined $value or $value = $INT_1; |
546
|
1
|
|
|
|
|
3
|
push @sockopts_enabled, [ $level, $optname, $value ]; |
547
|
|
|
|
|
|
|
} |
548
|
|
|
|
|
|
|
} |
549
|
|
|
|
|
|
|
|
550
|
30
|
|
|
|
|
77
|
my $blocking = $arg->{Blocking}; |
551
|
30
|
100
|
|
|
|
99
|
defined $blocking or $blocking = 1; |
552
|
|
|
|
|
|
|
|
553
|
30
|
|
|
|
|
47
|
my $v6only = $arg->{V6Only}; |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
# IO::Socket::INET defines this key. IO::Socket::IP always implements the |
556
|
|
|
|
|
|
|
# behaviour it requests, so we can ignore it, unless the caller is for some |
557
|
|
|
|
|
|
|
# reason asking to disable it. |
558
|
30
|
50
|
33
|
|
|
90
|
if( defined $arg->{MultiHomed} and !$arg->{MultiHomed} ) { |
559
|
0
|
|
|
|
|
0
|
croak "Cannot disable the MultiHomed parameter"; |
560
|
|
|
|
|
|
|
} |
561
|
|
|
|
|
|
|
|
562
|
30
|
|
|
|
|
43
|
my @infos; |
563
|
30
|
100
|
|
|
|
100
|
foreach my $local ( @localinfos ? @localinfos : {} ) { |
564
|
30
|
100
|
|
|
|
154
|
foreach my $peer ( @peerinfos ? @peerinfos : {} ) { |
565
|
|
|
|
|
|
|
next if defined $local->{family} and defined $peer->{family} and |
566
|
30
|
50
|
66
|
|
|
162
|
$local->{family} != $peer->{family}; |
|
|
|
33
|
|
|
|
|
567
|
|
|
|
|
|
|
next if defined $local->{socktype} and defined $peer->{socktype} and |
568
|
30
|
50
|
66
|
|
|
157
|
$local->{socktype} != $peer->{socktype}; |
|
|
|
33
|
|
|
|
|
569
|
|
|
|
|
|
|
next if defined $local->{protocol} and defined $peer->{protocol} and |
570
|
30
|
50
|
66
|
|
|
123
|
$local->{protocol} != $peer->{protocol}; |
|
|
|
33
|
|
|
|
|
571
|
|
|
|
|
|
|
|
572
|
30
|
100
|
100
|
|
|
147
|
my $family = $local->{family} || $peer->{family} or next; |
573
|
28
|
50
|
66
|
|
|
135
|
my $socktype = $local->{socktype} || $peer->{socktype} or next; |
574
|
28
|
|
50
|
|
|
111
|
my $protocol = $local->{protocol} || $peer->{protocol} || 0; |
575
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
push @infos, { |
577
|
|
|
|
|
|
|
family => $family, |
578
|
|
|
|
|
|
|
socktype => $socktype, |
579
|
|
|
|
|
|
|
protocol => $protocol, |
580
|
|
|
|
|
|
|
localaddr => $local->{addr}, |
581
|
|
|
|
|
|
|
peeraddr => $peer->{addr}, |
582
|
28
|
|
|
|
|
184
|
}; |
583
|
|
|
|
|
|
|
} |
584
|
|
|
|
|
|
|
} |
585
|
|
|
|
|
|
|
|
586
|
30
|
100
|
|
|
|
82
|
if( !@infos ) { |
587
|
|
|
|
|
|
|
# If there was a Family hint then create a plain unbound, unconnected socket |
588
|
2
|
100
|
|
|
|
5
|
if( defined $hints{family} ) { |
589
|
|
|
|
|
|
|
@infos = ( { |
590
|
|
|
|
|
|
|
family => $hints{family}, |
591
|
|
|
|
|
|
|
socktype => $hints{socktype}, |
592
|
|
|
|
|
|
|
protocol => $hints{protocol}, |
593
|
1
|
|
|
|
|
5
|
} ); |
594
|
|
|
|
|
|
|
} |
595
|
|
|
|
|
|
|
# If there wasn't, use getaddrinfo()'s AI_ADDRCONFIG side-effect to guess a |
596
|
|
|
|
|
|
|
# suitable family first. |
597
|
|
|
|
|
|
|
else { |
598
|
1
|
|
|
|
|
97
|
( my $err, @infos ) = getaddrinfo( "", "0", \%hints ); |
599
|
1
|
50
|
|
|
|
5
|
if( $err ) { |
600
|
0
|
|
|
|
|
0
|
$IO::Socket::errstr = $@ = "$err"; |
601
|
0
|
|
|
|
|
0
|
$! = EINVAL; |
602
|
0
|
|
|
|
|
0
|
return; |
603
|
|
|
|
|
|
|
} |
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
# We'll take all the @infos anyway, because some OSes (HPUX) are known to |
606
|
|
|
|
|
|
|
# ignore the AI_ADDRCONFIG hint and return AF_INET6 even if they don't |
607
|
|
|
|
|
|
|
# support them |
608
|
|
|
|
|
|
|
} |
609
|
|
|
|
|
|
|
} |
610
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
# In the nonblocking case, caller will be calling ->setup multiple times. |
612
|
|
|
|
|
|
|
# Store configuration in the object for the ->setup method |
613
|
|
|
|
|
|
|
# Yes, these are messy. Sorry, I can't help that... |
614
|
|
|
|
|
|
|
|
615
|
30
|
|
|
|
|
53
|
${*$self}{io_socket_ip_infos} = \@infos; |
|
30
|
|
|
|
|
106
|
|
616
|
|
|
|
|
|
|
|
617
|
30
|
|
|
|
|
59
|
${*$self}{io_socket_ip_idx} = -1; |
|
30
|
|
|
|
|
59
|
|
618
|
|
|
|
|
|
|
|
619
|
30
|
|
|
|
|
78
|
${*$self}{io_socket_ip_sockopts} = \@sockopts_enabled; |
|
30
|
|
|
|
|
87
|
|
620
|
30
|
|
|
|
|
62
|
${*$self}{io_socket_ip_v6only} = $v6only; |
|
30
|
|
|
|
|
51
|
|
621
|
30
|
|
|
|
|
40
|
${*$self}{io_socket_ip_listenqueue} = $listenqueue; |
|
30
|
|
|
|
|
52
|
|
622
|
30
|
|
|
|
|
50
|
${*$self}{io_socket_ip_blocking} = $blocking; |
|
30
|
|
|
|
|
54
|
|
623
|
|
|
|
|
|
|
|
624
|
30
|
|
|
|
|
55
|
${*$self}{io_socket_ip_errors} = [ undef, undef, undef ]; |
|
30
|
|
|
|
|
88
|
|
625
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
# ->setup is allowed to return false in nonblocking mode |
627
|
30
|
50
|
66
|
|
|
89
|
$self->setup or !$blocking or return undef; |
628
|
|
|
|
|
|
|
|
629
|
30
|
|
|
|
|
310
|
return $self; |
630
|
|
|
|
|
|
|
} |
631
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
sub setup |
633
|
|
|
|
|
|
|
{ |
634
|
31
|
|
|
31
|
0
|
87
|
my $self = shift; |
635
|
|
|
|
|
|
|
|
636
|
31
|
|
|
|
|
47
|
while(1) { |
637
|
31
|
|
|
|
|
38
|
${*$self}{io_socket_ip_idx}++; |
|
31
|
|
|
|
|
87
|
|
638
|
31
|
100
|
|
|
|
45
|
last if ${*$self}{io_socket_ip_idx} >= @{ ${*$self}{io_socket_ip_infos} }; |
|
31
|
|
|
|
|
77
|
|
|
31
|
|
|
|
|
39
|
|
|
31
|
|
|
|
|
132
|
|
639
|
|
|
|
|
|
|
|
640
|
30
|
|
|
|
|
59
|
my $info = ${*$self}{io_socket_ip_infos}->[${*$self}{io_socket_ip_idx}]; |
|
30
|
|
|
|
|
75
|
|
|
30
|
|
|
|
|
62
|
|
641
|
|
|
|
|
|
|
|
642
|
30
|
|
|
|
|
105
|
$self->socket( @{$info}{qw( family socktype protocol )} ) or |
643
|
30
|
50
|
|
|
|
56
|
( ${*$self}{io_socket_ip_errors}[2] = $!, next ); |
|
0
|
|
|
|
|
0
|
|
644
|
|
|
|
|
|
|
|
645
|
30
|
100
|
|
|
|
1886
|
$self->blocking( 0 ) unless ${*$self}{io_socket_ip_blocking}; |
|
30
|
|
|
|
|
110
|
|
646
|
|
|
|
|
|
|
|
647
|
30
|
|
|
|
|
91
|
foreach my $sockopt ( @{ ${*$self}{io_socket_ip_sockopts} } ) { |
|
30
|
|
|
|
|
38
|
|
|
30
|
|
|
|
|
125
|
|
648
|
4
|
|
|
|
|
15
|
my ( $level, $optname, $value ) = @$sockopt; |
649
|
4
|
50
|
|
|
|
17
|
$self->setsockopt( $level, $optname, $value ) or |
650
|
|
|
|
|
|
|
( $IO::Socket::errstr = $@ = "$!", return undef ); |
651
|
|
|
|
|
|
|
} |
652
|
|
|
|
|
|
|
|
653
|
30
|
0
|
33
|
|
|
106
|
if( defined ${*$self}{io_socket_ip_v6only} and defined $AF_INET6 and $info->{family} == $AF_INET6 ) { |
|
30
|
|
33
|
|
|
118
|
|
654
|
0
|
|
|
|
|
0
|
my $v6only = ${*$self}{io_socket_ip_v6only}; |
|
0
|
|
|
|
|
0
|
|
655
|
0
|
0
|
|
|
|
0
|
$self->setsockopt( IPPROTO_IPV6, IPV6_V6ONLY, pack "i", $v6only ) or |
656
|
|
|
|
|
|
|
( $IO::Socket::errstr = $@ = "$!", return undef ); |
657
|
|
|
|
|
|
|
} |
658
|
|
|
|
|
|
|
|
659
|
30
|
100
|
|
|
|
133
|
if( defined( my $addr = $info->{localaddr} ) ) { |
660
|
|
|
|
|
|
|
$self->bind( $addr ) or |
661
|
17
|
50
|
|
|
|
115
|
( ${*$self}{io_socket_ip_errors}[1] = $!, next ); |
|
0
|
|
|
|
|
0
|
|
662
|
|
|
|
|
|
|
} |
663
|
|
|
|
|
|
|
|
664
|
30
|
100
|
|
|
|
447
|
if( defined( my $listenqueue = ${*$self}{io_socket_ip_listenqueue} ) ) { |
|
30
|
|
|
|
|
196
|
|
665
|
10
|
50
|
|
|
|
119
|
$self->listen( $listenqueue ) or |
666
|
|
|
|
|
|
|
( $IO::Socket::errstr = $@ = "$!", return undef ); |
667
|
|
|
|
|
|
|
} |
668
|
|
|
|
|
|
|
|
669
|
30
|
100
|
|
|
|
297
|
if( defined( my $addr = $info->{peeraddr} ) ) { |
670
|
11
|
100
|
|
|
|
53
|
if( $self->connect( $addr ) ) { |
671
|
8
|
|
|
|
|
28
|
$! = 0; |
672
|
8
|
|
|
|
|
30
|
return 1; |
673
|
|
|
|
|
|
|
} |
674
|
|
|
|
|
|
|
|
675
|
3
|
50
|
33
|
|
|
48
|
if( $! == EINPROGRESS or $! == EWOULDBLOCK ) { |
676
|
3
|
|
|
|
|
6
|
${*$self}{io_socket_ip_connect_in_progress} = 1; |
|
3
|
|
|
|
|
13
|
|
677
|
3
|
|
|
|
|
20
|
return 0; |
678
|
|
|
|
|
|
|
} |
679
|
|
|
|
|
|
|
|
680
|
|
|
|
|
|
|
# If connect failed but we have no system error there must be an error |
681
|
|
|
|
|
|
|
# at the application layer, like a bad certificate with |
682
|
|
|
|
|
|
|
# IO::Socket::SSL. |
683
|
|
|
|
|
|
|
# In this case don't continue IP based multi-homing because the problem |
684
|
|
|
|
|
|
|
# cannot be solved at the IP layer. |
685
|
0
|
0
|
|
|
|
0
|
return 0 if ! $!; |
686
|
|
|
|
|
|
|
|
687
|
0
|
|
|
|
|
0
|
${*$self}{io_socket_ip_errors}[0] = $!; |
|
0
|
|
|
|
|
0
|
|
688
|
0
|
|
|
|
|
0
|
next; |
689
|
|
|
|
|
|
|
} |
690
|
|
|
|
|
|
|
|
691
|
19
|
|
|
|
|
98
|
return 1; |
692
|
|
|
|
|
|
|
} |
693
|
|
|
|
|
|
|
|
694
|
|
|
|
|
|
|
# Pick the most appropriate error, stringified |
695
|
1
|
|
|
|
|
3
|
$! = ( grep defined, @{ ${*$self}{io_socket_ip_errors}} )[0]; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
5
|
|
696
|
1
|
|
|
|
|
4
|
$IO::Socket::errstr = $@ = "$!"; |
697
|
1
|
|
|
|
|
4
|
return undef; |
698
|
|
|
|
|
|
|
} |
699
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
sub connect :method |
701
|
|
|
|
|
|
|
{ |
702
|
18
|
|
|
18
|
0
|
22951
|
my $self = shift; |
703
|
|
|
|
|
|
|
|
704
|
|
|
|
|
|
|
# It seems that IO::Socket hides EINPROGRESS errors, making them look like |
705
|
|
|
|
|
|
|
# a success. This is annoying here. |
706
|
|
|
|
|
|
|
# Instead of putting up with its frankly-irritating intentional breakage of |
707
|
|
|
|
|
|
|
# useful APIs I'm just going to end-run around it and call core's connect() |
708
|
|
|
|
|
|
|
# directly |
709
|
|
|
|
|
|
|
|
710
|
18
|
100
|
|
|
|
115
|
if( @_ ) { |
711
|
13
|
|
|
|
|
67
|
my ( $addr ) = @_; |
712
|
|
|
|
|
|
|
|
713
|
|
|
|
|
|
|
# Annoyingly IO::Socket's connect() is where the timeout logic is |
714
|
|
|
|
|
|
|
# implemented, so we'll have to reinvent it here |
715
|
13
|
|
|
|
|
23
|
my $timeout = ${*$self}{'io_socket_timeout'}; |
|
13
|
|
|
|
|
59
|
|
716
|
|
|
|
|
|
|
|
717
|
13
|
100
|
|
|
|
836
|
return connect( $self, $addr ) unless defined $timeout; |
718
|
|
|
|
|
|
|
|
719
|
1
|
|
|
|
|
8
|
my $was_blocking = $self->blocking( 0 ); |
720
|
|
|
|
|
|
|
|
721
|
1
|
50
|
|
|
|
141
|
my $err = defined connect( $self, $addr ) ? 0 : $!+0; |
722
|
|
|
|
|
|
|
|
723
|
1
|
50
|
33
|
|
|
16
|
if( !$err ) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
724
|
|
|
|
|
|
|
# All happy |
725
|
0
|
|
|
|
|
0
|
$self->blocking( $was_blocking ); |
726
|
0
|
|
|
|
|
0
|
return 1; |
727
|
|
|
|
|
|
|
} |
728
|
|
|
|
|
|
|
elsif( not( $err == EINPROGRESS or $err == EWOULDBLOCK ) ) { |
729
|
|
|
|
|
|
|
# Failed for some other reason |
730
|
0
|
|
|
|
|
0
|
$self->blocking( $was_blocking ); |
731
|
0
|
|
|
|
|
0
|
return undef; |
732
|
|
|
|
|
|
|
} |
733
|
|
|
|
|
|
|
elsif( !$was_blocking ) { |
734
|
|
|
|
|
|
|
# We shouldn't block anyway |
735
|
0
|
|
|
|
|
0
|
return undef; |
736
|
|
|
|
|
|
|
} |
737
|
|
|
|
|
|
|
|
738
|
1
|
|
|
|
|
3
|
my $vec = ''; vec( $vec, $self->fileno, 1 ) = 1; |
|
1
|
|
|
|
|
3
|
|
739
|
1
|
50
|
|
|
|
22
|
if( !select( undef, $vec, $vec, $timeout ) ) { |
740
|
0
|
|
|
|
|
0
|
$self->blocking( $was_blocking ); |
741
|
0
|
|
|
|
|
0
|
$! = ETIMEDOUT; |
742
|
0
|
|
|
|
|
0
|
return undef; |
743
|
|
|
|
|
|
|
} |
744
|
|
|
|
|
|
|
|
745
|
|
|
|
|
|
|
# Hoist the error by connect()ing a second time |
746
|
1
|
|
|
|
|
13
|
$err = $self->getsockopt( SOL_SOCKET, SO_ERROR ); |
747
|
1
|
50
|
|
|
|
25
|
$err = 0 if $err == EISCONN; # Some OSes give EISCONN |
748
|
|
|
|
|
|
|
|
749
|
1
|
|
|
|
|
4
|
$self->blocking( $was_blocking ); |
750
|
|
|
|
|
|
|
|
751
|
1
|
50
|
|
|
|
13
|
$! = $err, return undef if $err; |
752
|
1
|
|
|
|
|
3
|
return 1; |
753
|
|
|
|
|
|
|
} |
754
|
|
|
|
|
|
|
|
755
|
5
|
50
|
|
|
|
20
|
return 1 if !${*$self}{io_socket_ip_connect_in_progress}; |
|
5
|
|
|
|
|
25
|
|
756
|
|
|
|
|
|
|
|
757
|
|
|
|
|
|
|
# See if a connect attempt has just failed with an error |
758
|
5
|
100
|
|
|
|
37
|
if( my $errno = $self->getsockopt( SOL_SOCKET, SO_ERROR ) ) { |
759
|
1
|
|
|
|
|
23
|
delete ${*$self}{io_socket_ip_connect_in_progress}; |
|
1
|
|
|
|
|
3
|
|
760
|
1
|
|
|
|
|
4
|
${*$self}{io_socket_ip_errors}[0] = $! = $errno; |
|
1
|
|
|
|
|
8
|
|
761
|
1
|
|
|
|
|
4
|
return $self->setup; |
762
|
|
|
|
|
|
|
} |
763
|
|
|
|
|
|
|
|
764
|
|
|
|
|
|
|
# No error, so either connect is still in progress, or has completed |
765
|
|
|
|
|
|
|
# successfully. We can tell by trying to connect() again; either it will |
766
|
|
|
|
|
|
|
# succeed or we'll get EISCONN (connected successfully), or EALREADY |
767
|
|
|
|
|
|
|
# (still in progress). This even works on MSWin32. |
768
|
4
|
|
|
|
|
133
|
my $addr = ${*$self}{io_socket_ip_infos}[${*$self}{io_socket_ip_idx}]{peeraddr}; |
|
4
|
|
|
|
|
12
|
|
|
4
|
|
|
|
|
13
|
|
769
|
|
|
|
|
|
|
|
770
|
4
|
100
|
66
|
|
|
47
|
if( connect( $self, $addr ) or $! == EISCONN ) { |
771
|
2
|
|
|
|
|
6
|
delete ${*$self}{io_socket_ip_connect_in_progress}; |
|
2
|
|
|
|
|
8
|
|
772
|
2
|
|
|
|
|
6
|
$! = 0; |
773
|
2
|
|
|
|
|
7
|
return 1; |
774
|
|
|
|
|
|
|
} |
775
|
|
|
|
|
|
|
else { |
776
|
2
|
|
|
|
|
5
|
$! = EINPROGRESS; |
777
|
2
|
|
|
|
|
7
|
return 0; |
778
|
|
|
|
|
|
|
} |
779
|
|
|
|
|
|
|
} |
780
|
|
|
|
|
|
|
|
781
|
|
|
|
|
|
|
sub connected |
782
|
|
|
|
|
|
|
{ |
783
|
7
|
|
|
7
|
1
|
5874
|
my $self = shift; |
784
|
|
|
|
|
|
|
return defined $self->fileno && |
785
|
|
|
|
|
|
|
!${*$self}{io_socket_ip_connect_in_progress} && |
786
|
7
|
|
66
|
|
|
21
|
defined getpeername( $self ); # ->peername caches, we need to detect disconnection |
787
|
|
|
|
|
|
|
} |
788
|
|
|
|
|
|
|
|
789
|
|
|
|
|
|
|
=head1 METHODS |
790
|
|
|
|
|
|
|
|
791
|
|
|
|
|
|
|
As well as the following methods, this class inherits all the methods in |
792
|
|
|
|
|
|
|
L and L. |
793
|
|
|
|
|
|
|
|
794
|
|
|
|
|
|
|
=cut |
795
|
|
|
|
|
|
|
|
796
|
|
|
|
|
|
|
sub _get_host_service |
797
|
|
|
|
|
|
|
{ |
798
|
49
|
|
|
49
|
|
596
|
my $self = shift; |
799
|
49
|
|
|
|
|
93
|
my ( $addr, $flags, $xflags ) = @_; |
800
|
|
|
|
|
|
|
|
801
|
49
|
100
|
|
|
|
122
|
defined $addr or |
802
|
|
|
|
|
|
|
$! = ENOTCONN, return; |
803
|
|
|
|
|
|
|
|
804
|
43
|
100
|
|
|
|
99
|
$flags |= NI_DGRAM if $self->socktype == SOCK_DGRAM; |
805
|
|
|
|
|
|
|
|
806
|
43
|
|
50
|
|
|
640
|
my ( $err, $host, $service ) = getnameinfo( $addr, $flags, $xflags || 0 ); |
807
|
43
|
50
|
|
|
|
82
|
croak "getnameinfo - $err" if $err; |
808
|
|
|
|
|
|
|
|
809
|
43
|
|
|
|
|
217
|
return ( $host, $service ); |
810
|
|
|
|
|
|
|
} |
811
|
|
|
|
|
|
|
|
812
|
|
|
|
|
|
|
sub _unpack_sockaddr |
813
|
|
|
|
|
|
|
{ |
814
|
8
|
|
|
8
|
|
87
|
my ( $addr ) = @_; |
815
|
8
|
|
|
|
|
24
|
my $family = sockaddr_family $addr; |
816
|
|
|
|
|
|
|
|
817
|
8
|
50
|
0
|
|
|
22
|
if( $family == AF_INET ) { |
|
|
0
|
|
|
|
|
|
818
|
8
|
|
|
|
|
65
|
return ( Socket::unpack_sockaddr_in( $addr ) )[1]; |
819
|
|
|
|
|
|
|
} |
820
|
|
|
|
|
|
|
elsif( defined $AF_INET6 and $family == $AF_INET6 ) { |
821
|
0
|
|
|
|
|
0
|
return ( Socket::unpack_sockaddr_in6( $addr ) )[1]; |
822
|
|
|
|
|
|
|
} |
823
|
|
|
|
|
|
|
else { |
824
|
0
|
|
|
|
|
0
|
croak "Unrecognised address family $family"; |
825
|
|
|
|
|
|
|
} |
826
|
|
|
|
|
|
|
} |
827
|
|
|
|
|
|
|
|
828
|
|
|
|
|
|
|
=head2 sockhost_service |
829
|
|
|
|
|
|
|
|
830
|
|
|
|
|
|
|
( $host, $service ) = $sock->sockhost_service( $numeric ) |
831
|
|
|
|
|
|
|
|
832
|
|
|
|
|
|
|
Returns the hostname and service name of the local address (that is, the |
833
|
|
|
|
|
|
|
socket address given by the C method). |
834
|
|
|
|
|
|
|
|
835
|
|
|
|
|
|
|
If C<$numeric> is true, these will be given in numeric form rather than being |
836
|
|
|
|
|
|
|
resolved into names. |
837
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
The following four convenience wrappers may be used to obtain one of the two |
839
|
|
|
|
|
|
|
values returned here. If both host and service names are required, this method |
840
|
|
|
|
|
|
|
is preferable to the following wrappers, because it will call |
841
|
|
|
|
|
|
|
C only once. |
842
|
|
|
|
|
|
|
|
843
|
|
|
|
|
|
|
=cut |
844
|
|
|
|
|
|
|
|
845
|
|
|
|
|
|
|
sub sockhost_service |
846
|
|
|
|
|
|
|
{ |
847
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
848
|
0
|
|
|
|
|
0
|
my ( $numeric ) = @_; |
849
|
|
|
|
|
|
|
|
850
|
0
|
0
|
|
|
|
0
|
$self->_get_host_service( $self->sockname, $numeric ? NI_NUMERICHOST|NI_NUMERICSERV : 0 ); |
851
|
|
|
|
|
|
|
} |
852
|
|
|
|
|
|
|
|
853
|
|
|
|
|
|
|
=head2 sockhost |
854
|
|
|
|
|
|
|
|
855
|
|
|
|
|
|
|
$addr = $sock->sockhost |
856
|
|
|
|
|
|
|
|
857
|
|
|
|
|
|
|
Return the numeric form of the local address as a textual representation |
858
|
|
|
|
|
|
|
|
859
|
|
|
|
|
|
|
=head2 sockport |
860
|
|
|
|
|
|
|
|
861
|
|
|
|
|
|
|
$port = $sock->sockport |
862
|
|
|
|
|
|
|
|
863
|
|
|
|
|
|
|
Return the numeric form of the local port number |
864
|
|
|
|
|
|
|
|
865
|
|
|
|
|
|
|
=head2 sockhostname |
866
|
|
|
|
|
|
|
|
867
|
|
|
|
|
|
|
$host = $sock->sockhostname |
868
|
|
|
|
|
|
|
|
869
|
|
|
|
|
|
|
Return the resolved name of the local address |
870
|
|
|
|
|
|
|
|
871
|
|
|
|
|
|
|
=head2 sockservice |
872
|
|
|
|
|
|
|
|
873
|
|
|
|
|
|
|
$service = $sock->sockservice |
874
|
|
|
|
|
|
|
|
875
|
|
|
|
|
|
|
Return the resolved name of the local port number |
876
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
=cut |
878
|
|
|
|
|
|
|
|
879
|
9
|
|
|
9
|
1
|
2666
|
sub sockhost { my $self = shift; scalar +( $self->_get_host_service( $self->sockname, NI_NUMERICHOST, NIx_NOSERV ) )[0] } |
|
9
|
|
|
|
|
39
|
|
880
|
18
|
|
|
18
|
1
|
5710
|
sub sockport { my $self = shift; scalar +( $self->_get_host_service( $self->sockname, NI_NUMERICSERV, NIx_NOHOST ) )[1] } |
|
18
|
|
|
|
|
61
|
|
881
|
|
|
|
|
|
|
|
882
|
0
|
|
|
0
|
1
|
0
|
sub sockhostname { my $self = shift; scalar +( $self->_get_host_service( $self->sockname, 0, NIx_NOSERV ) )[0] } |
|
0
|
|
|
|
|
0
|
|
883
|
0
|
|
|
0
|
1
|
0
|
sub sockservice { my $self = shift; scalar +( $self->_get_host_service( $self->sockname, 0, NIx_NOHOST ) )[1] } |
|
0
|
|
|
|
|
0
|
|
884
|
|
|
|
|
|
|
|
885
|
|
|
|
|
|
|
=head2 sockaddr |
886
|
|
|
|
|
|
|
|
887
|
|
|
|
|
|
|
$addr = $sock->sockaddr |
888
|
|
|
|
|
|
|
|
889
|
|
|
|
|
|
|
Return the local address as a binary octet string |
890
|
|
|
|
|
|
|
|
891
|
|
|
|
|
|
|
=cut |
892
|
|
|
|
|
|
|
|
893
|
4
|
|
|
4
|
1
|
1834
|
sub sockaddr { my $self = shift; _unpack_sockaddr $self->sockname } |
|
4
|
|
|
|
|
15
|
|
894
|
|
|
|
|
|
|
|
895
|
|
|
|
|
|
|
=head2 peerhost_service |
896
|
|
|
|
|
|
|
|
897
|
|
|
|
|
|
|
( $host, $service ) = $sock->peerhost_service( $numeric ) |
898
|
|
|
|
|
|
|
|
899
|
|
|
|
|
|
|
Returns the hostname and service name of the peer address (that is, the |
900
|
|
|
|
|
|
|
socket address given by the C method), similar to the |
901
|
|
|
|
|
|
|
C method. |
902
|
|
|
|
|
|
|
|
903
|
|
|
|
|
|
|
The following four convenience wrappers may be used to obtain one of the two |
904
|
|
|
|
|
|
|
values returned here. If both host and service names are required, this method |
905
|
|
|
|
|
|
|
is preferable to the following wrappers, because it will call |
906
|
|
|
|
|
|
|
C only once. |
907
|
|
|
|
|
|
|
|
908
|
|
|
|
|
|
|
=cut |
909
|
|
|
|
|
|
|
|
910
|
|
|
|
|
|
|
sub peerhost_service |
911
|
|
|
|
|
|
|
{ |
912
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
913
|
0
|
|
|
|
|
0
|
my ( $numeric ) = @_; |
914
|
|
|
|
|
|
|
|
915
|
0
|
0
|
|
|
|
0
|
$self->_get_host_service( $self->peername, $numeric ? NI_NUMERICHOST|NI_NUMERICSERV : 0 ); |
916
|
|
|
|
|
|
|
} |
917
|
|
|
|
|
|
|
|
918
|
|
|
|
|
|
|
=head2 peerhost |
919
|
|
|
|
|
|
|
|
920
|
|
|
|
|
|
|
$addr = $sock->peerhost |
921
|
|
|
|
|
|
|
|
922
|
|
|
|
|
|
|
Return the numeric form of the peer address as a textual representation |
923
|
|
|
|
|
|
|
|
924
|
|
|
|
|
|
|
=head2 peerport |
925
|
|
|
|
|
|
|
|
926
|
|
|
|
|
|
|
$port = $sock->peerport |
927
|
|
|
|
|
|
|
|
928
|
|
|
|
|
|
|
Return the numeric form of the peer port number |
929
|
|
|
|
|
|
|
|
930
|
|
|
|
|
|
|
=head2 peerhostname |
931
|
|
|
|
|
|
|
|
932
|
|
|
|
|
|
|
$host = $sock->peerhostname |
933
|
|
|
|
|
|
|
|
934
|
|
|
|
|
|
|
Return the resolved name of the peer address |
935
|
|
|
|
|
|
|
|
936
|
|
|
|
|
|
|
=head2 peerservice |
937
|
|
|
|
|
|
|
|
938
|
|
|
|
|
|
|
$service = $sock->peerservice |
939
|
|
|
|
|
|
|
|
940
|
|
|
|
|
|
|
Return the resolved name of the peer port number |
941
|
|
|
|
|
|
|
|
942
|
|
|
|
|
|
|
=cut |
943
|
|
|
|
|
|
|
|
944
|
9
|
|
|
9
|
1
|
4533
|
sub peerhost { my $self = shift; scalar +( $self->_get_host_service( $self->peername, NI_NUMERICHOST, NIx_NOSERV ) )[0] } |
|
9
|
|
|
|
|
27
|
|
945
|
13
|
|
|
13
|
1
|
966
|
sub peerport { my $self = shift; scalar +( $self->_get_host_service( $self->peername, NI_NUMERICSERV, NIx_NOHOST ) )[1] } |
|
13
|
|
|
|
|
41
|
|
946
|
|
|
|
|
|
|
|
947
|
0
|
|
|
0
|
1
|
0
|
sub peerhostname { my $self = shift; scalar +( $self->_get_host_service( $self->peername, 0, NIx_NOSERV ) )[0] } |
|
0
|
|
|
|
|
0
|
|
948
|
0
|
|
|
0
|
1
|
0
|
sub peerservice { my $self = shift; scalar +( $self->_get_host_service( $self->peername, 0, NIx_NOHOST ) )[1] } |
|
0
|
|
|
|
|
0
|
|
949
|
|
|
|
|
|
|
|
950
|
|
|
|
|
|
|
=head2 peeraddr |
951
|
|
|
|
|
|
|
|
952
|
|
|
|
|
|
|
$addr = $peer->peeraddr |
953
|
|
|
|
|
|
|
|
954
|
|
|
|
|
|
|
Return the peer address as a binary octet string |
955
|
|
|
|
|
|
|
|
956
|
|
|
|
|
|
|
=cut |
957
|
|
|
|
|
|
|
|
958
|
4
|
|
|
4
|
1
|
9
|
sub peeraddr { my $self = shift; _unpack_sockaddr $self->peername } |
|
4
|
|
|
|
|
12
|
|
959
|
|
|
|
|
|
|
|
960
|
|
|
|
|
|
|
# This unbelievably dodgy hack works around the bug that IO::Socket doesn't do |
961
|
|
|
|
|
|
|
# it |
962
|
|
|
|
|
|
|
# https://rt.cpan.org/Ticket/Display.html?id=61577 |
963
|
|
|
|
|
|
|
sub accept |
964
|
|
|
|
|
|
|
{ |
965
|
5
|
|
|
5
|
1
|
1595
|
my $self = shift; |
966
|
5
|
50
|
|
|
|
36
|
my ( $new, $peer ) = $self->SUPER::accept( @_ ) or return; |
967
|
|
|
|
|
|
|
|
968
|
5
|
|
|
|
|
538
|
${*$new}{$_} = ${*$self}{$_} for qw( io_socket_domain io_socket_type io_socket_proto ); |
|
15
|
|
|
|
|
33
|
|
|
15
|
|
|
|
|
46
|
|
969
|
|
|
|
|
|
|
|
970
|
5
|
50
|
|
|
|
32
|
return wantarray ? ( $new, $peer ) |
971
|
|
|
|
|
|
|
: $new; |
972
|
|
|
|
|
|
|
} |
973
|
|
|
|
|
|
|
|
974
|
|
|
|
|
|
|
# This second unbelievably dodgy hack guarantees that $self->fileno doesn't |
975
|
|
|
|
|
|
|
# change, which is useful during nonblocking connect |
976
|
|
|
|
|
|
|
sub socket :method |
977
|
|
|
|
|
|
|
{ |
978
|
33
|
|
|
33
|
0
|
1024
|
my $self = shift; |
979
|
33
|
100
|
|
|
|
208
|
return $self->SUPER::socket(@_) if not defined $self->fileno; |
980
|
|
|
|
|
|
|
|
981
|
|
|
|
|
|
|
# I hate core prototypes sometimes... |
982
|
2
|
50
|
|
|
|
55
|
socket( my $tmph, $_[0], $_[1], $_[2] ) or return undef; |
983
|
|
|
|
|
|
|
|
984
|
2
|
50
|
|
|
|
11
|
dup2( $tmph->fileno, $self->fileno ) or die "Unable to dup2 $tmph onto $self - $!"; |
985
|
|
|
|
|
|
|
} |
986
|
|
|
|
|
|
|
|
987
|
|
|
|
|
|
|
# Versions of IO::Socket before 1.35 may leave socktype undef if from, say, an |
988
|
|
|
|
|
|
|
# ->fdopen call. In this case we'll apply a fix |
989
|
|
|
|
|
|
|
BEGIN { |
990
|
22
|
50
|
|
22
|
|
1856
|
if( eval($IO::Socket::VERSION) < 1.35 ) { |
991
|
|
|
|
|
|
|
*socktype = sub { |
992
|
0
|
|
|
|
|
0
|
my $self = shift; |
993
|
0
|
|
|
|
|
0
|
my $type = $self->SUPER::socktype; |
994
|
0
|
0
|
|
|
|
0
|
if( !defined $type ) { |
995
|
0
|
|
|
|
|
0
|
$type = $self->sockopt( Socket::SO_TYPE() ); |
996
|
|
|
|
|
|
|
} |
997
|
0
|
|
|
|
|
0
|
return $type; |
998
|
0
|
|
|
|
|
0
|
}; |
999
|
|
|
|
|
|
|
} |
1000
|
|
|
|
|
|
|
} |
1001
|
|
|
|
|
|
|
|
1002
|
|
|
|
|
|
|
=head2 as_inet |
1003
|
|
|
|
|
|
|
|
1004
|
|
|
|
|
|
|
$inet = $sock->as_inet |
1005
|
|
|
|
|
|
|
|
1006
|
|
|
|
|
|
|
Returns a new L instance wrapping the same filehandle. This |
1007
|
|
|
|
|
|
|
may be useful in cases where it is required, for backward-compatibility, to |
1008
|
|
|
|
|
|
|
have a real object of C type instead of C. |
1009
|
|
|
|
|
|
|
The new object will wrap the same underlying socket filehandle as the |
1010
|
|
|
|
|
|
|
original, so care should be taken not to continue to use both objects |
1011
|
|
|
|
|
|
|
concurrently. Ideally the original C<$sock> should be discarded after this |
1012
|
|
|
|
|
|
|
method is called. |
1013
|
|
|
|
|
|
|
|
1014
|
|
|
|
|
|
|
This method checks that the socket domain is C and will throw an |
1015
|
|
|
|
|
|
|
exception if it isn't. |
1016
|
|
|
|
|
|
|
|
1017
|
|
|
|
|
|
|
=cut |
1018
|
|
|
|
|
|
|
|
1019
|
|
|
|
|
|
|
sub as_inet |
1020
|
|
|
|
|
|
|
{ |
1021
|
1
|
|
|
1
|
1
|
5
|
my $self = shift; |
1022
|
1
|
50
|
|
|
|
7
|
croak "Cannot downgrade a non-PF_INET socket to IO::Socket::INET" unless $self->sockdomain == AF_INET; |
1023
|
1
|
|
|
|
|
15
|
return IO::Socket::INET->new_from_fd( $self->fileno, "r+" ); |
1024
|
|
|
|
|
|
|
} |
1025
|
|
|
|
|
|
|
|
1026
|
|
|
|
|
|
|
=head1 NON-BLOCKING |
1027
|
|
|
|
|
|
|
|
1028
|
|
|
|
|
|
|
If the constructor is passed a defined but false value for the C |
1029
|
|
|
|
|
|
|
argument then the socket is put into non-blocking mode. When in non-blocking |
1030
|
|
|
|
|
|
|
mode, the socket will not be set up by the time the constructor returns, |
1031
|
|
|
|
|
|
|
because the underlying C syscall would otherwise have to block. |
1032
|
|
|
|
|
|
|
|
1033
|
|
|
|
|
|
|
The non-blocking behaviour is an extension of the C API, |
1034
|
|
|
|
|
|
|
unique to C, because the former does not support multi-homed |
1035
|
|
|
|
|
|
|
non-blocking connect. |
1036
|
|
|
|
|
|
|
|
1037
|
|
|
|
|
|
|
When using non-blocking mode, the caller must repeatedly check for |
1038
|
|
|
|
|
|
|
writeability on the filehandle (for instance using C |
1039
|
|
|
|
|
|
|
Each time the filehandle is ready to write, the C method must be |
1040
|
|
|
|
|
|
|
called, with no arguments. Note that some operating systems, most notably |
1041
|
|
|
|
|
|
|
C do not report a C failure using write-ready; so you must |
1042
|
|
|
|
|
|
|
also C |
1043
|
|
|
|
|
|
|
|
1044
|
|
|
|
|
|
|
While C returns false, the value of C<$!> indicates whether it should |
1045
|
|
|
|
|
|
|
be tried again (by being set to the value C, or C on |
1046
|
|
|
|
|
|
|
MSWin32), or whether a permanent error has occurred (e.g. C). |
1047
|
|
|
|
|
|
|
|
1048
|
|
|
|
|
|
|
Once the socket has been connected to the peer, C will return true |
1049
|
|
|
|
|
|
|
and the socket will now be ready to use. |
1050
|
|
|
|
|
|
|
|
1051
|
|
|
|
|
|
|
Note that calls to the platform's underlying C function may |
1052
|
|
|
|
|
|
|
block. If C has to perform this lookup, the constructor will |
1053
|
|
|
|
|
|
|
block even when in non-blocking mode. |
1054
|
|
|
|
|
|
|
|
1055
|
|
|
|
|
|
|
To avoid this blocking behaviour, the caller should pass in the result of such |
1056
|
|
|
|
|
|
|
a lookup using the C or C arguments. This can be |
1057
|
|
|
|
|
|
|
achieved by using L, or the C function can be |
1058
|
|
|
|
|
|
|
called in a child process. |
1059
|
|
|
|
|
|
|
|
1060
|
|
|
|
|
|
|
use IO::Socket::IP; |
1061
|
|
|
|
|
|
|
use Errno qw( EINPROGRESS EWOULDBLOCK ); |
1062
|
|
|
|
|
|
|
|
1063
|
|
|
|
|
|
|
my @peeraddrinfo = ... # Caller must obtain the getaddinfo result here |
1064
|
|
|
|
|
|
|
|
1065
|
|
|
|
|
|
|
my $socket = IO::Socket::IP->new( |
1066
|
|
|
|
|
|
|
PeerAddrInfo => \@peeraddrinfo, |
1067
|
|
|
|
|
|
|
Blocking => 0, |
1068
|
|
|
|
|
|
|
) or die "Cannot construct socket - $@"; |
1069
|
|
|
|
|
|
|
|
1070
|
|
|
|
|
|
|
while( !$socket->connect and ( $! == EINPROGRESS || $! == EWOULDBLOCK ) ) { |
1071
|
|
|
|
|
|
|
my $wvec = ''; |
1072
|
|
|
|
|
|
|
vec( $wvec, fileno $socket, 1 ) = 1; |
1073
|
|
|
|
|
|
|
my $evec = ''; |
1074
|
|
|
|
|
|
|
vec( $evec, fileno $socket, 1 ) = 1; |
1075
|
|
|
|
|
|
|
|
1076
|
|
|
|
|
|
|
select( undef, $wvec, $evec, undef ) or die "Cannot select - $!"; |
1077
|
|
|
|
|
|
|
} |
1078
|
|
|
|
|
|
|
|
1079
|
|
|
|
|
|
|
die "Cannot connect - $!" if $!; |
1080
|
|
|
|
|
|
|
|
1081
|
|
|
|
|
|
|
... |
1082
|
|
|
|
|
|
|
|
1083
|
|
|
|
|
|
|
The example above uses C |
1084
|
|
|
|
|
|
|
analogously. C takes care when creating new socket filehandles |
1085
|
|
|
|
|
|
|
to preserve the actual file descriptor number, so such techniques as C |
1086
|
|
|
|
|
|
|
or C should be transparent to its reallocation of a different socket |
1087
|
|
|
|
|
|
|
underneath, perhaps in order to switch protocol family between C and |
1088
|
|
|
|
|
|
|
C. |
1089
|
|
|
|
|
|
|
|
1090
|
|
|
|
|
|
|
For another example using C and C, see the |
1091
|
|
|
|
|
|
|
F file in the module distribution. |
1092
|
|
|
|
|
|
|
|
1093
|
|
|
|
|
|
|
=cut |
1094
|
|
|
|
|
|
|
|
1095
|
|
|
|
|
|
|
=head1 C AND C PARSING |
1096
|
|
|
|
|
|
|
|
1097
|
|
|
|
|
|
|
To support the C API, the host and port information may be |
1098
|
|
|
|
|
|
|
passed in a single string rather than as two separate arguments. |
1099
|
|
|
|
|
|
|
|
1100
|
|
|
|
|
|
|
If either C or C (or their C<...Addr> synonyms) have any |
1101
|
|
|
|
|
|
|
of the following special forms then special parsing is applied. |
1102
|
|
|
|
|
|
|
|
1103
|
|
|
|
|
|
|
The value of the C<...Host> argument will be split to give both the hostname |
1104
|
|
|
|
|
|
|
and port (or service name): |
1105
|
|
|
|
|
|
|
|
1106
|
|
|
|
|
|
|
hostname.example.org:http # Host name |
1107
|
|
|
|
|
|
|
192.0.2.1:80 # IPv4 address |
1108
|
|
|
|
|
|
|
[2001:db8::1]:80 # IPv6 address |
1109
|
|
|
|
|
|
|
|
1110
|
|
|
|
|
|
|
In each case, the port or service name (e.g. C<80>) is passed as the |
1111
|
|
|
|
|
|
|
C or C argument. |
1112
|
|
|
|
|
|
|
|
1113
|
|
|
|
|
|
|
Either of C or C (or their C<...Port> synonyms) can |
1114
|
|
|
|
|
|
|
be either a service name, a decimal number, or a string containing both a |
1115
|
|
|
|
|
|
|
service name and number, in a form such as |
1116
|
|
|
|
|
|
|
|
1117
|
|
|
|
|
|
|
http(80) |
1118
|
|
|
|
|
|
|
|
1119
|
|
|
|
|
|
|
In this case, the name (C) will be tried first, but if the resolver does |
1120
|
|
|
|
|
|
|
not understand it then the port number (C<80>) will be used instead. |
1121
|
|
|
|
|
|
|
|
1122
|
|
|
|
|
|
|
If the C<...Host> argument is in this special form and the corresponding |
1123
|
|
|
|
|
|
|
C<...Service> or C<...Port> argument is also defined, the one parsed from |
1124
|
|
|
|
|
|
|
the C<...Host> argument will take precedence and the other will be ignored. |
1125
|
|
|
|
|
|
|
|
1126
|
|
|
|
|
|
|
=head2 split_addr |
1127
|
|
|
|
|
|
|
|
1128
|
|
|
|
|
|
|
( $host, $port ) = IO::Socket::IP->split_addr( $addr ) |
1129
|
|
|
|
|
|
|
|
1130
|
|
|
|
|
|
|
Utility method that provides the parsing functionality described above. |
1131
|
|
|
|
|
|
|
Returns a 2-element list, containing either the split hostname and port |
1132
|
|
|
|
|
|
|
description if it could be parsed, or the given address and C if it was |
1133
|
|
|
|
|
|
|
not recognised. |
1134
|
|
|
|
|
|
|
|
1135
|
|
|
|
|
|
|
IO::Socket::IP->split_addr( "hostname:http" ) |
1136
|
|
|
|
|
|
|
# ( "hostname", "http" ) |
1137
|
|
|
|
|
|
|
|
1138
|
|
|
|
|
|
|
IO::Socket::IP->split_addr( "192.0.2.1:80" ) |
1139
|
|
|
|
|
|
|
# ( "192.0.2.1", "80" ) |
1140
|
|
|
|
|
|
|
|
1141
|
|
|
|
|
|
|
IO::Socket::IP->split_addr( "[2001:db8::1]:80" ) |
1142
|
|
|
|
|
|
|
# ( "2001:db8::1", "80" ) |
1143
|
|
|
|
|
|
|
|
1144
|
|
|
|
|
|
|
IO::Socket::IP->split_addr( "something.else" ) |
1145
|
|
|
|
|
|
|
# ( "something.else", undef ) |
1146
|
|
|
|
|
|
|
|
1147
|
|
|
|
|
|
|
=cut |
1148
|
|
|
|
|
|
|
|
1149
|
|
|
|
|
|
|
sub split_addr |
1150
|
|
|
|
|
|
|
{ |
1151
|
47
|
|
|
47
|
1
|
171
|
shift; |
1152
|
47
|
|
|
|
|
84
|
my ( $addr ) = @_; |
1153
|
|
|
|
|
|
|
|
1154
|
47
|
|
|
|
|
132
|
local ( $1, $2 ); # Placate a taint-related bug; [perl #67962] |
1155
|
47
|
100
|
100
|
|
|
4854
|
if( $addr =~ m/\A\[($IPv6_re)\](?::([^\s:]*))?\z/ or |
1156
|
|
|
|
|
|
|
$addr =~ m/\A([^\s:]*):([^\s:]*)\z/ ) { |
1157
|
17
|
100
|
100
|
|
|
140
|
return ( $1, $2 ) if defined $2 and length $2; |
1158
|
4
|
|
|
|
|
19
|
return ( $1, undef ); |
1159
|
|
|
|
|
|
|
} |
1160
|
|
|
|
|
|
|
|
1161
|
30
|
|
|
|
|
245
|
return ( $addr, undef ); |
1162
|
|
|
|
|
|
|
} |
1163
|
|
|
|
|
|
|
|
1164
|
|
|
|
|
|
|
=head2 join_addr |
1165
|
|
|
|
|
|
|
|
1166
|
|
|
|
|
|
|
$addr = IO::Socket::IP->join_addr( $host, $port ) |
1167
|
|
|
|
|
|
|
|
1168
|
|
|
|
|
|
|
Utility method that performs the reverse of C, returning a string |
1169
|
|
|
|
|
|
|
formed by joining the specified host address and port number. The host address |
1170
|
|
|
|
|
|
|
will be wrapped in C<[]> brackets if required (because it is a raw IPv6 |
1171
|
|
|
|
|
|
|
numeric address). |
1172
|
|
|
|
|
|
|
|
1173
|
|
|
|
|
|
|
This can be especially useful when combined with the C or |
1174
|
|
|
|
|
|
|
C methods. |
1175
|
|
|
|
|
|
|
|
1176
|
|
|
|
|
|
|
say "Connected to ", IO::Socket::IP->join_addr( $sock->peerhost_service ); |
1177
|
|
|
|
|
|
|
|
1178
|
|
|
|
|
|
|
=cut |
1179
|
|
|
|
|
|
|
|
1180
|
|
|
|
|
|
|
sub join_addr |
1181
|
|
|
|
|
|
|
{ |
1182
|
4
|
|
|
4
|
1
|
7
|
shift; |
1183
|
4
|
|
|
|
|
8
|
my ( $host, $port ) = @_; |
1184
|
|
|
|
|
|
|
|
1185
|
4
|
100
|
|
|
|
14
|
$host = "[$host]" if $host =~ m/:/; |
1186
|
|
|
|
|
|
|
|
1187
|
4
|
100
|
|
|
|
19
|
return join ":", $host, $port if defined $port; |
1188
|
1
|
|
|
|
|
4
|
return $host; |
1189
|
|
|
|
|
|
|
} |
1190
|
|
|
|
|
|
|
|
1191
|
|
|
|
|
|
|
# Since IO::Socket->new( Domain => ... ) will delete the Domain parameter |
1192
|
|
|
|
|
|
|
# before calling ->configure, we need to keep track of which it was |
1193
|
|
|
|
|
|
|
|
1194
|
|
|
|
|
|
|
package # hide from indexer |
1195
|
|
|
|
|
|
|
IO::Socket::IP::_ForINET; |
1196
|
22
|
|
|
22
|
|
166
|
use base qw( IO::Socket::IP ); |
|
22
|
|
|
|
|
73
|
|
|
22
|
|
|
|
|
4101
|
|
1197
|
|
|
|
|
|
|
|
1198
|
|
|
|
|
|
|
sub configure |
1199
|
|
|
|
|
|
|
{ |
1200
|
|
|
|
|
|
|
# This is evil |
1201
|
2
|
|
|
2
|
|
782
|
my $self = shift; |
1202
|
2
|
|
|
|
|
5
|
my ( $arg ) = @_; |
1203
|
|
|
|
|
|
|
|
1204
|
2
|
|
|
|
|
4
|
bless $self, "IO::Socket::IP"; |
1205
|
2
|
|
|
|
|
10
|
$self->configure( { %$arg, Family => Socket::AF_INET() } ); |
1206
|
|
|
|
|
|
|
} |
1207
|
|
|
|
|
|
|
|
1208
|
|
|
|
|
|
|
package # hide from indexer |
1209
|
|
|
|
|
|
|
IO::Socket::IP::_ForINET6; |
1210
|
22
|
|
|
22
|
|
155
|
use base qw( IO::Socket::IP ); |
|
22
|
|
|
|
|
45
|
|
|
22
|
|
|
|
|
3707
|
|
1211
|
|
|
|
|
|
|
|
1212
|
|
|
|
|
|
|
sub configure |
1213
|
|
|
|
|
|
|
{ |
1214
|
|
|
|
|
|
|
# This is evil |
1215
|
0
|
|
|
0
|
|
|
my $self = shift; |
1216
|
0
|
|
|
|
|
|
my ( $arg ) = @_; |
1217
|
|
|
|
|
|
|
|
1218
|
0
|
|
|
|
|
|
bless $self, "IO::Socket::IP"; |
1219
|
0
|
|
|
|
|
|
$self->configure( { %$arg, Family => Socket::AF_INET6() } ); |
1220
|
|
|
|
|
|
|
} |
1221
|
|
|
|
|
|
|
|
1222
|
|
|
|
|
|
|
=head1 C INCOMPATIBILITES |
1223
|
|
|
|
|
|
|
|
1224
|
|
|
|
|
|
|
=over 4 |
1225
|
|
|
|
|
|
|
|
1226
|
|
|
|
|
|
|
=item * |
1227
|
|
|
|
|
|
|
|
1228
|
|
|
|
|
|
|
The behaviour enabled by C is in fact implemented by |
1229
|
|
|
|
|
|
|
C as it is required to correctly support searching for a |
1230
|
|
|
|
|
|
|
useable address from the results of the C call. The |
1231
|
|
|
|
|
|
|
constructor will ignore the value of this argument, except if it is defined |
1232
|
|
|
|
|
|
|
but false. An exception is thrown in this case, because that would request it |
1233
|
|
|
|
|
|
|
disable the C search behaviour in the first place. |
1234
|
|
|
|
|
|
|
|
1235
|
|
|
|
|
|
|
=item * |
1236
|
|
|
|
|
|
|
|
1237
|
|
|
|
|
|
|
C implements both the C and C parameters, |
1238
|
|
|
|
|
|
|
but it implements the interaction of both in a different way. |
1239
|
|
|
|
|
|
|
|
1240
|
|
|
|
|
|
|
In C<::INET>, supplying a timeout overrides the non-blocking behaviour, |
1241
|
|
|
|
|
|
|
meaning that the C operation will still block despite that the |
1242
|
|
|
|
|
|
|
caller asked for a non-blocking socket. This is not explicitly specified in |
1243
|
|
|
|
|
|
|
its documentation, nor does this author believe that is a useful behaviour - |
1244
|
|
|
|
|
|
|
it appears to come from a quirk of implementation. |
1245
|
|
|
|
|
|
|
|
1246
|
|
|
|
|
|
|
In C<::IP> therefore, the C parameter takes precedence - if a |
1247
|
|
|
|
|
|
|
non-blocking socket is requested, no operation will block. The C |
1248
|
|
|
|
|
|
|
parameter here simply defines the maximum time that a blocking C |
1249
|
|
|
|
|
|
|
call will wait, if it blocks at all. |
1250
|
|
|
|
|
|
|
|
1251
|
|
|
|
|
|
|
In order to specifically obtain the "blocking connect then non-blocking send |
1252
|
|
|
|
|
|
|
and receive" behaviour of specifying this combination of options to C<::INET> |
1253
|
|
|
|
|
|
|
when using C<::IP>, perform first a blocking connect, then afterwards turn the |
1254
|
|
|
|
|
|
|
socket into nonblocking mode. |
1255
|
|
|
|
|
|
|
|
1256
|
|
|
|
|
|
|
my $sock = IO::Socket::IP->new( |
1257
|
|
|
|
|
|
|
PeerHost => $peer, |
1258
|
|
|
|
|
|
|
Timeout => 20, |
1259
|
|
|
|
|
|
|
) or die "Cannot connect - $@"; |
1260
|
|
|
|
|
|
|
|
1261
|
|
|
|
|
|
|
$sock->blocking( 0 ); |
1262
|
|
|
|
|
|
|
|
1263
|
|
|
|
|
|
|
This code will behave identically under both C and |
1264
|
|
|
|
|
|
|
C. |
1265
|
|
|
|
|
|
|
|
1266
|
|
|
|
|
|
|
=back |
1267
|
|
|
|
|
|
|
|
1268
|
|
|
|
|
|
|
=cut |
1269
|
|
|
|
|
|
|
|
1270
|
|
|
|
|
|
|
=head1 TODO |
1271
|
|
|
|
|
|
|
|
1272
|
|
|
|
|
|
|
=over 4 |
1273
|
|
|
|
|
|
|
|
1274
|
|
|
|
|
|
|
=item * |
1275
|
|
|
|
|
|
|
|
1276
|
|
|
|
|
|
|
Investigate whether C upsets BSD's C watchers, and if so, |
1277
|
|
|
|
|
|
|
consider what possible workarounds might be applied. |
1278
|
|
|
|
|
|
|
|
1279
|
|
|
|
|
|
|
=back |
1280
|
|
|
|
|
|
|
|
1281
|
|
|
|
|
|
|
=head1 AUTHOR |
1282
|
|
|
|
|
|
|
|
1283
|
|
|
|
|
|
|
Paul Evans |
1284
|
|
|
|
|
|
|
|
1285
|
|
|
|
|
|
|
=cut |
1286
|
|
|
|
|
|
|
|
1287
|
|
|
|
|
|
|
0x55AA; |