-
Notifications
You must be signed in to change notification settings - Fork 58
/
Copy pathnat.nim
70 lines (62 loc) · 2.09 KB
/
nat.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
when (NimMajor, NimMinor) < (1, 4):
{.push raises: [Defect].}
else:
{.push raises: [].}
import
std/[strutils, options],
chronicles, stew/shims/net as stewNet,
eth/net/nat
logScope:
topics = "nat"
proc setupNat*(natConf, clientId: string, tcpPort, udpPort: Port):
tuple[ip: Option[ValidIpAddress],
tcpPort: Option[Port],
udpPort: Option[Port]] {.gcsafe, deprecated:
"Unsafe: this proc quits the app if something is not ok".} =
var
endpoint: tuple[ip: Option[ValidIpAddress],
tcpPort: Option[Port],
udpPort: Option[Port]]
nat: NatStrategy
case natConf.toLowerAscii:
of "any":
nat = NatAny
of "none":
nat = NatNone
of "upnp":
nat = NatUpnp
of "pmp":
nat = NatPmp
else:
if natConf.startsWith("extip:"):
try:
# any required port redirection is assumed to be done by hand
endpoint.ip = some(ValidIpAddress.init(natConf[6..^1]))
nat = NatNone
except ValueError:
error "not a valid IP address", address = natConf[6..^1]
quit QuitFailure
else:
error "not a valid NAT mechanism", value = natConf
quit QuitFailure
if nat != NatNone:
let extIp = getExternalIP(nat)
if extIP.isSome:
endpoint.ip = some(ValidIpAddress.init extIp.get)
# TODO redirectPorts in considered a gcsafety violation
# because it obtains the address of a non-gcsafe proc?
var extPorts: Option[(Port, Port)]
try:
extPorts = ({.gcsafe.}:
redirectPorts(tcpPort = tcpPort,
udpPort = udpPort,
description = clientId))
except Exception:
# @TODO: nat.nim Error: can raise an unlisted exception: Exception. Isolate here for now.
error "unable to determine external ports"
extPorts = none((Port, Port))
if extPorts.isSome:
let (extTcpPort, extUdpPort) = extPorts.get()
endpoint.tcpPort = some(extTcpPort)
endpoint.udpPort = some(extUdpPort)
return endpoint