diff options
author | Lizzy Fleckenstein <lizzy@vlhl.dev> | 2024-06-19 18:07:47 +0200 |
---|---|---|
committer | Lizzy Fleckenstein <lizzy@vlhl.dev> | 2024-06-19 18:07:55 +0200 |
commit | 49948b4cc0f73d02a8932c525690a35e8efb6ac5 (patch) | |
tree | 1ee33d5393046939a37fdef00b3484e87ff3ec6d /src/peer.c | |
parent | ead2881be92d33076c2104dbd75bad3561f26088 (diff) |
add client
Signed-off-by: Lizzy Fleckenstein <lizzy@vlhl.dev>
Diffstat (limited to 'src/peer.c')
-rw-r--r-- | src/peer.c | 164 |
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; -} |