Skip to content

Instantly share code, notes, and snippets.

@milesrout
Created July 27, 2023 07:21
Show Gist options
  • Save milesrout/21ee27544a729e3f01881dbc8e3961a0 to your computer and use it in GitHub Desktop.
Save milesrout/21ee27544a729e3f01881dbc8e3961a0 to your computer and use it in GitHub Desktop.
static vlong
promptline(char const *prompt, char *buf, vlong size);
#include "example-keys.h"
static int
mcrypt_server_handler(vlong s1, vlong)
{
int s2 = len32_start(s1);
if (s2 < 0)
err(s2, "len32_start");
int s3 = mcrypt_listen(s2, server_kex_private, client_kex_public, 0);
if (s3 < 0)
err(s3, "mcrypt_listen");
int s4 = padme_start(s3, 0, 20, PADME_LENGTHPREFIX);
if (s4 < 0)
err(s4, "padme_start");
for (;;) {
char buffer[64] = {0};
int len = mrecv(s4, buffer, sizeof buffer, 0);
if (len < 0)
err(len, "mrecv");
if (len == 0)
break;
printf("Rcvd: %.*s\n", len, buffer);
int e = msend(s4, "ACK", 3, 0);
if (e < 0)
err(e, "msend");
printf("Sent: ACK\n");
}
warnx("Done");
return 0;
}
static int
mcrypt_server_fibre(vlong, vlong)
{
int e;
int s1 = tcp_start();
if (s1 < 0)
err(s1, "tcp_start");
e = tcp_bind(s1, "localhost:5557");
if (e < 0)
err(e, "tcp_bind");
e = tcp_listen(s1, 32);
if (e < 0)
err(e, "tcp_listen");
struct bundle b;
bundle_init(&b);
for (;;) {
struct sockaddr_storage addr;
socklen_t addrlen = sizeof addr;
int c1 = tcp_accept(s1, (struct sockaddr *)&addr, &addrlen);
if (c1 < 0)
break;
int e = bundle_go(&b, mcrypt_server_handler, c1, (vlong)&addr);
if (e < 0)
break;
}
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
e = bundle_finish(&b, &now);
if (e < 0)
err(e, "bundle_finish");
warnx("Timer expired");
return 0;
}
static int
mcrypt_client_fibre(vlong, vlong)
{
int e;
// Create a TCP socket and connect to a server
int s1 = tcp_start();
if (s1 < 0)
err(s1, "tcp_start");
e = tcp_connect(s1, "localhost:5557");
if (e < 0)
err(e, "tcp_connect");
// Length-prefixed message protocol
int s2 = len32_start(s1);
if (s2 < 0)
err(s2, "len32_start");
// Encrypted message protocol
int s3 = mcrypt_connect(s2, client_kex_private, server_kex_public, 0);
if (s3 < 0)
err(s3, "mcrypt_connect");
// Padded messages protocol
int s4 = padme_start(s3, 0, 20, PADME_LENGTHPREFIX);
if (s4 < 0)
err(s4, "padme_start");
char msg[81];
int len = promptline("> ", msg, sizeof msg);
if (len < 0)
err(len, "promptline");
while (len >= 0) {
// Send a message
e = msend(s4, msg, len, 0);
if (e < 0)
err(e, "msend");
printf("Sent: %.*s\n", len, msg);
if (!len)
break;
// Receive a message
char buffer[8] = {0};
int nbytes = mrecv(s4, buffer, sizeof buffer - 1, 0);
if (nbytes < 0)
err(nbytes, "mrecv");
printf("Rcvd: %.*s\n", nbytes, buffer);
len--;
}
warnx("Done");
return 0;
}
static int
run_fibre_test(int (*test)(vlong, vlong))
{
int e;
e = fibre_init();
if (e < 0)
err(e, "fibre_init");
e = fibre_go(test, 0, 0);
if (e < 0)
err(e, "fibre_go");
fibre_main();
return 0;
}
static vlong
promptline(char const *prompt, char *buf, vlong size)
{
printf("%s", prompt);
fflush(stdout);
if (!fgets(buf, size, stdin)) {
if (feof(stdin))
return -EPROTO;
return -EMSGSIZE;
}
vlong len = strlen(buf);
if (len == size - 1)
return -EMSGSIZE;
assert(len);
assert(buf[len] == '\0');
len--;
assert(buf[len] == '\n');
buf[len] = '\0';
return len;
}
typedef long long vlong;
// General bytestream-oriented functions
int bsend(int, void const *buf, vlong len, struct timespec *deadline);
int brecv(int, void *buf, vlong len, struct timespec *deadline);
int bsendl(int, struct iolist *start, struct iolist *end, struct timespec *deadline);
int brecvl(int, struct iolist *start, struct iolist *end, struct timespec *deadline);
// General message-oriented functions
int msend(int, void const *buf, vlong len, struct timespec *deadline);
vlong mrecv(int, void *buf, vlong len, struct timespec *deadline);
int msendl(int, struct iolist *start, struct iolist *end, struct timespec *deadline);
vlong mrecvl(int, struct iolist *start, struct iolist *end, struct timespec *deadline);
// Transmission control protocol (RFC 9293)
// Base bytestream protocol - no underlying protocol
int tcp_start(void);
int tcp_listen(int, int queue);
int tcp_bind (int, char const *);
int tcp_connect(int, char const *);
int tcp_bind_addr (int, struct sockaddr const *, socklen_t);
int tcp_connect_addr(int, struct sockaddr const *, socklen_t);
int tcp_accept(int, struct sockaddr *, socklen_t *);
int tcp_stop(int);
// User datagram protocol (RFC 768)
// Base message-based protocol - no underlying protocol
int udp_start(void);
int udp_bind (int, char const *);
int udp_connect(int, char const *);
int udp_bind_addr (int, struct sockaddr const *, socklen_t);
int udp_connect_addr(int, struct sockaddr const *, socklen_t);
int udp_sendto (int, void const *buf, vlong len, struct sockaddr const *, socklen_t, struct timespec *deadline);
vlong udp_recvfrom(int, void *buf, vlong len, struct sockaddr *, socklen_t *, struct timespec *deadline);
int udp_stop(int);
// CRLF-terminated messages protocol
// (Underlying protocol must be bytestream)
int crlf_start(int);
int crlf_stop(int);
// Length-prefixed messages protocol
// (Underlying protocol must be bytestream)
int len32_start(int);
int len32_stop(int);
// PADME-padded messages protocol
// (Underlying protocol must be message-based)
enum padme_options { PADME_PSEUDORANDOM=1, PADME_LENGTHPREFIX=2, };
int padme_start(int, vlong minsize, vlong overhead, int opts);
int padme_stop(int);
// Encrypted bytestream protocol
// (Underlying protocol must be bytestream)
int crypt_listen(int, unsigned char priv_key[64], unsigned char pub_key[32], struct timespec *deadline);
int crypt_connect(int, unsigned char priv_key[64], unsigned char pub_key[32], struct timespec *deadline);
int crypt_stop(int);
// Encrypted message protocol
// (The underlying protocol must be message-based, and must be reliable and ordered eg. CRLF-on-TCP or LEN32-on-TCP.)
int mcrypt_listen(int, uint8_t const priv_key[64], uint8_t const pub_key[32], struct timespec *deadline);
int mcrypt_connect(int, uint8_t const priv_key[64], uint8_t const pub_key[32], struct timespec *deadline);
int mcrypt_stop(int);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment