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