Browse Source

more settings to kcp

v2ray 9 years ago
parent
commit
1238304b1d

+ 1 - 0
common/common.go

@@ -8,6 +8,7 @@ import (
 
 var (
 	ErrorAlreadyReleased = errors.New("Object already released.")
+	ErrBadConfiguration  = errors.New("Bad configuration.")
 )
 
 // Releasable interface is for those types that can release its members.

+ 18 - 6
transport/internet/kcp/config.go

@@ -1,20 +1,32 @@
 package kcp
 
 type Config struct {
-	Mtu    int // Maximum transmission unit
-	Sndwnd int // Sending window size
-	Rcvwnd int // Receiving window size
+	Mtu              int // Maximum transmission unit
+	Tti              int
+	UplinkCapacity   int
+	DownlinkCapacity int
+	Congestion       bool
 }
 
 func (this *Config) Apply() {
 	effectiveConfig = *this
 }
 
+func (this *Config) GetSendingWindowSize() int {
+	return this.UplinkCapacity * 1024 * 1024 / this.Mtu / (1000 / this.Tti)
+}
+
+func (this *Config) GetReceivingWindowSize() int {
+	return this.DownlinkCapacity * 1024 * 1024 / this.Mtu / (1000 / this.Tti)
+}
+
 func DefaultConfig() Config {
 	return Config{
-		Mtu:    1350,
-		Sndwnd: 1024,
-		Rcvwnd: 1024,
+		Mtu:              1350,
+		Tti:              20,
+		UplinkCapacity:   5,
+		DownlinkCapacity: 20,
+		Congestion:       false,
 	}
 }
 

+ 35 - 4
transport/internet/kcp/config_json.go

@@ -4,14 +4,18 @@ package kcp
 
 import (
 	"encoding/json"
-	"errors"
 
+	"github.com/v2ray/v2ray-core/common"
 	"github.com/v2ray/v2ray-core/common/log"
 )
 
 func (this *Config) UnmarshalJSON(data []byte) error {
 	type JSONConfig struct {
-		Mtu *int `json:"mtu"`
+		Mtu        *int  `json:"mtu"`
+		Tti        *int  `json:"tti"`
+		UpCap      *int  `json:"uplinkCapacity"`
+		DownCap    *int  `json:"downlinkCapacity"`
+		Congestion *bool `json:"congestion"`
 	}
 	jsonConfig := new(JSONConfig)
 	if err := json.Unmarshal(data, &jsonConfig); err != nil {
@@ -21,9 +25,36 @@ func (this *Config) UnmarshalJSON(data []byte) error {
 		mtu := *jsonConfig.Mtu
 		if mtu < 576 || mtu > 1460 {
 			log.Error("KCP|Config: Invalid MTU size: ", mtu)
-			return errors.New("Invalid configuration")
+			return common.ErrBadConfiguration
 		}
-		this.Mtu = *jsonConfig.Mtu
+		this.Mtu = mtu
+	}
+	if jsonConfig.Tti != nil {
+		tti := *jsonConfig.Tti
+		if tti < 10 || tti > 100 {
+			log.Error("KCP|Config: Invalid TTI: ", tti)
+			return common.ErrBadConfiguration
+		}
+		this.Tti = tti
+	}
+	if jsonConfig.UpCap != nil {
+		upCap := *jsonConfig.UpCap
+		if upCap < 0 {
+			log.Error("KCP|Config: Invalid uplink capacity: ", upCap)
+			return common.ErrBadConfiguration
+		}
+		this.UplinkCapacity = upCap
+	}
+	if jsonConfig.DownCap != nil {
+		downCap := *jsonConfig.DownCap
+		if downCap < 0 {
+			log.Error("KCP|Config: Invalid downlink capacity: ", downCap)
+			return common.ErrBadConfiguration
+		}
+		this.DownlinkCapacity = downCap
+	}
+	if jsonConfig.Congestion != nil {
+		this.Congestion = *jsonConfig.Congestion
 	}
 
 	return nil

+ 2 - 2
transport/internet/kcp/connection.go

@@ -79,8 +79,8 @@ func NewConnection(conv uint32, writerCloser io.WriteCloser, local *net.UDPAddr,
 
 	mtu := uint32(effectiveConfig.Mtu - block.HeaderSize() - headerSize)
 	conn.kcp = NewKCP(conv, mtu, conn.output)
-	conn.kcp.WndSize(effectiveConfig.Sndwnd, effectiveConfig.Rcvwnd)
-	conn.kcp.NoDelay(1, 20, 2, 1)
+	conn.kcp.WndSize(effectiveConfig.GetSendingWindowSize(), effectiveConfig.GetReceivingWindowSize())
+	conn.kcp.NoDelay(1, 20, 2, effectiveConfig.Congestion)
 	conn.kcp.current = conn.Elapsed()
 
 	go conn.updateTask()

+ 8 - 10
transport/internet/kcp/kcp.go

@@ -154,11 +154,11 @@ type KCP struct {
 
 	acklist []uint32
 
-	buffer     []byte
-	fastresend int32
-	nocwnd     int32
-	logmask    int32
-	output     Output
+	buffer            []byte
+	fastresend        int32
+	congestionControl bool
+	logmask           int32
+	output            Output
 }
 
 // NewKCP create a new kcp control object, 'conv' must equal in two endpoint
@@ -601,7 +601,7 @@ func (kcp *KCP) flush() {
 
 	// calculate window size
 	cwnd := _imin_(kcp.snd_wnd, kcp.rmt_wnd)
-	if kcp.nocwnd == 0 {
+	if kcp.congestionControl {
 		cwnd = _imin_(kcp.cwnd, cwnd)
 	}
 
@@ -819,7 +819,7 @@ func (kcp *KCP) SetMtu(mtu int) int {
 // interval: internal update timer interval in millisec, default is 100ms
 // resend: 0:disable fast resend(default), 1:enable fast resend
 // nc: 0:normal congestion control(default), 1:disable congestion control
-func (kcp *KCP) NoDelay(nodelay, interval, resend, nc int) int {
+func (kcp *KCP) NoDelay(nodelay, interval, resend int, congestionControl bool) int {
 	if nodelay >= 0 {
 		kcp.nodelay = uint32(nodelay)
 		if nodelay != 0 {
@@ -839,9 +839,7 @@ func (kcp *KCP) NoDelay(nodelay, interval, resend, nc int) int {
 	if resend >= 0 {
 		kcp.fastresend = int32(resend)
 	}
-	if nc >= 0 {
-		kcp.nocwnd = int32(nc)
-	}
+	kcp.congestionControl = congestionControl
 	return 0
 }