std::net::Ipv4Addr in core?

I'm an embedded developer so I don't have access to std. Could we move std::net::Ipv4 to core?

2 Likes

No, Ipv4Addr internally contains a C struct representing the address in the same way the native OS does. libcore however is meant to be OS independent and as such doesnt have access to libc.

1 Like

Having Ipv4Addr wrap in_addr isn't entirely necessary, you can have Ipv4Addr contain an OS-agnostic data format and translate this back and forth into the OS specific structure as needed. At least for IPv4 I would not expect this to result in any measurable performance impact, at worst it will be an endianness translation. For IPv6 there may be more of an impact since it will be 16-bytes that need to be swapped around, but still compared to anything else related to networking this should be a trivial cost.

I have a branch actually implementing this (along with moving SocketAddr as their parsers are intertwined) from months ago, I haven't pushed it to github yet, and if I remember correctly I had one endianness conversion missing somewhere that was making the tests fail. I'm not sure if I'll get back to working on it again, but I'll try to push it up so that if others want to they can take the work I've done so far.

4 Likes

OK, it wasn't clear to me that all those convenience functions were OS specific.

Since "IOT" is a thing it definitely makes sense for me to make part of the net module accessible for embedded projects.

Are there any cases where the OS-specific data format varies by OS on the target architecture? Or do all OSes for a given target architecture share the same storage format for IP addresses? If the latter, couldn't we go ahead and store the address in the format that requires no translation (e.g. little-endian or big-endian as appropriate)?

2 Likes

Here's the branch I mentioned. I don't remember the exact status since it appears it was 9 months ago when I was trying this out, but I believe it was compiling and failing some of the OS-agnostic unit tests in core/net/addr because of mismatched endianness somewhere.

I'm not an expert on embedded but can we make a network operations without platform-specific address type? Otherwise, it should be more considerable to separate the net crate from the std in the same sense as we did on alloc.

The main point of having Ipv4Addr and related types in core is to allow third-party crates to have a common language of base data types to speak. Currently if you want to provide a no-std networking library you'll have to use some other struct to pass your IP addresses around, and if you're integrating multiple different networking related libraries (e.g. a client for some protocol and a base network implementation) then you'll need to be translating between the data types they use (I haven't looked at what existing crates use, but a brief search on crates.io doesn't turn up any likely crates that provide this common set of types).

Actually being able to do any networking with a custom underlying implementation requires a much broader interface than GlobalAlloc, so I don't think trying to get types like TcpStream available at this point makes much sense. Those also rely on std::io traits, which have some real pain points about getting available on no-std. I think having the common language of the trivial data-only types like IpAddr available will make experimenting with no-std networking much easier and hopefully lead to ideas about how to make more available.

2 Likes

You may want to look at something like https://github.com/m-labs/smoltcp if you want a no_stdl TCP/IP stack.

I just need to store and print IP-addresses. So for now I don't need a networking stack. But thanks for the recommendation anyway!

Maybe it can be as simple as this?

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=17101cf9f8272895fae1350d72180baa

I'm not sure if you have an access to core::fmt or you need no_std; in the latter case you may want to follow this article

smoltcp is an interesting example in that they have their own SocketAddr-like type and IpAddr-like type, so if you wanted to run a generic HTTP client likely defining its own IP address type on top of a smoltcp stack you would have to be translating the IP address back and forth between the different representations.

1 Like

Does anyone know of an actual implementation of TCP/IP for which the internal representation of an IPv4 address is not a 32-bit unsigned integer in network byte order? I feel like we're maybe overdesigning this.

6 Likes

As someone who's about to start doing a bunch of networking stuff in a no_std context, I would love if there were network address types which work for both std and no_std, for the purposes of developing crates which also work in both contexts.

Also stumbled on this while experimenting a bit with no_std and trying to format/print an IP address. It would definitely make sense to have these available in no_std since they are well defined by the IETF and don't really need libc.

I have created an RFC for this here:

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.