#include <stdio.h>
#include <stdlib.h> /* EXIT_FAILURE */
#include <string.h> /* memset(3) */
#include <errno.h>
#include <assert.h>
#include <fcntl.h> /* close(2) */
#if _WIN32
#include <winsock2.h>
#else
#include <sys/time.h> /* struct timeval */
#include <sys/socket.h> /* AF_INET socklen_t struct sockaddr
* struct sockaddr_storage */
#include <netinet/in.h> /* struct sockaddr_in */
#endif
#include <unistd.h> /* close(2) */
#include <err.h> /* err(3) errx(3) */
#include <event.h> /* struct event struct event_base event_init(3)
* event_base_loop(3) */
#include <arena/proto.h>
#include "socket.h"
#include "lookup.h"
#include "tls.h"
static int pending = 2;
static void main_catch_accept(struct socket *s, struct socket *p, enum socket_errno so_errno, void *arg) {
struct tls *tls;
if (so_errno == SOCKET_ECANCELLED)
return; /* void */;
if (so_errno != SOCKET_ESUCCESS)
err(EXIT_FAILURE, "socket_accept: %s", socket_errlist[so_errno]);
socket_getsockinfo(p, 0, &tls);
if (tls != 0)
warnx("caught TLS accept");
else
warnx("caught accept");
socket_close(s);
socket_close(p);
return /* void */;
} /* main_catch_accept() */
static void main_catch_connect(struct socket *s, enum socket_errno so_errno, void *arg) {
struct tls *tls = 0;
assert(so_errno == SOCKET_ESUCCESS);
socket_getsockinfo(s, 0, &tls);
if (tls != 0)
warnx("caught TLS connect");
else
warnx("caught connect");
socket_close(s);
return /* void */;
} /* main_catch_connect() */
int main(int argc, char *argv[]) {
struct event_base *ev_base;
struct tls_identity *tid;
enum tls_errno tls_errno;
enum socket_errno so_errno;
struct socket *server, *client;
struct socket_name so_name;
struct sockaddr_in sin;
struct socket_options opts;
#if _WIN32
WSADATA wsaData;
#endif
#if _WIN32
if (NO_ERROR != WSAStartup(MAKEWORD(2, 2), &wsaData))
err(EXIT_FAILURE, "WSAStartup");
#endif
if (!(ev_base = event_init()))
err(EXIT_FAILURE, "event_init");
(void)memset(&sin, '\0', sizeof sin);
sin.sin_family = AF_INET;
sin.sin_port = htons(4000);
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
(void)socket_name_init_addr(&so_name, (struct sockaddr *)&sin, sizeof sin);
opts = socket_defaults;
opts.sa_reuseaddr = 1;
opts.sin_resolv = 1;
if (0 == (server = socket_open(&so_name, &opts, ev_base, ARENA_STDLIB, &so_errno)))
err(EXIT_FAILURE, "socket_open");
(void)socket_name_init_host(&so_name, "localhost", "4000", LOOKUP_IN_A, 0);
if (0 == (client = socket_open(&so_name, &socket_defaults, ev_base, ARENA_STDLIB, &so_errno)))
err(EXIT_FAILURE, "socket_open");
if (argc > 2) {
assert(0 == tls_init());
if (!(tid = tls_identity_open(&tls_defaults, 0, &tls_errno)))
errx(EXIT_FAILURE, "tls_context_open: %s", tls_errlist[tls_errno]);
assert(argc > 2);
assert(0 == tls_identity_certify(tid, argv[1], argv[2]));
socket_enable_tls(server, tid);
socket_enable_tls(client, tid);
}
socket_accept(server, &main_catch_accept, server, 0);
socket_connect(client, &main_catch_connect, client, 0);
event_base_loop(ev_base, 0);
return 0;
} /* main() */
syntax highlighted by Code2HTML, v. 0.9.1