Skip to content

Commit f0ef433

Browse files
committed
Make DNS operations non-blocking when using c-ares
Previously the connection and reconnection process would block the event loop waiting on DNS results. Without c-ares this is still the case here, but when c-ares is used this is now a non-blocking operation which progresses during normal xmpp_run_once calls along with everything else in the system.
1 parent f8cda0f commit f0ef433

File tree

6 files changed

+258
-178
lines changed

6 files changed

+258
-178
lines changed

src/conn.c

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,11 @@ static void _conn_sm_handle_stanza(xmpp_conn_t *const conn,
103103
static unsigned short _conn_default_port(xmpp_conn_t *conn,
104104
xmpp_conn_type_t type);
105105
static void _conn_reset(xmpp_conn_t *conn);
106-
static int _conn_connect(xmpp_conn_t *conn,
107-
const char *domain,
108-
xmpp_conn_type_t type,
109-
xmpp_conn_handler callback,
110-
void *userdata);
106+
static int _conn_preconnect(xmpp_conn_t *conn,
107+
char *domain,
108+
xmpp_conn_type_t type,
109+
xmpp_conn_handler callback,
110+
void *userdata);
111111
static void _send_valist(xmpp_conn_t *conn,
112112
const char *fmt,
113113
va_list ap,
@@ -709,14 +709,13 @@ int xmpp_connect_client(xmpp_conn_t *conn,
709709

710710
if (conn->xsock)
711711
sock_free(conn->xsock);
712-
conn->xsock = sock_new(conn, domain, altdomain, altport);
713-
if (!conn->xsock)
714-
goto err_mem;
715712

716-
rc = _conn_connect(conn, domain, XMPP_CLIENT, callback, userdata);
717-
strophe_free(conn->ctx, domain);
713+
/* domain ownership transfers to conn */
714+
if ((rc = _conn_preconnect(conn, domain, XMPP_CLIENT, callback, userdata))) {
715+
return rc;
716+
}
718717

719-
return rc;
718+
return sock_new(conn, domain, altdomain, altport);
720719

721720
err_mem:
722721
strophe_free(conn->ctx, domain);
@@ -752,6 +751,7 @@ int xmpp_connect_component(xmpp_conn_t *conn,
752751
xmpp_conn_handler callback,
753752
void *userdata)
754753
{
754+
int rc;
755755
/* The server domain, jid and password MUST be specified. */
756756
if (!(server && conn->jid && conn->pass))
757757
return XMPP_EINVOP;
@@ -769,13 +769,14 @@ int xmpp_connect_component(xmpp_conn_t *conn,
769769
port = port ? port : _conn_default_port(conn, XMPP_COMPONENT);
770770
if (conn->xsock)
771771
sock_free(conn->xsock);
772-
conn->xsock = sock_new(conn, NULL, server, port);
773-
if (!conn->xsock)
774-
return XMPP_EMEM;
775772

776773
/* JID serves as an identifier here and will be used as "to" attribute
777774
of the stream */
778-
return _conn_connect(conn, conn->jid, XMPP_COMPONENT, callback, userdata);
775+
if ((rc = _conn_preconnect(conn, strophe_strdup(conn->ctx, conn->jid), XMPP_COMPONENT, callback, userdata))) {
776+
return rc;
777+
}
778+
779+
return sock_new(conn, NULL, server, port);
779780
}
780781

781782
/** Initiate a raw connection to the XMPP server.
@@ -2170,11 +2171,11 @@ static void _conn_reset(xmpp_conn_t *conn)
21702171
handler_system_delete_all(conn);
21712172
}
21722173

2173-
static int _conn_connect(xmpp_conn_t *conn,
2174-
const char *domain,
2175-
xmpp_conn_type_t type,
2176-
xmpp_conn_handler callback,
2177-
void *userdata)
2174+
static int _conn_preconnect(xmpp_conn_t *conn,
2175+
char *domain,
2176+
xmpp_conn_type_t type,
2177+
xmpp_conn_handler callback,
2178+
void *userdata)
21782179
{
21792180
xmpp_open_handler open_handler;
21802181

@@ -2186,14 +2187,10 @@ static int _conn_connect(xmpp_conn_t *conn,
21862187
_conn_reset(conn);
21872188

21882189
conn->type = type;
2189-
conn->domain = strophe_strdup(conn->ctx, domain);
2190+
conn->domain = domain;
21902191
if (!conn->domain)
21912192
return XMPP_EMEM;
21922193

2193-
conn->sock = sock_connect(conn->xsock);
2194-
if (conn->sock == INVALID_SOCKET)
2195-
return XMPP_EINT;
2196-
21972194
/* setup handler */
21982195
conn->conn_handler = callback;
21992196
conn->userdata = userdata;

src/event.c

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -57,22 +57,19 @@
5757
#include "strophe.h"
5858
#include "common.h"
5959
#include "parser.h"
60+
#include "resolver.h"
6061

6162
#ifndef STROPHE_MESSAGE_BUFFER_SIZE
6263
/** Max buffer size for receiving messages. */
6364
#define STROPHE_MESSAGE_BUFFER_SIZE 4096
6465
#endif
6566

66-
static int _connect_next(xmpp_conn_t *conn)
67+
static void _connect_next(xmpp_conn_t *conn)
6768
{
6869
sock_close(conn->sock);
69-
conn->sock = sock_connect(conn->xsock);
70-
if (conn->sock == INVALID_SOCKET)
71-
return -1;
72-
70+
conn->sock = INVALID_SOCKET;
7371
conn->timeout_stamp = time_stamp();
74-
75-
return 0;
72+
sock_connect(conn->xsock);
7673
}
7774

7875
/** Run the event loop once.
@@ -224,13 +221,8 @@ void xmpp_run_once(xmpp_ctx_t *ctx, unsigned long timeout)
224221
FD_SET(conn->sock, &wfds);
225222
else {
226223
strophe_info(ctx, "xmpp", "Connection attempt timed out.");
227-
ret = _connect_next(conn);
228-
if (ret != 0) {
229-
conn->error = ETIMEDOUT;
230-
conn_disconnect(conn);
231-
} else {
232-
FD_SET(conn->sock, &wfds);
233-
}
224+
_connect_next(conn);
225+
if (conn->sock != INVALID_SOCKET) FD_SET(conn->sock, &wfds);
234226
}
235227
break;
236228
case XMPP_STATE_CONNECTED:
@@ -254,6 +246,13 @@ void xmpp_run_once(xmpp_ctx_t *ctx, unsigned long timeout)
254246
connitem = connitem->next;
255247
}
256248

249+
#ifdef HAVE_CARES
250+
if (ares_chan) {
251+
ares_fds(ares_chan, &rfds, &wfds);
252+
ares_timeout(ares_chan, &tv, &tv);
253+
}
254+
#endif
255+
257256
/* check for events */
258257
if (max > 0)
259258
ret = select(max + 1, &rfds, &wfds, NULL, &tv);
@@ -275,6 +274,10 @@ void xmpp_run_once(xmpp_ctx_t *ctx, unsigned long timeout)
275274
if (ret == 0 && tls_read_bytes == 0)
276275
return;
277276

277+
#ifdef HAVE_CARES
278+
if (ares_chan) ares_process(ares_chan, &rfds, &wfds);
279+
#endif
280+
278281
/* process events */
279282
connitem = ctx->connlist;
280283
while (connitem) {
@@ -292,11 +295,7 @@ void xmpp_run_once(xmpp_ctx_t *ctx, unsigned long timeout)
292295
/* connection failed */
293296
strophe_debug(ctx, "xmpp", "connection failed, error %d",
294297
ret);
295-
ret = _connect_next(conn);
296-
if (ret != 0) {
297-
conn->error = ret;
298-
conn_disconnect(conn);
299-
}
298+
_connect_next(conn);
300299
break;
301300
}
302301

0 commit comments

Comments
 (0)