// Copyright 2021 Martin Dosch. // Use of this source code is governed by the BSD-2-clause // license that can be found in the LICENSE file.package main 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 } return o[i].priority < o[j].priority } func connect(options xmpp.Options, directTLS bool) (*xmpp.Client, error) { // Look up SRV records if server is not specified manually. srvMixed := srvMixed{} if options.Host == "" { server := options.User[strings.Index(options.User, "@")+1:] // 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{strings.TrimSuffix(adr.Target, "."), false, adr.Port, adr.Priority, adr.Weight}) } } } // Look up xmpps-client SRV records. if _, addrs, err := net.LookupSRV("xmpps-client", "tcp", server); err == nil { if len(addrs) > 0 { if addrs[0].Target != "." { for _, adr := range addrs { srvMixed = append(srvMixed, srv{strings.TrimSuffix(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 = net.JoinHostPort(adr.host, fmt.Sprint(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 = net.JoinHostPort(adr.host, fmt.Sprint(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 = net.JoinHostPort(server, "5222") // Connect to server client, err := options.NewClient() return client, err } // Connect to server client, err := options.NewClient() return client, err }