WIP add xsock

This commit is contained in:
Dmitry Podgorny
2019-10-30 23:29:56 +02:00
parent 484e971323
commit 87d40d23db
5 changed files with 85 additions and 12 deletions

View File

@@ -160,6 +160,7 @@ struct _xmpp_conn_t {
xmpp_stream_error_t *stream_error;
sock_t sock;
xmpp_sock_t *xsock;
int ka_timeout; /* TCP keepalive timeout */
int ka_interval; /* TCP keepalive interval */

View File

@@ -689,7 +689,8 @@ void conn_disconnect(xmpp_conn_t * const conn)
tls_free(conn->tls);
conn->tls = NULL;
}
sock_close(conn->sock);
if (conn->sock >= 0)
sock_close(conn->sock);
/* fire off connection handler */
conn->conn_handler(conn, XMPP_CONN_DISCONNECT, conn->error,
@@ -1263,7 +1264,8 @@ static int _conn_connect(xmpp_conn_t * const conn,
conn->domain = xmpp_strdup(conn->ctx, domain);
if (!conn->domain) return XMPP_EMEM;
conn->sock = sock_connect(host, port);
conn->xsock = sock_new(conn->ctx, host, port);
conn->sock = sock_connect(conn->xsock);
xmpp_debug(conn->ctx, "xmpp", "sock_connect() to %s:%u returned %d",
host, port, conn->sock);
if (conn->sock == -1) return XMPP_EINT;

View File

@@ -51,6 +51,18 @@
#include "common.h"
#include "parser.h"
static int _connect_next(xmpp_conn_t *conn)
{
sock_close(conn->sock);
conn->sock = sock_connect(conn->xsock);
if (conn->sock < 0)
return -1;
conn->timeout_stamp = time_stamp();
return 0;
}
/** Run the event loop once.
* This function will run send any data that has been queued by
* xmpp_send and related functions and run through the Strophe even
@@ -180,6 +192,11 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout)
conn->connect_timeout)
FD_SET(conn->sock, &wfds);
else {
ret = _connect_next(conn);
if (ret == 0) {
FD_SET(conn->sock, &wfds);
break;
}
conn->error = ETIMEDOUT;
xmpp_info(ctx, "xmpp", "Connection attempt timed out.");
conn_disconnect(conn);
@@ -238,6 +255,11 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout)
/* check for error */
ret = sock_connect_error(conn->sock);
if (ret != 0) {
ret = _connect_next(conn);
if (ret == 0)
break;
}
if (ret != 0) {
/* connection failed */
xmpp_debug(ctx, "xmpp", "connection failed, error %d", ret);

View File

@@ -33,9 +33,17 @@
#include <fcntl.h>
#endif
#include "common.h"
#include "sock.h"
#include "snprintf.h"
struct _xmpp_sock_t {
xmpp_ctx_t *ctx;
struct addrinfo *ainfo_list;
struct addrinfo *current;
sock_t sock;
};
void sock_initialize(void)
{
#ifdef _WIN32
@@ -69,13 +77,23 @@ static int _in_progress(int error)
#endif
}
sock_t sock_connect(const char * const host, const unsigned short port)
xmpp_sock_t *sock_new(xmpp_ctx_t *ctx, const char *host, unsigned short port)
{
sock_t sock;
xmpp_sock_t *xsock;
char service[6];
struct addrinfo *res, *ainfo, hints;
struct addrinfo hints;
int err;
xsock = xmpp_alloc(ctx, sizeof *xsock);
if (xsock == NULL) {
xmpp_error(ctx, "sock", "Memory allocation error.");
return NULL;
}
xsock->ctx = ctx;
xsock->ainfo_list = NULL;
xsock->current = NULL;
xsock->sock = -1;
xmpp_snprintf(service, 6, "%u", port);
memset(&hints, 0, sizeof(struct addrinfo));
@@ -86,11 +104,33 @@ sock_t sock_connect(const char * const host, const unsigned short port)
hints.ai_protocol = IPPROTO_TCP;
hints.ai_socktype = SOCK_STREAM;
err = getaddrinfo(host, service, &hints, &res);
if (err != 0)
return -1;
err = getaddrinfo(host, service, &hints, &xsock->ainfo_list);
if (err != 0) {
xmpp_free(ctx, xsock);
xsock = NULL;
}
return xsock;
}
for (ainfo = res; ainfo != NULL; ainfo = ainfo->ai_next) {
void sock_free(xmpp_sock_t *xsock)
{
if (xsock->ainfo_list != NULL)
freeaddrinfo(xsock->ainfo_list);
xmpp_free(xsock->ctx, xsock);
}
sock_t sock_connect(xmpp_sock_t *xsock)
{
struct addrinfo *ainfo;
sock_t sock = -1;
int err;
if (xsock->current == NULL)
ainfo = xsock->ainfo_list;
else
ainfo = xsock->current->ai_next;
for (; ainfo != NULL; ainfo = ainfo->ai_next) {
sock = socket(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol);
if (sock < 0)
continue;
@@ -103,9 +143,13 @@ sock_t sock_connect(const char * const host, const unsigned short port)
}
sock_close(sock);
}
freeaddrinfo(res);
sock = ainfo == NULL ? -1 : sock;
xsock->sock = sock;
xsock->current = ainfo;
if (ainfo == NULL) {
freeaddrinfo(xsock->ainfo_list);
xsock->ainfo_list = NULL;
}
return sock;
}

View File

@@ -25,12 +25,16 @@ typedef int sock_t;
typedef SOCKET sock_t;
#endif
typedef struct _xmpp_sock_t xmpp_sock_t;
void sock_initialize(void);
void sock_shutdown(void);
int sock_error(void);
sock_t sock_connect(const char * const host, const unsigned short port);
xmpp_sock_t *sock_new(xmpp_ctx_t *ctx, const char *host, unsigned short port);
void sock_free(xmpp_sock_t *xsock);
sock_t sock_connect(xmpp_sock_t *xsock);
int sock_close(const sock_t sock);
int sock_set_blocking(const sock_t sock);