Ejemplo n.º 1
0
/** 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;
}
Ejemplo n.º 2
0
/** 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;
}
Ejemplo n.º 3
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);
}
Ejemplo n.º 4
0
/** 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;
}