summaryrefslogtreecommitdiff
path: root/lib9p/srv.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p/srv.c')
-rw-r--r--lib9p/srv.c70
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