Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
go-libp2p
Commits
4ff80c19
Commit
4ff80c19
authored
Aug 07, 2017
by
Lars Gierth
Committed by
GitHub
Aug 07, 2017
Browse files
Merge pull request #189 from libp2p/feat/dns
Resolve /dns4, /dns6, /dnsaddr multiaddrs
parents
6d63a88a
e0c5c22d
Changes
3
Hide whitespace changes
Inline
Side-by-side
p2p/host/basic/basic_host.go
View file @
4ff80c19
...
...
@@ -18,6 +18,7 @@ import (
pstore
"github.com/libp2p/go-libp2p-peerstore"
protocol
"github.com/libp2p/go-libp2p-protocol"
ma
"github.com/multiformats/go-multiaddr"
madns
"github.com/multiformats/go-multiaddr-dns"
msmux
"github.com/multiformats/go-multistream"
)
...
...
@@ -55,12 +56,13 @@ const NATPortMap Option = iota
// * uses an identity service to send + receive node information
// * uses a nat service to establish NAT port mappings
type
BasicHost
struct
{
network
inet
.
Network
mux
*
msmux
.
MultistreamMuxer
ids
*
identify
.
IDService
natmgr
NATManager
addrs
AddrsFactory
cmgr
connmgr
.
ConnManager
network
inet
.
Network
mux
*
msmux
.
MultistreamMuxer
ids
*
identify
.
IDService
natmgr
NATManager
addrs
AddrsFactory
maResolver
*
madns
.
Resolver
cmgr
connmgr
.
ConnManager
negtimeout
time
.
Duration
...
...
@@ -89,11 +91,16 @@ type HostOpts struct {
// If omitted, there's no override or filtering, and the results of Addrs and AllAddrs are the same.
AddrsFactory
AddrsFactory
// MultiaddrResolves holds the go-multiaddr-dns.Resolver used for resolving
// /dns4, /dns6, and /dnsaddr addresses before trying to connect to a peer.
MultiaddrResolver
*
madns
.
Resolver
// NATManager takes care of setting NAT port mappings, and discovering external addresses.
// If omitted, this will simply be disabled.
NATManager
NATManager
//
// BandwidthReporter is used for collecting aggregate metrics of the
// bandwidth used by various protocols.
BandwidthReporter
metrics
.
Reporter
// ConnManager is a libp2p connection manager
...
...
@@ -113,6 +120,7 @@ func NewHost(ctx context.Context, net inet.Network, opts *HostOpts) (*BasicHost,
mux
:
msmux
.
NewMultistreamMuxer
(),
negtimeout
:
DefaultNegotiationTimeout
,
addrs
:
DefaultAddrsFactory
,
maResolver
:
madns
.
DefaultResolver
,
}
if
opts
.
MultistreamMuxer
!=
nil
{
...
...
@@ -138,6 +146,10 @@ func NewHost(ctx context.Context, net inet.Network, opts *HostOpts) (*BasicHost,
h
.
natmgr
=
opts
.
NATManager
}
if
opts
.
MultiaddrResolver
!=
nil
{
h
.
maResolver
=
opts
.
MultiaddrResolver
}
if
opts
.
BandwidthReporter
!=
nil
{
h
.
bwc
=
opts
.
BandwidthReporter
h
.
ids
.
Reporter
=
opts
.
BandwidthReporter
...
...
@@ -197,6 +209,8 @@ func New(net inet.Network, opts ...interface{}) *BasicHost {
hostopts
.
AddrsFactory
=
AddrsFactory
(
o
)
case
connmgr
.
ConnManager
:
hostopts
.
ConnManager
=
o
case
*
madns
.
Resolver
:
hostopts
.
MultiaddrResolver
=
o
}
}
...
...
@@ -406,12 +420,11 @@ func (h *BasicHost) newStream(ctx context.Context, p peer.ID, pid protocol.ID) (
}
// Connect ensures there is a connection between this host and the peer with
// given peer.ID.
Connect will absorb the addresses in pi into its internal
//
peerstore. If there is not an active connection, Connect will issue a
//
h.Network.Dial, and block until a connection
is
open, or an error is
//
returned
.
// given peer.ID.
If there is not an active connection, Connect will issue a
//
h.Network.Dial, and block until a connection is open, or an error is returned.
//
Connect will absorb the addresses in pi into
i
t
s
internal peerstore.
//
It will also resolve any /dns4, /dns6, and /dnsaddr addresses
.
func
(
h
*
BasicHost
)
Connect
(
ctx
context
.
Context
,
pi
pstore
.
PeerInfo
)
error
{
// absorb addresses into peerstore
h
.
Peerstore
()
.
AddAddrs
(
pi
.
ID
,
pi
.
Addrs
,
pstore
.
TempAddrTTL
)
...
...
@@ -420,9 +433,46 @@ func (h *BasicHost) Connect(ctx context.Context, pi pstore.PeerInfo) error {
return
nil
}
resolved
,
err
:=
h
.
resolveAddrs
(
ctx
,
h
.
Peerstore
()
.
PeerInfo
(
pi
.
ID
))
if
err
!=
nil
{
return
err
}
h
.
Peerstore
()
.
AddAddrs
(
pi
.
ID
,
resolved
,
pstore
.
TempAddrTTL
)
return
h
.
dialPeer
(
ctx
,
pi
.
ID
)
}
func
(
h
*
BasicHost
)
resolveAddrs
(
ctx
context
.
Context
,
pi
pstore
.
PeerInfo
)
([]
ma
.
Multiaddr
,
error
)
{
proto
:=
ma
.
ProtocolWithCode
(
ma
.
P_IPFS
)
.
Name
p2paddr
,
err
:=
ma
.
NewMultiaddr
(
"/"
+
proto
+
"/"
+
pi
.
ID
.
Pretty
())
if
err
!=
nil
{
return
nil
,
err
}
var
addrs
[]
ma
.
Multiaddr
for
_
,
addr
:=
range
pi
.
Addrs
{
addrs
=
append
(
addrs
,
addr
)
if
!
madns
.
Matches
(
addr
)
{
continue
}
reqaddr
:=
addr
.
Encapsulate
(
p2paddr
)
resaddrs
,
err
:=
h
.
maResolver
.
Resolve
(
ctx
,
reqaddr
)
if
err
!=
nil
{
log
.
Infof
(
"error resolving %s: %s"
,
reqaddr
,
err
)
}
for
_
,
res
:=
range
resaddrs
{
pi
,
err
:=
pstore
.
InfoFromP2pAddr
(
res
)
if
err
!=
nil
{
log
.
Infof
(
"error parsing %s: %s"
,
res
,
err
)
}
addrs
=
append
(
addrs
,
pi
.
Addrs
...
)
}
}
return
addrs
,
nil
}
// dialPeer opens a connection to peer, and makes sure to identify
// the connection once it has been opened.
func
(
h
*
BasicHost
)
dialPeer
(
ctx
context
.
Context
,
p
peer
.
ID
)
error
{
...
...
p2p/host/basic/basic_host_test.go
View file @
4ff80c19
...
...
@@ -4,14 +4,17 @@ import (
"bytes"
"context"
"io"
"sort"
"testing"
"time"
host
"github.com/libp2p/go-libp2p-host"
inet
"github.com/libp2p/go-libp2p-net"
testutil
"github.com/libp2p/go-libp2p-netutil"
pstore
"github.com/libp2p/go-libp2p-peerstore"
protocol
"github.com/libp2p/go-libp2p-protocol"
ma
"github.com/multiformats/go-multiaddr"
madns
"github.com/multiformats/go-multiaddr-dns"
)
func
TestHostSimple
(
t
*
testing
.
T
)
{
...
...
@@ -330,3 +333,55 @@ func TestProtoDowngrade(t *testing.T) {
s2
.
Close
()
}
func
TestAddrResolution
(
t
*
testing
.
T
)
{
ctx
:=
context
.
Background
()
p1
,
err
:=
testutil
.
RandPeerID
()
if
err
!=
nil
{
t
.
Error
(
err
)
}
p2
,
err
:=
testutil
.
RandPeerID
()
if
err
!=
nil
{
t
.
Error
(
err
)
}
addr1
:=
ma
.
StringCast
(
"/dnsaddr/example.com"
)
addr2
:=
ma
.
StringCast
(
"/ip4/192.0.2.1/tcp/123"
)
p2paddr1
:=
ma
.
StringCast
(
"/dnsaddr/example.com/ipfs/"
+
p1
.
Pretty
())
p2paddr2
:=
ma
.
StringCast
(
"/ip4/192.0.2.1/tcp/123/ipfs/"
+
p1
.
Pretty
())
p2paddr3
:=
ma
.
StringCast
(
"/ip4/192.0.2.1/tcp/123/ipfs/"
+
p2
.
Pretty
())
backend
:=
&
madns
.
MockBackend
{
TXT
:
map
[
string
][]
string
{
"_dnsaddr.example.com"
:
[]
string
{
"dnsaddr="
+
p2paddr2
.
String
(),
"dnsaddr="
+
p2paddr3
.
String
(),
}},
}
resolver
:=
&
madns
.
Resolver
{
Backend
:
backend
}
h
:=
New
(
testutil
.
GenSwarmNetwork
(
t
,
ctx
),
resolver
)
defer
h
.
Close
()
pi
,
err
:=
pstore
.
InfoFromP2pAddr
(
p2paddr1
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
tctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
time
.
Millisecond
*
100
)
defer
cancel
()
_
=
h
.
Connect
(
tctx
,
*
pi
)
addrs
:=
h
.
Peerstore
()
.
Addrs
(
pi
.
ID
)
sort
.
Sort
(
sortedMultiaddrs
(
addrs
))
if
len
(
addrs
)
!=
2
||
!
addrs
[
0
]
.
Equal
(
addr1
)
||
!
addrs
[
1
]
.
Equal
(
addr2
)
{
t
.
Fatalf
(
"expected [%s %s], got %+v"
,
addr1
,
addr2
,
addrs
)
}
}
type
sortedMultiaddrs
[]
ma
.
Multiaddr
func
(
sma
sortedMultiaddrs
)
Len
()
int
{
return
len
(
sma
)
}
func
(
sma
sortedMultiaddrs
)
Swap
(
i
,
j
int
)
{
sma
[
i
],
sma
[
j
]
=
sma
[
j
],
sma
[
i
]
}
func
(
sma
sortedMultiaddrs
)
Less
(
i
,
j
int
)
bool
{
return
bytes
.
Compare
(
sma
[
i
]
.
Bytes
(),
sma
[
j
]
.
Bytes
())
==
1
}
package.json
View file @
4ff80c19
...
...
@@ -274,6 +274,12 @@
"hash"
:
"QmYv8PxtikjeL6AfsheUiJfoFRzKvx8hdwRf4odBWH7mQx"
,
"name"
:
"go-libp2p-circuit"
,
"version"
:
"1.1.3"
},
{
"author"
:
"lgierth"
,
"hash"
:
"QmS7xUmsTdVNU2t1bPV6o9aXuXfufAjNGYgh2bcN2z9DAs"
,
"name"
:
"go-multiaddr-dns"
,
"version"
:
"0.2.0"
}
],
"gxVersion"
:
"0.4.0"
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment