work on tcp lib

This commit is contained in:
eyedeekay
2025-05-26 17:54:53 -04:00
parent 905fef98db
commit 7775a19ffa
2 changed files with 70 additions and 23 deletions

View File

@ -35,7 +35,7 @@ const (
func Listen(network, address string) (net.Listener, error) {
// Validate network parameter
if !isValidNetwork(network) {
return nil, fmt.Errorf("tcp.Listen: invalid network type %q, must be tcp, tcp4, or tcp6", network)
return nil, fmt.Errorf("tcp.Listen: invalid network type %q for addr %s, must be tcp, tcp4, or tcp6", network, address)
}
// Validate address format by attempting to resolve
@ -77,33 +77,45 @@ func isValidNetwork(network string) bool {
// configureSocket applies production-ready socket options to the TCP listener
func configureSocket(listener *net.TCPListener) error {
// Get the underlying file descriptor for socket configuration
file, err := listener.File()
// Use SyscallConn to access the raw socket without duplicating the file descriptor
rawConn, err := listener.SyscallConn()
if err != nil {
return fmt.Errorf("failed to get listener file descriptor: %w", err)
}
defer file.Close()
fd := int(file.Fd())
// Enable SO_REUSEADDR to prevent "address already in use" errors
if err := syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {
return fmt.Errorf("failed to set SO_REUSEADDR: %w", err)
return fmt.Errorf("failed to get listener syscall connection: %w", err)
}
// Set receive buffer size for optimal throughput
if err := syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_RCVBUF, bufferSize); err != nil {
return fmt.Errorf("failed to set receive buffer size: %w", err)
}
// Apply socket options using the raw connection
var sockErr error
err = rawConn.Control(func(fd uintptr) {
// Enable SO_REUSEADDR to prevent "address already in use" errors
if err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {
sockErr = fmt.Errorf("failed to set SO_REUSEADDR: %w", err)
return
}
// Set send buffer size for optimal throughput
if err := syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_SNDBUF, bufferSize); err != nil {
return fmt.Errorf("failed to set send buffer size: %w", err)
}
// Set receive buffer size for optimal throughput
if err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_RCVBUF, bufferSize); err != nil {
sockErr = fmt.Errorf("failed to set receive buffer size: %w", err)
return
}
// Enable TCP_NODELAY to minimize latency (disable Nagle's algorithm)
if err := syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, syscall.TCP_NODELAY, 1); err != nil {
return fmt.Errorf("failed to set TCP_NODELAY: %w", err)
// Set send buffer size for optimal throughput
if err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_SNDBUF, bufferSize); err != nil {
sockErr = fmt.Errorf("failed to set send buffer size: %w", err)
return
}
// Enable TCP_NODELAY to minimize latency (disable Nagle's algorithm)
if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_NODELAY, 1); err != nil {
sockErr = fmt.Errorf("failed to set TCP_NODELAY: %w", err)
return
}
})
if err != nil {
return fmt.Errorf("failed to access socket for configuration: %w", err)
}
if sockErr != nil {
return sockErr
}
return nil

View File

@ -258,3 +258,38 @@ func BenchmarkListen(b *testing.B) {
listener.Close()
}
}
func TestConfigureSocket_NoResourceLeak(t *testing.T) {
// Create a listener
listener, err := net.Listen("tcp", ":0")
if err != nil {
t.Fatalf("Failed to create base listener: %v", err)
}
defer listener.Close()
tcpListener := listener.(*net.TCPListener)
// Configure the socket - this should not invalidate the listener
err = configureSocket(tcpListener)
if err != nil {
t.Fatalf("Socket configuration failed: %v", err)
}
// Verify the listener is still usable by accepting a connection
addr := listener.Addr().String()
// Test connection in a goroutine
go func() {
conn, err := net.Dial("tcp", addr)
if err == nil {
conn.Close()
}
}()
// This should succeed if the listener wasn't invalidated
conn, err := listener.Accept()
if err != nil {
t.Fatalf("Listener became unusable after configuration: %v", err)
}
conn.Close()
}