punchd/syni_prototype.nim

96 lines
2.8 KiB
Nim

import
net,
asyncnet,
asyncdispatch,
asyncutils,
punch
from strutils import format, join
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")
proc connectAsClient(clientAddress: string,
clientPort: Port,
serverAddress: string,
serverPort: Port) {.async.} =
var client = newAsyncSocket()
client.setSockOpt(OptReuseAddr, true)
client.getFd().setSockOptInt(IPPROTO_IP, IP_TTL, 2)
client.bindAddr(clientPort, clientAddress)
try:
echo "trying to connect"
await client.connect(serverAddress, serverPort)
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")
proc runServer(serverAddress: string,
serverPort: Port,
clientAddress: string,
clientPort: Port) {.async.} =
var server = newAsyncSocket()
server.setSockOpt(OptReuseAddr, true)
server.bindAddr(serverPort)
server.listen()
echo("listening on port $#".format(serverPort.uint16))
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
let serverAddress = "176.95.209.87"
let serverPort = Port(80)
let clientAddress = $getPrimaryIPAddr(parseIpAddress(serverAddress))
let clientPort = Port(1234)
case paramStr(1)
of "client":
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)
of "server":
asyncCheck runServer(serverAddress, serverPort, clientAddress, clientPort)
try:
runForever()
except ValueError:
echo "server got ValueError!"
discard
else:
usage()
when isMainModule:
main()