commit c56ccc84283eb9c7c5b4acd3ecdf245669145031 from: Omar Polo date: Tue Jul 05 17:05:37 2022 UTC don't die for OOM instead, drop the current connection (we can't do anything about it) and try to continue to work. OOM can be a temporary situation, and in every case it's not nice to terminate other in-flight connections. To do so, refactor the freeing of the connection into conn_free, which now also looks for the state of the timeout. In every case we reach conn_free the timeout is not pending, but it doesn't hurt to check for it anyway. Future changes may want to free early. commit - 82c452fabb98831c03c09da5d642ea6b77a3ad3d commit + c56ccc84283eb9c7c5b4acd3ecdf245669145031 blob - 80507c7c4b075bc8ecfd33e4ddd560f7c0373fec blob + 81359413f8f1662fb683a115f0f596b0b9c9adfe --- lstun.c +++ lstun.c @@ -124,6 +124,23 @@ spawn_ssh(void) } static void +conn_free(struct conn *c) +{ + if (c->sourcebev != NULL) + bufferevent_free(c->sourcebev); + if (c->tobev != NULL) + bufferevent_free(c->tobev); + + if (evtimer_pending(&c->waitev, NULL)) + evtimer_del(&c->waitev); + + close(c->source); + close(c->to); + + free(c); +} + +static void killing_time(int fd, short event, void *data) { if (ssh_pid == -1) @@ -163,14 +180,8 @@ errcb(struct bufferevent *bev, short event, void *d) log_info("closing connection (event=%x)", event); - bufferevent_free(c->sourcebev); - bufferevent_free(c->tobev); - - close(c->source); - close(c->to); + conn_free(c); - free(c); - if (--conn == 0) { log_debug("scheduling ssh termination (%llds)", (long long)timeout.tv_sec); @@ -193,9 +204,11 @@ connect_to_ssh(void) hints.ai_socktype = SOCK_STREAM; r = getaddrinfo(ssh_host, ssh_port, &hints, &res0); - if (r != 0) - fatal("getaddrinfo(\"%s\", \"%s\"): %s", + if (r != 0) { + log_warnx("getaddrinfo(\"%s\", \"%s\"): %s", ssh_host, ssh_port, gai_strerror(r)); + return -1; + } for (res = res0; res; res = res->ai_next) { sock = socket(res->ai_family, res->ai_socktype, @@ -255,8 +268,12 @@ try_to_connect(int fd, short event, void *d) c->sourcebev = bufferevent_new(c->source, sreadcb, nopcb, errcb, c); c->tobev = bufferevent_new(c->to, treadcb, nopcb, errcb, c); - if (c->sourcebev == NULL || c->tobev == NULL) - fatal("bufferevent_new"); + if (c->sourcebev == NULL || c->tobev == NULL) { + log_warn("bufferevent_new"); + conn_free(c); + return; + } + bufferevent_enable(c->sourcebev, EV_READ|EV_WRITE); bufferevent_enable(c->tobev, EV_READ|EV_WRITE); }