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
51fd99e3
Commit
51fd99e3
authored
Nov 11, 2015
by
Jeromy
Browse files
extract from 0.4.0
parent
5a0162c7
Changes
125
Show whitespace changes
Inline
Side-by-side
p2p/nat/nat.go
View file @
51fd99e3
...
@@ -8,14 +8,14 @@ import (
...
@@ -8,14 +8,14 @@ import (
"sync"
"sync"
"time"
"time"
ma
"github.com/
ipfs/go-ipfs/Godeps/_workspace/src/github.com/
jbenet/go-multiaddr"
ma
"github.com/jbenet/go-multiaddr"
manet
"github.com/
ipfs/go-ipfs/Godeps/_workspace/src/github.com/
jbenet/go-multiaddr-net"
manet
"github.com/jbenet/go-multiaddr-net"
nat
"github.com/
ipfs/go-ipfs/Godeps/_workspace/src/github.com/
fd/go-nat"
nat
"github.com/fd/go-nat"
goprocess
"github.com/
ipfs/go-ipfs/Godeps/_workspace/src/github.com/
jbenet/goprocess"
goprocess
"github.com/jbenet/goprocess"
periodic
"github.com/
ipfs/go-ipfs/Godeps/_workspace/src/github.com/
jbenet/goprocess/periodic"
periodic
"github.com/jbenet/goprocess/periodic"
notifier
"
github.com/ipfs/go-ipfs/
thirdparty/notifier"
notifier
"thirdparty/notifier"
logging
"
github.com/ipfs/go-ipfs/vendor/go-log-v1.0.0
"
logging
"
QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log
"
)
)
var
(
var
(
...
@@ -83,7 +83,7 @@ func (nat *NAT) Process() goprocess.Process {
...
@@ -83,7 +83,7 @@ func (nat *NAT) Process() goprocess.Process {
}
}
// Notifier is an object that assists NAT in notifying listeners.
// Notifier is an object that assists NAT in notifying listeners.
// It is implemented using
github.com/ipfs/go-ipfs/
thirdparty/notifier
// It is implemented using thirdparty/notifier
type
Notifier
struct
{
type
Notifier
struct
{
n
notifier
.
Notifier
n
notifier
.
Notifier
}
}
...
...
p2p/net/conn/conn.go
View file @
51fd99e3
...
@@ -6,16 +6,15 @@ import (
...
@@ -6,16 +6,15 @@ import (
"net"
"net"
"time"
"time"
msgio
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-msgio"
mpool
"github.com/jbenet/go-msgio/mpool"
mpool
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-msgio/mpool"
ma
"github.com/jbenet/go-multiaddr"
ma
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
manet
"github.com/jbenet/go-multiaddr-net"
manet
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
context
"golang.org/x/net/context"
context
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
u
"github.com/ipfs/go-ipfs/util"
logging
"github.com/ipfs/go-ipfs/vendor/go-log-v1.0.0"
ic
"github.com/ipfs/go-libp2p/p2p/crypto"
ic
"github.com/ipfs/go-libp2p/p2p/crypto"
peer
"github.com/ipfs/go-libp2p/p2p/peer"
peer
"github.com/ipfs/go-libp2p/p2p/peer"
lgbl
"github.com/ipfs/go-libp2p/util/eventlog/loggables"
u
"util"
lgbl
"util/eventlog/loggables"
logging
"QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log"
)
)
var
log
=
logging
.
Logger
(
"conn"
)
var
log
=
logging
.
Logger
(
"conn"
)
...
@@ -32,7 +31,6 @@ type singleConn struct {
...
@@ -32,7 +31,6 @@ type singleConn struct {
local
peer
.
ID
local
peer
.
ID
remote
peer
.
ID
remote
peer
.
ID
maconn
manet
.
Conn
maconn
manet
.
Conn
msgrw
msgio
.
ReadWriteCloser
event
io
.
Closer
event
io
.
Closer
}
}
...
@@ -44,7 +42,6 @@ func newSingleConn(ctx context.Context, local, remote peer.ID, maconn manet.Conn
...
@@ -44,7 +42,6 @@ func newSingleConn(ctx context.Context, local, remote peer.ID, maconn manet.Conn
local
:
local
,
local
:
local
,
remote
:
remote
,
remote
:
remote
,
maconn
:
maconn
,
maconn
:
maconn
,
msgrw
:
msgio
.
NewReadWriter
(
maconn
),
event
:
log
.
EventBegin
(
ctx
,
"connLifetime"
,
ml
),
event
:
log
.
EventBegin
(
ctx
,
"connLifetime"
,
ml
),
}
}
...
@@ -62,7 +59,7 @@ func (c *singleConn) Close() error {
...
@@ -62,7 +59,7 @@ func (c *singleConn) Close() error {
}()
}()
// close underlying connection
// close underlying connection
return
c
.
m
sgrw
.
Close
()
return
c
.
m
aconn
.
Close
()
}
}
// ID is an identifier unique to this connection.
// ID is an identifier unique to this connection.
...
@@ -123,31 +120,12 @@ func (c *singleConn) RemotePeer() peer.ID {
...
@@ -123,31 +120,12 @@ func (c *singleConn) RemotePeer() peer.ID {
// Read reads data, net.Conn style
// Read reads data, net.Conn style
func
(
c
*
singleConn
)
Read
(
buf
[]
byte
)
(
int
,
error
)
{
func
(
c
*
singleConn
)
Read
(
buf
[]
byte
)
(
int
,
error
)
{
return
c
.
m
sgrw
.
Read
(
buf
)
return
c
.
m
aconn
.
Read
(
buf
)
}
}
// Write writes data, net.Conn style
// Write writes data, net.Conn style
func
(
c
*
singleConn
)
Write
(
buf
[]
byte
)
(
int
,
error
)
{
func
(
c
*
singleConn
)
Write
(
buf
[]
byte
)
(
int
,
error
)
{
return
c
.
msgrw
.
Write
(
buf
)
return
c
.
maconn
.
Write
(
buf
)
}
func
(
c
*
singleConn
)
NextMsgLen
()
(
int
,
error
)
{
return
c
.
msgrw
.
NextMsgLen
()
}
// ReadMsg reads data, net.Conn style
func
(
c
*
singleConn
)
ReadMsg
()
([]
byte
,
error
)
{
return
c
.
msgrw
.
ReadMsg
()
}
// WriteMsg writes data, net.Conn style
func
(
c
*
singleConn
)
WriteMsg
(
buf
[]
byte
)
error
{
return
c
.
msgrw
.
WriteMsg
(
buf
)
}
// ReleaseMsg releases a buffer
func
(
c
*
singleConn
)
ReleaseMsg
(
m
[]
byte
)
{
c
.
msgrw
.
ReleaseMsg
(
m
)
}
}
// ID returns the ID of a given Conn.
// ID returns the ID of a given Conn.
...
...
p2p/net/conn/conn_test.go
View file @
51fd99e3
...
@@ -8,17 +8,25 @@ import (
...
@@ -8,17 +8,25 @@ import (
"testing"
"testing"
"time"
"time"
context
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
msgio
"github.com/jbenet/go-msgio"
travis
"github.com/ipfs/go-ipfs/util/testutil/ci/travis"
context
"golang.org/x/net/context"
travis
"util/testutil/ci/travis"
)
)
func
msgioWrap
(
c
Conn
)
msgio
.
ReadWriter
{
return
msgio
.
NewReadWriter
(
c
)
}
func
testOneSendRecv
(
t
*
testing
.
T
,
c1
,
c2
Conn
)
{
func
testOneSendRecv
(
t
*
testing
.
T
,
c1
,
c2
Conn
)
{
mc1
:=
msgioWrap
(
c1
)
mc2
:=
msgioWrap
(
c2
)
log
.
Debugf
(
"testOneSendRecv from %s to %s"
,
c1
.
LocalPeer
(),
c2
.
LocalPeer
())
log
.
Debugf
(
"testOneSendRecv from %s to %s"
,
c1
.
LocalPeer
(),
c2
.
LocalPeer
())
m1
:=
[]
byte
(
"hello"
)
m1
:=
[]
byte
(
"hello"
)
if
err
:=
c1
.
WriteMsg
(
m1
);
err
!=
nil
{
if
err
:=
m
c1
.
WriteMsg
(
m1
);
err
!=
nil
{
t
.
Fatal
(
err
)
t
.
Fatal
(
err
)
}
}
m2
,
err
:=
c2
.
ReadMsg
()
m2
,
err
:=
m
c2
.
ReadMsg
()
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatal
(
err
)
t
.
Fatal
(
err
)
}
}
...
@@ -28,11 +36,14 @@ func testOneSendRecv(t *testing.T, c1, c2 Conn) {
...
@@ -28,11 +36,14 @@ func testOneSendRecv(t *testing.T, c1, c2 Conn) {
}
}
func
testNotOneSendRecv
(
t
*
testing
.
T
,
c1
,
c2
Conn
)
{
func
testNotOneSendRecv
(
t
*
testing
.
T
,
c1
,
c2
Conn
)
{
mc1
:=
msgioWrap
(
c1
)
mc2
:=
msgioWrap
(
c2
)
m1
:=
[]
byte
(
"hello"
)
m1
:=
[]
byte
(
"hello"
)
if
err
:=
c1
.
WriteMsg
(
m1
);
err
==
nil
{
if
err
:=
m
c1
.
WriteMsg
(
m1
);
err
==
nil
{
t
.
Fatal
(
"write should have failed"
,
err
)
t
.
Fatal
(
"write should have failed"
,
err
)
}
}
_
,
err
:=
c2
.
ReadMsg
()
_
,
err
:=
m
c2
.
ReadMsg
()
if
err
==
nil
{
if
err
==
nil
{
t
.
Fatal
(
"read should have failed"
,
err
)
t
.
Fatal
(
"read should have failed"
,
err
)
}
}
...
@@ -72,10 +83,13 @@ func TestCloseLeak(t *testing.T) {
...
@@ -72,10 +83,13 @@ func TestCloseLeak(t *testing.T) {
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
c1
,
c2
,
_
,
_
:=
setupSingleConn
(
t
,
ctx
)
c1
,
c2
,
_
,
_
:=
setupSingleConn
(
t
,
ctx
)
mc1
:=
msgioWrap
(
c1
)
mc2
:=
msgioWrap
(
c2
)
for
i
:=
0
;
i
<
num
;
i
++
{
for
i
:=
0
;
i
<
num
;
i
++
{
b1
:=
[]
byte
(
fmt
.
Sprintf
(
"beep%d"
,
i
))
b1
:=
[]
byte
(
fmt
.
Sprintf
(
"beep%d"
,
i
))
c1
.
WriteMsg
(
b1
)
m
c1
.
WriteMsg
(
b1
)
b2
,
err
:=
c2
.
ReadMsg
()
b2
,
err
:=
m
c2
.
ReadMsg
()
if
err
!=
nil
{
if
err
!=
nil
{
panic
(
err
)
panic
(
err
)
}
}
...
@@ -84,8 +98,8 @@ func TestCloseLeak(t *testing.T) {
...
@@ -84,8 +98,8 @@ func TestCloseLeak(t *testing.T) {
}
}
b2
=
[]
byte
(
fmt
.
Sprintf
(
"boop%d"
,
i
))
b2
=
[]
byte
(
fmt
.
Sprintf
(
"boop%d"
,
i
))
c2
.
WriteMsg
(
b2
)
m
c2
.
WriteMsg
(
b2
)
b1
,
err
=
c1
.
ReadMsg
()
b1
,
err
=
m
c1
.
ReadMsg
()
if
err
!=
nil
{
if
err
!=
nil
{
panic
(
err
)
panic
(
err
)
}
}
...
@@ -114,9 +128,11 @@ func TestCloseLeak(t *testing.T) {
...
@@ -114,9 +128,11 @@ func TestCloseLeak(t *testing.T) {
wg
.
Wait
()
wg
.
Wait
()
// done!
// done!
<-
time
.
After
(
time
.
Millisecond
*
150
)
time
.
Sleep
(
time
.
Millisecond
*
150
)
if
runtime
.
NumGoroutine
()
>
20
{
ngr
:=
runtime
.
NumGoroutine
()
// panic("uncomment me to debug")
if
ngr
>
25
{
t
.
Fatal
(
"leaking goroutines:"
,
runtime
.
NumGoroutine
())
// note, this is really innacurate
//panic("uncomment me to debug")
t
.
Fatal
(
"leaking goroutines:"
,
ngr
)
}
}
}
}
p2p/net/conn/dial.go
View file @
51fd99e3
...
@@ -3,23 +3,32 @@ package conn
...
@@ -3,23 +3,32 @@ package conn
import
(
import
(
"fmt"
"fmt"
"math/rand"
"math/rand"
"net"
"strings"
"strings"
"syscall"
ma
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
ma
"github.com/jbenet/go-multiaddr"
manet
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
manet
"github.com/jbenet/go-multiaddr-net"
reuseport
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-reuseport"
context
"golang.org/x/net/context"
context
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
lgbl
"util/eventlog/loggables"
lgbl
"github.com/ipfs/go-libp2p/util/eventlog/loggables"
ci
"github.com/ipfs/go-libp2p/p2p/crypto"
addrutil
"github.com/ipfs/go-libp2p/p2p/net/swarm/addr"
addrutil
"github.com/ipfs/go-libp2p/p2p/net/swarm/addr"
transport
"github.com/ipfs/go-libp2p/p2p/net/transport"
peer
"github.com/ipfs/go-libp2p/p2p/peer"
peer
"github.com/ipfs/go-libp2p/p2p/peer"
)
)
type
WrapFunc
func
(
transport
.
Conn
)
transport
.
Conn
func
NewDialer
(
p
peer
.
ID
,
pk
ci
.
PrivKey
,
wrap
WrapFunc
)
*
Dialer
{
return
&
Dialer
{
LocalPeer
:
p
,
PrivateKey
:
pk
,
Wrapper
:
wrap
,
}
}
// String returns the string rep of d.
// String returns the string rep of d.
func
(
d
*
Dialer
)
String
()
string
{
func
(
d
*
Dialer
)
String
()
string
{
return
fmt
.
Sprintf
(
"<Dialer %s
%s
...>"
,
d
.
LocalPeer
,
d
.
LocalAddrs
[
0
]
)
return
fmt
.
Sprintf
(
"<Dialer %s ...>"
,
d
.
LocalPeer
)
}
}
// Dial connects to a peer over a particular address
// Dial connects to a peer over a particular address
...
@@ -95,112 +104,34 @@ func (d *Dialer) Dial(ctx context.Context, raddr ma.Multiaddr, remote peer.ID) (
...
@@ -95,112 +104,34 @@ func (d *Dialer) Dial(ctx context.Context, raddr ma.Multiaddr, remote peer.ID) (
return
connOut
,
nil
return
connOut
,
nil
}
}
// rawConnDial dials the underlying net.Conn + manet.Conns
func
(
d
*
Dialer
)
AddDialer
(
pd
transport
.
Dialer
)
{
func
(
d
*
Dialer
)
rawConnDial
(
ctx
context
.
Context
,
raddr
ma
.
Multiaddr
,
remote
peer
.
ID
)
(
manet
.
Conn
,
error
)
{
d
.
Dialers
=
append
(
d
.
Dialers
,
pd
)
// before doing anything, check we're going to be able to dial.
// we may not support the given address.
if
_
,
_
,
err
:=
manet
.
DialArgs
(
raddr
);
err
!=
nil
{
return
nil
,
err
}
if
strings
.
HasPrefix
(
raddr
.
String
(),
"/ip4/0.0.0.0"
)
{
log
.
Event
(
ctx
,
"connDialZeroAddr"
,
lgbl
.
Dial
(
"conn"
,
d
.
LocalPeer
,
remote
,
nil
,
raddr
))
return
nil
,
fmt
.
Errorf
(
"Attempted to connect to zero address: %s"
,
raddr
)
}
// get local addr to use.
laddr
:=
pickLocalAddr
(
d
.
LocalAddrs
,
raddr
)
logdial
:=
lgbl
.
Dial
(
"conn"
,
d
.
LocalPeer
,
remote
,
laddr
,
raddr
)
defer
log
.
EventBegin
(
ctx
,
"connDialRawConn"
,
logdial
)
.
Done
()
// make a copy of the manet.Dialer, we may need to change its timeout.
madialer
:=
d
.
Dialer
if
laddr
!=
nil
&&
reuseportIsAvailable
()
{
// we're perhaps going to dial twice. half the timeout, so we can afford to.
// otherwise our context would expire right after the first dial.
madialer
.
Dialer
.
Timeout
=
(
madialer
.
Dialer
.
Timeout
/
2
)
// dial using reuseport.Dialer, because we're probably reusing addrs.
// this is optimistic, as the reuseDial may fail to bind the port.
rpev
:=
log
.
EventBegin
(
ctx
,
"connDialReusePort"
,
logdial
)
if
nconn
,
retry
,
reuseErr
:=
reuseDial
(
madialer
.
Dialer
,
laddr
,
raddr
);
reuseErr
==
nil
{
// if it worked, wrap the raw net.Conn with our manet.Conn
logdial
[
"reuseport"
]
=
"success"
rpev
.
Done
()
return
manet
.
WrapNetConn
(
nconn
)
}
else
if
!
retry
{
// reuseDial is sure this is a legitimate dial failure, not a reuseport failure.
logdial
[
"reuseport"
]
=
"failure"
logdial
[
"error"
]
=
reuseErr
rpev
.
Done
()
return
nil
,
reuseErr
}
else
{
// this is a failure to reuse port. log it.
logdial
[
"reuseport"
]
=
"retry"
logdial
[
"error"
]
=
reuseErr
rpev
.
Done
()
}
}
defer
log
.
EventBegin
(
ctx
,
"connDialManet"
,
logdial
)
.
Done
()
return
madialer
.
Dial
(
raddr
)
}
}
func
reuseDial
(
dialer
net
.
Dialer
,
laddr
,
raddr
ma
.
Multiaddr
)
(
conn
net
.
Conn
,
retry
bool
,
err
error
)
{
// returns dialer that can dial the given address
if
laddr
==
nil
{
func
(
d
*
Dialer
)
subDialerForAddr
(
raddr
ma
.
Multiaddr
)
transport
.
Dialer
{
// if we're given no local address no sense in using reuseport to dial, dial out as usual.
for
_
,
pd
:=
range
d
.
Dialers
{
return
nil
,
true
,
reuseport
.
ErrReuseFailed
if
pd
.
Matches
(
raddr
)
{
return
pd
}
}
// give reuse.Dialer the manet.Dialer's Dialer.
// (wow, Dialer should've so been an interface...)
rd
:=
reuseport
.
Dialer
{
dialer
}
// get the local net.Addr manually
rd
.
D
.
LocalAddr
,
err
=
manet
.
ToNetAddr
(
laddr
)
if
err
!=
nil
{
return
nil
,
true
,
err
// something wrong with laddr. retry without.
}
// get the raddr dial args for rd.dial
network
,
netraddr
,
err
:=
manet
.
DialArgs
(
raddr
)
if
err
!=
nil
{
return
nil
,
true
,
err
// something wrong with laddr. retry without.
}
}
// rd.Dial gets us a net.Conn with SO_REUSEPORT and SO_REUSEADDR set.
return
nil
conn
,
err
=
rd
.
Dial
(
network
,
netraddr
)
return
conn
,
reuseErrShouldRetry
(
err
),
err
// hey! it worked!
}
}
// reuseErrShouldRetry diagnoses whether to retry after a reuse error.
// rawConnDial dials the underlying net.Conn + manet.Conns
// if we failed to bind, we should retry. if bind worked and this is a
func
(
d
*
Dialer
)
rawConnDial
(
ctx
context
.
Context
,
raddr
ma
.
Multiaddr
,
remote
peer
.
ID
)
(
transport
.
Conn
,
error
)
{
// real dial error (remote end didnt answer) then we should not retry.
if
strings
.
HasPrefix
(
raddr
.
String
(),
"/ip4/0.0.0.0"
)
{
func
reuseErrShouldRetry
(
err
error
)
bool
{
log
.
Event
(
ctx
,
"connDialZeroAddr"
,
lgbl
.
Dial
(
"conn"
,
d
.
LocalPeer
,
remote
,
nil
,
raddr
))
if
err
==
nil
{
return
nil
,
fmt
.
Errorf
(
"Attempted to connect to zero address: %s"
,
raddr
)
return
false
// hey, it worked! no need to retry.
}
// if it's a network timeout error, it's a legitimate failure.
if
nerr
,
ok
:=
err
.
(
net
.
Error
);
ok
&&
nerr
.
Timeout
()
{
return
false
}
}
errno
,
ok
:=
err
.
(
syscall
.
Errno
)
sd
:=
d
.
subDialerForAddr
(
raddr
)
if
!
ok
{
// not an errno? who knows what this is. retry.
if
sd
==
nil
{
return
true
return
nil
,
fmt
.
Errorf
(
"no dialer for %s"
,
raddr
)
}
}
switch
errno
{
return
sd
.
Dial
(
raddr
)
case
syscall
.
EADDRINUSE
,
syscall
.
EADDRNOTAVAIL
:
return
true
// failure to bind. retry.
case
syscall
.
ECONNREFUSED
:
return
false
// real dial error
default
:
return
true
// optimistically default to retry.
}
}
}
func
pickLocalAddr
(
laddrs
[]
ma
.
Multiaddr
,
raddr
ma
.
Multiaddr
)
(
laddr
ma
.
Multiaddr
)
{
func
pickLocalAddr
(
laddrs
[]
ma
.
Multiaddr
,
raddr
ma
.
Multiaddr
)
(
laddr
ma
.
Multiaddr
)
{
...
...
p2p/net/conn/dial_test.go
View file @
51fd99e3
...
@@ -8,9 +8,13 @@ import (
...
@@ -8,9 +8,13 @@ import (
"testing"
"testing"
"time"
"time"
tu
"github.com/ipfs/go-ipfs/util/testutil"
ic
"github.com/ipfs/go-libp2p/p2p/crypto"
transport
"github.com/ipfs/go-libp2p/p2p/net/transport"
peer
"github.com/ipfs/go-libp2p/p2p/peer"
tu
"util/testutil"
context
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
ma
"github.com/jbenet/go-multiaddr"
context
"golang.org/x/net/context"
)
)
func
echoListen
(
ctx
context
.
Context
,
listener
Listener
)
{
func
echoListen
(
ctx
context
.
Context
,
listener
Listener
)
{
...
@@ -49,6 +53,25 @@ func setupSingleConn(t *testing.T, ctx context.Context) (a, b Conn, p1, p2 tu.Pe
...
@@ -49,6 +53,25 @@ func setupSingleConn(t *testing.T, ctx context.Context) (a, b Conn, p1, p2 tu.Pe
return
setupConn
(
t
,
ctx
,
false
)
return
setupConn
(
t
,
ctx
,
false
)
}
}
func
Listen
(
ctx
context
.
Context
,
addr
ma
.
Multiaddr
,
local
peer
.
ID
,
sk
ic
.
PrivKey
)
(
Listener
,
error
)
{
list
,
err
:=
transport
.
NewTCPTransport
()
.
Listen
(
addr
)
if
err
!=
nil
{
return
nil
,
err
}
return
WrapTransportListener
(
ctx
,
list
,
local
,
sk
)
}
func
dialer
(
t
*
testing
.
T
,
a
ma
.
Multiaddr
)
transport
.
Dialer
{
tpt
:=
transport
.
NewTCPTransport
()
tptd
,
err
:=
tpt
.
Dialer
(
a
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
return
tptd
}
func
setupConn
(
t
*
testing
.
T
,
ctx
context
.
Context
,
secure
bool
)
(
a
,
b
Conn
,
p1
,
p2
tu
.
PeerNetParams
)
{
func
setupConn
(
t
*
testing
.
T
,
ctx
context
.
Context
,
secure
bool
)
(
a
,
b
Conn
,
p1
,
p2
tu
.
PeerNetParams
)
{
p1
=
tu
.
RandPeerNetParamsOrFatal
(
t
)
p1
=
tu
.
RandPeerNetParamsOrFatal
(
t
)
...
@@ -71,6 +94,8 @@ func setupConn(t *testing.T, ctx context.Context, secure bool) (a, b Conn, p1, p
...
@@ -71,6 +94,8 @@ func setupConn(t *testing.T, ctx context.Context, secure bool) (a, b Conn, p1, p
PrivateKey
:
key2
,
PrivateKey
:
key2
,
}
}
d2
.
AddDialer
(
dialer
(
t
,
p2
.
Addr
))
var
c2
Conn
var
c2
Conn
done
:=
make
(
chan
error
)
done
:=
make
(
chan
error
)
...
@@ -152,6 +177,7 @@ func testDialer(t *testing.T, secure bool) {
...
@@ -152,6 +177,7 @@ func testDialer(t *testing.T, secure bool) {
LocalPeer
:
p2
.
ID
,
LocalPeer
:
p2
.
ID
,
PrivateKey
:
key2
,
PrivateKey
:
key2
,
}
}
d2
.
AddDialer
(
dialer
(
t
,
p2
.
Addr
))
go
echoListen
(
ctx
,
l1
)
go
echoListen
(
ctx
,
l1
)
...
@@ -161,10 +187,10 @@ func testDialer(t *testing.T, secure bool) {
...
@@ -161,10 +187,10 @@ func testDialer(t *testing.T, secure bool) {
}
}
// fmt.Println("sending")
// fmt.Println("sending")
c
.
WriteMsg
([]
byte
(
"beep"
)
)
mc
:=
msgioWrap
(
c
)
c
.
WriteMsg
([]
byte
(
"b
oo
p"
))
m
c
.
WriteMsg
([]
byte
(
"b
ee
p"
))
mc
.
WriteMsg
([]
byte
(
"boop"
))
out
,
err
:=
c
.
ReadMsg
()
out
,
err
:=
m
c
.
ReadMsg
()
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatal
(
err
)
t
.
Fatal
(
err
)
}
}
...
@@ -175,7 +201,7 @@ func testDialer(t *testing.T, secure bool) {
...
@@ -175,7 +201,7 @@ func testDialer(t *testing.T, secure bool) {
t
.
Error
(
"unexpected conn output"
,
data
)
t
.
Error
(
"unexpected conn output"
,
data
)
}
}
out
,
err
=
c
.
ReadMsg
()
out
,
err
=
m
c
.
ReadMsg
()
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatal
(
err
)
t
.
Fatal
(
err
)
}
}
...
@@ -227,6 +253,7 @@ func testDialerCloseEarly(t *testing.T, secure bool) {
...
@@ -227,6 +253,7 @@ func testDialerCloseEarly(t *testing.T, secure bool) {
LocalPeer
:
p2
.
ID
,
LocalPeer
:
p2
.
ID
,
// PrivateKey: key2, -- dont give it key. we'll just close the conn.
// PrivateKey: key2, -- dont give it key. we'll just close the conn.
}
}
d2
.
AddDialer
(
dialer
(
t
,
p2
.
Addr
))
errs
:=
make
(
chan
error
,
100
)
errs
:=
make
(
chan
error
,
100
)
done
:=
make
(
chan
struct
{},
1
)
done
:=
make
(
chan
struct
{},
1
)
...
@@ -253,7 +280,7 @@ func testDialerCloseEarly(t *testing.T, secure bool) {
...
@@ -253,7 +280,7 @@ func testDialerCloseEarly(t *testing.T, secure bool) {
c
,
err
:=
d2
.
Dial
(
ctx
,
p1
.
Addr
,
p1
.
ID
)
c
,
err
:=
d2
.
Dial
(
ctx
,
p1
.
Addr
,
p1
.
ID
)
if
err
!=
nil
{
if
err
!=
nil
{
errs
<-
err
t
.
Fatal
(
err
)
}
}
c
.
Close
()
// close it early.
c
.
Close
()
// close it early.
...
...
p2p/net/conn/interface.go
View file @
51fd99e3
...
@@ -5,14 +5,13 @@ import (
...
@@ -5,14 +5,13 @@ import (
"net"
"net"
"time"
"time"
key
"github.com/ipfs/go-ipfs/blocks/key"
ic
"github.com/ipfs/go-libp2p/p2p/crypto"
ic
"github.com/ipfs/go-libp2p/p2p/crypto"
filter
"github.com/ipfs/go-libp2p/p2p/net/filter"
filter
"github.com/ipfs/go-libp2p/p2p/net/filter"
transport
"github.com/ipfs/go-libp2p/p2p/net/transport"
peer
"github.com/ipfs/go-libp2p/p2p/peer"
peer
"github.com/ipfs/go-libp2p/p2p/peer"
msgio
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-msgio"
ma
"github.com/jbenet/go-multiaddr"
ma
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
key
"github.com/whyrusleeping/go-key"
manet
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
)
)
// Map maps Keys (Peer.IDs) to Connections.
// Map maps Keys (Peer.IDs) to Connections.
...
@@ -46,30 +45,30 @@ type Conn interface {
...
@@ -46,30 +45,30 @@ type Conn interface {
SetReadDeadline
(
t
time
.
Time
)
error
SetReadDeadline
(
t
time
.
Time
)
error
SetWriteDeadline
(
t
time
.
Time
)
error
SetWriteDeadline
(
t
time
.
Time
)
error
msg
io
.
Reader
io
.
Reader
msg
io
.
Writer
io
.
Writer
}
}
// Dialer is an object that can open connections. We could have a "convenience"
// Dialer is an object that can open connections. We could have a "convenience"
// Dial function as before, but it would have many arguments, as dialing is
// Dial function as before, but it would have many arguments, as dialing is
// no longer simple (need a peerstore, a local peer, a context, a network, etc)
// no longer simple (need a peerstore, a local peer, a context, a network, etc)
type
Dialer
struct
{
type
Dialer
struct
{
// Dialer is an optional manet.Dialer to use.
Dialer
manet
.
Dialer
// LocalPeer is the identity of the local Peer.
// LocalPeer is the identity of the local Peer.
LocalPeer
peer
.
ID
LocalPeer
peer
.
ID
// LocalAddrs is a set of local addresses to use.
// LocalAddrs is a set of local addresses to use.
LocalAddrs
[]
ma
.
Multiaddr
//LocalAddrs []ma.Multiaddr
// Dialers are the sub-dialers usable by this dialer
// selected in order based on the address being dialed
Dialers
[]
transport
.
Dialer
// PrivateKey used to initialize a secure connection.
// PrivateKey used to initialize a secure connection.
// Warning: if PrivateKey is nil, connection will not be secured.
// Warning: if PrivateKey is nil, connection will not be secured.
PrivateKey
ic
.
PrivKey
PrivateKey
ic
.
PrivKey
// Wrapper to wrap the raw connection (optional)
// Wrapper to wrap the raw connection (optional)
Wrapper
func
(
manet
.
Conn
)
manet
.
Conn
Wrapper
WrapFunc
}
}
// Listener is an object that can accept connections. It matches net.Listener
// Listener is an object that can accept connections. It matches net.Listener
...
...
p2p/net/conn/listen.go
View file @
51fd99e3
...
@@ -5,25 +5,24 @@ import (
...
@@ -5,25 +5,24 @@ import (
"io"
"io"
"net"
"net"
ma
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
ma
"github.com/jbenet/go-multiaddr"
manet
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
tec
"github.com/jbenet/go-temp-err-catcher"
reuseport
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-reuseport"
"github.com/jbenet/goprocess"
tec
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-temp-err-catcher"
goprocessctx
"github.com/jbenet/goprocess/context"
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/goprocess"
context
"golang.org/x/net/context"
goprocessctx
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/goprocess/context"
context
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
ic
"github.com/ipfs/go-libp2p/p2p/crypto"
ic
"github.com/ipfs/go-libp2p/p2p/crypto"
filter
"github.com/ipfs/go-libp2p/p2p/net/filter"
filter
"github.com/ipfs/go-libp2p/p2p/net/filter"
transport
"github.com/ipfs/go-libp2p/p2p/net/transport"
peer
"github.com/ipfs/go-libp2p/p2p/peer"
peer
"github.com/ipfs/go-libp2p/p2p/peer"
)
)
// ConnWrapper is any function that wraps a raw multiaddr connection
// ConnWrapper is any function that wraps a raw multiaddr connection
type
ConnWrapper
func
(
manet
.
Conn
)
mane
t
.
Conn
type
ConnWrapper
func
(
transport
.
Conn
)
transpor
t
.
Conn
// listener is an object that can accept connections. It implements Listener
// listener is an object that can accept connections. It implements Listener
type
listener
struct
{
type
listener
struct
{
mane
t
.
Listener
transpor
t
.
Listener
local
peer
.
ID
// LocalPeer is the identity of the local Peer
local
peer
.
ID
// LocalPeer is the identity of the local Peer
privk
ic
.
PrivKey
// private key to use to initialize secure conns
privk
ic
.
PrivKey
// private key to use to initialize secure conns
...
@@ -147,13 +146,7 @@ func (l *listener) Loggable() map[string]interface{} {
...
@@ -147,13 +146,7 @@ func (l *listener) Loggable() map[string]interface{} {
}
}
}
}
// Listen listens on the particular multiaddr, with given peer and peerstore.
func
WrapTransportListener
(
ctx
context
.
Context
,
ml
transport
.
Listener
,
local
peer
.
ID
,
sk
ic
.
PrivKey
)
(
Listener
,
error
)
{
func
Listen
(
ctx
context
.
Context
,
addr
ma
.
Multiaddr
,
local
peer
.
ID
,
sk
ic
.
PrivKey
)
(
Listener
,
error
)
{
ml
,
err
:=
manetListen
(
addr
)
if
err
!=
nil
{
return
nil
,
err
}
l
:=
&
listener
{
l
:=
&
listener
{
Listener
:
ml
,
Listener
:
ml
,
local
:
local
,
local
:
local
,
...
@@ -175,23 +168,3 @@ type ListenerConnWrapper interface {
...
@@ -175,23 +168,3 @@ type ListenerConnWrapper interface {
func
(
l
*
listener
)
SetConnWrapper
(
cw
ConnWrapper
)
{
func
(
l
*
listener
)
SetConnWrapper
(
cw
ConnWrapper
)
{
l
.
wrapper
=
cw
l
.
wrapper
=
cw
}
}
func
manetListen
(
addr
ma
.
Multiaddr
)
(
manet
.
Listener
,
error
)
{
network
,
naddr
,
err
:=
manet
.
DialArgs
(
addr
)
if
err
!=
nil
{
return
nil
,
err
}
if
reuseportIsAvailable
()
{
nl
,
err
:=
reuseport
.
Listen
(
network
,
naddr
)
if
err
==
nil
{
// hey, it worked!
return
manet
.
WrapNetListener
(
nl
)
}
// reuseport is available, but we failed to listen. log debug, and retry normally.
log
.
Debugf
(
"reuseport available, but failed to listen: %s %s, %s"
,
network
,
naddr
,
err
)
}
// either reuseport not available, or it failed. try normally.
return
manet
.
Listen
(
addr
)
}
p2p/net/conn/secure_conn.go
View file @
51fd99e3
...
@@ -5,8 +5,8 @@ import (
...
@@ -5,8 +5,8 @@ import (
"net"
"net"
"time"
"time"
ma
"github.com/
ipfs/go-ipfs/Godeps/_workspace/src/github.com/
jbenet/go-multiaddr"
ma
"github.com/jbenet/go-multiaddr"
context
"
github.com/ipfs/go-ipfs/Godeps/_workspace/src/
golang.org/x/net/context"
context
"golang.org/x/net/context"
ic
"github.com/ipfs/go-libp2p/p2p/crypto"
ic
"github.com/ipfs/go-libp2p/p2p/crypto"
secio
"github.com/ipfs/go-libp2p/p2p/crypto/secio"
secio
"github.com/ipfs/go-libp2p/p2p/crypto/secio"
...
@@ -119,20 +119,6 @@ func (c *secureConn) Write(buf []byte) (int, error) {
...
@@ -119,20 +119,6 @@ func (c *secureConn) Write(buf []byte) (int, error) {
return
c
.
secure
.
ReadWriter
()
.
Write
(
buf
)
return
c
.
secure
.
ReadWriter
()
.
Write
(
buf
)
}
}
func
(
c
*
secureConn
)
NextMsgLen
()
(
int
,
error
)
{
return
c
.
secure
.
ReadWriter
()
.
NextMsgLen
()
}
// ReadMsg reads data, net.Conn style
func
(
c
*
secureConn
)
ReadMsg
()
([]
byte
,
error
)
{
return
c
.
secure
.
ReadWriter
()
.
ReadMsg
()
}
// WriteMsg writes data, net.Conn style
func
(
c
*
secureConn
)
WriteMsg
(
buf
[]
byte
)
error
{
return
c
.
secure
.
ReadWriter
()
.
WriteMsg
(
buf
)
}
// ReleaseMsg releases a buffer
// ReleaseMsg releases a buffer
func
(
c
*
secureConn
)
ReleaseMsg
(
m
[]
byte
)
{
func
(
c
*
secureConn
)
ReleaseMsg
(
m
[]
byte
)
{
c
.
secure
.
ReadWriter
()
.
ReleaseMsg
(
m
)
c
.
secure
.
ReadWriter
()
.
ReleaseMsg
(
m
)
...
...
p2p/net/conn/secure_conn_test.go
View file @
51fd99e3
...
@@ -7,10 +7,10 @@ import (
...
@@ -7,10 +7,10 @@ import (
"testing"
"testing"
"time"
"time"
travis
"github.com/ipfs/go-ipfs/util/testutil/ci/travis"
ic
"github.com/ipfs/go-libp2p/p2p/crypto"
ic
"github.com/ipfs/go-libp2p/p2p/crypto"
travis
"util/testutil/ci/travis"
context
"
github.com/ipfs/go-ipfs/Godeps/_workspace/src/
golang.org/x/net/context"
context
"golang.org/x/net/context"
)
)
func
upgradeToSecureConn
(
t
*
testing
.
T
,
ctx
context
.
Context
,
sk
ic
.
PrivKey
,
c
Conn
)
(
Conn
,
error
)
{
func
upgradeToSecureConn
(
t
*
testing
.
T
,
ctx
context
.
Context
,
sk
ic
.
PrivKey
,
c
Conn
)
(
Conn
,
error
)
{
...
@@ -105,7 +105,7 @@ func TestSecureCancelHandshake(t *testing.T) {
...
@@ -105,7 +105,7 @@ func TestSecureCancelHandshake(t *testing.T) {
done
:=
make
(
chan
error
)
done
:=
make
(
chan
error
)
go
secureHandshake
(
t
,
ctx
,
p1
.
PrivKey
,
c1
,
done
)
go
secureHandshake
(
t
,
ctx
,
p1
.
PrivKey
,
c1
,
done
)
<-
time
.
After
(
time
.
Millisecond
)
time
.
Sleep
(
time
.
Millisecond
)
cancel
()
// cancel ctx
cancel
()
// cancel ctx
go
secureHandshake
(
t
,
ctx
,
p2
.
PrivKey
,
c2
,
done
)
go
secureHandshake
(
t
,
ctx
,
p2
.
PrivKey
,
c2
,
done
)
...
@@ -145,13 +145,16 @@ func TestSecureCloseLeak(t *testing.T) {
...
@@ -145,13 +145,16 @@ func TestSecureCloseLeak(t *testing.T) {
}
}
runPair
:=
func
(
c1
,
c2
Conn
,
num
int
)
{
runPair
:=
func
(
c1
,
c2
Conn
,
num
int
)
{
mc1
:=
msgioWrap
(
c1
)
mc2
:=
msgioWrap
(
c2
)
log
.
Debugf
(
"runPair %d"
,
num
)
log
.
Debugf
(
"runPair %d"
,
num
)
for
i
:=
0
;
i
<
num
;
i
++
{
for
i
:=
0
;
i
<
num
;
i
++
{
log
.
Debugf
(
"runPair iteration %d"
,
i
)
log
.
Debugf
(
"runPair iteration %d"
,
i
)
b1
:=
[]
byte
(
"beep"
)
b1
:=
[]
byte
(
"beep"
)
c1
.
WriteMsg
(
b1
)
m
c1
.
WriteMsg
(
b1
)
b2
,
err
:=
c2
.
ReadMsg
()
b2
,
err
:=
m
c2
.
ReadMsg
()
if
err
!=
nil
{
if
err
!=
nil
{
panic
(
err
)
panic
(
err
)
}
}
...
@@ -160,8 +163,8 @@ func TestSecureCloseLeak(t *testing.T) {
...
@@ -160,8 +163,8 @@ func TestSecureCloseLeak(t *testing.T) {
}
}
b2
=
[]
byte
(
"beep"
)
b2
=
[]
byte
(
"beep"
)
c2
.
WriteMsg
(
b2
)
m
c2
.
WriteMsg
(
b2
)
b1
,
err
=
c1
.
ReadMsg
()
b1
,
err
=
m
c1
.
ReadMsg
()
if
err
!=
nil
{
if
err
!=
nil
{
panic
(
err
)
panic
(
err
)
}
}
...
@@ -169,7 +172,7 @@ func TestSecureCloseLeak(t *testing.T) {
...
@@ -169,7 +172,7 @@ func TestSecureCloseLeak(t *testing.T) {
panic
(
"bytes not equal"
)
panic
(
"bytes not equal"
)
}
}
<-
time
.
After
(
time
.
Microsecond
*
5
)
time
.
Sleep
(
time
.
Microsecond
*
5
)
}
}
}
}
...
@@ -196,13 +199,14 @@ func TestSecureCloseLeak(t *testing.T) {
...
@@ -196,13 +199,14 @@ func TestSecureCloseLeak(t *testing.T) {
}(
c1
,
c2
)
}(
c1
,
c2
)
}
}
log
.
Debugf
(
"Waiting...
\n
"
)
log
.
Debugf
(
"Waiting..."
)
wg
.
Wait
()
wg
.
Wait
()
// done!
// done!
<-
time
.
After
(
time
.
Millisecond
*
150
)
time
.
Sleep
(
time
.
Millisecond
*
150
)
if
runtime
.
NumGoroutine
()
>
20
{
ngr
:=
runtime
.
NumGoroutine
()
if
ngr
>
25
{
// panic("uncomment me to debug")
// panic("uncomment me to debug")
t
.
Fatal
(
"leaking goroutines:"
,
runtime
.
NumGoroutine
()
)
t
.
Fatal
(
"leaking goroutines:"
,
ngr
)
}
}
}
}
p2p/net/filter/filter.go
View file @
51fd99e3
...
@@ -3,12 +3,14 @@ package filter
...
@@ -3,12 +3,14 @@ package filter
import
(
import
(
"net"
"net"
"strings"
"strings"
"sync"
ma
"github.com/
ipfs/go-ipfs/Godeps/_workspace/src/github.com/
jbenet/go-multiaddr"
ma
"github.com/jbenet/go-multiaddr"
manet
"github.com/
ipfs/go-ipfs/Godeps/_workspace/src/github.com/
jbenet/go-multiaddr-net"
manet
"github.com/jbenet/go-multiaddr-net"
)
)
type
Filters
struct
{
type
Filters
struct
{
mu
sync
.
RWMutex
filters
map
[
string
]
*
net
.
IPNet
filters
map
[
string
]
*
net
.
IPNet
}
}
...
@@ -19,6 +21,8 @@ func NewFilters() *Filters {
...
@@ -19,6 +21,8 @@ func NewFilters() *Filters {
}
}
func
(
fs
*
Filters
)
AddDialFilter
(
f
*
net
.
IPNet
)
{
func
(
fs
*
Filters
)
AddDialFilter
(
f
*
net
.
IPNet
)
{
fs
.
mu
.
Lock
()
defer
fs
.
mu
.
Unlock
()
fs
.
filters
[
f
.
String
()]
=
f
fs
.
filters
[
f
.
String
()]
=
f
}
}
...
@@ -31,6 +35,8 @@ func (f *Filters) AddrBlocked(a ma.Multiaddr) bool {
...
@@ -31,6 +35,8 @@ func (f *Filters) AddrBlocked(a ma.Multiaddr) bool {
ipstr
:=
strings
.
Split
(
addr
,
":"
)[
0
]
ipstr
:=
strings
.
Split
(
addr
,
":"
)[
0
]
ip
:=
net
.
ParseIP
(
ipstr
)
ip
:=
net
.
ParseIP
(
ipstr
)
f
.
mu
.
RLock
()
defer
f
.
mu
.
RUnlock
()
for
_
,
ft
:=
range
f
.
filters
{
for
_
,
ft
:=
range
f
.
filters
{
if
ft
.
Contains
(
ip
)
{
if
ft
.
Contains
(
ip
)
{
return
true
return
true
...
@@ -41,6 +47,8 @@ func (f *Filters) AddrBlocked(a ma.Multiaddr) bool {
...
@@ -41,6 +47,8 @@ func (f *Filters) AddrBlocked(a ma.Multiaddr) bool {
func
(
f
*
Filters
)
Filters
()
[]
*
net
.
IPNet
{
func
(
f
*
Filters
)
Filters
()
[]
*
net
.
IPNet
{
var
out
[]
*
net
.
IPNet
var
out
[]
*
net
.
IPNet
f
.
mu
.
RLock
()
defer
f
.
mu
.
RUnlock
()
for
_
,
ff
:=
range
f
.
filters
{
for
_
,
ff
:=
range
f
.
filters
{
out
=
append
(
out
,
ff
)
out
=
append
(
out
,
ff
)
}
}
...
@@ -48,5 +56,7 @@ func (f *Filters) Filters() []*net.IPNet {
...
@@ -48,5 +56,7 @@ func (f *Filters) Filters() []*net.IPNet {
}
}
func
(
f
*
Filters
)
Remove
(
ff
*
net
.
IPNet
)
{
func
(
f
*
Filters
)
Remove
(
ff
*
net
.
IPNet
)
{
f
.
mu
.
Lock
()
defer
f
.
mu
.
Unlock
()
delete
(
f
.
filters
,
ff
.
String
())
delete
(
f
.
filters
,
ff
.
String
())
}
}
p2p/net/interface.go
View file @
51fd99e3
...
@@ -6,9 +6,9 @@ import (
...
@@ -6,9 +6,9 @@ import (
conn
"github.com/ipfs/go-libp2p/p2p/net/conn"
conn
"github.com/ipfs/go-libp2p/p2p/net/conn"
peer
"github.com/ipfs/go-libp2p/p2p/peer"
peer
"github.com/ipfs/go-libp2p/p2p/peer"
ma
"github.com/
ipfs/go-ipfs/Godeps/_workspace/src/github.com/
jbenet/go-multiaddr"
ma
"github.com/jbenet/go-multiaddr"
"github.com/
ipfs/go-ipfs/Godeps/_workspace/src/github.com/
jbenet/goprocess"
"github.com/jbenet/goprocess"
context
"
github.com/ipfs/go-ipfs/Godeps/_workspace/src/
golang.org/x/net/context"
context
"golang.org/x/net/context"
)
)
// MessageSizeMax is a soft (recommended) maximum for network messages.
// MessageSizeMax is a soft (recommended) maximum for network messages.
...
...
p2p/net/mock/interface.go
View file @
51fd99e3
...
@@ -14,7 +14,7 @@ import (
...
@@ -14,7 +14,7 @@ import (
"io"
"io"
"time"
"time"
ma
"github.com/
ipfs/go-ipfs/Godeps/_workspace/src/github.com/
jbenet/go-multiaddr"
ma
"github.com/jbenet/go-multiaddr"
)
)
type
Mocknet
interface
{
type
Mocknet
interface
{
...
...
p2p/net/mock/mock.go
View file @
51fd99e3
package
mocknet
package
mocknet
import
(
import
(
logging
"
github.com/ipfs/go-ipfs/vendor/go-log-v1.0.0
"
logging
"
QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log
"
context
"
github.com/ipfs/go-ipfs/Godeps/_workspace/src/
golang.org/x/net/context"
context
"golang.org/x/net/context"
)
)
var
log
=
logging
.
Logger
(
"mocknet"
)
var
log
=
logging
.
Logger
(
"mocknet"
)
...
...
p2p/net/mock/mock_conn.go
View file @
51fd99e3
...
@@ -8,7 +8,8 @@ import (
...
@@ -8,7 +8,8 @@ import (
inet
"github.com/ipfs/go-libp2p/p2p/net"
inet
"github.com/ipfs/go-libp2p/p2p/net"
peer
"github.com/ipfs/go-libp2p/p2p/peer"
peer
"github.com/ipfs/go-libp2p/p2p/peer"
ma
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
ma
"github.com/jbenet/go-multiaddr"
process
"github.com/jbenet/goprocess"
)
)
// conn represents one side's perspective of a
// conn represents one side's perspective of a
...
@@ -28,11 +29,31 @@ type conn struct {
...
@@ -28,11 +29,31 @@ type conn struct {
link
*
link
link
*
link
rconn
*
conn
// counterpart
rconn
*
conn
// counterpart
streams
list
.
List
streams
list
.
List
proc
process
.
Process
sync
.
RWMutex
sync
.
RWMutex
}
}
func
newConn
(
ln
,
rn
*
peernet
,
l
*
link
)
*
conn
{
c
:=
&
conn
{
net
:
ln
,
link
:
l
}
c
.
local
=
ln
.
peer
c
.
remote
=
rn
.
peer
c
.
localAddr
=
ln
.
ps
.
Addrs
(
ln
.
peer
)[
0
]
c
.
remoteAddr
=
rn
.
ps
.
Addrs
(
rn
.
peer
)[
0
]
c
.
localPrivKey
=
ln
.
ps
.
PrivKey
(
ln
.
peer
)
c
.
remotePubKey
=
rn
.
ps
.
PubKey
(
rn
.
peer
)
c
.
proc
=
process
.
WithTeardown
(
c
.
teardown
)
return
c
}
func
(
c
*
conn
)
Close
()
error
{
func
(
c
*
conn
)
Close
()
error
{
return
c
.
proc
.
Close
()
}
func
(
c
*
conn
)
teardown
()
error
{
for
_
,
s
:=
range
c
.
allStreams
()
{
for
_
,
s
:=
range
c
.
allStreams
()
{
s
.
Close
()
s
.
Close
()
}
}
...
...
p2p/net/mock/mock_link.go
View file @
51fd99e3
...
@@ -33,22 +33,8 @@ func (l *link) newConnPair(dialer *peernet) (*conn, *conn) {
...
@@ -33,22 +33,8 @@ func (l *link) newConnPair(dialer *peernet) (*conn, *conn) {
l
.
RLock
()
l
.
RLock
()
defer
l
.
RUnlock
()
defer
l
.
RUnlock
()
mkconn
:=
func
(
ln
,
rn
*
peernet
)
*
conn
{
c1
:=
newConn
(
l
.
nets
[
0
],
l
.
nets
[
1
],
l
)
c
:=
&
conn
{
net
:
ln
,
link
:
l
}
c2
:=
newConn
(
l
.
nets
[
1
],
l
.
nets
[
0
],
l
)
c
.
local
=
ln
.
peer
c
.
remote
=
rn
.
peer
c
.
localAddr
=
ln
.
ps
.
Addrs
(
ln
.
peer
)[
0
]
c
.
remoteAddr
=
rn
.
ps
.
Addrs
(
rn
.
peer
)[
0
]
c
.
localPrivKey
=
ln
.
ps
.
PrivKey
(
ln
.
peer
)
c
.
remotePubKey
=
rn
.
ps
.
PubKey
(
rn
.
peer
)
return
c
}
c1
:=
mkconn
(
l
.
nets
[
0
],
l
.
nets
[
1
])
c2
:=
mkconn
(
l
.
nets
[
1
],
l
.
nets
[
0
])
c1
.
rconn
=
c2
c1
.
rconn
=
c2
c2
.
rconn
=
c1
c2
.
rconn
=
c1
...
...
p2p/net/mock/mock_net.go
View file @
51fd99e3
...
@@ -5,18 +5,18 @@ import (
...
@@ -5,18 +5,18 @@ import (
"sort"
"sort"
"sync"
"sync"
testutil
"github.com/ipfs/go-ipfs/util/testutil"
ic
"github.com/ipfs/go-libp2p/p2p/crypto"
ic
"github.com/ipfs/go-libp2p/p2p/crypto"
host
"github.com/ipfs/go-libp2p/p2p/host"
host
"github.com/ipfs/go-libp2p/p2p/host"
bhost
"github.com/ipfs/go-libp2p/p2p/host/basic"
bhost
"github.com/ipfs/go-libp2p/p2p/host/basic"
inet
"github.com/ipfs/go-libp2p/p2p/net"
inet
"github.com/ipfs/go-libp2p/p2p/net"
peer
"github.com/ipfs/go-libp2p/p2p/peer"
peer
"github.com/ipfs/go-libp2p/p2p/peer"
p2putil
"github.com/ipfs/go-libp2p/p2p/test/util"
p2putil
"github.com/ipfs/go-libp2p/p2p/test/util"
testutil
"util/testutil"
ma
"github.com/
ipfs/go-ipfs/Godeps/_workspace/src/github.com/
jbenet/go-multiaddr"
ma
"github.com/jbenet/go-multiaddr"
"github.com/
ipfs/go-ipfs/Godeps/_workspace/src/github.com/
jbenet/goprocess"
"github.com/jbenet/goprocess"
goprocessctx
"github.com/
ipfs/go-ipfs/Godeps/_workspace/src/github.com/
jbenet/goprocess/context"
goprocessctx
"github.com/jbenet/goprocess/context"
context
"
github.com/ipfs/go-ipfs/Godeps/_workspace/src/
golang.org/x/net/context"
context
"golang.org/x/net/context"
)
)
// mocknet implements mocknet.Mocknet
// mocknet implements mocknet.Mocknet
...
@@ -34,7 +34,7 @@ type mocknet struct {
...
@@ -34,7 +34,7 @@ type mocknet struct {
proc
goprocess
.
Process
// for Context closing
proc
goprocess
.
Process
// for Context closing
ctx
context
.
Context
ctx
context
.
Context
sync
.
RW
Mutex
sync
.
Mutex
}
}
func
New
(
ctx
context
.
Context
)
Mocknet
{
func
New
(
ctx
context
.
Context
)
Mocknet
{
...
@@ -95,8 +95,8 @@ func (mn *mocknet) AddPeerWithPeerstore(p peer.ID, ps peer.Peerstore) (host.Host
...
@@ -95,8 +95,8 @@ func (mn *mocknet) AddPeerWithPeerstore(p peer.ID, ps peer.Peerstore) (host.Host
}
}
func
(
mn
*
mocknet
)
Peers
()
[]
peer
.
ID
{
func
(
mn
*
mocknet
)
Peers
()
[]
peer
.
ID
{
mn
.
R
Lock
()
mn
.
Lock
()
defer
mn
.
R
Unlock
()
defer
mn
.
Unlock
()
cp
:=
make
([]
peer
.
ID
,
0
,
len
(
mn
.
nets
))
cp
:=
make
([]
peer
.
ID
,
0
,
len
(
mn
.
nets
))
for
_
,
n
:=
range
mn
.
nets
{
for
_
,
n
:=
range
mn
.
nets
{
...
@@ -107,22 +107,22 @@ func (mn *mocknet) Peers() []peer.ID {
...
@@ -107,22 +107,22 @@ func (mn *mocknet) Peers() []peer.ID {
}
}
func
(
mn
*
mocknet
)
Host
(
pid
peer
.
ID
)
host
.
Host
{
func
(
mn
*
mocknet
)
Host
(
pid
peer
.
ID
)
host
.
Host
{
mn
.
R
Lock
()
mn
.
Lock
()
host
:=
mn
.
hosts
[
pid
]
host
:=
mn
.
hosts
[
pid
]
mn
.
R
Unlock
()
mn
.
Unlock
()
return
host
return
host
}
}
func
(
mn
*
mocknet
)
Net
(
pid
peer
.
ID
)
inet
.
Network
{
func
(
mn
*
mocknet
)
Net
(
pid
peer
.
ID
)
inet
.
Network
{
mn
.
R
Lock
()
mn
.
Lock
()
n
:=
mn
.
nets
[
pid
]
n
:=
mn
.
nets
[
pid
]
mn
.
R
Unlock
()
mn
.
Unlock
()
return
n
return
n
}
}
func
(
mn
*
mocknet
)
Hosts
()
[]
host
.
Host
{
func
(
mn
*
mocknet
)
Hosts
()
[]
host
.
Host
{
mn
.
R
Lock
()
mn
.
Lock
()
defer
mn
.
R
Unlock
()
defer
mn
.
Unlock
()
cp
:=
make
([]
host
.
Host
,
0
,
len
(
mn
.
hosts
))
cp
:=
make
([]
host
.
Host
,
0
,
len
(
mn
.
hosts
))
for
_
,
h
:=
range
mn
.
hosts
{
for
_
,
h
:=
range
mn
.
hosts
{
...
@@ -134,8 +134,8 @@ func (mn *mocknet) Hosts() []host.Host {
...
@@ -134,8 +134,8 @@ func (mn *mocknet) Hosts() []host.Host {
}
}
func
(
mn
*
mocknet
)
Nets
()
[]
inet
.
Network
{
func
(
mn
*
mocknet
)
Nets
()
[]
inet
.
Network
{
mn
.
R
Lock
()
mn
.
Lock
()
defer
mn
.
R
Unlock
()
defer
mn
.
Unlock
()
cp
:=
make
([]
inet
.
Network
,
0
,
len
(
mn
.
nets
))
cp
:=
make
([]
inet
.
Network
,
0
,
len
(
mn
.
nets
))
for
_
,
n
:=
range
mn
.
nets
{
for
_
,
n
:=
range
mn
.
nets
{
...
@@ -148,8 +148,8 @@ func (mn *mocknet) Nets() []inet.Network {
...
@@ -148,8 +148,8 @@ func (mn *mocknet) Nets() []inet.Network {
// Links returns a copy of the internal link state map.
// Links returns a copy of the internal link state map.
// (wow, much map. so data structure. how compose. ahhh pointer)
// (wow, much map. so data structure. how compose. ahhh pointer)
func
(
mn
*
mocknet
)
Links
()
LinkMap
{
func
(
mn
*
mocknet
)
Links
()
LinkMap
{
mn
.
R
Lock
()
mn
.
Lock
()
defer
mn
.
R
Unlock
()
defer
mn
.
Unlock
()
links
:=
map
[
string
]
map
[
string
]
map
[
Link
]
struct
{}{}
links
:=
map
[
string
]
map
[
string
]
map
[
Link
]
struct
{}{}
for
p1
,
lm
:=
range
mn
.
links
{
for
p1
,
lm
:=
range
mn
.
links
{
...
@@ -179,10 +179,10 @@ func (mn *mocknet) LinkAll() error {
...
@@ -179,10 +179,10 @@ func (mn *mocknet) LinkAll() error {
}
}
func
(
mn
*
mocknet
)
LinkPeers
(
p1
,
p2
peer
.
ID
)
(
Link
,
error
)
{
func
(
mn
*
mocknet
)
LinkPeers
(
p1
,
p2
peer
.
ID
)
(
Link
,
error
)
{
mn
.
R
Lock
()
mn
.
Lock
()
n1
:=
mn
.
nets
[
p1
]
n1
:=
mn
.
nets
[
p1
]
n2
:=
mn
.
nets
[
p2
]
n2
:=
mn
.
nets
[
p2
]
mn
.
R
Unlock
()
mn
.
Unlock
()
if
n1
==
nil
{
if
n1
==
nil
{
return
nil
,
fmt
.
Errorf
(
"network for p1 not in mocknet"
)
return
nil
,
fmt
.
Errorf
(
"network for p1 not in mocknet"
)
...
@@ -211,11 +211,11 @@ func (mn *mocknet) validate(n inet.Network) (*peernet, error) {
...
@@ -211,11 +211,11 @@ func (mn *mocknet) validate(n inet.Network) (*peernet, error) {
}
}
func
(
mn
*
mocknet
)
LinkNets
(
n1
,
n2
inet
.
Network
)
(
Link
,
error
)
{
func
(
mn
*
mocknet
)
LinkNets
(
n1
,
n2
inet
.
Network
)
(
Link
,
error
)
{
mn
.
R
Lock
()
mn
.
Lock
()
n1r
,
err1
:=
mn
.
validate
(
n1
)
n1r
,
err1
:=
mn
.
validate
(
n1
)
n2r
,
err2
:=
mn
.
validate
(
n2
)
n2r
,
err2
:=
mn
.
validate
(
n2
)
ld
:=
mn
.
linkDefaults
ld
:=
mn
.
linkDefaults
mn
.
R
Unlock
()
mn
.
Unlock
()
if
err1
!=
nil
{
if
err1
!=
nil
{
return
nil
,
err1
return
nil
,
err1
...
@@ -260,7 +260,7 @@ func (mn *mocknet) UnlinkNets(n1, n2 inet.Network) error {
...
@@ -260,7 +260,7 @@ func (mn *mocknet) UnlinkNets(n1, n2 inet.Network) error {
}
}
// get from the links map. and lazily contruct.
// get from the links map. and lazily contruct.
func
(
mn
*
mocknet
)
linksMapGet
(
p1
,
p2
peer
.
ID
)
*
map
[
*
link
]
struct
{}
{
func
(
mn
*
mocknet
)
linksMapGet
(
p1
,
p2
peer
.
ID
)
map
[
*
link
]
struct
{}
{
l1
,
found
:=
mn
.
links
[
p1
]
l1
,
found
:=
mn
.
links
[
p1
]
if
!
found
{
if
!
found
{
...
@@ -275,7 +275,7 @@ func (mn *mocknet) linksMapGet(p1, p2 peer.ID) *map[*link]struct{} {
...
@@ -275,7 +275,7 @@ func (mn *mocknet) linksMapGet(p1, p2 peer.ID) *map[*link]struct{} {
l2
=
l1
[
p2
]
l2
=
l1
[
p2
]
}
}
return
&
l2
return
l2
}
}
func
(
mn
*
mocknet
)
addLink
(
l
*
link
)
{
func
(
mn
*
mocknet
)
addLink
(
l
*
link
)
{
...
@@ -283,8 +283,8 @@ func (mn *mocknet) addLink(l *link) {
...
@@ -283,8 +283,8 @@ func (mn *mocknet) addLink(l *link) {
defer
mn
.
Unlock
()
defer
mn
.
Unlock
()
n1
,
n2
:=
l
.
nets
[
0
],
l
.
nets
[
1
]
n1
,
n2
:=
l
.
nets
[
0
],
l
.
nets
[
1
]
(
*
mn
.
linksMapGet
(
n1
.
peer
,
n2
.
peer
)
)
[
l
]
=
struct
{}{}
mn
.
linksMapGet
(
n1
.
peer
,
n2
.
peer
)[
l
]
=
struct
{}{}
(
*
mn
.
linksMapGet
(
n2
.
peer
,
n1
.
peer
)
)
[
l
]
=
struct
{}{}
mn
.
linksMapGet
(
n2
.
peer
,
n1
.
peer
)[
l
]
=
struct
{}{}
}
}
func
(
mn
*
mocknet
)
removeLink
(
l
*
link
)
{
func
(
mn
*
mocknet
)
removeLink
(
l
*
link
)
{
...
@@ -292,8 +292,8 @@ func (mn *mocknet) removeLink(l *link) {
...
@@ -292,8 +292,8 @@ func (mn *mocknet) removeLink(l *link) {
defer
mn
.
Unlock
()
defer
mn
.
Unlock
()
n1
,
n2
:=
l
.
nets
[
0
],
l
.
nets
[
1
]
n1
,
n2
:=
l
.
nets
[
0
],
l
.
nets
[
1
]
delete
(
*
mn
.
linksMapGet
(
n1
.
peer
,
n2
.
peer
),
l
)
delete
(
mn
.
linksMapGet
(
n1
.
peer
,
n2
.
peer
),
l
)
delete
(
*
mn
.
linksMapGet
(
n2
.
peer
,
n1
.
peer
),
l
)
delete
(
mn
.
linksMapGet
(
n2
.
peer
,
n1
.
peer
),
l
)
}
}
func
(
mn
*
mocknet
)
ConnectAllButSelf
()
error
{
func
(
mn
*
mocknet
)
ConnectAllButSelf
()
error
{
...
@@ -329,10 +329,10 @@ func (mn *mocknet) DisconnectNets(n1, n2 inet.Network) error {
...
@@ -329,10 +329,10 @@ func (mn *mocknet) DisconnectNets(n1, n2 inet.Network) error {
}
}
func
(
mn
*
mocknet
)
LinksBetweenPeers
(
p1
,
p2
peer
.
ID
)
[]
Link
{
func
(
mn
*
mocknet
)
LinksBetweenPeers
(
p1
,
p2
peer
.
ID
)
[]
Link
{
mn
.
R
Lock
()
mn
.
Lock
()
defer
mn
.
R
Unlock
()
defer
mn
.
Unlock
()
ls2
:=
*
mn
.
linksMapGet
(
p1
,
p2
)
ls2
:=
mn
.
linksMapGet
(
p1
,
p2
)
cp
:=
make
([]
Link
,
0
,
len
(
ls2
))
cp
:=
make
([]
Link
,
0
,
len
(
ls2
))
for
l
:=
range
ls2
{
for
l
:=
range
ls2
{
cp
=
append
(
cp
,
l
)
cp
=
append
(
cp
,
l
)
...
@@ -351,8 +351,8 @@ func (mn *mocknet) SetLinkDefaults(o LinkOptions) {
...
@@ -351,8 +351,8 @@ func (mn *mocknet) SetLinkDefaults(o LinkOptions) {
}
}
func
(
mn
*
mocknet
)
LinkDefaults
()
LinkOptions
{
func
(
mn
*
mocknet
)
LinkDefaults
()
LinkOptions
{
mn
.
R
Lock
()
mn
.
Lock
()
defer
mn
.
R
Unlock
()
defer
mn
.
Unlock
()
return
mn
.
linkDefaults
return
mn
.
linkDefaults
}
}
...
...
p2p/net/mock/mock_notif_test.go
View file @
51fd99e3
...
@@ -4,8 +4,8 @@ import (
...
@@ -4,8 +4,8 @@ import (
"testing"
"testing"
"time"
"time"
ma
"github.com/
ipfs/go-ipfs/Godeps/_workspace/src/github.com/
jbenet/go-multiaddr"
ma
"github.com/jbenet/go-multiaddr"
context
"
github.com/ipfs/go-ipfs/Godeps/_workspace/src/
golang.org/x/net/context"
context
"golang.org/x/net/context"
inet
"github.com/ipfs/go-libp2p/p2p/net"
inet
"github.com/ipfs/go-libp2p/p2p/net"
peer
"github.com/ipfs/go-libp2p/p2p/peer"
peer
"github.com/ipfs/go-libp2p/p2p/peer"
)
)
...
...
p2p/net/mock/mock_peernet.go
View file @
51fd99e3
...
@@ -8,10 +8,10 @@ import (
...
@@ -8,10 +8,10 @@ import (
inet
"github.com/ipfs/go-libp2p/p2p/net"
inet
"github.com/ipfs/go-libp2p/p2p/net"
peer
"github.com/ipfs/go-libp2p/p2p/peer"
peer
"github.com/ipfs/go-libp2p/p2p/peer"
ma
"github.com/
ipfs/go-ipfs/Godeps/_workspace/src/github.com/
jbenet/go-multiaddr"
ma
"github.com/jbenet/go-multiaddr"
"github.com/
ipfs/go-ipfs/Godeps/_workspace/src/github.com/
jbenet/goprocess"
"github.com/jbenet/goprocess"
goprocessctx
"github.com/
ipfs/go-ipfs/Godeps/_workspace/src/github.com/
jbenet/goprocess/context"
goprocessctx
"github.com/jbenet/goprocess/context"
context
"
github.com/ipfs/go-ipfs/Godeps/_workspace/src/
golang.org/x/net/context"
context
"golang.org/x/net/context"
)
)
// peernet implements inet.Network
// peernet implements inet.Network
...
...
p2p/net/mock/mock_stream.go
View file @
51fd99e3
...
@@ -5,7 +5,7 @@ import (
...
@@ -5,7 +5,7 @@ import (
"io"
"io"
"time"
"time"
process
"github.com/
ipfs/go-ipfs/Godeps/_workspace/src/github.com/
jbenet/goprocess"
process
"github.com/jbenet/goprocess"
inet
"github.com/ipfs/go-libp2p/p2p/net"
inet
"github.com/ipfs/go-libp2p/p2p/net"
)
)
...
...
p2p/net/mock/mock_test.go
View file @
51fd99e3
...
@@ -9,13 +9,13 @@ import (
...
@@ -9,13 +9,13 @@ import (
"testing"
"testing"
"time"
"time"
testutil
"github.com/ipfs/go-ipfs/util/testutil"
inet
"github.com/ipfs/go-libp2p/p2p/net"
inet
"github.com/ipfs/go-libp2p/p2p/net"
peer
"github.com/ipfs/go-libp2p/p2p/peer"
peer
"github.com/ipfs/go-libp2p/p2p/peer"
protocol
"github.com/ipfs/go-libp2p/p2p/protocol"
protocol
"github.com/ipfs/go-libp2p/p2p/protocol"
testutil
"util/testutil"
detectrace
"github.com/
ipfs/go-ipfs/Godeps/_workspace/src/github.com/
jbenet/go-detect-race"
detectrace
"github.com/jbenet/go-detect-race"
context
"
github.com/ipfs/go-ipfs/Godeps/_workspace/src/
golang.org/x/net/context"
context
"golang.org/x/net/context"
)
)
func
randPeer
(
t
*
testing
.
T
)
peer
.
ID
{
func
randPeer
(
t
*
testing
.
T
)
peer
.
ID
{
...
...
Prev
1
2
3
4
5
6
7
Next
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