punchd/syni_prototype.nim

96 lines
2.8 KiB
Nim
Raw Normal View History

2020-05-08 19:34:37 +02:00
import
2020-05-21 01:17:37 +02:00
net,
2020-05-08 19:34:37 +02:00
asyncnet,
asyncdispatch,
2020-05-21 01:17:37 +02:00
asyncreadline,
punch
2020-05-08 19:34:37 +02:00
2020-05-21 01:17:37 +02:00
from strutils import format, join
2020-05-08 19:34:37 +02:00
from nativesockets import setSockOptInt
from os import paramCount, paramStr
var IPPROTO_IP {.importc: "IPPROTO_IP", header: "<netinet/in.h>".}: cint
var IP_TTL {.importc: "IP_TTL", header: "<netinet/in.h>".}: cint
proc usage() =
echo("Usage: $# client|server".format(paramStr(0)))
proc processInput(client: AsyncSocket) {.async.} =
while true:
let input = await asyncReadline()
await client.send(input & "\c\L")
2020-05-21 01:17:37 +02:00
proc connectAsClient(clientAddress: string,
clientPort: Port,
serverAddress: string,
serverPort: Port) {.async.} =
2020-05-08 19:34:37 +02:00
var client = newAsyncSocket()
client.setSockOpt(OptReuseAddr, true)
client.getFd().setSockOptInt(IPPROTO_IP, IP_TTL, 2)
2020-05-21 01:17:37 +02:00
client.bindAddr(clientPort, clientAddress)
2020-05-08 19:34:37 +02:00
try:
2020-05-21 01:17:37 +02:00
echo "trying to connect"
await client.connect(serverAddress, serverPort)
2020-05-08 19:34:37 +02:00
let (address, port) = client.getPeerAddr()
echo("connected to $#:$#!".format(address, port.uint16))
asyncCheck processInput(client)
while true:
let line = await client.recvLine()
if line.len == 0: break
echo("server responded: $#".format(line))
except OSError as e:
echo("Error: $#".format(e.msg))
proc processClient(client: AsyncSocket) {.async.} =
while true:
let line = await client.recvLine()
if line.len == 0: break
echo("client sent message: $#".format(line))
await client.send(line & "\c\L")
2020-05-21 01:17:37 +02:00
proc runServer(serverAddress: string,
serverPort: Port,
clientAddress: string,
clientPort: Port) {.async.} =
2020-05-08 19:34:37 +02:00
var server = newAsyncSocket()
server.setSockOpt(OptReuseAddr, true)
2020-05-21 01:17:37 +02:00
server.bindAddr(serverPort)
2020-05-08 19:34:37 +02:00
server.listen()
2020-05-21 01:17:37 +02:00
echo("listening on port $#".format(serverPort.uint16))
2020-05-08 19:34:37 +02:00
while true:
let client = await server.accept()
let (address, port) = client.getPeerAddr()
echo("client $#:$# connected!".format(address, port.uint16()))
asyncCheck processClient(client)
proc main() =
if paramCount() != 1:
usage()
return
2020-05-21 01:17:37 +02:00
let serverAddress = "176.95.209.87"
let serverPort = Port(80)
let clientAddress = $getPrimaryIPAddr(parseIpAddress(serverAddress))
let clientPort = Port(1234)
2020-05-08 19:34:37 +02:00
case paramStr(1)
of "client":
2020-05-21 01:17:37 +02:00
asyncCheck punchHoleAsClient(clientAddress, clientPort, serverAddress, serverPort)
asyncCheck connectAsClient(clientAddress, clientPort, serverAddress, serverPort)
try:
runForever()
except NetworkInterfaceError as e:
echo(e.msg)
except PunchHoleError as e:
echo(e.msg)
2020-05-08 19:34:37 +02:00
of "server":
2020-05-21 01:17:37 +02:00
asyncCheck runServer(serverAddress, serverPort, clientAddress, clientPort)
try:
runForever()
except ValueError:
echo "server got ValueError!"
discard
2020-05-08 19:34:37 +02:00
else:
usage()
when isMainModule:
main()