2
0
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:
Jarrod Johnson 2022-09-06 16:08:31 -04:00
parent 7980534bad
commit 596fcb0f4c
3 changed files with 20 additions and 1 deletions

View File

@ -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:]

View File

@ -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:

View File

@ -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, []):