One document matched: draft-miniero-rtcweb-http-fallback-00.xml


<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt"?>
<?rfc toc="yes"?>
<?rfc symrefs="yes" ?>
<?rfc sortrefs="yes"?>
<?rfc iprnotified="no" ?>
<?rfc strict="yes" ?>

<rfc category="std" docName="draft-miniero-rtcweb-http-fallback-00" ipr="trust200902">
	<front>

		<title abbrev="HTTP Fallback for RTP">HTTP Fallback for RTP Media Streams</title>
		
		<author initials="L." surname="Miniero" fullname="Lorenzo Miniero">
		<organization>Meetecho</organization>
		<address>
			<postal>
				<street>Via Carlo Poerio 89</street>
				<code>80100</code> 
				<city>Napoli</city> 
				<country>Italy</country>
			</postal>
			<email>lorenzo@meetecho.com</email>
		</address>
		</author>
	
		<date year="2012"/>
		<workgroup/>
		<abstract>

			<t>
			Almost all VoIP endpoints, especially SIP and RTCWEB ones, make use of RTP to tranport
			media frames in real-time and communicate with each other. Since RTP uses UDP, the presence
			of network elements that filter UDP packets and/or only allow some protocols like SMTP or
			HTTP to pass through would make such a communication very hard to accomplish, if not impossible.
			</t>
			<t>This draft describes a way to implement an HTTP Fallback for RTP media streams, that is,
			a way to effectively encapsulate RTP packets in HTTP messages in order to traverse proxies
			and firewalls.</t>

		</abstract>
		<!-- Abstract -->
	</front>
	<middle>

	  <section anchor="sec:Introduction" title="Introduction">

		<t>NAT Traversal for RTP streams has long been a matter of discussion and research within the IETF.
		This lead through the years to the development of several solutions to address the issue, including
		specifications like the
		<xref target="RFC5389">Session Traversal Utilities for NAT (STUN)</xref>, the
		<xref target="RFC5766">Traversal Using Relays around NAT (TURN)</xref> and
		<xref target="RFC5245">Interactive Connectivity Establishment (ICE)</xref>.</t>

		<t>The above mentioned specifications have so far managed to enable real-time multimedia
		communication between heterogeneous endpoints located behind NATs and firewalls. They are not
		effective, though, whenever any of the involved endpoints is behind a particularly restrictive
		network component, e.g., a web proxy or firewall that only allows HTTP traffic to pass through.</t>

		<t>While not a frequent scenario, this situation can nevertheless happen often enough to become
		a serious impedement to real-time communications for users who happen to experience it. This is
		especially true when envisaging RTCWEB scenarios, where users make only use of their browser
		to place calls to their peers: within uch a framework, it is reasonable for a user to assume
		that such a call should be made possible in every possible deployment scenario, including the
		above-mentioned particularly restrictive one. In fact, this very use case is explicitly addressed
		in the RTCWEB <xref target="I-D.ietf-rtcweb-use-cases-and-requirements">Use-cases and Requirements</xref> draft.</t>

		<t>This problem is not new, and as a matter of fact is not limited to Voice over IP alone. Several different
		protocol implementations have faced the need to traverse such components, and many different approaches have been
		attempted and deployed to make it possible. According to the nature of the proxy/firewall in place, some
		implementations have succeeded in traversing such elements by just using TCP connections on ports 80 or 443 to reach their peers.
		This approach is especially needed whenever proxies allow HTTPS traffic to go through, since most proxies
		don't act as MITM elements for HTTPS and as such allow traffic on the 443 port to go through untouched.
		While trivial, this approach is indeed effective when the firewall simply applies a filter that only allows
		connections using port 80/443 to pass through. This approach, though, inevitably fails whenever the filtering
		compoment also inspects the incoming packets (e.g., a web proxy), since the traffic would immediately be
		recognized as not HTTP.</t>
		
		<t>An effective way to cope with such a use case is to implement an HTTP fallback for RTP media streams:
		that is, a way to effectively encapsulate, when needed, RTP packets in HTTP messages. Such an approach
		would help those streams traverse restrictive network components like web proxies and firewalls that only
		allow HTTP traffic to pass through, even those who directly manage all HTTP messages going by.</t>
		
		<t>Considering the asynchronous nature of RTP, proper approaches need of course to be taken to allow a mapping
		of RTP packets on HTTP messages, especially considering the request/response nature of the HTTP protocol itself.
		As mentioned above, similar problems have been addressed in the past, and in fact several different solutions
		have been proposed in the past to implement a bidirectional behaviour in HTTP, as documented in
		<xref target="RFC6202"/> and <xref target="RFC6455"/>. Besides, specification of a native server-push behaviour is
		currently under work in the HTTPBIS Working Group.</t>
		
		<t>Within the context of real-time multimedia communications and considering a scenario that involves
		two peers, whatever the signalling protocol and whichever the bidirectional HTTP technology being exploited,
		an HTTP fallback mechanism may fall in basically three different network topologies:</t>
		
		<t><list style="numbers">
		<t>A topology whereas only one of the involved peers needs HTTP fallback for RTP.</t>
		<t>A topology whereas both the involved peers need HTTP fallback for RTP, using two different intermediaries.</t>
		<t>A topology whereas both the involved peers need HTTP fallback for RTP, using the same intermediary.</t>
		</list></t>
		
		<t><xref target="fig:arch1"/> describes the first topology: in this scenario, only one of the involved peers
		(namely Alice) needs an HTTP fallback for her media streams (e.g., because she's in a hotel where the deployed
		WiFi connectivity makes use of a proxy that only allows web and mail connections to pass through), while
		Bob does not. In this case, Bob is using a publicly reachable address or has likely managed to traverse its
		NAT using one of the existing solutions. Bob may or may not be aware of the fact that he's sending RTP
		packets to a gateway: what's important is that Alice is, and that she's sending her RTP media packets using
		HTTP messages, and receiving the RTP packets Bob sends here through HTTP messages as well.
		</t>

<figure anchor="fig:arch1" title="Topology 1.: HTTP fallback for just one peer">
			<artwork><![CDATA[
                    +----------+
                    | RTP/HTTP |
          +---------+ Gateway  +-----------------------+
          |  HTTP   |          |                        \  RTP
          |         +----------+                         \
          |                                               \
          |                                               |
      +---+---+                                       +---+---+
      | Alice |                                       |  Bob  |
      +-------+                                       +---+---+


			]]></artwork>
	</figure>
		
		<t>A slightly more complex scenario is described in <xref target="fig:arch2"/>:
		in this scenario, both the involved peers (Alice and Bob) need an HTTP fallback for their media
		streams, meaning that both are sending and receiving RTP packets to and from each other using
		HTTP messages. Each one, though, sends HTTP messages to its own gateway, e.g., the gateway
		deployed by their network operator. The two gateways, who most likely are deployed
		on publicly reachable addresses, send each other Alice's and Bob's RTP packets using RTP
		to minimize the delay and jitter.
		</t>
		
<figure anchor="fig:arch2" title="Topology 2.: HTTP fallback for both peers">
			<artwork><![CDATA[
                +-----------+           +-----------+
                | RTP/HTTP  |    RTP    | RTP/HTTP  |
      +---------+ Gateway 1 +-----------+ Gateway 2 +---------+
      |  HTTP   |           |           |           |   HTTP  |
      |         +-----------+           +-----------+         |
      |                                                       |
      |                                                       |
  +---+---+                                              +---+---+
  | Alice |                                              |  Bob  |
  +-------+                                              +---+---+
 

			]]></artwork>
	</figure>


		<t><xref target="fig:arch3"/> presents a more specific use case as the one described
		in <xref target="fig:arch3"/>: both the involved peers (Alice and Bob) need an HTTP fallback
		for their media streams as before, but this time they happen to send HTTP messages to
		the same gateway: in this use case, how the gateway decides to bridge the two media
		streams is entirely implementation specific. It is very important, though, that all
		the characteristics of the original streams are preserved: this means, for instance,
		that the gateway must still make sure that STUN connectivity checks that may be in place keep
		on flowing and act accorgingly.
		</t>
		
<figure anchor="fig:arch3" title="Topology 3.: HTTP fallback for both peers, same gateway">
			<artwork><![CDATA[
                             +-----------+
                             | RTP/HTTP  |
      +----------------------+ Gateway   +--------------------+
      |  HTTP                | (shared)  |              HTTP  |
      |                      +-----------+                    |
      |                                                       |
      |                                                       |
  +---+---+                                              +---+---+
  | Alice |                                              |  Bob  |
  +-------+                                              +---+---+
 

			]]></artwork>
	</figure>
        
</section>

<!-- Introduction -->
		
<section anchor="sec:Terminology" title="Conventions and Terminology">

	<t>In this document, <xref target="RFC2119">BCP 14/RFC 2119</xref>
	defines the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
	NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY",
	and "OPTIONAL".</t>

	<t>TBD.</t>

</section>

<!-- Terminology -->


<section anchor="sec:RTPoverHTTP" title="Encapsulating RTP over HTTP">

	<t>As anticipated in <xref target="sec:Introduction"/>, several different approaches have
	already been proposed in the past to accomplish a bidirectional behaviour in HTTP. Some kind
	of approach like that is absolutely needed whenever HTTP is used to carry something different than
	just requests to access resources, e.g., encapsulating an asynchronous and bidirectional
	protocol. RTP makes no exception. That said, in order to minimize as much as possible the overhead
	caused by HTTP encapsulation and thus at least try and limit the delay that inevitably such a
	solution always adds, this specification tries to propose a lighter approach than the one
	proposed in literature. Since RTP packets can be either sent or received by
	an endpoint, this specification makes use of two different HTTP kind of messages to accomplish
	both the functionality:</t>
	
	<t>
	<list style="symbols">
	<t>HTTP GET messages to allow endpoints to receive RTP packets from the gateway.</t>
	<t>HTTP POST messages to allow endpoints to send RTP packets to the gateway.</t>
	</list>
	</t>

	<t>This means that each RTP media channel can be mapped to one or more HTTP connections,
	whereas all GET messages will be associated with the incoming RTP media stream, while all
	POST messages will be associated with the outgoing RTP media stream. Why more messages
	and/or connections may be involved and not one per request will be made clearer
	in the next sections.</t>
	
	<t>
		<xref target="fig:getpost"/> describes how such a mapping can be achieved.
	</t>
	
<figure anchor="fig:getpost" title="Mapping an RTP stream to HTTP connections">
			<artwork><![CDATA[
                             
  +-------+                 [ HTTP GET message(s): <<=== RTP ===<< ]
  | Alice |<<==== RTP ====>>[
  +-------+                 [ HTTP POST message(s): >>=== RTP ===>> ] 
  
			]]></artwork>
	</figure>
	
	<t>The next subsections will address all that is required to implement such
	a functionality, that is, how to request/reserve a mapping as depicted above,
	which MIME Type to report in the HTTP messages after that,
	the header to use in the payload to properly frame RTP packets, and two different
	approaches (chunked and not-chunked) to actually transport the packets on
	top of HTTP messages.</t>
	
	<section anchor="sec:reserve" title="Reserving and managing HTTP fallback channels">
	<t>Before HTTP fallback can be used, endpoints must of course reserve or request
	access to one of the available channels to their reference gateway. The same happens,
	for instance, when creating an allocation request in TURN.</t>
	<t>An endpoint can request an HTTP fallback channel by issuing an HTTP POST message
	to the /reserve node on the gateway: if successfull, the gateway will return a json object
	containing a unique identifier to address the channel, and the public address the gatewayed RTP stream will
	send from and receive on. This unique identifier will need to be used by the
	endpoint as the node to send all HTTP messages related to that specific RTP media stream to.</t>
	
	<t>
		<xref target="fig:reserveex"/> shows an example of a /reserve message:
	</t>
	
	<figure anchor="fig:reserveex" title="Example of a /reserve message">
			<artwork><![CDATA[
     POST /reserve HTTP/1.1
     Host: www.example.com
     Cache-Control: max-age=0
     User-Agent: cicciozzo
     Content-Type: application/x-www-form-urlencoded;charset=UTF-8
     Content-Length: 6
     
     blabla
		
		
     HTTP/1.1 200 OK
     Date: Mon, 06 Aug 2012 15:04:40 GMT
     Server: pippozzo
     Content-Type: application/json
     Content-Length: 64

     {
          "id" : "a1b2c3d4e5f6"
          "ip" : "203.0.113.2"
          "port" : "5000"
     }
			]]></artwork>
	</figure>
	
	<t>In this example, the endpoint successfully requests an HTTP fallback
	channel to its gateway, and the channel identifier is 'a1b2c3d4e5f6': this
	means that all HTTP messages will have to be sent to the /a1b2c3d4e5f6 node
	relatively to the gateway address. Besides, the endpoint now knows that the gateway
	will be bound to the public address 203.0.113.2:5000 when relaying RTP packets: as
	explained in a later section, this information can be used to add ICE candidates
	to the endpoint's SDP.</t>

	<t>Before this channel can be used, of course, the address of the RTP peer must be specified,
	or otherwise the endpoint will be stuck with an unattached HTTP fallback for its RTP media stream.
	Such a mapping can be specified sending a POST message to the /<uniqueid>/setpeer node
	on the gateway: the POST message MUST contain a JSON payload formatted as the response
	from the /reserve (id of the channel, ip and port of the RTP peer).</t>
	
	<t>[Editors note: this is obviously just a placeholder mostly: what should be in the reserve,
	setpeer and other messages that may need to be added (pause/resume/stop/??) and in the related response needs
	to be specified, e.g., in terms of what we want the channel to do for us and how,
	or even authorization, access control and the like. Besides, some kind of callback should
	be envisaged to inform the endpoint whenever the gateway gets rid of a reserved channel for any reason.]</t>
	
	<t>Once an HTTP fallback channel is ready, the endpoint can start using it to send and/or receive
	RTP packets to and from its peer through the gateway. As anticipated, to send RTP packets the
	endpoint MUST issue an HTTP POST to the /<uniqueid> node relatively to the gateway address.
	Whether the endpoint and the gateway will relay on a chunked transfer encoding or not, the query
	string in each request MUST contain a 'p' variable that addresses the sequence of HTTP POST messages
	that have been sent: that is, the first POST message MUST be sent to /<uniqueid>?p=1,
	the second, no matter how delayed (e.g., a second chunked message) to /<uniqueid>/?p=2 and
	so on, to allow the receiver to properly order the received payload. It is important to point out that
	this sequence value has nothing to do with the RTP sequence number: in fact, while RTP already
	envisages a sequence number that allows the peer to reorder packets accordingly, this sequence
	number is of no use when a single RTP packet is fragmented across different HTTP requests.
	The same approach MUST be followed by the endpoint when receiving packets by means of GET messages:
	the first POST message MUST be sent to /<uniqueid>?p=1, the second to /<uniqueid>/?p=2 and
	so on.</t>
	</section>

	<!-- Header -->
	
		
	<section anchor="sec:MIME" title="MIME Type">
	<t>Whenever an HTTP message carries a payload, a proper MIME type needs
	to be specified in the Content-Type header.</t>
	
	<t>[Editors Note: what would be the best choice here? a new MIME type might
	be the right choice, especially since it would allow network administrators
	to still have control over the encapsulated flows: this solution doesn't need
	to be sneaky! a new MIME type, though, may also cause messages to be dropped
	or refused by intermediaries that can't figure a way to deal with it: in this
	case, an existing MIME type may be considered for the purpose.]</t>
	
	</section>

	<!-- Header -->
	
	<section anchor="sec:Header" title="Packet header">

		<t>While RTP headers may have extensions stating how long the header
		will be, they do not contain any information about how long the overall
		packet is. Considering the streaming nature of TCP, this information needs
		to be made available when RTP packets are transported on top of HTTP instead:
		in fact, packets may be fragmented along the way before reaching their destination,
		and both the gateway and the endpoint must be able to univocally and without errors
		extract the original RTP packets as they were sent in the first place. This is especially
		true when the chunked mode is used in HTTP messages: as it will be explained in the next
		sections, in fact, chunked messages may be buffered and/or re-chunked by intermediaries,
		thus fragmenting the original RTP packets along the way.</t>
		<t>As such, whenever an RTP packet is encapsulated in an HTTP message, before
		being written to the connection it MUST be prefixed by an eight octets header,
		containing the static signature RTPH and the length in bytes of the whole
		RTP packet (header and payload) in hex code.</t>
	<t>
		<xref target="fig:headerex"/> presents an example of an RTP packet (in this case,
		a simple GSM frame with no extension headers) encapsulated in HTTP: the four-octets
		header RTPH002D tells the RTP packet that immediately follows is exactly 45 bytes long.
	</t>
<figure anchor="fig:headerex" title="Header of an encapsulated RTP-over-HTTP packet">
			<artwork><![CDATA[
      RTPH 002D [ .. 45 bytes follow .. ]
  
			]]></artwork>
	</figure>

	</section>

	<!-- Header -->

	<section anchor="sec:Chunked" title="Chunked mode">

		<t>The Chunked Transfer Coding as defined in <xref target="RFC2616"/> allows
		for a payload to be sent in chunks. Such a Transfer mode is usually exploited
		whenever the size of the payload is not known in advance. This is especially
		useful in streaming, as it allows for a persistent connection and continuous
		transfer of chunks without needing to issue further HTTP requests, thus
		minimizing the overhead imposed by HTTP message headers, besides the delay
		that issuing new HTTP messages may add.
		</t>

		<t>Whenever possible, such a transfer coding mode should be tried and be
		exploited by both the endpoint and the gateway. This means that the endpoint
		MUST set the 'Transfer-Encoding: chunked' and 'Expect: 100-continue' headers
		in the first RTP-related request it sends, be it a GET and POST messages. In case
		all of the intermediaries up to the gateway support chunking, the endpoint
		MUST send RTP packets as chunks. Any possible buffering/re-chunking that may
		occur along the path MUST be taken care of by the receiver according to the
		header specified in <xref target="sec:Header"/>.</t>
		
	</section>

	<!-- Chunked -->

	<section anchor="sec:UnChunked" title="Non-chunked mode">

		<t>Unfortunately, not always the Chunked Transfer Coding can be used to send
		and receive HTTP messages. Any of the intermediaries may only be an HTTP 1.0 compliant
		endpoint, or may arbitrarily choose to reject chunked messages for any reason. If that's the
		case, the endpoint MUST fallback to the default transfer mechanism, that is,
		issuing different requests for different RTP packets, increasing the 'p'
		sequence value accordingly. Both the endpoint and
		the gateway MAY choose to aggregate more RTP packets in the same message: in
		that case, though, each RTP packet MUST be properly prefixed by the header
		defined in <xref target="sec:Header"/>, in order to allow framing. Besides,
		the endpoint MAY want to issue more HTTP connections in parallel and send
		messages on them in turns.</t>
		
		<t>Even in this mode, the endpoint SHOULD try to open a persistent connection and keeping
		it alive for as long as possible: in case a connection is closed and the endpoint
		wants to keep on using it, it MUST open a new connection and send a new
		request coherently with the related RTP stream direction (e.g., a GET for 
		the incoming stream) and the current sequence value.</t>

	</section>

	<!-- UnChunked -->

</section>

<!-- RTPoverHTTP -->

<section anchor="sec:negotiation" title="Negotiation and relation to ICE">
			
	<t>While the previous sections describe how RTP packets can be carried
	on top of HTTP messages, they tell nothing about how support for any of those
	features can be negotiated. Such a negotiation within the context of an
	offer/answer is absolutely relevant, and can be related to the ICE mechanism.
	In fact, an HTTP fallback can be basically seen as an additional candidate
	for endpoints to report to their peers.
	</t>
	<t>While it is likely that HTTP fallback will only be used in extreme circumstances,
	that is, scenarios where the gathering of non-local ICE candidates failed (e.g.,
	because o UDP filtering), endpoints may choose to also report HTTP fallback
	candidates in their SDP along the other existing ones.</t>

	<section anchor="candidates" title="HTTP fallback candidates">

		<t>As explained in <xref target="sec:reserve"/>, reserving an HTTP fallback
		channel provides the endpoint with the public address the gateway will use
		to send and receive RTP packets on behalf of the endpoint itself. As such,
		this address can be added to the list of ICE candidates (if any) already
		gathered by the endpoint. This allows both HTTP fallback-aware and -unaware
		endpoints to interact with the gateway in order to indirectly communicate
		with the endpoint.</t>
		
		<t>[Editors Note: especially for topology 3, and considering TURN relays have something
		like this, it may have sense to also explicitly report an HTTP fallback somehow: how
		could this be reported as a candidate? a new protocol in the list? would
		this affect backward compatibility?]</t>

	</section>

	<!-- candidates -->
		
</section>

<!-- Negotiation -->

<section anchor="sec:security" title="Security Considerations">
			
	<t>TBD.: many, probably, and even more likely not less than the ones TURN already reports.</t>
		
</section>

<!-- Security Consideration -->

<section anchor="sec:IANA_Considerations" title="IANA Considerations">

	<t>TBD.</t>

</section>

<!-- IANA Considerations -->


<section title="Acknowledgments">

	<t>The authors would like to thank...</t>

</section>

<!-- Acknowledgments -->

	</middle>

	<!-- Middle -->

	<back>
		
	  <references title="Normative References">
     		<?rfc include="reference.RFC.2119"?>
     		<?rfc include="reference.RFC.2616"?>
     		<?rfc include="reference.RFC.2818"?>
     		<?rfc include="reference.RFC.3261"?>
     		<?rfc include="reference.RFC.3264"?>
     		<?rfc include="reference.RFC.3550"?>
     		<?rfc include="reference.RFC.5245"?>
     		<?rfc include="reference.RFC.5389"?>
     		<?rfc include="reference.RFC.5766"?>
       		<?rfc include="reference.I-D.ietf-rtcweb-use-cases-and-requirements"?>
	  </references>

	  <references title="Informative References">
     		<?rfc include="reference.RFC.6202"?>
     		<?rfc include="reference.RFC.6455"?>
   	  </references>

  	</back>

	<!-- Back -->

</rfc>

PAFTECH AB 2003-20262026-04-24 04:05:19