19 Nov 2020
This contribution is a new feature.
Currently a user can create a
SocketAddress (represent a socket address to which we may want to connect) from a string representation of an IP address.
That would be good if we had helpers to create it from packed byte representation.
To introduce the solution, we must know what an IP address (Internet Protocol address) is.
An IP address is a numerical label (an identifier) which is assigned to a device connected to a particular network (which uses IP to communicate).
We must also know that an IP address can be in the form of IPv4 or IPv6.
IPv4 is the first version of IP. It uses a 32-bit address scheme and it is the most widely used IP version.
It is expressed in dotted-decimal notation, with every bits represented by a number from 1 to 255.
Conversely, IPv6 is the most recent version of IP. It uses a 128-bit address scheme and it resolve some issues which are associated with IPv4.
It is represented by eight sets of four hexadecimal digits separated by a colon.
fe80:0:0:0:0:0:0:5 which can be abbreviated as
fe80::5 in our test case bellow.
To recap, IP addresses have the following length:
- IP V4 address: 4 bytes
- IP V6 address: 16 bytes
SocketAddress from packed byte representation#
As said above, the way we are going to differentiate an IPV6 address from IPV4 is thanks to their size.
We are first going to retrieve our IP Address which is a
ByteBuffer is a specific SwiftNIO type of object, it stores contiguoulsy allocated raw bytes.
Here is a definition of the API that we will use:
readableBytesView: a view into the readable bytes of the ByteBuffer
readableBytes: the number of bytes readable
copyBytes(at:to:length:): copies length bytes starting at the
Now that we have defined what a
ByteBuffer is, we are going to retrieve its size with
readableBytes and we will therefore be able to add our switch statement which will tell us if our
packedIpAddress is in the form of IPv6 (a length of 16) or IPv4 (a length of 4).
Then inside our switch statement we will use our
ByteBufferView (thanks to
readableBytesView) to create a new
Let's take a closer look at
sockaddr_in() (the behavior of
sockaddr_in6() is essentially the same):
Add a new
This error is thrown when we can't parse the packed byte representattion.
As said before, an IPv4 adress contains 4 bytes, let's take
[0x7F, 0x00, 0x00, 0x01] which is the
ByteBuffer representation of
An IPv6 adress contains 16 bytes, let's take the
ByteBuffer representation of
If we provide a
ByteBuffer IP address with a wrong length we need to throw a new
At first I started implementing the new error in the existing enum
But adding new cases to enumerations is a Semver major change.
This is why I implemented the error as a
This contribution allowed me to learn more about IP addresses and packed bytes representation.
Swift is not the language I usually use, so it allowed me to put into practice some concepts that I have learned in the past.