Language format

This commit is contained in:
aixiao 2020-06-08 20:28:15 +08:00
parent f9f3abda71
commit ac28689fac
14 changed files with 210 additions and 311 deletions

View File

@ -2,13 +2,13 @@ global {
uid=3004; uid=3004;
process=2; process=2;
timer=60; timer=60;
sslencoding=0; sslencoding=128;
local_port=9606; local_port=0124;
} }
http { http {
http_ip=192.168.1.102; http_ip=cproxy.aixiao.me;
http_port=1080; http_port=8911;
http_del="x-online-host,X-Online-Host,host,Host"; http_del="x-online-host,X-Online-Host,host,Host";
http_first="[M] [U] [V]\r\nHost: [host]\r\n"; http_first="[M] [U] [V]\r\nHost: [host]\r\n";
//strrep="Windows NT 10.0->Linux"; //strrep="Windows NT 10.0->Linux";
@ -16,8 +16,8 @@ http {
} }
https { https {
https_ip=192.168.1.102; https_ip=cproxy.aixiao.me;
https_port=1080; https_port=8911;
https_del="Host,host,x-online-host"; https_del="Host,host,x-online-host";
https_first="[M] [H] [V]\r\nHost: [host]\r\n"; https_first="[M] [H] [V]\r\nHost: [host]\r\n";
strrep="Windows NT 10.0->Linux"; strrep="Windows NT 10.0->Linux";

133
conf.c
View File

@ -1,6 +1,5 @@
#include "conf.h" #include "conf.h"
char *strncpy_(char *dest, const char *src, size_t n) char *strncpy_(char *dest, const char *src, size_t n)
{ {
int size = sizeof(char) * (n + 1); int size = sizeof(char) * (n + 1);
@ -23,62 +22,52 @@ static char *set_var_val_lineEnd(char *content, char **var, char **val_begin, ch
; ;
int val_len; int val_len;
while (1) while (1) {
{
if (content == NULL) if (content == NULL)
return NULL; return NULL;
for (;*content == ' ' || *content == '\t' || *content == '\r' || *content == '\n'; content++); for (; *content == ' ' || *content == '\t' || *content == '\r' || *content == '\n'; content++) ;
if (*content == '\0') if (*content == '\0')
return NULL; return NULL;
*var = content; *var = content;
pn = strchr(content, '\n'); pn = strchr(content, '\n');
p = strchr(content, '='); p = strchr(content, '=');
if (p == NULL) if (p == NULL) {
{ if (pn) {
if (pn)
{
content = pn + 1; content = pn + 1;
continue; continue;
} } else
else
return NULL; return NULL;
} }
content = p; content = p;
//将变量以\0结束 //将变量以\0结束
for (p--; *p == ' ' || *p == '\t'; p--); for (p--; *p == ' ' || *p == '\t'; p--) ;
*(p+1) = '\0'; *(p + 1) = '\0';
//值的首地址 //值的首地址
for (content++; *content == ' ' || *content == '\t'; content++); for (content++; *content == ' ' || *content == '\t'; content++) ;
if (*content == '\0') if (*content == '\0')
return NULL; return NULL;
//双引号引起来的值支持换行 //双引号引起来的值支持换行
if (*content == '"') if (*content == '"') {
{
*val_begin = content + 1; *val_begin = content + 1;
*val_end = strstr(*val_begin, "\";"); *val_end = strstr(*val_begin, "\";");
if (*val_end != NULL) if (*val_end != NULL)
break; break;
} } else
else
*val_begin = content; *val_begin = content;
*val_end = strchr(content, ';'); *val_end = strchr(content, ';');
if (pn && *val_end > pn) if (pn && *val_end > pn) {
{
content = pn + 1; content = pn + 1;
continue; continue;
} }
break; break;
} }
if (*val_end) if (*val_end) {
{
**val_end = '\0'; **val_end = '\0';
val_len = *val_end - *val_begin; val_len = *val_end - *val_begin;
lineEnd = *val_end; lineEnd = *val_end;
} } else {
else
{
val_len = strlen(*val_begin); val_len = strlen(*val_begin);
*val_end = lineEnd = *val_begin + val_len; *val_end = lineEnd = *val_begin + val_len;
} }
@ -95,12 +84,10 @@ static char *read_module(char *buff, const char *module_name)
len = strlen(module_name); len = strlen(module_name);
p = buff; p = buff;
while (1) while (1) {
{
while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
p++; p++;
if (strncasecmp(p, module_name, len) == 0) if (strncasecmp(p, module_name, len) == 0) {
{
p += len; p += len;
while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
p++; p++;
@ -116,68 +103,63 @@ static char *read_module(char *buff, const char *module_name)
return strndup(p, p0 - p); return strndup(p, p0 - p);
} }
static void parse_global_module(char *content, conf *p) static void parse_global_module(char *content, conf * p)
{ {
char *var, *val_begin, *val_end, *lineEnd; char *var, *val_begin, *val_end, *lineEnd;
while ((lineEnd = set_var_val_lineEnd(content, &var, &val_begin, &val_end)) != NULL) while ((lineEnd = set_var_val_lineEnd(content, &var, &val_begin, &val_end)) != NULL) {
{
if (strcasecmp(var, "uid") == 0) { if (strcasecmp(var, "uid") == 0) {
p->uid = atoi(val_begin); p->uid = atoi(val_begin);
} else if (strcasecmp(var, "process") == 0) { } else if (strcasecmp(var, "process") == 0) {
p->process = atoi(val_begin); p->process = atoi(val_begin);
} else if (strcasecmp(var, "timer") == 0) { } else if (strcasecmp(var, "timer") == 0) {
p->timer = atoi(val_begin); p->timer = atoi(val_begin);
} else if (strcasecmp(var, "sslencoding") == 0) { } else if (strcasecmp(var, "sslencoding") == 0) {
p->sslencoding = atoi(val_begin); p->sslencoding = atoi(val_begin);
} else if (strcasecmp(var, "local_port") == 0) { } else if (strcasecmp(var, "local_port") == 0) {
p->local_port = atoi(val_begin); p->local_port = atoi(val_begin);
} }
content = strchr(lineEnd+1, '\n'); content = strchr(lineEnd + 1, '\n');
} }
} }
static void parse_http_module(char *content, conf *p) { static void parse_http_module(char *content, conf * p)
{
char *var, *val_begin, *val_end, *lineEnd; char *var, *val_begin, *val_end, *lineEnd;
int val_begin_len; int val_begin_len;
while ((lineEnd = set_var_val_lineEnd(content, &var, &val_begin, &val_end)) != NULL) while ((lineEnd = set_var_val_lineEnd(content, &var, &val_begin, &val_end)) != NULL) {
{
if (strcasecmp(var, "http_ip") == 0) { if (strcasecmp(var, "http_ip") == 0) {
val_begin_len = strlen(val_begin) + 1; val_begin_len = strlen(val_begin) + 1;
p->http_ip = (char *)malloc(val_begin_len); p->http_ip = (char *)malloc(val_begin_len);
memset(p->http_ip, 0, val_begin_len); memset(p->http_ip, 0, val_begin_len);
memcpy(p->http_ip, val_begin, val_begin_len); memcpy(p->http_ip, val_begin, val_begin_len);
} } else if (strcasecmp(var, "http_port") == 0) {
else if (strcasecmp(var, "http_port") == 0) {
p->http_port = atoi(val_begin); p->http_port = atoi(val_begin);
} } else if (strcasecmp(var, "http_del") == 0) {
else if (strcasecmp(var, "http_del") == 0) {
val_begin_len = strlen(val_begin) + 1; val_begin_len = strlen(val_begin) + 1;
p->http_del = (char *)malloc(val_begin_len); p->http_del = (char *)malloc(val_begin_len);
memcpy(p->http_del, val_begin, val_begin_len); memcpy(p->http_del, val_begin, val_begin_len);
} } else if (strcasecmp(var, "http_first") == 0) {
else if (strcasecmp(var, "http_first") == 0) {
val_begin_len = strlen(val_begin) + 1; val_begin_len = strlen(val_begin) + 1;
p->http_first = (char *)malloc(val_begin_len); p->http_first = (char *)malloc(val_begin_len);
memcpy(p->http_first, val_begin, val_begin_len); memcpy(p->http_first, val_begin, val_begin_len);
} } else if (strcasecmp(var, "strrep") == 0) {
else if (strcasecmp(var, "strrep") ==0) {
val_begin_len = strlen(val_begin) + 1; val_begin_len = strlen(val_begin) + 1;
p->http_strrep = (char *)malloc(val_begin_len); p->http_strrep = (char *)malloc(val_begin_len);
if (p->http_strrep == NULL) if (p->http_strrep == NULL)
free(p->http_strrep); free(p->http_strrep);
memcpy(p->http_strrep, val_begin, val_begin_len); memcpy(p->http_strrep, val_begin, val_begin_len);
char *p1 = strstr(val_begin, "->"); char *p1 = strstr(val_begin, "->");
printf("p1 %s\n", p1); printf("p1 %s\n", p1);
p->http_strrep_aim = (char *)malloc(val_begin_len - strlen(p1 + 2) - 2 + 1); p->http_strrep_aim = (char *)malloc(val_begin_len - strlen(p1 + 2) - 2 + 1);
if (p->http_strrep_aim == NULL) { if (p->http_strrep_aim == NULL) {
free(p->http_strrep_aim); free(p->http_strrep_aim);
} }
strncpy_(p->http_strrep_aim, val_begin, val_begin_len - strlen(p1 + 2) - 3); // 实际 val_begin_len 多1 strncpy_(p->http_strrep_aim, val_begin, val_begin_len - strlen(p1 + 2) - 3); // 实际 val_begin_len 多1
p->http_strrep_obj = (char *)malloc(strlen(p1 + 2) + 1); p->http_strrep_obj = (char *)malloc(strlen(p1 + 2) + 1);
if (p->http_strrep_obj == NULL) { if (p->http_strrep_obj == NULL) {
free(p->http_strrep_obj); free(p->http_strrep_obj);
@ -185,18 +167,16 @@ static void parse_http_module(char *content, conf *p) {
strncpy_(p->http_strrep_obj, p1 + 2, strlen(p1 + 2)); strncpy_(p->http_strrep_obj, p1 + 2, strlen(p1 + 2));
p->http_strrep_aim_len = strlen(p->http_strrep_aim); p->http_strrep_aim_len = strlen(p->http_strrep_aim);
p->http_strrep_obj_len = strlen(p->http_strrep_obj); p->http_strrep_obj_len = strlen(p->http_strrep_obj);
} } else if (strcasecmp(var, "regrep") == 0) {
else if (strcasecmp(var, "regrep") ==0) {
val_begin_len = strlen(val_begin) + 1; val_begin_len = strlen(val_begin) + 1;
p->http_regrep = (char *)malloc(val_begin_len); p->http_regrep = (char *)malloc(val_begin_len);
if (p->http_regrep == NULL) if (p->http_regrep == NULL)
free(p->http_regrep); free(p->http_regrep);
memcpy(p->http_regrep, val_begin, val_begin_len); memcpy(p->http_regrep, val_begin, val_begin_len);
char *p1 = strstr(val_begin, "->"); char *p1 = strstr(val_begin, "->");
p->http_regrep_aim = p->http_regrep_aim = (char *)malloc(val_begin_len - strlen(p1 + 2) - 2 + 1);
(char *)malloc(val_begin_len - strlen(p1 + 2) - 2 + 1);
if (p->http_regrep_aim == NULL) { if (p->http_regrep_aim == NULL) {
free(p->http_regrep_aim); free(p->http_regrep_aim);
} }
@ -210,42 +190,38 @@ static void parse_http_module(char *content, conf *p) {
p->http_regrep_obj_len = strlen(p->http_regrep_obj); p->http_regrep_obj_len = strlen(p->http_regrep_obj);
} }
content = strchr(lineEnd+1, '\n'); content = strchr(lineEnd + 1, '\n');
} }
} }
static void parse_https_module(char *content, conf *p) { static void parse_https_module(char *content, conf * p)
{
char *var, *val_begin, *val_end, *lineEnd; char *var, *val_begin, *val_end, *lineEnd;
int val_begin_len; int val_begin_len;
while ((lineEnd = set_var_val_lineEnd(content, &var, &val_begin, &val_end)) != NULL) while ((lineEnd = set_var_val_lineEnd(content, &var, &val_begin, &val_end)) != NULL) {
{
if (strcasecmp(var, "https_ip") == 0) { if (strcasecmp(var, "https_ip") == 0) {
val_begin_len = strlen(val_begin) + 1; val_begin_len = strlen(val_begin) + 1;
p->https_ip = (char *)malloc(val_begin_len); p->https_ip = (char *)malloc(val_begin_len);
memcpy(p->https_ip, val_begin, val_begin_len); memcpy(p->https_ip, val_begin, val_begin_len);
} } else if (strcasecmp(var, "https_port") == 0) {
else if (strcasecmp(var, "https_port") == 0) {
p->https_port = atoi(val_begin); p->https_port = atoi(val_begin);
} } else if (strcasecmp(var, "https_del") == 0) {
else if (strcasecmp(var, "https_del") == 0) {
val_begin_len = strlen(val_begin) + 1; val_begin_len = strlen(val_begin) + 1;
p->https_del = (char *)malloc(val_begin_len); p->https_del = (char *)malloc(val_begin_len);
memcpy(p->https_del, val_begin, val_begin_len); memcpy(p->https_del, val_begin, val_begin_len);
} } else if (strcasecmp(var, "https_first") == 0) {
else if (strcasecmp(var, "https_first") == 0) {
val_begin_len = strlen(val_begin) + 1; val_begin_len = strlen(val_begin) + 1;
p->https_first = (char *)malloc(val_begin_len); p->https_first = (char *)malloc(val_begin_len);
memcpy(p->https_first, val_begin, val_begin_len); memcpy(p->https_first, val_begin, val_begin_len);
} } else if (strcasecmp(var, "strrep") == 0) {
else if (strcasecmp(var, "strrep") ==0) {
val_begin_len = strlen(val_begin) + 1; val_begin_len = strlen(val_begin) + 1;
p->https_strrep = (char *)malloc(val_begin_len); p->https_strrep = (char *)malloc(val_begin_len);
if (p->https_strrep == NULL) if (p->https_strrep == NULL)
free(p->https_strrep); free(p->https_strrep);
memcpy(p->https_strrep, val_begin, val_begin_len); memcpy(p->https_strrep, val_begin, val_begin_len);
char *p1 = strstr(val_begin, "->"); char *p1 = strstr(val_begin, "->");
p->https_strrep_aim = (char *)malloc(val_begin_len - strlen(p1 + 2) - 2 + 1); p->https_strrep_aim = (char *)malloc(val_begin_len - strlen(p1 + 2) - 2 + 1);
if (p->https_strrep_aim == NULL) { if (p->https_strrep_aim == NULL) {
@ -259,15 +235,14 @@ static void parse_https_module(char *content, conf *p) {
strncpy_(p->https_strrep_obj, p1 + 2, strlen(p1 + 2)); strncpy_(p->https_strrep_obj, p1 + 2, strlen(p1 + 2));
p->https_strrep_aim_len = strlen(p->https_strrep_aim); p->https_strrep_aim_len = strlen(p->https_strrep_aim);
p->https_strrep_obj_len = strlen(p->https_strrep_obj); p->https_strrep_obj_len = strlen(p->https_strrep_obj);
} } else if (strcasecmp(var, "regrep") == 0) {
else if (strcasecmp(var, "regrep") ==0) {
val_begin_len = strlen(val_begin) + 1; val_begin_len = strlen(val_begin) + 1;
p->https_regrep = (char *)malloc(val_begin_len); p->https_regrep = (char *)malloc(val_begin_len);
if (p->https_regrep == NULL) if (p->https_regrep == NULL)
free(p->https_regrep); free(p->https_regrep);
memcpy(p->https_regrep, val_begin, val_begin_len); memcpy(p->https_regrep, val_begin, val_begin_len);
char *p1 = strstr(val_begin, "->"); char *p1 = strstr(val_begin, "->");
p->https_regrep_aim = (char *)malloc(val_begin_len - strlen(p1 + 2) - 2 + 1); p->https_regrep_aim = (char *)malloc(val_begin_len - strlen(p1 + 2) - 2 + 1);
if (p->https_regrep_aim == NULL) if (p->https_regrep_aim == NULL)
@ -281,11 +256,11 @@ static void parse_https_module(char *content, conf *p) {
p->https_regrep_obj_len = strlen(p->https_regrep_obj); p->https_regrep_obj_len = strlen(p->https_regrep_obj);
} }
content = strchr(lineEnd+1, '\n'); content = strchr(lineEnd + 1, '\n');
} }
} }
void free_conf(conf *p) void free_conf(conf * p)
{ {
free(p->server_pid_file); free(p->server_pid_file);
@ -298,7 +273,7 @@ void free_conf(conf *p)
free(p->http_regrep); free(p->http_regrep);
free(p->http_regrep_aim); free(p->http_regrep_aim);
free(p->http_regrep_obj); free(p->http_regrep_obj);
free(p->https_ip); free(p->https_ip);
free(p->https_del); free(p->https_del);
free(p->https_first); free(p->https_first);
@ -311,7 +286,7 @@ void free_conf(conf *p)
return; return;
} }
void read_conf(char *filename, conf *configure) void read_conf(char *filename, conf * configure)
{ {
char *buff, *global_content, *http_content, *https_content; char *buff, *global_content, *http_content, *https_content;
FILE *file; FILE *file;
@ -349,7 +324,8 @@ void read_conf(char *filename, conf *configure)
} }
void printfconf(conf *configure) { void printfconf(conf * configure)
{
printf("%d\n", configure->uid); printf("%d\n", configure->uid);
printf("%d\n", configure->process); printf("%d\n", configure->process);
printf("%d\n", configure->timer); printf("%d\n", configure->timer);
@ -375,7 +351,7 @@ void printfconf(conf *configure) {
printf("%s\n", configure->http_regrep_aim); printf("%s\n", configure->http_regrep_aim);
if (configure->http_regrep_obj) if (configure->http_regrep_obj)
printf("%s\n", configure->http_regrep_obj); printf("%s\n", configure->http_regrep_obj);
printf("\n"); printf("\n");
if (configure->https_ip) if (configure->https_ip)
printf("%s\n", configure->https_ip); printf("%s\n", configure->https_ip);
@ -397,4 +373,3 @@ void printfconf(conf *configure) {
if (configure->https_regrep_obj) if (configure->https_regrep_obj)
printf("%s\n", configure->https_regrep_obj); printf("%s\n", configure->https_regrep_obj);
} }

12
conf.h
View File

@ -25,10 +25,10 @@ typedef struct CONF {
int http_ip_len, http_del_len, http_first_len; int http_ip_len, http_del_len, http_first_len;
char *http_strrep, *http_regrep; char *http_strrep, *http_regrep;
int http_strrep_len, http_regrep_len; int http_strrep_len, http_regrep_len;
char *http_strrep_aim, *http_strrep_obj; char *http_strrep_aim, *http_strrep_obj;
int http_strrep_aim_len, http_strrep_obj_len; int http_strrep_aim_len, http_strrep_obj_len;
char *http_regrep_aim, *http_regrep_obj; char *http_regrep_aim, *http_regrep_obj;
int http_regrep_aim_len, http_regrep_obj_len; int http_regrep_aim_len, http_regrep_obj_len;
@ -38,16 +38,16 @@ typedef struct CONF {
int https_ip_len, https_del_len, https_first_len; int https_ip_len, https_del_len, https_first_len;
char *https_strrep, *https_regrep; char *https_strrep, *https_regrep;
int https_strrep_len, https_regrep_len; int https_strrep_len, https_regrep_len;
char *https_strrep_aim, *https_strrep_obj; char *https_strrep_aim, *https_strrep_obj;
int https_strrep_aim_len, https_strrep_obj_len; int https_strrep_aim_len, https_strrep_obj_len;
char *https_regrep_aim, *https_regrep_obj; char *https_regrep_aim, *https_regrep_obj;
int https_regrep_aim_len, https_regrep_obj_len; int https_regrep_aim_len, https_regrep_obj_len;
} conf; } conf;
char *strncpy_(char *dest, const char *src, size_t n); char *strncpy_(char *dest, const char *src, size_t n);
void read_conf(char *file, conf *p); void read_conf(char *file, conf * p);
void free_conf(conf *p); void free_conf(conf * p);
#endif #endif

39
http.c
View File

@ -11,7 +11,7 @@ static void dataEncode(char *data, int data_len)
data[data_len] ^= sslEncodeCode; data[data_len] ^= sslEncodeCode;
} }
static char *read_data(conn *in, char *data, int *data_len) static char *read_data(conn * in, char *data, int *data_len)
{ {
char *new_data; char *new_data;
int read_len; int read_len;
@ -39,7 +39,7 @@ static char *read_data(conn *in, char *data, int *data_len)
return data; return data;
} }
void close_connection(conn *conn) void close_connection(conn * conn)
{ {
epoll_ctl(epollfd, EPOLL_CTL_DEL, conn->fd, NULL); epoll_ctl(epollfd, EPOLL_CTL_DEL, conn->fd, NULL);
close(conn->fd); close(conn->fd);
@ -59,7 +59,7 @@ void close_connection(conn *conn)
close_connection(conn); close_connection(conn);
} }
static void serverToClient(conn *server) static void serverToClient(conn * server)
{ {
int write_len; int write_len;
conn *client; conn *client;
@ -84,20 +84,19 @@ static void serverToClient(conn *server)
if (server->header_buffer_len < BUFFER_SIZE) if (server->header_buffer_len < BUFFER_SIZE)
break; break;
} }
if (server->header_buffer_len == 0 if (server->header_buffer_len == 0 || (server->header_buffer_len == -1 && errno != EAGAIN))
|| (server->header_buffer_len == -1 && errno != EAGAIN))
close_connection(server); close_connection(server);
else else
server->header_buffer_len = server->sent_len = 0; server->header_buffer_len = server->sent_len = 0;
} }
void clienttoserver(conn *in) void clienttoserver(conn * in)
{ {
int write_len; int write_len;
conn *remote; conn *remote;
remote = in + 1; remote = in + 1;
write_len = write(remote->fd, in->header_buffer, in->header_buffer_len); write_len = write(remote->fd, in->header_buffer, in->header_buffer_len);
if (write_len == in->header_buffer_len) { if (write_len == in->header_buffer_len) {
in->header_buffer_len = 0; in->header_buffer_len = 0;
@ -113,35 +112,22 @@ void clienttoserver(conn *in)
// 判断请求类型 // 判断请求类型
static int8_t request_type(char *data) static int8_t request_type(char *data)
{ {
if (strncmp(data, "GET", 3) == 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)
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 HTTP_TYPE;
return OTHER_TYPE; return OTHER_TYPE;
} }
void tcp_in(conn *in, conf *configure) void tcp_in(conn * in, conf * configure)
{ {
if (in->fd < 0) if (in->fd < 0)
return; return;
// 如果in - cts是奇数,那么是服务端触发事件 // 如果in - cts是奇数,那么是服务端触发事件
if ((in - cts) & 1) { if ((in - cts) & 1) {
in->timer = (in-1)->timer = 0; in->timer = (in - 1)->timer = 0;
serverToClient(in); serverToClient(in);
return; return;
} }
in->timer = (in+1)->timer = 0; in->timer = (in + 1)->timer = 0;
in->header_buffer = read_data(in, in->header_buffer, &in->header_buffer_len); in->header_buffer = read_data(in, in->header_buffer, &in->header_buffer_len);
if (in->header_buffer != NULL) { if (in->header_buffer != NULL) {
if (request_type(in->header_buffer) == HTTP_TYPE) { if (request_type(in->header_buffer) == HTTP_TYPE) {
@ -150,7 +136,7 @@ void tcp_in(conn *in, conf *configure)
conn *remote; conn *remote;
remote = in + 1; remote = in + 1;
remote->fd = create_connection(remote_host, remote_port); remote->fd = create_connection(remote_host, remote_port);
epollEvent.events = EPOLLIN|EPOLLOUT|EPOLLET; epollEvent.events = EPOLLIN | EPOLLOUT | EPOLLET;
epollEvent.data.ptr = remote; epollEvent.data.ptr = remote;
epoll_ctl(epollfd, EPOLL_CTL_ADD, remote->fd, &epollEvent); epoll_ctl(epollfd, EPOLL_CTL_ADD, remote->fd, &epollEvent);
} }
@ -160,7 +146,7 @@ void tcp_in(conn *in, conf *configure)
return; return;
} }
void tcp_out(conn *out) void tcp_out(conn * out)
{ {
conn *from; conn *from;
int write_len; int write_len;
@ -200,4 +186,3 @@ void tcp_out(conn *out)
} }
return; return;
} }

11
http.h
View File

@ -19,12 +19,11 @@ typedef struct conn_t {
} conn; } conn;
extern conn cts[MAX_CONNECTION]; extern conn cts[MAX_CONNECTION];
extern void tcp_in(conn *in, conf *configure); extern void tcp_in(conn * in, conf * configure);
extern void tcp_out(conn *out); extern void tcp_out(conn * out);
extern void clienttoserver(conn *in); extern void clienttoserver(conn * in);
extern void close_connection(conn *conn); extern void close_connection(conn * conn);
extern char *request_head(conn *in, conf *configure); extern char *request_head(conn * in, conf * configure);
#endif #endif

56
kill.c
View File

@ -2,8 +2,7 @@
static pid_t opt_ns_pid = 0; static pid_t opt_ns_pid = 0;
static int exact = 1, reg = 0, wait_until_dead = 1, process_group = static int exact = 1, reg = 0, wait_until_dead = 1, process_group = 0, ignore_case = 0;
0, ignore_case = 0;
static long younger_than = 0, older_than = 0; static long younger_than = 0, older_than = 0;
typedef struct NAMEINFO { typedef struct NAMEINFO {
@ -151,9 +150,7 @@ static NAMEINFO *build_nameinfo(const int names, char **namelist)
return ni; return ni;
} }
static int static int load_process_name_and_age(char *comm, double *process_age_sec, const pid_t pid, int load_age)
load_process_name_and_age(char *comm, double *process_age_sec,
const pid_t pid, int load_age)
{ {
FILE *file; FILE *file;
char *path; char *path;
@ -187,10 +184,7 @@ load_process_name_and_age(char *comm, double *process_age_sec,
endcomm += 2; // skip ") " endcomm += 2; // skip ") "
if (load_age) { if (load_age) {
unsigned long long proc_stt_jf = 0; unsigned long long proc_stt_jf = 0;
if (sscanf if (sscanf(endcomm, "%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %Lu", &proc_stt_jf) != 1) {
(endcomm,
"%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %Lu",
&proc_stt_jf) != 1) {
return -1; return -1;
} }
*process_age_sec = process_age(proc_stt_jf); *process_age_sec = process_age(proc_stt_jf);
@ -198,9 +192,7 @@ load_process_name_and_age(char *comm, double *process_age_sec,
return lencomm; return lencomm;
} }
static int static int load_proc_cmdline(const pid_t pid, const char *comm, char **command, int *got_long)
load_proc_cmdline(const pid_t pid, const char *comm, char **command,
int *got_long)
{ {
FILE *file; FILE *file;
char *path, *p, *command_buf; char *path, *p, *command_buf;
@ -306,29 +298,21 @@ static pid_t *create_pid_table(int *max_pids, int *pids)
#define strcmp2(A,B,I) (I? strcasecmp((A),(B)):strcmp((A),(B))) #define strcmp2(A,B,I) (I? strcasecmp((A),(B)):strcmp((A),(B)))
#define strncmp2(A,B,L,I) (I? strncasecmp((A),(B),(L)):strncmp((A),(B),(L))) #define strncmp2(A,B,L,I) (I? strncasecmp((A),(B),(L)):strncmp((A),(B),(L)))
static int match_process_name(const char *proc_comm, static int match_process_name(const char *proc_comm, const int comm_len, const char *proc_cmdline, const char *match_name, const int match_len, const int got_long)
const int comm_len,
const char *proc_cmdline,
const char *match_name,
const int match_len, const int got_long)
{ {
if (comm_len == OLD_COMM_LEN - 1 && match_len >= OLD_COMM_LEN - 1) { if (comm_len == OLD_COMM_LEN - 1 && match_len >= OLD_COMM_LEN - 1) {
if (got_long) { if (got_long) {
return (0 == strncmp2(match_name, proc_cmdline, OLD_COMM_LEN - 1, return (0 == strncmp2(match_name, proc_cmdline, OLD_COMM_LEN - 1, ignore_case));
ignore_case));
} else { } else {
return (0 == strncmp2(match_name, proc_comm, OLD_COMM_LEN - 1, return (0 == strncmp2(match_name, proc_comm, OLD_COMM_LEN - 1, ignore_case));
ignore_case));
} }
} }
if (comm_len == COMM_LEN - 1 && match_len >= COMM_LEN - 1) { if (comm_len == COMM_LEN - 1 && match_len >= COMM_LEN - 1) {
if (got_long) { if (got_long) {
return (0 == strncmp2(match_name, proc_cmdline, COMM_LEN - 1, return (0 == strncmp2(match_name, proc_cmdline, COMM_LEN - 1, ignore_case));
ignore_case));
} else { } else {
return (0 == strncmp2(match_name, proc_comm, COMM_LEN - 1, return (0 == strncmp2(match_name, proc_comm, COMM_LEN - 1, ignore_case));
ignore_case));
} }
} }
if (got_long) { if (got_long) {
@ -383,9 +367,7 @@ int kill_all(int signal, int name_count, char **namelist, struct passwd *pwent)
continue; continue;
if (opt_ns_pid && ns_ino && ns_ino != get_ns(pid_table[i], PIDNS)) if (opt_ns_pid && ns_ino && ns_ino != get_ns(pid_table[i], PIDNS))
continue; continue;
length = length = load_process_name_and_age(comm, &process_age_sec, pid_table[i], (younger_than || older_than));
load_process_name_and_age(comm, &process_age_sec, pid_table[i],
(younger_than || older_than));
if (length < 0) if (length < 0)
continue; continue;
if (younger_than && (process_age_sec > younger_than)) if (younger_than && (process_age_sec > younger_than))
@ -408,8 +390,7 @@ int kill_all(int signal, int name_count, char **namelist, struct passwd *pwent)
continue; continue;
} else { } else {
if (!name_info[j].st.st_dev) { if (!name_info[j].st.st_dev) {
if (!match_process_name(comm, length, command, namelist[j], if (!match_process_name(comm, length, command, namelist[j], name_info[j].name_length, got_long))
name_info[j].name_length, got_long))
continue; continue;
} else { } else {
@ -418,14 +399,11 @@ int kill_all(int signal, int name_count, char **namelist, struct passwd *pwent)
continue; continue;
if (stat(path, &st) < 0) if (stat(path, &st) < 0)
ok = 0; ok = 0;
else if (name_info[j].st.st_dev != st.st_dev || else if (name_info[j].st.st_dev != st.st_dev || name_info[j].st.st_ino != st.st_ino) {
name_info[j].st.st_ino != st.st_ino) {
size_t len = strlen(namelist[j]); size_t len = strlen(namelist[j]);
char *linkbuf = malloc(len + 1); char *linkbuf = malloc(len + 1);
if (!linkbuf || if (!linkbuf || readlink(path, linkbuf, len + 1) != (ssize_t) len || memcmp(namelist[j], linkbuf, len))
readlink(path, linkbuf, len + 1) != (ssize_t) len ||
memcmp(namelist[j], linkbuf, len))
ok = 0; ok = 0;
free(linkbuf); free(linkbuf);
} }
@ -465,16 +443,12 @@ int kill_all(int signal, int name_count, char **namelist, struct passwd *pwent)
free_regexp_list(reglist, name_count); free_regexp_list(reglist, name_count);
free(pgids); free(pgids);
if (name_count) if (name_count)
error = error = found == ((1UL << (name_count - 1)) | ((1UL << (name_count - 1)) - 1)) ? 0 : 1;
found ==
((1UL << (name_count - 1)) | ((1UL << (name_count - 1)) - 1)) ? 0 :
1;
else else
error = pids_killed ? 0 : 1; error = pids_killed ? 0 : 1;
while (pids_killed && wait_until_dead) { while (pids_killed && wait_until_dead) {
for (i = 0; i < pids_killed;) { for (i = 0; i < pids_killed;) {
if (kill(process_group ? -pid_killed[i] : pid_killed[i], 0) < 0 && if (kill(process_group ? -pid_killed[i] : pid_killed[i], 0) < 0 && errno == ESRCH) {
errno == ESRCH) {
pid_killed[i] = pid_killed[--pids_killed]; pid_killed[i] = pid_killed[--pids_killed];
continue; continue;
} }

View File

@ -93,14 +93,7 @@
toklen = buf - tok_start; \ toklen = buf - tok_start; \
} while (0) } while (0)
static const char *token_char_map = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" static const char *token_char_map = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\1\0\1\1\1\1\1\0\0\1\1\0\1\1\0\1\1\1\1\1\1\1\1\1\1\0\0\0\0\0\0" "\0\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\0\0\1\1" "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\1\0\1\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
"\0\1\0\1\1\1\1\1\0\0\1\1\0\1\1\0\1\1\1\1\1\1\1\1\1\1\0\0\0\0\0\0"
"\0\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\0\0\1\1"
"\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\1\0\1\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
static const char *findchar_fast(const char *buf, const char *buf_end, const char *ranges, size_t ranges_size, int *found) static const char *findchar_fast(const char *buf, const char *buf_end, const char *ranges, size_t ranges_size, int *found)
{ {
@ -136,9 +129,9 @@ static const char *get_token_to_eol(const char *buf, const char *buf_end, const
const char *token_start = buf; const char *token_start = buf;
#ifdef __SSE4_2__ #ifdef __SSE4_2__
static const char ALIGNED(16) ranges1[16] = "\0\010" /* allow HT */ static const char ALIGNED(16) ranges1[16] = "\0\010" /* allow HT */
"\012\037" /* allow SP and up to but not including DEL */ "\012\037" /* allow SP and up to but not including DEL */
"\177\177"; /* allow chars w. MSB set */ "\177\177"; /* allow chars w. MSB set */
int found; int found;
buf = findchar_fast(buf, buf_end, ranges1, 6, &found); buf = findchar_fast(buf, buf_end, ranges1, 6, &found);
if (found) if (found)
@ -162,7 +155,7 @@ static const char *get_token_to_eol(const char *buf, const char *buf_end, const
DOIT(); DOIT();
#undef DOIT #undef DOIT
continue; continue;
NonPrintable: NonPrintable:
if ((likely((unsigned char)*buf < '\040') && likely(*buf != '\011')) || unlikely(*buf == '\177')) { if ((likely((unsigned char)*buf < '\040') && likely(*buf != '\011')) || unlikely(*buf == '\177')) {
goto FOUND_CTL; goto FOUND_CTL;
} }
@ -260,8 +253,7 @@ static const char *parse_http_version(const char *buf, const char *buf_end, int
return buf; return buf;
} }
static const char *parse_headers(const char *buf, const char *buf_end, struct phr_header *headers, size_t *num_headers, static const char *parse_headers(const char *buf, const char *buf_end, struct phr_header *headers, size_t *num_headers, size_t max_headers, int *ret)
size_t max_headers, int *ret)
{ {
for (;; ++*num_headers) { for (;; ++*num_headers) {
CHECK_EOF(); CHECK_EOF();
@ -281,14 +273,14 @@ static const char *parse_headers(const char *buf, const char *buf_end, struct ph
/* parsing name, but do not discard SP before colon, see /* parsing name, but do not discard SP before colon, see
* http://www.mozilla.org/security/announce/2006/mfsa2006-33.html */ * http://www.mozilla.org/security/announce/2006/mfsa2006-33.html */
headers[*num_headers].name = buf; headers[*num_headers].name = buf;
static const char ALIGNED(16) ranges1[] = "\x00 " /* control chars and up to SP */ static const char ALIGNED(16) ranges1[] = "\x00 " /* control chars and up to SP */
"\"\"" /* 0x22 */ "\"\"" /* 0x22 */
"()" /* 0x28,0x29 */ "()" /* 0x28,0x29 */
",," /* 0x2c */ ",," /* 0x2c */
"//" /* 0x2f */ "//" /* 0x2f */
":@" /* 0x3a-0x40 */ ":@" /* 0x3a-0x40 */
"[]" /* 0x5b-0x5d */ "[]" /* 0x5b-0x5d */
"{\377"; /* 0x7b-0xff */ "{\377"; /* 0x7b-0xff */
int found; int found;
buf = findchar_fast(buf, buf_end, ranges1, sizeof(ranges1) - 1, &found); buf = findchar_fast(buf, buf_end, ranges1, sizeof(ranges1) - 1, &found);
if (!found) { if (!found) {
@ -338,9 +330,7 @@ static const char *parse_headers(const char *buf, const char *buf_end, struct ph
return buf; return buf;
} }
static const char *parse_request(const char *buf, const char *buf_end, const char **method, size_t *method_len, const char **path, static const char *parse_request(const char *buf, const char *buf_end, const char **method, size_t *method_len, const char **path, size_t *path_len, int *minor_version, struct phr_header *headers, size_t *num_headers, size_t max_headers, int *ret)
size_t *path_len, int *minor_version, struct phr_header *headers, size_t *num_headers,
size_t max_headers, int *ret)
{ {
/* skip first empty line (some clients add CRLF after POST content) */ /* skip first empty line (some clients add CRLF after POST content) */
CHECK_EOF(); CHECK_EOF();
@ -380,8 +370,7 @@ static const char *parse_request(const char *buf, const char *buf_end, const cha
return parse_headers(buf, buf_end, headers, num_headers, max_headers, ret); return parse_headers(buf, buf_end, headers, num_headers, max_headers, ret);
} }
int phr_parse_request(const char *buf_start, size_t len, const char **method, size_t *method_len, const char **path, int phr_parse_request(const char *buf_start, size_t len, const char **method, size_t *method_len, const char **path, size_t *path_len, int *minor_version, struct phr_header *headers, size_t *num_headers, size_t last_len)
size_t *path_len, int *minor_version, struct phr_header *headers, size_t *num_headers, size_t last_len)
{ {
const char *buf = buf_start, *buf_end = buf_start + len; const char *buf = buf_start, *buf_end = buf_start + len;
size_t max_headers = *num_headers; size_t max_headers = *num_headers;
@ -400,16 +389,14 @@ int phr_parse_request(const char *buf_start, size_t len, const char **method, si
return r; return r;
} }
if ((buf = parse_request(buf, buf_end, method, method_len, path, path_len, minor_version, headers, num_headers, max_headers, if ((buf = parse_request(buf, buf_end, method, method_len, path, path_len, minor_version, headers, num_headers, max_headers, &r)) == NULL) {
&r)) == NULL) {
return r; return r;
} }
return (int)(buf - buf_start); return (int)(buf - buf_start);
} }
static const char *parse_response(const char *buf, const char *buf_end, int *minor_version, int *status, const char **msg, static const char *parse_response(const char *buf, const char *buf_end, int *minor_version, int *status, const char **msg, size_t *msg_len, struct phr_header *headers, size_t *num_headers, size_t max_headers, int *ret)
size_t *msg_len, struct phr_header *headers, size_t *num_headers, size_t max_headers, int *ret)
{ {
/* parse "HTTP/1.x" */ /* parse "HTTP/1.x" */
if ((buf = parse_http_version(buf, buf_end, minor_version, ret)) == NULL) { if ((buf = parse_http_version(buf, buf_end, minor_version, ret)) == NULL) {
@ -451,8 +438,7 @@ static const char *parse_response(const char *buf, const char *buf_end, int *min
return parse_headers(buf, buf_end, headers, num_headers, max_headers, ret); return parse_headers(buf, buf_end, headers, num_headers, max_headers, ret);
} }
int phr_parse_response(const char *buf_start, size_t len, int *minor_version, int *status, const char **msg, size_t *msg_len, int phr_parse_response(const char *buf_start, size_t len, int *minor_version, int *status, const char **msg, size_t *msg_len, struct phr_header *headers, size_t *num_headers, size_t last_len)
struct phr_header *headers, size_t *num_headers, size_t last_len)
{ {
const char *buf = buf_start, *buf_end = buf + len; const char *buf = buf_start, *buf_end = buf + len;
size_t max_headers = *num_headers; size_t max_headers = *num_headers;
@ -523,7 +509,7 @@ static int decode_hex(int ch)
ssize_t phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf, size_t *_bufsz) ssize_t phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf, size_t *_bufsz)
{ {
size_t dst = 0, src = 0, bufsz = *_bufsz; size_t dst = 0, src = 0, bufsz = *_bufsz;
ssize_t ret = -2; /* incomplete */ ssize_t ret = -2; /* incomplete */
while (1) { while (1) {
switch (decoder->_state) { switch (decoder->_state) {
@ -548,7 +534,7 @@ ssize_t phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf, size_
} }
decoder->_hex_count = 0; decoder->_hex_count = 0;
decoder->_state = CHUNKED_IN_CHUNK_EXT; decoder->_state = CHUNKED_IN_CHUNK_EXT;
/* fallthru */ /* fallthru */
case CHUNKED_IN_CHUNK_EXT: case CHUNKED_IN_CHUNK_EXT:
/* RFC 7230 A.2 "Line folding in chunk extensions is disallowed" */ /* RFC 7230 A.2 "Line folding in chunk extensions is disallowed" */
for (;; ++src) { for (;; ++src) {
@ -567,25 +553,25 @@ ssize_t phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf, size_
} }
} }
decoder->_state = CHUNKED_IN_CHUNK_DATA; decoder->_state = CHUNKED_IN_CHUNK_DATA;
/* fallthru */ /* fallthru */
case CHUNKED_IN_CHUNK_DATA: { case CHUNKED_IN_CHUNK_DATA:{
size_t avail = bufsz - src; size_t avail = bufsz - src;
if (avail < decoder->bytes_left_in_chunk) { if (avail < decoder->bytes_left_in_chunk) {
if (dst != src)
memmove(buf + dst, buf + src, avail);
src += avail;
dst += avail;
decoder->bytes_left_in_chunk -= avail;
goto Exit;
}
if (dst != src) if (dst != src)
memmove(buf + dst, buf + src, avail); memmove(buf + dst, buf + src, decoder->bytes_left_in_chunk);
src += avail; src += decoder->bytes_left_in_chunk;
dst += avail; dst += decoder->bytes_left_in_chunk;
decoder->bytes_left_in_chunk -= avail; decoder->bytes_left_in_chunk = 0;
goto Exit; decoder->_state = CHUNKED_IN_CHUNK_CRLF;
} }
if (dst != src) /* fallthru */
memmove(buf + dst, buf + src, decoder->bytes_left_in_chunk);
src += decoder->bytes_left_in_chunk;
dst += decoder->bytes_left_in_chunk;
decoder->bytes_left_in_chunk = 0;
decoder->_state = CHUNKED_IN_CHUNK_CRLF;
}
/* fallthru */
case CHUNKED_IN_CHUNK_CRLF: case CHUNKED_IN_CHUNK_CRLF:
for (;; ++src) { for (;; ++src) {
if (src == bufsz) if (src == bufsz)
@ -610,7 +596,7 @@ ssize_t phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf, size_
if (buf[src++] == '\012') if (buf[src++] == '\012')
goto Complete; goto Complete;
decoder->_state = CHUNKED_IN_TRAILERS_LINE_MIDDLE; decoder->_state = CHUNKED_IN_TRAILERS_LINE_MIDDLE;
/* fallthru */ /* fallthru */
case CHUNKED_IN_TRAILERS_LINE_MIDDLE: case CHUNKED_IN_TRAILERS_LINE_MIDDLE:
for (;; ++src) { for (;; ++src) {
if (src == bufsz) if (src == bufsz)

View File

@ -39,32 +39,30 @@ extern "C" {
/* contains name and value of a header (name == NULL if is a continuing line /* contains name and value of a header (name == NULL if is a continuing line
* of a multiline header */ * of a multiline header */
struct phr_header { struct phr_header {
const char *name; const char *name;
size_t name_len; size_t name_len;
const char *value; const char *value;
size_t value_len; size_t value_len;
}; };
/* returns number of bytes consumed if successful, -2 if request is partial, /* returns number of bytes consumed if successful, -2 if request is partial,
* -1 if failed */ * -1 if failed */
int phr_parse_request(const char *buf, size_t len, const char **method, size_t *method_len, const char **path, size_t *path_len, int phr_parse_request(const char *buf, size_t len, const char **method, size_t *method_len, const char **path, size_t *path_len, int *minor_version, struct phr_header *headers, size_t *num_headers, size_t last_len);
int *minor_version, struct phr_header *headers, size_t *num_headers, size_t last_len);
/* ditto */ /* ditto */
int phr_parse_response(const char *_buf, size_t len, int *minor_version, int *status, const char **msg, size_t *msg_len, int phr_parse_response(const char *_buf, size_t len, int *minor_version, int *status, const char **msg, size_t *msg_len, struct phr_header *headers, size_t *num_headers, size_t last_len);
struct phr_header *headers, size_t *num_headers, size_t last_len);
/* ditto */ /* ditto */
int phr_parse_headers(const char *buf, size_t len, struct phr_header *headers, size_t *num_headers, size_t last_len); int phr_parse_headers(const char *buf, size_t len, struct phr_header *headers, size_t *num_headers, size_t last_len);
/* should be zero-filled before start */ /* should be zero-filled before start */
struct phr_chunked_decoder { struct phr_chunked_decoder {
size_t bytes_left_in_chunk; /* number of bytes left in current chunk */ size_t bytes_left_in_chunk; /* number of bytes left in current chunk */
char consume_trailer; /* if trailing headers should be consumed */ char consume_trailer; /* if trailing headers should be consumed */
char _hex_count; char _hex_count;
char _state; char _state;
}; };
/* the function rewrites the buffer given as (buf, bufsz) removing the chunked- /* the function rewrites the buffer given as (buf, bufsz) removing the chunked-
* encoding headers. When the function returns without an error, bufsz is * encoding headers. When the function returns without an error, bufsz is
@ -75,13 +73,12 @@ struct phr_chunked_decoder {
* octets left undecoded at the tail of the supplied buffer. Returns -1 on * octets left undecoded at the tail of the supplied buffer. Returns -1 on
* error. * error.
*/ */
ssize_t phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf, size_t *bufsz); ssize_t phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf, size_t *bufsz);
/* returns if the chunked decoder is in middle of chunked data */ /* returns if the chunked decoder is in middle of chunked data */
int phr_decode_chunked_is_in_data(struct phr_chunked_decoder *decoder); int phr_decode_chunked_is_in_data(struct phr_chunked_decoder *decoder);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif

68
proxy.c
View File

@ -14,8 +14,8 @@ struct epoll_event ev, events[MAX_CONNECTION + 1];
int epollfd, server_sock; int epollfd, server_sock;
conn cts[MAX_CONNECTION]; conn cts[MAX_CONNECTION];
int create_connection(char *remote_host, int remote_port)
int create_connection(char *remote_host, int remote_port) { {
struct sockaddr_in server_addr; struct sockaddr_in server_addr;
struct hostent *server; struct hostent *server;
int sock; int sock;
@ -23,27 +23,29 @@ int create_connection(char *remote_host, int remote_port) {
perror("socket"); perror("socket");
return -1; return -1;
} }
if ((server = gethostbyname(remote_host)) == NULL) { if ((server = gethostbyname(remote_host)) == NULL) {
perror("gethostbyname"); perror("gethostbyname");
errno = EFAULT; errno = EFAULT;
return -1; return -1;
} }
memset(&server_addr, 0, sizeof(server_addr)); memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET; server_addr.sin_family = AF_INET;
memcpy(&server_addr.sin_addr.s_addr, server->h_addr, server->h_length); memcpy(&server_addr.sin_addr.s_addr, server->h_addr, server->h_length);
server_addr.sin_port = htons(remote_port); server_addr.sin_port = htons(remote_port);
if (connect(sock, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) { if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("connect"); perror("connect");
close(sock);
return -1; return -1;
} }
fcntl(sock, F_SETFL, O_NONBLOCK); fcntl(sock, F_SETFL, O_NONBLOCK);
return sock; return sock;
} }
int create_server_socket(int port) { int create_server_socket(int port)
{
int server_sock; int server_sock;
int optval = 1; int optval = 1;
struct sockaddr_in server_addr; struct sockaddr_in server_addr;
@ -59,7 +61,7 @@ int create_server_socket(int port) {
server_addr.sin_family = AF_INET; server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port); server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) != 0) { if (bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) != 0) {
perror("bind"); perror("bind");
return -1; return -1;
} }
@ -83,17 +85,17 @@ void accept_client()
break; break;
if (client - cts >= MAX_CONNECTION) if (client - cts >= MAX_CONNECTION)
return; return;
client->timer = (client+1)->timer = 0; client->timer = (client + 1)->timer = 0;
client->fd = accept(server_sock, (struct sockaddr *)&addr, &addr_len); client->fd = accept(server_sock, (struct sockaddr *)&addr, &addr_len);
if (client->fd < 0) if (client->fd < 0)
return; return;
fcntl(client->fd, F_SETFL, O_NONBLOCK); fcntl(client->fd, F_SETFL, O_NONBLOCK);
epollEvent.events = EPOLLIN|EPOLLET; epollEvent.events = EPOLLIN | EPOLLET;
epollEvent.data.ptr = client; epollEvent.data.ptr = client;
epoll_ctl(epollfd, EPOLL_CTL_ADD, client->fd, &epollEvent); epoll_ctl(epollfd, EPOLL_CTL_ADD, client->fd, &epollEvent);
} }
void start_server(conf *configure) void start_server(conf * configure)
{ {
int n; int n;
pthread_t thId; pthread_t thId;
@ -106,7 +108,7 @@ void start_server(conf *configure)
if (events[n].data.fd == server_sock) { if (events[n].data.fd == server_sock) {
accept_client(); accept_client();
} else { } else {
if(events[n].events & EPOLLIN) { if (events[n].events & EPOLLIN) {
tcp_in((conn *) events[n].data.ptr, configure); tcp_in((conn *) events[n].data.ptr, configure);
} }
if (events[n].events & EPOLLOUT) { if (events[n].events & EPOLLOUT) {
@ -118,8 +120,7 @@ void start_server(conf *configure)
close(epollfd); close(epollfd);
} }
int int process_signal(int signal, char *process_name)
process_signal(int signal, char *process_name)
{ {
char bufer[PATH_SIZE]; char bufer[PATH_SIZE];
char comm[PATH_SIZE]; char comm[PATH_SIZE];
@ -182,7 +183,6 @@ int get_executable_path(char *processdir, char *processname, int len)
int _main(int argc, char *argv[]) int _main(int argc, char *argv[])
{ {
sslEncodeCode = 0;
int opt, i, process; int opt, i, process;
char path[PATH_SIZE] = { 0 }; char path[PATH_SIZE] = { 0 };
char executable_filename[PATH_SIZE] = { 0 }; char executable_filename[PATH_SIZE] = { 0 };
@ -192,11 +192,14 @@ int _main(int argc, char *argv[])
conf *configure = (struct CONF *)malloc(sizeof(struct CONF)); conf *configure = (struct CONF *)malloc(sizeof(struct CONF));
read_conf(inifile, configure); read_conf(inifile, configure);
timeout_minute = 0; sslEncodeCode = 0; // 默认SSL不转码
if (configure->timer > 0) if (configure->sslencoding > 0) // 如果配置文件有sslencoding值,优先使用配置文件读取的值
sslEncodeCode = configure->sslencoding;
timeout_minute = 0; // 默认不超时
if (configure->timer > 0) // 如果配置文件有值,优先使用配置文件读取的值
timeout_minute = configure->timer; timeout_minute = configure->timer;
process = 2; process = 2; // 默认开启2个进程
if (configure->process > 0) if (configure->process > 0) // 如果配置文件有值,优先使用配置文件读取的值
process = configure->process; process = configure->process;
//char optstring[] = ":l:f:t:p:c:e:s:h?"; //char optstring[] = ":l:f:t:p:c:e:s:h?";
@ -237,7 +240,7 @@ int _main(int argc, char *argv[])
} }
break; break;
case 't': case 't':
timeout_minute = (time_t)atoi(optarg); timeout_minute = (time_t) atoi(optarg); // 如果指定-t,优先使用参数提供的值(输入值 > 配置文件读取的值)
break; break;
case 'p': case 'p':
process = atoi(optarg); process = atoi(optarg);
@ -268,23 +271,18 @@ int _main(int argc, char *argv[])
default: default:
; ;
} }
} }
if (configure->sslencoding > 0)
sslEncodeCode = configure->sslencoding;
server_sock = create_server_socket(configure->local_port); server_sock = create_server_socket(configure->local_port);
signal(SIGPIPE, SIG_IGN); //忽略PIPE信号 signal(SIGPIPE, SIG_IGN); // 忽略PIPE信号
memset(cts, 0, sizeof(cts)); memset(cts, 0, sizeof(cts));
for (i = MAX_CONNECTION; i--; ) for (i = MAX_CONNECTION; i--;)
cts[i].fd = -1; cts[i].fd = -1;
//为服务端的结构体分配内存 // 为服务端的结构体分配内存
for (i = 1; i < MAX_CONNECTION; i += 2) for (i = 1; i < MAX_CONNECTION; i += 2) {
{
cts[i].header_buffer = (char *)malloc(BUFFER_SIZE); cts[i].header_buffer = (char *)malloc(BUFFER_SIZE);
if (cts[i].header_buffer == NULL) if (cts[i].header_buffer == NULL) {
{
fputs("out of memory.", stderr); fputs("out of memory.", stderr);
exit(1); exit(1);
} }
@ -296,8 +294,7 @@ int _main(int argc, char *argv[])
} }
while (process-- > 0 && fork() == 0) while (process-- > 0 && fork() == 0)
epollfd = epoll_create(MAX_CONNECTION);
epollfd = epoll_create(MAX_CONNECTION);
if (epollfd == -1) { if (epollfd == -1) {
perror("epoll_create"); perror("epoll_create");
exit(1); exit(1);
@ -311,7 +308,7 @@ int _main(int argc, char *argv[])
if (setegid(configure->uid) == -1 || seteuid(configure->uid) == -1) // 设置uid if (setegid(configure->uid) == -1 || seteuid(configure->uid) == -1) // 设置uid
exit(1); exit(1);
start_server(configure); start_server(configure);
return 0; return 0;
} }
@ -320,4 +317,3 @@ int main(int argc, char *argv[])
{ {
return _main(argc, argv); return _main(argc, argv);
} }

View File

@ -32,4 +32,3 @@ extern struct epoll_event ev, events[MAX_CONNECTION + 1];
int create_connection(char *remote_host, int remote_port); int create_connection(char *remote_host, int remote_port);
#endif #endif

View File

@ -48,8 +48,7 @@ char *replace(char *replace_memory, int *replace_memory_len, const char *src, co
} }
/* 正则表达式字符串替换str为可用free释放的指针 */ /* 正则表达式字符串替换str为可用free释放的指针 */
static char *regrep(char *str, int *str_len, const char *src, char *dest, static char *regrep(char *str, int *str_len, const char *src, char *dest, int dest_len)
int dest_len)
{ {
if (!str || !src || !dest) if (!str || !src || !dest)
return NULL; return NULL;
@ -75,9 +74,7 @@ static char *regrep(char *str, int *str_len, const char *src, char *dest,
/* 替换目标字符串中的子表达式 */ /* 替换目标字符串中的子表达式 */
for (i = 1; i < 10 && pm[i].rm_so > -1; i++) { for (i = 1; i < 10 && pm[i].rm_so > -1; i++) {
child_num[1] = i + 48; child_num[1] = i + 48;
real_dest = real_dest = replace(real_dest, &real_dest_len, child_num, 2, p + pm[i].rm_so, pm[i].rm_eo - pm[i].rm_so);
replace(real_dest, &real_dest_len, child_num, 2,
p + pm[i].rm_so, pm[i].rm_eo - pm[i].rm_so);
if (real_dest == NULL) { if (real_dest == NULL) {
regfree(&reg); regfree(&reg);
free(str); free(str);
@ -93,8 +90,7 @@ static char *regrep(char *str, int *str_len, const char *src, char *dest,
memcpy(p, real_dest, real_dest_len); memcpy(p, real_dest, real_dest_len);
if (match_len > real_dest_len) if (match_len > real_dest_len)
//strcpy(p + real_dest_len, p + match_len); //strcpy(p + real_dest_len, p + match_len);
memmove(p + real_dest_len, p + match_len, memmove(p + real_dest_len, p + match_len, *str_len - (p + match_len - str));
*str_len - (p + match_len - str));
p += real_dest_len; p += real_dest_len;
*str_len -= match_len - real_dest_len; *str_len -= match_len - real_dest_len;
} else { } else {
@ -149,9 +145,9 @@ char *delete_head(char *head, const char *character, int string)
if (p2 == NULL) { if (p2 == NULL) {
return head; return head;
} }
char tmp[head_len]; char tmp[head_len];
strncpy_(tmp, head, head_len-strlen(p1)-1); strncpy_(tmp, head, head_len - strlen(p1) - 1);
strcat(tmp, p2); strcat(tmp, p2);
return strcpy(head, tmp); return strcpy(head, tmp);
} }
@ -212,7 +208,7 @@ int extract_host(char *header, char *host, char *port)
char *get_path(char *url, char *path) char *get_path(char *url, char *path)
{ {
if (url) { if (url) {
char *p0 = strstr(url+7, "/"); char *p0 = strstr(url + 7, "/");
if (p0) if (p0)
return strncpy_(path, p0, strlen(p0)); return strncpy_(path, p0, strlen(p0));
else else
@ -221,37 +217,36 @@ char *get_path(char *url, char *path)
return NULL; return NULL;
} }
char *request_head(conn *in, conf *configure) char *request_head(conn * in, conf * configure)
{ {
const char *method, *path; const char *method, *path;
size_t method_len, path_len, num_headers; size_t method_len, path_len, num_headers;
int minor_version; int minor_version;
struct phr_header headers[32]; struct phr_header headers[32];
num_headers = sizeof(headers) / sizeof(headers[0]); num_headers = sizeof(headers) / sizeof(headers[0]);
phr_parse_request(in->header_buffer, strlen(in->header_buffer) - 1, &method, &method_len, &path, &path_len, &minor_version, headers, &num_headers, 0); phr_parse_request(in->header_buffer, strlen(in->header_buffer) - 1, &method, &method_len, &path, &path_len, &minor_version, headers, &num_headers, 0);
char M[method_len+2]; char M[method_len + 2];
strncpy_(M, method, method_len); strncpy_(M, method, method_len);
int M_len = strlen(M); int M_len = strlen(M);
//printf("%s\n", M); //printf("%s\n", M);
char U[path_len+1]; char U[path_len + 1];
strncpy_(U, path, path_len); strncpy_(U, path, path_len);
int U_len = strlen(U); int U_len = strlen(U);
//printf("%s\n", U); //printf("%s\n", U);
char V[9]; char V[9];
sprintf(V, "HTTP/1.%.d", minor_version); sprintf(V, "HTTP/1.%.d", minor_version);
int V_len = strlen(V); int V_len = strlen(V);
//printf("%s\n", V); //printf("%s\n", V);
char host[path_len]; char host[path_len];
char port[path_len]; char port[path_len];
char H[path_len*2]; char H[path_len * 2];
extract_host(in->header_buffer, host, port); extract_host(in->header_buffer, host, port);
//printfconf(configure); //printfconf(configure);
if (strncmp(M, "CONNECT", 7) == 0) { if (strncmp(M, "CONNECT", 7) == 0) {
@ -259,7 +254,7 @@ char *request_head(conn *in, conf *configure)
char *result = NULL; char *result = NULL;
char *incomplete_head; char *incomplete_head;
int incomplete_head_len; int incomplete_head_len;
if (configure->https_port > 0) if (configure->https_port > 0)
remote_port = configure->https_port; remote_port = configure->https_port;
if (configure->https_ip != NULL) if (configure->https_ip != NULL)
@ -301,13 +296,12 @@ char *request_head(conn *in, conf *configure)
if (configure->https_regrep) { 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 = regrep(incomplete_head, &incomplete_head_len, configure->https_regrep_aim, configure->https_regrep_obj, configure->https_regrep_obj_len);
} }
//printf("%s", incomplete_head); //printf("%s", incomplete_head);
memset(in->header_buffer, 0, strlen(in->header_buffer)); memset(in->header_buffer, 0, strlen(in->header_buffer));
strcpy(in->header_buffer, incomplete_head); strcpy(in->header_buffer, incomplete_head);
in->header_buffer_len = strlen(in->header_buffer); in->header_buffer_len = strlen(in->header_buffer);
free(incomplete_head); free(incomplete_head);
} else { } else {
char *incomplete_head; char *incomplete_head;
@ -316,8 +310,7 @@ char *request_head(conn *in, conf *configure)
int incomplete_head_len; int incomplete_head_len;
char url[U_len], uri[U_len]; char url[U_len], uri[U_len];
int uri_len; int uri_len;
strcpy(url, U); strcpy(url, U);
get_path(url, uri); get_path(url, uri);
uri_len = strlen(uri); uri_len = strlen(uri);
@ -364,7 +357,6 @@ char *request_head(conn *in, conf *configure)
if (configure->http_regrep) { 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 = regrep(incomplete_head, &incomplete_head_len, configure->http_regrep_aim, configure->http_regrep_obj, configure->http_regrep_obj_len);
} }
//printf("%s", incomplete_head); //printf("%s", incomplete_head);
memset(in->header_buffer, 0, strlen(in->header_buffer)); memset(in->header_buffer, 0, strlen(in->header_buffer));
strcpy(in->header_buffer, incomplete_head); strcpy(in->header_buffer, incomplete_head);
@ -374,4 +366,3 @@ char *request_head(conn *in, conf *configure)
return in->header_buffer; return in->header_buffer;
} }

View File

@ -11,7 +11,6 @@
void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen); void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen);
char *replace(char *replace_memory, int *replace_memory_len, const char *src, const int src_len, const char *dest, const int dest_len); char *replace(char *replace_memory, int *replace_memory_len, const char *src, const int src_len, const char *dest, const int dest_len);
char *request_head(conn *in, conf *configure); char *request_head(conn * in, conf * configure);
#endif #endif

View File

@ -7,16 +7,14 @@ void *close_timeout_connectionLoop(void *nullPtr)
{ {
int i; int i;
while (1) while (1) {
{
sleep(60); 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].fd > -1) {
{
if (cts[i].timer >= timeout_minute) if (cts[i].timer >= timeout_minute)
close_connection(cts + i); close_connection(cts + i);
else else
cts[i].timer++; cts[i].timer++;
} }
} }
} }

View File

@ -5,4 +5,4 @@ extern int timeout_minute;
void *close_timeout_connectionLoop(void *nullPtr); void *close_timeout_connectionLoop(void *nullPtr);
#endif #endif