Skip to content

Commit c7e76e4

Browse files
committed
Websocket simple proxy protocol implementation
Signed-off-by: Aleksey Mikhaylov <[email protected]>
1 parent 01fee37 commit c7e76e4

28 files changed

+488
-154
lines changed

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ Module.symvers
2626
# vscode project settings
2727
.vscode
2828

29+
# nodejs and npm
30+
node_modules
31+
package.json
32+
package-lock.json
33+
2934
# Python compiler cache files
3035
*.pyc
3136

Makefile

+3-2
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,14 @@ DBG_CFG ?= 0
5959
DBG_HTTP_PARSER ?= 0
6060
DBG_SS ?= 0
6161
DBG_TLS ?= 0
62+
DBG_WS ?= 0
6263
DBG_APM ?= 0
6364
DBG_HTTP_FRAME ?= 0
6465
DBG_HTTP_STREAM ?= 0
6566
DBG_HPACK ?= 0
6667
TFW_CFLAGS += -DDBG_CFG=$(DBG_CFG) -DDBG_HTTP_PARSER=$(DBG_HTTP_PARSER)
67-
TFW_CFLAGS += -DDBG_SS=$(DBG_SS) -DDBG_TLS=$(DBG_TLS) -DDBG_APM=$(DBG_APM)
68-
TFW_CFLAGS += -DDBG_HTTP_FRAME=$(DBG_HTTP_FRAME)
68+
TFW_CFLAGS += -DDBG_SS=$(DBG_SS) -DDBG_TLS=$(DBG_TLS) -DDBG_WS=$(DBG_WS)
69+
TFW_CFLAGS += -DDBG_APM=$(DBG_APM) -DDBG_HTTP_FRAME=$(DBG_HTTP_FRAME)
6970
TFW_CFLAGS += -DDBG_HTTP_STREAM=$(DBG_HTTP_STREAM)
7071
TFW_CFLAGS += -DDBG_HPACK=$(DBG_HPACK)
7172

db/core/htrie.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Tempesta DB
33
*
44
* Copyright (C) 2014 NatSys Lab. ([email protected]).
5-
* Copyright (C) 2015-2016 Tempesta Technologies.
5+
* Copyright (C) 2015-2022 Tempesta Technologies.
66
*
77
* This program is free software; you can redistribute it and/or modify it
88
* under the terms of the GNU General Public License as published by
@@ -104,7 +104,7 @@ typedef struct {
104104
#define TDB_HTRIE_ROOT(h) \
105105
(TdbHtrieNode *)((char *)(h) + TDB_HDR_SZ(h) + sizeof(TdbExt))
106106

107-
/* FIXME we can't store zero bytes by zero key. */
107+
/* TODO we can't store zero bytes by zero key. */
108108
static inline int
109109
tdb_live_fsrec(TdbHdr *dbh, TdbFRec *rec)
110110
{

db/core/if.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* User-space communication routines.
55
*
6-
* Copyright (C) 2015-2018 Tempesta Technologies, INC.
6+
* Copyright (C) 2015-2022 Tempesta Technologies, INC.
77
*
88
* This program is free software; you can redistribute it and/or modify it
99
* under the terms of the GNU General Public License as published by
@@ -201,7 +201,7 @@ tdb_if_select(struct sk_buff *skb, struct netlink_callback *cb)
201201
}
202202

203203
/*
204-
* FIXME implement select of all records:
204+
* TODO implement select of all records:
205205
* 1. full HTrie iterator is required;
206206
* 2. use many netlink frames to send probably large data set.
207207
*/

fw/cache.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -1347,7 +1347,7 @@ __set_etag(TfwCacheEntry *ce, TfwHttpResp *resp, long h_off, TdbVRec *h_trec,
13471347
tfw_http_msg_srvhdr_val(h, TFW_HTTP_HDR_ETAG, &h_val);
13481348

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

16561656
/* Update offsets of 304 headers to real values */
1657-
/* FIXME: #803 */
1657+
/* TODO: #803 */
16581658
trec = &ce->trec;
16591659
for (i = 0; i < ARRAY_SIZE(ce->hdrs_304); ++i) {
16601660
if (!ce->hdrs_304[i])

fw/cfg.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
* - Improve efficiency: too many memory allocations and data copying.
6565
*
6666
* Copyright (C) 2014 NatSys Lab. ([email protected]).
67-
* Copyright (C) 2015-2021 Tempesta Technologies, Inc.
67+
* Copyright (C) 2015-2022 Tempesta Technologies, Inc.
6868
*
6969
* This program is free software; you can redistribute it and/or modify it
7070
* under the terms of the GNU General Public License as published by
@@ -125,7 +125,7 @@ __alloc_and_copy_literal(const char *src, size_t len, bool keep_bs)
125125
}
126126

127127
/* Copy the string. Eat escaping backslashes if @keep_bs is not set. */
128-
/* FIXME: the logic looks like a tiny FSM,
128+
/* TODO: the logic looks like a tiny FSM,
129129
* so perhaps it should be included to the TFSM. */
130130
src_end = src + len;
131131
src_pos = src;

fw/connection.c

+22-6
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "log.h"
2626
#include "sync_socket.h"
2727
#include "http.h"
28+
#include "websocket.h"
2829

2930
TfwConnHooks *conn_hooks[TFW_CONN_MAX_PROTOS];
3031

@@ -125,14 +126,29 @@ tfw_connection_send(TfwConn *conn, TfwMsg *msg)
125126
}
126127

127128
int
128-
tfw_connection_recv(void *cdata, struct sk_buff *skb)
129+
tfw_connection_recv(TfwConn *conn, struct sk_buff *skb)
129130
{
130-
TfwConn *conn = cdata;
131-
TfwFsmData fsm_data = {
132-
.skb = skb,
133-
};
131+
int r = T_OK;
132+
struct sk_buff *next;
133+
134+
if (skb->prev)
135+
skb->prev->next = NULL;
136+
for (next = skb->next; skb;
137+
skb = next, next = next ? next->next : NULL)
138+
{
139+
if (likely(r == T_OK || r == T_POSTPONE)) {
140+
skb->next = skb->prev = NULL;
141+
if (unlikely(TFW_CONN_PROTO(conn) == TFW_FSM_WS
142+
|| TFW_CONN_PROTO(conn) == TFW_FSM_WSS))
143+
r = tfw_ws_msg_process(conn, skb);
144+
else
145+
r = tfw_http_msg_process(conn, skb);
146+
} else {
147+
__kfree_skb(skb);
148+
}
149+
}
134150

135-
return tfw_http_msg_process(conn, &fsm_data);
151+
return r;
136152
}
137153

138154
void

fw/connection.h

+8-6
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ enum {
5353
Conn_HttpsSrv = Conn_Srv | TFW_FSM_HTTPS,
5454

5555
/* Websocket plain */
56-
Conn_WsClnt = Conn_HttpClnt | TFW_FSM_WS,
57-
Conn_WsSrv = Conn_HttpSrv | TFW_FSM_WS,
56+
Conn_WsClnt = Conn_HttpClnt | TFW_FSM_WEBSOCKET,
57+
Conn_WsSrv = Conn_HttpSrv | TFW_FSM_WEBSOCKET,
5858

5959
/* Websocket secure */
60-
Conn_WssClnt = Conn_HttpsClnt | TFW_FSM_WS,
61-
Conn_WssSrv = Conn_HttpsSrv | TFW_FSM_WS,
60+
Conn_WssClnt = Conn_HttpsClnt | TFW_FSM_WEBSOCKET,
61+
Conn_WssSrv = Conn_HttpsSrv | TFW_FSM_WEBSOCKET,
6262
};
6363

6464
#define TFW_CONN_TYPE2IDX(t) TFW_FSM_TYPE(t)
@@ -94,9 +94,11 @@ enum {
9494
* @timer - The keep-alive/retry timer for the connection;
9595
* @stream - instance for control messages processing;
9696
* @peer - TfwClient or TfwServer handler. Hop-by-hop peer;
97+
* @pair - Paired TfwCliConn or TfwSrvConn for websocket connections;
9798
* @sk - an appropriate sock handler;
9899
* @destructor - called when a connection is destroyed;
99100
*/
101+
typedef struct tfw_conn_t TfwConn;
100102
#define TFW_CONN_COMMON \
101103
SsProto proto; \
102104
TfwGState state; \
@@ -105,6 +107,7 @@ enum {
105107
struct timer_list timer; \
106108
TfwStream stream; \
107109
TfwPeer *peer; \
110+
TfwConn *pair; \
108111
struct sock *sk; \
109112
void (*destructor)(void *);
110113

@@ -516,6 +519,7 @@ tfw_connection_validate_cleanup(TfwConn *conn)
516519
void tfw_connection_hooks_register(TfwConnHooks *hooks, int type);
517520
void tfw_connection_hooks_unregister(int type);
518521
int tfw_connection_send(TfwConn *conn, TfwMsg *msg);
522+
int tfw_connection_recv(TfwConn *conn, struct sk_buff *skb);
519523

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

530-
int tfw_connection_recv(void *cdata, struct sk_buff *skb);
531-
532534
#endif /* __TFW_CONNECTION_H__ */

fw/gfsm.c

+1-12
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
* tfw_gfsm_move().
5858
*
5959
* Copyright (C) 2014 NatSys Lab. ([email protected]).
60-
* Copyright (C) 2015-2018 Tempesta Technologies, Inc.
60+
* Copyright (C) 2015-2022 Tempesta Technologies, Inc.
6161
*
6262
* This program is free software; you can redistribute it and/or modify it
6363
* under the terms of the GNU General Public License as published by
@@ -193,17 +193,6 @@ __gfsm_fsm_exec(TfwGState *st, int fsm_id, TfwFsmData *data)
193193
return r;
194194
}
195195

196-
/**
197-
* Dispatch connection data to proper FSM by application protocol type.
198-
*/
199-
int
200-
tfw_gfsm_dispatch(TfwGState *st, void *obj, TfwFsmData *data)
201-
{
202-
int fsm_id = TFW_FSM_TYPE(((SsProto *)obj)->type);
203-
204-
return __gfsm_fsm_exec(st, fsm_id, data);
205-
}
206-
207196
/**
208197
* Move the FSM with descriptor @st to new the state @state and call all
209198
* registered hooks for it.

fw/gfsm.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,10 @@ enum {
8484
/* Protocols */
8585
TFW_FSM_HTTP,
8686
TFW_FSM_HTTPS,
87-
/* Not really a FSM */
88-
TFW_FSM_WS,
87+
/* Not really a FSM, used for connection hook registration only */
88+
TFW_FSM_WEBSOCKET,
89+
TFW_FSM_WS = TFW_FSM_WEBSOCKET | TFW_FSM_HTTP,
90+
TFW_FSM_WSS = TFW_FSM_WEBSOCKET | TFW_FSM_HTTPS,
8991

9092
/* Security rules enforcement. */
9193
TFW_FSM_FRANG_REQ,
@@ -187,7 +189,6 @@ typedef struct tfw_conn_t TfwConn;
187189
typedef int (*tfw_gfsm_handler_t)(TfwConn *conn, TfwFsmData *data);
188190

189191
void tfw_gfsm_state_init(TfwGState *st, void *obj, int st0);
190-
int tfw_gfsm_dispatch(TfwGState *st, void *obj, TfwFsmData *data);
191192
int tfw_gfsm_move(TfwGState *st, unsigned short state, TfwFsmData *data);
192193

193194
#ifdef DEBUG

0 commit comments

Comments
 (0)