From ffffbbcc8a3344a45c45884f11a1aee1407615ab Mon Sep 17 00:00:00 2001
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
Date: Mon, 21 Oct 2019 13:29:57 +0200
Subject: [PATCH] device: allow blackholing sockets

---
 device/boundif_windows.go |  6 ++++--
 device/conn_default.go    | 12 ++++++++++--
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/device/boundif_windows.go b/device/boundif_windows.go
index 7879a43..6908415 100644
--- a/device/boundif_windows.go
+++ b/device/boundif_windows.go
@@ -18,7 +18,7 @@ const (
 	sockoptIPV6_UNICAST_IF = 31
 )
 
-func (device *Device) BindSocketToInterface4(interfaceIndex uint32) error {
+func (device *Device) BindSocketToInterface4(interfaceIndex uint32, blackhole bool) error {
 	/* MSDN says for IPv4 this needs to be in net byte order, so that it's like an IP address with leading zeros. */
 	bytes := make([]byte, 4)
 	binary.BigEndian.PutUint32(bytes, interfaceIndex)
@@ -41,10 +41,11 @@ func (device *Device) BindSocketToInterface4(interfaceIndex uint32) error {
 	if err != nil {
 		return err
 	}
+	device.net.bind.(*nativeBind).blackhole4 = blackhole
 	return nil
 }
 
-func (device *Device) BindSocketToInterface6(interfaceIndex uint32) error {
+func (device *Device) BindSocketToInterface6(interfaceIndex uint32, blackhole bool) error {
 	sysconn, err := device.net.bind.(*nativeBind).ipv6.SyscallConn()
 	if err != nil {
 		return err
@@ -58,5 +59,6 @@ func (device *Device) BindSocketToInterface6(interfaceIndex uint32) error {
 	if err != nil {
 		return err
 	}
+	device.net.bind.(*nativeBind).blackhole6 = blackhole
 	return nil
 }
diff --git a/device/conn_default.go b/device/conn_default.go
index 820bb96..661f57d 100644
--- a/device/conn_default.go
+++ b/device/conn_default.go
@@ -21,8 +21,10 @@ import (
  */
 
 type nativeBind struct {
-	ipv4 *net.UDPConn
-	ipv6 *net.UDPConn
+	ipv4       *net.UDPConn
+	ipv6       *net.UDPConn
+	blackhole4 bool
+	blackhole6 bool
 }
 
 type NativeEndpoint net.UDPAddr
@@ -159,11 +161,17 @@ func (bind *nativeBind) Send(buff []byte, endpoint Endpoint) error {
 		if bind.ipv4 == nil {
 			return syscall.EAFNOSUPPORT
 		}
+		if bind.blackhole4 {
+			return nil
+		}
 		_, err = bind.ipv4.WriteToUDP(buff, (*net.UDPAddr)(nend))
 	} else {
 		if bind.ipv6 == nil {
 			return syscall.EAFNOSUPPORT
 		}
+		if bind.blackhole6 {
+			return nil
+		}
 		_, err = bind.ipv6.WriteToUDP(buff, (*net.UDPAddr)(nend))
 	}
 	return err