geomyidae

A small C-based gopherd. (gopher://bitreich.org/1/scm/geomyidae)
git clone git://r-36.net/geomyidae
Log | Files | Refs | README | LICENSE

commit e03b02a1d3a3f7669d4bd88741def54dad981d59
parent df8683b61ecb57affad4055f649560a2a789950e
Author: Christoph Lohmann <20h@r-36.net>
Date:   Fri, 11 Nov 2022 09:05:18 +0100

Add HAProxy support.

Diffstat:
Mgeomyidae.8 | 9+++++++++
Mmain.c | 62+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 68 insertions(+), 3 deletions(-)

diff --git a/geomyidae.8 b/geomyidae.8 @@ -18,6 +18,7 @@ .Op Fl e .Op Fl n .Op Fl s +.Op Fl y .Op Fl l Ar logfile .Op Fl v Ar loglevel .Op Fl b Ar base @@ -114,6 +115,9 @@ Don't perform reverse lookups. .It Fl s Log using syslog for logging. . +.It Fl y +Enable HAProxy support. +. .It Fl l Ar logfile Specify file where log output is written (no default). . @@ -483,6 +487,11 @@ Phrases_of_the_Ages.txt .Pp Care should to be exercised to avoid creating miss-Typed entries, unwanted recursions, and/or unintended writes in the working directory. +.Sh HAPROXY SUPPORT +Geomyidae has +.Em HAProxy +support. It can be enabled using the -y parameter. +. .Sh LOG FILES The log file (ie. /var/log/gopherd.log) has the following structure: . diff --git a/main.c b/main.c @@ -526,7 +526,7 @@ getlistenfd(struct addrinfo *hints, char *bindip, char *port, int *rlfdnum) void usage(void) { - dprintf(2, "usage: %s [-46cdens] [-l logfile] " + dprintf(2, "usage: %s [-46cdensy] [-l logfile] " #ifdef ENABLE_TLS "[-t keyfile certfile] " #endif /* ENABLE_TLS */ @@ -546,7 +546,7 @@ main(int argc, char *argv[]) int sock, dofork = 1, inetf = AF_UNSPEC, usechroot = 0, nocgi = 0, errno_save, nbindips = 0, i, j, nlfdret, *lfdret, listfd, maxlfd, istls = 0, - dotls = 0, + dotls = 0, dohaproxy = 0, tcpver = -1, haret = 0, #ifdef ENABLE_TLS tlspipe[2], shufbuf[1025], shuflen, wlen, shufpos, @@ -556,7 +556,9 @@ main(int argc, char *argv[]) fd_set rfd; char *port, *base, clienth[NI_MAXHOST], clientp[NI_MAXSERV], *user = NULL, *group = NULL, **bindips = NULL, - *ohost = NULL, *sport = NULL, *p, + *ohost = NULL, *sport = NULL, *p; + /* Must be as large as recvb, due to scanf restrictions. */ + char hachost[1025], hashost[1025], hacport[1025], hasport[1025], #ifdef ENABLE_TLS *certfile = NULL, *keyfile = NULL, #endif /* ENABLE_TLS */ @@ -574,9 +576,11 @@ main(int argc, char *argv[]) ARGBEGIN { case '4': inetf = AF_INET; + tcpver = 4; break; case '6': inetf = AF_INET6; + tcpver = 6; break; case 'b': base = EARGF(usage()); @@ -630,6 +634,9 @@ main(int argc, char *argv[]) case 'v': loglvl = atoi(EARGF(usage())); break; + case 'y': + dohaproxy = 1; + break; default: usage(); } ARGEND; @@ -942,6 +949,7 @@ main(int argc, char *argv[]) return 1; } +read_selector_again: maxrecv = sizeof(recvb) - 1; do { #ifdef ENABLE_TLS @@ -966,6 +974,54 @@ main(int argc, char *argv[]) if (rlen <= 0) return 1; + /* + * HAProxy v1 protocol support. + * TODO: Add other protocol version support. + */ + if (dohaproxy && !strncmp(recvb, "PROXY TCP", 9)) { + /* + * Be careful, we are using scanf. + * TODO: Use some better parsing. + */ + memset(hachost, 0, sizeof(hachost)); + memset(hashost, 0, sizeof(hashost)); + memset(hacport, 0, sizeof(hacport)); + memset(hasport, 0, sizeof(hasport)); + + haret = sscanf(recvb, "PROXY TCP%d %s %s %s %s", + &tcpver, hachost, hashost, hacport, + hasport); + if (haret != 5) + return 1; + + /* + * Be careful. Everything could be + * malicious. + */ + memset(clienth, 0, sizeof(clienth)); + memmove(clienth, hachost, sizeof(clienth)-1); + memset(serverh, 0, sizeof(serverh)); + memmove(serverh, hashost, sizeof(serverh)-1); + memset(clientp, 0, sizeof(clientp)); + memmove(clientp, hacport, sizeof(clientp)-1); + memset(serverp, 0, sizeof(serverp)); + memmove(serverp, hasport, sizeof(serverp)-1); + + if (!strncmp(serverh, "::ffff:", 7)) { + memmove(serverh, serverh+7, + strlen(serverh)-6); + } + if (!strncmp(clienth, "::ffff:", 7)) { + memmove(clienth, clienth+7, + strlen(clienth)-6); + } + if (loglvl & CONN) { + logentry(clienth, clientp, "-", + "haproxy connected"); + } + goto read_selector_again; + } + #ifdef ENABLE_TLS if (istls) { if (pipe(tlspipe) < 0) {