Support ipv6

This commit is contained in:
aixiao 2020-10-27 16:42:51 +08:00
parent c7d9d6ab03
commit ee08742da7
5 changed files with 125 additions and 36 deletions

View File

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

View File

@ -3,6 +3,7 @@
可以修改HTTP协议消息头(request).
可以修改HTTP协议CONNECT方法消息头.
可以修改HTTP协议GET方法消息头.
初步支持IPV6.
### Build
Linux编译:

View File

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

146
main.c
View File

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

1
main.h
View File

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