package POEDaemon::WheelRun::DNSChild; use strict; use warnings FATAL => 'all'; no warnings 'redefine'; use POE; use POEDaemon; sub states { return $_[0], [qw( dnschild_start dnschild_stop dnschild_childexit dns_query dnschild_result )]; } sub dnschild_start { my $kernel = $_[KERNEL]; $kernel->yield(wheelrun_exec => { prog => [ 'util/dnschild.sh' ], name => 'dnschild', stdout_event => 'dnschild_result', }); $kernel->delay(tcpclient_find_target => connretry_rand); } sub dnschild_stop { my $kernel = $_[KERNEL]; $kernel->yield(wheelrun_kill => { wheel_name => 'dnschild' }); } sub dnschild_childexit { my ($kernel, $heap) = @_[KERNEL, HEAP]; unless ($heap->{shutdown}) { $kernel->yield(shutdown => 'dnschild child abnormally terminated'); } } sub dns_query { my ($heap, $args) = @_[HEAP, ARG0]; return if $heap->{shutdown}; my $host = $args->{host} || return; my $wheel = $heap->{wheel_run}->{children_by_name}->{dnschild}->{wheel}; return unless $wheel; log_enabled && logline "put '%s'", $host; $wheel->put($host); } sub dnschild_result { my ($kernel, $heap, $line) = @_[KERNEL, HEAP, ARG0]; return if $heap->{shutdown}; log_enabled && logline "line = '%s'", $line; $line =~ s/^\s*//; $line =~ s/\s*$//; my @results; foreach my $result (split /\s+/, $line) { next unless $result; next if $result =~ /\./ && $heap->{tcpclient_connretry_count} <= 10; push @results, $result; } unless (@results) { log_enabled && logline 'no results, retry'; unless ($heap->{shutdown}) { $kernel->delay(tcpclient_find_target => connretry_rand); } return; } my $random_result = $results[int rand $#results + 1]; log_enabled && logline "random result '%s'", $random_result; my $socketdomain; if ($random_result =~ /\./) { $socketdomain = 'inet'; } elsif ($random_result =~ /:/) { $socketdomain = 'inet6'; } unless ($socketdomain) { log_enabled && logline 'invalid result, retry'; unless ($heap->{shutdown}) { $kernel->delay(tcpclient_find_target => connretry_rand); } return; } $kernel->yield(tcpclient_init => { socketdomain => $socketdomain, remoteaddress => $random_result, }); } 1;