Skip to content

Commit

Permalink
Release v0.38.2 (#3147)
Browse files Browse the repository at this point in the history
  • Loading branch information
sukunrt authored Jan 21, 2025
1 parent dd592c3 commit 6d93e73
Show file tree
Hide file tree
Showing 12 changed files with 145 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ concurrency:

jobs:
release-check:
uses: marcopolo/unified-github-workflows/.github/workflows/release-check.yml@e66cb9667a2e1148efda4591e29c56258eaf385b
uses: ipdxco/unified-github-workflows/.github/workflows/release-check.yml@v1.0
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,25 @@ Guidelines:
- ask questions or talk about things in our [discussion forums](https://discuss.libp2p.io), or open an [issue](https://github.com/libp2p/go-libp2p/issues) for bug reports, or #libp2p-implementers on [Filecoin slack](https://filecoin.io/slack).
- ensure you are able to contribute (no legal issues please -- we use the DCO)
- get in touch with @libp2p/go-libp2p-maintainers about how best to contribute
- No drive-by contributions seeking to collect airdrops.
- Many projects aim to reward contributors to common goods. Great. However,
this creates an unfortunate incentive for low-effort PRs, submitted solely to
claim rewards. These PRs consume maintainers’ time and energy to triage, with
little to no impact on end users. If we suspect this is the intent of a PR,
we may close it without comment. If you believe this was done in error,
contact us via email. Reference this README section and explain why your PR
is not a “drive-by contribution.”
- have fun!

There's a few things you can do right now to help out:
- Go through the modules below and **check out existing issues**. This would be especially useful for modules in active development. Some knowledge of IPFS/libp2p may be required, as well as the infrastructure behind it - for instance, you may need to read up on p2p and more complex operations like muxing to be able to help technically.
- **Perform code reviews**.
- **Add tests**. There can never be enough tests.
- Go through the modules below and **check out existing issues**. This would
be especially useful for modules in active development. Some knowledge of
IPFS/libp2p may be required, as well as the infrastructure behind it - for
instance, you may need to read up on p2p and more complex operations like
muxing to be able to help technically.


## Supported Go Versions

Expand Down
34 changes: 29 additions & 5 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -446,12 +446,9 @@ func (cfg *Config) newBasicHost(swrm *swarm.Swarm, eventBus event.Bus) (*bhost.B
return h, nil
}

// NewNode constructs a new libp2p Host from the Config.
//
// This function consumes the config. Do not reuse it (really!).
func (cfg *Config) NewNode() (host.Host, error) {
func (cfg *Config) validate() error {
if cfg.EnableAutoRelay && !cfg.Relay {
return nil, fmt.Errorf("cannot enable autorelay; relay is not enabled")
return fmt.Errorf("cannot enable autorelay; relay is not enabled")
}
// If possible check that the resource manager conn limit is higher than the
// limit set in the conn manager.
Expand All @@ -462,6 +459,33 @@ func (cfg *Config) NewNode() (host.Host, error) {
}
}

if len(cfg.PSK) > 0 && cfg.ShareTCPListener {
return errors.New("cannot use shared TCP listener with PSK")
}

return nil
}

// NewNode constructs a new libp2p Host from the Config.
//
// This function consumes the config. Do not reuse it (really!).
func (cfg *Config) NewNode() (host.Host, error) {

validateErr := cfg.validate()
if validateErr != nil {
if cfg.ResourceManager != nil {
cfg.ResourceManager.Close()
}
if cfg.ConnManager != nil {
cfg.ConnManager.Close()
}
if cfg.Peerstore != nil {
cfg.Peerstore.Close()
}

return nil, validateErr
}

if !cfg.DisableMetrics {
rcmgr.MustRegisterWith(cfg.PrometheusRegisterer)
}
Expand Down
11 changes: 10 additions & 1 deletion libp2p_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/core/peerstore"
"github.com/libp2p/go-libp2p/core/pnet"
"github.com/libp2p/go-libp2p/core/routing"
"github.com/libp2p/go-libp2p/core/transport"
rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager"
Expand Down Expand Up @@ -761,6 +762,7 @@ func TestSharedTCPAddr(t *testing.T) {
ListenAddrStrings("/ip4/0.0.0.0/tcp/8888/ws"),
)
require.NoError(t, err)
defer h.Close()
sawTCP := false
sawWS := false
for _, addr := range h.Addrs() {
Expand All @@ -773,5 +775,12 @@ func TestSharedTCPAddr(t *testing.T) {
}
require.True(t, sawTCP)
require.True(t, sawWS)
h.Close()

_, err = New(
ShareTCPListener(),
Transport(tcp.NewTCPTransport),
Transport(websocket.New),
PrivateNetwork(pnet.PSK([]byte{1, 2, 3})),
)
require.ErrorContains(t, err, "cannot use shared TCP listener with PSK")
}
17 changes: 11 additions & 6 deletions p2p/net/nat/nat.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"net/netip"
"sync"
"sync/atomic"
"time"

logging "github.com/ipfs/go-log/v2"
Expand Down Expand Up @@ -56,11 +57,11 @@ func DiscoverNAT(ctx context.Context) (*NAT, error) {
ctx, cancel := context.WithCancel(context.Background())
nat := &NAT{
nat: natInstance,
extAddr: extAddr,
mappings: make(map[entry]int),
ctx: ctx,
ctxCancel: cancel,
}
nat.extAddr.Store(&extAddr)
nat.refCount.Add(1)
go func() {
defer nat.refCount.Done()
Expand All @@ -77,7 +78,7 @@ type NAT struct {
natmu sync.Mutex
nat nat.NAT
// External IP of the NAT. Will be renewed periodically (every CacheTime).
extAddr netip.Addr
extAddr atomic.Pointer[netip.Addr]

refCount sync.WaitGroup
ctx context.Context
Expand All @@ -103,14 +104,15 @@ func (nat *NAT) GetMapping(protocol string, port int) (addr netip.AddrPort, foun
nat.mappingmu.Lock()
defer nat.mappingmu.Unlock()

if !nat.extAddr.IsValid() {
if !nat.extAddr.Load().IsValid() {
return netip.AddrPort{}, false
}
extPort, found := nat.mappings[entry{protocol: protocol, port: port}]
if !found {
// The mapping may have an invalid port.
if !found || extPort == 0 {
return netip.AddrPort{}, false
}
return netip.AddrPortFrom(nat.extAddr, uint16(extPort)), true
return netip.AddrPortFrom(*nat.extAddr.Load(), uint16(extPort)), true
}

// AddMapping attempts to construct a mapping on protocol and internal port.
Expand All @@ -135,6 +137,9 @@ func (nat *NAT) AddMapping(ctx context.Context, protocol string, port int) error
// do it once synchronously, so first mapping is done right away, and before exiting,
// allowing users -- in the optimistic case -- to use results right after.
extPort := nat.establishMapping(ctx, protocol, port)
// Don't validate the mapping here, we refresh the mappings based on this map.
// We can try getting a port again in case it succeeds. In the worst case,
// this is one extra LAN request every few minutes.
nat.mappings[entry{protocol: protocol, port: port}] = extPort
return nil
}
Expand Down Expand Up @@ -202,7 +207,7 @@ func (nat *NAT) background() {
if err == nil {
extAddr, _ = netip.AddrFromSlice(extIP)
}
nat.extAddr = extAddr
nat.extAddr.Store(&extAddr)
nextAddrUpdate = time.Now().Add(CacheTime)
}
t.Reset(time.Until(minTime(nextAddrUpdate, nextMappingUpdate)))
Expand Down
15 changes: 15 additions & 0 deletions p2p/net/nat/nat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,18 @@ func TestRemoveMapping(t *testing.T) {
_, found = nat.GetMapping("tcp", 10000)
require.False(t, found, "didn't expect port mapping for deleted mapping")
}

func TestAddMappingInvalidPort(t *testing.T) {
mockNAT, reset := setupMockNAT(t)
defer reset()

mockNAT.EXPECT().GetExternalAddress().Return(net.IPv4(1, 2, 3, 4), nil)
nat, err := DiscoverNAT(context.Background())
require.NoError(t, err)

mockNAT.EXPECT().AddPortMapping(gomock.Any(), "tcp", 10000, gomock.Any(), MappingDuration).Return(0, nil)
require.NoError(t, nat.AddMapping(context.Background(), "tcp", 10000))

_, found := nat.GetMapping("tcp", 10000)
require.False(t, found, "didn't expect a port mapping for invalid nat-ed port")
}
17 changes: 16 additions & 1 deletion p2p/net/swarm/swarm_dial_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,23 @@ func TestBlackHoledAddrBlocked(t *testing.T) {
require.ErrorIs(t, err, ErrDialRefusedBlackHole)
}

type mockDNSResolver struct {
ipsToReturn []net.IPAddr
txtsToReturn []string
}

var _ madns.BasicResolver = (*mockDNSResolver)(nil)

func (m *mockDNSResolver) LookupIPAddr(_ context.Context, _ string) ([]net.IPAddr, error) {
return m.ipsToReturn, nil
}

func (m *mockDNSResolver) LookupTXT(_ context.Context, _ string) ([]string, error) {
return m.txtsToReturn, nil
}

func TestSkipDialingManyDNS(t *testing.T) {
resolver, err := madns.NewResolver()
resolver, err := madns.NewResolver(madns.WithDefaultResolver(&mockDNSResolver{ipsToReturn: []net.IPAddr{{IP: net.ParseIP("1.2.3.4")}, {IP: net.ParseIP("1.2.3.5")}}}))
if err != nil {
t.Fatal(err)
}
Expand Down
36 changes: 36 additions & 0 deletions p2p/test/transport/transport_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/libp2p/go-libp2p/p2p/protocol/ping"
"github.com/libp2p/go-libp2p/p2p/security/noise"
tls "github.com/libp2p/go-libp2p/p2p/security/tls"
"github.com/libp2p/go-libp2p/p2p/transport/tcp"
libp2pwebrtc "github.com/libp2p/go-libp2p/p2p/transport/webrtc"
"go.uber.org/mock/gomock"

Expand Down Expand Up @@ -116,6 +117,41 @@ var transportsToTest = []TransportTestCase{
return h
},
},
{
Name: "TCP-Shared-WithMetrics / TLS / Yamux",
HostGenerator: func(t *testing.T, opts TransportTestCaseOpts) host.Host {
libp2pOpts := transformOpts(opts)
libp2pOpts = append(libp2pOpts, libp2p.ShareTCPListener())
libp2pOpts = append(libp2pOpts, libp2p.Security(tls.ID, tls.New))
libp2pOpts = append(libp2pOpts, libp2p.Muxer(yamux.ID, yamux.DefaultTransport))
libp2pOpts = append(libp2pOpts, libp2p.Transport(tcp.NewTCPTransport, tcp.WithMetrics()))
if opts.NoListen {
libp2pOpts = append(libp2pOpts, libp2p.NoListenAddrs)
} else {
libp2pOpts = append(libp2pOpts, libp2p.ListenAddrStrings("/ip4/127.0.0.1/tcp/0"))
}
h, err := libp2p.New(libp2pOpts...)
require.NoError(t, err)
return h
},
},
{
Name: "TCP-WithMetrics / TLS / Yamux",
HostGenerator: func(t *testing.T, opts TransportTestCaseOpts) host.Host {
libp2pOpts := transformOpts(opts)
libp2pOpts = append(libp2pOpts, libp2p.Security(tls.ID, tls.New))
libp2pOpts = append(libp2pOpts, libp2p.Muxer(yamux.ID, yamux.DefaultTransport))
libp2pOpts = append(libp2pOpts, libp2p.Transport(tcp.NewTCPTransport, tcp.WithMetrics()))
if opts.NoListen {
libp2pOpts = append(libp2pOpts, libp2p.NoListenAddrs)
} else {
libp2pOpts = append(libp2pOpts, libp2p.ListenAddrStrings("/ip4/127.0.0.1/tcp/0"))
}
h, err := libp2p.New(libp2pOpts...)
require.NoError(t, err)
return h
},
},
{
Name: "WebSocket-Shared",
HostGenerator: func(t *testing.T, opts TransportTestCaseOpts) host.Host {
Expand Down
11 changes: 11 additions & 0 deletions p2p/transport/tcp/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"sync"
"time"

"github.com/libp2p/go-libp2p/core/network"
"github.com/marten-seemann/tcp"
"github.com/mikioh/tcpinfo"
manet "github.com/multiformats/go-multiaddr/net"
Expand Down Expand Up @@ -252,6 +253,16 @@ func (c *tracingConn) Close() error {
return c.closeErr
}

func (c *tracingConn) Scope() network.ConnManagementScope {
if cs, ok := c.Conn.(interface {
Scope() network.ConnManagementScope
}); ok {
return cs.Scope()
}
// upgrader is expected to handle this
return nil
}

func (c *tracingConn) getTCPInfo() (*tcpinfo.Info, error) {
var o tcpinfo.Info
var b [256]byte
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// go:build: unix

package tcp

import (
Expand Down
2 changes: 1 addition & 1 deletion p2p/transport/webtransport/cert_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func newCertManager(hostKey ic.PrivKey, clock clock.Clock) (*certManager, error)
return m, nil
}

// getCurrentTimeBucket returns the canonical start time of the given time as
// getCurrentBucketStartTime returns the canonical start time of the given time as
// bucketed by ranges of certValidity since unix epoch (plus an offset). This
// lets you get the same time ranges across reboots without having to persist
// state.
Expand Down
2 changes: 1 addition & 1 deletion version.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"version": "v0.38.1"
"version": "v0.38.2"
}

0 comments on commit 6d93e73

Please sign in to comment.