Skip to content

Commit

Permalink
Add IPv6 support to redudp
Browse files Browse the repository at this point in the history
Not verified
  • Loading branch information
semigodking committed Mar 1, 2020
1 parent abeae8f commit ad2732e
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 10 deletions.
10 changes: 10 additions & 0 deletions libc-compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@
# define IP_RECVORIGDSTADDR IP_ORIGDSTADDR
#endif

#ifndef IPV6_ORIGDSTADDR
# warning Using hardcoded value for IPV6_ORIGDSTADDR as libc headers do not define it.
# define IPV6_ORIGDSTADDR 74
#endif

#ifndef IPV6_RECVORIGDSTADDR
# warning Using hardcoded value for IPV6_RECVORIGDSTADDR as libc headers do not define it.
# define IPV6_RECVORIGDSTADDR IPV6_ORIGDSTADDR
#endif

#ifndef IP_TRANSPARENT
# warning Using hardcoded value for IP_TRANSPARENT as libc headers do not define it.
# define IP_TRANSPARENT 19
Expand Down
29 changes: 21 additions & 8 deletions redudp.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@ static void bound_udp4_action(const void *nodep, const VISIT which, const int de

static int do_tproxy(redudp_instance* instance)
{
return instance->config.dest == NULL;
// When listner is bound to IPv6 address, TPORXY must be used.
return instance->config.bindaddr.ss_family == AF_INET6 || instance->config.dest == NULL;
}

struct sockaddr_storage* get_destaddr(redudp_client *client)
Expand Down Expand Up @@ -575,7 +576,7 @@ static int redudp_init_instance(redudp_instance *instance)
goto fail;
}

fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
fd = socket(instance->config.bindaddr.ss_family, SOCK_DGRAM, IPPROTO_UDP);
if (fd == -1) {
log_errno(LOG_ERR, "socket");
goto fail;
Expand All @@ -586,13 +587,25 @@ static int redudp_init_instance(redudp_instance *instance)
// iptables TPROXY target does not send packets to non-transparent sockets
if (0 != make_socket_transparent(fd))
goto fail;

error = setsockopt(fd, SOL_IP, IP_RECVORIGDSTADDR, &on, sizeof(on));
if (error) {
log_errno(LOG_ERR, "setsockopt(listener, SOL_IP, IP_RECVORIGDSTADDR)");
goto fail;

#ifdef SOL_IPV6
if (instance->config.bindaddr.ss_family == AF_INET) {
#endif
error = setsockopt(fd, SOL_IP, IP_RECVORIGDSTADDR, &on, sizeof(on));
if (error) {
log_errno(LOG_ERR, "setsockopt(listener, SOL_IP, IP_RECVORIGDSTADDR)");
goto fail;
}
#ifdef SOL_IPV6
}

else {
error = setsockopt(fd, SOL_IPV6, IPV6_RECVORIGDSTADDR, &on, sizeof(on));
if (error) {
log_errno(LOG_ERR, "setsockopt(listener, SOL_IPV6, IPV6_RECVORIGDSTADDR)");
goto fail;
}
}
#endif
log_error(LOG_INFO, "redudp @ %s: TPROXY", red_inet_ntop(&instance->config.bindaddr, buf1, sizeof(buf1)));
}
else {
Expand Down
7 changes: 5 additions & 2 deletions utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,11 @@ int red_recv_udp_pkt(
memset(toaddr, 0, sizeof(*toaddr));
for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (
cmsg->cmsg_level == SOL_IP &&
cmsg->cmsg_type == IP_ORIGDSTADDR &&
((cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_ORIGDSTADDR)
#ifdef SOL_IPV6
|| (cmsg->cmsg_level == SOL_IPV6 && cmsg->cmsg_type == IPV6_ORIGDSTADDR)
#endif
) &&
(cmsg->cmsg_len == CMSG_LEN(sizeof(struct sockaddr_in))
|| cmsg->cmsg_len == CMSG_LEN(sizeof(struct sockaddr_in6))) &&
cmsg->cmsg_len <= CMSG_LEN(sizeof(*toaddr))
Expand Down

0 comments on commit ad2732e

Please sign in to comment.