2

Simple Python UDP Server: trouble receiving packets from clients other than localhost

I am trying to listen datagrams over ipv6. Here are the messages I am interrested in:

$ sudo tcpdump | grep 20001
[sudo] password for miroslavv: 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
13:00:59.981338 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 86
13:00:59.981348 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 47
13:00:59.981733 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 114
13:00:59.981744 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 67
13:00:59.981940 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 60
13:00:59.982276 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 47
13:00:59.982492 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 47
13:00:59.982656 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 47
13:00:59.982974 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 69
13:00:59.982985 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 111
13:00:59.983335 IP6 fd01:e671:2015:5c01:a00:27ff:fe50:275f.20001 > ff05:e671:2015:5c01:a00:27ff:fe50:275f.20001: UDP, length 152

My platform is Debian testing. I tried the python examples, which seem to communicate perfectly with each other on the same machine. Yet, when the server is configured to listen for the above listed datagrams, it hangs in recv().

Firewall settings:

$ sudo iptables -L
[sudo] password for miroslavv: 
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

I have an ipv6:

$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.42.92  netmask 255.255.248.0  broadcast 192.168.47.255
        inet6 fd01:e671:2015:e3ff:219:fff:fe26:a27e  prefixlen 48  scopeid 0x0<global>
        inet6 fe80::219:fff:fe26:a27e  prefixlen 64  scopeid 0x20<link>
        ether 00:19:0f:26:a2:7e  txqueuelen 1000  (Ethernet)
        RX packets 3360785  bytes 943676498 (899.9 MiB)
        RX errors 0  dropped 6185  overruns 0  frame 0
        TX packets 473236  bytes 77103917 (73.5 MiB)
        TX errors 1  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1  (Local Loopback)
        RX packets 140  bytes 7912 (7.7 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 140  bytes 7912 (7.7 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

netcat is also silent:

$ netcat -u -l -p20001

A peculiar observation is the following. I managed to get some C++ code to read messages if at the same time boost::asio is reading from the same ip and port. Should boost polling be stopped, my code also stops receiving messages.

I already tried a bunch of example C programs, but am unable to receive even one UDP packet from anyone: 1, 2, 3, 4.

What is going on here?

1
  • The issues is probably me not joining a multicast group. Will post a more detailed answer once the whole thing works fine.
    – Vorac
    Commented Feb 15, 2017 at 11:15

1 Answer 1

0

Indeed, I was missing joining the multicast group. With examples about ipv6 multicast rather scarce, here is tested code:

struct addrinfo hint {}, *res;
hint.ai_flags = AI_PASSIVE;
hint.ai_family = AF_INET6;
hint.ai_socktype = SOCK_DGRAM;
getaddrinfo( server._rep.c_str(), std::to_string( port ).c_str(), &hint, &res )
mreq.ipv6mr_multiaddr = reinterpret_cast<  sockaddr_in6* >( res->ai_addr )->sin6_addr;
mreq.ipv6mr_interface if_nametoindex( iface.c_str();
setsockopt( _fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (void*)mreq, sizeof( mreq ) )

PS: Some helpful resources on the subject:

http://www.iitk.ac.in/LDP/HOWTO/Multicast-HOWTO.html#toc6

http://docs.oracle.com/cd/E19253-01/817-4415/sockets-149/index.html

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .