commit e03b02a1d3a3f7669d4bd88741def54dad981d59
parent df8683b61ecb57affad4055f649560a2a789950e
Author: Christoph Lohmann <20h@r-36.net>
Date: Fri, 11 Nov 2022 09:05:18 +0100
Add HAProxy support.
Diffstat:
M | geomyidae.8 | | | 9 | +++++++++ |
M | main.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) {