From 6f0b4aaf31cb8c52501df837ed1a20e78d04f230 Mon Sep 17 00:00:00 2001 From: Shelikhoo Date: Sat, 11 Jun 2016 22:22:43 +0800 Subject: [PATCH] KCP: sorrgated Listener and conn --- transport/hub/kcp.go | 104 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 transport/hub/kcp.go diff --git a/transport/hub/kcp.go b/transport/hub/kcp.go new file mode 100644 index 00000000..29ee1b5a --- /dev/null +++ b/transport/hub/kcp.go @@ -0,0 +1,104 @@ +package hub + +import ( + "errors" + "net" + "time" + + "github.com/v2ray/v2ray-core/common/log" + "github.com/v2ray/v2ray-core/transport/hub/kcpv" + "github.com/xtaci/kcp-go" +) + +type KCPVlistener struct { + lst *kcp.Listener + conf *kcpv.Config +} + +func (kvl *KCPVlistener) Accept() (*KCPVconn, error) { + conn, err := kvl.lst.Accept() + if err != nil { + return nil, err + } + nodelay, interval, resend, nc := 0, 40, 0, 0 + if kvl.conf.Mode != "manual" { + switch kvl.conf.Mode { + case "normal": + nodelay, interval, resend, nc = 0, 30, 2, 1 + case "fast": + nodelay, interval, resend, nc = 0, 20, 2, 1 + case "fast2": + nodelay, interval, resend, nc = 1, 20, 2, 1 + case "fast3": + nodelay, interval, resend, nc = 1, 10, 2, 1 + } + } else { + log.Error("kcp: Accepted Unsuccessfully: Manual mode is not supported.(yet!)") + return nil, errors.New("kcp: Manual Not Implemented") + } + + conn.SetNoDelay(nodelay, interval, resend, nc) + conn.SetWindowSize(kvl.conf.AdvancedConfigs.Sndwnd, kvl.conf.AdvancedConfigs.Rcvwnd) + conn.SetMtu(kvl.conf.AdvancedConfigs.Mtu) + conn.SetACKNoDelay(kvl.conf.AdvancedConfigs.Acknodelay) + conn.SetDSCP(kvl.conf.AdvancedConfigs.Dscp) + + kcv := &KCPVconn{hc: conn} + kcv.conf = kvl.conf + return kcv, nil +} +func (kvl *KCPVlistener) Close() error { + return kvl.lst.Close() +} +func (kvl *KCPVlistener) Addr() net.Addr { + return kvl.lst.Addr() +} + +type KCPVconn struct { + hc *kcp.UDPSession + conf *kcpv.Config + conntokeep time.Time +} + +func (kcpvc *KCPVconn) Read(b []byte) (int, error) { + ifb := time.Now().Add(time.Duration(kcpvc.conf.AdvancedConfigs.ReadTimeout) * time.Second) + if ifb.After(kcpvc.conntokeep) { + kcpvc.conntokeep = ifb + } + kcpvc.hc.SetDeadline(kcpvc.conntokeep) + return kcpvc.hc.Read(b) +} + +func (kcpvc *KCPVconn) Write(b []byte) (int, error) { + ifb := time.Now().Add(time.Duration(kcpvc.conf.AdvancedConfigs.WriteTimeout) * time.Second) + if ifb.After(kcpvc.conntokeep) { + kcpvc.conntokeep = ifb + } + kcpvc.hc.SetDeadline(kcpvc.conntokeep) + return kcpvc.hc.Write(b) +} + +func (kcpvc *KCPVconn) Close() error { + + return kcpvc.hc.Close() +} + +func (kcpvc *KCPVconn) LocalAddr() net.Addr { + return kcpvc.hc.LocalAddr() +} + +func (kcpvc *KCPVconn) RemoteAddr() net.Addr { + return kcpvc.hc.RemoteAddr() +} + +func (kcpvc *KCPVconn) SetDeadline(t time.Time) error { + return kcpvc.hc.SetDeadline(t) +} + +func (kcpvc *KCPVconn) SetReadDeadline(t time.Time) error { + return kcpvc.hc.SetReadDeadline(t) +} + +func (kcpvc *KCPVconn) SetWriteDeadline(t time.Time) error { + return kcpvc.hc.SetWriteDeadline(t) +}