func DefaultDial(proto, realm string) (io.ReadWriteCloser, error) { if proto != "tcp" && proto != "udp" { return nil, ErrInvalidProto(proto) } _, addrs, err := net.LookupSRV("kerberos", proto, realm) if err != nil { _, addrs, err = net.LookupSRV("kerberos-master", proto, realm) if err != nil { return nil, err } } var sock net.Conn for _, a := range addrs { addr := net.JoinHostPort(a.Target, strconv.Itoa(int(a.Port))) sock, err = net.Dial(proto, addr) if err == nil { break } } if err != nil { return nil, err } if proto == "udp" { // For datagram connections, we retry up to three times, then give up sock.SetReadDeadline(time.Now().Add(udpReadTimeout)) } return sock, nil }
func (c *connector) connectSRV(m cmdsMethod) (io.Closer, error) { if hostnameIsIP(c.uhost) { return nil, errors.New("cannot do SRV lookup on an IP address") } _, addrs, err := net.LookupSRV(m.name, m.explicitMethodName, c.uhost) if err != nil { return nil, err } c.inhibitFallback = c.inhibitFallback || len(addrs) > 0 for _, a := range addrs { if a.Target == "." { continue } conn, err := c.connectDial(m, a.Target, fmt.Sprintf("%d", a.Port)) if err != nil { continue } return conn, nil } return nil, errors.New("all SRV endpoints failed") }
// Creates an XMPP client identified by the given JID, authenticating // with the provided password and TLS config. Zero or more extensions // may be specified. The initial presence will be broadcast. If status // is non-nil, connection progress information will be sent on it. func NewClient(jid *JID, password string, tlsconf *tls.Config, exts []Extension, pr Presence, status chan<- Status) (*Client, error) { // Resolve the domain in the JID. domain := jid.Domain() _, srvs, err := net.LookupSRV(clientSrv, "tcp", domain) if err != nil { return nil, fmt.Errorf("LookupSrv %s: %v", domain, err) } if len(srvs) == 0 { return nil, fmt.Errorf("LookupSrv %s: no results", domain) } var tcp *net.TCPConn for _, srv := range srvs { addrStr := fmt.Sprintf("%s:%d", srv.Target, srv.Port) var addr *net.TCPAddr addr, err = net.ResolveTCPAddr("tcp", addrStr) if err != nil { err = fmt.Errorf("ResolveTCPAddr(%s): %s", addrStr, err.Error()) continue } tcp, err = net.DialTCP("tcp", nil, addr) if tcp != nil { break } } if tcp == nil { return nil, err } return newClient(tcp, jid, password, tlsconf, exts, pr, status) }
// Dial opens a new TCP connection with XMPP-style peer discovery. // Typically, Dial is not called directly but instead called when necessary by the stream object. func Dial(domain, service string, defaultPort uint16) (*net.TCPConn, error) { _, srvs, err := net.LookupSRV(service, "tcp", domain) // Try fallback process if SRV lookup fails if err != nil { addr, err := net.ResolveTCPAddr("tcp", fmt.Sprint(domain, ":", defaultPort)) if err != nil { return nil, err } return net.DialTCP("tcp", addr, nil) } if len(srvs) == 1 && srvs[0].Target == "." { return nil, errors.New("dial: '" + service + "' service does not exist at " + domain) } for _, srv := range srvs { conn, err := dialRecord(srv) if err == nil { return conn, err } } return nil, errors.New("dial: the server '" + domain + "' failed to respond.") }
func lookupSRVPermissive(domain string) ([]*net.SRV, error) { _, srvs, err := net.LookupSRV(clientSrv, "tcp", domain) // Success! if err == nil && len(srvs) > 0 { return srvs, nil } if err != nil { err = fmt.Errorf("LookupSrv %s: %v", domain, err) } if len(srvs) == 0 { err = fmt.Errorf("LookupSrv %s: no results", domain) } // Go one domain up: splitDomain := strings.SplitN(domain, ".", 2) // Nothing to split: if len(splitDomain) <= 1 { return nil, err } return lookupSRVPermissive(strings.Join(splitDomain[1:], ".")) }
func ResolveNetwork(network string) []string { var servers []string parts := strings.Split(network, ",") if len(parts) > 1 { log.Printf("Interpreting %q as list of servers instead of network name\n", network) for _, part := range parts { if strings.TrimSpace(part) != "" { servers = append(servers, part) } } return servers } _, addrs, err := net.LookupSRV("robustirc", "tcp", network) if err != nil { log.Fatal(err) } for _, addr := range addrs { target := addr.Target if target[len(target)-1] == '.' { target = target[:len(target)-1] } servers = append(servers, fmt.Sprintf("%s:%d", target, addr.Port)) } return servers }
func Init() { var err error if revel.DevMode { session, err = mgo.Dial("192.168.99.100") check(err) } else { session, err = mgo.Dial(os.Getenv("MONGO_PORT_27017_TCP_ADDR")) if err != nil { // try mesos _, srv, err := net.LookupSRV(os.Getenv("SERVICE_NAME"), "tcp", DOMAIN) if err != nil { log.Fatal(err) check(err) } else { url := fmt.Sprintf("%s:%d", srv[0].Target, srv[0].Port) fmt.Println("URL : " + url) session, err = mgo.Dial(url) } } } session.SetMode(mgo.Monotonic, true) importReferentData() }
// ExampleDiscover_refreshAsync updates the servers list asynchronously every // 100 milliseconds. func ExampleDiscover_refreshAsync() { discovery := dnsdisco.NewDiscovery("jabber", "tcp", "registro.br") // depending on where this examples run the retrieving time differs (DNS RTT), // so as we cannot sleep a deterministic period, to make this test more useful // we are creating a channel to alert the main go routine that we got an // answer from the network retrieved := make(chan bool) discovery.SetRetriever(dnsdisco.RetrieverFunc(func(service, proto, name string) (servers []*net.SRV, err error) { _, servers, err = net.LookupSRV(service, proto, name) retrieved <- true return })) // refresh the SRV records every 100 milliseconds stopRefresh := discovery.RefreshAsync(100 * time.Millisecond) <-retrieved // sleep for a short period only to allow the library to process the SRV // records retrieved from the network time.Sleep(100 * time.Millisecond) target, port := discovery.Choose() fmt.Printf("Target: %s\nPort: %d\n", target, port) close(stopRefresh) // Output: // Target: jabber.registro.br. // Port: 5269 }
func csResolveDnsSrv(spec *connSpec) bool { if len(spec.MemcachedHosts) > 1 || len(spec.HttpHosts) > 1 { return false } if spec.hasExplicitPort || spec.Scheme.IsHTTP() { return false } srvHostname := spec.HttpHosts[0].Host _, addrs, err := net.LookupSRV(spec.Scheme.String(), "tcp", srvHostname) if err != nil || len(addrs) == 0 { return false } var hostList []*connSpecAddr for _, srvRecord := range addrs { hostList = append(hostList, &connSpecAddr{srvRecord.Target, srvRecord.Port}) } spec.HttpHosts = nil spec.MemcachedHosts = nil if spec.Scheme.IsHTTP() { spec.HttpHosts = hostList } else { spec.MemcachedHosts = hostList } return true }
// This looks up a TeamSpeak host, immitating the manner in which the TeamSpeak // client looks it up. hostCombo should either be a host:port combination or a // lone hostname. If a port is not specified, the default port of 9987 will be // used. func ResolveHost(hostCombo string) ([]string, error) { hostname, port, err := net.SplitHostPort(hostCombo) if addrErr, ok := err.(*net.AddrError); ok && addrErr.Err == "missing port in address" { hostname = hostCombo port = "9987" } else if err != nil { return nil, err } _, records, err := net.LookupSRV("ts3", "udp", hostname) if err != nil { return nil, err } if len(records) > 0 { hosts := make([]string, len(records)) for i, record := range records { hosts[i] = net.JoinHostPort(record.Target, strconv.FormatInt(int64(record.Port), 10)) } return hosts, nil } addrs, err := net.LookupIP(hostname) if err != nil { return nil, err } hosts := make([]string, len(addrs)) for i, addr := range addrs { hosts[i] = net.JoinHostPort(addr.String(), port) } return hosts, nil }
func GetRingServer(servicename string) (string, error) { // All-In-One defaults h, _ := os.Hostname() d := strings.SplitN(h, ".", 2) if strings.HasSuffix(d[0], "-aio") { // TODO: Not sure about name, proto -- are those ever *not* "syndicate" // and "tcp"? switch servicename { case "value": return h + ":8443", nil case "group": return h + ":8444", nil } panic("Unknown service " + servicename) } service, err := GenServiceID(servicename, "syndicate", "tcp") if err != nil { return "", err } _, addrs, err := net.LookupSRV("", "", service) if err != nil { return "", err } if len(addrs) == 0 { return "", fmt.Errorf("Syndicate SRV lookup is empty") } return fmt.Sprintf("%s:%d", addrs[0].Target, addrs[0].Port), nil }
func lookupCassandraHosts(service, dns string) ([]string, error) { cname, srvs, err := net.LookupSRV(service, "tcp", dns) if err != nil { return nil, fmt.Errorf("Looking up SRV record (srv: %s, dns: %s): %s", service, dns, err) } log.Printf("CNAME: %s", cname) log.Printf("SRVs: %+v", srvs) if len(srvs) == 0 { return nil, fmt.Errorf("No SRV records found (srv: %s, dns: %s)", service, dns) } addrs := make([]string, len(srvs), len(srvs)) for i, srv := range srvs { addr := srv.Target if strings.HasSuffix(srv.Target, ".") { addr = addr[:len(addr)-1] } if srv.Port > 0 { addr = addr + ":" + strconv.FormatUint(uint64(srv.Port), 10) } addrs[i] = addr } return addrs, nil }
func main() { flag.Parse() args := flag.Args() if len(args) != 1 { fmt.Println("Please specify a single record to lookup") os.Exit(1) } if *verbose { fmt.Printf("looking up %s\n", args[0]) } cname, addrs, err := net.LookupSRV(*service, *proto, args[0]) if err != nil { fmt.Printf("unable to lookup %s: %s\n", args[0], err) os.Exit(2) } if *verbose { fmt.Printf("cname: %s\n", cname) } for _, addr := range addrs { fmt.Printf("%s:%d\n", addr.Target, addr.Port) } }
// newTarget parses the given address and tries to construct endpoints from it. func newTarget(name, addr string) (*target, error) { t := &target{ name: name, endpoints: []string{}, } u, err := url.Parse(addr) if err == nil && u.Scheme != "" { t.endpoints = append(t.endpoints, u.String()) } else { _, addrs, err := net.LookupSRV("", "", addr) if err != nil { return nil, err } for _, a := range addrs { host := strings.Trim(a.Target, ".") e := fmt.Sprintf("http://%s:%d/", host, a.Port) t.endpoints = append(t.endpoints, e) } } if len(t.endpoints) == 0 { return nil, fmt.Errorf("no endpoints for target '%s'", name) } return t, nil }
// Connect to the appropriate server and authenticate as the given JID // with the given password. This function will return as soon as a TCP // connection has been established, but before XMPP stream negotiation // has completed. The negotiation will occur asynchronously, and any // send operation to Client.Out will block until negotiation (resource // binding) is complete. func NewClient(jid *JID, password string, exts []Extension) (*Client, error) { // Resolve the domain in the JID. _, srvs, err := net.LookupSRV(clientSrv, "tcp", jid.Domain) if err != nil { return nil, errors.New("LookupSrv " + jid.Domain + ": " + err.Error()) } var tcp *net.TCPConn for _, srv := range srvs { addrStr := fmt.Sprintf("%s:%d", srv.Target, srv.Port) addr, err := net.ResolveTCPAddr("tcp", addrStr) if err != nil { err = fmt.Errorf("ResolveTCPAddr(%s): %s", addrStr, err.Error()) continue } tcp, err = net.DialTCP("tcp", nil, addr) if err != nil { err = fmt.Errorf("DialTCP(%s): %s", addr, err) continue } } if tcp == nil { return nil, err } return newClient(tcp, jid, password, exts) }
func Discover(domain string) *ServerManifest { for { // Step 1: DNS SRV lookup cname, addrs, err := net.LookupSRV("wave-server", "tcp", domain) if err == nil && len(addrs) > 0 { log.Println("DNS SRV lookup: ", cname, addrs[0].Target, addrs[0].Port) if manifest := GetManifest(addrs[0].Target, addrs[0].Port); manifest != nil { // HACK START manifest.Domain = domain // HACK END return manifest } } // Step 2: Lookup of wave.domain.com:80 if manifest := GetManifest("wave."+domain, 8080); manifest != nil { // HACK START manifest.Domain = domain // HACK END return manifest } // Step 3: Lookup domain.com:80 if manifest := GetManifest(domain, 8080); manifest != nil { // HACK START manifest.Domain = domain // HACK END return manifest } // Discovery failed return nil } return nil }
func countInstancesInCluster(lookupName string) (int, error) { _, srvRecords, err := net.LookupSRV("", "", lookupName) if err != nil { return 0, err } return len(srvRecords), nil }
func LookupSRV(service, proto, name string) []*net.SRV { _, addrs, err := net.LookupSRV(service, proto, name) if err != nil { return []*net.SRV{} } sort.Sort(sortSRV(addrs)) return addrs }
// lookupEtcdSrv tries to resolve an SRV query for the etcd service for the // specified domain. // // lookupEtcdSRV constructs the DNS name to look up following RFC 2782. // That is, it looks up _etcd._tcp.domain. func lookupEtcdSRV(domain string) ([]*net.SRV, error) { // Ignore the CNAME as we don't need it. _, addrs, err := net.LookupSRV("etcd", "tcp", domain) if err != nil { return addrs, err } return addrs, nil }
// lookup returned records are sorted by priority and randomized by weight within a priority. func lookup(service string) ([]*net.SRV, error) { _, addrs, err := net.LookupSRV("", "", service) if err != nil { log.Println("srv:", service) log.Println(err) return nil, ErrSRVLookupFailed } return addrs, nil }
func main() { _, addrs, err := net.LookupSRV(os.Args[1], os.Args[2], os.Args[3]) if err != nil { return } for _, addr := range addrs { fmt.Printf("%v:%v\n", addr.Target, addr.Port) } }
// Resolve performs a DNS SRV lookup for the XMPP server that serves the given // domain. func Resolve(domain string) (host string, port uint16, err error) { _, addrs, err := net.LookupSRV("xmpp-client", "tcp", domain) if err != nil { return "", 0, err } if len(addrs) == 0 { return "", 0, errors.New("xmpp: no SRV records found for " + domain) } return addrs[0].Target, addrs[0].Port, nil }
func GetRedisMaster() net.SRV { _, addrs, err := net.LookupSRV(*masterService, *protocol, fmt.Sprintf("%s.%s", *framework, *domain)) if err != nil { fmt.Println(err) return net.SRV{} } srvEntry := *(addrs[0]) return srvEntry }
func ResolveXMPPDomain(domain string) (string, uint16, error) { service := "xmpp-client" proto := "tcp" _, addrs, _ := net.LookupSRV(service, proto, domain) if len(addrs) > 0 { addr := addrs[0] return addr.Target, addr.Port, nil } return domain, 5222, nil }
func (b *srvBackends) NextBackend(conn net.Conn) string { _, addrs, err := net.LookupSRV("", "", b.name) if err != nil { log.Println("dns:", err) return "" } if len(addrs) == 0 { return "" } port := strconv.Itoa(int(addrs[0].Port)) return net.JoinHostPort(addrs[0].Target, port) }
func Dial(host string) (net.Conn, error) { _, srvs, _ := net.LookupSRV("xmpp-client", "tcp", host) var conn net.Conn var err error for _, x := range srvs { conn, err = net.Dial("tcp", x.Target+":"+strconv.Itoa(int(x.Port))) if err == nil { return conn, nil } } return net.Dial("tcp", host+":5222") }
func lookupSRV(name string) string { log.Printf("lookupSRV: name=%s", name) _, addrs, err := net.LookupSRV("", "", name) if err != nil { log.Println("dns:", err) return "" } if len(addrs) == 0 { return "" } port := strconv.Itoa(int(addrs[0].Port)) return net.JoinHostPort(addrs[0].Target, port) }
func lookup(svcName string) (sets.String, error) { endpoints := sets.NewString() _, srvRecords, err := net.LookupSRV("", "", svcName) if err != nil { return endpoints, err } for _, srvRecord := range srvRecords { // The SRV records ends in a "." for the root domain ep := fmt.Sprintf("%v", srvRecord.Target[:len(srvRecord.Target)-1]) endpoints.Insert(ep) } return endpoints, nil }
// LookupSRVPort determines the port for a service via an SRV lookup func LookupSRVPort(name string) (uint16, error) { _, addrs, err := net.LookupSRV("", "", name) if err != nil { return 0, err } if len(addrs) == 0 { err := errors.New("no srv results") return 0, err } return addrs[0].Port, nil }
func Test() { // lookup SRV records cname, addresses, err := net.LookupSRV("xmpp-server", "tcp", "google.com") // cname, addresses, err := net.LookupSRV("", "", "_xmpp-server._tcp.google.com") if err != nil { fmt.Println(err) return } fmt.Printf("cname : %s \n", cname) ap := fmt.Sprintf("http://%s:%d", strings.TrimRight(addresses[0].Target, "."), addresses[0].Port) fmt.Println(ap) }