216 lines
6.1 KiB
C
216 lines
6.1 KiB
C
|
#include "main.h"
|
|||
|
#include "http.h"
|
|||
|
#include "dns.h"
|
|||
|
#include <pthread.h>
|
|||
|
|
|||
|
#define VERSION "0.1"
|
|||
|
#define DEFAULT_DNS_IP "114.114.114.114"
|
|||
|
|
|||
|
struct epoll_event evs[MAX_CONNECTION + 2], ev;
|
|||
|
struct sockaddr_in addr;
|
|||
|
socklen_t addr_len;
|
|||
|
int efd;
|
|||
|
|
|||
|
static void usage()
|
|||
|
{
|
|||
|
puts("SpecialProxy(" VERSION "):\n"
|
|||
|
" -l [listenip:]listenport \033[35G default ip is 0.0.0.0\n"
|
|||
|
" -p proxy header \033[35G default is 'Host'\n"
|
|||
|
" -L local proxy header \033[35G default is 'Local'\n"
|
|||
|
" -d dns query address \033[35G default is " DEFAULT_DNS_IP "\n"
|
|||
|
" -s ssl proxy string \033[35G default is 'CONNECT'\n"
|
|||
|
" -a \033[35G all http requests repeat spilce\n"
|
|||
|
" -h display this infomaction\n"
|
|||
|
" -w worker process\n");
|
|||
|
exit(0);
|
|||
|
}
|
|||
|
|
|||
|
static void server_loop()
|
|||
|
{
|
|||
|
pthread_t thread_id;
|
|||
|
int n;
|
|||
|
|
|||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>accept<70><74><EFBFBD><EFBFBD><EFBFBD>̲<EFBFBD><CCB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>²<EFBFBD><C2B2>ᾪȺ
|
|||
|
pthread_create(&thread_id, NULL, accept_loop, NULL);
|
|||
|
ev.events = EPOLLIN;
|
|||
|
ev.data.fd = dnsFd;
|
|||
|
epoll_ctl(efd, EPOLL_CTL_ADD, dnsFd, &ev);
|
|||
|
while (1)
|
|||
|
{
|
|||
|
n = epoll_wait(efd, evs, MAX_CONNECTION + 2, -1);
|
|||
|
while (n-- > 0)
|
|||
|
{
|
|||
|
if (evs[n].data.fd == dnsFd)
|
|||
|
{
|
|||
|
if (evs[n].events & EPOLLIN)
|
|||
|
read_dns_rsp();
|
|||
|
if (evs[n].events & EPOLLOUT)
|
|||
|
dns_query();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (evs[n].events & EPOLLIN)
|
|||
|
tcp_in((conn_t *)evs[n].data.ptr);
|
|||
|
if (evs[n].events & EPOLLOUT)
|
|||
|
tcp_out((conn_t *)evs[n].data.ptr);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static void initializate(int argc, char **argv)
|
|||
|
{
|
|||
|
struct sockaddr_in dnsAddr;
|
|||
|
char *p;
|
|||
|
int opt, i, workers = 1;
|
|||
|
|
|||
|
addr_len = sizeof(addr);
|
|||
|
lisFd = -1;
|
|||
|
efd = epoll_create(MAX_CONNECTION + 2);
|
|||
|
if (efd < 0)
|
|||
|
{
|
|||
|
perror("epoll_create");
|
|||
|
exit(1);
|
|||
|
}
|
|||
|
dnsAddr.sin_family = addr.sin_family = AF_INET;
|
|||
|
//Ĭ<><C4AC>dns<6E><73>ַ
|
|||
|
dnsAddr.sin_addr.s_addr = inet_addr(DEFAULT_DNS_IP);
|
|||
|
dnsAddr.sin_port = htons(53);
|
|||
|
dns_connect(&dnsAddr); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>fd
|
|||
|
strict_spilce = 0;
|
|||
|
local_header = NULL;
|
|||
|
ssl_proxy = (char *)"CONNECT";
|
|||
|
local_header = (char *)"\nLocal:";
|
|||
|
proxy_header = (char *)"\nHost:";
|
|||
|
proxy_header_len = strlen(proxy_header);
|
|||
|
local_header_len = strlen(local_header);
|
|||
|
/* <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><D0B2><EFBFBD> */
|
|||
|
while ((opt = getopt(argc, argv, "d:l:p:s:w:L:ah")) != -1)
|
|||
|
{
|
|||
|
switch (opt)
|
|||
|
{
|
|||
|
case 'd':
|
|||
|
p = strchr(optarg, ':');
|
|||
|
if (p)
|
|||
|
{
|
|||
|
*p = '\0';
|
|||
|
dnsAddr.sin_port = htons(atoi(p+1));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
dnsAddr.sin_port = htons(53);
|
|||
|
}
|
|||
|
dnsAddr.sin_addr.s_addr = inet_addr(optarg);
|
|||
|
connect(dnsFd, (struct sockaddr *)&dnsAddr, sizeof(dnsAddr));
|
|||
|
break;
|
|||
|
|
|||
|
case 'l':
|
|||
|
p = strchr(optarg, ':');
|
|||
|
if (p)
|
|||
|
{
|
|||
|
*p = '\0';
|
|||
|
create_listen(optarg, atoi(p+1));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
create_listen((char *)"0.0.0.0", atoi(optarg));
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case 'p':
|
|||
|
//<2F><><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>ֵΪ "Proxy", proxy_header<65><72><EFBFBD><EFBFBD>Ϊ "\nProxy:"
|
|||
|
proxy_header_len = strlen(optarg) + 2;
|
|||
|
if (optarg[proxy_header_len] == ':')
|
|||
|
optarg[proxy_header_len--] = '\0';
|
|||
|
proxy_header = (char *)malloc(proxy_header_len + 1);
|
|||
|
if (proxy_header == NULL)
|
|||
|
{
|
|||
|
fputs("out of memory.\n", stderr);
|
|||
|
exit(1);
|
|||
|
}
|
|||
|
sprintf(proxy_header, "\n%s:", optarg);
|
|||
|
break;
|
|||
|
|
|||
|
case 'L':
|
|||
|
local_header_len = strlen(optarg) + 2;
|
|||
|
if (optarg[local_header_len] == ':')
|
|||
|
optarg[local_header_len--] = '\0';
|
|||
|
local_header = (char *)malloc(local_header_len + 1);
|
|||
|
if (local_header == NULL)
|
|||
|
{
|
|||
|
fputs("out of memory.\n", stderr);
|
|||
|
exit(1);
|
|||
|
}
|
|||
|
sprintf(local_header, "\n%s:", optarg);
|
|||
|
break;
|
|||
|
|
|||
|
case 's':
|
|||
|
ssl_proxy = optarg;
|
|||
|
break;
|
|||
|
|
|||
|
case 'a':
|
|||
|
strict_spilce = 1;
|
|||
|
break;
|
|||
|
|
|||
|
case 'w':
|
|||
|
workers = atoi(optarg);
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
usage();
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
if (lisFd < 0)
|
|||
|
{
|
|||
|
fputs("no listen address\n", stderr);
|
|||
|
exit(1);
|
|||
|
}
|
|||
|
memset(cts, 0, sizeof(cts));
|
|||
|
for (i = MAX_CONNECTION; i--; )
|
|||
|
cts[i].fd = -1;
|
|||
|
//Ϊ<><CEAA><EFBFBD><EFBFBD><EFBFBD>˵Ľṹ<C4BD><E1B9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
|
|||
|
for (i = 1; i < MAX_CONNECTION; i += 2)
|
|||
|
{
|
|||
|
cts[i].ready_data = (char *)malloc(BUFFER_SIZE);
|
|||
|
if (cts[i].ready_data == NULL)
|
|||
|
{
|
|||
|
fputs("out of memory.", stderr);
|
|||
|
exit(1);
|
|||
|
}
|
|||
|
}
|
|||
|
memset(dns_list, 0, sizeof(dns_list));
|
|||
|
for (i = MAX_CONNECTION / 2; i--; )
|
|||
|
{
|
|||
|
memcpy(dns_list[i].request, &i, sizeof(uint16_t));
|
|||
|
dns_list[i].request[2] = 1;
|
|||
|
dns_list[i].request[3] = 0;
|
|||
|
dns_list[i].request[4] = 0;
|
|||
|
dns_list[i].request[5] = 1;
|
|||
|
dns_list[i].request[6] = 0;
|
|||
|
dns_list[i].request[7] = 0;
|
|||
|
dns_list[i].request[8] = 0;
|
|||
|
dns_list[i].request[9] = 0;
|
|||
|
dns_list[i].request[10] = 0;
|
|||
|
dns_list[i].request[11] = 0;
|
|||
|
}
|
|||
|
signal(SIGPIPE, SIG_IGN);
|
|||
|
while (workers-- > 1 && fork() == 0)
|
|||
|
//<2F>ӽ<EFBFBD><D3BD><EFBFBD><EFBFBD>е<EFBFBD>dnsFd<46><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>룬<EFBFBD><EBA3AC>Ȼepoll<6C><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܶ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̵õ<CCB5><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
dns_connect(&dnsAddr);
|
|||
|
}
|
|||
|
|
|||
|
int main(int argc, char **argv)
|
|||
|
{
|
|||
|
initializate(argc, argv);
|
|||
|
//if (daemon(1, 1))
|
|||
|
if (daemon(1, 0))
|
|||
|
{
|
|||
|
perror("daemon");
|
|||
|
return 1;
|
|||
|
}
|
|||
|
server_loop();
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|