github.com/zignig/go-ipfs@v0.0.0-20141111235910-c9e5fdf55a52/exchange/bitswap/testnet/network.go (about) 1 package bitswap 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 8 context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context" 9 bsmsg "github.com/jbenet/go-ipfs/exchange/bitswap/message" 10 bsnet "github.com/jbenet/go-ipfs/exchange/bitswap/network" 11 peer "github.com/jbenet/go-ipfs/peer" 12 "github.com/jbenet/go-ipfs/util" 13 ) 14 15 type Network interface { 16 Adapter(peer.Peer) bsnet.Adapter 17 18 HasPeer(peer.Peer) bool 19 20 SendMessage( 21 ctx context.Context, 22 from peer.Peer, 23 to peer.Peer, 24 message bsmsg.BitSwapMessage) error 25 26 SendRequest( 27 ctx context.Context, 28 from peer.Peer, 29 to peer.Peer, 30 message bsmsg.BitSwapMessage) ( 31 incoming bsmsg.BitSwapMessage, err error) 32 } 33 34 // network impl 35 36 func VirtualNetwork() Network { 37 return &network{ 38 clients: make(map[util.Key]bsnet.Receiver), 39 } 40 } 41 42 type network struct { 43 clients map[util.Key]bsnet.Receiver 44 } 45 46 func (n *network) Adapter(p peer.Peer) bsnet.Adapter { 47 client := &networkClient{ 48 local: p, 49 network: n, 50 } 51 n.clients[p.Key()] = client 52 return client 53 } 54 55 func (n *network) HasPeer(p peer.Peer) bool { 56 _, found := n.clients[p.Key()] 57 return found 58 } 59 60 // TODO should this be completely asynchronous? 61 // TODO what does the network layer do with errors received from services? 62 func (n *network) SendMessage( 63 ctx context.Context, 64 from peer.Peer, 65 to peer.Peer, 66 message bsmsg.BitSwapMessage) error { 67 68 receiver, ok := n.clients[to.Key()] 69 if !ok { 70 return errors.New("Cannot locate peer on network") 71 } 72 73 // nb: terminate the context since the context wouldn't actually be passed 74 // over the network in a real scenario 75 76 go n.deliver(receiver, from, message) 77 78 return nil 79 } 80 81 func (n *network) deliver( 82 r bsnet.Receiver, from peer.Peer, message bsmsg.BitSwapMessage) error { 83 if message == nil || from == nil { 84 return errors.New("Invalid input") 85 } 86 87 nextPeer, nextMsg := r.ReceiveMessage(context.TODO(), from, message) 88 89 if (nextPeer == nil && nextMsg != nil) || (nextMsg == nil && nextPeer != nil) { 90 return errors.New("Malformed client request") 91 } 92 93 if nextPeer == nil && nextMsg == nil { 94 return nil 95 } 96 97 nextReceiver, ok := n.clients[nextPeer.Key()] 98 if !ok { 99 return errors.New("Cannot locate peer on network") 100 } 101 go n.deliver(nextReceiver, nextPeer, nextMsg) 102 return nil 103 } 104 105 var NoResponse = errors.New("No response received from the receiver") 106 107 // TODO 108 func (n *network) SendRequest( 109 ctx context.Context, 110 from peer.Peer, 111 to peer.Peer, 112 message bsmsg.BitSwapMessage) ( 113 incoming bsmsg.BitSwapMessage, err error) { 114 115 r, ok := n.clients[to.Key()] 116 if !ok { 117 return nil, errors.New("Cannot locate peer on network") 118 } 119 nextPeer, nextMsg := r.ReceiveMessage(context.TODO(), from, message) 120 121 // TODO dedupe code 122 if (nextPeer == nil && nextMsg != nil) || (nextMsg == nil && nextPeer != nil) { 123 r.ReceiveError(errors.New("Malformed client request")) 124 return nil, nil 125 } 126 127 // TODO dedupe code 128 if nextPeer == nil && nextMsg == nil { 129 return nil, nil 130 } 131 132 // TODO test when receiver doesn't immediately respond to the initiator of the request 133 if !bytes.Equal(nextPeer.ID(), from.ID()) { 134 go func() { 135 nextReceiver, ok := n.clients[nextPeer.Key()] 136 if !ok { 137 // TODO log the error? 138 } 139 n.deliver(nextReceiver, nextPeer, nextMsg) 140 }() 141 return nil, nil 142 } 143 return nextMsg, nil 144 } 145 146 type networkClient struct { 147 local peer.Peer 148 bsnet.Receiver 149 network Network 150 } 151 152 func (nc *networkClient) SendMessage( 153 ctx context.Context, 154 to peer.Peer, 155 message bsmsg.BitSwapMessage) error { 156 return nc.network.SendMessage(ctx, nc.local, to, message) 157 } 158 159 func (nc *networkClient) SendRequest( 160 ctx context.Context, 161 to peer.Peer, 162 message bsmsg.BitSwapMessage) (incoming bsmsg.BitSwapMessage, err error) { 163 return nc.network.SendRequest(ctx, nc.local, to, message) 164 } 165 166 func (nc *networkClient) DialPeer(ctx context.Context, p peer.Peer) error { 167 // no need to do anything because dialing isn't a thing in this test net. 168 if !nc.network.HasPeer(p) { 169 return fmt.Errorf("Peer not in network: %s", p) 170 } 171 return nil 172 } 173 174 func (nc *networkClient) SetDelegate(r bsnet.Receiver) { 175 nc.Receiver = r 176 }