/* Copyright (C) 2010 Tony Garnock-Jones. All rights reserved. */ #include #include #include #include #include #include #include #include #include #include #include #include #include typedef unsigned char u_char; #include #include "cmsg_private.h" #include "harness.h" #include "relay.h" #include "net.h" struct boot_args { struct sockaddr_in peername; int fd; }; static void relay_main(struct boot_args *args) { IOHandle *h = new_iohandle(args->fd); { char name[256]; endpoint_name(&args->peername, (cmsg_bytes_t) { .bytes = name, .len = sizeof(name) }); info("Accepted connection from %s on fd %d\n", name, args->fd); } free(args); iohandle_write(h, cmsg_cstring_bytes("Hi\n")); ICHECK(iohandle_flush(h), "iohandle_flush 1"); nap(1000); iohandle_write(h, cmsg_cstring_bytes("Proceed\n")); iohandle_settimeout(h, 3, 0); while (1) { cmsg_bytes_t buf = iohandle_readwait(h, 1); if (buf.len == 0) { switch (h->error_kind) { case EVBUFFER_TIMEOUT: info("Timeout\n"); iohandle_clear_error(h); iohandle_write(h, cmsg_cstring_bytes("Timed out\n")); break; default: info("Error! 0x%04X\n", h->error_kind); break; } break; } else { info("Read %d: %.*s\n", buf.len, buf.len, buf.bytes); iohandle_drain(h, buf.len); } iohandle_write(h, cmsg_cstring_bytes("OK, proceed\n")); } ICHECK(iohandle_flush(h), "iohandle_flush 2"); ICHECK(close(h->fd), "close"); delete_iohandle(h); } void start_relay(struct sockaddr_in const *peername, int fd) { struct boot_args *args = malloc(sizeof(*args)); args->peername = *peername; args->fd = fd; spawn((process_main_t) relay_main, args); }