[Melbourne-pm] Handling UDP packets via IO::Socket::INET in a sane manner.

Daniel Pittman daniel at rimspace.net
Mon Nov 30 04:01:44 PST 2009


Steven Haigh <netwiz at crc.id.au> writes:

> I'm wondering if anyone has a good method of using IO::Socket::INET in a
> UDP proxy type environment...
>
> I've written some (cruddy) code at the moment that listens on a UDP port
> for an incoming packet. It then re-writes some details in the packet, and
> then I need to send it on from the same UDP port number that we are
> listening on to a different host.
>
> Direction of traffic from client -> proxy -> server or server -> proxy ->
> client can be done by inspecting the data in the packet so it isn't a huge
> concern to have IO::Socket::INET have a sane way to tell traffic streams
> apart, but it might be interesting (and easier) if it did.
>
> From my (somewhat incomplete) code at the moment, it seems that the UDP
> packets are handled more like a TCP stream - in that even though I try to
> set peeraddr and peerport before writing a packet to the socket, the packet
> still ends up back at the client (which promptly gets confused!)

You didn't note how you were doing the packet receive and send operations;
traditionally, I would have expect this to work with the recv and sendto calls
as normal:

use Socket;
use IO::Socket::INET;
my $s = IO::Socket::INET->new(LocalPort => 9000, Proto => 'udp') or die;
my $buf;

my $dst = sockaddr_in(10000, inat_aton('192.168.1.1'));

while (1) {
    $buf = undef;
    $s->recv($buf, 65535) or last;
    $s->send($buf, undef, $dst) or die "sendto: $!";
}

Obviously, season to taste; I would personally grab something like AnyEvent to
help wrap up the process of buffering and asynchronous processing, unless you
don't care about buffering in the proxy.[1]

Presumably you can also fiddle the destination and use write, but I confess
that I have not tried: I grew up on recv and send(to) for UDP, and use them
automatically when needed.

> From some extensive googling, it seems just about everything I've found
> focuses on TCP streams - and my perl-foo is just not smart enough to filter
> out the good stuff from the trivial example code to figure out what I need.

Mostly, using the packet oriented API makes it work as expected, I find.

        Daniel

Footnotes: 
[1]  Given this is UDP you may, or may not, depending on your application.

-- 
✣ Daniel Pittman            ✉ daniel at rimspace.net            ☎ +61 401 155 707
               ♽ made with 100 percent post-consumer electrons


More information about the Melbourne-pm mailing list