+ /*
+ * This case is the be all and end all patch to catch and nuke 4in6
+ * instead of special-casing shit all over the place and wreaking merry
+ * havoc with crap, instead, we just recreate sockaddr and strip ::ffff: prefix
+ * if it's a 4in6 IP.
+ *
+ * This is, of course, much improved over the older way of handling this
+ * (pretend it doesn't exist + hack around it -- yes, both were done!)
+ *
+ * Big, big thanks to danieldg for his work on this.
+ * -- w00t
+ */
+ static const unsigned char prefix4in6[12] = { 0,0,0,0, 0,0,0,0, 0,0,0xFF,0xFF };
+ if (!memcmp(prefix4in6, &client.in6.sin6_addr, 12))
+ {
+ // recreate as a sockaddr_in using the IPv4 IP
+ uint16_t sport = client.in6.sin6_port;
+ client.in4.sin_family = AF_INET;
+ client.in4.sin_port = sport;
+ memcpy(&client.in4.sin_addr.s_addr, client.in6.sin6_addr.s6_addr + 12, sizeof(uint32_t));
+
+ sport = server.in6.sin6_port;
+ server.in4.sin_family = AF_INET;
+ server.in4.sin_port = sport;
+ memcpy(&server.in4.sin_addr.s_addr, server.in6.sin6_addr.s6_addr + 12, sizeof(uint32_t));
+ }
+ }
+ else if (client.family() == AF_UNIX)
+ {
+ // Clients connecting via UNIX sockets don't have paths so give them
+ // the server path as defined in RFC 1459 section 8.1.1.
+ //
+ // strcpy is safe here because sizeof(sockaddr_un.sun_path) is equal on both.
+ strcpy(client.un.sun_path, server.un.sun_path);