Add files via upload

This commit is contained in:
mmmdbybyd 2019-01-26 11:53:32 +08:00 committed by GitHub
parent 03192d9e8f
commit 3a4c630c86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 112 additions and 120 deletions

View File

@ -1,6 +1,7 @@
OBJ := SpecialProxy OBJ := SpecialProxy
CC := gcc CC := gcc
CFLAGS := -O2 -Wall -pthread CFLAGS := -O2 -Wall -pthread
STRIP := strip
#如果是安卓编译 #如果是安卓编译
ifeq ($(ANDROID_DATA),/data) ifeq ($(ANDROID_DATA),/data)
CFLAGS := -O2 -pie -Wall CFLAGS := -O2 -pie -Wall
@ -10,7 +11,7 @@ endif
all : main.o http.o dns.o timeout.o all : main.o http.o dns.o timeout.o
$(CC) $(CFLAGS) $(DEFS) -o $(OBJ) $^ $(CC) $(CFLAGS) $(DEFS) -o $(OBJ) $^
strip $(OBJ) $(STRIP) $(OBJ)
-chmod 777 $(OBJ) 2>&- -chmod 777 $(OBJ) 2>&-
.c.o : .c.o :

View File

@ -21,13 +21,16 @@ SpecialProxy
服务器的返回数据也编码 服务器的返回数据也编码
##### 启动参数: ##### 启动参数:
-l [监听ip:]监听端口 默认监听IP为 "0.0.0.0" -l [监听ip:]监听端口 默认监听IP为 "0.0.0.0"
-p 代理头域 默认为 "Host" -p 代理头域 默认为 "Host"
-L 本地代理头域 默认为 "Local" -L 本地代理头域 默认为 "Local"
-d DNS查询IP[:端口] 默认为 "114.114.114.114" -d DNS查询IP[:端口] 默认为 "114.114.114.114"
-s SSL代理字符串 默认为 "CONNECT" -s SSL代理字符串 默认为 "CONNECT"
-e host和数据的编码代码(128-255) 默认为0不编码
-t 连接超时时间, 单位: 分 默认不超时
-i 忽略host前字符个数 默认为0
-u 设置uid -u 设置uid
-a 对所有HTTP请求重新拼接 -a 对所有HTTP请求重新拼接
-h 显示帮助 -h 显示帮助
-w 工作进程数 -w 工作进程数

39
dns.c
View File

@ -1,24 +1,23 @@
#include "dns.h" #include "dns.h"
#include "http.h" #include "http.h"
struct dns dns_list[MAX_CONNECTION / 2]; //一个客户端 + 一个服务端 占用一个dns结构体 struct dns dns_list[MAX_CONNECTION >> 1]; //一个客户端 + 一个服务端 占用一个dns结构体
int dnsFd; int dnsFd;
void read_dns_rsp() void read_dns_rsp()
{ {
char rsp_data[512], *p, ip[16]; static char rsp_data[512], *ip, *p;
unsigned char *_p;
struct dns *dns; struct dns *dns;
conn_t *client; conn_t *client;
int16_t len, dns_flag; int16_t len, dns_id;
while ((len = read(dnsFd, rsp_data, 512)) > 11) while ((len = read(dnsFd, rsp_data, 512)) > 11)
{ {
memcpy(&dns_flag, rsp_data, 2); memcpy(&dns_id, rsp_data, 2);
dns = dns_list + dns_flag; dns = dns_list + dns_id;
client = cts + (dns_flag << 1); client = cts + (dns_id << 1);
//判断是否是正常DNS回应是否已关闭连接 //判断是否是正常DNS回应是否已关闭连接
if (dns_flag > MAX_CONNECTION >> 1 || client->fd < 0) if (dns_id > MAX_CONNECTION >> 1 || client->fd < 0)
continue; continue;
if (dns->request_len + 12 > len || (unsigned char)rsp_data[3] != 128) //char只有7位可用则正数最高为127 if (dns->request_len + 12 > len || (unsigned char)rsp_data[3] != 128) //char只有7位可用则正数最高为127
{ {
@ -28,7 +27,7 @@ void read_dns_rsp()
/* get domain ip */ /* get domain ip */
p = rsp_data + dns->request_len + 11; p = rsp_data + dns->request_len + 11;
ip[0] = 0; ip = NULL;
while (p - rsp_data + 4 <= len) while (p - rsp_data + 4 <= len)
{ {
//type //type
@ -37,19 +36,10 @@ void read_dns_rsp()
p += *p + 12; p += *p + 12;
continue; continue;
} }
_p = (unsigned char *)p + 1; ip = p + 1;
sprintf(ip, "%d.%d.%d.%d", _p[0], _p[1], _p[2], _p[3]);
break; break;
} }
if (ip[0]) if (ip == NULL || connectionToServer(*(in_addr_t *)ip, client + 1) != 0)
{
if (connectionToServer(ip, client + 1) != 0)
{
close_connection(client);
continue;
}
}
else
{ {
close_connection(client); close_connection(client);
continue; continue;
@ -62,15 +52,14 @@ static int8_t send_dns_req(struct dns *dns)
{ {
int write_len; int write_len;
write_len = write(dnsFd, dns->request + dns->sent_len, dns->request_len - dns->sent_len); write_len = write(dnsFd, dns->request, dns->request_len);
if (write_len == dns->request_len - dns->sent_len) if (write_len == dns->request_len - dns->sent_len)
{ {
dns->sent_len = dns->request_len; dns->sent_len = dns->request_len;
return 0; return 0;
} }
else if (write_len >= 0) else if (write_len > 0)
{ {
dns->sent_len += write_len;
return 1; return 1;
} }
else else
@ -110,8 +99,7 @@ int8_t build_dns_req(struct dns *dns, char *domain)
domain_size = strlen(domain); domain_size = strlen(domain);
p = dns->request + 12; p = dns->request + 12;
memcpy(p+1, domain, domain_size); memcpy(p+1, domain, domain_size + 1);
*(p+1+domain_size) = 0;
while ((_p = strchr(p+1, '.')) != NULL) while ((_p = strchr(p+1, '.')) != NULL)
{ {
*p = _p - p - 1; *p = _p - p - 1;
@ -127,7 +115,6 @@ int8_t build_dns_req(struct dns *dns, char *domain)
switch (send_dns_req(dns)) switch (send_dns_req(dns))
{ {
case 0: case 0:
ev.data.fd = dnsFd;
return 0; return 0;
case 1: case 1:

60
http.c
View File

@ -2,31 +2,33 @@
#include "dns.h" #include "dns.h"
#include "timeout.h" #include "timeout.h"
#define SSL_RSP "HTTP/1.1 200 Connection established\r\n\r\n" #define SSL_RSP "HTTP/1.1 200 Connection established\r\nVia: SpecialProxy_CuteBi\r\n\r\n"
#define HTTP_TYPE 0 #define HTTP_TYPE 0
#define OTHER_TYPE 1 #define OTHER_TYPE 1
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, ignore_host_before_count;
uint8_t strict_spilce, sslEncodeCode; uint8_t strict_spilce, sslEncodeCode;
/* 对数据进行编码 */ /* 对数据进行编码 */
static void dataEncode(char *data, int data_len) static void dataEncode(char *data, int data_len)
{ {
if (sslEncodeCode == 0) if (sslEncodeCode)
return; while (data_len-- > 0)
while (data_len-- > 0) data[data_len] ^= sslEncodeCode;
data[data_len] ^= sslEncodeCode;
} }
int8_t connectionToServer(char *ip, conn_t *server) int8_t connectionToServer(in_addr_t ip, conn_t *server)
{ {
struct sockaddr_in addr;
server->fd = socket(AF_INET, SOCK_STREAM, 0); server->fd = socket(AF_INET, SOCK_STREAM, 0);
if (server->fd < 0) if (server->fd < 0)
return 1; return 1;
fcntl(server->fd, F_SETFL, O_NONBLOCK); fcntl(server->fd, F_SETFL, O_NONBLOCK);
addr.sin_addr.s_addr = inet_addr(ip); addr.sin_family = AF_INET;
addr.sin_addr.s_addr = ip;
addr.sin_port = htons(server->destPort); addr.sin_port = htons(server->destPort);
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;
@ -121,6 +123,7 @@ static char *read_data(conn_t *in, char *data, int *data_len)
static char *get_host(char *data) static char *get_host(char *data)
{ {
char *hostEnd, *host; char *hostEnd, *host;
int i;
host = strstr(data, local_header); host = strstr(data, local_header);
if (host != NULL) if (host != NULL)
@ -128,7 +131,7 @@ static char *get_host(char *data)
char *local_host; char *local_host;
host += local_header_len; host += local_header_len;
while (*host == ' ') while (*host == ' ' || *host == '\t')
host++; host++;
for (hostEnd = host; *hostEnd < 58 && *hostEnd > 48; hostEnd++); for (hostEnd = host; *hostEnd < 58 && *hostEnd > 48; hostEnd++);
//判断该头域是否正确使用 //判断该头域是否正确使用
@ -146,29 +149,25 @@ static char *get_host(char *data)
if (host == NULL) if (host == NULL)
return NULL; return NULL;
host += proxy_header_len; host += proxy_header_len;
while (*host == ' ') while (*host == ' ' || *host == '\t')
host++; host++;
for (i = 0; i < ignore_host_before_count; i++)
if (host[i] == '\0') //防止越界
break;
host += i;
hostEnd = strchr(host, '\r'); hostEnd = strchr(host, '\r');
if (hostEnd) return hostEnd ? strndup(host, hostEnd - host) : strdup(host);
return strndup(host, hostEnd - host);
else
return strdup(host);
} }
/* 删除请求头中的头域 */ /* 删除请求头中的头域 */
static void del_hdr(char *header, int *header_len) static void del_hdr(char *header, int *header_len)
{ {
char *key_end, *line_begin, *line_end; char *line_begin, *line_end;
int key_len;
for (line_begin = strchr(header, '\n'); line_begin++ && *line_begin != '\r'; line_begin = line_end) for (line_begin = strchr(header, '\n'); line_begin++ && *line_begin != '\r'; line_begin = line_end)
{ {
key_end = strchr(line_begin, ':'); line_end = strchr(line_begin, '\n');
if (key_end == NULL) if (strncasecmp(line_begin, "host:", 5) == 0 || strncasecmp(line_begin, local_header + 1, local_header_len - 1) == 0 || strncasecmp(line_begin, proxy_header + 1, proxy_header_len - 1) == 0)
return;
key_len = key_end - line_begin;
line_end = strchr(key_end, '\n');
if (strncasecmp(line_begin, "host", key_len) == 0 || strncmp(line_begin, local_header + 1, key_len) == 0 || strncmp(line_begin, proxy_header + 1, key_len) == 0)
{ {
if (line_end++) if (line_end++)
{ {
@ -273,7 +272,7 @@ static int8_t parse_host(conn_t *server, char *host)
for (p = host; (*p > 47 && *p < 58) || *p == '.'; p++); for (p = host; (*p > 47 && *p < 58) || *p == '.'; p++);
if (*p == '\0') if (*p == '\0')
{ {
if (connectionToServer(host, server) != 0) if (connectionToServer(inet_addr(host), server) != 0)
return 1; return 1;
} }
else if (build_dns_req(dns_list + ((server - cts) >> 1), host) == -1) else if (build_dns_req(dns_list + ((server - cts) >> 1), host) == -1)
@ -358,7 +357,7 @@ void tcp_out(conn_t *to)
from = to - 1; from = to - 1;
else else
from = to + 1; from = to + 1;
from->last_event_time = to->last_event_time = time(NULL); from->timer = to->timer = 0;
write_len = write(to->fd, from->ready_data + from->sent_len, from->ready_data_len - from->sent_len); write_len = write(to->fd, from->ready_data + from->sent_len, from->ready_data_len - from->sent_len);
if (write_len == from->ready_data_len - from->sent_len) if (write_len == from->ready_data_len - from->sent_len)
{ {
@ -406,13 +405,13 @@ void tcp_in(conn_t *in)
//如果in - cts是奇数那么是服务端触发事件 //如果in - cts是奇数那么是服务端触发事件
if ((in - cts) & 1) if ((in - cts) & 1)
{ {
in->last_event_time = (in-1)->last_event_time = time(NULL); in->timer = (in-1)->timer = 0;
if (in->ready_data_len <= 0) if (in->ready_data_len <= 0)
serverToClient(in); serverToClient(in);
return; return;
} }
in->last_event_time = (in+1)->last_event_time = time(NULL); in->timer = (in+1)->timer = 0;
in->incomplete_data = read_data(in, in->incomplete_data, &in->incomplete_data_len); in->incomplete_data = read_data(in, in->incomplete_data, &in->incomplete_data_len);
if (in->incomplete_data == NULL) if (in->incomplete_data == NULL)
{ {
@ -501,7 +500,9 @@ void tcp_in(conn_t *in)
void accept_client() void accept_client()
{ {
struct epoll_event epollEvent; struct epoll_event epollEvent;
struct sockaddr_in addr;
conn_t *client; conn_t *client;
socklen_t addr_len = sizeof(addr);
/* 偶数为客户端,奇数为服务端 */ /* 偶数为客户端,奇数为服务端 */
for (client = cts; client - cts < MAX_CONNECTION; client += 2) for (client = cts; client - cts < MAX_CONNECTION; client += 2)
@ -509,7 +510,7 @@ void accept_client()
break; break;
if (client - cts >= MAX_CONNECTION) if (client - cts >= MAX_CONNECTION)
return; return;
client->last_event_time = (client+1)->last_event_time = time(NULL); client->timer = (client+1)->timer = 0;
client->fd = accept(lisFd, (struct sockaddr *)&addr, &addr_len); client->fd = accept(lisFd, (struct sockaddr *)&addr, &addr_len);
if (client->fd < 0) if (client->fd < 0)
return; return;
@ -521,6 +522,7 @@ void accept_client()
void create_listen(char *ip, int port) void create_listen(char *ip, int port)
{ {
struct sockaddr_in addr;
int optval = 1; int optval = 1;
if ((lisFd = socket(AF_INET, SOCK_STREAM, 0)) < 0) if ((lisFd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
@ -528,6 +530,7 @@ void create_listen(char *ip, int port)
perror("socket"); perror("socket");
exit(1); exit(1);
} }
addr.sin_family = AF_INET;
addr.sin_port = htons(port); addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(ip); addr.sin_addr.s_addr = inet_addr(ip);
if (setsockopt(lisFd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) if (setsockopt(lisFd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0)
@ -546,6 +549,3 @@ void create_listen(char *ip, int port)
exit(1); exit(1);
} }
} }

11
http.h
View File

@ -5,8 +5,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, timer;
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;
@ -17,13 +16,13 @@ typedef struct tcp_connection {
extern void create_listen(char *ip, int port); extern void create_listen(char *ip, int port);
extern void accept_client(); 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(in_addr_t ip, conn_t *server);
extern void tcp_in(conn_t *ct); extern void tcp_in(conn_t *in);
extern void tcp_out(conn_t *ct); extern void tcp_out(conn_t *to);
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, ignore_host_before_count;
extern uint8_t strict_spilce, sslEncodeCode; extern uint8_t strict_spilce, sslEncodeCode;
#endif #endif

36
main.c
View File

@ -4,12 +4,10 @@
#include "dns.h" #include "dns.h"
#include <pthread.h> #include <pthread.h>
#define VERSION "0.3" #define VERSION "0.4"
#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;
struct sockaddr_in addr;
socklen_t addr_len;
int efd; int efd;
static void usage() static void usage()
@ -20,9 +18,10 @@ static void usage()
" -L local proxy header \033[35G default is 'Local'\n" " -L local proxy header \033[35G default is 'Local'\n"
" -d dns query address \033[35G default is " DEFAULT_DNS_IP "\n" " -d dns query address \033[35G default is " DEFAULT_DNS_IP "\n"
" -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 minute \033[35G default is no timeout\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" " -e ssl data encode code(128-255) \033[35G default is 0\n"
" -i ignore host before string count \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");
@ -40,7 +39,8 @@ static void server_loop()
ev.events = EPOLLIN; ev.events = EPOLLIN;
ev.data.fd = lisFd; ev.data.fd = lisFd;
epoll_ctl(efd, EPOLL_CTL_ADD, lisFd, &ev); epoll_ctl(efd, EPOLL_CTL_ADD, lisFd, &ev);
pthread_create(&thId, NULL, &close_timeout_connectionLoop, NULL); if (timeout_minute)
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);
@ -74,17 +74,15 @@ static void initializate(int argc, char **argv)
char *p; char *p;
int opt, i, workers; int opt, i, workers;
/* 初始化部分变量值 */ /* 初始化部分变量值 */
addr_len = sizeof(addr);
lisFd = -1; lisFd = -1;
workers = 1; workers = 1;
dnsAddr.sin_family = addr.sin_family = AF_INET; dnsAddr.sin_family = AF_INET;
//默认dns地址 //默认dns地址
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
timeout_seconds = DEFAULT_TIMEOUT; ignore_host_before_count = timeout_minute = strict_spilce = sslEncodeCode = 0;
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:";
@ -92,7 +90,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:e:w:t:u:L:ah")) != -1) while ((opt = getopt(argc, argv, "d:l:p:s:e:i:w:t:u:L:ah")) != -1)
{ {
switch (opt) switch (opt)
{ {
@ -155,12 +153,16 @@ static void initializate(int argc, char **argv)
sslEncodeCode = atoi(optarg); sslEncodeCode = atoi(optarg);
break; break;
case 'i':
ignore_host_before_count = atoi(optarg);
break;
case 'a': case 'a':
strict_spilce = 1; strict_spilce = 1;
break; break;
case 't': case 't':
timeout_seconds = (time_t)atoi(optarg); timeout_minute = (time_t)atoi(optarg);
break; break;
case 'w': case 'w':
@ -185,7 +187,7 @@ static void initializate(int argc, char **argv)
break; break;
} }
} }
/* 初始化剩下的变量值 */ /* 初始化的变量值 */
if (lisFd < 0) if (lisFd < 0)
{ {
fputs("no listen address\n", stderr); fputs("no listen address\n", stderr);
@ -204,9 +206,9 @@ static void initializate(int argc, char **argv)
exit(1); exit(1);
} }
} }
//设置dns请求头首部 //设置dns请求头首部
memset(dns_list, 0, sizeof(dns_list)); memset(dns_list, 0, sizeof(dns_list));
for (i = MAX_CONNECTION / 2; i--; ) for (i = MAX_CONNECTION >> 1; i--; )
{ {
memcpy(dns_list[i].request, &i, sizeof(uint16_t)); memcpy(dns_list[i].request, &i, sizeof(uint16_t));
dns_list[i].request[2] = 1; dns_list[i].request[2] = 1;

View File

@ -1,8 +1,7 @@
#include "main.h" #include "main.h"
#include "http.h" #include "http.h"
#include "time.h"
int timeout_seconds; int timeout_minute;
void *close_timeout_connectionLoop(void *nullPtr) void *close_timeout_connectionLoop(void *nullPtr)
{ {
@ -10,9 +9,14 @@ void *close_timeout_connectionLoop(void *nullPtr)
while (1) while (1)
{ {
sleep(1); sleep(60);
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)
close_connection(cts + i); {
if (cts[i].timer >= timeout_minute)
close_connection(cts + i);
else
cts[i].timer = 0;
}
} }
} }

View File

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