NAT port mapping

This commit is contained in:
Ștefan Talpalaru 2019-04-17 03:56:28 +02:00
parent 91bf7630ae
commit d4aff04cbd
No known key found for this signature in database
GPG Key ID: CBF7934204F1B6F9
10 changed files with 72 additions and 10 deletions

10
.gitmodules vendored
View File

@ -128,3 +128,13 @@
url = https://github.com/status-im/nim-libp2p.git url = https://github.com/status-im/nim-libp2p.git
ignore = dirty ignore = dirty
branch = master branch = master
[submodule "vendor/nim-result"]
path = vendor/nim-result
url = https://github.com/arnetheduck/nim-result.git
ignore = dirty
branch = master
[submodule "vendor/nim-nat-traversal"]
path = vendor/nim-nat-traversal
url = https://github.com/status-im/nim-nat-traversal.git
ignore = dirty
branch = master

View File

@ -83,7 +83,7 @@ TOOLS_DIRS := premix tests
# comma-separated values for the "clean" target # comma-separated values for the "clean" target
TOOLS_CSV := $(subst $(SPACE),$(COMMA),$(TOOLS)) TOOLS_CSV := $(subst $(SPACE),$(COMMA),$(TOOLS))
.PHONY: all $(TOOLS) deps github-ssh build-nim update status ntags ctags nimbus testsuite test clean mrproper fetch-dlls test-libp2p-daemon .PHONY: all $(TOOLS) deps github-ssh build-nim update status ntags ctags nimbus testsuite test clean mrproper fetch-dlls test-libp2p-daemon nat-libs libminiupnpc.a libnatpmp.a
# default target, because it's the first one that doesn't start with '.' # default target, because it's the first one that doesn't start with '.'
all: $(TOOLS) nimbus all: $(TOOLS) nimbus
@ -100,7 +100,7 @@ $(TOOLS): | build deps
$(ENV_SCRIPT) nim c $(NIM_PARAMS) -o:build/$@ "$${TOOL_DIR}/$@.nim" $(ENV_SCRIPT) nim c $(NIM_PARAMS) -o:build/$@ "$${TOOL_DIR}/$@.nim"
# a phony target, because teaching `make` how to do conditional recompilation of Nim projects is too complicated # a phony target, because teaching `make` how to do conditional recompilation of Nim projects is too complicated
nimbus: | build deps nimbus: | build deps nat-libs
echo -e $(BUILD_MSG) "build/$@" && \ echo -e $(BUILD_MSG) "build/$@" && \
$(ENV_SCRIPT) nim nimbus $(NIM_PARAMS) nimbus.nims $(ENV_SCRIPT) nim nimbus $(NIM_PARAMS) nimbus.nims
@ -114,6 +114,14 @@ build:
# and a check for the actual compiler build # and a check for the actual compiler build
deps: $(NIM_BINARY) $(NIMBLE_DIR) nimbus.nims deps: $(NIM_BINARY) $(NIMBLE_DIR) nimbus.nims
nat-libs: | libminiupnpc.a libnatpmp.a
libminiupnpc.a: | deps
+ $(MAKE) -C vendor/nim-nat-traversal/vendor/miniupnp/miniupnpc $@ $(HANDLE_OUTPUT)
libnatpmp.a: | deps
+ $(MAKE) -C vendor/nim-nat-traversal/vendor/libnatpmp $@ $(HANDLE_OUTPUT)
#- depends on Git submodules being initialised #- depends on Git submodules being initialised
#- fakes a Nimble package repository with the minimum info needed by the Nim compiler #- fakes a Nimble package repository with the minimum info needed by the Nim compiler
# for runtime path (i.e.: the second line in $(NIMBLE_DIR)/pkgs/*/*.nimble-link) # for runtime path (i.e.: the second line in $(NIMBLE_DIR)/pkgs/*/*.nimble-link)
@ -147,6 +155,8 @@ test-reproducibility:
clean: clean:
rm -rf build/{nimbus,$(TOOLS_CSV),all_tests,test_rpc,*.exe} vendor/go/bin \ rm -rf build/{nimbus,$(TOOLS_CSV),all_tests,test_rpc,*.exe} vendor/go/bin \
$(NIMBLE_DIR) $(NIM_BINARY) $(NIM_DIR)/nimcache nimcache $(NIMBLE_DIR) $(NIM_BINARY) $(NIM_DIR)/nimcache nimcache
+ $(MAKE) -C vendor/nim-nat-traversal/vendor/miniupnp/miniupnpc clean $(HANDLE_OUTPUT)
+ $(MAKE) -C vendor/nim-nat-traversal/vendor/libnatpmp clean $(HANDLE_OUTPUT)
# dangerous cleaning, because you may have not-yet-pushed branches and commits in those vendor repos you're about to delete # dangerous cleaning, because you may have not-yet-pushed branches and commits in those vendor repos you're about to delete
mrproper: clean mrproper: clean

View File

@ -9,3 +9,5 @@
passL = "-Wl,--no-insert-timestamp" passL = "-Wl,--no-insert-timestamp"
@end @end
--threads:on

View File

@ -9,7 +9,7 @@
import import
parseopt, strutils, macros, os, times, parseopt, strutils, macros, os, times,
chronos, eth/[keys, common, p2p], chronicles, nimcrypto/hash, chronos, eth/[keys, common, p2p, net/nat], chronicles, nimcrypto/hash,
./db/select_backend, ./db/select_backend,
./vm/interpreter/vm_forks ./vm/interpreter/vm_forks
@ -132,6 +132,8 @@ type
networkId*: uint ## Network ID as integer networkId*: uint ## Network ID as integer
ident*: string ## Server ident name string ident*: string ## Server ident name string
nodeKey*: PrivateKey ## Server private key nodeKey*: PrivateKey ## Server private key
nat*: NatStrategy ## NAT strategy
externalIP*: string ## user-provided external IP
DebugConfiguration* = object DebugConfiguration* = object
## Debug configuration object ## Debug configuration object
@ -474,6 +476,23 @@ proc processNetArguments(key, value: string): ConfigStatus =
config.net.nodeKey = res config.net.nodeKey = res
elif skey == "ident": elif skey == "ident":
config.net.ident = value config.net.ident = value
elif skey == "nat":
case value.toLowerAscii:
of "any":
config.net.nat = NatAny
of "upnp":
config.net.nat = NatUpnp
of "pmp":
config.net.nat = NatPmp
of "none":
config.net.nat = NatNone
else:
if isIpAddress(value):
config.net.externalIP = value
config.net.nat = NatNone
else:
error "not a valid NAT mechanism, nor a valid IP address", value
result = ErrorParseOption
else: else:
result = EmptyOption result = EmptyOption
@ -551,6 +570,7 @@ proc initConfiguration(): NimbusConfiguration =
result.net.bindPort = 30303'u16 result.net.bindPort = 30303'u16
result.net.discPort = 30303'u16 result.net.discPort = 30303'u16
result.net.ident = NimbusIdent result.net.ident = NimbusIdent
result.net.nat = NatAny
const dataDir = getDefaultDataDir() const dataDir = getDefaultDataDir()
@ -592,6 +612,7 @@ NETWORKING OPTIONS:
--discport:<value> Network listening UDP port (defaults to --port argument) --discport:<value> Network listening UDP port (defaults to --port argument)
--maxpeers:<value> Maximum number of network peers (default: 25) --maxpeers:<value> Maximum number of network peers (default: 25)
--maxpendpeers:<value> Maximum number of pending connection attempts (default: 0) --maxpendpeers:<value> Maximum number of pending connection attempts (default: 0)
--nat:<value> NAT port mapping mechanism (any|none|upnp|pmp|<external IP>) (default: "any")
--nodiscover Disables the peer discovery mechanism (manual peer addition) --nodiscover Disables the peer discovery mechanism (manual peer addition)
--v5discover Enables the experimental RLPx V5 (Topic Discovery) mechanism --v5discover Enables the experimental RLPx V5 (Topic Discovery) mechanism
--nodekey:<value> P2P node private key (as hexadecimal string) --nodekey:<value> P2P node private key (as hexadecimal string)

View File

@ -2,5 +2,4 @@
-d:"chronicles_sinks=textlines[file]" -d:"chronicles_sinks=textlines[file]"
-d:"chronicles_runtime_filtering=on" -d:"chronicles_runtime_filtering=on"
-d:nimDebugDlOpen -d:nimDebugDlOpen
--threads:on

View File

@ -8,11 +8,12 @@
# those terms. # those terms.
import import
os, strutils, net, eth/keys, db/[storage_types, db_chain, select_backend], os, strutils, net, options,
eth/keys, db/[storage_types, db_chain, select_backend],
eth/common as eth_common, eth/p2p as eth_p2p, eth/common as eth_common, eth/p2p as eth_p2p,
chronos, json_rpc/rpcserver, chronicles, chronos, json_rpc/rpcserver, chronicles,
eth/p2p/rlpx_protocols/[eth_protocol, les_protocol], eth/p2p/rlpx_protocols/[eth_protocol, les_protocol],
eth/p2p/blockchain_sync, eth/p2p/blockchain_sync, eth/net/nat,
config, genesis, rpc/[common, p2p, debug, whisper], p2p/chain, config, genesis, rpc/[common, p2p, debug, whisper], p2p/chain,
eth/trie/db eth/trie/db
@ -43,8 +44,6 @@ proc start(): NimbusObject =
setLogLevel(conf.debug.logLevel) setLogLevel(conf.debug.logLevel)
if len(conf.debug.logFile) != 0: if len(conf.debug.logFile) != 0:
discard defaultChroniclesStream.output.open(conf.debug.logFile, fmAppend) discard defaultChroniclesStream.output.open(conf.debug.logFile, fmAppend)
else:
discard defaultChroniclesStream.output.open(stdout)
## Creating RPC Server ## Creating RPC Server
if RpcFlags.Enabled in conf.rpc.flags: if RpcFlags.Enabled in conf.rpc.flags:
@ -63,6 +62,23 @@ proc start(): NimbusObject =
address.ip = parseIpAddress("0.0.0.0") address.ip = parseIpAddress("0.0.0.0")
address.tcpPort = Port(conf.net.bindPort) address.tcpPort = Port(conf.net.bindPort)
address.udpPort = Port(conf.net.discPort) address.udpPort = Port(conf.net.discPort)
if conf.net.nat == NatNone:
if conf.net.externalIP != "":
# any required port redirection is assumed to be done by hand
address.ip = parseIpAddress(conf.net.externalIP)
else:
# automated NAT traversal
let extIP = getExternalIP(conf.net.nat)
# TODO: dynamic IPs are common, so our external IP might change while the
# program is running. How can we update our advertised enode address and any
# other place that might use this external IP?
if extIP.isSome:
address.ip = extIP.get()
let extPorts = redirectPorts(tcpPort = address.tcpPort,
udpPort = address.udpPort,
description = NIMBUS_NAME & " " & NIMBUS_VERSION)
if extPorts.isSome:
(address.tcpPort, address.udpPort) = extPorts.get()
createDir(conf.dataDir) createDir(conf.dataDir)
let trieDB = trieDB newChainDb(conf.dataDir) let trieDB = trieDB newChainDb(conf.dataDir)
@ -133,6 +149,9 @@ when isMainModule:
## Pring Nimbus header ## Pring Nimbus header
echo NimbusHeader echo NimbusHeader
## show logs on stdout until we get the user's logging choice
discard defaultChroniclesStream.output.open(stdout)
## Processing command line arguments ## Processing command line arguments
if processArguments(message) != ConfigStatus.Success: if processArguments(message) != ConfigStatus.Success:
echo message echo message

View File

@ -1,4 +1,3 @@
-d:chronicles_line_numbers -d:chronicles_line_numbers
-d:"chronicles_sinks=textblocks" -d:"chronicles_sinks=textblocks"
--threads:on

2
vendor/nim-eth vendored

@ -1 +1 @@
Subproject commit a6be6426ab60b43a1a71c9fc96e0cba9c54154fa Subproject commit 3db5f4c5dd47fc6a6b8624572935a813d6e3930d

1
vendor/nim-nat-traversal vendored Submodule

@ -0,0 +1 @@
Subproject commit 0bcb394f5787bde62e3c275e185498e2de20d637

1
vendor/nim-result vendored Submodule

@ -0,0 +1 @@
Subproject commit ca56ea36b8dd7f644305c383dbebd28c1e44399b