in reply to AnyEvent::Handle::UDP -- can't get it to receive?

The things you learn when you're bored at work... :)
Never did anything with sockets or AnyEvent before, but here it goes.
After getting the latest AnyEvent (v5.24 is incompatible with AnyEvent::Handle::UDP v0.033) and AnyEvent::Handle::UDP packages from CPAN, this code seems to work:
#!/usr/bin/perl use strict; use warnings; use AnyEvent; #use AnyEvent::DNS; use AnyEvent::Handle::UDP; use AnyEvent::Socket (); use Socket; use Net::DNS::Packet; use Data::Dump; my $cb = sub {}; my($proto) = shift; my $fqdn = "$proto.local"; #my $data = AnyEvent::DNS::dns_pack { rd => 1, qd => [[$fqdn, "ptr"]] +}; my $d = Net::DNS::Packet->new($fqdn, "PTR"); my $data = $d->data; my %found; my $callback = sub {}; my $cv_recv = AnyEvent->condvar; my $t; $t = AnyEvent::Handle::UDP->new( # fh => $sock, #bind => ['0.0.0.0', 5353], timeout => 3, on_timeout => sub { print STDERR "WTF? timeout...\n"; #undef $t; #$cb->(values %found); }, on_error => sub { print STDERR "An error has occurred:"; Data::Dump::dd(@_); }, on_recv => sub { print STDERR "callback!!\n"; my $buf = shift; my $handle = shift; my ($res,$err) = Net::DNS::Packet->new(\$buf, 1); my @rr = grep { lc $_->[0] eq $fqdn && $_->[1] eq 'ptr' } @{ +$res->{an} }; my @srv = grep { $_->[1] eq 'srv' } @{$res->{ar}}; if (@rr == 1 && @srv == 1) { my $name = $rr[0]->[3]; $name =~ s/\.$fqdn$//; my $service = { name => $name, host => $srv[0]->[6], port => $srv[0]->[5], proto => $proto, }; $found{$rr[0]->[3]} ||= do { $callback->($service) if $callback; $service; }; } $cv_recv->send; }, ); #$t->bind_to(pack_sockaddr_in(0, Socket::inet_aton('0.0.0.0'))); # Doe +s not work for some reason $t->bind_to(['0.0.0.0',0]); my $cv_send = $t->push_send($data, pack_sockaddr_in(53, Socket::inet_a +ton('IP_OF_DNS-SERVER_HERE'))); print("Waiting for data to be sent..."); $cv_send->recv; print("[OK]\n"); print("Waiting for data to arrive..."); $cv_recv->recv; print("[OK]\n");
Output:
me@server:~/testscripts$ ./monks17.pl localhost Waiting for data to be sent...[OK] callback!! Waiting for data to arrive...;; HEADER SECTION ;; id = 32508 ;; qr = 1 opcode = QUERY aa = 0 tc = 0 rd = 1 ;; ra = 1 ad = 0 cd = 0 rcode = NXDOMAIN ;; qdcount = 1 ancount = 0 nscount = 1 arcount = 0 ;; QUESTION SECTION (1 record) ;; localhost.local. IN PTR ;; ANSWER SECTION (0 records) ;; AUTHORITY SECTION (1 record) . 900 IN SOA a.root-servers.net. nstld.verisign-grs +.com. ( 2012042600 ; Serial 1800 ; Refresh 900 ; Retry 604800 ; Expire 86400 ) ; Minimum TTL ;; ADDITIONAL SECTION (0 records) [OK] me@server:~/testscripts$

Replies are listed 'Best First'.
Re^2: AnyEvent::Handle::UDP -- can't get it to receive?
by Anonymous Monk on Apr 27, 2012 at 00:16 UTC
    Dude!
    $cv_send->recv;

    I've actually got a fair amount of AnyEvent experience, and I totally missed this. You are my new best friend.

    Wait, you say you've never done anything with either sockets or AnyEvent before? Quick learner. Anyway, would you mind PM'ing me with your email; if you're bored at work again I might have some PayPal-able learning for you...

    Eric.

      Ug, yeah, whoops, that was me (creeble). Forgot to log in.
        Hmmno thanks. I already have a job, and though it has its ups and downs, I'm not looking for another :).
        You're still free to keep asking questions to the monks in general though.

        Edit: Cleaned up code and perltidy'd it. There seems to be a bug in Net::DNS::Packet where, if you remove the debug-flag when creating a new packet object from raw data, the answer section doesn't get decoded.
        use strict; use warnings; use AnyEvent::Handle::UDP; use Socket; use Net::DNS::Packet; use Data::Dump; my $target_host = shift; if (!defined $target_host) { print ("Usage: $0 hostname\n"); exit 1; } my $d = Net::DNS::Packet->new($target_host, "PTR"); my $cv_recv = AnyEvent->condvar; my $t = AnyEvent::Handle::UDP->new( timeout => 3, on_timeout => sub { print STDERR "Nothing happened within the specified timeout ti +meframe...\n"; }, on_error => sub { print STDERR "An error has occurred:"; Data::Dump::dd(@_); }, on_recv => sub { my ($buf, $handle) = @_; my ($res, $err) = Net::DNS::Packet->new(\$buf,1); if ($err) { print STDERR $err . "\n"; } else { Data::Dump::dd($res); } $cv_recv->send; }, ); $t->bind_to(['0.0.0.0', 0]); my $cv_send = $t->push_send($d->data, pack_sockaddr_in(53, Socket::ine +t_aton('IP_OF_DNS-SERVER_HERE'))); print ("Waiting for data to be sent..."); $cv_send->recv; print ("[OK]\n"); print ("Waiting for data to arrive..."); $cv_recv->recv; print ("[OK]\n");