1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/c++/domain-socket-bridge/domain-socket-bridge.c Fri Nov 18 21:41:23 2016 +0100
1.3 @@ -0,0 +1,113 @@
1.4 +#include <string.h>
1.5 +#include <errno.h>
1.6 +#include <stdio.h>
1.7 +#include <signal.h>
1.8 +
1.9 +#include <event2/bufferevent.h>
1.10 +#include <event2/buffer.h>
1.11 +#include <event2/listener.h>
1.12 +#include <event2/util.h>
1.13 +#include <event2/event.h>
1.14 +
1.15 +static const char MESSAGE[] = "Hello, World!\n";
1.16 +
1.17 +static const int PORT = 9995;
1.18 +
1.19 +static void listener_cb(struct evconnlistener *, evutil_socket_t,
1.20 + struct sockaddr *, int socklen, void *);
1.21 +static void conn_write_cb(struct bufferevent *, void *);
1.22 +static void conn_event_cb(struct bufferevent *, short, void *);
1.23 +static void signal_cb(evutil_socket_t, short, void *);
1.24 +
1.25 +int main(int argc, char **argv) {
1.26 + struct event_base *base;
1.27 + struct evconnlistener *listener;
1.28 + struct event *signal_event;
1.29 +
1.30 + struct sockaddr_in sin;
1.31 +
1.32 + base = event_base_new();
1.33 + if (!base) {
1.34 + fprintf(stderr, "Could not initialize libevent!\n");
1.35 + return 1;
1.36 + }
1.37 +
1.38 + memset(&sin, 0, sizeof (sin));
1.39 + sin.sin_family = AF_INET;
1.40 + sin.sin_port = htons(PORT);
1.41 +
1.42 + listener = evconnlistener_new_bind(base, listener_cb, (void *) base,
1.43 + LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, -1,
1.44 + (struct sockaddr*) &sin,
1.45 + sizeof (sin));
1.46 +
1.47 + if (!listener) {
1.48 + fprintf(stderr, "Could not create a listener!\n");
1.49 + return 1;
1.50 + }
1.51 +
1.52 + signal_event = evsignal_new(base, SIGINT, signal_cb, (void *) base);
1.53 +
1.54 + if (!signal_event || event_add(signal_event, NULL) < 0) {
1.55 + fprintf(stderr, "Could not create/add a signal event!\n");
1.56 + return 1;
1.57 + }
1.58 +
1.59 + event_base_dispatch(base);
1.60 +
1.61 + evconnlistener_free(listener);
1.62 + event_free(signal_event);
1.63 + event_base_free(base);
1.64 +
1.65 + printf("done\n");
1.66 + return 0;
1.67 +}
1.68 +
1.69 +static void listener_cb(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *sa, int socklen, void *user_data) {
1.70 + struct event_base *base = (event_base *) user_data;
1.71 + struct bufferevent *bev;
1.72 +
1.73 + bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); // zavírá spojení
1.74 + //bev = bufferevent_socket_new(base, fd, 0); // nezavírá spojení
1.75 + if (!bev) {
1.76 + fprintf(stderr, "Error constructing bufferevent!");
1.77 + event_base_loopbreak(base);
1.78 + return;
1.79 + }
1.80 + bufferevent_setcb(bev, NULL, conn_write_cb, conn_event_cb, NULL);
1.81 + bufferevent_enable(bev, EV_WRITE);
1.82 + bufferevent_disable(bev, EV_READ);
1.83 +
1.84 + printf("někdo se k nám připojil! / %p\n", bev);
1.85 +
1.86 + bufferevent_write(bev, MESSAGE, strlen(MESSAGE));
1.87 +}
1.88 +
1.89 +static void conn_write_cb(struct bufferevent *bev, void *user_data) {
1.90 + struct evbuffer *output = bufferevent_get_output(bev);
1.91 + if (evbuffer_get_length(output) == 0) {
1.92 + printf("flushed answer / %p\n", bev);
1.93 + bufferevent_free(bev);
1.94 + }
1.95 +}
1.96 +
1.97 +static void conn_event_cb(struct bufferevent *bev, short events, void *user_data) {
1.98 + if (events & BEV_EVENT_EOF) {
1.99 + printf("Connection closed.\n");
1.100 + } else if (events & BEV_EVENT_ERROR) {
1.101 + printf("Got an error on the connection: %s\n",
1.102 + strerror(errno)); /*XXX win32*/
1.103 + }
1.104 +
1.105 + // None of the other events can happen here, since we haven't enabled timeouts
1.106 + bufferevent_free(bev);
1.107 +}
1.108 +
1.109 +static void signal_cb(evutil_socket_t sig, short events, void *user_data) {
1.110 + struct event_base *base = (event_base *) user_data;
1.111 + struct timeval delay = {2, 123};
1.112 +
1.113 + printf("Zachycen SIGINT (Ctrl+C); ukončuji program během %ld sekund a %ld mikrosekund.\n", delay.tv_sec, delay.tv_usec);
1.114 +
1.115 + event_base_loopexit(base, &delay);
1.116 +}