diff options
Diffstat (limited to 'net9p.c')
-rw-r--r-- | net9p.c | 226 |
1 files changed, 30 insertions, 196 deletions
@@ -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(); } |