summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins/socket_default
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@corsac.net>2017-05-30 20:59:31 +0200
committerYves-Alexis Perez <corsac@corsac.net>2017-05-30 20:59:31 +0200
commitbba25e2ff6c4a193acb54560ea4417537bd2954e (patch)
tree9e074fe343f9ab6f5ce1e9c5142d9a6cf180fcda /src/libcharon/plugins/socket_default
parent05ddd767992d68bb38c7f16ece142e8c2e9ae016 (diff)
downloadvyos-strongswan-bba25e2ff6c4a193acb54560ea4417537bd2954e.tar.gz
vyos-strongswan-bba25e2ff6c4a193acb54560ea4417537bd2954e.zip
New upstream version 5.5.3
Diffstat (limited to 'src/libcharon/plugins/socket_default')
-rw-r--r--src/libcharon/plugins/socket_default/Makefile.in2
-rw-r--r--src/libcharon/plugins/socket_default/socket_default_socket.c55
2 files changed, 50 insertions, 7 deletions
diff --git a/src/libcharon/plugins/socket_default/Makefile.in b/src/libcharon/plugins/socket_default/Makefile.in
index f66ae1679..b87afa4a6 100644
--- a/src/libcharon/plugins/socket_default/Makefile.in
+++ b/src/libcharon/plugins/socket_default/Makefile.in
@@ -358,6 +358,7 @@ docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
fips_mode = @fips_mode@
+fuzz_plugins = @fuzz_plugins@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
host = @host@
@@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@
json_LIBS = @json_LIBS@
libdir = @libdir@
libexecdir = @libexecdir@
+libfuzzer = @libfuzzer@
libiptc_CFLAGS = @libiptc_CFLAGS@
libiptc_LIBS = @libiptc_LIBS@
linux_headers = @linux_headers@
diff --git a/src/libcharon/plugins/socket_default/socket_default_socket.c b/src/libcharon/plugins/socket_default/socket_default_socket.c
index ba22b0c2b..109b3fe9b 100644
--- a/src/libcharon/plugins/socket_default/socket_default_socket.c
+++ b/src/libcharon/plugins/socket_default/socket_default_socket.c
@@ -142,6 +142,11 @@ struct private_socket_default_socket_t {
bool set_source;
/**
+ * TRUE to force sending source interface on outbound packetrs
+ */
+ bool set_sourceif;
+
+ /**
* A counter to implement round-robin selection of read sockets
*/
u_int rr_counter;
@@ -362,12 +367,33 @@ static ssize_t send_msg_generic(int skt, struct msghdr *msg)
return sendmsg(skt, msg, 0);
}
+#if defined(IP_PKTINFO) || defined(HAVE_IN6_PKTINFO)
+
+/**
+ * Find the interface index a source address is installed on
+ */
+static int find_srcif(host_t *src)
+{
+ char *ifname;
+ int idx = 0;
+
+ if (charon->kernel->get_interface(charon->kernel, src, &ifname))
+ {
+ idx = if_nametoindex(ifname);
+ free(ifname);
+ }
+ return idx;
+}
+
+#endif /* IP_PKTINFO || HAVE_IN6_PKTINFO */
+
/**
* 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)
+static ssize_t send_msg_v4(private_socket_default_socket_t *this, int skt,
+ struct msghdr *msg, host_t *src)
{
char buf[CMSG_SPACE(sizeof(struct in_pktinfo))] = {};
struct cmsghdr *cmsg;
@@ -383,6 +409,10 @@ static ssize_t send_msg_v4(int skt, struct msghdr *msg, host_t *src)
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg);
+ if (this->set_sourceif)
+ {
+ pktinfo->ipi_ifindex = find_srcif(src);
+ }
addr = &pktinfo->ipi_spec_dst;
sin = (struct sockaddr_in*)src->get_sockaddr(src);
@@ -392,7 +422,8 @@ static ssize_t send_msg_v4(int skt, struct msghdr *msg, host_t *src)
#elif defined(IP_SENDSRCADDR)
-static ssize_t send_msg_v4(int skt, struct msghdr *msg, host_t *src)
+static ssize_t send_msg_v4(private_socket_default_socket_t *this, int skt,
+ struct msghdr *msg, host_t *src)
{
char buf[CMSG_SPACE(sizeof(struct in_addr))] = {};
struct cmsghdr *cmsg;
@@ -415,7 +446,8 @@ static ssize_t send_msg_v4(int skt, struct msghdr *msg, host_t *src)
#else /* IP_PKTINFO || IP_RECVDSTADDR */
-static ssize_t send_msg_v4(int skt, struct msghdr *msg, host_t *src)
+static ssize_t send_msg_v4(private_socket_default_socket_t *this,
+ int skt, struct msghdr *msg, host_t *src)
{
return send_msg_generic(skt, msg);
}
@@ -427,7 +459,8 @@ static ssize_t send_msg_v4(int skt, struct msghdr *msg, host_t *src)
*/
#ifdef HAVE_IN6_PKTINFO
-static ssize_t send_msg_v6(int skt, struct msghdr *msg, host_t *src)
+static ssize_t send_msg_v6(private_socket_default_socket_t *this, int skt,
+ struct msghdr *msg, host_t *src)
{
char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))] = {};
struct cmsghdr *cmsg;
@@ -441,6 +474,10 @@ static ssize_t send_msg_v6(int skt, struct msghdr *msg, host_t *src)
cmsg->cmsg_type = IPV6_PKTINFO;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsg);
+ if (this->set_sourceif)
+ {
+ pktinfo->ipi6_ifindex = find_srcif(src);
+ }
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);
@@ -448,7 +485,8 @@ static ssize_t send_msg_v6(int skt, struct msghdr *msg, host_t *src)
#else /* HAVE_IN6_PKTINFO */
-static ssize_t send_msg_v6(int skt, struct msghdr *msg, host_t *src)
+static ssize_t send_msg_v6(private_socket_default_socket_t *this,
+ int skt, struct msghdr *msg, host_t *src)
{
return send_msg_generic(skt, msg);
}
@@ -564,11 +602,11 @@ METHOD(socket_t, sender, status_t,
{
if (family == AF_INET)
{
- bytes_sent = send_msg_v4(skt, &msg, src);
+ bytes_sent = send_msg_v4(this, skt, &msg, src);
}
else
{
- bytes_sent = send_msg_v6(skt, &msg, src);
+ bytes_sent = send_msg_v6(this, skt, &msg, src);
}
}
else
@@ -831,6 +869,9 @@ socket_default_socket_t *socket_default_socket_create()
.set_source = lib->settings->get_bool(lib->settings,
"%s.plugins.socket-default.set_source", TRUE,
lib->ns),
+ .set_sourceif = lib->settings->get_bool(lib->settings,
+ "%s.plugins.socket-default.set_sourceif", FALSE,
+ lib->ns),
);
if (this->port && this->port == this->natt)