github.com/anacrolix/torrent@v1.61.0/webrtc.go (about) 1 package torrent 2 3 import ( 4 "io" 5 "net" 6 "strconv" 7 "time" 8 9 "github.com/pion/webrtc/v4" 10 "go.opentelemetry.io/otel" 11 "go.opentelemetry.io/otel/attribute" 12 "go.opentelemetry.io/otel/trace" 13 14 "github.com/anacrolix/torrent/webtorrent" 15 ) 16 17 const webrtcNetwork = "webrtc" 18 19 type webrtcNetConn struct { 20 io.ReadWriteCloser 21 webtorrent.DataChannelContext 22 } 23 24 type webrtcNetAddr struct { 25 *webrtc.ICECandidate 26 } 27 28 var _ net.Addr = webrtcNetAddr{} 29 30 func (webrtcNetAddr) Network() string { 31 // Now that we have the ICE candidate, we can tell if it's over udp or tcp. But should we use 32 // that for the network? 33 return webrtcNetwork 34 } 35 36 func (me webrtcNetAddr) String() string { 37 return net.JoinHostPort(me.Address, strconv.FormatUint(uint64(me.Port), 10)) 38 } 39 40 func (me webrtcNetConn) LocalAddr() net.Addr { 41 // I'm not sure if this evolves over time. It might also be unavailable if the PeerConnection is 42 // closed or closes itself. The same concern applies to RemoteAddr. 43 pair, err := me.DataChannelContext.GetSelectedIceCandidatePair() 44 if err != nil { 45 panic(err) 46 } 47 return webrtcNetAddr{pair.Local} 48 } 49 50 func (me webrtcNetConn) RemoteAddr() net.Addr { 51 // See comments on LocalAddr. 52 pair, err := me.DataChannelContext.GetSelectedIceCandidatePair() 53 if err != nil { 54 panic(err) 55 } 56 return webrtcNetAddr{pair.Remote} 57 } 58 59 // Do we need these for WebRTC connections exposed as net.Conns? Can we set them somewhere inside 60 // PeerConnection or on the channel or some transport? 61 62 func (w webrtcNetConn) SetDeadline(t time.Time) error { 63 w.Span.AddEvent("SetDeadline", trace.WithAttributes(attribute.String("time", t.String()))) 64 return nil 65 } 66 67 func (w webrtcNetConn) SetReadDeadline(t time.Time) error { 68 w.Span.AddEvent("SetReadDeadline", trace.WithAttributes(attribute.String("time", t.String()))) 69 return nil 70 } 71 72 func (w webrtcNetConn) SetWriteDeadline(t time.Time) error { 73 w.Span.AddEvent("SetWriteDeadline", trace.WithAttributes(attribute.String("time", t.String()))) 74 return nil 75 } 76 77 func (w webrtcNetConn) Read(b []byte) (n int, err error) { 78 _, span := otel.Tracer(tracerName).Start(w.Context, "Read") 79 defer span.End() 80 span.SetAttributes(attribute.Int("buf_len", len(b))) 81 n, err = w.ReadWriteCloser.Read(b) 82 span.RecordError(err) 83 span.SetAttributes(attribute.Int("bytes_read", n)) 84 return 85 }