diff options
Diffstat (limited to 'src/libcharon/plugins/socket_default/socket_default_socket.c')
-rw-r--r-- | src/libcharon/plugins/socket_default/socket_default_socket.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/src/libcharon/plugins/socket_default/socket_default_socket.c b/src/libcharon/plugins/socket_default/socket_default_socket.c index 4139afe5a..ea976dfe9 100644 --- a/src/libcharon/plugins/socket_default/socket_default_socket.c +++ b/src/libcharon/plugins/socket_default/socket_default_socket.c @@ -445,6 +445,7 @@ METHOD(socket_t, sender, status_t, #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); @@ -453,7 +454,6 @@ METHOD(socket_t, sender, status_t, cmsg->cmsg_type = IP_PKTINFO; cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg); - memset(pktinfo, 0, sizeof(struct in_pktinfo)); addr = &pktinfo->ipi_spec_dst; #elif defined(IP_SENDSRCADDR) cmsg->cmsg_type = IP_SENDSRCADDR; @@ -471,6 +471,7 @@ METHOD(socket_t, sender, status_t, 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); @@ -478,7 +479,6 @@ METHOD(socket_t, sender, status_t, cmsg->cmsg_type = IPV6_PKTINFO; cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsg); - memset(pktinfo, 0, sizeof(struct in6_pktinfo)); sin = (struct sockaddr_in6*)src->get_sockaddr(src); memcpy(&pktinfo->ipi6_addr, &sin->sin6_addr, sizeof(struct in6_addr)); } @@ -611,6 +611,24 @@ static int open_socket(private_socket_default_socket_t *this, return -1; } } +#ifdef SO_MARK + { /* set optional MARK on socket (requires CAP_NET_ADMIN) */ + char *fwmark; + mark_t mark; + + fwmark = lib->settings->get_str(lib->settings, + "%s.plugins.socket-default.fwmark", NULL, charon->name); + if (fwmark && mark_from_string(fwmark, &mark)) + { + if (setsockopt(skt, SOL_SOCKET, SO_MARK, &mark.value, + sizeof(mark.value)) < 0) + { + DBG1(DBG_NET, "unable to set SO_MARK on socket: %s", + strerror(errno)); + } + } + } +#endif if (!hydra->kernel_interface->bypass_socket(hydra->kernel_interface, skt, family)) |