]> Sergey Matveev's repositories - btrtrc.git/blob - webrtc.go
Drop support for go 1.20
[btrtrc.git] / webrtc.go
1 package torrent
2
3 import (
4         "net"
5         "strconv"
6         "time"
7
8         "github.com/pion/datachannel"
9         "github.com/pion/webrtc/v3"
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         datachannel.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 }