diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-09-27 22:27:01 -0600 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-09-27 22:27:01 -0600 |
commit | 7ec97df3ee8edfd102fe573eaa61cf4e5c6284cb (patch) | |
tree | e696f30da5645cdd3cb09971d9544622e9943bcf /lib9p/9p.c | |
parent | fa357459f88bb8f0170d1a68df66e7d068d59996 (diff) |
wip fixes
Diffstat (limited to 'lib9p/9p.c')
-rw-r--r-- | lib9p/9p.c | 72 |
1 files changed, 44 insertions, 28 deletions
@@ -13,12 +13,12 @@ #include "internal.h" -enum lib9p_version lib9p_ctx_version(lib9p_ctx *ctx) { +enum lib9p_version lib9p_ctx_version(struct lib9p_ctx *ctx) { assert(ctx); return ctx->version; } -uint32_t lib9p_ctx_max_msg_size(lib9p_ctx *ctx) { +uint32_t lib9p_ctx_max_msg_size(struct lib9p_ctx *ctx) { assert(ctx); return ctx->max_msg_size; } @@ -45,50 +45,66 @@ int lib9p_errorf(struct lib9p_ctx *ctx, uint32_t linux_errno, char const *fmt, . return -1; } -size_t lib9p_unmarshal_size(struct lib9p_ctx *ctx, uint8_t *net_bytes) { +ssize_t lib9p_unmarshal_size(struct lib9p_ctx *ctx, uint8_t *net_bytes) { /* Header */ - uint32_t net_len = decode_u32le(net_bytes); - if (net_len < 7) + struct _checksize_ctx subctx = { + .ctx = ctx, + .net_size = decode_u32le(net_bytes), + .net_bytes = net_bytes, + + .net_offset = 7, + .host_extra = 0, + }; + if (subctx.net_size < subctx.net_offset) return lib9p_error(ctx, LINUX_EBADMSG, "message is too short"); uint8_t typ = net_bytes[4]; - uint32_t net_offset = 7; /* Body */ - if (!versions[ctx->version]->msgs[typ].unmarshal_extrasize) + struct _vtable_msg vtable = _lib9p_vtables[ctx->version].msgs[typ]; + if (!vtable.unmarshal_extrasize) return lib9p_errorf(ctx, LINUX_EOPNOTSUPP, "unknown message type %"PRIu8, typ); - size_t host_size = versions[ctx->version]->msgs[typ].unmarshal_basesize; - if (versions[ctx->version]->msgs[typ].unmarshal_extrasize(net_len, net_bytes, &net_offset, &host_size)) - return lib9p_error(ctx, LINUX_EBADMSG, "message is too short for content"); + if (vtable.unmarshal_extrasize(&subctx)) + return -1; - return host_size; + return (ssize_t)(vtable.unmarshal_basesize + subctx.host_extra); } -uint8_t lib9p_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, uint16_t *out_tag, void *out_body) { +void lib9p_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, + enum lib9p_msg_type *ret_typ, uint16_t *ret_tag, void *ret_body) { /* Header */ - uint8_t typ = net_bytes[4]; - *out_tag = decode_u16le(&net_bytes[5]); - uint32_t net_offset = 7; + struct _unmarshal_ctx subctx = { + .ctx = ctx, + .net_bytes = net_bytes, - /* Body */ - void *host_extra = out_body + versions[ctx->version]->msgs[typ].unmarshal_basesize; - if (versions[ctx->version]->msgs[typ].unmarshal(net_bytes, &net_offset, &host_extra, out_body)) - return lib9p_error(ctx, LINUX_EBADMSG, "message contains invalid UTF-8"); + .net_offset = 7, + }; + *ret_typ = net_bytes[4]; + *ret_tag = decode_u16le(&net_bytes[5]); - return typ; + /* Body */ + struct _vtable_msg vtable = _lib9p_vtables[ctx->version].msgs[*ret_typ]; + subctx.extra = ret_body + vtable.unmarshal_basesize; + vtable.unmarshal(&subctx, ret_body); } -uint32_t lib9p_marshal(struct lib9p_ctx *ctx, uint8_t typ, uint16_t msgid, void *body, uint8_t *out_bytes) { +bool lib9p_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, uint16_t tag, void *body, + uint8_t *ret_bytes) { /* Header */ - out_bytes[4] = typ; - encode_u16le(msgid, &out_bytes[5]); - uint32_t net_offset = 7; + struct _marshal_ctx subctx = { + .ctx = ctx, + .net_bytes = ret_bytes, + .net_offset = 7, + }; + ret_bytes[4] = typ; + encode_u16le(tag, &ret_bytes[5]); /* Body */ - if (versions[ctx->version]->msgs[typ].marshal(ctx, body, out_bytes, &net_offset)) - return 0; + struct _vtable_msg vtable = _lib9p_vtables[ctx->version].msgs[typ]; + if (vtable.marshal(&subctx, body)) + return true; /* Header, again */ - encode_u32le(net_offset, out_bytes); + encode_u32le(subctx.net_offset, ret_bytes); - return net_offset; + return false; } |