go.dedis.ch/onet/v4@v4.0.0-pre1/network/tcp_test.go (about)

     1  package network
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"fmt"
     7  	"net"
     8  	"strconv"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  	"go.dedis.ch/kyber/v4/util/key"
    15  	"go.dedis.ch/onet/v4/log"
    16  	"golang.org/x/xerrors"
    17  )
    18  
    19  func init() {
    20  	RegisterMessage(BigMsg{})
    21  	SimpleMessageType = RegisterMessage(SimpleMessage{})
    22  }
    23  
    24  type BigMsg struct {
    25  	Array []byte
    26  }
    27  
    28  type fakeConn struct {
    29  	// how many bytes does it write at maximum at each call
    30  	max int
    31  	// do we fail on the first write
    32  	fail1 bool
    33  	done1 bool
    34  	// do we fail on every successive write
    35  	failRest bool
    36  	// how many total bytes have we written
    37  	writtenBytes int
    38  	*net.TCPConn
    39  }
    40  
    41  type fakeAddr string
    42  
    43  func (f fakeAddr) Network() string {
    44  	return "network"
    45  }
    46  
    47  func (f fakeAddr) String() string {
    48  	return "network-string"
    49  }
    50  
    51  func (f *fakeConn) Read(b []byte) (n int, e error) {
    52  	return 0, nil
    53  }
    54  
    55  func (f *fakeConn) Write(b []byte) (n int, e error) {
    56  	if !f.done1 && f.fail1 {
    57  		return 0, ErrUnknown
    58  	} else if f.failRest {
    59  		return 0, ErrUnknown
    60  	}
    61  	if len(b) < f.max {
    62  		f.writtenBytes += len(b)
    63  		return len(b), nil
    64  	}
    65  	f.writtenBytes += f.max
    66  	return f.max, nil
    67  }
    68  
    69  func TestTCPsendRaw(t *testing.T) {
    70  	tests := []struct {
    71  		msg           []byte
    72  		conn          *fakeConn
    73  		errExpected   bool
    74  		bytesExpected int
    75  	}{
    76  		{ // fail at writing size
    77  			make([]byte, 100),
    78  			&fakeConn{100, true, false, false, 0, &net.TCPConn{}},
    79  			true,
    80  			0,
    81  		},
    82  		{ // fail at writing msg
    83  			make([]byte, 100),
    84  			&fakeConn{100, false, false, true, 0, &net.TCPConn{}},
    85  			true,
    86  			0,
    87  		},
    88  		{ // write undersize message
    89  			make([]byte, 99),
    90  			&fakeConn{100, false, false, false, 0, &net.TCPConn{}},
    91  			false,
    92  			99,
    93  		},
    94  		{ // write exact message
    95  			make([]byte, 100),
    96  			&fakeConn{100, false, false, false, 0, &net.TCPConn{}},
    97  			false,
    98  			100,
    99  		},
   100  		{ // write oversize message
   101  			make([]byte, 101),
   102  			&fakeConn{100, false, false, false, 0, &net.TCPConn{}},
   103  			false,
   104  			101,
   105  		},
   106  	}
   107  
   108  	for i, test := range tests {
   109  		tcp := &TCPConn{
   110  			conn: test.conn,
   111  		}
   112  		_, err := tcp.sendRaw(test.msg)
   113  		if test.errExpected {
   114  			if err == nil {
   115  				t.Error("Should have had an error here")
   116  			}
   117  			continue
   118  		}
   119  		// - 4 is for the size, uint32_t
   120  		if test.bytesExpected != test.conn.writtenBytes-4 {
   121  			t.Error(i, "Wrong number of bytes? ", test.bytesExpected, test.conn.writtenBytes)
   122  		}
   123  	}
   124  }
   125  
   126  // Test the receiving part of a message for tcp connections if the response is
   127  // buffered correctly.
   128  func TestTCPConnReceiveRaw(t *testing.T) {
   129  	addr := make(chan string)
   130  	done := make(chan bool)
   131  	check := make(chan bool)
   132  
   133  	checking := func() bool {
   134  		select {
   135  		case <-check:
   136  			return false
   137  		case <-time.After(20 * time.Millisecond):
   138  			return true
   139  		}
   140  	}
   141  	// prepare the msg
   142  	msg := &BigMsg{Array: make([]byte, 7893)}
   143  	buff, err := Marshal(msg)
   144  	require.Nil(t, err)
   145  
   146  	fn := func(c net.Conn) {
   147  		// different slices of bytes
   148  		maxChunk := 1400
   149  		slices := make([][]byte, 0)
   150  		currentChunk := 0
   151  		for currentChunk+maxChunk < len(buff) {
   152  			slices = append(slices, buff[currentChunk:currentChunk+maxChunk])
   153  			currentChunk += maxChunk
   154  		}
   155  		slices = append(slices, buff[currentChunk:])
   156  		// send the size first
   157  		binary.Write(c, globalOrder, Size(len(buff)))
   158  		// then send pieces and check if the other side already returned or not
   159  		for i, slice := range slices[:len(slices)-1] {
   160  			log.Lvlf1("Will write slice %d/%d...", i+1, len(slices))
   161  			if n, err := c.Write(slice); err != nil || n != len(slice) {
   162  				t.Fatal("Could not write enough")
   163  			}
   164  			log.Lvl1(" OK")
   165  			if !checking() {
   166  				t.Fatal("Already returned even if not finished")
   167  			}
   168  			time.Sleep(5 * time.Millisecond)
   169  		}
   170  		// the last one should make the other end return
   171  		log.Lvl1("Will write last piece...")
   172  		if n, err := c.Write(slices[len(slices)-1]); n != len(slices[len(slices)-1]) || err != nil {
   173  			t.Fatal("could not send the last piece")
   174  		}
   175  		log.Lvl1(" OK")
   176  		check <- true
   177  	}
   178  
   179  	fnBad := func(c net.Conn) {
   180  		// send the size first
   181  		binary.Write(c, globalOrder, Size(MaxPacketSize+1))
   182  	}
   183  
   184  	listen := func(f func(c net.Conn)) {
   185  		ln, err := net.Listen("tcp", "127.0.0.1:0")
   186  		require.Nil(t, err)
   187  		addr <- ln.Addr().String()
   188  		c, err := ln.Accept()
   189  		require.Nil(t, err)
   190  		f(c)
   191  		<-done
   192  		require.Nil(t, ln.Close())
   193  		done <- true
   194  	}
   195  	go listen(fn)
   196  
   197  	// get addr
   198  	listeningAddr := <-addr
   199  	c, err := NewTCPConn(NewTCPAddress(listeningAddr), tSuite)
   200  	require.Nil(t, err)
   201  
   202  	buffRaw, err := c.receiveRaw()
   203  	checking()
   204  	if !bytes.Equal(buff, buffRaw) {
   205  		t.Fatal("Bytes are not the same ")
   206  	} else if err != nil {
   207  		t.Error(err)
   208  	}
   209  
   210  	// tell the listener to close
   211  	done <- true
   212  	// wait until it is closed
   213  	<-done
   214  
   215  	go listen(fnBad)
   216  
   217  	listeningAddr = <-addr
   218  	c, err = NewTCPConn(NewTCPAddress(listeningAddr), tSuite)
   219  	require.Nil(t, err)
   220  
   221  	_, err = c.receiveRaw()
   222  	require.NotNil(t, err)
   223  
   224  	require.Nil(t, c.Close())
   225  	// tell the listener to close
   226  	done <- true
   227  	// wait until it is closed
   228  	<-done
   229  
   230  }
   231  
   232  // test the creation of a new conn by opening a golang
   233  // listener and making a TCPConn connect to it,then close it.
   234  func TestTCPConn(t *testing.T) {
   235  	addr := make(chan string)
   236  	done := make(chan bool)
   237  
   238  	_, err := NewTCPConn(NewTCPAddress("127.0.0.1:7878"), tSuite)
   239  	if err == nil {
   240  		t.Fatal("Should not be able to connect here")
   241  	}
   242  	go func() {
   243  		ln, err := net.Listen("tcp", "127.0.0.1:0")
   244  		require.Nil(t, err)
   245  		addr <- ln.Addr().String()
   246  		_, err = ln.Accept()
   247  		require.Nil(t, err)
   248  		// wait until it can be closed
   249  		<-done
   250  		require.Nil(t, ln.Close())
   251  		done <- true
   252  	}()
   253  
   254  	// get addr
   255  	listeningAddr := <-addr
   256  	c, err := NewTCPConn(NewTCPAddress(listeningAddr), tSuite)
   257  	require.Nil(t, err)
   258  	require.Equal(t, c.Local().NetworkAddress(), c.conn.LocalAddr().String())
   259  	require.Equal(t, c.Type(), PlainTCP)
   260  	require.Nil(t, c.Close())
   261  	// tell the listener to close
   262  	done <- true
   263  	// wait until it is closed
   264  	<-done
   265  }
   266  
   267  func TestTCPConnTimeout(t *testing.T) {
   268  	var timeoutForTest = 100 * time.Millisecond
   269  
   270  	// Need to lock because using 'timeout' from 'tcp.go'.
   271  	timeoutLock.Lock()
   272  	tmp := timeout
   273  	timeout = timeoutForTest
   274  	dialTimeout = timeoutForTest
   275  	timeoutLock.Unlock()
   276  
   277  	defer func() {
   278  		timeoutLock.Lock()
   279  		timeout = tmp
   280  		timeoutLock.Unlock()
   281  	}()
   282  
   283  	addr := NewAddress(PlainTCP, "127.0.0.1:5678")
   284  	ln, err := NewTCPListener(addr, tSuite)
   285  	if err != nil {
   286  		t.Fatal("error setup listener", err)
   287  	}
   288  	ready := make(chan bool)
   289  	connStat := make(chan error)
   290  
   291  	connFn := func(c Conn) {
   292  		// receive first a good packet
   293  		_, err := c.Receive()
   294  		connStat <- err
   295  
   296  		// then this receive should throw out the error
   297  		_, err = c.Receive()
   298  		connStat <- err
   299  
   300  		// put the far-side receiver into broken mode
   301  		tc := c.(*TCPConn)
   302  		tc.receiveRawTest = func() ([]byte, error) {
   303  			time.Sleep(2 * timeoutForTest)
   304  			return nil, nil
   305  		}
   306  
   307  		// this should throw also: need to send enough bytes here
   308  		// that we overload the kernel's buffers and it creates
   309  		// back-pressure on us to stop sending by blocking on
   310  		// the send system call so that Go's SendDeadline is passed.
   311  		msg := &BigMsg{Array: make([]byte, 20*1e6)}
   312  		_, err = c.Send(msg)
   313  		connStat <- err
   314  	}
   315  	go func() {
   316  		ready <- true
   317  		err := ln.Listen(connFn)
   318  		require.Nil(t, err, "Listener stop incorrectly")
   319  	}()
   320  
   321  	<-ready
   322  	c, err := NewTCPConn(addr, tSuite)
   323  	require.Nil(t, err, "Could not open connection")
   324  	// Test bandwitdth measurements also
   325  	sentLen, err := c.Send(&SimpleMessage{3})
   326  	require.Nil(t, err)
   327  	require.NotZero(t, sentLen)
   328  	select {
   329  	case err := <-connStat:
   330  		assert.NoError(t, err)
   331  	case <-time.After(2 * timeoutForTest):
   332  		t.Error("Did not received message after timeout...")
   333  	}
   334  
   335  	// find the timeout from recv
   336  	select {
   337  	case err := <-connStat:
   338  		assert.Error(t, err)
   339  	case <-time.After(2 * timeoutForTest):
   340  		t.Error("Did not received message after timeout...")
   341  	}
   342  
   343  	// the timeout from send too
   344  	select {
   345  	case err := <-connStat:
   346  		assert.True(t, xerrors.Is(err, ErrTimeout))
   347  	case <-time.After(10 * timeoutForTest):
   348  		t.Error("Did not received message after timeout...")
   349  	}
   350  
   351  	assert.Nil(t, c.Close())
   352  	assert.Nil(t, ln.Stop())
   353  }
   354  
   355  func TestTCPDialTimeout(t *testing.T) {
   356  	oldDialTimeout := dialTimeout
   357  	SetTCPDialTimeout(100 * time.Millisecond)
   358  	defer SetTCPDialTimeout(oldDialTimeout)
   359  
   360  	// We're hoping that Cloudflare is not running a server on this address
   361  	// so we'll get a timeout error.
   362  	addr := NewAddress(PlainTCP, "1.1.1.2:1234")
   363  	done := make(chan struct{}, 1)
   364  	go func() {
   365  		_, err := NewTCPConn(addr, tSuite)
   366  		require.Contains(t, err.Error(), "timeout")
   367  		done <- struct{}{}
   368  	}()
   369  
   370  	select {
   371  	case <-done:
   372  	case <-time.After(time.Second):
   373  		require.Fail(t, "should have timed out after a short duration")
   374  	}
   375  }
   376  
   377  func TestTCPConnWithListener(t *testing.T) {
   378  	addr := NewAddress(PlainTCP, "127.0.0.1:5678")
   379  	ln, err := NewTCPListener(addr, tSuite)
   380  	if err != nil {
   381  		t.Fatal("error setup listener", err)
   382  	}
   383  	ready := make(chan bool)
   384  	stop := make(chan bool)
   385  	connStat := make(chan uint64)
   386  
   387  	connFn := func(c Conn) {
   388  		connStat <- c.Rx()
   389  		c.Receive()
   390  		connStat <- c.Rx()
   391  	}
   392  	go func() {
   393  		ready <- true
   394  		err := ln.Listen(connFn)
   395  		require.Nil(t, err, "Listener stop incorrectly")
   396  		stop <- true
   397  	}()
   398  
   399  	<-ready
   400  	c, err := NewTCPConn(addr, tSuite)
   401  	require.Nil(t, err, "Could not open connection")
   402  	// Test bandwitdth measurements also
   403  	rx1 := <-connStat
   404  	tx1 := c.Tx()
   405  	sentLen, err := c.Send(&SimpleMessage{3})
   406  	require.Nil(t, err)
   407  	tx2 := c.Tx()
   408  	rx2 := <-connStat
   409  
   410  	if (tx2 - tx1) != (rx2 - rx1) {
   411  		t.Errorf("Connections did see same bytes? %d tx vs %d rx", (tx2 - tx1), (rx2 - rx1))
   412  	}
   413  	require.Equal(t, tx2-tx1, sentLen)
   414  
   415  	require.Nil(t, ln.Stop(), "Error stopping listener")
   416  	select {
   417  	case <-stop:
   418  	case <-time.After(100 * time.Millisecond):
   419  		t.Fatal("Could not stop listener")
   420  
   421  	}
   422  }
   423  
   424  // will create a TCPListener with a specific address to listen on and
   425  // open a golang net.TCPConn to it
   426  func TestTCPListenerWithListenAddr(t *testing.T) {
   427  	// Testing different wrong configurations.
   428  	testVectorWrong := []struct {
   429  		addr   Address
   430  		listen string
   431  	}{
   432  		{NewAddress(PlainTCP, "1.2.3.4:0"), ":0"},
   433  	}
   434  	for _, tv := range testVectorWrong {
   435  		_, err := NewTCPListenerWithListenAddr(tv.addr, tSuite, tv.listen)
   436  		require.NotNil(t, err, fmt.Sprintf(`Should fail: invalid combination of 
   437  			'addr' (%s) and 'listenAddr' (%s)`, tv.addr, tv.listen))
   438  	}
   439  
   440  	// Testing different working configurations.
   441  	testVector := []struct {
   442  		addr         Address
   443  		listen       string
   444  		expectedHost string
   445  	}{
   446  		{NewAddress(PlainTCP, "1.2.3.4:0"), "127.0.0.1", "127.0.0.1"},
   447  		{NewAddress(PlainTCP, "1.2.3.4:0"), "127.0.0.1:0", "127.0.0.1"},
   448  		{NewAddress(PlainTCP, "1.2.3.4:0"), "", "::"},
   449  	}
   450  	for _, tv := range testVector {
   451  		ln, err := NewTCPListenerWithListenAddr(tv.addr, tSuite, tv.listen)
   452  		require.Nil(t, err, "Error setup listener")
   453  		host, _, err := net.SplitHostPort(ln.Address().NetworkAddress())
   454  		require.Nil(t, err, "Error splitting address of listener")
   455  		require.Equal(t, tv.expectedHost, host)
   456  
   457  		ready := make(chan bool)
   458  		stop := make(chan bool)
   459  		connReceived := make(chan bool)
   460  
   461  		connFn := func(c Conn) {
   462  			connReceived <- true
   463  			c.Close()
   464  		}
   465  		go func() {
   466  			ready <- true
   467  			err := ln.Listen(connFn)
   468  			require.Nil(t, err, "Listener stop incorrectly")
   469  			stop <- true
   470  		}()
   471  
   472  		<-ready
   473  		_, err = net.Dial("tcp", ln.Address().NetworkAddress())
   474  		require.Nil(t, err, "Could not open connection")
   475  		<-connReceived
   476  		require.Nil(t, ln.Stop(), "Error stopping listener")
   477  		select {
   478  		case <-stop:
   479  		case <-time.After(100 * time.Millisecond):
   480  			t.Fatal("Could not stop listener")
   481  		}
   482  
   483  		require.Nil(t, ln.listen(nil))
   484  	}
   485  
   486  	// Testing different working configurations using static ports (but not
   487  	// listening because we don't want to risk any error).
   488  	testVectorStaticPort := []struct {
   489  		addr            Address
   490  		listen          string
   491  		expectedAddress string
   492  	}{
   493  		{NewAddress(PlainTCP, "1.2.3.4:1234"), "4.3.2.1", "4.3.2.1:1234"},
   494  		{NewAddress(PlainTCP, "1.2.3.4:1234"), "4.3.2.1:4321", "4.3.2.1:4321"},
   495  		{NewAddress(PlainTCP, "1.2.3.4:1234"), "", ":1234"},
   496  	}
   497  	for _, tv := range testVectorStaticPort {
   498  		// using directly 'getListenAddress' which is used by
   499  		// 'NewTCPListenerWithListenAddr' to figure out the address to listen
   500  		// to given the server address and listen address from 'private.toml'
   501  		listenAddr, err := getListenAddress(tv.addr, tv.listen)
   502  		require.Nil(t, err, "Error getting the listen address")
   503  		require.Equal(t, tv.expectedAddress, listenAddr)
   504  	}
   505  }
   506  
   507  // will create a TCPListener globally binding & open a golang net.TCPConn to it
   508  func TestTCPListener(t *testing.T) {
   509  	addr := NewAddress(PlainTCP, "127.0.0.1:0")
   510  	ln, err := NewTCPListener(addr, tSuite)
   511  	require.Nil(t, err, "Error setup listener")
   512  
   513  	// Making sure the listener is globally binding
   514  	host, _, err := net.SplitHostPort(ln.Address().NetworkAddress())
   515  	require.Nil(t, err, "Error splitting address of listener")
   516  	require.Equal(t, "::", host, "Listener did not bind globally when given no specific listen address")
   517  
   518  	ready := make(chan bool)
   519  	stop := make(chan bool)
   520  	connReceived := make(chan bool)
   521  
   522  	connFn := func(c Conn) {
   523  		connReceived <- true
   524  		c.Close()
   525  	}
   526  	go func() {
   527  		ready <- true
   528  		err := ln.Listen(connFn)
   529  		require.Nil(t, err, "Listener stop incorrectly")
   530  		stop <- true
   531  	}()
   532  
   533  	<-ready
   534  	_, err = net.Dial("tcp", ln.Address().NetworkAddress())
   535  	require.Nil(t, err, "Could not open connection")
   536  	<-connReceived
   537  	require.Nil(t, ln.Stop(), "Error stopping listener")
   538  	select {
   539  	case <-stop:
   540  	case <-time.After(100 * time.Millisecond):
   541  		t.Fatal("Could not stop listener")
   542  	}
   543  
   544  	require.Nil(t, ln.listen(nil))
   545  }
   546  
   547  func TestTCPRouter(t *testing.T) {
   548  	wrongAddr := &ServerIdentity{Address: NewLocalAddress("127.0.0.1:2000")}
   549  	_, err := NewTCPRouter(wrongAddr, tSuite)
   550  	if err == nil {
   551  		t.Fatal("Should not setup Router with local address")
   552  	}
   553  
   554  	addr := &ServerIdentity{Address: NewAddress(PlainTCP, "127.0.0.1:2000")}
   555  	h1, err := NewTCPRouter(addr, tSuite)
   556  	if err != nil {
   557  		t.Fatal("Could not setup host")
   558  	}
   559  	defer h1.Stop()
   560  	_, err = NewTCPRouter(addr, tSuite)
   561  	if err == nil {
   562  		t.Fatal("Should not succeed with same port")
   563  	}
   564  }
   565  
   566  // Test closing and opening of Host on same address
   567  func TestTCPHostClose(t *testing.T) {
   568  	h1, err := NewTestTCPHost(2001)
   569  	if err != nil {
   570  		t.Fatal("Error setup TestTCPHost")
   571  	}
   572  	h2, err2 := NewTestTCPHost(2002)
   573  	if err2 != nil {
   574  		t.Fatal("Error setup TestTCPHost2")
   575  	}
   576  	go h1.Listen(acceptAndClose)
   577  	si := NewTestServerIdentity(NewLocalAddress("127.0.0.1:7878"))
   578  	if _, err := h2.Connect(si); err == nil {
   579  		t.Fatal("Should not connect to dummy address or different type")
   580  	}
   581  	_, err = h2.Connect(NewTestServerIdentity(h1.TCPListener.Address()))
   582  	if err != nil {
   583  		t.Fatal("Couldn't Connect()", err)
   584  	}
   585  
   586  	err = h1.Stop()
   587  	if err != nil {
   588  		t.Fatal("Couldn't close:", err)
   589  	}
   590  	err = h2.Stop()
   591  	if err != nil {
   592  		t.Fatal("Couldn't close:", err)
   593  	}
   594  	log.Lvl3("Finished first connection, starting 2nd")
   595  	h3, err3 := NewTestTCPHost(2003)
   596  	if err3 != nil {
   597  		t.Fatal("Could not setup host", err)
   598  	}
   599  	go h3.Listen(acceptAndClose)
   600  	_, err = h2.Connect(NewTestServerIdentity(h3.TCPListener.Address()))
   601  	if err != nil {
   602  		t.Fatal(h2, "Couldn Connect() to", h3)
   603  	}
   604  	log.Lvl3("Closing h3")
   605  	err = h3.Stop()
   606  	if err != nil {
   607  		// try closing the underlying connection manually and fail
   608  		t.Fatal("Couldn't Stop()", h3)
   609  	}
   610  }
   611  
   612  type dummyErr struct {
   613  	timeout   bool
   614  	temporary bool
   615  }
   616  
   617  func (d *dummyErr) Timeout() bool {
   618  	return d.timeout
   619  }
   620  
   621  func (d *dummyErr) Temporary() bool {
   622  	return d.temporary
   623  }
   624  
   625  func (d *dummyErr) Error() string {
   626  	return "dummy error"
   627  }
   628  
   629  func TestHandleError(t *testing.T) {
   630  	require.Equal(t, ErrClosed, handleError(xerrors.New("use of closed")))
   631  	require.Equal(t, ErrCanceled, handleError(xerrors.New("canceled")))
   632  	require.Equal(t, ErrEOF, handleError(xerrors.New("EOF")))
   633  
   634  	require.Equal(t, ErrUnknown, handleError(xerrors.New("random error")))
   635  
   636  	de := dummyErr{true, true}
   637  	de.temporary = false
   638  	require.Equal(t, ErrTimeout, handleError(&de))
   639  	de.timeout = false
   640  	require.Equal(t, ErrUnknown, handleError(&de))
   641  }
   642  
   643  func NewTestTCPHost(port int) (*TCPHost, error) {
   644  	addr := NewTCPAddress("127.0.0.1:" + strconv.Itoa(port))
   645  	kp := key.NewKeyPair(tSuite)
   646  	e := NewServerIdentity(kp.Public, addr)
   647  	e.SetPrivate(kp.Private)
   648  	return NewTCPHost(e, tSuite)
   649  }
   650  
   651  // Returns a ServerIdentity out of the address
   652  func NewTestServerIdentity(address Address) *ServerIdentity {
   653  	kp := key.NewKeyPair(tSuite)
   654  	e := NewServerIdentity(kp.Public, address)
   655  	return e
   656  }
   657  
   658  // SimpleMessage is just used to transfer one integer
   659  type SimpleMessage struct {
   660  	I int64
   661  }
   662  
   663  var SimpleMessageType MessageTypeID
   664  
   665  type simpleMessageProc struct {
   666  	t     *testing.T
   667  	relay chan SimpleMessage
   668  }
   669  
   670  func newSimpleMessageProc(t *testing.T) *simpleMessageProc {
   671  	return &simpleMessageProc{
   672  		t:     t,
   673  		relay: make(chan SimpleMessage),
   674  	}
   675  }
   676  
   677  func (smp *simpleMessageProc) Process(e *Envelope) {
   678  	if e.MsgType != SimpleMessageType {
   679  		smp.t.Fatal("Wrong message")
   680  	}
   681  	sm := e.Msg.(*SimpleMessage)
   682  	smp.relay <- *sm
   683  }
   684  
   685  type statusMessage struct {
   686  	Ok  bool
   687  	Val int64
   688  }
   689  
   690  var statusMsgID = RegisterMessage(statusMessage{})
   691  
   692  type simpleProcessor struct {
   693  	relay chan statusMessage
   694  }
   695  
   696  func newSimpleProcessor() *simpleProcessor {
   697  	return &simpleProcessor{
   698  		relay: make(chan statusMessage),
   699  	}
   700  }
   701  func (sp *simpleProcessor) Process(env *Envelope) {
   702  	if env.MsgType != statusMsgID {
   703  
   704  		sp.relay <- statusMessage{false, 0}
   705  	}
   706  	sm := env.Msg.(*statusMessage)
   707  
   708  	sp.relay <- *sm
   709  }
   710  
   711  func sendrcvProc(from, to *Router) error {
   712  	sp := newSimpleProcessor()
   713  	// new processing
   714  	to.RegisterProcessor(sp, statusMsgID)
   715  	sentLen, err := from.Send(to.ServerIdentity, &statusMessage{true, 10})
   716  	if err != nil {
   717  		return err
   718  	}
   719  	if sentLen == 0 {
   720  		return xerrors.New("sentLen is zero")
   721  	}
   722  
   723  	select {
   724  	case <-sp.relay:
   725  		err = nil
   726  	case <-time.After(1 * time.Second):
   727  		err = xerrors.New("timeout")
   728  	}
   729  	// delete the processing
   730  	to.RegisterProcessor(nil, statusMsgID)
   731  	return err
   732  }
   733  
   734  func waitConnections(r *Router, sid *ServerIdentity) error {
   735  	for i := 0; i < 10; i++ {
   736  		c := r.connection(sid.ID)
   737  		if c != nil {
   738  			return nil
   739  		}
   740  		time.Sleep(WaitRetry)
   741  	}
   742  	return xerrors.Errorf("Didn't see connection to %s in router", sid.Address)
   743  }
   744  
   745  func acceptAndClose(c Conn) {
   746  	c.Close()
   747  	return
   748  }