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"
)
}
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
+}