/* CLIENT */ func (n *Node) Dial(peerPubKey *rsa.PublicKey) (conn Conn, err error) { infoHash, err := pubKeyToInfoHash(peerPubKey) if err != nil { return } peerNotifications := make(chan string, peerChanBufferCapacity) n.dht.subscribeToInfoHash(dht.InfoHash(infoHash), peerNotifications) // ask for the infohash n.dht.PeersRequest(infoHash, false) connSuccessChan := make(chan interface{}) for peerNotification := range peerNotifications { go func(peerNotification string) { // ASSUMPTION: peerNotifications doesn't yield duplicates. someConn, connErr := n.handlePotentialPeer(peerNotification, peerPubKey) if err != nil { Log(LOG_INFO, "Failed to connect to potential peer %s: %s", peerNotification, connErr) } connSuccessChan <- someConn }(peerNotification) } maybeConn, err := netutils.ReadWithTimeout(connSuccessChan, 30000) if err != nil { return } return maybeConn.(Conn), nil }
func TestClientServerProtocol(t *testing.T) { /* connA, connB, err := NewTestTCPConns() if err != nil { t.Errorf("failed to create client/server TCP conns: ", err) return } */ connA, connB := NewTestConns() keyFile := "../data/mypriv.rsa" keyA, err := node.RsaKeyFromPEM(keyFile) if err != nil { t.Errorf("failed loading key file: %s", err) return } keyB, err := node.RsaKeyFromPEM(keyFile) if err != nil { t.Errorf("failed loading key file: %s", err) return } sentByA := [][]byte{[]byte{1, 0, 0, 0, 1}, []byte{2, 0, 0, 0, 2}} sentByB := [][]byte{[]byte{3, 0, 0, 0, 3, 4, 7}, bytes.Repeat([]byte{66}, 256)} clientDone := make(chan interface{}) serverDone := make(chan interface{}) contactList := node.NewContactList() contactList.AddContact(&node.Contact{&keyA.PublicKey}) go func() { var clientConn net.Conn = nil var clientErr error = nil clientConn, clientErr = node.HandleClientConn(connA, keyA, &keyB.PublicKey) if clientErr != nil { t.Errorf("client failed with: %s", clientErr) return } for _, chunk := range sentByA { clientConn.Write(chunk) } allBytesFromB := bytes.Join(sentByB[:], []byte{}) recvBuf := make([]byte, len(allBytesFromB)) _, err := io.ReadFull(clientConn, recvBuf) if err != nil { t.Errorf("client A failed to receive expected bytes in full") return } if !bytes.Equal(recvBuf, allBytesFromB) { t.Errorf("client A did not receive expected bytes") return } clientDone <- true }() go func() { var serverConn net.Conn = nil var serverErr error = nil serverConn, serverErr = node.HandleServerConn(connB, keyB, contactList) if serverErr != nil { t.Errorf("server failed with: %s", serverErr) return } allBytesFromA := bytes.Join(sentByA[:], []byte{}) recvBuf := make([]byte, len(allBytesFromA)) _, err := io.ReadFull(serverConn, recvBuf) if err != nil { t.Errorf("server B failed to receive expected bytes in full") return } if !bytes.Equal(recvBuf, allBytesFromA) { t.Errorf("server B did not receive expected bytes") return } for _, chunk := range sentByB { _, err := serverConn.Write(chunk) if err != nil { t.Errorf("failed to send message") return } } serverDone <- true }() _, err = netutils.ReadWithTimeout(serverDone, 1000) if err != nil { t.Errorf("server failed to terminate: %s", err) return } _, err = netutils.ReadWithTimeout(clientDone, 1000) if err != nil { t.Errorf("server failed to terminate: %s", err) return } }