protoverse

A metaverse protocol
git clone git://jb55.com/protoverse
Log | Files | Refs | README | LICENSE

commit 15f98e34fe369beab4d471be7d0968701319f9e2
parent 2f1bf7afd55173ee3258bc781176a3ba5ee1eab2
Author: William Casarin <jb55@jb55.com>
Date:   Wed, 23 Sep 2020 13:53:26 -0700

sending data is working

Signed-off-by: William Casarin <jb55@jb55.com>

Diffstat:
Mclient.c | 7++++++-
Mcursor.c | 27++++++++++++++++++++++-----
Mcursor.h | 1+
Mio.c | 9++++-----
Mio.h | 7+++----
Mnet.c | 29++++++++++++++++++++---------
Mnet.h | 2+-
Mprotoverse.c | 3+--
Mserve.c | 59+++++++++++++++++++++++------------------------------------
9 files changed, 81 insertions(+), 63 deletions(-)

diff --git a/client.c b/client.c @@ -45,11 +45,16 @@ int protoverse_connect(const char *server_ip_str, int port) packet.data.chat.sender = 0xFFFFFF; send_packet(sockfd, &server_addr, &packet); + recv_packet(sockfd, &cursor, &server_addr, &packet); + print_packet(&packet); packet.type = PKT_FETCH_DATA; - packet.data.fetch.path = "/some/room.space"; + packet.data.fetch.path = "TAGS"; send_packet(sockfd, &server_addr, &packet); + recv_packet(sockfd, &cursor, &server_addr, &packet); + + print_packet(&packet); return 1; } diff --git a/cursor.c b/cursor.c @@ -50,6 +50,26 @@ int push_byte(struct cursor *cursor, u8 c) return 1; } +int pull_data_into_cursor(struct cursor *cursor, + struct cursor *dest, + unsigned char **data, + int len) +{ + int ok; + + if (dest->p + len >= dest->end) { + printf("not enough room in dest buffer\n"); + return 0; + } + + ok = pull_data(cursor, dest->p, len); + if (!ok) return 0; + + *data = dest->p; + dest->p += len; + + return 1; +} int pull_data(struct cursor *cursor, u8 *data, int len) { @@ -122,7 +142,7 @@ int pull_varint(struct cursor *cursor, int *n) /* is_last */ if ((b & 0x80) == 0) { - return 1; + return i+1; } if (i == 4) return 0; @@ -184,12 +204,9 @@ int pull_prefixed_str(struct cursor *cursor, struct cursor *dest_buf, const char return 0; } - ok = pull_data(cursor, dest_buf->p, len); + ok = pull_data_into_cursor(cursor, dest_buf, (unsigned char**)str, len); if (!ok) return 0; - *str = (char*)dest_buf->p; - dest_buf->p += len; - ok = push_byte(dest_buf, 0); return 1; diff --git a/cursor.h b/cursor.h @@ -21,6 +21,7 @@ int push_varint(struct cursor *cursor, int i); int push_data(struct cursor *cursor, unsigned char *data, int len); int push_byte(struct cursor *cursor, unsigned char c); +int pull_data_into_cursor(struct cursor *cursor, struct cursor *dest, unsigned char **data, int len); int pull_data(struct cursor *cursor, unsigned char *data, int len); int pull_byte(struct cursor *cursor, unsigned char *c); int pull_int(struct cursor *cursor, int *i); diff --git a/io.c b/io.c @@ -3,7 +3,7 @@ #include <string.h> -int read_fd(FILE *fd, unsigned char *buf, size_t buflen, size_t *written) +int read_fd(FILE *fd, unsigned char *buf, int buflen, int *written) { unsigned char *p = buf; int len = 0; @@ -21,8 +21,7 @@ int read_fd(FILE *fd, unsigned char *buf, size_t buflen, size_t *written) } -int read_file(const char *filename, unsigned char *buf, size_t buflen, - size_t *written) +int read_file(const char *filename, unsigned char *buf, int buflen, int *written) { FILE *file = NULL; int ok; @@ -40,8 +39,8 @@ int read_file(const char *filename, unsigned char *buf, size_t buflen, } -int read_file_or_stdin(const char *filename, unsigned char *buf, - size_t buflen, size_t *written) +int read_file_or_stdin(const char *filename, unsigned char *buf, int buflen, + int *written) { if (filename == NULL) { return read_fd(stdin, buf, buflen, written); diff --git a/io.h b/io.h @@ -4,10 +4,9 @@ #include <stdio.h> -int read_fd(FILE *fd, unsigned char *buf, size_t buflen, size_t *written); -int read_file(const char *filename, unsigned char *buf, size_t buflen, size_t *written); -int read_file_or_stdin(const char *filename, unsigned char *buf, - size_t buflen, size_t *written); +int read_fd(FILE *fd, unsigned char *buf, int buflen, int *written); +int read_file(const char *filename, unsigned char *buf, int buflen, int *written); +int read_file_or_stdin(const char *filename, unsigned char *buf, int buflen, int *written); #endif /* PROTOVERSE_IO_H */ diff --git a/net.c b/net.c @@ -5,6 +5,9 @@ #include "varint.h" #include <sys/types.h> +#include <assert.h> +#include <error.h> +#include <errno.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> @@ -28,7 +31,7 @@ static int pull_fetch_response_packet(struct cursor *c, struct cursor *buf, if (!ok) return 0; ok = pull_varint(c, &resp->data_len); if (!ok) return 0; - return pull_data(c, resp->data, resp->data_len); + return pull_data_into_cursor(c, buf, &resp->data, resp->data_len); } static int push_fetch_packet(struct cursor *c, struct fetch_packet *fetch) @@ -61,6 +64,7 @@ static int pull_fetch_packet(struct cursor *c, struct cursor *buf, struct fetch_ return pull_prefixed_str(c, buf, &fetch->path); } + int send_packet(int sockfd, struct sockaddr_in *to_addr, struct packet *packet) { static unsigned char buf[0xFFFF]; @@ -69,12 +73,10 @@ int send_packet(int sockfd, struct sockaddr_in *to_addr, struct packet *packet) len = push_packet(buf, sizeof(buf), packet); if (!len) return 0; - ok = sendto(sockfd, buf, len, 0, - (struct sockaddr*)to_addr, - sizeof(struct sockaddr_in)); + ok = sendto(sockfd, buf, len, 0, (struct sockaddr*)to_addr, sizeof(*to_addr)); if (ok != len) { - printf("sendto: sent %d != packet_len %d\n", ok, len); + printf("sendto: sent %d != packet_len %d - %s\n", ok, len, strerror(errno)); return 0; } @@ -85,12 +87,14 @@ int recv_packet(int sockfd, struct cursor *buf, struct sockaddr_in *from, struct { static unsigned char tmp[0xFFFF]; struct cursor tmp_cursor; - socklen_t size; + socklen_t size = sizeof(*from); + int bytes; - recvfrom(sockfd, tmp, sizeof(tmp), 0, (struct sockaddr*)from, &size); + bytes = recvfrom(sockfd, tmp, sizeof(tmp), 0, (struct sockaddr*)from, &size); + assert(size == sizeof(*from)); make_cursor(tmp, tmp + sizeof(tmp), &tmp_cursor); - return pull_packet(&tmp_cursor, buf, packet); + return pull_packet(&tmp_cursor, buf, packet, bytes); } static int push_envelope(struct cursor *cursor, enum packet_type type, int len) @@ -189,13 +193,20 @@ static int pull_packet_data(struct cursor *c, struct cursor *buf, return 0; } -int pull_packet(struct cursor *c, struct cursor *buf, struct packet *packet) +int pull_packet(struct cursor *c, struct cursor *buf, struct packet *packet, + int received_bytes) { int ok, env_size, len, capacity_left; env_size = pull_envelope(c, &packet->type, &len); if (!env_size) return 0; + if (len + env_size != received_bytes) { + printf("invalid packet size. expected %d, got %d\n", len+env_size, + received_bytes); + return 0; + } + capacity_left = cursor_remaining_capacity(c) - 1; if (len > capacity_left) { printf("sanity: packet larger (%d) than remaining buffer size: %d", len, capacity_left); diff --git a/net.h b/net.h @@ -43,7 +43,7 @@ int send_packet(int fd, struct sockaddr_in *to_addr, struct packet *packet); int recv_packet(int sockfd, struct cursor *buf, struct sockaddr_in *from, struct packet *packet); int push_packet(unsigned char *buf, int bufsize, struct packet *packet); -int pull_packet(struct cursor *c, struct cursor *buf, struct packet *packet); +int pull_packet(struct cursor *c, struct cursor *buf, struct packet *packet, int received_bytes); int packet_eq(struct packet *a, struct packet *b); void print_packet(struct packet *packet); diff --git a/protoverse.c b/protoverse.c @@ -66,8 +66,7 @@ static int parse_file(struct parser *parser, const char *filename, u16 *root) struct cursor attributes; struct cursor cells; - size_t count; - int ok; + int count, ok; parser->tokens = &tokens; parser->attributes = &attributes; diff --git a/serve.c b/serve.c @@ -7,6 +7,7 @@ #include <string.h> #include <errno.h> #include <assert.h> +#include <stdlib.h> #include "serve.h" #include "net.h" @@ -25,37 +26,16 @@ struct file_cache { static int load_data(struct cursor *buf, const char *path, int *data_len, unsigned char **data) { - /* TODO: better file cache */ - static struct file_cache file_cache[MAX_CACHED_FILES] = {0}; - static int cached_files = 0; - struct file_cache *cached_file; - int i, ok; - size_t written; - - for (i = 0; i < cached_files; i++) { - if (!strcmp(path, file_cache[i].path)) { - *data_len = file_cache[i].data_len; - *data = file_cache[i].dat; - return 1; - } - } + int ok; - ok = read_file(path, buf->p, buf->end - buf->p, &written); + ok = read_file(path, buf->p, buf->end - buf->p, data_len); if (!ok) return 0; - assert(written <= (size_t)(buf->end - buf->p)); + assert(*data_len <= buf->end - buf->p); *data = buf->p; - buf->p += written; - - if (cached_files + 1 > MAX_CACHED_FILES) - return 1; - - cached_file = &file_cache[cached_files++]; - cached_file->path = path; - cached_file->data_len = written; - cached_file->dat = buf->p - written; + buf->p += *data_len; return 1; } @@ -70,6 +50,8 @@ static int make_fetch_response(struct cursor *buf, ok = load_data(buf, path, &data_len, &response->data.fetch_response.data); + /* printf("load_data %d ok %d\n", data_len, ok); */ + if (!ok) return 0; response->type = PKT_FETCH_DATA_RESPONSE; @@ -90,13 +72,12 @@ static int handle_packet(int sockfd, print_packet(packet); switch (packet->type) { case PKT_CHAT: - return 0; + return send_packet(sockfd, from, packet); case PKT_FETCH_DATA: ok = make_fetch_response(buf, &response, packet->data.fetch.path); if (!ok) return 0; return send_packet(sockfd, from, &response); - case PKT_FETCH_DATA_RESPONSE: printf("todo: handle fetch response\n"); return 0; @@ -109,18 +90,20 @@ static int handle_packet(int sockfd, int protoverse_serve(struct protoverse_server *server) { - static unsigned char buf_[0xFFFF]; + #define FILEBUF_SIZE 31457280 + static unsigned char *buf_; struct in_addr my_addr; struct sockaddr_in bind_addr; struct sockaddr_in from; struct packet packet; struct cursor buf; - socklen_t from_addr_len; + /* socklen_t from_addr_len; */ int err, ok, fd; - make_cursor(buf_, buf_ + sizeof(buf_), &buf); + buf_ = malloc(FILEBUF_SIZE); + make_cursor(buf_, buf_ + FILEBUF_SIZE, &buf); if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { printf("socket creation failed: %s\n", strerror(errno)); @@ -136,8 +119,7 @@ int protoverse_serve(struct protoverse_server *server) bind_addr.sin_port = server->port == 0 || server->port == -1 ? 1988 : server->port; bind_addr.sin_addr = my_addr; - err = bind(fd, (struct sockaddr*)&bind_addr, - sizeof(bind_addr)) == -1; + err = bind(fd, (struct sockaddr*)&bind_addr, sizeof(bind_addr)) == -1; if (err) { printf("bind failed: %s\n", strerror(errno)); @@ -146,14 +128,19 @@ int protoverse_serve(struct protoverse_server *server) while (1) { ok = recv_packet(fd, &buf, &from, &packet); - assert(sizeof(from) == from_addr_len); if (!ok) { printf("malformed packet\n"); continue; } - handle_packet(fd, &buf, &from, &packet); - } -} + ok = handle_packet(fd, &buf, &from, &packet); + if (!ok) { + printf("handle packet failed for "); + print_packet(&packet); + } + buf.p = buf.start; + } + free(buf_); +}