Totally stuck --> UDP packets refused

Discussion in 'Linux Networking' started by Palmisano, Aug 28, 2014.

  1. Palmisano

    Palmisano Guest


    I did try to fix this myself, for some hours but no success. I am sure
    it is a simple thing I am overlooking, but what...

    I wrote a C program on my Fedora server, that does the following.
    The prog on my server (name=zon IP= sends a command to a
    device on the LAN (name=ics1000, IP= using UDP port 9760
    (this is a command to switch on a lamp).
    The UDP command works, because the lamp goes on.

    The device returns an acknowledge message on UDP port 9761 (so a
    different port). My program is trying to read that response on the
    9761 port, but the ack message never reaches the program because the
    server seems to block the port (the select() times out).

    Here is a tcpdump of the em1 ifc when I send the command:

    # tcpdump host
    23:01:02.112832 IP zon.57758 > ics1000.9760: UDP, length 11
    23:01:02.221171 IP ics1000.9760 > zon.9761: UDP, length 8
    23:01:02.221196 IP zon > ics1000: ICMP zon udp port 9761 unreachable,

    aha, unreachable...

    So my thought was: FIREWALL. So I added 9761 UDP to iptables (and
    restarted iptables):
    # iptables -L

    Chain INPUT (policy ACCEPT)
    target prot opt source destination
    ACCEPT udp -- anywhere anywhere udp dpt:9761
    ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
    ACCEPT icmp -- anywhere anywhere
    ACCEPT all -- anywhere anywhere
    ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ftp
    ACCEPT udp -- anywhere anywhere state NEW udp dpt:netbios-ns
    ACCEPT udp -- anywhere anywhere state NEW udp dpts:dpap:8775
    ACCEPT udp -- anywhere anywhere state NEW udp dpt:9761
    ACCEPT udp -- anywhere anywhere state NEW udp dpt:dsm-scm-target
    REJECT all -- anywhere anywhere reject-with icmp-host-prohibited

    Chain FORWARD (policy ACCEPT)
    target prot opt source destination
    REJECT all -- anywhere anywhere
    reject-with icmp-host-prohibited

    Chain OUTPUT (policy ACCEPT)
    target prot opt source destination

    I even switched iptables off:
    # systemctl stop iptables.service

    Makes NO difference. I am totally lost now. Any hints?

    Thx, Palmi
    Palmisano, Aug 28, 2014
    1. Advertisements

  2. Palmisano

    Jorgen Grahn Guest

    I.e. your server is the client.
    It is more usual for an UDP server to send the response to the host
    and port where the request came from. Uses up less fixed port
    numbers, is nicer to firewalls, and easier to debug (you can use
    netcat -u to talk to the server).
    The more likely explanation is that noone is listening on zon.9761
    (or *.9761). Check with netstat -uapn. You can also run your client
    program under strace to see if it sets up the socket properly.


    Jorgen Grahn, Aug 28, 2014
    1. Advertisements

  3. Jorgen Grahn a écrit :
    I agree. "Port unreachable" is the ICMP type/code generated by the UDP
    stack when nothing listens on the destination port. The REJECT rule at
    the end of the INPUT chain in the iptables ruleset would have generated
    a "host prohibited" ICMP type/code.
    Pascal Hambourg, Aug 29, 2014
  4. Palmisano

    Palmisano Guest

    Great advice guys. I am blushing with shame.
    The bind() failed and due to a typo that I overlooked <n> times, the
    exit value test didn't notic ethe failure.

    Fixed now.

    BTW: I agree that replying on another port is weird. But I didn't
    build the device that accepts the commands :).

    Your help is appreciated!
    Palmisano, Aug 29, 2014
  5. Palmisano

    Jorgen Grahn Guest

    That's the beauty of strace: no matter how badly your code handles
    errors from system calls, strace will reveal them.
    Oh. Well, one thing I've learned is that a lot of protocols are
    designed by people who don't quite understand what they're doing.
    So if the protocol seems weird to me, it may not be my fault ...
    Happy to help! Done this kind of debugging many times myself ...

    Jorgen Grahn, Aug 30, 2014
  6. Palmisano

    Palmisano Guest

    Ouch, that hurt... I am always *very* precise with defensive
    programming and error handling. This time a quick & dirty experiment
    showed that quick is indeed often dirty.
    Hmm, the whole device interface is 'suboptimal'. It works, but it was
    never well thought over before it was created.
    Palmisano, Aug 30, 2014
  7. Palmisano a écrit :
    It may make things a bit easier to use 9761 as the source port for the
    outgoing packet instead of an ephemeral port. I see two advantages :
    - it requires only one single UDP socket for sending and receiving ;
    - a stateful iptables ruleset can handle the reply packet automatically
    (as ESTABLISHED) without requiring an explicit rule in the INPUT chain.
    Pascal Hambourg, Aug 30, 2014
  8. Palmisano

    Jorgen Grahn Guest

    A third one: it's easier to see that someone else is using the port,
    so the client can't do its job properly. With two sockets, you'd have
    to claim 9761 first and then create the sending one.

    Jorgen Grahn, Aug 30, 2014
  9. Palmisano

    Jorgen Grahn Guest

    The hurting was unintentional. I just meant that it doesn't matter to
    strace how well you handle errors. I'm often sloppy with error
    handling when I'm prototyping new socket code, because I know I can
    rely on strace. Then I fix it up, of course, and pay attention to
    what the man pages say about errors.

    I should also mention ltrace, which does the same thing but on the
    libc interface level. If you use e.g. getaddrinfo(3) (and you should
    use it!) that maps to a whole bunch of system calls that you're not
    really interested in.

    Jorgen Grahn, Aug 30, 2014
  10. Palmisano

    Palmisano Guest

    The hurting was a joke :). The strace is a good tip! Thx again!
    Palmisano, Aug 31, 2014
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.