p2p/discover: map listening port using configured mechanism

This commit is contained in:
Felix Lange 2015-02-13 11:38:34 +01:00
parent 82f0bd9009
commit 170eb3ac68
4 changed files with 35 additions and 18 deletions

View File

@ -30,6 +30,7 @@ import (
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/p2p/discover" "github.com/ethereum/go-ethereum/p2p/discover"
"github.com/ethereum/go-ethereum/p2p/nat"
) )
func main() { func main() {
@ -38,8 +39,10 @@ func main() {
genKey = flag.String("genkey", "", "generate a node key and quit") genKey = flag.String("genkey", "", "generate a node key and quit")
nodeKeyFile = flag.String("nodekey", "", "private key filename") nodeKeyFile = flag.String("nodekey", "", "private key filename")
nodeKeyHex = flag.String("nodekeyhex", "", "private key as hex (for testing)") nodeKeyHex = flag.String("nodekeyhex", "", "private key as hex (for testing)")
nodeKey *ecdsa.PrivateKey natdesc = flag.String("nat", "none", "port mapping mechanism (any|none|upnp|pmp|extip:<IP>)")
err error
nodeKey *ecdsa.PrivateKey
err error
) )
flag.Parse() flag.Parse()
logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.DebugLevel)) logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.DebugLevel))
@ -49,6 +52,10 @@ func main() {
os.Exit(0) os.Exit(0)
} }
natm, err := nat.Parse(*natdesc)
if err != nil {
log.Fatalf("-nat: %v", err)
}
switch { switch {
case *nodeKeyFile == "" && *nodeKeyHex == "": case *nodeKeyFile == "" && *nodeKeyHex == "":
log.Fatal("Use -nodekey or -nodekeyhex to specify a private key") log.Fatal("Use -nodekey or -nodekeyhex to specify a private key")
@ -64,7 +71,7 @@ func main() {
} }
} }
if _, err := discover.ListenUDP(nodeKey, *listenAddr); err != nil { if _, err := discover.ListenUDP(nodeKey, *listenAddr, natm); err != nil {
log.Fatal(err) log.Fatal(err)
} }
select {} select {}

View File

@ -10,6 +10,7 @@ import (
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/p2p/nat"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
) )
@ -82,6 +83,7 @@ type udp struct {
addpending chan *pending addpending chan *pending
replies chan reply replies chan reply
closing chan struct{} closing chan struct{}
nat nat.Interface
*Table *Table
} }
@ -121,17 +123,26 @@ type reply struct {
} }
// ListenUDP returns a new table that listens for UDP packets on laddr. // ListenUDP returns a new table that listens for UDP packets on laddr.
func ListenUDP(priv *ecdsa.PrivateKey, laddr string) (*Table, error) { func ListenUDP(priv *ecdsa.PrivateKey, laddr string, natm nat.Interface) (*Table, error) {
net, realaddr, err := listen(priv, laddr) t, realaddr, err := listen(priv, laddr, natm)
if err != nil { if err != nil {
return nil, err return nil, err
} }
net.Table = newTable(net, PubkeyID(&priv.PublicKey), realaddr) if natm != nil {
log.Debugf("Listening, %v\n", net.self) if !realaddr.IP.IsLoopback() {
return net.Table, nil go nat.Map(natm, t.closing, "udp", realaddr.Port, realaddr.Port, "ethereum discovery")
}
// TODO: react to external IP changes over time.
if ext, err := natm.ExternalIP(); err == nil {
realaddr = &net.UDPAddr{IP: ext, Port: realaddr.Port}
}
}
t.Table = newTable(t, PubkeyID(&priv.PublicKey), realaddr)
log.Infoln("Listening, ", t.self)
return t.Table, nil
} }
func listen(priv *ecdsa.PrivateKey, laddr string) (*udp, *net.UDPAddr, error) { func listen(priv *ecdsa.PrivateKey, laddr string, nat nat.Interface) (*udp, *net.UDPAddr, error) {
addr, err := net.ResolveUDPAddr("udp", laddr) addr, err := net.ResolveUDPAddr("udp", laddr)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err

View File

@ -18,8 +18,8 @@ func init() {
func TestUDP_ping(t *testing.T) { func TestUDP_ping(t *testing.T) {
t.Parallel() t.Parallel()
n1, _ := ListenUDP(newkey(), "127.0.0.1:0") n1, _ := ListenUDP(newkey(), "127.0.0.1:0", nil)
n2, _ := ListenUDP(newkey(), "127.0.0.1:0") n2, _ := ListenUDP(newkey(), "127.0.0.1:0", nil)
defer n1.Close() defer n1.Close()
defer n2.Close() defer n2.Close()
@ -48,8 +48,8 @@ func find(tab *Table, id NodeID) *Node {
func TestUDP_findnode(t *testing.T) { func TestUDP_findnode(t *testing.T) {
t.Parallel() t.Parallel()
n1, _ := ListenUDP(newkey(), "127.0.0.1:0") n1, _ := ListenUDP(newkey(), "127.0.0.1:0", nil)
n2, _ := ListenUDP(newkey(), "127.0.0.1:0") n2, _ := ListenUDP(newkey(), "127.0.0.1:0", nil)
defer n1.Close() defer n1.Close()
defer n2.Close() defer n2.Close()
@ -98,7 +98,7 @@ func TestUDP_replytimeout(t *testing.T) {
} }
defer fd.Close() defer fd.Close()
n1, _ := ListenUDP(newkey(), "127.0.0.1:0") n1, _ := ListenUDP(newkey(), "127.0.0.1:0", nil)
defer n1.Close() defer n1.Close()
n2 := n1.bumpOrAdd(randomID(n1.self.ID, 10), fd.LocalAddr().(*net.UDPAddr)) n2 := n1.bumpOrAdd(randomID(n1.self.ID, 10), fd.LocalAddr().(*net.UDPAddr))
@ -116,8 +116,8 @@ func TestUDP_replytimeout(t *testing.T) {
func TestUDP_findnodeMultiReply(t *testing.T) { func TestUDP_findnodeMultiReply(t *testing.T) {
t.Parallel() t.Parallel()
n1, _ := ListenUDP(newkey(), "127.0.0.1:0") n1, _ := ListenUDP(newkey(), "127.0.0.1:0", nil)
n2, _ := ListenUDP(newkey(), "127.0.0.1:0") n2, _ := ListenUDP(newkey(), "127.0.0.1:0", nil)
udp2 := n2.net.(*udp) udp2 := n2.net.(*udp)
defer n1.Close() defer n1.Close()
defer n2.Close() defer n2.Close()

View File

@ -182,7 +182,7 @@ func (srv *Server) Start() (err error) {
} }
// dial stuff // dial stuff
dt, err := discover.ListenUDP(srv.PrivateKey, srv.ListenAddr) dt, err := discover.ListenUDP(srv.PrivateKey, srv.ListenAddr, srv.NAT)
if err != nil { if err != nil {
return err return err
} }
@ -194,7 +194,6 @@ func (srv *Server) Start() (err error) {
srv.loopWG.Add(1) srv.loopWG.Add(1)
go srv.dialLoop() go srv.dialLoop()
} }
if srv.NoDial && srv.ListenAddr == "" { if srv.NoDial && srv.ListenAddr == "" {
srvlog.Warnln("I will be kind-of useless, neither dialing nor listening.") srvlog.Warnln("I will be kind-of useless, neither dialing nor listening.")
} }