<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!-- One method to get references from the online citation libraries.
     There has to be one entity for each item to be referenced. 
     An alternate method (rfc include) is described in the references. -->

<!ENTITY RFC2119 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY RFC2616 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2616.xml">
<!ENTITY RFC4380 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.4380.xml">
]>
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
<?rfc strict="yes" ?>
<?rfc toc="yes"?>
<?rfc tocdepth="4"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes" ?>
<?rfc compact="yes" ?>
<?rfc subcompact="no" ?>
<rfc category="info" docName="draft-vyncke-http-server-64aware-00" ipr="full3978">
  <front>
    <title abbrev="IPv6 Auto-Redirect">IPv6 Connectivity Check and Redirection by HTTP Servers</title>
    <author initials="E" fullname="Eric Vyncke" surname="Vyncke">
      <organization>Cisco Systems</organization>
      <address>
        <postal>
          <street>De Kleetlaan, 6A</street>
          <region></region>
          <code>B-1831</code>
          <city>Diegem</city>
          <country>Belgium</country>
        </postal>
        <phone>+32 2 778 4677</phone>
        <email>evyncke@cisco.com</email>
      </address>
    </author>
    <date month="September" year="2008" />

    <!-- If the month and year are both specified and are the current ones, xml2rfc will fill 
         in the current day for you. If only the current year is specified, xml2rfc will fill 
	 in the current day and month for you. If the year is not the current one, it is 
	 necessary to specify at least a month (xml2rfc assumes day="1" if not specified for the 
	 purpose of calculating the expiry date).  With drafts it is normally sufficient to 
	 specify just the year. -->

    <!-- Meta-data Declarations -->

    <area>Application</area>
    <workgroup>Internet Engineering Task Force</workgroup>
    <keyword>HTML</keyword>
    <keyword>6coexist</keyword>
    <abstract>
      <t>Rather than forcing the client to decide whether IPv4 or IPv6 is more 
	  convenient to reach a web server; this document proposes to let the web
	  server check whether there is IPv6 connectivity to the client; then
	  the web server can do a HTTP redirect to the force the client to
	  use IPv6.</t>
	  
	  <t>This is done easily by a script within the server HTML pages and 
	  does not require any change in the client applications or configuration.
	  The client still can control whether he/she wants to enabled IPv6.</t>
	  
	  <t>This draft could be discussed on the Applications Discuss mailing list,
		https://www.ietf.org/mailman/listinfo/apps-discuss.</t>
    </abstract>
  </front>

  <middle>
    <section title="Introduction">
	
      <t>It is often claimed that web servers are not dual-stack 
	  because the IPv6 has poor connectivity. Therefore, little to no
	  web servers are dual-stacks; it is common to find the same
	  content on www.example.com (for IPv4 access) and on ipv6.example.com
	  (for IPv6 access).</t>
	  
	  <t>The drawback of this setup is that once a user uses www.example.com,
	  then all his/her communication will be over IPv4. This document proposes
	  that the web server MAY run a dynamic and transparent check for the
	  IPv6 connectivity between the client and the server and if there is
	  IPv6 connectivity, then the client MAY be transparently redirected to
	  the IPv6 server, i.e. ipv6.example.com.</t>
	  
	  <t>The check and the redirect can easily be done 
	  by a script within the server HTML pages and 
	  MUST NOT require any change in the client applications or configuration.
	  The client still can control whether he/she wants to enabled IPv6.</t>

      <section title="Requirements Language">
        <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
        "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
        document are to be interpreted as described in <xref
        target="RFC2119">RFC 2119</xref>.</t>
      </section>
    </section>

    <section anchor="redirect" title="Verifying IPv6 Connectivity and Redirection">
		<section anchor="how" title="How can this be done?">
		<t>The procedure can be described as:
		<list style="numbers">
			<t>the IPv4 web server has a start page which includes a small
			transparent image which is located on the ipv6.example.com web
			server. Note: this kind of image is often used on web sites to 
			count access or as a spacer; it is usually a 1 by 1 pixel image.</t>
			<t>the HTML SRC tag includes two events: onload() and
			onerror() which are commonly implemented in browsers.</t>
			<t>if the client has only access to IPv4: the image will fail
			to load but the overall aspect of the web page will not be
			affected as the size of the error is only 1 by 1 pixel. The
			onerror() event is also triggered which could lead to 
			change the web page content (see <xref target="CodeExample">
			the code example</xref>) or even replace the 1x1 image
			by another 1x1 image reachable over IPv4.</t>
			<t>if the client has also access to IPv6 (i.e. it has the
			IPv6 protocol installed and has a valid IPv6 connectivity),
			then the image will load and the onload() event will be
			triggered. The script code associated with the onload()
			can force an immediate redirect of the client to the
			IPv6 web content.</t>
		</list>
		</t>
		
		<t>All the above is only implemented in the HTTP server and
		does not require any change in the client even if the actual
		script is done by the client browser. 
		</t>
		
		<t>The redirect is also mostly transparent to the user.
		</t>
		
		<t>The IPv6 connectivity works independently whether the
		client has configured IPv4 or IPv6 as his/her preferred
		protocol. For instance, it will work with <xref target="RFC4380">
		Teredo</xref> tunnels
		even if those are usually configured as less preferable
		than IPv4.</t>
		
			<section anchor="CodeExample" title="Example of HTML and Ecmascript Code">
		<t>Here is an example in <xref target="HTML">HTML</xref> and in ECMAscript
		<xref target="ECMA-262">ECMA-262</xref> (also known as JavaScript). It
		demonstrates two things which occur when IPv6 connectivity is detected
		(see the function IPv6Image()):
		<list style="numbers">
		<t>the appearance of the web page is changed (a text about
		IPv6 is displayed) and could now differ
		from the IPv4 only web page; this step is optional;
		</t>
		
		<t>a immediate redirection to http://ipv6.example.com is 
		executed; this is the core step.
		</t>
		</list>
		</t>
      <figure>
		<preamble>Here is the HTML image tag which MUST include
		the onload() event and MAY include the onerror()
		event. It MAY be followed
		by a HTML span element which is used to display
		the result of the IPv6 connectivity check.</preamble>
        <artwork align="left"><![CDATA[
<img src="http://ipv6.example.com/1x1pixel.gif" 
	width="1" height="1" border="none" 
	onerror="NoIPv6Image();" onload="IPv6Image();">
<span id="CheckV6">Checking whether you have IPv6 access... </span>

            ]]></artwork>
      </figure>
      <figure>
		<preamble>The example below implements the mandatory
		onload() event handler, IPv6Image(), 
		which redirects to the IPv6 version
		of the web site and the optional onerror() event
		handler, NoIPv6Image(), which is triggered 
		when IPv6 connectivity does not
		exist (in this example, it is used to display a
		message).
		</preamble>
        <artwork align="left"><![CDATA[
<script language="javascript">

// Call back when IPv6 image can load
function IPv6Image() {
	document.getElementById('CheckV6').innerHTML='Good news: ' +
		'you have IPv6 connectivity, redirecting to IPv6' ;
	document.location='http://ipv6.example.com' ;
}

// Call back when IPv6 image cannot load
function NoIPv6Image() {
	document.getElementById('CheckV6').innerHTML='Bad news: ' +
		'you have no IPv6 connectivity.';
} ;

</script>
            ]]></artwork>
      </figure>

			</section>
			<section anchor="poc" title="Proof of Concept">
			<t>There is a very simple proof of concept of this technique. It
			is hosted on a web server at the University of Liège in Belgium
			and can be reached via the following URI:
			</t>
			<t><list>
				<t>http://sigma.hec.be/~evyncke/family/ip.php: the
				normal dual-stack URI.
				</t>
				<t>http://193.190.125.15/~evyncke/family/ip.php: if you
				would like to check the technique as if your browser preferred
				IPv4.
				</t>
				<t>http://[2001:6a8:2c80:1::15]/~evyncke/family/ip.php: if you
				would like to check the technique as if your browser preferred
				IPv6.
				</t>
			</list></t>
			</section>
		</section>
		<section anchor="benefits" title="Benefits of this Technique">
		
		<t>The main benefit of this technique is that there is nothing to install or to configure
		at the client side. Nevertheless, the client has still the possibility to use
		only IPv4 by configuring his/her protocol stacks.</t>
		
		<t>Another benefit is that there is basically little connectivity 
		risk associated with this
		procedure, the client is redirect to the IPv6 version of the web server
		only if a HTTP transaction has been completed successfully over IPv6. 
		This transaction
		is a normal HTTP transaction with full TCP handshake and HTTP
		protocol, so, it includes several
		IPv6 datagrams of varying size. Therefore, if it is successful
		then the IPv6 connectivity between the client and the server
		has been proven.</t>
		
		<t>Note: if Path MTU Discovery is a concern, the 1x1 pixel image 
		could changed to a larger
		one as long as it is kept transparent. As soon as the larger 
		image exceeds 1,500 bytes, Path MTU
		discovery will need to be successful to display the image 
		and to trigger the intrinsic event 'onload()'.
		</t>
		</section>
    </section>

	<section anchor="extensions" title="Extensions">
		<t>This section briefly describes potential extensions of this technique.
		</t>
		
		<section anchor="cookies" title="Improving the User's Experience">
		<t>By using another script associated to the onload() event,
		the user experience could be improved:</t>

		<t><list>
			<t>The default page can dynamically be updated to reflect the
			availability of IPv6 connectivity;</t>
			<t>A pop-up window can be displayed asking the user whether
			he/she wants to be redirect to the IPv6 version of the
			web server;</t>
			<t>A <xref target="RFC2616">HTTP</xref> can be used by the web
			server to remember the user's decision.</t>
		</list></t>

		</section>
		<section anchor="extension_to_stats" 
			title="Extension to only measure the amount of IPv6 capable client">
		<t>Rather then taking the drastic decision of redirecting its client to
		its IPv6 content, the web server can simply log the result of the connectivity
		check:
		</t>
		
		<t><list style="symbols">
			<t>IPv4 client with no IPv6 connectivity;</t>
			<t>IPv4 client with IPv6 connectivity.</t>
		</list></t>
		
		<t>This can be achieved by loading the 1x1 image over IPv6 but the image source
		is no more a static image file but rather a server script (PHP, Perl, etc.) which
		is called with the IPv4 address of the client as an argument. 
		Even if the server script execution (used to generate the image) is 
		initiated over IPv6, it can retrieve the original IPv4 address from
		the HTTP query and 
		log the association between the IPv4 and IPv6 addresses.
		</t>

		<t>The <xref target="PHP">PHP</xref> code fragment below shows 
		how it can be done. This fragment
		is run when the dual-stack client connects to www.example.com; 
		it collects the client IPv4 address with the help of 
		$_SERVER['REMOTE_ADDR'] and
		passes it as an argument to the 1x1pixel.php server script 
		which is accessed
		over IPv6.
		</t>
		
		<figure>
        <artwork align="left"><![CDATA[
<img 
 src="http://ipv6.example.com/1x1pixel.php?<=?$_SERVER['REMOTE_ADDR']?>" 
 width="1" height="1" border="none" 
 onerror="NoIPv6Image();" onload="IPv6Image();">
            ]]></artwork>
		</figure>
		</section>
	</section>
	
    <section anchor="Acknowledgements" title="Acknowledgements">
      <t>This I-D is based on some discussions with Chip Popoviciu.
	  </t>
    </section>

    <section anchor="IANA" title="IANA Considerations">
      <t>This memo includes no request to IANA.
	  </t>

	  </section>

    <section anchor="Security" title="Security Considerations">
      <t>No security issue has been identified.</t>
	  <t>Note: this technique requires to enable script
	  execution on the client browser; this setting
	  is sometimes deemed less secure than preventing the
	  execution of any script by the browser.</t>
    </section>
  </middle>

  <back>
    <!-- References split into informative and normative -->

    <!-- There are 2 ways to insert reference entries from the citation libraries:
     1. define an ENTITY at the top, and use "ampersand character"RFC2629; here (as shown)
     2. simply use a PI "less than character"?rfc include="reference.RFC.2119.xml"?> here
        (for I-Ds: include="reference.I-D.narten-iana-considerations-rfc2434bis.xml")

     Both are cited textually in the same manner: by using xref elements.
     If you use the PI option, xml2rfc will, by default, try to find included files in the same
     directory as the including file. You can also define the XML_LIBRARY environment variable
     with a value containing a set of directories to search.  These can be either in the local
     filing system or remote ones accessed by http (http://domain/dir/... ).-->

    <references title="Normative References">
      <!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml"?-->
      &RFC2119;
	  &RFC2616;
	  &RFC4380;
	  
      <reference anchor="ECMA-262"
                 target="http://www.ecma-international.org/publications/standards/Ecma-262.htm">
        <front>
          <title>ECMAScript Language Specification </title>
          <author>
            <organization>ECMA</organization>
          </author>
          <date year="1999" />
        </front>
      </reference>
	  
      <reference anchor="HTML"
                 target="http://www.w3.org/TR/html401/">
        <front>
          <title>HTML 4.01 Specification</title>
          <author>
            <organization>W3C</organization>
          </author>
          <date year="1999" />
        </front>
      </reference>

      <reference anchor="PHP"
                 target="http://www.php.net">
        <front>
          <title>PHP: Hypertext Preprocessor</title>
          <author>
            <organization>The PHP Group</organization>
          </author>
        </front>
      </reference>

    </references>

  </back>
</rfc>
