Faster, async local ip discovery

This commit is contained in:
shortcutme 2019-11-25 14:40:52 +01:00
parent 4f8e941e39
commit 29346cdef5
No known key found for this signature in database
GPG key ID: 5B63BAE6CB9613AE

View file

@ -17,6 +17,7 @@ import gevent
logger = logging.getLogger("Upnp") logger = logging.getLogger("Upnp")
class UpnpError(Exception): class UpnpError(Exception):
pass pass
@ -128,33 +129,47 @@ def _parse_igd_profile(profile_xml):
# add description # add description
def _get_local_ips(): def _get_local_ips():
def method1():
try:
# get local ip using UDP and a broadcast address
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
# Not using <broadcast> because gevents getaddrinfo doesn't like that
# using port 1 as per hobbldygoop's comment about port 0 not working on osx:
# https://github.com/sirMackk/ZeroNet/commit/fdcd15cf8df0008a2070647d4d28ffedb503fba2#commitcomment-9863928
s.connect(('239.255.255.250', 1))
return [s.getsockname()[0]]
except:
pass
def method2():
# Get ip by using UDP and a normal address (google dns ip)
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('8.8.8.8', 0))
return [s.getsockname()[0]]
except:
pass
def method3():
# Get ip by '' hostname . Not supported on all platforms.
try:
return socket.gethostbyname_ex('')[2]
except:
pass
threads = [
gevent.spawn(method1),
gevent.spawn(method2),
gevent.spawn(method3)
]
gevent.joinall(threads, timeout=5)
local_ips = [] local_ips = []
for thread in threads:
try: if thread.value:
# get local ip using UDP and a broadcast address local_ips += thread.value
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
# Not using <broadcast> because gevents getaddrinfo doesn't like that
# using port 1 as per hobbldygoop's comment about port 0 not working on osx:
# https://github.com/sirMackk/ZeroNet/commit/fdcd15cf8df0008a2070647d4d28ffedb503fba2#commitcomment-9863928
s.connect(('239.255.255.250', 1))
local_ips.append(s.getsockname()[0])
except:
pass
# Get ip by using UDP and a normal address (google dns ip)
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('8.8.8.8', 0))
local_ips.append(s.getsockname()[0])
except:
pass
# Get ip by '' hostname . Not supported on all platforms.
try:
local_ips += socket.gethostbyname_ex('')[2]
except:
pass
# Delete duplicates # Delete duplicates
local_ips = list(set(local_ips)) local_ips = list(set(local_ips))
@ -373,8 +388,6 @@ if __name__ == "__main__":
print("Success:", ask_to_open_port(15443, "ZeroNet", protos=["TCP"])) print("Success:", ask_to_open_port(15443, "ZeroNet", protos=["TCP"]))
print("Done in", time.time() - s) print("Done in", time.time() - s)
print("Closing port...") print("Closing port...")
print("Success:", ask_to_close_port(15443, "ZeroNet", protos=["TCP"])) print("Success:", ask_to_close_port(15443, "ZeroNet", protos=["TCP"]))
print("Done in", time.time() - s) print("Done in", time.time() - s)