mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-09 14:50:56 +00:00
Expose connection type and relay status in the UI
This commit is contained in:
parent
2c0f8dc546
commit
8f2db99c86
@ -16,17 +16,17 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/syncthing/protocol"
|
"github.com/syncthing/protocol"
|
||||||
|
|
||||||
"github.com/syncthing/relaysrv/client"
|
"github.com/syncthing/relaysrv/client"
|
||||||
"github.com/syncthing/syncthing/lib/config"
|
"github.com/syncthing/syncthing/lib/config"
|
||||||
"github.com/syncthing/syncthing/lib/events"
|
"github.com/syncthing/syncthing/lib/events"
|
||||||
"github.com/syncthing/syncthing/lib/model"
|
"github.com/syncthing/syncthing/lib/model"
|
||||||
|
"github.com/syncthing/syncthing/lib/osutil"
|
||||||
|
|
||||||
"github.com/thejerf/suture"
|
"github.com/thejerf/suture"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DialerFactory func(*url.URL, *tls.Config) (*tls.Conn, error)
|
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 (
|
var (
|
||||||
dialers = make(map[string]DialerFactory, 0)
|
dialers = make(map[string]DialerFactory, 0)
|
||||||
@ -41,7 +41,7 @@ type connectionSvc struct {
|
|||||||
myID protocol.DeviceID
|
myID protocol.DeviceID
|
||||||
model *model.Model
|
model *model.Model
|
||||||
tlsCfg *tls.Config
|
tlsCfg *tls.Config
|
||||||
conns chan intermediateConnection
|
conns chan model.IntermediateConnection
|
||||||
|
|
||||||
lastRelayCheck map[protocol.DeviceID]time.Time
|
lastRelayCheck map[protocol.DeviceID]time.Time
|
||||||
|
|
||||||
@ -49,11 +49,6 @@ type connectionSvc struct {
|
|||||||
connType map[protocol.DeviceID]model.ConnectionType
|
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 {
|
func newConnectionSvc(cfg *config.Wrapper, myID protocol.DeviceID, mdl *model.Model, tlsCfg *tls.Config) *connectionSvc {
|
||||||
svc := &connectionSvc{
|
svc := &connectionSvc{
|
||||||
Supervisor: suture.NewSimple("connectionSvc"),
|
Supervisor: suture.NewSimple("connectionSvc"),
|
||||||
@ -61,7 +56,7 @@ func newConnectionSvc(cfg *config.Wrapper, myID protocol.DeviceID, mdl *model.Mo
|
|||||||
myID: myID,
|
myID: myID,
|
||||||
model: mdl,
|
model: mdl,
|
||||||
tlsCfg: tlsCfg,
|
tlsCfg: tlsCfg,
|
||||||
conns: make(chan intermediateConnection),
|
conns: make(chan model.IntermediateConnection),
|
||||||
|
|
||||||
connType: make(map[protocol.DeviceID]model.ConnectionType),
|
connType: make(map[protocol.DeviceID]model.ConnectionType),
|
||||||
lastRelayCheck: make(map[protocol.DeviceID]time.Time),
|
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() {
|
func (s *connectionSvc) handle() {
|
||||||
next:
|
next:
|
||||||
for c := range s.conns {
|
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
|
// 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,
|
// of the TLS handshake. Unfortunately this can't be a hard error,
|
||||||
// because there are implementations out there that don't support
|
// because there are implementations out there that don't support
|
||||||
// protocol negotiation (iOS for one...).
|
// protocol negotiation (iOS for one...).
|
||||||
if !cs.NegotiatedProtocolIsMutual || cs.NegotiatedProtocol != bepProtocolName {
|
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
|
// We should have received exactly one certificate from the other
|
||||||
@ -125,8 +120,8 @@ next:
|
|||||||
// connection.
|
// connection.
|
||||||
certs := cs.PeerCertificates
|
certs := cs.PeerCertificates
|
||||||
if cl := len(certs); cl != 1 {
|
if cl := len(certs); cl != 1 {
|
||||||
l.Infof("Got peer certificate list of length %d != 1 from %s; protocol error", cl, c.conn.RemoteAddr())
|
l.Infof("Got peer certificate list of length %d != 1 from %s; protocol error", cl, c.Conn.RemoteAddr())
|
||||||
c.conn.Close()
|
c.Conn.Close()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
remoteCert := certs[0]
|
remoteCert := certs[0]
|
||||||
@ -137,7 +132,7 @@ next:
|
|||||||
// clients between the same NAT gateway, and global discovery.
|
// clients between the same NAT gateway, and global discovery.
|
||||||
if remoteID == myID {
|
if remoteID == myID {
|
||||||
l.Infof("Connected to myself (%s) - should not happen", remoteID)
|
l.Infof("Connected to myself (%s) - should not happen", remoteID)
|
||||||
c.conn.Close()
|
c.Conn.Close()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +141,7 @@ next:
|
|||||||
s.mut.RLock()
|
s.mut.RLock()
|
||||||
ct, ok := s.connType[remoteID]
|
ct, ok := s.connType[remoteID]
|
||||||
s.mut.RUnlock()
|
s.mut.RUnlock()
|
||||||
if ok && !ct.IsDirect() && c.connType.IsDirect() {
|
if ok && !ct.IsDirect() && c.ConnType.IsDirect() {
|
||||||
if debugNet {
|
if debugNet {
|
||||||
l.Debugln("Switching connections", remoteID)
|
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
|
// in parallel we don't want to do that or we end up with no
|
||||||
// connections still established...
|
// connections still established...
|
||||||
l.Infof("Connected to already connected device (%s)", remoteID)
|
l.Infof("Connected to already connected device (%s)", remoteID)
|
||||||
c.conn.Close()
|
c.Conn.Close()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,41 +172,41 @@ next:
|
|||||||
// Incorrect certificate name is something the user most
|
// Incorrect certificate name is something the user most
|
||||||
// likely wants to know about, since it's an advanced
|
// likely wants to know about, since it's an advanced
|
||||||
// config. Warn instead of Info.
|
// config. Warn instead of Info.
|
||||||
l.Warnf("Bad certificate from %s (%v): %v", remoteID, c.conn.RemoteAddr(), err)
|
l.Warnf("Bad certificate from %s (%v): %v", remoteID, c.Conn.RemoteAddr(), err)
|
||||||
c.conn.Close()
|
c.Conn.Close()
|
||||||
continue next
|
continue next
|
||||||
}
|
}
|
||||||
|
|
||||||
// If rate limiting is set, and based on the address we should
|
// If rate limiting is set, and based on the address we should
|
||||||
// limit the connection, then we wrap it in a limiter.
|
// 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 {
|
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 {
|
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)
|
protoConn := protocol.NewConnection(remoteID, rd, wr, s.model, name, deviceCfg.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 {
|
||||||
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{
|
s.model.AddConnection(model.Connection{
|
||||||
c.conn,
|
c.Conn,
|
||||||
protoConn,
|
protoConn,
|
||||||
c.connType,
|
c.ConnType,
|
||||||
})
|
})
|
||||||
s.mut.Lock()
|
s.mut.Lock()
|
||||||
s.connType[remoteID] = c.connType
|
s.connType[remoteID] = c.ConnType
|
||||||
s.mut.Unlock()
|
s.mut.Unlock()
|
||||||
continue next
|
continue next
|
||||||
}
|
}
|
||||||
@ -220,14 +215,14 @@ next:
|
|||||||
if !s.cfg.IgnoredDevice(remoteID) {
|
if !s.cfg.IgnoredDevice(remoteID) {
|
||||||
events.Default.Log(events.DeviceRejected, map[string]string{
|
events.Default.Log(events.DeviceRejected, map[string]string{
|
||||||
"device": remoteID.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 {
|
} 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.model.Close(deviceID, fmt.Errorf("switching connections"))
|
||||||
}
|
}
|
||||||
|
|
||||||
s.conns <- intermediateConnection{
|
s.conns <- model.IntermediateConnection{
|
||||||
conn, model.ConnectionTypeBasicDial,
|
conn, model.ConnectionTypeBasicDial,
|
||||||
}
|
}
|
||||||
continue nextDevice
|
continue nextDevice
|
||||||
@ -347,7 +342,10 @@ func (s *connectionSvc) connect() {
|
|||||||
l.Debugln("Sucessfully joined relay session", inv)
|
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
|
var tc *tls.Conn
|
||||||
|
|
||||||
@ -362,7 +360,7 @@ func (s *connectionSvc) connect() {
|
|||||||
tc.Close()
|
tc.Close()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
s.conns <- intermediateConnection{
|
s.conns <- model.IntermediateConnection{
|
||||||
tc, model.ConnectionTypeRelayDial,
|
tc, model.ConnectionTypeRelayDial,
|
||||||
}
|
}
|
||||||
continue nextDevice
|
continue nextDevice
|
||||||
@ -414,19 +412,3 @@ func (s *connectionSvc) CommitConfiguration(from, to config.Configuration) bool
|
|||||||
|
|
||||||
return true
|
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/syncthing/syncthing/lib/model"
|
"github.com/syncthing/syncthing/lib/model"
|
||||||
|
"github.com/syncthing/syncthing/lib/osutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -46,7 +47,10 @@ func tcpDialer(uri *url.URL, tlsCfg *tls.Config) (*tls.Conn, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
setTCPOptions(conn)
|
err = osutil.SetTCPOptions(conn)
|
||||||
|
if err != nil {
|
||||||
|
l.Infoln(err)
|
||||||
|
}
|
||||||
|
|
||||||
tc := tls.Client(conn, tlsCfg)
|
tc := tls.Client(conn, tlsCfg)
|
||||||
err = tc.Handshake()
|
err = tc.Handshake()
|
||||||
@ -58,7 +62,7 @@ func tcpDialer(uri *url.URL, tlsCfg *tls.Config) (*tls.Conn, error) {
|
|||||||
return tc, nil
|
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)
|
tcaddr, err := net.ResolveTCPAddr("tcp", uri.Host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Fatalln("listen (BEP/tcp):", err)
|
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())
|
l.Debugln("connect from", conn.RemoteAddr())
|
||||||
}
|
}
|
||||||
|
|
||||||
tcpConn := conn.(*net.TCPConn)
|
err = osutil.SetTCPOptions(conn.(*net.TCPConn))
|
||||||
setTCPOptions(tcpConn)
|
if err != nil {
|
||||||
|
l.Infoln(err)
|
||||||
|
}
|
||||||
|
|
||||||
tc := tls.Server(conn, tlsCfg)
|
tc := tls.Server(conn, tlsCfg)
|
||||||
err = tc.Handshake()
|
err = tc.Handshake()
|
||||||
@ -92,7 +98,7 @@ func tcpListener(uri *url.URL, tlsCfg *tls.Config, conns chan<- intermediateConn
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
conns <- intermediateConnection{
|
conns <- model.IntermediateConnection{
|
||||||
tc, model.ConnectionTypeBasicAccept,
|
tc, model.ConnectionTypeBasicAccept,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -628,6 +628,9 @@ func (s *apiSvc) getSystemStatus(w http.ResponseWriter, r *http.Request) {
|
|||||||
if cfg.Options().GlobalAnnEnabled && discoverer != nil {
|
if cfg.Options().GlobalAnnEnabled && discoverer != nil {
|
||||||
res["extAnnounceOK"] = discoverer.ExtAnnounceOK()
|
res["extAnnounceOK"] = discoverer.ExtAnnounceOK()
|
||||||
}
|
}
|
||||||
|
if relaySvc != nil {
|
||||||
|
res["relayClientStatus"] = relaySvc.ClientStatus()
|
||||||
|
}
|
||||||
cpuUsageLock.RLock()
|
cpuUsageLock.RLock()
|
||||||
var cpusum float64
|
var cpusum float64
|
||||||
for _, p := range cpuUsagePercent {
|
for _, p := range cpuUsagePercent {
|
||||||
|
@ -34,8 +34,10 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/events"
|
"github.com/syncthing/syncthing/lib/events"
|
||||||
"github.com/syncthing/syncthing/lib/model"
|
"github.com/syncthing/syncthing/lib/model"
|
||||||
"github.com/syncthing/syncthing/lib/osutil"
|
"github.com/syncthing/syncthing/lib/osutil"
|
||||||
|
"github.com/syncthing/syncthing/lib/relay"
|
||||||
"github.com/syncthing/syncthing/lib/symlinks"
|
"github.com/syncthing/syncthing/lib/symlinks"
|
||||||
"github.com/syncthing/syncthing/lib/upgrade"
|
"github.com/syncthing/syncthing/lib/upgrade"
|
||||||
|
|
||||||
"github.com/syndtr/goleveldb/leveldb"
|
"github.com/syndtr/goleveldb/leveldb"
|
||||||
"github.com/syndtr/goleveldb/leveldb/errors"
|
"github.com/syndtr/goleveldb/leveldb/errors"
|
||||||
"github.com/syndtr/goleveldb/leveldb/opt"
|
"github.com/syndtr/goleveldb/leveldb/opt"
|
||||||
@ -110,6 +112,7 @@ var (
|
|||||||
readRateLimit *ratelimit.Bucket
|
readRateLimit *ratelimit.Bucket
|
||||||
stop = make(chan int)
|
stop = make(chan int)
|
||||||
discoverer *discover.Discoverer
|
discoverer *discover.Discoverer
|
||||||
|
relaySvc *relay.Svc
|
||||||
cert tls.Certificate
|
cert tls.Certificate
|
||||||
lans []*net.IPNet
|
lans []*net.IPNet
|
||||||
)
|
)
|
||||||
@ -671,14 +674,14 @@ func syncthingMain() {
|
|||||||
// Start the relevant services
|
// Start the relevant services
|
||||||
|
|
||||||
connectionSvc := newConnectionSvc(cfg, myID, m, tlsCfg)
|
connectionSvc := newConnectionSvc(cfg, myID, m, tlsCfg)
|
||||||
relaySvc := newRelaySvc(cfg, tlsCfg, connectionSvc.conns)
|
relaySvc = relay.NewSvc(cfg, tlsCfg, connectionSvc.conns)
|
||||||
connectionSvc.Add(relaySvc)
|
connectionSvc.Add(relaySvc)
|
||||||
mainSvc.Add(connectionSvc)
|
mainSvc.Add(connectionSvc)
|
||||||
|
|
||||||
// Start discovery
|
// Start discovery
|
||||||
|
|
||||||
localPort := addr.Port
|
localPort := addr.Port
|
||||||
discoverer = discovery(localPort)
|
discoverer = discovery(localPort, relaySvc)
|
||||||
|
|
||||||
// Start UPnP. The UPnP service will restart global discovery if the
|
// Start UPnP. The UPnP service will restart global discovery if the
|
||||||
// external port changes.
|
// external port changes.
|
||||||
@ -908,10 +911,9 @@ func shutdown() {
|
|||||||
stop <- exitSuccess
|
stop <- exitSuccess
|
||||||
}
|
}
|
||||||
|
|
||||||
func discovery(extPort int) *discover.Discoverer {
|
func discovery(extPort int, relaySvc *relay.Svc) *discover.Discoverer {
|
||||||
opts := cfg.Options()
|
opts := cfg.Options()
|
||||||
disc := discover.NewDiscoverer(myID, opts.ListenAddress, opts.RelayServers)
|
disc := discover.NewDiscoverer(myID, opts.ListenAddress, relaySvc)
|
||||||
|
|
||||||
if opts.LocalAnnEnabled {
|
if opts.LocalAnnEnabled {
|
||||||
l.Infoln("Starting local discovery announcements")
|
l.Infoln("Starting local discovery announcements")
|
||||||
disc.StartLocal(opts.LocalAnnPort, opts.LocalAnnMCAddr)
|
disc.StartLocal(opts.LocalAnnPort, opts.LocalAnnMCAddr)
|
||||||
|
@ -74,7 +74,7 @@ func (s *verboseSvc) formatEvent(ev events.Event) string {
|
|||||||
return fmt.Sprintf("Discovered device %v at %v", data["device"], data["addrs"])
|
return fmt.Sprintf("Discovered device %v at %v", data["device"], data["addrs"])
|
||||||
case events.DeviceConnected:
|
case events.DeviceConnected:
|
||||||
data := ev.Data.(map[string]string)
|
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:
|
case events.DeviceDisconnected:
|
||||||
data := ev.Data.(map[string]string)
|
data := ev.Data.(map[string]string)
|
||||||
return fmt.Sprintf("Disconnected from device %v", data["id"])
|
return fmt.Sprintf("Disconnected from device %v", data["id"])
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
"Edit Folder": "Edit Folder",
|
"Edit Folder": "Edit Folder",
|
||||||
"Editing": "Editing",
|
"Editing": "Editing",
|
||||||
"Enable UPnP": "Enable UPnP",
|
"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.",
|
"Enter ignore patterns, one per line.": "Enter ignore patterns, one per line.",
|
||||||
"Error": "Error",
|
"Error": "Error",
|
||||||
"External File Versioning": "External File Versioning",
|
"External File Versioning": "External File Versioning",
|
||||||
@ -120,6 +120,8 @@
|
|||||||
"Quick guide to supported patterns": "Quick guide to supported patterns",
|
"Quick guide to supported patterns": "Quick guide to supported patterns",
|
||||||
"RAM Utilization": "RAM Utilization",
|
"RAM Utilization": "RAM Utilization",
|
||||||
"Random": "Random",
|
"Random": "Random",
|
||||||
|
"Relayed via": "Relayed via",
|
||||||
|
"Relays": "Relays",
|
||||||
"Release Notes": "Release Notes",
|
"Release Notes": "Release Notes",
|
||||||
"Remove": "Remove",
|
"Remove": "Remove",
|
||||||
"Rescan": "Rescan",
|
"Rescan": "Rescan",
|
||||||
|
@ -385,6 +385,19 @@
|
|||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr ng-if="system.relayClientStatus != undefined && relayClientsTotal > 0">
|
||||||
|
<th><span class="fa fa-fw fa-sitemap"></span> <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>
|
<tr>
|
||||||
<th><span class="fa fa-fw fa-clock-o"></span> <span translate>Uptime</span></th>
|
<th><span class="fa fa-fw fa-clock-o"></span> <span translate>Uptime</span></th>
|
||||||
<td class="text-right">{{system.uptime | duration:"m"}}</td>
|
<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>
|
<td class="text-right">{{connections[deviceCfg.deviceID].outbps | binary}}B/s ({{connections[deviceCfg.deviceID].outBytesTotal | binary}}B)</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th><span class="fa fa-fw fa-link"></span> <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>
|
<td class="text-right">{{deviceAddr(deviceCfg)}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr ng-if="deviceCfg.compression != 'metadata'">
|
<tr ng-if="deviceCfg.compression != 'metadata'">
|
||||||
|
@ -176,6 +176,7 @@ angular.module('syncthing.core')
|
|||||||
outbps: 0,
|
outbps: 0,
|
||||||
inBytesTotal: 0,
|
inBytesTotal: 0,
|
||||||
outBytesTotal: 0,
|
outBytesTotal: 0,
|
||||||
|
type: arg.data.type,
|
||||||
address: arg.data.addr
|
address: arg.data.addr
|
||||||
};
|
};
|
||||||
$scope.completion[arg.data.id] = {
|
$scope.completion[arg.data.id] = {
|
||||||
@ -346,14 +347,24 @@ angular.module('syncthing.core')
|
|||||||
$http.get(urlbase + '/system/status').success(function (data) {
|
$http.get(urlbase + '/system/status').success(function (data) {
|
||||||
$scope.myID = data.myID;
|
$scope.myID = data.myID;
|
||||||
$scope.system = data;
|
$scope.system = data;
|
||||||
|
|
||||||
$scope.announceServersTotal = data.extAnnounceOK ? Object.keys(data.extAnnounceOK).length : 0;
|
$scope.announceServersTotal = data.extAnnounceOK ? Object.keys(data.extAnnounceOK).length : 0;
|
||||||
var failed = [];
|
var failedAnnounce = [];
|
||||||
for (var server in data.extAnnounceOK) {
|
for (var server in data.extAnnounceOK) {
|
||||||
if (!data.extAnnounceOK[server]) {
|
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);
|
console.log("refreshSystem", data);
|
||||||
|
File diff suppressed because one or more lines are too long
@ -22,13 +22,14 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/beacon"
|
"github.com/syncthing/syncthing/lib/beacon"
|
||||||
"github.com/syncthing/syncthing/lib/events"
|
"github.com/syncthing/syncthing/lib/events"
|
||||||
"github.com/syncthing/syncthing/lib/osutil"
|
"github.com/syncthing/syncthing/lib/osutil"
|
||||||
|
"github.com/syncthing/syncthing/lib/relay"
|
||||||
"github.com/syncthing/syncthing/lib/sync"
|
"github.com/syncthing/syncthing/lib/sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Discoverer struct {
|
type Discoverer struct {
|
||||||
myID protocol.DeviceID
|
myID protocol.DeviceID
|
||||||
listenAddrs []string
|
listenAddrs []string
|
||||||
relays []Relay
|
relaySvc *relay.Svc
|
||||||
localBcastIntv time.Duration
|
localBcastIntv time.Duration
|
||||||
localBcastStart time.Time
|
localBcastStart time.Time
|
||||||
cacheLifetime time.Duration
|
cacheLifetime time.Duration
|
||||||
@ -56,11 +57,11 @@ var (
|
|||||||
ErrIncorrectMagic = errors.New("incorrect magic number")
|
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{
|
return &Discoverer{
|
||||||
myID: id,
|
myID: id,
|
||||||
listenAddrs: addresses,
|
listenAddrs: addresses,
|
||||||
relays: measureLatency(relayAdresses),
|
relaySvc: relaySvc,
|
||||||
localBcastIntv: 30 * time.Second,
|
localBcastIntv: 30 * time.Second,
|
||||||
cacheLifetime: 5 * time.Minute,
|
cacheLifetime: 5 * time.Minute,
|
||||||
negCacheCutoff: 3 * time.Minute,
|
negCacheCutoff: 3 * time.Minute,
|
||||||
@ -143,7 +144,7 @@ func (d *Discoverer) StartGlobal(servers []string, extPort uint16) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
d.extPort = extPort
|
d.extPort = extPort
|
||||||
pkt := d.announcementPkt()
|
pkt := d.announcementPkt(true)
|
||||||
wg := sync.NewWaitGroup()
|
wg := sync.NewWaitGroup()
|
||||||
clients := make(chan Client, len(servers))
|
clients := make(chan Client, len(servers))
|
||||||
for _, address := range servers {
|
for _, address := range servers {
|
||||||
@ -317,49 +318,32 @@ func (d *Discoverer) All() map[protocol.DeviceID][]CacheEntry {
|
|||||||
return devices
|
return devices
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Discoverer) announcementPkt() *Announce {
|
func (d *Discoverer) announcementPkt(allowExternal bool) *Announce {
|
||||||
var addrs []string
|
var addrs []string
|
||||||
if d.extPort != 0 {
|
if d.extPort != 0 && allowExternal {
|
||||||
addrs = []string{fmt.Sprintf("tcp://:%d", d.extPort)}
|
addrs = []string{fmt.Sprintf("tcp://:%d", d.extPort)}
|
||||||
} else {
|
} else {
|
||||||
for _, aurl := range d.listenAddrs {
|
addrs = resolveAddrs(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
|
|
||||||
}
|
relayAddrs := make([]string, 0)
|
||||||
addr, err := net.ResolveTCPAddr("tcp", uri.Host)
|
if d.relaySvc != nil {
|
||||||
if err != nil {
|
status := d.relaySvc.ClientStatus()
|
||||||
l.Warnln("discover: %v: not announcing %s", err, aurl)
|
for uri, ok := range status {
|
||||||
continue
|
if ok {
|
||||||
} else if debug {
|
relayAddrs = append(relayAddrs, uri)
|
||||||
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{
|
return &Announce{
|
||||||
Magic: AnnouncementMagic,
|
Magic: AnnouncementMagic,
|
||||||
This: Device{d.myID[:], addrs, d.relays},
|
This: Device{d.myID[:], addrs, measureLatency(relayAddrs)},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Discoverer) sendLocalAnnouncements() {
|
func (d *Discoverer) sendLocalAnnouncements() {
|
||||||
var addrs = resolveAddrs(d.listenAddrs)
|
var pkt = d.announcementPkt(false)
|
||||||
|
|
||||||
var pkt = Announce{
|
|
||||||
Magic: AnnouncementMagic,
|
|
||||||
This: Device{d.myID[:], addrs, d.relays},
|
|
||||||
}
|
|
||||||
msg := pkt.MustMarshalXDR()
|
msg := pkt.MustMarshalXDR()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
@ -7,11 +7,17 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/syncthing/protocol"
|
"github.com/syncthing/protocol"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type IntermediateConnection struct {
|
||||||
|
Conn *tls.Conn
|
||||||
|
ConnType ConnectionType
|
||||||
|
}
|
||||||
|
|
||||||
type Connection struct {
|
type Connection struct {
|
||||||
net.Conn
|
net.Conn
|
||||||
protocol.Connection
|
protocol.Connection
|
||||||
|
@ -219,6 +219,7 @@ type ConnectionInfo struct {
|
|||||||
protocol.Statistics
|
protocol.Statistics
|
||||||
Address string
|
Address string
|
||||||
ClientVersion string
|
ClientVersion string
|
||||||
|
Type ConnectionType
|
||||||
}
|
}
|
||||||
|
|
||||||
func (info ConnectionInfo) MarshalJSON() ([]byte, error) {
|
func (info ConnectionInfo) MarshalJSON() ([]byte, error) {
|
||||||
@ -227,6 +228,7 @@ func (info ConnectionInfo) MarshalJSON() ([]byte, error) {
|
|||||||
"inBytesTotal": info.InBytesTotal,
|
"inBytesTotal": info.InBytesTotal,
|
||||||
"outBytesTotal": info.OutBytesTotal,
|
"outBytesTotal": info.OutBytesTotal,
|
||||||
"address": info.Address,
|
"address": info.Address,
|
||||||
|
"type": info.Type.String(),
|
||||||
"clientVersion": info.ClientVersion,
|
"clientVersion": info.ClientVersion,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -249,6 +251,7 @@ func (m *Model) ConnectionStats() map[string]interface{} {
|
|||||||
}
|
}
|
||||||
if addr := m.conn[device].RemoteAddr(); addr != nil {
|
if addr := m.conn[device].RemoteAddr(); addr != nil {
|
||||||
ci.Address = addr.String()
|
ci.Address = addr.String()
|
||||||
|
ci.Type = conn.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
conns[device.String()] = ci
|
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 {
|
if conn, ok := m.conn[deviceID]; ok {
|
||||||
|
event["type"] = conn.Type.String()
|
||||||
addr := conn.RemoteAddr()
|
addr := conn.RemoteAddr()
|
||||||
if addr != nil {
|
if addr != nil {
|
||||||
event["addr"] = addr.String()
|
event["addr"] = addr.String()
|
||||||
|
@ -11,10 +11,12 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/calmh/du"
|
"github.com/calmh/du"
|
||||||
"github.com/syncthing/syncthing/lib/sync"
|
"github.com/syncthing/syncthing/lib/sync"
|
||||||
@ -221,3 +223,21 @@ func DiskFreePercentage(path string) (freePct float64, err error) {
|
|||||||
u, err := du.Get(path)
|
u, err := du.Get(path)
|
||||||
return (float64(u.FreeBytes) / float64(u.TotalBytes)) * 100, err
|
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
lib/relay/debug.go
Normal file
19
lib/relay/debug.go
Normal 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
|
||||||
|
)
|
@ -4,7 +4,7 @@
|
|||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
// 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/.
|
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
package main
|
package relay
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
@ -16,16 +16,17 @@ import (
|
|||||||
"github.com/syncthing/relaysrv/protocol"
|
"github.com/syncthing/relaysrv/protocol"
|
||||||
"github.com/syncthing/syncthing/lib/config"
|
"github.com/syncthing/syncthing/lib/config"
|
||||||
"github.com/syncthing/syncthing/lib/model"
|
"github.com/syncthing/syncthing/lib/model"
|
||||||
|
"github.com/syncthing/syncthing/lib/osutil"
|
||||||
"github.com/syncthing/syncthing/lib/sync"
|
"github.com/syncthing/syncthing/lib/sync"
|
||||||
|
|
||||||
"github.com/thejerf/suture"
|
"github.com/thejerf/suture"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newRelaySvc(cfg *config.Wrapper, tlsCfg *tls.Config, conns chan<- intermediateConnection) *relaySvc {
|
func NewSvc(cfg *config.Wrapper, tlsCfg *tls.Config, conns chan<- model.IntermediateConnection) *Svc {
|
||||||
svc := &relaySvc{
|
svc := &Svc{
|
||||||
Supervisor: suture.New("relaySvc", suture.Spec{
|
Supervisor: suture.New("Svc", suture.Spec{
|
||||||
Log: func(log string) {
|
Log: func(log string) {
|
||||||
if debugNet {
|
if debug {
|
||||||
l.Infoln(log)
|
l.Infoln(log)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -58,7 +59,7 @@ func newRelaySvc(cfg *config.Wrapper, tlsCfg *tls.Config, conns chan<- intermedi
|
|||||||
return svc
|
return svc
|
||||||
}
|
}
|
||||||
|
|
||||||
type relaySvc struct {
|
type Svc struct {
|
||||||
*suture.Supervisor
|
*suture.Supervisor
|
||||||
cfg *config.Wrapper
|
cfg *config.Wrapper
|
||||||
tlsCfg *tls.Config
|
tlsCfg *tls.Config
|
||||||
@ -70,7 +71,7 @@ type relaySvc struct {
|
|||||||
invitations chan protocol.SessionInvitation
|
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 {
|
for _, addr := range to.Options.RelayServers {
|
||||||
_, err := url.Parse(addr)
|
_, err := url.Parse(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -80,12 +81,12 @@ func (s *relaySvc) VerifyConfiguration(from, to config.Configuration) error {
|
|||||||
return nil
|
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))
|
existing := make(map[string]struct{}, len(to.Options.RelayServers))
|
||||||
for _, addr := range to.Options.RelayServers {
|
for _, addr := range to.Options.RelayServers {
|
||||||
uri, err := url.Parse(addr)
|
uri, err := url.Parse(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if debugNet {
|
if debug {
|
||||||
l.Debugln("Failed to parse relay address", addr, err)
|
l.Debugln("Failed to parse relay address", addr, err)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
@ -95,7 +96,7 @@ func (s *relaySvc) CommitConfiguration(from, to config.Configuration) bool {
|
|||||||
|
|
||||||
_, ok := s.tokens[uri.String()]
|
_, ok := s.tokens[uri.String()]
|
||||||
if !ok {
|
if !ok {
|
||||||
if debugNet {
|
if debug {
|
||||||
l.Debugln("Connecting to relay", uri)
|
l.Debugln("Connecting to relay", uri)
|
||||||
}
|
}
|
||||||
c := client.NewProtocolClient(uri, s.tlsCfg.Certificates, s.invitations)
|
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()
|
s.mut.Lock()
|
||||||
delete(s.clients, uri)
|
delete(s.clients, uri)
|
||||||
s.mut.Unlock()
|
s.mut.Unlock()
|
||||||
if debugNet {
|
if debug {
|
||||||
l.Debugln("Disconnecting from relay", uri, err)
|
l.Debugln("Disconnecting from relay", uri, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,7 +124,7 @@ func (s *relaySvc) CommitConfiguration(from, to config.Configuration) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *relaySvc) ClientStatus() map[string]bool {
|
func (s *Svc) ClientStatus() map[string]bool {
|
||||||
s.mut.RLock()
|
s.mut.RLock()
|
||||||
status := make(map[string]bool, len(s.clients))
|
status := make(map[string]bool, len(s.clients))
|
||||||
for uri, client := range s.clients {
|
for uri, client := range s.clients {
|
||||||
@ -136,7 +137,7 @@ func (s *relaySvc) ClientStatus() map[string]bool {
|
|||||||
type invitationReceiver struct {
|
type invitationReceiver struct {
|
||||||
invitations chan protocol.SessionInvitation
|
invitations chan protocol.SessionInvitation
|
||||||
tlsCfg *tls.Config
|
tlsCfg *tls.Config
|
||||||
conns chan<- intermediateConnection
|
conns chan<- model.IntermediateConnection
|
||||||
stop chan struct{}
|
stop chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,18 +150,21 @@ func (r *invitationReceiver) Serve() {
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case inv := <-r.invitations:
|
case inv := <-r.invitations:
|
||||||
if debugNet {
|
if debug {
|
||||||
l.Debugln("Received relay invitation", inv)
|
l.Debugln("Received relay invitation", inv)
|
||||||
}
|
}
|
||||||
conn, err := client.JoinSession(inv)
|
conn, err := client.JoinSession(inv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if debugNet {
|
if debug {
|
||||||
l.Debugf("Failed to join relay session %s: %v", inv, err)
|
l.Debugf("Failed to join relay session %s: %v", inv, err)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
setTCPOptions(conn.(*net.TCPConn))
|
err = osutil.SetTCPOptions(conn.(*net.TCPConn))
|
||||||
|
if err != nil {
|
||||||
|
l.Infoln(err)
|
||||||
|
}
|
||||||
|
|
||||||
var tc *tls.Conn
|
var tc *tls.Conn
|
||||||
|
|
||||||
@ -175,7 +179,7 @@ func (r *invitationReceiver) Serve() {
|
|||||||
tc.Close()
|
tc.Close()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
r.conns <- intermediateConnection{
|
r.conns <- model.IntermediateConnection{
|
||||||
tc, model.ConnectionTypeRelayAccept,
|
tc, model.ConnectionTypeRelayAccept,
|
||||||
}
|
}
|
||||||
case <-r.stop:
|
case <-r.stop:
|
Loading…
Reference in New Issue
Block a user