1// Copyright 2013 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5// Package xmpp implements the XMPP IM protocol, as specified in RFC 6120 and 6// 6121. 7package xmpp 8 9import ( 10 "errors" 11 "net" 12 "strconv" 13 "strings" 14 15 ourNet "github.com/coyim/coyim/net" 16 "golang.org/x/net/proxy" 17) 18 19var ( 20 // ErrServiceNotAvailable means that the service is decidedly not available at this domain 21 ErrServiceNotAvailable = errors.New("service not available") 22) 23 24// Resolve performs a DNS SRV lookup for the XMPP server that serves the given 25// domain. 26func Resolve(domain string) (hostport []string, err error) { 27 return massage(net.LookupSRV("xmpp-client", "tcp", domain)) 28} 29 30// ResolveSRVWithProxy performs a DNS SRV lookup for the xmpp server that serves the given domain over the given proxy 31func ResolveSRVWithProxy(proxy proxy.Dialer, domain string) (hostport []string, err error) { 32 return massage(ourNet.LookupSRV(proxy, "xmpp-client", "tcp", domain)) 33} 34 35func massage(cname string, addrs []*net.SRV, err error) ([]string, error) { 36 if err != nil { 37 return nil, err 38 } 39 40 // https://xmpp.org/rfcs/rfc6120.html#tcp-resolution-prefer 41 if len(addrs) == 1 && addrs[0].Target == "." { 42 return nil, ErrServiceNotAvailable 43 } 44 45 ret := make([]string, 0, len(addrs)) 46 for _, addr := range addrs { 47 hostport := net.JoinHostPort( 48 strings.TrimSuffix(addr.Target, "."), 49 strconv.Itoa(int(addr.Port)), 50 ) 51 52 ret = append(ret, hostport) 53 } 54 55 return ret, nil 56} 57