summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordefanor <defanor@uberspace.net>2023-04-15 19:23:12 +0300
committerdefanor <defanor@uberspace.net>2023-04-15 21:00:03 +0300
commitf53cb7886439619860ff86451318a5a04fc49322 (patch)
treecccc26f72cd0a69eaede0e71c4008076422bcea3
parentecc91dd9f2fe31b28e4a9027502eaf07c757594d (diff)
Add a path MTU discovery setting for TCP sockets
-rw-r--r--src/rexmpp.c1
-rw-r--r--src/rexmpp.h2
-rw-r--r--src/rexmpp_tcp.c32
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);