7
7
"fmt"
8
8
"io"
9
9
"net"
10
+ "sync"
10
11
"time"
11
12
12
13
"github.com/pion/datachannel"
@@ -81,9 +82,10 @@ func Dial(conn net.Conn, iceServers []webrtc.ICEServer) (*Dialer, error) {
81
82
flushCandidates ()
82
83
83
84
dialer := & Dialer {
84
- conn : conn ,
85
- ctrl : ctrl ,
86
- rtc : rtc ,
85
+ conn : conn ,
86
+ ctrl : ctrl ,
87
+ rtc : rtc ,
88
+ connClosers : make ([]io.Closer , 0 ),
87
89
}
88
90
89
91
return dialer , dialer .negotiate ()
@@ -97,6 +99,9 @@ type Dialer struct {
97
99
ctrl * webrtc.DataChannel
98
100
ctrlrw datachannel.ReadWriteCloser
99
101
rtc * webrtc.PeerConnection
102
+
103
+ connClosers []io.Closer
104
+ connClosersMut sync.Mutex
100
105
}
101
106
102
107
func (d * Dialer ) negotiate () (err error ) {
@@ -111,16 +116,27 @@ func (d *Dialer) negotiate() (err error) {
111
116
112
117
go func () {
113
118
defer close (errCh )
119
+ defer func () {
120
+ _ = d .conn .Close ()
121
+ }()
114
122
err := waitForConnectionOpen (context .Background (), d .rtc )
115
123
if err != nil {
116
- _ = d .conn .Close ()
117
124
errCh <- err
118
125
return
119
126
}
120
- go func () {
121
- // Closing this connection took 30ms+.
122
- _ = d .conn .Close ()
123
- }()
127
+ d .rtc .OnConnectionStateChange (func (pcs webrtc.PeerConnectionState ) {
128
+ if pcs == webrtc .PeerConnectionStateConnected {
129
+ return
130
+ }
131
+
132
+ // Close connections opened while the RTC was alive.
133
+ d .connClosersMut .Lock ()
134
+ defer d .connClosersMut .Unlock ()
135
+ for _ , connCloser := range d .connClosers {
136
+ _ = connCloser .Close ()
137
+ }
138
+ d .connClosers = make ([]io.Closer , 0 )
139
+ })
124
140
}()
125
141
126
142
for {
@@ -210,6 +226,10 @@ func (d *Dialer) DialContext(ctx context.Context, network, address string) (net.
210
226
if err != nil {
211
227
return nil , fmt .Errorf ("create data channel: %w" , err )
212
228
}
229
+ d .connClosersMut .Lock ()
230
+ d .connClosers = append (d .connClosers , dc )
231
+ d .connClosersMut .Unlock ()
232
+
213
233
err = waitForDataChannelOpen (ctx , dc )
214
234
if err != nil {
215
235
return nil , fmt .Errorf ("wait for open: %w" , err )
0 commit comments