Skip to content

Commit

Permalink
Merge pull request #131 from Blaok/master
Browse files Browse the repository at this point in the history
Add IPv6 support for ss-redir
  • Loading branch information
madeye committed Oct 27, 2014
2 parents 1235900 + afe4392 commit 8b4539e
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 13 deletions.
41 changes: 29 additions & 12 deletions src/redir.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@
#include <time.h>
#include <unistd.h>
#include <limits.h>
#include <linux/if.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_ipv6/ip6_tables.h>

#ifdef HAVE_CONFIG_H
#include "config.h"
Expand All @@ -58,15 +60,19 @@
#define BUF_SIZE 2048
#endif

int getdestaddr(int fd, struct sockaddr_in *destaddr)
int getdestaddr(int fd, struct sockaddr_storage *destaddr)
{
socklen_t socklen = sizeof(*destaddr);
int error;
int error=0;

error = getsockopt(fd, SOL_IP, SO_ORIGINAL_DST, destaddr, &socklen);
if (error)
error = getsockopt(fd, SOL_IPV6, IP6T_SO_ORIGINAL_DST,destaddr, &socklen);
if (error) // Didn't find a proper way to detect IP version.
{
return -1;
error = getsockopt(fd, SOL_IP, SO_ORIGINAL_DST,destaddr, &socklen);
if(error)
{
return -1;
}
}
return 0;
}
Expand Down Expand Up @@ -394,13 +400,24 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents)
// send destaddr
char *ss_addr_to_send = malloc(BUF_SIZE);
ssize_t addr_len = 0;
ss_addr_to_send[addr_len++] = 1;
if(AF_INET6==server->destaddr.ss_family) // IPv6
{
ss_addr_to_send[addr_len++] = 4; //Type 4 is IPv6 address

// handle IP V4 only
size_t in_addr_len = sizeof(struct in_addr);
memcpy(ss_addr_to_send + addr_len, &server->destaddr.sin_addr, in_addr_len);
addr_len += in_addr_len;
memcpy(ss_addr_to_send + addr_len, &server->destaddr.sin_port, 2);
size_t in_addr_len = sizeof(struct in6_addr);
memcpy(ss_addr_to_send + addr_len, &(((struct sockaddr_in6*)&(server->destaddr))->sin6_addr), in_addr_len);
addr_len += in_addr_len;
memcpy(ss_addr_to_send + addr_len, &(((struct sockaddr_in6*)&(server->destaddr))->sin6_port), 2);
}
else //IPv4
{
ss_addr_to_send[addr_len++] = 1; //Type 1 is IPv4 address

size_t in_addr_len = sizeof(struct in_addr);
memcpy(ss_addr_to_send + addr_len, &((struct sockaddr_in*)&(server->destaddr))->sin_addr, in_addr_len);
addr_len += in_addr_len;
memcpy(ss_addr_to_send + addr_len, &((struct sockaddr_in*)&(server->destaddr))->sin_port, 2);
}
addr_len += 2;
ss_addr_to_send = ss_encrypt(BUF_SIZE, ss_addr_to_send, &addr_len, server->e_ctx);
if (ss_addr_to_send == NULL)
Expand Down Expand Up @@ -612,7 +629,7 @@ void close_and_free_server(EV_P_ struct server *server)
static void accept_cb (EV_P_ ev_io *w, int revents)
{
struct listen_ctx *listener = (struct listen_ctx *)w;
struct sockaddr_in destaddr;
struct sockaddr_storage destaddr;
int err;

int clientfd = accept(listener->fd, NULL, NULL);
Expand Down
2 changes: 1 addition & 1 deletion src/redir.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ struct server
ssize_t buf_len;
ssize_t buf_idx;
char *buf; // server send from, remote recv into
struct sockaddr_in destaddr;
struct sockaddr_storage destaddr;
struct enc_ctx *e_ctx;
struct enc_ctx *d_ctx;
struct server_ctx *recv_ctx;
Expand Down

0 comments on commit 8b4539e

Please sign in to comment.