func main() { var ( listenAddr = flag.String("addr", ":30301", "listen address") genKey = flag.String("genkey", "", "generate a node key and quit") nodeKeyFile = flag.String("nodekey", "", "private key filename") nodeKeyHex = flag.String("nodekeyhex", "", "private key as hex (for testing)") natdesc = flag.String("nat", "none", "port mapping mechanism (any|none|upnp|pmp|extip:<IP>)") nodeKey *ecdsa.PrivateKey err error ) flag.Parse() logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.DebugLevel)) if *genKey != "" { writeKey(*genKey) os.Exit(0) } natm, err := nat.Parse(*natdesc) if err != nil { log.Fatalf("-nat: %v", err) } switch { case *nodeKeyFile == "" && *nodeKeyHex == "": log.Fatal("Use -nodekey or -nodekeyhex to specify a private key") case *nodeKeyFile != "" && *nodeKeyHex != "": log.Fatal("Options -nodekey and -nodekeyhex are mutually exclusive") case *nodeKeyFile != "": if nodeKey, err = crypto.LoadECDSA(*nodeKeyFile); err != nil { log.Fatalf("-nodekey: %v", err) } case *nodeKeyHex != "": if nodeKey, err = crypto.HexToECDSA(*nodeKeyHex); err != nil { log.Fatalf("-nodekeyhex: %v", err) } } if _, err := discover.ListenUDP(nodeKey, *listenAddr, natm, ""); err != nil { log.Fatal(err) } select {} }
// Start starts running the server. // Servers can not be re-used after stopping. func (srv *Server) Start() (err error) { srv.lock.Lock() defer srv.lock.Unlock() if srv.running { return errors.New("server already running") } srv.running = true glog.V(logger.Info).Infoln("Starting Server") // static fields if srv.PrivateKey == nil { return fmt.Errorf("Server.PrivateKey must be set to a non-nil key") } if srv.newTransport == nil { srv.newTransport = newRLPX } if srv.Dialer == nil { srv.Dialer = &net.Dialer{Timeout: defaultDialTimeout} } srv.quit = make(chan struct{}) srv.addpeer = make(chan *conn) srv.delpeer = make(chan *Peer) srv.posthandshake = make(chan *conn) srv.addstatic = make(chan *discover.Node) srv.peerOp = make(chan peerOpFunc) srv.peerOpDone = make(chan struct{}) // node table if srv.Discovery { ntab, err := discover.ListenUDP(srv.PrivateKey, srv.ListenAddr, srv.NAT, srv.NodeDatabase) if err != nil { return err } srv.ntab = ntab } dynPeers := srv.MaxPeers / 2 if !srv.Discovery { dynPeers = 0 } dialer := newDialState(srv.StaticNodes, srv.ntab, dynPeers) // handshake srv.ourHandshake = &protoHandshake{Version: baseProtocolVersion, Name: srv.Name, ID: discover.PubkeyID(&srv.PrivateKey.PublicKey)} for _, p := range srv.Protocols { srv.ourHandshake.Caps = append(srv.ourHandshake.Caps, p.cap()) } // listen/dial if srv.ListenAddr != "" { if err := srv.startListening(); err != nil { return err } } if srv.NoDial && srv.ListenAddr == "" { glog.V(logger.Warn).Infoln("I will be kind-of useless, neither dialing nor listening.") } srv.loopWG.Add(1) go srv.run(dialer) srv.running = true return nil }