aboutsummaryrefslogtreecommitdiffstats
path: root/p2p
diff options
context:
space:
mode:
Diffstat (limited to 'p2p')
-rw-r--r--p2p/discover/database.go5
-rw-r--r--p2p/discover/table.go2
-rw-r--r--p2p/discover/udp.go46
-rw-r--r--p2p/discover/udp_test.go25
-rw-r--r--p2p/nat/nat.go45
-rw-r--r--p2p/nat/nat_test.go48
-rw-r--r--p2p/nat/natupnp_test.go223
-rw-r--r--p2p/peer.go5
-rw-r--r--p2p/peer_test.go24
-rw-r--r--p2p/server.go4
-rw-r--r--p2p/server_test.go15
-rw-r--r--p2p/testlog_test.go25
12 files changed, 360 insertions, 107 deletions
diff --git a/p2p/discover/database.go b/p2p/discover/database.go
index dc0b97ddf..2b9da0423 100644
--- a/p2p/discover/database.go
+++ b/p2p/discover/database.go
@@ -17,6 +17,7 @@ import (
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/errors"
"github.com/syndtr/goleveldb/leveldb/iterator"
+ "github.com/syndtr/goleveldb/leveldb/opt"
"github.com/syndtr/goleveldb/leveldb/storage"
"github.com/syndtr/goleveldb/leveldb/util"
)
@@ -72,8 +73,8 @@ func newMemoryNodeDB() (*nodeDB, error) {
// newPersistentNodeDB creates/opens a leveldb backed persistent node database,
// also flushing its contents in case of a version mismatch.
func newPersistentNodeDB(path string, version int) (*nodeDB, error) {
- // Try to open the cache, recovering any corruption
- db, err := leveldb.OpenFile(path, nil)
+ opts := &opt.Options{OpenFilesCacheCapacity: 5}
+ db, err := leveldb.OpenFile(path, opts)
if _, iscorrupted := err.(*errors.ErrCorrupted); iscorrupted {
db, err = leveldb.RecoverFile(path, nil)
}
diff --git a/p2p/discover/table.go b/p2p/discover/table.go
index 2c9cb80d5..5e6dd8d0d 100644
--- a/p2p/discover/table.go
+++ b/p2p/discover/table.go
@@ -25,7 +25,7 @@ const (
hashBits = len(common.Hash{}) * 8
nBuckets = hashBits + 1 // Number of buckets
- maxBondingPingPongs = 10
+ maxBondingPingPongs = 16
)
type Table struct {
diff --git a/p2p/discover/udp.go b/p2p/discover/udp.go
index 1213c12c8..539ccd460 100644
--- a/p2p/discover/udp.go
+++ b/p2p/discover/udp.go
@@ -363,7 +363,31 @@ const (
headSize = macSize + sigSize // space of packet frame data
)
-var headSpace = make([]byte, headSize)
+var (
+ headSpace = make([]byte, headSize)
+
+ // Neighbors responses are sent across multiple packets to
+ // stay below the 1280 byte limit. We compute the maximum number
+ // of entries by stuffing a packet until it grows too large.
+ maxNeighbors int
+)
+
+func init() {
+ p := neighbors{Expiration: ^uint64(0)}
+ maxSizeNode := rpcNode{IP: make(net.IP, 16), UDP: ^uint16(0), TCP: ^uint16(0)}
+ for n := 0; ; n++ {
+ p.Nodes = append(p.Nodes, maxSizeNode)
+ size, _, err := rlp.EncodeToReader(p)
+ if err != nil {
+ // If this ever happens, it will be caught by the unit tests.
+ panic("cannot encode: " + err.Error())
+ }
+ if headSize+size+1 >= 1280 {
+ maxNeighbors = n
+ break
+ }
+ }
+}
func (t *udp) send(toaddr *net.UDPAddr, ptype byte, req interface{}) error {
packet, err := encodePacket(t.priv, ptype, req)
@@ -402,7 +426,10 @@ func encodePacket(priv *ecdsa.PrivateKey, ptype byte, req interface{}) ([]byte,
// readLoop runs in its own goroutine. it handles incoming UDP packets.
func (t *udp) readLoop() {
defer t.conn.Close()
- buf := make([]byte, 4096) // TODO: good buffer size
+ // Discovery packets are defined to be no larger than 1280 bytes.
+ // Packets larger than this size will be cut at the end and treated
+ // as invalid because their hash won't match.
+ buf := make([]byte, 1280)
for {
nbytes, from, err := t.conn.ReadFromUDP(buf)
if err != nil {
@@ -504,15 +531,16 @@ func (req *findnode) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte
closest := t.closest(target, bucketSize).entries
t.mutex.Unlock()
- // TODO: this conversion could use a cached version of the slice
- closestrpc := make([]rpcNode, len(closest))
+ p := neighbors{Expiration: uint64(time.Now().Add(expiration).Unix())}
+ // Send neighbors in chunks with at most maxNeighbors per packet
+ // to stay below the 1280 byte limit.
for i, n := range closest {
- closestrpc[i] = nodeToRPC(n)
+ p.Nodes = append(p.Nodes, nodeToRPC(n))
+ if len(p.Nodes) == maxNeighbors || i == len(closest)-1 {
+ t.send(from, neighborsPacket, p)
+ p.Nodes = p.Nodes[:0]
+ }
}
- t.send(from, neighborsPacket, neighbors{
- Nodes: closestrpc,
- Expiration: uint64(time.Now().Add(expiration).Unix()),
- })
return nil
}
diff --git a/p2p/discover/udp_test.go b/p2p/discover/udp_test.go
index f175835a8..11fa31d7c 100644
--- a/p2p/discover/udp_test.go
+++ b/p2p/discover/udp_test.go
@@ -163,17 +163,22 @@ func TestUDP_findnode(t *testing.T) {
))
// check that closest neighbors are returned.
test.packetIn(nil, findnodePacket, &findnode{Target: testTarget, Expiration: futureExp})
- test.waitPacketOut(func(p *neighbors) {
- expected := test.table.closest(targetHash, bucketSize)
- if len(p.Nodes) != bucketSize {
- t.Errorf("wrong number of results: got %d, want %d", len(p.Nodes), bucketSize)
- }
- for i := range p.Nodes {
- if p.Nodes[i].ID != expected.entries[i].ID {
- t.Errorf("result mismatch at %d:\n got: %v\n want: %v", i, p.Nodes[i], expected.entries[i])
+ expected := test.table.closest(targetHash, bucketSize)
+
+ waitNeighbors := func(want []*Node) {
+ test.waitPacketOut(func(p *neighbors) {
+ if len(p.Nodes) != len(want) {
+ t.Errorf("wrong number of results: got %d, want %d", len(p.Nodes), bucketSize)
}
- }
- })
+ for i := range p.Nodes {
+ if p.Nodes[i].ID != want[i].ID {
+ t.Errorf("result mismatch at %d:\n got: %v\n want: %v", i, p.Nodes[i], expected.entries[i])
+ }
+ }
+ })
+ }
+ waitNeighbors(expected.entries[:maxNeighbors])
+ waitNeighbors(expected.entries[maxNeighbors:])
}
func TestUDP_findnodeMultiReply(t *testing.T) {
diff --git a/p2p/nat/nat.go b/p2p/nat/nat.go
index fe00bdab0..9acb34398 100644
--- a/p2p/nat/nat.go
+++ b/p2p/nat/nat.go
@@ -86,13 +86,13 @@ func Map(m Interface, c chan struct{}, protocol string, extport, intport int, na
refresh := time.NewTimer(mapUpdateInterval)
defer func() {
refresh.Stop()
- glog.V(logger.Debug).Infof("Deleting port mapping: %s %d -> %d (%s) using %s\n", protocol, extport, intport, name, m)
+ glog.V(logger.Debug).Infof("deleting port mapping: %s %d -> %d (%s) using %s\n", protocol, extport, intport, name, m)
m.DeleteMapping(protocol, extport, intport)
}()
- glog.V(logger.Debug).Infof("add mapping: %s %d -> %d (%s) using %s\n", protocol, extport, intport, name, m)
if err := m.AddMapping(protocol, intport, extport, name, mapTimeout); err != nil {
- glog.V(logger.Warn).Infof("network port %d could not be mapped: %v\n", intport, err)
- glog.V(logger.Debug).Infof("mapping with %v returned %v\n", m, err)
+ glog.V(logger.Debug).Infof("network port %s:%d could not be mapped: %v\n", protocol, intport, err)
+ } else {
+ glog.V(logger.Info).Infof("mapped network port %s:%d -> %d (%s) using %s\n", protocol, extport, intport, name, m)
}
for {
select {
@@ -101,10 +101,9 @@ func Map(m Interface, c chan struct{}, protocol string, extport, intport int, na
return
}
case <-refresh.C:
- glog.V(logger.Detail).Infof("refresh mapping: %s %d -> %d (%s) using %s\n", protocol, extport, intport, name, m)
+ glog.V(logger.Detail).Infof("refresh port mapping %s:%d -> %d (%s) using %s\n", protocol, extport, intport, name, m)
if err := m.AddMapping(protocol, intport, extport, name, mapTimeout); err != nil {
- glog.V(logger.Warn).Infof("network port %d could not be mapped: %v\n", intport, err)
- glog.V(logger.Debug).Infof("mapping with %v returned %v\n", m, err)
+ glog.V(logger.Debug).Infof("network port %s:%d could not be mapped: %v\n", protocol, intport, err)
}
refresh.Reset(mapUpdateInterval)
}
@@ -172,8 +171,9 @@ func PMP(gateway net.IP) Interface {
// This type is useful because discovery can take a while but we
// want return an Interface value from UPnP, PMP and Auto immediately.
type autodisc struct {
- what string
- done <-chan Interface
+ what string // type of interface being autodiscovered
+ once sync.Once
+ doit func() Interface
mu sync.Mutex
found Interface
@@ -181,9 +181,10 @@ type autodisc struct {
func startautodisc(what string, doit func() Interface) Interface {
// TODO: monitor network configuration and rerun doit when it changes.
- done := make(chan Interface)
- ad := &autodisc{what: what, done: done}
- go func() { done <- doit(); close(done) }()
+ ad := &autodisc{what: what, doit: doit}
+ // Start the auto discovery as early as possible so it is already
+ // in progress when the rest of the stack calls the methods.
+ go ad.wait()
return ad
}
@@ -218,19 +219,15 @@ func (n *autodisc) String() string {
}
}
+// wait blocks until auto-discovery has been performed.
func (n *autodisc) wait() error {
- n.mu.Lock()
- found := n.found
- n.mu.Unlock()
- if found != nil {
- // already discovered
- return nil
- }
- if found = <-n.done; found == nil {
- return errors.New("no UPnP or NAT-PMP router discovered")
+ n.once.Do(func() {
+ n.mu.Lock()
+ n.found = n.doit()
+ n.mu.Unlock()
+ })
+ if n.found == nil {
+ return fmt.Errorf("no %s router discovered", n.what)
}
- n.mu.Lock()
- n.found = found
- n.mu.Unlock()
return nil
}
diff --git a/p2p/nat/nat_test.go b/p2p/nat/nat_test.go
new file mode 100644
index 000000000..95c50522e
--- /dev/null
+++ b/p2p/nat/nat_test.go
@@ -0,0 +1,48 @@
+package nat
+
+import (
+ "bytes"
+ "net"
+ "testing"
+ "time"
+)
+
+// This test checks that autodisc doesn't hang and returns
+// consistent results when multiple goroutines call its methods
+// concurrently.
+func TestAutoDiscRace(t *testing.T) {
+ ad := startautodisc("thing", func() Interface {
+ time.Sleep(500 * time.Millisecond)
+ return extIP{33, 44, 55, 66}
+ })
+
+ // Spawn a few concurrent calls to ad.ExternalIP.
+ type rval struct {
+ ip net.IP
+ err error
+ }
+ results := make(chan rval, 50)
+ for i := 0; i < cap(results); i++ {
+ go func() {
+ ip, err := ad.ExternalIP()
+ results <- rval{ip, err}
+ }()
+ }
+
+ // Check that they all return the correct result within the deadline.
+ deadline := time.After(550 * time.Millisecond)
+ for i := 0; i < cap(results); i++ {
+ select {
+ case <-deadline:
+ t.Fatal("deadline exceeded")
+ case rval := <-results:
+ if rval.err != nil {
+ t.Errorf("result %d: unexpected error: %v", i, rval.err)
+ }
+ wantIP := net.IP{33, 44, 55, 66}
+ if !bytes.Equal(rval.ip, wantIP) {
+ t.Errorf("result %d: got IP %v, want %v", i, rval.ip, wantIP)
+ }
+ }
+ }
+}
diff --git a/p2p/nat/natupnp_test.go b/p2p/nat/natupnp_test.go
new file mode 100644
index 000000000..074e97c81
--- /dev/null
+++ b/p2p/nat/natupnp_test.go
@@ -0,0 +1,223 @@
+package nat
+
+import (
+ "fmt"
+ "io"
+ "net"
+ "net/http"
+ "strings"
+ "testing"
+
+ "github.com/huin/goupnp/httpu"
+)
+
+func TestUPNP_DDWRT(t *testing.T) {
+ dev := &fakeIGD{
+ t: t,
+ ssdpResp: "HTTP/1.1 200 OK\r\n" +
+ "Cache-Control: max-age=300\r\n" +
+ "Date: Sun, 10 May 2015 10:05:33 GMT\r\n" +
+ "Ext: \r\n" +
+ "Location: http://{{listenAddr}}/InternetGatewayDevice.xml\r\n" +
+ "Server: POSIX UPnP/1.0 DD-WRT Linux/V24\r\n" +
+ "ST: urn:schemas-upnp-org:device:WANConnectionDevice:1\r\n" +
+ "USN: uuid:CB2471CC-CF2E-9795-8D9C-E87B34C16800::urn:schemas-upnp-org:device:WANConnectionDevice:1\r\n" +
+ "\r\n",
+ httpResps: map[string]string{
+ "GET /InternetGatewayDevice.xml": `
+ <?xml version="1.0"?>
+ <root xmlns="urn:schemas-upnp-org:device-1-0">
+ <specVersion>
+ <major>1</major>
+ <minor>0</minor>
+ </specVersion>
+ <device>
+ <deviceType>urn:schemas-upnp-org:device:InternetGatewayDevice:1</deviceType>
+ <manufacturer>DD-WRT</manufacturer>
+ <manufacturerURL>http://www.dd-wrt.com</manufacturerURL>
+ <modelDescription>Gateway</modelDescription>
+ <friendlyName>Asus RT-N16:DD-WRT</friendlyName>
+ <modelName>Asus RT-N16</modelName>
+ <modelNumber>V24</modelNumber>
+ <serialNumber>0000001</serialNumber>
+ <modelURL>http://www.dd-wrt.com</modelURL>
+ <UDN>uuid:A13AB4C3-3A14-E386-DE6A-EFEA923A06FE</UDN>
+ <serviceList>
+ <service>
+ <serviceType>urn:schemas-upnp-org:service:Layer3Forwarding:1</serviceType>
+ <serviceId>urn:upnp-org:serviceId:L3Forwarding1</serviceId>
+ <SCPDURL>/x_layer3forwarding.xml</SCPDURL>
+ <controlURL>/control?Layer3Forwarding</controlURL>
+ <eventSubURL>/event?Layer3Forwarding</eventSubURL>
+ </service>
+ </serviceList>
+ <deviceList>
+ <device>
+ <deviceType>urn:schemas-upnp-org:device:WANDevice:1</deviceType>
+ <friendlyName>WANDevice</friendlyName>
+ <manufacturer>DD-WRT</manufacturer>
+ <manufacturerURL>http://www.dd-wrt.com</manufacturerURL>
+ <modelDescription>Gateway</modelDescription>
+ <modelName>router</modelName>
+ <modelURL>http://www.dd-wrt.com</modelURL>
+ <UDN>uuid:48FD569B-F9A9-96AE-4EE6-EB403D3DB91A</UDN>
+ <serviceList>
+ <service>
+ <serviceType>urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1</serviceType>
+ <serviceId>urn:upnp-org:serviceId:WANCommonIFC1</serviceId>
+ <SCPDURL>/x_wancommoninterfaceconfig.xml</SCPDURL>
+ <controlURL>/control?WANCommonInterfaceConfig</controlURL>
+ <eventSubURL>/event?WANCommonInterfaceConfig</eventSubURL>
+ </service>
+ </serviceList>
+ <deviceList>
+ <device>
+ <deviceType>urn:schemas-upnp-org:device:WANConnectionDevice:1</deviceType>
+ <friendlyName>WAN Connection Device</friendlyName>
+ <manufacturer>DD-WRT</manufacturer>
+ <manufacturerURL>http://www.dd-wrt.com</manufacturerURL>
+ <modelDescription>Gateway</modelDescription>
+ <modelName>router</modelName>
+ <modelURL>http://www.dd-wrt.com</modelURL>
+ <UDN>uuid:CB2471CC-CF2E-9795-8D9C-E87B34C16800</UDN>
+ <serviceList>
+ <service>
+ <serviceType>urn:schemas-upnp-org:service:WANIPConnection:1</serviceType>
+ <serviceId>urn:upnp-org:serviceId:WANIPConn1</serviceId>
+ <SCPDURL>/x_wanipconnection.xml</SCPDURL>
+ <controlURL>/control?WANIPConnection</controlURL>
+ <eventSubURL>/event?WANIPConnection</eventSubURL>
+ </service>
+ </serviceList>
+ </device>
+ </deviceList>
+ </device>
+ <device>
+ <deviceType>urn:schemas-upnp-org:device:LANDevice:1</deviceType>
+ <friendlyName>LANDevice</friendlyName>
+ <manufacturer>DD-WRT</manufacturer>
+ <manufacturerURL>http://www.dd-wrt.com</manufacturerURL>
+ <modelDescription>Gateway</modelDescription>
+ <modelName>router</modelName>
+ <modelURL>http://www.dd-wrt.com</modelURL>
+ <UDN>uuid:04021998-3B35-2BDB-7B3C-99DA4435DA09</UDN>
+ <serviceList>
+ <service>
+ <serviceType>urn:schemas-upnp-org:service:LANHostConfigManagement:1</serviceType>
+ <serviceId>urn:upnp-org:serviceId:LANHostCfg1</serviceId>
+ <SCPDURL>/x_lanhostconfigmanagement.xml</SCPDURL>
+ <controlURL>/control?LANHostConfigManagement</controlURL>
+ <eventSubURL>/event?LANHostConfigManagement</eventSubURL>
+ </service>
+ </serviceList>
+ </device>
+ </deviceList>
+ <presentationURL>http://{{listenAddr}}</presentationURL>
+ </device>
+ </root>
+ `,
+ // The response to our GetNATRSIPStatus call. This
+ // particular implementation has a bug where the elements
+ // inside u:GetNATRSIPStatusResponse are not properly
+ // namespaced.
+ "POST /control?WANIPConnection": `
+ <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
+ <s:Body>
+ <u:GetNATRSIPStatusResponse xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1">
+ <NewRSIPAvailable>0</NewRSIPAvailable>
+ <NewNATEnabled>1</NewNATEnabled>
+ </u:GetNATRSIPStatusResponse>
+ </s:Body>
+ </s:Envelope>
+ `,
+ },
+ }
+ if err := dev.listen(); err != nil {
+ t.Skipf("cannot listen: %v", err)
+ }
+ dev.serve()
+ defer dev.close()
+
+ // Attempt to discover the fake device.
+ discovered := discoverUPnP()
+ if discovered == nil {
+ t.Fatalf("not discovered")
+ }
+ upnp, _ := discovered.(*upnp)
+ if upnp.service != "IGDv1-IP1" {
+ t.Errorf("upnp.service mismatch: got %q, want %q", upnp.service, "IGDv1-IP1")
+ }
+ wantURL := "http://" + dev.listener.Addr().String() + "/InternetGatewayDevice.xml"
+ if upnp.dev.URLBaseStr != wantURL {
+ t.Errorf("upnp.dev.URLBaseStr mismatch: got %q, want %q", upnp.dev.URLBaseStr, wantURL)
+ }
+}
+
+// fakeIGD presents itself as a discoverable UPnP device which sends
+// canned responses to HTTPU and HTTP requests.
+type fakeIGD struct {
+ t *testing.T // for logging
+
+ listener net.Listener
+ mcastListener *net.UDPConn
+
+ // This should be a complete HTTP response (including headers).
+ // It is sent as the response to any sspd packet. Any occurrence
+ // of "{{listenAddr}}" is replaced with the actual TCP listen
+ // address of the HTTP server.
+ ssdpResp string
+ // This one should contain XML payloads for all requests
+ // performed. The keys contain method and path, e.g. "GET /foo/bar".
+ // As with ssdpResp, "{{listenAddr}}" is replaced with the TCP
+ // listen address.
+ httpResps map[string]string
+}
+
+// httpu.Handler
+func (dev *fakeIGD) ServeMessage(r *http.Request) {
+ dev.t.Logf(`HTTPU request %s %s`, r.Method, r.RequestURI)
+ conn, err := net.Dial("udp4", r.RemoteAddr)
+ if err != nil {
+ fmt.Printf("reply Dial error: %v", err)
+ return
+ }
+ defer conn.Close()
+ io.WriteString(conn, dev.replaceListenAddr(dev.ssdpResp))
+}
+
+// http.Handler
+func (dev *fakeIGD) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ if resp, ok := dev.httpResps[r.Method+" "+r.RequestURI]; ok {
+ dev.t.Logf(`HTTP request "%s %s" --> %d`, r.Method, r.RequestURI, 200)
+ io.WriteString(w, dev.replaceListenAddr(resp))
+ } else {
+ dev.t.Logf(`HTTP request "%s %s" --> %d`, r.Method, r.RequestURI, 404)
+ w.WriteHeader(http.StatusNotFound)
+ }
+}
+
+func (dev *fakeIGD) replaceListenAddr(resp string) string {
+ return strings.Replace(resp, "{{listenAddr}}", dev.listener.Addr().String(), -1)
+}
+
+func (dev *fakeIGD) listen() (err error) {
+ if dev.listener, err = net.Listen("tcp", "127.0.0.1:0"); err != nil {
+ return err
+ }
+ laddr := &net.UDPAddr{IP: net.ParseIP("239.255.255.250"), Port: 1900}
+ if dev.mcastListener, err = net.ListenMulticastUDP("udp", nil, laddr); err != nil {
+ dev.listener.Close()
+ return err
+ }
+ return nil
+}
+
+func (dev *fakeIGD) serve() {
+ go httpu.Serve(dev.mcastListener, dev)
+ go http.Serve(dev.listener, dev)
+}
+
+func (dev *fakeIGD) close() {
+ dev.mcastListener.Close()
+ dev.listener.Close()
+}
diff --git a/p2p/peer.go b/p2p/peer.go
index ac691f2ce..c7ec08887 100644
--- a/p2p/peer.go
+++ b/p2p/peer.go
@@ -131,10 +131,11 @@ func (p *Peer) run() DiscReason {
case err := <-p.protoErr:
reason = discReasonForError(err)
case reason = <-p.disc:
+ p.politeDisconnect(reason)
+ reason = DiscRequested
}
close(p.closed)
- p.politeDisconnect(reason)
p.wg.Wait()
glog.V(logger.Debug).Infof("%v: Disconnected: %v\n", p, reason)
return reason
@@ -191,7 +192,7 @@ func (p *Peer) handle(msg Msg) error {
// check errors because, the connection will be closed after it.
rlp.Decode(msg.Payload, &reason)
glog.V(logger.Debug).Infof("%v: Disconnect Requested: %v\n", p, reason[0])
- return DiscRequested
+ return reason[0]
case msg.Code < baseProtocolLength:
// ignore other base protocol messages
return msg.Discard()
diff --git a/p2p/peer_test.go b/p2p/peer_test.go
index fb76818a0..59dcb7ba4 100644
--- a/p2p/peer_test.go
+++ b/p2p/peer_test.go
@@ -50,8 +50,6 @@ func testPeer(protos []Protocol) (func(), *conn, *Peer, <-chan DiscReason) {
}
func TestPeerProtoReadMsg(t *testing.T) {
- defer testlog(t).detach()
-
done := make(chan struct{})
proto := Protocol{
Name: "a",
@@ -88,8 +86,6 @@ func TestPeerProtoReadMsg(t *testing.T) {
}
func TestPeerProtoEncodeMsg(t *testing.T) {
- defer testlog(t).detach()
-
proto := Protocol{
Name: "a",
Length: 2,
@@ -112,8 +108,6 @@ func TestPeerProtoEncodeMsg(t *testing.T) {
}
func TestPeerWriteForBroadcast(t *testing.T) {
- defer testlog(t).detach()
-
closer, rw, peer, peerErr := testPeer([]Protocol{discard})
defer closer()
@@ -152,8 +146,6 @@ func TestPeerWriteForBroadcast(t *testing.T) {
}
func TestPeerPing(t *testing.T) {
- defer testlog(t).detach()
-
closer, rw, _, _ := testPeer(nil)
defer closer()
if err := SendItems(rw, pingMsg); err != nil {
@@ -165,26 +157,24 @@ func TestPeerPing(t *testing.T) {
}
func TestPeerDisconnect(t *testing.T) {
- defer testlog(t).detach()
-
closer, rw, _, disc := testPeer(nil)
defer closer()
if err := SendItems(rw, discMsg, DiscQuitting); err != nil {
t.Fatal(err)
}
- if err := ExpectMsg(rw, discMsg, []interface{}{DiscRequested}); err != nil {
- t.Error(err)
- }
- closer()
- if reason := <-disc; reason != DiscRequested {
- t.Errorf("run returned wrong reason: got %v, want %v", reason, DiscRequested)
+ select {
+ case reason := <-disc:
+ if reason != DiscQuitting {
+ t.Errorf("run returned wrong reason: got %v, want %v", reason, DiscRequested)
+ }
+ case <-time.After(500 * time.Millisecond):
+ t.Error("peer did not return")
}
}
// This test is supposed to verify that Peer can reliably handle
// multiple causes of disconnection occurring at the same time.
func TestPeerDisconnectRace(t *testing.T) {
- defer testlog(t).detach()
maybe := func() bool { return rand.Intn(1) == 1 }
for i := 0; i < 1000; i++ {
diff --git a/p2p/server.go b/p2p/server.go
index 3c6fb5893..8f768bdff 100644
--- a/p2p/server.go
+++ b/p2p/server.go
@@ -18,12 +18,12 @@ import (
)
const (
- defaultDialTimeout = 10 * time.Second
+ defaultDialTimeout = 15 * time.Second
refreshPeersInterval = 30 * time.Second
staticPeerCheckInterval = 15 * time.Second
// Maximum number of concurrently handshaking inbound connections.
- maxAcceptConns = 10
+ maxAcceptConns = 50
// Maximum number of concurrently dialing outbound connections.
maxDialingConns = 10
diff --git a/p2p/server_test.go b/p2p/server_test.go
index bf9df31ab..55fc81572 100644
--- a/p2p/server_test.go
+++ b/p2p/server_test.go
@@ -46,8 +46,6 @@ func startTestServer(t *testing.T, pf newPeerHook) *Server {
}
func TestServerListen(t *testing.T) {
- defer testlog(t).detach()
-
// start the test server
connected := make(chan *Peer)
srv := startTestServer(t, func(p *Peer) {
@@ -78,8 +76,6 @@ func TestServerListen(t *testing.T) {
}
func TestServerDial(t *testing.T) {
- defer testlog(t).detach()
-
// run a one-shot TCP server to handle the connection.
listener, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
@@ -126,8 +122,6 @@ func TestServerDial(t *testing.T) {
}
func TestServerBroadcast(t *testing.T) {
- defer testlog(t).detach()
-
var connected sync.WaitGroup
srv := startTestServer(t, func(p *Peer) {
p.running = matchProtocols([]Protocol{discard}, []Cap{discard.cap()}, p.rw)
@@ -172,8 +166,6 @@ func TestServerBroadcast(t *testing.T) {
//
// It also serves as a light-weight integration test.
func TestServerDisconnectAtCap(t *testing.T) {
- defer testlog(t).detach()
-
started := make(chan *Peer)
srv := &Server{
ListenAddr: "127.0.0.1:0",
@@ -224,8 +216,6 @@ func TestServerDisconnectAtCap(t *testing.T) {
// Tests that static peers are (re)connected, and done so even above max peers.
func TestServerStaticPeers(t *testing.T) {
- defer testlog(t).detach()
-
// Create a test server with limited connection slots
started := make(chan *Peer)
server := &Server{
@@ -312,7 +302,6 @@ func TestServerStaticPeers(t *testing.T) {
// Tests that trusted peers and can connect above max peer caps.
func TestServerTrustedPeers(t *testing.T) {
- defer testlog(t).detach()
// Create a trusted peer to accept connections from
key := newkey()
@@ -374,8 +363,6 @@ func TestServerTrustedPeers(t *testing.T) {
// Tests that a failed dial will temporarily throttle a peer.
func TestServerMaxPendingDials(t *testing.T) {
- defer testlog(t).detach()
-
// Start a simple test server
server := &Server{
ListenAddr: "127.0.0.1:0",
@@ -443,8 +430,6 @@ func TestServerMaxPendingDials(t *testing.T) {
}
func TestServerMaxPendingAccepts(t *testing.T) {
- defer testlog(t).detach()
-
// Start a test server and a peer sink for synchronization
started := make(chan *Peer)
server := &Server{
diff --git a/p2p/testlog_test.go b/p2p/testlog_test.go
deleted file mode 100644
index ac973bcf5..000000000
--- a/p2p/testlog_test.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package p2p
-
-import (
- "testing"
-
- "github.com/ethereum/go-ethereum/logger"
-)
-
-type testLogger struct{ t *testing.T }
-
-func testlog(t *testing.T) testLogger {
- logger.Reset()
- l := testLogger{t}
- logger.AddLogSystem(l)
- return l
-}
-
-func (l testLogger) LogPrint(msg logger.LogMsg) {
- l.t.Logf("%s", msg.String())
-}
-
-func (testLogger) detach() {
- logger.Flush()
- logger.Reset()
-}