@@ -16,6 +16,7 @@ type netNode struct {
16
16
17
17
type networkOptions struct {
18
18
includeAliasedNetworks bool
19
+ includeEmptyNetworks bool
19
20
}
20
21
21
22
var (
@@ -33,21 +34,30 @@ func IncludeAliasedNetworks(networks *networkOptions) {
33
34
networks .includeAliasedNetworks = true
34
35
}
35
36
36
- // Networks returns an iterator that can be used to traverse all networks in
37
+ // IncludeEmptyNetworks is an option for Networks and NetworksWithin
38
+ // that makes them include networks without any data in the iteration.
39
+ func IncludeEmptyNetworks (networks * networkOptions ) {
40
+ networks .includeEmptyNetworks = true
41
+ }
42
+
43
+ // Networks returns an iterator that can be used to traverse the networks in
37
44
// the database.
38
45
//
39
46
// Please note that a MaxMind DB may map IPv4 networks into several locations
40
47
// in an IPv6 database. This iterator will only iterate over these once by
41
48
// default. To iterate over all the IPv4 network locations, use the
42
49
// [IncludeAliasedNetworks] option.
50
+ //
51
+ // Networks without data are excluded by default. To include them, use
52
+ // [IncludeEmptyNetworks].
43
53
func (r * Reader ) Networks (options ... NetworksOption ) iter.Seq [Result ] {
44
54
if r .Metadata .IPVersion == 6 {
45
55
return r .NetworksWithin (allIPv6 , options ... )
46
56
}
47
57
return r .NetworksWithin (allIPv4 , options ... )
48
58
}
49
59
50
- // NetworksWithin returns an iterator that can be used to traverse all networks
60
+ // NetworksWithin returns an iterator that can be used to traverse the networks
51
61
// in the database which are contained in a given prefix.
52
62
//
53
63
// Please note that a MaxMind DB may map IPv4 networks into several locations
@@ -57,6 +67,9 @@ func (r *Reader) Networks(options ...NetworksOption) iter.Seq[Result] {
57
67
//
58
68
// If the provided prefix is contained within a network in the database, the
59
69
// iterator will iterate over exactly one network, the containing network.
70
+ //
71
+ // Networks without data are excluded by default. To include them, use
72
+ // [IncludeEmptyNetworks].
60
73
func (r * Reader ) NetworksWithin (prefix netip.Prefix , options ... NetworksOption ) iter.Seq [Result ] {
61
74
return func (yield func (Result ) bool ) {
62
75
if r .Metadata .IPVersion == 4 && prefix .Addr ().Is6 () {
@@ -106,7 +119,25 @@ func (r *Reader) NetworksWithin(prefix netip.Prefix, options ...NetworksOption)
106
119
node := nodes [len (nodes )- 1 ]
107
120
nodes = nodes [:len (nodes )- 1 ]
108
121
109
- for node .pointer != r .Metadata .NodeCount {
122
+ for {
123
+ if node .pointer == r .Metadata .NodeCount {
124
+ if n .includeEmptyNetworks {
125
+ ip := node .ip
126
+ if isInIPv4Subtree (ip ) {
127
+ ip = v6ToV4 (ip )
128
+ }
129
+
130
+ ok := yield (Result {
131
+ ip : ip ,
132
+ offset : notFound ,
133
+ prefixLen : uint8 (node .bit ),
134
+ })
135
+ if ! ok {
136
+ return
137
+ }
138
+ }
139
+ break
140
+ }
110
141
// This skips IPv4 aliases without hardcoding the networks that the writer
111
142
// currently aliases.
112
143
if ! n .includeAliasedNetworks && r .ipv4Start != 0 &&
0 commit comments