Changeset 169fd56 for router


Ignore:
Timestamp:
Mar 27, 2016 12:55:28 PM (5 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
e69f39f6
Parents:
97a6cbd
Message:

Transport:
Include Maxmind geoip-api-java library v1.3.1 (LGPL v2.1)
Use Maxmind database for geoip lookup if it exists
Debian:
Don't bundle geoip.txt and geoipv6.dat.gz, depend on geoip-database instead

Location:
router/java/src
Files:
7 added
1 edited

Legend:

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

    r97a6cbd r169fd56  
    1717import java.util.concurrent.atomic.AtomicBoolean;
    1818
     19import com.maxmind.geoip.InvalidDatabaseException;
     20import com.maxmind.geoip.LookupService;
     21
    1922import net.i2p.I2PAppContext;
    2023import net.i2p.data.DataHelper;
     
    2528import net.i2p.util.ConcurrentHashSet;
    2629import net.i2p.util.Log;
     30import net.i2p.util.SystemVersion;
    2731
    2832/**
     
    5761    private int _lookupRunCount;
    5862   
     63    static final String PROP_GEOIP_ENABLED = "routerconsole.geoip.enable";
     64    public static final String PROP_GEOIP_DIR = "geoip.dir";
     65    public static final String GEOIP_DIR_DEFAULT = "geoip";
     66    static final String GEOIP_FILE_DEFAULT = "geoip.txt";
     67    static final String COUNTRY_FILE_DEFAULT = "countries.txt";
     68    public static final String PROP_IP_COUNTRY = "i2np.lastCountry";
     69    public static final String PROP_DEBIAN_GEOIP = "geoip.dat";
     70    public static final String PROP_DEBIAN_GEOIPV6 = "geoip.v6.dat";
     71    private static final String DEBIAN_GEOIP_FILE = "/usr/share/GeoIP/GeoIP.dat";
     72    private static final String DEBIAN_GEOIPV6_FILE = "/usr/share/GeoIP/GeoIPv6.dat";
     73    private static final boolean ENABLE_DEBIAN = !SystemVersion.isWindows();
     74    /** maxmind API */
     75    private static final String UNKNOWN_COUNTRY_CODE = "--";
     76
    5977    /**
    6078     *  @param context RouterContext in production, I2PAppContext for testing only
     
    7290        readCountryFile();
    7391    }
    74    
    75     static final String PROP_GEOIP_ENABLED = "routerconsole.geoip.enable";
    76     public static final String PROP_GEOIP_DIR = "geoip.dir";
    77     public static final String GEOIP_DIR_DEFAULT = "geoip";
    78     static final String GEOIP_FILE_DEFAULT = "geoip.txt";
    79     static final String COUNTRY_FILE_DEFAULT = "countries.txt";
    80     public static final String PROP_IP_COUNTRY = "i2np.lastCountry";
    8192
    8293    /**
     
    146157                if (search.length > 0) {
    147158                    Arrays.sort(search);
    148                     String[] countries = readGeoIPFile(search);
    149                     for (int i = 0; i < countries.length; i++) {
    150                         if (countries[i] != null)
    151                             _IPToCountry.put(search[i], countries[i]);
    152                         else
    153                             _notFound.add(search[i]);
     159                    File f = new File(_context.getProperty(PROP_DEBIAN_GEOIP, DEBIAN_GEOIP_FILE));
     160                    if (ENABLE_DEBIAN && f.exists()) {
     161                        // Maxmind database
     162                        LookupService ls = null;
     163                        try {
     164                            ls = new LookupService(f, LookupService.GEOIP_STANDARD);
     165                            for (int i = 0; i < search.length; i++) {
     166                                long ip = search[i].longValue();
     167                                // returns upper case or "--"
     168                                String uc = ls.getCountry(ip).getCode();
     169                                if (!uc.equals(UNKNOWN_COUNTRY_CODE)) {
     170                                    String cached = _codeCache.get(uc.toLowerCase(Locale.US));
     171                                    _IPToCountry.put(search[i], cached);
     172                                } else {
     173                                    _notFound.add(search[i]);
     174                                }
     175                            }
     176                        } catch (IOException ioe) {
     177                            _log.error("GeoIP failure", ioe);
     178                        } catch (InvalidDatabaseException ide) {
     179                            _log.error("GeoIP failure", ide);
     180                        } finally {
     181                            if (ls != null) ls.close();
     182                        }
     183                    } else {
     184                        // Tor-style database
     185                        String[] countries = readGeoIPFile(search);
     186                        for (int i = 0; i < countries.length; i++) {
     187                            if (countries[i] != null)
     188                                _IPToCountry.put(search[i], countries[i]);
     189                            else
     190                                _notFound.add(search[i]);
     191                        }
    154192                    }
    155193                }
     
    159197                if (search.length > 0) {
    160198                    Arrays.sort(search);
    161                     String[] countries = GeoIPv6.readGeoIPFile(_context, search, _codeCache);
    162                     for (int i = 0; i < countries.length; i++) {
    163                         if (countries[i] != null)
    164                             _IPToCountry.put(search[i], countries[i]);
    165                         else
    166                             _notFound.add(search[i]);
     199                    File f = new File(_context.getProperty(PROP_DEBIAN_GEOIPV6, DEBIAN_GEOIPV6_FILE));
     200                    if (ENABLE_DEBIAN && f.exists()) {
     201                        // Maxmind database
     202                        LookupService ls = null;
     203                        try {
     204                            ls = new LookupService(f, LookupService.GEOIP_STANDARD);
     205                            for (int i = 0; i < search.length; i++) {
     206                                long ip = search[i].longValue();
     207                                String ipv6 = toV6(ip);
     208                                // returns upper case or "--"
     209                                String uc = ls.getCountryV6(ipv6).getCode();
     210                                if (!uc.equals(UNKNOWN_COUNTRY_CODE)) {
     211                                    String cached = _codeCache.get(uc.toLowerCase(Locale.US));
     212                                    _IPToCountry.put(search[i], cached);
     213                                } else {
     214                                    _notFound.add(search[i]);
     215                                }
     216                            }
     217                        } catch (IOException ioe) {
     218                            _log.error("GeoIP failure", ioe);
     219                        } catch (InvalidDatabaseException ide) {
     220                            _log.error("GeoIP failure", ide);
     221                        } finally {
     222                            if (ls != null) ls.close();
     223                        }
     224                    } else {
     225                        // Tor-style database
     226                        String[] countries = GeoIPv6.readGeoIPFile(_context, search, _codeCache);
     227                        for (int i = 0; i < countries.length; i++) {
     228                            if (countries[i] != null)
     229                                _IPToCountry.put(search[i], countries[i]);
     230                            else
     231                                _notFound.add(search[i]);
     232                        }
    167233                    }
    168234                }
     
    406472
    407473    /**
     474     * @return e.g. aabb:ccdd:eeff:1122::
     475     * @since 0.9.26 for maxmind
     476     */
     477    private static String toV6(long ip) {
     478        StringBuilder buf = new StringBuilder(21);
     479        for (int i = 0; i < 4; i++) {
     480            buf.append(Long.toHexString((ip >> ((3-i)*16)) & 0xffff));
     481            buf.append(':');
     482        }
     483        buf.append(':');
     484        return buf.toString();
     485    }
     486
     487    /**
    408488     * Get the country for a country code
    409489     * @param code two-letter lower case code
Note: See TracChangeset for help on using the changeset viewer.