ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent/lib/AnyEvent/Socket.pm
(Generate patch)

Comparing AnyEvent/lib/AnyEvent/Socket.pm (file contents):
Revision 1.28 by root, Mon May 26 05:09:53 2008 UTC vs.
Revision 1.59 by root, Wed Aug 20 12:37:21 2008 UTC

2 2
3AnyEvent::Socket - useful IPv4 and IPv6 stuff. 3AnyEvent::Socket - useful IPv4 and IPv6 stuff.
4 4
5=head1 SYNOPSIS 5=head1 SYNOPSIS
6 6
7 use AnyEvent::Socket; 7 use AnyEvent::Socket;
8 8
9 tcp_connect "gameserver.deliantra.net", 13327, sub { 9 tcp_connect "gameserver.deliantra.net", 13327, sub {
10 my ($fh) = @_ 10 my ($fh) = @_
11 or die "gameserver.deliantra.net connect failed: $!"; 11 or die "gameserver.deliantra.net connect failed: $!";
12 12
13 # enjoy your filehandle 13 # enjoy your filehandle
14 }; 14 };
15 15
16 # a simple tcp server 16 # a simple tcp server
17 tcp_server undef, 8888, sub { 17 tcp_server undef, 8888, sub {
18 my ($fh, $host, $port) = @_; 18 my ($fh, $host, $port) = @_;
19 19
20 syswrite $fh, "The internet is full, $host:$port. Go away!\015\012"; 20 syswrite $fh, "The internet is full, $host:$port. Go away!\015\012";
21 }; 21 };
22 22
23=head1 DESCRIPTION 23=head1 DESCRIPTION
24 24
25This module implements various utility functions for handling internet 25This module implements various utility functions for handling internet
26protocol addresses and sockets, in an as transparent and simple way as 26protocol addresses and sockets, in an as transparent and simple way as
38no warnings; 38no warnings;
39use strict; 39use strict;
40 40
41use Carp (); 41use Carp ();
42use Errno (); 42use Errno ();
43use Socket qw(AF_INET SOCK_STREAM SOCK_DGRAM SOL_SOCKET SO_REUSEADDR); 43use Socket qw(AF_INET AF_UNIX SOCK_STREAM SOCK_DGRAM SOL_SOCKET SO_REUSEADDR);
44 44
45use AnyEvent qw(WIN32); 45use AnyEvent ();
46use AnyEvent::Util qw(guard fh_nonblocking AF_INET6); 46use AnyEvent::Util qw(guard fh_nonblocking AF_INET6);
47use AnyEvent::DNS (); 47use AnyEvent::DNS ();
48 48
49use base 'Exporter'; 49use base 'Exporter';
50 50
51our @EXPORT = qw(parse_ipv4 parse_ipv6 parse_ip format_ip inet_aton tcp_server tcp_connect); 51our @EXPORT = qw(
52 parse_hostport
53 parse_ipv4 parse_ipv6
54 parse_ip parse_address
55 format_ip format_address
56 address_family
57 inet_aton
58 tcp_server
59 tcp_connect
60);
52 61
53our $VERSION = '1.0'; 62our $VERSION = 4.231;
54 63
55=item $ipn = parse_ipv4 $dotted_quad 64=item $ipn = parse_ipv4 $dotted_quad
56 65
57Tries to parse the given dotted quad IPv4 address and return it in 66Tries to parse the given dotted quad IPv4 address and return it in
58octet form (or undef when it isn't in a parsable format). Supports all 67octet form (or undef when it isn't in a parsable format). Supports all
70 79
71 # check leading parts against range 80 # check leading parts against range
72 return undef if grep $_ >= 256, @_[0 .. @_ - 2]; 81 return undef if grep $_ >= 256, @_[0 .. @_ - 2];
73 82
74 # check trailing part against range 83 # check trailing part against range
75 return undef if $_[-1] >= 1 << (8 * (4 - $#_)); 84 return undef if $_[-1] >= 2 ** (8 * (4 - $#_));
76 85
77 pack "N", (pop) 86 pack "N", (pop)
78 + ($_[0] << 24) 87 + ($_[0] << 24)
79 + ($_[1] << 16) 88 + ($_[1] << 16)
80 + ($_[2] << 8); 89 + ($_[2] << 8);
128 137
129 # and done 138 # and done
130 pack "n*", map hex, @h, @t 139 pack "n*", map hex, @h, @t
131} 140}
132 141
142sub parse_unix($) {
143 $_[0] eq "unix/"
144 ? pack "S", AF_UNIX
145 : undef
146
147}
148
133=item $ipn = parse_ip $text 149=item $ipn = parse_address $text
134 150
135Combines C<parse_ipv4> and C<parse_ipv6> in one function. 151Combines C<parse_ipv4> and C<parse_ipv6> in one function. The address
152here refers to the host address (not socket address) in network form
153(binary).
136 154
137=cut 155If the C<$text> is C<unix/>, then this function returns a special token
156recognised by the other functions in this module to mean "UNIX domain
157socket".
138 158
159=item $text = AnyEvent::Socket::aton $ipn
160
161Same as C<parse_address>, but not exported (think C<Socket::inet_aton> but
162I<without> name resolution).
163
164=cut
165
139sub parse_ip($) { 166sub parse_address($) {
140 &parse_ipv4 || &parse_ipv6 167 &parse_ipv4 || &parse_ipv6 || &parse_unix
141} 168}
142 169
170*aton = \&parse_address;
171
172=item ($host, $service) = parse_hostport $string[, $default_service]
173
174Splitting a string of the form C<hostname:port> is a common
175problem. Unfortunately, just splitting on the colon makes it hard to
176specify IPv6 addresses and doesn't support the less common but well
177standardised C<[ip literal]> syntax.
178
179This function tries to do this job in a better way, it supports the
180following formats, where C<port> can be a numerical port number of a
181service name, or a C<name=port> string, and the C< port> and C<:port>
182parts are optional. Also, everywhere where an IP address is supported
183a hostname or unix domain socket address is also supported (see
184C<parse_unix>).
185
186 hostname:port e.g. "www.linux.org", "www.x.de:443", "www.x.de:https=443"
187 ipv4:port e.g. "198.182.196.56", "127.1:22"
188 ipv6 e.g. "::1", "affe::1"
189 [ipv4or6]:port e.g. "[::1]", "[10.0.1]:80"
190 [ipv4or6] port e.g. "[127.0.0.1]", "[www.x.org] 17"
191 ipv4or6 port e.g. "::1 443", "10.0.0.1 smtp"
192
193It also supports defaulting the service name in a simple way by using
194C<$default_service> if no service was detected. If neither a service was
195detected nor a default was specified, then this function returns the
196empty list. The same happens when a parse error weas detected, such as a
197hostname with a colon in it (the function is rather conservative, though).
198
199Example:
200
201 print join ",", parse_hostport "localhost:443";
202 # => "localhost,443"
203
204 print join ",", parse_hostport "localhost", "https";
205 # => "localhost,https"
206
207 print join ",", parse_hostport "[::1]";
208 # => "," (empty list)
209
210=cut
211
212sub parse_hostport($;$) {
213 my ($host, $port);
214
215 for ("$_[0]") { # work on a copy, just in case, and also reset pos
216
217 # parse host, special cases: "ipv6" or "ipv6 port"
218 unless (
219 ($host) = /^\s* ([0-9a-fA-F:]*:[0-9a-fA-F:]*:[0-9a-fA-F\.:]*)/xgc
220 and parse_ipv6 $host
221 ) {
222 /^\s*/xgc;
223
224 if (/^ \[ ([^\[\]]+) \]/xgc) {
225 $host = $1;
226 } elsif (/^ ([^\[\]:\ ]+) /xgc) {
227 $host = $1;
228 } else {
229 return;
230 }
231 }
232
233 # parse port
234 if (/\G (?:\s+|:) ([^:[:space:]]+) \s*$/xgc) {
235 $port = $1;
236 } elsif (/\G\s*$/gc && length $_[1]) {
237 $port = $_[1];
238 } else {
239 return;
240 }
241 }
242
243 # hostnames must not contain :'s
244 return if $host =~ /:/ && !parse_ipv6 $host;
245
246 ($host, $port)
247}
248
249=item $sa_family = address_family $ipn
250
251Returns the address family/protocol-family (AF_xxx/PF_xxx, in one value :)
252of the given host address in network format.
253
254=cut
255
256sub address_family($) {
257 4 == length $_[0]
258 ? AF_INET
259 : 16 == length $_[0]
260 ? AF_INET6
261 : unpack "S", $_[0]
262}
263
143=item $text = format_ip $ipn 264=item $text = format_address $ipn
144 265
145Takes either an IPv4 address (4 octets) or and IPv6 address (16 octets) 266Covnvert a host address in network format (e.g. 4 octets for IPv4 or 16
146and converts it into textual form. 267octets for IPv6) and convert it into textual form.
268
269Returns C<unix/> for UNIX domain sockets.
147 270
148This function works similarly to C<inet_ntop AF_INET || AF_INET6, ...>, 271This function works similarly to C<inet_ntop AF_INET || AF_INET6, ...>,
149except it automatically detects the address type. 272except it automatically detects the address type.
150 273
151=cut 274Returns C<undef> if it cannot detect the type.
152 275
153sub format_ip; 276=item $text = AnyEvent::Socket::ntoa $ipn
277
278Same as format_address, but not exported (think C<inet_ntoa>).
279
280=cut
281
282sub format_address;
154sub format_ip($) { 283sub format_address($) {
155 if (4 == length $_[0]) { 284 my $af = address_family $_[0];
285 if ($af == AF_INET) {
156 return join ".", unpack "C4", $_[0] 286 return join ".", unpack "C4", $_[0]
157 } elsif (16 == length $_[0]) { 287 } elsif ($af == AF_INET6) {
288 if (v0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 eq $_[0]) {
289 return "::";
290 } elsif (v0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1 eq $_[0]) {
291 return "::1";
292 } elsif (v0.0.0.0.0.0.0.0.0.0.0.0 eq substr $_[0], 0, 12) {
293 # v4compatible
294 return "::" . format_address substr $_[0], 12;
158 if (v0.0.0.0.0.0.0.0.0.0.255.255 eq substr $_[0], 0, 12) { 295 } elsif (v0.0.0.0.0.0.0.0.0.0.255.255 eq substr $_[0], 0, 12) {
159 # v4mapped 296 # v4mapped
160 return "::ffff:" . format_ip substr $_[0], 12; 297 return "::ffff:" . format_address substr $_[0], 12;
298 } elsif (v0.0.0.0.0.0.0.0.255.255.0.0 eq substr $_[0], 0, 12) {
299 # v4translated
300 return "::ffff:0:" . format_address substr $_[0], 12;
161 } else { 301 } else {
162 my $ip = sprintf "%x:%x:%x:%x:%x:%x:%x:%x", unpack "n8", $_[0]; 302 my $ip = sprintf "%x:%x:%x:%x:%x:%x:%x:%x", unpack "n8", $_[0];
163 303
304 # this is rather sucky, I admit
164 $ip =~ s/^0:(?:0:)*(0$)?/::/ 305 $ip =~ s/^0:(?:0:)*(0$)?/::/
165 or $ip =~ s/(:0)+$/::/ 306 or $ip =~ s/(:0){7}$/::/ or $ip =~ s/(:0){7}/:/
166 or $ip =~ s/(:0)+/:/; 307 or $ip =~ s/(:0){6}$/::/ or $ip =~ s/(:0){6}/:/
308 or $ip =~ s/(:0){5}$/::/ or $ip =~ s/(:0){5}/:/
309 or $ip =~ s/(:0){4}$/::/ or $ip =~ s/(:0){4}/:/
310 or $ip =~ s/(:0){3}$/::/ or $ip =~ s/(:0){3}/:/
311 or $ip =~ s/(:0){2}$/::/ or $ip =~ s/(:0){2}/:/
312 or $ip =~ s/(:0){1}$/::/ or $ip =~ s/(:0){1}/:/;
167 return $ip 313 return $ip
168 } 314 }
315 } elsif ($af == AF_UNIX) {
316 return "unix/"
169 } else { 317 } else {
170 return undef 318 return undef
171 } 319 }
172} 320}
321
322*ntoa = \&format_address;
173 323
174=item inet_aton $name_or_address, $cb->(@addresses) 324=item inet_aton $name_or_address, $cb->(@addresses)
175 325
176Works similarly to its Socket counterpart, except that it uses a 326Works similarly to its Socket counterpart, except that it uses a
177callback. Also, if a host has only an IPv6 address, this might be passed 327callback. Also, if a host has only an IPv6 address, this might be passed
178to the callback instead (use the length to detect this - 4 for IPv4, 16 328to the callback instead (use the length to detect this - 4 for IPv4, 16
179for IPv6). 329for IPv6).
180 330
181Unlike the L<Socket> function of the same name, you can get multiple IPv4 331Unlike the L<Socket> function of the same name, you can get multiple IPv4
182and IPv6 addresses as result. 332and IPv6 addresses as result (and maybe even other adrdess types).
183 333
184=cut 334=cut
185 335
186sub inet_aton { 336sub inet_aton {
187 my ($name, $cb) = @_; 337 my ($name, $cb) = @_;
205 } 355 }
206 }); 356 });
207 } 357 }
208} 358}
209 359
360# check for broken platforms with extra field in sockaddr structure
361# kind of a rfc vs. bsd issue, as usual (ok, normally it's a
362# unix vs. bsd issue, a iso C vs. bsd issue or simply a
363# correctness vs. bsd issue.
364my $pack_family = (0x55 == Socket::sockaddr_family "\x55\x55")
365 ? "xC" : "S";
366
210=item $sa = AnyEvent::Socket::pack_sockaddr $port, $host 367=item $sa = AnyEvent::Socket::pack_sockaddr $service, $host
211 368
212Pack the given port/host combination into a binary sockaddr structure. Handles 369Pack the given port/host combination into a binary sockaddr
213both IPv4 and IPv6 host addresses. 370structure. Handles both IPv4 and IPv6 host addresses, as well as UNIX
371domain sockets (C<$host> == C<unix/> and C<$service> == absolute
372pathname).
214 373
215=cut 374=cut
216 375
217sub pack_sockaddr($$) { 376sub pack_sockaddr($$) {
218 if (4 == length $_[1]) { 377 my $af = address_family $_[1];
378
379 if ($af == AF_INET) {
219 Socket::pack_sockaddr_in $_[0], $_[1] 380 Socket::pack_sockaddr_in $_[0], $_[1]
220 } elsif (16 == length $_[1]) { 381 } elsif ($af == AF_INET6) {
221 pack "SnL a16 L", 382 pack "$pack_family nL a16 L",
222 AF_INET6, 383 AF_INET6,
223 $_[0], # port 384 $_[0], # port
224 0, # flowinfo 385 0, # flowinfo
225 $_[1], # addr 386 $_[1], # addr
226 0 # scope id 387 0 # scope id
388 } elsif ($af == AF_UNIX) {
389 Socket::pack_sockaddr_un $_[0]
227 } else { 390 } else {
228 Carp::croak "pack_sockaddr: invalid host"; 391 Carp::croak "pack_sockaddr: invalid host";
229 } 392 }
230} 393}
231 394
232=item ($port, $host) = AnyEvent::Socket::unpack_sockaddr $sa 395=item ($service, $host) = AnyEvent::Socket::unpack_sockaddr $sa
233 396
234Unpack the given binary sockaddr structure (as used by bind, getpeername 397Unpack the given binary sockaddr structure (as used by bind, getpeername
235etc.) into a C<$port, $host> combination. 398etc.) into a C<$service, $host> combination.
236 399
237Handles both IPv4 and IPv6 sockaddr structures. 400For IPv4 and IPv6, C<$service> is the port number and C<$host> the host
401address in network format (binary).
402
403For UNIX domain sockets, C<$service> is the absolute pathname and C<$host>
404is a special token that is understood by the other functions in this
405module (C<format_address> converts it to C<unix/>).
238 406
239=cut 407=cut
240 408
241sub unpack_sockaddr($) { 409sub unpack_sockaddr($) {
242 my $af = unpack "S", $_[0]; 410 my $af = Socket::sockaddr_family $_[0];
243 411
244 if ($af == AF_INET) { 412 if ($af == AF_INET) {
245 Socket::unpack_sockaddr_in $_[0] 413 Socket::unpack_sockaddr_in $_[0]
246 } elsif ($af == AF_INET6) { 414 } elsif ($af == AF_INET6) {
247 unpack "x2 n x4 a16", $_[0] 415 unpack "x2 n x4 a16", $_[0]
416 } elsif ($af == AF_UNIX) {
417 ((Socket::unpack_sockaddr_un $_[0]), pack "S", AF_UNIX)
248 } else { 418 } else {
249 Carp::croak "unpack_sockaddr: unsupported protocol family $af"; 419 Carp::croak "unpack_sockaddr: unsupported protocol family $af";
250 } 420 }
251} 421}
252 422
253sub _tcp_port($) { 423=item resolve_sockaddr $node, $service, $proto, $family, $type, $cb->([$family, $type, $proto, $sockaddr], ...)
254 $_[0] =~ /^(\d*)$/ and return $1*1;
255 424
256 (getservbyname $_[0], "tcp")[2] 425Tries to resolve the given nodename and service name into protocol families
426and sockaddr structures usable to connect to this node and service in a
427protocol-independent way. It works remotely similar to the getaddrinfo
428posix function.
429
430For internet addresses, C<$node> is either an IPv4 or IPv6 address or an
431internet hostname, and C<$service> is either a service name (port name
432from F</etc/services>) or a numerical port number. If both C<$node> and
433C<$service> are names, then SRV records will be consulted to find the real
434service, otherwise they will be used as-is. If you know that the service
435name is not in your services database, then you can specify the service in
436the format C<name=port> (e.g. C<http=80>).
437
438For UNIX domain sockets, C<$node> must be the string C<unix/> and
439C<$service> must be the absolute pathname of the socket. In this case,
440C<$proto> will be ignored.
441
442C<$proto> must be a protocol name, currently C<tcp>, C<udp> or
443C<sctp>. The default is currently C<tcp>, but in the future, this function
444might try to use other protocols such as C<sctp>, depending on the socket
445type and any SRV records it might find.
446
447C<$family> must be either C<0> (meaning any protocol is OK), C<4> (use
448only IPv4) or C<6> (use only IPv6). This setting might be influenced by
449C<$ENV{PERL_ANYEVENT_PROTOCOLS}>.
450
451C<$type> must be C<SOCK_STREAM>, C<SOCK_DGRAM> or C<SOCK_SEQPACKET> (or
452C<undef> in which case it gets automatically chosen).
453
454The callback will receive zero or more array references that contain
455C<$family, $type, $proto> for use in C<socket> and a binary
456C<$sockaddr> for use in C<connect> (or C<bind>).
457
458The application should try these in the order given.
459
460Example:
461
462 resolve_sockaddr "google.com", "http", 0, undef, undef, sub { ... };
463
464=cut
465
466# microsoft can't even get getprotobyname working (the etc/protocols file
467# gets lost fairly often on windows), so we have to hardcode some common
468# protocol numbers ourselves.
469our %PROTO_BYNAME;
470
471$PROTO_BYNAME{tcp} = &Socket::IPPROTO_TCP if defined &Socket::IPPROTO_TCP;
472$PROTO_BYNAME{udp} = &Socket::IPPROTO_UDP if defined &Socket::IPPROTO_UDP;
473$PROTO_BYNAME{icmp} = &Socket::IPPROTO_ICMP if defined &Socket::IPPROTO_ICMP;
474
475sub resolve_sockaddr($$$$$$) {
476 my ($node, $service, $proto, $family, $type, $cb) = @_;
477
478 if ($node eq "unix/") {
479 return $cb->() if $family || !/^\//; # no can do
480
481 return $cb->([AF_UNIX, $type, 0, Socket::pack_sockaddr_un $service]);
482 }
483
484 unless (AF_INET6) {
485 $family != 6
486 or return $cb->();
487
488 $family = 4;
489 }
490
491 $cb->() if $family == 4 && !$AnyEvent::PROTOCOL{ipv4};
492 $cb->() if $family == 6 && !$AnyEvent::PROTOCOL{ipv6};
493
494 $family ||= 4 unless $AnyEvent::PROTOCOL{ipv6};
495 $family ||= 6 unless $AnyEvent::PROTOCOL{ipv4};
496
497 $proto ||= "tcp";
498 $type ||= $proto eq "udp" ? SOCK_DGRAM : SOCK_STREAM;
499
500 my $proton = $PROTO_BYNAME{lc $proto} || (getprotobyname $proto)[2]
257 or Carp::croak "$_[0]: service unknown" 501 or Carp::croak "$proto: protocol unknown";
502
503 my $port;
504
505 if ($service =~ /^(\S+)=(\d+)$/) {
506 ($service, $port) = ($1, $2);
507 } elsif ($service =~ /^\d+$/) {
508 ($service, $port) = (undef, $service);
509 } else {
510 $port = (getservbyname $service, $proto)[2]
511 or Carp::croak "$service/$proto: service unknown";
512 }
513
514 my @target = [$node, $port];
515
516 # resolve a records / provide sockaddr structures
517 my $resolve = sub {
518 my @res;
519 my $cv = AnyEvent->condvar (cb => sub {
520 $cb->(
521 map $_->[2],
522 sort {
523 $AnyEvent::PROTOCOL{$b->[1]} <=> $AnyEvent::PROTOCOL{$a->[1]}
524 or $a->[0] <=> $b->[0]
525 }
526 @res
527 )
528 });
529
530 $cv->begin;
531 for my $idx (0 .. $#target) {
532 my ($node, $port) = @{ $target[$idx] };
533
534 if (my $noden = parse_address $node) {
535 my $af = address_family $noden;
536
537 if ($af == AF_INET && $family != 6) {
538 push @res, [$idx, "ipv4", [AF_INET, $type, $proton,
539 pack_sockaddr $port, $noden]]
540 }
541
542 if ($af == AF_INET6 && $family != 4) {
543 push @res, [$idx, "ipv6", [AF_INET6, $type, $proton,
544 pack_sockaddr $port, $noden]]
545 }
546 } else {
547 # ipv4
548 if ($family != 6) {
549 $cv->begin;
550 AnyEvent::DNS::a $node, sub {
551 push @res, [$idx, "ipv4", [AF_INET, $type, $proton,
552 pack_sockaddr $port, parse_ipv4 $_]]
553 for @_;
554 $cv->end;
555 };
556 }
557
558 # ipv6
559 if ($family != 4) {
560 $cv->begin;
561 AnyEvent::DNS::aaaa $node, sub {
562 push @res, [$idx, "ipv6", [AF_INET6, $type, $proton,
563 pack_sockaddr $port, parse_ipv6 $_]]
564 for @_;
565 $cv->end;
566 };
567 }
568 }
569 }
570 $cv->end;
571 };
572
573 # try srv records, if applicable
574 if ($node eq "localhost") {
575 @target = (["127.0.0.1", $port], ["::1", $port]);
576 &$resolve;
577 } elsif (defined $service && !parse_address $node) {
578 AnyEvent::DNS::srv $service, $proto, $node, sub {
579 my (@srv) = @_;
580
581 # no srv records, continue traditionally
582 @srv
583 or return &$resolve;
584
585 # the only srv record has "." ("" here) => abort
586 $srv[0][2] ne "" || $#srv
587 or return $cb->();
588
589 # use srv records then
590 @target = map ["$_->[3].", $_->[2]],
591 grep $_->[3] ne ".",
592 @srv;
593
594 &$resolve;
595 };
596 } else {
597 &$resolve;
598 }
258} 599}
259 600
260=item $guard = tcp_connect $host, $service, $connect_cb[, $prepare_cb] 601=item $guard = tcp_connect $host, $service, $connect_cb[, $prepare_cb]
261 602
262This is a convenience function that creates a TCP socket and makes a 100% 603This is a convenience function that creates a TCP socket and makes a 100%
263non-blocking connect to the given C<$host> (which can be a hostname or a 604non-blocking connect to the given C<$host> (which can be a hostname or
605a textual IP address, or the string C<unix/> for UNIX domain sockets)
264textual IP address) and C<$service> (which can be a numeric port number or 606and C<$service> (which can be a numeric port number or a service name,
265a service name, or a C<servicename=portnumber> string). 607or a C<servicename=portnumber> string, or the pathname to a UNIX domain
608socket).
266 609
267If both C<$host> and C<$port> are names, then this function will use SRV 610If both C<$host> and C<$port> are names, then this function will use SRV
268records to locate the real target(s). 611records to locate the real target(s).
269 612
270In either case, it will create a list of target hosts (e.g. for multihomed 613In either case, it will create a list of target hosts (e.g. for multihomed
313lessen the impact of this windows bug, a default timeout of 30 seconds 656lessen the impact of this windows bug, a default timeout of 30 seconds
314will be imposed on windows. Cygwin is not affected. 657will be imposed on windows. Cygwin is not affected.
315 658
316Simple Example: connect to localhost on port 22. 659Simple Example: connect to localhost on port 22.
317 660
318 tcp_connect localhost => 22, sub { 661 tcp_connect localhost => 22, sub {
319 my $fh = shift 662 my $fh = shift
320 or die "unable to connect: $!"; 663 or die "unable to connect: $!";
321 # do something 664 # do something
322 }; 665 };
323 666
324Complex Example: connect to www.google.com on port 80 and make a simple 667Complex Example: connect to www.google.com on port 80 and make a simple
325GET request without much error handling. Also limit the connection timeout 668GET request without much error handling. Also limit the connection timeout
326to 15 seconds. 669to 15 seconds.
327 670
357 # could call $fh->bind etc. here 700 # could call $fh->bind etc. here
358 701
359 15 702 15
360 }; 703 };
361 704
705Example: connect to a UNIX domain socket.
706
707 tcp_connect "unix/", "/tmp/.X11-unix/X0", sub {
708 ...
709 }
710
362=cut 711=cut
363 712
364sub tcp_connect($$$;$) { 713sub tcp_connect($$$;$) {
365 my ($host, $port, $connect, $prepare) = @_; 714 my ($host, $port, $connect, $prepare) = @_;
366 715
367 # see http://cr.yp.to/docs/connect.html for some background 716 # see http://cr.yp.to/docs/connect.html for some background
717 # also http://advogato.org/article/672.html
368 718
369 my %state = ( fh => undef ); 719 my %state = ( fh => undef );
370 720
371 # name resolution 721 # name/service to type/sockaddr resolution
372 AnyEvent::DNS::addr $host, $port, 0, 0, 0, sub { 722 resolve_sockaddr $host, $port, 0, 0, 0, sub {
373 my @target = @_; 723 my @target = @_;
374 724
375 $state{next} = sub { 725 $state{next} = sub {
376 return unless exists $state{fh}; 726 return unless exists $state{fh};
377 727
389 739
390 fh_nonblocking $state{fh}, 1; 740 fh_nonblocking $state{fh}, 1;
391 741
392 my $timeout = $prepare && $prepare->($state{fh}); 742 my $timeout = $prepare && $prepare->($state{fh});
393 743
394 $timeout ||= 30 if WIN32; 744 $timeout ||= 30 if AnyEvent::WIN32;
395 745
396 $state{to} = AnyEvent->timer (after => $timeout, cb => sub { 746 $state{to} = AnyEvent->timer (after => $timeout, cb => sub {
397 $! = &Errno::ETIMEDOUT; 747 $! = &Errno::ETIMEDOUT;
398 $state{next}(); 748 $state{next}();
399 }) if $timeout; 749 }) if $timeout;
410 760
411 my $guard = guard { 761 my $guard = guard {
412 %state = (); 762 %state = ();
413 }; 763 };
414 764
415 $connect->($state{fh}, format_ip $host, $port, sub { 765 $connect->($state{fh}, format_address $host, $port, sub {
416 $guard->cancel; 766 $guard->cancel;
417 $state{next}(); 767 $state{next}();
418 }); 768 });
419 } else { 769 } else {
420 # dummy read to fetch real error code 770 # dummy read to fetch real error code
424 }; 774 };
425 775
426 # now connect 776 # now connect
427 if (connect $state{fh}, $sockaddr) { 777 if (connect $state{fh}, $sockaddr) {
428 $connected->(); 778 $connected->();
429 } elsif ($! == &Errno::EINPROGRESS || $! == &Errno::EWOULDBLOCK) { # EINPROGRESS is POSIX 779 } elsif ($! == &Errno::EINPROGRESS # POSIX
780 || $! == &Errno::EWOULDBLOCK
781 # WSAEINPROGRESS intentionally not checked - it means something else entirely
782 || $! == AnyEvent::Util::WSAEINVAL # not convinced, but doesn't hurt
783 || $! == AnyEvent::Util::WSAEWOULDBLOCK) {
430 $state{ww} = AnyEvent->io (fh => $state{fh}, poll => 'w', cb => $connected); 784 $state{ww} = AnyEvent->io (fh => $state{fh}, poll => 'w', cb => $connected);
431 } else { 785 } else {
432 %state = (); 786 $state{next}();
433 $connect->();
434 } 787 }
435 }; 788 };
436 789
437 $! = &Errno::ENXIO; 790 $! = &Errno::ENXIO;
438 $state{next}(); 791 $state{next}();
439 }; 792 };
440 793
441 defined wantarray && guard { %state = () } 794 defined wantarray && guard { %state = () }
442} 795}
443 796
444=item $guard = tcp_server $host, $port, $accept_cb[, $prepare_cb] 797=item $guard = tcp_server $host, $service, $accept_cb[, $prepare_cb]
445 798
446Create and bind a TCP socket to the given host, and port, set the 799Create and bind a stream socket to the given host, and port, set the
447SO_REUSEADDR flag and call C<listen>. 800SO_REUSEADDR flag (if applicable) and call C<listen>. Unlike the name
801implies, this function can also bind on UNIX domain sockets.
448 802
449C<$host> must be an IPv4 or IPv6 address (or C<undef>, in which case it 803For internet sockets, C<$host> must be an IPv4 or IPv6 address (or
450binds either to C<0> or to C<::>, depending on whether IPv4 or IPv6 is the 804C<undef>, in which case it binds either to C<0> or to C<::>, depending
451preferred protocol). 805on whether IPv4 or IPv6 is the preferred protocol, and maybe to both in
806future versions, as applicable).
452 807
453To bind to the IPv4 wildcard address, use C<0>, to bind to the IPv6 808To bind to the IPv4 wildcard address, use C<0>, to bind to the IPv6
454wildcard address, use C<::>. 809wildcard address, use C<::>.
455 810
456The port is specified by C<$port>, which must be either a service name or 811The port is specified by C<$service>, which must be either a service name or
457a numeric port number (or C<0> or C<undef>, in which case an ephemeral 812a numeric port number (or C<0> or C<undef>, in which case an ephemeral
458port will be used). 813port will be used).
814
815For UNIX domain sockets, C<$host> must be C<unix/> and C<$service> must be
816the absolute pathname of the socket. This function will try to C<unlink>
817the socket before it tries to bind to it. See SECURITY CONSIDERATIONS,
818below.
459 819
460For each new connection that could be C<accept>ed, call the C<< 820For each new connection that could be C<accept>ed, call the C<<
461$accept_cb->($fh, $host, $port) >> with the file handle (in non-blocking 821$accept_cb->($fh, $host, $port) >> with the file handle (in non-blocking
462mode) as first and the peer host and port as second and third arguments 822mode) as first and the peer host and port as second and third arguments
463(see C<tcp_connect> for details). 823(see C<tcp_connect> for details).
475address and port number of the local socket endpoint as second and third 835address and port number of the local socket endpoint as second and third
476arguments. 836arguments.
477 837
478It should return the length of the listen queue (or C<0> for the default). 838It should return the length of the listen queue (or C<0> for the default).
479 839
840Note to IPv6 users: RFC-compliant behaviour for IPv6 sockets listening on
841C<::> is to bind to both IPv6 and IPv4 addresses by default on dual-stack
842hosts. Unfortunately, only GNU/Linux seems to implement this properly, so
843if you want both IPv4 and IPv6 listening sockets you should create the
844IPv6 socket first and then attempt to bind on the IPv4 socket, but ignore
845any C<EADDRINUSE> errors.
846
480Example: bind on some TCP port on the local machine and tell each client 847Example: bind on some TCP port on the local machine and tell each client
481to go away. 848to go away.
482 849
483 tcp_server undef, undef, sub { 850 tcp_server undef, undef, sub {
484 my ($fh, $host, $port) = @_; 851 my ($fh, $host, $port) = @_;
490 }; 857 };
491 858
492=cut 859=cut
493 860
494sub tcp_server($$$;$) { 861sub tcp_server($$$;$) {
495 my ($host, $port, $accept, $prepare) = @_; 862 my ($host, $service, $accept, $prepare) = @_;
496 863
497 $host = $AnyEvent::PROTOCOL{ipv4} < $AnyEvent::PROTOCOL{ipv6} && AF_INET6 864 $host = $AnyEvent::PROTOCOL{ipv4} < $AnyEvent::PROTOCOL{ipv6} && AF_INET6
498 ? "::" : "0" 865 ? "::" : "0"
499 unless defined $host; 866 unless defined $host;
500 867
501 my $ipn = parse_ip $host 868 my $ipn = parse_address $host
502 or Carp::croak "AnyEvent::Socket::tcp_server: cannot parse '$host' as IPv4 or IPv6 address"; 869 or Carp::croak "AnyEvent::Socket::tcp_server: cannot parse '$host' as host address";
503 870
504 my $domain = 4 == length $ipn ? AF_INET : AF_INET6; 871 my $af = address_family $ipn;
505 872
506 my %state; 873 my %state;
507 874
875 # win32 perl is too stupid to get this right :/
876 Carp::croak "tcp_server/socket: address family not supported"
877 if AnyEvent::WIN32 && $af == AF_UNIX;
878
508 socket $state{fh}, $domain, SOCK_STREAM, 0 879 socket $state{fh}, $af, SOCK_STREAM, 0
509 or Carp::croak "socket: $!"; 880 or Carp::croak "tcp_server/socket: $!";
510 881
882 if ($af == AF_INET || $af == AF_INET6) {
511 setsockopt $state{fh}, SOL_SOCKET, SO_REUSEADDR, 1 883 setsockopt $state{fh}, SOL_SOCKET, SO_REUSEADDR, 1
512 or Carp::croak "so_reuseaddr: $!"; 884 or Carp::croak "tcp_server/so_reuseaddr: $!"
885 unless AnyEvent::WIN32; # work around windows bug
513 886
887 unless ($service =~ /^\d*$/) {
888 $service = (getservbyname $service, "tcp")[2]
889 or Carp::croak "$service: service unknown"
890 }
891 } elsif ($af == AF_UNIX) {
892 unlink $service;
893 }
894
514 bind $state{fh}, pack_sockaddr _tcp_port $port, $ipn 895 bind $state{fh}, pack_sockaddr $service, $ipn
515 or Carp::croak "bind: $!"; 896 or Carp::croak "bind: $!";
516 897
517 fh_nonblocking $state{fh}, 1; 898 fh_nonblocking $state{fh}, 1;
518 899
519 my $len; 900 my $len;
520 901
521 if ($prepare) { 902 if ($prepare) {
522 my ($port, $host) = unpack_sockaddr getsockname $state{fh}; 903 my ($service, $host) = unpack_sockaddr getsockname $state{fh};
523 $len = $prepare && $prepare->($state{fh}, format_ip $host, $port); 904 $len = $prepare && $prepare->($state{fh}, format_address $host, $service);
524 } 905 }
525 906
526 $len ||= 128; 907 $len ||= 128;
527 908
528 listen $state{fh}, $len 909 listen $state{fh}, $len
530 911
531 $state{aw} = AnyEvent->io (fh => $state{fh}, poll => 'r', cb => sub { 912 $state{aw} = AnyEvent->io (fh => $state{fh}, poll => 'r', cb => sub {
532 # this closure keeps $state alive 913 # this closure keeps $state alive
533 while (my $peer = accept my $fh, $state{fh}) { 914 while (my $peer = accept my $fh, $state{fh}) {
534 fh_nonblocking $fh, 1; # POSIX requires inheritance, the outside world does not 915 fh_nonblocking $fh, 1; # POSIX requires inheritance, the outside world does not
916
535 my ($port, $host) = unpack_sockaddr $peer; 917 my ($service, $host) = unpack_sockaddr $peer;
536 $accept->($fh, format_ip $host, $port); 918 $accept->($fh, format_address $host, $service);
537 } 919 }
538 }); 920 });
539 921
540 defined wantarray 922 defined wantarray
541 ? guard { %state = () } # clear fh and watcher, which breaks the circular dependency 923 ? guard { %state = () } # clear fh and watcher, which breaks the circular dependency
544 926
5451; 9271;
546 928
547=back 929=back
548 930
931=head1 SECURITY CONSIDERATIONS
932
933This module is quite powerful, with with power comes the ability to abuse
934as well: If you accept "hostnames" and ports from untrusted sources,
935then note that this can be abused to delete files (host=C<unix/>). This
936is not really a problem with this module, however, as blindly accepting
937any address and protocol and trying to bind a server or connect to it is
938harmful in general.
939
549=head1 AUTHOR 940=head1 AUTHOR
550 941
551 Marc Lehmann <schmorp@schmorp.de> 942 Marc Lehmann <schmorp@schmorp.de>
552 http://home.schmorp.de/ 943 http://home.schmorp.de/
553 944

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines