Browse Source

Merge pull request #131 from Blaok/master

Add IPv6 support for ss-redir
pull/140/head
Max Lv 10 years ago
parent
commit
8b4539e7d8
2 changed files with 30 additions and 13 deletions
  1. 41
      src/redir.c
  2. 2
      src/redir.h

41
src/redir.c

@ -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"
@ -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;
}
@ -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)
@ -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);

2
src/redir.h

@ -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;

Loading…
Cancel
Save