xmpp/xmpp.go
changeset 175 fc8702a8572e
parent 166 8093a2da46db
child 176 52c100897e9d
equal deleted inserted replaced
166:8093a2da46db 175:fc8702a8572e
    87 // may be specified. The initial presence will be broadcast. If status
    87 // may be specified. The initial presence will be broadcast. If status
    88 // is non-nil, connection progress information will be sent on it.
    88 // is non-nil, connection progress information will be sent on it.
    89 func NewClient(jid *JID, password string, tlsconf tls.Config, exts []Extension,
    89 func NewClient(jid *JID, password string, tlsconf tls.Config, exts []Extension,
    90 	pr Presence, status chan<- Status) (*Client, error) {
    90 	pr Presence, status chan<- Status) (*Client, error) {
    91 
    91 
       
    92 	// Resolve the domain in the JID.
       
    93 	_, srvs, err := net.LookupSRV(clientSrv, "tcp", jid.Domain)
       
    94 	if err != nil {
       
    95 		return nil, fmt.Errorf("LookupSrv %s: %v", jid.Domain, err)
       
    96 	}
       
    97 	if len(srvs) == 0 {
       
    98 		return nil, fmt.Errorf("LookupSrv %s: no results", jid.Domain)
       
    99 	}
       
   100 
       
   101 	var tcp *net.TCPConn
       
   102 	for _, srv := range srvs {
       
   103 		addrStr := fmt.Sprintf("%s:%d", srv.Target, srv.Port)
       
   104 		var addr *net.TCPAddr
       
   105 		addr, err = net.ResolveTCPAddr("tcp", addrStr)
       
   106 		if err != nil {
       
   107 			err = fmt.Errorf("ResolveTCPAddr(%s): %s",
       
   108 				addrStr, err.Error())
       
   109 			continue
       
   110 		}
       
   111 		tcp, err = net.DialTCP("tcp", nil, addr)
       
   112 		if tcp != nil {
       
   113 			break
       
   114 		}
       
   115 	}
       
   116 	if tcp == nil {
       
   117 		return nil, err
       
   118 	}
       
   119 
       
   120 	return newClient(tcp, jid, password, tlsconf, exts, pr, status)
       
   121 }
       
   122 
       
   123 // Connect to the specified host and port. This is otherwise identical
       
   124 // to NewClient.
       
   125 func NewClientFromHost(jid *JID, password string, tlsconf tls.Config,
       
   126 	exts []Extension, pr Presence, status chan<- Status, host string,
       
   127 	port int) (*Client, error) {
       
   128 
       
   129 	addrStr := fmt.Sprintf("%s:%d", host, port)
       
   130 	addr, err := net.ResolveTCPAddr("tcp", addrStr)
       
   131 	if err != nil {
       
   132 		return nil, err
       
   133 	}
       
   134 	tcp, err := net.DialTCP("tcp", nil, addr)
       
   135 	if err != nil {
       
   136 		return nil, err
       
   137 	}
       
   138 
       
   139 	return newClient(tcp, jid, password, tlsconf, exts, pr, status)
       
   140 }
       
   141 
       
   142 func newClient(tcp *net.TCPConn, jid *JID, password string, tlsconf tls.Config,
       
   143 	exts []Extension, pr Presence, status chan<- Status) (*Client, error) {
       
   144 
    92 	// Include the mandatory extensions.
   145 	// Include the mandatory extensions.
    93 	roster := newRosterExt()
   146 	roster := newRosterExt()
    94 	exts = append(exts, roster.Extension)
   147 	exts = append(exts, roster.Extension)
    95 	exts = append(exts, bindExt)
   148 	exts = append(exts, bindExt)
    96 
   149 
   114 			}
   167 			}
   115 			extStanza[k] = v
   168 			extStanza[k] = v
   116 		}
   169 		}
   117 	}
   170 	}
   118 
   171 
   119 	// Resolve the domain in the JID.
   172 	// The thing that called this made a TCP connection, so now we
   120 	_, srvs, err := net.LookupSRV(clientSrv, "tcp", jid.Domain)
   173 	// can signal that it's connected.
   121 	if err != nil {
       
   122 		return nil, fmt.Errorf("LookupSrv %s: %v", jid.Domain, err)
       
   123 	}
       
   124 	if len(srvs) == 0 {
       
   125 		return nil, fmt.Errorf("LookupSrv %s: no results", jid.Domain)
       
   126 	}
       
   127 
       
   128 	var tcp *net.TCPConn
       
   129 	for _, srv := range srvs {
       
   130 		addrStr := fmt.Sprintf("%s:%d", srv.Target, srv.Port)
       
   131 		var addr *net.TCPAddr
       
   132 		addr, err = net.ResolveTCPAddr("tcp", addrStr)
       
   133 		if err != nil {
       
   134 			err = fmt.Errorf("ResolveTCPAddr(%s): %s",
       
   135 				addrStr, err.Error())
       
   136 			continue
       
   137 		}
       
   138 		tcp, err = net.DialTCP("tcp", nil, addr)
       
   139 		if tcp != nil {
       
   140 			break
       
   141 		}
       
   142 	}
       
   143 	if tcp == nil {
       
   144 		return nil, err
       
   145 	}
       
   146 	cl.setStatus(StatusConnected)
   174 	cl.setStatus(StatusConnected)
   147 
   175 
   148 	// Start the transport handler, initially unencrypted.
   176 	// Start the transport handler, initially unencrypted.
   149 	recvReader, recvWriter := io.Pipe()
   177 	recvReader, recvWriter := io.Pipe()
   150 	sendReader, sendWriter := io.Pipe()
   178 	sendReader, sendWriter := io.Pipe()