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

.

parent aadd5d0f
......@@ -5,9 +5,10 @@ from __future__ import print_function
import sys, time
from socket import socket, AF_INET, SOCK_DGRAM, IPPROTO_UDP, SOL_SOCKET, \
SO_REUSEADDR, IPPROTO_IP, IP_ADD_MEMBERSHIP, IP_MULTICAST_TTL, IP_MULTICAST_LOOP, \
inet_aton, INADDR_ANY
from socket import socket, AF_INET, AF_INET6, SOCK_DGRAM, IPPROTO_UDP, \
SOL_SOCKET, SO_REUSEADDR, IPPROTO_IP, IPPROTO_IPV6, IP_ADD_MEMBERSHIP, \
IPV6_JOIN_GROUP, IP_MULTICAST_TTL, IPV6_MULTICAST_HOPS, IP_MULTICAST_LOOP, \
IPV6_MULTICAST_LOOP, inet_pton
import socket as net
from struct import pack
......@@ -16,41 +17,61 @@ from golang import sync, context
group4 = '224.1.1.1'
group6 = 'XXX'
group6 = 'ff15:7079:7468:6f6e:6465:6d6f:6d63:6173'
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.
def mjoin_tx(group, port, ttl=2):
# XXX autodetect ip4/ip6 based on group addr
sk = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
sk, ip6 = _udpsockfor(group)
# 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))
# so that what we send is received locally as well
sk.setsockopt(IPPROTO_IP, IP_MULTICAST_LOOP, 1)
if ip6:
sk.setsockopt(IPPROTO_IPV6, IPV6_MULTICAST_LOOP, 1)
else:
sk.setsockopt(IPPROTO_IP, IP_MULTICAST_LOOP, 1)
return sk
# mjoin_rx returns socket prepated to send/receive to/from multicast group:port.
def mjoin_rx(group, port):
# XXX autodetect ip4/ip6 based on group addr
sk = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
sk, ip6 = _udpsockfor(group)
sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sk.bind((group, port)) # works for reception even from multiple ifaces
#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
for ifidx, ifname in net.if_nameindex():
print("joining %s @ [%d]%s" % (group, ifidx, ifname))
mreq = pack("4sii", inet_aton(group), INADDR_ANY, ifidx)
#print(repr(mreq), len(mreq))
sk.setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP, mreq)
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))
sk.setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP, mreq)
return sk
......
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