mirror of
https://github.com/xcat2/confluent.git
synced 2024-11-22 09:32:21 +00:00
Implement mitigations for ovewhelming SSDP
First, for a given contiguous set of snoop activity, start ignoring a given peer during that contiguous chenk after it has been considered once. Further, make get_hwaddr cheaper for attempts against remote IPs. To facilitate the above, create an efficient 'ip_is_local' to be a relatively cheap function, with potential to cache result in future if it needs to be even cheaper.
This commit is contained in:
parent
7980534bad
commit
596fcb0f4c
@ -142,6 +142,7 @@ def snoop(handler, byehandler=None, protocol=None, uuidlookup=None):
|
||||
tracelog.log(traceback.format_exc(), ltype=log.DataTypes.event,
|
||||
event=log.Events.stacktrace)
|
||||
known_peers = set([])
|
||||
recent_peers = set([])
|
||||
net6 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
|
||||
net6.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1)
|
||||
for ifidx in util.list_interface_indexes():
|
||||
@ -171,11 +172,14 @@ def snoop(handler, byehandler=None, protocol=None, uuidlookup=None):
|
||||
r = select.select((net4, net6), (), (), 60)
|
||||
if r:
|
||||
r = r[0]
|
||||
recent_peers = set([])
|
||||
while r:
|
||||
for s in r:
|
||||
(rsp, peer) = s.recvfrom(9000)
|
||||
if rsp[:4] == b'PING':
|
||||
continue
|
||||
if peer in recent_peers:
|
||||
continue
|
||||
rsp = rsp.split(b'\r\n')
|
||||
if b' ' not in rsp[0]:
|
||||
continue
|
||||
@ -183,6 +187,7 @@ def snoop(handler, byehandler=None, protocol=None, uuidlookup=None):
|
||||
if method == b'NOTIFY':
|
||||
if peer in known_peers:
|
||||
continue
|
||||
recent_peers.add(peer)
|
||||
mac = neighutil.get_hwaddr(peer[0])
|
||||
if not mac:
|
||||
probepeer = (peer[0], struct.unpack('H', os.urandom(2))[0] | 1025) + peer[2:]
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
# A consolidated manage of neighbor table information management.
|
||||
|
||||
import confluent.netutil as netutil
|
||||
import confluent.util as util
|
||||
import os
|
||||
import eventlet.semaphore as semaphore
|
||||
@ -96,7 +97,7 @@ def get_hwaddr(ipaddr):
|
||||
_update_neigh()
|
||||
updated = True
|
||||
hwaddr = neightable.get(ipaddr, None)
|
||||
if not hwaddr and not updated:
|
||||
if not hwaddr and not updated and netutil.ip_is_local(ipaddr):
|
||||
_update_neigh()
|
||||
hwaddr = neightable.get(ipaddr, None)
|
||||
if hwaddr:
|
||||
|
@ -84,6 +84,19 @@ def ip_on_same_subnet(first, second, prefix):
|
||||
return ip & mask == oip & mask
|
||||
|
||||
|
||||
def ip_is_local(ipaddr):
|
||||
fam, _, _, _, ainfo = socket.getaddrinfo(ipaddr, 0, proto=socket.IPPROTO_UDP)[0]
|
||||
ipn = socket.inet_pton(fam, ainfo[0])
|
||||
if fam == socket.AF_INET6 and ipn.startswith(b'\xfe\x80'):
|
||||
return True
|
||||
for addr in get_my_addresses():
|
||||
if fam != addr[0]:
|
||||
continue
|
||||
if ipn_on_same_subnet(addr[0], ipn, addr[1], addr[2]):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def address_is_local(address):
|
||||
for iface in netifaces.interfaces():
|
||||
for i4 in netifaces.ifaddresses(iface).get(2, []):
|
||||
|
Loading…
Reference in New Issue
Block a user