diff options
author | Omar Polo <op@omarpolo.com> | 2024-08-03 10:27:07 +0000 |
---|---|---|
committer | Omar Polo <op@omarpolo.com> | 2024-08-03 10:27:07 +0000 |
commit | 040f7aaca1032511212b4fbad28717dcfadc3d49 (patch) | |
tree | c7d45134b16420b998f9b4fd78d060972b5a9549 /server.c | |
parent | 9360fb1a552b13b24f0b21bfd7146460e87341e0 (diff) |
add support for using the proxy protocol v1 when proxying too
This is symmetrical to the support for *incoming* requests. The
new regress case uses this to proxy to itself using the proxy-protocol
v1.
Fixes https://github.com/omar-polo/gmid/issues/31
Diffstat (limited to 'server.c')
-rw-r--r-- | server.c | 34 |
1 files changed, 28 insertions, 6 deletions
@@ -556,21 +556,23 @@ check_matching_certificate(X509_STORE *store, struct client *c) } static int -proxy_socket(struct client *c, const char *host, const char *port) +proxy_socket(struct client *c, struct proxy *p) { struct addrinfo hints, *res, *res0; int r, sock, save_errno; const char *cause = NULL; + char to[NI_MAXHOST], to_port[NI_MAXSERV]; + int err; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; /* XXX: asr_run? :> */ - r = getaddrinfo(host, port, &hints, &res0); + r = getaddrinfo(p->host, p->port, &hints, &res0); if (r != 0) { log_warnx("getaddrinfo(\"%s\", \"%s\"): %s", - host, port, gai_strerror(r)); + p->host, p->port, gai_strerror(r)); return -1; } @@ -595,10 +597,30 @@ proxy_socket(struct client *c, const char *host, const char *port) } if (sock == -1) - log_warn("can't connect to %s:%s: %s", host, port, cause); + log_warn("can't connect to %s:%s: %s", p->host, p->port, cause); + + if (res && sock != -1 && p->proxy) { + err = getnameinfo(res->ai_addr, res->ai_addrlen, + to, sizeof(to), to_port, sizeof(to_port), + NI_NUMERICHOST|NI_NUMERICSERV); + if (err != 0) { + log_warnx("getnameinfo failed: %s", gai_strerror(err)); + strlcpy(to, c->rhost, sizeof(to)); + strlcpy(to_port, c->rserv, sizeof(to_port)); + } - freeaddrinfo(res0); + r = snprintf(c->buf.data, sizeof(c->buf.data), + "PROXY TCP%c %s %s %s %s\r\n", + c->addr->ai_family == AF_INET ? '4' : '6', + c->rhost, to, c->rserv, to_port); + if (r < 0 || (size_t)r >= sizeof(c->buf.data)) { + log_warnx("failed serialize info for the proxy protocol"); + c->buf.data[0] = '\0'; + } else + c->buf.len = r; + } + freeaddrinfo(res0); return sock; } @@ -618,7 +640,7 @@ apply_reverse_proxy(struct client *c) log_debug("opening proxy connection for %s:%s", p->host, p->port); - if ((c->pfd = proxy_socket(c, p->host, p->port)) == -1) { + if ((c->pfd = proxy_socket(c, p)) == -1) { start_reply(c, PROXY_ERROR, "proxy error"); return 1; } |