Skip to content

Commit

Permalink
fix: kcp set nodelay for client impove stability, dump all records wh…
Browse files Browse the repository at this point in the history
…en quiting server
  • Loading branch information
Night12138 committed Oct 24, 2022
1 parent ff777bb commit 66d3f56
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 26 deletions.
Binary file added gover/__debug_bin
Binary file not shown.
10 changes: 6 additions & 4 deletions gover/kcp/kcp.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package kcp

/*
#cgo CFLAGS: -O3
#include "ikcp.h"
typedef int (*OutputCallback)(const char *buf, int len, struct IKCPCB *kcp, void *user);
typedef const char const_char;
Expand Down Expand Up @@ -75,14 +77,14 @@ func (k *KCP) Recv(data []byte) int {
return int(ret)
}

func (k *KCP) Check() uint32 {
cur := C.uint32_t(currentMs())
func (k *KCP) Check(current uint32) uint32 {
cur := C.uint32_t(current)
ret := C.ikcp_check(k.priv, cur)
return uint32(ret)
}

func (k *KCP) Update() {
cur := C.uint32_t(currentMs())
func (k *KCP) Update(current uint32) {
cur := C.uint32_t(current)
C.ikcp_update(k.priv, cur)
}

Expand Down
7 changes: 5 additions & 2 deletions gover/proxy/kcp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ package proxy
import (
"testing"

"github.com/MoonlightPS/Iridium-gidra/gover/kcp_"
"github.com/MoonlightPS/Iridium-gidra/gover/kcp"
)

func TestKCP(t *testing.T) {
kobj := kcp_.NewKCPWithToken(1, 2, func(buf []byte, size int) {})
kobj, err := kcp.NewKCPWithToken(1, 2, func(buf []byte, size int) {})
if err != nil {
panic(err)
}
kobj.SetMtu(1200)
kobj.WndSize(1024, 1024)
kobj.NoDelay(1, 10, 2, 1)
Expand Down
55 changes: 41 additions & 14 deletions gover/proxy/socket.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,22 @@ type KCPConn struct {
running bool
keyID int
seed uint64
once sync.Once
}

func (c *KCPConn) Start() {
go func() {
// recv from server
buf := make([]byte, BUFFER_SIZE)
remote, server, local := c.remote, c.server, c.writeLocal
remote, server := c.remote, c.server
for {
n, err := remote.Read(buf)
// colorlog.Debug("read from server, n: %d", n)
if err != nil {
colorlog.Error("read udp from server failed, err: %+v", err)
if errors.Is(err, net.ErrClosed) {
return
}
continue
}
if IsHandshakePacket(buf[:n]) {
Expand All @@ -54,12 +58,7 @@ func (c *KCPConn) Start() {
}
switch handshake.m1 {
case HANDSHAKE_FIN:
local(buf[:n])
remote.Close()
c.running = false
close(c.cChan)
close(c.sChan)
c.recorder.Stop()
c.Close(handshake)
return
}
continue
Expand All @@ -82,8 +81,9 @@ func (c *KCPConn) Start() {
go func() {
// update client
for c.running {
c.client.Update()
next := c.client.Check() - kcp.CurrentMs()
cur := kcp.CurrentMs()
c.client.Update(cur)
next := c.client.Check(cur) - cur
if next > 0 {
time.Sleep(time.Millisecond * time.Duration(next))
}
Expand All @@ -92,8 +92,9 @@ func (c *KCPConn) Start() {
go func() {
// update server
for c.running {
c.server.Update()
next := c.server.Check() - kcp.CurrentMs()
cur := kcp.CurrentMs()
c.server.Update(cur)
next := c.server.Check(cur) - cur
if next > 0 {
time.Sleep(time.Millisecond * time.Duration(next))
}
Expand Down Expand Up @@ -178,7 +179,20 @@ func (c *KCPConn) Input(data []byte, size int) int {
}

func (c *KCPConn) Close(hs *Handshake) {
c.remote.Write(hs.Compose())
c.once.Do(func() {
if hs == nil {
hs = NewHandshakePacket(HANDSHAKE_FIN, c.hs.conv, c.hs.token, 1, 0x19419494)
}
c.remote.Write(hs.Compose())
c.remote.Close()
c.writeLocal(hs.Compose())
c.running = false
close(c.cChan)
close(c.sChan)
c.recorder.Stop()
c.client.Free()
c.server.Free()
})
}

func ConstructKCPConn(remote *net.UDPAddr, writeLocal WriteFunc, hs *Handshake, key *utils.PacketKey, keyID int) (*KCPConn, error) {
Expand Down Expand Up @@ -231,6 +245,7 @@ func ConstructKCPConn(remote *net.UDPAddr, writeLocal WriteFunc, hs *Handshake,
}
client.SetMtu(1200)
client.WndSize(1024, 1024)
client.NoDelay(1, 10, 2, 1)

server, err := kcp.NewKCPWithToken(handshake.conv, handshake.token, func(buf []byte, size int) {
// colorlog.Debug("send to server, n: %d", size)
Expand Down Expand Up @@ -285,6 +300,7 @@ type KCPSocket struct {
}

func (k *KCPSocket) Start() {
k.conns = &sync.Map{}
go func() {
// recv from local
buf := make([]byte, BUFFER_SIZE)
Expand All @@ -294,6 +310,9 @@ func (k *KCPSocket) Start() {
// colorlog.Debug("read from %+v, n: %d", addr, n)
if err != nil {
colorlog.Error("read udp from local failed, err: %+v", err)
if errors.Is(err, net.ErrClosed) {
return
}
continue
}
if IsHandshakePacket(buf[:n]) {
Expand Down Expand Up @@ -334,13 +353,21 @@ func (k *KCPSocket) Start() {
}()
}

func (s *KCPSocket) Stop() {
s.local.Close()
s.conns.Range(func(key, value interface{}) bool {
value.(*KCPConn).Close(nil)
return true
})
s.conns = nil
}

func NewKCPSocket(local *net.UDPConn, remote *net.UDPAddr, dispatchKey *utils.PacketKey, keyID int) *KCPSocket {
conns := &sync.Map{}
return &KCPSocket{
local: local,
remote: remote,
key: dispatchKey,
keyID: keyID,
conns: conns,
conns: nil,
}
}
14 changes: 9 additions & 5 deletions gover/proxy/socket_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,24 @@ import (
"testing"
"time"

"github.com/MoonlightPS/Iridium-gidra/gover/kcp_"
"github.com/MoonlightPS/Iridium-gidra/gover/kcp"
)

func BenchmarkSyncMap(b *testing.B) {
m := &sync.Map{}
for i := 0; i < 10000; i++ {
m.Store(i, kcp_.NewKCPWithToken(1, 2, func(buf []byte, size int) {}))
k, err := kcp.NewKCPWithToken(1, 2, func(buf []byte, size int) {})
if err != nil {
panic(err)
}
m.Store(i, k)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
m.Range(func(key, value interface{}) bool {
obj := value.(*kcp_.KCP)
obj.Input(make([]byte, 1024), true, false)
return false
obj := value.(*kcp.KCP)
obj.Input(make([]byte, 1024))
return true
})
}
}
Expand Down
3 changes: 2 additions & 1 deletion gover/utils/recorder.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ func (r *Recorder) Stop() {
colorlog.Warn("marshaling records failed, err: %+v", err)
return
}
fileName := fmt.Sprintf("log_%d_%d.json", time.Now().UnixMilli(), rand.Int()%10000)
fileName := fmt.Sprintf("log_%s_%d.json", time.Now().Format("2006_01_02_15_04_05"), rand.Int()%10000)
os.WriteFile(fileName, content, 0644)
colorlog.Info("log write to %s, with %d packet(s)", fileName, len(r.d))
}

func (r *Recorder) Record(packet []byte) {
Expand Down

0 comments on commit 66d3f56

Please sign in to comment.