swift-nio icon indicating copy to clipboard operation
swift-nio copied to clipboard

Provide IPAddress type

Open Lukasa opened this issue 4 years ago • 8 comments

If you want to work with a complete socket address type including port, we have a helper in SocketAddress. However, the moment you want to talk only about an IP address we force you to hold an in_addr or in_addr6 structure: hardly the friendliest versions of these data types.

We should provide a helpful wrapper IPAddress type that can be converted into those types as needed. This would be a much friendlier way to work with IP addresses. This is a good issue for those who are familiar with either IP addresses or Swift.

Lukasa avatar Sep 24 '20 11:09 Lukasa

Hi, I would like to work on this issue. I think we want a structure inherent from SocketAddress to only work on IP address with name IPAddress

shekhar-rajak avatar Jul 06 '21 06:07 shekhar-rajak

I don't think we need to involve SocketAddress: an independent type called NIOIPAddress is probably sufficient.

Lukasa avatar Jul 06 '21 06:07 Lukasa

Thanks I will work on it.

shekhar-rajak avatar Jul 06 '21 06:07 shekhar-rajak

I was exploring the codebase, here is my findings :

  • init(ipAddress: String, port: Int) is the constructor that takes IP in string & port in Int type. So we want a new type named NIOIPAddress to have the same behaviour to check ip4 and ip6 with other attributes related to IP address
  • This new type NIOIPAddress should be class I think.

I want to understand some of the test cases and requirements for this new type NIOIPAddress so that I can work on it as per the unit tests.

shekhar-rajak avatar Jul 07 '21 09:07 shekhar-rajak

Yes, we absolutely want an init(string: String) constructor. I think we need a few others:

  • init<Bytes: Collection>(packedBytes bytes: Bytes) where Element == UInt8
  • init(posixIPv4Address: in_addr)
  • init(posixIPv6Address: in6_addr)

I don't think NIOIPAddress should be a class though, I think it should be an enum with two cases, each of which should be structs. It certainly wants to have value semantics.

For our test cases, we need to confirm that it can accept the wide range of string formats for IP addresses:

  • IPv4 dotted decimal (a.b.c.d)
  • IPv6 segmented (hexadecimal separated by colons) (see https://datatracker.ietf.org/doc/html/rfc4291.html#section-2.2)
  • IPv6 segmented with scope ID (see https://datatracker.ietf.org/doc/html/rfc4007.html#section-11)

We also need to be able to produce these string representations when requested, as well as have a default implementation of CustomStringConvertible. The type also needs to be Hashable. Finally, we need to able to produce in_addr and in6_addr as appropriate.

Lukasa avatar Jul 07 '21 10:07 Lukasa

Thanks a lot @Lukasa ! I understood the scenario. I have good amount of test cases in mind to work in implementation part.

shekhar-rajak avatar Jul 07 '21 10:07 shekhar-rajak

Hey @Lukasa thanks for the good description. As I was working on this I came to the topic of zone/scope-id of the IPv6Address.

IPv6 segmented with scope ID (see https://datatracker.ietf.org/doc/html/rfc4007.html#section-11)

As I was reading through this: https://docs.huihoo.com/doxygen/linux/kernel/3.7/uapi_2linux_2in6_8h_source.html I noticed that the zone/scope-id is part of the IPv6SocketAddress and the IPv6Address only contains the bytes. Should there be an optional zone: String? as part of the IPv6Address struct or should this and the string initialiser with zone/scope-id part of the IPv6SocketAddress?

SeJV avatar Feb 19 '22 11:02 SeJV

Yeah that's a good question. I'm ok with the idea of kicking the scope zone ID to the curb for the IPv6Address on the grounds that it is not really part of the address itself but is part of the contextual information on a specific machine. So it belongs in IPv6SocketAddress and not IPv6Address.

Lukasa avatar Feb 21 '22 08:02 Lukasa