This is a snapshot of an early working draft and has therefore been superseded by the HTML standard.

This document will not be further updated.

HTML 5

Call For Comments — 27 October 2007

6.3. Network connections

To enable Web applications to communicate with each other in local area networks, and to maintain bidirectional communications with their originating server, this specification introduces the Connection interface.

The Window interface provides three constructors for creating Connection objects: TCPConnection(), for creating a direct (possibly encrypted) link to another node on the Internet using TCP/IP; LocalBroadcastConnection(), for creating a connection to any listening peer on a local network (which could be a local TCP/IP subnet using UDP, a Bluetooth PAN, or another kind of network infrastructure); and PeerToPeerConnection(), for a direct peer-to-peer connection (which could again be over TCP/IP, Bluetooth, IrDA, or some other type of network).

This interface does not allow for raw access to the underlying network. For example, this interface could not be used to implement an IRC client without proxying messages through a custom server.

6.3.1. Introduction

This section is non-normative.

An introduction to the client-side and server-side of using the direct connection APIs.

An example of a party-line implementation of a broadcast service, and direct peer-to-peer chat for direct local connections.

6.3.2. The Connection interface

interface Connection {
  readonly attribute DOMString network;
  readonly attribute DOMString peer;
  readonly attribute int readyState;
           attribute EventListener onopen;
           attribute EventListener onread;
           attribute EventListener onclose;
  void send(in DOMString data);
  void disconnect();
};

Connection objects must also implement the EventTarget interface. [DOM3EVENTS]

When a Connection object is created, the UA must try to establish a connection, as described in the sections below describing each connection type.

The network attribute represents the name of the network connection (the value depends on the kind of connection being established). The peer attribute identifies the remote host for direct (non-broadcast) connections.

The network attribute must be set as soon as the Connection object is created, and keeps the same value for the lifetime of the object. The peer attribute must initially be set to the empty string and must be updated once, when the connection is established, after which point it must keep the same value for the lifetime of the object.

The readyState attribute represents the state of the connection. When the object is created it must be set to 0. It can have the following values:

0 Connecting
The connection has not yet been established.
1 Connected
The connection is established and communication is possible.
2 Closed
The connection has been closed.

Once a connection is established, the readyState attribute's value must be changed to 1, and the open event must be fired on the Connection object.

When data is received, the read event will be fired on the Connection object.

When the connection is closed, the readyState attribute's value must be changed to 2, and the close event must be fired on the Connection object.

The onopen, onread, and onclose attributes must, when set, register their new value as an event listener for their respective events (namely open, read, and close), and unregister their previous value if any.

The send() method transmits data using the connection. If the connection is not yet established, it must raise an INVALID_STATE_ERR exception. If the connection is established, then the behaviour depends on the connection type, as described below.

The disconnect() method must close the connection, if it is open. If the connection is already closed, it must do nothing. Closing the connection causes a close event to be fired and the readyState attribute's value to change, as described above.

6.3.3. Connection Events

All the events described in this section are events in no namespace, which do not bubble, are not cancelable, and have no default action.

The open event is fired when the connection is established. UAs must use the normal Event interface when firing this event.

The close event is fired when the connection is closed (whether by the author, calling the disconnect() method, or by the server, or by a network error). UAs must use the normal Event interface when firing this event as well.

No information regarding why the connection was closed is passed to the application in this version of this specification.

The read event is fired when when data is received for a connection. UAs must use the ConnectionReadEvent interface for this event.

interface ConnectionReadEvent : Event {
  readonly attribute DOMString data;
  readonly attribute DOMString source;
  void initConnectionReadEvent(in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMString dataArg);
  void initConnectionReadEventNS(in DOMString namespaceURI, in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMString dataArg);
};

The initConnectionReadEvent() and initConnectionReadEventNS() methods must initialise the event in a manner analogous to the similarly-named methods in the DOM3 Events interfaces. [DOM3EVENTS]

The data attribute represents the data that was transmitted from the peer.

The source attribute represents the name of the peer. This is primarily useful on broadcast connections; on direct connections it is equal to the peer attribute on the Connection object.

Events that would be fired during script execution (e.g. between the connection object being created — and thus the connection being established — and the current script completing; or, during the execution of a read event handler) must be buffered, and those events queued up and each one individually fired after the script has completed.

6.3.4. TCP connections

The TCPConnection(subdomain, port, secure) constructor on the Window interface returns a new object implementing the Connection interface, set up for a direct connection to a specified host on the page's domain.

When this constructor is invoked, the following steps must be followed.

First, if the domain part of the script's origin is not a host name (e.g. it is an IP address) then the UA must raise a security exception. We currently don't allow connections to be set up back to an originating IP address, but we could, if the subdomain is the empty string.

Then, if the subdomain argument is null or the empty string, the target host is the domain part of the script's origin. Otherwise, the subdomain argument is prepended to the domain part of the script's origin with a dot separating the two strings, and that is the target host.

If either:

...then the UA must raise a security exception.

Otherwise, the user agent must verify that the the string representing the script's domain in IDNA format can be obtained without errors. If it cannot, then the user agent must raise a security exception.

The user agent may also raise a security exception at this time if, for some reason, permission to create a direct TCP connection to the relevant host is denied. Reasons could include the UA being instructed by the user to not allow direct connections, or the UA establishing (for instance using UPnP) that the network topology will cause connections on the specified port to be directed at the wrong host.

If no exceptions are raised by the previous steps, then a new Connection object must be created, its peer attribute must be set to a string consisting of the name of the target host, a colon (U+003A COLON), and the port number as decimal digits, and its network attribute must be set to the same value as the peer attribute.

This object must then be returned.

The user agent must then begin trying to establish a connection with the target host and specified port. (This typically would begin in the backgound, while the script continues to execute.)

If the secure boolean argument is set to true, then the user agent must establish a secure connection with the target host and specified port using TLS or another protocol, negotiated with the server. [RFC2246] If this fails the user agent must act as if it had closed the connection.

Once a secure connection is established, or if the secure boolean argument is not set to true, then the user agent must continue to connect to the server using the protocol described in the section entitled clients connecting over TCP. All data on connections made using TLS must be sent as "application data".

Once the connection is established, the UA must act as described in the section entitled sending and receiving data over TCP.

User agents should allow multiple TCP connections to be established per host. In particular, user agents should not apply per-host HTTP connection limits to connections established with the TCPConnection constructor.

6.3.5. Broadcast connections

The LocalBroadcastConnection() constructor on the Window interface returns a new object implementing the Connection interface, set up to broadcast on the local network.

When this constructor is invoked, a new Connection object must be created.

The network attribute of the object must be set to the string representing the script's domain in IDNA format. If this string cannot be obtained, then the user agent must raise a security exception exception when the constructor is called.

The peer attribute must be set to the empty string.

The object must then be returned, unless, for some reason, permission to broadcast on the local network is to be denied. In the latter case, a security exception must be raised instead. User agents may deny such permission for any reason, for example a user preference.

If the object is returned (i.e. if no exception is raised), the user agent must the begin broadcasting and listening on the local network, in the background, as described below. The user agent may define "the local network" in any way it considers appropriate and safe; for instance the user agent may ask the user which network (e.g. Bluetooth, IrDA, Ethernet, etc) the user would like to broadcast on before beginning broadcasting.

UAs may broadcast and listen on multiple networks at once. For example, the UA could broadcast on both Bluetooth and Wifi at the same time.

As soon as the object is returned, the connection has been established, which implies that the open event must be fired. Broadcast connections are never closed.

6.3.5.1. Broadcasting over TCP/IP

Should we drop this altogether? Letting people fill the local network with garbage seems unwise.

We need to register a UDP port for this. For now this spec refers to port 18080/udp.

Since this feature requires that the user agent listen to a particular port, some platforms might prevent more than one user agent per IP address from using this feature at any one time.

On TCP/IP networks, broadcast connections transmit data using UDP over port 18080.

When the send(data) method is invoked on a Connection object that was created by the LocalBroadcastConnection() constructor, the user agent must follow these steps:

  1. Create a string consisting of the value of the network attribute of the Connection object, a U+0020 SPACE character, a U+0002 START OF TEXT character, and the data argument.
  2. Encode the string as UTF-8.
  3. If the resulting byte stream is longer than 65487 bytes, raise an INDEX_SIZE_ERR DOM exception and stop.
  4. Create a UDP packet whose data is the byte stream, with the source and destination ports being 18080, and with appropriate length and checksum fields. Transmit this packet to IPv4 address 255.255.255.255 or IPv6 address ff02::1, as appropriate. IPv6 applications will also have to enable reception from this address.

When a broadcast connection is opened on a TCP/IP network, the user agent should listen for UDP packets on port 18080.

When the user agent receives a packet on port 18080, the user agent must attempt to decode that packet's data as UTF-8. If the data is not fully correct UTF-8 (i.e. if there are decoding errors) then the packet must be ignored. Otherwise, the user agent must check to see if the decoded string contains a U+0020 SPACE character. If it does not, then the packet must again be ignored (it might be a peer discovery packet from a PeerToPeerConnection() constructor). If it does then the user agent must split the string at the first space character. All the characters before the space are then known as d, and all the characters after the space are known as s. If s is not at least one character long, or if the first character of s is not a U+0002 START OF TEXT character, then the packet must be ignored. (This allows for future extension of this protocol.)

Otherwise, for each Connection object that was created by the LocalBroadcastConnection() constructor and whose network attribute exactly matches d, a read event must be fired on the Connection object. The string s, with the first character removed, must be used as the data, and the source IP address of the packet as the source.

Making the source IP available means that if two or more machines in a private network can be made to go to a hostile page simultaneously, the hostile page can determine the IP addresses used locally (i.e. on the other side of any NAT router). Is there some way we can keep link-local IP addresses secret while still allowing for applications to distinguish between multiple participants?

6.3.5.2. Broadcasting over Bluetooth

Does anyone know enough about Bluetooth to write this section?

6.3.5.3. Broadcasting over IrDA

Does anyone know enough about IrDA to write this section?

6.3.6. Peer-to-peer connections

The PeerToPeerConnection() constructor on the Window interface returns a new object implementing the Connection interface, set up for a direct connection to a user-specified host.

When this constructor is invoked, a new Connection object must be created.

The network attribute of the object must be set to the string representing the script's domain in IDNA format. If this string cannot be obtained, then the user agent must raise a security exception exception when the constructor is called.

The peer attribute must be set to the empty string.

The object must then be returned, unless, for some reason, permission to establish peer-to-peer connections is generally disallowed, for example due to administrator settings. In the latter case, a security exception must be raised instead.

The user agent must then, typically while the script resumes execution, find a remote host to establish a connection to. To do this it must start broadcasting and listening for peer discovery messages and listening for incoming connection requests on all the supported networks. How this is performed depends on the type of network and is described below.

The UA should inform the user of the clients that are detected, and allow the user to select one to connect to. UAs may also allow users to explicit specify hosts that were not detected, e.g. by having the user enter an IP address.

If an incoming connection is detected before the user specifies a target host, the user agent should ask the user to confirm that this is the host they wish to connect to. If it is, the connection should be accepted and the UA will act as the server in this connection. (Which UA acts as the server and which acts as the client is not discernible at the DOM API level.)

If no incoming connection is detected and if the user specifies a particular target host, a connection should be established to that host, with the UA acting as the client in the connection.

No more than one connection must be established per Connection object, so once a connection has been established, the user agent must stop listening for further connections (unless, or until such time as, another Connection object is being created).

If at any point the user cancels the connection process or the remote host refuses the connection, then the user agent must act as if it had closed the connection, and stop trying to connect.

6.3.6.1. Peer-to-peer connections over TCP/IP

Should we replace this section with something that uses Rendez-vous/zeroconf or equivalent?

We need to register ports for this. For now this spec refers to port 18080/udp and 18080/tcp.

Since this feature requires that the user agent listen to a particular port, some platforms might prevent more than one user agent per IP address from using this feature at any one time.

When using TCP/IP, broadcasting peer discovery messages must be done by creating UDP packets every few seconds containing as their data the value of the connection's network attribute, encoded as UTF-8, with the source and destination ports being set to 18080 and appropriate length and checksum fields, and sending these packets to address (in IPv4) 255.255.255.255 or (in IPv6) ff02::1, as appropriate.

Listening for peer discovery messages must be done by examining incoming UDP packets on port 18080. IPv6 applications will also have to enable reception from the ff02::1 address. If their payload is exactly byte-for-byte equal to a UTF-8 encoded version of the value of the connection's network attribute, then the source address of that packet represents the address of a host that is ready to accept a peer-to-peer connection, and it should therefore be offered to the user.

Incoming connection requests must be listened for on TCP port 18080. If an incoming connection is received, the UA must act as a server, as described in the section entitled servers accepting connections over TCP.

If no incoming connection requests are accepted and the user instead specifies a target host to connect to, the UA acts as a client: the user agent must attempt to connect to the user-specified host on port 18080, as described in the section entitled clients connecting over TCP.

Once the connection is established, the UA must act as described in the section entitled sending and receiving data over TCP.

This specification does not include a way to establish secure (encrypted) peer-to-peer connections at this time. If you can see a good way to do this, let me know.

6.3.6.2. Peer-to-peer connections over Bluetooth

Does anyone know enough about Bluetooth to write this section?

6.3.6.3. Peer-to-peer connections over IrDA

Does anyone know enough about IrDA to write this section?

6.3.7. The common protocol for TCP-based connections

The same protocol is used for TCPConnection and PeerToPeerConnection connection types. This section describes how such connections are established from the client and server sides, and then describes how data is sent and received over such connections (which is the same for both clients and servers).

6.3.7.1. Clients connecting over TCP

This section defines the client-side requirements of the protocol used by the TCPConnection and PeerToPeerConnection connection types.

If a TCP connection to the specified target host and port cannot be established, for example because the target host is a domain name that cannot be resolved to an IP address, or because packets cannot be routed to the host, the user agent should retry creating the connection. If the user agent gives up trying to connect, the user agent must act as if it had closed the connection.

No information regarding the state of the connection is passed to the application while the connection is being established in this version of this specification.

Once a TCP/IP connection to the remote host is established, the user agent must transmit the following sequence of bytes, represented here in hexadecimal form:

0x48 0x65 0x6C 0x6C 0x6F 0x0A

This represents the string "Hello" followed by a newline, encoded in UTF-8.

The user agent must then read all the bytes sent from the remote host, up to the first 0x0A byte (inclusive). That string of bytes is then compared byte-for-byte to the following string of bytes:

0x57 0x65 0x6C 0x63 0x6F 0x6E 0x65 0x0A

This says "Welcome".

If the server sent back a string in any way different to this, then the user agent must close the connection and give up trying to connect.

Otherwise, the user agent must then take the string representing the script's domain in IDNA format, encode it as UTF-8, and send that to the remote host, followed by a 0x0A byte (a U+000A LINE FEED in UTF-8).

The user agent must then read all the bytes sent from the remote host, up to the first 0x0A byte (inclusive). That string of bytes must then be compared byte-for-byte to the string that was just sent to the server (the one with the IDNA domain name and ending with a newline character). If the server sent back a string in any way different to this, then the user agent must close the connection and give up trying to connect.

Otherwise, the connection has been established (and events and so forth get fired, as described above).

If at any point during this process the connection is closed prematurely, then the user agent must close the connection and give up trying to connect.

6.3.7.2. Servers accepting connections over TCP

This section defines the server side of the protocol described in the previous section. For authors, it should be used as a guide for how to implement servers that can communicate with Web pages over TCP. For UAs these are the requirements for the server part of PeerToPeerConnections.

Once a TCP/IP connection from a remote host is established, the user agent must transmit the following sequence of bytes, represented here in hexadecimal form:

0x57 0x65 0x6C 0x63 0x6F 0x6E 0x65 0x0A

This says "Welcome" and a newline in UTF-8.

The user agent must then read all the bytes sent from the remote host, up to the first 0x0A byte (inclusive). That string of bytes is then compared byte-for-byte to the following string of bytes:

0x48 0x65 0x6C 0x6C 0x6F 0x0A

"Hello" and a newline.

If the remote host sent back a string in any way different to this, then the user agent must close the connection and give up trying to connect.

Otherwise, the user agent must then take the string representing the script's domain in IDNA format, encode it as UTF-8, and send that to the remote host, followed by a 0x0A byte (a U+000A LINE FEED in UTF-8).

The user agent must then read all the bytes sent from the remote host, up to the first 0x0A byte (inclusive). That string of bytes must then be compared byte-for-byte to the string that was just sent to that host (the one with the IDNA domain name and ending with a newline character). If the remote host sent back a string in any way different to this, then the user agent must close the connection and give up trying to connect.

Otherwise, the connection has been established (and events and so forth get fired, as described above).

For author-written servers (as opposed to the server side of a peer-to-peer connection), the script's domain would be replaced by the hostname of the server. Alternatively, such servers might instead wait for the client to send its domain string, and then simply echo it back. This would allow connections from pages on any domain, instead of just pages originating from the same host. The client compares the two strings to ensure they are the same before allowing the connection to be used by author script.

If at any point during this process the connection is closed prematurely, then the user agent must close the connection and give up trying to connect.

6.3.7.3. Sending and receiving data over TCP

When the send(data) method is invoked on the connection's corresponding Connection object, the user agent must take the data argument, replace any U+0000 NULL and U+0017 END OF TRANSMISSION BLOCK characters in it with U+FFFD REPLACEMENT CHARACTER characters, then transmit a U+0002 START OF TEXT character, this new data string and a single U+0017 END OF TRANSMISSION BLOCK character (in that order) to the remote host, all encoded as UTF-8.

When the user agent receives bytes on the connection, the user agent must buffer received bytes until it receives a 0x17 byte (a U+0017 END OF TRANSMISSION BLOCK character). If the first buffered byte is not a 0x02 byte (a U+0002 START OF TEXT character encoded as UTF-8) then all the data up to the 0x17 byte, inclusive, must be dropped. (This allows for future extension of this protocol.) Otherwise, all the data from (but not including) the 0x02 byte and up to (but not including) the 0x17 byte must be taken, interpreted as a UTF-8 string, and a read event must be fired on the Connection object with that string as the data. If that string cannot be decoded as UTF-8 without errors, the packet should be ignored.

This protocol does not yet allow binary data (e.g. an image or media data) to be efficiently transmitted. A future version of this protocol might allow this by using the prefix character U+001F INFORMATION SEPARATOR ONE, followed by binary data which uses a particular byte (e.g. 0xFF) to encode byte 0x17 somehow (since otherwise 0x17 would be treated as transmission end by down-level UAs).

6.3.8. Security

Need to write this section.

If you have an unencrypted page that is (through a man-in-the-middle attack) changed, it can access a secure service that is using IP authentication and then send that data back to the attacker. Ergo we should probably stop unencrypted pages from accessing encrypted services, on the principle that the actual level of security is zero. Then again, if we do that, we prevent insecure sites from using SSL as a tunneling mechanism.

Should consider dropping the subdomain-only restriction. It doesn't seem to add anything, and prevents cross-domain chatter.

6.3.9. Relationship to other standards

Should have a section talking about the fact that we blithely ignoring IANA's port assignments here.

Should explain why we are not reusing HTTP for this. (HTTP is too heavy-weight for such a simple need; requiring authors to implement an HTTP server just to have a party line is too much of a barrier to entry; cannot rely on prebuilt components; having a simple protocol makes it much easier to do RAD; HTTP doesn't fit the needs and doesn't have the security model needed; etc)