Skip to content

Commit

Permalink
Use netip.AddrPort rather than ips.IPPort (#3094)
Browse files Browse the repository at this point in the history
  • Loading branch information
StephenButtolph authored Jun 10, 2024
1 parent 504766e commit cd0c6e1
Show file tree
Hide file tree
Showing 52 changed files with 662 additions and 822 deletions.
5 changes: 3 additions & 2 deletions api/info/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package info

import (
"context"
"net/netip"
"time"

"github.com/ava-labs/avalanchego/ids"
Expand All @@ -19,7 +20,7 @@ var _ Client = (*client)(nil)
type Client interface {
GetNodeVersion(context.Context, ...rpc.Option) (*GetNodeVersionReply, error)
GetNodeID(context.Context, ...rpc.Option) (ids.NodeID, *signer.ProofOfPossession, error)
GetNodeIP(context.Context, ...rpc.Option) (string, error)
GetNodeIP(context.Context, ...rpc.Option) (netip.AddrPort, error)
GetNetworkID(context.Context, ...rpc.Option) (uint32, error)
GetNetworkName(context.Context, ...rpc.Option) (string, error)
GetBlockchainID(context.Context, string, ...rpc.Option) (ids.ID, error)
Expand Down Expand Up @@ -54,7 +55,7 @@ func (c *client) GetNodeID(ctx context.Context, options ...rpc.Option) (ids.Node
return res.NodeID, res.NodePOP, err
}

func (c *client) GetNodeIP(ctx context.Context, options ...rpc.Option) (string, error) {
func (c *client) GetNodeIP(ctx context.Context, options ...rpc.Option) (netip.AddrPort, error) {
res := &GetNodeIPReply{}
err := c.requester.SendRequest(ctx, "info.getNodeIP", struct{}{}, res, options...)
return res.IP, err
Expand Down
11 changes: 6 additions & 5 deletions api/info/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"net/http"
"net/netip"

"github.com/gorilla/rpc/v2"
"go.uber.org/zap"
Expand All @@ -17,8 +18,8 @@ import (
"github.com/ava-labs/avalanchego/network/peer"
"github.com/ava-labs/avalanchego/snow/networking/benchlist"
"github.com/ava-labs/avalanchego/snow/validators"
"github.com/ava-labs/avalanchego/utils"
"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/avalanchego/utils/ips"
"github.com/ava-labs/avalanchego/utils/json"
"github.com/ava-labs/avalanchego/utils/logging"
"github.com/ava-labs/avalanchego/utils/set"
Expand All @@ -37,7 +38,7 @@ type Info struct {
Parameters
log logging.Logger
validators validators.Manager
myIP ips.DynamicIPPort
myIP *utils.Atomic[netip.AddrPort]
networking network.Network
chainManager chains.Manager
vmManager vms.Manager
Expand Down Expand Up @@ -67,7 +68,7 @@ func NewService(
validators validators.Manager,
chainManager chains.Manager,
vmManager vms.Manager,
myIP ips.DynamicIPPort,
myIP *utils.Atomic[netip.AddrPort],
network network.Network,
benchlist benchlist.Manager,
) (http.Handler, error) {
Expand Down Expand Up @@ -144,7 +145,7 @@ type GetNetworkIDReply struct {

// GetNodeIPReply are the results from calling GetNodeIP
type GetNodeIPReply struct {
IP string `json:"ip"`
IP netip.AddrPort `json:"ip"`
}

// GetNodeIP returns the IP of this node
Expand All @@ -154,7 +155,7 @@ func (i *Info) GetNodeIP(_ *http.Request, _ *struct{}, reply *GetNodeIPReply) er
zap.String("method", "getNodeIP"),
)

reply.IP = i.myIP.IPPort().String()
reply.IP = i.myIP.Get()
return nil
}

Expand Down
8 changes: 3 additions & 5 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ func getStateSyncConfig(v *viper.Viper) (node.StateSyncConfig, error) {
if ip == "" {
continue
}
addr, err := ips.ToIPPort(ip)
addr, err := ips.ParseAddrPort(ip)
if err != nil {
return node.StateSyncConfig{}, fmt.Errorf("couldn't parse state sync ip %s: %w", ip, err)
}
Expand Down Expand Up @@ -507,14 +507,13 @@ func getBootstrapConfig(v *viper.Viper, networkID uint32) (node.BootstrapConfig,
if ip == "" {
continue
}

addr, err := ips.ToIPPort(ip)
addr, err := ips.ParseAddrPort(ip)
if err != nil {
return node.BootstrapConfig{}, fmt.Errorf("couldn't parse bootstrap ip %s: %w", ip, err)
}
config.Bootstrappers = append(config.Bootstrappers, genesis.Bootstrapper{
// ID is populated below
IP: ips.IPDesc(addr),
IP: addr,
})
}

Expand All @@ -525,7 +524,6 @@ func getBootstrapConfig(v *viper.Viper, networkID uint32) (node.BootstrapConfig,
if id == "" {
continue
}

nodeID, err := ids.NodeIDFromString(id)
if err != nil {
return node.BootstrapConfig{}, fmt.Errorf("couldn't parse bootstrap peer id %s: %w", id, err)
Expand Down
6 changes: 3 additions & 3 deletions genesis/bootstrappers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ package genesis
import (
"encoding/json"
"fmt"
"net/netip"

_ "embed"

"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/avalanchego/utils/ips"
"github.com/ava-labs/avalanchego/utils/sampler"
)

Expand All @@ -31,8 +31,8 @@ func init() {
// Represents the relationship between the nodeID and the nodeIP.
// The bootstrapper is sometimes called "anchor" or "beacon" node.
type Bootstrapper struct {
ID ids.NodeID `json:"id"`
IP ips.IPDesc `json:"ip"`
ID ids.NodeID `json:"id"`
IP netip.AddrPort `json:"ip"`
}

// GetBootstrappers returns all default bootstrappers for the provided network.
Expand Down
3 changes: 2 additions & 1 deletion message/mock_outbound_message_builder.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 11 additions & 6 deletions message/outbound_msg_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package message

import (
"net/netip"
"time"

"github.com/ava-labs/avalanchego/ids"
Expand All @@ -21,7 +22,7 @@ type OutboundMsgBuilder interface {
Handshake(
networkID uint32,
myTime uint64,
ip ips.IPPort,
ip netip.AddrPort,
client string,
major uint32,
minor uint32,
Expand Down Expand Up @@ -228,7 +229,7 @@ func (b *outMsgBuilder) Pong() (OutboundMessage, error) {
func (b *outMsgBuilder) Handshake(
networkID uint32,
myTime uint64,
ip ips.IPPort,
ip netip.AddrPort,
client string,
major uint32,
minor uint32,
Expand All @@ -244,14 +245,16 @@ func (b *outMsgBuilder) Handshake(
) (OutboundMessage, error) {
subnetIDBytes := make([][]byte, len(trackedSubnets))
encodeIDs(trackedSubnets, subnetIDBytes)
// TODO: Use .AsSlice() after v1.12.x activates.
addr := ip.Addr().As16()
return b.builder.createOutbound(
&p2p.Message{
Message: &p2p.Message_Handshake{
Handshake: &p2p.Handshake{
NetworkId: networkID,
MyTime: myTime,
IpAddr: ip.IP.To16(),
IpPort: uint32(ip.Port),
IpAddr: addr[:],
IpPort: uint32(ip.Port()),
IpSigningTime: ipSigningTime,
IpNodeIdSig: ipNodeIDSig,
TrackedSubnets: subnetIDBytes,
Expand Down Expand Up @@ -299,10 +302,12 @@ func (b *outMsgBuilder) GetPeerList(
func (b *outMsgBuilder) PeerList(peers []*ips.ClaimedIPPort, bypassThrottling bool) (OutboundMessage, error) {
claimIPPorts := make([]*p2p.ClaimedIpPort, len(peers))
for i, p := range peers {
// TODO: Use .AsSlice() after v1.12.x activates.
ip := p.AddrPort.Addr().As16()
claimIPPorts[i] = &p2p.ClaimedIpPort{
X509Certificate: p.Cert.Raw,
IpAddr: p.IPPort.IP.To16(),
IpPort: uint32(p.IPPort.Port),
IpAddr: ip[:],
IpPort: uint32(p.AddrPort.Port()),
Timestamp: p.Timestamp,
Signature: p.Signature,
TxId: ids.Empty[:],
Expand Down
37 changes: 26 additions & 11 deletions nat/nat.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
package nat

import (
"net"
"net/netip"
"sync"
"time"

"go.uber.org/zap"

"github.com/ava-labs/avalanchego/utils/ips"
"github.com/ava-labs/avalanchego/utils"
"github.com/ava-labs/avalanchego/utils/logging"
)

Expand All @@ -29,7 +29,7 @@ type Router interface {
// Undo a port mapping
UnmapPort(intPort, extPort uint16) error
// Return our external IP
ExternalIP() (net.IP, error)
ExternalIP() (netip.Addr, error)
}

// GetRouter returns a router on the current network.
Expand Down Expand Up @@ -63,7 +63,13 @@ func NewPortMapper(log logging.Logger, r Router) *Mapper {

// Map external port [extPort] (exposed to the internet) to internal port [intPort] (where our process is listening)
// and set [ip]. Does this every [updateTime]. [ip] may be nil.
func (m *Mapper) Map(intPort, extPort uint16, desc string, ip ips.DynamicIPPort, updateTime time.Duration) {
func (m *Mapper) Map(
intPort uint16,
extPort uint16,
desc string,
ip *utils.Atomic[netip.AddrPort],
updateTime time.Duration,
) {
if !m.r.SupportsNAT() {
return
}
Expand Down Expand Up @@ -110,7 +116,13 @@ func (m *Mapper) retryMapPort(intPort, extPort uint16, desc string, timeout time

// keepPortMapping runs in the background to keep a port mapped. It renews the mapping from [extPort]
// to [intPort]] every [updateTime]. Updates [ip] every [updateTime].
func (m *Mapper) keepPortMapping(intPort, extPort uint16, desc string, ip ips.DynamicIPPort, updateTime time.Duration) {
func (m *Mapper) keepPortMapping(
intPort uint16,
extPort uint16,
desc string,
ip *utils.Atomic[netip.AddrPort],
updateTime time.Duration,
) {
updateTimer := time.NewTimer(updateTime)

defer func(extPort uint16) {
Expand Down Expand Up @@ -150,22 +162,25 @@ func (m *Mapper) keepPortMapping(intPort, extPort uint16, desc string, ip ips.Dy
}
}

func (m *Mapper) updateIP(ip ips.DynamicIPPort) {
func (m *Mapper) updateIP(ip *utils.Atomic[netip.AddrPort]) {
if ip == nil {
return
}
newIP, err := m.r.ExternalIP()
newAddr, err := m.r.ExternalIP()
if err != nil {
m.log.Error("failed to get external IP",
zap.Error(err),
)
return
}
oldIP := ip.IPPort().IP
ip.SetIP(newIP)
if !oldIP.Equal(newIP) {
oldAddrPort := ip.Get()
oldAddr := oldAddrPort.Addr()
if newAddr != oldAddr {
port := oldAddrPort.Port()
ip.Set(netip.AddrPortFrom(newAddr, port))
m.log.Info("external IP updated",
zap.Stringer("newIP", newIP),
zap.Stringer("oldIP", oldAddr),
zap.Stringer("newIP", newAddr),
)
}
}
Expand Down
23 changes: 14 additions & 9 deletions nat/no_router.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package nat
import (
"errors"
"net"
"net/netip"
"time"
)

Expand All @@ -19,7 +20,7 @@ var (
const googleDNSServer = "8.8.8.8:80"

type noRouter struct {
ip net.IP
ip netip.Addr
ipErr error
}

Expand All @@ -35,26 +36,30 @@ func (noRouter) UnmapPort(uint16, uint16) error {
return nil
}

func (r noRouter) ExternalIP() (net.IP, error) {
func (r noRouter) ExternalIP() (netip.Addr, error) {
return r.ip, r.ipErr
}

func getOutboundIP() (net.IP, error) {
func getOutboundIP() (netip.Addr, error) {
conn, err := net.Dial("udp", googleDNSServer)
if err != nil {
return nil, err
return netip.Addr{}, err
}

addr := conn.LocalAddr()
localAddr := conn.LocalAddr()
if err := conn.Close(); err != nil {
return nil, err
return netip.Addr{}, err
}

udpAddr, ok := addr.(*net.UDPAddr)
udpAddr, ok := localAddr.(*net.UDPAddr)
if !ok {
return nil, errFetchingIP
return netip.Addr{}, errFetchingIP
}
return udpAddr.IP, nil
addr := udpAddr.AddrPort().Addr()
if addr.Is4In6() {
addr = addr.Unmap()
}
return addr, nil
}

// NewNoRouter returns a router that assumes the network is public
Expand Down
8 changes: 4 additions & 4 deletions nat/pmp.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ package nat
import (
"errors"
"math"
"net"
"net/netip"
"time"

"github.com/jackpal/gateway"
Expand Down Expand Up @@ -66,12 +66,12 @@ func (r *pmpRouter) UnmapPort(internalPort uint16, _ uint16) error {
return err
}

func (r *pmpRouter) ExternalIP() (net.IP, error) {
func (r *pmpRouter) ExternalIP() (netip.Addr, error) {
response, err := r.client.GetExternalAddress()
if err != nil {
return nil, err
return netip.Addr{}, err
}
return response.ExternalIPAddress[:], nil
return netip.AddrFrom4(response.ExternalIPAddress), nil
}

func getPMPRouter() *pmpRouter {
Expand Down
Loading

0 comments on commit cd0c6e1

Please sign in to comment.