1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

sspc: ssv1: add serialization protocol versioning

Let's add a byte on the first message that sspc clients send,
indicating the version of the serialization protocol that the
client was built with.

Start the version at 1, we will add some more changes in other
patches and call v1 (now it has the versioning baked in)
the first real supported serialization version, this patch must
be applied with the next patches to actually represent v1
protocol changes.

This doesn't require user setting, the client is told what version
it supports in LWS_SSS_CLIENT_PROTOCOL_VERSION.  The proxy knows
what version(s) it can support and loudly hangs up on the client
if it doesn't understand its protocol version.
This commit is contained in:
Andy Green 2020-12-31 14:07:13 +00:00
parent c82910d30c
commit 4fc4c671fa
5 changed files with 60 additions and 12 deletions

View file

@ -63,8 +63,9 @@
*
* - 0: LWSSS_SER_TXPRE_STREAMTYPE
* - 1: 2-byte MSB-first rest-of-frame length
* - 3: 4 byte MSB-first initial tx credit
* - 7: the streamtype name with no NUL
* - 3: 1-byte Client SSS protocol version (introduced in SSSv1)
* - 4: 4-byte MSB-first initial tx credit
* - 8: the streamtype name with no NUL
*
* - Proxied tx
*
@ -362,7 +363,14 @@ typedef struct lws_ss_info {
* In the special case of _lws_smd streamtype, this is used to indicate
* the connection's rx class mask.
* */
uint8_t flags;
uint8_t flags;
uint8_t sss_protocol_version;
/**< used in proxy / serialization case to hold the SS serialization
* protocol level to use with this peer... clients automatically request
* the most recent version they were built with
* (LWS_SSS_CLIENT_PROTOCOL_VERSION) and the proxy stores the requested
* version in here
*/
} lws_ss_info_t;

View file

@ -22,6 +22,9 @@
* IN THE SOFTWARE.
*/
/* current SS Serialization protocol version */
#define LWS_SSS_CLIENT_PROTOCOL_VERSION 1
/*
* Secure Stream state
*/
@ -226,6 +229,7 @@ struct lws_ss_serialization_parser {
uint8_t slen;
uint8_t rsl_pos;
uint8_t rsl_idx;
uint8_t protocol_version;
};
/*

View file

@ -248,15 +248,18 @@ callback_sspc_client(struct lws *wsi, enum lws_callback_reasons reason,
* We are negotating the opening of a particular
* streamtype
*/
n = (int)strlen(h->ssi.streamtype) + 4;
n = (int)strlen(h->ssi.streamtype) + 5;
s[0] = LWSSS_SER_TXPRE_STREAMTYPE;
lws_ser_wu16be(&s[1], (uint16_t)n);
lws_ser_wu32be(&s[3], (uint32_t)h->txc.peer_tx_cr_est);
/* SSSv1: add protocol version byte (initially 1) */
s[3] = (uint8_t)LWS_SSS_CLIENT_PROTOCOL_VERSION;
lws_ser_wu32be(&s[4], (uint32_t)h->txc.peer_tx_cr_est);
//h->txcr_out = txc;
lws_strncpy((char *)&s[7], h->ssi.streamtype, sizeof(s) - 7);
lws_strncpy((char *)&s[8], h->ssi.streamtype, sizeof(s) - 8);
n += 3;
h->state = LPCSCLI_WAITING_CREATE_RESULT;
break;
case LPCSCLI_LOCAL_CONNECTED:

View file

@ -68,6 +68,7 @@ typedef enum {
RPAR_RX_TXCR_UPDATE,
RPAR_STREAMTYPE,
RPAR_INIT_PROVERS,
RPAR_INITTXC0,
RPAR_TXCR0,
@ -441,10 +442,9 @@ lws_ss_deserialize_parse(struct lws_ss_serialization_parser *par,
goto hangup;
if (*state != LPCSPROX_WAIT_INITIAL_TX)
goto hangup;
if (par->rem < 4)
if (par->rem < 1 + 4 + 1)
goto hangup;
par->ctr = 0;
par->ps = RPAR_INITTXC0;
par->ps = RPAR_INIT_PROVERS;
break;
case LWSSS_SER_TXPRE_METADATA:
@ -781,6 +781,31 @@ payload_ff:
par->ps = RPAR_TYPE;
break;
case RPAR_INIT_PROVERS:
/* Protocol version byte for this connection */
par->protocol_version = *cp++;
/*
* So we have to know what versions of the serialization
* protocol we can support at the proxy side, and
* reject anythng we don't know how to deal with
* noisily in the logs.
*/
if (par->protocol_version != 1) {
lwsl_err("%s: Rejecting client with "
"unsupported SSv%d protocol\n",
__func__, par->protocol_version);
goto hangup;
}
if (!--par->rem)
goto hangup;
par->ctr = 0;
par->ps = RPAR_INITTXC0;
break;
case RPAR_INITTXC0:
if (!--par->rem)
goto hangup;
@ -1086,8 +1111,9 @@ payload_ff:
par->ps = RPAR_TYPE;
par->streamtype[par->ctr] = '\0';
lwsl_notice("%s: creating proxied ss '%s', txcr %d\n",
__func__, par->streamtype, par->txcr_out);
lwsl_info("%s: proxy ss '%s', sssv%d, txcr %d\n",
__func__, par->streamtype,
par->protocol_version, par->txcr_out);
ssi->streamtype = par->streamtype;
if (par->txcr_out) // !!!
@ -1100,6 +1126,7 @@ payload_ff:
*/
ssi->flags |= LWSSSINFLAGS_PROXIED;
ssi->sss_protocol_version = par->protocol_version;
if (lws_ss_create(context, 0, ssi, parconn, pss,
NULL, NULL)) {
/*

View file

@ -618,7 +618,13 @@ lws_ss_create(struct lws_context *context, int tsi, const lws_ss_info_t *ssi,
if (!h)
return 2;
__lws_lc_tag(&context->lcg[LWSLCG_WSI_SS_CLIENT], &h->lc, ssi->streamtype ? ssi->streamtype : "nostreamtype");
if (ssi->sss_protocol_version)
__lws_lc_tag(&context->lcg[LWSLCG_WSI_SS_CLIENT], &h->lc, "%s|v%u",
ssi->streamtype ? ssi->streamtype : "nostreamtype",
(unsigned int)ssi->sss_protocol_version);
else
__lws_lc_tag(&context->lcg[LWSLCG_WSI_SS_CLIENT], &h->lc, "%s",
ssi->streamtype ? ssi->streamtype : "nostreamtype");
h->info = *ssi;
h->policy = pol;