int main(int argc, char **argv) { SSL_CTX *ctx; struct evconnlistener *listener; struct event_base *evbase; struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(9999); sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */ ctx = evssl_init(); if (ctx == NULL) return 1; evbase = event_base_new(); listener = evconnlistener_new_bind( evbase, ssl_acceptcb, (void *)ctx, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, 1024, (struct sockaddr *)&sin, sizeof(sin)); event_base_loop(evbase, 0); evconnlistener_free(listener); SSL_CTX_free(ctx); return 0; }
static int new_peer() { int flag = 1; int fd = -1; struct sockaddr_in sin; SSL_CTX *ctx; SSL *ssl; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(0); sin.sin_port = htons(9093); if ((fd = socket(sin.sin_family, SOCK_STREAM, IPPROTO_TCP)) < 0) { jlog(L_ERROR, "socket failed"); goto out; } if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &flag, sizeof(flag)) < 0 || setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag)) < 0) { jlog(L_ERROR, "setsockopt failed"); goto out; } if (evutil_make_socket_nonblocking(fd) < 0) { jlog(L_ERROR, "evutil_make_socket_nonblocking failed"); goto out; } if ((ctx = evssl_init()) == NULL) { jlog(L_ERROR, "evssl_init failed"); goto out; } if ((ssl = SSL_new(ctx)) == NULL) { jlog(L_ERROR, "SSL_new failed"); goto out; } if ((bufev_sock = bufferevent_openssl_socket_new(base, fd, ssl, BUFFEREVENT_SSL_CONNECTING, BEV_OPT_CLOSE_ON_FREE)) == NULL) { jlog(L_ERROR, "bufferevent_socket_new failed"); goto out; } bufferevent_enable(bufev_sock, EV_READ|EV_WRITE); bufferevent_setcb(bufev_sock, on_read_cb, NULL, on_event_cb, NULL); if (bufferevent_socket_connect(bufev_sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) { jlog(L_ERROR, "bufferevent_socket_connected failed"); goto out; } return 0; out: if (bufev_sock != NULL) bufferevent_free(bufev_sock); return -1; }
int tnt_fork(int imsg_fds[2]) { pid_t pid; struct imsgbuf ibuf; struct imsg_data data; struct passwd *pw; struct event_base *evbase = NULL; struct event *sigterm = NULL; struct event *sigint = NULL; struct event *imsg_event = NULL; struct server server; struct event_config *evcfg; switch ((pid = fork())) { case -1: log_err(TNT_OSERR, "fork"); break; case 0: tnt_setproctitle("[unpriv]"); log_set_prefix("unpriv"); break; default: tnt_setproctitle("[priv]"); log_set_prefix("priv"); return pid; } if ((pw = getpwnam(TNETACLE_USER)) == NULL) { log_errx(1, "unknown user " TNETACLE_USER); return TNT_NOUSER; } /*Allocate the event config*/ evcfg = event_config_new(); /* Initialize the OpenSSL library */ SSL_library_init(); SSL_load_error_strings(); /* We MUST have entropy, or else there's no point to crypto. */ if (!RAND_poll()) { log_errx(TNT_SOFTWARE, "[INIT] failed to find an entropy source"); /* never returns */ } if (serv_opts.encryption) server.server_ctx = evssl_init(); else server.server_ctx = NULL; tnt_priv_drop(pw); #if defined(Darwin) /* It's sad isn't it ?*/ event_config_avoid_method(evcfg, "kqueue"); event_config_avoid_method(evcfg, "poll"); event_config_avoid_method(evcfg, "devpoll"); if ((evbase = event_base_new_with_config(evcfg)) == NULL) { log_err(1, "libevent"); } #else if ((evbase = event_base_new_with_config(evcfg)) == NULL) { log_err(1, "libevent"); } #endif sigterm = event_new(evbase, SIGTERM, EV_SIGNAL, &chld_sighdlr, evbase); sigint = event_new(evbase, SIGINT, EV_SIGNAL, &chld_sighdlr, evbase); signal(SIGPIPE, SIG_IGN); signal(SIGHUP, SIG_IGN); signal(SIGCHLD, SIG_DFL); if (server_init(&server, evbase) == -1) log_errx(1, "failed to init the server socket"); data.ibuf = &ibuf; data.evbase = evbase; data.server = &server; imsg_event = init_pipe_endpoint(imsg_fds, &data); event_add(sigterm, NULL); event_add(sigint, NULL); event_add(imsg_event, NULL); log_info("tnetacle ready"); /* Immediately request the creation of a tun interface */ imsg_compose(&ibuf, IMSG_CREATE_DEV, 0, 0, -1, NULL, 0); log_info("starting event loop"); event_base_dispatch(evbase); /* cleanely exit */ msgbuf_write(&ibuf.w); msgbuf_clear(&ibuf.w); /* Shutdown the server */ server_delete(&server); /* * It may look like we freed this one twice, * once here and once in tnetacled.c but this is not the case. * Please don't erase this ! */ event_free(sigterm); event_free(sigint); close(event_get_fd(imsg_event)); event_free(imsg_event); event_base_free(evbase); event_config_free(evcfg); log_info("tnetacle exiting"); exit(TNT_OK); }