|
|
@@ -8,7 +8,9 @@ package relay
|
|
|
|
|
|
import (
|
|
|
"crypto/tls"
|
|
|
+ "encoding/json"
|
|
|
"net"
|
|
|
+ "net/http"
|
|
|
"net/url"
|
|
|
"time"
|
|
|
|
|
|
@@ -82,7 +84,8 @@ func (s *Svc) VerifyConfiguration(from, to config.Configuration) error {
|
|
|
}
|
|
|
|
|
|
func (s *Svc) CommitConfiguration(from, to config.Configuration) bool {
|
|
|
- existing := make(map[string]struct{}, len(to.Options.RelayServers))
|
|
|
+ existing := make(map[string]*url.URL, len(to.Options.RelayServers))
|
|
|
+
|
|
|
for _, addr := range to.Options.RelayServers {
|
|
|
uri, err := url.Parse(addr)
|
|
|
if err != nil {
|
|
|
@@ -91,32 +94,74 @@ func (s *Svc) CommitConfiguration(from, to config.Configuration) bool {
|
|
|
}
|
|
|
continue
|
|
|
}
|
|
|
+ existing[uri.String()] = uri
|
|
|
+ }
|
|
|
+
|
|
|
+ // Expand dynamic addresses into a set of relays
|
|
|
+ for key, uri := range existing {
|
|
|
+ if uri.Scheme != "dynamic+http" && uri.Scheme != "dynamic+https" {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ delete(existing, key)
|
|
|
+
|
|
|
+ uri.Scheme = uri.Scheme[8:]
|
|
|
|
|
|
- existing[uri.String()] = struct{}{}
|
|
|
+ data, err := http.Get(uri.String())
|
|
|
+ if err != nil {
|
|
|
+ if debug {
|
|
|
+ l.Debugln("Failed to lookup dynamic relays", err)
|
|
|
+ }
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ var ann dynamicAnnouncement
|
|
|
+ err = json.NewDecoder(data.Body).Decode(&ann)
|
|
|
+ data.Body.Close()
|
|
|
+ if err != nil {
|
|
|
+ if debug {
|
|
|
+ l.Debugln("Failed to lookup dynamic relays", err)
|
|
|
+ }
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ for _, relayAnn := range ann.Relays {
|
|
|
+ ruri, err := url.Parse(relayAnn.URL)
|
|
|
+ if err != nil {
|
|
|
+ if debug {
|
|
|
+ l.Debugln("Failed to parse dynamic relay address", relayAnn.URL, err)
|
|
|
+ }
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if debug {
|
|
|
+ l.Debugln("Found", ruri, "via", uri)
|
|
|
+ }
|
|
|
+ existing[ruri.String()] = ruri
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- _, ok := s.tokens[uri.String()]
|
|
|
+ for key, uri := range existing {
|
|
|
+ _, ok := s.tokens[key]
|
|
|
if !ok {
|
|
|
if debug {
|
|
|
l.Debugln("Connecting to relay", uri)
|
|
|
}
|
|
|
c := client.NewProtocolClient(uri, s.tlsCfg.Certificates, s.invitations)
|
|
|
- s.tokens[uri.String()] = s.Add(c)
|
|
|
+ s.tokens[key] = s.Add(c)
|
|
|
s.mut.Lock()
|
|
|
- s.clients[uri.String()] = c
|
|
|
+ s.clients[key] = c
|
|
|
s.mut.Unlock()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- for uri, token := range s.tokens {
|
|
|
- _, ok := existing[uri]
|
|
|
+ for key, token := range s.tokens {
|
|
|
+ _, ok := existing[key]
|
|
|
if !ok {
|
|
|
err := s.Remove(token)
|
|
|
- delete(s.tokens, uri)
|
|
|
+ delete(s.tokens, key)
|
|
|
s.mut.Lock()
|
|
|
- delete(s.clients, uri)
|
|
|
+ delete(s.clients, key)
|
|
|
s.mut.Unlock()
|
|
|
if debug {
|
|
|
- l.Debugln("Disconnecting from relay", uri, err)
|
|
|
+ l.Debugln("Disconnecting from relay", key, err)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -195,3 +240,11 @@ func (r *invitationReceiver) Stop() {
|
|
|
r.stop <- struct{}{}
|
|
|
r.stop = nil
|
|
|
}
|
|
|
+
|
|
|
+type dynamicAnnouncement struct {
|
|
|
+ Relays []relayAnnouncement `json:"relays"`
|
|
|
+}
|
|
|
+
|
|
|
+type relayAnnouncement struct {
|
|
|
+ URL string `json:"url"`
|
|
|
+}
|