Initial working source caching
This commit is contained in:
		
							parent
							
								
									566269275e
								
							
						
					
					
						commit
						69fe86edf0
					
				@ -2,6 +2,8 @@ package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"golang.org/x/net/ipv4"
 | 
			
		||||
	"golang.org/x/net/ipv6"
 | 
			
		||||
	"net"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@ -42,7 +44,6 @@ func unsafeCloseUDPListener(device *Device) error {
 | 
			
		||||
	if netc.bind != nil {
 | 
			
		||||
		err = netc.bind.Close()
 | 
			
		||||
		netc.bind = nil
 | 
			
		||||
		netc.update.Add(1)
 | 
			
		||||
	}
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
@ -68,6 +69,8 @@ func UpdateUDPListener(device *Device) error {
 | 
			
		||||
 | 
			
		||||
	if device.tun.isUp.Get() {
 | 
			
		||||
 | 
			
		||||
		device.log.Debug.Println("UDP bind updating")
 | 
			
		||||
 | 
			
		||||
		// bind to new port
 | 
			
		||||
 | 
			
		||||
		var err error
 | 
			
		||||
@ -94,8 +97,10 @@ func UpdateUDPListener(device *Device) error {
 | 
			
		||||
 | 
			
		||||
		// decrease waitgroup to 0
 | 
			
		||||
 | 
			
		||||
		go device.RoutineReceiveIncomming(ipv4.Version, netc.bind)
 | 
			
		||||
		go device.RoutineReceiveIncomming(ipv6.Version, netc.bind)
 | 
			
		||||
 | 
			
		||||
		device.log.Debug.Println("UDP bind has been updated")
 | 
			
		||||
		netc.update.Done()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,6 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"golang.org/x/net/ipv4"
 | 
			
		||||
	"golang.org/x/net/ipv6"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
@ -23,10 +21,9 @@ type Device struct {
 | 
			
		||||
	}
 | 
			
		||||
	net struct {
 | 
			
		||||
		mutex  sync.RWMutex
 | 
			
		||||
		bind   UDPBind        // bind interface
 | 
			
		||||
		port   uint16         // listening port
 | 
			
		||||
		fwmark uint32         // mark value (0 = disabled)
 | 
			
		||||
		update sync.WaitGroup // the bind was updated (acting as a barrier)
 | 
			
		||||
		bind   UDPBind // bind interface
 | 
			
		||||
		port   uint16  // listening port
 | 
			
		||||
		fwmark uint32  // mark value (0 = disabled)
 | 
			
		||||
	}
 | 
			
		||||
	mutex        sync.RWMutex
 | 
			
		||||
	privateKey   NoisePrivateKey
 | 
			
		||||
@ -167,7 +164,6 @@ func NewDevice(tun TUNDevice, logLevel int) *Device {
 | 
			
		||||
 | 
			
		||||
	device.net.port = 0
 | 
			
		||||
	device.net.bind = nil
 | 
			
		||||
	device.net.update.Add(1)
 | 
			
		||||
 | 
			
		||||
	// start workers
 | 
			
		||||
 | 
			
		||||
@ -179,8 +175,6 @@ func NewDevice(tun TUNDevice, logLevel int) *Device {
 | 
			
		||||
	go device.RoutineReadFromTUN()
 | 
			
		||||
	go device.RoutineTUNEventReader()
 | 
			
		||||
	go device.ratelimiter.RoutineGarbageCollector(device.signal.stop)
 | 
			
		||||
	go device.RoutineReceiveIncomming(ipv4.Version)
 | 
			
		||||
	go device.RoutineReceiveIncomming(ipv6.Version)
 | 
			
		||||
	return device
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,7 @@ func printUsage() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
 | 
			
		||||
	// parse arguments
 | 
			
		||||
 | 
			
		||||
	var foreground bool
 | 
			
		||||
 | 
			
		||||
@ -20,12 +20,13 @@ type QueueHandshakeElement struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type QueueInboundElement struct {
 | 
			
		||||
	dropped int32
 | 
			
		||||
	mutex   sync.Mutex
 | 
			
		||||
	buffer  *[MaxMessageSize]byte
 | 
			
		||||
	packet  []byte
 | 
			
		||||
	counter uint64
 | 
			
		||||
	keyPair *KeyPair
 | 
			
		||||
	dropped  int32
 | 
			
		||||
	mutex    sync.Mutex
 | 
			
		||||
	buffer   *[MaxMessageSize]byte
 | 
			
		||||
	packet   []byte
 | 
			
		||||
	counter  uint64
 | 
			
		||||
	keyPair  *KeyPair
 | 
			
		||||
	endpoint Endpoint
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (elem *QueueInboundElement) Drop() {
 | 
			
		||||
@ -92,25 +93,13 @@ func (device *Device) addToHandshakeQueue(
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (device *Device) RoutineReceiveIncomming(IPVersion int) {
 | 
			
		||||
func (device *Device) RoutineReceiveIncomming(IP int, bind UDPBind) {
 | 
			
		||||
 | 
			
		||||
	logDebug := device.log.Debug
 | 
			
		||||
	logDebug.Println("Routine, receive incomming, IP version:", IPVersion)
 | 
			
		||||
	logDebug.Println("Routine, receive incomming, IP version:", IP)
 | 
			
		||||
 | 
			
		||||
	for {
 | 
			
		||||
 | 
			
		||||
		// wait for bind
 | 
			
		||||
 | 
			
		||||
		logDebug.Println("Waiting for UDP socket, IP version:", IPVersion)
 | 
			
		||||
 | 
			
		||||
		device.net.update.Wait()
 | 
			
		||||
		device.net.mutex.RLock()
 | 
			
		||||
		bind := device.net.bind
 | 
			
		||||
		device.net.mutex.RUnlock()
 | 
			
		||||
		if bind == nil {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// receive datagrams until conn is closed
 | 
			
		||||
 | 
			
		||||
		buffer := device.GetMessageBuffer()
 | 
			
		||||
@ -124,7 +113,7 @@ func (device *Device) RoutineReceiveIncomming(IPVersion int) {
 | 
			
		||||
 | 
			
		||||
			var endpoint Endpoint
 | 
			
		||||
 | 
			
		||||
			switch IPVersion {
 | 
			
		||||
			switch IP {
 | 
			
		||||
			case ipv4.Version:
 | 
			
		||||
				size, err = bind.ReceiveIPv4(buffer[:], &endpoint)
 | 
			
		||||
			case ipv6.Version:
 | 
			
		||||
@ -181,10 +170,11 @@ func (device *Device) RoutineReceiveIncomming(IPVersion int) {
 | 
			
		||||
 | 
			
		||||
				peer := value.peer
 | 
			
		||||
				elem := &QueueInboundElement{
 | 
			
		||||
					packet:  packet,
 | 
			
		||||
					buffer:  buffer,
 | 
			
		||||
					keyPair: keyPair,
 | 
			
		||||
					dropped: AtomicFalse,
 | 
			
		||||
					packet:   packet,
 | 
			
		||||
					buffer:   buffer,
 | 
			
		||||
					keyPair:  keyPair,
 | 
			
		||||
					dropped:  AtomicFalse,
 | 
			
		||||
					endpoint: endpoint,
 | 
			
		||||
				}
 | 
			
		||||
				elem.mutex.Lock()
 | 
			
		||||
 | 
			
		||||
@ -396,7 +386,6 @@ func (device *Device) RoutineHandshake() {
 | 
			
		||||
			peer.TimerAnyAuthenticatedPacketReceived()
 | 
			
		||||
 | 
			
		||||
			// update endpoint
 | 
			
		||||
			// TODO: Discover destination address also, only update on change
 | 
			
		||||
 | 
			
		||||
			peer.mutex.Lock()
 | 
			
		||||
			peer.endpoint.set = true
 | 
			
		||||
@ -453,6 +442,13 @@ func (device *Device) RoutineHandshake() {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// update endpoint
 | 
			
		||||
 | 
			
		||||
			peer.mutex.Lock()
 | 
			
		||||
			peer.endpoint.set = true
 | 
			
		||||
			peer.endpoint.value = elem.endpoint
 | 
			
		||||
			peer.mutex.Unlock()
 | 
			
		||||
 | 
			
		||||
			logDebug.Println("Received handshake initation from", peer)
 | 
			
		||||
 | 
			
		||||
			peer.TimerEphemeralKeyCreated()
 | 
			
		||||
@ -521,6 +517,13 @@ func (peer *Peer) RoutineSequentialReceiver() {
 | 
			
		||||
			}
 | 
			
		||||
			kp.mutex.Unlock()
 | 
			
		||||
 | 
			
		||||
			// update endpoint
 | 
			
		||||
 | 
			
		||||
			peer.mutex.Lock()
 | 
			
		||||
			peer.endpoint.set = true
 | 
			
		||||
			peer.endpoint.value = elem.endpoint
 | 
			
		||||
			peer.mutex.Unlock()
 | 
			
		||||
 | 
			
		||||
			// check for keep-alive
 | 
			
		||||
 | 
			
		||||
			if len(elem.packet) == 0 {
 | 
			
		||||
@ -552,7 +555,8 @@ func (peer *Peer) RoutineSequentialReceiver() {
 | 
			
		||||
 | 
			
		||||
				src := elem.packet[IPv4offsetSrc : IPv4offsetSrc+net.IPv4len]
 | 
			
		||||
				if device.routingTable.LookupIPv4(src) != peer {
 | 
			
		||||
					logInfo.Println("Packet with unallowed source IP from", peer.String())
 | 
			
		||||
					logInfo.Println(src)
 | 
			
		||||
					logInfo.Println("Packet with unallowed source IPv4 from", peer.String())
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
@ -577,7 +581,8 @@ func (peer *Peer) RoutineSequentialReceiver() {
 | 
			
		||||
 | 
			
		||||
				src := elem.packet[IPv6offsetSrc : IPv6offsetSrc+net.IPv6len]
 | 
			
		||||
				if device.routingTable.LookupIPv6(src) != peer {
 | 
			
		||||
					logInfo.Println("Packet with unallowed source IP from", peer.String())
 | 
			
		||||
					logInfo.Println(src)
 | 
			
		||||
					logInfo.Println("Packet with unallowed source IPv6 from", peer.String())
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,7 @@ netns0="wg-test-$$-0"
 | 
			
		||||
netns1="wg-test-$$-1"
 | 
			
		||||
netns2="wg-test-$$-2"
 | 
			
		||||
program="../wireguard-go"
 | 
			
		||||
export LOG_LEVEL="error"
 | 
			
		||||
export LOG_LEVEL="debug"
 | 
			
		||||
 | 
			
		||||
pretty() { echo -e "\x1b[32m\x1b[1m[+] ${1:+NS$1: }${2}\x1b[0m" >&3; }
 | 
			
		||||
pp() { pretty "" "$*"; "$@"; }
 | 
			
		||||
@ -147,6 +147,8 @@ tests() {
 | 
			
		||||
    n1 iperf3 -Z -n 1G -b 0 -u -c fd00::2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
echo "4"
 | 
			
		||||
 | 
			
		||||
[[ $(ip1 link show dev wg1) =~ mtu\ ([0-9]+) ]] && orig_mtu="${BASH_REMATCH[1]}"
 | 
			
		||||
big_mtu=$(( 34816 - 1500 + $orig_mtu ))
 | 
			
		||||
 | 
			
		||||
@ -185,14 +187,14 @@ ip0 -4 addr del 127.0.0.1/8 dev lo
 | 
			
		||||
ip0 -4 addr add 127.212.121.99/8 dev lo
 | 
			
		||||
n0 wg set wg1 listen-port 9999
 | 
			
		||||
n0 wg set wg1 peer "$pub2" endpoint 127.0.0.1:20000
 | 
			
		||||
n1 ping6 -W 1 -c 1 fd00::20000
 | 
			
		||||
[[ $(n2 wg show wg2 endpoints) == "$pub1    127.212.121.99:9999" ]]
 | 
			
		||||
n1 ping6 -W 1 -c 1 fd00::2
 | 
			
		||||
[[ $(n2 wg show wg2 endpoints) == "$pub1	127.212.121.99:9999" ]]
 | 
			
		||||
 | 
			
		||||
# Test using IPv6 that roaming works
 | 
			
		||||
n1 wg set wg1 listen-port 9998
 | 
			
		||||
n1 wg set wg1 peer "$pub2" endpoint [::1]:20000
 | 
			
		||||
n1 ping -W 1 -c 1 192.168.241.2
 | 
			
		||||
[[ $(n2 wg show wg2 endpoints) == "$pub1    [::1]:9998" ]]
 | 
			
		||||
[[ $(n2 wg show wg2 endpoints) == "$pub1	[::1]:9998" ]]
 | 
			
		||||
 | 
			
		||||
# Test that crypto-RP filter works
 | 
			
		||||
n1 wg set wg1 peer "$pub2" allowed-ips 192.168.241.0/24
 | 
			
		||||
@ -212,7 +214,7 @@ n2 ncat -u 192.168.241.1 1111 <<<"X"
 | 
			
		||||
! read -r -N 1 -t 1 out <&4
 | 
			
		||||
kill $nmap_pid
 | 
			
		||||
n0 wg set wg1 peer "$more_specific_key" remove
 | 
			
		||||
[[ $(n1 wg show wg1 endpoints) == "$pub2    [::1]:9997" ]]
 | 
			
		||||
[[ $(n1 wg show wg1 endpoints) == "$pub2	[::1]:9997" ]]
 | 
			
		||||
 | 
			
		||||
ip1 link del wg1
 | 
			
		||||
ip2 link del wg2
 | 
			
		||||
@ -232,8 +234,9 @@ ip2 link del wg2
 | 
			
		||||
# ip1 link add dev wg1 type wireguard
 | 
			
		||||
# ip2 link add dev wg1 type wireguard
 | 
			
		||||
 | 
			
		||||
n1 $program wg1
 | 
			
		||||
n2 $program wg2
 | 
			
		||||
n1 $program -f wg1 &
 | 
			
		||||
n2 $program -f wg2 &
 | 
			
		||||
sleep 5
 | 
			
		||||
 | 
			
		||||
configure_peers
 | 
			
		||||
 | 
			
		||||
@ -263,7 +266,7 @@ n0 iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -d 10.0.0.0/24 -j SNAT --to
 | 
			
		||||
n0 wg set wg1 peer "$pub2" endpoint 10.0.0.100:20000 persistent-keepalive 1
 | 
			
		||||
n1 ping -W 1 -c 1 192.168.241.2
 | 
			
		||||
n2 ping -W 1 -c 1 192.168.241.1
 | 
			
		||||
[[ $(n2 wg show wg2 endpoints) == "$pub1    10.0.0.1:10000" ]]
 | 
			
		||||
[[ $(n2 wg show wg2 endpoints) == "$pub1	10.0.0.1:10000" ]]
 | 
			
		||||
# Demonstrate n2 can still send packets to n1, since persistent-keepalive will prevent connection tracking entry from expiring (to see entries: `n0 conntrack -L`).
 | 
			
		||||
pp sleep 3
 | 
			
		||||
n2 ping -W 1 -c 1 192.168.241.1
 | 
			
		||||
@ -288,8 +291,9 @@ ip2 link del wg2
 | 
			
		||||
 | 
			
		||||
# ip1 link add dev wg1 type wireguard
 | 
			
		||||
# ip2 link add dev wg1 type wireguard
 | 
			
		||||
n1 $program wg1
 | 
			
		||||
n2 $program wg1
 | 
			
		||||
n1 $program -f wg1 &
 | 
			
		||||
n2 $program -f wg2 &
 | 
			
		||||
sleep 5
 | 
			
		||||
 | 
			
		||||
configure_peers
 | 
			
		||||
 | 
			
		||||
@ -336,17 +340,18 @@ waitiface $netns1 veth1
 | 
			
		||||
waitiface $netns2 veth2
 | 
			
		||||
n0 wg set wg2 peer "$pub1" endpoint 10.0.0.1:10000
 | 
			
		||||
n2 ping -W 1 -c 1 192.168.241.1
 | 
			
		||||
[[ $(n0 wg show wg2 endpoints) == "$pub1    10.0.0.1:10000" ]]
 | 
			
		||||
[[ $(n0 wg show wg2 endpoints) == "$pub1	10.0.0.1:10000" ]]
 | 
			
		||||
n0 wg set wg2 peer "$pub1" endpoint [fd00:aa::1]:10000
 | 
			
		||||
n2 ping -W 1 -c 1 192.168.241.1
 | 
			
		||||
[[ $(n0 wg show wg2 endpoints) == "$pub1    [fd00:aa::1]:10000" ]]
 | 
			
		||||
[[ $(n0 wg show wg2 endpoints) == "$pub1	[fd00:aa::1]:10000" ]]
 | 
			
		||||
n0 wg set wg2 peer "$pub1" endpoint 10.0.0.2:10000
 | 
			
		||||
n2 ping -W 1 -c 1 192.168.241.1
 | 
			
		||||
[[ $(n0 wg show wg2 endpoints) == "$pub1    10.0.0.2:10000" ]]
 | 
			
		||||
[[ $(n0 wg show wg2 endpoints) == "$pub1	10.0.0.2:10000" ]]
 | 
			
		||||
n0 wg set wg2 peer "$pub1" endpoint [fd00:aa::2]:10000
 | 
			
		||||
n2 ping -W 1 -c 1 192.168.241.1
 | 
			
		||||
[[ $(n0 wg show wg2 endpoints) == "$pub1    [fd00:aa::2]:10000" ]]
 | 
			
		||||
[[ $(n0 wg show wg2 endpoints) == "$pub1	[fd00:aa::2]:10000" ]]
 | 
			
		||||
 | 
			
		||||
ip1 link del veth1
 | 
			
		||||
ip1 link del wg1
 | 
			
		||||
ip2 link del wg2
 | 
			
		||||
echo "done"
 | 
			
		||||
 | 
			
		||||
@ -248,7 +248,6 @@ func ipcSetOperation(device *Device, socket *bufio.ReadWriter) *IPCError {
 | 
			
		||||
 | 
			
		||||
				peer.mutex.Lock()
 | 
			
		||||
				err := peer.endpoint.value.SetDst(value)
 | 
			
		||||
				fmt.Println(peer.endpoint.value.DstToString(), err)
 | 
			
		||||
				peer.endpoint.set = (err == nil)
 | 
			
		||||
				peer.mutex.Unlock()
 | 
			
		||||
				if err != nil {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user