Support ipv6
This commit is contained in:
parent
c7d9d6ab03
commit
ee08742da7
@ -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";
|
||||
|
@ -3,6 +3,7 @@
|
||||
可以修改HTTP协议消息头(request).
|
||||
可以修改HTTP协议CONNECT方法消息头.
|
||||
可以修改HTTP协议GET方法消息头.
|
||||
初步支持IPV6.
|
||||
|
||||
### Build
|
||||
Linux编译:
|
||||
|
@ -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
146
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user