-/* $OpenBSD: relay.c,v 1.239 2018/06/10 20:41:47 benno Exp $ */
+/* $OpenBSD: relay.c,v 1.240 2018/08/06 17:31:31 benno Exp $ */
/*
* Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
&rlay->rl_sessions, con);
timersub(&tv_now, &con->se_tv_last, &tv);
if (timercmp(&tv, &rlay->rl_conf.timeout, >=))
- relay_close(con, "hard timeout");
+ relay_close(con, "hard timeout", 1);
}
}
case RELAY_PROTO_HTTP:
if (relay_httpdesc_init(out) == -1) {
relay_close(con,
- "failed to allocate http descriptor");
+ "failed to allocate http descriptor", 1);
return;
}
con->se_out.toread = TOREAD_HTTP_HEADER;
bufferevent_enable(con->se_in.bev, EV_READ);
if (relay_splice(&con->se_out) == -1)
- relay_close(con, strerror(errno));
+ relay_close(con, strerror(errno), 1);
}
void
case RELAY_PROTO_HTTP:
if (relay_httpdesc_init(&con->se_in) == -1) {
relay_close(con,
- "failed to allocate http descriptor");
+ "failed to allocate http descriptor", 1);
return;
}
con->se_in.toread = TOREAD_HTTP_HEADER;
con->se_in.bev = bufferevent_new(con->se_in.s, inrd, inwr,
relay_error, &con->se_in);
if (con->se_in.bev == NULL) {
- relay_close(con, "failed to allocate input buffer event");
+ relay_close(con, "failed to allocate input buffer event", 1);
return;
}
bufferevent_enable(con->se_in.bev, EV_READ|EV_WRITE);
if (relay_splice(&con->se_in) == -1)
- relay_close(con, strerror(errno));
+ relay_close(con, strerror(errno), 1);
}
void
return;
done:
- relay_close(con, "last write (done)");
+ relay_close(con, "last write (done)", 0);
return;
fail:
- relay_close(con, strerror(errno));
+ relay_close(con, strerror(errno), 1);
}
void
return;
done:
- relay_close(con, "last read (done)");
+ relay_close(con, "last read (done)", 0);
return;
fail:
- relay_close(con, strerror(errno));
+ relay_close(con, strerror(errno), 1);
}
/*
case -1:
goto fail;
case 0:
- relay_close(con, "buffer event timeout");
+ relay_close(con, "buffer event timeout", 1);
break;
case 1:
cre->timedout = 1;
break;
}
} else {
- relay_close(con, "buffer event timeout");
+ relay_close(con, "buffer event timeout", 1);
}
return;
}
case -1:
goto fail;
case 0:
- relay_close(con, "splice timeout");
+ relay_close(con, "splice timeout", 1);
return;
case 1:
bufferevent_enable(bev, EV_READ);
break;
}
} else if (cre->dst->timedout) {
- relay_close(con, "splice timeout");
+ relay_close(con, "splice timeout", 1);
return;
}
if (relay_spliceadjust(cre) == -1)
} else if (cre->toread == TOREAD_UNLIMITED || cre->toread == 0)
return;
- relay_close(con, "done");
+ relay_close(con, "done", 0);
return;
}
- relay_close(con, "buffer event error");
+ relay_close(con, "buffer event error", 1);
return;
fail:
- relay_close(con, strerror(errno));
+ relay_close(con, strerror(errno), 1);
}
void
/* Pre-allocate output buffer */
con->se_out.output = evbuffer_new();
if (con->se_out.output == NULL) {
- relay_close(con, "failed to allocate output buffer");
+ relay_close(con, "failed to allocate output buffer", 1);
return;
}
slen = sizeof(con->se_out.ss);
if (getsockname(s, (struct sockaddr *)&con->se_out.ss,
&slen) == -1) {
- relay_close(con, "peer lookup failed");
+ relay_close(con, "peer lookup failed", 1);
return;
}
con->se_out.port = relay_socket_getport(&con->se_out.ss);
con->se_out.ss.ss_family = AF_UNSPEC;
} else if (rlay->rl_conf.flags & F_NATLOOK) {
if ((cnl = calloc(1, sizeof(*cnl))) == NULL) {
- relay_close(con, "failed to allocate nat lookup");
+ relay_close(con, "failed to allocate nat lookup", 1);
return;
}
slen = sizeof(cnl->dst);
if (getsockname(s,
(struct sockaddr *)&cnl->dst, &slen) == -1) {
- relay_close(con, "failed to get local address");
+ relay_close(con, "failed to get local address", 1);
return;
}
if (con->se_out.ss.ss_family == AF_UNSPEC && cnl->in == -1 &&
rlay->rl_conf.dstss.ss_family == AF_UNSPEC &&
TAILQ_EMPTY(&rlay->rl_tables)) {
- relay_close(con, "session NAT lookup failed");
+ relay_close(con, "session NAT lookup failed", 1);
return;
}
if (cnl->in != -1) {
if (bcmp(&rlay->rl_conf.ss, &out->ss, sizeof(out->ss)) == 0 &&
out->port == rlay->rl_conf.port) {
log_debug("%s: session %d: looping", __func__, con->se_id);
- relay_close(con, "session aborted");
+ relay_close(con, "session aborted", 1);
return;
}
if (rlay->rl_proto->request == NULL)
fatalx("invalide UDP session");
if ((*rlay->rl_proto->request)(con) == -1)
- relay_close(con, "session failed");
+ relay_close(con, "session failed", 1);
return;
}
if (rlay->rl_conf.fwdmode == FWD_TRANS)
relay_bindanyreq(con, 0, IPPROTO_TCP);
else if (relay_connect(con) == -1) {
- relay_close(con, "session failed");
+ relay_close(con, "session failed", 1);
return;
}
}
struct rsession *con = arg;
if (con->se_bnds == -1) {
- relay_close(con, "bindany failed, invalid socket");
+ relay_close(con, "bindany failed, invalid socket", 1);
return;
}
if (relay_connect(con) == -1)
- relay_close(con, "session failed");
+ relay_close(con, "session failed", 1);
}
void
}
void
-relay_close(struct rsession *con, const char *msg)
+relay_close(struct rsession *con, const char *msg, int err)
{
char ibuf[128], obuf[128], *ptr = NULL;
struct relay *rlay = con->se_relay;
if (con->se_out.bev != NULL)
bufferevent_disable(con->se_out.bev, EV_READ|EV_WRITE);
- if ((env->sc_conf.opts & RELAYD_OPT_LOGUPDATE) && msg != NULL) {
+ if ((env->sc_conf.opts & (RELAYD_OPT_LOGCON|RELAYD_OPT_LOGCONERR)) &&
+ msg != NULL) {
bzero(&ibuf, sizeof(ibuf));
bzero(&obuf, sizeof(obuf));
(void)print_host(&con->se_in.ss, ibuf, sizeof(ibuf));
ptr = evbuffer_readln(con->se_log, NULL,
EVBUFFER_EOL_CRLF);
}
- log_info("relay %s, "
- "session %d (%d active), %s, %s -> %s:%d, "
- "%s%s%s", rlay->rl_conf.name, con->se_id, relay_sessions,
- con->se_tag != 0 ? tag_id2name(con->se_tag) : "0", ibuf,
- obuf, ntohs(con->se_out.port), msg, ptr == NULL ? "" : ",",
- ptr == NULL ? "" : ptr);
+ if (err == 0 && (env->sc_conf.opts & RELAYD_OPT_LOGCON))
+ log_info("relay %s, "
+ "session %d (%d active), %s, %s -> %s:%d, "
+ "%s%s%s", rlay->rl_conf.name, con->se_id,
+ relay_sessions, con->se_tag != 0 ?
+ tag_id2name(con->se_tag) : "0", ibuf, obuf,
+ ntohs(con->se_out.port), msg, ptr == NULL ?
+ "" : ",", ptr == NULL ? "" : ptr);
+ if (err == 1 && (env->sc_conf.opts & RELAYD_OPT_LOGCONERR))
+ log_warn("relay %s, "
+ "session %d (%d active), %s, %s -> %s:%d, "
+ "%s%s%s", rlay->rl_conf.name, con->se_id,
+ relay_sessions, con->se_tag != 0 ?
+ tag_id2name(con->se_tag) : "0", ibuf, obuf,
+ ntohs(con->se_out.port), msg, ptr == NULL ?
+ "" : ",", ptr == NULL ? "" : ptr);
free(ptr);
}
return;
err:
- relay_close(con, errstr);
+ relay_close(con, errstr, 1);
}
void
char *msg;
if (event == EV_TIMEOUT) {
- relay_close(con, "TLS handshake timeout");
+ relay_close(con, "TLS handshake timeout", 1);
return;
}
con->se_in.tlscert = NULL;
if (con->se_in.tlscert == NULL)
relay_close(con,
- "could not create certificate");
+ "could not create certificate", 1);
else
relay_session(con);
return;
} else {
if (asprintf(&msg, "TLS handshake error: %s",
tls_error(cre->tls)) >= 0) {
- relay_close(con, msg);
+ relay_close(con, msg, 1);
free(msg);
} else {
- relay_close(con, "TLS handshake error");
+ relay_close(con, "TLS handshake error", 1);
}
return;
}
-/* $OpenBSD: relay_http.c,v 1.70 2017/11/27 16:25:50 benno Exp $ */
+/* $OpenBSD: relay_http.c,v 1.71 2018/08/06 17:31:31 benno Exp $ */
/*
* Copyright (c) 2006 - 2016 Reyk Floeter <reyk@openbsd.org>
action = relay_test(proto, cre);
switch (action) {
case RES_FAIL:
- relay_close(con, "filter rule failed");
+ relay_close(con, "filter rule failed", 1);
return;
case RES_BAD:
relay_abort_http(con, 400, "Bad Request",
}
}
if (con->se_done) {
- relay_close(con, "last http read (done)");
+ relay_close(con, "last http read (done)", 0);
return;
}
switch (relay_splice(cre)) {
case -1:
- relay_close(con, strerror(errno));
+ relay_close(con, strerror(errno), 1);
case 1:
return;
case 0:
/* The callback readcb() might have freed the session. */
return;
done:
- relay_close(con, "last http content read");
+ relay_close(con, "last http content read", 0);
return;
fail:
- relay_close(con, strerror(errno));
+ relay_close(con, strerror(errno), 1);
}
void
*/
if (sscanf(line, "%llx", &llval) != 1 || llval < 0) {
free(line);
- relay_close(con, "invalid chunk size");
+ relay_close(con, "invalid chunk size", 1);
return;
}
return;
done:
- relay_close(con, "last http chunk read (done)");
+ relay_close(con, "last http chunk read (done)", 0);
return;
fail:
- relay_close(con, strerror(errno));
+ relay_close(con, strerror(errno), 1);
}
void
/* In some cases this function may be called from generic places */
if (rlay->rl_proto->type != RELAY_PROTO_HTTP ||
(rlay->rl_proto->flags & F_RETURN) == 0) {
- relay_close(con, msg);
+ relay_close(con, msg, 0);
return;
}
done:
free(body);
if (asprintf(&httpmsg, "%s (%03d %s)", msg, code, httperr) == -1)
- relay_close(con, msg);
+ relay_close(con, msg, 1);
else {
- relay_close(con, httpmsg);
+ relay_close(con, httpmsg, 1);
free(httpmsg);
}
}
-/* $OpenBSD: relay_udp.c,v 1.48 2018/04/18 12:10:54 claudio Exp $ */
+/* $OpenBSD: relay_udp.c,v 1.49 2018/08/06 17:31:31 benno Exp $ */
/*
* Copyright (c) 2007 - 2013 Reyk Floeter <reyk@openbsd.org>
(priv = (*proto->validate)(con, rlay, &ss, buf, len)) == NULL)
return;
- relay_close(con, "unknown response");
+ relay_close(con, "unknown response", 1);
free(priv);
}
/* Pre-allocate output buffer */
con->se_out.output = evbuffer_new();
if (con->se_out.output == NULL) {
- relay_close(con, "failed to allocate output buffer");
+ relay_close(con, "failed to allocate output buffer", 1);
return;
}
con->se_haslog = 0;
con->se_log = evbuffer_new();
if (con->se_log == NULL) {
- relay_close(con, "failed to allocate log buffer");
+ relay_close(con, "failed to allocate log buffer", 1);
return;
}
if (rlay->rl_conf.flags & F_NATLOOK) {
if ((cnl = calloc(1, sizeof(*cnl))) == NULL) {
- relay_close(con, "failed to allocate natlookup");
+ relay_close(con, "failed to allocate natlookup", 1);
return;
}
}
/* Save the received data */
if (evbuffer_add(con->se_out.output, buf, len) == -1) {
- relay_close(con, "failed to store buffer");
+ relay_close(con, "failed to store buffer", 1);
free(cnl);
return;
}
if (sig != EV_TIMEOUT)
fatalx("invalid timeout event");
- relay_close(con, "udp timeout");
+ relay_close(con, "udp timeout", 1);
}
/*
} else {
priv = con->se_priv;
if (priv == NULL || key != priv->dp_inkey) {
- relay_close(con, "invalid response");
+ relay_close(con, "invalid response", 1);
return (NULL);
}
relay_dns_result(con, buf, len);
slen = con->se_out.ss.ss_len;
if (sendto(rlay->rl_s, buf, len, 0,
(struct sockaddr *)&con->se_in.ss, slen) == -1) {
- relay_close(con, "response failed");
+ relay_close(con, "response failed", 1);
return;
}
- relay_close(con, "session closed");
+ relay_close(con, "session closed", 0);
}
int