UDP multicast client over ipv6

3

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

Estou tentando ouvir datagramas em ipv6. Aqui estão as mensagens em que estou interrested:

$ 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

Minha plataforma é o teste do Debian. Eu tentei os exemplos do python, que parecem se comunicar perfeitamente uns com os outros na mesma máquina. No entanto, quando o servidor está configurado para escutar os datagramas listados acima, ele trava em recv() .

Configurações do firewall:

$ 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

Eu tenho um 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 também é silencioso:

$ netcat -u -l -p20001

Uma observação peculiar é a seguinte. Eu consegui obter algum código C ++ para ler mensagens if ao mesmo tempo boost::asio está lendo do mesmo ip e porta. Se o polling for interrompido, meu código também deixará de receber mensagens.

Já experimentei vários exemplos de programas em C, mas não consigo receber nem mesmo um pacote UDP de ninguém: 1 , 2 , 3 , 4 .

O que está acontecendo aqui?

    
por Vorac 14.02.2017 / 14:40

1 resposta

0

Na verdade, eu estava faltando se juntar ao grupo multicast. Com exemplos sobre o multicast ipv6 bastante escasso, aqui está o código testado:

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: Alguns recursos úteis sobre o assunto:

link

link

    
por 16.02.2017 / 15:40