Support ipv6
This commit is contained in:
parent
c7d9d6ab03
commit
ee08742da7
@ -8,7 +8,7 @@ global {
|
|||||||
}
|
}
|
||||||
|
|
||||||
http {
|
http {
|
||||||
http_ip=8.210.203.112;
|
http_ip=47.240.75.93;
|
||||||
http_port=124;
|
http_port=124;
|
||||||
http_del="Host";
|
http_del="Host";
|
||||||
http_first="[M] http://[host][U] [V]\r\nHost: [host]\r\n";
|
http_first="[M] http://[host][U] [V]\r\nHost: [host]\r\n";
|
||||||
@ -17,7 +17,7 @@ http {
|
|||||||
}
|
}
|
||||||
|
|
||||||
https {
|
https {
|
||||||
https_ip=8.210.203.112;
|
https_ip=47.240.75.93;
|
||||||
https_port=124;
|
https_port=124;
|
||||||
https_del="Host,host,x-online-host";
|
https_del="Host,host,x-online-host";
|
||||||
https_first="[M] [U] [V]\r\nHost: [host]\r\n";
|
https_first="[M] [U] [V]\r\nHost: [host]\r\n";
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
可以修改HTTP协议消息头(request).
|
可以修改HTTP协议消息头(request).
|
||||||
可以修改HTTP协议CONNECT方法消息头.
|
可以修改HTTP协议CONNECT方法消息头.
|
||||||
可以修改HTTP协议GET方法消息头.
|
可以修改HTTP协议GET方法消息头.
|
||||||
|
初步支持IPV6.
|
||||||
|
|
||||||
### Build
|
### Build
|
||||||
Linux编译:
|
Linux编译:
|
||||||
|
@ -152,7 +152,6 @@ void tcp_in(conn * in, conf * configure)
|
|||||||
close_connection(in);
|
close_connection(in);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
remote = in + 1;
|
remote = in + 1;
|
||||||
if (in->request_type == OTHER_TYPE)
|
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) {
|
if (request_type(in->header_buffer) == HTTP_TYPE) {
|
||||||
in->header_buffer = request_head(in, configure);
|
in->header_buffer = request_head(in, configure);
|
||||||
struct epoll_event epollEvent;
|
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.events = EPOLLIN | EPOLLOUT | EPOLLET;
|
||||||
epollEvent.data.ptr = remote;
|
epollEvent.data.ptr = remote;
|
||||||
epoll_ctl(epollfd, EPOLL_CTL_ADD, remote->fd, &epollEvent);
|
epoll_ctl(epollfd, EPOLL_CTL_ADD, remote->fd, &epollEvent);
|
||||||
}
|
}
|
||||||
|
//printf("%s", in->header_buffer);
|
||||||
dataEncode(in->header_buffer, in->header_buffer_len);
|
dataEncode(in->header_buffer, in->header_buffer_len);
|
||||||
|
|
||||||
handle_data_complete:
|
handle_data_complete:
|
||||||
if (remote->fd >= 0) {
|
if (remote->fd >= 0) {
|
||||||
//clientToserver(in);
|
clientToserver(in);
|
||||||
tcp_out(remote);
|
//tcp_out(remote);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
146
main.c
146
main.c
@ -12,7 +12,7 @@
|
|||||||
#define SERVER_STATUS 3
|
#define SERVER_STATUS 3
|
||||||
|
|
||||||
struct epoll_event ev, events[MAX_CONNECTION + 1];
|
struct epoll_event ev, events[MAX_CONNECTION + 1];
|
||||||
int epollfd, server_sock;
|
int epollfd, server_sock, server_sock6;
|
||||||
conn cts[MAX_CONNECTION];
|
conn cts[MAX_CONNECTION];
|
||||||
int local_port;
|
int local_port;
|
||||||
char local_host[128];
|
char local_host[128];
|
||||||
@ -49,6 +49,47 @@ int create_connection(char *remote_host, int remote_port)
|
|||||||
return sock;
|
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 create_server_socket(int port)
|
||||||
{
|
{
|
||||||
int server_sock;
|
int server_sock;
|
||||||
@ -77,6 +118,44 @@ int create_server_socket(int port)
|
|||||||
return server_sock;
|
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()
|
void accept_client()
|
||||||
{
|
{
|
||||||
struct epoll_event epollEvent;
|
struct epoll_event epollEvent;
|
||||||
@ -100,6 +179,29 @@ void accept_client()
|
|||||||
epoll_ctl(epollfd, EPOLL_CTL_ADD, client->fd, &epollEvent);
|
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)
|
void *http_proxy_loop(void *p)
|
||||||
{
|
{
|
||||||
conf *configure = (conf *) p;
|
conf *configure = (conf *) p;
|
||||||
@ -110,6 +212,9 @@ void *http_proxy_loop(void *p)
|
|||||||
while (n-- > 0) {
|
while (n-- > 0) {
|
||||||
if (events[n].data.fd == server_sock) {
|
if (events[n].data.fd == server_sock) {
|
||||||
accept_client();
|
accept_client();
|
||||||
|
}
|
||||||
|
else if (events[n].data.fd == server_sock6) {
|
||||||
|
accept_client6();
|
||||||
} else {
|
} else {
|
||||||
if (events[n].events & EPOLLIN) {
|
if (events[n].events & EPOLLIN) {
|
||||||
tcp_in((conn *) events[n].data.ptr, configure);
|
tcp_in((conn *) events[n].data.ptr, configure);
|
||||||
@ -124,31 +229,6 @@ void *http_proxy_loop(void *p)
|
|||||||
return NULL;
|
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)
|
int process_signal(int signal, char *process_name)
|
||||||
{
|
{
|
||||||
char bufer[PATH_SIZE];
|
char bufer[PATH_SIZE];
|
||||||
@ -291,8 +371,7 @@ void _main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
free_conf(configure);
|
free_conf(configure);
|
||||||
inifile = optarg;
|
read_conf(optarg, configure);
|
||||||
read_conf(inifile, configure);
|
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
sslEncodeCode = atoi(optarg);
|
sslEncodeCode = atoi(optarg);
|
||||||
@ -337,7 +416,9 @@ void _main(int argc, char *argv[])
|
|||||||
exit(1);
|
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);
|
epollfd = epoll_create(MAX_CONNECTION);
|
||||||
if (epollfd == -1) {
|
if (epollfd == -1) {
|
||||||
perror("epoll_create");
|
perror("epoll_create");
|
||||||
@ -349,6 +430,13 @@ void _main(int argc, char *argv[])
|
|||||||
if (-1 == epoll_ctl(epollfd, EPOLL_CTL_ADD, server_sock, &event)) {
|
if (-1 == epoll_ctl(epollfd, EPOLL_CTL_ADD, server_sock, &event)) {
|
||||||
exit(1);
|
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
|
if (setegid(configure->uid) == -1 || seteuid(configure->uid) == -1) // 设置uid
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
|
1
main.h
1
main.h
@ -34,5 +34,6 @@ extern int process;
|
|||||||
extern int epollfd;
|
extern int epollfd;
|
||||||
extern struct epoll_event ev, events[MAX_CONNECTION + 1];
|
extern struct epoll_event ev, events[MAX_CONNECTION + 1];
|
||||||
int create_connection(char *remote_host, int remote_port);
|
int create_connection(char *remote_host, int remote_port);
|
||||||
|
int create_connection6(char *remote_host, int remote_port);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user