Everybody knows Uniform Resource Identifier (URI)1. As its name suggests, it’s a way to identify a resource (for instance a file or a phone number). It is often confused with Uniform Resource Locator (URL), which is actually a form of URI. A URL is a compact string representation for a resource available via the Internet2.

Today I want to share with you the way I define another type of resources: network sockets. Everybody knows what a network socket is, right ?

The socket families I often use are inet, inet6 and unix. But there are much more types of endpoints: ipx, bluetooth,…

To configure the sockets my services or APIs have to bind, I’m now using URIs! For instance:

inet://127.0.0.1:80?reuseaddr=true

In this example I basically create a socket IPv4 on address 127.0.0.1 and port 80 with SO_REUSEADDR option enabled.

Syntax

The URI scheme defines which socket family I have to use:

  • inet for IPv4 sockets
  • inet6 for IPv6 sockets
  • unix for Unix sockets

Hopefully these schemes are not (yet) registered at IANA3.

The URI’s authority and path depend on the family used. Query arguments are used to configure options of the socket. They also depend on the family used.

IPv4 sockets

For inet family the authority is mandatory. It contains:

  • the hostname (optional):
    • either a IPv4, for instance 127.0.0.1
    • or a hostname which needs to be resolved as a IPv4 address
    • if not specified, the default value is 0.0.0.0: it binds on all IPv4 addresses
  • the port (mandatory)

The path is not used in this case, it remains empty.

Here are some examples:

  • inet://127.0.0.1:8080 binds on address 127.0.0.1 and port 8080, easy!
  • inet://example.com:5432 resolves example.com to an IPv4 and binds on port 5432
  • inet://:80?reuseaddr=true listen on port 80 and accept connections on any IPv4 of the system (0.0.0.0) even if there are remaining connections in TIME_WAIT

IPv6 sockets

Idem than inet but for IPv6 and with URI scheme inet6. Some query argments might defer.

You’re probably wondering why I use inet and inet6. Indeed I could use an IPv6 address with the inet scheme. However it doesn’t work with domain name resolution. For instance inet://localhost:80 will bind on IPv4 address 127.0.0.1 while inet6://localhost:80 will bind on IPv6 address ::1.

Unix sockets

Authority part is not used for unix family. However the path is used like a file:/ URI. It defines the path of the unix socket.

For instance: unix:///var/run/my-socket.sock

Specification & implementation

I don’t think there is already a specification or RFC which tackle this idea.

I guess this trick is already used in some many implementations. To be honnest I didn’t look a lot. But feel free to share your godsend!