Skip to content

Commit

Permalink
Do not ignore SO_ERROR value on connect
Browse files Browse the repository at this point in the history
Otherwise we will mark the connection as successful and a subsequent read/write will return EOF. In reality, the connect
syscall failed. Checking the return value of Getsockoptint(... SO_ERROR) will tell us whether the connect syscall
succeeded. A return value of 0 means success - anything else can be interpreted by syscall.Errno and means failure.

I was mislead into thinking the returned `err` from `Getsockoptint` is the actual socket error - in reality, it's whether the `getsockopt` syscall succeeded or not.

- Golang src: https://github.com/golang/go/blob/04879acdebbb08bdca00356f043d769c4b4375ce/src/syscall/syscall_unix.go#L312
- Sanity check that uninit values are set to 0: https://go.dev/play/p/vCLjDd6WwL-
- syscall.Errno is safe for any input value: https://cs.opensource.google/go/go/+/refs/tags/go1.23.3:src/syscall/syscall_unix.go;l=110
  • Loading branch information
sergiu128 committed Nov 27, 2024
1 parent 08d3705 commit 32aaa2e
Showing 1 changed file with 4 additions and 1 deletion.
5 changes: 4 additions & 1 deletion internal/socket_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,13 @@ func connect(fd int, remoteAddr net.Addr, timeout time.Duration, opts ...sonicop
return sonicerrors.ErrTimeout
}

_, err = syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_ERROR)
socketErr, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_ERROR)
if err != nil {
return os.NewSyscallError("getsockopt", err)
}
if socketErr != 0 {
return syscall.Errno(socketErr)
}
}

return nil
Expand Down

0 comments on commit 32aaa2e

Please sign in to comment.