Commit 51fd99e3 authored by Jeromy's avatar Jeromy
Browse files

extract from 0.4.0

parent 5a0162c7
...@@ -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
} }
......
...@@ -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.msgrw.Close() return c.maconn.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.msgrw.Read(buf) return c.maconn.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.
......
...@@ -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 := mc1.WriteMsg(m1); err != nil {
t.Fatal(err) t.Fatal(err)
} }
m2, err := c2.ReadMsg() m2, err := mc2.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 := mc1.WriteMsg(m1); err == nil {
t.Fatal("write should have failed", err) t.Fatal("write should have failed", err)
} }
_, err := c2.ReadMsg() _, err := mc2.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) mc1.WriteMsg(b1)
b2, err := c2.ReadMsg() b2, err := mc2.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) mc2.WriteMsg(b2)
b1, err = c1.ReadMsg() b1, err = mc1.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)
} }
} }
...@@ -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) {
......
...@@ -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("boop")) mc.WriteMsg([]byte("beep"))
mc.WriteMsg([]byte("boop"))
out, err := c.ReadMsg() out, err := mc.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 = mc.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.
......
...@@ -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
msgio.Reader io.Reader
msgio.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
......
...@@ -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) manet.Conn type ConnWrapper func(transport.Conn) transport.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 {
manet.Listener transport.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)
}
...@@ -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)
......
...@@ -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) mc1.WriteMsg(b1)
b2, err := c2.ReadMsg() b2, err := mc2.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) mc2.WriteMsg(b2)
b1, err = c1.ReadMsg() b1, err = mc1.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)
} }
} }
...@@ -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())
} }
...@@ -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.
......
...@@ -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 {
......
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")
......
...@@ -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()
} }
......
...@@ -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
......
...@@ -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.RWMutex 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.RLock() mn.Lock()
defer mn.RUnlock() 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.RLock() mn.Lock()
host := mn.hosts[pid] host := mn.hosts[pid]
mn.RUnlock() 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.RLock() mn.Lock()
n := mn.nets[pid] n := mn.nets[pid]
mn.RUnlock() mn.Unlock()
return n return n
} }
func (mn *mocknet) Hosts() []host.Host { func (mn *mocknet) Hosts() []host.Host {
mn.RLock() mn.Lock()
defer mn.RUnlock() 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.RLock() mn.Lock()
defer mn.RUnlock() 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.RLock() mn.Lock()
defer mn.RUnlock() 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.RLock() mn.Lock()
n1 := mn.nets[p1] n1 := mn.nets[p1]
n2 := mn.nets[p2] n2 := mn.nets[p2]
mn.RUnlock() 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.RLock() 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.RUnlock() 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.RLock() mn.Lock()
defer mn.RUnlock() 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.RLock() mn.Lock()
defer mn.RUnlock() defer mn.Unlock()
return mn.linkDefaults return mn.linkDefaults
} }
......
...@@ -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"
) )
......
...@@ -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
......
...@@ -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"
) )
......
...@@ -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 {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment