github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/routing/dht/dht_net.go (about) 1 package dht 2 3 import ( 4 "errors" 5 "time" 6 7 ggio "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/gogo/protobuf/io" 8 ctxio "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-context/io" 9 context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context" 10 inet "github.com/ipfs/go-ipfs/p2p/net" 11 peer "github.com/ipfs/go-ipfs/p2p/peer" 12 pb "github.com/ipfs/go-ipfs/routing/dht/pb" 13 ) 14 15 // handleNewStream implements the inet.StreamHandler 16 func (dht *IpfsDHT) handleNewStream(s inet.Stream) { 17 go dht.handleNewMessage(s) 18 } 19 20 func (dht *IpfsDHT) handleNewMessage(s inet.Stream) { 21 defer s.Close() 22 23 ctx := dht.Context() 24 cr := ctxio.NewReader(ctx, s) // ok to use. we defer close stream in this func 25 cw := ctxio.NewWriter(ctx, s) // ok to use. we defer close stream in this func 26 r := ggio.NewDelimitedReader(cr, inet.MessageSizeMax) 27 w := ggio.NewDelimitedWriter(cw) 28 mPeer := s.Conn().RemotePeer() 29 30 // receive msg 31 pmes := new(pb.Message) 32 if err := r.ReadMsg(pmes); err != nil { 33 log.Debugf("Error unmarshaling data: %s", err) 34 return 35 } 36 37 // update the peer (on valid msgs only) 38 dht.updateFromMessage(ctx, mPeer, pmes) 39 40 // get handler for this msg type. 41 handler := dht.handlerForMsgType(pmes.GetType()) 42 if handler == nil { 43 log.Debug("got back nil handler from handlerForMsgType") 44 return 45 } 46 47 // dispatch handler. 48 rpmes, err := handler(ctx, mPeer, pmes) 49 if err != nil { 50 log.Debugf("handle message error: %s", err) 51 return 52 } 53 54 // if nil response, return it before serializing 55 if rpmes == nil { 56 log.Debug("Got back nil response from request.") 57 return 58 } 59 60 // send out response msg 61 if err := w.WriteMsg(rpmes); err != nil { 62 log.Debugf("send response error: %s", err) 63 return 64 } 65 66 return 67 } 68 69 // sendRequest sends out a request, but also makes sure to 70 // measure the RTT for latency measurements. 71 func (dht *IpfsDHT) sendRequest(ctx context.Context, p peer.ID, pmes *pb.Message) (*pb.Message, error) { 72 73 log.Debugf("%s dht starting stream", dht.self) 74 s, err := dht.host.NewStream(ProtocolDHT, p) 75 if err != nil { 76 return nil, err 77 } 78 defer s.Close() 79 80 cr := ctxio.NewReader(ctx, s) // ok to use. we defer close stream in this func 81 cw := ctxio.NewWriter(ctx, s) // ok to use. we defer close stream in this func 82 r := ggio.NewDelimitedReader(cr, inet.MessageSizeMax) 83 w := ggio.NewDelimitedWriter(cw) 84 85 start := time.Now() 86 87 if err := w.WriteMsg(pmes); err != nil { 88 return nil, err 89 } 90 log.Event(ctx, "dhtSentMessage", dht.self, p, pmes) 91 92 rpmes := new(pb.Message) 93 if err := r.ReadMsg(rpmes); err != nil { 94 return nil, err 95 } 96 if rpmes == nil { 97 return nil, errors.New("no response to request") 98 } 99 100 // update the peer (on valid msgs only) 101 dht.updateFromMessage(ctx, p, rpmes) 102 103 dht.peerstore.RecordLatency(p, time.Since(start)) 104 log.Event(ctx, "dhtReceivedMessage", dht.self, p, rpmes) 105 return rpmes, nil 106 } 107 108 // sendMessage sends out a message 109 func (dht *IpfsDHT) sendMessage(ctx context.Context, p peer.ID, pmes *pb.Message) error { 110 111 log.Debugf("%s dht starting stream", dht.self) 112 s, err := dht.host.NewStream(ProtocolDHT, p) 113 if err != nil { 114 return err 115 } 116 defer s.Close() 117 118 cw := ctxio.NewWriter(ctx, s) // ok to use. we defer close stream in this func 119 w := ggio.NewDelimitedWriter(cw) 120 121 if err := w.WriteMsg(pmes); err != nil { 122 return err 123 } 124 log.Event(ctx, "dhtSentMessage", dht.self, p, pmes) 125 return nil 126 } 127 128 func (dht *IpfsDHT) updateFromMessage(ctx context.Context, p peer.ID, mes *pb.Message) error { 129 dht.Update(ctx, p) 130 return nil 131 }