Commit Diff


commit - 8884ce6e02f8f1ea0b15823c11c1e1bb7629523b
commit + 8850afbc91be6f71fa7f70886d9ba5af5b929560
blob - 91f2ae141880b4771d4eb12ef79677dd8f2ef080
blob + a6e75d2299d2c41f34d5c1b14e362742c30ab00a
--- kamid.h
+++ kamid.h
@@ -127,6 +127,66 @@ struct kd_auth_req {
 	char		hash[128+1];
 };
 
+/*
+ * 9p message header.
+ *
+ * The message itself is len bytes long (counting the whole header
+ * too.)
+ */
+struct np_msg_header {
+	uint32_t	len;
+	uint8_t		type;
+	uint16_t	tag;
+};
+
+/* useful constants */
+#define NOTAG		((uint16_t)~0U)
+#define NOFID		((uint32_t)~0U)
+#define NOUID		(-1)
+
+/* 9p message types */
+enum {
+	Tversion =	100,
+	Rversion,
+	Tauth =		102,
+	Rauth,
+	Tattach =	104,
+	Rattach,
+	Terror =	106,	/* illegal */
+	Rerror,
+	Tflush =	108,
+	Rflush,
+	Twalk =		110,
+	Rwalk,
+	Topen =		112,
+	Ropen,
+	Tcreate =	114,
+	Rcreate,
+	Tread =		116,
+	Rread,
+	Twrite =	118,
+	Rwrite,
+	Tclunk =	120,
+	Rclunk,
+	Tremove =	122,
+	Rremove,
+	Tstat =		124,
+	Rstat,
+	Twstat =	126,
+	Rwstat,
+	Tmax,
+
+	/*
+	 * plan9ports' include/fcall.h also has a
+	 *
+	 *	Topenfd = 98,
+	 *	Ropenfd,
+	 *
+	 * which it's not mentioned in the 9p "rfc" over at
+	 * 9p.cat-v.org.  Ignoring that for now.
+	 */
+};
+
 /* kamid.c */
 extern int verbose;
 int	main_imsg_compose_listener(int, int, uint32_t, const void *, uint16_t);
blob - 13c1cb43fb3b509b9e88dad55b3133a1a5b22535
blob + 1dcdc3e0f3bd120797390ab132321125fa10d833
--- listener.c
+++ listener.c
@@ -22,6 +22,7 @@
 
 #include <sys/socket.h>
 
+#include <endian.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <pwd.h>
@@ -350,8 +351,10 @@ listener_dispatch_main(int fd, short event, void *d)
 				log_info("got AUTH_DIR but client gone");
 				break;
 			}
+
 			listener_imsg_compose_client(client, IMSG_AUTH_DIR,
 			    0, imsg.data, IMSG_DATA_SIZE(imsg));
+
 			client->bev = bufferevent_new(client->fd,
 			    client_read, client_write, client_error,
 			    client);
@@ -369,12 +372,17 @@ listener_dispatch_main(int fd, short event, void *d)
 				    EV_WRITE, client_tls_writecb, client->bev);
 			}
 
-			/* TODO: adjust watermarks */
-                        bufferevent_setwatermark(client->bev, EV_WRITE, 1, 0);
-			bufferevent_setwatermark(client->bev, EV_READ,  1, 0);
-
+			/*
+			 * Read or write at least a header before
+			 * firing the callbacks.  High watermark of 0
+			 * to never stop reading/writing; probably to
+			 * be revisited.
+			 */
+			bufferevent_setwatermark(client->bev, EV_READ|EV_WRITE,
+			    sizeof(struct np_msg_header), 0);
 			bufferevent_enable(client->bev, EV_READ|EV_WRITE);
 			break;
+
 		default:
 			log_debug("%s: unexpected imsg %d", __func__,
 			    imsg.hdr.type);
@@ -661,19 +669,22 @@ client_read(struct bufferevent *bev, void *d)
 {
 	struct client	*client = d;
 	struct evbuffer	*src = EVBUFFER_INPUT(bev);
-	char		 buf[BUFSIZ];
-	size_t		 len;
-
-	if (!EVBUFFER_LENGTH(src))
-		return;
+	uint32_t	 len;
 
-	len = bufferevent_read(bev, buf, sizeof(buf));
-	if (len == 0) {
-		(*bev->errorcb)(bev, EVBUFFER_READ, bev->cbarg);
-		return;
-	}
+	for (;;) {
+		if (EVBUFFER_LENGTH(src) < 4)
+			return;
 
-	listener_imsg_compose_client(client, IMSG_BUF, client->id, buf, len);
+		memcpy(&len, EVBUFFER_DATA(src), sizeof(len));
+		len = le32toh(len);
+
+		if (len > EVBUFFER_LENGTH(src))
+			return;
+
+		listener_imsg_compose_client(client, IMSG_BUF, client->id,
+		    EVBUFFER_DATA(src), len);
+		evbuffer_drain(src, len);
+	}
 }
 
 static void