Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add dns support inipfs p2p forward and refactor code #5533

Merged
merged 2 commits into from
Oct 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 62 additions & 18 deletions core/commands/p2p.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strconv"
"strings"
"text/tabwriter"
"time"

cmds "github.com/ipfs/go-ipfs/commands"
core "github.com/ipfs/go-ipfs/core"
Expand All @@ -19,6 +20,7 @@ import (
ma "gx/ipfs/QmYmsdtJ3HsodkePE3eU3TsCaP2YvPZJ4LoXnNkDE5Tpt7/go-multiaddr"
"gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol"
"gx/ipfs/QmesXvbRGyKQn1XbPHx1Mr5E6RTJYR9c8zwFVuGZq9Aa1j/go-ipfs-addr"
madns "gx/ipfs/QmfXU2MhWoegxHoeMd3A2ytL2P6CY4FfqGWc23LTNWBwZt/go-multiaddr-dns"
)

// P2PProtoPrefix is the default required prefix for protocol names
Expand Down Expand Up @@ -49,6 +51,16 @@ type P2PStreamsOutput struct {
Streams []P2PStreamInfoOutput
}

const (
allowCustomProtocolOptionName = "allow-custom-protocol"
allOptionName = "all"
protocolOptionName = "protocol"
listenAddressOptionName = "listen-address"
targetAddressOptionName = "target-address"
)

var resolveTimeout = 10 * time.Second

// P2PCmd is the 'ipfs p2p' command
var P2PCmd = &cmds.Command{
Helptext: cmdkit.HelpText{
Expand Down Expand Up @@ -91,7 +103,7 @@ Example:
cmdkit.StringArg("target-address", true, false, "Target endpoint."),
},
Options: []cmdkit.Option{
cmdkit.BoolOption("allow-custom-protocol", "Don't require /x/ prefix"),
cmdkit.BoolOption(allowCustomProtocolOptionName, "Don't require /x/ prefix"),
},
Run: func(req cmds.Request, res cmds.Response) {
n, err := p2pGetNode(req)
Expand All @@ -112,13 +124,13 @@ Example:
return
}

target, err := ipfsaddr.ParseString(targetOpt)
targets, err := parseIpfsAddr(targetOpt)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}

allowCustom, _, err := req.Option("allow-custom-protocol").Bool()
allowCustom, _, err := req.Option(allowCustomProtocolOptionName).Bool()
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
Expand All @@ -129,14 +141,45 @@ Example:
return
}

if err := forwardLocal(n.Context(), n.P2P, n.Peerstore, proto, listen, target); err != nil {
if err := forwardLocal(n.Context(), n.P2P, n.Peerstore, proto, listen, targets); err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}
res.SetOutput(nil)
},
}

// parseIpfsAddr is a function that takes in addr string and return ipfsAddrs
func parseIpfsAddr(addr string) ([]ipfsaddr.IPFSAddr, error) {
mutiladdr, err := ma.NewMultiaddr(addr)
if err != nil {
return nil, err
}
if _, err := mutiladdr.ValueForProtocol(ma.P_IPFS); err == nil {
iaddrs := make([]ipfsaddr.IPFSAddr, 1)
iaddrs[0], err = ipfsaddr.ParseMultiaddr(mutiladdr)
if err != nil {
return nil, err
}
return iaddrs, nil
}
// resolve mutiladdr whose protocol is not ma.P_IPFS
ctx, cancel := context.WithTimeout(context.Background(), resolveTimeout)
addrs, err := madns.Resolve(ctx, mutiladdr)
cancel()
if len(addrs) == 0 {
return nil, errors.New("fail to resolve the multiaddr:" + mutiladdr.String())
}
iaddrs := make([]ipfsaddr.IPFSAddr, len(addrs))
for i, addr := range addrs {
iaddrs[i], err = ipfsaddr.ParseMultiaddr(addr)
if err != nil {
return nil, err
}
}
return iaddrs, nil
}

var p2pListenCmd = &cmds.Command{
Helptext: cmdkit.HelpText{
Tagline: "Create libp2p service",
Expand All @@ -156,7 +199,7 @@ Example:
cmdkit.StringArg("target-address", true, false, "Target endpoint."),
},
Options: []cmdkit.Option{
cmdkit.BoolOption("allow-custom-protocol", "Don't require /x/ prefix"),
cmdkit.BoolOption(allowCustomProtocolOptionName, "Don't require /x/ prefix"),
},
Run: func(req cmds.Request, res cmds.Response) {
n, err := p2pGetNode(req)
Expand All @@ -176,7 +219,7 @@ Example:
return
}

allowCustom, _, err := req.Option("allow-custom-protocol").Bool()
allowCustom, _, err := req.Option(allowCustomProtocolOptionName).Bool()
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
Expand Down Expand Up @@ -204,13 +247,14 @@ func forwardRemote(ctx context.Context, p *p2p.P2P, proto protocol.ID, target ma
}

// forwardLocal forwards local connections to a libp2p service
func forwardLocal(ctx context.Context, p *p2p.P2P, ps pstore.Peerstore, proto protocol.ID, bindAddr ma.Multiaddr, addr ipfsaddr.IPFSAddr) error {
if addr != nil {
func forwardLocal(ctx context.Context, p *p2p.P2P, ps pstore.Peerstore, proto protocol.ID, bindAddr ma.Multiaddr, addrs []ipfsaddr.IPFSAddr) error {
for _, addr := range addrs {
ps.AddAddr(addr.ID(), addr.Multiaddr(), pstore.TempAddrTTL)
}

// TODO: return some info
_, err := p.ForwardLocal(ctx, addr.ID(), proto, bindAddr)
// the length of the addrs must large than 0
// peerIDs in addr must be the same and choose addr[0] to connect
_, err := p.ForwardLocal(ctx, addrs[0].ID(), proto, bindAddr)
return err
}

Expand Down Expand Up @@ -283,10 +327,10 @@ var p2pCloseCmd = &cmds.Command{
Tagline: "Stop listening for new connections to forward.",
},
Options: []cmdkit.Option{
cmdkit.BoolOption("all", "a", "Close all listeners."),
cmdkit.StringOption("protocol", "p", "Match protocol name"),
cmdkit.StringOption("listen-address", "l", "Match listen address"),
cmdkit.StringOption("target-address", "t", "Match target address"),
cmdkit.BoolOption(allOptionName, "a", "Close all listeners."),
cmdkit.StringOption(protocolOptionName, "p", "Match protocol name"),
cmdkit.StringOption(listenAddressOptionName, "l", "Match listen address"),
cmdkit.StringOption(targetAddressOptionName, "t", "Match target address"),
},
Run: func(req cmds.Request, res cmds.Response) {
n, err := p2pGetNode(req)
Expand All @@ -295,10 +339,10 @@ var p2pCloseCmd = &cmds.Command{
return
}

closeAll, _, _ := req.Option("all").Bool()
protoOpt, p, _ := req.Option("protocol").String()
listenOpt, l, _ := req.Option("listen-address").String()
targetOpt, t, _ := req.Option("target-address").String()
closeAll, _, _ := req.Option(allOptionName).Bool()
protoOpt, p, _ := req.Option(protocolOptionName).String()
listenOpt, l, _ := req.Option(listenAddressOptionName).String()
targetOpt, t, _ := req.Option(targetAddressOptionName).String()

proto := protocol.ID(protoOpt)

Expand Down
22 changes: 20 additions & 2 deletions test/sharness/t0180-p2p.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ check_test_ports() {
test_expect_success "test ports are closed" '
(! (netstat -lnp | grep "LISTEN" | grep ":10101 ")) &&
(! (netstat -lnp | grep "LISTEN" | grep ":10102 "))&&
(! (netstat -lnp | grep "LISTEN" | grep ":10103 "))
(! (netstat -lnp | grep "LISTEN" | grep ":10103 ")) &&
(! (netstat -lnp | grep "LISTEN" | grep ":10104 "))
'
}
check_test_ports
Expand Down Expand Up @@ -73,10 +74,27 @@ test_server_to_client() {

spawn_sending_server

test_expect_success 'S->C Setup client side' '
test_expect_success 'S->C(/ipfs/peerID) Setup client side' '
ipfsi 1 p2p forward /x/p2p-test /ip4/127.0.0.1/tcp/10102 /ipfs/${PEERID_0} 2>&1 > dialer-stdouterr.log
'

test_expect_success 'S->C Setup(dnsaddr/addr/ipfs/peerID) client side' '
ipfsi 1 p2p forward /x/p2p-test /ip4/127.0.0.1/tcp/10103 /dnsaddr/bootstrap.libp2p.io/ipfs/${PEERID_0} 2>&1 > dialer-stdouterr.log
'

test_expect_success 'S->C Setup(dnsaddr/addr) client side' '
ipfsi 1 p2p forward /x/p2p-test /ip4/127.0.0.1/tcp/10104 /dnsaddr/bootstrap.libp2p.io/ 2>&1 > dialer-stdouterr.log
'


test_expect_success 'S->C Output is empty' '
test_must_be_empty dialer-stdouterr.log
'
magik6k marked this conversation as resolved.
Show resolved Hide resolved

test_expect_success "'ipfs p2p ls | grep' succeeds" '
ipfsi 1 p2p ls | grep "/x/p2p-test /ip4/127.0.0.1/tcp/10104"
'

test_server_to_client

test_expect_success 'S->C Connect with dead server' '
Expand Down