webrtc.go 2.3 KB

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