[MEDIUM] add support for logging via a UNIX socket
The code in haproxy-1.3.13.1 only supports syslogging to an internet
address. The attached patch:
- Adds support for syslogging to a UNIX domain socket (e.g., /dev/log).
If the address field begins with '/' (absolute file path), then
AF_UNIX is used to construct the socket. Otherwise, AF_INET is used.
- Achieves clean single-source build on both Mac OS X and Linux
(sockaddr_in.sin_len and sockaddr_un.sun_len field aren't always present).
For handling sendto() failures in send_log(), it appears that the existing
code is fine (no need to close/recreate socket) for both UDP and UNIX-domain
syslog server. So I left things alone (did not close/recreate socket).
Closing/recreating socket after each failure would also work, but would lead
to increased amount of unnecessary socket creation/destruction if syslog is
temporarily unavailable for some reason (especially for verbose loggers).
Please consider this patch for inclusion into the upstream haproxy codebase.
diff --git a/src/standard.c b/src/standard.c
index 40ad47e..647a6c8 100644
--- a/src/standard.c
+++ b/src/standard.c
@@ -77,6 +77,37 @@
return (n) ? ultoa_r(n, buffer, size) : (alt ? alt : "");
}
+/*
+ * converts <str> to a struct sockaddr_un* which is locally allocated.
+ * The format is "/path", where "/path" is a path to a UNIX domain socket.
+ */
+struct sockaddr_un *str2sun(char *str)
+{
+ static struct sockaddr_un sun;
+ int strsz; /* length included null */
+
+ memset(&sun, 0, sizeof(sun));
+ str = strdup(str);
+ if (str == NULL)
+ goto out_nofree;
+
+ strsz = strlen(str) + 1;
+ if (strsz > sizeof(sun.sun_path)) {
+ Alert("Socket path '%s' too long (max %d)\n",
+ str, sizeof(sun.sun_path) - 1);
+ goto out_nofree;
+ }
+
+#ifndef __SOCKADDR_COMMON
+ sun.sun_len = sizeof(sun);
+#endif /* !__SOCKADDR_COMMON */
+ sun.sun_family = AF_UNIX;
+ memcpy(sun.sun_path, str, strsz);
+
+ free(str);
+ out_nofree:
+ return &sun;
+}
/*
* Returns non-zero if character <s> is a hex digit (0-9, a-f, A-F), else zero.
@@ -153,6 +184,9 @@
else
sa.sin_addr = *(struct in_addr *) *(he->h_addr_list);
}
+#ifndef __SOCKADDR_COMMON
+ sa.sin_len = sizeof(sa);
+#endif /* !__SOCKADDR_COMMON */
sa.sin_port = htons(port);
sa.sin_family = AF_INET;