From f53cb7886439619860ff86451318a5a04fc49322 Mon Sep 17 00:00:00 2001 From: defanor Date: Sat, 15 Apr 2023 19:23:12 +0300 Subject: Add a path MTU discovery setting for TCP sockets --- src/rexmpp.c | 1 + src/rexmpp.h | 2 ++ src/rexmpp_tcp.c | 32 +++++++++++++++++++------------- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/rexmpp.c b/src/rexmpp.c index d7e1364..e494a14 100644 --- a/src/rexmpp.c +++ b/src/rexmpp.c @@ -555,6 +555,7 @@ rexmpp_err_t rexmpp_init (rexmpp_t *s, s->client_version = PACKAGE_VERSION; s->local_address = NULL; s->jingle_prefer_rtcp_mux = 1; + s->path_mtu_discovery = -1; s->send_buffer = NULL; s->send_queue = NULL; s->server_srv = NULL; diff --git a/src/rexmpp.h b/src/rexmpp.h index c6d4428..71edacb 100644 --- a/src/rexmpp.h +++ b/src/rexmpp.h @@ -278,6 +278,8 @@ struct rexmpp const char *client_version; /* XEP-0092 */ const char *local_address; /* For ICE, XEP-0176 */ int jingle_prefer_rtcp_mux; + int path_mtu_discovery; /* An IP_MTU_DISCOVER parameter for + TCP sockets, or -1 to not set it */ /* Resource limits. */ uint32_t stanza_queue_size; diff --git a/src/rexmpp_tcp.c b/src/rexmpp_tcp.c index 77509b2..a248fec 100644 --- a/src/rexmpp_tcp.c +++ b/src/rexmpp_tcp.c @@ -99,6 +99,22 @@ rexmpp_tcp_connected (rexmpp_tcp_conn_t *conn, int fd) { return REXMPP_CONN_DONE; } +int rexmpp_tcp_socket(rexmpp_t *s, int domain) { + int sock = socket(domain, SOCK_STREAM, 0); + + /* Make it non-blocking */ + int flags = fcntl(sock, F_GETFL, 0); + fcntl(sock, F_SETFL, flags | O_NONBLOCK); + + /* Set path MTU discovery, if provided */ + if (s->path_mtu_discovery != -1) { + setsockopt(sock, SOL_IP, IP_MTU_DISCOVER, &(s->path_mtu_discovery), + sizeof(s->path_mtu_discovery)); + } + + return sock; +} + rexmpp_tcp_conn_error_t rexmpp_tcp_conn_init (rexmpp_t *s, rexmpp_tcp_conn_t *conn, @@ -122,14 +138,10 @@ rexmpp_tcp_conn_init (rexmpp_t *s, conn->resolution_v6 = REXMPP_CONN_RESOLUTION_INACTIVE; struct sockaddr_in addr_v4; - int flags; if (inet_pton(AF_INET, host, &(addr_v4.sin_addr))) { addr_v4.sin_family = AF_INET; addr_v4.sin_port = htons(port); - conn->sockets[conn->connection_attempts] = - socket(AF_INET, SOCK_STREAM, 0); - flags = fcntl(conn->sockets[conn->connection_attempts], F_GETFL, 0); - fcntl(conn->sockets[conn->connection_attempts], F_SETFL, flags | O_NONBLOCK); + conn->sockets[conn->connection_attempts] = rexmpp_tcp_socket(s, AF_INET); if (connect(conn->sockets[conn->connection_attempts], (struct sockaddr*)&addr_v4, sizeof(addr_v4))) { @@ -149,10 +161,7 @@ rexmpp_tcp_conn_init (rexmpp_t *s, addr_v6.sin6_port = htons(port); addr_v6.sin6_flowinfo = 0; addr_v6.sin6_scope_id = 0; - conn->sockets[conn->connection_attempts] = - socket(AF_INET6, SOCK_STREAM, 0); - flags = fcntl(conn->sockets[conn->connection_attempts], F_GETFL, 0); - fcntl(conn->sockets[conn->connection_attempts], F_SETFL, flags | O_NONBLOCK); + conn->sockets[conn->connection_attempts] = rexmpp_tcp_socket(s, AF_INET6); if (connect(conn->sockets[conn->connection_attempts], (struct sockaddr*)&addr_v6, sizeof(addr_v6))) { @@ -295,10 +304,7 @@ rexmpp_tcp_conn_proceed (rexmpp_t *s, addrlen = sizeof(addr_v4); } - conn->sockets[conn->connection_attempts] = - socket(domain, SOCK_STREAM, 0); - int flags = fcntl(conn->sockets[conn->connection_attempts], F_GETFL, 0); - fcntl(conn->sockets[conn->connection_attempts], F_SETFL, flags | O_NONBLOCK); + conn->sockets[conn->connection_attempts] = rexmpp_tcp_socket(s, domain); if (connect(conn->sockets[conn->connection_attempts], addr, addrlen)) { if (errno == EINPROGRESS) { gettimeofday(&(conn->next_connection_time), NULL); -- cgit v1.2.3