Mix xmpp-client and xmpps-client SRV records (sorted by prio)

srvlookup
Martin Dosch 3 years ago
parent 4297630c32
commit d00ca7cd37

@ -7,56 +7,95 @@ package main
import (
"fmt"
"net"
"sort"
"strings"
"github.com/mattn/go-xmpp" // BSD-3-Clause
)
type srv struct {
host string
xmpps bool
port uint16
priority uint16
weight uint16
}
type srvMixed []srv
type byPriority []srv
func (o byPriority) Len() int { return len(o) }
func (o byPriority) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
func (o byPriority) Less(i, j int) bool {
if o[i].priority == o[j].priority {
return o[i].weight > o[j].weight
} else {
return o[i].priority < o[j].priority
}
}
func connect(options xmpp.Options, directTLS bool) (*xmpp.Client, error) {
// Lookup SRV records if server is not specified manually
// Look up SRV records if server is not specified manually.
srvMixed := srvMixed{}
if options.Host == "" {
server := options.User[strings.LastIndex(options.User, "@")+1:]
// Lookup xmpp-client SRV records if direct TLS is not required
if !directTLS {
if _, addrs, err := net.LookupSRV("xmpp-client", "tcp", server); err == nil {
if len(addrs) > 0 {
for _, adr := range addrs {
options.Host = fmt.Sprintf("%s:%d", adr.Target, adr.Port)
// Connect to server
client, err := options.NewClient()
if err == nil {
return client, err
}
}
// Look up xmpp-client SRV records.
if _, addrs, err := net.LookupSRV("xmpp-client", "tcp", server); err == nil {
if len(addrs) > 0 {
for _, adr := range addrs {
srvMixed = append(srvMixed, srv{adr.Target, false,
adr.Port, adr.Priority, adr.Weight})
}
}
// Try port 5222 if no xmpp-client SRV records are provided.
options.Host = server + ":5222"
// Connect to server
client, err := options.NewClient()
if err == nil {
return client, err
}
// Unset STartTLS as we try direct TLS now
options.NoTLS = false
options.StartTLS = false
}
// Lookup xmpps-client SRV records
// TODO: Fallback to 5223 and 443 if no xmpps-client SRV records exist
// Look up xmpps-client SRV records.
if _, addrs, err := net.LookupSRV("xmpps-client", "tcp", server); err == nil {
if len(addrs) > 0 {
for _, adr := range addrs {
options.Host = fmt.Sprintf("%s:%d", adr.Target, adr.Port)
srvMixed = append(srvMixed, srv{adr.Target, true,
adr.Port, adr.Priority, adr.Weight})
}
}
}
if len(srvMixed) > 0 {
// Sort xmpp- and xmpps-client SRV records according to the priority
// and wight.
sort.Sort(byPriority(srvMixed))
for _, adr := range srvMixed {
if !directTLS && !adr.xmpps {
// Use StartTLS
options.NoTLS = true
options.StartTLS = true
options.Host = fmt.Sprintf("%s:%d", adr.host, adr.port)
// Connect to server
client, err := options.NewClient()
if err == nil {
return client, err
}
} else if adr.xmpps {
// Use direct TLS
options.NoTLS = false
options.StartTLS = false
options.Host = fmt.Sprintf("%s:%d", adr.host, adr.port)
// Connect to server
client, err := options.NewClient()
if err == nil {
return client, err
}
}
}
}
// Try port 5222 if no xmpp-client SRV records are provided.
options.NoTLS = true
options.StartTLS = true
options.Host = fmt.Sprintf("%s:%d", server, 5222)
// Connect to server
client, err := options.NewClient()
return client, err
}
// Connect to server
client, err := options.NewClient()
return client, err
}

Loading…
Cancel
Save