diff --git a/api/api_common.go b/api/api_common.go index aa63e9815..0c20d0ad9 100644 --- a/api/api_common.go +++ b/api/api_common.go @@ -6,6 +6,7 @@ import ( "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" + ma "github.com/multiformats/go-multiaddr" "github.com/filecoin-project/go-jsonrpc/auth" @@ -28,6 +29,7 @@ type Common interface { NetDisconnect(context.Context, peer.ID) error NetFindPeer(context.Context, peer.ID) (peer.AddrInfo, error) NetPubsubScores(context.Context) ([]PubsubScore, error) + NetAutoNatStatus(context.Context) (NatInfo, error) // MethodGroup: Common @@ -65,3 +67,8 @@ type Version struct { func (v Version) String() string { return fmt.Sprintf("%s+api%s", v.Version, v.APIVersion.String()) } + +type NatInfo struct { + Reachability network.Reachability + PublicAddr ma.Multiaddr +} diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 5be189c98..49a0c2afc 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -49,6 +49,7 @@ type CommonStruct struct { NetDisconnect func(context.Context, peer.ID) error `perm:"write"` NetFindPeer func(context.Context, peer.ID) (peer.AddrInfo, error) `perm:"read"` NetPubsubScores func(context.Context) ([]api.PubsubScore, error) `perm:"read"` + NetAutoNatStatus func(context.Context) (api.NatInfo, error) `perm:"read"` ID func(context.Context) (peer.ID, error) `perm:"read"` Version func(context.Context) (api.Version, error) `perm:"read"` @@ -331,6 +332,7 @@ func (c *CommonStruct) AuthNew(ctx context.Context, perms []auth.Permission) ([] func (c *CommonStruct) NetPubsubScores(ctx context.Context) ([]api.PubsubScore, error) { return c.Internal.NetPubsubScores(ctx) } + func (c *CommonStruct) NetConnectedness(ctx context.Context, pid peer.ID) (network.Connectedness, error) { return c.Internal.NetConnectedness(ctx, pid) } @@ -355,6 +357,10 @@ func (c *CommonStruct) NetFindPeer(ctx context.Context, p peer.ID) (peer.AddrInf return c.Internal.NetFindPeer(ctx, p) } +func (c *CommonStruct) NetAutoNatStatus(ctx context.Context) (api.NatInfo, error) { + return c.Internal.NetAutoNatStatus(ctx) +} + // ID implements API.ID func (c *CommonStruct) ID(ctx context.Context) (peer.ID, error) { return c.Internal.ID(ctx) diff --git a/cli/net.go b/cli/net.go index 2e35f552f..e960a7234 100644 --- a/cli/net.go +++ b/cli/net.go @@ -24,6 +24,7 @@ var netCmd = &cli.Command{ NetId, netFindPeer, netScores, + netReachability, }, } @@ -202,3 +203,28 @@ var netFindPeer = &cli.Command{ return nil }, } + +var netReachability = &cli.Command{ + Name: "reachability", + Usage: "Print information about reachability from the internet", + Action: func(cctx *cli.Context) error { + api, closer, err := GetAPI(cctx) + if err != nil { + return err + } + defer closer() + + ctx := ReqContext(cctx) + + i, err := api.NetAutoNatStatus(ctx) + if err != nil { + return err + } + + fmt.Println("AutoNAT status: ", i.Reachability.String()) + if i.PublicAddr != nil { + fmt.Println("Public address: ", i.PublicAddr.String()) + } + return nil + }, +} diff --git a/node/impl/common/common.go b/node/impl/common/common.go index 1d2695b6e..89078dd39 100644 --- a/node/impl/common/common.go +++ b/node/impl/common/common.go @@ -2,6 +2,7 @@ package common import ( "context" + basichost "github.com/libp2p/go-libp2p/p2p/host/basic" "sort" "strings" @@ -28,6 +29,7 @@ type CommonAPI struct { fx.In APISecret *dtypes.APIAlg + RawHost lp2p.RawHost Host host.Host Router lp2p.BaseIpfsRouting Sk *dtypes.ScoreKeeper @@ -113,6 +115,23 @@ func (a *CommonAPI) NetFindPeer(ctx context.Context, p peer.ID) (peer.AddrInfo, return a.Router.FindPeer(ctx, p) } +func (a *CommonAPI) NetAutoNatStatus(ctx context.Context) (i api.NatInfo, err error) { + autonat := a.RawHost.(*basichost.BasicHost).AutoNat + + var maddr ma.Multiaddr + if autonat.Status() == network.ReachabilityPublic { + maddr, err = autonat.PublicAddr() + if err != nil { + return api.NatInfo{}, err + } + } + + return api.NatInfo{ + Reachability: autonat.Status(), + PublicAddr: maddr, + }, nil +} + func (a *CommonAPI) ID(context.Context) (peer.ID, error) { return a.Host.ID(), nil }