Browse Source

尝试将ss-redir的转发改为IPv6转发

目前`IP6T_SO_ORIGINAL_DST`这个东西上边,不能正确获取原始目标地址。尝试`curl bt.byr.cn`,前面一部分地址可以看到是`a:50::2001:da8:215:4078`,但是格式完全不对,内容也不全,正确的地址应该是`2001:da8:215:4078:250:56ff:fe97:654d`。估计是某些针对IPv4的设定没有改过来。改日再看。
另外吐槽一下原版毫无注释的代码……
pull/131/head
Blaok 10 years ago
parent
commit
cef3586733
2 changed files with 24 additions and 10 deletions
  1. 32
      src/redir.c
  2. 2
      src/redir.h

32
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,16 +60,16 @@
#define BUF_SIZE 2048
#endif
int getdestaddr(int fd, struct sockaddr_in *destaddr)
int getdestaddr( struct listen_ctx * listener, struct sockaddr_in *destaddr)
{
socklen_t socklen = sizeof(*destaddr);
int error;
/* socklen_t socklen = sizeof(*destaddr);
int error=0;
error = getsockopt(fd, SOL_IP, SO_ORIGINAL_DST, destaddr, &socklen);
// error = getsockopt(listener->fd, (listener->local.isIPv6()?SOL_IP6:SOL_IP), (listener->local.isIPv6()?IP6T_SO_ORIGINAL_DST:SO_ORIGINAL_DST), destaddr, &socklen);
if (error)
{
return -1;
}
}*/
return 0;
}
@ -104,6 +106,7 @@ int create_and_bind(const char *addr, const char *port)
int opt = 1;
setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
// setsockopt(listen_sock, IPPROTO_IPV6, SO_REUSEADDR, &opt, sizeof(opt));
setsockopt(listen_sock, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
#ifdef SO_NOSIGPIPE
setsockopt(listen_sock, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
@ -398,9 +401,9 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents)
// 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);
memcpy(ss_addr_to_send + addr_len, &server->destaddr.sin6_addr, in_addr_len);
addr_len += in_addr_len;
memcpy(ss_addr_to_send + addr_len, &server->destaddr.sin_port, 2);
memcpy(ss_addr_to_send + addr_len, &server->destaddr.sin6_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 +615,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_in6 destaddr;
int err;
int clientfd = accept(listener->fd, NULL, NULL);
@ -622,7 +625,18 @@ static void accept_cb (EV_P_ ev_io *w, int revents)
return;
}
err = getdestaddr(clientfd, &destaddr);
//err = getdestaddr(listener, &destaddr);
printf("Connet server %s, port %s.\n",listener->remote_addr->host,listener->remote_addr->port);
printf("%d %s\n",listener->sock.sa_family,listener->sock.sa_data);
socklen_t socklen = sizeof(destaddr);
//err = getsockopt(listener->fd, (listener->local.isIPv6()?SOL_IP6:SOL_IP), (listener->local.isIPv6()?IP6T_SO_ORIGINAL_DST:SO_ORIGINAL_DST), destaddr, &socklen);
err = getsockopt(clientfd, IPPROTO_IPV6, IP6T_SO_ORIGINAL_DST, &destaddr, &socklen);
//
char str[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &destaddr, str, INET6_ADDRSTRLEN);
printf("%s\n", str);
if (err)
{
ERROR("getdestaddr");

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_in6 destaddr;
struct enc_ctx *e_ctx;
struct enc_ctx *d_ctx;
struct server_ctx *recv_ctx;

Loading…
Cancel
Save