From cef3586733e43de08f9d384f871707dfc2b41d21 Mon Sep 17 00:00:00 2001 From: Blaok Date: Fri, 24 Oct 2014 11:30:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=9D=E8=AF=95=E5=B0=86ss-redir=E7=9A=84?= =?UTF-8?q?=E8=BD=AC=E5=8F=91=E6=94=B9=E4=B8=BAIPv6=E8=BD=AC=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 目前`IP6T_SO_ORIGINAL_DST`这个东西上边,不能正确获取原始目标地址。尝试`curl bt.byr.cn`,前面一部分地址可以看到是`a:50::2001:da8:215:4078`,但是格式完全不对,内容也不全,正确的地址应该是`2001:da8:215:4078:250:56ff:fe97:654d`。估计是某些针对IPv4的设定没有改过来。改日再看。 另外吐槽一下原版毫无注释的代码…… --- src/redir.c | 32 +++++++++++++++++++++++--------- src/redir.h | 2 +- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/redir.c b/src/redir.c index aad0bf0e..67ad39b2 100644 --- a/src/redir.c +++ b/src/redir.c @@ -37,7 +37,9 @@ #include #include #include +#include #include +#include #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"); diff --git a/src/redir.h b/src/redir.h index ea0141c9..05e3b1a7 100644 --- a/src/redir.h +++ b/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;