Allow the client to specify a host and port to connect to, rather than using SRV records.
authorChris Jones <chris@cjones.org>
Wed, 06 Nov 2013 20:38:03 -0700
changeset 175 fc8702a8572e
parent 166 8093a2da46db
child 176 52c100897e9d
Allow the client to specify a host and port to connect to, rather than using SRV records.
xmpp/xmpp.go
--- a/xmpp/xmpp.go	Wed Oct 02 23:22:27 2013 -0600
+++ b/xmpp/xmpp.go	Wed Nov 06 20:38:03 2013 -0700
@@ -89,6 +89,59 @@
 func NewClient(jid *JID, password string, tlsconf tls.Config, exts []Extension,
 	pr Presence, status chan<- Status) (*Client, error) {
 
+	// Resolve the domain in the JID.
+	_, srvs, err := net.LookupSRV(clientSrv, "tcp", jid.Domain)
+	if err != nil {
+		return nil, fmt.Errorf("LookupSrv %s: %v", jid.Domain, err)
+	}
+	if len(srvs) == 0 {
+		return nil, fmt.Errorf("LookupSrv %s: no results", jid.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)
+}
+
+// Connect to the specified host and port. This is otherwise identical
+// to NewClient.
+func NewClientFromHost(jid *JID, password string, tlsconf tls.Config,
+	exts []Extension, pr Presence, status chan<- Status, host string,
+	port int) (*Client, error) {
+
+	addrStr := fmt.Sprintf("%s:%d", host, port)
+	addr, err := net.ResolveTCPAddr("tcp", addrStr)
+	if err != nil {
+		return nil, err
+	}
+	tcp, err := net.DialTCP("tcp", nil, addr)
+	if err != nil {
+		return nil, err
+	}
+
+	return newClient(tcp, jid, password, tlsconf, exts, pr, status)
+}
+
+func newClient(tcp *net.TCPConn, jid *JID, password string, tlsconf tls.Config,
+	exts []Extension, pr Presence, status chan<- Status) (*Client, error) {
+
 	// Include the mandatory extensions.
 	roster := newRosterExt()
 	exts = append(exts, roster.Extension)
@@ -116,33 +169,8 @@
 		}
 	}
 
-	// Resolve the domain in the JID.
-	_, srvs, err := net.LookupSRV(clientSrv, "tcp", jid.Domain)
-	if err != nil {
-		return nil, fmt.Errorf("LookupSrv %s: %v", jid.Domain, err)
-	}
-	if len(srvs) == 0 {
-		return nil, fmt.Errorf("LookupSrv %s: no results", jid.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
-	}
+	// The thing that called this made a TCP connection, so now we
+	// can signal that it's connected.
 	cl.setStatus(StatusConnected)
 
 	// Start the transport handler, initially unencrypted.