From cd64085694c7c4aa96312e88905015eea4d8b63d Mon Sep 17 00:00:00 2001 From: "Luke T. Shumaker" Date: Thu, 26 Dec 2024 18:01:31 -0700 Subject: lib9p: Split the generated tables up --- lib9p/9p.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'lib9p/9p.c') diff --git a/lib9p/9p.c b/lib9p/9p.c index a3d81d0..b464f63 100644 --- a/lib9p/9p.c +++ b/lib9p/9p.c @@ -1,6 +1,6 @@ /* lib9p/9p.c - Base 9P protocol utilities for both clients and servers * - * Copyright (C) 2024 Luke T. Shumaker + * Copyright (C) 2024-2025 Luke T. Shumaker * SPDX-License-Identifier: AGPL-3.0-or-later */ @@ -9,6 +9,9 @@ #include /* for vsnprintf() */ #include /* for strncpy() */ +#define LOG_NAME 9P +#include /* for const_byte_str() */ + #include #include "internal.h" @@ -69,7 +72,7 @@ const char *lib9p_msg_type_str(struct lib9p_ctx *ctx, enum lib9p_msg_type typ) { #pragma GCC diagnostic ignored "-Wtype-limits" assert(0 <= typ && typ <= 0xFF); #pragma GCC diagnostic pop - return _lib9p_versions[ctx->version].msgs[typ].name; + return _lib9p_table_msg_name[ctx->version][typ] ?: const_byte_str(typ); } /* main message functions *****************************************************/ @@ -87,7 +90,7 @@ ssize_t lib9p_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) { if (subctx.net_size < 5) return lib9p_error(ctx, LINUX_EBADMSG, "message is impossibly short"); uint8_t typ = net_bytes[4]; - struct _table_msg table = _lib9p_versions[ctx->version].msgs[typ]; + struct _lib9p_recv_tentry table = ((typ % 2 == 0) ? _lib9p_table_Tmsg_recv : _lib9p_table_Rmsg_recv)[ctx->version][typ/2]; if (!table.validate) return lib9p_errorf(ctx, LINUX_EOPNOTSUPP, "unknown message type: %s (protocol_version=%s)", lib9p_msg_type_str(ctx, typ), lib9p_version_str(ctx->version)); @@ -116,8 +119,9 @@ void lib9p_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, .net_offset = 0, }; - *ret_typ = net_bytes[4]; - struct _table_msg table = _lib9p_versions[ctx->version].msgs[*ret_typ]; + enum lib9p_msg_type typ = net_bytes[4]; + *ret_typ = typ; + struct _lib9p_recv_tentry table = ((typ % 2 == 0) ? _lib9p_table_Tmsg_recv : _lib9p_table_Rmsg_recv)[ctx->version][typ/2]; subctx.extra = ret_body + table.basesize; table.unmarshal(&subctx, ret_body); } @@ -130,7 +134,7 @@ bool lib9p_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body, .net_offset = 0, }; - struct _table_msg table = _lib9p_versions[ctx->version].msgs[typ]; + struct _lib9p_send_tentry table = ((typ % 2 == 0) ? _lib9p_table_Tmsg_send : _lib9p_table_Rmsg_send)[ctx->version][typ/2]; return table.marshal(&subctx, body); } -- cgit v1.2.3-2-g168b From c3b9d7e802d7d2e31131692d621515ac88178ebb Mon Sep 17 00:00:00 2001 From: "Luke T. Shumaker" Date: Mon, 16 Dec 2024 14:51:10 -0500 Subject: lib9p: Split lib9p_{validate,unmarshal,marshal} into _Tmsg and _Rmsg variants --- lib9p/9p.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 60 insertions(+), 15 deletions(-) (limited to 'lib9p/9p.c') diff --git a/lib9p/9p.c b/lib9p/9p.c index b464f63..8f3ae78 100644 --- a/lib9p/9p.c +++ b/lib9p/9p.c @@ -77,7 +77,11 @@ const char *lib9p_msg_type_str(struct lib9p_ctx *ctx, enum lib9p_msg_type typ) { /* main message functions *****************************************************/ -ssize_t lib9p_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) { +static +ssize_t _lib9p_validate(uint8_t xxx_low_typ_bit, + const char *xxx_errmsg, + const struct _lib9p_recv_tentry xxx_table[LIB9P_VER_NUM][0x80], + struct lib9p_ctx *ctx, uint8_t *net_bytes) { /* Inspect the first 5 bytes ourselves. */ struct _validate_ctx subctx = { .ctx = ctx, @@ -90,13 +94,16 @@ ssize_t lib9p_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) { if (subctx.net_size < 5) return lib9p_error(ctx, LINUX_EBADMSG, "message is impossibly short"); uint8_t typ = net_bytes[4]; - struct _lib9p_recv_tentry table = ((typ % 2 == 0) ? _lib9p_table_Tmsg_recv : _lib9p_table_Rmsg_recv)[ctx->version][typ/2]; - if (!table.validate) + if (typ % 2 != xxx_low_typ_bit) + return lib9p_errorf(ctx, LINUX_EOPNOTSUPP, "%s: message_type=%s", xxx_errmsg, + lib9p_msg_type_str(ctx, typ)); + struct _lib9p_recv_tentry tentry = xxx_table[ctx->version][typ/2]; + if (!tentry.validate) return lib9p_errorf(ctx, LINUX_EOPNOTSUPP, "unknown message type: %s (protocol_version=%s)", lib9p_msg_type_str(ctx, typ), lib9p_version_str(ctx->version)); - /* Now use the message-type-specific table to process the whole thing. */ - if (table.validate(&subctx)) + /* Now use the message-type-specific tentry to process the whole thing. */ + if (tentry.validate(&subctx)) return -1; assert(subctx.net_offset <= subctx.net_size); if (subctx.net_offset < subctx.net_size) @@ -105,13 +112,25 @@ ssize_t lib9p_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) { /* Return. */ ssize_t ret; - if (__builtin_add_overflow(table.basesize, subctx.host_extra, &ret)) + if (__builtin_add_overflow(tentry.basesize, subctx.host_extra, &ret)) return lib9p_error(ctx, LINUX_EMSGSIZE, "unmarshalled payload overflows SSIZE_MAX"); return ret; } -void lib9p_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, - enum lib9p_msg_type *ret_typ, void *ret_body) { +ssize_t lib9p_Tmsg_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) { + return _lib9p_validate(0, "expected a T-message but got an R-message", _lib9p_table_Tmsg_recv, + ctx, net_bytes); +} + +ssize_t lib9p_Rmsg_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) { + return _lib9p_validate(1, "expected an R-message but got a T-message", _lib9p_table_Rmsg_recv, + ctx, net_bytes); +} + +static +void _lib9p_unmarshal(const struct _lib9p_recv_tentry xxx_table[LIB9P_VER_NUM][0x80], + struct lib9p_ctx *ctx, uint8_t *net_bytes, + enum lib9p_msg_type *ret_typ, void *ret_body) { struct _unmarshal_ctx subctx = { .ctx = ctx, .net_bytes = net_bytes, @@ -121,21 +140,47 @@ void lib9p_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, enum lib9p_msg_type typ = net_bytes[4]; *ret_typ = typ; - struct _lib9p_recv_tentry table = ((typ % 2 == 0) ? _lib9p_table_Tmsg_recv : _lib9p_table_Rmsg_recv)[ctx->version][typ/2]; - subctx.extra = ret_body + table.basesize; - table.unmarshal(&subctx, ret_body); + struct _lib9p_recv_tentry tentry = xxx_table[ctx->version][typ/2]; + subctx.extra = ret_body + tentry.basesize; + tentry.unmarshal(&subctx, ret_body); +} + +void lib9p_Tmsg_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, + enum lib9p_msg_type *ret_typ, void *ret_body) { + _lib9p_unmarshal(_lib9p_table_Tmsg_recv, + ctx, net_bytes, ret_typ, ret_body); } -bool lib9p_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body, - uint8_t *ret_bytes) { +void lib9p_Rmsg_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, + enum lib9p_msg_type *ret_typ, void *ret_body) { + _lib9p_unmarshal(_lib9p_table_Rmsg_recv, + ctx, net_bytes, ret_typ, ret_body); +} + +static +bool _lib9p_marshal(const struct _lib9p_send_tentry xxx_table[LIB9P_VER_NUM][0x80], + struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body, + uint8_t *ret_bytes) { struct _marshal_ctx subctx = { .ctx = ctx, .net_bytes = ret_bytes, .net_offset = 0, }; - struct _lib9p_send_tentry table = ((typ % 2 == 0) ? _lib9p_table_Tmsg_send : _lib9p_table_Rmsg_send)[ctx->version][typ/2]; - return table.marshal(&subctx, body); + struct _lib9p_send_tentry tentry = xxx_table[ctx->version][typ/2]; + return tentry.marshal(&subctx, body); +} + +bool lib9p_Tmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body, + uint8_t *ret_bytes) { + assert(typ % 2 == 0); + return _lib9p_marshal(_lib9p_table_Tmsg_send, ctx, typ, body, ret_bytes); +} + +bool lib9p_Rmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body, + uint8_t *ret_bytes) { + assert(typ % 2 == 1); + return _lib9p_marshal(_lib9p_table_Rmsg_send, ctx, typ, body, ret_bytes); } /* `struct lib9p_stat` helpers ************************************************/ -- cgit v1.2.3-2-g168b From f263b08d4457e36126f150566219472f3a05c906 Mon Sep 17 00:00:00 2001 From: "Luke T. Shumaker" Date: Mon, 16 Dec 2024 14:56:05 -0500 Subject: lib9p: Rename `lib9p_*_stat()` to `lib9p_stat_*()` for consistency --- lib9p/9p.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'lib9p/9p.c') diff --git a/lib9p/9p.c b/lib9p/9p.c index 8f3ae78..ecb75fd 100644 --- a/lib9p/9p.c +++ b/lib9p/9p.c @@ -185,7 +185,7 @@ bool lib9p_Rmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *bo /* `struct lib9p_stat` helpers ************************************************/ -bool lib9p_validate_stat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, +bool lib9p_stat_validate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, uint32_t *ret_net_size, ssize_t *ret_host_size) { struct _validate_ctx subctx = { .ctx = ctx, @@ -195,7 +195,7 @@ bool lib9p_validate_stat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_ .net_offset = 0, .host_extra = 0, }; - if (_lib9p_validate_stat(&subctx)) + if (_lib9p_stat_validate(&subctx)) return true; if (ret_net_size) *ret_net_size = subctx.net_offset; @@ -205,7 +205,7 @@ bool lib9p_validate_stat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_ return false; } -uint32_t lib9p_unmarshal_stat(struct lib9p_ctx *ctx, uint8_t *net_bytes, +uint32_t lib9p_stat_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, struct lib9p_stat *ret_obj, void *ret_extra) { struct _unmarshal_ctx subctx = { .ctx = ctx, @@ -214,11 +214,11 @@ uint32_t lib9p_unmarshal_stat(struct lib9p_ctx *ctx, uint8_t *net_bytes, .extra = ret_extra, }; - _lib9p_unmarshal_stat(&subctx, ret_obj); + _lib9p_stat_unmarshal(&subctx, ret_obj); return subctx.net_offset; } -uint32_t lib9p_marshal_stat(struct lib9p_ctx *ctx, uint32_t max_net_size, struct lib9p_stat *obj, +uint32_t lib9p_stat_marshal(struct lib9p_ctx *ctx, uint32_t max_net_size, struct lib9p_stat *obj, uint8_t *ret_bytes) { struct lib9p_ctx _ctx = *ctx; _ctx.max_msg_size = max_net_size; @@ -227,7 +227,7 @@ uint32_t lib9p_marshal_stat(struct lib9p_ctx *ctx, uint32_t max_net_size, struct .net_bytes = ret_bytes, .net_offset = 0, }; - if (_lib9p_marshal_stat(&subctx, obj)) + if (_lib9p_stat_marshal(&subctx, obj)) return 0; return subctx.net_offset; } -- cgit v1.2.3-2-g168b