8
8
import java .util .*;
9
9
import java .util .regex .*;
10
10
import java .math .BigInteger ;
11
+ import java .nio .ByteBuffer ;
11
12
import java .nio .MappedByteBuffer ;
12
13
import java .nio .ByteOrder ;
13
14
import java .nio .channels .FileChannel ;
@@ -114,7 +115,7 @@ private enum Modes {
114
115
private boolean AS_ENABLED ;
115
116
private boolean LASTSEEN_ENABLED ;
116
117
117
- private static final String _ModuleVersion = "2.1 .0" ;
118
+ private static final String _ModuleVersion = "2.2 .0" ;
118
119
119
120
public IP2Proxy () {
120
121
@@ -372,16 +373,29 @@ private boolean LoadBIN() throws IOException {
372
373
_IPv6ColumnSize = 16 + ((_DBColumn - 1 ) << 2 ); // 4 bytes each column, except IPFrom column which is 16 bytes
373
374
374
375
// since both IPv4 and IPv6 use 4 bytes for the below columns, can just do it once here
375
- COUNTRY_POSITION_OFFSET = (COUNTRY_POSITION [_DBType ] != 0 ) ? (COUNTRY_POSITION [_DBType ] - 1 ) << 2 : 0 ;
376
- REGION_POSITION_OFFSET = (REGION_POSITION [_DBType ] != 0 ) ? (REGION_POSITION [_DBType ] - 1 ) << 2 : 0 ;
377
- CITY_POSITION_OFFSET = (CITY_POSITION [_DBType ] != 0 ) ? (CITY_POSITION [_DBType ] - 1 ) << 2 : 0 ;
378
- ISP_POSITION_OFFSET = (ISP_POSITION [_DBType ] != 0 ) ? (ISP_POSITION [_DBType ] - 1 ) << 2 : 0 ;
379
- PROXYTYPE_POSITION_OFFSET = (PROXYTYPE_POSITION [_DBType ] != 0 ) ? (PROXYTYPE_POSITION [_DBType ] - 1 ) << 2 : 0 ;
380
- DOMAIN_POSITION_OFFSET = (DOMAIN_POSITION [_DBType ] != 0 ) ? (DOMAIN_POSITION [_DBType ] - 1 ) << 2 : 0 ;
381
- USAGETYPE_POSITION_OFFSET = (USAGETYPE_POSITION [_DBType ] != 0 ) ? (USAGETYPE_POSITION [_DBType ] - 1 ) << 2 : 0 ;
382
- ASN_POSITION_OFFSET = (ASN_POSITION [_DBType ] != 0 ) ? (ASN_POSITION [_DBType ] - 1 ) << 2 : 0 ;
383
- AS_POSITION_OFFSET = (AS_POSITION [_DBType ] != 0 ) ? (AS_POSITION [_DBType ] - 1 ) << 2 : 0 ;
384
- LASTSEEN_POSITION_OFFSET = (LASTSEEN_POSITION [_DBType ] != 0 ) ? (LASTSEEN_POSITION [_DBType ] - 1 ) << 2 : 0 ;
376
+ // COUNTRY_POSITION_OFFSET = (COUNTRY_POSITION[_DBType] != 0) ? (COUNTRY_POSITION[_DBType] - 1) << 2 : 0;
377
+ // REGION_POSITION_OFFSET = (REGION_POSITION[_DBType] != 0) ? (REGION_POSITION[_DBType] - 1) << 2 : 0;
378
+ // CITY_POSITION_OFFSET = (CITY_POSITION[_DBType] != 0) ? (CITY_POSITION[_DBType] - 1) << 2 : 0;
379
+ // ISP_POSITION_OFFSET = (ISP_POSITION[_DBType] != 0) ? (ISP_POSITION[_DBType] - 1) << 2 : 0;
380
+ // PROXYTYPE_POSITION_OFFSET = (PROXYTYPE_POSITION[_DBType] != 0) ? (PROXYTYPE_POSITION[_DBType] - 1) << 2 : 0;
381
+ // DOMAIN_POSITION_OFFSET = (DOMAIN_POSITION[_DBType] != 0) ? (DOMAIN_POSITION[_DBType] - 1) << 2 : 0;
382
+ // USAGETYPE_POSITION_OFFSET = (USAGETYPE_POSITION[_DBType] != 0) ? (USAGETYPE_POSITION[_DBType] - 1) << 2 : 0;
383
+ // ASN_POSITION_OFFSET = (ASN_POSITION[_DBType] != 0) ? (ASN_POSITION[_DBType] - 1) << 2 : 0;
384
+ // AS_POSITION_OFFSET = (AS_POSITION[_DBType] != 0) ? (AS_POSITION[_DBType] - 1) << 2 : 0;
385
+ // LASTSEEN_POSITION_OFFSET = (LASTSEEN_POSITION[_DBType] != 0) ? (LASTSEEN_POSITION[_DBType] - 1) << 2 : 0;
386
+
387
+ // slightly different offset for reading by row
388
+ COUNTRY_POSITION_OFFSET = (COUNTRY_POSITION [_DBType ] != 0 ) ? (COUNTRY_POSITION [_DBType ] - 2 ) << 2 : 0 ;
389
+ REGION_POSITION_OFFSET = (REGION_POSITION [_DBType ] != 0 ) ? (REGION_POSITION [_DBType ] - 2 ) << 2 : 0 ;
390
+ CITY_POSITION_OFFSET = (CITY_POSITION [_DBType ] != 0 ) ? (CITY_POSITION [_DBType ] - 2 ) << 2 : 0 ;
391
+ ISP_POSITION_OFFSET = (ISP_POSITION [_DBType ] != 0 ) ? (ISP_POSITION [_DBType ] - 2 ) << 2 : 0 ;
392
+ PROXYTYPE_POSITION_OFFSET = (PROXYTYPE_POSITION [_DBType ] != 0 ) ? (PROXYTYPE_POSITION [_DBType ] - 2 ) << 2 : 0 ;
393
+ DOMAIN_POSITION_OFFSET = (DOMAIN_POSITION [_DBType ] != 0 ) ? (DOMAIN_POSITION [_DBType ] - 2 ) << 2 : 0 ;
394
+ USAGETYPE_POSITION_OFFSET = (USAGETYPE_POSITION [_DBType ] != 0 ) ? (USAGETYPE_POSITION [_DBType ] - 2 ) << 2 : 0 ;
395
+ ASN_POSITION_OFFSET = (ASN_POSITION [_DBType ] != 0 ) ? (ASN_POSITION [_DBType ] - 2 ) << 2 : 0 ;
396
+ AS_POSITION_OFFSET = (AS_POSITION [_DBType ] != 0 ) ? (AS_POSITION [_DBType ] - 2 ) << 2 : 0 ;
397
+ LASTSEEN_POSITION_OFFSET = (LASTSEEN_POSITION [_DBType ] != 0 ) ? (LASTSEEN_POSITION [_DBType ] - 2 ) << 2 : 0 ;
398
+
385
399
386
400
COUNTRY_ENABLED = (COUNTRY_POSITION [_DBType ] != 0 ) ? true : false ;
387
401
REGION_ENABLED = (REGION_POSITION [_DBType ] != 0 ) ? true : false ;
@@ -477,7 +491,9 @@ public ProxyResult ProxyQuery(String IPAddress) throws IOException {
477
491
public ProxyResult ProxyQuery (String IPAddress , Modes Mode ) throws IOException {
478
492
ProxyResult Result = new ProxyResult ();
479
493
RandomAccessFile RF = null ;
480
- MappedByteBuffer Buf = null ;
494
+ // MappedByteBuffer Buf = null;
495
+ ByteBuffer Buf = null ;
496
+ ByteBuffer DataBuf = null ;
481
497
482
498
try {
483
499
if (IPAddress == null || IPAddress .length () == 0 ) {
@@ -538,7 +554,7 @@ public ProxyResult ProxyQuery(String IPAddress, Modes Mode) throws IOException {
538
554
return Result ;
539
555
}
540
556
541
- long CountryPos = 0 ;
557
+ long Pos = 0 ;
542
558
long Low = 0 ;
543
559
long High = 0 ;
544
560
long Mid = 0 ;
@@ -579,7 +595,9 @@ public ProxyResult ProxyQuery(String IPAddress, Modes Mode) throws IOException {
579
595
High = _DBCount ;
580
596
581
597
if (_UseMemoryMappedFile ) {
582
- Buf = _IPv4Buffer ;
598
+ // Buf = _IPv4Buffer;
599
+ Buf = _IPv4Buffer .duplicate (); // this enables this thread to maintain its own position in a multi-threaded environment
600
+ Buf .order (ByteOrder .LITTLE_ENDIAN );
583
601
BufCapacity = Buf .capacity ();
584
602
}
585
603
else {
@@ -611,7 +629,9 @@ public ProxyResult ProxyQuery(String IPAddress, Modes Mode) throws IOException {
611
629
High = _DBCountIPv6 ;
612
630
613
631
if (_UseMemoryMappedFile ) {
614
- Buf = _IPv6Buffer ;
632
+ // Buf = _IPv6Buffer;
633
+ Buf = _IPv6Buffer .duplicate (); // this enables this thread to maintain its own position in a multi-threaded environment
634
+ Buf .order (ByteOrder .LITTLE_ENDIAN );
615
635
BufCapacity = Buf .capacity ();
616
636
}
617
637
else {
@@ -654,73 +674,97 @@ public ProxyResult ProxyQuery(String IPAddress, Modes Mode) throws IOException {
654
674
String AS = MSG_NOT_SUPPORTED ;
655
675
String Last_Seen = MSG_NOT_SUPPORTED ;
656
676
677
+ int FirstCol = 4 ; // IP From is 4 bytes
657
678
if (IPType == 6 ) { // IPv6
658
- RowOffset = RowOffset + 12 ; // coz below is assuming all columns are 4 bytes, so got 12 left to go to make 16 bytes total
679
+ FirstCol = 16 ; // IPv6 is 16 bytes
680
+ // RowOffset = RowOffset + 12; // coz below is assuming all columns are 4 bytes, so got 12 left to go to make 16 bytes total
681
+ }
682
+
683
+ // read the row here after the IP From column (remaining columns are all 4 bytes)
684
+ int RowLen = ColumnSize - FirstCol ;
685
+ byte [] Row ;
686
+ Row = ReadRow (RowOffset + FirstCol , RowLen , Buf , RF );
687
+
688
+ if (_UseMemoryMappedFile ) {
689
+ DataBuf = _MapDataBuffer .duplicate (); // this is to enable reading of a range of bytes in multi-threaded environment
690
+ DataBuf .order (ByteOrder .LITTLE_ENDIAN );
659
691
}
660
692
661
693
if (PROXYTYPE_ENABLED ) {
662
694
if (Mode == Modes .ALL || Mode == Modes .PROXY_TYPE || Mode == Modes .IS_PROXY ) {
663
- Proxy_Type = ReadStr (Read32 (RowOffset + PROXYTYPE_POSITION_OFFSET , Buf , RF ).longValue (), RF );
695
+ // Proxy_Type = ReadStr(Read32(RowOffset + PROXYTYPE_POSITION_OFFSET, Buf, RF).longValue(), RF);
696
+ Proxy_Type = ReadStr (Read32_Row (Row , PROXYTYPE_POSITION_OFFSET ).longValue (), DataBuf , RF );
664
697
}
665
698
}
666
699
667
700
if (COUNTRY_ENABLED ) {
668
701
if (Mode == Modes .ALL || Mode == Modes .COUNTRY_SHORT || Mode == Modes .COUNTRY_LONG || Mode == Modes .IS_PROXY ) {
669
- CountryPos = Read32 (RowOffset + COUNTRY_POSITION_OFFSET , Buf , RF ).longValue ();
702
+ // CountryPos = Read32(RowOffset + COUNTRY_POSITION_OFFSET, Buf, RF).longValue();
703
+ Pos = Read32_Row (Row , COUNTRY_POSITION_OFFSET ).longValue ();
670
704
}
671
705
if (Mode == Modes .ALL || Mode == Modes .COUNTRY_SHORT || Mode == Modes .IS_PROXY ) {
672
- Country_Short = ReadStr (CountryPos , RF );
706
+ // Country_Short = ReadStr(CountryPos, RF);
707
+ Country_Short = ReadStr (Pos , DataBuf , RF );
673
708
}
674
709
if (Mode == Modes .ALL || Mode == Modes .COUNTRY_LONG ) {
675
- Country_Long = ReadStr (CountryPos + 3 , RF );
710
+ // Country_Long = ReadStr(CountryPos + 3, RF);
711
+ Country_Long = ReadStr (Pos + 3 , DataBuf , RF );
676
712
}
677
713
}
678
714
679
715
if (REGION_ENABLED ) {
680
716
if (Mode == Modes .ALL || Mode == Modes .REGION ) {
681
- Region = ReadStr (Read32 (RowOffset + REGION_POSITION_OFFSET , Buf , RF ).longValue (), RF );
717
+ // Region = ReadStr(Read32(RowOffset + REGION_POSITION_OFFSET, Buf, RF).longValue(), RF);
718
+ Region = ReadStr (Read32_Row (Row , REGION_POSITION_OFFSET ).longValue (), DataBuf , RF );
682
719
}
683
720
}
684
721
685
722
if (CITY_ENABLED ) {
686
723
if (Mode == Modes .ALL || Mode == Modes .CITY ) {
687
- City = ReadStr (Read32 (RowOffset + CITY_POSITION_OFFSET , Buf , RF ).longValue (), RF );
724
+ // City = ReadStr(Read32(RowOffset + CITY_POSITION_OFFSET, Buf, RF).longValue(), RF);
725
+ City = ReadStr (Read32_Row (Row , CITY_POSITION_OFFSET ).longValue (), DataBuf , RF );
688
726
}
689
727
}
690
728
691
729
if (ISP_ENABLED ) {
692
730
if (Mode == Modes .ALL || Mode == Modes .ISP ) {
693
- ISP = ReadStr (Read32 (RowOffset + ISP_POSITION_OFFSET , Buf , RF ).longValue (), RF );
731
+ // ISP = ReadStr(Read32(RowOffset + ISP_POSITION_OFFSET, Buf, RF).longValue(), RF);
732
+ ISP = ReadStr (Read32_Row (Row , ISP_POSITION_OFFSET ).longValue (), DataBuf , RF );
694
733
}
695
734
}
696
735
697
736
if (DOMAIN_ENABLED ) {
698
737
if (Mode == Modes .ALL || Mode == Modes .DOMAIN ) {
699
- Domain = ReadStr (Read32 (RowOffset + DOMAIN_POSITION_OFFSET , Buf , RF ).longValue (), RF );
738
+ // Domain = ReadStr(Read32(RowOffset + DOMAIN_POSITION_OFFSET, Buf, RF).longValue(), RF);
739
+ Domain = ReadStr (Read32_Row (Row , DOMAIN_POSITION_OFFSET ).longValue (), DataBuf , RF );
700
740
}
701
741
}
702
742
703
743
if (USAGETYPE_ENABLED ) {
704
744
if (Mode == Modes .ALL || Mode == Modes .USAGE_TYPE ) {
705
- Usage_Type = ReadStr (Read32 (RowOffset + USAGETYPE_POSITION_OFFSET , Buf , RF ).longValue (), RF );
745
+ // Usage_Type = ReadStr(Read32(RowOffset + USAGETYPE_POSITION_OFFSET, Buf, RF).longValue(), RF);
746
+ Usage_Type = ReadStr (Read32_Row (Row , USAGETYPE_POSITION_OFFSET ).longValue (), DataBuf , RF );
706
747
}
707
748
}
708
749
709
750
if (ASN_ENABLED ) {
710
751
if (Mode == Modes .ALL || Mode == Modes .ASN ) {
711
- ASN = ReadStr (Read32 (RowOffset + ASN_POSITION_OFFSET , Buf , RF ).longValue (), RF );
752
+ // ASN = ReadStr(Read32(RowOffset + ASN_POSITION_OFFSET, Buf, RF).longValue(), RF);
753
+ ASN = ReadStr (Read32_Row (Row , ASN_POSITION_OFFSET ).longValue (), DataBuf , RF );
712
754
}
713
755
}
714
756
715
757
if (AS_ENABLED ) {
716
758
if (Mode == Modes .ALL || Mode == Modes .AS ) {
717
- AS = ReadStr (Read32 (RowOffset + AS_POSITION_OFFSET , Buf , RF ).longValue (), RF );
759
+ // AS = ReadStr(Read32(RowOffset + AS_POSITION_OFFSET, Buf, RF).longValue(), RF);
760
+ AS = ReadStr (Read32_Row (Row , AS_POSITION_OFFSET ).longValue (), DataBuf , RF );
718
761
}
719
762
}
720
763
721
764
if (LASTSEEN_ENABLED ) {
722
765
if (Mode == Modes .ALL || Mode == Modes .LAST_SEEN ) {
723
- Last_Seen = ReadStr (Read32 (RowOffset + LASTSEEN_POSITION_OFFSET , Buf , RF ).longValue (), RF );
766
+ // Last_Seen = ReadStr(Read32(RowOffset + LASTSEEN_POSITION_OFFSET, Buf, RF).longValue(), RF);
767
+ Last_Seen = ReadStr (Read32_Row (Row , LASTSEEN_POSITION_OFFSET ).longValue (), DataBuf , RF );
724
768
}
725
769
}
726
770
@@ -1011,7 +1055,20 @@ private void Reverse(byte[] Arr) {
1011
1055
}
1012
1056
}
1013
1057
1014
- private BigInteger Read32Or128 (final long Position , final int IPType , final MappedByteBuffer Buf , final RandomAccessFile RH ) throws IOException {
1058
+ private byte [] ReadRow (final long Position , final long MyLen , final ByteBuffer Buf , final RandomAccessFile RH ) throws IOException {
1059
+ byte [] Row = new byte [(int )MyLen ];
1060
+ if (_UseMemoryMappedFile ) {
1061
+ Buf .position ((int )Position );
1062
+ Buf .get (Row , (int )0 , (int )MyLen );
1063
+ }
1064
+ else {
1065
+ RH .seek (Position - 1 );
1066
+ RH .read (Row , (int )0 , (int )MyLen );
1067
+ }
1068
+ return Row ;
1069
+ }
1070
+
1071
+ private BigInteger Read32Or128 (final long Position , final int IPType , final ByteBuffer Buf , final RandomAccessFile RH ) throws IOException {
1015
1072
if (IPType == 4 ) {
1016
1073
return Read32 (Position , Buf , RH );
1017
1074
}
@@ -1021,28 +1078,33 @@ else if (IPType == 6) {
1021
1078
return BigInteger .ZERO ;
1022
1079
}
1023
1080
1024
- private BigInteger Read128 (final long Position , final MappedByteBuffer Buf , final RandomAccessFile RH ) throws IOException {
1081
+ private BigInteger Read128 (final long Position , final ByteBuffer Buf , final RandomAccessFile RH ) throws IOException {
1025
1082
BigInteger RetVal = BigInteger .ZERO ;
1026
1083
final int BSize = 16 ;
1027
1084
byte Bytes [] = new byte [BSize ];
1028
1085
1029
1086
if (_UseMemoryMappedFile ) {
1030
- for (int x = 0 ; x < BSize ; x ++) {
1031
- Bytes [x ] = Buf .get ((int )Position + x ); // use absolute offset to be thread-safe
1032
- }
1087
+ Buf .position ((int )Position );
1088
+ Buf .get (Bytes , (int )0 , BSize );
1033
1089
}
1034
1090
else {
1035
1091
RH .seek (Position - 1 );
1036
- for (int x = 0 ; x < BSize ; x ++) {
1037
- Bytes [x ] = RH .readByte ();
1038
- }
1092
+ RH .read (Bytes , (int )0 , BSize );
1039
1093
}
1040
1094
Reverse (Bytes );
1041
1095
RetVal = new BigInteger (1 , Bytes );
1042
1096
return RetVal ;
1043
1097
}
1044
-
1045
- private BigInteger Read32 (final long Position , final MappedByteBuffer Buf , final RandomAccessFile RH ) throws IOException {
1098
+
1099
+ private BigInteger Read32_Row (byte [] Row , final int From ) throws IOException {
1100
+ final int Len = 4 ; // 4 bytes
1101
+ byte Bytes [] = new byte [Len ];
1102
+ System .arraycopy (Row , From , Bytes , (int )0 , Len );
1103
+ Reverse (Bytes );
1104
+ return new BigInteger (1 , Bytes );
1105
+ }
1106
+
1107
+ private BigInteger Read32 (final long Position , final ByteBuffer Buf , final RandomAccessFile RH ) throws IOException {
1046
1108
if (_UseMemoryMappedFile ) {
1047
1109
// simulate unsigned int by using long
1048
1110
return BigInteger .valueOf (Buf .getInt ((int )Position ) & 0xffffffffL ); // use absolute offset to be thread-safe
@@ -1051,27 +1113,24 @@ private BigInteger Read32(final long Position, final MappedByteBuffer Buf, final
1051
1113
final int BSize = 4 ;
1052
1114
RH .seek (Position - 1 );
1053
1115
byte Bytes [] = new byte [BSize ];
1054
- for (int x = 0 ; x < BSize ; x ++) {
1055
- Bytes [x ] = RH .readByte ();
1056
- }
1116
+ RH .read (Bytes , (int )0 , BSize );
1057
1117
Reverse (Bytes );
1058
1118
return new BigInteger (1 , Bytes );
1059
1119
}
1060
1120
}
1061
-
1062
- private String ReadStr (long Position , final RandomAccessFile RH ) throws IOException {
1121
+
1122
+ private String ReadStr (long Position , final ByteBuffer Buf , final RandomAccessFile RH ) throws IOException {
1063
1123
final int Size ;
1064
- char CBuf [] = null ;
1124
+ byte [] Bytes = null ;
1065
1125
1066
1126
if (_UseMemoryMappedFile ) {
1067
1127
Position = Position - _MapDataOffset ; // position stored in BIN file is for full file, not just the mapped data segment, so need to minus
1068
1128
Size = _MapDataBuffer .get ((int )Position ); // use absolute offset to be thread-safe
1069
1129
1070
1130
try {
1071
- CBuf = new char [Size ];
1072
- for (int x = 0 ; x < Size ; x ++) {
1073
- CBuf [x ] = (char )_MapDataBuffer .get ((int )Position + 1 + x ); // use absolute offset to be thread-safe
1074
- }
1131
+ Bytes = new byte [Size ];
1132
+ Buf .position ((int )Position + 1 );
1133
+ Buf .get (Bytes , (int )0 , Size );
1075
1134
}
1076
1135
catch (NegativeArraySizeException e ) {
1077
1136
return null ;
@@ -1081,16 +1140,16 @@ private String ReadStr(long Position, final RandomAccessFile RH) throws IOExcept
1081
1140
RH .seek (Position );
1082
1141
Size = RH .read ();
1083
1142
try {
1084
- CBuf = new char [Size ];
1085
- for (int x = 0 ; x < Size ; x ++) {
1086
- CBuf [x ] = (char )RH .read ();
1087
- }
1143
+ Bytes = new byte [Size ];
1144
+ RH .read (Bytes , (int )0 , Size );
1088
1145
}
1089
1146
catch (NegativeArraySizeException e ) {
1090
1147
return null ;
1091
1148
}
1092
1149
}
1093
- return String .copyValueOf (CBuf );
1150
+
1151
+ String S = new String (Bytes );
1152
+ return S ;
1094
1153
}
1095
1154
1096
1155
private BigInteger [] IP2No (String IP ) throws UnknownHostException {
@@ -1125,12 +1184,14 @@ else if (IA instanceof Inet4Address) { // this will run in cases of IPv4-mapped
1125
1184
IPType = "4" ;
1126
1185
A2 = A2 .shiftRight (80 );
1127
1186
A2 = A2 .and (LAST_32BITS );
1187
+ A3 = new BigInteger ("4" );
1128
1188
}
1129
1189
else if (A2 .compareTo (FROM_TEREDO ) >= 0 && A2 .compareTo (TO_TEREDO ) <= 0 ) {
1130
1190
// Teredo so need to remap to ipv4
1131
1191
IPType = "4" ;
1132
1192
A2 = A2 .not ();
1133
1193
A2 = A2 .and (LAST_32BITS );
1194
+ A3 = new BigInteger ("4" );
1134
1195
}
1135
1196
A1 = new BigInteger (IPType );
1136
1197
}
0 commit comments