import (
"errors"
+ "golang.org/x/net/ipv4"
+ "golang.org/x/net/ipv6"
"net"
)
if netc.bind != nil {
err = netc.bind.Close()
netc.bind = nil
- netc.update.Add(1)
}
return err
}
if device.tun.isUp.Get() {
+ device.log.Debug.Println("UDP bind updating")
+
// bind to new port
var err 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
package main
import (
- "golang.org/x/net/ipv4"
- "golang.org/x/net/ipv6"
"runtime"
"sync"
"sync/atomic"
}
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
device.net.port = 0
device.net.bind = nil
- device.net.update.Add(1)
// start workers
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
}
}
func main() {
+
// parse arguments
var foreground bool
}
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() {
}
}
-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()
var endpoint Endpoint
- switch IPVersion {
+ switch IP {
case ipv4.Version:
size, err = bind.ReceiveIPv4(buffer[:], &endpoint)
case ipv6.Version:
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()
peer.TimerAnyAuthenticatedPacketReceived()
// update endpoint
- // TODO: Discover destination address also, only update on change
peer.mutex.Lock()
peer.endpoint.set = true
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()
}
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 {
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
}
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
}
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 "" "$*"; "$@"; }
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 ))
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
! 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
# 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
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
# 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
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"
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 {