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.35 by root, Wed May 28 21:23:41 2008 UTC vs.
Revision 1.90 by root, Thu Jul 16 04:16:25 2009 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
47use AnyEvent::DNS (); 47use AnyEvent::DNS ();
48 48
49use base 'Exporter'; 49use base 'Exporter';
50 50
51our @EXPORT = qw( 51our @EXPORT = qw(
52 parse_hostport
52 parse_ipv4 parse_ipv6 53 parse_ipv4 parse_ipv6
53 parse_ip parse_address 54 parse_ip parse_address
55 format_ipv4 format_ipv6
54 format_ip format_address 56 format_ip format_address
55 address_family 57 address_family
56 inet_aton 58 inet_aton
57 tcp_server 59 tcp_server
58 tcp_connect 60 tcp_connect
59); 61);
60 62
61our $VERSION = '1.0'; 63our $VERSION = 4.82;
62 64
63=item $ipn = parse_ipv4 $dotted_quad 65=item $ipn = parse_ipv4 $dotted_quad
64 66
65Tries to parse the given dotted quad IPv4 address and return it in 67Tries to parse the given dotted quad IPv4 address and return it in
66octet form (or undef when it isn't in a parsable format). Supports all 68octet form (or undef when it isn't in a parsable format). Supports all
78 80
79 # check leading parts against range 81 # check leading parts against range
80 return undef if grep $_ >= 256, @_[0 .. @_ - 2]; 82 return undef if grep $_ >= 256, @_[0 .. @_ - 2];
81 83
82 # check trailing part against range 84 # check trailing part against range
83 return undef if $_[-1] >= 1 << (8 * (4 - $#_)); 85 return undef if $_[-1] >= 2 ** (8 * (4 - $#_));
84 86
85 pack "N", (pop) 87 pack "N", (pop)
86 + ($_[0] << 24) 88 + ($_[0] << 24)
87 + ($_[1] << 16) 89 + ($_[1] << 16)
88 + ($_[2] << 8); 90 + ($_[2] << 8);
143 ? pack "S", AF_UNIX 145 ? pack "S", AF_UNIX
144 : undef 146 : undef
145 147
146} 148}
147 149
148=item $ipn = parse_address $text 150=item $ipn = parse_address $ip
149 151
150Combines C<parse_ipv4> and C<parse_ipv6> in one function. The address 152Combines C<parse_ipv4> and C<parse_ipv6> in one function. The address
151here refers to the host address (not socket address) in network form 153here refers to the host address (not socket address) in network form
152(binary). 154(binary).
153 155
154If the C<$text> is C<unix/>, then this function returns a special token 156If the C<$text> is C<unix/>, then this function returns a special token
155recognised by the other functions in this module to mean "UNIX domain 157recognised by the other functions in this module to mean "UNIX domain
156socket". 158socket".
157 159
160If the C<$text> to parse is a mapped IPv4 in IPv6 address (:ffff::<ipv4>),
161then it will be treated as an IPv4 address. If you don't want that, you
162have to call C<parse_ipv4> and/or C<parse_ipv6> manually.
163
164=item $ipn = AnyEvent::Socket::aton $ip
165
166Same as C<parse_address>, but not exported (think C<Socket::inet_aton> but
167I<without> name resolution).
168
158=cut 169=cut
159 170
160sub parse_address($) { 171sub parse_address($) {
161 &parse_ipv4 || &parse_ipv6 || &parse_unix 172 for (&parse_ipv6) {
173 if ($_) {
174 s/^\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff//;
175 return $_;
176 } else {
177 return &parse_ipv4 || &parse_unix
178 }
179 }
162} 180}
163 181
164*parse_ip =\&parse_address; #d# 182*aton = \&parse_address;
183
184=item ($host, $service) = parse_hostport $string[, $default_service]
185
186Splitting a string of the form C<hostname:port> is a common
187problem. Unfortunately, just splitting on the colon makes it hard to
188specify IPv6 addresses and doesn't support the less common but well
189standardised C<[ip literal]> syntax.
190
191This function tries to do this job in a better way, it supports the
192following formats, where C<port> can be a numerical port number of a
193service name, or a C<name=port> string, and the C< port> and C<:port>
194parts are optional. Also, everywhere where an IP address is supported
195a hostname or unix domain socket address is also supported (see
196C<parse_unix>).
197
198 hostname:port e.g. "www.linux.org", "www.x.de:443", "www.x.de:https=443"
199 ipv4:port e.g. "198.182.196.56", "127.1:22"
200 ipv6 e.g. "::1", "affe::1"
201 [ipv4or6]:port e.g. "[::1]", "[10.0.1]:80"
202 [ipv4or6] port e.g. "[127.0.0.1]", "[www.x.org] 17"
203 ipv4or6 port e.g. "::1 443", "10.0.0.1 smtp"
204
205It also supports defaulting the service name in a simple way by using
206C<$default_service> if no service was detected. If neither a service was
207detected nor a default was specified, then this function returns the
208empty list. The same happens when a parse error weas detected, such as a
209hostname with a colon in it (the function is rather conservative, though).
210
211Example:
212
213 print join ",", parse_hostport "localhost:443";
214 # => "localhost,443"
215
216 print join ",", parse_hostport "localhost", "https";
217 # => "localhost,https"
218
219 print join ",", parse_hostport "[::1]";
220 # => "," (empty list)
221
222=cut
223
224sub parse_hostport($;$) {
225 my ($host, $port);
226
227 for ("$_[0]") { # work on a copy, just in case, and also reset pos
228
229 # parse host, special cases: "ipv6" or "ipv6 port"
230 unless (
231 ($host) = /^\s* ([0-9a-fA-F:]*:[0-9a-fA-F:]*:[0-9a-fA-F\.:]*)/xgc
232 and parse_ipv6 $host
233 ) {
234 /^\s*/xgc;
235
236 if (/^ \[ ([^\[\]]+) \]/xgc) {
237 $host = $1;
238 } elsif (/^ ([^\[\]:\ ]+) /xgc) {
239 $host = $1;
240 } else {
241 return;
242 }
243 }
244
245 # parse port
246 if (/\G (?:\s+|:) ([^:[:space:]]+) \s*$/xgc) {
247 $port = $1;
248 } elsif (/\G\s*$/gc && length $_[1]) {
249 $port = $_[1];
250 } else {
251 return;
252 }
253 }
254
255 # hostnames must not contain :'s
256 return if $host =~ /:/ && !parse_ipv6 $host;
257
258 ($host, $port)
259}
165 260
166=item $sa_family = address_family $ipn 261=item $sa_family = address_family $ipn
167 262
168Returns the address family/protocol-family (AF_xxx/PF_xxx, in one value :) 263Returns the address family/protocol-family (AF_xxx/PF_xxx, in one value :)
169of the given host address in network format. 264of the given host address in network format.
176 : 16 == length $_[0] 271 : 16 == length $_[0]
177 ? AF_INET6 272 ? AF_INET6
178 : unpack "S", $_[0] 273 : unpack "S", $_[0]
179} 274}
180 275
276=item $text = format_ipv4 $ipn
277
278Expects a four octet string representing a binary IPv4 address and returns
279its textual format. Rarely used, see C<format_address> for a nicer
280interface.
281
282=item $text = format_ipv6 $ipn
283
284Expects a sixteen octet string representing a binary IPv6 address and
285returns its textual format. Rarely used, see C<format_address> for a
286nicer interface.
287
181=item $text = format_address $ipn 288=item $text = format_address $ipn
182 289
183Covnvert a host address in network format (e.g. 4 octets for IPv4 or 16 290Covnvert a host address in network format (e.g. 4 octets for IPv4 or 16
184octets for IPv6) and convert it into textual form. 291octets for IPv6) and convert it into textual form.
185 292
188This function works similarly to C<inet_ntop AF_INET || AF_INET6, ...>, 295This function works similarly to C<inet_ntop AF_INET || AF_INET6, ...>,
189except it automatically detects the address type. 296except it automatically detects the address type.
190 297
191Returns C<undef> if it cannot detect the type. 298Returns C<undef> if it cannot detect the type.
192 299
193=cut 300If the C<$ipn> is a mapped IPv4 in IPv6 address (:ffff::<ipv4>), then just
301the contained IPv4 address will be returned. If you do not want that, you
302have to call C<format_ipv6> manually.
194 303
195sub format_address; 304=item $text = AnyEvent::Socket::ntoa $ipn
305
306Same as format_address, but not exported (think C<inet_ntoa>).
307
308=cut
309
310sub format_ipv4($) {
311 join ".", unpack "C4", $_[0]
312}
313
314sub format_ipv6($) {
315 if (v0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 eq $_[0]) {
316 return "::";
317 } elsif (v0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1 eq $_[0]) {
318 return "::1";
319 } elsif (v0.0.0.0.0.0.0.0.0.0.0.0 eq substr $_[0], 0, 12) {
320 # v4compatible
321 return "::" . format_ipv4 substr $_[0], 12;
322 } elsif (v0.0.0.0.0.0.0.0.0.0.255.255 eq substr $_[0], 0, 12) {
323 # v4mapped
324 return "::ffff:" . format_ipv4 substr $_[0], 12;
325 } elsif (v0.0.0.0.0.0.0.0.255.255.0.0 eq substr $_[0], 0, 12) {
326 # v4translated
327 return "::ffff:0:" . format_ipv4 substr $_[0], 12;
328 } else {
329 my $ip = sprintf "%x:%x:%x:%x:%x:%x:%x:%x", unpack "n8", $_[0];
330
331 # this is rather sucky, I admit
332 $ip =~ s/^0:(?:0:)*(0$)?/::/
333 or $ip =~ s/(:0){7}$/::/ or $ip =~ s/(:0){7}/:/
334 or $ip =~ s/(:0){6}$/::/ or $ip =~ s/(:0){6}/:/
335 or $ip =~ s/(:0){5}$/::/ or $ip =~ s/(:0){5}/:/
336 or $ip =~ s/(:0){4}$/::/ or $ip =~ s/(:0){4}/:/
337 or $ip =~ s/(:0){3}$/::/ or $ip =~ s/(:0){3}/:/
338 or $ip =~ s/(:0){2}$/::/ or $ip =~ s/(:0){2}/:/
339 or $ip =~ s/(:0){1}$/::/ or $ip =~ s/(:0){1}/:/;
340 return $ip
341 }
342}
343
196sub format_address($) { 344sub format_address($) {
197 my $af = address_family $_[0]; 345 my $af = address_family $_[0];
198 if ($af == AF_INET) { 346 if ($af == AF_INET) {
199 return join ".", unpack "C4", $_[0] 347 return &format_ipv4;
200 } elsif ($af == AF_INET6) { 348 } elsif ($af == AF_INET6) {
201 if (v0.0.0.0.0.0.0.0.0.0.0.0 eq substr $_[0], 0, 12) {
202 # v4compatible
203 return "::" . format_address substr $_[0], 12;
204 } elsif (v0.0.0.0.0.0.0.0.0.0.255.255 eq substr $_[0], 0, 12) { 349 return (v0.0.0.0.0.0.0.0.0.0.255.255 eq substr $_[0], 0, 12)
205 # v4mapped 350 ? format_ipv4 substr $_[0], 12
206 return "::ffff:" . format_address substr $_[0], 12; 351 : &format_ipv6;
207 } elsif (v0.0.0.0.0.0.0.0.255.255.0.0 eq substr $_[0], 0, 12) {
208 # v4translated
209 return "::ffff:0:" . format_address substr $_[0], 12;
210 } else {
211 my $ip = sprintf "%x:%x:%x:%x:%x:%x:%x:%x", unpack "n8", $_[0];
212
213 $ip =~ s/^0:(?:0:)*(0$)?/::/
214 or $ip =~ s/(:0)+$/::/
215 or $ip =~ s/(:0)+/:/;
216 return $ip
217 }
218 } elsif ($af == AF_UNIX) { 352 } elsif ($af == AF_UNIX) {
219 return "unix/" 353 return "unix/"
220 } else { 354 } else {
221 return undef 355 return undef
222 } 356 }
223} 357}
224 358
225*format_ip = \&format_address; 359*ntoa = \&format_address;
226 360
227=item inet_aton $name_or_address, $cb->(@addresses) 361=item inet_aton $name_or_address, $cb->(@addresses)
228 362
229Works similarly to its Socket counterpart, except that it uses a 363Works similarly to its Socket counterpart, except that it uses a
230callback. Also, if a host has only an IPv6 address, this might be passed 364callback. Also, if a host has only an IPv6 address, this might be passed
262 396
263# check for broken platforms with extra field in sockaddr structure 397# check for broken platforms with extra field in sockaddr structure
264# kind of a rfc vs. bsd issue, as usual (ok, normally it's a 398# kind of a rfc vs. bsd issue, as usual (ok, normally it's a
265# unix vs. bsd issue, a iso C vs. bsd issue or simply a 399# unix vs. bsd issue, a iso C vs. bsd issue or simply a
266# correctness vs. bsd issue. 400# correctness vs. bsd issue.
267my $pack_family = 0x55 == Socket::sockaddr_family "\x55\x55" 401my $pack_family = (0x55 == Socket::sockaddr_family "\x55\x55")
268 ? "xC" : "S"; 402 ? "xC" : "S";
269 403
270=item $sa = AnyEvent::Socket::pack_sockaddr $service, $host 404=item $sa = AnyEvent::Socket::pack_sockaddr $service, $host
271 405
272Pack the given port/host combination into a binary sockaddr 406Pack the given port/host combination into a binary sockaddr
346C<sctp>. The default is currently C<tcp>, but in the future, this function 480C<sctp>. The default is currently C<tcp>, but in the future, this function
347might try to use other protocols such as C<sctp>, depending on the socket 481might try to use other protocols such as C<sctp>, depending on the socket
348type and any SRV records it might find. 482type and any SRV records it might find.
349 483
350C<$family> must be either C<0> (meaning any protocol is OK), C<4> (use 484C<$family> must be either C<0> (meaning any protocol is OK), C<4> (use
351only IPv4) or C<6> (use only IPv6). This setting might be influenced by 485only IPv4) or C<6> (use only IPv6). The default is influenced by
352C<$ENV{PERL_ANYEVENT_PROTOCOLS}>. 486C<$ENV{PERL_ANYEVENT_PROTOCOLS}>.
353 487
354C<$type> must be C<SOCK_STREAM>, C<SOCK_DGRAM> or C<SOCK_SEQPACKET> (or 488C<$type> must be C<SOCK_STREAM>, C<SOCK_DGRAM> or C<SOCK_SEQPACKET> (or
355C<undef> in which case it gets automatically chosen). 489C<undef> in which case it gets automatically chosen to be C<SOCK_STREAM>
490unless C<$proto> is C<udp>).
356 491
357The callback will receive zero or more array references that contain 492The callback will receive zero or more array references that contain
358C<$family, $type, $proto> for use in C<socket> and a binary 493C<$family, $type, $proto> for use in C<socket> and a binary
359C<$sockaddr> for use in C<connect> (or C<bind>). 494C<$sockaddr> for use in C<connect> (or C<bind>).
360 495
364 499
365 resolve_sockaddr "google.com", "http", 0, undef, undef, sub { ... }; 500 resolve_sockaddr "google.com", "http", 0, undef, undef, sub { ... };
366 501
367=cut 502=cut
368 503
504# microsoft can't even get getprotobyname working (the etc/protocols file
505# gets lost fairly often on windows), so we have to hardcode some common
506# protocol numbers ourselves.
507our %PROTO_BYNAME;
508
509$PROTO_BYNAME{tcp} = &Socket::IPPROTO_TCP if defined &Socket::IPPROTO_TCP;
510$PROTO_BYNAME{udp} = &Socket::IPPROTO_UDP if defined &Socket::IPPROTO_UDP;
511$PROTO_BYNAME{icmp} = &Socket::IPPROTO_ICMP if defined &Socket::IPPROTO_ICMP;
512
369sub resolve_sockaddr($$$$$$) { 513sub resolve_sockaddr($$$$$$) {
370 my ($node, $service, $proto, $family, $type, $cb) = @_; 514 my ($node, $service, $proto, $family, $type, $cb) = @_;
371 515
372 if ($node eq "unix/") { 516 if ($node eq "unix/") {
373 return $cb->() if $family || !/^\//; # no can do 517 return $cb->() if $family || $service !~ /^\//; # no can do
374 518
375 return $cb->([AF_UNIX, $type, 0, Socket::pack_sockaddr_un $service]); 519 return $cb->([AF_UNIX, defined $type ? $type : SOCK_STREAM, 0, Socket::pack_sockaddr_un $service]);
376 } 520 }
377 521
378 unless (AF_INET6) { 522 unless (AF_INET6) {
379 $family != 6 523 $family != 6
380 or return $cb->(); 524 or return $cb->();
389 $family ||= 6 unless $AnyEvent::PROTOCOL{ipv4}; 533 $family ||= 6 unless $AnyEvent::PROTOCOL{ipv4};
390 534
391 $proto ||= "tcp"; 535 $proto ||= "tcp";
392 $type ||= $proto eq "udp" ? SOCK_DGRAM : SOCK_STREAM; 536 $type ||= $proto eq "udp" ? SOCK_DGRAM : SOCK_STREAM;
393 537
394 my $proton = (getprotobyname $proto)[2] 538 my $proton = $PROTO_BYNAME{lc $proto} || (getprotobyname $proto)[2]
395 or Carp::croak "$proto: protocol unknown"; 539 or Carp::croak "$proto: protocol unknown";
396 540
397 my $port; 541 my $port;
398 542
399 if ($service =~ /^(\S+)=(\d+)$/) { 543 if ($service =~ /^(\S+)=(\d+)$/) {
424 $cv->begin; 568 $cv->begin;
425 for my $idx (0 .. $#target) { 569 for my $idx (0 .. $#target) {
426 my ($node, $port) = @{ $target[$idx] }; 570 my ($node, $port) = @{ $target[$idx] };
427 571
428 if (my $noden = parse_address $node) { 572 if (my $noden = parse_address $node) {
573 my $af = address_family $noden;
574
429 if (4 == length $noden && $family != 6) { 575 if ($af == AF_INET && $family != 6) {
430 push @res, [$idx, "ipv4", [AF_INET, $type, $proton, 576 push @res, [$idx, "ipv4", [AF_INET, $type, $proton,
431 pack_sockaddr $port, $noden]] 577 pack_sockaddr $port, $noden]]
432 } 578 }
433 579
434 if (16 == length $noden && $family != 4) { 580 if ($af == AF_INET6 && $family != 4) {
435 push @res, [$idx, "ipv6", [AF_INET6, $type, $proton, 581 push @res, [$idx, "ipv6", [AF_INET6, $type, $proton,
436 pack_sockaddr $port, $noden]] 582 pack_sockaddr $port, $noden]]
437 } 583 }
438 } else { 584 } else {
439 # ipv4 585 # ipv4
440 if ($family != 6) { 586 if ($family != 6) {
441 $cv->begin; 587 $cv->begin;
442 a $node, sub { 588 AnyEvent::DNS::a $node, sub {
443 push @res, [$idx, "ipv4", [AF_INET, $type, $proton, 589 push @res, [$idx, "ipv4", [AF_INET, $type, $proton,
444 pack_sockaddr $port, parse_ipv4 $_]] 590 pack_sockaddr $port, parse_ipv4 $_]]
445 for @_; 591 for @_;
446 $cv->end; 592 $cv->end;
447 }; 593 };
448 } 594 }
449 595
450 # ipv6 596 # ipv6
451 if ($family != 4) { 597 if ($family != 4) {
452 $cv->begin; 598 $cv->begin;
453 aaaa $node, sub { 599 AnyEvent::DNS::aaaa $node, sub {
454 push @res, [$idx, "ipv6", [AF_INET6, $type, $proton, 600 push @res, [$idx, "ipv6", [AF_INET6, $type, $proton,
455 pack_sockaddr $port, parse_ipv6 $_]] 601 pack_sockaddr $port, parse_ipv6 $_]]
456 for @_; 602 for @_;
457 $cv->end; 603 $cv->end;
458 }; 604 };
465 # try srv records, if applicable 611 # try srv records, if applicable
466 if ($node eq "localhost") { 612 if ($node eq "localhost") {
467 @target = (["127.0.0.1", $port], ["::1", $port]); 613 @target = (["127.0.0.1", $port], ["::1", $port]);
468 &$resolve; 614 &$resolve;
469 } elsif (defined $service && !parse_address $node) { 615 } elsif (defined $service && !parse_address $node) {
470 srv $service, $proto, $node, sub { 616 AnyEvent::DNS::srv $service, $proto, $node, sub {
471 my (@srv) = @_; 617 my (@srv) = @_;
472 618
473 # no srv records, continue traditionally 619 # no srv records, continue traditionally
474 @srv 620 @srv
475 or return &$resolve; 621 or return &$resolve;
476 622
477 # only srv record has "." => abort 623 # the only srv record has "." ("" here) => abort
478 $srv[0][2] ne "." || $#srv 624 $srv[0][2] ne "" || $#srv
479 or return $cb->(); 625 or return $cb->();
480 626
481 # use srv records then 627 # use srv records then
482 @target = map ["$_->[3].", $_->[2]], 628 @target = map ["$_->[3].", $_->[2]],
483 grep $_->[3] ne ".", 629 grep $_->[3] ne ".",
548lessen the impact of this windows bug, a default timeout of 30 seconds 694lessen the impact of this windows bug, a default timeout of 30 seconds
549will be imposed on windows. Cygwin is not affected. 695will be imposed on windows. Cygwin is not affected.
550 696
551Simple Example: connect to localhost on port 22. 697Simple Example: connect to localhost on port 22.
552 698
553 tcp_connect localhost => 22, sub { 699 tcp_connect localhost => 22, sub {
554 my $fh = shift 700 my $fh = shift
555 or die "unable to connect: $!"; 701 or die "unable to connect: $!";
556 # do something 702 # do something
557 }; 703 };
558 704
559Complex Example: connect to www.google.com on port 80 and make a simple 705Complex Example: connect to www.google.com on port 80 and make a simple
560GET request without much error handling. Also limit the connection timeout 706GET request without much error handling. Also limit the connection timeout
561to 15 seconds. 707to 15 seconds.
562 708
566 or die "unable to connect: $!"; 712 or die "unable to connect: $!";
567 713
568 my $handle; # avoid direct assignment so on_eof has it in scope. 714 my $handle; # avoid direct assignment so on_eof has it in scope.
569 $handle = new AnyEvent::Handle 715 $handle = new AnyEvent::Handle
570 fh => $fh, 716 fh => $fh,
717 on_error => sub {
718 warn "error $_[2]\n";
719 },
571 on_eof => sub { 720 on_eof => sub {
572 undef $handle; # keep it alive till eof 721 $handle->destroy; # destroy handle
573 warn "done.\n"; 722 warn "done.\n";
574 }; 723 };
575 724
576 $handle->push_write ("GET / HTTP/1.0\015\012\015\012"); 725 $handle->push_write ("GET / HTTP/1.0\015\012\015\012");
577 726
609 # also http://advogato.org/article/672.html 758 # also http://advogato.org/article/672.html
610 759
611 my %state = ( fh => undef ); 760 my %state = ( fh => undef );
612 761
613 # name/service to type/sockaddr resolution 762 # name/service to type/sockaddr resolution
614 resolve_sockaddr $host, $port, 0, 0, 0, sub { 763 resolve_sockaddr $host, $port, 0, 0, undef, sub {
615 my @target = @_; 764 my @target = @_;
616 765
617 $state{next} = sub { 766 $state{next} = sub {
618 return unless exists $state{fh}; 767 return unless exists $state{fh};
619 768
634 my $timeout = $prepare && $prepare->($state{fh}); 783 my $timeout = $prepare && $prepare->($state{fh});
635 784
636 $timeout ||= 30 if AnyEvent::WIN32; 785 $timeout ||= 30 if AnyEvent::WIN32;
637 786
638 $state{to} = AnyEvent->timer (after => $timeout, cb => sub { 787 $state{to} = AnyEvent->timer (after => $timeout, cb => sub {
639 $! = &Errno::ETIMEDOUT; 788 $! = Errno::ETIMEDOUT;
640 $state{next}(); 789 $state{next}();
641 }) if $timeout; 790 }) if $timeout;
642 791
643 # called when the connect was successful, which, 792 # called when the connect was successful, which,
644 # in theory, could be the case immediately (but never is in practise) 793 # in theory, could be the case immediately (but never is in practise)
645 my $connected = sub { 794 $state{connected} = sub {
646 delete $state{ww};
647 delete $state{to};
648
649 # we are connected, or maybe there was an error 795 # we are connected, or maybe there was an error
650 if (my $sin = getpeername $state{fh}) { 796 if (my $sin = getpeername $state{fh}) {
651 my ($port, $host) = unpack_sockaddr $sin; 797 my ($port, $host) = unpack_sockaddr $sin;
652 798
799 delete $state{ww}; delete $state{to};
800
653 my $guard = guard { 801 my $guard = guard { %state = () };
654 %state = ();
655 };
656 802
657 $connect->($state{fh}, format_address $host, $port, sub { 803 $connect->(delete $state{fh}, format_address $host, $port, sub {
658 $guard->cancel; 804 $guard->cancel;
659 $state{next}(); 805 $state{next}();
660 }); 806 });
661 } else { 807 } else {
662 # dummy read to fetch real error code 808 # dummy read to fetch real error code
663 sysread $state{fh}, my $buf, 1 if $! == &Errno::ENOTCONN; 809 sysread $state{fh}, my $buf, 1 if $! == Errno::ENOTCONN;
810
811 return if $! == Errno::EAGAIN; # skip spurious wake-ups
812
813 delete $state{ww}; delete $state{to};
814
664 $state{next}(); 815 $state{next}();
665 } 816 }
666 }; 817 };
667 818
668 # now connect 819 # now connect
669 if (connect $state{fh}, $sockaddr) { 820 if (connect $state{fh}, $sockaddr) {
670 $connected->(); 821 $state{connected}->();
671 } elsif ($! == &Errno::EINPROGRESS # POSIX 822 } elsif ($! == Errno::EINPROGRESS # POSIX
672 || $! == &Errno::EWOULDBLOCK 823 || $! == Errno::EWOULDBLOCK
673 # WSAEINPROGRESS intentionally not checked - it means something else entirely 824 # WSAEINPROGRESS intentionally not checked - it means something else entirely
674 || $! == AnyEvent::Util::WSAEINVAL # not convinced, but doesn't hurt 825 || $! == AnyEvent::Util::WSAEINVAL # not convinced, but doesn't hurt
675 || $! == AnyEvent::Util::WSAEWOULDBLOCK) { 826 || $! == AnyEvent::Util::WSAEWOULDBLOCK) {
676 $state{ww} = AnyEvent->io (fh => $state{fh}, poll => 'w', cb => $connected); 827 $state{ww} = AnyEvent->io (fh => $state{fh}, poll => 'w', cb => $state{connected});
677 } else { 828 } else {
678 $state{next}(); 829 $state{next}();
679 } 830 }
680 }; 831 };
681 832
682 $! = &Errno::ENXIO; 833 $! = Errno::ENXIO;
683 $state{next}(); 834 $state{next}();
684 }; 835 };
685 836
686 defined wantarray && guard { %state = () } 837 defined wantarray && guard { %state = () }
687} 838}
691Create and bind a stream socket to the given host, and port, set the 842Create and bind a stream socket to the given host, and port, set the
692SO_REUSEADDR flag (if applicable) and call C<listen>. Unlike the name 843SO_REUSEADDR flag (if applicable) and call C<listen>. Unlike the name
693implies, this function can also bind on UNIX domain sockets. 844implies, this function can also bind on UNIX domain sockets.
694 845
695For internet sockets, C<$host> must be an IPv4 or IPv6 address (or 846For internet sockets, C<$host> must be an IPv4 or IPv6 address (or
696C<undef>, in which case it binds either to C<0> or to C<::>, depending on 847C<undef>, in which case it binds either to C<0> or to C<::>, depending
697whether IPv4 or IPv6 is the preferred protocol). 848on whether IPv4 or IPv6 is the preferred protocol, and maybe to both in
849future versions, as applicable).
698 850
699To bind to the IPv4 wildcard address, use C<0>, to bind to the IPv6 851To bind to the IPv4 wildcard address, use C<0>, to bind to the IPv6
700wildcard address, use C<::>. 852wildcard address, use C<::>.
701 853
702The port is specified by C<$service>, which must be either a service name or 854The port is specified by C<$service>, which must be either a service name or
726address and port number of the local socket endpoint as second and third 878address and port number of the local socket endpoint as second and third
727arguments. 879arguments.
728 880
729It should return the length of the listen queue (or C<0> for the default). 881It should return the length of the listen queue (or C<0> for the default).
730 882
883Note to IPv6 users: RFC-compliant behaviour for IPv6 sockets listening on
884C<::> is to bind to both IPv6 and IPv4 addresses by default on dual-stack
885hosts. Unfortunately, only GNU/Linux seems to implement this properly, so
886if you want both IPv4 and IPv6 listening sockets you should create the
887IPv6 socket first and then attempt to bind on the IPv4 socket, but ignore
888any C<EADDRINUSE> errors.
889
731Example: bind on some TCP port on the local machine and tell each client 890Example: bind on some TCP port on the local machine and tell each client
732to go away. 891to go away.
733 892
734 tcp_server undef, undef, sub { 893 tcp_server undef, undef, sub {
735 my ($fh, $host, $port) = @_; 894 my ($fh, $host, $port) = @_;
738 }, sub { 897 }, sub {
739 my ($fh, $thishost, $thisport) = @_; 898 my ($fh, $thishost, $thisport) = @_;
740 warn "bound to $thishost, port $thisport\n"; 899 warn "bound to $thishost, port $thisport\n";
741 }; 900 };
742 901
902Example: bind a server on a unix domain socket.
903
904 tcp_server "unix/", "/tmp/mydir/mysocket", sub {
905 my ($fh) = @_;
906 };
907
743=cut 908=cut
744 909
745sub tcp_server($$$;$) { 910sub tcp_server($$$;$) {
746 my ($host, $service, $accept, $prepare) = @_; 911 my ($host, $service, $accept, $prepare) = @_;
747 912
754 919
755 my $af = address_family $ipn; 920 my $af = address_family $ipn;
756 921
757 my %state; 922 my %state;
758 923
924 # win32 perl is too stupid to get this right :/
925 Carp::croak "tcp_server/socket: address family not supported"
926 if AnyEvent::WIN32 && $af == AF_UNIX;
927
759 socket $state{fh}, $af, SOCK_STREAM, 0 928 socket $state{fh}, $af, SOCK_STREAM, 0
760 or Carp::croak "socket: $!"; 929 or Carp::croak "tcp_server/socket: $!";
761 930
762 if ($af == AF_INET || $af == AF_INET6) { 931 if ($af == AF_INET || $af == AF_INET6) {
763 setsockopt $state{fh}, SOL_SOCKET, SO_REUSEADDR, 1 932 setsockopt $state{fh}, SOL_SOCKET, SO_REUSEADDR, 1
764 or Carp::croak "so_reuseaddr: $!" 933 or Carp::croak "tcp_server/so_reuseaddr: $!"
765 unless !AnyEvent::WIN32; # work around windows bug 934 unless AnyEvent::WIN32; # work around windows bug
766 935
767 unless ($service =~ /^\d*$/) { 936 unless ($service =~ /^\d*$/) {
768 $service = (getservbyname $service, "tcp")[2] 937 $service = (getservbyname $service, "tcp")[2]
769 or Carp::croak "$service: service unknown" 938 or Carp::croak "$service: service unknown"
770 } 939 }
791 960
792 $state{aw} = AnyEvent->io (fh => $state{fh}, poll => 'r', cb => sub { 961 $state{aw} = AnyEvent->io (fh => $state{fh}, poll => 'r', cb => sub {
793 # this closure keeps $state alive 962 # this closure keeps $state alive
794 while (my $peer = accept my $fh, $state{fh}) { 963 while (my $peer = accept my $fh, $state{fh}) {
795 fh_nonblocking $fh, 1; # POSIX requires inheritance, the outside world does not 964 fh_nonblocking $fh, 1; # POSIX requires inheritance, the outside world does not
965
796 my ($service, $host) = unpack_sockaddr $peer; 966 my ($service, $host) = unpack_sockaddr $peer;
797 $accept->($fh, format_address $host, $service); 967 $accept->($fh, format_address $host, $service);
798 } 968 }
799 }); 969 });
800 970
805 975
8061; 9761;
807 977
808=back 978=back
809 979
980=head1 SECURITY CONSIDERATIONS
981
982This module is quite powerful, with with power comes the ability to abuse
983as well: If you accept "hostnames" and ports from untrusted sources,
984then note that this can be abused to delete files (host=C<unix/>). This
985is not really a problem with this module, however, as blindly accepting
986any address and protocol and trying to bind a server or connect to it is
987harmful in general.
988
810=head1 AUTHOR 989=head1 AUTHOR
811 990
812 Marc Lehmann <schmorp@schmorp.de> 991 Marc Lehmann <schmorp@schmorp.de>
813 http://home.schmorp.de/ 992 http://home.schmorp.de/
814 993

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines