]> Sergey Matveev's repositories - btrtrc.git/blobdiff - webrtc.go
Drop support for go 1.20
[btrtrc.git] / webrtc.go
index 8afe7db3060db10bf7fac7a537e1a80ef8bdcc59..ca4f80fb9f19d08d7f4e9adf66e9826d75b0d32b 100644 (file)
--- a/webrtc.go
+++ b/webrtc.go
@@ -2,10 +2,14 @@ package torrent
 
 import (
        "net"
+       "strconv"
        "time"
 
        "github.com/pion/datachannel"
-       "github.com/pion/webrtc/v2"
+       "github.com/pion/webrtc/v3"
+       "go.opentelemetry.io/otel"
+       "go.opentelemetry.io/otel/attribute"
+       "go.opentelemetry.io/otel/trace"
 
        "github.com/anacrolix/torrent/webtorrent"
 )
@@ -18,34 +22,64 @@ type webrtcNetConn struct {
 }
 
 type webrtcNetAddr struct {
-       webrtc.SessionDescription
+       *webrtc.ICECandidate
 }
 
+var _ net.Addr = webrtcNetAddr{}
+
 func (webrtcNetAddr) Network() string {
+       // Now that we have the ICE candidate, we can tell if it's over udp or tcp. But should we use
+       // that for the network?
        return webrtcNetwork
 }
 
 func (me webrtcNetAddr) String() string {
-       // TODO: What can I show here that's more like other protocols?
-       return "<WebRTC>"
+       return net.JoinHostPort(me.Address, strconv.FormatUint(uint64(me.Port), 10))
 }
 
 func (me webrtcNetConn) LocalAddr() net.Addr {
-       return webrtcNetAddr{me.Local}
+       // I'm not sure if this evolves over time. It might also be unavailable if the PeerConnection is
+       // closed or closes itself. The same concern applies to RemoteAddr.
+       pair, err := me.DataChannelContext.GetSelectedIceCandidatePair()
+       if err != nil {
+               panic(err)
+       }
+       return webrtcNetAddr{pair.Local}
 }
 
 func (me webrtcNetConn) RemoteAddr() net.Addr {
-       return webrtcNetAddr{me.Remote}
+       // See comments on LocalAddr.
+       pair, err := me.DataChannelContext.GetSelectedIceCandidatePair()
+       if err != nil {
+               panic(err)
+       }
+       return webrtcNetAddr{pair.Remote}
 }
 
+// Do we need these for WebRTC connections exposed as net.Conns? Can we set them somewhere inside
+// PeerConnection or on the channel or some transport?
+
 func (w webrtcNetConn) SetDeadline(t time.Time) error {
+       w.Span.AddEvent("SetDeadline", trace.WithAttributes(attribute.String("time", t.String())))
        return nil
 }
 
 func (w webrtcNetConn) SetReadDeadline(t time.Time) error {
+       w.Span.AddEvent("SetReadDeadline", trace.WithAttributes(attribute.String("time", t.String())))
        return nil
 }
 
 func (w webrtcNetConn) SetWriteDeadline(t time.Time) error {
+       w.Span.AddEvent("SetWriteDeadline", trace.WithAttributes(attribute.String("time", t.String())))
        return nil
 }
+
+func (w webrtcNetConn) Read(b []byte) (n int, err error) {
+       _, span := otel.Tracer(tracerName).Start(w.Context, "Read")
+       defer span.End()
+       span.SetAttributes(attribute.Int("buf_len", len(b)))
+       n, err = w.ReadWriteCloser.Read(b)
+       span.RecordError(err)
+       span.SetAttributes(attribute.Int("bytes_read", n))
+       return
+}