rfc8805xml2.original.xml   rfc8805.xml 
<?xml version="1.0" encoding="UTF-8"?> <?xml version='1.0' encoding='utf-8'?>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?> <!DOCTYPE rfc SYSTEM "rfc2629-xhtml.ent">
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<?rfc toc="yes"?>
<?rfc tocdepth="4"?>
<?rfc sortrefs="yes"?>
<?rfc symrefs="yes"?>
<rfc category="info" docName="draft-google-self-published-geofeeds-09"
ipr="trust200902">
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<?rfc toc="yes" ?>
<?rfc symrefs="yes" ?>
<?rfc sortrefs="yes"?>
<?rfc iprnotified="no" ?>
<?rfc strict="yes" ?>
<?rfc compact="yes" ?>
<?rfc subcompact="no" ?> <rfc xmlns:xi="http://www.w3.org/2001/XInclude" category="info"
docName="draft-google-self-published-geofeeds-09" ipr="trust200902"
obsoletes="" updates="" submissionType="independent" xml:lang="en"
tocInclude="true" tocDepth="4" sortRefs="true" symRefs="true"
version="3" number="8805">
<!-- xml2rfc v2v3 conversion 2.41.0 -->
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<front> <front>
<title abbrev="Self-published IP Geofeeds">A Format for Self-published IP <title abbrev="Self-Published IP Geofeeds">A Format for Self-Published IP
Geolocation Feeds</title> Geolocation Feeds</title>
<seriesInfo name="RFC" value="8805"/>
<author fullname="Erik Kline" initials="E." surname="Kline"> <author fullname="Erik Kline" initials="E." surname="Kline">
<organization>Loon LLC</organization> <organization>Loon LLC</organization>
<address> <address>
<postal> <postal>
<street>1600 Amphitheatre Parkway</street> <street>1600 Amphitheatre Parkway</street>
<city>Mountain View</city> <city>Mountain View</city>
<region>California</region> <region>CA</region>
<code>94043</code> <code>94043</code>
<country>United States of America</country> <country>United States of America</country>
</postal> </postal>
<email>ek@loon.com</email> <email>ek@loon.com</email>
</address> </address>
</author> </author>
<author fullname="Krzysztof Duleba" initials="K."
<author fullname="Krzysztof Duleba" initials="K." surname="Duleba"> surname="Duleba">
<organization>Google Switzerland GmbH</organization> <organization>Google</organization>
<address> <address>
<postal> <postal>
<street>Brandschenkestrasse 110</street> <street>1600 Amphitheatre Parkway</street>
<code>8002</code> <city>Mountain View</city>
<city>Zürich</city> <region>CA</region>
<country>Switzerland</country> <code>94043</code>
<country>United States of America</country>
</postal> </postal>
<email>kduleba@google.com</email> <email>kduleba@google.com</email>
</address> </address>
</author> </author>
<author fullname="Zoltan Szamonek" initials="Z." surname="Szamonek"> <author fullname="Zoltan Szamonek" initials="Z." surname="Szamonek">
<organization>Google Switzerland GmbH</organization> <organization>Google Switzerland GmbH</organization>
<address> <address>
<postal> <postal>
<street>Brandschenkestrasse 110</street> <street>Brandschenkestrasse 110</street>
<code>8002</code> <code>8002</code>
<city>Zürich</city> <city>Zürich</city>
<country>Switzerland</country> <country>Switzerland</country>
</postal> </postal>
<email>zszami@google.com</email> <email>zszami@google.com</email>
</address> </address>
</author> </author>
<author fullname="Stefan Moser" initials="S." surname="Moser"> <author fullname="Stefan Moser" initials="S." surname="Moser">
<organization>Google Switzerland GmbH</organization> <organization>Google Switzerland GmbH</organization>
<address> <address>
<postal> <postal>
<street>Brandschenkestrasse 110</street> <street>Brandschenkestrasse 110</street>
<code>8002</code> <code>8002</code>
<city>Zürich</city> <city>Zürich</city>
<country>Switzerland</country> <country>Switzerland</country>
</postal> </postal>
<email>smoser@google.com</email> <email>smoser@google.com</email>
</address> </address>
</author> </author>
skipping to change at line 89 skipping to change at line 67
<address> <address>
<postal> <postal>
<street>Brandschenkestrasse 110</street> <street>Brandschenkestrasse 110</street>
<code>8002</code> <code>8002</code>
<city>Zürich</city> <city>Zürich</city>
<country>Switzerland</country> <country>Switzerland</country>
</postal> </postal>
<email>smoser@google.com</email> <email>smoser@google.com</email>
</address> </address>
</author> </author>
<author fullname="Warren Kumari" initials="W." surname="Kumari">
<author fullname="Warren Kumari" initials="W." surname="Kumari">
<organization>Google</organization> <organization>Google</organization>
<address> <address>
<postal> <postal>
<street>1600 Amphitheatre Parkway</street> <street>1600 Amphitheatre Parkway</street>
<city>Mountain View, CA</city> <city>Mountain View</city>
<region>CA</region>
<code>94043</code> <code>94043</code>
<country>US</country> <country>United States of America</country>
</postal> </postal>
<email>warren@kumari.net</email> <email>warren@kumari.net</email>
</address> </address>
</author> </author>
<date month="July" year="2020"/>
<date/>
<abstract> <abstract>
<t>This document records a format whereby a network operator can publish <t>This document records a format whereby a network operator can publish
a mapping of IP address prefixes to simplified geolocation information, a mapping of IP address prefixes to simplified geolocation information,
colloquially termed a geolocation "feed". Interested parties can poll colloquially termed a "geolocation feed". Interested parties can poll
and parse these feeds to update or merge with other geolocation data and parse these feeds to update or merge with other geolocation data
sources and procedures. This format intentionally only allows specifying sources and procedures. This format intentionally only allows specifying
coarse level location.</t> coarse-level location.</t>
<t>Some technical organizations operating networks that move from one <t>Some technical organizations operating networks that move from one
conference location to the next have already experimentally published conference location to the next have already experimentally published
small geolocation feeds.</t> small geolocation feeds.</t>
<t>This document describes a currently deployed format. At <t>This document describes a currently deployed format. At
least one consumer (Google) has incorporated these feeds into a least one consumer (Google) has incorporated these feeds into a
geolocation data pipeline, and a significant number of ISPs are geolocation data pipeline, and a significant number of ISPs are
using it to inform them where their prefixes should be geolocated.</t> using it to inform them where their prefixes should be geolocated.</t>
</abstract> </abstract>
</front> </front>
<middle> <middle>
<section title="Introduction"> <section numbered="true" toc="default">
<section title="Motivation"> <name>Introduction</name>
<section numbered="true" toc="default">
<name>Motivation</name>
<t>Providers of services over the Internet have grown to depend on <t>Providers of services over the Internet have grown to depend on
best-effort geolocation information to improve the user experience. best-effort geolocation information to improve the user experience.
Locality information can aid in directing traffic to the nearest Locality information can aid in directing traffic to the nearest
serving location, inferring likely native language, and providing serving location, inferring likely native language, and providing
additional context for services involving search queries.</t> additional context for services involving search queries.</t>
<t>When an ISP, for example, changes the location where an IP prefix <t>When an ISP, for example, changes the location where an IP prefix
is deployed, services which make use of geolocation information may is deployed, services that make use of geolocation information may
begin to suffer degraded performance. This can lead to customer begin to suffer degraded performance. This can lead to customer
complaints, possibly to the ISP directly. Dissemination of correct complaints, possibly to the ISP directly. Dissemination of correct
geolocation data is complicated by the lack of any centralized means geolocation data is complicated by the lack of any centralized means
to coordinate and communicate geolocation information to all to coordinate and communicate geolocation information to all
interested consumers of the data.</t> interested consumers of the data.</t>
<t>This document records a format whereby a network operator (an ISP, <t>This document records a format whereby a network operator (an ISP,
an enterprise, or any organization which deems the geolocation of its an enterprise, or any organization that deems the geolocation of its
IP prefixes to be of concern) can publish a mapping of IP address IP prefixes to be of concern) can publish a mapping of IP address
prefixes to simplified geolocation information, colloquially termed a prefixes to simplified geolocation information, colloquially termed a
"geolocation feed". Interested parties can poll and parse these feeds "geolocation feed". Interested parties can poll and parse these feeds
to update or merge with other geolocation data sources and to update or merge with other geolocation data sources and
procedures.</t> procedures.</t>
<t>This document describes a currently deployed format. At
<t>This document describes a currently deployed format. At
least one consumer (Google) has incorporated these feeds into a least one consumer (Google) has incorporated these feeds into a
geolocation data pipeline, and a significant number of ISPs are geolocation data pipeline, and a significant number of ISPs are
using it to inform them where their prefixes should be geolocated.</t> using it to inform them where their prefixes should be geolocated.</t>
</section> </section>
<section numbered="true" toc="default">
<section title="Requirements Notation"> <name>Requirements Notation</name>
<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", <t>
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>",
"OPTIONAL" in this document are to be interpreted as described in "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
BCP 14 <xref target="RFC2119"/> and <xref target="RFC8174"/> when, NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>",
and only when, they appear in all capitals, as shown here.</t> "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are
to be interpreted as
described in BCP&nbsp;14 <xref target="RFC2119"/> <xref target="RFC8174"/>
when, and only when, they appear in all capitals, as shown here.
</t>
<t>As this is an informational document about a data format and set of <t>As this is an informational document about a data format and set of
operational practices presently in use, requirements notation captures operational practices presently in use, requirements notation captures
the design goals of the authors and implementors.</t> the design goals of the authors and implementors.</t>
</section> </section>
<section numbered="true" toc="default">
<section title="Assumptions About Publication"> <name>Assumptions about Publication</name>
<t>This document describes both a format and a mechanism for <t>This document describes both a format and a mechanism for
publishing data, with the assumption that the network operator to whom publishing data, with the assumption that the network operator to whom
operational responsibility has been delegated for any published data operational responsibility has been delegated for any published data
wishes it to be public. Any privacy risk is bounded by the format, and wishes it to be public. Any privacy risk is bounded by the format, and
feed publishers MAY omit prefixes or any location field associated with feed publishers <bcp14>MAY</bcp14> omit prefixes or any location field a
a given prefix to further protect privacy (see <xref target="spec"/> ssociated with
a given prefix to further protect privacy (see <xref target="spec" forma
t="default"/>
for details about which fields exactly may be omitted). Feed publishers for details about which fields exactly may be omitted). Feed publishers
assume the responsibility of determining which data should be made assume the responsibility of determining which data should be made
public.</t> public.</t>
<t>This document does not incorporate a mechanism to communicate <t>This document does not incorporate a mechanism to communicate
acceptable use policies for self-published data. Publication itself is acceptable use policies for self-published data. Publication itself is
inferred as a desire by the publisher for the data to be usefully inferred as a desire by the publisher for the data to be usefully
consumed, similar to the publication of information like host names, consumed, similar to the publication of information like host names,
cryptographic keys, and SPF records <xref target="RFC4408"/> in the cryptographic keys, and Sender Policy Framework (SPF) records <xref
DNS.</t> target="RFC7208" format="default"/> in the DNS.</t>
</section> </section>
</section> </section>
<section numbered="true" toc="default">
<section title="Self-Published IP Geolocation Feeds"> <name>Self-Published IP Geolocation Feeds</name>
<t>The format described here was developed to address the need of <t>The format described here was developed to address the need of
network operators to rapidly and usefully share geolocation information network operators to rapidly and usefully share geolocation information
changes. Originally, there arose a specific case where regional changes. Originally, there arose a specific case where regional
operators found it desirable to publish location changes rather than operators found it desirable to publish location changes rather than
wait for geolocation algorithms to "learn" about them. Later, technical wait for geolocation algorithms to "learn" about them. Later, technical
conferences which frequently use the same network prefixes advertised conferences that frequently use the same network prefixes advertised
from different conference locations experimented by publishing from different conference locations experimented by publishing
geolocation feeds, updated in advance of network location changes, in geolocation feeds updated in advance of network location changes in
order to better serve conference attendees.</t> order to better serve conference attendees.</t>
<t>At its simplest, the mechanism consists of a network operator <t>At its simplest, the mechanism consists of a network operator
publishing a file (the "geolocation feed"), which contains several text publishing a file (the "geolocation feed") that contains several text
entries, one per line. Each entry is keyed by a unique (within the feed) entries, one per line. Each entry is keyed by a unique (within the feed)
IP prefix (or single IP address) followed by a sequence of network IP prefix (or single IP address) followed by a sequence of network
locality attributes to be ascribed to the given prefix.</t> locality attributes to be ascribed to the given prefix.</t>
<section anchor="spec" numbered="true" toc="default">
<section anchor="spec" title="Specification"> <name>Specification</name>
<t>For operational simplicity, every feed should contain data about <t>For operational simplicity, every feed should contain data about
all IP addresses the provider wants to publish. Alternatives, like all IP addresses the provider wants to publish. Alternatives, like
publishing only entries for IP addresses whose geolocation data has publishing only entries for IP addresses whose geolocation data has
changed or differ from current observed geolocation behavior "at changed or differ from current observed geolocation behavior "at
large", are likely to be too operationally complex.</t> large", are likely to be too operationally complex.</t>
<t>Feeds <bcp14>MUST</bcp14> use UTF-8 <xref target="RFC3629"
<t>Feeds MUST use UTF-8 <xref target="RFC3629"/> character encoding. format="default"/> character encoding.
Lines are delimited by a line break (CRLF) (as specifed in Lines are delimited by a line break (CRLF) (as specified in
<xref target="RFC4180"/>), and blank lines are ignored. <xref target="RFC4180" format="default"/>), and blank lines are ignored.
Text from a '#' character to the end of the current line is treated Text from a '#' character to the end of the current line is treated
as a comment only and is similarily ignored (note that this does not as a comment only and is similarly ignored (note that this does not
stricly follow <xref target="RFC4180"/>, which has no support for strictly follow <xref target="RFC4180" format="default"/>, which has no
comments). support for comments).</t>
</t> <t>Feed lines that are not comments <bcp14>MUST</bcp14> be formatted
as comma-separated values (CSV), as described in <xref
<t>Feed lines that are not comments MUST be in comma separated value target="RFC4180" format="default"/>. Each feed entry is a text line of
(CSV) format as described in <xref target="RFC4180"/>. Each feed entry the form:</t>
is a text line of the form: <artwork name="" type="" align="left" alt=""><![CDATA[
<figure> ip_prefix,alpha2code,region,city,postal_code
<artwork><![CDATA[ ]]></artwork>
ip_prefix,alpha2code,region,city,postal_code <t>The IP prefix field is <bcp14>REQUIRED</bcp14>, all others are
]]></artwork> <bcp14>OPTIONAL</bcp14> (can be empty), though the requisite minimum
</figure></t> number of commas <bcp14>SHOULD</bcp14> be present.</t>
<section numbered="true" toc="default">
<t>The IP prefix field is REQUIRED, all others are OPTIONAL (can be <name>Geolocation Feed Individual Entry Fields</name>
empty), though the requisite minimum number of commas SHOULD be <section numbered="true" toc="default">
present.</t> <name>IP Prefix</name>
<t><bcp14>REQUIRED</bcp14>: Each IP prefix field
<section title="Geolocation Feed Individual Entry Fields"> <bcp14>MUST</bcp14> be either a single IP address or an IP prefix
<section title="IP Prefix"> in Classless Inter-Domain Routing (CIDR) notation in conformance
<t>REQUIRED. Each IP prefix field MUST be either a single IP with <xref target="RFC4632" sectionFormat="of" section="3.1"/> for
address or an IP prefix in CIDR notation in conformance with <eref IPv4 or <xref target="RFC4291" sectionFormat="of" section="2.3"/>
target="http://tools.ietf.org/html/rfc4632#section-3.1">section for IPv6.</t>
3.1</eref> of <xref target="RFC4632"/> for IPv4 or <eref
target="http://tools.ietf.org/html/rfc4291#section-2.3">section
2.3</eref> of <xref target="RFC4291"/> for IPv6.</t>
<t>Examples include "192.0.2.1" and "192.0.2.0/24" for IPv4 and <t>Examples include "192.0.2.1" and "192.0.2.0/24" for IPv4 and
"2001:db8::1" and "2001:db8::/32" for IPv6.</t> "2001:db8::1" and "2001:db8::/32" for IPv6.</t>
</section> </section>
<section numbered="true" toc="default">
<section title="Alpha2code (previously: 'country')"> <name>Alpha2code (Previously: 'country')</name>
<t>OPTIONAL. The alpha2code field, if non-empty, MUST be a 2 letter <t><bcp14>OPTIONAL</bcp14>: The alpha2code field, if non-empty,
<bcp14>MUST</bcp14> be a 2-letter
ISO country code conforming to ISO 3166-1 alpha 2 <xref ISO country code conforming to ISO 3166-1 alpha 2 <xref
target="ISO.3166.1alpha2"/>. Parsers SHOULD treat this field target="ISO.3166.1alpha2" format="default"/>. Parsers
<bcp14>SHOULD</bcp14> treat this field
case-insensitively.</t> case-insensitively.</t>
<t>Earlier versions of this document called this field "country", <t>Earlier versions of this document called this field "country",
and it may still be referred to as such in existing and it may still be referred to as such in existing
tools / interfaces.</t> tools/interfaces.</t>
<t>Parsers <bcp14>MAY</bcp14> additionally support other 2-letter
<t>Parsers MAY additionally support other 2 letter codes outside codes outside the ISO 3166-1 alpha 2 codes, such as the 2-letter
the ISO 3166-1 alpha 2 codes. For example, 2 letter codes from the codes from the "Exceptionally reserved codes" <xref
<eref target="https://www.iso.org/glossary-for-iso-3166.html"> target="ISO-GLOSSARY" format="default"/> set.</t>
"Exceptionally reserved codes"</eref> set may appear in this field,
e.g. <eref target="https://www.iso.org/obp/ui/#iso:code:3166:UK"
>"UK"</eref>
or <eref target="https://www.iso.org/obp/ui/#iso:code:3166:EU"
>"EU"</eref>.</t>
<t>Examples include "US" for the United States, "JP" for Japan, <t>Examples include "US" for the United States, "JP" for Japan,
and "PL" for Poland.</t> and "PL" for Poland.</t>
</section>
<section title="Region">
<t>OPTIONAL. The region field, if non-empty, MUST be a ISO region
code conforming to ISO 3166-2 <xref target="ISO.3166.2"/>. Parsers
SHOULD treat this field case-insensitively.</t>
</section>
<section numbered="true" toc="default">
<name>Region</name>
<t><bcp14>OPTIONAL</bcp14>: The region field, if non-empty,
<bcp14>MUST</bcp14> be an ISO region code conforming to ISO 3166-2
<xref target="ISO.3166.2" format="default"/>. Parsers
<bcp14>SHOULD</bcp14> treat this field case-insensitively.</t>
<t>Examples include "ID-RI" for the Riau province of Indonesia and <t>Examples include "ID-RI" for the Riau province of Indonesia and
"NG-RI" for the Rivers province in Nigeria.</t> "NG-RI" for the Rivers province in Nigeria.</t>
</section> </section>
<section numbered="true" toc="default">
<section title="City"> <name>City</name>
<t>OPTIONAL. The city field, if non-empty, SHOULD be free UTF-8 <t><bcp14>OPTIONAL</bcp14>: The city field, if non-empty,
<bcp14>SHOULD</bcp14> be free UTF-8
text, excluding the comma (',') character.</t> text, excluding the comma (',') character.</t>
<t>Examples include "Dublin", "New York", and "Sao Paulo"
<t>Examples include "Dublin", "New York", and "São Paulo"
(specifically "S" followed by 0xc3, 0xa3, and "o Paulo").</t> (specifically "S" followed by 0xc3, 0xa3, and "o Paulo").</t>
</section> </section>
<section anchor="postal" numbered="true" toc="default">
<section anchor="postal" title="Postal Code"> <name>Postal Code</name>
<t>OPTIONAL, DEPRECATED. The postal code field, if non-empty, <t><bcp14>OPTIONAL</bcp14>, DEPRECATED: The postal code field, if
SHOULD be free UTF-8 text, excluding the comma (',') character. non-empty, <bcp14>SHOULD</bcp14> be free UTF-8 text, excluding the
The use of this field is deprecated; consumers of feeds should comma (',') character. The use of this field is deprecated;
be able to parse feeds containing these fields, but new feeds consumers of feeds should be able to parse feeds containing these
SHOULD NOT include this field, due to the granularity of this fields, but new feeds <bcp14>SHOULD NOT</bcp14> include this
information. See <xref target="privacy"/> for additional field due to the granularity of this information. See <xref
discussion.</t> target="privacy" format="default"/> for additional discussion.</t>
<t>Examples include "106-6126" (in Minato ward, Tokyo, Japan).</t> <t>Examples include "106-6126" (in Minato ward, Tokyo, Japan).</t>
</section> </section>
</section> </section>
<section numbered="true" toc="default">
<section title="Prefixes With No Geolocation Information"> <name>Prefixes with No Geolocation Information</name>
<t>Feed publishers may indicate that some IP prefixes should not <t>Feed publishers may indicate that some IP prefixes should not
have any associated geolocation information. It may be that some have any associated geolocation information. It may be that some
prefixes under their administrative control are reserved, not yet prefixes under their administrative control are reserved, not yet
allocated or deployed, or are in the process of being redeployed allocated or deployed, or in the process of being redeployed
elsewhere and existing geolocation information can, from the elsewhere and existing geolocation information can, from the
perspective of the publisher, safely be discarded.</t> perspective of the publisher, safely be discarded.</t>
<t>This special case can be indicated by explicitly leaving blank <t>This special case can be indicated by explicitly leaving blank
all fields which specify any degree of geolocation information. For all fields that specify any degree of geolocation information. For
example: <figure> example: </t>
<artwork><![CDATA[ <artwork name="" type="" align="left" alt=""><![CDATA[
192.0.2.0/24,,,, 192.0.2.0/24,,,,
2001:db8:1::/48,,,, 2001:db8:1::/48,,,,
2001:db8:2::/48,,,, 2001:db8:2::/48,,,,
]]></artwork> ]]></artwork>
</figure></t> <t>Historically, the user-assigned alpha2code identifier of "ZZ" has
been used for this same purpose. This is not necessarily preferred,
<t>Historically, the user-assigned alpha2code identifier of "ZZ" has b and no specific interpretation of any of the other user-assigned
een alpha2code codes is currently defined.</t>
used for this same purpose. This is not necessarily preferred, and
no specific interpretation of any of the other user-assigned alpha2cod
e
codes is currently defined.</t>
</section> </section>
<section numbered="true" toc="default">
<section title="Additional Parsing Requirements"> <name>Additional Parsing Requirements</name>
<t>Feed entries missing an IP address or prefix field or having an <t>Feed entries that do not have an IP address or prefix field or have
IP address or prefix field which fails to parse correctly MUST be an
discarded.</t> IP address or prefix field that fails to parse correctly
<bcp14>MUST</bcp14> be discarded.</t>
<t>While publishers SHOULD follow <xref target="RFC5952"/> style for <t>While publishers <bcp14>SHOULD</bcp14> follow <xref
IPv6 prefix fields, consumers MUST nevertheless accept all valid target="RFC5952" format="default"/> for IPv6 prefix fields,
string representations.</t> consumers <bcp14>MUST</bcp14> nevertheless accept all valid string
representations.</t>
<t>Duplicate IP address or prefix entries MUST be considered an <t>Duplicate IP address or prefix entries <bcp14>MUST</bcp14> be
error, and consumer implementations SHOULD log the repeated entries considered an error, and consumer implementations
for further administrative review. Publishers SHOULD take measures <bcp14>SHOULD</bcp14> log the repeated entries for further
to ensure there is one and only one entry per IP address and administrative review. Publishers <bcp14>SHOULD</bcp14> take
prefix.</t> measures to ensure there is one and only one entry per IP address
and prefix.</t>
<t>Multiple entries which constitute nested prefixes are permitted. <t>Multiple entries that constitute nested prefixes are
Consumers SHOULD consider the entry with the longest matching prefix permitted. Consumers <bcp14>SHOULD</bcp14> consider the entry with
(i.e. the "most specific") to be the best matching entry for a given the longest matching prefix (i.e., the "most specific") to be the
IP address.</t> best matching entry for a given IP address.</t>
<t>Feed entries with non-empty optional fields that fail to parse,
<t>Feed entries with non-empty optional fields which fail to parse, either in part or in full, <bcp14>SHOULD</bcp14> be discarded. It is
either in part or in full, SHOULD be discarded. It is RECOMMENDED <bcp14>RECOMMENDED</bcp14> that they also be logged for further
that they also be logged for further administrative review.</t> administrative review.</t>
<t>For compatibility with future additional fields, a parser
<t>For compatibility with future additional fields, a parser MUST <bcp14>MUST</bcp14> ignore any fields beyond those it expects. The
ignore any fields beyond those it expects. The data from fields data from fields that are expected and that parse successfully
which are expected and which parse successfully MUST still be <bcp14>MUST</bcp14> still be considered valid. Per <xref
considered valid. Per <xref target="future_work"/> no extensions to target="future_work" format="default"/>, no extensions to this format
this format are in use nor are any anticipated.</t> are in use nor are any anticipated.</t>
</section> </section>
</section> </section>
<section numbered="true" toc="default">
<section title="Examples"> <name>Examples</name>
<t>Example entries using different IP address formats and describing <t>Example entries using different IP address formats and describing
locations at alpha2code ("country code"), region, and city granularity l locations at alpha2code ("country code"), region, and city granularity
evel, level, respectively: </t>
respectively: <figure> <artwork name="" type="" align="left" alt=""><![CDATA[
<artwork><![CDATA[ 192.0.2.0/25,US,US-AL,,
192.0.2.0/25,US,US-AL,, 192.0.2.5,US,US-AL,Alabaster,
192.0.2.5,US,US-AL,Alabaster, 192.0.2.128/25,PL,PL-MZ,,
192.0.2.128/25,PL,PL-MZ,, 2001:db8::/32,PL,,,
2001:db8::/32,PL,,, 2001:db8:cafe::/48,PL,PL-MZ,,
2001:db8:cafe::/48,PL,PL-MZ,, ]]></artwork>
]]></artwork>
</figure></t>
<t>The IETF network publishes geolocation information for the meeting <t>The IETF network publishes geolocation information for the meeting
prefixes, and generally just comment out the last meeting information prefixes, and generally just comment out the last meeting information
and append the new meeting information. The <xref target="GEO_IETF"/> and append the new meeting information. The <xref target="GEO_IETF"
at the time of this writing contains:</t> format="default"/>, at the time of this writing, contains:
<t><figure>
<artwork><![CDATA[
# IETF106 (Singapore) - November 2019 - Singapore, SG
130.129.0.0/16,SG,SG-01,Singapore,
2001:df8::/32,SG,SG-01,Singapore,
31.133.128.0/18,SG,SG-01,Singapore,
31.130.224.0/20,SG,SG-01,Singapore,
2001:67c:1230::/46,SG,SG-01,Singapore,
2001:67c:370::/48,SG,SG-01,Singapore,
]]></artwork>
</figure></t>
</t>
<artwork name="" type="" align="left" alt=""><![CDATA[
# IETF106 (Singapore) - November 2019 - Singapore, SG
130.129.0.0/16,SG,SG-01,Singapore,
2001:df8::/32,SG,SG-01,Singapore,
31.133.128.0/18,SG,SG-01,Singapore,
31.130.224.0/20,SG,SG-01,Singapore,
2001:67c:1230::/46,SG,SG-01,Singapore,
2001:67c:370::/48,SG,SG-01,Singapore,
]]></artwork>
<t>Experimentally, RIPE has published geolocation information for <t>Experimentally, RIPE has published geolocation information for
their conference network prefixes, which change location in accordance their conference network prefixes, which change location in accordance
with each new event. <xref target="GEO_RIPE_NCC"/> at the time of with each new event. <xref target="GEO_RIPE_NCC" format="default"/>, at
writing contains: <figure> the time of
<artwork><![CDATA[ writing, contains:</t>
193.0.24.0/21,NL,NL-ZH,Rotterdam, <artwork name="" type="" align="left" alt=""><![CDATA[
2001:67c:64::/48,NL,NL-ZH,Rotterdam, 193.0.24.0/21,NL,NL-ZH,Rotterdam,
]]></artwork> 2001:67c:64::/48,NL,NL-ZH,Rotterdam,
</figure></t> ]]></artwork>
<t>Similarly, ICANN has published geolocation information for their <t>Similarly, ICANN has published geolocation information for their
portable conference network prefixes. <xref target="GEO_ICANN"/> at portable conference network prefixes. <xref target="GEO_ICANN" format="d
the time of writing contains: <figure> efault"/>, at
<artwork><![CDATA[ the time of writing, contains: </t>
199.91.192.0/21,MA,MA-07,Marrakech <artwork name="" type="" align="left" alt=""><![CDATA[
2620:f:8000::/48,MA,MA-07,Marrakech 199.91.192.0/21,MA,MA-07,Marrakech
]]></artwork> 2620:f:8000::/48,MA,MA-07,Marrakech
</figure></t> ]]></artwork>
<t>A longer example is the <xref target="GEO_Google" format="default"/>
<t>A longer example is the <xref target="GEO_Google"/> Google Corp Google Corp
Geofeed, which lists the geo-location information for Google corporate Geofeed, which lists the geolocation information for Google corporate
offices.</t> offices.</t>
<t>At the time of writing, Google processes approximately 400 feeds <t>At the time of writing, Google processes approximately 400 feeds
comprising more than 750,000 IPv4 and IPv6 prefixes.</t> comprising more than 750,000 IPv4 and IPv6 prefixes.</t>
</section> </section>
</section> </section>
<section anchor="consumers" numbered="true" toc="default">
<section anchor="consumers" <name>Consuming Self-Published IP Geolocation Feeds</name>
title="Consuming Self-Published IP Geolocation Feeds"> <t>Consumers <bcp14>MAY</bcp14> treat published feed data as a hint only
<t>Consumers MAY treat published feed data as a hint only and MAY choose and <bcp14>MAY</bcp14> choose
to prefer other sources of geolocation information for any given IP to prefer other sources of geolocation information for any given IP
prefix. Regardless of a consumer's stance with respect to a given prefix. Regardless of a consumer's stance with respect to a given
published feed, there are some points of note for sensibly and published feed, there are some points of note for sensibly and
effectively consuming published feeds.</t> effectively consuming published feeds.</t>
<section anchor="integrity" numbered="true" toc="default">
<section anchor="integrity" title="Feed Integrity"> <name>Feed Integrity</name>
<t>The integrity of published information SHOULD be protected by <t>The integrity of published information <bcp14>SHOULD</bcp14> be
securing the means of publication, for example by using HTTP over TLS protected by securing the means of publication, for example, by using
<xref target="RFC2818"/>. Whenever possible, consumers SHOULD prefer HTTP over TLS <xref target="RFC2818" format="default"/>. Whenever
retrieving geolocation feeds in a manner that guarantees integrity of possible, consumers <bcp14>SHOULD</bcp14> prefer retrieving
the feed.</t> geolocation feeds in a manner that guarantees integrity of the
feed.</t>
</section> </section>
<section anchor="authority" numbered="true" toc="default">
<section anchor="authority" title="Verification of Authority"> <name>Verification of Authority</name>
<t>Consumers of self-published IP geolocation feeds SHOULD perform <t>Consumers of self-published IP geolocation feeds <bcp14>SHOULD</bcp14
> perform
some form of verification that the publisher is in fact authoritative some form of verification that the publisher is in fact authoritative
for the addresses in the feed. The actual means of verification is for the addresses in the feed. The actual means of verification is
likely dependent upon the way in which the feed is discovered. Ad hoc likely dependent upon the way in which the feed is discovered. Ad hoc
shared URIs, for example, will likely require an ad hoc verification shared URIs, for example, will likely require an ad hoc verification
process. Future automated means of feed discovery SHOULD have an process. Future automated means of feed discovery <bcp14>SHOULD</bcp14> have an
accompanying automated means of verification.</t> accompanying automated means of verification.</t>
<t>A consumer should only trust geolocation information for IP addresses <t>A consumer should only trust geolocation information for IP addresses
or prefixes for which the publisher has been verified as or prefixes for which the publisher has been verified as
administratively authoritative. All other geolocation feed entries administratively authoritative. All other geolocation feed entries
should be ignored and logged for further administrative review.</t> should be ignored and logged for further administrative review.</t>
</section> </section>
<section anchor="accuracy" numbered="true" toc="default">
<section anchor="accuracy" title="Verification of Accuracy"> <name>Verification of Accuracy</name>
<t>Errors and inaccuracies may occur at many levels, and publication <t>Errors and inaccuracies may occur at many levels, and publication
and consumption of geolocation data are no exceptions. To the extent and consumption of geolocation data are no exceptions. To the extent
practical, consumers SHOULD take steps to verify the accuracy of practical, consumers <bcp14>SHOULD</bcp14> take steps to verify the accu racy of
published locality. Verification methodology, resolution of published locality. Verification methodology, resolution of
discrepancies, and preference for alternative sources of data are left discrepancies, and preference for alternative sources of data are left
to the discretion of the feed consumer.</t> to the discretion of the feed consumer.</t>
<t>Consumers <bcp14>SHOULD</bcp14> decide on discrepancy thresholds
<t>Consumers SHOULD decide on discrepancy thresholds and SHOULD flag and <bcp14>SHOULD</bcp14> flag, for administrative review, feed entries
for administrative review feed entries which exceed set that exceed set thresholds.</t>
thresholds.</t>
</section> </section>
<section numbered="true" toc="default">
<section title="Refreshing Feed Information"> <name>Refreshing Feed Information</name>
<t>As a publisher can change geolocation data at any time and without <t>As a publisher can change geolocation data at any time and without
notification, consumers SHOULD implement mechanisms to periodically notification, consumers <bcp14>SHOULD</bcp14> implement mechanisms to pe riodically
refresh local copies of feed data. In the absence of any other refresh refresh local copies of feed data. In the absence of any other refresh
timing information, it is recommended that consumers SHOULD refresh timing information, it is recommended that consumers <bcp14>SHOULD</bcp1
feeds no less often than weekly, and no more often than is likely 4> refresh
feeds no less often than weekly and no more often than is likely
to cause issues to the publisher.</t> to cause issues to the publisher.</t>
<t>For feeds available via HTTPS (or HTTP), the publisher <bcp14>MAY</bc
<t>For feeds available via HTTPS (or HTTP), the publisher MAY p14>
communicate refresh timing information by means of the standard HTTP communicate refresh timing information by means of the standard HTTP
expiration model (<eref expiration model (<xref target="RFC7234"/>). Specifically, publishers ca
target="http://tools.ietf.org/html/rfc2616#section-13.2">section n
13.2</eref> of <xref target="RFC2616"/>). Specifically, publishers can include either an Expires header (<xref target="RFC7234"
include either an <eref sectionFormat="of" section="5.3"/>) or a Cache-Control header (<xref
target="http://tools.ietf.org/html/rfc2616#section-14.21">Expires target="RFC7234" sectionFormat="of" section="5.2"/>) specifying the
header</eref> or a <eref max-age. Where practical, consumers <bcp14>SHOULD</bcp14> refresh feed
target="http://tools.ietf.org/html/rfc2616#section-14.9">Cache-Control information before the expiry time is reached.</t>
header</eref> specifying the max-age. Where practical, consumers
SHOULD refresh feed information before the expiry time is reached.</t>
</section> </section>
</section> </section>
<section anchor="privacy" numbered="true" toc="default">
<section anchor="privacy" title="Privacy Considerations"> <name>Privacy Considerations</name>
<t>Publishers of geolocation feeds are advised to have fully considered <t>Publishers of geolocation feeds are advised to have fully considered
any and all privacy implications of the disclosure of such information any and all privacy implications of the disclosure of such information
for the users of the described networks prior to publication. A thorough for the users of the described networks prior to publication. A thorough
comprehension of the <eref comprehension of the security considerations (<xref target="RFC6772"
target="http://tools.ietf.org/html/rfc6772#section-13">security sectionFormat="of" section="13"/>) of a chosen geolocation policy is
considerations</eref> of a chosen geolocation policy is highly highly recommended, including an understanding of some of the
recommended, including an understanding of some of the <eref limitations of information obscurity (<xref target="RFC6772"
target="http://tools.ietf.org/html/rfc6772#section-13.5">limitations of sectionFormat="of" section="13.5"/>) (see also <xref target="RFC6772"
information obscurity</eref> (see also <xref target="RFC6772"/>).</t> format="default"/>).</t>
<t>As noted in <xref target="spec"/>, each location field in an entry is <t>As noted in <xref target="spec" format="default"/>, each location
field in an entry is
optional, in order to support expressing only the level of specificity optional, in order to support expressing only the level of specificity
which the publisher has deemed acceptable. There is no requirement that that the publisher has deemed acceptable. There is no requirement that
the level of specificity be consistent across all entries within a feed. the level of specificity be consistent across all entries within a feed.
In particular, the Postal Code field (<xref target="postal"/>) can In particular, the Postal Code field (<xref target="postal" format="defaul t"/>) can
provide very specific geolocation, sometimes within a building. Such provide very specific geolocation, sometimes within a building. Such
specific Postal Code values MUST NOT be published in geofeeds without specific Postal Code values <bcp14>MUST NOT</bcp14> be published in geofee ds without
the express consent of the parties being located.</t> the express consent of the parties being located.</t>
<t>Operators who publish geolocation information are strongly encouraged <t>Operators who publish geolocation information are strongly encouraged
to inform affected users/customers of this fact and of the potential to inform affected users/customers of this fact and of the potential
privacy-related consequences and trade-offs.</t> privacy-related consequences and trade-offs.</t>
</section> </section>
<section numbered="true" toc="default">
<section title="Relation to Other Work"> <name>Relation to Other Work</name>
<t>While not originally done in conjunction with the <xref <t>While not originally done in conjunction with the GEOPRIV
target="GEOPRIV"/> working group, Richard Barnes observed that this work Working Group <xref
target="GEOPRIV" format="default"/>, Richard Barnes
observed that this work
is nevertheless consistent with that which the group has defined, both is nevertheless consistent with that which the group has defined, both
for address format and for privacy. The data elements in geolocation for address format and for privacy. The data elements in geolocation
feeds are equivalent to the following XML structure (vis. <xref feeds are equivalent to the following XML structure (<xref
target="RFC5139"/>): <figure> target="RFC5139" format="default"/> <xref
<artwork><![CDATA[ target="W3C.REC-xml-20081126" format="default"/>):
<civicAddress>
<country>country</country>
<A1>region</A1>
<A2>city</A2>
<PC>postal_code</PC>
</civicAddress>
]]></artwork>
</figure></t>
</t>
<sourcecode type="xml"><![CDATA[
<civicAddress>
<country>country</country>
<A1>region</A1>
<A2>city</A2>
<PC>postal_code</PC>
</civicAddress>
]]></sourcecode>
<t>Providing geolocation information to this granularity is equivalent <t>Providing geolocation information to this granularity is equivalent
to the following privacy policy (vis. the definition of the <eref to the following privacy policy (the definition of the 'building'
target="http://tools.ietf.org/html/rfc6772#section-6.5.1"> <xref target="RFC6772" sectionFormat="of" section="6.5.1"/> level of
'building'</eref> level of disclosure): <figure> disclosure):</t>
<artwork><![CDATA[ <sourcecode type="xml"><![CDATA[
<ruleset> <ruleset>
<rule> <rule>
<conditions/> <conditions/>
<actions/> <actions/>
<transformations> <transformations>
<provide-location profile="civic-transformation"> <provide-location profile="civic-transformation">
<provide-civic>building</provide-civic> <provide-civic>building</provide-civic>
</provide-location> </provide-location>
</transformations> </transformations>
</rule> </rule>
</ruleset> </ruleset>
]]></artwork> ]]></sourcecode>
</figure></t>
</section> </section>
<section anchor="Security" numbered="true" toc="default">
<section anchor="Security" title="Security Considerations"> <name>Security Considerations</name>
<t>As there is no true security in the obscurity of the location of any <t>As there is no true security in the obscurity of the location of any
given IP address, self-publication of this data fundamentally opens no given IP address, self-publication of this data fundamentally opens no
new attack vectors. For publishers, self-published data may increase new attack vectors. For publishers, self-published data may increase
the ease with which such location data might be exploited (it can, for the ease with which such location data might be exploited (it can, for
example, make easy the discovery of prefixes populated with customers example, make easy the discovery of prefixes populated with customers
as distinct from prefixes not generally in use).</t> as distinct from prefixes not generally in use).</t>
<t>For consumers, feed retrieval processes may receive input from <t>For consumers, feed retrieval processes may receive input from
potentially hostile sources (e.g. in the event of hijacked traffic). As potentially hostile sources (e.g., in the event of hijacked traffic). As
such, proper input validation and defense measures MUST be taken (see such, proper input validation and defense measures <bcp14>MUST</bcp14> be
the discussion in <xref target="integrity"/>).</t> taken (see
the discussion in <xref target="integrity" format="default"/>).</t>
<t>Similarly, consumers who do not perform sufficient verification of <t>Similarly, consumers who do not perform sufficient verification of
published data bear the same risks as from other forms of geolocation published data bear the same risks as from other forms of geolocation
configuration errors (see the discussion in <xref target="authority"/> configuration errors (see the discussion in Sections <xref
and <xref target="accuracy"/>).</t> target="authority" format="counter"/>
and <xref target="accuracy" format="counter"/>).</t>
<t>Validation of a feed's contents includes verifying that the publisher <t>Validation of a feed's contents includes verifying that the publisher
is authoritative for the IP prefixes included in the feed. Failure to is authoritative for the IP prefixes included in the feed. Failure to
verify IP prefix authority would, for example, allow ISP Bob to make verify IP prefix authority would, for example, allow ISP Bob to make
geolocation statements about IP space held by ISP Alice. At this time geolocation statements about IP space held by ISP Alice. At this time,
only out-of-band verification methods are implemented (i.e. an ISP's only out-of-band verification methods are implemented (i.e., an ISP's
feed may be verified against publicly available IP allocation data). feed may be verified against publicly available IP allocation data).
</t> </t>
</section> </section>
<section anchor="future_work" numbered="true" toc="default">
<section anchor="future_work" title="Planned Future Work"> <name>Planned Future Work</name>
<t>In order to more flexibly support future extensions, use of a more <t>In order to more flexibly support future extensions, use of a more
expressive feed format has been suggested. Use of JavaScript Object expressive feed format has been suggested. Use of JavaScript Object
Notation (JSON, <xref target="RFC4627"/>), specifically, has been Notation (JSON) <xref target="RFC8259" format="default"/>,
discussed. However, at the time of writing no such specification nor specifically, has been
discussed. However, at the time of writing, no such specification nor
implementation exists. Nevertheless, work on extensions is deferred implementation exists. Nevertheless, work on extensions is deferred
until a more suitable format has been selected.</t> until a more suitable format has been selected.</t>
<t>The authors are planning on writing a document describing such a <t>The authors are planning on writing a document describing such a
new format. This document describes a currently deployed and used new format. This document describes a currently deployed and used
format. Given the extremely limited extensibility of the present format format. Given the extremely limited extensibility of the present format
no extensions to it are anticipated. Extensibility requirements are no extensions to it are anticipated. Extensibility requirements are
instead expected to be integral to the development of a new format.</t> instead expected to be integral to the development of a new format.</t>
</section> </section>
<section numbered="true" toc="default">
<section title="Finding Self-Published IP Geolocation Feeds"> <name>Finding Self-Published IP Geolocation Feeds</name>
<t>The issue of finding, and later verifying, geolocation feeds is not <t>The issue of finding, and later verifying, geolocation feeds is not
formally specified in this document. At this time, only ad hoc feed formally specified in this document. At this time, only ad hoc feed
discovery and verification has a modicum of established practice (see discovery and verification has a modicum of established practice (see
below); discussion of other mechanisms has been removed for clarity.</t> below); discussion of other mechanisms has been removed for clarity.</t>
<section numbered="true" toc="default">
<section title="Ad Hoc 'Well Known' URIs"> <name>Ad Hoc 'Well-Known' URIs</name>
<t>To date, geolocation feeds have been shared informally in the form <t>To date, geolocation feeds have been shared informally in the form
of HTTPS URIs exchanged in email threads. Three of example URIs of HTTPS URIs exchanged in email threads. Three example URIs (<xref
documented below (<xref target="GEO_IETF"/>, <xref target="GEO_RIPE_NCC" target="GEO_IETF" format="default"/>, <xref target="GEO_RIPE_NCC"
/>, format="default"/>, and <xref target="GEO_ICANN" format="default"/>)
<xref target="GEO_ICANN"/>) describe networks that change locations peri describe networks that change locations periodically, the operators
odically, and operational practices of which are well known within their
the operators and operational practices of which are well known within respective technical communities.</t>
their respective technical communities.</t>
<t>The contents of the feeds are verified by a similarly ad hoc <t>The contents of the feeds are verified by a similarly ad hoc
process including: <list style="symbols"> process, including: </t>
<t>personal knowledge of the parties involved in the exchange, <ul spacing="normal">
and</t> <li>personal knowledge of the parties involved in the exchange
and</li>
<t>comparison of feed-advertised prefixes with the BGP-advertised <li>comparison of feed-advertised prefixes with the BGP-advertised
prefixes of Autonomous System Numbers known to be operated by the prefixes of Autonomous System Numbers known to be operated by the
publishers.</t> publishers.</li>
</list></t> </ul>
<t>Ad hoc mechanisms, while useful for early experimentation by <t>Ad hoc mechanisms, while useful for early experimentation by
producers and consumers, are unlikely to be adequate for long-term, producers and consumers, are unlikely to be adequate for long-term,
widespread use by multiple parties. Future versions of any such widespread use by multiple parties. Future versions of any such
self-published geolocation feed mechanism SHOULD address scalability self-published geolocation feed mechanism <bcp14>SHOULD</bcp14> address scalability
concerns by defining a means for automated discovery and verification concerns by defining a means for automated discovery and verification
of operational authority of advertised prefixes.</t> of operational authority of advertised prefixes.</t>
</section> </section>
<section numbered="true" toc="default">
<section title="Other Mechanisms"> <name>Other Mechanisms</name>
<t>Previous versions of this document referenced use of the <t>Previous versions of this document referenced use of the
WHOIS service (<xref target="RFC3912"/>) operated by RIRs as well as WHOIS service <xref target="RFC3912" format="default"/> operated by
Regional Internet Registries (RIRs), as well as
possible DNS-based schemes to discover and validate geofeeds. possible DNS-based schemes to discover and validate geofeeds.
To the authors' knowledge support for such mechanisms has never been To the authors' knowledge, support for such mechanisms has never been
implemented, and this speculative text has been removed to avoid implemented, and this speculative text has been removed to avoid
ambiguity.</t> ambiguity.</t>
</section> </section>
</section> </section>
<section numbered="true" toc="default">
<section title="IANA Considerations"> <name>IANA Considerations</name>
<t>This document makes no requests of the IANA.</t> <t>This document has no IANA actions.</t>
</section>
<section title="Acknowledgements">
<t>The authors would like to express their gratitude to reviewers and
early implementers, including but not limited to Mikael Abrahamsson,
Andrew Alston, Ray Bellis, John Bond, Alissa Cooper, Andras Erdei,
Stephen Farrell, Marco Hogewoning, Mike Joseph, Maciej Kuzniar,
George Michaelson, Menno Schepers, Justyna Sidorska, Pim van Pelt, and
Bjoern A.&nbsp;Zeeb.</t>
<t>Richard L.&nbsp;Barnes and Andy Newton in particular contributed
substantial review, text, and advice.</t>
</section> </section>
</middle> </middle>
<back> <back>
<references title="Normative References"> <references>
<reference anchor="ISO.3166.1alpha2" <name>References</name>
target="http://www.iso.org/iso/home/standards/country_codes/iso <references>
-3166-1_decoding_table.htm"> <name>Normative References</name>
<front> <reference anchor="ISO.3166.1alpha2" target="http://www.iso.org/iso/home
<title>ISO 3166-1 decoding table</title> /standards/country_codes/iso-3166-1_decoding_table.htm">
<front>
<author fullname="ISO 3166 Maintenance agency"> <title>ISO 3166-1 decoding table</title>
<organization abbrev="ISO">International Organization for <author>
Standardization</organization> <organization>ISO</organization>
</author> </author>
</front>
<date/> </reference>
</front> <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer
</reference> ence.RFC.2119.xml"/>
<xi:include
<?rfc include='reference.RFC.2616.xml'?> href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.
<?rfc include='reference.RFC.3629.xml'?> 7234.xml"/>
<?rfc include='reference.RFC.4180.xml'?>
<?rfc include='reference.RFC.4291.xml'?>
<?rfc include='reference.RFC.4632.xml'?>
<?rfc include='reference.RFC.5952.xml'?>
<reference anchor="ISO.3166.2"
target="http://www.iso.org/iso/home/standards/country_codes.htm
#2012_iso3166-2">
<front>
<title>ISO 3166-2:2007</title>
<author fullname="ISO 3166 Maintenance agency">
<organization abbrev="ISO">International Organization for
Standardization</organization>
</author>
<date/>
</front>
</reference>
</references>
<references title="Informative References">
<?rfc include='reference.RFC.2119.xml'?>
<?rfc include='reference.RFC.2818.xml'?>
<?rfc include='reference.RFC.3912.xml'?>
<?rfc include='reference.RFC.4408.xml'?>
<?rfc include='reference.RFC.4627.xml'?>
<?rfc include='reference.RFC.5139.xml'?>
<?rfc include='reference.RFC.6772.xml'?>
<?rfc include='reference.RFC.8174.xml'?>
<reference anchor="GEO_IETF"
target="https://noc.ietf.org/geo/google.csv">
<front>
<title>IETF Meeting Network Geolocation Data</title>
<author fullname="Warren" initials="A." surname="Kumari"> <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer
<organization abbrev="IETF NOC">Internet Engineering Task Force ence.RFC.3629.xml"/>
(IETF) NOC</organization> <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer
</author> ence.RFC.4180.xml"/>
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer
ence.RFC.4291.xml"/>
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer
ence.RFC.4632.xml"/>
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer
ence.RFC.5952.xml"/>
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer
ence.RFC.8174.xml"/>
<reference anchor="ISO.3166.2" target="http://www.iso.org/iso/home/stand
ards/country_codes.htm#2012_iso3166-2">
<front>
<title>ISO 3166-2:2007</title>
<author>
<organization>ISO</organization>
</author>
</front>
</reference>
<date/> <reference anchor="W3C.REC-xml-20081126" target="http://www.w3.org/TR/2008/REC-x
</front> ml-20081126" quoteTitle="true" derivedAnchor="W3C.REC-xml-20081126">
</reference> <front>
<title>Extensible Markup Language (XML) 1.0 (Fifth Edition)</title>
<author initials="T." surname="Bray" fullname="Tim Bray">
<organization showOnFrontPage="true"/>
</author>
<author initials="J." surname="Paoli" fullname="Jean Paoli">
<organization showOnFrontPage="true"/>
</author>
<author initials="M." surname="Sperberg-McQueen" fullname="Michael S
perberg-McQueen">
<organization showOnFrontPage="true"/>
</author>
<author initials="E." surname="Maler" fullname="Eve Maler">
<organization showOnFrontPage="true"/>
</author>
<author initials="F." surname="Yergeau" fullname="François Yergeau">
<organization showOnFrontPage="true"/>
</author>
<date month="November" year="2008"/>
</front>
<seriesInfo name="World Wide Web Consortium Recommendation" value="REC
-xml-20081126"/>
<format type="HTML" target="http://www.w3.org/TR/2008/REC-xml-20081126
"/>
</reference>
<reference anchor="GEO_RIPE_NCC" </references>
target="https://meetings.ripe.net/geo/google.csv"> <references>
<front> <name>Informative References</name>
<title>RIPE NCC Meeting Geolocation Data</title> <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer
ence.RFC.2818.xml"/>
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer
ence.RFC.3912.xml"/>
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer
ence.RFC.7208.xml"/>
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer
ence.RFC.8259.xml"/>
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer
ence.RFC.5139.xml"/>
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer
ence.RFC.6772.xml"/>
<author fullname="Menno Schepers" initials="M." surname="Schepers"> <reference anchor="GEO_IETF" target="https://noc.ietf.org/geo/google.csv
<organization abbrev="RIPE NCC">R&eacute;seaux IP Europ&eacute;ens ">
<front>
<title>IETF Meeting Network Geolocation Data</title>
<author initials="W." surname="Kumari" fullname="Warren Kumari">
<organization/>
</author>
</front>
</reference>
<reference anchor="GEO_RIPE_NCC" target="https://meetings.ripe.net/geo/g
oogle.csv">
<front>
<title>RIPE NCC Meeting Geolocation Data</title>
<author fullname="Menno Schepers" initials="M." surname="Schepers">
<organization abbrev="RIPE NCC">Réseaux IP Européens
Network Coordination Centre</organization> Network Coordination Centre</organization>
</author> </author>
</front>
<date/> </reference>
</front> <reference anchor="GEO_ICANN" target="https://meeting-services.icann.org
</reference> /geo/google.csv">
<front>
<reference anchor="GEO_ICANN" <title>ICANN Meeting Geolocation Data</title>
target="https://meeting-services.icann.org/geo/google.csv"> <author>
<front> <organization>ICANN</organization>
<title>ICANN Meeting Geolocation Data</title> </author>
</front>
<author> </reference>
<organization abbrev="ICANN">Internet Corporation For Assigned <reference anchor="GEO_Google" target="https://www.gstatic.com/geofeed/c
Names and Numbers</organization> orp_external">
</author> <front>
<title>Google Corp Geofeed</title>
<date/> <author>
</front> <organization>Google, LLC</organization>
</reference> </author>
</front>
<reference anchor="GEO_Google" </reference>
target="https://www.gstatic.com/geofeed/corp_external"> <reference anchor="GEOPRIV" target="http://datatracker.ietf.org/wg/geopr
<front> iv/">
<title>Google Corp Geofeed</title> <front>
<author> <title>Geographic Location/Privacy (geopriv)</title>
<organization>Google, LLC</organization> <author>
</author> <organization>IETF</organization>
</author>
<date/> <date/>
</front> </front>
</reference> </reference>
<reference anchor="IPADDR_PY" target="http://code.google.com/p/ipaddr-py
<reference anchor="GEOPRIV" /">
target="http://datatracker.ietf.org/wg/geopriv/"> <front>
<front> <title>Google's Python IP address manipulation library</title>
<title>IETF geopriv Working Group</title> <author fullname="Mike Shields" initials="M." surname="Shields">
<organization abbrev="Google">Google Inc.</organization>
<author> </author>
<organization abbrev="IETF">Internet Engineering Task <author fullname="Peter Moody" initials="P." surname="Moody">
Force</organization> <organization abbrev="Google">Google Inc.</organization>
</author> </author>
<date/>
<date/> </front>
</front> </reference>
</reference> <reference anchor="ISO-GLOSSARY"
target="https://www.iso.org/glossary-for-iso-3166.html">
<reference anchor="IPADDR_PY" <front>
target="http://code.google.com/p/ipaddr-py/"> <title>Glossary for ISO 3166</title>
<front> <author>
<title>Python IP address manipulation library</title> <organization>ISO</organization>
</author>
<author fullname="Mike Shields" initials="M." surname="Shields"> <date/>
<organization abbrev="Google">Google Inc.</organization> </front>
</author> </reference>
<author fullname="Peter Moody" initials="P." surname="Moody">
<organization abbrev="Google">Google Inc.</organization>
</author>
<date/> </references>
</front>
</reference>
</references> </references>
<section numbered="true" toc="default">
<section title="Sample Python Validation Code"> <name>Sample Python Validation Code</name>
<t>Included here is a simple format validator in Python for <t>Included here is a simple format validator in Python for
self-published ipgeo feeds. This tool reads CSV data in the self-published ipgeo feeds. This tool reads CSV data in the
self-published ipgeo feed format from the standard input and performs self-published ipgeo feed format from the standard input and performs
basic validation. It is intended for use by feed publishers before basic validation. It is intended for use by feed publishers before
launching a feed. Note that this validator does not verify the launching a feed. Note that this validator does not verify the
uniqueness of every IP prefix entry within the feed as a whole, but only uniqueness of every IP prefix entry within the feed as a whole but only
verifies the syntax of each single line from within the feed. A complete verifies the syntax of each single line from within the feed. A complete
validator MUST also ensure IP prefix uniqueness.</t> validator <bcp14>MUST</bcp14> also ensure IP prefix uniqueness.</t>
<t>The main source file "ipgeo_feed_validator.py" follows. It requires <t>The main source file "ipgeo_feed_validator.py" follows. It requires
use of the open source ipaddr Python library for IP address and CIDR use of the open source ipaddr Python library for IP address and CIDR
parsing and validation <xref target="IPADDR_PY"/>.</t> parsing and validation <xref target="IPADDR_PY" format="default"/>.</t>
<sourcecode name="" type="python" markers="true"><![CDATA[
<t><figure>
<artwork><![CDATA[
<CODE BEGINS>
#!/usr/bin/python #!/usr/bin/python
# #
# Copyright (c) 2012 IETF Trust and the persons identified as authors of # Copyright (c) 2012 IETF Trust and the persons identified as
# the code. All rights reserved. Redistribution and use in source and # authors of the code. All rights reserved. Redistribution and use
# binary forms, with or without modification, is permitted pursuant to, # in source and binary forms, with or without modification, is
# and subject to the license terms contained in, the Simplified BSD # permitted pursuant to, and subject to the license terms contained
# License set forth in Section 4.c of the IETF Trust's Legal Provisions # in, the Simplified BSD License set forth in Section 4.c of the
# Relating to IETF Documents (http://trustee.ietf.org/license-info). # IETF Trust's Legal Provisions Relating to IETF
# Documents (http://trustee.ietf.org/license-info).
"""Simple format validator for self-published ipgeo feeds. """Simple format validator for self-published ipgeo feeds.
This tool reads CSV data in the self-published ipgeo feed format from This tool reads CSV data in the self-published ipgeo feed format
the standard input and performs basic validation. It is intended for from the standard input and performs basic validation. It is
use by feed publishers before launching a feed. intended for use by feed publishers before launching a feed.
""" """
import csv import csv
import ipaddr import ipaddr
import re import re
import sys import sys
class IPGeoFeedValidator(object): class IPGeoFeedValidator(object):
def __init__(self): def __init__(self):
self.prefixes = {} self.prefixes = {}
skipping to change at line 838 skipping to change at line 769
for line in feed: for line in feed:
self._ValidateLine(line) self._ValidateLine(line)
def SetOutputStream(self, logfile): def SetOutputStream(self, logfile):
"""Controls where the output messages go do (STDERR by default). """Controls where the output messages go do (STDERR by default).
Use None to disable logging. Use None to disable logging.
Args: Args:
logfile: a file object (e.g., sys.stdout or sys.stderr) or None. logfile: a file object (e.g., sys.stdout) or None.
""" """
self.output_stream = logfile self.output_stream = logfile
def CountErrors(self, severity): def CountErrors(self, severity):
"""How many ERRORs or WARNINGs were generated.""" """How many ERRORs or WARNINGs were generated."""
return len(self.output_log.get(severity, [])) return len(self.output_log.get(severity, []))
############################################################ ############################################################
def _ValidateLine(self, line): def _ValidateLine(self, line):
line = line.rstrip('\r\n') line = line.rstrip('\r\n')
skipping to change at line 929 skipping to change at line 860
if len(alpha2code) != 2 or not alpha2code.isalpha(): if len(alpha2code) != 2 or not alpha2code.isalpha():
self._ReportError( self._ReportError(
'Alpha 2 code must be in the ISO 3166-1 alpha 2 format.') 'Alpha 2 code must be in the ISO 3166-1 alpha 2 format.')
return False return False
return True return True
def _IsRegionCodeCorrect(self, region_code): def _IsRegionCodeCorrect(self, region_code):
if len(region_code) == 0: if len(region_code) == 0:
return True return True
if '-' not in region_code: if '-' not in region_code:
self._ReportError('Region code must be in the ISO 3166-2 format.') self._ReportError('Region code must be in ISO 3166-2 format.')
return False return False
parts = region_code.split('-') parts = region_code.split('-')
if not self._IsAlpha2CodeCorrect(parts[0]): if not self._IsAlpha2CodeCorrect(parts[0]):
return False return False
return True return True
############################################################ ############################################################
def _ReportError(self, message): def _ReportError(self, message):
self._ReportWithSeverity('ERROR', message) self._ReportWithSeverity('ERROR', message)
skipping to change at line 972 skipping to change at line 903
############################################################ ############################################################
def main(): def main():
feed_validator = IPGeoFeedValidator() feed_validator = IPGeoFeedValidator()
feed_validator.Validate(sys.stdin) feed_validator.Validate(sys.stdin)
if feed_validator.CountErrors('ERROR'): if feed_validator.CountErrors('ERROR'):
sys.exit(1) sys.exit(1)
if __name__ == '__main__': if __name__ == '__main__':
main() main()
<CODE ENDS> ]]></sourcecode>
]]></artwork>
</figure></t>
<t>A unit test file, "ipgeo_feed_validator_test.py" is provided as well. <t>A unit test file, "ipgeo_feed_validator_test.py" is provided as well.
It provides basic test coverage of the code above, though does not test It provides basic test coverage of the code above, though does not test
correct handling of non-ASCII UTF-8 strings.</t> correct handling of non-ASCII UTF-8 strings.</t>
<sourcecode name="" type="python" markers="true"><![CDATA[
<t><figure>
<artwork><![CDATA[
<CODE BEGINS>
#!/usr/bin/python #!/usr/bin/python
# #
# Copyright (c) 2012 IETF Trust and the persons identified as authors of # Copyright (c) 2012 IETF Trust and the persons identified as
# the code. All rights reserved. Redistribution and use in source and # authors of the code. All rights reserved. Redistribution and use
# binary forms, with or without modification, is permitted pursuant to, # in source and binary forms, with or without modification, is
# and subject to the license terms contained in, the Simplified BSD # permitted pursuant to, and subject to the license terms contained
# License set forth in Section 4.c of the IETF Trust's Legal Provisions # in, the Simplified BSD License set forth in Section 4.c of the
# Relating to IETF Documents (http://trustee.ietf.org/license-info). # IETF Trust's Legal Provisions Relating to IETF
# Documents (http://trustee.ietf.org/license-info).
import sys import sys
from ipgeo_feed_validator import IPGeoFeedValidator from ipgeo_feed_validator import IPGeoFeedValidator
class IPGeoFeedValidatorTest(object): class IPGeoFeedValidatorTest(object):
def __init__(self): def __init__(self):
self.validator = IPGeoFeedValidator() self.validator = IPGeoFeedValidator()
self.validator.SetOutputStream(None) self.validator.SetOutputStream(None)
self.successes = 0 self.successes = 0
self.failures = 0 self.failures = 0
skipping to change at line 1033 skipping to change at line 958
self.TestFeedLine('55.66.77.88,ZZ,,,', 0, 0) self.TestFeedLine('55.66.77.88,ZZ,,,', 0, 0)
self.TestFeedLine('55.66.77.88,US,,,', 0, 0) self.TestFeedLine('55.66.77.88,US,,,', 0, 0)
self.TestFeedLine('55.66.77.88,USA,,,', 1, 0) self.TestFeedLine('55.66.77.88,USA,,,', 1, 0)
self.TestFeedLine('55.66.77.88,99,,,', 1, 0) self.TestFeedLine('55.66.77.88,99,,,', 1, 0)
self.TestFeedLine('55.66.77.88,US,US-CA,,', 0, 0) self.TestFeedLine('55.66.77.88,US,US-CA,,', 0, 0)
self.TestFeedLine('55.66.77.88,US,USA-CA,,', 1, 0) self.TestFeedLine('55.66.77.88,US,USA-CA,,', 1, 0)
self.TestFeedLine('55.66.77.88,USA,USA-CA,,', 2, 0) self.TestFeedLine('55.66.77.88,USA,USA-CA,,', 2, 0)
self.TestFeedLine('55.66.77.88,US,US-CA,Mountain View,', 0, 0) self.TestFeedLine('55.66.77.88,US,US-CA,Mountain View,', 0, 0)
self.TestFeedLine('55.66.77.88,US,US-CA,Mountain View,94043', 0, 0) self.TestFeedLine('55.66.77.88,US,US-CA,Mountain View,94043',
0, 0)
self.TestFeedLine('55.66.77.88,US,US-CA,Mountain View,94043,' self.TestFeedLine('55.66.77.88,US,US-CA,Mountain View,94043,'
'1600 Ampthitheatre Parkway', 0, 1) '1600 Ampthitheatre Parkway', 0, 1)
self.TestFeedLine('55.66.77.0/24,US,,,', 0, 0) self.TestFeedLine('55.66.77.0/24,US,,,', 0, 0)
self.TestFeedLine('55.66.77.88/24,US,,,', 1, 0) self.TestFeedLine('55.66.77.88/24,US,,,', 1, 0)
self.TestFeedLine('55.66.77.88/32,US,,,', 0, 0) self.TestFeedLine('55.66.77.88/32,US,,,', 0, 0)
self.TestFeedLine('55.66.77/24,US,,,', 1, 0) self.TestFeedLine('55.66.77/24,US,,,', 1, 0)
self.TestFeedLine('55.66.77.0/35,US,,,', 1, 0) self.TestFeedLine('55.66.77.0/35,US,,,', 1, 0)
self.TestFeedLine('172.15.30.1,US,,,', 0, 0) self.TestFeedLine('172.15.30.1,US,,,', 0, 0)
skipping to change at line 1055 skipping to change at line 981
self.TestFeedLine('192.167.100.1,US,,,', 0, 0) self.TestFeedLine('192.167.100.1,US,,,', 0, 0)
self.TestFeedLine('192.168.100.1,US,,,', 1, 0) self.TestFeedLine('192.168.100.1,US,,,', 1, 0)
self.TestFeedLine('10.0.5.9,US,,,', 1, 0) self.TestFeedLine('10.0.5.9,US,,,', 1, 0)
self.TestFeedLine('10.0.5.0/24,US,,,', 1, 0) self.TestFeedLine('10.0.5.0/24,US,,,', 1, 0)
self.TestFeedLine('fc00::/48,PL,,,', 1, 0) self.TestFeedLine('fc00::/48,PL,,,', 1, 0)
self.TestFeedLine('fe00::/48,PL,,,', 0, 0) self.TestFeedLine('fe00::/48,PL,,,', 0, 0)
print ('%d tests passed, %d failed' print ('%d tests passed, %d failed'
% (self.successes, self.failures)) % (self.successes, self.failures))
def IsOutputLogCorrectAtSeverity(self, severity, expected_msg_count): def IsOutputLogCorrectAtSeverity(self, severity,
expected_msg_count):
msg_count = self.validator.CountErrors(severity) msg_count = self.validator.CountErrors(severity)
if msg_count != expected_msg_count: if msg_count != expected_msg_count:
print ('TEST FAILED: %s\nexpected %d %s[s], observed %d\n%s\n' % ( print ('TEST FAILED: %s\nexpected %d %s[s], observed %d\n%s\n'
self.validator.line, expected_msg_count, severity, msg_count, % (self.validator.line, expected_msg_count, severity,
msg_count,
str(self.validator.output_log[severity]))) str(self.validator.output_log[severity])))
return False return False
return True return True
def IsOutputLogCorrect(self, new_errors, new_warnings): def IsOutputLogCorrect(self, new_errors, new_warnings):
retval = True retval = True
if not self.IsOutputLogCorrectAtSeverity('ERROR', new_errors): if not self.IsOutputLogCorrectAtSeverity('ERROR', new_errors):
retval = False retval = False
if not self.IsOutputLogCorrectAtSeverity('WARNING', new_warnings): if not self.IsOutputLogCorrectAtSeverity('WARNING',
new_warnings):
retval = False retval = False
return retval return retval
def TestFeedLine(self, line, warning_count, error_count): def TestFeedLine(self, line, warning_count, error_count):
self.validator.output_log['WARNING'] = [] self.validator.output_log['WARNING'] = []
self.validator.output_log['ERROR'] = [] self.validator.output_log['ERROR'] = []
self.validator._ValidateLine(line) self.validator._ValidateLine(line)
if not self.IsOutputLogCorrect(warning_count, error_count): if not self.IsOutputLogCorrect(warning_count, error_count):
self.failures += 1 self.failures += 1
return False return False
self.successes += 1 self.successes += 1
return True return True
if __name__ == '__main__': if __name__ == '__main__':
IPGeoFeedValidatorTest().Run() IPGeoFeedValidatorTest().Run()
<CODE ENDS> ]]></sourcecode>
]]></artwork>
</figure></t> </section>
<section numbered="false" toc="default">
<name>Acknowledgements</name>
<t>The authors would like to express their gratitude to reviewers and
early implementors, including but not limited to <contact
fullname="Mikael Abrahamsson"/>, <contact fullname="Andrew Alston"/>,
<contact fullname="Ray Bellis"/>, <contact fullname="John Bond"/>,
<contact fullname="Alissa Cooper"/>, <contact fullname="Andras Erdei"/>,
<contact fullname="Stephen Farrell"/>, <contact fullname="Marco
Hogewoning"/>, <contact fullname="Mike Joseph"/>, <contact
fullname="Maciej Kuzniar"/>, <contact fullname="George Michaelson"/>,
<contact fullname="Menno Schepers"/>, <contact fullname="Justyna
Sidorska"/>, <contact fullname="Pim van Pelt"/>, and <contact
fullname="Bjoern A. Zeeb"/>.</t>
<t>In particular, <contact fullname="Richard L. Barnes"/> and <contact
fullname="Andy Newton"/> contributed substantial review,
text, and advice.</t>
</section> </section>
</back> </back>
</rfc> </rfc>
 End of changes. 130 change blocks. 
567 lines changed or deleted 542 lines changed or added

This html diff was produced by rfcdiff 1.45. The latest version is available from http://tools.ietf.org/tools/rfcdiff/