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