diff options
Diffstat (limited to 'debian/patches/0001-socket-default-Refactor-setting-source-address-when-.patch')
-rw-r--r-- | debian/patches/0001-socket-default-Refactor-setting-source-address-when-.patch | 199 |
1 files changed, 199 insertions, 0 deletions
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 + |