This commit is contained in:
yumoqing 2022-02-28 12:06:25 +08:00
parent 4edcf6e510
commit 244c939c9c
6 changed files with 91 additions and 90 deletions

View File

@ -22,20 +22,14 @@ class AcrossNat(object):
except pmp.NATPMPUnsupportedError:
self.pmp_supported = False
def init_upnp(self):
try:
self.upnp = UPnP()
devices = self.upnp.discover()
if len(devices) == 0:
self.upnp_supported = False
except:
self.upnp_supported = False
async def get_external_ip(self):
if self.pmp_supported:
return self._pmp_get_external_ip()
self.external_ip = pmp.get_public_address()
return self.external_ip
if self.upnp_supported:
if self.upnp is None:
await self.init_upnp()
return await self.upnp.get_external_ip()
try:
@ -43,13 +37,10 @@ class AcrossNat(object):
except:
return get('https://ipapi.co/ip/').text
def _pmp_get_external_ip(self):
return pmp.get_public_address()
def _upnp_get_external_ip(self):
await def upnp_map_port(inner_port, protocol='TCP', from_port=40003):
async def upnp_map_port(self, inner_port,
protocol='TCP', from_port=40003):
if self.upnp is None:
await self.init_upnp()
protocol = protocol.upper()
external_port = from_port
while external_port < 52333:
@ -68,6 +59,8 @@ class AcrossNat(object):
return None
async def is_port_mapped(self, external_port, protocol='TCP'):
if self.upnp is None:
await self.init_upnp()
protocol = protocol.upper()
if self.upnp_supported:
x = await self.upnp.get_specific_port_mapping(external_port,
@ -78,81 +71,25 @@ class AcrossNat(object):
raise Exception('not implemented')
async def port_unmap(self, external_port, protocol='TCP'):
if self.upnp is None:
await self.init_upnp()
protocol = protocol.upper()
if self.upnp_supported:
await self.upnp.delete_port_mapping(external_port, protocol)
raise Exception('not implemented')
def map_port(self, inner_port, protocol='tcp', from_port=40003):
if pmp_supported:
return _map_port(inner_port, protocol=protocol)
return self.upnp.add_port_mapping(
inner_port, protocol=protocol)
pmp_supported = True
"""
_natmap mapping a localhost port to network gateway outter ip's port
input:
port: integer, localhost host port
protocal: string, 'tcp', or 'udp', default is 'tcp'
from_port: integer, the return port will from this prot,
default is 49000, if mapping failed, increases by one,
and try it again.
return:
gateway outter ip's port, if gateway not support natpmp, return None
"""
def pmp_getExtenalIPAddress():
return pmp.get_public_address()
def get_external_ip():
global pmp_supported
if pmp_supported:
try:
return pmp_get_public_address()
except pmp.NATPMPUnsupportedError:
pmp_supported = False
except Exception as e:
raise e
upnp = UPnP()
devices = upnp.discover()
if len(devices) < 1:
return None
d = devices[0]
services = d.get_services()
def _pmp_natmap(innerport,
protocol='tcp',
from_port=49000,
timeout=3600):
gateway = pmp.get_gateway_addr()
ret_port = from_port
while 1:
try:
mode = pmp.NATPMP_PROTOCOL_TCP
if protocol != 'tcp':
mode = pmp.NATPMP_PROTOCOL_UDP
x = pmp.map_port(mode,
ret_port,
innerport,
timeout,
gateway_ip=gateway)
def pmp_map_port(self, inner_port, protocol='TCP', from_port=40003):
if protocol.upper() == 'TCP':
x = pmp.map_tcp_port(from_port, inner_port,
lifetime=999999999)
return x.public_port
except pmp.NATPMPUnsupportedError:
return None
except Exception, e:
time.sleep(0.01)
ret_port+=1
if ret_port > 60000:
return None
x = pmp.map_udp_port(from_port, inner_port,
lifetime=999999999)
return x.public_port
async def map_port(self, inner_port, protocol='tcp', from_port=40003):
if self.pmp_supported:
return self.pmp_map_port(inner_port, protocol=protocol)
return await self.upnp_map_port( inner_port, protocol=protocol)
def natmap(

View File

@ -68,6 +68,8 @@ class KeyChain(object):
self.keylen = keylen
self.keypool = {
}
delta = datetime.timedelta(0)
self.timezone = datetime.timezone(delta, name='gmt')
def genKey(self, y, m, d):
vv = y * 1000 + m * 100 + d
@ -95,7 +97,7 @@ class KeyChain(object):
return self.encode_bytes(bdata)
def encode_bytes(self, bdata):
dt = datetime.datetime.now()
dt = datetime.datetime.now(self.timezone)
key = self.genKey(dt.year, dt.month, dt.day)
data = key + bdata
return self.crypter.encode_bytes(data, key)
@ -107,7 +109,7 @@ class KeyChain(object):
return None
def decode_bytes(self, data):
dt = datetime.datetime.now()
dt = datetime.datetime.now(self.timezone)
key = self.genKey(dt.year, dt.month, dt.day)
d = self._decode(data, key)
if d is not None:

View File

@ -8,6 +8,7 @@ cryptography
brotli
aiohttp
aioupnp
natpmp
asyncio
requests
jinja2

17
test/test_across_nat.py Normal file
View File

@ -0,0 +1,17 @@
from appPublic.across_nat import *
import asyncio
async def run():
an = AcrossNat()
an.pmp_supported = False
x = await an.get_external_ip()
print('external ip=', x)
print('pmp_supported=', an.pmp_supported,
'upnp_supported=', an.upnp_supported)
for p in [ 8080, 8081 ]:
x = await an.map_port(p, 'TCP')
print(p, '-->', x)
loop = asyncio.get_event_loop()
loop.run_until_complete(run())

26
test/test_aioupnp.py Normal file
View File

@ -0,0 +1,26 @@
import asyncio
from aioupnp.upnp import UPnP
async def main():
upnp = await UPnP.discover()
print(dir(upnp))
print('gateway=', upnp.gateway, upnp.gateway_address, upnp.lan_address)
print(await upnp.get_external_ip())
print(await upnp.get_redirects())
x = await upnp.get_specific_port_mapping(40009, 'TCP')
if len(x) == 0:
print('port available')
print("adding a port mapping")
x = await upnp.add_port_mapping(40009, 'TCP', 8999, '192.168.1.8', 'test mapping')
print('x=', x, await upnp.get_redirects())
# print("deleting the port mapping")
# await upnp.delete_port_mapping(51234, 'TCP')
print(await upnp.get_redirects())
asyncio.run(main())

18
test/zmqreply.py Normal file
View File

@ -0,0 +1,18 @@
from appPublic.zmq_reqrep import ZmqReplier
import time
def handler(b):
print(b.decode('utf-8'))
return 'got it'
x = ZmqReplier('tcp://127.0.0.1:9999', handler)
x.run()
f = 0
while 1:
time.sleep(0.1)
if f==0:
print(dir(x.sock.get_peer()))
f += 1
x.stop()