Async port opening using different nic ips
This commit is contained in:
parent
5026f1b0a8
commit
b01e381087
1 changed files with 35 additions and 14 deletions
|
@ -7,6 +7,7 @@ from xml.dom.minidom import parseString
|
|||
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
|
||||
|
@ -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":
|
||||
|
@ -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(
|
||||
|
@ -330,7 +351,7 @@ 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)
|
||||
|
||||
|
@ -338,15 +359,15 @@ def ask_to_close_port(port=15441, desc="UpnpPunch", retries=3, protos=("TCP", "U
|
|||
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue