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

24
http.c
View File

@ -2,7 +2,9 @@
#include "dns.h" #include "dns.h"
#include "timeout.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 HTTP_TYPE 0
#define OTHER_TYPE 1 #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) void tcp_in(conn_t *in)
{ {
conn_t *server; conn_t *server;
@ -453,9 +471,7 @@ void tcp_in(conn_t *in)
} }
if (strstr(in->incomplete_data, ssl_proxy)) if (strstr(in->incomplete_data, ssl_proxy))
{ {
server->is_ssl = in->is_ssl = 1; if (respond_sslStatus(in) != 0)
/* 这时候即使fd是非阻塞也只需要判断返回值是否小于0 */
if (write(in->fd, SSL_RSP, sizeof(SSL_RSP)-1) < 0)
{ {
free(host); free(host);
close_connection(in); close_connection(in);

7
http.h
View File

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

8
main.c
View File

@ -4,8 +4,7 @@
#include "dns.h" #include "dns.h"
#include <pthread.h> #include <pthread.h>
#define VERSION "0.4" #define VERSION "0.5"
#define DEFAULT_DNS_IP "114.114.114.114"
struct epoll_event evs[MAX_CONNECTION + 1], ev; struct epoll_event evs[MAX_CONNECTION + 1], ev;
int efd; int efd;
@ -81,7 +80,7 @@ static void initializate(int argc, char **argv)
//默认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);
ignore_host_before_count = timeout_minute = strict_spilce = sslEncodeCode = 0; ignore_host_before_count = timeout_minute = strict_spilce = sslEncodeCode = 0;
local_header = NULL; local_header = NULL;
ssl_proxy = (char *)"CONNECT"; ssl_proxy = (char *)"CONNECT";
@ -102,7 +101,8 @@ static void initializate(int argc, char **argv)
dnsAddr.sin_port = htons(atoi(p+1)); dnsAddr.sin_port = htons(atoi(p+1));
} }
dnsAddr.sin_addr.s_addr = inet_addr(optarg); 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; break;
case 'l': case 'l':