// peerMultiConn returns the MultiConn responsible for handling this peer. // if there is none, it creates one and returns it. Note that timeouts // and connection teardowns will remove it. func (s *Swarm) peerMultiConn(p peer.Peer) (*conn.MultiConn, error) { s.connsLock.Lock() mc, found := s.conns[p.Key()] if found { s.connsLock.Unlock() return mc, nil } // multiconn doesn't exist, make a new one. mc, err := conn.NewMultiConn(s.Context(), s.local, p, nil) if err != nil { s.connsLock.Unlock() log.Errorf("error creating multiconn: %s", err) return nil, err } s.conns[p.Key()] = mc s.connsLock.Unlock() // kick off reader goroutine s.Children().Add(1) mc.Children().Add(1) // child of Conn as well. go s.fanInSingle(mc) return mc, nil }
func (r *dhtQueryRunner) addPeerToQuery(next peer.Peer, benchmark peer.Peer) { if next == nil { // wtf why are peers nil?!? log.Error("Query getting nil peers!!!\n") return } // if new peer further away than whom we got it from, bother (loops) if benchmark != nil && kb.Closer(benchmark.ID(), next.ID(), r.query.key) { return } // if already seen, no need. r.Lock() _, found := r.peersSeen[next.Key()] if found { r.Unlock() return } r.peersSeen[next.Key()] = next r.Unlock() log.Debugf("adding peer to query: %v\n", next) // do this after unlocking to prevent possible deadlocks. r.peersRemaining.Increment(1) select { case r.peersToQuery.EnqChan <- next: case <-r.ctx.Done(): } }
func (n *network) Adapter(p peer.Peer) bsnet.BitSwapNetwork { client := &networkClient{ local: p, network: n, } n.clients[p.Key()] = client return client }
// ledger lazily instantiates a ledger func (s *strategist) ledger(p peer.Peer) *ledger { l, ok := s.ledgerMap[peerKey(p.Key())] if !ok { l = newLedger(p, s.strategyFunc) s.ledgerMap[peerKey(p.Key())] = l } return l }
func peerIsPartner(p peer.Peer, s Strategy) bool { for _, partner := range s.Peers() { if partner.Key() == p.Key() { return true } } return false }
func (rs *hashTable) Announce(p peer.Peer, k u.Key) error { rs.lock.Lock() defer rs.lock.Unlock() _, ok := rs.providers[k] if !ok { rs.providers[k] = make(peer.Map) } rs.providers[k][p.Key()] = p return nil }
// TODO(brian): handle errors func (bs *bitswap) ReceiveMessage(ctx context.Context, p peer.Peer, incoming bsmsg.BitSwapMessage) ( peer.Peer, bsmsg.BitSwapMessage) { log.Debugf("ReceiveMessage from %v", p.Key()) log.Debugf("Message wantlist: %v", incoming.Wantlist()) if p == nil { log.Error("Received message from nil peer!") // TODO propagate the error upward return nil, nil } if incoming == nil { log.Error("Got nil bitswap message!") // TODO propagate the error upward return nil, nil } // Record message bytes in ledger // TODO: this is bad, and could be easily abused. // Should only track *useful* messages in ledger bs.strategy.MessageReceived(p, incoming) // FIRST for _, block := range incoming.Blocks() { // TODO verify blocks? if err := bs.blockstore.Put(&block); err != nil { continue // FIXME(brian): err ignored } bs.notifications.Publish(block) err := bs.HasBlock(ctx, block) if err != nil { log.Warningf("HasBlock errored: %s", err) } } message := bsmsg.New() for _, wanted := range bs.wantlist.Keys() { message.AddWanted(wanted) } for _, key := range incoming.Wantlist() { // TODO: might be better to check if we have the block before checking // if we should send it to someone if bs.strategy.ShouldSendBlockToPeer(key, p) { if block, errBlockNotFound := bs.blockstore.Get(key); errBlockNotFound != nil { continue } else { message.AddBlock(*block) } } } defer bs.strategy.MessageSent(p, message) log.Debug("Returning message.") return p, message }
// TODO should this be completely asynchronous? // TODO what does the network layer do with errors received from services? func (n *network) SendMessage( ctx context.Context, from peer.Peer, to peer.Peer, message bsmsg.BitSwapMessage) error { receiver, ok := n.clients[to.Key()] if !ok { return errors.New("Cannot locate peer on network") } // nb: terminate the context since the context wouldn't actually be passed // over the network in a real scenario go n.deliver(receiver, from, message) return nil }
// TODO func (n *network) SendRequest( ctx context.Context, from peer.Peer, to peer.Peer, message bsmsg.BitSwapMessage) ( incoming bsmsg.BitSwapMessage, err error) { r, ok := n.clients[to.Key()] if !ok { return nil, errors.New("Cannot locate peer on network") } nextPeer, nextMsg := r.ReceiveMessage(context.TODO(), from, message) // TODO dedupe code if (nextPeer == nil && nextMsg != nil) || (nextMsg == nil && nextPeer != nil) { r.ReceiveError(errors.New("Malformed client request")) return nil, nil } // TODO dedupe code if nextPeer == nil && nextMsg == nil { return nil, nil } // TODO test when receiver doesn't immediately respond to the initiator of the request if !bytes.Equal(nextPeer.ID(), from.ID()) { go func() { nextReceiver, ok := n.clients[nextPeer.Key()] if !ok { // TODO log the error? } n.deliver(nextReceiver, nextPeer, nextMsg) }() return nil, nil } return nextMsg, nil }
func (n *network) HasPeer(p peer.Peer) bool { _, found := n.clients[p.Key()] return found }