Skip to content

Commit

Permalink
Merge pull request matomo-org#6690 from joostdekeijzer/3581_IPv6_2
Browse files Browse the repository at this point in the history
Another try to implement IPv6 support
  • Loading branch information
Matthieu Aubry committed Nov 28, 2014
2 parents 7acab3d + 49be3f0 commit d539707
Show file tree
Hide file tree
Showing 14 changed files with 6,588 additions and 5,062 deletions.
2,389 changes: 1,796 additions & 593 deletions libs/MaxMindGeoIP/geoip.inc

Large diffs are not rendered by default.

382 changes: 193 additions & 189 deletions libs/MaxMindGeoIP/geoipcity.inc

Large diffs are not rendered by default.

8,633 changes: 4,444 additions & 4,189 deletions libs/MaxMindGeoIP/geoipregionvars.php

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions plugins/UserCountry/LocationProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -444,8 +444,7 @@ public static function prettyFormatLocation($locationInfo, $newline = "\n", $inc

/**
* Returns an IP address from an array that was passed into getLocation. This
* will return an IPv4 address or null if the address is IPv6 (IPv6 is not
* supported yet).
* will return an IPv4 address or IPv6 address.
*
* @param array $info Must have 'ip' key.
* @return string|null
Expand All @@ -454,7 +453,11 @@ protected function getIpFromInfo($info)
{
$ip = \Piwik\Network\IP::fromStringIP($info['ip']);

return $ip->toIPv4String();
if ($ip instanceof \Piwik\Network\IPv6 && $ip->isMappedIPv4()) {
return $ip->toIPv4String();
} else {
return $ip->toString();
}
}
}

41 changes: 34 additions & 7 deletions plugins/UserCountry/LocationProvider/GeoIp/Php.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ public function __destruct()
public function getLocation($info)
{
$ip = $this->getIpFromInfo($info);
$isIPv6 = filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6);

$result = array();

Expand All @@ -104,7 +105,11 @@ public function getLocation($info)
case GEOIP_CITY_EDITION_REV0: // city database type
case GEOIP_CITY_EDITION_REV1:
case GEOIP_CITYCOMBINED_EDITION:
$location = geoip_record_by_addr($locationGeoIp, $ip);
if ($isIPv6) {
$location = geoip_record_by_addr_v6($locationGeoIp, $ip);
} else {
$location = geoip_record_by_addr($locationGeoIp, $ip);
}
if (!empty($location)) {
$result[self::COUNTRY_CODE_KEY] = $location->country_code;
$result[self::REGION_CODE_KEY] = $location->region;
Expand All @@ -117,36 +122,58 @@ public function getLocation($info)
break;
case GEOIP_REGION_EDITION_REV0: // region database type
case GEOIP_REGION_EDITION_REV1:
$location = geoip_region_by_addr($locationGeoIp, $ip);
if ($isIPv6) {
// NOTE: geoip_region_by_addr_v6 does not exist (yet?), so we
// return the country code and an empty region code
$location = array(geoip_country_code_by_addr_v6($locationGeoIp, $ip), '');
} else {
$location = geoip_region_by_addr($locationGeoIp, $ip);
}
if (!empty($location)) {
$result[self::COUNTRY_CODE_KEY] = $location[0];
$result[self::REGION_CODE_KEY] = $location[1];
}
break;
case GEOIP_COUNTRY_EDITION: // country database type
$result[self::COUNTRY_CODE_KEY] = geoip_country_code_by_addr($locationGeoIp, $ip);
if ($isIPv6) {
$result[self::COUNTRY_CODE_KEY] = geoip_country_code_by_addr_v6($locationGeoIp, $ip);
} else {
$result[self::COUNTRY_CODE_KEY] = geoip_country_code_by_addr($locationGeoIp, $ip);
}
break;
default: // unknown database type, log warning and fallback to country edition
Log::warning("Found unrecognized database type: %s", $locationGeoIp->databaseType);

$result[self::COUNTRY_CODE_KEY] = geoip_country_code_by_addr($locationGeoIp, $ip);
if ($isIPv6) {
$result[self::COUNTRY_CODE_KEY] = geoip_country_code_by_addr_v6($locationGeoIp, $ip);
} else {
$result[self::COUNTRY_CODE_KEY] = geoip_country_code_by_addr($locationGeoIp, $ip);
}
break;
}
}

// NOTE: ISP & ORG require commercial dbs to test. this code has been tested manually,
// NOTE: ISP & ORG require commercial dbs to test. The code has been tested manually,
// but not by system tests.
$ispGeoIp = $this->getGeoIpInstance($key = 'isp');
if ($ispGeoIp) {
$isp = geoip_org_by_addr($ispGeoIp, $ip);
if ($isIPv6) {
$isp = geoip_name_by_addr_v6($ispGeoIp, $ip);
} else {
$isp = geoip_org_by_addr($ispGeoIp, $ip);
}
if (!empty($isp)) {
$result[self::ISP_KEY] = utf8_encode($isp);
}
}

$orgGeoIp = $this->getGeoIpInstance($key = 'org');
if ($orgGeoIp) {
$org = geoip_org_by_addr($orgGeoIp, $ip);
if ($isIPv6) {
$org = geoip_name_by_addr_v6($orgGeoIp, $ip);
} else {
$org = geoip_org_by_addr($orgGeoIp, $ip);
}
if (!empty($org)) {
$result[self::ORG_KEY] = utf8_encode($org);
}
Expand Down
4 changes: 2 additions & 2 deletions tests/PHPUnit/Fixtures/ManyVisitsWithGeoIP.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class ManyVisitsWithGeoIP extends Fixture
'::ffff:137.82.130.49', // in British Columbia (mapped ipv4)
'137.82.130.0', // anonymization tests
'137.82.0.0',
'2001:db8:85a3:0:0:8a2e:370:7334', // ipv6 (geoip lookup not supported)
'2001:db8:85a3:0:0:8a2e:370:7334', // ipv6
'113.62.1.1', // in Lhasa, Tibet
'151.100.101.92', // in Rome, Italy (using country DB, so only Italy will show)
'103.29.196.229', // in Indonesia (Bali), (only Indonesia will show up)
Expand Down Expand Up @@ -257,4 +257,4 @@ public static function unsetLocationProvider()
// ignore error
}
}
}
}
13 changes: 12 additions & 1 deletion tests/PHPUnit/System/ManyVisitorsOneWebsiteTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,17 @@ public function getApiForTesting()
'periods' => array('month'),
'otherRequestParameters' => array('ip' => '194.57.91.215')
)),

array(array('UserCountry.getLocationFromIP'), array(
'otherRequestParameters' => array('ip' => '194.57.91.215')
)),

array(array('UserCountry.getLocationFromIP'), array(
'testSuffix' => '_IPv6',
'otherRequestParameters' => array(
'ip' => '2001:db8:85a3:0:0:8a2e:370:7334',
)
)),
);

// Randomly fails on 5.3
Expand Down Expand Up @@ -160,4 +171,4 @@ public function getApiForTesting()
}
}

ManyVisitorsOneWebsiteTest::$fixture = new ManyVisitsWithGeoIP();
ManyVisitorsOneWebsiteTest::$fixture = new ManyVisitsWithGeoIP();
Original file line number Diff line number Diff line change
Expand Up @@ -2277,17 +2277,17 @@
<browserCode>UNK</browserCode>
<browserVersion />
<events>1</events>
<continent>Unknown</continent>
<continentCode>unk</continentCode>
<country>Unknown</country>
<countryCode>xx</countryCode>
<countryFlag>plugins/UserCountry/images/flags/xx.png</countryFlag>
<continent>North America</continent>
<continentCode>amn</continentCode>
<country>United States</country>
<countryCode>us</countryCode>
<countryFlag>plugins/UserCountry/images/flags/us.png</countryFlag>
<region />
<regionCode />
<city />
<location>Unknown</location>
<latitude />
<longitude />
<location>United States</location>
<latitude>38</latitude>
<longitude>-97</longitude>
<visitLocalTime>12:34:06</visitLocalTime>
<visitLocalHour>12</visitLocalHour>
<daysSinceLastVisit>10</daysSinceLastVisit>
Expand Down Expand Up @@ -2519,17 +2519,17 @@
<browserCode>UNK</browserCode>
<browserVersion />
<events>0</events>
<continent>Unknown</continent>
<continentCode>unk</continentCode>
<country>Unknown</country>
<countryCode>xx</countryCode>
<countryFlag>plugins/UserCountry/images/flags/xx.png</countryFlag>
<continent>North America</continent>
<continentCode>amn</continentCode>
<country>United States</country>
<countryCode>us</countryCode>
<countryFlag>plugins/UserCountry/images/flags/us.png</countryFlag>
<region />
<regionCode />
<city />
<location>Unknown</location>
<latitude />
<longitude />
<location>United States</location>
<latitude>38</latitude>
<longitude>-97</longitude>
<visitLocalTime>12:34:06</visitLocalTime>
<visitLocalHour>12</visitLocalHour>
<daysSinceLastVisit>11</daysSinceLastVisit>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
<result>
<row>gb</row>
<row>ca</row>
<row>xx</row>
<row>ru</row>
<row>us</row>
<row>it</row>
<row>id</row>
<row>fr</row>
<row>id</row>
<row>ti</row>
<row>mk</row>
<row>us</row>
<row>xx</row>
</result>
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
<row>49.25</row>
<row>123.456</row>
<row>47.249</row>
<row>124.456</row>
<row>38</row>
<row>29.65</row>
<row>124.456</row>
<row>1</row>
</result>
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
<row>-123.133</row>
<row>21.321</row>
<row>6.018</row>
<row>22.231</row>
<row>-97</row>
<row>91.1</row>
<row>22.231</row>
<row>2</row>
</result>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<result>
<row>
<country_code>US</country_code>
<region_code />
<city_name />
<area_code>0</area_code>
<lat>38</lat>
<long>-97</long>
<postal_code />
<continent_code>amn</continent_code>
<continent_name>North America</continent_name>
<country_name>United States</country_name>
<ip>2001:db8:85a3:0:0:8a2e:370:7334</ip>
</row>
</result>
Original file line number Diff line number Diff line change
Expand Up @@ -27,34 +27,34 @@
</row>
<row>
<label>North America</label>
<nb_visits>7</nb_visits>
<nb_actions>11</nb_actions>
<nb_visits>9</nb_visits>
<nb_actions>15</nb_actions>
<max_actions>3</max_actions>
<sum_visit_length>3783</sum_visit_length>
<bounce_count>4</bounce_count>
<sum_visit_length>5044</sum_visit_length>
<bounce_count>5</bounce_count>
<goals>
<row idgoal='1'>
<nb_conversions>7</nb_conversions>
<nb_visits_converted>7</nb_visits_converted>
<revenue>35</revenue>
<nb_conversions>9</nb_conversions>
<nb_visits_converted>9</nb_visits_converted>
<revenue>45</revenue>
</row>
<row idgoal='2'>
<nb_conversions>3</nb_conversions>
<nb_visits_converted>3</nb_visits_converted>
<revenue>15</revenue>
<nb_conversions>4</nb_conversions>
<nb_visits_converted>4</nb_visits_converted>
<revenue>20</revenue>
</row>
</goals>
<nb_conversions>10</nb_conversions>
<revenue>50</revenue>
<sum_daily_nb_uniq_visitors>4</sum_daily_nb_uniq_visitors>
<nb_conversions>13</nb_conversions>
<revenue>65</revenue>
<sum_daily_nb_uniq_visitors>5</sum_daily_nb_uniq_visitors>
<sum_daily_nb_users>1</sum_daily_nb_users>
<code>North America</code>
</row>
<row>
<label>Unknown</label>
<label>Asia</label>
<nb_visits>4</nb_visits>
<nb_actions>8</nb_actions>
<max_actions>3</max_actions>
<nb_actions>6</nb_actions>
<max_actions>2</max_actions>
<sum_visit_length>2522</sum_visit_length>
<bounce_count>2</bounce_count>
<goals>
Expand All @@ -73,31 +73,31 @@
<revenue>30</revenue>
<sum_daily_nb_uniq_visitors>2</sum_daily_nb_uniq_visitors>
<sum_daily_nb_users>0</sum_daily_nb_users>
<code>Unknown</code>
<code>Asia</code>
</row>
<row>
<label>Asia</label>
<nb_visits>4</nb_visits>
<nb_actions>6</nb_actions>
<max_actions>2</max_actions>
<sum_visit_length>2522</sum_visit_length>
<bounce_count>2</bounce_count>
<label>Unknown</label>
<nb_visits>2</nb_visits>
<nb_actions>4</nb_actions>
<max_actions>3</max_actions>
<sum_visit_length>1261</sum_visit_length>
<bounce_count>1</bounce_count>
<goals>
<row idgoal='1'>
<nb_conversions>4</nb_conversions>
<nb_visits_converted>4</nb_visits_converted>
<revenue>20</revenue>
</row>
<row idgoal='2'>
<nb_conversions>2</nb_conversions>
<nb_visits_converted>2</nb_visits_converted>
<revenue>10</revenue>
</row>
<row idgoal='2'>
<nb_conversions>1</nb_conversions>
<nb_visits_converted>1</nb_visits_converted>
<revenue>5</revenue>
</row>
</goals>
<nb_conversions>6</nb_conversions>
<revenue>30</revenue>
<sum_daily_nb_uniq_visitors>2</sum_daily_nb_uniq_visitors>
<nb_conversions>3</nb_conversions>
<revenue>15</revenue>
<sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors>
<sum_daily_nb_users>0</sum_daily_nb_users>
<code>Asia</code>
<code>Unknown</code>
</row>
</result>
Loading

0 comments on commit d539707

Please sign in to comment.