diff --git a/cmd/devp2p/discv4cmd.go b/cmd/devp2p/discv4cmd.go index 9525bec668..8580c61216 100644 --- a/cmd/devp2p/discv4cmd.go +++ b/cmd/devp2p/discv4cmd.go @@ -81,6 +81,18 @@ var ( Name: "bootnodes", Usage: "Comma separated nodes used for bootstrapping", } + nodekeyFlag = cli.StringFlag{ + Name: "nodekey", + Usage: "Hex-encoded node key", + } + nodedbFlag = cli.StringFlag{ + Name: "nodedb", + Usage: "Nodes database location", + } + listenAddrFlag = cli.StringFlag{ + Name: "addr", + Usage: "Listening address", + } crawlTimeoutFlag = cli.DurationFlag{ Name: "timeout", Usage: "Time limit for the crawl.", @@ -172,6 +184,62 @@ func discv4Crawl(ctx *cli.Context) error { return nil } +// startV4 starts an ephemeral discovery V4 node. +func startV4(ctx *cli.Context) *discover.UDPv4 { + ln, config := makeDiscoveryConfig(ctx) + socket := listen(ln, ctx.String(listenAddrFlag.Name)) + disc, err := discover.ListenV4(socket, ln, config) + if err != nil { + exit(err) + } + return disc +} + +func makeDiscoveryConfig(ctx *cli.Context) (*enode.LocalNode, discover.Config) { + var cfg discover.Config + + if ctx.IsSet(nodekeyFlag.Name) { + key, err := crypto.HexToECDSA(ctx.String(nodekeyFlag.Name)) + if err != nil { + exit(fmt.Errorf("-%s: %v", nodekeyFlag.Name, err)) + } + cfg.PrivateKey = key + } else { + cfg.PrivateKey, _ = crypto.GenerateKey() + } + + if commandHasFlag(ctx, bootnodesFlag) { + bn, err := parseBootnodes(ctx) + if err != nil { + exit(err) + } + cfg.Bootnodes = bn + } + + dbpath := ctx.String(nodedbFlag.Name) + db, err := enode.OpenDB(dbpath) + if err != nil { + exit(err) + } + ln := enode.NewLocalNode(db, cfg.PrivateKey) + return ln, cfg +} + +func listen(ln *enode.LocalNode, addr string) *net.UDPConn { + if addr == "" { + addr = "0.0.0.0:0" + } + socket, err := net.ListenPacket("udp4", addr) + if err != nil { + exit(err) + } + usocket := socket.(*net.UDPConn) + uaddr := socket.LocalAddr().(*net.UDPAddr) + ln.SetFallbackIP(net.IP{127, 0, 0, 1}) + ln.SetFallbackUDP(uaddr.Port) + return usocket +} + func parseBootnodes(ctx *cli.Context) ([]*enode.Node, error) { s := params.RinkebyBootnodes if ctx.IsSet(bootnodesFlag.Name) { @@ -187,40 +255,3 @@ func parseBootnodes(ctx *cli.Context) ([]*enode.Node, error) { } return nodes, nil } - -// startV4 starts an ephemeral discovery V4 node. -func startV4(ctx *cli.Context) *discover.UDPv4 { - socket, ln, cfg, err := listen() - if err != nil { - exit(err) - } - if commandHasFlag(ctx, bootnodesFlag) { - bn, err := parseBootnodes(ctx) - if err != nil { - exit(err) - } - cfg.Bootnodes = bn - } - disc, err := discover.ListenV4(socket, ln, cfg) - if err != nil { - exit(err) - } - return disc -} - -func listen() (*net.UDPConn, *enode.LocalNode, discover.Config, error) { - var cfg discover.Config - cfg.PrivateKey, _ = crypto.GenerateKey() - db, _ := enode.OpenDB("") - ln := enode.NewLocalNode(db, cfg.PrivateKey) - - socket, err := net.ListenUDP("udp4", &net.UDPAddr{IP: net.IP{0, 0, 0, 0}}) - if err != nil { - db.Close() - return nil, nil, cfg, err - } - addr := socket.LocalAddr().(*net.UDPAddr) - ln.SetFallbackIP(net.IP{127, 0, 0, 1}) - ln.SetFallbackUDP(addr.Port) - return socket, ln, cfg, nil -} diff --git a/cmd/devp2p/discv5cmd.go b/cmd/devp2p/discv5cmd.go index 049f576b40..7f2d9b9950 100644 --- a/cmd/devp2p/discv5cmd.go +++ b/cmd/devp2p/discv5cmd.go @@ -57,7 +57,12 @@ var ( Name: "listen", Usage: "Runs a node", Action: discv5Listen, - Flags: []cli.Flag{bootnodesFlag}, + Flags: []cli.Flag{ + bootnodesFlag, + nodekeyFlag, + nodedbFlag, + listenAddrFlag, + }, } ) @@ -99,7 +104,7 @@ func discv5Crawl(ctx *cli.Context) error { } func discv5Listen(ctx *cli.Context) error { - disc := startV5(nil) + disc := startV5(ctx) defer disc.Close() fmt.Println(disc.Self()) @@ -108,18 +113,9 @@ func discv5Listen(ctx *cli.Context) error { // startV5 starts an ephemeral discovery v5 node. func startV5(ctx *cli.Context) *discover.UDPv5 { - socket, ln, cfg, err := listen() - if err != nil { - exit(err) - } - if commandHasFlag(ctx, bootnodesFlag) { - bn, err := parseBootnodes(ctx) - if err != nil { - exit(err) - } - cfg.Bootnodes = bn - } - disc, err := discover.ListenV5(socket, ln, cfg) + ln, config := makeDiscoveryConfig(ctx) + socket := listen(ln, ctx.String(listenAddrFlag.Name)) + disc, err := discover.ListenV5(socket, ln, config) if err != nil { exit(err) }