From 2ef432f63220599a143eb5ab12a9fec916fcc4b5 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Tue, 26 Apr 2016 19:48:34 +0000 Subject: [PATCH] conn: xmpp_conn_set_keepalive() stores parameters in conn Store keepalive parameters in conn object. This allows call the function with a disconnected conn. Also, the parameters are not cleared on reconnect and applied once a socket is created. --- examples/basic.c | 11 ++++++++++- src/common.h | 7 +++++-- src/conn.c | 23 ++++++++++++++--------- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/examples/basic.c b/examples/basic.c index 652d860..4da61f1 100644 --- a/examples/basic.c +++ b/examples/basic.c @@ -14,6 +14,9 @@ #include +/* hardcoded TCP keepalive timeout and interval */ +#define KA_TIMEOUT 60 +#define KA_INTERVAL 1 /* define a handler for connection events */ void conn_handler(xmpp_conn_t * const conn, const xmpp_conn_event_t status, @@ -43,6 +46,7 @@ int main(int argc, char **argv) xmpp_log_t *log; char *jid, *pass, *host = NULL; long flags = 0; + int tcp_keepalive = 0; int i; /* take a jid and password on the command line */ @@ -53,6 +57,8 @@ int main(int argc, char **argv) flags |= XMPP_CONN_FLAG_MANDATORY_TLS; else if (strcmp(argv[i], "--legacy-ssl") == 0) flags |= XMPP_CONN_FLAG_LEGACY_SSL; + else if (strcmp(argv[i], "--tcp-keepalive") == 0) + tcp_keepalive = 1; else break; } @@ -61,7 +67,8 @@ int main(int argc, char **argv) "Options:\n" " --disable-tls Disable TLS.\n" " --mandatory-tls Deny plaintext connection.\n" - " --legacy-ssl Use old style SSL.\n\n" + " --legacy-ssl Use old style SSL.\n" + " --tcp-keepalive Configure TCP keepalive.\n\n" "Note: --disable-tls conflicts with --mandatory-tls or " "--legacy-ssl\n"); return 1; @@ -89,6 +96,8 @@ int main(int argc, char **argv) /* configure connection properties (optional) */ xmpp_conn_set_flags(conn, flags); + /* configure TCP keepalive (optional) */ + if (tcp_keepalive) xmpp_conn_set_keepalive(conn, KA_TIMEOUT, KA_INTERVAL); /* setup authentication information */ xmpp_conn_set_jid(conn, jid); diff --git a/src/common.h b/src/common.h index 8d79215..48c3577 100644 --- a/src/common.h +++ b/src/common.h @@ -155,9 +155,12 @@ struct _xmpp_conn_t { uint64_t timeout_stamp; int error; xmpp_stream_error_t *stream_error; - sock_t sock; - tls_t *tls; + sock_t sock; + int ka_timeout; /* TCP keepalive timeout */ + int ka_interval; /* TCP keepalive interval */ + + tls_t *tls; int tls_support; int tls_disabled; int tls_mandatory; diff --git a/src/conn.c b/src/conn.c index b0a648d..5fe5e06 100644 --- a/src/conn.c +++ b/src/conn.c @@ -90,6 +90,8 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) conn->type = XMPP_UNKNOWN; conn->state = XMPP_STATE_DISCONNECTED; conn->sock = -1; + conn->ka_timeout = 0; + conn->ka_interval = 0; conn->tls = NULL; conn->timeout_stamp = 0; conn->error = 0; @@ -185,7 +187,9 @@ xmpp_conn_t *xmpp_conn_clone(xmpp_conn_t * const conn) /** Set TCP keepalive parameters * Turn on TCP keepalive and set timeout and interval. Zero timeout - * disables TCP keepalives. + * disables TCP keepalives. The parameters are applied immediately for + * a non disconnected object. Also, they are applied when the connection + * object connects successfully. * * @param conn a Strophe connection object * @param timeout TCP keepalive timeout in seconds @@ -195,14 +199,14 @@ xmpp_conn_t *xmpp_conn_clone(xmpp_conn_t * const conn) */ void xmpp_conn_set_keepalive(xmpp_conn_t * const conn, int timeout, int interval) { - int ret; + int ret = 0; + + conn->ka_timeout = timeout; + conn->ka_interval = interval; + + if (conn->state != XMPP_STATE_DISCONNECTED) + ret = sock_set_keepalive(conn->sock, timeout, interval); - if (conn->state == XMPP_STATE_DISCONNECTED) { - xmpp_error(conn->ctx, "xmpp", "Setting TCP keepalive impossible on" - "disconnected connection"); - return; - } - ret = sock_set_keepalive(conn->sock, timeout, interval); if (ret < 0) { xmpp_error(conn->ctx, "xmpp", "Setting TCP keepalive (%d,%d) error: %d", timeout, interval, sock_error()); @@ -1003,7 +1007,6 @@ static int _conn_connect(xmpp_conn_t * const conn, xmpp_conn_handler callback, void * const userdata) { - if (conn->state != XMPP_STATE_DISCONNECTED) return -1; if (type != XMPP_CLIENT && type != XMPP_COMPONENT) return -1; @@ -1017,6 +1020,8 @@ static int _conn_connect(xmpp_conn_t * const conn, xmpp_debug(conn->ctx, "xmpp", "sock_connect() to %s:%u returned %d", host, port, conn->sock); if (conn->sock == -1) return -1; + if (conn->ka_timeout || conn->ka_interval) + sock_set_keepalive(conn->sock, conn->ka_timeout, conn->ka_interval); /* setup handler */ conn->conn_handler = callback;