diff --git a/readloop_linux.go b/readloop_linux.go index 2e01c45..6226478 100644 --- a/readloop_linux.go +++ b/readloop_linux.go @@ -4,6 +4,7 @@ package kcp import ( "net" + "os" "sync/atomic" "github.com/pkg/errors" @@ -47,6 +48,17 @@ func (s *UDPSession) readLoop() { s.packetInput(msg.Buffers[0][:msg.N]) } } else { + // compatibility issue: + // for linux kernel<=2.6.32, support for sendmmsg is not available + // an error of type os.SyscallError will be returned + if operr, ok := err.(*net.OpError); ok { + if se, ok := operr.Err.(*os.SyscallError); ok { + if se.Syscall == "recvmmsg" { + s.defaultReadLoop() + return + } + } + } s.notifyReadError(errors.WithStack(err)) return } @@ -90,6 +102,17 @@ func (l *Listener) monitor() { } } } else { + // compatibility issue: + // for linux kernel<=2.6.32, support for sendmmsg is not available + // an error of type os.SyscallError will be returned + if operr, ok := err.(*net.OpError); ok { + if se, ok := operr.Err.(*os.SyscallError); ok { + if se.Syscall == "recvmmsg" { + l.defaultMonitor() + return + } + } + } l.notifyReadError(errors.WithStack(err)) return } diff --git a/tx_linux.go b/tx_linux.go index b6f2e11..e609aac 100644 --- a/tx_linux.go +++ b/tx_linux.go @@ -3,6 +3,8 @@ package kcp import ( + "net" + "os" "sync/atomic" "github.com/pkg/errors" @@ -28,6 +30,18 @@ func (s *UDPSession) tx(txqueue []ipv4.Message) { npkts += n txqueue = txqueue[n:] } else { + // compatibility issue: + // for linux kernel<=2.6.32, support for sendmmsg is not available + // an error of type os.SyscallError will be returned + if operr, ok := err.(*net.OpError); ok { + if se, ok := operr.Err.(*os.SyscallError); ok { + if se.Syscall == "sendmmsg" { + s.xconn = nil // set s.xconn to nil permanently + s.defaultTx(txqueue) + return + } + } + } s.notifyWriteError(errors.WithStack(err)) break }