From 5bdb69f214e3ad7ffd61d12b91180026e012db7c Mon Sep 17 00:00:00 2001 From: Christian Ulrich Date: Sun, 25 Oct 2020 10:46:29 +0100 Subject: [PATCH] store transport protocol in an Attempt; consider protocol when comparing attempts; puncher.getProtocol not needed anymore --- punchd.nim | 19 ++++++++++--------- puncher.nim | 14 ++++++-------- tcp_nutss.nim | 13 ++++++------- tcp_syni.nim | 10 ++++++---- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/punchd.nim b/punchd.nim index 5125ee7..a61b963 100644 --- a/punchd.nim +++ b/punchd.nim @@ -31,10 +31,10 @@ proc sendToClient(unixSock: AsyncSocket, msg: string, let unixFd = unixSock.getFd.AsyncFD await unixFd.asyncSendMsg(msg, cmsgs) -proc findAttemptsByLocalAddr(punchd: Punchd, srcIp: IpAddress, - srcPort: Port): seq[Attempt] = +proc findAttemptsByLocalAddr(punchd: Punchd, protocol: Protocol, + srcIp: IpAddress, srcPort: Port): seq[Attempt] = proc matchesLocalAddr(a: Attempt): bool = - a.srcIp == srcIp and a.srcPort == srcPort + a.protocol == protocol and a.srcIp == srcIp and a.srcPort == srcPort punchd.attempts.filter(matchesLocalAddr) proc acceptConnections(punchd: Punchd, ip: IpAddress, port: Port, @@ -68,19 +68,20 @@ proc acceptConnections(punchd: Punchd, ip: IpAddress, port: Port, else: let acceptFuture = punchd.attempts[i].acceptFuture.get() acceptFuture.complete(peer) - let localAddrMatches = punchd.findAttemptsByLocalAddr(ip, port) + let localAddrMatches = punchd.findAttemptsByLocalAddr(protocol, ip, port) if localAddrMatches.len() <= 1: break sock.close() -proc addAttempt(punchd: Punchd, attempt: Attempt, puncher: Puncher) = - let localAddrMatches = punchd.findAttemptsByLocalAddr(attempt.srcIp, +proc addAttempt(punchd: Punchd, attempt: Attempt) = + let localAddrMatches = punchd.findAttemptsByLocalAddr(attempt.protocol, + attempt.srcIp, attempt.srcPort) punchd.attempts.add(attempt) if localAddrMatches.len() == 0: if attempt.acceptFuture.isSome(): asyncCheck punchd.acceptConnections(attempt.srcIp, attempt.srcPort, - puncher.getProtocol()) + attempt.protocol) elif localAddrMatches.contains(attempt): raise newException(PunchHoleError, "hole punching for given parameters already active") @@ -101,7 +102,7 @@ proc handleRequest(punchd: Punchd, line: string, case args[0]: of "initiate": attempt = puncher.parseInitiateRequest(args[3]) - punchd.addAttempt(attempt, puncher) + punchd.addAttempt(attempt) proc progress(extraArgs: string) {.async.} = let msg = &"progress|{id}|{args[2]}|{args[3]}|{extraArgs}\n" await sendToClient(unixSock, msg) @@ -110,7 +111,7 @@ proc handleRequest(punchd: Punchd, line: string, of "respond": attempt = puncher.parseRespondRequest(args[3]) - punchd.addAttempt(attempt, puncher) + punchd.addAttempt(attempt) sock = await puncher.respond(attempt) punchd.removeAttempt(attempt) diff --git a/puncher.nim b/puncher.nim index 4750454..196b86e 100644 --- a/puncher.nim +++ b/puncher.nim @@ -16,6 +16,7 @@ type ## protocol can be obtained by calling ``getProcotol``. The puncher expects ## the caller to complete the future when a connections from ## ``dstIp``:``dstPort`` has been accepted. + protocol*: Protocol srcIp*: IpAddress srcPort*: Port dstIp*: IpAddress @@ -40,10 +41,11 @@ const Timeout* = 3000 proc `==`*(a, b: Attempt): bool = ## ``==`` for hole punching attempts. ## - ## Two hole punching attempts are considered equal if their ``srcIp``, - ## ``srcPort`` and ``dstIp`` are equal and their ``dstPorts`` overlap. - a.srcIp == b.srcIp and a.srcPort == b.srcPort and a.dstIp == b.dstIp and - a.dstPorts.any(proc (p: Port): bool = p in b.dstPorts) + ## Two hole punching attempts are considered equal if their ``protocol`` is + ## the same, ``srcIp``, ``srcPort`` and ``dstIp`` are equal and their + ## ``dstPorts`` overlap. + a.protocol == b.protocol and a.srcIp == b.srcIp and a.srcPort == b.srcPort and + a.dstIp == b.dstIp and a.dstPorts.any(proc (p: Port): bool = p in b.dstPorts) method cleanup*(attempt: Attempt): Future[void] {.base, async.} = ## Cleans up when an attempt finished (either successful or not). @@ -51,10 +53,6 @@ method cleanup*(attempt: Attempt): Future[void] {.base, async.} = ## Does nothing. Override for custom attempt types. discard -method getProtocol*(puncher: Puncher): Protocol {.base.} = - ## Returns the transport protocol the puncher employs. - raise newException(CatchableError, "Method without implementation override") - method parseInitiateRequest*(puncher: Puncher, args: string): Attempt {.base.} = ## Creates a new hole punching attempt by parsing arguments of an ``initiate`` ## request. diff --git a/tcp_nutss.nim b/tcp_nutss.nim index 01c1d2a..ca15a68 100644 --- a/tcp_nutss.nim +++ b/tcp_nutss.nim @@ -56,23 +56,22 @@ proc initTcpNutssPuncher*(): TcpNutssPuncher = randomize() TcpNutssPuncher() -method getProtocol*(puncher: TcpNutssPuncher): Protocol = - IPPROTO_TCP - method parseInitiateRequest*(puncher: TcpNutssPuncher, args: string): Attempt = let parsed = parseMessage[InitiateRequest](args) let localIp = getPrimaryIPAddr(parsed.dstIp) let predictedDstPorts = predictPortRange(parsed.dstPorts) let acceptFuture = newFuture[AsyncSocket]("parseInitiateRequest") - Attempt(srcIp: localIp, srcPort: parsed.srcPorts[0], dstIp: parsed.dstIp, - dstPorts: predictedDstPorts, acceptFuture: some(acceptFuture)) + Attempt(protocol: IPPROTO_TCP, srcIp: localIp, srcPort: parsed.srcPorts[0], + dstIp: parsed.dstIp, dstPorts: predictedDstPorts, + acceptFuture: some(acceptFuture)) method parseRespondRequest*(puncher: TcpNutssPuncher, args: string): Attempt = let parsed = parseMessage[RespondRequest](args) let localIp = getPrimaryIPAddr(parsed.dstIp) let predictedDstPorts = predictPortRange(parsed.dstPorts) - Attempt(srcIp: localIp, srcPort: parsed.srcPorts[0], dstIp: parsed.dstIp, - dstPorts: predictedDstPorts, acceptFuture: none(Future[AsyncSocket])) + Attempt(protocol: IPPROTO_TCP, srcIp: localIp, srcPort: parsed.srcPorts[0], + dstIp: parsed.dstIp, dstPorts: predictedDstPorts, + acceptFuture: none(Future[AsyncSocket])) method initiate*(puncher: TcpNutssPuncher, attempt: Attempt, progress: PunchProgressCb): Future[AsyncSocket] {.async.} = diff --git a/tcp_syni.nim b/tcp_syni.nim index d2f6f34..3b78f36 100644 --- a/tcp_syni.nim +++ b/tcp_syni.nim @@ -137,8 +137,9 @@ method parseInitiateRequest*(puncher: TcpSyniPuncher, args: string): Attempt = let parsed = parseMessage[InitiateRequest](args) let localIp = getPrimaryIPAddr(parsed.dstIp) let predictedDstPorts = predictPortRange(parsed.dstPorts) - TcpSyniInitiateAttempt(srcIp: localIp, srcPort: parsed.srcPorts[0], - dstIp: parsed.dstIp, dstPorts: predictedDstPorts, + TcpSyniInitiateAttempt(protocol: IPPROTO_TCP, srcIp: localIp, + srcPort: parsed.srcPorts[0], dstIp: parsed.dstIp, + dstPorts: predictedDstPorts, acceptFuture: none(Future[AsyncSocket])) method parseRespondRequest*(puncher: TcpSyniPuncher, args: string): Attempt = @@ -146,8 +147,9 @@ method parseRespondRequest*(puncher: TcpSyniPuncher, args: string): Attempt = let localIp = getPrimaryIPAddr(parsed.dstIp) let predictedDstPorts = predictPortRange(parsed.dstPorts) let acceptFuture = newFuture[AsyncSocket]("parseRespondRequest") - TcpSyniRespondAttempt(srcIp: localIp, srcPort: parsed.srcPorts[0], - dstIp: parsed.dstIp, dstPorts: predictedDstPorts, + TcpSyniRespondAttempt(protocol: IPPROTO_TCP, srcIp: localIp, + srcPort: parsed.srcPorts[0], dstIp: parsed.dstIp, + dstPorts: predictedDstPorts, acceptFuture: some(acceptFuture), seqNums: parsed.seqNums)