@@ -18,6 +18,7 @@ public final class MaxMindDbReader implements Closeable {
1818 (byte ) 0xCD , (byte ) 0xEF , 'M' , 'a' , 'x' , 'M' , 'i' , 'n' , 'd' , '.' ,
1919 'c' , 'o' , 'm' };
2020
21+ private int ipV4Start ;
2122 private final Decoder decoder ;
2223 private final Metadata metadata ;
2324 private final ThreadBuffer threadBuffer ;
@@ -93,20 +94,11 @@ private int findAddressInTree(InetAddress address)
9394 throws InvalidDatabaseException {
9495 byte [] rawAddress = address .getAddress ();
9596
96- boolean isIp4AddressInIp6Db = rawAddress .length == 4
97- && this .metadata .ipVersion == 6 ;
98- int ipStartBit = isIp4AddressInIp6Db ? 96 : 0 ;
97+ int nodeNum = this .startNode (rawAddress .length * 8 );
9998
100- // The first node of the tree is always node 0, at the beginning of the
101- // value
102- int nodeNum = 0 ;
103-
104- for (int i = 0 ; i < rawAddress .length * 8 + ipStartBit ; i ++) {
105- int bit = 0 ;
106- if (i >= ipStartBit ) {
107- int b = 0xFF & rawAddress [(i - ipStartBit ) / 8 ];
108- bit = 1 & (b >> 7 - (i % 8 ));
109- }
99+ for (int i = 0 ; i < rawAddress .length * 8 ; i ++) {
100+ int b = 0xFF & rawAddress [i / 8 ];
101+ int bit = 1 & (b >> 7 - (i % 8 ));
110102 int record = this .readNode (nodeNum , bit );
111103
112104 if (record == this .metadata .nodeCount ) {
@@ -122,6 +114,35 @@ int record = this.readNode(nodeNum, bit);
122114 throw new InvalidDatabaseException ("Something bad happened" );
123115 }
124116
117+ private int startNode (int length ) throws InvalidDatabaseException {
118+ // Check if we are looking up an IPv4 address in an IPv6 tree. If this
119+ // is the case, we can skip over the first 96 nodes.
120+ if (this .metadata .ipVersion == 6 && length == 32 ) {
121+ return this .ipV4StartNode ();
122+ }
123+ // The first node of the tree is always node 0, at the beginning of the
124+ // value
125+ return 0 ;
126+ }
127+
128+ private int ipV4StartNode () throws InvalidDatabaseException {
129+ // This is a defensive check. There is no reason to call this when you
130+ // have an IPv4 tree.
131+ if (this .metadata .ipVersion == 4 ) {
132+ return 0 ;
133+ }
134+
135+ if (this .ipV4Start != 0 ) {
136+ return this .ipV4Start ;
137+ }
138+ int nodeNum = 0 ;
139+ for (int i = 0 ; i < 96 ; i ++) {
140+ nodeNum = this .readNode (nodeNum , 0 );
141+ }
142+ this .ipV4Start = nodeNum ;
143+ return nodeNum ;
144+ }
145+
125146 private int readNode (int nodeNumber , int index )
126147 throws InvalidDatabaseException {
127148 ByteBuffer buffer = this .threadBuffer .get ();
0 commit comments