summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net9p.c226
-rw-r--r--net9p.h3
-rw-r--r--netio.h4
-rw-r--r--netio_posix.c4
-rw-r--r--srv9p.c10
5 files changed, 43 insertions, 204 deletions
diff --git a/net9p.c b/net9p.c
index 8890586..f7c8195 100644
--- a/net9p.c
+++ b/net9p.c
@@ -1,210 +1,44 @@
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <error.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <endian.h>
-
#include "net9p.h"
+#include "net9p_defs.h"
+#include "netio.h"
-/* "T" messages are client->server requests, and "R" messages are
- * server->client responses. I do not know what the Plan 9 designers
- * intended "T" and "R" to stand for.
- */
-enum v9fs_msg_type {
- /* "9P2000" base protocol
- * https://ericvh.github.io/9p-rfc/rfc9p2000.html
- * https://github.com/ericvh/9p-rfc/blob/master/9p2000.xml
- *
- * But due to incompleteness, the Plan 9 manual section-5 and
- * the Plan 9 headers (particularly fcall.h) are a better
- * references.
- */
- V9FS_Tversion = 100, /* "412" "4s" */
- V9FS_Rversion = 101, /* "412" "4s" */
- V9FS_Tauth = 102, /* "412" "4ss" */
- V9FS_Rauth = 103, /* "412" "TODO" */
- V9FS_Tattach = 104, /* "412" "TODO" */
- V9FS_Rattach = 105, /* "412" "TODO" */
- /*V9FS_Terror = 106, /* There is no Terror request, only Rerror responses */
- V9FS_Rerror = 107, /* "412" "TODO" */
- V9FS_Tflush = 108, /* "412" "TODO" */
- V9FS_Rflush = 109, /* "412" "TODO" */
- V9FS_Twalk = 110, /* "412" "TODO" */
- V9FS_Rwalk = 111, /* "412" "TODO" */
- V9FS_Topen = 112, /* "412" "TODO" */
- V9FS_Ropen = 113, /* "412" "TODO" */
- V9FS_Tcreate = 114, /* "412" "TODO" */
- V9FS_Rcreate = 115, /* "412" "TODO" */
- V9FS_Tread = 116, /* "412" "TODO" */
- V9FS_Rread = 117, /* "412" "TODO" */
- V9FS_Twrite = 118, /* "412" "TODO" */
- V9FS_Rwrite = 119, /* "412" "TODO" */
- V9FS_Tclunk = 120, /* "412" "TODO" */
- V9FS_Rclunk = 121, /* "412" "TODO" */
- V9FS_Tremove = 122, /* "412" "TODO" */
- V9FS_Rremove = 123, /* "412" "TODO" */
- V9FS_Tstat = 124, /* "412" "TODO" */
- V9FS_Rstat = 125, /* "412" "TODO" */
- V9FS_Twstat = 126, /* "412" "TODO" */
- V9FS_Rwstat = 127, /* "412" "TODO" */
-
- /* "9P2000.u" Unix extension
- * https://ericvh.github.io/9p-rfc/rfc9p2000.u.html
- * https://github.com/ericvh/9p-rfc/blob/master/9p2000.u.xml
- */
-
- /* "9P2000.L" Linux extension
- * https://github.com/ericvh/9p-rfc/blob/master/9p2000.L.xml
- */
- V9FS_TLERROR = 6,
- V9FS_RLERROR,
- V9FS_TSTATFS = 8,
- V9FS_RSTATFS,
- V9FS_TLOPEN = 12,
- V9FS_RLOPEN,
- V9FS_TLCREATE = 14,
- V9FS_RLCREATE,
- V9FS_TSYMLINK = 16,
- V9FS_RSYMLINK,
- V9FS_TMKNOD = 18,
- V9FS_RMKNOD,
- V9FS_TRENAME = 20,
- V9FS_RRENAME,
- V9FS_TREADLINK = 22,
- V9FS_RREADLINK,
- V9FS_TGETATTR = 24,
- V9FS_RGETATTR,
- V9FS_TSETATTR = 26,
- V9FS_RSETATTR,
- V9FS_TXATTRWALK = 30,
- V9FS_RXATTRWALK,
- V9FS_TXATTRCREATE = 32,
- V9FS_RXATTRCREATE,
- V9FS_TREADDIR = 40,
- V9FS_RREADDIR,
- V9FS_TFSYNC = 50,
- V9FS_RFSYNC,
- V9FS_TLOCK = 52,
- V9FS_RLOCK,
- V9FS_TGETLOCK = 54,
- V9FS_RGETLOCK,
- V9FS_TLINK = 70,
- V9FS_RLINK,
- V9FS_TMKDIR = 72,
- V9FS_RMKDIR,
- V9FS_TRENAMEAT = 74,
- V9FS_RRENAMEAT,
- V9FS_TUNLINKAT = 76,
- V9FS_RUNLINKAT,
-};
-
-/* 1 - u8
- * 2 - u16le
- * 4 - u32le
- * 8 - u16le
- * d - data (u32le `n`, then `n` bytes of data)
- * s - string (u16le `n`, then `n` bytes of UTF-8)
- * q - qid (13 bytes, idk)
- */
-
-static const char const *msgfmt[255] = {
- /* All messages start with a "size[4] type[1] tag[2]"
- * prefix; that is not included in this table. */
-
- [V9FS_Tversion] = "max_msg_size[4] s",
- [V9FS_Rversion] = "4s",
-
- [V9FS_Tauth] = "4ss",
- [V9FS_Rauth] = "q",
-
- [V9FS_Rerror] = "s",
-
- [V9FS_Tflush] = "2",
- [V9FS_Rflush] = "",
-
- [V9FS_Tattach] = "44ss",
- [V9FS_Rattach] = "q",
-
- [V9FS_Twalk] = "TODO",
- [V9FS_Rwalk] = "TODO",
-
- [V9FS_Topen] = "41",
- [V9FS_Ropen] = "q4",
-
- [V9FS_Tcreate] = "4s41",
- [V9FS_Rcreate] = "q4",
-
- [V9FS_Tread] = "484",
- [V9FS_Rread] = "d",
-
- [V9FS_Twrite] = "48d",
- [V9FS_Rwrite] = "4",
-
- [V9FS_Tclunk] = "4",
- [V9FS_Rclunk] = "",
-
- [V9FS_Tremove] = "4",
- [V9FS_Rremove] = "",
-
- [V9FS_Tstat] = "4",
- [V9FS_Rstat] = "TODO",
-
- [V9FS_Twstat] = "TODO",
- [V9FS_Rwstat] = "",
-};
+#define MAX_MSG_SIZE 1024
+int read_msg(int conn, uint16_t *out_tag, void **out_body) {
+ uint8_t buf[MAX_MSG_SIZE];
+ size_t todo = 7, done = 0;
+ while (done < todo) {
+ ssize_t r = netio_read(conn, buf, 7);
+ if (r < 0)
+ return r;
+ done += r;
+ }
+ todo = docode_u32le(buf);
+ if (todo < 7)
+ return -EINVAL;
+ while (done < todo) {
+ ssize_t r = netio_read(conn, buf, 7);
+ if (r < 0)
+ return r;
+ done += r;
+ }
+ return v9fs_unmarshal_msg(buf, out_tag, out_body);
+}
-void net9p_listen_cr(void *_arg) {
- (void)_arg;
+void net9p_cr(void *_arg) {
+ int sock = *((int *)_arg);
cr_begin();
- union {
- struct sockaddr_in in;
- struct sockaddr gen;
- } addr;
- memset(&addr, 0, sizeof addr);
- addr.in.sin_family = AF_INET;
- addr.in.sin_port = htons(9001);
-
- int fd = socket(AF_INET, SOCK_STREAM|SOCK_NONBLOCK, 0);
- if (fd < 0)
- error(1, errno, "socket");
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)) < 0)
- error(1, errno, "setsockopt");
- if (bind(fd, &addr.gen, sizeof addr) < 0)
- error(1, errno, "bind");
- if (listen(fd, 5) < 0)
- error(1, errno, "listen");
-
for (;;) {
- int conn = accept(fd, NULL, NULL);
+ int conn = netio_accept(sock);
if (conn < 0) {
- if (errno == EAGAIN || errno == EWOULDBLOCK) {
- cr_yield();
- continue;
- }
- error(1, errno, "accept");
+ error(0, -conn, "netio_accept");
+ continue;
}
- if (!coroutine_add(net9p_worker_cr, &conn))
- error(1, 0, "coroutine_add(net9p_worker_cr, &%d)", conn);
- }
-
- cr_end();
-}
-void net9p_worker_cr(void *_arg) {
- int fd = *((int *)_arg);
- cr_begin();
-
- close(fd);
+
+ }
cr_end();
}
diff --git a/net9p.h b/net9p.h
index 7b5f9f4..f28a525 100644
--- a/net9p.h
+++ b/net9p.h
@@ -3,7 +3,6 @@
#include "coroutine.h"
-COROUTINE net9p_listen_cr(void *);
-COROUTINE net9p_worker_cr(void *);
+COROUTINE net9p_cr(void *);
#endif /* _NET9P_H_ */
diff --git a/netio.h b/netio.h
index 53233cb..8d9fa50 100644
--- a/netio.h
+++ b/netio.h
@@ -6,8 +6,8 @@
int netio_listen(uint16_t port);
int netio_accept(int sock);
-int netio_read(int conn, void *buf, size_t count);
-int netio_write(int conn, void *buf, size_t count);
+size_t netio_read(int conn, void *buf, size_t count);
+size_t netio_write(int conn, void *buf, size_t count);
int netio_close(int conn, bool rd, bool wr);
#endif /* _NETIO_H_ */
diff --git a/netio_posix.c b/netio_posix.c
index 57c46df..3730f98 100644
--- a/netio_posix.c
+++ b/netio_posix.c
@@ -156,7 +156,7 @@ int netio_accept(int sock) {
#endif
}
-int netio_read(int conn, void *buf, size_t count) {
+size_t netio_read(int conn, void *buf, size_t count) {
int r;
struct aiocb ctl_block = {
.aio_fildes = conn,
@@ -179,7 +179,7 @@ int netio_read(int conn, void *buf, size_t count) {
return r ? -abs(r) : aio_return(&ctl_block);
}
-int netio_write(int conn, void *buf, size_t count) {
+size_t netio_write(int conn, void *buf, size_t count) {
int r;
struct aiocb ctl_block = {
.aio_fildes = conn,
diff --git a/srv9p.c b/srv9p.c
index 489b33e..c7d1dde 100644
--- a/srv9p.c
+++ b/srv9p.c
@@ -1,11 +1,17 @@
#include <error.h>
#include <stdio.h>
+
#include "coroutine.h"
#include "net9p.h"
int main() {
- if (!coroutine_add(net9p_listen_cr, NULL))
- error(1, 0, "coroutine_add(net9p_listen_cr, NULL)");
+ int sock = netio_listen(9000);
+ if (sock < 0)
+ error(1, -sock, "netio_listen");
+
+ for (int i = 0; i < 8; i++)
+ if (!coroutine_add(net9p_cr, NULL))
+ error(1, 0, "coroutine_add(net9p_cr, NULL)");
coroutine_main();
return 1;