… | |
… | |
22 | =cut |
22 | =cut |
23 | |
23 | |
24 | package AnyEvent::MP::Kernel; |
24 | package AnyEvent::MP::Kernel; |
25 | |
25 | |
26 | use common::sense; |
26 | use common::sense; |
27 | use POSIX (); |
|
|
28 | use Carp (); |
27 | use Carp (); |
29 | |
28 | |
30 | use AnyEvent (); |
29 | use AnyEvent (); |
31 | use Guard (); |
30 | use Guard (); |
32 | |
31 | |
… | |
… | |
849 | |
848 | |
850 | $port = "0" if $port eq "*"; |
849 | $port = "0" if $port eq "*"; |
851 | |
850 | |
852 | if ($host eq "*") { |
851 | if ($host eq "*") { |
853 | $cv->begin; |
852 | $cv->begin; |
854 | # use fork_call, as Net::Interface is big, and we need it rarely. |
853 | |
855 | require AnyEvent::Util; |
854 | my $get_addr = sub { |
856 | AnyEvent::Util::fork_call ( |
|
|
857 | sub { |
|
|
858 | my @addr; |
855 | my @addr; |
859 | |
856 | |
860 | require Net::Interface; |
857 | require Net::Interface; |
861 | |
858 | |
|
|
859 | # Net::Interface hangs on some systems, so hope for the best |
|
|
860 | local $SIG{ALRM} = 'DEFAULT'; |
|
|
861 | alarm 2; |
|
|
862 | |
862 | for my $if (Net::Interface->interfaces) { |
863 | for my $if (Net::Interface->interfaces) { |
863 | # we statically lower-prioritise ipv6 here, TODO :() |
864 | # we statically lower-prioritise ipv6 here, TODO :() |
864 | for $_ ($if->address (Net::Interface::AF_INET ())) { |
865 | for $_ ($if->address (Net::Interface::AF_INET ())) { |
865 | next if /^\x7f/; # skip localhost etc. |
866 | next if /^\x7f/; # skip localhost etc. |
866 | push @addr, $_; |
867 | push @addr, $_; |
867 | } |
|
|
868 | for ($if->address (Net::Interface::AF_INET6 ())) { |
|
|
869 | #next if $if->scope ($_) <= 2; |
|
|
870 | next unless /^[\x20-\x3f\xfc\xfd]/; # global unicast, site-local unicast |
|
|
871 | push @addr, $_; |
|
|
872 | } |
|
|
873 | |
|
|
874 | } |
868 | } |
875 | @addr |
869 | for ($if->address (Net::Interface::AF_INET6 ())) { |
876 | }, sub { |
870 | #next if $if->scope ($_) <= 2; |
877 | for my $ip (@_) { |
871 | next unless /^[\x20-\x3f\xfc\xfd]/; # global unicast, site-local unicast |
878 | push @res, [ |
872 | push @addr, $_; |
879 | $pri += 1e-5, |
|
|
880 | AnyEvent::Socket::format_hostport AnyEvent::Socket::format_address $ip, $port |
|
|
881 | ]; |
|
|
882 | } |
873 | } |
883 | $cv->end; |
|
|
884 | } |
874 | } |
|
|
875 | |
|
|
876 | alarm 0; |
|
|
877 | |
|
|
878 | @addr |
885 | ); |
879 | }; |
|
|
880 | |
|
|
881 | my @addr; |
|
|
882 | |
|
|
883 | if (AnyEvent::WIN32) { |
|
|
884 | @addr = $get_addr->(); |
|
|
885 | } else { |
|
|
886 | # use a child process, as Net::Interface is big, and we need it only once. |
|
|
887 | |
|
|
888 | pipe my $r, my $w |
|
|
889 | or die "pipe: $!"; |
|
|
890 | |
|
|
891 | if (fork eq 0) { |
|
|
892 | close $r; |
|
|
893 | syswrite $w, pack "(C/a*)*", $get_addr->(); |
|
|
894 | require POSIX; |
|
|
895 | POSIX::_exit (0); |
|
|
896 | } else { |
|
|
897 | close $w; |
|
|
898 | |
|
|
899 | my $addr; |
|
|
900 | |
|
|
901 | 1 while sysread $r, $addr, 1024, length $addr; |
|
|
902 | |
|
|
903 | @addr = unpack "(C/a*)*", $addr; |
|
|
904 | } |
|
|
905 | } |
|
|
906 | |
|
|
907 | for my $ip (@addr) { |
|
|
908 | push @res, [ |
|
|
909 | $pri += 1e-5, |
|
|
910 | AnyEvent::Socket::format_hostport AnyEvent::Socket::format_address $ip, $port |
|
|
911 | ]; |
|
|
912 | } |
|
|
913 | $cv->end; |
886 | } else { |
914 | } else { |
887 | $cv->begin; |
915 | $cv->begin; |
888 | AnyEvent::Socket::resolve_sockaddr $host, $port, "tcp", 0, undef, sub { |
916 | AnyEvent::Socket::resolve_sockaddr $host, $port, "tcp", 0, undef, sub { |
889 | for (@_) { |
917 | for (@_) { |
890 | my ($service, $host) = AnyEvent::Socket::unpack_sockaddr $_->[3]; |
918 | my ($service, $host) = AnyEvent::Socket::unpack_sockaddr $_->[3]; |
… | |
… | |
973 | # connect to all seednodes |
1001 | # connect to all seednodes |
974 | set_seeds map $_->recv, map _resolve $_, @$seeds; |
1002 | set_seeds map $_->recv, map _resolve $_, @$seeds; |
975 | |
1003 | |
976 | master_search; |
1004 | master_search; |
977 | |
1005 | |
|
|
1006 | # save gobs of memory |
|
|
1007 | undef &_resolve; |
|
|
1008 | *configure = sub (@){ }; |
|
|
1009 | |
978 | for (@{ $CONFIG->{services} }) { |
1010 | for (@{ $CONFIG->{services} }) { |
979 | if (ref) { |
1011 | if (ref) { |
980 | my ($func, @args) = @$_; |
1012 | my ($func, @args) = @$_; |
981 | (load_func $func)->(@args); |
1013 | (load_func $func)->(@args); |
982 | } elsif (s/::$//) { |
1014 | } elsif (s/::$//) { |