Add files via upload
This commit is contained in:
parent
a4c9932ec1
commit
6e23178411
25
README.md
25
README.md
@ -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
|
||||||
~~~~~
|
~~~~~
|
@ -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
24
http.c
@ -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
7
http.h
@ -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
8
main.c
@ -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':
|
||||||
|
Loading…
Reference in New Issue
Block a user