diff options
Diffstat (limited to 'lib9p/srv.c')
-rw-r--r-- | lib9p/srv.c | 70 |
1 files changed, 30 insertions, 40 deletions
diff --git a/lib9p/srv.c b/lib9p/srv.c index 9a68a2b..039b4c2 100644 --- a/lib9p/srv.c +++ b/lib9p/srv.c @@ -16,8 +16,7 @@ struct lib9p_srvconn { cid_t reader; int fd; /* mutable */ - uint32_t max_msg_size; - enum lib9p_version version; + struct lib9p_ctx ctx; unsigned int refcount; }; @@ -26,6 +25,19 @@ struct lib9p_srvreq { uint8_t *msg; }; +static void marshal_error(struct lib9p_ctx *ctx, uint16_t tag, uint8_t *net) { + struct lib9p_msg_Rerror host = { + .ename = { + .len = strnlen(ctx->err_msg, CONFIG_9P_MAX_ERR_SIZE), + .utf8 = (uint8_t*)ctx->err_msg, + }, + .errno = ctx->err_num, + }; + lib9p_marshal(ctx, LIB9P_TYP_Rerror, tag, &host, net); +} + +void handle_message(struct lib9p_srvconn *conn, uint8_t *net); + COROUTINE lib9p_srv_read_cr(void *_srv) { uint8_t buf[CONFIG_9P_MAX_MSG_SIZE]; @@ -37,9 +49,11 @@ COROUTINE lib9p_srv_read_cr(void *_srv) { struct lib9p_srvconn conn = { .srv = srv, .reader = cr_getcid(), - - .max_msg_size = CONFIG_9P_MAX_MSG_SIZE, - .version = LIB9P_VER_UNINITIALIZED, + + .ctx = { + .version = LIB9P_VER_UNINITIALIZED, + .max_msg_size = CONFIG_9P_MAX_MSG_SIZE, + }, .refcount = 1, }; conn.fd = netio_accept(srv->sockfd); @@ -54,7 +68,7 @@ COROUTINE lib9p_srv_read_cr(void *_srv) { while (done < goal) { ssize_t r = netio_read(conn.fd, &buf[done], sizeof(buf)-done); if (r < 0) { - fprintf(stderr, "error: read: %m", -r); + fprintf(stderr, "error: read: %s", strerror(-r)); goto close; } else if (r == 0) { if (done != 0) @@ -69,16 +83,11 @@ COROUTINE lib9p_srv_read_cr(void *_srv) { fprintf(stderr, "error: T-message is impossibly small"); goto close; } - if (goal > conn.max_msg_size) { - struct lib9p_ctx ctx = { - .version = conn.version, - .max_msg_size = conn.max_msg_size, - }; - if (initialized) - lib9p_errorf(&ctx, LINUX_EMSGSIZE, "T-message larger than negotiated limit (%zu > %zu)", goal, conn.max_msg_size); - else - lib9p_errorf(&ctx, LINUX_EMSGSIZE, "T-message larger than server limit (%zu > %zu)", goal, conn.max_msg_size); - marshal_error(&ctx, buf); + if (goal > conn.ctx.max_msg_size) { + lib9p_errorf(&conn.ctx, LINUX_EMSGSIZE, "T-message larger than %s limit (%zu > %zu)", + conn.ctx.version ? "negotiated" : "server", goal, conn.ctx.max_msg_size); + uint16_t tag = decode_u16le(&buf[5]); + marshal_error(&conn.ctx, tag, buf); netio_write(conn.fd, buf, decode_u32le(buf)); continue; } @@ -86,7 +95,7 @@ COROUTINE lib9p_srv_read_cr(void *_srv) { while (done < goal) { ssize_t r = netio_read(conn.fd, &buf[done], sizeof(buf)-done); if (r < 0) { - fprintf(stderr, "error: read: %m", -r); + fprintf(stderr, "error: read: %s", strerror(-r)); goto close; } else if (r == 0) { fprintf(stderr, "error: read: unexpected EOF"); @@ -96,7 +105,7 @@ COROUTINE lib9p_srv_read_cr(void *_srv) { } /* Handle the message... */ - if (conn.version == LIB9P_VER_UNINITIALIZED) { + if (conn.ctx.version == LIB9P_VER_UNINITIALIZED) { /* ...synchronously if we haven't negotiated the protocol yet, ... */ handle_message(&conn, buf); } else { @@ -140,7 +149,7 @@ COROUTINE lib9p_srv_write_cr(void *_srv) { cr_end(); } -void handle_message(lib9p_srvconn *conn, uint8_t *net) { +void handle_message(struct lib9p_srvconn *conn, uint8_t *net) { uint8_t host[CONFIG_9P_MAX_MSG_SIZE]; struct lib9p_ctx ctx = { @@ -175,24 +184,5 @@ void handle_message(lib9p_srvconn *conn, uint8_t *net) { netio_write(req.conn->fd, net, decode_u32le(net)); } -static inline uint16_t min_u16(uint16_t a, b) { - return (a < b) ? a : b; -} - -/* We have special code for marshaling Rerror because we don't ever - * want to produce an error because the err_msg is too long for the - * `ctx->max_msg_size`! */ -void marshal_error(struct lib9p_ctx *ctx, uint16_t tag, uint8_t *net) { - struct lib9p_msg_Rerror host = { - .ename = { - .len = strnlen(ctx->err_msg, CONFIG_9P_MAX_ERR_SIZE), - .utf8 = ctx->err_msg, - }, - }; - if (host.ename.len + ctx->Rerror_overhead > ctx->max_msg_size) - host.ename.len = ctx->max_msg_size - overhead; - lib9p_marshal(ctx, tag, host, net); -} - -ERANGE for reply too large -EPROTONOSUPPORT for version errors +// EMSGSIZE for request too large +// EPROTONOSUPPORT for version errors |