change hint format to "tcp:HOST:PORT"
This commit is contained in:
parent
d71c8492c1
commit
b27cbd19b6
|
@ -1,5 +1,5 @@
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import threading, socket, SocketServer
|
import re, threading, socket, SocketServer
|
||||||
from binascii import hexlify
|
from binascii import hexlify
|
||||||
from ..util import ipaddrs
|
from ..util import ipaddrs
|
||||||
from ..util.hkdf import HKDF
|
from ..util.hkdf import HKDF
|
||||||
|
@ -72,30 +72,62 @@ def send_to(skt, data):
|
||||||
while sent < len(data):
|
while sent < len(data):
|
||||||
sent += skt.send(data[sent:])
|
sent += skt.send(data[sent:])
|
||||||
|
|
||||||
def wait_for(skt, expected, hint):
|
def wait_for(skt, expected, description):
|
||||||
got = b""
|
got = b""
|
||||||
while len(got) < len(expected):
|
while len(got) < len(expected):
|
||||||
got += skt.recv(1)
|
got += skt.recv(1)
|
||||||
if expected[:len(got)] != got:
|
if expected[:len(got)] != got:
|
||||||
raise BadHandshake("got '%r' want '%r' on %s" %
|
raise BadHandshake("got '%r' want '%r' on %s" %
|
||||||
(got, expected, hint))
|
(got, expected, description))
|
||||||
|
|
||||||
|
# The hint format is: TYPE,VALUE= /^([a-zA-Z0-9]+):(.*)$/ . VALUE depends
|
||||||
|
# upon TYPE, and it can have more colons in it. For TYPE=tcp (the only one
|
||||||
|
# currently defined), ADDR,PORT = /^(.*):(\d+)$/ , so ADDR can have colons.
|
||||||
|
# ADDR can be a hostname, ipv4 dotted-quad, or ipv6 colon-hex. If the hint
|
||||||
|
# publisher wants anonymity, their only hint's ADDR will end in .onion .
|
||||||
|
|
||||||
|
def parse_hint_tcp(hint):
|
||||||
|
# return tuple or None for an unparseable hint
|
||||||
|
mo = re.search(r'^([a-zA-Z0-9]+):(.*)$', hint)
|
||||||
|
if not mo:
|
||||||
|
print("unparseable hint '%s'" % (hint,))
|
||||||
|
return None
|
||||||
|
hint_type = mo.group(1)
|
||||||
|
if hint_type != "tcp":
|
||||||
|
print("unknown hint type '%s' in '%s'" % (hint_type, hint))
|
||||||
|
return None
|
||||||
|
hint_value = mo.group(2)
|
||||||
|
mo = re.search(r'^(.*):(\d+)$', hint_value)
|
||||||
|
if not mo:
|
||||||
|
print("unparseable TCP hint '%s'" % (hint,))
|
||||||
|
return None
|
||||||
|
hint_host = mo.group(1)
|
||||||
|
try:
|
||||||
|
hint_port = int(mo.group(2))
|
||||||
|
except ValueError:
|
||||||
|
print("non-numeric port in TCP hint '%s'" % (hint,))
|
||||||
|
return None
|
||||||
|
return hint_host, hint_port
|
||||||
|
|
||||||
def connector(owner, hint, description,
|
def connector(owner, hint, description,
|
||||||
send_handshake, expected_handshake, relay_handshake=None):
|
send_handshake, expected_handshake, relay_handshake=None):
|
||||||
addr,port = hint.split(",")
|
parsed_hint = parse_hint_tcp(hint)
|
||||||
|
if not parsed_hint:
|
||||||
|
return # unparseable
|
||||||
|
addr,port = parsed_hint
|
||||||
skt = None
|
skt = None
|
||||||
try:
|
try:
|
||||||
skt = socket.create_connection((addr,port),
|
skt = socket.create_connection((addr,port),
|
||||||
TIMEOUT) # timeout or ECONNREFUSED
|
TIMEOUT) # timeout or ECONNREFUSED
|
||||||
skt.settimeout(TIMEOUT)
|
skt.settimeout(TIMEOUT)
|
||||||
#print("socket(%s) connected" % (hint,))
|
#print("socket(%s) connected" % (description,))
|
||||||
if relay_handshake:
|
if relay_handshake:
|
||||||
send_to(skt, relay_handshake)
|
send_to(skt, relay_handshake)
|
||||||
wait_for(skt, "ok\n", hint)
|
wait_for(skt, "ok\n", description)
|
||||||
#print("relay ready %r" % (hint,))
|
#print("relay ready %r" % (description,))
|
||||||
send_to(skt, send_handshake)
|
send_to(skt, send_handshake)
|
||||||
wait_for(skt, expected_handshake, hint)
|
wait_for(skt, expected_handshake, description)
|
||||||
#print("connector ready %r" % (hint,))
|
#print("connector ready %r" % (description,))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
try:
|
try:
|
||||||
if skt:
|
if skt:
|
||||||
|
@ -180,7 +212,7 @@ class Common:
|
||||||
def _start_server(self):
|
def _start_server(self):
|
||||||
server = MyTCPServer(("", 0), None)
|
server = MyTCPServer(("", 0), None)
|
||||||
_, port = server.server_address
|
_, port = server.server_address
|
||||||
self.my_direct_hints = ["%s,%d" % (addr, port)
|
self.my_direct_hints = ["tcp:%s:%d" % (addr, port)
|
||||||
for addr in ipaddrs.find_addresses()]
|
for addr in ipaddrs.find_addresses()]
|
||||||
server.owner = self
|
server.owner = self
|
||||||
server_thread = threading.Thread(target=server.serve_forever)
|
server_thread = threading.Thread(target=server.serve_forever)
|
||||||
|
@ -232,7 +264,7 @@ class Common:
|
||||||
def _start_connector(self, hint, is_relay=False):
|
def _start_connector(self, hint, is_relay=False):
|
||||||
description = "->%s" % (hint,)
|
description = "->%s" % (hint,)
|
||||||
if is_relay:
|
if is_relay:
|
||||||
description = "->relay@%s" % (hint,)
|
description = "->relay:%s" % (hint,)
|
||||||
args = (self, hint, description,
|
args = (self, hint, description,
|
||||||
self._send_this(), self._expect_this())
|
self._send_this(), self._expect_this())
|
||||||
if is_relay:
|
if is_relay:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user