From ee08742da782268b7d279be2d76ecb6bfc2c6b8a Mon Sep 17 00:00:00 2001 From: aixiao Date: Tue, 27 Oct 2020 16:42:51 +0800 Subject: [PATCH] Support ipv6 --- CProxy.conf | 4 +- README.md | 1 + http_proxy.c | 9 ++-- main.c | 146 +++++++++++++++++++++++++++++++++++++++++---------- main.h | 1 + 5 files changed, 125 insertions(+), 36 deletions(-) diff --git a/CProxy.conf b/CProxy.conf index af983bf..8604a6b 100644 --- a/CProxy.conf +++ b/CProxy.conf @@ -8,7 +8,7 @@ global { } http { - http_ip=8.210.203.112; + http_ip=47.240.75.93; http_port=124; http_del="Host"; http_first="[M] http://[host][U] [V]\r\nHost: [host]\r\n"; @@ -17,7 +17,7 @@ http { } https { - https_ip=8.210.203.112; + https_ip=47.240.75.93; https_port=124; https_del="Host,host,x-online-host"; https_first="[M] [U] [V]\r\nHost: [host]\r\n"; diff --git a/README.md b/README.md index 317d955..3f5d828 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ 可以修改HTTP协议消息头(request). 可以修改HTTP协议CONNECT方法消息头. 可以修改HTTP协议GET方法消息头. + 初步支持IPV6. ### Build Linux编译: diff --git a/http_proxy.c b/http_proxy.c index ca5974c..c859550 100644 --- a/http_proxy.c +++ b/http_proxy.c @@ -152,7 +152,6 @@ void tcp_in(conn * in, conf * configure) close_connection(in); return; } - remote = in + 1; if (in->request_type == OTHER_TYPE) { @@ -162,18 +161,18 @@ void tcp_in(conn * in, conf * configure) if (request_type(in->header_buffer) == HTTP_TYPE) { in->header_buffer = request_head(in, configure); struct epoll_event epollEvent; - remote->fd = create_connection(remote_host, remote_port); + remote->fd = create_connection6(remote_host, remote_port); epollEvent.events = EPOLLIN | EPOLLOUT | EPOLLET; epollEvent.data.ptr = remote; epoll_ctl(epollfd, EPOLL_CTL_ADD, remote->fd, &epollEvent); } - + //printf("%s", in->header_buffer); dataEncode(in->header_buffer, in->header_buffer_len); handle_data_complete: if (remote->fd >= 0) { - //clientToserver(in); - tcp_out(remote); + clientToserver(in); + //tcp_out(remote); } return; diff --git a/main.c b/main.c index 17718b6..ab5daee 100644 --- a/main.c +++ b/main.c @@ -12,7 +12,7 @@ #define SERVER_STATUS 3 struct epoll_event ev, events[MAX_CONNECTION + 1]; -int epollfd, server_sock; +int epollfd, server_sock, server_sock6; conn cts[MAX_CONNECTION]; int local_port; char local_host[128]; @@ -49,6 +49,47 @@ int create_connection(char *remote_host, int remote_port) return sock; } +int create_connection6(char *remote_host, int remote_port) +{ + char port[270]; + int sock = -1; + struct addrinfo *result; + struct addrinfo hints; + bzero(&hints, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + + memset(port, 0, 270); + sprintf(port, "%d", remote_port); // 转为字符串 + if ((getaddrinfo(remote_host, port, &hints, &result)) != 0) + return -1; + switch (result->ai_family) { + case AF_INET:{ + sock = socket(result->ai_family, result->ai_socktype, result->ai_protocol); + if (connect(sock, result->ai_addr, result->ai_addrlen) < 0) { + perror("AF_INET connect"); + close(sock); + return -1; + } + break; + } + case AF_INET6:{ + sock = socket(result->ai_family, result->ai_socktype, result->ai_protocol); + if (connect(sock, result->ai_addr, result->ai_addrlen) < 0) { + perror("AF_INET6 connect"); + close(sock); + return -1; + } + break; + } + default: + printf("Unknown\n"); + break; + } + freeaddrinfo(result); + fcntl(sock, F_SETFL, O_NONBLOCK); + return sock; +} + int create_server_socket(int port) { int server_sock; @@ -77,6 +118,44 @@ int create_server_socket(int port) return server_sock; } +int create_server_socket6(int port) +{ + int server_sock; + int optval = SO_REUSEADDR; + struct sockaddr_in6 server_addr; + if ((server_sock = socket(AF_INET6, SOCK_STREAM, 0)) < 0) { + perror("socket"); + return -1; + } + + if (setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) { + perror("setsockopt"); + return -1; + } + + if (setsockopt(server_sock, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval)) < 0) { + perror("setsockopt"); + return -1; + } + + memset(&server_addr, 0, sizeof(server_addr)); + server_addr.sin6_family = AF_INET6; + server_addr.sin6_port = htons(port); + server_addr.sin6_addr = in6addr_any; + + if (bind(server_sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in6)) != 0) { + perror("bind"); + return -1; + } + + if (listen(server_sock, 20) < 0) { + perror("listen"); + return -1; + } + + return server_sock; +} + void accept_client() { struct epoll_event epollEvent; @@ -100,6 +179,29 @@ void accept_client() epoll_ctl(epollfd, EPOLL_CTL_ADD, client->fd, &epollEvent); } +void accept_client6() +{ + struct epoll_event epollEvent; + struct sockaddr_in6 addr; + conn *client; + socklen_t addr_len = sizeof(addr); + + // 偶数为客户端,奇数为服务端 + for (client = cts; client - cts < MAX_CONNECTION; client += 2) + if (client->fd < 0) + break; + if (client - cts >= MAX_CONNECTION) + return; + client->timer = (client + 1)->timer = 0; + client->fd = accept(server_sock6, (struct sockaddr *)&addr, &addr_len); + if (client->fd < 0) + return; + fcntl(client->fd, F_SETFL, O_NONBLOCK); + epollEvent.events = EPOLLIN | EPOLLET; + epollEvent.data.ptr = client; + epoll_ctl(epollfd, EPOLL_CTL_ADD, client->fd, &epollEvent); +} + void *http_proxy_loop(void *p) { conf *configure = (conf *) p; @@ -110,6 +212,9 @@ void *http_proxy_loop(void *p) while (n-- > 0) { if (events[n].data.fd == server_sock) { accept_client(); + } + else if (events[n].data.fd == server_sock6) { + accept_client6(); } else { if (events[n].events & EPOLLIN) { tcp_in((conn *) events[n].data.ptr, configure); @@ -124,31 +229,6 @@ void *http_proxy_loop(void *p) return NULL; } -void *start_server(conf * configure) -{ - int n; - pthread_t thread_id; - if (timeout_minute) - pthread_create(&thread_id, NULL, &tcp_timeout_check, NULL); - - while (1) { - n = epoll_wait(epollfd, events, MAX_CONNECTION, -1); - while (n-- > 0) { - if (events[n].data.fd == server_sock) { - accept_client(); - } else { - if (events[n].events & EPOLLIN) { - tcp_in((conn *) events[n].data.ptr, configure); - } - if (events[n].events & EPOLLOUT) { - tcp_out((conn *) events[n].data.ptr); - } - } - } - } - close(epollfd); -} - int process_signal(int signal, char *process_name) { char bufer[PATH_SIZE]; @@ -291,8 +371,7 @@ void _main(int argc, char *argv[]) break; case 'c': free_conf(configure); - inifile = optarg; - read_conf(inifile, configure); + read_conf(optarg, configure); break; case 'e': sslEncodeCode = atoi(optarg); @@ -337,7 +416,9 @@ void _main(int argc, char *argv[]) exit(1); } } - server_sock = create_server_socket(configure->tcp_listen); + + server_sock = create_server_socket(configure->tcp_listen); // IPV4 + server_sock6 = create_server_socket6(configure->tcp_listen);// IPV6 epollfd = epoll_create(MAX_CONNECTION); if (epollfd == -1) { perror("epoll_create"); @@ -349,6 +430,13 @@ void _main(int argc, char *argv[]) if (-1 == epoll_ctl(epollfd, EPOLL_CTL_ADD, server_sock, &event)) { exit(1); } + + event.events = EPOLLIN; + event.data.fd = server_sock6; + if (-1 == epoll_ctl(epollfd, EPOLL_CTL_ADD, server_sock6, &event)) { + exit(1); + } + if (setegid(configure->uid) == -1 || seteuid(configure->uid) == -1) // 设置uid exit(1); diff --git a/main.h b/main.h index 4895988..8df2ad0 100644 --- a/main.h +++ b/main.h @@ -34,5 +34,6 @@ extern int process; extern int epollfd; extern struct epoll_event ev, events[MAX_CONNECTION + 1]; int create_connection(char *remote_host, int remote_port); +int create_connection6(char *remote_host, int remote_port); #endif