@@ -18,10 +18,6 @@ import (
18
18
"golang.org/x/sys/unix"
19
19
)
20
20
21
- const (
22
- FD_ERR = - 1
23
- )
24
-
25
21
type IPv4Source struct {
26
22
Src [4 ]byte
27
23
Ifindex int32
@@ -63,6 +59,7 @@ type nativeBind struct {
63
59
sock4 int
64
60
sock6 int
65
61
lastMark uint32
62
+ closing sync.RWMutex
66
63
}
67
64
68
65
var _ Endpoint = (* NativeEndpoint )(nil )
@@ -129,7 +126,7 @@ func createBind(port uint16) (Bind, uint16, error) {
129
126
port = newPort
130
127
}
131
128
132
- if bind .sock4 == FD_ERR && bind .sock6 == FD_ERR {
129
+ if bind .sock4 == - 1 && bind .sock6 == - 1 {
133
130
return nil , 0 , errors .New ("ipv4 and ipv6 not supported" )
134
131
}
135
132
@@ -141,6 +138,9 @@ func (bind *nativeBind) LastMark() uint32 {
141
138
}
142
139
143
140
func (bind * nativeBind ) SetMark (value uint32 ) error {
141
+ bind .closing .RLock ()
142
+ defer bind .closing .RUnlock ()
143
+
144
144
if bind .sock6 != - 1 {
145
145
err := unix .SetsockoptInt (
146
146
bind .sock6 ,
@@ -171,20 +171,26 @@ func (bind *nativeBind) SetMark(value uint32) error {
171
171
return nil
172
172
}
173
173
174
- func closeUnblock (fd int ) error {
175
- // shutdown to unblock readers and writers
176
- unix .Shutdown (fd , unix .SHUT_RDWR )
177
- return unix .Close (fd )
178
- }
179
-
180
174
func (bind * nativeBind ) Close () error {
181
175
var err1 , err2 error
176
+ bind .closing .RLock ()
177
+ if bind .sock6 != - 1 {
178
+ unix .Shutdown (bind .sock6 , unix .SHUT_RDWR )
179
+ }
180
+ if bind .sock4 != - 1 {
181
+ unix .Shutdown (bind .sock4 , unix .SHUT_RDWR )
182
+ }
183
+ bind .closing .RUnlock ()
184
+ bind .closing .Lock ()
182
185
if bind .sock6 != - 1 {
183
- err1 = closeUnblock (bind .sock6 )
186
+ err1 = unix .Close (bind .sock6 )
187
+ bind .sock6 = - 1
184
188
}
185
189
if bind .sock4 != - 1 {
186
- err2 = closeUnblock (bind .sock4 )
190
+ err2 = unix .Close (bind .sock4 )
191
+ bind .sock4 = - 1
187
192
}
193
+ bind .closing .Unlock ()
188
194
189
195
if err1 != nil {
190
196
return err1
@@ -193,6 +199,9 @@ func (bind *nativeBind) Close() error {
193
199
}
194
200
195
201
func (bind * nativeBind ) ReceiveIPv6 (buff []byte ) (int , Endpoint , error ) {
202
+ bind .closing .RLock ()
203
+ defer bind .closing .RUnlock ()
204
+
196
205
var end NativeEndpoint
197
206
if bind .sock6 == - 1 {
198
207
return 0 , nil , syscall .EAFNOSUPPORT
@@ -206,6 +215,9 @@ func (bind *nativeBind) ReceiveIPv6(buff []byte) (int, Endpoint, error) {
206
215
}
207
216
208
217
func (bind * nativeBind ) ReceiveIPv4 (buff []byte ) (int , Endpoint , error ) {
218
+ bind .closing .RLock ()
219
+ defer bind .closing .RUnlock ()
220
+
209
221
var end NativeEndpoint
210
222
if bind .sock4 == - 1 {
211
223
return 0 , nil , syscall .EAFNOSUPPORT
@@ -219,6 +231,9 @@ func (bind *nativeBind) ReceiveIPv4(buff []byte) (int, Endpoint, error) {
219
231
}
220
232
221
233
func (bind * nativeBind ) Send (buff []byte , end Endpoint ) error {
234
+ bind .closing .RLock ()
235
+ defer bind .closing .RUnlock ()
236
+
222
237
nend := end .(* NativeEndpoint )
223
238
if ! nend .isV6 {
224
239
if bind .sock4 == - 1 {
@@ -316,7 +331,7 @@ func create4(port uint16) (int, uint16, error) {
316
331
)
317
332
318
333
if err != nil {
319
- return FD_ERR , 0 , err
334
+ return - 1 , 0 , err
320
335
}
321
336
322
337
addr := unix.SockaddrInet4 {
@@ -338,7 +353,7 @@ func create4(port uint16) (int, uint16, error) {
338
353
return unix .Bind (fd , & addr )
339
354
}(); err != nil {
340
355
unix .Close (fd )
341
- return FD_ERR , 0 , err
356
+ return - 1 , 0 , err
342
357
}
343
358
344
359
sa , err := unix .Getsockname (fd )
@@ -360,7 +375,7 @@ func create6(port uint16) (int, uint16, error) {
360
375
)
361
376
362
377
if err != nil {
363
- return FD_ERR , 0 , err
378
+ return - 1 , 0 , err
364
379
}
365
380
366
381
// set sockopts and bind
@@ -392,7 +407,7 @@ func create6(port uint16) (int, uint16, error) {
392
407
393
408
}(); err != nil {
394
409
unix .Close (fd )
395
- return FD_ERR , 0 , err
410
+ return - 1 , 0 , err
396
411
}
397
412
398
413
sa , err := unix .Getsockname (fd )
0 commit comments