Check in all of it
2 files changed, 133 insertions(+), 0 deletions(-)

A => excuses.go
A => main.go
A => excuses.go +53 -0
@@ 0,0 1,53 @@ 
+package main
+
+var excuses = []string{
+	"Android doesn't support DHCPv6",
+	"AWS doesn't support it",
+	"Azure doesn't support it",
+	"Can't we just buy more IPv4 addresses?",
+	"Did you mean IPTV?",
+	"End users don't care about IPv6",
+	"Github doesn't support IPv6",
+	"Hex is hard",
+	"I don't want to expose my MAC address",
+	"I don't want to lose the security provided by NAT",
+	"IPv6 addresses are too long to remember",
+	"IPv6 is a security risk",
+	"IPv6 is just a fad",
+	"IPv6 isn't an Internet Standard yet",
+	"IPv6 isn't supported by OVH Cloud",
+	"IPv6 is slower than IPv4",
+	"IPv6 just isn't a priority",
+	"It'll break our GeoIP",
+	"It'll make it easier for the government to track me",
+	"It's not mature enough",
+	"It's not supported by Google Compute",
+	"It's on our roadmap",
+	"It's too complicated",
+	"It's too hard to support",
+	"Larger headers are less efficient",
+	"My transit provider doesn't support IPv6",
+	"NAT444 is fine",
+	"None of our customers want it",
+	"Our business intelligence team can't even parse IPv4 logfiles",
+	"Our Dynamic DNS doesn't support it",
+	"Our Lawful Intercept doesn't support IPv6 yet",
+	"Our recursive DNS can't handle the extra load",
+	"Our vendor doesn't support it",
+	"There's no certification track",
+	"There's no ROI on deploying IPv6",
+	"Those stupid Privacy Extension addresses keep changing",
+	"Too many people have broken IPv6 stacks",
+	"Vendor bugs",
+	"We can use RFC6598",
+	"We don't have a lab to test it",
+	"We don't need that many addresses",
+	"We forgot to include IPv6 in our last RFP",
+	"We have IPv6, but we just want to keep things simple",
+	"We have no roadmap for native IPv6 as we rolled out 6RD.",
+	"We'll deploy IPv6 right after we deploy DNSSEC",
+	"We've still got plenty of IPv4",
+	"We would have to rewrite our entire application to support it",
+	"What do you mean I have to wrap an IP in square brackets?",
+	"What's IPv6?",
+}

          
A => main.go +80 -0
@@ 0,0 1,80 @@ 
+package main
+
+import (
+	"flag"
+	"fmt"
+	"math/rand"
+	"net"
+	"time"
+)
+
+var (
+	header = "Today's excuse to not implement IPv6 is:"
+	footer = "Brought to you courtesy https://ipv6excuses.com/"
+	past time.Time
+)
+
+func pickExcuse() string {
+	index := rand.Intn(len(excuses))
+	excuse := excuses[index]
+	return fmt.Sprintf("%s\n\n%s\n\n%s\n", header, excuse, footer)
+}
+
+func listenUDP(address string) {
+	udpAddr, err := net.ResolveUDPAddr("udp", address)
+	if err != nil {
+		panic(err)
+	}
+	c, err := net.ListenUDP("udp", udpAddr)
+	if err != nil {
+		panic(err)
+	}
+
+	for {
+		_, ret, err := c.ReadFrom(nil)
+		if err != nil {
+			panic(err)
+		}
+		excuse := pickExcuse()
+		c.WriteTo([]byte(excuse), ret)
+	}
+}
+
+func listenTCP(address string) {
+	tcpAddr, err := net.ResolveTCPAddr("tcp", address)
+	if err != nil {
+		panic(err)
+	}
+
+	c, err := net.ListenTCP("tcp", tcpAddr)
+	if err != nil {
+		panic(err)
+	}
+	defer c.Close()
+
+	for {
+		conn, err := c.AcceptTCP()
+		if err != nil {
+			panic(err)
+		}
+		go func() {
+			excuse := pickExcuse()
+			conn.SetLinger(3)
+			conn.Write([]byte(excuse))
+			conn.SetReadDeadline(past)
+			conn.Close()
+		}()
+	}
+}
+
+func main() {
+	var address = flag.String("address", "0.0.0.0", "Address to listen on")
+	var port = flag.Int("port", 17, "Port to listen on")
+	flag.Parse()
+
+	addr := fmt.Sprintf("%s:%d", *address, *port)
+
+	go listenTCP(addr)
+	go listenUDP(addr)
+	select { }
+}