… | |
… | |
33 | |
33 | |
34 | =cut |
34 | =cut |
35 | |
35 | |
36 | package AnyEvent::Socket; |
36 | package AnyEvent::Socket; |
37 | |
37 | |
38 | no warnings; |
|
|
39 | use strict; |
|
|
40 | |
|
|
41 | use Carp (); |
38 | use Carp (); |
42 | use Errno (); |
39 | use Errno (); |
43 | use Socket qw(AF_INET AF_UNIX SOCK_STREAM SOCK_DGRAM SOL_SOCKET SO_REUSEADDR); |
40 | use Socket qw(AF_INET AF_UNIX SOCK_STREAM SOCK_DGRAM SOL_SOCKET SO_REUSEADDR); |
44 | |
41 | |
45 | use AnyEvent (); |
42 | use AnyEvent (); BEGIN { AnyEvent::common_sense } |
46 | use AnyEvent::Util qw(guard fh_nonblocking AF_INET6); |
43 | use AnyEvent::Util qw(guard fh_nonblocking AF_INET6); |
47 | use AnyEvent::DNS (); |
44 | use AnyEvent::DNS (); |
48 | |
45 | |
49 | use base 'Exporter'; |
46 | use base 'Exporter'; |
50 | |
47 | |
51 | our @EXPORT = qw( |
48 | our @EXPORT = qw( |
|
|
49 | getprotobyname |
52 | parse_hostport |
50 | parse_hostport |
53 | parse_ipv4 parse_ipv6 |
51 | parse_ipv4 parse_ipv6 |
54 | parse_ip parse_address |
52 | parse_ip parse_address |
55 | format_ipv4 format_ipv6 |
53 | format_ipv4 format_ipv6 |
56 | format_ip format_address |
54 | format_ip format_address |
… | |
… | |
58 | inet_aton |
56 | inet_aton |
59 | tcp_server |
57 | tcp_server |
60 | tcp_connect |
58 | tcp_connect |
61 | ); |
59 | ); |
62 | |
60 | |
63 | our $VERSION = 4.82; |
61 | our $VERSION = 4.881; |
64 | |
62 | |
65 | =item $ipn = parse_ipv4 $dotted_quad |
63 | =item $ipn = parse_ipv4 $dotted_quad |
66 | |
64 | |
67 | Tries to parse the given dotted quad IPv4 address and return it in |
65 | Tries to parse the given dotted quad IPv4 address and return it in |
68 | octet form (or undef when it isn't in a parsable format). Supports all |
66 | octet form (or undef when it isn't in a parsable format). Supports all |
… | |
… | |
179 | } |
177 | } |
180 | } |
178 | } |
181 | |
179 | |
182 | *aton = \&parse_address; |
180 | *aton = \&parse_address; |
183 | |
181 | |
|
|
182 | =item ($name, $aliases, $proto) = getprotobyname $name |
|
|
183 | |
|
|
184 | Works like the builtin function of the same name, except it tries hard to |
|
|
185 | work even on broken platforms (well, that's windows), where getprotobyname |
|
|
186 | is traditionally very unreliable. |
|
|
187 | |
|
|
188 | =cut |
|
|
189 | |
|
|
190 | # microsoft can't even get getprotobyname working (the etc/protocols file |
|
|
191 | # gets lost fairly often on windows), so we have to hardcode some common |
|
|
192 | # protocol numbers ourselves. |
|
|
193 | our %PROTO_BYNAME; |
|
|
194 | |
|
|
195 | $PROTO_BYNAME{tcp} = Socket::IPPROTO_TCP () if defined &Socket::IPPROTO_TCP; |
|
|
196 | $PROTO_BYNAME{udp} = Socket::IPPROTO_UDP () if defined &Socket::IPPROTO_UDP; |
|
|
197 | $PROTO_BYNAME{icmp} = Socket::IPPROTO_ICMP() if defined &Socket::IPPROTO_ICMP; |
|
|
198 | |
|
|
199 | sub getprotobyname($) { |
|
|
200 | my $name = lc shift; |
|
|
201 | |
|
|
202 | defined (my $proton = $PROTO_BYNAME{$name} || (getprotobyname $name)[2]) |
|
|
203 | or return; |
|
|
204 | |
|
|
205 | ($name, uc $name, $proton) |
|
|
206 | } |
|
|
207 | |
184 | =item ($host, $service) = parse_hostport $string[, $default_service] |
208 | =item ($host, $service) = parse_hostport $string[, $default_service] |
185 | |
209 | |
186 | Splitting a string of the form C<hostname:port> is a common |
210 | Splitting a string of the form C<hostname:port> is a common |
187 | problem. Unfortunately, just splitting on the colon makes it hard to |
211 | problem. Unfortunately, just splitting on the colon makes it hard to |
188 | specify IPv6 addresses and doesn't support the less common but well |
212 | specify IPv6 addresses and doesn't support the less common but well |
… | |
… | |
203 | ipv4or6 port e.g. "::1 443", "10.0.0.1 smtp" |
227 | ipv4or6 port e.g. "::1 443", "10.0.0.1 smtp" |
204 | |
228 | |
205 | It also supports defaulting the service name in a simple way by using |
229 | It also supports defaulting the service name in a simple way by using |
206 | C<$default_service> if no service was detected. If neither a service was |
230 | C<$default_service> if no service was detected. If neither a service was |
207 | detected nor a default was specified, then this function returns the |
231 | detected nor a default was specified, then this function returns the |
208 | empty list. The same happens when a parse error weas detected, such as a |
232 | empty list. The same happens when a parse error was detected, such as a |
209 | hostname with a colon in it (the function is rather conservative, though). |
233 | hostname with a colon in it (the function is rather conservative, though). |
210 | |
234 | |
211 | Example: |
235 | Example: |
212 | |
236 | |
213 | print join ",", parse_hostport "localhost:443"; |
237 | print join ",", parse_hostport "localhost:443"; |
… | |
… | |
392 | } |
416 | } |
393 | }); |
417 | }); |
394 | } |
418 | } |
395 | } |
419 | } |
396 | |
420 | |
|
|
421 | BEGIN { |
|
|
422 | *sockaddr_family = $Socket::VERSION >= 1.75 |
|
|
423 | ? \&Socket::sockaddr_family |
|
|
424 | : # for 5.6.x, we need to do something much more horrible |
|
|
425 | (Socket::pack_sockaddr_in 0x5555, "\x55\x55\x55\x55" |
|
|
426 | | eval { Socket::pack_sockaddr_un "U" }) =~ /^\x00/ |
|
|
427 | ? sub { unpack "xC", $_[0] } |
|
|
428 | : sub { unpack "S" , $_[0] }; |
|
|
429 | } |
|
|
430 | |
397 | # check for broken platforms with extra field in sockaddr structure |
431 | # check for broken platforms with extra field in sockaddr structure |
398 | # kind of a rfc vs. bsd issue, as usual (ok, normally it's a |
432 | # kind of a rfc vs. bsd issue, as usual (ok, normally it's a |
399 | # unix vs. bsd issue, a iso C vs. bsd issue or simply a |
433 | # unix vs. bsd issue, a iso C vs. bsd issue or simply a |
400 | # correctness vs. bsd issue. |
434 | # correctness vs. bsd issue.) |
401 | my $pack_family = (0x55 == Socket::sockaddr_family "\x55\x55") |
435 | my $pack_family = 0x55 == sockaddr_family ("\x55\x55") |
402 | ? "xC" : "S"; |
436 | ? "xC" : "S"; |
403 | |
437 | |
404 | =item $sa = AnyEvent::Socket::pack_sockaddr $service, $host |
438 | =item $sa = AnyEvent::Socket::pack_sockaddr $service, $host |
405 | |
439 | |
406 | Pack the given port/host combination into a binary sockaddr |
440 | Pack the given port/host combination into a binary sockaddr |
… | |
… | |
442 | module (C<format_address> converts it to C<unix/>). |
476 | module (C<format_address> converts it to C<unix/>). |
443 | |
477 | |
444 | =cut |
478 | =cut |
445 | |
479 | |
446 | sub unpack_sockaddr($) { |
480 | sub unpack_sockaddr($) { |
447 | my $af = Socket::sockaddr_family $_[0]; |
481 | my $af = sockaddr_family $_[0]; |
448 | |
482 | |
449 | if ($af == AF_INET) { |
483 | if ($af == AF_INET) { |
450 | Socket::unpack_sockaddr_in $_[0] |
484 | Socket::unpack_sockaddr_in $_[0] |
451 | } elsif ($af == AF_INET6) { |
485 | } elsif ($af == AF_INET6) { |
452 | unpack "x2 n x4 a16", $_[0] |
486 | unpack "x2 n x4 a16", $_[0] |
… | |
… | |
499 | |
533 | |
500 | resolve_sockaddr "google.com", "http", 0, undef, undef, sub { ... }; |
534 | resolve_sockaddr "google.com", "http", 0, undef, undef, sub { ... }; |
501 | |
535 | |
502 | =cut |
536 | =cut |
503 | |
537 | |
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. |
|
|
507 | our %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 | |
|
|
513 | sub resolve_sockaddr($$$$$$) { |
538 | sub resolve_sockaddr($$$$$$) { |
514 | my ($node, $service, $proto, $family, $type, $cb) = @_; |
539 | my ($node, $service, $proto, $family, $type, $cb) = @_; |
515 | |
540 | |
516 | if ($node eq "unix/") { |
541 | if ($node eq "unix/") { |
517 | return $cb->() if $family || $service !~ /^\//; # no can do |
542 | return $cb->() if $family || $service !~ /^\//; # no can do |
… | |
… | |
533 | $family ||= 6 unless $AnyEvent::PROTOCOL{ipv4}; |
558 | $family ||= 6 unless $AnyEvent::PROTOCOL{ipv4}; |
534 | |
559 | |
535 | $proto ||= "tcp"; |
560 | $proto ||= "tcp"; |
536 | $type ||= $proto eq "udp" ? SOCK_DGRAM : SOCK_STREAM; |
561 | $type ||= $proto eq "udp" ? SOCK_DGRAM : SOCK_STREAM; |
537 | |
562 | |
538 | my $proton = $PROTO_BYNAME{lc $proto} || (getprotobyname $proto)[2] |
563 | my $proton = getprotobyname $proto |
539 | or Carp::croak "$proto: protocol unknown"; |
564 | or Carp::croak "$proto: protocol unknown"; |
540 | |
565 | |
541 | my $port; |
566 | my $port; |
542 | |
567 | |
543 | if ($service =~ /^(\S+)=(\d+)$/) { |
568 | if ($service =~ /^(\S+)=(\d+)$/) { |
… | |
… | |
766 | |
791 | |
767 | $state{next} = sub { |
792 | $state{next} = sub { |
768 | return unless exists $state{fh}; |
793 | return unless exists $state{fh}; |
769 | |
794 | |
770 | my $target = shift @target |
795 | my $target = shift @target |
771 | or do { |
|
|
772 | %state = (); |
|
|
773 | return $connect->(); |
796 | or return (%state = (), $connect->()); |
774 | }; |
|
|
775 | |
797 | |
776 | my ($domain, $type, $proto, $sockaddr) = @$target; |
798 | my ($domain, $type, $proto, $sockaddr) = @$target; |
777 | |
799 | |
778 | # socket creation |
800 | # socket creation |
779 | socket $state{fh}, $domain, $type, $proto |
801 | socket $state{fh}, $domain, $type, $proto |