mirror of
https://github.com/syncthing/syncthing.git
synced 2024-11-16 10:28:49 -07:00
Implement incoming rate limit (fixes #613)
This commit is contained in:
parent
baf8a63121
commit
6e8272f78f
File diff suppressed because one or more lines are too long
24
cmd/syncthing/limitedreader.go
Normal file
24
cmd/syncthing/limitedreader.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file).
|
||||||
|
// All rights reserved. Use of this source code is governed by an MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/juju/ratelimit"
|
||||||
|
)
|
||||||
|
|
||||||
|
type limitedReader struct {
|
||||||
|
r io.Reader
|
||||||
|
bucket *ratelimit.Bucket
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *limitedReader) Read(buf []byte) (int, error) {
|
||||||
|
n, err := r.r.Read(buf)
|
||||||
|
if r.bucket != nil {
|
||||||
|
r.bucket.Wait(int64(n))
|
||||||
|
}
|
||||||
|
return n, err
|
||||||
|
}
|
@ -82,15 +82,16 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
cfg config.Configuration
|
cfg config.Configuration
|
||||||
myID protocol.NodeID
|
myID protocol.NodeID
|
||||||
confDir string
|
confDir string
|
||||||
logFlags int = log.Ltime
|
logFlags int = log.Ltime
|
||||||
rateBucket *ratelimit.Bucket
|
writeRateLimit *ratelimit.Bucket
|
||||||
stop = make(chan int)
|
readRateLimit *ratelimit.Bucket
|
||||||
discoverer *discover.Discoverer
|
stop = make(chan int)
|
||||||
externalPort int
|
discoverer *discover.Discoverer
|
||||||
cert tls.Certificate
|
externalPort int
|
||||||
|
cert tls.Certificate
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -381,11 +382,14 @@ func syncthingMain() {
|
|||||||
MinVersion: tls.VersionTLS12,
|
MinVersion: tls.VersionTLS12,
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the write rate should be limited, set up a rate limiter for it.
|
// If the read or write rate should be limited, set up a rate limiter for it.
|
||||||
// This will be used on connections created in the connect and listen routines.
|
// This will be used on connections created in the connect and listen routines.
|
||||||
|
|
||||||
if cfg.Options.MaxSendKbps > 0 {
|
if cfg.Options.MaxSendKbps > 0 {
|
||||||
rateBucket = ratelimit.NewBucketWithRate(float64(1000*cfg.Options.MaxSendKbps), int64(5*1000*cfg.Options.MaxSendKbps))
|
writeRateLimit = ratelimit.NewBucketWithRate(float64(1000*cfg.Options.MaxSendKbps), int64(5*1000*cfg.Options.MaxSendKbps))
|
||||||
|
}
|
||||||
|
if cfg.Options.MaxRecvKbps > 0 {
|
||||||
|
readRateLimit = ratelimit.NewBucketWithRate(float64(1000*cfg.Options.MaxRecvKbps), int64(5*1000*cfg.Options.MaxRecvKbps))
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is the first time the user runs v0.9, archive the old indexes and config.
|
// If this is the first time the user runs v0.9, archive the old indexes and config.
|
||||||
@ -790,15 +794,20 @@ next:
|
|||||||
continue next
|
continue next
|
||||||
}
|
}
|
||||||
|
|
||||||
// If rate limiting is set, we wrap the write side of the
|
// If rate limiting is set, we wrap the connection in a
|
||||||
// connection in a limiter.
|
// limiter.
|
||||||
var wr io.Writer = conn
|
var wr io.Writer = conn
|
||||||
if rateBucket != nil {
|
if writeRateLimit != nil {
|
||||||
wr = &limitedWriter{conn, rateBucket}
|
wr = &limitedWriter{conn, writeRateLimit}
|
||||||
|
}
|
||||||
|
|
||||||
|
var rd io.Reader = conn
|
||||||
|
if readRateLimit != nil {
|
||||||
|
rd = &limitedReader{conn, readRateLimit}
|
||||||
}
|
}
|
||||||
|
|
||||||
name := fmt.Sprintf("%s-%s", conn.LocalAddr(), conn.RemoteAddr())
|
name := fmt.Sprintf("%s-%s", conn.LocalAddr(), conn.RemoteAddr())
|
||||||
protoConn := protocol.NewConnection(remoteID, conn, wr, m, name, nodeCfg.Compression)
|
protoConn := protocol.NewConnection(remoteID, rd, wr, m, name, nodeCfg.Compression)
|
||||||
|
|
||||||
l.Infof("Established secure connection to %s at %s", remoteID, name)
|
l.Infof("Established secure connection to %s at %s", remoteID, name)
|
||||||
if debugNet {
|
if debugNet {
|
||||||
|
@ -119,6 +119,7 @@ type OptionsConfiguration struct {
|
|||||||
LocalAnnMCAddr string `xml:"localAnnounceMCAddr" default:"[ff32::5222]:21026"`
|
LocalAnnMCAddr string `xml:"localAnnounceMCAddr" default:"[ff32::5222]:21026"`
|
||||||
ParallelRequests int `xml:"parallelRequests" default:"16"`
|
ParallelRequests int `xml:"parallelRequests" default:"16"`
|
||||||
MaxSendKbps int `xml:"maxSendKbps"`
|
MaxSendKbps int `xml:"maxSendKbps"`
|
||||||
|
MaxRecvKbps int `xml:"maxRecvKbps"`
|
||||||
ReconnectIntervalS int `xml:"reconnectionIntervalS" default:"60"`
|
ReconnectIntervalS int `xml:"reconnectionIntervalS" default:"60"`
|
||||||
StartBrowser bool `xml:"startBrowser" default:"true"`
|
StartBrowser bool `xml:"startBrowser" default:"true"`
|
||||||
UPnPEnabled bool `xml:"upnpEnabled" default:"true"`
|
UPnPEnabled bool `xml:"upnpEnabled" default:"true"`
|
||||||
|
@ -31,6 +31,7 @@ func TestDefaultValues(t *testing.T) {
|
|||||||
LocalAnnMCAddr: "[ff32::5222]:21026",
|
LocalAnnMCAddr: "[ff32::5222]:21026",
|
||||||
ParallelRequests: 16,
|
ParallelRequests: 16,
|
||||||
MaxSendKbps: 0,
|
MaxSendKbps: 0,
|
||||||
|
MaxRecvKbps: 0,
|
||||||
ReconnectIntervalS: 60,
|
ReconnectIntervalS: 60,
|
||||||
StartBrowser: true,
|
StartBrowser: true,
|
||||||
UPnPEnabled: true,
|
UPnPEnabled: true,
|
||||||
@ -121,6 +122,7 @@ func TestOverriddenValues(t *testing.T) {
|
|||||||
LocalAnnMCAddr: "quux:3232",
|
LocalAnnMCAddr: "quux:3232",
|
||||||
ParallelRequests: 32,
|
ParallelRequests: 32,
|
||||||
MaxSendKbps: 1234,
|
MaxSendKbps: 1234,
|
||||||
|
MaxRecvKbps: 2341,
|
||||||
ReconnectIntervalS: 6000,
|
ReconnectIntervalS: 6000,
|
||||||
StartBrowser: false,
|
StartBrowser: false,
|
||||||
UPnPEnabled: false,
|
UPnPEnabled: false,
|
||||||
|
1
config/testdata/overridenvalues.xml
vendored
1
config/testdata/overridenvalues.xml
vendored
@ -9,6 +9,7 @@
|
|||||||
<localAnnounceMCAddr>quux:3232</localAnnounceMCAddr>
|
<localAnnounceMCAddr>quux:3232</localAnnounceMCAddr>
|
||||||
<parallelRequests>32</parallelRequests>
|
<parallelRequests>32</parallelRequests>
|
||||||
<maxSendKbps>1234</maxSendKbps>
|
<maxSendKbps>1234</maxSendKbps>
|
||||||
|
<maxRecvKbps>2341</maxRecvKbps>
|
||||||
<reconnectionIntervalS>6000</reconnectionIntervalS>
|
<reconnectionIntervalS>6000</reconnectionIntervalS>
|
||||||
<startBrowser>false</startBrowser>
|
<startBrowser>false</startBrowser>
|
||||||
<upnpEnabled>false</upnpEnabled>
|
<upnpEnabled>false</upnpEnabled>
|
||||||
|
@ -538,6 +538,10 @@
|
|||||||
<label translate for="ListenStr">Sync Protocol Listen Addresses</label>
|
<label translate for="ListenStr">Sync Protocol Listen Addresses</label>
|
||||||
<input id="ListenStr" class="form-control" type="text" ng-model="tmpOptions.ListenStr">
|
<input id="ListenStr" class="form-control" type="text" ng-model="tmpOptions.ListenStr">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label translate for="MaxRecvKbps">Incoming Rate Limit (KiB/s)</label>
|
||||||
|
<input id="MaxRecvKbps" class="form-control" type="number" ng-model="tmpOptions.MaxRecvKbps">
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label translate for="MaxSendKbps">Outgoing Rate Limit (KiB/s)</label>
|
<label translate for="MaxSendKbps">Outgoing Rate Limit (KiB/s)</label>
|
||||||
<input id="MaxSendKbps" class="form-control" type="number" ng-model="tmpOptions.MaxSendKbps">
|
<input id="MaxSendKbps" class="form-control" type="number" ng-model="tmpOptions.MaxSendKbps">
|
||||||
|
Loading…
Reference in New Issue
Block a user