summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2015-11-02 21:01:26 +0100
committerYves-Alexis Perez <corsac@debian.org>2015-11-03 17:29:10 +0100
commita9533d350af941e9bdd656f349a1bbb07911a422 (patch)
tree45f1a35b8d86fbe9df56aad66417a6f0b76f52d8
parent4ed8e788242fc1ee94acea233636ae4839f4ceeb (diff)
downloadvyos-strongswan-a9533d350af941e9bdd656f349a1bbb07911a422.tar.gz
vyos-strongswan-a9533d350af941e9bdd656f349a1bbb07911a422.zip
Add patch to fix IPv6 source adress selection
0001-socket-default-Refactor-setting-source-address-when- added (taken from ab8337b in the socket-default-refactor branch), fix source address selection with IPv6
-rw-r--r--debian/changelog4
-rw-r--r--debian/patches/0001-socket-default-Refactor-setting-source-address-when-.patch199
-rw-r--r--debian/patches/series1
3 files changed, 204 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog
index 7c47e0980..29758e6ea 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -9,6 +9,10 @@ strongswan (5.3.3-1) UNRELEASED; urgency=medium
* New upstream release. closes: #803772
* debian/strongswan-starter.install:
- install new pki --dn manpage to ipsec-starter package.
+ * debian/patches:
+ - 0001-socket-default-Refactor-setting-source-address-when- added (taken
+ from ab8337b in the socket-default-refactor branch), fix source address
+ selection with IPv6
-- Yves-Alexis Perez <corsac@debian.org> Thu, 22 Oct 2015 11:44:21 +0200
diff --git a/debian/patches/0001-socket-default-Refactor-setting-source-address-when-.patch b/debian/patches/0001-socket-default-Refactor-setting-source-address-when-.patch
new file mode 100644
index 000000000..4bb774fd0
--- /dev/null
+++ b/debian/patches/0001-socket-default-Refactor-setting-source-address-when-.patch
@@ -0,0 +1,199 @@
+From ab8337b3e8e5d4b8650b7d03b7193c7e734554f0 Mon Sep 17 00:00:00 2001
+From: Tobias Brunner <tobias@strongswan.org>
+Date: Mon, 2 Nov 2015 16:22:38 +0100
+Subject: [PATCH] socket-default: Refactor setting source address when sending
+ messages
+
+This ensures we don't pass data (via msg_control) defined in a different
+scope to sendmsg() and also makes the code clearer than with the interleaving
+ifdefs.
+---
+ .../plugins/socket_default/socket_default_socket.c | 153 ++++++++++++++-------
+ 1 file changed, 107 insertions(+), 46 deletions(-)
+
+diff --git a/src/libcharon/plugins/socket_default/socket_default_socket.c b/src/libcharon/plugins/socket_default/socket_default_socket.c
+index 5585377..c9a2d51 100644
+--- a/src/libcharon/plugins/socket_default/socket_default_socket.c
++++ b/src/libcharon/plugins/socket_default/socket_default_socket.c
+@@ -355,6 +355,107 @@ METHOD(socket_t, receiver, status_t,
+ return SUCCESS;
+ }
+
++/**
++ * Generic function to send a message.
++ */
++static ssize_t send_msg_generic(int skt, struct msghdr *msg)
++{
++ return sendmsg(skt, msg, 0);
++}
++
++/**
++ * Send a message with the IPv4 source address set, if possible.
++ */
++#ifdef IP_PKTINFO
++
++static ssize_t send_msg_v4(int skt, struct msghdr *msg, host_t *src)
++{
++ char buf[CMSG_SPACE(sizeof(struct in_pktinfo))] = {};
++ struct cmsghdr *cmsg;
++ struct in_addr *addr;
++ struct in_pktinfo *pktinfo;
++ struct sockaddr_in *sin;
++
++ msg->msg_control = buf;
++ msg->msg_controllen = sizeof(buf);
++ cmsg = CMSG_FIRSTHDR(msg);
++ cmsg->cmsg_level = SOL_IP;
++ cmsg->cmsg_type = IP_PKTINFO;
++ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
++
++ pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg);
++ addr = &pktinfo->ipi_spec_dst;
++
++ sin = (struct sockaddr_in*)src->get_sockaddr(src);
++ memcpy(addr, &sin->sin_addr, sizeof(struct in_addr));
++ return send_msg_generic(skt, msg);
++}
++
++#elif defined(IP_SENDSRCADDR)
++
++static ssize_t send_msg_v4(int skt, struct msghdr *msg, host_t *src)
++{
++ char buf[CMSG_SPACE(sizeof(struct in_addr))] = {};
++ struct cmsghdr *cmsg;
++ struct in_addr *addr;
++ struct sockaddr_in *sin;
++
++ msg->msg_control = buf;
++ msg->msg_controllen = sizeof(buf);
++ cmsg = CMSG_FIRSTHDR(msg);
++ cmsg->cmsg_level = SOL_IP;
++ cmsg->cmsg_type = IP_SENDSRCADDR;
++ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
++
++ addr = (struct in_addr*)CMSG_DATA(cmsg);
++
++ sin = (struct sockaddr_in*)src->get_sockaddr(src);
++ memcpy(addr, &sin->sin_addr, sizeof(struct in_addr));
++ return send_msg_generic(skt, msg);
++}
++
++#else /* IP_PKTINFO || IP_RECVDSTADDR */
++
++static ssize_t send_msg_v4(int skt, struct msghdr *msg, host_t *src)
++{
++ return send_msg_generic(skt, msg);
++}
++
++#endif /* IP_PKTINFO || IP_RECVDSTADDR */
++
++/**
++ * Send a message with the IPv6 source address set, if possible.
++ */
++#ifdef HAVE_IN6_PKTINFO
++
++static ssize_t send_msg_v6(int skt, struct msghdr *msg, host_t *src)
++{
++ char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))] = {};
++ struct cmsghdr *cmsg;
++ struct in6_pktinfo *pktinfo;
++ struct sockaddr_in6 *sin;
++
++ msg->msg_control = buf;
++ msg->msg_controllen = sizeof(buf);
++ cmsg = CMSG_FIRSTHDR(msg);
++ cmsg->cmsg_level = SOL_IPV6;
++ cmsg->cmsg_type = IPV6_PKTINFO;
++ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
++ pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsg);
++ sin = (struct sockaddr_in6*)src->get_sockaddr(src);
++ memcpy(&pktinfo->ipi6_addr, &sin->sin6_addr, sizeof(struct in6_addr));
++ return send_msg_generic(skt, msg);
++}
++
++#else /* HAVE_IN6_PKTINFO */
++
++static ssize_t send_msg_v6(int skt, struct msghdr *msg, host_t *src)
++{
++ return send_msg_generic(skt, msg);
++}
++
++#endif /* HAVE_IN6_PKTINFO */
++
+ METHOD(socket_t, sender, status_t,
+ private_socket_default_socket_t *this, packet_t *packet)
+ {
+@@ -363,7 +464,6 @@ METHOD(socket_t, sender, status_t,
+ chunk_t data;
+ host_t *src, *dst;
+ struct msghdr msg;
+- struct cmsghdr *cmsg;
+ struct iovec iov;
+ u_int8_t *dscp;
+
+@@ -465,56 +565,17 @@ METHOD(socket_t, sender, status_t,
+ {
+ if (family == AF_INET)
+ {
+-#if defined(IP_PKTINFO) || defined(IP_SENDSRCADDR)
+- struct in_addr *addr;
+- struct sockaddr_in *sin;
+-#ifdef IP_PKTINFO
+- char buf[CMSG_SPACE(sizeof(struct in_pktinfo))];
+- struct in_pktinfo *pktinfo;
+-#elif defined(IP_SENDSRCADDR)
+- char buf[CMSG_SPACE(sizeof(struct in_addr))];
+-#endif
+- memset(buf, 0, sizeof(buf));
+- msg.msg_control = buf;
+- msg.msg_controllen = sizeof(buf);
+- cmsg = CMSG_FIRSTHDR(&msg);
+- cmsg->cmsg_level = SOL_IP;
+-#ifdef IP_PKTINFO
+- cmsg->cmsg_type = IP_PKTINFO;
+- cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+- pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg);
+- addr = &pktinfo->ipi_spec_dst;
+-#elif defined(IP_SENDSRCADDR)
+- cmsg->cmsg_type = IP_SENDSRCADDR;
+- cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
+- addr = (struct in_addr*)CMSG_DATA(cmsg);
+-#endif
+- sin = (struct sockaddr_in*)src->get_sockaddr(src);
+- memcpy(addr, &sin->sin_addr, sizeof(struct in_addr));
+-#endif /* IP_PKTINFO || IP_SENDSRCADDR */
++ bytes_sent = send_msg_v4(skt, &msg, src);
+ }
+-#ifdef HAVE_IN6_PKTINFO
+ else
+ {
+- char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
+- struct in6_pktinfo *pktinfo;
+- struct sockaddr_in6 *sin;
+-
+- memset(buf, 0, sizeof(buf));
+- msg.msg_control = buf;
+- msg.msg_controllen = sizeof(buf);
+- cmsg = CMSG_FIRSTHDR(&msg);
+- cmsg->cmsg_level = SOL_IPV6;
+- cmsg->cmsg_type = IPV6_PKTINFO;
+- cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
+- pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsg);
+- sin = (struct sockaddr_in6*)src->get_sockaddr(src);
+- memcpy(&pktinfo->ipi6_addr, &sin->sin6_addr, sizeof(struct in6_addr));
++ bytes_sent = send_msg_v6(skt, &msg, src);
+ }
+-#endif /* HAVE_IN6_PKTINFO */
+ }
+-
+- bytes_sent = sendmsg(skt, &msg, 0);
++ else
++ {
++ bytes_sent = send_msg_generic(skt, &msg);
++ }
+
+ if (bytes_sent != data.len)
+ {
+--
+2.6.2
+
diff --git a/debian/patches/series b/debian/patches/series
index 6d7cc1dfa..f96ab5864 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,3 +1,4 @@
01_fix-manpages.patch
03_systemd-service.patch
04_disable-libtls-tests.patch
+0001-socket-default-Refactor-setting-source-address-when-.patch