implement SYNI accept logic

This commit is contained in:
Christian Ulrich 2020-07-11 14:46:37 +02:00
parent d57f293efa
commit 07716a3709
No known key found for this signature in database
GPG Key ID: 8241BE099775A097
1 changed files with 37 additions and 0 deletions

View File

@ -77,6 +77,18 @@ proc captureSeqNumbers(puncher: TcpSyniPuncher, rawFd: AsyncFD,
break break
await cb(seqNums) 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], proc initPuncher*(srcPort: Port, dstIp: IpAddress, dstPorts: array[3, Port],
seqNums: seq[uint32] = @[]): Future[TcpSyniPuncher] {.async.} = seqNums: seq[uint32] = @[]): Future[TcpSyniPuncher] {.async.} =
let localIp = getPrimaryIPAddr(dstIp) 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 echo &"connection {srcIP}:{srcPort.int} -> {dstIp}:{dstPort.int} failed: ", e.msg
discard 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, proc connect*(puncher: TcpSyniPuncher,
progressCb: PunchProgressCb): Future[AsyncSocket] = progressCb: PunchProgressCb): Future[AsyncSocket] =
result = newFuture[AsyncSocket]("tcp_syni.connect") result = newFuture[AsyncSocket]("tcp_syni.connect")
@ -119,3 +150,9 @@ 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")
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)