diff options
Diffstat (limited to 'lib9p/9p.c')
-rw-r--r-- | lib9p/9p.c | 39 |
1 files changed, 13 insertions, 26 deletions
@@ -36,24 +36,24 @@ int lib9p_errorf(struct lib9p_ctx *ctx, uint32_t linux_errno, char const *fmt, . } ssize_t lib9p_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) { - /* Header */ + /* Inspect the first 5 bytes ourselves. */ struct _validate_ctx subctx = { .ctx = ctx, .net_size = decode_u32le(net_bytes), .net_bytes = net_bytes, - .net_offset = 7, + .net_offset = 0, .host_extra = 0, }; - if (subctx.net_size < subctx.net_offset) - return lib9p_error(ctx, LINUX_EBADMSG, "message is too short"); + if (subctx.net_size < 5) + return lib9p_error(ctx, LINUX_EBADMSG, "message is impossibly short"); uint8_t typ = net_bytes[4]; - - /* Body */ struct _vtable_msg vtable = _lib9p_vtables[ctx->version].msgs[typ]; if (!vtable.validate) return lib9p_errorf(ctx, LINUX_EOPNOTSUPP, "unknown message type: %s (protocol_version=%s)", lib9p_msg_type_str(typ), lib9p_version_str(ctx->version)); + + /* Now use the message-type-specific vtable to process the whole thing. */ if (vtable.validate(&subctx)) return -1; assert(subctx.net_offset <= subctx.net_size); @@ -61,49 +61,36 @@ ssize_t lib9p_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) { return lib9p_errorf(ctx, LINUX_EBADMSG, "message has %"PRIu32" extra bytes", subctx.net_size - subctx.net_offset); + /* Return. */ ssize_t ret; if (__builtin_add_overflow(vtable.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, uint16_t *ret_tag, void *ret_body) { - /* Header */ + enum lib9p_msg_type *ret_typ, void *ret_body) { struct _unmarshal_ctx subctx = { .ctx = ctx, .net_bytes = net_bytes, - .net_offset = 7, + .net_offset = 0, }; - *ret_typ = net_bytes[4]; - *ret_tag = decode_u16le(&net_bytes[5]); - /* Body */ + *ret_typ = net_bytes[4]; struct _vtable_msg vtable = _lib9p_vtables[ctx->version].msgs[*ret_typ]; subctx.extra = ret_body + vtable.basesize; vtable.unmarshal(&subctx, ret_body); } -bool lib9p_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, uint16_t tag, void *body, +bool lib9p_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body, uint8_t *ret_bytes) { - /* Header */ struct _marshal_ctx subctx = { .ctx = ctx, .net_bytes = ret_bytes, - .net_offset = 7, + .net_offset = 0, }; - ret_bytes[4] = typ; - encode_u16le(tag, &ret_bytes[5]); - /* Body */ struct _vtable_msg vtable = _lib9p_vtables[ctx->version].msgs[typ]; - if (vtable.marshal(&subctx, body)) - return true; - - /* Header, again */ - encode_u32le(subctx.net_offset, ret_bytes); - - return false; + return vtable.marshal(&subctx, body); } |