Skip to content

API Proposal TCP

Irakli Gozalishvili edited this page Sep 25, 2018 · 4 revisions

Webextensions TCP API proposal

Irakli Gozalishvili (@gozala / gozala@mozilla.com)

Background

Over tha past few years new p2p protocols (IPFS, Dat, SSB) have emerged that are becoming increasingly more popular. Unfortunately rather then enriching web ecosystem and growing Firefox user base they are forced to being developed & grow user base outside, usually via Electron based applications like Beaker Browser, Patchwork SSB client and alike. They also have correpsponding web-extensions (IPFS Companion, DatFox, PatchFox) but they are only able to redirect calls to either gateway & compromise on providing decentralization / p2p-ness (whic is the whole point) or redirect to a separately installed local server application and compromise on UX which naturally forces ecosystem to grow in separate Electron app space.

In order to deliver p2p network implementers need to be able to establish direct connections between nodes. Mentioned protocols use TCP server / client sockets (usually in combination with other transport options) to achieve direct connections. This proposal draws inspiration from prior art:

Proposal

This section details a proposed webextensions API for connecting to a TCP sockets and for accepting connections on the local TCP server socket. It is broken into a few high-level sections:

Permissions

As with most existing webextension APIs, this API will expose new top-level permission that could be included into permissions or optional_permissions.

tcp-connect:${address}:${port}

Web extension may request permission to connect to any address / port via following permission "tcp-connect:*:*" or request connect to a specific address on any port "tcp-connect:127.0.0.1:*" or access to a specific address / port "tcp-connect:127.0.0.1:8080".

Outlined TCPSocket.connect function will not appear in an extension’s browser namespace unless above permission is included in the extension manifest.

tcp-listen:${port}

Web extension may request permission to listen for incoming on a specific port via following permission tcp-listen:3030 or request to listen to incoming connections on arbirtary port via tcp-listen:* permission.

Outlined TCPSocket.listen function will not appear in an extension’s browser namespace unless above permission is included in the extension manifest.

In this way, a user who installs an extension that uses this API can be offered a prompt describing message describing corresponding permission.

In case of optional_permission request can also be requested at runtime via existing permissions API.

Putting these pieces together, the TCPSocket.connect() method will only succeed for connections thar are permitted to the running extension. Similarly, calls to the TCPSocket.listen() will only succeed for for the ports that running extension has being granted access to. Calls to any of these methods on address / port to which permission han not being granted to will fail with a “permission denied” error.

API Methods

TCPConnectionOptions interface

Name type description
address number Network address to connect to
port number Port to connect to
useSecureTransport boolean Connection to use TLS

TCPSocket.connect method

Method will establish TCP connection to the requested address / port as long as the running extension is granted permission to do so. If permission isn't granted, returned promise will fail with "permission denied" error.

Name Returns
connect(TCPConnectionOptions) Promise<TCPClientSocket>

TCPSocket.TCPClientSocket Object

Represents a client TCP socket and can be used for sending / receiving message from the server socket.

Name type description
address number Network address of the socket
port number Port of the socket
ssl boolean True if TLS is used
readyState "connecting","open","closing" "closed" status of the socket
opened Promise<void> Promise that is resolved once connection is established
closed Promise<void> Promise that is resolved once connection is closed
write(ArrayBuffer, byteOffset?: number, byteLength?: number) Promise<void> Writes data to a socket
read() Promise<ArrayBuffer> Returns promise that is resolved with next data chunk
suspend() void Pause reading incoming data
resume() void Resume reading incoming data
close() Promise<void> Close the socket and resolve return promise that resolves once closed. Will wait for all queued data to drain
closeImmediately() void Close the socket without waiting queued data to be drained

TCPServerOptions interface

Name type description
port ?number Port to listen on. If omitted or is -1 will be selected automatically
backLog number Queue size of pending connections. May be silently limited. If omitted or -1 default value is used

TCPSocket.listen method

Creates server socket and puts it in the listening state. It will asynchronously listen for and accept client connections. Lack of permission causes returned promise to fail with "permission denied" error.

Name Returns
connect(?TCPServerOptions) Promise<TCPServerSocket>

TCPSocket.TCPServerSocket Object

Represents a TCP server socket that can be used to handle client connections.

Name type description
localPort number The port of this server socket
close() void Close the server socket
connections AsyncIterator Async iterator of connecting client connections.
Clone this wiki locally