… | |
… | |
295 | if $t =~ /^\d*$/; |
295 | if $t =~ /^\d*$/; |
296 | |
296 | |
297 | my ($host, $port) = AnyEvent::Socket::parse_hostport $t, "aemp=$DEFAULT_PORT" |
297 | my ($host, $port) = AnyEvent::Socket::parse_hostport $t, "aemp=$DEFAULT_PORT" |
298 | or Carp::croak "$t: unparsable transport descriptor"; |
298 | or Carp::croak "$t: unparsable transport descriptor"; |
299 | |
299 | |
|
|
300 | $port = "0" if $port eq "*"; |
|
|
301 | |
|
|
302 | if ($host eq "*") { |
300 | $cv->begin; |
303 | $cv->begin; |
|
|
304 | # use fork_call, as Net::Interface is big, and we need it rarely. |
|
|
305 | require AnyEvent::Util; |
|
|
306 | AnyEvent::Util::fork_call ( |
|
|
307 | sub { |
|
|
308 | my @addr; |
|
|
309 | |
|
|
310 | require Net::Interface; |
|
|
311 | |
|
|
312 | for my $if (Net::Interface->interfaces) { |
|
|
313 | # we statically lower-prioritise ipv6 here, TODO :() |
|
|
314 | for my $_ ($if->address (Net::Interface::AF_INET ())) { |
|
|
315 | next if /^\x7f/; # skip localhost etc. |
|
|
316 | push @addr, $_; |
|
|
317 | } |
|
|
318 | for ($if->address (Net::Interface::AF_INET6 ())) { |
|
|
319 | #next if $if->scope ($_) <= 2; |
|
|
320 | next unless /^[\x20-\x3f\xfc\xfd]/; # global unicast, site-local unicast |
|
|
321 | push @addr, $_; |
|
|
322 | } |
|
|
323 | |
|
|
324 | } |
|
|
325 | @addr |
|
|
326 | }, sub { |
|
|
327 | for my $ip (@_) { |
|
|
328 | push @res, [ |
|
|
329 | $pri += 1e-5, |
|
|
330 | AnyEvent::Socket::format_hostport AnyEvent::Socket::format_address $ip, $port |
|
|
331 | ]; |
|
|
332 | } |
|
|
333 | $cv->end; |
|
|
334 | } |
|
|
335 | ); |
|
|
336 | } else { |
|
|
337 | $cv->begin; |
301 | AnyEvent::Socket::resolve_sockaddr $host, $port, "tcp", 0, undef, sub { |
338 | AnyEvent::Socket::resolve_sockaddr $host, $port, "tcp", 0, undef, sub { |
302 | for (@_) { |
339 | for (@_) { |
303 | my ($service, $host) = AnyEvent::Socket::unpack_sockaddr $_->[3]; |
340 | my ($service, $host) = AnyEvent::Socket::unpack_sockaddr $_->[3]; |
304 | push @res, [ |
341 | push @res, [ |
305 | $pri += 1e-5, |
342 | $pri += 1e-5, |
306 | AnyEvent::Socket::format_hostport AnyEvent::Socket::format_address $host, $service |
343 | AnyEvent::Socket::format_hostport AnyEvent::Socket::format_address $host, $service |
307 | ]; |
344 | ]; |
|
|
345 | } |
|
|
346 | $cv->end; |
308 | } |
347 | }; |
309 | $cv->end; |
|
|
310 | }; |
348 | } |
311 | } |
349 | } |
312 | |
350 | |
313 | $cv->end; |
351 | $cv->end; |
314 | |
352 | |
315 | $cv |
353 | $cv |
… | |
… | |
331 | $NODE{$NODE}{id} = $NODE; |
369 | $NODE{$NODE}{id} = $NODE; |
332 | |
370 | |
333 | my $seeds = $CONFIG->{seeds}; |
371 | my $seeds = $CONFIG->{seeds}; |
334 | my $binds = $CONFIG->{binds}; |
372 | my $binds = $CONFIG->{binds}; |
335 | |
373 | |
336 | $binds ||= [$NODE]; |
374 | $binds ||= ["*"]; |
337 | |
375 | |
338 | $WARN->(8, "node $NODE starting up."); |
376 | $WARN->(8, "node $NODE starting up."); |
339 | |
377 | |
340 | $LISTENER = []; |
378 | $LISTENER = []; |
341 | %LISTENER = (); |
379 | %LISTENER = (); |
… | |
… | |
343 | for (map _resolve $_, @$binds) { |
381 | for (map _resolve $_, @$binds) { |
344 | for my $bind ($_->recv) { |
382 | for my $bind ($_->recv) { |
345 | my ($host, $port) = AnyEvent::Socket::parse_hostport $bind |
383 | my ($host, $port) = AnyEvent::Socket::parse_hostport $bind |
346 | or Carp::croak "$bind: unparsable local bind address"; |
384 | or Carp::croak "$bind: unparsable local bind address"; |
347 | |
385 | |
348 | $LISTENER{$bind} = AnyEvent::MP::Transport::mp_server $host, $port; |
386 | $port =~ s/^.*=//; # remove bogus aemp= |
|
|
387 | |
|
|
388 | my $listener = AnyEvent::MP::Transport::mp_server |
|
|
389 | $host, |
|
|
390 | $port, |
|
|
391 | prepare => sub { |
|
|
392 | my (undef, $host, $port) = @_; |
|
|
393 | $bind = AnyEvent::Socket::format_hostport $host, $port; |
|
|
394 | }, |
|
|
395 | ; |
|
|
396 | $LISTENER{$bind} = $listener; |
349 | push @$LISTENER, $bind; |
397 | push @$LISTENER, $bind; |
350 | } |
398 | } |
351 | } |
399 | } |
352 | |
400 | |
353 | # the global service is mandatory currently |
401 | # the global service is mandatory currently |