This repository has been archived by the owner on Jul 12, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
config.go
142 lines (112 loc) · 3.93 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package transportc
import (
"net"
"time"
"github.com/gaukas/logging"
"github.com/pion/ice/v2"
"github.com/pion/webrtc/v3"
)
const (
MTU_DEFAULT = 1024
MAX_RECV_TIMEOUT_DEFAULT = time.Second * 10
)
// Config is the configuration for the Dialer and Listener.
type Config struct {
// CandidateNetworkTypes restricts ICE agent to gather
// on only selected types of networks.
CandidateNetworkTypes []webrtc.NetworkType
// InterfaceFilter restricts ICE agent to gather ICE candidates
// on only selected interfaces.
InterfaceFilter func(interfaceName string) (allowed bool)
// IPs includes a slice of IP addresses and one single ICE Candidate Type.
// If set, will add these IPs as ICE Candidates
IPs *NAT1To1IPs
// ListenerDTLSRole defines the DTLS role when Listening.
// MUST be either DTLSRoleClient or DTLSRoleServer, as defined in RFC4347
// DTLSRoleClient will send the ClientHello and start the handshake.
// DTLSRoleServer will wait for the ClientHello.
ListenerDTLSRole DTLSRole
Logger logging.Logger
// PortRange is the range of ports to use for the DataChannel.
PortRange *PortRange
// ReusePeerConnection indicates whether to reuse the same PeerConnection
// if possible, when Dialer dials multiple times.
//
// If set to true, Dialer.Dial() creates a new DataChannel on the same PeerConnection.
// Otherwise, Dialer.Dial() negotiates for a new PeerConnection and creates a new DataChannel on it.
ReusePeerConnection bool
// Signal offers the automatic signaling when establishing the DataChannel.
Signal Signal
Timeout time.Duration
// UDPMux allows serving multiple DataChannels over the one or more pre-established UDP socket.
UDPMux ice.UDPMux
// WebRTCConfiguration is the configuration for the underlying WebRTC PeerConnection.
WebRTCConfiguration webrtc.Configuration
}
// NewDialer creates a new Dialer from the given configuration.
func (c *Config) NewDialer() (*Dialer, error) {
settingEngine, err := c.BuildSettingEngine()
if err != nil {
return nil, err
}
if c.Logger == nil {
c.Logger = logging.DefaultStderrLogger(logging.LOG_WARN)
}
return &Dialer{
logger: c.Logger,
signal: c.Signal,
timeout: c.Timeout,
settingEngine: settingEngine,
configuration: c.WebRTCConfiguration,
reusePeerConnection: c.ReusePeerConnection,
}, nil
}
// NewListener creates a new Listener from the given configuration.
func (c *Config) NewListener() (*Listener, error) {
settingEngine, err := c.BuildSettingEngine()
if err != nil {
return nil, err
}
if c.Logger == nil {
c.Logger = logging.DefaultStderrLogger(logging.LOG_ERROR)
}
settingEngine.SetAnsweringDTLSRole(c.ListenerDTLSRole) // ignore if any error
l := &Listener{
logger: c.Logger,
signal: c.Signal,
timeout: c.Timeout,
runningStatus: LISTENER_NEW,
settingEngine: settingEngine,
configuration: c.WebRTCConfiguration,
peerConnections: make(map[uint64]*webrtc.PeerConnection),
conns: make(chan net.Conn),
closed: make(chan bool),
}
return l, nil
}
// BuildSettingEngine builds a SettingEngine from the configuration.
func (c *Config) BuildSettingEngine() (webrtc.SettingEngine, error) {
var settingEngine webrtc.SettingEngine = webrtc.SettingEngine{}
if c.IPs != nil {
settingEngine.SetNAT1To1IPs(c.IPs.IPs, c.IPs.Type)
}
if c.PortRange != nil {
err := settingEngine.SetEphemeralUDPPortRange(c.PortRange.Min, c.PortRange.Max)
if err != nil {
return webrtc.SettingEngine{}, err
}
}
if c.UDPMux != nil {
settingEngine.SetICEUDPMux(c.UDPMux)
}
if c.CandidateNetworkTypes != nil {
settingEngine.SetNetworkTypes(c.CandidateNetworkTypes)
}
if c.InterfaceFilter != nil {
settingEngine.SetInterfaceFilter(c.InterfaceFilter)
}
// GW: Making sure we will get a detached DataChannel as
// a datachannel.ReadWriteCloser upon datachannel.onOpen event.
settingEngine.DetachDataChannels()
return settingEngine, nil
}