The modified code supports C proxy.

This commit is contained in:
aixiao 2022-04-04 20:00:36 +08:00
parent 3383ecbbf7
commit 1141fca0e4
13 changed files with 92 additions and 70 deletions

0
.gitignore vendored Normal file → Executable file
View File

0
LICENSE Normal file → Executable file
View File

18
Makefile Normal file → Executable file
View 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
README.md Normal file → Executable file
View File

0
SpecialProxy.sh Normal file → Executable file
View File

0
dns.c Normal file → Executable file
View File

0
dns.h Normal file → Executable file
View File

138
http.c Normal file → Executable file
View 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);
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"))) 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); {
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;

0
http.h Normal file → Executable file
View File

2
main.c Normal file → Executable file
View 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;

0
main.h Normal file → Executable file
View File

4
timeout.c Normal file → Executable file
View 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++;
} }

0
timeout.h Normal file → Executable file
View File