github.com/metacubex/tfo-go@v0.0.0-20240228025757-be1269474a66/tfo_listen_generic.go (about)

     1  //go:build freebsd || linux || windows
     2  
     3  package tfo
     4  
     5  import (
     6  	"context"
     7  	"errors"
     8  	"net"
     9  	"syscall"
    10  )
    11  
    12  // defaultBacklog is Go std's listen(2) backlog.
    13  // We use this as the default TFO backlog.
    14  const defaultBacklog = 4096
    15  
    16  func (lc *ListenConfig) listenTFO(ctx context.Context, network, address string) (net.Listener, error) {
    17  	ctrlFn := lc.Control
    18  	backlog := lc.Backlog
    19  	if backlog == 0 {
    20  		backlog = defaultBacklog
    21  	}
    22  	llc := *lc
    23  	llc.Control = func(network, address string, c syscall.RawConn) (err error) {
    24  		if ctrlFn != nil {
    25  			if err = ctrlFn(network, address, c); err != nil {
    26  				return err
    27  			}
    28  		}
    29  
    30  		if cerr := c.Control(func(fd uintptr) {
    31  			err = setTFOListenerWithBacklog(fd, backlog)
    32  		}); cerr != nil {
    33  			return cerr
    34  		}
    35  
    36  		if err != nil {
    37  			if !lc.Fallback || !errors.Is(err, ErrUnsupported) {
    38  				return wrapSyscallError("setsockopt(TCP_FASTOPEN)", err)
    39  			}
    40  			runtimeListenNoTFO.Store(true)
    41  		}
    42  		return nil
    43  	}
    44  	return llc.ListenConfig.Listen(ctx, network, address)
    45  }