Add files via upload

This commit is contained in:
mmmdbybyd 2019-03-10 05:23:50 +08:00 committed by GitHub
parent a4c9932ec1
commit 6e23178411
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 46 additions and 23 deletions

View File

@ -1,24 +1,29 @@
SpecialProxy
======
用epoll多路复用io写的一个HTTP代理轻快自带DNS解析
用epoll多路复用io写的一个超匿HTTP代理轻快自带DNS解析
主要用来配合客户端: https://github.com/mmmdbybyd/CProxy
##### SpecialProxy有如下特性
1. 普通HTTP代理通过请求头首行的host或者Host头域字段获得目标主机
SpecialProxy不从首行获取目标主机
它可以自定义代理头域默认是Host
SpecialProxy不从首行获取目标主机 它可以自定义代理头域默认是Host
普通http代理用默认的'Host'Host伪装使用自定义代理
2. 普通HTTP代理SSL代理是判断CONNECT请求方法
SpecialProxy可以通过自定义特定字符串进行SSL代理默认是CONNECT
用于将TCP伪装成HTTP流量
3. 普通HTTP代理如果遇到多个连续的HTTP请求头只重新拼接第一个请求头
SpecialProxy可以开启严格模式-a参数对所以请求头都重新拼接。
用于处理客户端一个连接同时发送多个HTTP请求头
4. -L参数设置重定向到本地端口的头域比如-L Local
然后请求头中含有Local: 443代理会将请求发送到127.0.0.1:443
然后请求头中含有Local: 443代理会将请求发送到127.0.0.1:443。
用于openvpn转接之类的
5. -e设置数据编码的代码
对客户端Host以及请求附带的数据编码
服务器的返回数据也编码
服务器的返回数据也编码。
用于科学上网
##### 启动参数:
-l [监听ip:]监听端口 默认监听IP为 "0.0.0.0"
@ -28,7 +33,7 @@ SpecialProxy
-s SSL代理字符串 默认为 "CONNECT"
-e host和数据的编码代码(128-255) 默认为0不编码
-t 连接超时时间, 单位: 分 默认不超时
-i 忽略host前字符个数 默认为0
-i 忽略host前字符个数 默认为0(部分人用得到)
-u 设置uid
-a 对所有HTTP请求重新拼接
-h 显示帮助
@ -41,6 +46,10 @@ SpecialProxy
~~~~~
Linux/Android:
make
Android-ndk:
ndk-build
~~~~~
##### 启动:
~~~~~
#SpecialProxy -l 监听端口 -p 代理头 -t 超时(分钟) -e 加密编码 -d dnsIP
SpecialProxy -l 80 -p Meng -t 2 -e 170 -d 8.8.8.8
~~~~~

View File

@ -13,8 +13,7 @@ do
echo "Please input 1-65535."
done
read -p "Please input SpecialProxy proxy header(default is 'Meng'): " proxy_header
echo -n "Please input SpecialProxy encode code(default is 0, no encode): "
read encodeCode
read -p "Please input SpecialProxy encode code(default is 0, no encode): " encodeCode
apt-get -y gcc make git || yum install -y gcc make git
git clone https://github.com/mmmdbybyd/SpecialProxy.git
[ ! -d SpecialProxy ] && Exit "\033[41;37mdownload SpecialProxy source code failed\033[0m"
@ -23,4 +22,4 @@ make || Exit "\033[41;37mcompile tinyproxy failed\033[0m"
dnsip=`grep nameserver /etc/resolv.conf | grep -Eo '[1-9]{1,3}[0-9]{0,2}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -n 1`
./SpecialProxy -l $server_port -p ${proxy_header:-Meng} -t 5 -d ${dnsip:-114.114.114.114} -e ${encodeCode:-0} && \
Exit "\033[32mSpeciaoProxy is running.\033[0m" || \
Exit "\033[41;37mSpeciaoProxy is stopping.\033[0m"
Exit "\033[41;37mSpeciaoProxy is stopping.\033[0m"

24
http.c
View File

@ -2,7 +2,9 @@
#include "dns.h"
#include "timeout.h"
#define SSL_RSP "HTTP/1.1 200 Connection established\r\nVia: SpecialProxy_CuteBi\r\n\r\n"
#define SSL_RSP_CONNECT "HTTP/1.1 200 Connection established\r\nServer: SpecialProxy_CuteBi\r\nConnection: keep-alive\r\n\r\n"
#define SSL_RSP_HTTP "HTTP/1.1 200 OK\r\nContent-length: 99999999\r\nServer: SpecialProxy_CuteBi\r\nContent-Type: text/plain; charset=utf-8\r\nConnection: keep-alive\r\n\r\n"
#define SSL_RSP_WEBSOCKET "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: SpecialProxy_CuteBi\r\n\r\n"
#define HTTP_TYPE 0
#define OTHER_TYPE 1
@ -395,6 +397,22 @@ void tcp_out(conn_t *to)
}
}
/* ssl代理回应 */
static int respond_sslStatus(conn_t *in)
{
/*
使http请求伪装CONNECT代理
使fd是非阻塞也只需要判断返回值是否小于0
*/
if (memcmp(in->incomplete_data, "CON", 3) == 0)
return (write(in->fd, SSL_RSP_CONNECT, sizeof(SSL_RSP_CONNECT)-1) <= 0);
else if (*in->incomplete_data == 'G' && (strstr(in->incomplete_data, "websocket") || strstr(in->incomplete_data, "WebSocket")))
return (write(in->fd, SSL_RSP_WEBSOCKET, sizeof(SSL_RSP_WEBSOCKET)-1) <= 0);
return (write(in->fd, SSL_RSP_HTTP, sizeof(SSL_RSP_HTTP)-1) <= 0);
}
void tcp_in(conn_t *in)
{
conn_t *server;
@ -453,9 +471,7 @@ void tcp_in(conn_t *in)
}
if (strstr(in->incomplete_data, ssl_proxy))
{
server->is_ssl = in->is_ssl = 1;
/* 这时候即使fd是非阻塞也只需要判断返回值是否小于0 */
if (write(in->fd, SSL_RSP, sizeof(SSL_RSP)-1) < 0)
if (respond_sslStatus(in) != 0)
{
free(host);
close_connection(in);

7
http.h
View File

@ -7,10 +7,9 @@ typedef struct tcp_connection {
char *ready_data, *incomplete_data;
int fd, ready_data_len, incomplete_data_len, sent_len, timer;
uint16_t destPort;
unsigned reread_data :1;
unsigned request_type :1;
unsigned keep_alive :1;
unsigned is_ssl :1;
unsigned reread_data :1,
request_type :1,
keep_alive :1;
} conn_t;
extern void create_listen(char *ip, int port);

8
main.c
View File

@ -4,8 +4,7 @@
#include "dns.h"
#include <pthread.h>
#define VERSION "0.4"
#define DEFAULT_DNS_IP "114.114.114.114"
#define VERSION "0.5"
struct epoll_event evs[MAX_CONNECTION + 1], ev;
int efd;
@ -81,7 +80,7 @@ static void initializate(int argc, char **argv)
//默认dns地址
dnsAddr.sin_addr.s_addr = inet_addr(DEFAULT_DNS_IP);
dnsAddr.sin_port = htons(53);
dns_connect(&dnsAddr); //主进程中的fd
dns_connect(&dnsAddr);
ignore_host_before_count = timeout_minute = strict_spilce = sslEncodeCode = 0;
local_header = NULL;
ssl_proxy = (char *)"CONNECT";
@ -102,7 +101,8 @@ static void initializate(int argc, char **argv)
dnsAddr.sin_port = htons(atoi(p+1));
}
dnsAddr.sin_addr.s_addr = inet_addr(optarg);
connect(dnsFd, (struct sockaddr *)&dnsAddr, sizeof(dnsAddr));
close(dnsFd);
dns_connect(dnsFd, (struct sockaddr *)&dnsAddr, sizeof(dnsAddr));
break;
case 'l':