2020-07-30 18:10:31 +08:00
|
|
|
|
#include "http_proxy.h"
|
|
|
|
|
#include "main.h"
|
2020-01-21 19:48:05 +08:00
|
|
|
|
|
2020-03-24 11:46:32 +08:00
|
|
|
|
int sslEncodeCode;
|
2020-09-09 21:55:48 +08:00
|
|
|
|
int remote_port;
|
2021-05-18 14:18:56 +08:00
|
|
|
|
char remote_host[CACHE_SIZE];
|
2021-12-23 09:02:41 +08:00
|
|
|
|
int timeout_minute;
|
2020-03-24 11:46:32 +08:00
|
|
|
|
|
|
|
|
|
/* 对数据进行编码 */
|
2021-07-20 22:17:06 +08:00
|
|
|
|
void dataEncode(char *data, int data_len, unsigned code)
|
2020-03-24 11:46:32 +08:00
|
|
|
|
{
|
2021-07-20 22:17:06 +08:00
|
|
|
|
while (data_len-- > 0)
|
|
|
|
|
data[data_len] ^= code;
|
2020-03-24 11:46:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-12-23 09:02:41 +08:00
|
|
|
|
void *tcp_timeout_check(void *nullPtr)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
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++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-26 17:40:17 +08:00
|
|
|
|
static char *read_data(conn_t * in, char *data, int *data_len)
|
2020-01-21 19:48:05 +08:00
|
|
|
|
{
|
|
|
|
|
char *new_data;
|
|
|
|
|
int read_len;
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
new_data = (char *)realloc(data, *data_len + BUFFER_SIZE + 1);
|
|
|
|
|
if (new_data == NULL) {
|
|
|
|
|
free(data);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
data = new_data;
|
|
|
|
|
read_len = read(in->fd, data + *data_len, BUFFER_SIZE);
|
|
|
|
|
// 判断是否关闭连接
|
|
|
|
|
if (read_len <= 0) {
|
|
|
|
|
if (read_len == 0 || *data_len == 0 || errno != EAGAIN) {
|
|
|
|
|
free(data);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
*data_len += read_len;
|
|
|
|
|
} while (read_len == BUFFER_SIZE);
|
|
|
|
|
*(data + *data_len) = '\0';
|
|
|
|
|
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-15 10:43:06 +08:00
|
|
|
|
void close_connection(conn_t * conn)
|
2020-01-21 19:48:05 +08:00
|
|
|
|
{
|
|
|
|
|
epoll_ctl(epollfd, EPOLL_CTL_DEL, conn->fd, NULL);
|
|
|
|
|
close(conn->fd);
|
2020-12-15 10:43:06 +08:00
|
|
|
|
if ((conn - cts) & 1) {
|
2020-01-21 19:48:05 +08:00
|
|
|
|
char *server_data;
|
|
|
|
|
|
2020-11-26 17:40:17 +08:00
|
|
|
|
server_data = conn->ready_data;
|
|
|
|
|
memset(conn, 0, sizeof(conn_t));
|
|
|
|
|
conn->ready_data = server_data;
|
2020-12-15 10:43:06 +08:00
|
|
|
|
conn--->fd = -1;
|
|
|
|
|
} else {
|
2020-11-26 17:40:17 +08:00
|
|
|
|
free(conn->ready_data);
|
|
|
|
|
free(conn->incomplete_data);
|
|
|
|
|
memset(conn, 0, sizeof(conn_t));
|
2020-12-15 10:43:06 +08:00
|
|
|
|
conn++->fd = -1;
|
2020-11-26 17:40:17 +08:00
|
|
|
|
}
|
2020-01-21 19:48:05 +08:00
|
|
|
|
if (conn->fd >= 0)
|
|
|
|
|
close_connection(conn);
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-15 10:43:06 +08:00
|
|
|
|
static void serverToClient(conn_t * server)
|
2020-01-21 19:48:05 +08:00
|
|
|
|
{
|
2020-11-26 17:40:17 +08:00
|
|
|
|
conn_t *client;
|
2020-01-21 19:48:05 +08:00
|
|
|
|
int write_len;
|
|
|
|
|
|
2020-11-26 17:40:17 +08:00
|
|
|
|
client = server - 1;
|
2020-12-15 10:43:06 +08:00
|
|
|
|
while ((server->ready_data_len = read(server->fd, server->ready_data, BUFFER_SIZE)) > 0) {
|
2021-07-20 22:17:06 +08:00
|
|
|
|
dataEncode(server->ready_data, server->ready_data_len, sslEncodeCode);
|
2020-11-26 17:40:17 +08:00
|
|
|
|
write_len = write(client->fd, server->ready_data, server->ready_data_len);
|
2020-12-15 10:43:06 +08:00
|
|
|
|
if (write_len <= 0) {
|
2020-01-21 19:48:05 +08:00
|
|
|
|
if (write_len == 0 || errno != EAGAIN)
|
|
|
|
|
close_connection(server);
|
|
|
|
|
else
|
|
|
|
|
server->sent_len = 0;
|
|
|
|
|
return;
|
2020-12-15 10:43:06 +08:00
|
|
|
|
} else if (write_len < server->ready_data_len) {
|
2020-01-21 19:48:05 +08:00
|
|
|
|
server->sent_len = write_len;
|
2020-12-15 10:43:06 +08:00
|
|
|
|
ev.events = EPOLLIN | EPOLLOUT | EPOLLET;
|
2020-01-21 19:48:05 +08:00
|
|
|
|
ev.data.ptr = client;
|
|
|
|
|
epoll_ctl(epollfd, EPOLL_CTL_MOD, client->fd, &ev);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-11-26 17:40:17 +08:00
|
|
|
|
if (server->ready_data_len < BUFFER_SIZE)
|
2020-01-21 19:48:05 +08:00
|
|
|
|
break;
|
|
|
|
|
}
|
2020-11-26 17:40:17 +08:00
|
|
|
|
//判断是否关闭连接
|
|
|
|
|
if (server->ready_data_len == 0 || (server->ready_data_len == -1 && errno != EAGAIN))
|
2020-01-21 19:48:05 +08:00
|
|
|
|
close_connection(server);
|
|
|
|
|
else
|
2020-11-26 17:40:17 +08:00
|
|
|
|
server->ready_data_len = server->sent_len = 0;
|
2020-01-21 19:48:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-11-26 17:40:17 +08:00
|
|
|
|
void clientToserver(conn_t * in)
|
2020-08-26 20:40:35 +08:00
|
|
|
|
{
|
|
|
|
|
int write_len;
|
2020-11-26 17:40:17 +08:00
|
|
|
|
conn_t *remote;
|
2020-08-26 20:40:35 +08:00
|
|
|
|
remote = in + 1;
|
|
|
|
|
|
2020-11-26 17:40:17 +08:00
|
|
|
|
write_len = write(remote->fd, in->ready_data, in->ready_data_len);
|
|
|
|
|
if (write_len == in->ready_data_len) {
|
|
|
|
|
in->ready_data_len = 0;
|
|
|
|
|
in->ready_data = NULL;
|
2020-08-26 20:40:35 +08:00
|
|
|
|
} else {
|
|
|
|
|
close_connection(remote);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-21 19:48:05 +08:00
|
|
|
|
// 判断请求类型
|
|
|
|
|
static int8_t request_type(char *data)
|
|
|
|
|
{
|
2021-07-20 22:17:06 +08:00
|
|
|
|
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 ||
|
2021-12-09 19:31:51 +08:00
|
|
|
|
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)
|
2020-01-21 19:48:05 +08:00
|
|
|
|
return HTTP_TYPE;
|
|
|
|
|
return OTHER_TYPE;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-26 17:40:17 +08:00
|
|
|
|
// Check for valid IPv4 or Iv6 string. Returns AF_INET for IPv4, AF_INET6 for IPv6
|
2020-12-15 10:43:06 +08:00
|
|
|
|
int check_ipversion(char *address)
|
2020-01-21 19:48:05 +08:00
|
|
|
|
{
|
2020-11-26 17:40:17 +08:00
|
|
|
|
struct in6_addr bindaddr;
|
|
|
|
|
|
|
|
|
|
if (inet_pton(AF_INET, address, &bindaddr) == 1) {
|
2020-12-15 10:43:06 +08:00
|
|
|
|
return AF_INET;
|
2020-11-26 17:40:17 +08:00
|
|
|
|
} else {
|
|
|
|
|
if (inet_pton(AF_INET6, address, &bindaddr) == 1) {
|
|
|
|
|
return AF_INET6;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-12-09 19:31:51 +08:00
|
|
|
|
|
2020-11-26 17:40:17 +08:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-15 10:43:06 +08:00
|
|
|
|
int create_connection6(char *remote_host, int remote_port)
|
|
|
|
|
{
|
2021-12-09 19:31:51 +08:00
|
|
|
|
struct addrinfo hints;
|
2022-01-19 21:48:02 +08:00
|
|
|
|
struct addrinfo *res = NULL;
|
2020-11-26 17:40:17 +08:00
|
|
|
|
int sock;
|
2020-12-15 10:43:06 +08:00
|
|
|
|
int validfamily = 0;
|
2021-05-18 14:18:56 +08:00
|
|
|
|
char portstr[CACHE_SIZE];
|
2020-11-26 17:40:17 +08:00
|
|
|
|
|
|
|
|
|
memset(&hints, 0x00, sizeof(hints));
|
|
|
|
|
|
2020-12-15 10:43:06 +08:00
|
|
|
|
hints.ai_flags = AI_NUMERICSERV; // numeric service number, not resolve
|
|
|
|
|
hints.ai_family = AF_UNSPEC;
|
2020-11-26 17:40:17 +08:00
|
|
|
|
hints.ai_socktype = SOCK_STREAM;
|
|
|
|
|
|
|
|
|
|
sprintf(portstr, "%d", remote_port);
|
|
|
|
|
|
|
|
|
|
// check for numeric IP to specify IPv6 or IPv4 socket
|
|
|
|
|
if ((validfamily = check_ipversion(remote_host)) != 0) {
|
2020-12-15 10:43:06 +08:00
|
|
|
|
hints.ai_family = validfamily;
|
|
|
|
|
hints.ai_flags |= AI_NUMERICHOST; // remote_host是有效的数字ip,跳过解析
|
2020-11-26 17:40:17 +08:00
|
|
|
|
}
|
2021-12-09 19:31:51 +08:00
|
|
|
|
|
2022-01-19 21:48:02 +08:00
|
|
|
|
|
2021-12-09 19:31:51 +08:00
|
|
|
|
//getaddrinfo方法
|
2020-11-26 17:40:17 +08:00
|
|
|
|
// 检查指定的主机是否有效。 如果remote_host是主机名,尝试解析地址
|
2020-12-15 10:43:06 +08:00
|
|
|
|
if (getaddrinfo(remote_host, portstr, &hints, &res) != 0) {
|
2020-11-26 17:40:17 +08:00
|
|
|
|
errno = EFAULT;
|
|
|
|
|
perror("getaddrinfo");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2021-12-09 19:31:51 +08:00
|
|
|
|
|
2020-11-26 17:40:17 +08:00
|
|
|
|
if ((sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) {
|
|
|
|
|
perror("socket");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2020-12-15 10:43:06 +08:00
|
|
|
|
|
2020-11-26 17:40:17 +08:00
|
|
|
|
if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) {
|
|
|
|
|
perror("connect");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-09 19:31:51 +08:00
|
|
|
|
|
2020-11-26 17:40:17 +08:00
|
|
|
|
if (res != NULL)
|
2020-12-15 10:43:06 +08:00
|
|
|
|
freeaddrinfo(res);
|
2021-12-09 19:31:51 +08:00
|
|
|
|
|
2022-01-19 21:48:02 +08:00
|
|
|
|
|
|
|
|
|
/*
|
2021-12-09 19:31:51 +08:00
|
|
|
|
//通用sockaddr_storage结构体
|
|
|
|
|
struct sockaddr_storage remote_addr;
|
|
|
|
|
memset(&remote_addr, 0, sizeof(struct sockaddr_storage));
|
|
|
|
|
if (validfamily == AF_INET) {
|
|
|
|
|
struct sockaddr_in *addr_v4 = (struct sockaddr_in *)&remote_addr;
|
|
|
|
|
addr_v4->sin_family = AF_INET;
|
|
|
|
|
addr_v4->sin_port = htons(remote_port);
|
|
|
|
|
inet_aton(remote_host, &(addr_v4->sin_addr));
|
|
|
|
|
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
|
|
|
|
perror("socket");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
struct sockaddr_in6 *addr_v6 = (struct sockaddr_in6 *)&remote_addr;
|
|
|
|
|
addr_v6->sin6_family = AF_INET6;
|
|
|
|
|
addr_v6->sin6_port = htons(remote_port);
|
|
|
|
|
inet_pton(AF_INET6, remote_host, &(addr_v6->sin6_addr));
|
|
|
|
|
if ((sock = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {
|
|
|
|
|
perror("socket");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-11-26 17:40:17 +08:00
|
|
|
|
|
2021-12-09 19:31:51 +08:00
|
|
|
|
if (connect(sock, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr_storage)) < 0) {
|
|
|
|
|
perror("connect");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2022-01-19 21:48:02 +08:00
|
|
|
|
*/
|
2021-12-09 19:31:51 +08:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
//普通方法
|
|
|
|
|
if (validfamily == AF_INET) {
|
|
|
|
|
struct sockaddr_in remote_addr;
|
|
|
|
|
memset(&remote_addr, 0, sizeof(remote_addr));
|
|
|
|
|
remote_addr.sin_family = AF_INET;
|
|
|
|
|
remote_addr.sin_port = htons(remote_port);
|
|
|
|
|
remote_addr.sin_addr.s_addr = inet_addr(remote_host);
|
|
|
|
|
|
|
|
|
|
if ((sock = socket(validfamily, SOCK_STREAM, 0)) < 0) {
|
|
|
|
|
perror("socket");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (connect(sock, (struct sockaddr *)&remote_addr, sizeof(remote_addr)) < 0) {
|
|
|
|
|
perror("connect");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return sock;
|
|
|
|
|
} else {
|
|
|
|
|
struct sockaddr_in6 remote_addr;
|
|
|
|
|
memset(&remote_addr, 0, sizeof(remote_addr));
|
|
|
|
|
remote_addr.sin6_family = AF_INET6;
|
|
|
|
|
remote_addr.sin6_port = htons(remote_port);
|
|
|
|
|
inet_pton(AF_INET6, remote_host, &(remote_addr.sin6_addr));
|
|
|
|
|
|
|
|
|
|
if ((sock = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {
|
|
|
|
|
perror("socket");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (connect(sock, (struct sockaddr *)&remote_addr, sizeof(remote_addr)) < 0) {
|
|
|
|
|
perror("connect");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return sock;
|
|
|
|
|
}
|
|
|
|
|
*/
|
2020-11-26 17:40:17 +08:00
|
|
|
|
return sock;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 读取到的数据全部就绪,将incomplete_data复制到ready_data */
|
2020-12-15 10:43:06 +08:00
|
|
|
|
static int8_t copy_data(conn_t * ct)
|
2020-11-26 17:40:17 +08:00
|
|
|
|
{
|
2021-07-20 22:17:06 +08:00
|
|
|
|
dataEncode(ct->incomplete_data, ct->incomplete_data_len, sslEncodeCode);
|
2020-12-15 10:43:06 +08:00
|
|
|
|
if (ct->ready_data) {
|
2020-11-26 17:40:17 +08:00
|
|
|
|
char *new_data;
|
|
|
|
|
|
|
|
|
|
new_data = (char *)realloc(ct->ready_data, ct->ready_data_len + ct->incomplete_data_len);
|
|
|
|
|
if (new_data == NULL)
|
|
|
|
|
return 1;
|
|
|
|
|
ct->ready_data = new_data;
|
|
|
|
|
memcpy(new_data + ct->ready_data_len, ct->incomplete_data, ct->incomplete_data_len);
|
|
|
|
|
ct->ready_data_len += ct->incomplete_data_len;
|
|
|
|
|
free(ct->incomplete_data);
|
2020-12-15 10:43:06 +08:00
|
|
|
|
} else {
|
2020-11-26 17:40:17 +08:00
|
|
|
|
ct->ready_data = ct->incomplete_data;
|
|
|
|
|
ct->ready_data_len = ct->incomplete_data_len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ct->incomplete_data = NULL;
|
|
|
|
|
ct->incomplete_data_len = 0;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void tcp_in(conn_t * in, conf * configure)
|
|
|
|
|
{
|
2022-01-19 21:48:02 +08:00
|
|
|
|
char *headerEnd;
|
2020-11-26 17:40:17 +08:00
|
|
|
|
conn_t *server;
|
|
|
|
|
|
2020-01-21 19:48:05 +08:00
|
|
|
|
if (in->fd < 0)
|
|
|
|
|
return;
|
2020-11-26 17:40:17 +08:00
|
|
|
|
//如果in - cts是奇数,那么是服务端触发事件
|
2020-12-15 10:43:06 +08:00
|
|
|
|
if ((in - cts) & 1) {
|
|
|
|
|
in->timer = (in - 1)->timer = 0;
|
2020-11-26 17:40:17 +08:00
|
|
|
|
if (in->ready_data_len <= 0)
|
|
|
|
|
serverToClient(in);
|
2020-01-21 19:48:05 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
2020-11-26 17:40:17 +08:00
|
|
|
|
|
2020-12-15 10:43:06 +08:00
|
|
|
|
in->timer = (in + 1)->timer = 0;
|
2020-11-26 17:40:17 +08:00
|
|
|
|
in->incomplete_data = read_data(in, in->incomplete_data, &in->incomplete_data_len);
|
2020-12-15 10:43:06 +08:00
|
|
|
|
if (in->incomplete_data == NULL) {
|
2020-08-16 07:58:53 +08:00
|
|
|
|
close_connection(in);
|
|
|
|
|
return;
|
2020-08-26 20:40:35 +08:00
|
|
|
|
}
|
2020-11-26 17:40:17 +08:00
|
|
|
|
server = in + 1;
|
|
|
|
|
server->request_type = in->request_type = request_type(in->incomplete_data);
|
2022-01-19 21:48:02 +08:00
|
|
|
|
if (in->request_type == OTHER_TYPE)
|
|
|
|
|
{
|
|
|
|
|
//如果是第一次读取数据,并且不是HTTP请求的,关闭连接。复制数据失败的也关闭连接
|
|
|
|
|
if (in->reread_data == 0 || copy_data(in) != 0)
|
|
|
|
|
{
|
|
|
|
|
close_connection(in);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
goto handle_data_complete;
|
|
|
|
|
}
|
|
|
|
|
headerEnd = strstr(in->incomplete_data, "\n\r");
|
|
|
|
|
//请求头不完整,等待下次读取
|
|
|
|
|
if (headerEnd == NULL)
|
|
|
|
|
return;
|
|
|
|
|
if (in->request_type == HTTP_TYPE) {
|
2020-11-26 17:40:17 +08:00
|
|
|
|
in->incomplete_data = request_head(in, configure);
|
|
|
|
|
server->fd = create_connection6(remote_host, remote_port);
|
2022-01-12 09:41:32 +08:00
|
|
|
|
|
2020-11-26 17:40:17 +08:00
|
|
|
|
if (server->fd < 0)
|
|
|
|
|
printf("remote->fd ERROR!\n");
|
|
|
|
|
fcntl(server->fd, F_SETFL, O_NONBLOCK);
|
|
|
|
|
ev.events = EPOLLIN | EPOLLOUT | EPOLLET;
|
|
|
|
|
ev.data.ptr = server;
|
|
|
|
|
epoll_ctl(epollfd, EPOLL_CTL_ADD, server->fd, &ev);
|
2022-01-19 21:48:02 +08:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
if (in->reread_data == 0)
|
|
|
|
|
{
|
|
|
|
|
in->reread_data = 1;
|
2020-08-26 20:40:35 +08:00
|
|
|
|
}
|
2020-12-15 10:43:06 +08:00
|
|
|
|
if (in->incomplete_data == NULL || copy_data(in) != 0) {
|
2020-11-26 17:40:17 +08:00
|
|
|
|
close_connection(in);
|
|
|
|
|
return;
|
2020-08-26 20:40:35 +08:00
|
|
|
|
}
|
2022-01-19 21:48:02 +08:00
|
|
|
|
// 数据处理完毕,可以发送
|
|
|
|
|
handle_data_complete:
|
2020-11-26 17:40:17 +08:00
|
|
|
|
// 这个判断是防止 多次读取客户端数据,但是没有和服务端建立连接,导致报错
|
|
|
|
|
if (server->fd >= 0)
|
|
|
|
|
tcp_out(server);
|
2020-01-21 19:48:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-12-15 10:43:06 +08:00
|
|
|
|
void tcp_out(conn_t * to)
|
2020-01-21 19:48:05 +08:00
|
|
|
|
{
|
2020-11-26 17:40:17 +08:00
|
|
|
|
conn_t *from;
|
2020-01-21 19:48:05 +08:00
|
|
|
|
int write_len;
|
|
|
|
|
|
2020-11-26 17:40:17 +08:00
|
|
|
|
if (to->fd == -1)
|
2020-01-21 19:48:05 +08:00
|
|
|
|
return;
|
2020-11-26 17:40:17 +08:00
|
|
|
|
else if ((to - cts) & 1)
|
|
|
|
|
from = to - 1;
|
2020-01-21 19:48:05 +08:00
|
|
|
|
else
|
2020-11-26 17:40:17 +08:00
|
|
|
|
from = to + 1;
|
|
|
|
|
from->timer = to->timer = 0;
|
2022-01-19 21:48:02 +08:00
|
|
|
|
|
2020-11-26 17:40:17 +08:00
|
|
|
|
write_len = write(to->fd, from->ready_data + from->sent_len, from->ready_data_len - from->sent_len);
|
2020-12-15 10:43:06 +08:00
|
|
|
|
if (write_len == from->ready_data_len - from->sent_len) {
|
2020-11-26 17:40:17 +08:00
|
|
|
|
//服务端的数据可能没全部写入到客户端
|
2020-12-15 10:43:06 +08:00
|
|
|
|
if ((from - cts) & 1) {
|
2020-01-21 19:48:05 +08:00
|
|
|
|
serverToClient(from);
|
2020-12-15 10:43:06 +08:00
|
|
|
|
if (from->fd >= 0 && from->ready_data_len == 0) {
|
|
|
|
|
ev.events = EPOLLIN | EPOLLET;
|
2020-11-26 17:40:17 +08:00
|
|
|
|
ev.data.ptr = to;
|
|
|
|
|
epoll_ctl(epollfd, EPOLL_CTL_MOD, to->fd, &ev);
|
2020-01-21 19:48:05 +08:00
|
|
|
|
}
|
2020-12-15 10:43:06 +08:00
|
|
|
|
} else {
|
|
|
|
|
ev.events = EPOLLIN | EPOLLET;
|
2020-11-26 17:40:17 +08:00
|
|
|
|
ev.data.ptr = to;
|
|
|
|
|
epoll_ctl(epollfd, EPOLL_CTL_MOD, to->fd, &ev);
|
|
|
|
|
free(from->ready_data);
|
|
|
|
|
from->ready_data = NULL;
|
|
|
|
|
from->ready_data_len = 0;
|
|
|
|
|
}
|
2020-12-15 10:43:06 +08:00
|
|
|
|
} else if (write_len > 0) {
|
2020-01-21 19:48:05 +08:00
|
|
|
|
from->sent_len += write_len;
|
2020-12-15 10:43:06 +08:00
|
|
|
|
ev.events = EPOLLIN | EPOLLOUT | EPOLLET;
|
2020-11-26 17:40:17 +08:00
|
|
|
|
ev.data.ptr = to;
|
|
|
|
|
epoll_ctl(epollfd, EPOLL_CTL_MOD, to->fd, &ev);
|
2020-12-15 10:43:06 +08:00
|
|
|
|
} else if (errno != EAGAIN) {
|
2020-11-26 17:40:17 +08:00
|
|
|
|
close_connection(to);
|
2020-01-21 19:48:05 +08:00
|
|
|
|
}
|
|
|
|
|
}
|