@@ -338,88 +338,76 @@ func (s *Server) Start(onDone func(err error)) (stop func(), stopped <-chan stru
338
338
}
339
339
340
340
// NewTCPListener creates a new TCP listener.
341
- func NewTCPListener (network , addr string ) (net.Listener , error ) {
342
- var opts []controlOptions
343
-
344
- switch network {
345
- case "tcp" , "tcp4" :
346
- network = "tcp4"
347
- opts = tcpOptions
348
-
349
- case "tcp6" :
350
- opts = tcpOptionsV6
351
-
352
- default :
341
+ func NewTCPListener (network , addr string , control ControlFn ) (net.Listener , error ) {
342
+ network , ok := networkNames [network ]
343
+ if ! ok {
353
344
return nil , fmt .Errorf ("unsupported network: %s" , network )
354
345
}
355
346
356
- lc := net.ListenConfig {Control : makeControl ( opts ) }
347
+ lc := net.ListenConfig {Control : control }
357
348
358
349
return lc .Listen (context .Background (), network , addr )
359
350
}
360
351
361
352
// NewUDPPacketConn creates a new UDP packet connection.
362
- func NewUDPPacketConn (network , addr string ) (net.PacketConn , error ) {
363
- var opts []controlOptions
364
-
365
- switch network {
366
- case "udp" , "udp4" :
367
- network = "udp4"
368
- opts = udpOptions
369
-
370
- case "udp6" :
371
- opts = udpOptionsV6
372
-
373
- default :
353
+ func NewUDPPacketConn (network , addr string , control ControlFn ) (net.PacketConn , error ) {
354
+ network , ok := networkNames [network ]
355
+ if ! ok {
374
356
return nil , fmt .Errorf ("unsupported network: %s" , network )
375
357
}
376
358
377
- lc := net.ListenConfig {
378
- Control : makeControl (opts ),
379
- }
359
+ lc := net.ListenConfig {Control : control }
380
360
381
361
return lc .ListenPacket (context .Background (), network , addr )
382
362
}
383
363
384
- var (
385
- tcpOptions = []controlOptions {
386
- {unix .IPPROTO_IP , unix .IP_RECVTTL , 1 , "failed to set IP_RECVTTL" },
387
- {unix .IPPROTO_TCP , unix .TCP_FASTOPEN , 5 , "failed to set TCP_FASTOPEN" }, // tcp specific stuff from systemd
388
- {unix .IPPROTO_TCP , unix .TCP_NODELAY , 1 , "failed to set TCP_NODELAY" }, // tcp specific stuff from systemd
389
- {unix .IPPROTO_IP , unix .IP_TTL , 1 , "failed to set IP_TTL" },
390
- }
364
+ // ControlFn is an alias to [net.ListenConfig.Control] function.
365
+ type ControlFn = func (string , string , syscall.RawConn ) error
391
366
392
- tcpOptionsV6 = []controlOptions {
393
- {unix .IPPROTO_IPV6 , unix .IPV6_RECVHOPLIMIT , 1 , "failed to set IPV6_RECVHOPLIMIT" },
394
- {unix .IPPROTO_TCP , unix .TCP_FASTOPEN , 5 , "failed to set TCP_FASTOPEN" }, // tcp specific stuff from systemd
395
- {unix .IPPROTO_TCP , unix .TCP_NODELAY , 1 , "failed to set TCP_NODELAY" }, // tcp specific stuff from systemd
396
- {unix .IPPROTO_IPV6 , unix .IPV6_UNICAST_HOPS , 1 , "failed to set IPV6_UNICAST_HOPS" },
397
- }
367
+ // MakeControl creates a control function for setting socket options.
368
+ func MakeControl (network string , forwardEnabled bool ) (ControlFn , error ) {
369
+ maxHops := 1
398
370
399
- udpOptions = []controlOptions {
400
- {unix .IPPROTO_IP , unix .IP_RECVTTL , 1 , "failed to set IP_RECVTTL" },
401
- {unix .IPPROTO_IP , unix .IP_TTL , 1 , "failed to set IP_TTL" },
371
+ if forwardEnabled {
372
+ maxHops = 2
402
373
}
403
374
404
- udpOptionsV6 = []controlOptions {
405
- {unix .IPPROTO_IPV6 , unix .IPV6_RECVHOPLIMIT , 1 , "failed to set IPV6_RECVHOPLIMIT" },
406
- {unix .IPPROTO_IPV6 , unix .IPV6_UNICAST_HOPS , 1 , "failed to set IPV6_UNICAST_HOPS" },
407
- }
408
- )
375
+ var options []controlOptions
409
376
410
- type controlOptions struct {
411
- level int
412
- opt int
413
- val int
414
- errorMessage string
415
- }
377
+ switch network {
378
+ case "tcp" , "tcp4" :
379
+ options = []controlOptions {
380
+ {unix .IPPROTO_IP , unix .IP_RECVTTL , maxHops , "failed to set IP_RECVTTL" },
381
+ {unix .IPPROTO_TCP , unix .TCP_FASTOPEN , 5 , "failed to set TCP_FASTOPEN" }, // tcp specific stuff from systemd
382
+ {unix .IPPROTO_TCP , unix .TCP_NODELAY , 1 , "failed to set TCP_NODELAY" }, // tcp specific stuff from systemd
383
+ {unix .IPPROTO_IP , unix .IP_TTL , maxHops , "failed to set IP_TTL" },
384
+ }
385
+ case "tcp6" :
386
+ options = []controlOptions {
387
+ {unix .IPPROTO_IPV6 , unix .IPV6_RECVHOPLIMIT , maxHops , "failed to set IPV6_RECVHOPLIMIT" },
388
+ {unix .IPPROTO_TCP , unix .TCP_FASTOPEN , 5 , "failed to set TCP_FASTOPEN" }, // tcp specific stuff from systemd
389
+ {unix .IPPROTO_TCP , unix .TCP_NODELAY , 1 , "failed to set TCP_NODELAY" }, // tcp specific stuff from systemd
390
+ {unix .IPPROTO_IPV6 , unix .IPV6_UNICAST_HOPS , maxHops , "failed to set IPV6_UNICAST_HOPS" },
391
+ }
392
+ case "udp" , "udp4" :
393
+ options = []controlOptions {
394
+ {unix .IPPROTO_IP , unix .IP_RECVTTL , maxHops , "failed to set IP_RECVTTL" },
395
+ {unix .IPPROTO_IP , unix .IP_TTL , maxHops , "failed to set IP_TTL" },
396
+ }
397
+ case "udp6" :
398
+ options = []controlOptions {
399
+ {unix .IPPROTO_IPV6 , unix .IPV6_RECVHOPLIMIT , maxHops , "failed to set IPV6_RECVHOPLIMIT" },
400
+ {unix .IPPROTO_IPV6 , unix .IPV6_UNICAST_HOPS , maxHops , "failed to set IPV6_UNICAST_HOPS" },
401
+ }
402
+ default :
403
+ return nil , fmt .Errorf ("unsupported network: %s" , network )
404
+ }
416
405
417
- func makeControl (opts []controlOptions ) func (string , string , syscall.RawConn ) error {
418
406
return func (_ string , _ string , c syscall.RawConn ) error {
419
407
var resErr error
420
408
421
409
err := c .Control (func (fd uintptr ) {
422
- for _ , opt := range opts {
410
+ for _ , opt := range options {
423
411
opErr := unix .SetsockoptInt (int (fd ), opt .level , opt .opt , opt .val )
424
412
if opErr != nil {
425
413
resErr = fmt .Errorf (opt .errorMessage + ": %w" , opErr )
@@ -437,5 +425,21 @@ func makeControl(opts []controlOptions) func(string, string, syscall.RawConn) er
437
425
}
438
426
439
427
return nil
440
- }
428
+ }, nil
429
+ }
430
+
431
+ type controlOptions struct {
432
+ level int
433
+ opt int
434
+ val int
435
+ errorMessage string
436
+ }
437
+
438
+ var networkNames = map [string ]string {
439
+ "tcp" : "tcp4" ,
440
+ "tcp4" : "tcp4" ,
441
+ "tcp6" : "tcp6" ,
442
+ "udp" : "udp4" ,
443
+ "udp4" : "udp4" ,
444
+ "udp6" : "udp6" ,
441
445
}
0 commit comments