Skip to content

Commit

Permalink
Async port opening using different nic ips
Browse files Browse the repository at this point in the history
  • Loading branch information
shortcutme committed Nov 9, 2017
1 parent 5026f1b commit b01e381
Showing 1 changed file with 35 additions and 14 deletions.
49 changes: 35 additions & 14 deletions src/util/UpnpPunch.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from xml.parsers.expat import ExpatError

from gevent import socket
import gevent

# Relevant UPnP spec:
# http://www.upnp.org/specs/gw/UPnP-gw-WANIPConnection-v1-Service.pdf
Expand Down Expand Up @@ -46,7 +47,7 @@ def perform_m_search(local_ip):

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

sock.bind((local_ip, 10000))
sock.bind((local_ip, 0))

sock.sendto(ssdp_request, ('239.255.255.250', 1900))
if local_ip == "127.0.0.1":
Expand Down Expand Up @@ -295,20 +296,40 @@ def _communicate_with_igd(port=15441,
Manage sending a message generated by 'fn'.
"""

# Retry every ip 'retries' times
local_ips = _get_local_ips() * retries
local_ips = _get_local_ips()
success = False

def job(local_ip):
for retry in range(retries):
try:
_orchestrate_soap_request(local_ip, port, fn, desc, protos)
return True
except (UpnpError, IGDError) as e:
logging.debug('Upnp request using "{0}" failed: {1}'.format(
local_ip, e))
gevent.sleep(1)
return False

threads = []

for local_ip in local_ips:
try:
_orchestrate_soap_request(local_ip, port, fn, desc, protos)
thread = gevent.spawn(job, local_ip)
threads.append(thread)
gevent.sleep(0.1)
if any([thread.value for thread in threads]):
success = True
break
except (UpnpError, IGDError) as e:
logging.debug('Upnp request using "{0}" failed: {1}'.format(
local_ip, e))
success = False
continue

# Wait another 10sec for competition or any positibe result
for _ in range(10):
all_done = all([thread.value != None for thread in threads])
any_succeed = any([thread.value for thread in threads])
if all_done or any_succeed:
break
gevent.sleep(1)

if any([thread.value for thread in threads]):
success = True

if not success:
raise UpnpError(
Expand All @@ -330,23 +351,23 @@ def ask_to_close_port(port=15441, desc="UpnpPunch", retries=3, protos=("TCP", "U
# retries=1 because multiple successes cause 500 response and failure
_communicate_with_igd(port=port,
desc=desc,
retries=1,
retries=retries,
fn=_create_close_message,
protos=protos)



if __name__ == "__main__":
from gevent import monkey
monkey.patch_socket()
monkey.patch_all()
logging.getLogger().setLevel(logging.DEBUG)
import time

s = time.time()
print "Opening port..."
print ask_to_open_port(15443, "ZeroNet", retries=3, protos=["TCP"])
print ask_to_open_port(15443, "ZeroNet",protos=["TCP"])
print "Done in", time.time()-s

print "Closing port..."
print ask_to_close_port(15443, "ZeroNet", retries=3, protos=["TCP"])
print ask_to_close_port(15443, "ZeroNet", protos=["TCP"])
print "Done in", time.time()-s

0 comments on commit b01e381

Please sign in to comment.