Skip to content

Commit 10ff81d

Browse files
committed
exec gofmt on the code & fix some problems for test
1 parent f013ce9 commit 10ff81d

10 files changed

Lines changed: 90 additions & 116 deletions

File tree

.github/workflows/test.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ jobs:
129129
./librespeed-cli --local-json config_librespeed.json --server 2 --json --share --telemetry-level disabled | python3 -m json.tool
130130
131131
ping 10.66.0.2 -w 20 -c 10
132-
ping6 fd00:66:0::2 -w 20 -c 10 || true
132+
ping6 fd00:66:0::2 -w 20 -c 10
133133
# TODO: remove this temporal hack for linux
134134
ping awl-tester.awl -w 20 -c 10 || true
135135
@@ -232,6 +232,7 @@ jobs:
232232
./librespeed-cli --local-json config_librespeed.json --server 2 --json --share --telemetry-level disabled | python3 -m json.tool
233233
234234
ping 10.66.0.2 -c 10
235+
ping6 fd00:66:0::2 -c 10
235236
ping awl-tester.awl -c 10
236237
237238
sleep 1
@@ -252,6 +253,7 @@ jobs:
252253
./librespeed-cli.exe --local-json config_librespeed.json --server 2 --json --share --telemetry-level disabled | python3 -m json.tool
253254
254255
ping -w 20000 -n 10 10.66.0.2
256+
ping -6 -w 20000 -n 10 fd00:66:0::2
255257
ping -w 20000 -n 10 -a awl-tester.awl
256258
257259
# ---- VPN gateway server (exit-node) mode: runtime enable/disable round-trips OS state ----

application_test.go

Lines changed: 44 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -795,51 +795,6 @@ func TestUpdatePeerSettingsIPAddr(t *testing.T) {
795795
ts.NoError(err)
796796
})
797797

798-
t.Run("IPv6TunnelPackets", func(t *testing.T) {
799-
const packetSize = 1500
800-
const packetsCount = 10
801-
802-
peer2Config, err := peer1.api.KnownPeerConfig(peer2.PeerID())
803-
ts.NoError(err)
804-
805-
peer2IPv4 := net.ParseIP(peer2Config.IPAddr).To4()
806-
ts.NotNil(peer2IPv4)
807-
808-
awlSubnet4, err := netip.ParsePrefix(peer1.app.Conf.VPNConfig.IPNet)
809-
ts.NoError(err)
810-
awlSubnet6, err := netip.ParsePrefix(peer1.app.Conf.VPNConfig.IPNetV6)
811-
ts.NoError(err)
812-
813-
// Map IPv4 to IPv6 using the same logic as peerIPv6FromIPv4
814-
peer2IPv6 := make(net.IP, net.IPv6len)
815-
copy(peer2IPv6, awlSubnet6.Addr().AsSlice())
816-
v4Mask := net.CIDRMask(awlSubnet4.Bits(), 32)
817-
for i := 0; i < net.IPv4len; i++ {
818-
peer2IPv6[12+i] |= peer2IPv4[i] &^ v4Mask[i]
819-
}
820-
821-
// Configure tunnel for packet testing
822-
peer1.tun.SetInboundCapture(packetSize, nil)
823-
peer2.tun.SetInboundCapture(packetSize, nil)
824-
peer1.tun.ClearInboundCount()
825-
peer2.tun.ClearInboundCount()
826-
827-
// Wait for IP map to be ready
828-
time.Sleep(100 * time.Millisecond)
829-
830-
// Send IPv6 packets from peer1 to peer2
831-
packet := testPacketWithDestV6(packetSize, peer2IPv6.String())
832-
for i := 0; i < packetsCount; i++ {
833-
peer1.tun.Outbound <- [][]byte{packet}
834-
}
835-
836-
// Wait for packet processing
837-
time.Sleep(500 * time.Millisecond)
838-
839-
// Verify packet reception
840-
received := peer2.tun.InboundCount()
841-
ts.EqualValues(packetsCount, received)
842-
})
843798
}
844799

845800
func TestDisableVPNInterface(t *testing.T) {
@@ -980,6 +935,50 @@ func TestTunnelPackets(t *testing.T) {
980935
received2 := peer2.tun.InboundCount()
981936
ts.EqualValues(packetsCount, received1)
982937
ts.EqualValues(packetsCount, received2)
938+
939+
// --- IPv6 Routing Test ---
940+
peer2ConfigInPeer1, _ := peer1.app.Conf.GetPeer(peer2.PeerID())
941+
peer2IPv4 := net.ParseIP(peer2ConfigInPeer1.IPAddr).To4()
942+
943+
peer1ConfigInPeer2, _ := peer2.app.Conf.GetPeer(peer1.PeerID())
944+
peer1IPv4 := net.ParseIP(peer1ConfigInPeer2.IPAddr).To4()
945+
946+
awlSubnet4, _ := netip.ParsePrefix(peer1.app.Conf.VPNConfig.IPNet)
947+
awlSubnet6, _ := netip.ParsePrefix(peer1.app.Conf.VPNConfig.IPNetV6)
948+
v4Mask := net.CIDRMask(awlSubnet4.Bits(), 32)
949+
awlNet6 := &net.IPNet{IP: awlSubnet6.Addr().AsSlice(), Mask: net.CIDRMask(awlSubnet6.Bits(), 128)}
950+
baseV6 := awlNet6.IP.Mask(awlNet6.Mask).To16()
951+
952+
peer1IPv6 := make(net.IP, net.IPv6len)
953+
copy(peer1IPv6, baseV6)
954+
for i := 0; i < net.IPv4len; i++ {
955+
peer1IPv6[12+i] |= peer1IPv4[i] &^ v4Mask[i]
956+
}
957+
958+
peer2IPv6 := make(net.IP, net.IPv6len)
959+
copy(peer2IPv6, baseV6)
960+
for i := 0; i < net.IPv4len; i++ {
961+
peer2IPv6[12+i] |= peer2IPv4[i] &^ v4Mask[i]
962+
}
963+
964+
ts.t.Logf("DEBUG: peer1 IPNetV6: %v", peer1.app.Conf.VPNConfig.IPNetV6)
965+
ts.t.Logf("DEBUG: peer1IPv6 calculated: %s, peer2IPv6 calculated: %s", peer1IPv6.String(), peer2IPv6.String())
966+
967+
peer1.tun.ClearInboundCount()
968+
peer2.tun.ClearInboundCount()
969+
970+
// Send IPv6 packets from peer1 to peer2
971+
const ipv6PacketsCount = 10
972+
ipv6Packet := testPacketWithSrcDestV6(packetSize, peer1IPv6.String(), peer2IPv6.String())
973+
974+
for i := 0; i < ipv6PacketsCount; i++ {
975+
peer1.tun.Outbound <- [][]byte{ipv6Packet}
976+
time.Sleep(10 * time.Millisecond)
977+
}
978+
979+
time.Sleep(1 * time.Second)
980+
receivedIPv6 := peer2.tun.InboundCount()
981+
ts.EqualValues(ipv6PacketsCount, receivedIPv6, "peer2 should receive exactly %d IPv6 packets", ipv6PacketsCount)
983982
}
984983

985984
func BenchmarkTunnelPackets(b *testing.B) {

service/tunnel.go

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,13 @@ import (
66
"fmt"
77
"io"
88
"net"
9-
"strings"
109
"sync"
1110
"sync/atomic"
1211
"time"
1312

1413
"github.com/ipfs/go-log/v2"
1514
"github.com/libp2p/go-libp2p/core/network"
1615
"github.com/libp2p/go-libp2p/core/peer"
17-
"go.uber.org/zap"
1816

1917
"github.com/anywherelan/awl/awlevent"
2018
"github.com/anywherelan/awl/config"
@@ -34,7 +32,7 @@ type Tunnel struct {
3432
device *vpn.Device
3533
logger *log.ZapEventLogger
3634

37-
isClosed atomic.Bool
35+
isClosed atomic.Bool
3836
peersLock sync.RWMutex
3937
peerIDToPeer map[peer.ID]*VpnPeer
4038
// netIPToPeer maps both IPv4 and IPv6 string representations to a VpnPeer.
@@ -821,7 +819,7 @@ func readBatchFromChan(ch chan *vpn.Packet, buf []*vpn.Packet, offset int) []*vp
821819
// peerIPv6FromIPv4 derives a peer's IPv6 address from their IPv4 address
822820
// by taking the host portion of the IPv4 address (unmasked by the IPv4 subnet)
823821
// and mapping it into the custom IPv6 subnet.
824-
// Returns nil if subnets are invalid, if peerIPv4 is out of bounds,
822+
// Returns nil if subnets are invalid, if peerIPv4 is out of bounds,
825823
// or if the IPv6 subnet capacity is smaller than the IPv4 subnet capacity.
826824
func peerIPv6FromIPv4(peerIPv4 net.IP, awlSubnet4 *net.IPNet, awlSubnet6 *net.IPNet) net.IP {
827825
if awlSubnet4 == nil || awlSubnet6 == nil {
@@ -839,7 +837,7 @@ func peerIPv6FromIPv4(peerIPv4 net.IP, awlSubnet4 *net.IPNet, awlSubnet6 *net.IP
839837
return nil
840838
}
841839

842-
// Capacity check: If IPv4 host bits exceed IPv6 host bits,
840+
// Capacity check: If IPv4 host bits exceed IPv6 host bits,
843841
// the IPv6 subnet cannot accommodate all addresses of the IPv4 subnet.
844842
v4HostBits := 32 - v4MaskLen
845843
v6HostBits := 128 - v6MaskLen
@@ -866,7 +864,7 @@ func peerIPv6FromIPv4(peerIPv4 net.IP, awlSubnet4 *net.IPNet, awlSubnet6 *net.IP
866864
}
867865

868866
// Align and embed the IPv4 host offset into the tail of the IPv6 address.
869-
// Since capacity is already verified (v4HostBits <= v6HostBits),
867+
// Since capacity is already verified (v4HostBits <= v6HostBits),
870868
// the IPv4 bytes safely fit into the trailing bytes of the IPv6 address.
871869
addr := make(net.IP, net.IPv6len)
872870
copy(addr, baseV6)
@@ -878,16 +876,3 @@ func peerIPv6FromIPv4(peerIPv4 net.IP, awlSubnet4 *net.IPNet, awlSubnet6 *net.IP
878876

879877
return addr
880878
}
881-
882-
func (t *Tunnel) logRoutingTable() {
883-
if !t.logger.Desugar().Core().Enabled(zap.DebugLevel) {
884-
return
885-
}
886-
// The caller HandleReadPackets already holds the RLock, so we don't need to take it again.
887-
routes := make([]string, 0, len(t.netIPToPeer))
888-
for ip, peer := range t.netIPToPeer {
889-
routes = append(routes, fmt.Sprintf(" %s -> %s", ip, peer.peerID))
890-
}
891-
// Use a single log call to avoid interleaving
892-
t.logger.Debug("Dumping IPv4/IPv6 routing table:\n" + strings.Join(routes, "\n"))
893-
}

service/tunnel_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ func TestPeerIPv6FromIPv4(t *testing.T) {
4646
{
4747
name: "capacity mismatch v4 host bits > v6 host bits",
4848
peerIPv4: "10.66.0.5",
49-
awlSubnet4: "10.66.0.0/16", // 16 host bits
49+
awlSubnet4: "10.66.0.0/16", // 16 host bits
5050
awlSubnet6: "fd00:66::/120", // 8 host bits
51-
expected: "", // expected nil
51+
expected: "", // expected nil
5252
},
5353
{
5454
name: "invalid mask lengths (v4)",

test_suite_test.go

Lines changed: 31 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"context"
66
"crypto/rand"
7+
"encoding/binary"
78
"encoding/hex"
89
"errors"
910
"fmt"
@@ -549,8 +550,8 @@ func testPacket(length int) []byte {
549550
return testPacketWithDest(length, "10.66.0.2")
550551
}
551552

552-
func testPacketWithSrcDest(length int, srcIP, destIP string) []byte {
553-
data, err := hex.DecodeString("4500002828f540004011fd490a4200010a420002a9d0238200148bfd68656c6c6f20776f726c6421")
553+
func buildPacketFromHex(length int, srcIP, destIP net.IP, hexStr string) []byte {
554+
data, err := hex.DecodeString(hexStr)
554555
if err != nil {
555556
panic(err)
556557
}
@@ -572,69 +573,57 @@ func testPacketWithSrcDest(length int, srcIP, destIP string) []byte {
572573
}
573574
vpnPacket.Parse()
574575

576+
if srcIP != nil {
577+
copy(vpnPacket.Src, srcIP)
578+
}
579+
if destIP != nil {
580+
copy(vpnPacket.Dst, destIP)
581+
}
582+
583+
vpnPacket.RecalculateChecksum()
584+
585+
return vpnPacket.Packet
586+
}
587+
588+
func testPacketWithSrcDest(length int, srcIP, destIP string) []byte {
575589
srcIPParsed := net.ParseIP(srcIP).To4()
576590
if srcIPParsed == nil {
577591
panic(fmt.Sprintf("invalid source IP: %s", srcIP))
578592
}
579-
copy(vpnPacket.Src, srcIPParsed)
580-
581593
destIPParsed := net.ParseIP(destIP).To4()
582594
if destIPParsed == nil {
583595
panic(fmt.Sprintf("invalid destination IP: %s", destIP))
584596
}
585-
copy(vpnPacket.Dst, destIPParsed)
586-
587-
vpnPacket.RecalculateChecksum()
588-
589-
return vpnPacket.Packet
597+
return buildPacketFromHex(length, srcIPParsed, destIPParsed, "4500002828f540004011fd490a4200010a420002a9d0238200148bfd68656c6c6f20776f726c6421")
590598
}
591599

592600
func testPacketWithDest(length int, destIP string) []byte {
593601
return testPacketWithSrcDest(length, "10.66.0.1", destIP)
594602
}
595603

596604
func testPacketWithSrcDestV6(length int, srcIP, destIP string) []byte {
597-
data, err := hex.DecodeString("6000000000141140fd000000000000000000000000000001fd00000000000000000000000000000204d2162e0014000068656c6c6f20776f726c6421")
598-
if err != nil {
599-
panic(err)
600-
}
601-
602-
packet := data
603-
if length > len(data) {
604-
packet = make([]byte, length)
605-
copy(packet, data)
606-
_, err = rand.Read(packet[len(data):])
607-
if err != nil {
608-
panic(err)
609-
}
610-
}
611-
612-
vpnPacket := vpn.Packet{}
613-
_, err = vpnPacket.ReadFrom(bytes.NewReader(packet))
614-
if err != nil {
615-
panic(err)
616-
}
617-
vpnPacket.Parse()
618-
619605
srcIPParsed := net.ParseIP(srcIP).To16()
620606
if srcIPParsed == nil {
621607
panic(fmt.Sprintf("invalid source IPv6: %s", srcIP))
622608
}
623-
copy(vpnPacket.Src, srcIPParsed)
624-
625609
destIPParsed := net.ParseIP(destIP).To16()
626610
if destIPParsed == nil {
627611
panic(fmt.Sprintf("invalid destination IPv6: %s", destIP))
628612
}
629-
copy(vpnPacket.Dst, destIPParsed)
630-
631-
vpnPacket.RecalculateChecksum()
632-
633-
return vpnPacket.Packet
634-
}
635-
636-
func testPacketWithDestV6(length int, destIP string) []byte {
637-
return testPacketWithSrcDestV6(length, "fd00:66:0::1", destIP)
613+
packet := buildPacketFromHex(length, srcIPParsed, destIPParsed, "6000000000141140fd000000000000000000000000000001fd00000000000000000000000000000204d2162e0014000068656c6c6f20776f726c6421")
614+
if length > 40 {
615+
payloadLen := uint16(length - 40)
616+
binary.BigEndian.PutUint16(packet[4:], payloadLen)
617+
binary.BigEndian.PutUint16(packet[44:], payloadLen)
618+
619+
// Recalculate checksum after modifying lengths
620+
vpnPacket := vpn.Packet{}
621+
vpnPacket.Packet = packet
622+
if vpnPacket.Parse() {
623+
vpnPacket.RecalculateChecksum()
624+
}
625+
}
626+
return packet
638627
}
639628

640629
// parsePacketIPs extracts src and dst IPs from a raw IPv4 packet.

vpn/netstate/nat_linux.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ func setupIptables6(ipt6 *iptables.IPTables, state *natState) error {
208208
return fmt.Errorf("add IPv6 DROP rule for %s to %s: %w", priv, awlForwardChain6, err)
209209
}
210210
}
211-
211+
212212
if err := ipt6.Append("filter", awlForwardChain6, "-j", "ACCEPT"); err != nil {
213213
return fmt.Errorf("add ACCEPT rule to %s: %w", awlForwardChain6, err)
214214
}

vpn/netstate/private_subnets.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,4 @@ func parsePrefixList(subnets []string, name string) []netip.Prefix {
6262
prefixes = append(prefixes, p)
6363
}
6464
return prefixes
65-
}
65+
}

vpn/netstate/routes_linux.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ package netstate
55
import (
66
"errors"
77
"fmt"
8+
"golang.org/x/sys/unix"
89
"net"
910
"syscall"
10-
"golang.org/x/sys/unix"
1111

1212
"github.com/vishvananda/netlink"
1313
)

vpn/packet.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import (
1212
)
1313

1414
const (
15-
IPProtocolTCP = 6
16-
IPProtocolUDP = 17
15+
IPProtocolTCP = 6
16+
IPProtocolUDP = 17
1717
IPProtocolICMPv6 = 58
1818

1919
ipv4offsetChecksum = 10
@@ -278,7 +278,6 @@ func checksumIPv6TCPUDP(headerAndPayload []byte, protocol uint32, srcIP net.IP,
278278
return tcpipChecksum(headerAndPayload, csum)
279279
}
280280

281-
282281
// Calculate the TCP/IP checksum defined in rfc1071. The passed-in csum is any
283282
// initial checksum data that's already been computed.
284283
// Borrowed from google/gopacket

vpn/packet_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func TestPacket_RecalculateChecksum_IPv6(t *testing.T) {
2828
packet.RecalculateChecksum()
2929
// Just verify it doesn't crash and actually modifies the checksum if it was 0000
3030
a.NotEqual(rawData, packet.Packet)
31-
31+
3232
// Test idempotency
3333
firstRecalculate := append([]byte(nil), packet.Packet...)
3434
packet.RecalculateChecksum()

0 commit comments

Comments
 (0)