From 1141fca0e4a8f00e16e63b69a9940bf79ad1df57 Mon Sep 17 00:00:00 2001 From: aixiao Date: Mon, 4 Apr 2022 20:00:36 +0800 Subject: [PATCH] The modified code supports C proxy. --- .gitignore | 0 LICENSE | 0 Makefile | 18 +++---- README.md | 0 SpecialProxy.sh | 0 dns.c | 0 dns.h | 0 http.c | 138 +++++++++++++++++++++++++++--------------------- http.h | 0 main.c | 2 + main.h | 0 timeout.c | 4 +- timeout.h | 0 13 files changed, 92 insertions(+), 70 deletions(-) mode change 100644 => 100755 .gitignore mode change 100644 => 100755 LICENSE mode change 100644 => 100755 Makefile mode change 100644 => 100755 README.md mode change 100644 => 100755 SpecialProxy.sh mode change 100644 => 100755 dns.c mode change 100644 => 100755 dns.h mode change 100644 => 100755 http.c mode change 100644 => 100755 http.h mode change 100644 => 100755 main.c mode change 100644 => 100755 main.h mode change 100644 => 100755 timeout.c mode change 100644 => 100755 timeout.h diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/Makefile b/Makefile old mode 100644 new mode 100755 index d179f90..e15f1d2 --- a/Makefile +++ b/Makefile @@ -1,21 +1,19 @@ +CROSS_COMPILE ?= +CC := $(CROSS_COMPILE)gcc +STRIP := $(CROSS_COMPILE)strip +CFLAGS := -O2 -g -Wall -pthread 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 $(CC) $(CFLAGS) $(DEFS) -o $(OBJ) $^ - $(STRIP) $(OBJ) - -chmod 777 $(OBJ) 2>&- + : $(STRIP) $(OBJ) + -chmod 755 $(OBJ) 2>&- .c.o : $(CC) $(CFLAGS) $(DEFS) -c $< clean : rm -f *.o + rm $(OBJ) + diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/SpecialProxy.sh b/SpecialProxy.sh old mode 100644 new mode 100755 diff --git a/dns.c b/dns.c old mode 100644 new mode 100755 diff --git a/dns.h b/dns.h old mode 100644 new mode 100755 diff --git a/http.c b/http.c old mode 100644 new mode 100755 index afdc3c7..fa74c73 --- a/http.c +++ b/http.c @@ -2,6 +2,7 @@ #include "dns.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_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" @@ -67,6 +68,7 @@ void close_connection(conn_t *conn) } if (conn->fd >= 0) close_connection(conn); + } @@ -105,6 +107,7 @@ static char *read_data(conn_t *in, char *data, int *data_len) } data = new_data; read_len = read(in->fd, data + *data_len, BUFFER_SIZE); + dataEncode(data, read_len); /* 判断是否关闭连接 */ if (read_len <= 0) { @@ -288,7 +291,7 @@ static int8_t parse_host(conn_t *server, char *host) /* 读取到的数据全部就绪,将incomplete_data复制到ready_data */ 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) { char *new_data; @@ -348,55 +351,6 @@ static void serverToClient(conn_t *server) 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代理回应 */ static int respond_sslStatus(conn_t *in) { @@ -404,12 +358,25 @@ 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); + */ + char buffer[SSL_RSP]; + + 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"))) - 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); } @@ -458,10 +425,13 @@ void tcp_in(conn_t *in) close_connection(in); return; } - dataEncode(host, strlen(host)); - /* 第一次读取数据 */ + + //dataEncode(host, strlen(host)); + // 第一次读取数据 if (in->reread_data == 0) { + // 打印HTTP HEAD + //printf("%s", in->incomplete_data); in->reread_data = 1; 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); free(host); + if (in->incomplete_data == NULL || copy_data(in) != 0) { close_connection(in); return; } - //数据处理完毕,可以发送 + // 数据处理完毕,可以发送 handle_data_complete: - //这个判断是防止 多次读取客户端数据,但是没有和服务端建立连接,导致报错 + // 这个判断是防止 多次读取客户端数据,但是没有和服务端建立连接,导致报错 if (server->fd >= 0) 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() { struct epoll_event epollEvent; diff --git a/http.h b/http.h old mode 100644 new mode 100755 diff --git a/main.c b/main.c old mode 100644 new mode 100755 index 833597d..7053282 --- a/main.c +++ b/main.c @@ -238,11 +238,13 @@ static void initializate(int argc, char **argv) int main(int argc, char **argv) { initializate(argc, argv); + if (daemon(1, 1)) { perror("daemon"); return 1; } + server_loop(); return 0; diff --git a/main.h b/main.h old mode 100644 new mode 100755 diff --git a/timeout.c b/timeout.c old mode 100644 new mode 100755 index 9e45e9d..626b380 --- a/timeout.c +++ b/timeout.c @@ -13,8 +13,10 @@ void *close_timeout_connectionLoop(void *nullPtr) for (i = 0; i < MAX_CONNECTION; i += 2) if (cts[i].fd > -1) { - if (cts[i].timer >= timeout_minute) + if (cts[i].timer >= timeout_minute) { + printf("关闭连接\n"); close_connection(cts + i); + } else cts[i].timer++; } diff --git a/timeout.h b/timeout.h old mode 100644 new mode 100755