protoverse

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

commit 1dfd648a8a904ec313daf0a6a9ff4c591db281c8
parent f87b7718b8506a257c3518319e89ebd06367ee5c
Author: William Casarin <jb55@jb55.com>
Date:   Sun,  5 Jul 2020 21:43:25 -0700

client/server

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

Diffstat:
MMakefile | 2+-
Aclient.c | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aclient.h | 7+++++++
Aprotocol.h | 1+
Mprotoverse.c | 51++++++++++++++++++++++++++++++++++++++++++---------
Aserve.c | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aserve.h | 7+++++++
7 files changed, 167 insertions(+), 10 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,7 +1,7 @@ CFLAGS = -Wno-error=unused-function -O1 -g -std=c89 -Wall -Wextra -Werror -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations -Wdeclaration-after-statement -OBJS = io.o parse.o cursor.o describe.o +OBJS = io.o parse.o cursor.o describe.o serve.o client.o protoverse: protoverse.c $(OBJS) $(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@ diff --git a/client.c b/client.c @@ -0,0 +1,54 @@ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include "client.h" + +int inet_aton(const char *cp, struct in_addr *inp); + +int protoverse_connect(const char *server_ip_str, int port) +{ + int sockfd; + struct in_addr server_in_addr; + struct sockaddr_in server_addr; + static char buf[2048]; + ssize_t sent; + const char msg[] = "hello, world"; + + if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + printf("socket creation failed: %s\n", strerror(errno)); + return 0; + } + + if (inet_aton(server_ip_str, &server_in_addr) == 0) { + printf("could not parse server ip: %s\n", strerror(errno)); + return 0; + } + + server_addr.sin_family = AF_INET; + server_addr.sin_port = port == 0 || port == -1 ? 1988 : port; + server_addr.sin_addr = server_in_addr; + + strncpy(buf, msg, sizeof(buf)); + + printf("sending '%s' to %s\n", msg, server_ip_str); + sent = sendto(sockfd, buf, sizeof(msg), MSG_CONFIRM, + (struct sockaddr*)&server_addr, + sizeof(server_addr)); + + printf("does this work?\n"); + + if (sent != sizeof(msg)) { + printf("expected to send %ld, sent %ld instead\n", + sizeof(msg), sent); + exit(1); + } + + return 1; +} diff --git a/client.h b/client.h @@ -0,0 +1,7 @@ + +#ifndef PROTOVERSE_CLIENT_H +#define PROTOVERSE_CLIENT_H + +int protoverse_connect(const char *server_ip_str, int port); + +#endif /* PROTOVERSE_CLIENT_H */ diff --git a/protocol.h b/protocol.h @@ -0,0 +1 @@ + diff --git a/protoverse.c b/protoverse.c @@ -2,8 +2,13 @@ #include "io.h" #include "parse.h" #include "describe.h" +#include "serve.h" +#include "client.h" #include <assert.h> +#include <string.h> + +#define streq(a, b) strcmp(a,b) == 0 static void print_all_cells(struct parser *parser) { @@ -108,28 +113,56 @@ static int describe(struct parser *parser, u16 root_cell) make_cursor((u8*)strbuf, (u8*)strbuf + sizeof(strbuf), &strs); - describe_cells(cell, parser, &strs, 2, 0); + describe_cells(cell, parser, &strs, 10, 0); printf("\n\ndescription\n-----------\n\n%s\n", strbuf); return 1; } +static int usage(void) +{ + printf("usage: protoverse <command> [args]\n\n"); + printf(" COMMANDS\n\n"); + printf(" parse file.space\n"); + printf(" serve file.space\n"); + printf(" client\n"); + + return 1; +} + int main(int argc, const char *argv[]) { const char *space; + const char *cmd; struct parser parser; u16 root; int ok; - space = argc == 2 ? argv[1] : "satoshis-citadel.space"; - - ok = parse_file(&parser, space, &root); - if (!ok) return 1; - - print_cell_tree(&parser, root, 0); - - describe(&parser, root); + if (argc < 2) + return usage(); + + cmd = argv[1]; + + if (streq(cmd, "parse")) { + if (argc != 3) + return usage(); + space = argv[2]; + ok = parse_file(&parser, space, &root); + if (!ok) return 1; + + print_cell_tree(&parser, root, 0); + + describe(&parser, root); + } else if (streq(cmd, "serve")) { + if (argc != 3) + return usage(); + space = argv[2]; + printf("serving protoverse on port 1988...\n"); + protoverse_serve("127.0.0.1", 1988); + } else if (streq(cmd, "client")) { + protoverse_connect("127.0.0.1", 1988); + } return 0; } diff --git a/serve.c b/serve.c @@ -0,0 +1,55 @@ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> + +#include "serve.h" + +int inet_aton(const char *cp, struct in_addr *inp); + +int protoverse_serve(const char *bind_addr_str, int port) +{ + int fd; + struct in_addr my_addr; + struct sockaddr_in bind_addr; + struct sockaddr addr; + socklen_t addrlen; + ssize_t recv_len; + static char buf[1024]; + int err; + + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + printf("socket creation failed: %s\n", strerror(errno)); + return 0; + } + + if (inet_aton(bind_addr_str, &my_addr) == 0) { + printf("inet_aton failed: %s\n", strerror(errno)); + return 0; + } + + bind_addr.sin_family = AF_INET; + bind_addr.sin_port = port == 0 || port == -1 ? 1988 : port; + bind_addr.sin_addr = my_addr; + + err = bind(fd, (struct sockaddr*)&bind_addr, + sizeof(bind_addr)) == -1; + + if (err) { + printf("bind failed: %s\n", strerror(errno)); + return 0; + } + + while (1) { + recv_len = recvfrom(fd, buf, sizeof(buf), 0, &addr, + &addrlen); + + printf("got '%.*s'\n", (int)recv_len, buf); + } +} + + diff --git a/serve.h b/serve.h @@ -0,0 +1,7 @@ + +#ifndef PROTOVERSE_SERVE_H +#define PROTOVERSE_SERVE_H + +int protoverse_serve(const char *bind, int port); + +#endif