// NewStream opens a new stream to given peer p, and writes a p2p/protocol // header with given protocol.ID. If there is no connection to p, attempts // to create one. If ProtocolID is "", writes no header. // (Threadsafe) func (h *BasicHost) NewStream(pid protocol.ID, p peer.ID) (inet.Stream, error) { s, err := h.Network().NewStream(p) if err != nil { return nil, err } logStream := mstream.WrapStream(s, pid, h.bwc) lzcon := msmux.NewMSSelect(logStream, string(pid)) return &streamWrapper{ Stream: logStream, rw: lzcon, }, nil }
func (ids *IDService) RequestHandler(s inet.Stream) { defer s.Close() c := s.Conn() bwc := ids.Host.GetBandwidthReporter() s = mstream.WrapStream(s, ID, bwc) w := ggio.NewDelimitedWriter(s) mes := pb.Identify{} ids.populateMessage(&mes, s.Conn()) w.WriteMsg(&mes) log.Debugf("%s sent message to %s %s", ID, c.RemotePeer(), c.RemoteMultiaddr()) }
// newStreamHandler is the remote-opened stream handler for inet.Network // TODO: this feels a bit wonky func (h *BasicHost) newStreamHandler(s inet.Stream) { protoID, handle, err := h.Mux().ReadHeader(s) if err != nil { if err == io.EOF { log.Debugf("protocol EOF: %s", s.Conn().RemotePeer()) } else { log.Warning("protocol mux failed: %s", err) } return } logStream := mstream.WrapStream(s, protoID, h.bwc) go handle(logStream) }
// NewStream opens a new stream to given peer p, and writes a p2p/protocol // header with given protocol.ID. If there is no connection to p, attempts // to create one. If ProtocolID is "", writes no header. // (Threadsafe) func (h *BasicHost) NewStream(pid protocol.ID, p peer.ID) (inet.Stream, error) { s, err := h.Network().NewStream(p) if err != nil { return nil, err } logStream := mstream.WrapStream(s, pid, h.bwc) if err := protocol.WriteHeader(logStream, pid); err != nil { logStream.Close() return nil, err } return logStream, nil }
func (ids *IDService) IdentifyConn(c inet.Conn) { ids.currmu.Lock() if wait, found := ids.currid[c]; found { ids.currmu.Unlock() log.Debugf("IdentifyConn called twice on: %s", c) <-wait // already identifying it. wait for it. return } ids.currid[c] = make(chan struct{}) ids.currmu.Unlock() s, err := c.NewStream() if err != nil { log.Debugf("error opening initial stream for %s", ID) log.Event(context.TODO(), "IdentifyOpenFailed", c.RemotePeer()) c.Close() return } else { bwc := ids.Host.GetBandwidthReporter() s = mstream.WrapStream(s, ID, bwc) // ok give the response to our handler. if err := msmux.SelectProtoOrFail(ID, s); err != nil { log.Debugf("error writing stream header for %s", ID) log.Event(context.TODO(), "IdentifyOpenFailed", c.RemotePeer()) s.Close() return } else { ids.ResponseHandler(s) } } ids.currmu.Lock() ch, found := ids.currid[c] delete(ids.currid, c) ids.currmu.Unlock() if !found { log.Debugf("IdentifyConn failed to find channel (programmer error) for %s", c) return } close(ch) // release everyone waiting. }