Skip to content

Commit 1e2df9f

Browse files
committed
fix(checkConn): try to peek into the connection instead of consuming
Initially connCheck was reading a byte from the socket which won't allow the code for processing push notification to work properly once a byte is read. Try to peek instead of reading, so later the next operations over the connection can work with the correct data.
1 parent 409dac1 commit 1e2df9f

File tree

1 file changed

+17
-4
lines changed

1 file changed

+17
-4
lines changed

internal/pool/conn_check.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@ import (
88
"net"
99
"syscall"
1010
"time"
11+
"unsafe"
1112
)
1213

1314
var errUnexpectedRead = errors.New("unexpected read from socket")
1415

16+
// connCheck checks if the connection is still alive and if there is data in the socket
17+
// it will try to peek at the next byte without consuming it since we may want to work with it
18+
// later on (e.g. push notifications)
1519
func connCheck(conn net.Conn) error {
1620
// Reset previous timeout.
1721
_ = conn.SetDeadline(time.Time{})
@@ -29,16 +33,25 @@ func connCheck(conn net.Conn) error {
2933

3034
if err := rawConn.Read(func(fd uintptr) bool {
3135
var buf [1]byte
32-
n, err := syscall.Read(int(fd), buf[:])
36+
// Use MSG_PEEK to peek at data without consuming it
37+
n, _, errno := syscall.Syscall6(
38+
syscall.SYS_RECVFROM,
39+
fd,
40+
uintptr(unsafe.Pointer(&buf[0])),
41+
1,
42+
syscall.MSG_PEEK, // This ensures the byte stays in the socket buffer
43+
0, 0,
44+
)
45+
3346
switch {
34-
case n == 0 && err == nil:
47+
case n == 0 && errno == 0:
3548
sysErr = io.EOF
3649
case n > 0:
3750
sysErr = errUnexpectedRead
38-
case err == syscall.EAGAIN || err == syscall.EWOULDBLOCK:
51+
case errno == syscall.EAGAIN || errno == syscall.EWOULDBLOCK:
3952
sysErr = nil
4053
default:
41-
sysErr = err
54+
sysErr = errno
4255
}
4356
return true
4457
}); err != nil {

0 commit comments

Comments
 (0)