summaryrefslogtreecommitdiff
path: root/lib9p/9p.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p/9p.c')
-rw-r--r--lib9p/9p.c39
1 files changed, 13 insertions, 26 deletions
diff --git a/lib9p/9p.c b/lib9p/9p.c
index 8633a44..0e71071 100644
--- a/lib9p/9p.c
+++ b/lib9p/9p.c
@@ -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);
}