diff --git a/tcp_syni.nim b/tcp_syni.nim index 69cd156..9c06c2d 100644 --- a/tcp_syni.nim +++ b/tcp_syni.nim @@ -77,6 +77,18 @@ proc captureSeqNumbers(puncher: TcpSyniPuncher, rawFd: AsyncFD, break await cb(seqNums) +proc injectSyns(rawFd: AsyncFD, srcIp: IpAddress, srcPort: Port, + dstIp: IpAddress, dstPort: Port, + seqNums: seq[uint32]) {.async.} = + for seqNum in seqNums: + let ipPacket = IpPacket(protocol: tcp, + tcpIpSrc: srcIp, + tcpIpDst: dstIp, + tcpPortSrc: dstPort, + tcpPortDst: srcPort, + tcpSeqNumber: seqNum) + asyncCheck rawFd.send(serialize(ipPacket)) + proc initPuncher*(srcPort: Port, dstIp: IpAddress, dstPorts: array[3, Port], seqNums: seq[uint32] = @[]): Future[TcpSyniPuncher] {.async.} = let localIp = getPrimaryIPAddr(dstIp) @@ -107,6 +119,25 @@ proc doConnect(srcIp: IpAddress, srcPort: Port, dstIp: IpAddress, echo &"connection {srcIP}:{srcPort.int} -> {dstIp}:{dstPort.int} failed: ", e.msg discard +proc doAccept(srcIp: IpAddress, srcPort: Port, dstIp: IpAddress, dstPort: Port, + future: Future[AsyncSocket]) {.async.} = + let sock = newAsyncSocket() + sock.setSockOpt(OptReuseAddr, true) + sock.getFd.setSockOptInt(IPPROTO_IP, IP_TTL, 2) + sock.bindAddr(srcPort, $srcIp) + try: + await sock.connect($dstIp, dstPort) + echo "connected during accept phase" + sock.close() + except OSError: + discard + try: + let connectedSock = await sock.accept() + future.complete(connectedSock) + except OSError as e: + echo &"connection {srcIP}:{srcPort.int} -> {dstIp}:{dstPort.int} failed: ", e.msg + discard + proc connect*(puncher: TcpSyniPuncher, progressCb: PunchProgressCb): Future[AsyncSocket] = result = newFuture[AsyncSocket]("tcp_syni.connect") @@ -119,3 +150,9 @@ proc connect*(puncher: TcpSyniPuncher, proc accept*(puncher: TcpSyniPuncher): Future[AsyncSocket] = result = newFuture[AsyncSocket]("tcp_syni.accept") + let rawFd = setupTcpInjectingSocket() + for dstPort in puncher.dstPorts: + asyncCheck doAccept(puncher.srcIp, puncher.srcPort, puncher.dstIp, dstPort, + result) + asyncCheck injectSyns(rawFd, puncher.srcIp, puncher.srcPort, puncher.dstIp, + dstPort, puncher.seqNums)