/** Initiate a connection to the XMPP server. * This function returns immediately after starting the connection * process to the XMPP server, and notifications of connection state changes * will be sent to the callback function. The domain and port to connect to * are usually determined by an SRV lookup for the xmpp-client service at * the domain specified in the JID. If SRV lookup fails, altdomain and * altport will be used instead if specified. * * @param conn a Strophe connection object * @param altdomain a string with domain to use if SRV lookup fails. If this * is NULL, the domain from the JID will be used. * @param altport an integer port number to use if SRV lookup fails. If this * is 0, the default port will be assumed. * @param callback a xmpp_conn_handler callback function that will receive * notifications of connection status * @param userdata an opaque data pointer that will be passed to the callback * * @return XMPP_EOK (0) on success or a number less than 0 on failure * * @ingroup Connections */ int xmpp_connect_client(xmpp_conn_t * const conn, const char * const altdomain, unsigned short altport, xmpp_conn_handler callback, void * const userdata) { resolver_srv_rr_t *srv_rr_list = NULL; resolver_srv_rr_t *rr; char *domain; const char *host = NULL; unsigned short port = 0; int found = XMPP_DOMAIN_NOT_FOUND; int rc; domain = xmpp_jid_domain(conn->ctx, conn->jid); if (!domain) return XMPP_EMEM; if (altdomain != NULL) { xmpp_debug(conn->ctx, "xmpp", "Connecting via altdomain."); host = altdomain; port = altport ? altport : _conn_default_port(conn, XMPP_CLIENT); found = XMPP_DOMAIN_ALTDOMAIN; /* SSL tunneled connection on 5223 port is legacy and doesn't * have an SRV record. */ } else if (!conn->tls_legacy_ssl) { found = resolver_srv_lookup(conn->ctx, "xmpp-client", "tcp", domain, &srv_rr_list); } if (XMPP_DOMAIN_NOT_FOUND == found) { xmpp_debug(conn->ctx, "xmpp", "SRV lookup failed, " "connecting via domain."); host = domain; port = altport ? altport : _conn_default_port(conn, XMPP_CLIENT); found = XMPP_DOMAIN_ALTDOMAIN; } rr = srv_rr_list; do { if (XMPP_DOMAIN_FOUND == found && rr != NULL) { host = rr->target; port = rr->port; rr = rr->next; } rc = _conn_connect(conn, domain, host, port, XMPP_CLIENT, callback, userdata); } while (rc != 0 && rr != NULL); xmpp_free(conn->ctx, domain); resolver_srv_free(conn->ctx, srv_rr_list); return rc; }
/** Initiate a component connection to server. * This function returns immediately after starting the connection * process to the XMPP server, and notifiations of connection state changes * will be sent to the internal callback function that will set up handler * for the component handshake as defined in XEP-0114. * The domain and port to connect to must be provided in this case as the JID * provided to the call serves as component identifier to the server and is * not subject to DNS resolution. * * @param conn a Strophe connection object * @param server a string with domain to use directly as the domain can't be * extracted from the component name/JID. If this is not set, the call * will fail. * @param port an integer port number to use to connect to server expecting * an external component. If this is 0, the port 5347 will be assumed. * @param callback a xmpp_conn_handler callback function that will receive * notifications of connection status * @param userdata an opaque data pointer that will be passed to the callback * * @return 0 on success and -1 on an error * * @ingroup Connections */ int xmpp_connect_component(xmpp_conn_t * const conn, const char * const server, unsigned short port, xmpp_conn_handler callback, void * const userdata) { int connectport; if (conn->state != XMPP_STATE_DISCONNECTED) return -1; if (conn->domain != NULL) xmpp_free(conn->ctx, conn->domain); conn->type = XMPP_COMPONENT; conn->secured = 0; conn->tls_failed = 0; /* JID serves as an identificator here and will be used as "to" attribute of the stream */ conn->domain = xmpp_strdup(conn->ctx, conn->jid); /* The server domain, jid and password MUST be specified. */ if (!(server && conn->jid && conn->pass)) return -1; connectport = port ? port : _conn_default_port(conn); xmpp_debug(conn->ctx, "xmpp", "Connecting via %s", server); conn->sock = sock_connect(server, connectport); xmpp_debug(conn->ctx, "xmpp", "sock_connect to %s:%d returned %d", server, connectport, conn->sock); if (conn->sock == -1) return -1; /* XEP-0114 does not support TLS */ conn->tls_disabled = 1; /* setup handler */ conn->conn_handler = callback; conn->userdata = userdata; conn_prepare_reset(conn, auth_handle_component_open); /* FIXME: it could happen that the connect returns immediately as * successful, though this is pretty unlikely. This would be a little * hard to fix, since we'd have to detect and fire off the callback * from within the event loop */ conn->state = XMPP_STATE_CONNECTING; conn->timeout_stamp = time_stamp(); xmpp_debug(conn->ctx, "xmpp", "attempting to connect to %s", server); return 0; }
/** Initiate a component connection to server. * This function returns immediately after starting the connection * process to the XMPP server, and notifications of connection state changes * will be sent to the internal callback function that will set up handler * for the component handshake as defined in XEP-0114. * The domain and port to connect to must be provided in this case as the JID * provided to the call serves as component identifier to the server and is * not subject to DNS resolution. * * @param conn a Strophe connection object * @param server a string with domain to use directly as the domain can't be * extracted from the component name/JID. If this is not set, the call * will fail. * @param port an integer port number to use to connect to server expecting * an external component. If this is 0, the port 5347 will be assumed. * @param callback a xmpp_conn_handler callback function that will receive * notifications of connection status * @param userdata an opaque data pointer that will be passed to the callback * * @return XMPP_EOK (0) on success or a number less than 0 on failure * * @ingroup Connections */ int xmpp_connect_component(xmpp_conn_t * const conn, const char * const server, unsigned short port, xmpp_conn_handler callback, void * const userdata) { /* The server domain, jid and password MUST be specified. */ if (!(server && conn->jid && conn->pass)) return XMPP_EINVOP; /* XEP-0114 does not support TLS */ xmpp_conn_disable_tls(conn); if (!conn->tls_disabled) { xmpp_error(conn->ctx, "conn", "Failed to disable TLS. " "XEP-0114 does not support TLS"); return XMPP_EINT; } port = port ? port : _conn_default_port(conn, XMPP_COMPONENT); /* JID serves as an identifier here and will be used as "to" attribute of the stream */ return _conn_connect(conn, conn->jid, server, port, XMPP_COMPONENT, callback, userdata); }
/** Initiate a connection to the XMPP server. * This function returns immediately after starting the connection * process to the XMPP server, and notifiations of connection state changes * will be sent to the callback function. The domain and port to connect to * are usually determined by an SRV lookup for the xmpp-client service at * the domain specified in the JID. If SRV lookup fails, altdomain and * altport will be used instead if specified. * * @param conn a Strophe connection object * @param altdomain a string with domain to use if SRV lookup fails. If this * is NULL, the domain from the JID will be used. * @param altport an integer port number to use if SRV lookup fails. If this * is 0, the default port will be assumed. * @param callback a xmpp_conn_handler callback function that will receive * notifications of connection status * @param userdata an opaque data pointer that will be passed to the callback * * @return 0 on success and -1 on an error * * @ingroup Connections */ int xmpp_connect_client(xmpp_conn_t * const conn, const char * const altdomain, unsigned short altport, xmpp_conn_handler callback, void * const userdata) { char domain[2048]; int port; const char *prefdomain = NULL; int found; if (conn->state != XMPP_STATE_DISCONNECTED) return -1; if (conn->domain != NULL) xmpp_free(conn->ctx, conn->domain); conn->type = XMPP_CLIENT; conn->secured = 0; conn->tls_failed = 0; conn->domain = xmpp_jid_domain(conn->ctx, conn->jid); if (!conn->domain) return -1; if (altdomain != NULL) { xmpp_debug(conn->ctx, "xmpp", "Connecting via altdomain."); prefdomain = altdomain; port = altport ? altport : _conn_default_port(conn); } else { found = sock_srv_lookup("xmpp-client", "tcp", conn->domain, domain, sizeof(domain), &port); if (!found) { xmpp_debug(conn->ctx, "xmpp", "SRV lookup failed, " "connecting via domain."); prefdomain = conn->domain; port = altport ? altport : _conn_default_port(conn); } if (conn->tls_legacy_ssl) { /* SSL tunneled connection on 5223 port is legacy and doesn't * have an SRV record. Force port 5223 here unless altport is * specified. */ port = altport ? altport : XMPP_PORT_CLIENT_LEGACY_SSL; } } if (prefdomain != NULL) { strncpy(domain, prefdomain, sizeof(domain)); domain[sizeof(domain) - 1] = '\0'; } conn->sock = sock_connect(domain, port); xmpp_debug(conn->ctx, "xmpp", "sock_connect to %s:%d returned %d", domain, port, conn->sock); if (conn->sock == -1) return -1; /* setup handler */ conn->conn_handler = callback; conn->userdata = userdata; /* FIXME: it could happen that the connect returns immediately as * successful, though this is pretty unlikely. This would be a little * hard to fix, since we'd have to detect and fire off the callback * from within the event loop */ conn->state = XMPP_STATE_CONNECTING; conn->timeout_stamp = time_stamp(); xmpp_debug(conn->ctx, "xmpp", "attempting to connect to %s", domain); return 0; }