WebSocket async working

This commit is contained in:
2023-01-03 16:12:45 +01:00
parent c1706edcea
commit 896486b64a
8 changed files with 108 additions and 92 deletions

View File

@ -38,7 +38,8 @@ typedef struct {
typedef struct {
client_ctx_t *client;
sock *s1, *s2, *s, *r;
sock *socket;
void *other;
} ws_ctx_t;
void tcp_acceptor_func(client_ctx_t *ctx);
@ -61,4 +62,8 @@ void tcp_close(client_ctx_t *ctx);
void proxy_close(proxy_ctx_t *ctx);
int ws_handle_connection(client_ctx_t *ctx);
void ws_close(ws_ctx_t *ctx);
#endif //SESIMOS_FUNC_H

View File

@ -27,23 +27,16 @@ void proxy_handler_func(client_ctx_t *ctx) {
if (ctx->use_proxy == 0) {
proxy_close(ctx->proxy);
request_complete(ctx);
handle_request(ctx);
} else if (ctx->use_proxy == 1) {
proxy_handler_2(ctx);
request_complete(ctx);
} else if (ctx->use_proxy == 2) {
// WebSocket
sock_set_timeout(&ctx->socket, WS_TIMEOUT);
sock_set_timeout(&ctx->proxy->proxy, WS_TIMEOUT);
info("Upgrading connection to WebSocket connection");
if (ws_handle_connection(&ctx->socket, &ctx->proxy->proxy) != 0) {
ctx->c_keep_alive = 0;
proxy_close(ctx->proxy);
}
info("WebSocket connection closed");
ws_handle_connection(ctx);
return;
}
request_complete(ctx);
handle_request(ctx);
}
static int proxy_handler_1(client_ctx_t *ctx) {

View File

@ -6,15 +6,89 @@
* @date 2022-12-30
*/
#include "../defs.h"
#include "func.h"
#include "../logger.h"
#include "../lib/websocket.h"
#include "../workers.h"
#include <errno.h>
static int ws_frame_handler(ws_ctx_t *ctx);
void ws_frame_handler_func(ws_ctx_t *ctx) {
logger_set_prefix("[%*s]%s", INET6_ADDRSTRLEN, ctx->client->socket.s_addr, ctx->client->log_prefix);
if (ws_frame_handler(ctx) == 0) {
if (ctx->client->ws_close == 3) {
ws_close(ctx);
} else {
ws_handle_frame(ctx);
}
} else {
ws_close(ctx);
}
}
int ws_handle_connection(client_ctx_t *ctx) {
info("Upgrading to WebSocket connection");
sock_set_timeout(&ctx->socket, WS_TIMEOUT);
sock_set_timeout(&ctx->proxy->proxy, WS_TIMEOUT);
ws_ctx_t *a = malloc(sizeof(ws_ctx_t));
ws_ctx_t *b = malloc(sizeof(ws_ctx_t));
a->other = b, b->other = a;
a->client = ctx, b->client = ctx;
a->socket = &ctx->socket, b->socket = &ctx->proxy->proxy;
ws_handle_frame(a);
ws_handle_frame(b);
return 0;
}
static int ws_frame_handler(ws_ctx_t *ctx) {
// TODO WebSocket Frame Handler
ws_frame frame;
char buf[CHUNK_SIZE];
sock *socket = ctx->socket;
sock *other = (ctx->socket == &ctx->client->socket) ? &ctx->client->proxy->proxy : &ctx->client->socket;
if (ws_recv_frame_header(socket, &frame) != 0)
return -1;
debug("WebSocket: Peer %s, Opcode=0x%X, Len=%li", (ctx->socket == &ctx->client->socket) ? "1" : "2", frame.opcode, frame.len);
if (frame.opcode == 0x8) {
ctx->client->ws_close |= (ctx->socket == &ctx->client->socket) ? 1 : 2;
}
if (ws_send_frame_header(other, &frame) != 0)
return -1;
if (frame.len > 0) {
long ret = sock_splice(other, socket, buf, sizeof(buf), frame.len);
if (ret < 0) {
error("Unable to forward data in WebSocket");
return -1;
} else if (ret != frame.len) {
error("Unable to forward correct number of bytes in WebSocket");
return -1;
}
}
return 0;
}
void ws_close(ws_ctx_t *ctx) {
ws_ctx_t *other = ctx->other;
if (other) {
other->other = NULL;
logger_set_prefix("[%*s]%s", INET6_ADDRSTRLEN, ctx->client->socket.s_addr, ctx->client->log_prefix);
info("Closing WebSocket connection");
proxy_close(ctx->client->proxy);
tcp_close(ctx->client);
}
free(ctx);
errno = 0;
}