Ver código fonte

Implement incoming rate limit (fixes #613)

Jakob Borg 11 anos atrás
pai
commit
6e8272f78f

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
auto/gui.files.go


+ 24 - 0
cmd/syncthing/limitedreader.go

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

+ 25 - 16
cmd/syncthing/main.go

@@ -82,15 +82,16 @@ func init() {
 }
 
 var (
-	cfg          config.Configuration
-	myID         protocol.NodeID
-	confDir      string
-	logFlags     int = log.Ltime
-	rateBucket   *ratelimit.Bucket
-	stop         = make(chan int)
-	discoverer   *discover.Discoverer
-	externalPort int
-	cert         tls.Certificate
+	cfg            config.Configuration
+	myID           protocol.NodeID
+	confDir        string
+	logFlags       int = log.Ltime
+	writeRateLimit *ratelimit.Bucket
+	readRateLimit  *ratelimit.Bucket
+	stop           = make(chan int)
+	discoverer     *discover.Discoverer
+	externalPort   int
+	cert           tls.Certificate
 )
 
 const (
@@ -381,11 +382,14 @@ func syncthingMain() {
 		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.
 
 	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.
@@ -790,15 +794,20 @@ next:
 					continue next
 				}
 
-				// If rate limiting is set, we wrap the write side of the
-				// connection in a limiter.
+				// If rate limiting is set, we wrap the connection in a
+				// limiter.
 				var wr io.Writer = conn
-				if rateBucket != nil {
-					wr = &limitedWriter{conn, rateBucket}
+				if writeRateLimit != nil {
+					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())
-				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)
 				if debugNet {

+ 1 - 0
config/config.go

@@ -119,6 +119,7 @@ type OptionsConfiguration struct {
 	LocalAnnMCAddr     string   `xml:"localAnnounceMCAddr" default:"[ff32::5222]:21026"`
 	ParallelRequests   int      `xml:"parallelRequests" default:"16"`
 	MaxSendKbps        int      `xml:"maxSendKbps"`
+	MaxRecvKbps        int      `xml:"maxRecvKbps"`
 	ReconnectIntervalS int      `xml:"reconnectionIntervalS" default:"60"`
 	StartBrowser       bool     `xml:"startBrowser" default:"true"`
 	UPnPEnabled        bool     `xml:"upnpEnabled" default:"true"`

+ 2 - 0
config/config_test.go

@@ -31,6 +31,7 @@ func TestDefaultValues(t *testing.T) {
 		LocalAnnMCAddr:     "[ff32::5222]:21026",
 		ParallelRequests:   16,
 		MaxSendKbps:        0,
+		MaxRecvKbps:        0,
 		ReconnectIntervalS: 60,
 		StartBrowser:       true,
 		UPnPEnabled:        true,
@@ -121,6 +122,7 @@ func TestOverriddenValues(t *testing.T) {
 		LocalAnnMCAddr:     "quux:3232",
 		ParallelRequests:   32,
 		MaxSendKbps:        1234,
+		MaxRecvKbps:        2341,
 		ReconnectIntervalS: 6000,
 		StartBrowser:       false,
 		UPnPEnabled:        false,

+ 1 - 0
config/testdata/overridenvalues.xml

@@ -9,6 +9,7 @@
         <localAnnounceMCAddr>quux:3232</localAnnounceMCAddr>
         <parallelRequests>32</parallelRequests>
         <maxSendKbps>1234</maxSendKbps>
+        <maxRecvKbps>2341</maxRecvKbps>
         <reconnectionIntervalS>6000</reconnectionIntervalS>
         <startBrowser>false</startBrowser>
         <upnpEnabled>false</upnpEnabled>

+ 4 - 0
gui/index.html

@@ -538,6 +538,10 @@
                   <label translate for="ListenStr">Sync Protocol Listen Addresses</label>
                   <input id="ListenStr" class="form-control" type="text" ng-model="tmpOptions.ListenStr">
                 </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">
                   <label translate for="MaxSendKbps">Outgoing Rate Limit (KiB/s)</label>
                   <input id="MaxSendKbps" class="form-control" type="number" ng-model="tmpOptions.MaxSendKbps">

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff