@@ -14,12 +14,7 @@ type netNode struct {
14
14
pointer uint
15
15
}
16
16
17
- // networks represents a set of subnets that we are iterating over.
18
- type networks struct {
19
- err error
20
- reader * Reader
21
- nodes []netNode
22
- lastNode netNode
17
+ type networkOptions struct {
23
18
includeAliasedNetworks bool
24
19
}
25
20
@@ -29,12 +24,12 @@ var (
29
24
)
30
25
31
26
// NetworksOption are options for Networks and NetworksWithin.
32
- type NetworksOption func (* networks )
27
+ type NetworksOption func (* networkOptions )
33
28
34
29
// IncludeAliasedNetworks is an option for Networks and NetworksWithin
35
30
// that makes them iterate over aliases of the IPv4 subtree in an IPv6
36
31
// database, e.g., ::ffff:0:0/96, 2001::/32, and 2002::/16.
37
- func IncludeAliasedNetworks (networks * networks ) {
32
+ func IncludeAliasedNetworks (networks * networkOptions ) {
38
33
networks .includeAliasedNetworks = true
39
34
}
40
35
@@ -63,131 +58,111 @@ func (r *Reader) Networks(options ...NetworksOption) iter.Seq[Result] {
63
58
// If the provided prefix is contained within a network in the database, the
64
59
// iterator will iterate over exactly one network, the containing network.
65
60
func (r * Reader ) NetworksWithin (prefix netip.Prefix , options ... NetworksOption ) iter.Seq [Result ] {
66
- n := r .networksWithin (prefix , options ... )
67
61
return func (yield func (Result ) bool ) {
68
- for n .next () {
69
- if n .err != nil {
70
- yield (Result {err : n .err })
71
- return
72
- }
73
-
74
- ip := n .lastNode .ip
75
- if isInIPv4Subtree (ip ) {
76
- ip = v6ToV4 (ip )
77
- }
78
-
79
- offset , err := r .resolveDataPointer (n .lastNode .pointer )
80
- ok := yield (Result {
81
- decoder : r .decoder ,
82
- ip : ip ,
83
- offset : uint (offset ),
84
- prefixLen : uint8 (n .lastNode .bit ),
85
- err : err ,
62
+ if r .Metadata .IPVersion == 4 && prefix .Addr ().Is6 () {
63
+ yield (Result {
64
+ err : fmt .Errorf (
65
+ "error getting networks with '%s': you attempted to use an IPv6 network in an IPv4-only database" ,
66
+ prefix ,
67
+ ),
86
68
})
87
- if ! ok {
88
- return
89
- }
90
- }
91
- if n .err != nil {
92
- yield (Result {err : n .err })
69
+ return
93
70
}
94
- }
95
- }
96
71
97
- func (r * Reader ) networksWithin (prefix netip.Prefix , options ... NetworksOption ) * networks {
98
- if r .Metadata .IPVersion == 4 && prefix .Addr ().Is6 () {
99
- return & networks {
100
- err : fmt .Errorf (
101
- "error getting networks with '%s': you attempted to use an IPv6 network in an IPv4-only database" ,
102
- prefix ,
103
- ),
72
+ n := & networkOptions {}
73
+ for _ , option := range options {
74
+ option (n )
104
75
}
105
- }
106
-
107
- networks := & networks {reader : r }
108
- for _ , option := range options {
109
- option (networks )
110
- }
111
76
112
- ip := prefix .Addr ()
113
- netIP := ip
114
- stopBit := prefix .Bits ()
115
- if ip .Is4 () {
116
- netIP = v4ToV16 (ip )
117
- stopBit += 96
118
- }
119
-
120
- pointer , bit := r .traverseTree (ip , 0 , stopBit )
77
+ ip := prefix .Addr ()
78
+ netIP := ip
79
+ stopBit := prefix .Bits ()
80
+ if ip .Is4 () {
81
+ netIP = v4ToV16 (ip )
82
+ stopBit += 96
83
+ }
121
84
122
- prefix , err := netIP .Prefix (bit )
123
- if err != nil {
124
- networks .err = fmt .Errorf ("prefixing %s with %d" , netIP , bit )
125
- }
85
+ pointer , bit := r .traverseTree (ip , 0 , stopBit )
126
86
127
- networks .nodes = []netNode {
128
- {
129
- ip : prefix .Addr (),
130
- bit : uint (bit ),
131
- pointer : pointer ,
132
- },
133
- }
87
+ prefix , err := netIP .Prefix (bit )
88
+ if err != nil {
89
+ yield (Result {
90
+ err : fmt .Errorf ("prefixing %s with %d" , netIP , bit ),
91
+ })
92
+ }
134
93
135
- return networks
136
- }
94
+ nodes := []netNode {
95
+ {
96
+ ip : prefix .Addr (),
97
+ bit : uint (bit ),
98
+ pointer : pointer ,
99
+ },
100
+ }
137
101
138
- // next prepares the next network for reading with the Network method. It
139
- // returns true if there is another network to be processed and false if there
140
- // are no more networks or if there is an error.
141
- func (n * networks ) next () bool {
142
- if n .err != nil {
143
- return false
144
- }
145
- for len (n .nodes ) > 0 {
146
- node := n .nodes [len (n .nodes )- 1 ]
147
- n .nodes = n .nodes [:len (n .nodes )- 1 ]
148
-
149
- for node .pointer != n .reader .Metadata .NodeCount {
150
- // This skips IPv4 aliases without hardcoding the networks that the writer
151
- // currently aliases.
152
- if ! n .includeAliasedNetworks && n .reader .ipv4Start != 0 &&
153
- node .pointer == n .reader .ipv4Start && ! isInIPv4Subtree (node .ip ) {
154
- break
155
- }
102
+ for len (nodes ) > 0 {
103
+ node := nodes [len (nodes )- 1 ]
104
+ nodes = nodes [:len (nodes )- 1 ]
156
105
157
- if node .pointer > n .reader .Metadata .NodeCount {
158
- n .lastNode = node
159
- return true
160
- }
161
- ipRight := node .ip .As16 ()
162
- if len (ipRight ) <= int (node .bit >> 3 ) {
163
- displayAddr := node .ip
164
- displayBits := node .bit
165
- if isInIPv4Subtree (node .ip ) {
166
- displayAddr = v6ToV4 (displayAddr )
167
- displayBits -= 96
106
+ for node .pointer != r .Metadata .NodeCount {
107
+ // This skips IPv4 aliases without hardcoding the networks that the writer
108
+ // currently aliases.
109
+ if ! n .includeAliasedNetworks && r .ipv4Start != 0 &&
110
+ node .pointer == r .ipv4Start && ! isInIPv4Subtree (node .ip ) {
111
+ break
168
112
}
169
113
170
- n .err = newInvalidDatabaseError (
171
- "invalid search tree at %s/%d" , displayAddr , displayBits )
172
- return false
173
- }
174
- ipRight [node .bit >> 3 ] |= 1 << (7 - (node .bit % 8 ))
114
+ if node .pointer > r .Metadata .NodeCount {
115
+ ip := node .ip
116
+ if isInIPv4Subtree (ip ) {
117
+ ip = v6ToV4 (ip )
118
+ }
119
+
120
+ offset , err := r .resolveDataPointer (node .pointer )
121
+ ok := yield (Result {
122
+ decoder : r .decoder ,
123
+ ip : ip ,
124
+ offset : uint (offset ),
125
+ prefixLen : uint8 (node .bit ),
126
+ err : err ,
127
+ })
128
+ if ! ok {
129
+ return
130
+ }
131
+ break
132
+ }
133
+ ipRight := node .ip .As16 ()
134
+ if len (ipRight ) <= int (node .bit >> 3 ) {
135
+ displayAddr := node .ip
136
+ displayBits := node .bit
137
+ if isInIPv4Subtree (node .ip ) {
138
+ displayAddr = v6ToV4 (displayAddr )
139
+ displayBits -= 96
140
+ }
141
+
142
+ yield (Result {
143
+ ip : displayAddr ,
144
+ prefixLen : uint8 (node .bit ),
145
+ err : newInvalidDatabaseError (
146
+ "invalid search tree at %s/%d" , displayAddr , displayBits ),
147
+ })
148
+ return
149
+ }
150
+ ipRight [node .bit >> 3 ] |= 1 << (7 - (node .bit % 8 ))
175
151
176
- offset := node .pointer * n . reader .nodeOffsetMult
177
- rightPointer := n . reader .nodeReader .readRight (offset )
152
+ offset := node .pointer * r .nodeOffsetMult
153
+ rightPointer := r .nodeReader .readRight (offset )
178
154
179
- node .bit ++
180
- n . nodes = append (n . nodes , netNode {
181
- pointer : rightPointer ,
182
- ip : netip .AddrFrom16 (ipRight ),
183
- bit : node .bit ,
184
- })
155
+ node .bit ++
156
+ nodes = append (nodes , netNode {
157
+ pointer : rightPointer ,
158
+ ip : netip .AddrFrom16 (ipRight ),
159
+ bit : node .bit ,
160
+ })
185
161
186
- node .pointer = n .reader .nodeReader .readLeft (offset )
162
+ node .pointer = r .nodeReader .readLeft (offset )
163
+ }
187
164
}
188
165
}
189
-
190
- return false
191
166
}
192
167
193
168
var ipv4SubtreeBoundary = netip .MustParseAddr ("::255.255.255.255" ).Next ()
0 commit comments