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

24
vendor/github.com/pion/datachannel/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,24 @@
### JetBrains IDE ###
#####################
.idea/
### Emacs Temporary Files ###
#############################
*~
### Folders ###
###############
bin/
vendor/
node_modules/
### Files ###
#############
*.ivf
*.ogg
tags
cover.out
*.sw[poe]
*.wasm
examples/sfu-ws/cert.pem
examples/sfu-ws/key.pem

89
vendor/github.com/pion/datachannel/.golangci.yml generated vendored Normal file
View File

@@ -0,0 +1,89 @@
linters-settings:
govet:
check-shadowing: true
misspell:
locale: US
exhaustive:
default-signifies-exhaustive: true
gomodguard:
blocked:
modules:
- github.com/pkg/errors:
recommendations:
- errors
linters:
enable:
- asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers
- bodyclose # checks whether HTTP response body is closed successfully
- deadcode # Finds unused code
- depguard # Go linter that checks if package imports are in a list of acceptable packages
- dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())
- dupl # Tool for code clone detection
- errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases
- exhaustive # check exhaustiveness of enum switch statements
- exportloopref # checks for pointers to enclosing loop variables
- gci # Gci control golang package import order and make it always deterministic.
- gochecknoglobals # Checks that no globals are present in Go code
- gochecknoinits # Checks that no init functions are present in Go code
- gocognit # Computes and checks the cognitive complexity of functions
- goconst # Finds repeated strings that could be replaced by a constant
- gocritic # The most opinionated Go source code linter
- godox # Tool for detection of FIXME, TODO and other comment keywords
- goerr113 # Golang linter to check the errors handling expressions
- gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification
- gofumpt # Gofumpt checks whether code was gofumpt-ed.
- goheader # Checks is file header matches to pattern
- goimports # Goimports does everything that gofmt does. Additionally it checks unused imports
- golint # Golint differs from gofmt. Gofmt reformats Go source code, whereas golint prints out style mistakes
- gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations.
- goprintffuncname # Checks that printf-like functions are named with `f` at the end
- gosec # Inspects source code for security problems
- gosimple # Linter for Go source code that specializes in simplifying a code
- govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string
- ineffassign # Detects when assignments to existing variables are not used
- misspell # Finds commonly misspelled English words in comments
- nakedret # Finds naked returns in functions greater than a specified function length
- noctx # noctx finds sending http request without context.Context
- scopelint # Scopelint checks for unpinned variables in go programs
- staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks
- structcheck # Finds unused struct fields
- stylecheck # Stylecheck is a replacement for golint
- typecheck # Like the front-end of a Go compiler, parses and type-checks Go code
- unconvert # Remove unnecessary type conversions
- unparam # Reports unused function parameters
- unused # Checks Go code for unused constants, variables, functions and types
- varcheck # Finds unused global variables and constants
- whitespace # Tool for detection of leading and trailing whitespace
disable:
- funlen # Tool for detection of long functions
- gocyclo # Computes and checks the cyclomatic complexity of functions
- godot # Check if comments end in a period
- gomnd # An analyzer to detect magic numbers.
- lll # Reports long lines
- maligned # Tool to detect Go structs that would take less memory if their fields were sorted
- nestif # Reports deeply nested if statements
- nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity
- nolintlint # Reports ill-formed or insufficient nolint directives
- prealloc # Finds slice declarations that could potentially be preallocated
- rowserrcheck # checks whether Err of rows is checked successfully
- sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed.
- testpackage # linter that makes you use a separate _test package
- wsl # Whitespace Linter - Forces you to use empty lines!
issues:
exclude-use-default: false
exclude-rules:
# Allow complex tests, better to be self contained
- path: _test\.go
linters:
- gocognit
# Allow complex main function in examples
- path: examples
text: "of func `main` is high"
linters:
- gocognit
run:
skip-dirs-use-default: false

16
vendor/github.com/pion/datachannel/AUTHORS.txt generated vendored Normal file
View File

@@ -0,0 +1,16 @@
# Thank you to everyone that made Pion possible. If you are interested in contributing
# we would love to have you https://github.com/pion/webrtc/wiki/Contributing
#
# This file is auto generated, using git to list all individuals contributors.
# see `.github/generate-authors.sh` for the scripting
Atsushi Watanabe <atsushi.w@ieee.org>
backkem <mail@backkem.me>
Benny Daon <benny@tuzig.com>
Eric Daniels <eric@erdaniels.com>
Hugo Arregui <hugo.arregui@gmail.com>
Hugo Arregui <hugo@decentraland.org>
John Bradley <jrb@turrettech.com>
Norman Rasmussen <norman@rasmussen.co.za>
Sean DuBois <seaduboi@amazon.com>
Sean DuBois <sean@siobud.com>
Yutaka Takeda <yt0916@gmail.com>

20
vendor/github.com/pion/datachannel/DESIGN.md generated vendored Normal file
View File

@@ -0,0 +1,20 @@
<h1 align="center">
Design
</h1>
### Portable
Pion Data Channels is written in Go and extremely portable. Anywhere Golang runs, Pion Data Channels should work as well! Instead of dealing with complicated
cross-compiling of multiple libraries, you now can run anywhere with one `go build`
### Simple API
The API is based on an io.ReadWriteCloser.
### Readable
If code comes from an RFC we try to make sure everything is commented with a link to the spec.
This makes learning and debugging easier, this library was written to also serve as a guide for others.
### Tested
Every commit is tested via travis-ci Go provides fantastic facilities for testing, and more will be added as time goes on.
### Shared libraries
Every pion product is built using shared libraries, allowing others to review and reuse our libraries.

21
vendor/github.com/pion/datachannel/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

37
vendor/github.com/pion/datachannel/README.md generated vendored Normal file
View File

@@ -0,0 +1,37 @@
<h1 align="center">
<br>
Pion Data Channels
<br>
</h1>
<h4 align="center">A Go implementation of WebRTC Data Channels</h4>
<p align="center">
<a href="https://pion.ly"><img src="https://img.shields.io/badge/pion-datachannel-gray.svg?longCache=true&colorB=brightgreen" alt="Pion Data Channels"></a>
<!--<a href="https://sourcegraph.com/github.com/pion/webrtc?badge"><img src="https://sourcegraph.com/github.com/pion/webrtc/-/badge.svg" alt="Sourcegraph Widget"></a>-->
<a href="https://pion.ly/slack"><img src="https://img.shields.io/badge/join-us%20on%20slack-gray.svg?longCache=true&logo=slack&colorB=brightgreen" alt="Slack Widget"></a>
<br>
<a href="https://travis-ci.org/pion/datachannel"><img src="https://travis-ci.org/pion/datachannel.svg?branch=master" alt="Build Status"></a>
<a href="https://pkg.go.dev/github.com/pion/datachannel"><img src="https://godoc.org/github.com/pion/datachannel?status.svg" alt="GoDoc"></a>
<a href="https://codecov.io/gh/pion/datachannel"><img src="https://codecov.io/gh/pion/datachannel/branch/master/graph/badge.svg" alt="Coverage Status"></a>
<a href="https://goreportcard.com/report/github.com/pion/datachannel"><img src="https://goreportcard.com/badge/github.com/pion/datachannel" alt="Go Report Card"></a>
<!--<a href="https://www.codacy.com/app/Sean-Der/webrtc"><img src="https://api.codacy.com/project/badge/Grade/18f4aec384894e6aac0b94effe51961d" alt="Codacy Badge"></a>-->
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
</p>
<br>
See [DESIGN.md](DESIGN.md) for an overview of features and future goals.
### Roadmap
The library is used as a part of our WebRTC implementation. Please refer to that [roadmap](https://github.com/pion/webrtc/issues/9) to track our major milestones.
### Community
Pion has an active community on the [Golang Slack](https://invite.slack.golangbridge.org/). Sign up and join the **#pion** channel for discussions and support. You can also use [Pion mailing list](https://groups.google.com/forum/#!forum/pion).
We are always looking to support **your projects**. Please reach out if you have something to build!
If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly)
### Contributing
Check out the **[contributing wiki](https://github.com/pion/webrtc/wiki/Contributing)** to join the group of amazing people making this project possible:
### License
MIT License - see [LICENSE](LICENSE) for full text

20
vendor/github.com/pion/datachannel/codecov.yml generated vendored Normal file
View File

@@ -0,0 +1,20 @@
#
# DO NOT EDIT THIS FILE
#
# It is automatically copied from https://github.com/pion/.goassets repository.
#
coverage:
status:
project:
default:
# Allow decreasing 2% of total coverage to avoid noise.
threshold: 2%
patch:
default:
target: 70%
only_pulls: true
ignore:
- "examples/*"
- "examples/**/*"

391
vendor/github.com/pion/datachannel/datachannel.go generated vendored Normal file
View File

@@ -0,0 +1,391 @@
// Package datachannel implements WebRTC Data Channels
package datachannel
import (
"fmt"
"io"
"sync"
"sync/atomic"
"github.com/pion/logging"
"github.com/pion/sctp"
)
const receiveMTU = 8192
// Reader is an extended io.Reader
// that also returns if the message is text.
type Reader interface {
ReadDataChannel([]byte) (int, bool, error)
}
// Writer is an extended io.Writer
// that also allows indicating if a message is text.
type Writer interface {
WriteDataChannel([]byte, bool) (int, error)
}
// ReadWriteCloser is an extended io.ReadWriteCloser
// that also implements our Reader and Writer.
type ReadWriteCloser interface {
io.Reader
io.Writer
Reader
Writer
io.Closer
}
// DataChannel represents a data channel
type DataChannel struct {
Config
// stats
messagesSent uint32
messagesReceived uint32
bytesSent uint64
bytesReceived uint64
mu sync.Mutex
onOpenCompleteHandler func()
openCompleteHandlerOnce sync.Once
stream *sctp.Stream
log logging.LeveledLogger
}
// Config is used to configure the data channel.
type Config struct {
ChannelType ChannelType
Negotiated bool
Priority uint16
ReliabilityParameter uint32
Label string
Protocol string
LoggerFactory logging.LoggerFactory
}
func newDataChannel(stream *sctp.Stream, config *Config) (*DataChannel, error) {
return &DataChannel{
Config: *config,
stream: stream,
log: config.LoggerFactory.NewLogger("datachannel"),
}, nil
}
// Dial opens a data channels over SCTP
func Dial(a *sctp.Association, id uint16, config *Config) (*DataChannel, error) {
stream, err := a.OpenStream(id, sctp.PayloadTypeWebRTCBinary)
if err != nil {
return nil, err
}
dc, err := Client(stream, config)
if err != nil {
return nil, err
}
return dc, nil
}
// Client opens a data channel over an SCTP stream
func Client(stream *sctp.Stream, config *Config) (*DataChannel, error) {
msg := &channelOpen{
ChannelType: config.ChannelType,
Priority: config.Priority,
ReliabilityParameter: config.ReliabilityParameter,
Label: []byte(config.Label),
Protocol: []byte(config.Protocol),
}
if !config.Negotiated {
rawMsg, err := msg.Marshal()
if err != nil {
return nil, fmt.Errorf("failed to marshal ChannelOpen %w", err)
}
if _, err = stream.WriteSCTP(rawMsg, sctp.PayloadTypeWebRTCDCEP); err != nil {
return nil, fmt.Errorf("failed to send ChannelOpen %w", err)
}
}
return newDataChannel(stream, config)
}
// Accept is used to accept incoming data channels over SCTP
func Accept(a *sctp.Association, config *Config, existingChannels ...*DataChannel) (*DataChannel, error) {
stream, err := a.AcceptStream()
if err != nil {
return nil, err
}
for _, ch := range existingChannels {
if ch.StreamIdentifier() == stream.StreamIdentifier() {
ch.stream.SetDefaultPayloadType(sctp.PayloadTypeWebRTCBinary)
return ch, nil
}
}
stream.SetDefaultPayloadType(sctp.PayloadTypeWebRTCBinary)
dc, err := Server(stream, config)
if err != nil {
return nil, err
}
return dc, nil
}
// Server accepts a data channel over an SCTP stream
func Server(stream *sctp.Stream, config *Config) (*DataChannel, error) {
buffer := make([]byte, receiveMTU)
n, ppi, err := stream.ReadSCTP(buffer)
if err != nil {
return nil, err
}
if ppi != sctp.PayloadTypeWebRTCDCEP {
return nil, fmt.Errorf("%w %s", ErrInvalidPayloadProtocolIdentifier, ppi)
}
openMsg, err := parseExpectDataChannelOpen(buffer[:n])
if err != nil {
return nil, fmt.Errorf("failed to parse DataChannelOpen packet %w", err)
}
config.ChannelType = openMsg.ChannelType
config.Priority = openMsg.Priority
config.ReliabilityParameter = openMsg.ReliabilityParameter
config.Label = string(openMsg.Label)
config.Protocol = string(openMsg.Protocol)
dataChannel, err := newDataChannel(stream, config)
if err != nil {
return nil, err
}
err = dataChannel.writeDataChannelAck()
if err != nil {
return nil, err
}
err = dataChannel.commitReliabilityParams()
if err != nil {
return nil, err
}
return dataChannel, nil
}
// Read reads a packet of len(p) bytes as binary data
func (c *DataChannel) Read(p []byte) (int, error) {
n, _, err := c.ReadDataChannel(p)
return n, err
}
// ReadDataChannel reads a packet of len(p) bytes
func (c *DataChannel) ReadDataChannel(p []byte) (int, bool, error) {
for {
n, ppi, err := c.stream.ReadSCTP(p)
if err == io.EOF {
// When the peer sees that an incoming stream was
// reset, it also resets its corresponding outgoing stream.
if closeErr := c.stream.Close(); closeErr != nil {
return 0, false, closeErr
}
}
if err != nil {
return 0, false, err
}
if ppi == sctp.PayloadTypeWebRTCDCEP {
if err = c.handleDCEP(p[:n]); err != nil {
c.log.Errorf("Failed to handle DCEP: %s", err.Error())
}
continue
} else if ppi == sctp.PayloadTypeWebRTCBinaryEmpty || ppi == sctp.PayloadTypeWebRTCStringEmpty {
n = 0
}
atomic.AddUint32(&c.messagesReceived, 1)
atomic.AddUint64(&c.bytesReceived, uint64(n))
isString := ppi == sctp.PayloadTypeWebRTCString || ppi == sctp.PayloadTypeWebRTCStringEmpty
return n, isString, err
}
}
// MessagesSent returns the number of messages sent
func (c *DataChannel) MessagesSent() uint32 {
return atomic.LoadUint32(&c.messagesSent)
}
// MessagesReceived returns the number of messages received
func (c *DataChannel) MessagesReceived() uint32 {
return atomic.LoadUint32(&c.messagesReceived)
}
// OnOpen sets an event handler which is invoked when
// a DATA_CHANNEL_ACK message is received.
// The handler is called only on thefor the channel opened
// https://datatracker.ietf.org/doc/html/draft-ietf-rtcweb-data-protocol-09#section-5.2
func (c *DataChannel) OnOpen(f func()) {
c.mu.Lock()
c.openCompleteHandlerOnce = sync.Once{}
c.onOpenCompleteHandler = f
c.mu.Unlock()
}
func (c *DataChannel) onOpenComplete() {
c.mu.Lock()
hdlr := c.onOpenCompleteHandler
c.mu.Unlock()
if hdlr != nil {
go c.openCompleteHandlerOnce.Do(func() {
hdlr()
})
}
}
// BytesSent returns the number of bytes sent
func (c *DataChannel) BytesSent() uint64 {
return atomic.LoadUint64(&c.bytesSent)
}
// BytesReceived returns the number of bytes received
func (c *DataChannel) BytesReceived() uint64 {
return atomic.LoadUint64(&c.bytesReceived)
}
// StreamIdentifier returns the Stream identifier associated to the stream.
func (c *DataChannel) StreamIdentifier() uint16 {
return c.stream.StreamIdentifier()
}
func (c *DataChannel) handleDCEP(data []byte) error {
msg, err := parse(data)
if err != nil {
return fmt.Errorf("failed to parse DataChannel packet %w", err)
}
switch msg := msg.(type) {
case *channelAck:
c.log.Debug("Received DATA_CHANNEL_ACK")
if err = c.commitReliabilityParams(); err != nil {
return err
}
c.onOpenComplete()
default:
return fmt.Errorf("%w %v", ErrInvalidMessageType, msg)
}
return nil
}
// Write writes len(p) bytes from p as binary data
func (c *DataChannel) Write(p []byte) (n int, err error) {
return c.WriteDataChannel(p, false)
}
// WriteDataChannel writes len(p) bytes from p
func (c *DataChannel) WriteDataChannel(p []byte, isString bool) (n int, err error) {
// https://tools.ietf.org/html/draft-ietf-rtcweb-data-channel-12#section-6.6
// SCTP does not support the sending of empty user messages. Therefore,
// if an empty message has to be sent, the appropriate PPID (WebRTC
// String Empty or WebRTC Binary Empty) is used and the SCTP user
// message of one zero byte is sent. When receiving an SCTP user
// message with one of these PPIDs, the receiver MUST ignore the SCTP
// user message and process it as an empty message.
var ppi sctp.PayloadProtocolIdentifier
switch {
case !isString && len(p) > 0:
ppi = sctp.PayloadTypeWebRTCBinary
case !isString && len(p) == 0:
ppi = sctp.PayloadTypeWebRTCBinaryEmpty
case isString && len(p) > 0:
ppi = sctp.PayloadTypeWebRTCString
case isString && len(p) == 0:
ppi = sctp.PayloadTypeWebRTCStringEmpty
}
atomic.AddUint32(&c.messagesSent, 1)
atomic.AddUint64(&c.bytesSent, uint64(len(p)))
if len(p) == 0 {
_, err := c.stream.WriteSCTP([]byte{0}, ppi)
return 0, err
}
return c.stream.WriteSCTP(p, ppi)
}
func (c *DataChannel) writeDataChannelAck() error {
ack := channelAck{}
ackMsg, err := ack.Marshal()
if err != nil {
return fmt.Errorf("failed to marshal ChannelOpen ACK: %w", err)
}
if _, err = c.stream.WriteSCTP(ackMsg, sctp.PayloadTypeWebRTCDCEP); err != nil {
return fmt.Errorf("failed to send ChannelOpen ACK: %w", err)
}
return err
}
// Close closes the DataChannel and the underlying SCTP stream.
func (c *DataChannel) Close() error {
// https://tools.ietf.org/html/draft-ietf-rtcweb-data-channel-13#section-6.7
// Closing of a data channel MUST be signaled by resetting the
// corresponding outgoing streams [RFC6525]. This means that if one
// side decides to close the data channel, it resets the corresponding
// outgoing stream. When the peer sees that an incoming stream was
// reset, it also resets its corresponding outgoing stream. Once this
// is completed, the data channel is closed. Resetting a stream sets
// the Stream Sequence Numbers (SSNs) of the stream back to 'zero' with
// a corresponding notification to the application layer that the reset
// has been performed. Streams are available for reuse after a reset
// has been performed.
return c.stream.Close()
}
// BufferedAmount returns the number of bytes of data currently queued to be
// sent over this stream.
func (c *DataChannel) BufferedAmount() uint64 {
return c.stream.BufferedAmount()
}
// BufferedAmountLowThreshold returns the number of bytes of buffered outgoing
// data that is considered "low." Defaults to 0.
func (c *DataChannel) BufferedAmountLowThreshold() uint64 {
return c.stream.BufferedAmountLowThreshold()
}
// SetBufferedAmountLowThreshold is used to update the threshold.
// See BufferedAmountLowThreshold().
func (c *DataChannel) SetBufferedAmountLowThreshold(th uint64) {
c.stream.SetBufferedAmountLowThreshold(th)
}
// OnBufferedAmountLow sets the callback handler which would be called when the
// number of bytes of outgoing data buffered is lower than the threshold.
func (c *DataChannel) OnBufferedAmountLow(f func()) {
c.stream.OnBufferedAmountLow(f)
}
func (c *DataChannel) commitReliabilityParams() error {
switch c.Config.ChannelType {
case ChannelTypeReliable:
c.stream.SetReliabilityParams(false, sctp.ReliabilityTypeReliable, c.Config.ReliabilityParameter)
case ChannelTypeReliableUnordered:
c.stream.SetReliabilityParams(true, sctp.ReliabilityTypeReliable, c.Config.ReliabilityParameter)
case ChannelTypePartialReliableRexmit:
c.stream.SetReliabilityParams(false, sctp.ReliabilityTypeRexmit, c.Config.ReliabilityParameter)
case ChannelTypePartialReliableRexmitUnordered:
c.stream.SetReliabilityParams(true, sctp.ReliabilityTypeRexmit, c.Config.ReliabilityParameter)
case ChannelTypePartialReliableTimed:
c.stream.SetReliabilityParams(false, sctp.ReliabilityTypeTimed, c.Config.ReliabilityParameter)
case ChannelTypePartialReliableTimedUnordered:
c.stream.SetReliabilityParams(true, sctp.ReliabilityTypeTimed, c.Config.ReliabilityParameter)
default:
return fmt.Errorf("%w %v", ErrInvalidChannelType, c.Config.ChannelType)
}
return nil
}

24
vendor/github.com/pion/datachannel/errors.go generated vendored Normal file
View File

@@ -0,0 +1,24 @@
package datachannel
import "errors"
var (
// ErrDataChannelMessageTooShort means that the data isn't long enough to be a valid DataChannel message
ErrDataChannelMessageTooShort = errors.New("DataChannel message is not long enough to determine type")
// ErrInvalidPayloadProtocolIdentifier means that we got a DataChannel messages with a Payload Protocol Identifier
// we don't know how to handle
ErrInvalidPayloadProtocolIdentifier = errors.New("DataChannel message Payload Protocol Identifier is value we can't handle")
// ErrInvalidChannelType means that the remote requested a channel type that we don't support
ErrInvalidChannelType = errors.New("invalid Channel Type")
// ErrInvalidMessageType is returned when a DataChannel Message has a type we don't support
ErrInvalidMessageType = errors.New("invalid Message Type")
// ErrExpectedAndActualLengthMismatch is when the declared length and actual length don't match
ErrExpectedAndActualLengthMismatch = errors.New("expected and actual length do not match")
// ErrUnexpectedDataChannelType is when a message type does not match the expected type
ErrUnexpectedDataChannelType = errors.New("expected and actual message type does not match")
)

73
vendor/github.com/pion/datachannel/message.go generated vendored Normal file
View File

@@ -0,0 +1,73 @@
package datachannel
import (
"fmt"
)
// message is a parsed DataChannel message
type message interface {
Marshal() ([]byte, error)
Unmarshal([]byte) error
}
// messageType is the first byte in a DataChannel message that specifies type
type messageType byte
// DataChannel Message Types
const (
dataChannelAck messageType = 0x02
dataChannelOpen messageType = 0x03
)
func (t messageType) String() string {
switch t {
case dataChannelAck:
return "DataChannelAck"
case dataChannelOpen:
return "DataChannelOpen"
default:
return fmt.Sprintf("Unknown MessageType: %d", t)
}
}
// parse accepts raw input and returns a DataChannel message
func parse(raw []byte) (message, error) {
if len(raw) == 0 {
return nil, ErrDataChannelMessageTooShort
}
var msg message
switch messageType(raw[0]) {
case dataChannelOpen:
msg = &channelOpen{}
case dataChannelAck:
msg = &channelAck{}
default:
return nil, fmt.Errorf("%w %v", ErrInvalidMessageType, messageType(raw[0]))
}
if err := msg.Unmarshal(raw); err != nil {
return nil, err
}
return msg, nil
}
// parseExpectDataChannelOpen parses a DataChannelOpen message
// or throws an error
func parseExpectDataChannelOpen(raw []byte) (*channelOpen, error) {
if len(raw) == 0 {
return nil, ErrDataChannelMessageTooShort
}
if actualTyp := messageType(raw[0]); actualTyp != dataChannelOpen {
return nil, fmt.Errorf("%w expected(%s) actual(%s)", ErrUnexpectedDataChannelType, actualTyp, dataChannelOpen)
}
msg := &channelOpen{}
if err := msg.Unmarshal(raw); err != nil {
return nil, err
}
return msg, nil
}

View File

@@ -0,0 +1,22 @@
package datachannel
// channelAck is used to ACK a DataChannel open
type channelAck struct{}
const (
channelOpenAckLength = 4
)
// Marshal returns raw bytes for the given message
func (c *channelAck) Marshal() ([]byte, error) {
raw := make([]byte, channelOpenAckLength)
raw[0] = uint8(dataChannelAck)
return raw, nil
}
// Unmarshal populates the struct with the given raw data
func (c *channelAck) Unmarshal(raw []byte) error {
// Message type already checked in Parse and there is no further data
return nil
}

View File

@@ -0,0 +1,122 @@
package datachannel
import (
"encoding/binary"
"fmt"
)
/*
channelOpen represents a DATA_CHANNEL_OPEN Message
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Message Type | Channel Type | Priority |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reliability Parameter |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Label Length | Protocol Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| Label |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| Protocol |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
type channelOpen struct {
ChannelType ChannelType
Priority uint16
ReliabilityParameter uint32
Label []byte
Protocol []byte
}
const (
channelOpenHeaderLength = 12
)
// ChannelType determines the reliability of the WebRTC DataChannel
type ChannelType byte
// ChannelType enums
const (
// ChannelTypeReliable determines the Data Channel provides a
// reliable in-order bi-directional communication.
ChannelTypeReliable ChannelType = 0x00
// ChannelTypeReliableUnordered determines the Data Channel
// provides a reliable unordered bi-directional communication.
ChannelTypeReliableUnordered ChannelType = 0x80
// ChannelTypePartialReliableRexmit determines the Data Channel
// provides a partially-reliable in-order bi-directional communication.
// User messages will not be retransmitted more times than specified in the Reliability Parameter.
ChannelTypePartialReliableRexmit ChannelType = 0x01
// ChannelTypePartialReliableRexmitUnordered determines
// the Data Channel provides a partial reliable unordered bi-directional communication.
// User messages will not be retransmitted more times than specified in the Reliability Parameter.
ChannelTypePartialReliableRexmitUnordered ChannelType = 0x81
// ChannelTypePartialReliableTimed determines the Data Channel
// provides a partial reliable in-order bi-directional communication.
// User messages might not be transmitted or retransmitted after
// a specified life-time given in milli- seconds in the Reliability Parameter.
// This life-time starts when providing the user message to the protocol stack.
ChannelTypePartialReliableTimed ChannelType = 0x02
// The Data Channel provides a partial reliable unordered bi-directional
// communication. User messages might not be transmitted or retransmitted
// after a specified life-time given in milli- seconds in the Reliability Parameter.
// This life-time starts when providing the user message to the protocol stack.
ChannelTypePartialReliableTimedUnordered ChannelType = 0x82
)
// ChannelPriority enums
const (
ChannelPriorityBelowNormal uint16 = 128
ChannelPriorityNormal uint16 = 256
ChannelPriorityHigh uint16 = 512
ChannelPriorityExtraHigh uint16 = 1024
)
// Marshal returns raw bytes for the given message
func (c *channelOpen) Marshal() ([]byte, error) {
labelLength := len(c.Label)
protocolLength := len(c.Protocol)
totalLen := channelOpenHeaderLength + labelLength + protocolLength
raw := make([]byte, totalLen)
raw[0] = uint8(dataChannelOpen)
raw[1] = byte(c.ChannelType)
binary.BigEndian.PutUint16(raw[2:], c.Priority)
binary.BigEndian.PutUint32(raw[4:], c.ReliabilityParameter)
binary.BigEndian.PutUint16(raw[8:], uint16(labelLength))
binary.BigEndian.PutUint16(raw[10:], uint16(protocolLength))
endLabel := channelOpenHeaderLength + labelLength
copy(raw[channelOpenHeaderLength:endLabel], c.Label)
copy(raw[endLabel:endLabel+protocolLength], c.Protocol)
return raw, nil
}
// Unmarshal populates the struct with the given raw data
func (c *channelOpen) Unmarshal(raw []byte) error {
if len(raw) < channelOpenHeaderLength {
return fmt.Errorf("%w expected(%d) actual(%d)", ErrExpectedAndActualLengthMismatch, channelOpenHeaderLength, len(raw))
}
c.ChannelType = ChannelType(raw[1])
c.Priority = binary.BigEndian.Uint16(raw[2:])
c.ReliabilityParameter = binary.BigEndian.Uint32(raw[4:])
labelLength := binary.BigEndian.Uint16(raw[8:])
protocolLength := binary.BigEndian.Uint16(raw[10:])
if expectedLen := int(channelOpenHeaderLength + labelLength + protocolLength); len(raw) != expectedLen {
return fmt.Errorf("%w expected(%d) actual(%d)", ErrExpectedAndActualLengthMismatch, expectedLen, len(raw))
}
c.Label = raw[channelOpenHeaderLength : channelOpenHeaderLength+labelLength]
c.Protocol = raw[channelOpenHeaderLength+labelLength : channelOpenHeaderLength+labelLength+protocolLength]
return nil
}

26
vendor/github.com/pion/datachannel/renovate.json generated vendored Normal file
View File

@@ -0,0 +1,26 @@
{
"extends": [
"config:base"
],
"postUpdateOptions": [
"gomodTidy"
],
"commitBody": "Generated by renovateBot",
"packageRules": [
{
"matchUpdateTypes": ["minor", "patch", "pin", "digest"],
"automerge": true
},
{
"packagePatterns": ["^golang.org/x/"],
"schedule": ["on the first day of the month"]
}
],
"ignorePaths": [
".github/workflows/generate-authors.yml",
".github/workflows/lint.yaml",
".github/workflows/renovate-go-mod-fix.yaml",
".github/workflows/test.yaml",
".github/workflows/tidy-check.yaml"
]
}