probe ports and use results to register and notify peer
This commit is contained in:
parent
187b232162
commit
6e36b5addd
|
@ -22,6 +22,8 @@ type
|
||||||
sock: AsyncSocket
|
sock: AsyncSocket
|
||||||
outMessages: TableRef[string, Future[string]]
|
outMessages: TableRef[string, Future[string]]
|
||||||
peerNotifications: FutureStream[string]
|
peerNotifications: FutureStream[string]
|
||||||
|
probedIp: IpAddress
|
||||||
|
probedPorts: seq[Port]
|
||||||
|
|
||||||
# Punchd messages
|
# Punchd messages
|
||||||
ProgressTcpSyniConnect* = object
|
ProgressTcpSyniConnect* = object
|
||||||
|
@ -152,36 +154,50 @@ proc punchHole(punchdConn: PunchdConnection, serverConn: ServerConnection,
|
||||||
future.fail(e)
|
future.fail(e)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
future.fail(e)
|
future.fail(e)
|
||||||
let myPorts = &"{1234},{1234},{1234}"
|
let myPorts = (@[Port(1234)] & serverConn.probedPorts).join(",")
|
||||||
let peerPorts = peerInfo.ports.join(",")
|
let peerPorts = peerInfo.ports.join(",")
|
||||||
let req = &"{ipAddress}|{myPorts}|{peerInfo.ip}|{peerPorts}"
|
let req = &"{ipAddress}|{myPorts}|{peerInfo.ip}|{peerPorts}"
|
||||||
let pResp = await punchdConn.sendRequest("tcp-syni-connect", req, progressCb)
|
let pResp = await punchdConn.sendRequest("tcp-syni-connect", req, progressCb)
|
||||||
result = pResp.sock
|
result = pResp.sock
|
||||||
|
|
||||||
|
proc initServerConnection(serverHostname: string, serverPort: Port,
|
||||||
|
myPort: Port, probePorts: bool):
|
||||||
|
Future[ServerConnection] {.async.} =
|
||||||
|
if probePorts:
|
||||||
|
for i in 0 .. 1:
|
||||||
|
let sock = newAsyncSocket()
|
||||||
|
sock.setSockOpt(OptReuseAddr, true)
|
||||||
|
sock.bindAddr(myPort)
|
||||||
|
await sock.connect(serverHostname, serverPort)
|
||||||
|
let line = await sock.recvLine(maxLength = 400)
|
||||||
|
let endpoint = parseMessage[NotifyEndpoint](line)
|
||||||
|
result.probedPorts.add(endpoint.port)
|
||||||
|
sock.close()
|
||||||
|
result.sock = await asyncnet.dial(serverHostname, serverPort)
|
||||||
|
let line = await result.sock.recvLine(maxLength = 400)
|
||||||
|
result.probedIp = parseMessage[NotifyEndpoint](line).ip
|
||||||
|
result.outMessages = newTable[string, Future[string]]()
|
||||||
|
result.peerNotifications = newFutureStream[string]("initServerConnection")
|
||||||
|
|
||||||
proc runApp(serverHostname: string, serverPort: Port, peerId: string,
|
proc runApp(serverHostname: string, serverPort: Port, peerId: string,
|
||||||
otherPeerId: string = "") {.async.} =
|
otherPeerId: string = "") {.async.} =
|
||||||
# TODO: determine endpoint in another proc
|
|
||||||
randomize() # initialize random number generator
|
randomize() # initialize random number generator
|
||||||
var punchdConn = PunchdConnection()
|
var punchdConn = PunchdConnection()
|
||||||
punchdConn.sock = newAsyncSocket(AF_UNIX, SOCK_STREAM, IPPROTO_IP)
|
punchdConn.sock = newAsyncSocket(AF_UNIX, SOCK_STREAM, IPPROTO_IP)
|
||||||
punchdConn.outMessages = newTable[string, OutgoingPunchdMessage]()
|
punchdConn.outMessages = newTable[string, OutgoingPunchdMessage]()
|
||||||
punchdConn.inConnections = newFutureStream[AsyncSocket]("runApp")
|
punchdConn.inConnections = newFutureStream[AsyncSocket]("runApp")
|
||||||
await punchdConn.sock.connectUnix("/tmp/punchd.socket")
|
await punchdConn.sock.connectUnix("/tmp/punchd.socket")
|
||||||
var serverConn = ServerConnection()
|
|
||||||
serverConn.sock = await asyncnet.dial(serverHostname, serverPort, IPPROTO_TCP)
|
|
||||||
serverConn.outMessages = newTable[string, Future[string]]()
|
|
||||||
serverConn.peerNotifications = newFutureStream[string]("runApp")
|
|
||||||
let resp = await serverConn.sock.recvLine(maxLength = 400)
|
|
||||||
let endpoint = parseMessage[NotifyEndpoint](resp)
|
|
||||||
echo &"rendezvous server says I am {endpoint.ip}:{endpoint.port.int}"
|
|
||||||
asyncCheck handlePunchdMessages(punchdConn)
|
asyncCheck handlePunchdMessages(punchdConn)
|
||||||
asyncCheck handleServerMessages(serverConn)
|
|
||||||
asyncCheck handlePeerNotifications(serverConn, punchdConn, peerId)
|
|
||||||
if otherPeerId.len == 0:
|
if otherPeerId.len == 0:
|
||||||
# register and wait for connections
|
# register and wait for connections
|
||||||
let req = &"{peerId}|{endpoint.ip}|{endpoint.port.int},{endpoint.port.int},{endpoint.port.int}"
|
let serverConn = await initServerConnection(serverHostname, serverPort,
|
||||||
|
Port(4321), true)
|
||||||
|
asyncCheck handleServerMessages(serverConn)
|
||||||
|
asyncCheck handlePeerNotifications(serverConn, punchdConn, peerId)
|
||||||
|
let myPorts = (@[Port(4321)] & serverConn.probedPorts).join(",")
|
||||||
|
let req = &"{peerId}|{serverConn.probedIp}|{myPorts}"
|
||||||
|
echo "registering: ", req
|
||||||
discard await serverConn.sendRequest("register", req)
|
discard await serverConn.sendRequest("register", req)
|
||||||
echo "registered"
|
|
||||||
while true:
|
while true:
|
||||||
let (hasSock, sock) = await punchdConn.inConnections.read
|
let (hasSock, sock) = await punchdConn.inConnections.read
|
||||||
if not hasSock:
|
if not hasSock:
|
||||||
|
@ -193,8 +209,11 @@ proc runApp(serverHostname: string, serverPort: Port, peerId: string,
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# initiate a new connection
|
# initiate a new connection
|
||||||
let sock = await punchHole(punchdConn, serverConn, endpoint.ip, peerId,
|
let serverConn = await initServerConnection(serverHostname, serverPort,
|
||||||
otherPeerId)
|
Port(1234), true)
|
||||||
|
asyncCheck handleServerMessages(serverConn)
|
||||||
|
let sock = await punchHole(punchdConn, serverConn, serverConn.probedIp,
|
||||||
|
peerId, otherPeerId)
|
||||||
await sock.send("ping")
|
await sock.send("ping")
|
||||||
let msg = await sock.recv(1000)
|
let msg = await sock.recv(1000)
|
||||||
echo "received message: ", msg
|
echo "received message: ", msg
|
||||||
|
|
Loading…
Reference in New Issue