+ ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "Can't get peername: %s", strerror(errno));
+ irc::sockets::aptosa(bind_addr, bind_port, server);
+ }
+
+ if (client.sa.sa_family == AF_INET6)
+ {
+ /*
+ * 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));
+ }
+ }
+
+ SocketEngine::NonBlocking(incomingSockfd);
+
+ ModResult res;
+ FIRST_MOD_RESULT(OnAcceptConnection, res, (incomingSockfd, this, &client, &server));
+ if (res == MOD_RES_PASSTHRU)
+ {
+ std::string type = bind_tag->getString("type", "clients");
+ if (type == "clients")
+ {
+ ServerInstance->Users->AddUser(incomingSockfd, this, &client, &server);
+ res = MOD_RES_ALLOW;
+ }
+ }
+ if (res == MOD_RES_ALLOW)
+ {
+ ServerInstance->stats.Accept++;
+ }
+ else
+ {
+ ServerInstance->stats.Refused++;
+ ServerInstance->Logs->Log("SOCKET", LOG_DEFAULT, "Refusing connection on %s - %s",
+ bind_desc.c_str(), res == MOD_RES_DENY ? "Connection refused by module" : "Module for this port not found");
+ SocketEngine::Close(incomingSockfd);