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 77d5b78..c821a88 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 e41e78b..d23e45e 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,
        );