more settings to kcp

pull/215/head
v2ray 2016-06-20 16:10:47 +02:00
parent b131f64f7b
commit 1238304b1d
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
5 changed files with 64 additions and 22 deletions

View File

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

View File

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

View File

@ -4,14 +4,18 @@ package kcp
import ( import (
"encoding/json" "encoding/json"
"errors"
"github.com/v2ray/v2ray-core/common"
"github.com/v2ray/v2ray-core/common/log" "github.com/v2ray/v2ray-core/common/log"
) )
func (this *Config) UnmarshalJSON(data []byte) error { func (this *Config) UnmarshalJSON(data []byte) error {
type JSONConfig struct { 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) jsonConfig := new(JSONConfig)
if err := json.Unmarshal(data, &jsonConfig); err != nil { if err := json.Unmarshal(data, &jsonConfig); err != nil {
@ -21,9 +25,36 @@ func (this *Config) UnmarshalJSON(data []byte) error {
mtu := *jsonConfig.Mtu mtu := *jsonConfig.Mtu
if mtu < 576 || mtu > 1460 { if mtu < 576 || mtu > 1460 {
log.Error("KCP|Config: Invalid MTU size: ", mtu) 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 return nil

View File

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

View File

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