fix:“RawConn 不稳定导致连接被误杀
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user