fix:“RawConn 不稳定导致连接被误杀

This commit is contained in:
nnbcccscdscdsc
2026-03-23 22:04:09 +08:00
parent 32e77df476
commit ce84ddb591
3 changed files with 43 additions and 2 deletions

View File

@@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"io"
"strings"
"syscall"
"time"
@@ -150,9 +151,15 @@ func (c *TCPConn) writeFrameLinux(frame []byte) error {
}
})
if err != nil {
if isRawConnNotPollable(err) {
return writeFullFallback(c.conn, frame[written:])
}
return err
}
if opErr != nil {
if isRawConnNotPollable(opErr) {
return writeFullFallback(c.conn, frame[written:])
}
return opErr
}
if written != len(frame) {
@@ -367,6 +374,15 @@ func (c *TCPConn) readFullLinux(buf []byte) (int64, error) {
firstRXTime = rxTimestamp
}
if err != nil {
if isRawConnNotPollable(err) {
if fallbackErr := readFullFallback(c.conn, buf[offset:]); fallbackErr != nil {
if errors.Is(fallbackErr, io.EOF) && offset > 0 {
return firstRXTime, io.ErrUnexpectedEOF
}
return firstRXTime, fallbackErr
}
return firstRXTime, nil
}
if errors.Is(err, io.EOF) && offset > 0 {
return firstRXTime, io.ErrUnexpectedEOF
}
@@ -460,3 +476,27 @@ func parseSCMTimestampingData(data []byte) int64 {
func isWouldBlock(err error) bool {
return errors.Is(err, syscall.EAGAIN) || errors.Is(err, syscall.EWOULDBLOCK)
}
func isRawConnNotPollable(err error) bool {
return err != nil && strings.Contains(err.Error(), "not pollable")
}
func writeFullFallback(w io.Writer, buf []byte) error {
for len(buf) > 0 {
n, err := w.Write(buf)
if err != nil {
return err
}
if n <= 0 {
return io.ErrShortWrite
}
buf = buf[n:]
}
return nil
}
func readFullFallback(r io.Reader, buf []byte) error {
_, err := io.ReadFull(r, buf)
return err
}