Skip to content

Commit 3a4bcb9

Browse files
committed
fix sendmmsg/recvmmsg compatibility issue for old linux kernel
1 parent 0934811 commit 3a4bcb9

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

readloop_linux.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package kcp
44

55
import (
66
"net"
7+
"os"
78
"sync/atomic"
89

910
"github.com/pkg/errors"
@@ -47,6 +48,17 @@ func (s *UDPSession) readLoop() {
4748
s.packetInput(msg.Buffers[0][:msg.N])
4849
}
4950
} else {
51+
// compatibility issue:
52+
// for linux kernel<=2.6.32, support for sendmmsg is not available
53+
// an error of type os.SyscallError will be returned
54+
if operr, ok := err.(*net.OpError); ok {
55+
if se, ok := operr.Err.(*os.SyscallError); ok {
56+
if se.Syscall == "recvmmsg" {
57+
s.defaultReadLoop()
58+
return
59+
}
60+
}
61+
}
5062
s.notifyReadError(errors.WithStack(err))
5163
return
5264
}
@@ -90,6 +102,17 @@ func (l *Listener) monitor() {
90102
}
91103
}
92104
} else {
105+
// compatibility issue:
106+
// for linux kernel<=2.6.32, support for sendmmsg is not available
107+
// an error of type os.SyscallError will be returned
108+
if operr, ok := err.(*net.OpError); ok {
109+
if se, ok := operr.Err.(*os.SyscallError); ok {
110+
if se.Syscall == "recvmmsg" {
111+
l.defaultMonitor()
112+
return
113+
}
114+
}
115+
}
93116
l.notifyReadError(errors.WithStack(err))
94117
return
95118
}

tx_linux.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
package kcp
44

55
import (
6+
"net"
7+
"os"
68
"sync/atomic"
79

810
"github.com/pkg/errors"
@@ -28,6 +30,18 @@ func (s *UDPSession) tx(txqueue []ipv4.Message) {
2830
npkts += n
2931
txqueue = txqueue[n:]
3032
} else {
33+
// compatibility issue:
34+
// for linux kernel<=2.6.32, support for sendmmsg is not available
35+
// an error of type os.SyscallError will be returned
36+
if operr, ok := err.(*net.OpError); ok {
37+
if se, ok := operr.Err.(*os.SyscallError); ok {
38+
if se.Syscall == "sendmmsg" {
39+
s.xconn = nil // set s.xconn to nil permanently
40+
s.defaultTx(txqueue)
41+
return
42+
}
43+
}
44+
}
3145
s.notifyWriteError(errors.WithStack(err))
3246
break
3347
}

0 commit comments

Comments
 (0)