Hi guys,

Yesterday I had put up a post about a query I had for UDP sockets - send call on udp socket. To summarize it, when udp socket makes a send system call it returns true, irrespective of the status of the receiving host/port. And as per the UDP protocol, any reported asynchronous errors are are passed to the user.

So if I do a send, which returns true and then I do a recv or send, the first send's errors are reported during the later operations.

The code that I used was:
#!/usr/bin/perl -w use strict; use IO::Socket; my $client = new IO::Socket::INET( PeerAddr => '127.0.0.1', PeerPort => 3333, Proto => 'udp' ); (!$client) && die "failed to create sock: $!"; my ($request, $response); $request = 'the request to rule the world'; while(1 == 1) { if (! defined($client->send($request))) { print "send failed: $!\n"; } else { print "send succeeded\n"; } sleep 3; }
With no server running on 127.0.0.1:3333 the output I got was,
send succeeded send failed: Connection refused. send succeeded send failed: Connection refused. send succeeded . . .

which happens because of asynchronous errors received on network. I concluded, that if my send call fails, the error will be obtained at any point in time, but I will get the error.

I was wrong. Because if I change the PeerAddr to a unreachable host, the output I get is

send succeeded send succeeded send succeeded send succeeded . . .

The output I was expecting was

send succeeded send failed: Destination host unreachable. send succeeded send failed: Destination host unreachable. send succeeded send failed: Destination host unreachable. . . .

Because I should have got the error of host unreachable like I got for connection refused. I looked up to the udp and socket man pages on my system and found the following snippet in the udp man page:

All fatal errors will be passed to the user as an error return even when the socket is not connected. This includes asynchronous errors received from the network. You may get an error for an earlier packet that was sent on the same socket. This behaviour differs from many other BSD socket implementations which don’t pass any errors unless the socket is connected. Linux behaviour mandated by RFC 1122.

Snippet from socket man page SOCKET OPTIONS section for option SO_BSDCOMPAT:

If enabled ICMP errors received for a UDP socket will not be passed to the user program. In later kernel versions, support for this option has been phased out: Linux 2.4 silently ignores it, and Linux 2.6 generates a kernel warning (printk()) if a program uses this option.

Which means that I will get UDP send errors only if my destination host is up. I tried using the getsockopt() method from Socket module to check if SO_BSDCOMPAT option is set. But the Socket.pm module file does not have this option in its list of queriable options.

Perl is installed directly from the rpm and has not been compiled. My system parameters are

  1. OS: RHEL5, 64 bit virtual machine
  2. perl -v: v5.8.8 built for x86_64-linux-gnu-thread-multi
  3. uname -a: Linux myhostname 2.6.18-53.el5 #1 SMP Wed Oct 10 16:34:19 EDT 2007 x86_64 x86_64 x86_64 GNU/Linux

My questions:

  1. Shouldn't send() be reporting 'Destination host unreachable'?
  2. Does IO::Socket::INET have SO_BSDCOMPAT option set on in Perl v5.8.8?
  3. Is there a way of knowing if SO_BSDCOMPAT option is on for a socket?

thanks and regards,

Saurabh


In reply to udp send not reporting host unreachable errors by saurabh.hirani

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.