Skip to content

Commit

Permalink
test the IP address and subnet generation
Browse files Browse the repository at this point in the history
Test the IP address and subnet generation to avoid breaking the existing
generation when updating or refactoring it. Given that the subnet
generation uses some binary operations, it is hard to spot potential
errors.

For this usecase the function generating the subnet was externalized to
be accessible from the test code instead of an inlined function.
  • Loading branch information
Sven Püschel authored and pslldq committed Nov 18, 2024
1 parent 88dcf67 commit 018c0d4
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 25 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ jobs:
git diff --exit-code
go vet ./...
- name: Build project
- name: Build and test project
run: |
go test ./...
mkdir bin
GOBIN="$PWD/bin" CGO_ENABLED=0 go install ./...
Expand Down
50 changes: 26 additions & 24 deletions etcdconfigweb/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,31 @@ var MISSING_V6MTU = errors.New("Missing v6mtu query parameter")
var MISSING_PUBKEY = errors.New("Missing pubkey query parameter")
var MISSING_NONCE = errors.New("Missing nonce query parameter")

func generateNodeAddressesAndRanges(info *ffbs.NodeInfo) {
const V4_BASE uint32 = 10 << 24
const V4_RANGE_SIZE uint8 = 10
const V6_BASE_HIGH uint64 = 0x20010bf70381 << 16

num := *info.ID

var v4Addr [net.IPv4len]byte
binary.BigEndian.PutUint32(v4Addr[:], V4_BASE|(uint32(num)<<V4_RANGE_SIZE))
v4range := fmt.Sprintf("%s/%d", net.IP(v4Addr[:]), 8*net.IPv4len-V4_RANGE_SIZE)
v4Addr[net.IPv4len-1] = 1
v4addr := net.IP(v4Addr[:]).String()

var v6Addr [net.IPv6len]byte
binary.BigEndian.PutUint64(v6Addr[:8], V6_BASE_HIGH|uint64(num))
v6range := fmt.Sprintf("%s/64", net.IP(v6Addr[:]))
v6Addr[net.IPv6len-1] = 1
v6addr := net.IP(v6Addr[:]).String()

info.Address4 = &v4addr
info.Range4 = &v4range
info.Address6 = &v6addr
info.Range6 = &v6range
}

func (ch ConfigHandler) handleRequest(ctx context.Context, query url.Values, headers http.Header) (*ConfigResponse, error) {
var v6mtu uint64
var err error
Expand Down Expand Up @@ -80,30 +105,7 @@ func (ch ConfigHandler) handleRequest(ctx context.Context, query url.Values, hea
}

// insert new node
err := ch.etcdHandler.CreateNode(ctx, pubkey, func(info *ffbs.NodeInfo) {
const V4_BASE uint32 = 10 << 24
const V4_RANGE_SIZE uint8 = 10
const V6_BASE_HIGH uint64 = 0x20010bf70381 << 16

num := *info.ID

var v4Addr [net.IPv4len]byte
binary.BigEndian.PutUint32(v4Addr[:], V4_BASE|(uint32(num)<<V4_RANGE_SIZE))
v4range := fmt.Sprintf("%s/%d", net.IP(v4Addr[:]), 8*net.IPv4len-V4_RANGE_SIZE)
v4Addr[net.IPv4len-1] = 1
v4addr := net.IP(v4Addr[:]).String()

var v6Addr [net.IPv6len]byte
binary.BigEndian.PutUint64(v6Addr[:8], V6_BASE_HIGH|uint64(num))
v6range := fmt.Sprintf("%s/64", net.IP(v6Addr[:]))
v6Addr[net.IPv6len-1] = 1
v6addr := net.IP(v6Addr[:]).String()

info.Address4 = &v4addr
info.Range4 = &v4range
info.Address6 = &v6addr
info.Range6 = &v6range
})
err := ch.etcdHandler.CreateNode(ctx, pubkey, generateNodeAddressesAndRanges)
if err != nil {
return nil, err
}
Expand Down
31 changes: 31 additions & 0 deletions etcdconfigweb/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package main

import (
"testing"

"github.com/ffbs/etcd-tools/ffbs"

"github.com/stretchr/testify/assert"
)

func TestGenerateAddressesAndRanges(t *testing.T) {
// Using https://freifunk-bs.de/map/#!/de/map/f4068dcf9fe1 as an example
id := uint64(30)
node := ffbs.NodeInfo{ID: &id}
generateNodeAddressesAndRanges(&node)
assert.Equal(t, "10.0.120.1", *node.Address4)
assert.Equal(t, "10.0.120.0/22", *node.Range4)
assert.Equal(t, "2001:bf7:381:1e::1", *node.Address6)
assert.Equal(t, "2001:bf7:381:1e::/64", *node.Range6)
}

func TestGenerateHighestAddressesAndRanges(t *testing.T) {
// IPv4 base range is /8. Range of every subnet is /22 => 22-8 = 14 bits of freedom
id := uint64(16383)
node := ffbs.NodeInfo{ID: &id}
generateNodeAddressesAndRanges(&node)
assert.Equal(t, "10.255.252.1", *node.Address4)
assert.Equal(t, "10.255.252.0/22", *node.Range4)
assert.Equal(t, "2001:bf7:381:3fff::1", *node.Address6)
assert.Equal(t, "2001:bf7:381:3fff::/64", *node.Range6)
}
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ toolchain go1.22.9

require (
github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.9.0
go.etcd.io/etcd/client/v3 v3.5.17
go.seankhliao.com/signify v0.0.0-20200507101447-944db0e32d56
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6
Expand All @@ -14,6 +15,7 @@ require (
require (
github.com/coreos/go-semver v0.3.0 // indirect
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/ebfe/bcrypt_pbkdf v0.0.0-20140212075826-3c8d2dcb253a // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
Expand All @@ -23,6 +25,7 @@ require (
github.com/mdlayher/genetlink v1.3.2 // indirect
github.com/mdlayher/netlink v1.7.2 // indirect
github.com/mdlayher/socket v0.4.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
go.etcd.io/etcd/api/v3 v3.5.17 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.17 // indirect
Expand All @@ -40,4 +43,5 @@ require (
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/grpc v1.59.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
Expand Down

0 comments on commit 018c0d4

Please sign in to comment.