Add files via upload

This commit is contained in:
mmmdbybyd 2018-12-21 19:13:07 +08:00 committed by GitHub
parent d550baa3ad
commit 7858b7dc29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 68 additions and 64 deletions

View File

@ -40,4 +40,4 @@ Linux/Android:
make make
Android-ndk: Android-ndk:
ndk-build ndk-build
~~~~~ ~~~~~

68
http.c
View File

@ -9,7 +9,16 @@
conn_t cts[MAX_CONNECTION]; conn_t cts[MAX_CONNECTION];
char *local_header, *proxy_header, *ssl_proxy; char *local_header, *proxy_header, *ssl_proxy;
int lisFd, proxy_header_len, local_header_len; int lisFd, proxy_header_len, local_header_len;
uint8_t strict_spilce; uint8_t strict_spilce, sslEncodeCode;
/* 对数据进行编码 */
static void dataEncode(char *data, int data_len)
{
if (sslEncodeCode == 0)
return;
while (data_len-- > 0)
data[data_len] ^= sslEncodeCode;
}
int8_t connectionToServer(char *ip, conn_t *server) int8_t connectionToServer(char *ip, conn_t *server)
{ {
@ -22,7 +31,7 @@ int8_t connectionToServer(char *ip, conn_t *server)
if (connect(server->fd, (struct sockaddr *)&addr, sizeof(addr)) != 0 && errno != EINPROGRESS) if (connect(server->fd, (struct sockaddr *)&addr, sizeof(addr)) != 0 && errno != EINPROGRESS)
return 1; return 1;
ev.data.ptr = server; ev.data.ptr = server;
ev.events = EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP|EPOLLET; ev.events = EPOLLIN|EPOLLOUT|EPOLLET;
epoll_ctl(efd, EPOLL_CTL_ADD, server->fd, &ev); epoll_ctl(efd, EPOLL_CTL_ADD, server->fd, &ev);
return 0; return 0;
@ -249,7 +258,7 @@ static char *build_request(char *client_data, int *data_len, char *host)
} }
/* 解析Host */ /* 解析Host */
int8_t parse_host(conn_t *server, char *host) static int8_t parse_host(conn_t *server, char *host)
{ {
char *port, *p; char *port, *p;
@ -278,6 +287,7 @@ int8_t parse_host(conn_t *server, char *host)
/* 读取到的数据全部就绪将incomplete_data复制到ready_data */ /* 读取到的数据全部就绪将incomplete_data复制到ready_data */
static int8_t copy_data(conn_t *ct) static int8_t copy_data(conn_t *ct)
{ {
dataEncode(ct->incomplete_data, ct->incomplete_data_len);
if (ct->ready_data) if (ct->ready_data)
{ {
char *new_data; char *new_data;
@ -306,14 +316,14 @@ static void serverToClient(conn_t *server)
conn_t *client; conn_t *client;
int write_len; int write_len;
errno = 0;
client = server - 1; client = server - 1;
while ((server->ready_data_len = read(server->fd, server->ready_data, BUFFER_SIZE)) > 0) while ((server->ready_data_len = read(server->fd, server->ready_data, BUFFER_SIZE)) > 0)
{ {
dataEncode(server->ready_data, server->ready_data_len);
write_len = write(client->fd, server->ready_data, server->ready_data_len); write_len = write(client->fd, server->ready_data, server->ready_data_len);
if (write_len == -1) if (write_len <= 0)
{ {
if (errno != EAGAIN) if (write_len == 0 || errno != EAGAIN)
close_connection(server); close_connection(server);
else else
server->sent_len = 0; server->sent_len = 0;
@ -322,7 +332,7 @@ static void serverToClient(conn_t *server)
else if (write_len < server->ready_data_len) else if (write_len < server->ready_data_len)
{ {
server->sent_len = write_len; server->sent_len = write_len;
ev.events = EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP|EPOLLET; ev.events = EPOLLIN|EPOLLOUT|EPOLLET;
ev.data.ptr = client; ev.data.ptr = client;
epoll_ctl(efd, EPOLL_CTL_MOD, client->fd, &ev); epoll_ctl(efd, EPOLL_CTL_MOD, client->fd, &ev);
return; return;
@ -331,7 +341,7 @@ static void serverToClient(conn_t *server)
break; break;
} }
//判断是否关闭连接 //判断是否关闭连接
if (server->ready_data_len == 0 || (errno != EAGAIN && errno != 0)) if (server->ready_data_len == 0 || (server->ready_data_len == -1 && errno != EAGAIN))
close_connection(server); close_connection(server);
else else
server->ready_data_len = server->sent_len = 0; server->ready_data_len = server->sent_len = 0;
@ -358,14 +368,14 @@ void tcp_out(conn_t *to)
serverToClient(from); serverToClient(from);
if (from->fd >= 0 && from->ready_data_len == 0) if (from->fd >= 0 && from->ready_data_len == 0)
{ {
ev.events = EPOLLIN|EPOLLERR|EPOLLHUP|EPOLLET; ev.events = EPOLLIN|EPOLLET;
ev.data.ptr = to; ev.data.ptr = to;
epoll_ctl(efd, EPOLL_CTL_MOD, to->fd, &ev); epoll_ctl(efd, EPOLL_CTL_MOD, to->fd, &ev);
} }
} }
else else
{ {
ev.events = EPOLLIN|EPOLLERR|EPOLLHUP|EPOLLET; ev.events = EPOLLIN|EPOLLET;
ev.data.ptr = to; ev.data.ptr = to;
epoll_ctl(efd, EPOLL_CTL_MOD, to->fd, &ev); epoll_ctl(efd, EPOLL_CTL_MOD, to->fd, &ev);
free(from->ready_data); free(from->ready_data);
@ -376,7 +386,7 @@ void tcp_out(conn_t *to)
else if (write_len > 0) else if (write_len > 0)
{ {
from->sent_len += write_len; from->sent_len += write_len;
ev.events = EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP|EPOLLET; ev.events = EPOLLIN|EPOLLOUT|EPOLLET;
ev.data.ptr = to; ev.data.ptr = to;
epoll_ctl(efd, EPOLL_CTL_MOD, to->fd, &ev); epoll_ctl(efd, EPOLL_CTL_MOD, to->fd, &ev);
} }
@ -397,7 +407,7 @@ void tcp_in(conn_t *in)
if ((in - cts) & 1) if ((in - cts) & 1)
{ {
in->last_event_time = (in-1)->last_event_time = time(NULL); in->last_event_time = (in-1)->last_event_time = time(NULL);
if (in->ready_data_len == 0) if (in->ready_data_len <= 0)
serverToClient(in); serverToClient(in);
return; return;
} }
@ -431,6 +441,7 @@ void tcp_in(conn_t *in)
close_connection(in); close_connection(in);
return; return;
} }
dataEncode(host, strlen(host));
/* 第一次读取数据 */ /* 第一次读取数据 */
if (in->reread_data == 0) if (in->reread_data == 0)
{ {
@ -487,30 +498,25 @@ void tcp_in(conn_t *in)
tcp_out(server); tcp_out(server);
} }
void *accept_loop(void *ptr) void accept_client()
{ {
struct epoll_event epollEvent; struct epoll_event epollEvent;
conn_t *client; conn_t *client;
/* 偶数为客户端,奇数为服务端 */
for (client = cts; client - cts < MAX_CONNECTION; client += 2)
if (client->fd < 0)
break;
if (client - cts >= MAX_CONNECTION)
return;
client->last_event_time = (client+1)->last_event_time = time(NULL);
client->fd = accept(lisFd, (struct sockaddr *)&addr, &addr_len);
if (client->fd < 0)
return;
fcntl(client->fd, F_SETFL, O_NONBLOCK);
epollEvent.events = EPOLLIN|EPOLLET; epollEvent.events = EPOLLIN|EPOLLET;
while (1) epollEvent.data.ptr = client;
{ epoll_ctl(efd, EPOLL_CTL_ADD, client->fd, &epollEvent);
/* 偶数为客户端,奇数为服务端 */
for (client = cts; client - cts < MAX_CONNECTION; client += 2)
if (client->fd < 0)
break;
if (client - cts >= MAX_CONNECTION)
{
sleep(3);
continue;
}
while ((client->fd = accept(lisFd, (struct sockaddr *)&addr, &addr_len)) < 0);
fcntl(client->fd, F_SETFL, O_NONBLOCK);
epollEvent.data.ptr = client;
epoll_ctl(efd, EPOLL_CTL_ADD, client->fd, &epollEvent);
}
return NULL;
} }
void create_listen(char *ip, int port) void create_listen(char *ip, int port)

6
http.h
View File

@ -6,7 +6,7 @@
typedef struct tcp_connection { typedef struct tcp_connection {
char *ready_data, *incomplete_data; char *ready_data, *incomplete_data;
int fd, ready_data_len, incomplete_data_len, sent_len; int fd, ready_data_len, incomplete_data_len, sent_len;
unsigned int last_event_time; time_t last_event_time;
uint16_t destPort; uint16_t destPort;
unsigned reread_data :1; unsigned reread_data :1;
unsigned request_type :1; unsigned request_type :1;
@ -15,7 +15,7 @@ typedef struct tcp_connection {
} conn_t; } conn_t;
extern void create_listen(char *ip, int port); extern void create_listen(char *ip, int port);
extern void *accept_loop(void *ptr); extern void accept_client();
extern void close_connection(conn_t *conn); extern void close_connection(conn_t *conn);
extern int8_t connectionToServer(char *ip, conn_t *server); extern int8_t connectionToServer(char *ip, conn_t *server);
extern void tcp_in(conn_t *ct); extern void tcp_in(conn_t *ct);
@ -24,6 +24,6 @@ extern void tcp_out(conn_t *ct);
extern conn_t cts[MAX_CONNECTION]; extern conn_t cts[MAX_CONNECTION];
extern char *local_header, *proxy_header, *ssl_proxy; extern char *local_header, *proxy_header, *ssl_proxy;
extern int lisFd, local_header_len, proxy_header_len; extern int lisFd, local_header_len, proxy_header_len;
extern uint8_t strict_spilce; extern uint8_t strict_spilce, sslEncodeCode;
#endif #endif

35
main.c
View File

@ -4,7 +4,7 @@
#include "dns.h" #include "dns.h"
#include <pthread.h> #include <pthread.h>
#define VERSION "0.2" #define VERSION "0.3"
#define DEFAULT_DNS_IP "114.114.114.114" #define DEFAULT_DNS_IP "114.114.114.114"
struct epoll_event evs[MAX_CONNECTION + 1], ev; struct epoll_event evs[MAX_CONNECTION + 1], ev;
@ -22,6 +22,7 @@ static void usage()
" -s ssl proxy string \033[35G default is 'CONNECT'\n" " -s ssl proxy string \033[35G default is 'CONNECT'\n"
" -t timeout \033[35G default is 35s\n" " -t timeout \033[35G default is 35s\n"
" -u uid \033[35G running uid\n" " -u uid \033[35G running uid\n"
" -e ssl data encode code \033[35G default is 0\n"
" -a \033[35G all http requests repeat spilce\n" " -a \033[35G all http requests repeat spilce\n"
" -h display this infomaction\n" " -h display this infomaction\n"
" -w worker process\n"); " -w worker process\n");
@ -30,20 +31,26 @@ static void usage()
static void server_loop() static void server_loop()
{ {
pthread_t thread_id; pthread_t thId;
int n; int n;
//单独进程accept多进程并发环境下不会惊群 ev.events = EPOLLIN|EPOLLET;
pthread_create(&thread_id, NULL, accept_loop, NULL);
ev.events = EPOLLIN;
ev.data.fd = dnsFd; ev.data.fd = dnsFd;
epoll_ctl(efd, EPOLL_CTL_ADD, dnsFd, &ev); epoll_ctl(efd, EPOLL_CTL_ADD, dnsFd, &ev);
ev.events = EPOLLIN;
ev.data.fd = lisFd;
epoll_ctl(efd, EPOLL_CTL_ADD, lisFd, &ev);
pthread_create(&thId, NULL, &close_timeout_connectionLoop, NULL);
while (1) while (1)
{ {
n = epoll_wait(efd, evs, MAX_CONNECTION + 1, -1); n = epoll_wait(efd, evs, MAX_CONNECTION + 1, -1);
while (n-- > 0) while (n-- > 0)
{ {
if (evs[n].data.fd == dnsFd) if (evs[n].data.fd == lisFd)
{
accept_client();
}
else if (evs[n].data.fd == dnsFd)
{ {
if (evs[n].events & EPOLLIN) if (evs[n].events & EPOLLIN)
read_dns_rsp(); read_dns_rsp();
@ -52,11 +59,6 @@ static void server_loop()
} }
else else
{ {
if ((evs[n].events & EPOLLERR) || (evs[n].events & EPOLLHUP))
{
if (((conn_t *)evs[n].data.ptr)->fd >= 0)
close_connection((conn_t *)evs[n].data.ptr);
}
if (evs[n].events & EPOLLIN) if (evs[n].events & EPOLLIN)
tcp_in((conn_t *)evs[n].data.ptr); tcp_in((conn_t *)evs[n].data.ptr);
if (evs[n].events & EPOLLOUT) if (evs[n].events & EPOLLOUT)
@ -81,7 +83,8 @@ static void initializate(int argc, char **argv)
dnsAddr.sin_addr.s_addr = inet_addr(DEFAULT_DNS_IP); dnsAddr.sin_addr.s_addr = inet_addr(DEFAULT_DNS_IP);
dnsAddr.sin_port = htons(53); dnsAddr.sin_port = htons(53);
dns_connect(&dnsAddr); //主进程中的fd dns_connect(&dnsAddr); //主进程中的fd
strict_spilce = timeout_seconds = 0; timeout_seconds = DEFAULT_TIMEOUT;
strict_spilce = sslEncodeCode = 0;
local_header = NULL; local_header = NULL;
ssl_proxy = (char *)"CONNECT"; ssl_proxy = (char *)"CONNECT";
local_header = (char *)"\nLocal:"; local_header = (char *)"\nLocal:";
@ -89,7 +92,7 @@ static void initializate(int argc, char **argv)
proxy_header_len = strlen(proxy_header); proxy_header_len = strlen(proxy_header);
local_header_len = strlen(local_header); local_header_len = strlen(local_header);
/* 处理命令行参数 */ /* 处理命令行参数 */
while ((opt = getopt(argc, argv, "d:l:p:s:w:t:u:L:ah")) != -1) while ((opt = getopt(argc, argv, "d:l:p:s:e:w:t:u:L:ah")) != -1)
{ {
switch (opt) switch (opt)
{ {
@ -148,12 +151,16 @@ static void initializate(int argc, char **argv)
ssl_proxy = optarg; ssl_proxy = optarg;
break; break;
case 'e':
sslEncodeCode = atoi(optarg);
break;
case 'a': case 'a':
strict_spilce = 1; strict_spilce = 1;
break; break;
case 't': case 't':
timeout_seconds = (unsigned int)atoi(optarg); timeout_seconds = (time_t)atoi(optarg);
break; break;
case 'w': case 'w':

View File

@ -2,26 +2,17 @@
#include "http.h" #include "http.h"
#include "time.h" #include "time.h"
unsigned int timeout_seconds; int timeout_seconds;
void *close_timeout_connectionLoop(void *nullPtr) void *close_timeout_connectionLoop(void *nullPtr)
{ {
time_t currentTime; int i;
int i, recv_return;
char c;
while (1) while (1)
{ {
sleep(1); sleep(1);
currentTime = time(NULL);
for (i = 0; i < MAX_CONNECTION; i += 2) for (i = 0; i < MAX_CONNECTION; i += 2)
{ if (cts[i].fd > -1&& (int)(time(NULL) - cts[i].last_event_time) >= timeout_seconds)
if (cts[i].fd > -1 && cts[i].is_ssl == 0 && cts[i].last_event_time != 0 && currentTime - cts[i].last_event_time >= (time_t)timeout_seconds) close_connection(cts + i);
{
recv_return = recv(cts[i].fd, &c, 1, MSG_PEEK);
if (recv_return == 0 && errno != EAGAIN)
close_connection(cts + i);
}
}
} }
} }

View File

@ -1,11 +1,11 @@
#ifndef TIME_H #ifndef TIME_H
#define TIME_H #define TIME_H
#define DEFAULT_TIMEOUT 35 #define DEFAULT_TIMEOUT 60
#include <time.h> #include <time.h>
extern unsigned int timeout_seconds; extern int timeout_seconds;
void *close_timeout_connectionLoop(void *nullPtr); void *close_timeout_connectionLoop(void *nullPtr);