Commit 7cc29499 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent aadd5d0f
...@@ -5,9 +5,10 @@ from __future__ import print_function ...@@ -5,9 +5,10 @@ from __future__ import print_function
import sys, time import sys, time
from socket import socket, AF_INET, SOCK_DGRAM, IPPROTO_UDP, SOL_SOCKET, \ from socket import socket, AF_INET, AF_INET6, SOCK_DGRAM, IPPROTO_UDP, \
SO_REUSEADDR, IPPROTO_IP, IP_ADD_MEMBERSHIP, IP_MULTICAST_TTL, IP_MULTICAST_LOOP, \ SOL_SOCKET, SO_REUSEADDR, IPPROTO_IP, IPPROTO_IPV6, IP_ADD_MEMBERSHIP, \
inet_aton, INADDR_ANY IPV6_JOIN_GROUP, IP_MULTICAST_TTL, IPV6_MULTICAST_HOPS, IP_MULTICAST_LOOP, \
IPV6_MULTICAST_LOOP, inet_pton
import socket as net import socket as net
from struct import pack from struct import pack
...@@ -16,39 +17,59 @@ from golang import sync, context ...@@ -16,39 +17,59 @@ from golang import sync, context
group4 = '224.1.1.1' group4 = '224.1.1.1'
group6 = 'XXX' group6 = 'ff15:7079:7468:6f6e:6465:6d6f:6d63:6173'
port = 5678 port = 5678
def _udpsockfor(ipaddr): # -> (sk, isipv6)
ip6 = (':' in ipaddr) # autodetect ip4/ip6 based on group addr
if ip6:
sk = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)
else:
sk = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
return (sk, ip6)
# mjoin_tx returns socket prepated to send/receive to/from multicast group:port. # mjoin_tx returns socket prepated to send/receive to/from multicast group:port.
def mjoin_tx(group, port, ttl=2): def mjoin_tx(group, port, ttl=2):
# XXX autodetect ip4/ip6 based on group addr sk, ip6 = _udpsockfor(group)
sk = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
# set ttl and default destination address (for tx) # set ttl and default destination address (for tx)
sk.setsockopt(IPPROTO_IP, IP_MULTICAST_TTL, pack('b', ttl)) bttl = pack('b', ttl)
if ip6:
sk.setsockopt(IPPROTO_IPV6, IPV6_MULTICAST_HOPS, bttl)
else:
sk.setsockopt(IPPROTO_IP, IP_MULTICAST_TTL, bttl)
sk.connect((group, port)) sk.connect((group, port))
# so that what we send is received locally as well # so that what we send is received locally as well
if ip6:
sk.setsockopt(IPPROTO_IPV6, IPV6_MULTICAST_LOOP, 1)
else:
sk.setsockopt(IPPROTO_IP, IP_MULTICAST_LOOP, 1) sk.setsockopt(IPPROTO_IP, IP_MULTICAST_LOOP, 1)
return sk return sk
# mjoin_rx returns socket prepated to send/receive to/from multicast group:port. # mjoin_rx returns socket prepated to send/receive to/from multicast group:port.
def mjoin_rx(group, port): def mjoin_rx(group, port):
# XXX autodetect ip4/ip6 based on group addr sk, ip6 = _udpsockfor(group)
sk = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sk.bind((group, port)) # works for reception even from multiple ifaces sk.bind((group, port)) # works for reception even from multiple ifaces
#sk.bind(('', port)) # XXX and later IP_MULTICAST_ALL=0 ? #sk.bind(('', port)) # XXX and later IP_MULTICAST_ALL=0 ?
## join the group (for rx)
#mreq = pack("4sl", inet_aton(group), INADDR_ANY)
#sk.setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP, mreq)
# join the group on all interfaces # join the group on all interfaces
for ifidx, ifname in net.if_nameindex(): for ifidx, ifname in net.if_nameindex():
print("joining %s @ [%d]%s" % (group, ifidx, ifname)) print("joining %s @ [%d]%s" % (group, ifidx, ifname))
mreq = pack("4sii", inet_aton(group), INADDR_ANY, ifidx) bifidx = pack("@i", ifidx)
if ip6:
mreq = inet_pton(AF_INET6, group) + \
bifidx
sk.setsockopt(IPPROTO_IPV6, IPV6_JOIN_GROUP, mreq) # = IPV6_ADD_MEMBERSHIP
else:
mreq = inet_pton(AF_INET, group) + \
inet_pton(AF_INET, '0.0.0.0') + \
bifidx
#print(repr(mreq), len(mreq)) #print(repr(mreq), len(mreq))
sk.setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP, mreq) sk.setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP, mreq)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment