mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-28 11:43:50 +00:00
Merge pull request #131 from Blaok/master
Add IPv6 support for ss-redir
This commit is contained in:
+29
-12
@@ -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);
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user