conn: refactore connect functions
Common code is moved to a separated function.
This commit is contained in:
@@ -131,6 +131,8 @@ struct _xmpp_handlist_t {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAX_DOMAIN_LEN 256
|
||||||
|
|
||||||
#define SASL_MASK_PLAIN 0x01
|
#define SASL_MASK_PLAIN 0x01
|
||||||
#define SASL_MASK_DIGESTMD5 0x02
|
#define SASL_MASK_DIGESTMD5 0x02
|
||||||
#define SASL_MASK_ANONYMOUS 0x04
|
#define SASL_MASK_ANONYMOUS 0x04
|
||||||
|
|||||||
194
src/conn.c
194
src/conn.c
@@ -57,7 +57,15 @@ static void _handle_stream_end(char *name,
|
|||||||
void * const userdata);
|
void * const userdata);
|
||||||
static void _handle_stream_stanza(xmpp_stanza_t *stanza,
|
static void _handle_stream_stanza(xmpp_stanza_t *stanza,
|
||||||
void * const userdata);
|
void * const userdata);
|
||||||
static unsigned short _conn_default_port(xmpp_conn_t * const conn);
|
static unsigned short _conn_default_port(xmpp_conn_t * const conn,
|
||||||
|
xmpp_conn_type_t type);
|
||||||
|
static int _conn_connect(xmpp_conn_t * const conn,
|
||||||
|
const char * const domain,
|
||||||
|
const char * const host,
|
||||||
|
unsigned short port,
|
||||||
|
xmpp_conn_type_t type,
|
||||||
|
xmpp_conn_handler callback,
|
||||||
|
void * const userdata);
|
||||||
|
|
||||||
/** Create a new Strophe connection object.
|
/** Create a new Strophe connection object.
|
||||||
*
|
*
|
||||||
@@ -124,7 +132,6 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx)
|
|||||||
_handle_stream_stanza,
|
_handle_stream_stanza,
|
||||||
conn);
|
conn);
|
||||||
conn->reset_parser = 0;
|
conn->reset_parser = 0;
|
||||||
conn_prepare_reset(conn, auth_handle_open);
|
|
||||||
|
|
||||||
conn->authenticated = 0;
|
conn->authenticated = 0;
|
||||||
conn->conn_handler = NULL;
|
conn->conn_handler = NULL;
|
||||||
@@ -433,66 +440,45 @@ int xmpp_connect_client(xmpp_conn_t * const conn,
|
|||||||
xmpp_conn_handler callback,
|
xmpp_conn_handler callback,
|
||||||
void * const userdata)
|
void * const userdata)
|
||||||
{
|
{
|
||||||
char domain[2048];
|
char *buf = NULL;
|
||||||
|
char *domain;
|
||||||
|
const char *host;
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
const char *prefdomain = NULL;
|
int found = 0;
|
||||||
int found;
|
int rc;
|
||||||
|
|
||||||
if (conn->state != XMPP_STATE_DISCONNECTED)
|
domain = xmpp_jid_domain(conn->ctx, conn->jid);
|
||||||
return -1;
|
if (!domain) 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) {
|
if (altdomain != NULL) {
|
||||||
xmpp_debug(conn->ctx, "xmpp", "Connecting via altdomain.");
|
xmpp_debug(conn->ctx, "xmpp", "Connecting via altdomain.");
|
||||||
prefdomain = altdomain;
|
host = altdomain;
|
||||||
port = altport ? altport : _conn_default_port(conn);
|
port = altport ? altport : _conn_default_port(conn, XMPP_CLIENT);
|
||||||
} else {
|
found = 1;
|
||||||
found = resolver_srv_lookup("xmpp-client", "tcp", conn->domain,
|
|
||||||
domain, sizeof(domain), &port);
|
/* SSL tunneled connection on 5223 port is legacy and doesn't
|
||||||
if (!found) {
|
* have an SRV record. */
|
||||||
xmpp_debug(conn->ctx, "xmpp", "SRV lookup failed, "
|
} else if (!conn->tls_legacy_ssl) {
|
||||||
"connecting via domain.");
|
host = buf = xmpp_alloc(conn->ctx, MAX_DOMAIN_LEN);
|
||||||
prefdomain = conn->domain;
|
if (buf != NULL) {
|
||||||
port = altport ? altport : _conn_default_port(conn);
|
found = resolver_srv_lookup("xmpp-client", "tcp", domain,
|
||||||
}
|
buf, MAX_DOMAIN_LEN, &port);
|
||||||
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));
|
if (!found) {
|
||||||
domain[sizeof(domain) - 1] = '\0';
|
xmpp_debug(conn->ctx, "xmpp", "SRV lookup failed, "
|
||||||
|
"connecting via domain.");
|
||||||
|
host = domain;
|
||||||
|
port = altport ? altport : _conn_default_port(conn, XMPP_CLIENT);
|
||||||
}
|
}
|
||||||
conn->sock = sock_connect(domain, port);
|
|
||||||
xmpp_debug(conn->ctx, "xmpp", "sock_connect to %s:%u returned %d",
|
|
||||||
domain, port, conn->sock);
|
|
||||||
if (conn->sock == -1) return -1;
|
|
||||||
|
|
||||||
/* setup handler */
|
rc = _conn_connect(conn, domain, host, port, XMPP_CLIENT,
|
||||||
conn->conn_handler = callback;
|
callback, userdata);
|
||||||
conn->userdata = userdata;
|
xmpp_free(conn->ctx, domain);
|
||||||
|
if (buf) xmpp_free(conn->ctx, buf);
|
||||||
|
|
||||||
/* FIXME: it could happen that the connect returns immediately as
|
return rc;
|
||||||
* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Initiate a component connection to server.
|
/** Initiate a component connection to server.
|
||||||
@@ -522,50 +508,22 @@ int xmpp_connect_component(xmpp_conn_t * const conn, const char * const server,
|
|||||||
unsigned short port, xmpp_conn_handler callback,
|
unsigned short port, xmpp_conn_handler callback,
|
||||||
void * const userdata)
|
void * const userdata)
|
||||||
{
|
{
|
||||||
unsigned short 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. */
|
/* The server domain, jid and password MUST be specified. */
|
||||||
if (!(server && conn->jid && conn->pass)) return -1;
|
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:%u returned %d",
|
|
||||||
server, connectport, conn->sock);
|
|
||||||
if (conn->sock == -1) return -1;
|
|
||||||
|
|
||||||
/* XEP-0114 does not support TLS */
|
/* XEP-0114 does not support TLS */
|
||||||
conn->tls_disabled = 1;
|
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 -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* setup handler */
|
port = port ? port : _conn_default_port(conn, XMPP_COMPONENT);
|
||||||
conn->conn_handler = callback;
|
/* JID serves as an identificator here and will be used as "to" attribute
|
||||||
conn->userdata = userdata;
|
of the stream */
|
||||||
|
return _conn_connect(conn, conn->jid, server, port, XMPP_COMPONENT,
|
||||||
conn_prepare_reset(conn, auth_handle_component_open);
|
callback, 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", server);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Cleanly disconnect the connection.
|
/** Cleanly disconnect the connection.
|
||||||
@@ -996,15 +954,63 @@ static void _handle_stream_stanza(xmpp_stanza_t *stanza,
|
|||||||
handler_fire_stanza(conn, stanza);
|
handler_fire_stanza(conn, stanza);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned short _conn_default_port(xmpp_conn_t * const conn)
|
static unsigned short _conn_default_port(xmpp_conn_t * const conn,
|
||||||
|
xmpp_conn_type_t type)
|
||||||
{
|
{
|
||||||
switch (conn->type) {
|
switch (type) {
|
||||||
case XMPP_CLIENT:
|
case XMPP_CLIENT:
|
||||||
return conn->tls_legacy_ssl ? XMPP_PORT_CLIENT_LEGACY_SSL :
|
return conn->tls_legacy_ssl ? XMPP_PORT_CLIENT_LEGACY_SSL :
|
||||||
XMPP_PORT_CLIENT;
|
XMPP_PORT_CLIENT;
|
||||||
case XMPP_COMPONENT:
|
case XMPP_COMPONENT:
|
||||||
return XMPP_PORT_COMPONENT;
|
return XMPP_PORT_COMPONENT;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _conn_connect(xmpp_conn_t * const conn,
|
||||||
|
const char * const domain,
|
||||||
|
const char * const host,
|
||||||
|
unsigned short port,
|
||||||
|
xmpp_conn_type_t type,
|
||||||
|
xmpp_conn_handler callback,
|
||||||
|
void * const userdata)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (conn->state != XMPP_STATE_DISCONNECTED) return -1;
|
||||||
|
if (type != XMPP_CLIENT && type != XMPP_COMPONENT) return -1;
|
||||||
|
/* conn->stream_error must be released in order to support reconnect. */
|
||||||
|
if (conn->type != XMPP_UNKNOWN) return -1;
|
||||||
|
if (conn->domain != NULL)
|
||||||
|
xmpp_free(conn->ctx, conn->domain);
|
||||||
|
|
||||||
|
conn->type = type;
|
||||||
|
conn->secured = 0;
|
||||||
|
conn->tls_failed = 0;
|
||||||
|
conn->error = 0;
|
||||||
|
conn->domain = xmpp_strdup(conn->ctx, domain);
|
||||||
|
if (!conn->domain) return -1;
|
||||||
|
|
||||||
|
conn->sock = sock_connect(host, port);
|
||||||
|
xmpp_debug(conn->ctx, "xmpp", "sock_connect() to %s:%u returned %d",
|
||||||
|
host, port, conn->sock);
|
||||||
|
if (conn->sock == -1) return -1;
|
||||||
|
|
||||||
|
/* setup handler */
|
||||||
|
conn->conn_handler = callback;
|
||||||
|
conn->userdata = userdata;
|
||||||
|
|
||||||
|
conn_prepare_reset(conn, type == XMPP_CLIENT ? auth_handle_open :
|
||||||
|
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", host);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user