only accept once and only use one injection socket

This commit is contained in:
Christian Ulrich 2020-07-18 15:04:06 +02:00
parent ef68519eec
commit 3f9cb6a3b1
No known key found for this signature in database
GPG Key ID: 8241BE099775A097
1 changed files with 20 additions and 19 deletions

View File

@ -131,14 +131,15 @@ proc doConnect(srcIp: IpAddress, srcPort: Port, dstIp: IpAddress,
echo &"connection {srcIP}:{srcPort.int} -> {dstIp}:{dstPort.int} failed: ", e.msg echo &"connection {srcIP}:{srcPort.int} -> {dstIp}:{dstPort.int} failed: ", e.msg
discard discard
proc doAccept(srcIp: IpAddress, srcPort: Port, dstIp: IpAddress, dstPort: Port, proc doAccept(puncher: TcpSyniPuncher, future: Future[AsyncSocket]) {.async.} =
seqNums: seq[uint32], future: Future[AsyncSocket]) {.async.} = for dstPort in puncher.dstPorts:
# TODO: connect in parallel for better performance
try: try:
let sock = newAsyncSocket() let sock = newAsyncSocket()
sock.setSockOpt(OptReuseAddr, true) sock.setSockOpt(OptReuseAddr, true)
sock.getFd.setSockOptInt(IPPROTO_IP, IP_TTL, 2) sock.getFd.setSockOptInt(IPPROTO_IP, IP_TTL, 2)
sock.bindAddr(srcPort, $srcIp) sock.bindAddr(puncher.srcPort, $(puncher.srcIp))
await sock.connect($dstIp, dstPort) await sock.connect($(puncher.dstIp), dstPort)
echo "connected during accept phase" echo "connected during accept phase"
sock.close() sock.close()
except OSError: except OSError:
@ -146,16 +147,18 @@ proc doAccept(srcIp: IpAddress, srcPort: Port, dstIp: IpAddress, dstPort: Port,
try: try:
# FIXME: timeout # FIXME: timeout
let rawFd = setupTcpInjectingSocket() let rawFd = setupTcpInjectingSocket()
asyncCheck injectSyns(rawFd, dstIp, dstPort, srcIp, srcPort, seqNums) for dstPort in puncher.dstPorts:
asyncCheck injectSyns(rawFd, puncher.dstIp, dstPort, puncher.srcIp,
puncher.srcPort, puncher.seqNums)
let sock = newAsyncSocket() let sock = newAsyncSocket()
sock.setSockOpt(OptReuseAddr, true) sock.setSockOpt(OptReuseAddr, true)
sock.setSockOpt(OptReusePort, true) sock.bindAddr(puncher.srcPort, $(puncher.srcIp))
sock.bindAddr(srcPort, $srcIp)
sock.listen() sock.listen()
echo &"accepting connections from {puncher.dstIp}:{puncher.dstPorts[0].int}"
let connectedSock = await sock.accept() let connectedSock = await sock.accept()
future.complete(connectedSock) future.complete(connectedSock)
except OSError as e: except OSError as e:
echo &"accepting connection {dstIP}:{dstPort.int} -> {srcIp}:{srcPort.int} failed: ", e.msg echo &"accepting connections from {puncher.dstIP}:{puncher.dstPorts[0].int} failed: ", e.msg
discard discard
proc connect*(puncher: TcpSyniPuncher, proc connect*(puncher: TcpSyniPuncher,
@ -170,6 +173,4 @@ proc connect*(puncher: TcpSyniPuncher,
proc accept*(puncher: TcpSyniPuncher): Future[AsyncSocket] = proc accept*(puncher: TcpSyniPuncher): Future[AsyncSocket] =
result = newFuture[AsyncSocket]("tcp_syni.accept") result = newFuture[AsyncSocket]("tcp_syni.accept")
for dstPort in puncher.dstPorts: asyncCheck puncher.doAccept(result)
asyncCheck doAccept(puncher.srcIp, puncher.srcPort, puncher.dstIp, dstPort,
puncher.seqNums, result)