feat: Waku v2 bridge

Issue #12610
This commit is contained in:
Michal Iskierko
2023-11-12 13:29:38 +01:00
parent 56e7bd01ca
commit 6d31343205
6716 changed files with 1982502 additions and 5891 deletions

View File

@@ -0,0 +1,75 @@
package mux
import (
"errors"
"io"
"net"
"time"
"github.com/pion/ice/v2"
"github.com/pion/transport/packetio"
)
// Endpoint implements net.Conn. It is used to read muxed packets.
type Endpoint struct {
mux *Mux
buffer *packetio.Buffer
}
// Close unregisters the endpoint from the Mux
func (e *Endpoint) Close() (err error) {
err = e.close()
if err != nil {
return err
}
e.mux.RemoveEndpoint(e)
return nil
}
func (e *Endpoint) close() error {
return e.buffer.Close()
}
// Read reads a packet of len(p) bytes from the underlying conn
// that are matched by the associated MuxFunc
func (e *Endpoint) Read(p []byte) (int, error) {
return e.buffer.Read(p)
}
// Write writes len(p) bytes to the underlying conn
func (e *Endpoint) Write(p []byte) (int, error) {
n, err := e.mux.nextConn.Write(p)
if errors.Is(err, ice.ErrNoCandidatePairs) {
return 0, nil
} else if errors.Is(err, ice.ErrClosed) {
return 0, io.ErrClosedPipe
}
return n, err
}
// LocalAddr is a stub
func (e *Endpoint) LocalAddr() net.Addr {
return e.mux.nextConn.LocalAddr()
}
// RemoteAddr is a stub
func (e *Endpoint) RemoteAddr() net.Addr {
return e.mux.nextConn.RemoteAddr()
}
// SetDeadline is a stub
func (e *Endpoint) SetDeadline(t time.Time) error {
return nil
}
// SetReadDeadline is a stub
func (e *Endpoint) SetReadDeadline(t time.Time) error {
return nil
}
// SetWriteDeadline is a stub
func (e *Endpoint) SetWriteDeadline(t time.Time) error {
return nil
}

155
vendor/github.com/pion/webrtc/v3/internal/mux/mux.go generated vendored Normal file
View File

@@ -0,0 +1,155 @@
// Package mux multiplexes packets on a single socket (RFC7983)
package mux
import (
"errors"
"io"
"net"
"sync"
"github.com/pion/ice/v2"
"github.com/pion/logging"
"github.com/pion/transport/packetio"
)
// The maximum amount of data that can be buffered before returning errors.
const maxBufferSize = 1000 * 1000 // 1MB
// Config collects the arguments to mux.Mux construction into
// a single structure
type Config struct {
Conn net.Conn
BufferSize int
LoggerFactory logging.LoggerFactory
}
// Mux allows multiplexing
type Mux struct {
lock sync.RWMutex
nextConn net.Conn
endpoints map[*Endpoint]MatchFunc
bufferSize int
closedCh chan struct{}
log logging.LeveledLogger
}
// NewMux creates a new Mux
func NewMux(config Config) *Mux {
m := &Mux{
nextConn: config.Conn,
endpoints: make(map[*Endpoint]MatchFunc),
bufferSize: config.BufferSize,
closedCh: make(chan struct{}),
log: config.LoggerFactory.NewLogger("mux"),
}
go m.readLoop()
return m
}
// NewEndpoint creates a new Endpoint
func (m *Mux) NewEndpoint(f MatchFunc) *Endpoint {
e := &Endpoint{
mux: m,
buffer: packetio.NewBuffer(),
}
// Set a maximum size of the buffer in bytes.
// NOTE: We actually won't get anywhere close to this limit.
// SRTP will constantly read from the endpoint and drop packets if it's full.
e.buffer.SetLimitSize(maxBufferSize)
m.lock.Lock()
m.endpoints[e] = f
m.lock.Unlock()
return e
}
// RemoveEndpoint removes an endpoint from the Mux
func (m *Mux) RemoveEndpoint(e *Endpoint) {
m.lock.Lock()
defer m.lock.Unlock()
delete(m.endpoints, e)
}
// Close closes the Mux and all associated Endpoints.
func (m *Mux) Close() error {
m.lock.Lock()
for e := range m.endpoints {
err := e.close()
if err != nil {
return err
}
delete(m.endpoints, e)
}
m.lock.Unlock()
err := m.nextConn.Close()
if err != nil {
return err
}
// Wait for readLoop to end
<-m.closedCh
return nil
}
func (m *Mux) readLoop() {
defer func() {
close(m.closedCh)
}()
buf := make([]byte, m.bufferSize)
for {
n, err := m.nextConn.Read(buf)
switch {
case errors.Is(err, io.EOF), errors.Is(err, ice.ErrClosed):
return
case errors.Is(err, io.ErrShortBuffer), errors.Is(err, packetio.ErrTimeout):
m.log.Errorf("mux: failed to read from packetio.Buffer %s\n", err.Error())
continue
case err != nil:
m.log.Errorf("mux: ending readLoop packetio.Buffer error %s\n", err.Error())
return
}
if err = m.dispatch(buf[:n]); err != nil {
m.log.Errorf("mux: ending readLoop dispatch error %s\n", err.Error())
return
}
}
}
func (m *Mux) dispatch(buf []byte) error {
var endpoint *Endpoint
m.lock.Lock()
for e, f := range m.endpoints {
if f(buf) {
endpoint = e
break
}
}
m.lock.Unlock()
if endpoint == nil {
if len(buf) > 0 {
m.log.Warnf("Warning: mux: no endpoint for packet starting with %d\n", buf[0])
} else {
m.log.Warnf("Warning: mux: no endpoint for zero length packet")
}
return nil
}
_, err := endpoint.buffer.Write(buf)
if err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,62 @@
package mux
// MatchFunc allows custom logic for mapping packets to an Endpoint
type MatchFunc func([]byte) bool
// MatchAll always returns true
func MatchAll(b []byte) bool {
return true
}
// MatchRange returns true if the first byte of buf is in [lower..upper]
func MatchRange(lower, upper byte, buf []byte) bool {
if len(buf) < 1 {
return false
}
b := buf[0]
return b >= lower && b <= upper
}
// MatchFuncs as described in RFC7983
// https://tools.ietf.org/html/rfc7983
// +----------------+
// | [0..3] -+--> forward to STUN
// | |
// | [16..19] -+--> forward to ZRTP
// | |
// packet --> | [20..63] -+--> forward to DTLS
// | |
// | [64..79] -+--> forward to TURN Channel
// | |
// | [128..191] -+--> forward to RTP/RTCP
// +----------------+
// MatchDTLS is a MatchFunc that accepts packets with the first byte in [20..63]
// as defied in RFC7983
func MatchDTLS(b []byte) bool {
return MatchRange(20, 63, b)
}
// MatchSRTPOrSRTCP is a MatchFunc that accepts packets with the first byte in [128..191]
// as defied in RFC7983
func MatchSRTPOrSRTCP(b []byte) bool {
return MatchRange(128, 191, b)
}
func isRTCP(buf []byte) bool {
// Not long enough to determine RTP/RTCP
if len(buf) < 4 {
return false
}
return buf[1] >= 192 && buf[1] <= 223
}
// MatchSRTP is a MatchFunc that only matches SRTP and not SRTCP
func MatchSRTP(buf []byte) bool {
return MatchSRTPOrSRTCP(buf) && !isRTCP(buf)
}
// MatchSRTCP is a MatchFunc that only matches SRTCP and not SRTP
func MatchSRTCP(buf []byte) bool {
return MatchSRTPOrSRTCP(buf) && isRTCP(buf)
}