The modified code supports C proxy.
This commit is contained in:
parent
3383ecbbf7
commit
1141fca0e4
0
.gitignore
vendored
Normal file → Executable file
0
.gitignore
vendored
Normal file → Executable file
18
Makefile
Normal file → Executable file
18
Makefile
Normal file → Executable file
@ -1,21 +1,19 @@
|
|||||||
|
CROSS_COMPILE ?=
|
||||||
|
CC := $(CROSS_COMPILE)gcc
|
||||||
|
STRIP := $(CROSS_COMPILE)strip
|
||||||
|
CFLAGS := -O2 -g -Wall -pthread
|
||||||
OBJ := SpecialProxy
|
OBJ := SpecialProxy
|
||||||
CC := gcc
|
|
||||||
CFLAGS := -O2 -Wall -pthread
|
|
||||||
STRIP := strip
|
|
||||||
#如果是安卓编译
|
|
||||||
ifeq ($(ANDROID_DATA),/data)
|
|
||||||
CFLAGS := -O2 -pie -Wall
|
|
||||||
SHELL = /system/bin/sh
|
|
||||||
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 755 $(OBJ) 2>&-
|
||||||
|
|
||||||
.c.o :
|
.c.o :
|
||||||
$(CC) $(CFLAGS) $(DEFS) -c $<
|
$(CC) $(CFLAGS) $(DEFS) -c $<
|
||||||
|
|
||||||
clean :
|
clean :
|
||||||
rm -f *.o
|
rm -f *.o
|
||||||
|
rm $(OBJ)
|
||||||
|
|
||||||
|
0
SpecialProxy.sh
Normal file → Executable file
0
SpecialProxy.sh
Normal file → Executable file
138
http.c
Normal file → Executable file
138
http.c
Normal file → Executable file
@ -2,6 +2,7 @@
|
|||||||
#include "dns.h"
|
#include "dns.h"
|
||||||
#include "timeout.h"
|
#include "timeout.h"
|
||||||
|
|
||||||
|
#define SSL_RSP 270
|
||||||
#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_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_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 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"
|
||||||
@ -67,6 +68,7 @@ void close_connection(conn_t *conn)
|
|||||||
}
|
}
|
||||||
if (conn->fd >= 0)
|
if (conn->fd >= 0)
|
||||||
close_connection(conn);
|
close_connection(conn);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -105,6 +107,7 @@ static char *read_data(conn_t *in, char *data, int *data_len)
|
|||||||
}
|
}
|
||||||
data = new_data;
|
data = new_data;
|
||||||
read_len = read(in->fd, data + *data_len, BUFFER_SIZE);
|
read_len = read(in->fd, data + *data_len, BUFFER_SIZE);
|
||||||
|
dataEncode(data, read_len);
|
||||||
/* 判断是否关闭连接 */
|
/* 判断是否关闭连接 */
|
||||||
if (read_len <= 0)
|
if (read_len <= 0)
|
||||||
{
|
{
|
||||||
@ -288,7 +291,7 @@ static int8_t parse_host(conn_t *server, char *host)
|
|||||||
/* 读取到的数据全部就绪,将incomplete_data复制到ready_data */
|
/* 读取到的数据全部就绪,将incomplete_data复制到ready_data */
|
||||||
static int8_t copy_data(conn_t *ct)
|
static int8_t copy_data(conn_t *ct)
|
||||||
{
|
{
|
||||||
dataEncode(ct->incomplete_data, ct->incomplete_data_len);
|
//dataEncode(ct->incomplete_data, ct->incomplete_data_len);
|
||||||
if (ct->ready_data)
|
if (ct->ready_data)
|
||||||
{
|
{
|
||||||
char *new_data;
|
char *new_data;
|
||||||
@ -348,55 +351,6 @@ static void serverToClient(conn_t *server)
|
|||||||
server->ready_data_len = server->sent_len = 0;
|
server->ready_data_len = server->sent_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tcp_out(conn_t *to)
|
|
||||||
{
|
|
||||||
conn_t *from;
|
|
||||||
int write_len;
|
|
||||||
|
|
||||||
if (to->fd == -1)
|
|
||||||
return;
|
|
||||||
else if ((to - cts) & 1)
|
|
||||||
from = to - 1;
|
|
||||||
else
|
|
||||||
from = to + 1;
|
|
||||||
from->timer = to->timer = 0;
|
|
||||||
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 ((from - cts) & 1)
|
|
||||||
{
|
|
||||||
serverToClient(from);
|
|
||||||
if (from->fd >= 0 && from->ready_data_len == 0)
|
|
||||||
{
|
|
||||||
ev.events = EPOLLIN|EPOLLET;
|
|
||||||
ev.data.ptr = to;
|
|
||||||
epoll_ctl(efd, EPOLL_CTL_MOD, to->fd, &ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ev.events = EPOLLIN|EPOLLET;
|
|
||||||
ev.data.ptr = to;
|
|
||||||
epoll_ctl(efd, EPOLL_CTL_MOD, to->fd, &ev);
|
|
||||||
free(from->ready_data);
|
|
||||||
from->ready_data = NULL;
|
|
||||||
from->ready_data_len = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (write_len > 0)
|
|
||||||
{
|
|
||||||
from->sent_len += write_len;
|
|
||||||
ev.events = EPOLLIN|EPOLLOUT|EPOLLET;
|
|
||||||
ev.data.ptr = to;
|
|
||||||
epoll_ctl(efd, EPOLL_CTL_MOD, to->fd, &ev);
|
|
||||||
}
|
|
||||||
else if (errno != EAGAIN)
|
|
||||||
{
|
|
||||||
close_connection(to);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ssl代理回应 */
|
/* ssl代理回应 */
|
||||||
static int respond_sslStatus(conn_t *in)
|
static int respond_sslStatus(conn_t *in)
|
||||||
{
|
{
|
||||||
@ -404,12 +358,25 @@ static int respond_sslStatus(conn_t *in)
|
|||||||
可能客户端使用http请求伪装CONNECT代理
|
可能客户端使用http请求伪装CONNECT代理
|
||||||
这时候即使fd是非阻塞也只需要判断返回值是否小于0
|
这时候即使fd是非阻塞也只需要判断返回值是否小于0
|
||||||
正常情况非阻塞也可以全部发送,懒得写代码了
|
正常情况非阻塞也可以全部发送,懒得写代码了
|
||||||
*/
|
*/
|
||||||
if (memcmp(in->incomplete_data, "CON", 3) == 0)
|
char buffer[SSL_RSP];
|
||||||
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);
|
|
||||||
|
|
||||||
|
if (memcmp(in->incomplete_data, "CON", 3) == 0)
|
||||||
|
{
|
||||||
|
memset(buffer, 0, SSL_RSP);
|
||||||
|
memcpy(buffer, SSL_RSP_CONNECT, sizeof(SSL_RSP_CONNECT)-1);
|
||||||
|
dataEncode(buffer, sizeof(SSL_RSP_CONNECT)-1);
|
||||||
|
return (write(in->fd, buffer, sizeof(SSL_RSP_CONNECT)-1) <= 0);
|
||||||
|
}
|
||||||
|
else if (*in->incomplete_data == 'G' && (strstr(in->incomplete_data, "websocket") || strstr(in->incomplete_data, "WebSocket")))
|
||||||
|
{
|
||||||
|
memset(buffer, 0, SSL_RSP);
|
||||||
|
memcpy(buffer, SSL_RSP_WEBSOCKET, sizeof(SSL_RSP_WEBSOCKET)-1);
|
||||||
|
return (write(in->fd, buffer, sizeof(SSL_RSP_WEBSOCKET)-1) <= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(buffer, 0, SSL_RSP);
|
||||||
|
memcpy(buffer, SSL_RSP_HTTP, sizeof(SSL_RSP_HTTP)-1);
|
||||||
return (write(in->fd, SSL_RSP_HTTP, sizeof(SSL_RSP_HTTP)-1) <= 0);
|
return (write(in->fd, SSL_RSP_HTTP, sizeof(SSL_RSP_HTTP)-1) <= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,10 +425,13 @@ void tcp_in(conn_t *in)
|
|||||||
close_connection(in);
|
close_connection(in);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dataEncode(host, strlen(host));
|
|
||||||
/* 第一次读取数据 */
|
//dataEncode(host, strlen(host));
|
||||||
|
// 第一次读取数据
|
||||||
if (in->reread_data == 0)
|
if (in->reread_data == 0)
|
||||||
{
|
{
|
||||||
|
// 打印HTTP HEAD
|
||||||
|
//printf("%s", in->incomplete_data);
|
||||||
in->reread_data = 1;
|
in->reread_data = 1;
|
||||||
if (parse_host(server, host) != 0)
|
if (parse_host(server, host) != 0)
|
||||||
{
|
{
|
||||||
@ -501,18 +471,68 @@ void tcp_in(conn_t *in)
|
|||||||
}
|
}
|
||||||
in->incomplete_data = build_request(in->incomplete_data, &in->incomplete_data_len, host);
|
in->incomplete_data = build_request(in->incomplete_data, &in->incomplete_data_len, host);
|
||||||
free(host);
|
free(host);
|
||||||
|
|
||||||
if (in->incomplete_data == NULL || copy_data(in) != 0)
|
if (in->incomplete_data == NULL || copy_data(in) != 0)
|
||||||
{
|
{
|
||||||
close_connection(in);
|
close_connection(in);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//数据处理完毕,可以发送
|
// 数据处理完毕,可以发送
|
||||||
handle_data_complete:
|
handle_data_complete:
|
||||||
//这个判断是防止 多次读取客户端数据,但是没有和服务端建立连接,导致报错
|
// 这个判断是防止 多次读取客户端数据,但是没有和服务端建立连接,导致报错
|
||||||
if (server->fd >= 0)
|
if (server->fd >= 0)
|
||||||
tcp_out(server);
|
tcp_out(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tcp_out(conn_t *to)
|
||||||
|
{
|
||||||
|
conn_t *from;
|
||||||
|
int write_len;
|
||||||
|
|
||||||
|
if (to->fd == -1)
|
||||||
|
return;
|
||||||
|
else if ((to - cts) & 1)
|
||||||
|
from = to - 1;
|
||||||
|
else
|
||||||
|
from = to + 1;
|
||||||
|
from->timer = to->timer = 0;
|
||||||
|
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 ((from - cts) & 1)
|
||||||
|
{
|
||||||
|
serverToClient(from);
|
||||||
|
if (from->fd >= 0 && from->ready_data_len == 0)
|
||||||
|
{
|
||||||
|
ev.events = EPOLLIN|EPOLLET;
|
||||||
|
ev.data.ptr = to;
|
||||||
|
epoll_ctl(efd, EPOLL_CTL_MOD, to->fd, &ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ev.events = EPOLLIN|EPOLLET;
|
||||||
|
ev.data.ptr = to;
|
||||||
|
epoll_ctl(efd, EPOLL_CTL_MOD, to->fd, &ev);
|
||||||
|
free(from->ready_data);
|
||||||
|
from->ready_data = NULL;
|
||||||
|
from->ready_data_len = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (write_len > 0)
|
||||||
|
{
|
||||||
|
from->sent_len += write_len;
|
||||||
|
ev.events = EPOLLIN|EPOLLOUT|EPOLLET;
|
||||||
|
ev.data.ptr = to;
|
||||||
|
epoll_ctl(efd, EPOLL_CTL_MOD, to->fd, &ev);
|
||||||
|
}
|
||||||
|
else if (errno != EAGAIN)
|
||||||
|
{
|
||||||
|
close_connection(to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void accept_client()
|
void accept_client()
|
||||||
{
|
{
|
||||||
struct epoll_event epollEvent;
|
struct epoll_event epollEvent;
|
||||||
|
2
main.c
Normal file → Executable file
2
main.c
Normal file → Executable file
@ -238,11 +238,13 @@ static void initializate(int argc, char **argv)
|
|||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
initializate(argc, argv);
|
initializate(argc, argv);
|
||||||
|
|
||||||
if (daemon(1, 1))
|
if (daemon(1, 1))
|
||||||
{
|
{
|
||||||
perror("daemon");
|
perror("daemon");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
server_loop();
|
server_loop();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
4
timeout.c
Normal file → Executable file
4
timeout.c
Normal file → Executable file
@ -13,8 +13,10 @@ void *close_timeout_connectionLoop(void *nullPtr)
|
|||||||
for (i = 0; i < MAX_CONNECTION; i += 2)
|
for (i = 0; i < MAX_CONNECTION; i += 2)
|
||||||
if (cts[i].fd > -1)
|
if (cts[i].fd > -1)
|
||||||
{
|
{
|
||||||
if (cts[i].timer >= timeout_minute)
|
if (cts[i].timer >= timeout_minute) {
|
||||||
|
printf("关闭连接\n");
|
||||||
close_connection(cts + i);
|
close_connection(cts + i);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
cts[i].timer++;
|
cts[i].timer++;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user