]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
ha: Double receive buffer size for HA messages and make it configurable
authorTobias Brunner <tobias@strongswan.org>
Wed, 14 Feb 2018 13:51:24 +0000 (14:51 +0100)
committerTobias Brunner <tobias@strongswan.org>
Wed, 14 Feb 2018 13:52:18 +0000 (14:52 +0100)
With IKEv1 we transmit both public DH factors (used to derive the initial
IV) besides the shared secret.  So these messages could get significantly
larger than 1024 bytes, depending on the DH group (modp2048 just about
fits into it).  The new default of 2048 bytes should be fine up to modp4096
and for larger groups the buffer size may be increased (an error is
logged should this happen).

conf/plugins/ha.opt
src/libcharon/plugins/ha/ha_socket.c

index 77d5b788805d94c9905170a02b5ed7d553681e2b..c821a880b89238565f1f6a9863261a72d13cf000 100644 (file)
@@ -2,6 +2,13 @@ charon.plugins.ha.autobalance = 0
        Interval in seconds to automatically balance handled segments between nodes.
        Set to 0 to disable.
 
+charon.plugin.ha.buflen = 2048
+       Buffer size for received HA messages.
+
+       Buffer size for received HA messages. For IKEv1 the public DH factors are
+       also transmitted so depending on the DH group the HA messages can get quite
+       big (the default should be fine up to _modp4096_).
+
 charon.plugins.ha.fifo_interface = yes
 
 charon.plugins.ha.heartbeat_delay = 1000
index e41e78bbf03f6ca46967f4c28b3a04e6a2ab7680..d23e45e0bcc00bdcbe5c033d8f4b37761814f69e 100644 (file)
@@ -1,6 +1,7 @@
 /*
+ * Copyright (C) 2018 Tobias Brunner
  * Copyright (C) 2008-2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -52,6 +53,11 @@ struct private_ha_socket_t {
         * remote host to receive/send to
         */
        host_t *remote;
+
+       /**
+        * Receive buffer size
+        */
+       u_int buflen;
 };
 
 /**
@@ -120,13 +126,26 @@ METHOD(ha_socket_t, pull, ha_message_t*,
        while (TRUE)
        {
                ha_message_t *message;
-               char buf[1024];
+               char buf[this->buflen];
+               struct iovec iov = {
+                       .iov_base = buf,
+                       .iov_len = this->buflen,
+               };
+               struct msghdr msg = {
+                       .msg_iov = &iov,
+                       .msg_iovlen = 1,
+               };
                bool oldstate;
                ssize_t len;
 
                oldstate = thread_cancelability(TRUE);
-               len = recv(this->fd, buf, sizeof(buf), 0);
+               len = recvmsg(this->fd, &msg, 0);
                thread_cancelability(oldstate);
+               if (msg.msg_flags & MSG_TRUNC)
+               {
+                       DBG1(DBG_CFG, "HA message exceeds receive buffer");
+                       continue;
+               }
                if (len <= 0)
                {
                        switch (errno)
@@ -208,6 +227,8 @@ ha_socket_t *ha_socket_create(char *local, char *remote)
                },
                .local = host_create_from_dns(local, 0, HA_PORT),
                .remote = host_create_from_dns(remote, 0, HA_PORT),
+               .buflen = lib->settings->get_int(lib->settings,
+                                                                                "%s.plugins.ha.buflen", 2048, lib->ns),
                .fd = -1,
        );