mirror of https://github.com/ethereum/go-ethereum
p2p: support configuring NAT in TOML file (#31041)
This is an alternative for #27407 with a solution based on gencodec. With the PR, one can now configure like this: ``` # config.toml [Node.P2P] NAT = "extip:33.33.33.33" ``` ```shell $ geth --config config.toml ... INFO [01-17|16:37:31.436] Started P2P networking self=enode://2290...ab@33.33.33.33:30303 ```pull/30661/merge
parent
c43faa3d9d
commit
218b697f05
@ -0,0 +1,144 @@ |
||||
// Copyright 2025 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
package p2p |
||||
|
||||
import ( |
||||
"crypto/ecdsa" |
||||
"fmt" |
||||
|
||||
"github.com/ethereum/go-ethereum/common/mclock" |
||||
"github.com/ethereum/go-ethereum/log" |
||||
"github.com/ethereum/go-ethereum/p2p/enode" |
||||
"github.com/ethereum/go-ethereum/p2p/nat" |
||||
"github.com/ethereum/go-ethereum/p2p/netutil" |
||||
) |
||||
|
||||
//go:generate go run github.com/fjl/gencodec -type Config -field-override configMarshaling -formats toml -out config_toml.go
|
||||
|
||||
// Config holds Server options.
|
||||
type Config struct { |
||||
// This field must be set to a valid secp256k1 private key.
|
||||
PrivateKey *ecdsa.PrivateKey `toml:"-"` |
||||
|
||||
// MaxPeers is the maximum number of peers that can be
|
||||
// connected. It must be greater than zero.
|
||||
MaxPeers int |
||||
|
||||
// MaxPendingPeers is the maximum number of peers that can be pending in the
|
||||
// handshake phase, counted separately for inbound and outbound connections.
|
||||
// Zero defaults to preset values.
|
||||
MaxPendingPeers int `toml:",omitempty"` |
||||
|
||||
// DialRatio controls the ratio of inbound to dialed connections.
|
||||
// Example: a DialRatio of 2 allows 1/2 of connections to be dialed.
|
||||
// Setting DialRatio to zero defaults it to 3.
|
||||
DialRatio int `toml:",omitempty"` |
||||
|
||||
// NoDiscovery can be used to disable the peer discovery mechanism.
|
||||
// Disabling is useful for protocol debugging (manual topology).
|
||||
NoDiscovery bool |
||||
|
||||
// DiscoveryV4 specifies whether V4 discovery should be started.
|
||||
DiscoveryV4 bool `toml:",omitempty"` |
||||
|
||||
// DiscoveryV5 specifies whether the new topic-discovery based V5 discovery
|
||||
// protocol should be started or not.
|
||||
DiscoveryV5 bool `toml:",omitempty"` |
||||
|
||||
// Name sets the node name of this server.
|
||||
Name string `toml:"-"` |
||||
|
||||
// BootstrapNodes are used to establish connectivity
|
||||
// with the rest of the network.
|
||||
BootstrapNodes []*enode.Node |
||||
|
||||
// BootstrapNodesV5 are used to establish connectivity
|
||||
// with the rest of the network using the V5 discovery
|
||||
// protocol.
|
||||
BootstrapNodesV5 []*enode.Node `toml:",omitempty"` |
||||
|
||||
// Static nodes are used as pre-configured connections which are always
|
||||
// maintained and re-connected on disconnects.
|
||||
StaticNodes []*enode.Node |
||||
|
||||
// Trusted nodes are used as pre-configured connections which are always
|
||||
// allowed to connect, even above the peer limit.
|
||||
TrustedNodes []*enode.Node |
||||
|
||||
// Connectivity can be restricted to certain IP networks.
|
||||
// If this option is set to a non-nil value, only hosts which match one of the
|
||||
// IP networks contained in the list are considered.
|
||||
NetRestrict *netutil.Netlist `toml:",omitempty"` |
||||
|
||||
// NodeDatabase is the path to the database containing the previously seen
|
||||
// live nodes in the network.
|
||||
NodeDatabase string `toml:",omitempty"` |
||||
|
||||
// Protocols should contain the protocols supported
|
||||
// by the server. Matching protocols are launched for
|
||||
// each peer.
|
||||
Protocols []Protocol `toml:"-" json:"-"` |
||||
|
||||
// If ListenAddr is set to a non-nil address, the server
|
||||
// will listen for incoming connections.
|
||||
//
|
||||
// If the port is zero, the operating system will pick a port. The
|
||||
// ListenAddr field will be updated with the actual address when
|
||||
// the server is started.
|
||||
ListenAddr string |
||||
|
||||
// If DiscAddr is set to a non-nil value, the server will use ListenAddr
|
||||
// for TCP and DiscAddr for the UDP discovery protocol.
|
||||
DiscAddr string |
||||
|
||||
// If set to a non-nil value, the given NAT port mapper
|
||||
// is used to make the listening port available to the
|
||||
// Internet.
|
||||
NAT nat.Interface `toml:",omitempty"` |
||||
|
||||
// If Dialer is set to a non-nil value, the given Dialer
|
||||
// is used to dial outbound peer connections.
|
||||
Dialer NodeDialer `toml:"-"` |
||||
|
||||
// If NoDial is true, the server will not dial any peers.
|
||||
NoDial bool `toml:",omitempty"` |
||||
|
||||
// If EnableMsgEvents is set then the server will emit PeerEvents
|
||||
// whenever a message is sent to or received from a peer
|
||||
EnableMsgEvents bool |
||||
|
||||
// Logger is a custom logger to use with the p2p.Server.
|
||||
Logger log.Logger `toml:"-"` |
||||
|
||||
clock mclock.Clock |
||||
} |
||||
|
||||
type configMarshaling struct { |
||||
NAT configNAT |
||||
} |
||||
|
||||
type configNAT struct { |
||||
nat.Interface |
||||
} |
||||
|
||||
func (w *configNAT) UnmarshalText(input []byte) error { |
||||
n, err := nat.Parse(string(input)) |
||||
if err != nil { |
||||
return fmt.Errorf("invalid NAT specification: %v", err) |
||||
} |
||||
w.Interface = n |
||||
return nil |
||||
} |
@ -0,0 +1,165 @@ |
||||
// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
|
||||
|
||||
package p2p |
||||
|
||||
import ( |
||||
"crypto/ecdsa" |
||||
|
||||
"github.com/ethereum/go-ethereum/log" |
||||
"github.com/ethereum/go-ethereum/p2p/enode" |
||||
"github.com/ethereum/go-ethereum/p2p/nat" |
||||
"github.com/ethereum/go-ethereum/p2p/netutil" |
||||
) |
||||
|
||||
var _ = (*configMarshaling)(nil) |
||||
|
||||
// MarshalTOML marshals as TOML.
|
||||
func (c Config) MarshalTOML() (interface{}, error) { |
||||
type Config struct { |
||||
PrivateKey *ecdsa.PrivateKey `toml:"-"` |
||||
MaxPeers int |
||||
MaxPendingPeers int `toml:",omitempty"` |
||||
DialRatio int `toml:",omitempty"` |
||||
NoDiscovery bool |
||||
DiscoveryV4 bool `toml:",omitempty"` |
||||
DiscoveryV5 bool `toml:",omitempty"` |
||||
Name string `toml:"-"` |
||||
BootstrapNodes []*enode.Node |
||||
BootstrapNodesV5 []*enode.Node `toml:",omitempty"` |
||||
StaticNodes []*enode.Node |
||||
TrustedNodes []*enode.Node |
||||
NetRestrict *netutil.Netlist `toml:",omitempty"` |
||||
NodeDatabase string `toml:",omitempty"` |
||||
Protocols []Protocol `toml:"-" json:"-"` |
||||
ListenAddr string |
||||
DiscAddr string |
||||
NAT nat.Interface `toml:",omitempty"` |
||||
Dialer NodeDialer `toml:"-"` |
||||
NoDial bool `toml:",omitempty"` |
||||
EnableMsgEvents bool |
||||
Logger log.Logger `toml:"-"` |
||||
} |
||||
var enc Config |
||||
enc.PrivateKey = c.PrivateKey |
||||
enc.MaxPeers = c.MaxPeers |
||||
enc.MaxPendingPeers = c.MaxPendingPeers |
||||
enc.DialRatio = c.DialRatio |
||||
enc.NoDiscovery = c.NoDiscovery |
||||
enc.DiscoveryV4 = c.DiscoveryV4 |
||||
enc.DiscoveryV5 = c.DiscoveryV5 |
||||
enc.Name = c.Name |
||||
enc.BootstrapNodes = c.BootstrapNodes |
||||
enc.BootstrapNodesV5 = c.BootstrapNodesV5 |
||||
enc.StaticNodes = c.StaticNodes |
||||
enc.TrustedNodes = c.TrustedNodes |
||||
enc.NetRestrict = c.NetRestrict |
||||
enc.NodeDatabase = c.NodeDatabase |
||||
enc.Protocols = c.Protocols |
||||
enc.ListenAddr = c.ListenAddr |
||||
enc.DiscAddr = c.DiscAddr |
||||
enc.NAT = c.NAT |
||||
enc.Dialer = c.Dialer |
||||
enc.NoDial = c.NoDial |
||||
enc.EnableMsgEvents = c.EnableMsgEvents |
||||
enc.Logger = c.Logger |
||||
return &enc, nil |
||||
} |
||||
|
||||
// UnmarshalTOML unmarshals from TOML.
|
||||
func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { |
||||
type Config struct { |
||||
PrivateKey *ecdsa.PrivateKey `toml:"-"` |
||||
MaxPeers *int |
||||
MaxPendingPeers *int `toml:",omitempty"` |
||||
DialRatio *int `toml:",omitempty"` |
||||
NoDiscovery *bool |
||||
DiscoveryV4 *bool `toml:",omitempty"` |
||||
DiscoveryV5 *bool `toml:",omitempty"` |
||||
Name *string `toml:"-"` |
||||
BootstrapNodes []*enode.Node |
||||
BootstrapNodesV5 []*enode.Node `toml:",omitempty"` |
||||
StaticNodes []*enode.Node |
||||
TrustedNodes []*enode.Node |
||||
NetRestrict *netutil.Netlist `toml:",omitempty"` |
||||
NodeDatabase *string `toml:",omitempty"` |
||||
Protocols []Protocol `toml:"-" json:"-"` |
||||
ListenAddr *string |
||||
DiscAddr *string |
||||
NAT *configNAT `toml:",omitempty"` |
||||
Dialer NodeDialer `toml:"-"` |
||||
NoDial *bool `toml:",omitempty"` |
||||
EnableMsgEvents *bool |
||||
Logger log.Logger `toml:"-"` |
||||
} |
||||
var dec Config |
||||
if err := unmarshal(&dec); err != nil { |
||||
return err |
||||
} |
||||
if dec.PrivateKey != nil { |
||||
c.PrivateKey = dec.PrivateKey |
||||
} |
||||
if dec.MaxPeers != nil { |
||||
c.MaxPeers = *dec.MaxPeers |
||||
} |
||||
if dec.MaxPendingPeers != nil { |
||||
c.MaxPendingPeers = *dec.MaxPendingPeers |
||||
} |
||||
if dec.DialRatio != nil { |
||||
c.DialRatio = *dec.DialRatio |
||||
} |
||||
if dec.NoDiscovery != nil { |
||||
c.NoDiscovery = *dec.NoDiscovery |
||||
} |
||||
if dec.DiscoveryV4 != nil { |
||||
c.DiscoveryV4 = *dec.DiscoveryV4 |
||||
} |
||||
if dec.DiscoveryV5 != nil { |
||||
c.DiscoveryV5 = *dec.DiscoveryV5 |
||||
} |
||||
if dec.Name != nil { |
||||
c.Name = *dec.Name |
||||
} |
||||
if dec.BootstrapNodes != nil { |
||||
c.BootstrapNodes = dec.BootstrapNodes |
||||
} |
||||
if dec.BootstrapNodesV5 != nil { |
||||
c.BootstrapNodesV5 = dec.BootstrapNodesV5 |
||||
} |
||||
if dec.StaticNodes != nil { |
||||
c.StaticNodes = dec.StaticNodes |
||||
} |
||||
if dec.TrustedNodes != nil { |
||||
c.TrustedNodes = dec.TrustedNodes |
||||
} |
||||
if dec.NetRestrict != nil { |
||||
c.NetRestrict = dec.NetRestrict |
||||
} |
||||
if dec.NodeDatabase != nil { |
||||
c.NodeDatabase = *dec.NodeDatabase |
||||
} |
||||
if dec.Protocols != nil { |
||||
c.Protocols = dec.Protocols |
||||
} |
||||
if dec.ListenAddr != nil { |
||||
c.ListenAddr = *dec.ListenAddr |
||||
} |
||||
if dec.DiscAddr != nil { |
||||
c.DiscAddr = *dec.DiscAddr |
||||
} |
||||
if dec.NAT != nil { |
||||
c.NAT = dec.NAT |
||||
} |
||||
if dec.Dialer != nil { |
||||
c.Dialer = dec.Dialer |
||||
} |
||||
if dec.NoDial != nil { |
||||
c.NoDial = *dec.NoDial |
||||
} |
||||
if dec.EnableMsgEvents != nil { |
||||
c.EnableMsgEvents = *dec.EnableMsgEvents |
||||
} |
||||
if dec.Logger != nil { |
||||
c.Logger = dec.Logger |
||||
} |
||||
return nil |
||||
} |
Loading…
Reference in new issue