|  | @@ -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)
 | 
	
		
			
				|  |  | +}
 |