Changeset ef44c36


Ignore:
Timestamp:
Nov 20, 2018 2:14:34 PM (2 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
5c0c69c
Parents:
f1297e7c
Message:

GeoIP: Hook maxmind geoip2 code into transport lookup.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • router/java/src/net/i2p/router/transport/GeoIP.java

    rf1297e7c ref44c36  
    1717import java.util.concurrent.atomic.AtomicBoolean;
    1818
     19import com.maxmind.db.CHMCache;
    1920import com.maxmind.geoip.InvalidDatabaseException;
    2021import com.maxmind.geoip.LookupService;
     22import com.maxmind.geoip2.DatabaseReader;
    2123
    2224import net.i2p.I2PAppContext;
     
    6567    public static final String GEOIP_DIR_DEFAULT = "geoip";
    6668    static final String GEOIP_FILE_DEFAULT = "geoip.txt";
     69    static final String GEOIP2_FILE_DEFAULT = "GeoLite2-Country.mmdb";
    6770    static final String COUNTRY_FILE_DEFAULT = "countries.txt";
    6871    public static final String PROP_IP_COUNTRY = "i2np.lastCountry";
     
    7174    private static final String DEBIAN_GEOIP_FILE = "/usr/share/GeoIP/GeoIP.dat";
    7275    private static final String DEBIAN_GEOIPV6_FILE = "/usr/share/GeoIP/GeoIPv6.dat";
    73     private static final boolean ENABLE_DEBIAN = !(SystemVersion.isWindows() || SystemVersion.isAndroid());
     76    private static final boolean DISABLE_DEBIAN = false;
     77    private static final boolean ENABLE_DEBIAN = !DISABLE_DEBIAN && !(SystemVersion.isWindows() || SystemVersion.isAndroid());
    7478    /** maxmind API */
    7579    private static final String UNKNOWN_COUNTRY_CODE = "--";
     
    148152            if (_lock.getAndSet(true))
    149153                return;
     154            File geoip2 = getGeoIP2();
     155            DatabaseReader dbr = null;
    150156            try {
    151157                // clear the negative cache every few runs, to prevent it from getting too big
     
    159165                    File f = new File(_context.getProperty(PROP_DEBIAN_GEOIP, DEBIAN_GEOIP_FILE));
    160166                    if (ENABLE_DEBIAN && f.exists()) {
    161                         // Maxmind database
     167                        // Maxmind v1 database
    162168                        LookupService ls = null;
    163169                        try {
    164170                            ls = new LookupService(f, LookupService.GEOIP_STANDARD);
    165171                            for (int i = 0; i < search.length; i++) {
    166                                 long ip = search[i].longValue();
     172                                Long ipl = search[i];
     173                                long ip = ipl.longValue();
    167174                                // returns upper case or "--"
    168175                                String uc = ls.getCountry(ip).getCode();
    169176                                if (!uc.equals(UNKNOWN_COUNTRY_CODE)) {
    170177                                    String cached = _codeCache.get(uc.toLowerCase(Locale.US));
    171                                     _IPToCountry.put(search[i], cached);
     178                                    _IPToCountry.put(ipl, cached);
    172179                                } else {
    173                                     _notFound.add(search[i]);
     180                                    _notFound.add(ipl);
    174181                                }
    175182                            }
     
    180187                        } finally {
    181188                            if (ls != null) ls.close();
     189                        }
     190                    } else if (geoip2 != null) {
     191                        // Maxmind v2 database
     192                        try {
     193                            dbr = openGeoIP2(geoip2);
     194                            for (int i = 0; i < search.length; i++) {
     195                                Long ipl = search[i];
     196                                String ipv4 = toV4(ipl);
     197                                // returns upper case or null
     198                                String uc = dbr.country(ipv4);
     199                                if (uc != null) {
     200                                    String cached = _codeCache.get(uc.toLowerCase(Locale.US));
     201                                    _IPToCountry.put(ipl, cached);
     202                                } else {
     203                                    _notFound.add(ipl);
     204                                }
     205                            }
     206                        } catch (IOException ioe) {
     207                            _log.error("GeoIP2 failure", ioe);
    182208                        }
    183209                    } else {
     
    199225                    File f = new File(_context.getProperty(PROP_DEBIAN_GEOIPV6, DEBIAN_GEOIPV6_FILE));
    200226                    if (ENABLE_DEBIAN && f.exists()) {
    201                         // Maxmind database
     227                        // Maxmind v1 database
    202228                        LookupService ls = null;
    203229                        try {
    204230                            ls = new LookupService(f, LookupService.GEOIP_STANDARD);
    205231                            for (int i = 0; i < search.length; i++) {
    206                                 long ip = search[i].longValue();
     232                                Long ipl = search[i];
     233                                long ip = ipl.longValue();
    207234                                String ipv6 = toV6(ip);
    208235                                // returns upper case or "--"
     
    213240                                    if (cached == null)
    214241                                        cached = lc;
    215                                     _IPToCountry.put(search[i], cached);
     242                                    _IPToCountry.put(ipl, cached);
    216243                                } else {
    217                                     _notFound.add(search[i]);
     244                                    _notFound.add(ipl);
    218245                                }
    219246                            }
     
    225252                            if (ls != null) ls.close();
    226253                        }
    227                     } else {
    228                         // Tor-style database
     254                    } else if (geoip2 != null) {
     255                        // Maxmind v2 database
     256                        try {
     257                            if (dbr == null)
     258                                dbr = openGeoIP2(geoip2);
     259                            for (int i = 0; i < search.length; i++) {
     260                                Long ipl = search[i];
     261                                String ipv6 = toV6(ipl);
     262                                // returns upper case or null
     263                                String uc = dbr.country(ipv6);
     264                                if (uc != null) {
     265                                    String cached = _codeCache.get(uc.toLowerCase(Locale.US));
     266                                    _IPToCountry.put(ipl, cached);
     267                                } else {
     268                                    _notFound.add(ipl);
     269                                }
     270                            }
     271                        } catch (IOException ioe) {
     272                            _log.error("GeoIP2 failure", ioe);
     273                        }
     274                     } else {
     275                        // I2P format IPv6 database
    229276                        String[] countries = GeoIPv6.readGeoIPFile(_context, search, _codeCache);
    230277                        for (int i = 0; i < countries.length; i++) {
     
    237284                }
    238285            } finally {
     286                if (dbr != null) try { dbr.close(); } catch (IOException ioe) {}
    239287                _lock.set(false);
    240288            }
    241289        }
     290    }
     291
     292   /**
     293    * Get the GeoIP2 database file
     294    *
     295    * @return null if not found
     296    * @since 0.9.38
     297    */
     298    private File getGeoIP2() {
     299        String geoDir = _context.getProperty(PROP_GEOIP_DIR, GEOIP_DIR_DEFAULT);
     300        File geoFile = new File(geoDir);
     301        if (!geoFile.isAbsolute())
     302            geoFile = new File(_context.getBaseDir(), geoDir);
     303        geoFile = new File(geoFile, GEOIP2_FILE_DEFAULT);
     304        if (!geoFile.exists()) {
     305            if (_log.shouldLog(Log.WARN))
     306                _log.warn("GeoIP2 file not found: " + geoFile.getAbsolutePath());
     307            return null;
     308        }
     309        return geoFile;
     310    }
     311
     312   /**
     313    * Open a GeoIP2 database
     314    * @since 0.9.38
     315    */
     316    private DatabaseReader openGeoIP2(File geoFile) throws IOException {
     317        DatabaseReader.Builder b = new DatabaseReader.Builder(geoFile);
     318        b.withCache(new CHMCache(256));
     319        DatabaseReader rv = b.build();
     320        if (_log.shouldDebug())
     321            _log.debug("Opened GeoIP2 Database, Metadata: " + rv.getMetadata());
     322        return rv;
    242323    }
    243324
     
    475556
    476557    /**
     558     * @return e.g. 1.2.3.4
     559     * @since 0.9.38 for maxmind
     560     */
     561    private static String toV4(long ip) {
     562        StringBuilder buf = new StringBuilder(15);
     563        for (int i = 0; i < 4; i++) {
     564            buf.append(Long.toString((ip >> ((3-i)*8)) & 0xff));
     565            if (i == 3)
     566                break;
     567            buf.append('.');
     568        }
     569        return buf.toString();
     570    }
     571
     572    /**
    477573     * @return e.g. aabb:ccdd:eeff:1122::
    478574     * @since 0.9.26 for maxmind
     
    499595/***
    500596    public static void main(String args[]) {
    501         GeoIP g = new GeoIP(new Router().getContext());
     597        GeoIP g = new GeoIP(I2PAppContext.getGlobalContext());
    502598        String tests[] = {"0.0.0.0", "0.0.0.1", "0.0.0.2", "0.0.0.255", "1.0.0.0",
    503599                                        "94.3.3.3", "77.1.2.3", "127.0.0.0", "127.127.127.127", "128.0.0.0",
Note: See TracChangeset for help on using the changeset viewer.