summaryrefslogtreecommitdiff
path: root/src/peer.c
diff options
context:
space:
mode:
authorLizzy Fleckenstein <lizzy@vlhl.dev>2024-06-19 18:07:47 +0200
committerLizzy Fleckenstein <lizzy@vlhl.dev>2024-06-19 18:07:55 +0200
commit49948b4cc0f73d02a8932c525690a35e8efb6ac5 (patch)
tree1ee33d5393046939a37fdef00b3484e87ff3ec6d /src/peer.c
parentead2881be92d33076c2104dbd75bad3561f26088 (diff)
add client
Signed-off-by: Lizzy Fleckenstein <lizzy@vlhl.dev>
Diffstat (limited to 'src/peer.c')
-rw-r--r--src/peer.c164
1 files changed, 0 insertions, 164 deletions
diff --git a/src/peer.c b/src/peer.c
deleted file mode 100644
index f984aec..0000000
--- a/src/peer.c
+++ /dev/null
@@ -1,164 +0,0 @@
-// SPDX-FileCopyrightText: 2024 Lizzy Fleckenstein <lizzy@vlhl.dev>
-//
-// SPDX-License-Identifier: AGPL-3.0-or-later
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <poll.h>
-#include <errno.h>
-#include "peer.h"
-
-void peer_init(peer *p, int socket)
-{
- p->socket = socket;
- p->disco = false;
-
- p->in.header = true;
- p->in.len = 0;
- p->in.promised = 0;
- p->in.buffer = malloc(PEER_INBUFFER_SIZE);
-
- p->out.cursor = 0;
- p->out.avail = 0;
- p->out.buffer = malloc(PEER_OUTBUFFER_SIZE);
-}
-
-void peer_free(peer *p)
-{
- close(p->socket);
- free(p->in.buffer);
- free(p->out.buffer);
-}
-
-// in
-
-static void next_in(peer *p, bool header, size_t len)
-{
- p->in.header = header;
- p->in.len = 0;
- p->in.buffer = malloc(p->in.promised = len);
-}
-
-static bool peer_in_ready(peer *p)
-{
- ssize_t got = read(p->socket, p->in.buffer + p->in.len, p->in.promised - p->in.len);
- if (got < 0) {
- switch (errno) {
- case ECONNRESET:
- p->disco = true;
- return true;
- case EINTR:
- return peer_in_ready(p); // retry
- default:
- perror("read");
- return false;
- }
- }
-
- p->in.len += got;
- if (p->in.len == p->in.promised && p->in.len != 0) {
- if (!p->in.header)
- return true;
-
- size_t len = *(pkt_header *) p->in.buffer;
- if (len > PEER_INBUFFER_SIZE)
- // TODO: figure out what to do if packet too large (disconnect?)
- next_in(p, true, sizeof(pkt_header));
- else
- next_in(p, false, len);
- }
-
- return false;
-}
-
-// out
-
-static void send_raw(peer *p, void *data, size_t len)
-{
- memcpy(p->out.buffer + p->out.cursor + p->out.avail, data, len);
- p->out.avail += len;
-}
-
-static bool out_space(peer *p, size_t len)
-{
- if (len + p->out.avail > PEER_OUTBUFFER_SIZE)
- return false;
-
- if (p->out.cursor + p->out.avail + len > PEER_OUTBUFFER_SIZE) {
- memmove(p->out.buffer, p->out.buffer + p->out.cursor, p->out.avail);
- p->out.cursor = 0;
- }
-
- return true;
-}
-
-bool peer_send(peer *p, void *data, size_t len)
-{
- if (len > PEER_INBUFFER_SIZE)
- return false;
-
- pkt_header hdr = (pkt_header) len;
-
- if (!out_space(p, sizeof hdr + len))
- return false;
-
- send_raw(p, &hdr, sizeof hdr);
- send_raw(p, data, len);
-
- return true;
-}
-
-static bool peer_out_ready(peer *p)
-{
- ssize_t written = write(p->socket, p->out.buffer + p->out.cursor, p->out.avail);
- if (written < 0) {
- switch (errno) {
- case ECONNRESET:
- p->disco = true;
- return true;
- case EINTR:
- return peer_out_ready(p);
- default:
- perror("write");
- return false;
- }
- }
-
- p->out.avail -= written;
- if (p->out.avail == 0)
- p->out.cursor = 0;
-
- return false;
-}
-
-// poll
-
-struct pollfd peer_prepare(peer *p)
-{
- struct pollfd pfd = {0};
-
- pfd.fd = p->socket;
- if (p->in.len == p->in.promised)
- next_in(p, true, sizeof(pkt_header));
-
- pfd.events = POLLIN | (p->out.avail ? POLLOUT : 0);
-
- return pfd;
-}
-
-bool peer_ready(peer *p, struct pollfd pfd)
-{
- bool x = false;
-
- if (pfd.revents & (POLLHUP | POLLERR))
- p->disco = true;
-
- if (pfd.revents & POLLIN)
- x = x || peer_in_ready(p);
- if (pfd.revents & POLLOUT)
- x = x || peer_out_ready(p);
-
- return x;
-}