Skip to content

Commit

Permalink
Websocket simple proxy protocol implementation
Browse files Browse the repository at this point in the history
Signed-off-by: Aleksey Mikhaylov <[email protected]>
  • Loading branch information
ttaym committed Apr 8, 2022
1 parent fae14bf commit 8dd6b95
Show file tree
Hide file tree
Showing 29 changed files with 550 additions and 171 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ Module.symvers
# vscode project settings
.vscode

# nodejs and npm
node_modules
package.json
package-lock.json

# Python compiler cache files
*.pyc

Expand Down
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,14 @@ DBG_CFG ?= 0
DBG_HTTP_PARSER ?= 0
DBG_SS ?= 0
DBG_TLS ?= 0
DBG_WS ?= 0
DBG_APM ?= 0
DBG_HTTP_FRAME ?= 0
DBG_HTTP_STREAM ?= 0
DBG_HPACK ?= 0
TFW_CFLAGS += -DDBG_CFG=$(DBG_CFG) -DDBG_HTTP_PARSER=$(DBG_HTTP_PARSER)
TFW_CFLAGS += -DDBG_SS=$(DBG_SS) -DDBG_TLS=$(DBG_TLS) -DDBG_APM=$(DBG_APM)
TFW_CFLAGS += -DDBG_HTTP_FRAME=$(DBG_HTTP_FRAME)
TFW_CFLAGS += -DDBG_SS=$(DBG_SS) -DDBG_TLS=$(DBG_TLS) -DDBG_WS=$(DBG_WS)
TFW_CFLAGS += -DDBG_APM=$(DBG_APM) -DDBG_HTTP_FRAME=$(DBG_HTTP_FRAME)
TFW_CFLAGS += -DDBG_HTTP_STREAM=$(DBG_HTTP_STREAM)
TFW_CFLAGS += -DDBG_HPACK=$(DBG_HPACK)

Expand Down
4 changes: 2 additions & 2 deletions db/core/htrie.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Tempesta DB
*
* Copyright (C) 2014 NatSys Lab. ([email protected]).
* Copyright (C) 2015-2016 Tempesta Technologies.
* Copyright (C) 2015-2022 Tempesta Technologies.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -104,7 +104,7 @@ typedef struct {
#define TDB_HTRIE_ROOT(h) \
(TdbHtrieNode *)((char *)(h) + TDB_HDR_SZ(h) + sizeof(TdbExt))

/* FIXME we can't store zero bytes by zero key. */
/* TODO we can't store zero bytes by zero key. */
static inline int
tdb_live_fsrec(TdbHdr *dbh, TdbFRec *rec)
{
Expand Down
4 changes: 2 additions & 2 deletions db/core/if.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* User-space communication routines.
*
* Copyright (C) 2015-2018 Tempesta Technologies, INC.
* Copyright (C) 2015-2022 Tempesta Technologies, INC.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -201,7 +201,7 @@ tdb_if_select(struct sk_buff *skb, struct netlink_callback *cb)
}

/*
* FIXME implement select of all records:
* TODO implement select of all records:
* 1. full HTrie iterator is required;
* 2. use many netlink frames to send probably large data set.
*/
Expand Down
4 changes: 2 additions & 2 deletions fw/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -1347,7 +1347,7 @@ __set_etag(TfwCacheEntry *ce, TfwHttpResp *resp, long h_off, TdbVRec *h_trec,
tfw_http_msg_srvhdr_val(h, TFW_HTTP_HDR_ETAG, &h_val);

/* Update supposed Etag offset to real value. */
/* FIXME: #803 */
/* TODO: #803 */
e_p = TDB_PTR(db->hdr, h_off);
if (e_p + TFW_CSTR_HDRLEN > h_trec->data + h_trec->len) {
h_trec = tdb_next_rec_chunk(db, h_trec);
Expand Down Expand Up @@ -1654,7 +1654,7 @@ tfw_cache_copy_resp(TfwCacheEntry *ce, TfwHttpResp *resp, TfwStr *rph,
}

/* Update offsets of 304 headers to real values */
/* FIXME: #803 */
/* TODO: #803 */
trec = &ce->trec;
for (i = 0; i < ARRAY_SIZE(ce->hdrs_304); ++i) {
if (!ce->hdrs_304[i])
Expand Down
4 changes: 2 additions & 2 deletions fw/cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
* - Improve efficiency: too many memory allocations and data copying.
*
* Copyright (C) 2014 NatSys Lab. ([email protected]).
* Copyright (C) 2015-2021 Tempesta Technologies, Inc.
* Copyright (C) 2015-2022 Tempesta Technologies, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -125,7 +125,7 @@ __alloc_and_copy_literal(const char *src, size_t len, bool keep_bs)
}

/* Copy the string. Eat escaping backslashes if @keep_bs is not set. */
/* FIXME: the logic looks like a tiny FSM,
/* TODO: the logic looks like a tiny FSM,
* so perhaps it should be included to the TFSM. */
src_end = src + len;
src_pos = src;
Expand Down
28 changes: 22 additions & 6 deletions fw/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "log.h"
#include "sync_socket.h"
#include "http.h"
#include "websocket.h"

TfwConnHooks *conn_hooks[TFW_CONN_MAX_PROTOS];

Expand Down Expand Up @@ -125,14 +126,29 @@ tfw_connection_send(TfwConn *conn, TfwMsg *msg)
}

int
tfw_connection_recv(void *cdata, struct sk_buff *skb)
tfw_connection_recv(TfwConn *conn, struct sk_buff *skb)
{
TfwConn *conn = cdata;
TfwFsmData fsm_data = {
.skb = skb,
};
int r = T_OK;
struct sk_buff *next;

if (skb->prev)
skb->prev->next = NULL;
for (next = skb->next; skb;
skb = next, next = next ? next->next : NULL)
{
if (likely(r == T_OK || r == T_POSTPONE)) {
skb->next = skb->prev = NULL;
if (unlikely(TFW_CONN_PROTO(conn) == TFW_FSM_WS
|| TFW_CONN_PROTO(conn) == TFW_FSM_WSS))
r = tfw_ws_msg_process(conn, skb);
else
r = tfw_http_msg_process(conn, skb);
} else {
__kfree_skb(skb);
}
}

return tfw_http_msg_process(conn, &fsm_data);
return r;
}

void
Expand Down
14 changes: 8 additions & 6 deletions fw/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ enum {
Conn_HttpsSrv = Conn_Srv | TFW_FSM_HTTPS,

/* Websocket plain */
Conn_WsClnt = Conn_HttpClnt | TFW_FSM_WS,
Conn_WsSrv = Conn_HttpSrv | TFW_FSM_WS,
Conn_WsClnt = Conn_HttpClnt | TFW_FSM_WEBSOCKET,
Conn_WsSrv = Conn_HttpSrv | TFW_FSM_WEBSOCKET,

/* Websocket secure */
Conn_WssClnt = Conn_HttpsClnt | TFW_FSM_WS,
Conn_WssSrv = Conn_HttpsSrv | TFW_FSM_WS,
Conn_WssClnt = Conn_HttpsClnt | TFW_FSM_WEBSOCKET,
Conn_WssSrv = Conn_HttpsSrv | TFW_FSM_WEBSOCKET,
};

#define TFW_CONN_TYPE2IDX(t) TFW_FSM_TYPE(t)
Expand Down Expand Up @@ -94,9 +94,11 @@ enum {
* @timer - The keep-alive/retry timer for the connection;
* @stream - instance for control messages processing;
* @peer - TfwClient or TfwServer handler. Hop-by-hop peer;
* @pair - Paired TfwCliConn or TfwSrvConn for websocket connections;
* @sk - an appropriate sock handler;
* @destructor - called when a connection is destroyed;
*/
typedef struct tfw_conn_t TfwConn;
#define TFW_CONN_COMMON \
SsProto proto; \
TfwGState state; \
Expand All @@ -105,6 +107,7 @@ enum {
struct timer_list timer; \
TfwStream stream; \
TfwPeer *peer; \
TfwConn *pair; \
struct sock *sk; \
void (*destructor)(void *);

Expand Down Expand Up @@ -516,6 +519,7 @@ tfw_connection_validate_cleanup(TfwConn *conn)
void tfw_connection_hooks_register(TfwConnHooks *hooks, int type);
void tfw_connection_hooks_unregister(int type);
int tfw_connection_send(TfwConn *conn, TfwMsg *msg);
int tfw_connection_recv(TfwConn *conn, struct sk_buff *skb);

/* Generic helpers, used for both client and server connections. */
void tfw_connection_init(TfwConn *conn);
Expand All @@ -527,6 +531,4 @@ int tfw_connection_close(TfwConn *conn, bool sync);
void tfw_connection_drop(TfwConn *conn);
void tfw_connection_release(TfwConn *conn);

int tfw_connection_recv(void *cdata, struct sk_buff *skb);

#endif /* __TFW_CONNECTION_H__ */
13 changes: 1 addition & 12 deletions fw/gfsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
* tfw_gfsm_move().
*
* Copyright (C) 2014 NatSys Lab. ([email protected]).
* Copyright (C) 2015-2018 Tempesta Technologies, Inc.
* Copyright (C) 2015-2022 Tempesta Technologies, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -193,17 +193,6 @@ __gfsm_fsm_exec(TfwGState *st, int fsm_id, TfwFsmData *data)
return r;
}

/**
* Dispatch connection data to proper FSM by application protocol type.
*/
int
tfw_gfsm_dispatch(TfwGState *st, void *obj, TfwFsmData *data)
{
int fsm_id = TFW_FSM_TYPE(((SsProto *)obj)->type);

return __gfsm_fsm_exec(st, fsm_id, data);
}

/**
* Move the FSM with descriptor @st to new the state @state and call all
* registered hooks for it.
Expand Down
7 changes: 4 additions & 3 deletions fw/gfsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,10 @@ enum {
/* Protocols */
TFW_FSM_HTTP,
TFW_FSM_HTTPS,
/* Not really a FSM */
TFW_FSM_WS,
/* Not really a FSM, used for connection hook registration only */
TFW_FSM_WEBSOCKET,
TFW_FSM_WS = TFW_FSM_WEBSOCKET | TFW_FSM_HTTP,
TFW_FSM_WSS = TFW_FSM_WEBSOCKET | TFW_FSM_HTTPS,

/* Security rules enforcement. */
TFW_FSM_FRANG_REQ,
Expand Down Expand Up @@ -187,7 +189,6 @@ typedef struct tfw_conn_t TfwConn;
typedef int (*tfw_gfsm_handler_t)(TfwConn *conn, TfwFsmData *data);

void tfw_gfsm_state_init(TfwGState *st, void *obj, int st0);
int tfw_gfsm_dispatch(TfwGState *st, void *obj, TfwFsmData *data);
int tfw_gfsm_move(TfwGState *st, unsigned short state, TfwFsmData *data);

#ifdef DEBUG
Expand Down
Loading

0 comments on commit 8dd6b95

Please sign in to comment.