Files
go2rtc/pkg/wyze/tutk/dtls.go
T
2026-01-17 12:09:38 +01:00

121 lines
2.7 KiB
Go

package tutk
import (
"net"
"sync"
"time"
"github.com/pion/dtls/v3"
)
func NewDtlsClient(c *Conn, channel uint8, psk []byte) (*dtls.Conn, error) {
adapter := &ChannelAdapter{conn: c, channel: channel}
return dtls.Client(adapter, c.addr, buildDtlsConfig(psk, false))
}
func NewDtlsServer(c *Conn, channel uint8, psk []byte) (*dtls.Conn, error) {
adapter := &ChannelAdapter{conn: c, channel: channel}
return dtls.Server(adapter, c.addr, buildDtlsConfig(psk, true))
}
func buildDtlsConfig(psk []byte, isServer bool) *dtls.Config {
config := &dtls.Config{
PSK: func(hint []byte) ([]byte, error) {
return psk, nil
},
PSKIdentityHint: []byte(PSKIdentity),
InsecureSkipVerify: true,
InsecureSkipVerifyHello: true,
MTU: 1200,
FlightInterval: 300 * time.Millisecond,
ExtendedMasterSecret: dtls.DisableExtendedMasterSecret,
}
if isServer {
config.CipherSuites = []dtls.CipherSuiteID{dtls.TLS_PSK_WITH_AES_128_CBC_SHA256}
} else {
config.CustomCipherSuites = CustomCipherSuites
}
return config
}
type ChannelAdapter struct {
conn *Conn
channel uint8
mu sync.Mutex
readDeadline time.Time
}
func (a *ChannelAdapter) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
var buf chan []byte
if a.channel == IOTCChannelMain {
buf = a.conn.clientBuf
} else {
buf = a.conn.serverBuf
}
a.mu.Lock()
deadline := a.readDeadline
a.mu.Unlock()
if !deadline.IsZero() {
timeout := time.Until(deadline)
if timeout <= 0 {
return 0, nil, &timeoutError{}
}
timer := time.NewTimer(timeout)
defer timer.Stop()
select {
case data := <-buf:
return copy(p, data), a.conn.addr, nil
case <-timer.C:
return 0, nil, &timeoutError{}
case <-a.conn.ctx.Done():
return 0, nil, net.ErrClosed
}
}
select {
case data := <-buf:
return copy(p, data), a.conn.addr, nil
case <-a.conn.ctx.Done():
return 0, nil, net.ErrClosed
}
}
func (a *ChannelAdapter) WriteTo(p []byte, _ net.Addr) (int, error) {
if err := a.conn.WriteDTLS(p, a.channel); err != nil {
return 0, err
}
return len(p), nil
}
func (a *ChannelAdapter) Close() error { return nil }
func (a *ChannelAdapter) LocalAddr() net.Addr { return &net.UDPAddr{} }
func (a *ChannelAdapter) SetDeadline(t time.Time) error {
a.mu.Lock()
a.readDeadline = t
a.mu.Unlock()
return nil
}
func (a *ChannelAdapter) SetReadDeadline(t time.Time) error {
a.mu.Lock()
a.readDeadline = t
a.mu.Unlock()
return nil
}
func (a *ChannelAdapter) SetWriteDeadline(time.Time) error { return nil }
type timeoutError struct{}
func (e *timeoutError) Error() string { return "i/o timeout" }
func (e *timeoutError) Timeout() bool { return true }
func (e *timeoutError) Temporary() bool { return true }