diff --git a/CProxy.conf b/CProxy.conf old mode 100644 new mode 100755 index f137373..7d5115a --- a/CProxy.conf +++ b/CProxy.conf @@ -1,7 +1,7 @@ global { uid=3004; process=2; - timeout=60; + timeout=10; encode=128; tcp_listen=0124; tcp6_listen=0124; @@ -12,7 +12,7 @@ http { http_ip="47.240.75.93"; http_port=127; http_del="Host"; - http_first="[M] http://[host][U] [V]\r\nHost: [host]\r\n"; + http_first="[M] http://[host][U] [V]\r\nHost: [H]\r\n"; //strrep="Windows NT 10.0->Linux"; //regrep="Host:*.+?->Host: [host]:80"; } @@ -23,7 +23,7 @@ https { https_del="Host,host,x-online-host"; https_first="[M] [U] [V]\r\nHost: [host]\r\n"; //strrep="Windows NT 10.0->Linux"; - //regrep="Host*.+?->Host: [H]"; + //regrep="Host*.+?->host: [host]:443"; } httpdns { diff --git a/CProxy.conf.explain b/CProxy.conf.explain old mode 100644 new mode 100755 index dca5252..4e41557 --- a/CProxy.conf.explain +++ b/CProxy.conf.explain @@ -38,7 +38,7 @@ process=2; //进程数量(已经弃用) timeout=60; //超时时间(秒) sslencoding=128; //编码(非零生效) tcp_listen=0124; //TCP监听端口 -tcp6_listen=0124; //TCP6监听端口 (TCP和TCP6可以使用同一个端口, IPV4的数据走内部IPV6程序结构, IPV6数据走内部IPV6程序结构.) +tcp6_listen=0124; //TCP6监听端口 (TCP和TCP6可以使用同一个端口, IPV4的数据走内部IPV4程序结构, IPV6数据走内部IPV6程序结构.) dns_listen=0125; //UDP监听端口 @@ -52,8 +52,8 @@ http、https 模块关键字: [M], [method], [uri], [U], [V], [version], [H], [h [port] 原请求端口 [H] 原请求[host]:[port] -http_ip=cproxy.aixiao.me; //指定HTTP服务器 -http_port=124; //端口 +http_ip=cproxy.aixiao.me; //指定HTTP服务器IP +http_port=124; //指定HTTP服务器端口 http_del="x-online-host,X-Online-Host,host,Host"; //删除HTTP头字段,逗号分开 http_first="[M] [U] [V]\r\nHost: [H]\r\n"; //自定义HTTP头 关键字strrep替换字符串指令. @@ -65,4 +65,5 @@ httpdns模块 httpdns 模块关键字: [M], [D], [V], \r, \n, \v, \f, \b, \t, \a. 默认 [M] 为 GET 默认 [V] 为 HTTP/1.0 -addr=119.29.29.29:53; //httpdns服务器IP +addr=119.29.29.29:53; //HTTPDNS服务器IP + diff --git a/Makefile b/Makefile old mode 100644 new mode 100755 index 662b464..75e1eb6 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CROSS_COMPILE ?= CC := $(CROSS_COMPILE)gcc STRIP := $(CROSS_COMPILE)strip -CFLAGS += -g -O2 -Wall -pthread -static +CFLAGS += -g -O2 -Wall -pthread LIBS = OBJ := CProxy diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 3f5d828..6a7e3f4 --- a/README.md +++ b/README.md @@ -1,11 +1,13 @@ -### CProxy +# CProxy + EPOLL多路复用IO, Android/Linux本地二级代理. 可以修改HTTP协议消息头(request). 可以修改HTTP协议CONNECT方法消息头. 可以修改HTTP协议GET方法消息头. - 初步支持IPV6. + 支持IPV6. + +## Build -### Build Linux编译: git clone https://github.com/niuyuling/CProxy.git cd CProxy @@ -18,20 +20,18 @@ Android NDK 编译: ndk-build NDK_PROJECT_PATH=. NDK_APPLICATION_MK=Application.mk APP_BUILD_SCRIPT=Android.mk -### Help Information +## Help Information + CProxy proxy server Author: aixiao@aixiao.me - Usage: [-?hpt] [-s signal] [-c filename] + Usage: [-?h] [-s signal] [-c filename] Options: - -p --process : process number - -t --timeout : timeout minute - -e --coding : ssl coding, [0-128] -s --signal : send signal to a master process: stop, quit, restart, reload, status -c --config : set configuration file, default: CProxy.conf -? -h --? --help : help information - Mar 22 2020 09:29:11 Compile、link. + Dec 19 2020 09:18:15 Compile、link. #启动 ./CProxy -c CProxy.conf @@ -43,4 +43,3 @@ ./CProxy -s restart -c CProxy.conf #状态(只打印 Pid) ./CProxy -s status - \ No newline at end of file diff --git a/conf.c b/conf.c old mode 100644 new mode 100755 index 6a23b84..8216d36 --- a/conf.c +++ b/conf.c @@ -363,7 +363,7 @@ void read_conf(char *filename, conf * configure) file = fopen(filename, "r"); if (file == NULL) { - perror("cannot open config file."); + printf("cannot open config file."); exit(-1); } fseek(file, 0, SEEK_END); diff --git a/help.c b/help.c old mode 100644 new mode 100755 index 157c704..593948a --- a/help.c +++ b/help.c @@ -10,13 +10,10 @@ char help_information(void) "aixiao@aixiao.me", }; - static const char usage[] = "Usage: [-?hpt] [-s signal] [-c filename]"; + static const char usage[] = "Usage: [-?h] [-s signal] [-c filename]"; static const char *s_help[] = { "", "Options:", - " -p --process : process number", - " -t --timeout : timeout minute", - " -e --coding : ssl coding, [0-128]", " -s --signal : send signal to a master process: stop, quit, restart, reload, status", " -c --config : set configuration file, default: CProxy.conf", " -? -h --? --help : help information", diff --git a/http_proxy.c b/http_proxy.c old mode 100644 new mode 100755 index 7b21940..bd078aa --- a/http_proxy.c +++ b/http_proxy.c @@ -3,7 +3,7 @@ int sslEncodeCode; int remote_port; -char remote_host[270]; +char remote_host[CACHE_SIZE]; /* 对数据进行编码 */ void dataEncode(char *data, int data_len) @@ -115,7 +115,20 @@ void clientToserver(conn_t * in) // 判断请求类型 static int8_t request_type(char *data) { - if (strncmp(data, "GET", 3) == 0 || strncmp(data, "POST", 4) == 0 || strncmp(data, "CONNECT", 7) == 0 || strncmp(data, "HEAD", 4) == 0 || strncmp(data, "PUT", 3) == 0 || strncmp(data, "OPTIONS", 7) == 0 || strncmp(data, "MOVE", 4) == 0 || strncmp(data, "COPY", 4) == 0 || strncmp(data, "TRACE", 5) == 0 || strncmp(data, "DELETE", 6) == 0 || strncmp(data, "LINK", 4) == 0 || strncmp(data, "UNLINK", 6) == 0 || strncmp(data, "PATCH", 5) == 0 || strncmp(data, "WRAPPED", 7) == 0) + if (strncmp(data, "GET", 3) == 0 || + strncmp(data, "POST", 4) == 0 || + strncmp(data, "CONNECT", 7) == 0 || + strncmp(data, "HEAD", 4) == 0 || + strncmp(data, "PUT", 3) == 0 || + strncmp(data, "OPTIONS", 7) == 0 || + strncmp(data, "MOVE", 4) == 0 || + strncmp(data, "COPY", 4) == 0 || + strncmp(data, "TRACE", 5) == 0 || + strncmp(data, "DELETE", 6) == 0 || + strncmp(data, "LINK", 4) == 0 || + strncmp(data, "UNLINK", 6) == 0 || + strncmp(data, "PATCH", 5) == 0 || + strncmp(data, "WRAPPED", 7) == 0) return HTTP_TYPE; return OTHER_TYPE; } @@ -140,7 +153,7 @@ int create_connection6(char *remote_host, int remote_port) struct addrinfo hints, *res = NULL; int sock; int validfamily = 0; - char portstr[270]; + char portstr[CACHE_SIZE]; memset(&hints, 0x00, sizeof(hints)); @@ -237,7 +250,6 @@ void tcp_in(conn_t * in, conf * configure) ev.events = EPOLLIN | EPOLLOUT | EPOLLET; ev.data.ptr = server; epoll_ctl(epollfd, EPOLL_CTL_ADD, server->fd, &ev); - } if (in->incomplete_data == NULL || copy_data(in) != 0) { diff --git a/http_proxy.h b/http_proxy.h old mode 100644 new mode 100755 index 9096d6d..c107b95 --- a/http_proxy.h +++ b/http_proxy.h @@ -9,7 +9,7 @@ #define OTHER_TYPE 1 extern int remote_port; -extern char remote_host[270]; +extern char remote_host[CACHE_SIZE]; extern int sslEncodeCode; typedef struct tcp_connection { diff --git a/http_request.c b/http_request.c old mode 100644 new mode 100755 index 655e3fd..c4a0da3 --- a/http_request.c +++ b/http_request.c @@ -158,15 +158,19 @@ char *delete_head(char *head, const char *character, int string) int extract_host(char *header, char *host, char *port) { + memset(port, 0, strlen(port)); + memset(host, 0, strlen(host)); +//printf("%s\n", header); char *_p = strstr(header, "CONNECT"); // 在 CONNECT 方法中解析 隧道主机名称及端口号 if (_p) { if (strchr(header, '[') || strchr(header, ']')) { // IPv6 char *_p1 = strchr(header, '['); char *_p2 = strchr(_p1 + 1, ']'); - strncpy(host, _p1 + 1, (int)(_p2 - _p1) - 1); - remote_port = 443; + + char *_p3 = strchr(_p2 + 1, ' '); + strncpy(port, _p2 + 2, (int)(_p3 - _p2) - 1); return 0; } @@ -182,41 +186,105 @@ int extract_host(char *header, char *host, char *port) return -1; } return 0; - } - - char *p = strstr(header, "Host:"); - if (!p) { - return -1; - } - char *p1 = strchr(p, '\n'); - if (!p1) { - return -1; - } - - char *p2 = strchr(p + 5, ':'); // 5是指'Host:'的长度 - if (p2 && p2 < p1) { - memcpy(port, p2 + 1, (int)(p1 - p2 - 1)); - memcpy(host, p + 5 + 1, (int)(p2 - p - 5 - 1)); // Host: } else { - memset(port, 0, strlen(port)); - memset(host, 0, strlen(host)); - memcpy(host, p + 5 + 1, (int)(p1 - p - 5 - 1 - 1)); - memcpy(port, "80", 2); + + char *p = strstr(header, "Host:"); + if (!p) { + return -1; + } + char *p1 = strchr(p, '\n'); + if (!p1) { + return -1; + } + + char *p2 = strchr(p + 5, ':'); // 5是指'Host:'的长度 + + int h_len = (int)(p1 - p - 6); + char s_host[h_len]; + strncpy(s_host, p + 6, p1 - p - 6); + s_host[h_len] = '\0'; + char *p3 = strchr(s_host, ':'); + char *p4 = NULL; + if (p3) + p4 = strchr(p3 + 1, ':'); + + if (p4 != NULL) { // IPV6 + char *p5 = NULL; + char *p6 = NULL; + p5 = strchr(header, ' '); + if (p5) + p6 = strchr(p5 + 1, ' '); + + char url[p6 - p5 - 1]; + memset(url, 0, p6 - p5 - 1); + strncpy(url, p5 + 1, p6 - p5 - 1); + url[p6 - p5 - 1] = '\0'; + + if (strstr(url, "http") != NULL) { // 去除 'http://' + memcpy(url, url + 7, strlen(url) - 7); + url[strlen(url) - 7] = '\0'; + char *p7 = strchr(url, '/'); + if (p7) // 去除 uri + url[p7 - url] = '\0'; + + char *p8 = strchr(url, ']'); + if (p8) { + strcpy(port, p8 + 2); + strncpy(host, url + 1, strlen(url) - strlen(p8) - 1); + + if (strlen(p8) < 3) { + strcpy(port, "80"); + strncpy(host, url + 1, strlen(url) - strlen(p8) - 1); + } + } + return 0; + } else { // HTTP头为不规范的url时处理Host, 主要Proxifier转发url为'/'时 + //printf("s_host: %s\n", s_host); + char *_p1 = strchr(s_host, '['); + char *_p2 = strchr(_p1+1, ']'); + if (_p1 && _p2) { + memcpy(host, _p1+1, _p2 - _p1 -1); + if (strlen(_p2) < 3) { + strcpy(port, "80"); + } else { + strcpy(port, _p2+2); + } + + } + return 0; + } + + + + return -1; + } + + if (p2 && p2 < p1) { + memcpy(port, p2 + 1, (int)(p1 - p2 - 1)); + memcpy(host, p + 5 + 1, (int)(p2 - p - 5 - 1)); + } else { + memcpy(host, p + 5 + 1, (int)(p1 - p - 5 - 1 - 1)); + memcpy(port, "80", 2); + } + + return 0; } + return 0; } -char *get_path(char *url, char *path) +char *get_http_path(char *url, char *path) { char *_p0; _p0 = NULL; if (url) { _p0 = strstr(url + 7, "/"); if (_p0) - return strncpy_(path, _p0, (int)strlen(_p0)); + return memcpy(path, _p0, (int)strlen(_p0)); else - return NULL; + memcpy(path, "/", 1); // 如果没有资源路径就默认"/" } + return NULL; } @@ -240,12 +308,58 @@ void free_http_request(struct http_request *http_request) free(http_request->uri); } +void get_http_host_port_len(char *head, int *host_len, int *port_len) { + *host_len = 0; + *port_len = 0; + char *_p1 = strstr(head, "Host"); // 判断Host行 + if (_p1) { // 为真时 + char *_p2 = strstr(_p1, "\n"); + *host_len = (int)(_p2 - _p1); + + char host[*host_len+1]; + memcpy(host, _p1, *host_len); + host[*host_len] = '\0'; + + char *_p3 = strrchr(host, ':'); + if (_p3) { + *port_len = strlen(_p3+1); + } else { + *port_len = *host_len; + } + } else { // 为假时 + char *_p1 = strstr(head, "host"); + if (_p1) { + char *_p2 = strstr(_p1, "\n"); + *host_len = (int)(_p2 - _p1); + + char host[*host_len+1]; + memcpy(host, _p1, *host_len); + host[*host_len] = '\0'; + + char *_p3 = strrchr(host, ':'); + if (_p3) { + *port_len = strlen(_p3+1); + } else { + *port_len = *host_len; + } + } else { // 未找到时使用HTTP_HEAD_CACHE_SIZE大小 + *host_len = HTTP_HEAD_CACHE_SIZE; + *port_len = HTTP_HEAD_CACHE_SIZE; + } + } + + return ; +} + void parse_request_head(char *http_request_line, struct http_request *http_request) { char *p; char *head; size_t head_len; char *m, *u; + int host_len = 0; + int port_len = 0; + int uri_len = 0; p = strstr(http_request_line, "\r\n"); // 查找"\r\n" if (p == NULL) { @@ -259,8 +373,8 @@ void parse_request_head(char *http_request_line, struct http_request *http_reque memset(head, 0, head_len * 2); memcpy(head, http_request_line, head_len); - http_request->M = (char *)malloc(sizeof(char) * head_len); - http_request->U = (char *)malloc(sizeof(char) * head_len); + http_request->M = (char *)malloc(sizeof(char) * 7); + http_request->U = (char *)malloc(sizeof(char) * HTTP_HEAD_CACHE_SIZE); http_request->V = (char *)malloc(10); if (http_request->M == NULL) { perror("malloc"); @@ -271,32 +385,62 @@ void parse_request_head(char *http_request_line, struct http_request *http_reque if (http_request->V == NULL) { perror("malloc"); } - memset(http_request->M, 0, head_len); - memset(http_request->U, 0, head_len); + memset(http_request->M, 0, 7); + memset(http_request->U, 0, HTTP_HEAD_CACHE_SIZE); memset(http_request->V, 0, 10); - m = strstr(head, " "); + m = strchr(head, ' '); http_request->M_len = strlen(head) - strlen(m); + //http_request->M_len = m - head; memcpy(http_request->M, head, http_request->M_len); - u = strstr(m + 1, " "); + u = strchr(m + 1, ' '); http_request->U_len = strlen(m + 1) - strlen(u); + //http_request->U_len = u - m -1; memcpy(http_request->U, m + 1, http_request->U_len); memcpy(http_request->V, u + 1, 8); http_request->V_len = 8; + http_request->U_len = (int)strlen(http_request->U); + + // 获取Host、Port长度 + get_http_host_port_len(http_request_line, &host_len, &port_len); + + // URI LENGTH + char *_p0 = strstr(http_request->U, "http://"); + if (_p0) { // 标准头 + char *_p1 = strchr(http_request->U + 7, '/'); + if (_p1) { + uri_len = (int)strlen(_p1); + } + } else { // 非标准头 + char *_p1 = strchr(http_request->U, '/'); + if (_p1) { + uri_len = (int)strlen(_p1); + } else { + uri_len = 1; // 没有uri时 + } + } - if (http_request->U_len < 0) - return; + http_request->host = (char *)malloc(sizeof(char) * host_len+1); + if (http_request->host == NULL) + perror("malloc"); + http_request->port = (char *)malloc(sizeof(char) * port_len+1); + if (http_request->port == NULL) + perror("malloc"); + http_request->url = (char *)malloc(sizeof(char) * http_request->U_len+1); + if (http_request->url == NULL) + perror("malloc"); + http_request->uri = (char *)malloc(sizeof(char) * uri_len+1); + if (http_request->uri == NULL) + perror("malloc"); + http_request->H = (char *)malloc(sizeof(char) * host_len + port_len + 1); + if (http_request->H == NULL) + perror("malloc"); - http_request->host = (char *)malloc(sizeof(char) * head_len + CACHE_SIZE); - http_request->port = (char *)malloc(sizeof(char) * head_len); - http_request->url = (char *)malloc(sizeof(char) * head_len); - http_request->uri = (char *)malloc(sizeof(char) * head_len); - http_request->H = (char *)malloc(sizeof(char) * head_len * 2); - memset(http_request->host, 0, head_len + CACHE_SIZE); - memset(http_request->port, 0, head_len); - memset(http_request->url, 0, head_len); - memset(http_request->uri, 0, head_len); - memset(http_request->H, 0, head_len * 2); + memset(http_request->host, 0, host_len+1); + memset(http_request->port, 0, port_len+1); + memset(http_request->url, 0, http_request->U_len+1); + memset(http_request->uri, 0, uri_len+1); + memset(http_request->H, 0, host_len + port_len + 1); if (extract_host(http_request_line, http_request->host, http_request->port) == -1) return; @@ -306,8 +450,9 @@ void parse_request_head(char *http_request_line, struct http_request *http_reque strcat(http_request->H, ":"); strcat(http_request->H, http_request->port); memcpy(http_request->url, http_request->U, http_request->U_len); - get_path(http_request->url, http_request->uri); + get_http_path(http_request->url, http_request->uri); + http_request->U_len = (int)strlen(http_request->U); http_request->url_len = (int)strlen(http_request->url); http_request->uri_len = (int)strlen(http_request->uri); http_request->H_len = (int)strlen(http_request->H); @@ -330,7 +475,7 @@ char *request_head(conn_t * in, conf * configure) char https_del_copy[configure->https_del_len * 2]; char *result = NULL; - memset(remote_host, 0, 270); + memset(remote_host, 0, CACHE_SIZE); if (configure->https_port > 0) remote_port = configure->https_port; if (configure->https_ip != NULL) @@ -351,10 +496,6 @@ char *request_head(conn_t * in, conf * configure) } splice_head(incomplete_head, "\n", configure->https_first); incomplete_head_len = strlen(incomplete_head); - if (configure->https_strrep) - incomplete_head = replace(incomplete_head, &incomplete_head_len, configure->https_strrep_aim, configure->https_strrep_aim_len, configure->https_strrep_obj, configure->https_strrep_obj_len); - if (configure->https_regrep) - incomplete_head = regrep(incomplete_head, &incomplete_head_len, configure->https_regrep_aim, configure->https_regrep_obj, configure->https_regrep_obj_len); incomplete_head = replace(incomplete_head, &incomplete_head_len, "\\r", 2, "\r", 1); incomplete_head = replace(incomplete_head, &incomplete_head_len, "\\n", 2, "\n", 1); incomplete_head = replace(incomplete_head, &incomplete_head_len, "\\b", 2, "\b", 1); @@ -372,30 +513,48 @@ char *request_head(conn_t * in, conf * configure) incomplete_head = replace(incomplete_head, &incomplete_head_len, "[host]", 6, http_request->host, http_request->host_len); incomplete_head = replace(incomplete_head, &incomplete_head_len, "[port]", 6, http_request->port, http_request->port_len); incomplete_head = replace(incomplete_head, &incomplete_head_len, "[H]", 3, http_request->H, http_request->H_len); - //printf("%s", incomplete_head); // 打印HTTP HEADER + if (configure->https_strrep) + incomplete_head = replace(incomplete_head, &incomplete_head_len, configure->https_strrep_aim, configure->https_strrep_aim_len, configure->https_strrep_obj, configure->https_strrep_obj_len); + if (configure->https_regrep) + incomplete_head = regrep(incomplete_head, &incomplete_head_len, configure->https_regrep_aim, configure->https_regrep_obj, configure->https_regrep_obj_len); + incomplete_head = replace(incomplete_head, &incomplete_head_len, "[H]", 3, http_request->H, http_request->H_len); + incomplete_head = replace(incomplete_head, &incomplete_head_len, "[host]", 6, http_request->host, http_request->host_len); + incomplete_head = replace(incomplete_head, &incomplete_head_len, "[port]", 6, http_request->port, http_request->port_len); + incomplete_head_len = strlen(incomplete_head); // 更新HTTPS HEADER长度 + //printf("%s", incomplete_head); // 打印HTTPS HEADER - memset(in->incomplete_data, 0, strlen(in->incomplete_data)); - strcpy(in->incomplete_data, incomplete_head); - in->incomplete_data_len = strlen(in->incomplete_data); - free(incomplete_head); - } else { + char *new_incomplete_data; + new_incomplete_data = (char *)realloc(in->incomplete_data, incomplete_head_len + 1); // 更新incomplete_data堆内存 + if (new_incomplete_data == NULL) { + perror("realloc"); + return NULL; + } + in->incomplete_data = new_incomplete_data; + memset(in->incomplete_data, 0, incomplete_head_len + 1); // 清空incomplete_data数据 + strcpy(in->incomplete_data, incomplete_head); // 更新incomplete_data数据 + in->incomplete_data_len = strlen(in->incomplete_data); // 更新incomplete_data长度 + free(incomplete_head); // 释放incomplete_head内存 + + } + + if (strncmp(in->incomplete_data, "GET", 3) == 0 || strncmp(in->incomplete_data, "POST", 4) == 0) { char *incomplete_head; int incomplete_head_len; char http_del_copy[configure->http_del_len]; char *result = NULL; - memset(remote_host, 0, 270); + memset(remote_host, 0, CACHE_SIZE); if (configure->http_port > 0) remote_port = configure->http_port; if (configure->http_ip != NULL) strcpy(remote_host, configure->http_ip); - //memmove(remote_host, configure->http_ip, strlen(configure->http_ip)); incomplete_head = (char *)malloc(sizeof(char) * (BUFFER_SIZE)); if (incomplete_head == NULL) { - free(incomplete_head); perror("malloc"); + free(incomplete_head); } + memset(incomplete_head, 0, sizeof(char) * (BUFFER_SIZE)); memcpy(incomplete_head, in->incomplete_data, strlen(in->incomplete_data)); memcpy(http_del_copy, configure->http_del, configure->http_del_len); @@ -431,13 +590,23 @@ char *request_head(conn_t * in, conf * configure) if (configure->http_regrep) incomplete_head = regrep(incomplete_head, &incomplete_head_len, configure->http_regrep_aim, configure->http_regrep_obj, configure->http_regrep_obj_len); incomplete_head = replace(incomplete_head, &incomplete_head_len, "[host]", 6, http_request->host, http_request->host_len); - incomplete_head_len = strlen(incomplete_head); - //printf("%s", incomplete_head); + incomplete_head = replace(incomplete_head, &incomplete_head_len, "[port]", 6, http_request->port, http_request->port_len); + incomplete_head = replace(incomplete_head, &incomplete_head_len, "[H]", 3, http_request->H, http_request->H_len); + incomplete_head_len = strlen(incomplete_head); // 更新HTTP HEADER长度 + //printf("%s", incomplete_head); // 打印HTTP HEADER - memset(in->incomplete_data, 0, in->incomplete_data_len); - memmove(in->incomplete_data, incomplete_head, incomplete_head_len + 1); - in->incomplete_data_len = strlen(in->incomplete_data); - free(incomplete_head); + + char *new_incomplete_data; + new_incomplete_data = (char *)realloc(in->incomplete_data, incomplete_head_len + 1); // 更新incomplete_data堆内存 + if (new_incomplete_data == NULL) { + perror("realloc"); + return NULL; + } + in->incomplete_data = new_incomplete_data; + memset(in->incomplete_data, 0, incomplete_head_len + 1); // 清空incomplete_data数据 + memmove(in->incomplete_data, incomplete_head, incomplete_head_len + 1); // 更新incomplete_data数据 + in->incomplete_data_len = strlen(in->incomplete_data); // 更新incomplete_data长度 + free(incomplete_head); // 释放incomplete_head内存 } free_http_request(http_request); diff --git a/http_request.h b/http_request.h old mode 100644 new mode 100755 diff --git a/httpdns.c b/httpdns.c old mode 100644 new mode 100755 index 6c6aab1..ff21103 --- a/httpdns.c +++ b/httpdns.c @@ -20,7 +20,9 @@ int read_cache_file() { char *buff, *answer, *question; long file_size; + int fn; + fn = 0; cache = cache_temp = NULL; cache_using = 0; if ((cfp = fopen(cachePath, "rb+")) == NULL) { @@ -36,7 +38,9 @@ int read_cache_file() return 1; } rewind(cfp); - fread(buff, file_size, 1, cfp); + if ((fn = fread(buff, file_size, 1, cfp)) < 0) { + perror("fread"); + } //读取缓存,一组缓存的内容为[ipDomain\0],其中ip占5字节 for (answer = buff; answer - buff < file_size; answer = question + cache->question_len + 2) { diff --git a/main.c b/main.c old mode 100644 new mode 100755 index a374e4c..0849d7b --- a/main.c +++ b/main.c @@ -15,7 +15,7 @@ struct epoll_event ev, events[MAX_CONNECTION + 1]; int epollfd, server_sock, server_sock6; conn_t cts[MAX_CONNECTION]; int local_port; -char local_host[128]; +char local_host[CACHE_SIZE]; int process; int create_connection(char *remote_host, int remote_port) @@ -182,24 +182,20 @@ void *http_proxy_loop(void *p) n = epoll_wait(epollfd, events, MAX_CONNECTION, -1); while (n-- > 0) { if (events[n].data.fd == server_sock6) { - //printf("accept_client6()!!!\n"); accept_client6(); - ; } else if (events[n].data.fd == server_sock) { - //printf("accept_client()!!!\n"); accept_client(); } else { if (events[n].events & EPOLLIN) { - //printf("tcp_in()!!!\n"); tcp_in((conn_t *) events[n].data.ptr, configure); } if (events[n].events & EPOLLOUT) { - //printf("tcp_out()!!!\n"); tcp_out((conn_t *) events[n].data.ptr); } } } } + close(epollfd); return NULL; } @@ -208,6 +204,20 @@ void *start_server(conf * configure) { int n; pthread_t thread_id; + + ev.events = EPOLLIN; + ev.data.fd = server_sock; + if (-1 == epoll_ctl(epollfd, EPOLL_CTL_ADD, server_sock, &ev)) { + perror("epoll_ctl"); + exit(1); + } + ev.events = EPOLLIN; + ev.data.fd = server_sock6; + if (-1 == epoll_ctl(epollfd, EPOLL_CTL_ADD, server_sock6, &ev)) { + perror("epoll_ctl"); + exit(1); + } + if (timeout_minute) pthread_create(&thread_id, NULL, &tcp_timeout_check, NULL); @@ -228,7 +238,9 @@ void *start_server(conf * configure) } } } + close(epollfd); + return NULL; } int process_signal(int signal, char *process_name) @@ -266,9 +278,9 @@ int process_signal(int signal, char *process_name) } closedir(dir); - if (signal == SERVER_STATUS) { // 状态 - n -= 2; // 去除最后一个搜索时的本身进程和最后加一后未使用的 - for (; n >= 0; n--) { // 依据数组从大到小的下标打印PID + if (signal == SERVER_STATUS) { // 状态 + n -= 2; // 去除最后一个搜索时的本身进程和最后加一后未使用的 + for (; n >= 0; n--) { // 依据数组从大到小的下标打印PID printf("\t%d\n", number[n]); } } @@ -303,6 +315,7 @@ void server_ini() perror("daemon"); return; } + //while (process-- > 1 && fork() == 0); } @@ -399,15 +412,15 @@ void _main(int argc, char *argv[]) ; } } - + // 设置每个进程允许打开的最大文件数 rt.rlim_max = rt.rlim_cur = MAX_CONNECTION * 2; if (setrlimit(RLIMIT_NOFILE, &rt) == -1) { perror("setrlimit"); } - - server_ini(); // 守护进程 - httpdns_initialize(configure); // 初始化httpdns + + server_ini(); // 守护进程 + httpdns_initialize(configure); // 初始化httpdns memset(cts, 0, sizeof(cts)); for (i = MAX_CONNECTION; i--;) cts[i].fd = -1; @@ -420,8 +433,8 @@ void _main(int argc, char *argv[]) } } - server_sock = create_server_socket(configure->tcp_listen); // IPV4 - server_sock6 = create_server_socket6(configure->tcp6_listen); // IPV6 + server_sock = create_server_socket(configure->tcp_listen); // IPV4 + server_sock6 = create_server_socket6(configure->tcp6_listen); // IPV6 epollfd = epoll_create(MAX_CONNECTION); if (epollfd == -1) { perror("epoll_create"); @@ -430,9 +443,10 @@ void _main(int argc, char *argv[]) if (setegid(configure->uid) == -1 || seteuid(configure->uid) == -1) // 设置uid exit(1); - - //start_server(configure); // 单线程 - //httpdns_loop(configure); +/* + start_server(configure); // 单线程 + httpdns_loop(configure); +*/ pthread_t thread_id = 0; sigset_t signal_mask; @@ -441,6 +455,7 @@ void _main(int argc, char *argv[]) if (pthread_sigmask(SIG_BLOCK, &signal_mask, NULL) != 0) { printf("block sigpipe error\n"); } + if (timeout_minute) pthread_create(&thread_id, NULL, &tcp_timeout_check, NULL); if (pthread_create(&thread_id, NULL, &http_proxy_loop, (void *)configure) != 0) @@ -464,7 +479,7 @@ void _main(int argc, char *argv[]) return; } -int main(int argc, char *argv[]) +int main(int argc, char *argv[], char **env) { _main(argc, argv); return 0; diff --git a/main.h b/main.h old mode 100644 new mode 100755 index 8df2ad0..9e28961 --- a/main.h +++ b/main.h @@ -26,9 +26,10 @@ #define BUFFER_SIZE 8192 #define PATH_SIZE 270 #define CACHE_SIZE 270 +#define HTTP_HEAD_CACHE_SIZE 1024 extern int local_port; -extern char local_host[128]; +extern char local_host[CACHE_SIZE]; extern int process; extern int epollfd; diff --git a/timeout.c b/timeout.c old mode 100644 new mode 100755 index acf4e3b..264a10d --- a/timeout.c +++ b/timeout.c @@ -10,12 +10,13 @@ void *tcp_timeout_check(void *nullPtr) while (1) { sleep(60); - for (i = 0; i < MAX_CONNECTION; i += 2) + for (i = 0; i < MAX_CONNECTION; i += 2) { if (cts[i].fd > -1) { if (cts[i].timer >= timeout_minute) { close_connection(cts + i); } else cts[i].timer++; } + } } }