Expose connection type and relay status in the UI

This commit is contained in:
Audrius Butkevicius committed 2015-08-19 21:11:55 +01:00
1 parent 2c0f8dc546
commit 8f2db99c86
15 files changed
+183 -123

No files matched your search

+33 -51
View File
@@ -16,17 +16,17 @@ import (
"time"
"github.com/syncthing/protocol"
"github.com/syncthing/relaysrv/client"
"github.com/syncthing/syncthing/lib/config"
"github.com/syncthing/syncthing/lib/events"
"github.com/syncthing/syncthing/lib/model"
"github.com/syncthing/syncthing/lib/osutil"
"github.com/thejerf/suture"
)
type DialerFactory func(*url.URL, *tls.Config) (*tls.Conn, error)
type ListenerFactory func(*url.URL, *tls.Config, chan<- intermediateConnection)
type ListenerFactory func(*url.URL, *tls.Config, chan<- model.IntermediateConnection)
var (
dialers = make(map[string]DialerFactory, 0)
@@ -41,7 +41,7 @@ type connectionSvc struct {
myID protocol.DeviceID
model *model.Model
tlsCfg *tls.Config
conns chan intermediateConnection
conns chan model.IntermediateConnection
lastRelayCheck map[protocol.DeviceID]time.Time
@@ -49,11 +49,6 @@ type connectionSvc struct {
connType map[protocol.DeviceID]model.ConnectionType
}
type intermediateConnection struct {
conn *tls.Conn
connType model.ConnectionType
}
func newConnectionSvc(cfg *config.Wrapper, myID protocol.DeviceID, mdl *model.Model, tlsCfg *tls.Config) *connectionSvc {
svc := &connectionSvc{
Supervisor: suture.NewSimple("connectionSvc"),
@@ -61,7 +56,7 @@ func newConnectionSvc(cfg *config.Wrapper, myID protocol.DeviceID, mdl *model.Mo
myID: myID,
model: mdl,
tlsCfg: tlsCfg,
conns: make(chan intermediateConnection),
conns: make(chan model.IntermediateConnection),
connType: make(map[protocol.DeviceID]model.ConnectionType),
lastRelayCheck: make(map[protocol.DeviceID]time.Time),
@@ -110,14 +105,14 @@ func newConnectionSvc(cfg *config.Wrapper, myID protocol.DeviceID, mdl *model.Mo
func (s *connectionSvc) handle() {
next:
for c := range s.conns {
cs := c.conn.ConnectionState()
cs := c.Conn.ConnectionState()
// We should have negotiated the next level protocol "bep/1.0" as part
// of the TLS handshake. Unfortunately this can't be a hard error,
// because there are implementations out there that don't support
// protocol negotiation (iOS for one...).
if !cs.NegotiatedProtocolIsMutual || cs.NegotiatedProtocol != bepProtocolName {
l.Infof("Peer %s did not negotiate bep/1.0", c.conn.RemoteAddr())
l.Infof("Peer %s did not negotiate bep/1.0", c.Conn.RemoteAddr())
}
// We should have received exactly one certificate from the other
@@ -125,8 +120,8 @@ next:
// connection.
certs := cs.PeerCertificates
if cl := len(certs); cl != 1 {
l.Infof("Got peer certificate list of length %d != 1 from %s; protocol error", cl, c.conn.RemoteAddr())
c.conn.Close()
l.Infof("Got peer certificate list of length %d != 1 from %s; protocol error", cl, c.Conn.RemoteAddr())
c.Conn.Close()
continue
}
remoteCert := certs[0]
@@ -137,7 +132,7 @@ next:
// clients between the same NAT gateway, and global discovery.
if remoteID == myID {
l.Infof("Connected to myself (%s) - should not happen", remoteID)
c.conn.Close()
c.Conn.Close()
continue
}
@@ -146,7 +141,7 @@ next:
s.mut.RLock()
ct, ok := s.connType[remoteID]
s.mut.RUnlock()
if ok && !ct.IsDirect() && c.connType.IsDirect() {
if ok && !ct.IsDirect() && c.ConnType.IsDirect() {
if debugNet {
l.Debugln("Switching connections", remoteID)
}
@@ -159,7 +154,7 @@ next:
// in parallel we don't want to do that or we end up with no
// connections still established...
l.Infof("Connected to already connected device (%s)", remoteID)
c.conn.Close()
c.Conn.Close()
continue
}
@@ -177,41 +172,41 @@ next:
// Incorrect certificate name is something the user most
// likely wants to know about, since it's an advanced
// config. Warn instead of Info.
l.Warnf("Bad certificate from %s (%v): %v", remoteID, c.conn.RemoteAddr(), err)
c.conn.Close()
l.Warnf("Bad certificate from %s (%v): %v", remoteID, c.Conn.RemoteAddr(), err)
c.Conn.Close()
continue next
}
// If rate limiting is set, and based on the address we should
// limit the connection, then we wrap it in a limiter.
limit := s.shouldLimit(c.conn.RemoteAddr())
limit := s.shouldLimit(c.Conn.RemoteAddr())
wr := io.Writer(c.conn)
wr := io.Writer(c.Conn)
if limit && writeRateLimit != nil {
wr = &limitedWriter{c.conn, writeRateLimit}
wr = &limitedWriter{c.Conn, writeRateLimit}
}
rd := io.Reader(c.conn)
rd := io.Reader(c.Conn)
if limit && readRateLimit != nil {
rd = &limitedReader{c.conn, readRateLimit}
rd = &limitedReader{c.Conn, readRateLimit}
}
name := fmt.Sprintf("%s-%s (%s)", c.conn.LocalAddr(), c.conn.RemoteAddr(), c.connType)
name := fmt.Sprintf("%s-%s (%s)", c.Conn.LocalAddr(), c.Conn.RemoteAddr(), c.ConnType)
protoConn := protocol.NewConnection(remoteID, rd, wr, s.model, name, deviceCfg.Compression)
l.Infof("Established secure connection to %s at %s", remoteID, name)
if debugNet {
l.Debugf("cipher suite: %04X in lan: %t", c.conn.ConnectionState().CipherSuite, !limit)
l.Debugf("cipher suite: %04X in lan: %t", c.Conn.ConnectionState().CipherSuite, !limit)
}
s.model.AddConnection(model.Connection{
c.conn,
c.Conn,
protoConn,
c.connType,
c.ConnType,
})
s.mut.Lock()
s.connType[remoteID] = c.connType
s.connType[remoteID] = c.ConnType
s.mut.Unlock()
continue next
}
@@ -220,14 +215,14 @@ next:
if !s.cfg.IgnoredDevice(remoteID) {
events.Default.Log(events.DeviceRejected, map[string]string{
"device": remoteID.String(),
"address": c.conn.RemoteAddr().String(),
"address": c.Conn.RemoteAddr().String(),
})
l.Infof("Connection from %s (%s) with unknown device ID %s", c.conn.RemoteAddr(), c.connType, remoteID)
l.Infof("Connection from %s (%s) with unknown device ID %s", c.Conn.RemoteAddr(), c.ConnType, remoteID)
} else {
l.Infof("Connection from %s (%s) with ignored device ID %s", c.conn.RemoteAddr(), c.connType, remoteID)
l.Infof("Connection from %s (%s) with ignored device ID %s", c.Conn.RemoteAddr(), c.ConnType, remoteID)
}
c.conn.Close()
c.Conn.Close()
}
}
@@ -294,7 +289,7 @@ func (s *connectionSvc) connect() {
s.model.Close(deviceID, fmt.Errorf("switching connections"))
}
s.conns <- intermediateConnection{
s.conns <- model.IntermediateConnection{
conn, model.ConnectionTypeBasicDial,
}
continue nextDevice
@@ -347,7 +342,10 @@ func (s *connectionSvc) connect() {
l.Debugln("Sucessfully joined relay session", inv)
}
setTCPOptions(conn.(*net.TCPConn))
err = osutil.SetTCPOptions(conn.(*net.TCPConn))
if err != nil {
l.Infoln(err)
}
var tc *tls.Conn
@@ -362,7 +360,7 @@ func (s *connectionSvc) connect() {
tc.Close()
continue
}
s.conns <- intermediateConnection{
s.conns <- model.IntermediateConnection{
tc, model.ConnectionTypeRelayDial,
}
continue nextDevice
@@ -414,19 +412,3 @@ func (s *connectionSvc) CommitConfiguration(from, to config.Configuration) bool
return true
}
func setTCPOptions(conn *net.TCPConn) {
var err error
if err = conn.SetLinger(0); err != nil {
l.Infoln(err)
}
if err = conn.SetNoDelay(false); err != nil {
l.Infoln(err)
}
if err = conn.SetKeepAlivePeriod(60 * time.Second); err != nil {
l.Infoln(err)
}
if err = conn.SetKeepAlive(true); err != nil {
l.Infoln(err)
}
}
+11 -5
View File
@@ -13,6 +13,7 @@ import (
"strings"
"github.com/syncthing/syncthing/lib/model"
"github.com/syncthing/syncthing/lib/osutil"
)
func init() {
@@ -46,7 +47,10 @@ func tcpDialer(uri *url.URL, tlsCfg *tls.Config) (*tls.Conn, error) {
return nil, err
}
setTCPOptions(conn)
err = osutil.SetTCPOptions(conn)
if err != nil {
l.Infoln(err)
}
tc := tls.Client(conn, tlsCfg)
err = tc.Handshake()
@@ -58,7 +62,7 @@ func tcpDialer(uri *url.URL, tlsCfg *tls.Config) (*tls.Conn, error) {
return tc, nil
}
func tcpListener(uri *url.URL, tlsCfg *tls.Config, conns chan<- intermediateConnection) {
func tcpListener(uri *url.URL, tlsCfg *tls.Config, conns chan<- model.IntermediateConnection) {
tcaddr, err := net.ResolveTCPAddr("tcp", uri.Host)
if err != nil {
l.Fatalln("listen (BEP/tcp):", err)
@@ -81,8 +85,10 @@ func tcpListener(uri *url.URL, tlsCfg *tls.Config, conns chan<- intermediateConn
l.Debugln("connect from", conn.RemoteAddr())
}
tcpConn := conn.(*net.TCPConn)
setTCPOptions(tcpConn)
err = osutil.SetTCPOptions(conn.(*net.TCPConn))
if err != nil {
l.Infoln(err)
}
tc := tls.Server(conn, tlsCfg)
err = tc.Handshake()
@@ -92,7 +98,7 @@ func tcpListener(uri *url.URL, tlsCfg *tls.Config, conns chan<- intermediateConn
continue
}
conns <- intermediateConnection{
conns <- model.IntermediateConnection{
tc, model.ConnectionTypeBasicAccept,
}
}
+3
View File
@@ -628,6 +628,9 @@ func (s *apiSvc) getSystemStatus(w http.ResponseWriter, r *http.Request) {
if cfg.Options().GlobalAnnEnabled && discoverer != nil {
res["extAnnounceOK"] = discoverer.ExtAnnounceOK()
}
if relaySvc != nil {
res["relayClientStatus"] = relaySvc.ClientStatus()
}
cpuUsageLock.RLock()
var cpusum float64
for _, p := range cpuUsagePercent {
+7 -5
View File
@@ -34,8 +34,10 @@ import (
"github.com/syncthing/syncthing/lib/events"
"github.com/syncthing/syncthing/lib/model"
"github.com/syncthing/syncthing/lib/osutil"
"github.com/syncthing/syncthing/lib/relay"
"github.com/syncthing/syncthing/lib/symlinks"
"github.com/syncthing/syncthing/lib/upgrade"
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/errors"
"github.com/syndtr/goleveldb/leveldb/opt"
@@ -110,6 +112,7 @@ var (
readRateLimit *ratelimit.Bucket
stop = make(chan int)
discoverer *discover.Discoverer
relaySvc *relay.Svc
cert tls.Certificate
lans []*net.IPNet
)
@@ -671,14 +674,14 @@ func syncthingMain() {
// Start the relevant services
connectionSvc := newConnectionSvc(cfg, myID, m, tlsCfg)
relaySvc := newRelaySvc(cfg, tlsCfg, connectionSvc.conns)
relaySvc = relay.NewSvc(cfg, tlsCfg, connectionSvc.conns)
connectionSvc.Add(relaySvc)
mainSvc.Add(connectionSvc)
// Start discovery
localPort := addr.Port
discoverer = discovery(localPort)
discoverer = discovery(localPort, relaySvc)
// Start UPnP. The UPnP service will restart global discovery if the
// external port changes.
@@ -908,10 +911,9 @@ func shutdown() {
stop <- exitSuccess
}
func discovery(extPort int) *discover.Discoverer {
func discovery(extPort int, relaySvc *relay.Svc) *discover.Discoverer {
opts := cfg.Options()
disc := discover.NewDiscoverer(myID, opts.ListenAddress, opts.RelayServers)
disc := discover.NewDiscoverer(myID, opts.ListenAddress, relaySvc)
if opts.LocalAnnEnabled {
l.Infoln("Starting local discovery announcements")
disc.StartLocal(opts.LocalAnnPort, opts.LocalAnnMCAddr)
+1 -1
View File
@@ -74,7 +74,7 @@ func (s *verboseSvc) formatEvent(ev events.Event) string {
return fmt.Sprintf("Discovered device %v at %v", data["device"], data["addrs"])
case events.DeviceConnected:
data := ev.Data.(map[string]string)
return fmt.Sprintf("Connected to device %v at %v", data["id"], data["addr"])
return fmt.Sprintf("Connected to device %v at %v (type %s)", data["id"], data["addr"], data["type"])
case events.DeviceDisconnected:
data := ev.Data.(map[string]string)
return fmt.Sprintf("Disconnected from device %v", data["id"])
+3 -1
View File
@@ -49,7 +49,7 @@
"Edit Folder": "Edit Folder",
"Editing": "Editing",
"Enable UPnP": "Enable UPnP",
"Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.": "Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.",
"Enter ignore patterns, one per line.": "Enter ignore patterns, one per line.",
"Error": "Error",
"External File Versioning": "External File Versioning",
@@ -120,6 +120,8 @@
"Quick guide to supported patterns": "Quick guide to supported patterns",
"RAM Utilization": "RAM Utilization",
"Random": "Random",
"Relayed via": "Relayed via",
"Relays": "Relays",
"Release Notes": "Release Notes",
"Remove": "Remove",
"Rescan": "Rescan",
+18 -1
View File
@@ -385,6 +385,19 @@
</span>
</td>
</tr>
<tr ng-if="system.relayClientStatus != undefined && relayClientsTotal > 0">
<th><span class="fa fa-fw fa-sitemap"></span>&nbsp;<span translate>Relays</span></th>
<td class="text-right">
<span ng-if="relayClientsFailed.length == 0" class="data text-success">
<span>OK</span>
</span>
<span ng-if="relayClientsFailed.length != 0" class="data" ng-class="{'text-danger': relayClientsFailed.length == relayClientsTotal}">
<span popover data-trigger="hover" data-placement="bottom" data-content="{{relayClientsFailed.join('\n')}}">
{{relayClientsTotal-relayClientsFailed.length}}/{{relayClientsTotal}}
</span>
</span>
</td>
</tr>
<tr>
<th><span class="fa fa-fw fa-clock-o"></span>&nbsp;<span translate>Uptime</span></th>
<td class="text-right">{{system.uptime | duration:"m"}}</td>
@@ -430,7 +443,11 @@
<td class="text-right">{{connections[deviceCfg.deviceID].outbps | binary}}B/s ({{connections[deviceCfg.deviceID].outBytesTotal | binary}}B)</td>
</tr>
<tr>
<th><span class="fa fa-fw fa-link"></span>&nbsp;<span translate>Address</span></th>
<th>
<span class="fa fa-fw fa-link"></span>
<span translate ng-if="connections[deviceCfg.deviceID].type.indexOf('basic') == 0" >Address</span>
<span translate ng-if="connections[deviceCfg.deviceID].type.indexOf('relay') == 0" >Relayed via</span>
</th>
<td class="text-right">{{deviceAddr(deviceCfg)}}</td>
</tr>
<tr ng-if="deviceCfg.compression != 'metadata'">
+14 -3
View File
@@ -176,6 +176,7 @@ angular.module('syncthing.core')
outbps: 0,
inBytesTotal: 0,
outBytesTotal: 0,
type: arg.data.type,
address: arg.data.addr
};
$scope.completion[arg.data.id] = {
@@ -346,14 +347,24 @@ angular.module('syncthing.core')
$http.get(urlbase + '/system/status').success(function (data) {
$scope.myID = data.myID;
$scope.system = data;
$scope.announceServersTotal = data.extAnnounceOK ? Object.keys(data.extAnnounceOK).length : 0;
var failed = [];
var failedAnnounce = [];
for (var server in data.extAnnounceOK) {
if (!data.extAnnounceOK[server]) {
failed.push(server);
failedAnnounce.push(server);
}
}
$scope.announceServersFailed = failed;
$scope.announceServersFailed = failedAnnounce;
$scope.relayClientsTotal = data.relayClientStatus ? Object.keys(data.relayClientStatus).length : 0;
var failedRelays = [];
for (var relay in data.relayClientStatus) {
if (!data.relayClientStatus[relay]) {
failedRelays.push(relay);
}
}
$scope.relayClientsFailed = failedRelays;
console.log("refreshSystem", data);
+4 -4
View File
@@ -5,7 +5,7 @@ import (
)
const (
AssetsBuildDate = "Wed, 19 Aug 2015 19:52:35 GMT"
AssetsBuildDate = "Wed, 19 Aug 2015 20:10:12 GMT"
)
func Assets() map[string][]byte {
@@ -24,7 +24,7 @@ func Assets() map[string][]byte {
assets["assets/lang/lang-de.json"], _ = base64.StdEncoding.DecodeString("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 truncated
assets["assets/lang/lang-el.json"], _ = base64.StdEncoding.DecodeString("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 truncated
assets["assets/lang/lang-en-GB.json"], _ = base64.StdEncoding.DecodeString("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 truncated
assets["assets/lang/lang-en.json"], _ = base64.StdEncoding.DecodeString("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 truncated
assets["assets/lang/lang-en.json"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/+Q7224cN5bv+QquAWElQOkoySYPfjEcO94Yjh1tbG+QgYABu4rdzVF1sUKy1O4IGszXDDC/MZ8yXzLnRharL5KtWLGDeZHIc+Ph7dxYffmJUureQ9WauY72wqi2X06NV26mar0OqnYmtP8d1VKfGxVMG8zk3v13ZTjOg6wA/hfn1YXxwboWemvVuqimRlVu2YHEaWPUysaF6ry5sK4PiTbkgX+bEFHm9Kl6ZtYkUpqCmLo+EpgaAqwiMhNYmoKoawLCvwxQj2HMygg89Qb0E9fUxie09AY0zm9GwAeJpgRlQm9CEAJqjhCmRJkBeaHbyojK0h6j1CPXzuy89xqnWRJuYIStadRjHTURpnZGuZV62Lp2vcQdeB303KgfTed8tO38gbBcT5NEdQs9NdFWzJR7gm6VeRONb3WDB2Cp21ot4E9jgooLk/YeBE7U0wgoADvlzdLB8UWCmYXzMvNuSb2wpunygvOhu9MB0iT2LAIrsA+ZmNeqpnMWQEHeJhgB7oZulW2jd3VfwSVlGrgasFVwW3RdAxWoGhc2JCQovzJNIxO/A7mich/dEo5Spfpu7nUtJ3YbyuTfwN3W3sz65r+QruwKQT8nCfSfQY9OX6vX0Tb213yYN0FCCJs5N42jtR46gmwMTBZsgdKzyPd2E5QIXTCMxoYA+bgQWJoDwrTxWK0WplV9gAXTkY9H1D6iPdWqsa1JrG9HnIV3ePPTrItuImhbQ5ZMfeu941ltwhJpZ/G04uk1TTCggheldiG2mZy3cwtXZ5MnwzPLGiCLqP75D/XFyedf8c1xaCLgpKP5id5O4YD4cF9kvQMDD/LYNCaS9tIqwfUArzOCzu7Tx4xKnTGyhq2xM1vlU7YbMWJ6oZemIKXuiODygO/NwZU6vDzQbMkPro7USreR7EvF+zVRyUUww4NC7OUlw65QyKUIuXorIaUyYRCZ7tZjG4RVlq3sC4mrejy1w7KMAIlo1TZO1+pHLfsyAoyJZKihN0aLsSy7TPBtbcml0/8BVDjqslsQDK667A4EMmJqCqLVGH+8Pm1PCVl0EwEYDXYkECF1Gjwq3Al1eHYvVt39zz6z3X0072f3jlUCLVyIAjxSOrl1uEJAUa9bvbTV2T3cz874mfNLpbMhrXFnwEOt0UrgDRH2CSv3cahSLoydt84bBXEcutxwDO7GoDAycIXWN9CJyGTdSpP2bXLmT9Av/3/23kS3D8esTzSAa/DyZkm3YtQXEmQ87cEV/uDl9GyCCsLx6HsGRSjMbGnJhquphcsL7k+WoGa30Dh3jnYPFl1V5MTCBOIFg+76ycNXHISEdUBVJ3mw9yx2UJhFYQhEocAkxBSDS+TD4r3pGo3hkMMwgmyvmq7VS4iRIHqAiCpp+t7k7VWxhsOPDnXZQT8LtxDsvHft72SozYl13kUyyOxvZfMgXapp8xzcwBS6we0BR7lFUsZvKbiDnC5ybGdApxDTXa6aHs6A35jxB9JBliKb75Hl5o449aEzQj7XIZasCTAiOtVxUZBQtyQIAzIZh/99/RSB+C8DFES9CwwVOFAAOSGsnK+FcC96rwC4nX4PM6EGxu8tzKpVo6xxJ1xYTGu8OOrcFlTjpmA1HycTTySbsN2k6qXxF6LxHtSI8WVMKpR9JvnONB2i6L+A3BK9xJxYhg4jn5KpQ4y0SjDuKPmWAT+AxoTZio5oC6iQt+Br0ZpidAOrvISo4vCZ/eazcER816AHAd7Djcr5GO8r1kBqvcTkcO16nywHEME+olmHlNWbFmHZYoC9cWD+MTyZpNHvRHZSPeWLPFjuJXSq58hlntsLOIIwCkZXAD60EzNRtaNaj3kDd702smq34uRhnxnTJY9LezcGMNH32s/RzDyxPlAkOQYkIgI0mJ5XBlSomXILWpAHY9pMRZ2EFOvDDQG6avOGbYJKwnxNyu4WgTp85aJujjYIM5gZnlPB7TXn5Eg6BiSiN3bZL9XDuZAMXSEwUYPn0+qHtiH1xwAhsi2xPfHG4MzO1ctOc5S+DyWMVG0Bp+A6PAi/9KZnrl1wYembaFVjLkyDvqWutK/VIQSr1QI9EGI72Lna4q1wYI6IlO/qrXl56BdGTB43EnBVJCVFb0APPq3oZfTokI76QuII4XJ3Vwi8A5rIY1KNWwz+4RmC4K90ZzPqwz8BgI6lXqO+kHS5wJqagujJuaNdIWTR3SIYovJtYCaeu/3m9zq0CIC98hYCE64S8WCbMCbFaCDFKGIxKZoxEFFXXEjsegxW1E8S1VTeUPplZwoGxkK6GCxwxhP1CjgjnDODEZLXFaZAh389UpVukZmLQmCMVVhAclbBCsw48/k4FCkWhQpFQ9QLZH1TU1gXKe04bIyGK2uWXVxT2oG61mam4U7tCo9tW8ztaJLnfNfjyJRASsCXhzYgH4ekDINFg6WbmhnlqZwO4/HS8oAhNU7W+D2IGSm00lz0KLtCgI8iZkVIaY4QoyJzQTWGM8v/9bY6V/Mezz+csdB3iITF7YrQ6WYiFvbjw+ebBdtNkBBCyOGWhOeWgE2j15hQWXqQKLsFQci4MIBpjV7gQgu2ACQizN4YS60EDnDwGUytEqweNs2Aot4I/RQLGRe6pMmgTIgVXiGg5gihXhgjdbENyIhMLHvRS2i8royiFoNfap4p/RcQKJccRG4LClarinJ7+LEAd3mB+R9lbymNtXFBZ/3dGLYGYWzBQ099RZ64OchbMKRBIi5OYH5pCwoZCU6NAli45FF/mySAhYWBBw+/H1kyF/AwcI2gJXmxgg8G8hG0IK9JUKaTbiKAa6qslLGNz0ZSnq7Uc0i30aDSS4ReUr6uwYdIHp52l/fjvQnLyq0kh0/NAYGvU8CkawwDct0+WfAkES5D7MPg93QNJj/awDWaUW2CPBokGBScgNNMbqIFRdP0fu9Rf+t0+64mNy+xAQot7uSgV8BAoDGzyK7yN0731qOm6faxhrFZCWmPUQrfu9I7zzZQiC12d4W/ezCJrZ0DfF/Yj4aFqnhD2O8gtTliubdjlYGXcBdGYfQGRMggQYdVfOQ4TSu7QhD1fG7wou+a+l5kZoY7/I13K6kwjQGZCPYP8oMgFKmX0K7r2OekpiA4LCCENAWBYfypd9FVrtlZsrqBYhCT5inNAcFFC3y5n0IWDm6ix8B31U4S+X6CTSG2pQJD2HiODG4WV2iJwezR6z1GlnjZjZvdH49yKwlbagQqjbK735jGBm4HK8eUOzkL1CZjMJBr4c2Ge46Lc6zYxuObAmYEnXfTxizZ/1IticKd1sT0EAlzmkCEGf0a5P3rb38fj34H8q+bgnkD0bY1dFYK6fC/wtd0ANIY3vzSG8yMJNT2Zgaru6Ddw1IjKinLXRbIuFaVheJdCzFM9s/4w6jDC4RJH9gGj199gXkI+VZzlb+fNrZq1kpfaNvQe6eO6vKg983BFc3oVvyXwH91VaowLkwOt1Hjuwq+HmCeCimpvcBhJsX8lhhdpGnDeiYidkKQ3IxEZ51/vwGHSdbZlWKczR+2TRvdnmetrqHYJQZGN/RkSjdF8vSZ69s6OeszfuA+609OvjRK4qmze+CLdOPmqV5QxiYTrr1x9bfWYSEPPjlWOZRXxKMdWn9ohYZFgtvk1x0eyZ6SW0/JLVoTemOq4Tiu6aMuNHwSokWvIZ3FR3NQo2t0xIQ8HKesJdhfRQvddcOHh+rpTLJ6SX6p8BkMieZHrxovcH7kgqu4JM2KbIVnr+faDkf0jzyFciMiBR7DIcl1J3yBVpAS25qmMdRxtPrqC7RmX31dlKJC9Hj9sJCCFgaaDuNILDTwlPiDVZgsKRW2Ds3UEJMcm2KZP1YFh0WcYSSYP1HE7yAUftOxNPS9RChLgB1WyJCK0i2DjyXbtN40/JEvUY/qX3ldftcxi6mmd9u9RvIail1ilpJ+St2yzFQPv/6fYf/oUxeIu8PR7i08TvuXZ1rD2IeTo2PaP3X46RFhenwwCxVE5urwz0cj+RD275jFx6bgdYvYtxaCkGsmkQi2hNCu37Clu2lGoiRktlJNY1eA1u/+UHegg7vAkEnnb8nhEJ6bDnJOen3+8kSOKZnGkq3W671cKHKTHiTR5/H7eAB5DIsSbUNMS3k7Q3u+j2VlzGhl/mOmvHOj8ZUHzjsaXjkW+Jn1wkP6+isEZjvW6SaOYZhSteEWyg8f8KrsO6/vzrg9aLRLqpqf47v0sDCHYBlxeY/J/wL+JBMV7xYe1+1oS5/3IrNQVd5lZ/guW+O7LDktTCIq/N5zPHvXfrr545GpiSsMq09oUT4/OUFVsIAENIX2dzzMMKGN37S8057finfv0Gn9Z/RFlXhDiN4CGcCJ+pPxTi2NHnZmnyK3kbRLLTDBw2kQocf03SVK3jH6TQy7Bsn0t1z6d+QfVLjW/dzkd/BzKIiA8Nn4+oN4eHIf4Ex6lKTfkrsYnl+QkgO4QQqskhj6PL/bC8hKrMnreAMxLj4Dp09/dYPJfVsPX/Dxb2Doy0Y8iAY/z5W6lGsuBov9HgUmJQFI1aLxr8jKx9gbaUQU3Z5HsGQ7aqn7kcz8uj1vpY6dmglBj1Q1Y6SdUOm5TloC7vBePZbPfYpeQlPFnXHcTIj8Pc/4Sx7pqVdOXR7I5A+uCjrCXArm6mrEJvMfOgk5+s6/7CYCdEuMo5aAg1HfvXp1+pLCC/l+chvIxLLKSJKaI0TI32yOARtEeOTGRy19cctlMj6UHIxGyHu3AhhQyrypjOH4ergwbHw1xiCGah3FdZuM1PpAKvBC/IS3SNc1FxqHn4UcswsBJvDFKJh+hTR8n5sNBv0AbFSkCfz472iWdyp/3xQ4edg9RHqEpferokxiy8fjuaGRUhSR3iNVtlIVllvxN6+W7CSaJ9KYnnhgNyB9gn1M/Pi2WT6Q/sE05mX+mR9gfs6vLLine truncated
assets["assets/lang/lang-es-ES.json"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/7R8zY4cR3L/fZ8i/wSI/www2+aurT3wsAI1JCVC/DKH1MIGASO7K7snyarKUmXVDJuDMfwcvvFiQAceFrrxYmD7Tfwk/kVEflV/cCitZUDmdGVkZmRkfEfkXv1O4f9u3VOtWenBXhjVjs3c9MotVaXXXlXO+Pb/D6rRb43ypvVmduuuuvWqVe3mU2N6F2c6VRlVbT5qr1qnBmtahh9s5Wa3TvI2l1jqjevVhem9dS1+rTFhUHOjFq7psNS8NurSDueq682FdaOPsD5srYGkudDyefNzi4n4Tzdz67yyTef6QbeD8aobDZACOh4nKlYn+LAmoAi2t643PiP6/JH63qxpu9NagyqVqRU+pvG5Gwcavbcw/UJjOI0sBsJUxha8QRqqKv68+auubF98VfdxzoUpBlVlfee8JbqWgA9dXZm+BOwNwzkcoAQkOi8Z+GuC/tt/R/gxUW+h+84M+utiGkjAmN+3vQHyIO3WoCmHp2e70O3CyAHj31tj6tS1S7sae00kKiG3RuK8ulb39aAJ8qWrcLc1/qv04HwB4i7Vvda164YY5ZXXK6NeGGIB267C2e8bb8CWnekbULRXuEvTXmw+Olw9zmgb5l3bLl3fgB/w9+hdpkvdneu5GeyCUa6Xer75Cb8yvVtl3oGFWl0TkzW6rdQ5/l+NtYZzEzkN+MzUowFD+OxwcY0DYxHA0oInl71r+JdfM0nk9qKwYV2s6MJGjjh46F2tVZ3FYKYe1FhrcU5SWZm5YbY3tW1sqys+Y52uXXnbLnpg9V5XOvP9IUoSGo+EQBOigVB57hpfiJE9ocf3iXNA1HQL4gLdaoS0BBhIOK4XOOqqAhQIMpxbHwdBoktT13z601HXP47WTIQi7UAHMy3YejLK1yk7MhsTJTYflGYhwIyBlMXmpzYffBxAYdyqGrsVFjVBggdsDhItgqYgqM0HgOnEgt8YIqlZjvX/oynlzwgxrni1B31PSkYdzfHhOI6ePn+lXg2Wdoli8crzCTCSgMBPK1O7yT1UJiq9BFYb0BqqSenlIHriMfSh1b0ael2AOc/a5tT0vU6a6FR4lweE3coRqPITdXlOtPa4MD0Isw66H8hYgBNta8JcwOr+RC1G5llPbKKVSAfswnvhHCiievOxNbrYpSMlE6gQfpZaCGqiNaxgFRMzUZVpgSt6N4XuLAkSCZapvQHyfcAQJBGBcGASRUzj9s2CVl1BdurppDp/z3PW+HQ+qL/9pP545w9fiVg70k4QHlJvQ2/n4J7e3w2LbU0g1ebB0KAPWa5TyPbcEXeDBHfjPvdNbQY+wjeuvDn5XqWBfHNiWdSj+8w49xn7PbYlglVksKFCEivmLyJHn5//VDeM3VPXzHtzA/DVbRH229fq6Oq2FgNz+/pYXcIgs4pcyHXPVLRoMoG1+oPJ0urqSsauabGrsNg1FmPNIcyxAFPCfVHZGJIhdOU6X09xDNYuDScJwreAnFAdFibsUJDeLUaWhEjL9GFiWe+7y7Z2ulIvtFztD5Dzha3whRwqLKz7ld6GztvSaLmpjAeVHQEKWX5QWfZc6N/MQfSrcENkcN/lMWB2QwLgHi+ERgIWDFSi0Grywl49b5/T8Hd6DvVHy/CXBDSI09bAVplOwzeAWL6+Zbu7ZJNe31I6+iSQRwxU61Y3doEBsA5sPSlJ0dis1yu6MpjKNWkrEs8wfSYqNZgnWEgYoezfhK0rch8co6PJusH4CSaj6QeHLd0EAZpCXgbd3jjvLWk9IJXNRzTGVXK0ZtNz21ULycdCA9l7fwIzauhQrGUnKIONAdWLfZJ5pHtHOAmEsajYvPpEbaav0X15SJ7ID8lfEXbkX7pwPioT3Yy4wEONiRW8G9OwzEx+Rxha+/kIq/+sD9xDf7TFcp5VRgeYyaSDCBUzJxPY02NDouYWugQGOVC0EhNWO/eWFPOS7pRtq5/B5THkrTy891I8Mr/2hD9T+zFw46WquPpkd+UxUWhPfmo2fPMRApiCk1m09D35LN7S+tpPFsLus/Isgjy5iuwkzfwQg6HgIcqBIIC1JreRbSFbAzVfqzP4kvCr4HnGQ+h+cU6aTDyilla2hLIufcNyl3QWTbuYBvu850M6NRdbI6JRbHUYfTjv7DM0HX6nLSxcxL//ZJO7YIJrOViO9Cjus21VWDO1NLh/8SDz+V/fKrCBPEcauF9Pgq53A5sL8SwC0yH6rZjpHDRSdI0h7XAVdkBK/zg6zxRgi+9sgJkfom5b1CN4q99PG0ZlZSPW5HnE4Pkc1MA/pmXHyJcGAFh1FFjsB8feZmKQA3shzgrXUDOC4j+t+rFz6ihgeZzJlexK+GvyvfRi4lVtQTzRPvi9p+Equx5xju2yrxYgn+vhnOBejIOeRkZTQF8slpTMt68e0Wf6J39RiCHOyVsS7wk7eH/pejbU8e+w0yPS8Uv9Xn0LIpFzRd9f+VHDfqojrHX8mXWhpiQDMA7bvhn8bFnj12zzmNRRqw5F+jSXzBmJyy9e3rSmD+6N/J2u9tvazcEb96N1jl5LYTZXDHJogjoz/YVQhP4CW/fRcbppjbMh4PTAk+O2BfSdqTum83qsElN8h+AG9nbF0/KPMPqIbQwzqdjh6QAxHZtzYYlto70NnIyYwIvV2QffUlwFa0YeJK6xgYd29L395h8QZJL8bz7iiym9yTRcrNDjpoccVg8xN1fphjIBazf2US9T8sGQj06Zjt609C3pPihYB0VBHl7wU36jtRPuMbPAVALvkotduYI8MdUYlOPKXhjOGZKHis9HdoaoAPdPaUjzDlqpMseCesowBg1Bc4KwwSdUR6Q/zRuyCO4EVqN1Mt/2r28l4n5vTBddGL7JJ5RwhBBkwxRBH+NySIs/tL1nJ/3J5oOHtgQtyILYpnC5HmsGrClJszA4EiuazX/WA6VmYhoIhLdzW01neWM4IPnBkkKmM2w+0TQyle8zZNCkjAO885zjfOwWN4hsTRBT8G1hOwSijl66QdfHBaiMxu9hyhPOIr+SbM1WsoYuKOeB84x3thkbdW8VYhyEWHDH8TGJ9xNoefgoWj1raz7X2ebn2qlGPmcv84lteamHcAeIEG/VWacldDo0FGdy0g8W23XEjz+OZpRpREqyksFgJSW+cHVGb8Q1qdpcwIbCBaggzJU6QnyDy4ajQKNdbSSqQDC2FlBRA6cIWioEAwLWWlrjaOFoM0megBafZAGveFh0flzMukT6pyYo3Kdju9D562URQT7l0Pr+bgBJYNnOP+VU9OnU8gJkIgWI9RtiQgnXt+TgqZOMQ/69L4o5synjPw0c8rQhpuAvbE5qPvue45Tv0+/lchrvJzXzDEfahzQ4EEpvB+1nXaoTxD/jyMhuHCk9Hi1+7kLkkOtBbSi54Lj8UiR3Xbnwyn2RnfAjdMaOlXgGAvbELJKNlAxpO9aIZrbykORcRbc06HV2YI1IPZdiRvJP1V+CI7voDcf3dqmAFRWdgjaGipqpl5iJwIn49Byh9YIi5KN/P1YUWs1NSEiSZfTnkPkFyLOUKJe9u0loQ8Gfppv5cbSUgSR8ZvAhGAPKEXurWI2TN8QZ9QV95i1FIAUR2l7KS6OntJIkBaA63uRyF5OBs4451gGGY12x7z5wPHpUGyowwYYMa45HiUyVWWqI6b6gyLYFWY9n2Yd1ZCSAiK4b6JtWs/9N6Ywc/xxV5g1u60IvqPjBWQrCvqRPx+7TkkR+OwzKfvpz4MxHbj1hKdGHfMOtYaO5WXL6QrIwxHM6lP1Cep3xfo7fS33hKFUsSzEufPUSFhfVDSUlvYq20hJDU8imD2n9bWQvteS9ik2N7ygjHOGo2mguo2HUUn7UW8OTwshWNn6UpMDFntn/PNrFW7UaSXxAWT92NB/X3xUu4bfj5qNWuLeOpK8yObHjHR+rEOYX954cKBtgJAFR2NpI2QryVabnXoT7ekr3JRp0l+YZmCJ4ZjX5K32n7AZTzNVsvyTh0U8B1L263gMEQlRuC5JjigvJuMe/+VRSs5xvPnmYzOyPYxpVIAQ1WLWFnWzO1YmnxoR8aQChmjXCbD0hB8MGaxGXakv8SMvI4Ch0z4NnWqjzLWKfKiNwhhNFA/QCjhcYt1jxDDewGIK4S9mMOOOcsgUc68csiB3OZxLe1BKMaSmEFrE522/6COJIobvnQicxYpDs2Z59ZYdiXy67F4mGnX0p+xmCYdEfeTNCYTsNUGw6EHHFZryhsD9x8hntHAs+vNRkpHAWTvNeU4ehBPSwKThE9kR2Zgm19uS2ZZliut+aP502PUF5Z9O68/77+Hoyu+Jtd7bLMBB/ZUMxxvTJUIQqsXoCkpJR4ZqcbjhhpGFaQ4olcthsWtOpOKXdD8EWZDMwAwFS/Vgh7my4yjrkKnzJfJ9L6QDzy5C4eeIgAprTOMUgZeQwBb44XJpUropmLuIPwg2jz/6CrqBJBuslrTjJnrEngGCPvSpdJ1vagiyBn+EDG8KFvYFxpTmzqHbLY5zZqvnaqv2ZK/IcYK2YmlxhZursJs/EPWilLua6haBWGNvZ30+TsavYhwqOF5230C6ZZJ68rNosB3E6fhOaJLPMRKnjyUk9bS2nWwQRlvoRyHkhByX4JwVFxqECUVh3dHpVKNgwokhoYmlUQFjq8EmTU5wM1pmljzeUObwA7cYICCJWGDgUf5Hy5FR2jr8cwshp9EWmjGOvzaeW6kA5BPMI9BhZRfLZhyL5vvjrrIFo7w02OgMKb/66E22cubEHC5w6CZVPNz9XduXUcpwQZ9CrlSFddEMZCJa6PhRHnbHJ/aZ3lyFN+UiMMl17CzO5KlMzFPDDWbILVrTFrzTuui6WOgfTFomMM/GgeB47R/kYFBY9793gEDr/sqxmzblxmsdHy1HUpGJLG+SwMkCUhj2lq6jVZ26o1ANGVcLine truncated
assets["assets/lang/lang-es.json"], _ = base64.StdEncoding.DecodeString("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 truncated
assets["assets/lang/lang-fi.json"], _ = base64.StdEncoding.DecodeString("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 truncated
@@ -50,7 +50,7 @@ func Assets() map[string][]byte {
assets["assets/lang/lang-zh-TW.json"], _ = base64.StdEncoding.DecodeString("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 truncated
assets["assets/lang/prettyprint.js"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/1xSUY7TMBD95xRWvrISuQASEiQsCxSVKpuF79nGm5g442hst9oijsNJuBgzdtSW/eq892bGb15zAFIWcNiRDuF5IYNBvVW/iseheFPU0Q5ABrB4XeyBiQYC2BW+O4DVuDdXvCq/rxzeSI8X6aT3I4NeM7jTNKdxbQWR1pMAZHCLgzV+TLC6qy+MKh/QBN2rjcGhd7Ns1rL5fgFcJ3x1e39hVMmFSRaeDNMfDa6NTySQ2GJGVfP+TKiyAYQeZGyMTH+KeL7eBCY+85EZ/pSjvwA/p71mPLlq0zK1caQlhvQri6zMfTVhjOwsjeIjM1tHRz0woWo3zX//WBEkkg8xJGuI/3Vtn9GRl6wW6dq5NaolVHWbCApxiGxGlTXBydibrO66F2quIenkqvYb662bkztVrlUSJYI2ep9t+4Pke9R9fjhIkF2kKcM4MXyYiFPP7aexarby748G07tSpL2sdD+ulQ7MUb6X36/+AQAA//8BAAD//5YJ/N+MAgAA")
assets["assets/lang/valid-langs.js"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/yTMvQ6CMBTF8d2nIJ29j2CiEOOgUVNJHIxDgQqVppC2dPDpvacsv38/kpOUL5Kyprso14diV7xE04utaFVmz3/atSbfAtNpRlvgMnQq0ZCh44P7McBnqDpwh4UxkfliaZzoLLkWL64BWHRYnHGaI5Vy7b3m+onkDcVOSEzE/DIyv4Gq69r6Kd6bPwAAAP//AQAA//8bXi5E0gAAAA==")
assets["index.html"], _ = base64.StdEncoding.DecodeString("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 truncated
assets["index.html"], _ = base64.StdEncoding.DecodeString("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 truncated
assets["modal.html"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/3RST0/cPhC9/z7F/HLogkQ2gDjRXaoWqVIlKiHBpceJPUlcHDuyJ9BtlO/eibNNYbUcEv97783Mm9lo8wzKYozbrPUaLVSoKQPG0jhNv7ZZfpGBq3NkDrlGxrxE9aSD77bZMAjVR4JPwKEnuIZVZGSjVjCOB6wn2pUeg06sL95bQneS2KcT+OY/gM3/eS5LUcCt73bB1A3Dye0pXJ5fXMFjQ/Cwc4ob42r43HPjQ1wn+Mx5bEyEB98HRcLXBF99aEHuYl/+JMXAHlhEmEIbwVfp8N3/NtYi3PelNWoWujOKXKQzeF7D5fp8Dd8qQFCS0sK6v4MXjOA8gzaRgyl7Jg0vhhsBSMzKWDqb5X74HhQ68CWjkcURIEPD3F0XRTvHX/tQF6JaSLxiKirPkyGHzcm1QevrZO3+fljNL7ZeXYPFUNNs5jG28o7J8f79GKIh6X4AtBR4/ufDMPW0j+O48ITZXL0lsmFLrwACiZ1ULYmaapsZCZ39ZVQoQya60+Wkuikm6GvuMCS9cfwXsGiulrQLyfv9Gkqvd8khDuiisr2m95n7/NIgZm91Ku9lVl4XLV1m74B3HW2z+bBwSnYgX66pwt5y2sc2gzT8MiStWZSP2PTGGTYtxcWWD66M3ccZliqyyHRzOyV8aNymmJM6Uu6y3W/2yx8AAAD//wEAAP//qvxG6f8DAAA=")
assets["syncthing/app.js"], _ = base64.StdEncoding.DecodeString("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")
assets["syncthing/core/aboutModalDirective.js"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/1SOMQ7CMAxF954im1upSnc6cQBG2ENqWktOglwHhFDvTgpSgT/+/yw/F8fMTmxIQ2asYX5ErxPF0fokCE1lSuxAgl7pVgB3TlkPaXAMrbnkQlOKpm7M842uEdQs8af4lLMKed0Z2EP7NymGKzvFo3BZN4NuNei+/06EdztpYNiul75amr56AQAA//8BAAD//xLf4CHFAAAA")
@@ -79,7 +79,7 @@ func Assets() map[string][]byte {
assets["syncthing/core/selectOnClickDirective.js"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/3SQQWvEIBCF7/srPBRiIEjPXXooe2+hPZYeRKeprJkpo2YpJf+9atLdJWzeSZ/z+Z5q7JPXrAayyYNswg+a+OWwV4YYmnYnspR1DCa6sQyAz8sXPHhnjk0nPlMGHKGQdyeHlk6t+K1QEUNMjFdGkXd4fLjigqFv6ES+dwCMndAxcmhXUNEyoQhlY1bx8hZQNGoWc+cS9iiWlqqH+PZvy3a/yXL+IcicJZNqumHQEV6LvcVVRs2pz2ThQBgzGuTygvf7jw3y3FQxDDTCk/c1KWxFXQBt7Vyqpt8Yn1bedN5N+105/AMAAP//AQAA//+SF+4JDAIAAA==")
assets["syncthing/core/shutdownDialogDirective.js"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/1SOwQqDQAxE737F3qIg672eCv2F9r6sqQZitsRspRT/vdqC1DnOTDIvSJ85qB9TlxlLmF4SbSDpfUyKUBVule9IMRo9t8KQrUuzXChw6qF297xeUBJXVu79rW9StKzyZ/zMyZSinRycoT5EhuODg+FVeU13imajaI6bN8LZDzYy7B+WtliqtvgAAAD//wEAAP//3qFOo80AAAA=")
assets["syncthing/core/shutdownDialogView.html"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/0TOTaqDMBAH8PXzFMNsXL16gZhNj+AJ0jjWQJwJzgQp1ru3lkK3P/h/uEXGkCGNPepcbZSNEdSCVX1LjZFUEVIU7rHIRuu/TBOCJcvU4763wzcFV1lKJqMWnmBrYM3B6DjQN3+u/MQPD442J77DHBRuRAznMpwlF9cV37juc8o3LwAAAP//AQAA//99X8KxnQAAAA==")
assets["syncthing/core/syncthingController.js"], _ = base64.StdEncoding.DecodeString("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 truncated
assets["syncthing/core/syncthingController.js"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/9x9+3fbNtLo7/0rGN3cSq4VOekjZ9eut8f1o+uvSZwTJ+13jzebQ0mQxYYiVT6seJvcv/3O4EESxAAEZae79+PpaWRyMBgMgJnBYDAIk+syDrPJKp2XMRsN89tkViyj5HoySzM23PkigAd+J4voerQo4WOUJqOHcToL8dfLLL2J5izbCf7gkPgYHyfLYhV/9zyds1GRlWxnsgzz5cuMLaIPo+GD4c4BL/qprqvI0jhm2Wh4qag5rl4Ox4EiIxg9zGfpmo2Dh8uiWI/rmsfBM/gVs0uW3UQzADi9YUmRN6kcljkL8iKLZsXw4Ivq9d5esM6im7Bge0sWr1kWzIHOJEKseQ12E2YAx25OADA4DB4faF+S8Ca6BkKS66NNeAvfF2GcMx0mTeIoYfS3jOVFmGH5+nsFULUeqar5Mmo2Dh+NA5OwLNJj3ovi/WjnQIPOWXGeFAAcxpKrE+ggIGQ5Dp48hqcFLxg64XQ2cX3SWVlO42i2x/HRjJR1zdLVOma8WYfBH58OzO9IuuvbeYKDBSBwiFEwCeNsy2kkLMvSDL9dvTW+wdxgMV1sdXt+Al+GQ+PLnCHfLRjFx1fsNydNizSG2dMFtc7SIp2l8fES5jKbmyOq6s51mhUwYEMaj/gO0/ImYhsrFkGThZScseQUGUmzpFxfZ+GcnSeLFACSMo4tjLkswsLJEwcAsOMahq3l6w3Qbh1kCWNzzkCix8S312kRxvp8174fl1kG8+JleI0z+4kFCj9fRv/iICamRRjFnAqq9fxbVy0a1BlnGMCVCZ+AbG6Bb1HVBkLRGiPfmWKCLm6mtwXL94PHY+3tAjDj21o+NDGPNlEyTzc7kyn8OxpO2QJ0TpnEaTjXxHxbtBnyVZ/zn3ZM8h+C1hpU+kHMlctyBjM0H7iq0qUo6AwpPitUMOjDbLYc7UxiwLnjpgL7/6iezFpNw2w13A+GJywejtsf5lEmvwUj+L3ThkCtjQAoAtvfirScLfHjm/Ucem/Y7AqCvPOZg7giA839KLUSaPmuyAtBNmwezaJsFrNH6SPo+sRKbZiDNory90N66NS9KjXRxYtn5y9OXV0ZLYKR1Lpffhk8qJVsGxCfjBVllug6r6Hb8EFGpTHOjOvR8M35BUc9bPa6QMS16OUttGfV1rryo1DM9o9SdXGpZ4E6qQWnBeKslpyjNpHcfppcs2JUZvE0BMtoNxju5ZzmPSkzhzuTXEyYUc1jGFEhxT5D3CJgi5s7Qukqc4OtouLvr1+/5ArEk8Cb2Z5QW9sQpynEz0OfYKDUe9vQqKtMB5H2YW/Fpitgga3VrMpI1QUsPpSNqlU5Gv6vhBWbNHvPOQatBzsKrMvhMpqz4Y4JXWPshs2XZcHFhxXSpgSUuDg785EXLU3z8WPwQPDknmTGYqGEBsl2gq9IVYfssrJ+p01bF7OG1YDX9DFDHo6DMDOqB5v/FOZJAQbMZsmSIAwQQwAqMw7QzMgnwa8swKVXscTlV1iUOTBlDn+nMMhu28jgLUjGMmNBWhaAMiyGebDJUliffvHndlaTE9jwe+0xBAGkE8mQw0MwMSk4yZWjQHZvwCf/OEjSIggTwWv+iiypOhYlWWsetJrDmREwaEqbtL8dBt8+fowKtPHy+8Pgu7/+1UnwNUtK5FAXib2kRrOUr/RolumWIu0SKOadc4pzrucsk11x+fro9em7478fvfjp9MRvuqGzYC4UGHaHqR+w95qr2CsEkYuotw5NYQLzvmZSCU2K1Gy2vSiTa0L+kv/R0jP4wDA5X4DAEIWCZZgHvEdBlKD9CB07RqEBMiW5DQAmiKO8CNIFhUiu5qM8SKc4hQvG5c4KpALoaKgkgSWuLK+AwVa5pXDlS7AS4luoOy2vlxNy7kqe8Ik7lNQObfNBW3VpjGotPdWz5Xh6dnF89Ozd+YuT0/9+9+blCQwuz1FFG4yetZ6c/nJ+fPru5Pzy+OLFi9Nj71ph1EA/EQ6bKzW0J9H8bR/j14/SnmRyad5BpGNi2YoYK66qvmS6NtfV6gGt6PocJT/ispyv2F04PKCK2zXbr6TMBP+kAcP5HP0vDVh8Yw5qqwCpfYF+HHpXCMKfPH7cVYuHxaOcpGAnu50QDdEqPJCTdM37dVJmR2Dmr1FyWTW5kHZljj4csRBBSxqF3pSBjEtYBLIuC0KFKEnREz1DK2Nu8h2wbViwCZMCLaYwf8/NKzCzMvx7Fb5nIPNmyxR9GMGPaEmxYA5LuoKXodBBsWl5jWhWwbzMkDjuvA1jdBWX63GQp4gl5+J0lqbvIyAAiCaRATFFtGIobfH3IspA9N5EeVSAXEaZXoBlp7CA1F7DCGI0YWEyr/EB6CrN0JgE62eRlqA24H95EF6nY6ROcoLC83sJBgP6b0xNhFqVk/gLUoh6K52VK6BnIijElWMczthob/TDPvz3z4+Trw7+kX+1UxeCv/5xCP8bXf3z4O1XO5OvHu58/Cf8f28cDB4+GRBGA5crNQKb8miRAsQN6kKHA1h24pbEJEk3MGB3g8HBKvzwCAYZ//TN4+Cr4Otv4X/fPH382GryWQQRELjbYMv3zZoeBQor/IP7BTb68UFDqnRaUJyY+9KDUs6/Ov2vHmLe4qivJZL48lZYXt465+zi2cnpq+1oaW8H1LRIkwm6+xF28x1pBIV4dv7Tu8ujX3wJLLlnkXtGpStLkdDLTyLE6F6UcH/hFt6S1k4Q50HzXT8Hj+/wuvj1xbOLo5N3L19d/PTq9PLS33TP5TYGbbuLPUZyNwOfBWiEERdVovejROCj+KPQXNWGZhudjhJM0wrhlWO5ULUEMGrAV4iCsGVVgYyBdprzvQYUGflEvgB7e8L1ub0odEDE5mdZurrIousoaSAxPvVCdwrCbwNal5EY668eSNdlHGvNky88iwqvWrMsvukoDEoN1jhFdovKO0tLUJTlukKHdkERxCzMUWGvWTaDkYlKnKtekOebtIRF1ZQ1waaRUNPTmJkLH3xQKagavg+eoF9AtnSXZOyu2Xu7aix8fxjYnQj4NDjjqzJ4sdbgF0PTak7iIyjal//Sdi4+7cbsG298ylbs2ade2jEITu/Lf91wwLd99cMOOW2sA/JJ/VdHiZM0YVUB/IOGJySOTaXjQwi41h6vzZX2YFQXqWBtI6thx4vtWbVjeigrdg1JuQB9AQVlnf7WTO1f26p6zh4lqFuM6RLZDUZJBEZJV9FeLVfPNGPhezsIPXf9jUB8zBAA9fPA6tgdnKQbvuP8UoIOxsYw62veXb55/vzo1f+5Jx+e1a+mTJy8XK3C7LbtGgFrbPZM37Xv4R2RTTm+eP7y2enr84sX9+iRfGCu9Jv2qtPCI0sQ9gw5MizFSa7WsC0bFpsIahjDQEw5N0sKPT4En0qSzVbrxmzt0XzkGhZGf8JAODwGthmKAXRR0t6vM3mCD7Zj97CLPVAzYcphU3cNXdyH7xPREtxfBDr2EGPf8Xn66tXFqx4mt89Moz2ztfM6dxOprSNwS0hbvozlrtc4WLIQQ6nGgViiWFZ9YrdG2376A/HsB01s+22s+230+/LfT00RcKBHNM7ZFMzGGegg+L9ac1QQVTs0//CI1lKI7j3D2JyBBo7rU1GCEAt6/VdQnpwMBBj2j3zbsRXOWUuuQufTPcHEHwSBh0N4zRLcnXzz6vwYhjBYNkmhGtxnfdrqUyHK9aFl14ydkrz9aOpN5/5YMn8cyNU5Vd53YVzBixDRMY8SsO4x40P0nCV4tOKp6VugpwsOuGWYH6tA0QdRfrpaF7cXU/SX6J5awyvRCjIVP0jZ0HL1vsNNJJYcCZ/3ZYHznYbUACe/pVEygqlsxDbQtVzH6TSMj5KEcw+j0WBmu2ojC2i12r1duYFVvidJld9AUGan4WzZnAz8y/GCjlEwFYMClyjPT+7H5U9zWJGdp1mhKAVawqw9gI24V/Hrebhuef8lRKu4GH4TGOn5SEe1Q7DMbvGTMte6hSKrUCJm205qVHxcddTI7CglVSjZ0JYH7aHHBX81cR1DRSpCbX/GHtBiV1sqEq+tbl2eSaEXtnFJygBxbjzgb2uXiZoqZWADC/UprWJxhXHyoVAz/uLn4Adt7JkAO5OYJdfFMthvm6v48HU3t4NUCcvmdGXb5pwiNG+Juhxr7wcm+JXA5Vy+6sRN1mW+HIliW+4n2Jl8piKy9TrtnZSxOLw9jiM0VLUeany4FKEzRC8ZQL499QoLtk8cGP3E0VfdZFbW2VVGkSv+xqO3BIGir3iZu3dVk9WtfhK1QS+ZKxfCQBJiYUAaRt47BaTUIaw30zT1jLLHh46055W2o+05Ua1xWrvVGktRbpESHUiTJRx9jYWjNGjfCkAeTWD0rAUVp9mK6gy/biHkDXU1tnjTePQOh+Br64bU3jJo0Lq2qE2dH0SFfH0h6waYL+991WFztdjdDI1+MgtYNo2sU9PEcOXrYsHH6WbBh3S14OPhbnGzoI+3hVNi9bjQDMLH7nlxOl1Uw03HC12VFT/pe/GSlPXcQmmpza6xg9f3KVLpgxF9LLpGHFYvs44f70zxfFwd/WAJmEJNNELYR9VR0R1gNF8q08NuTvRA45Qp4CIAcMPPEisiohJRyvIoMkDxPCyWk1X4YQSr9ZH2vQ4BA3rNYLXXBhi2pZhbNHgDtQhRc9StxZ85KtfgrLV/CmZhMVsGIzLq28IWQojYWkGFzdhnnd6EOnqWb+Kajq36LEqzrEXCRXNlxXXbbLDAutjggew1y4pbKOrc39lKnlmHoWrZVTR/ax+I8mvHSDCgnKNQq9k+DtVnn7r9BiFnU+dAJBljGYp0UyzAPexn/WA07YiklUBV7nPYzLwODtpTrjMZnN97oV4dACf9/C5WCDI/GxfU4cCe2g3K9GKD6We1eIgtowFKbMeCLine truncated
assets["syncthing/core/uniqueFolderDirective.js"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/7SSwW4yMQyE7zyFD7+0IK3CHc5/b1V74h5tvKzVkIDtQFHFuzdhUaGwtJWqzgVp4vkYW2vDMnnLZhVd8jiuZB8a7SgsTRMZq8kIsowjxkZpmwdSoE3Ch+gdclVDm/I8xQDjCbwdh4sYNXG4MHpzkzJnBlVYPkaHvqo/vXsKL7MLoDRxjTWgX9VgVVlqaJT95ApbVHzzb21ZkMWkIB21Oj6jtoS7hfUJh8JF1J7+z6Ajzev/fyUpv/cCRdMp7BCki8m7UClsrSdnFe8G+pqCuiiTpPubcyrnjvNBwCFfQvCiaXsMiemsPO3CM2ePM/K86zfdtUPoGYBlWwHrGa3b/6J/a3PHrxf4aScS6OF/dM5B9/ThftzwNnu44p05h/moPL4DAAD//wEAAP//r65WJ1IDAAA=")
assets["syncthing/core/upgradingDialogDirective.js"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/1yOwQrCMBBE7/2K3LaFkt7tSfAX9B7SNV3YJmW7UUT676YKRZ3jzNudcTFkdmKnNGTGGpZH9DpSDNYnQWgqU2QHEvRKtwLkOYgbCnAixylAa665nFCKpm7M881vEtQs8cv4mIsKeT0YOEL7EylOMzvFs3BJ9xndNqP7K70Q3u2oE8P+Yu2rtemrFwAAAP//AQAA//99zQ2GzwAAAA==")
assets["syncthing/core/upgradingDialogView.html"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/1zOTarDMAwE4PXLKYQ2WSW5gO0zPCg9gHDcVODaxlIIJc3dm5b+QLfDN8yYSx4pAo8W5zJVGjlNCKKks1jkdMoI7HOySLXmpfNcfQzdXBCUNQaL69oe380WbqCVkkTSsG3omj9TnJFC6Zu7wzV5Pe8cWOCz2pvh4Rz88v8YSAIsxPoifb/j4hozPN+75g4AAP//AQAA///kaeW6xgAAAA==")
+19 -35
View File
@@ -22,13 +22,14 @@ import (
"github.com/syncthing/syncthing/lib/beacon"
"github.com/syncthing/syncthing/lib/events"
"github.com/syncthing/syncthing/lib/osutil"
"github.com/syncthing/syncthing/lib/relay"
"github.com/syncthing/syncthing/lib/sync"
)
type Discoverer struct {
myID protocol.DeviceID
listenAddrs []string
relays []Relay
relaySvc *relay.Svc
localBcastIntv time.Duration
localBcastStart time.Time
cacheLifetime time.Duration
@@ -56,11 +57,11 @@ var (
ErrIncorrectMagic = errors.New("incorrect magic number")
)
func NewDiscoverer(id protocol.DeviceID, addresses []string, relayAdresses []string) *Discoverer {
func NewDiscoverer(id protocol.DeviceID, addresses []string, relaySvc *relay.Svc) *Discoverer {
return &Discoverer{
myID: id,
listenAddrs: addresses,
relays: measureLatency(relayAdresses),
relaySvc: relaySvc,
localBcastIntv: 30 * time.Second,
cacheLifetime: 5 * time.Minute,
negCacheCutoff: 3 * time.Minute,
@@ -143,7 +144,7 @@ func (d *Discoverer) StartGlobal(servers []string, extPort uint16) {
}
d.extPort = extPort
pkt := d.announcementPkt()
pkt := d.announcementPkt(true)
wg := sync.NewWaitGroup()
clients := make(chan Client, len(servers))
for _, address := range servers {
@@ -317,49 +318,32 @@ func (d *Discoverer) All() map[protocol.DeviceID][]CacheEntry {
return devices
}
func (d *Discoverer) announcementPkt() *Announce {
func (d *Discoverer) announcementPkt(allowExternal bool) *Announce {
var addrs []string
if d.extPort != 0 {
if d.extPort != 0 && allowExternal {
addrs = []string{fmt.Sprintf("tcp://:%d", d.extPort)}
} else {
for _, aurl := range d.listenAddrs {
uri, err := url.Parse(aurl)
if err != nil {
if debug {
l.Debugf("discovery: failed to parse listen address %s: %s", aurl, err)
}
continue
addrs = resolveAddrs(d.listenAddrs)
}
relayAddrs := make([]string, 0)
if d.relaySvc != nil {
status := d.relaySvc.ClientStatus()
for uri, ok := range status {
if ok {
relayAddrs = append(relayAddrs, uri)
}
addr, err := net.ResolveTCPAddr("tcp", uri.Host)
if err != nil {
l.Warnln("discover: %v: not announcing %s", err, aurl)
continue
} else if debug {
l.Debugf("discover: resolved %s as %#v", aurl, uri.Host)
}
if len(addr.IP) == 0 || addr.IP.IsUnspecified() {
uri.Host = fmt.Sprintf(":%d", addr.Port)
} else if bs := addr.IP.To4(); bs != nil {
uri.Host = fmt.Sprintf("%s:%d", bs.String(), addr.Port)
} else if bs := addr.IP.To16(); bs != nil {
uri.Host = fmt.Sprintf("[%s]:%d", bs.String(), addr.Port)
}
addrs = append(addrs, uri.String())
}
}
return &Announce{
Magic: AnnouncementMagic,
This: Device{d.myID[:], addrs, d.relays},
This: Device{d.myID[:], addrs, measureLatency(relayAddrs)},
}
}
func (d *Discoverer) sendLocalAnnouncements() {
var addrs = resolveAddrs(d.listenAddrs)
var pkt = Announce{
Magic: AnnouncementMagic,
This: Device{d.myID[:], addrs, d.relays},
}
var pkt = d.announcementPkt(false)
msg := pkt.MustMarshalXDR()
for {
+6
View File
@@ -7,11 +7,17 @@
package model
import (
"crypto/tls"
"net"
"github.com/syncthing/protocol"
)
type IntermediateConnection struct {
Conn *tls.Conn
ConnType ConnectionType
}
type Connection struct {
net.Conn
protocol.Connection
+4
View File
@@ -219,6 +219,7 @@ type ConnectionInfo struct {
protocol.Statistics
Address string
ClientVersion string
Type ConnectionType
}
func (info ConnectionInfo) MarshalJSON() ([]byte, error) {
@@ -227,6 +228,7 @@ func (info ConnectionInfo) MarshalJSON() ([]byte, error) {
"inBytesTotal": info.InBytesTotal,
"outBytesTotal": info.OutBytesTotal,
"address": info.Address,
"type": info.Type.String(),
"clientVersion": info.ClientVersion,
})
}
@@ -249,6 +251,7 @@ func (m *Model) ConnectionStats() map[string]interface{} {
}
if addr := m.conn[device].RemoteAddr(); addr != nil {
ci.Address = addr.String()
ci.Type = conn.Type
}
conns[device.String()] = ci
@@ -585,6 +588,7 @@ func (m *Model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon
}
if conn, ok := m.conn[deviceID]; ok {
event["type"] = conn.Type.String()
addr := conn.RemoteAddr()
if addr != nil {
event["addr"] = addr.String()
+20
View File
@@ -11,10 +11,12 @@ import (
"errors"
"fmt"
"io"
"net"
"os"
"path/filepath"
"runtime"
"strings"
"time"
"github.com/calmh/du"
"github.com/syncthing/syncthing/lib/sync"
@@ -221,3 +223,21 @@ func DiskFreePercentage(path string) (freePct float64, err error) {
u, err := du.Get(path)
return (float64(u.FreeBytes) / float64(u.TotalBytes)) * 100, err
}
// SetTCPOptions sets syncthings default TCP options on a TCP connection
func SetTCPOptions(conn *net.TCPConn) error {
var err error
if err = conn.SetLinger(0); err != nil {
return err
}
if err = conn.SetNoDelay(false); err != nil {
return err
}
if err = conn.SetKeepAlivePeriod(60 * time.Second); err != nil {
return err
}
if err = conn.SetKeepAlive(true); err != nil {
return err
}
return nil
}
+19
View File
@@ -0,0 +1,19 @@
// Copyright (C) 2015 The Syncthing Authors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.
package relay
import (
"os"
"strings"
"github.com/calmh/logger"
)
var (
debug = strings.Contains(os.Getenv("STTRACE"), "relay") || os.Getenv("STTRACE") == "all"
l = logger.DefaultLogger
)
+21 -17
View File
@@ -4,7 +4,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.
package main
package relay
import (
"crypto/tls"
@@ -16,16 +16,17 @@ import (
"github.com/syncthing/relaysrv/protocol"
"github.com/syncthing/syncthing/lib/config"
"github.com/syncthing/syncthing/lib/model"
"github.com/syncthing/syncthing/lib/osutil"
"github.com/syncthing/syncthing/lib/sync"
"github.com/thejerf/suture"
)
func newRelaySvc(cfg *config.Wrapper, tlsCfg *tls.Config, conns chan<- intermediateConnection) *relaySvc {
svc := &relaySvc{
Supervisor: suture.New("relaySvc", suture.Spec{
func NewSvc(cfg *config.Wrapper, tlsCfg *tls.Config, conns chan<- model.IntermediateConnection) *Svc {
svc := &Svc{
Supervisor: suture.New("Svc", suture.Spec{
Log: func(log string) {
if debugNet {
if debug {
l.Infoln(log)
}
},
@@ -58,7 +59,7 @@ func newRelaySvc(cfg *config.Wrapper, tlsCfg *tls.Config, conns chan<- intermedi
return svc
}
type relaySvc struct {
type Svc struct {
*suture.Supervisor
cfg *config.Wrapper
tlsCfg *tls.Config
@@ -70,7 +71,7 @@ type relaySvc struct {
invitations chan protocol.SessionInvitation
}
func (s *relaySvc) VerifyConfiguration(from, to config.Configuration) error {
func (s *Svc) VerifyConfiguration(from, to config.Configuration) error {
for _, addr := range to.Options.RelayServers {
_, err := url.Parse(addr)
if err != nil {
@@ -80,12 +81,12 @@ func (s *relaySvc) VerifyConfiguration(from, to config.Configuration) error {
return nil
}
func (s *relaySvc) CommitConfiguration(from, to config.Configuration) bool {
func (s *Svc) CommitConfiguration(from, to config.Configuration) bool {
existing := make(map[string]struct{}, len(to.Options.RelayServers))
for _, addr := range to.Options.RelayServers {
uri, err := url.Parse(addr)
if err != nil {
if debugNet {
if debug {
l.Debugln("Failed to parse relay address", addr, err)
}
continue
@@ -95,7 +96,7 @@ func (s *relaySvc) CommitConfiguration(from, to config.Configuration) bool {
_, ok := s.tokens[uri.String()]
if !ok {
if debugNet {
if debug {
l.Debugln("Connecting to relay", uri)
}
c := client.NewProtocolClient(uri, s.tlsCfg.Certificates, s.invitations)
@@ -114,7 +115,7 @@ func (s *relaySvc) CommitConfiguration(from, to config.Configuration) bool {
s.mut.Lock()
delete(s.clients, uri)
s.mut.Unlock()
if debugNet {
if debug {
l.Debugln("Disconnecting from relay", uri, err)
}
}
@@ -123,7 +124,7 @@ func (s *relaySvc) CommitConfiguration(from, to config.Configuration) bool {
return true
}
func (s *relaySvc) ClientStatus() map[string]bool {
func (s *Svc) ClientStatus() map[string]bool {
s.mut.RLock()
status := make(map[string]bool, len(s.clients))
for uri, client := range s.clients {
@@ -136,7 +137,7 @@ func (s *relaySvc) ClientStatus() map[string]bool {
type invitationReceiver struct {
invitations chan protocol.SessionInvitation
tlsCfg *tls.Config
conns chan<- intermediateConnection
conns chan<- model.IntermediateConnection
stop chan struct{}
}
@@ -149,18 +150,21 @@ func (r *invitationReceiver) Serve() {
for {
select {
case inv := <-r.invitations:
if debugNet {
if debug {
l.Debugln("Received relay invitation", inv)
}
conn, err := client.JoinSession(inv)
if err != nil {
if debugNet {
if debug {
l.Debugf("Failed to join relay session %s: %v", inv, err)
}
continue
}
setTCPOptions(conn.(*net.TCPConn))
err = osutil.SetTCPOptions(conn.(*net.TCPConn))
if err != nil {
l.Infoln(err)
}
var tc *tls.Conn
@@ -175,7 +179,7 @@ func (r *invitationReceiver) Serve() {
tc.Close()
continue
}
r.conns <- intermediateConnection{
r.conns <- model.IntermediateConnection{
tc, model.ConnectionTypeRelayAccept,
}
case <-r.stop: