forked from ldcsoftware/kcp-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreadloop_linux.go
54 lines (48 loc) · 1.14 KB
/
readloop_linux.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// +build linux
package kcp
import (
"net"
"os"
"sync/atomic"
gouuid "github.com/satori/go.uuid"
"golang.org/x/net/ipv4"
)
// monitor incoming data for all connections of server
func (t *UDPTunnel) readLoop() {
// default version
if t.xconn == nil {
t.defaultReadLoop()
return
}
// x/net version
msgs := make([]ipv4.Message, batchSize)
for k := range msgs {
msgs[k].Buffers = [][]byte{xmitBuf.Get().([]byte)[:mtuLimit]}
}
for {
if count, err := t.xconn.ReadBatch(msgs, 0); err == nil {
for i := 0; i < count; i++ {
msg := &msgs[i]
if msg.N >= gouuid.Size+IKCP_OVERHEAD {
t.input(msg.Buffers[0][:msg.N], msg.Addr)
msg.Buffers[0] = xmitBuf.Get().([]byte)[:mtuLimit]
} else {
atomic.AddUint64(&DefaultSnmp.InErrs, 1)
}
}
} 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" {
t.defaultReadLoop()
return
}
}
}
t.notifyReadError(err)
}
}
}