From c53db89556670931e5b00e0ab66b6011bacdf656 Mon Sep 17 00:00:00 2001 From: Yves-Alexis Perez Date: Tue, 3 Nov 2015 17:14:13 +0100 Subject: Add source address selection patch for socket-dynamic plugin The socket-dynamic plugin has the same issue as the socket-default one so even if few people use it, it's worth fixing there too --- ...mic-Refactor-setting-source-address-when-.patch | 139 +++++++++++++++++++++ debian/patches/series | 1 + 2 files changed, 140 insertions(+) create mode 100644 debian/patches/0001-socket-dynamic-Refactor-setting-source-address-when-.patch (limited to 'debian/patches') diff --git a/debian/patches/0001-socket-dynamic-Refactor-setting-source-address-when-.patch b/debian/patches/0001-socket-dynamic-Refactor-setting-source-address-when-.patch new file mode 100644 index 000000000..3b74c6b70 --- /dev/null +++ b/debian/patches/0001-socket-dynamic-Refactor-setting-source-address-when-.patch @@ -0,0 +1,139 @@ +From 9e8b4aa5c86775e72c2fd3bd764cba896351914a Mon Sep 17 00:00:00 2001 +From: Tobias Brunner +Date: Tue, 3 Nov 2015 15:35:16 +0100 +Subject: [PATCH] socket-dynamic: Refactor setting source address when sending + messages + +Basically the same change as the one for the socket-default plugin. +--- + .../plugins/socket_dynamic/socket_dynamic_socket.c | 94 ++++++++++++++-------- + 1 file changed, 62 insertions(+), 32 deletions(-) + +diff --git a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c +index b82a69e..a032134 100644 +--- a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c ++++ b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c +@@ -527,6 +527,62 @@ static dynsock_t *find_socket(private_socket_dynamic_socket_t *this, + return skt; + } + ++/** ++ * 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. ++ */ ++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); ++} ++ ++/** ++ * Send a message with the IPv6 source address set. ++ */ ++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); ++} ++ + METHOD(socket_t, sender, status_t, + private_socket_dynamic_socket_t *this, packet_t *packet) + { +@@ -536,7 +592,6 @@ METHOD(socket_t, sender, status_t, + ssize_t len; + chunk_t data; + struct msghdr msg; +- struct cmsghdr *cmsg; + struct iovec iov; + + src = packet->get_source(packet); +@@ -564,43 +619,18 @@ METHOD(socket_t, sender, status_t, + { + if (family == AF_INET) + { +- struct in_addr *addr; +- struct sockaddr_in *sin; +- char buf[CMSG_SPACE(sizeof(struct in_pktinfo))]; +- struct in_pktinfo *pktinfo; +- +- memset(buf, 0, sizeof(buf)); +- 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)); ++ len = send_msg_v4(skt->fd, &msg, src); + } + 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)); ++ len = send_msg_v6(skt->fd, &msg, src); + } + } ++ else ++ { ++ len = send_msg_generic(skt->fd, &msg); ++ } + +- len = sendmsg(skt->fd, &msg, 0); + if (len != data.len) + { + DBG1(DBG_NET, "error writing to socket: %s", strerror(errno)); +-- +2.6.2 + diff --git a/debian/patches/series b/debian/patches/series index f96ab5864..791c61c82 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -2,3 +2,4 @@ 03_systemd-service.patch 04_disable-libtls-tests.patch 0001-socket-default-Refactor-setting-source-address-when-.patch +0001-socket-dynamic-Refactor-setting-source-address-when-.patch -- cgit v1.2.3