Return the full length of sockaddr_in
in socket functions with in/out addrlen
#550
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Relevant links: rust3ds/ctru-rs#174, discussion on courses of action, original change in libc crate, problematic test.
CC: @ian-h-chamberlain @adryzz @AzureMarker
The kernel implementation of
sockaddr
data, used by allsoc
services, is composed of 8 bytes of data. While this is true, thesockaddr_in
definition exposed by libctru is more closely related to the corresponding Linux (and many other systems') definition, having an additional 8 byte padding field (sin_zero
). This is a generally favorable design decision for compatibility with most *nix software. However, unlike most Posix-complying implementations, the current implementation inlibctru
only handles the transfer of the 8 bytes actually manipulated by the OS.This particularity imposes 2 "differentiating" factors that may hinder compatiblity with code written for standard *nix platforms:
sockaddr_in
memory are left with uninitialized data (not a big deal since that memory isn't responsibility oflibctru
). This also shouldn't be a problem since the implementation of functions with an in/out*addrlen
argument correctly specify that only the first 8 bytes were modified (also,sin_zero
isn't supposed to ever be read).sockaddr_in
structure (16 bytes), meaning that programs expecting the size given to be the same as the output will be unpleasantly surprised when they find out thesockaddr_in
struct is "unexpectedly" oversized. For this reason (and for the fact thatsin_zero
is a fundamentally important field for most implementations), platforms such as Linux actually return the full 16 byte length, taking into consideration those 8 trailing bytes. This isn't done bylibctru
, which only returns a socket address length of 8.I am fully aware that this is basically a non-existent problem, and as far as I can tell, the Posix standard isn't even broken by having an oversized
sockaddr_in
definition, since data length issues are to be resolved using the*addrlen
parameter, and not by "expecting" sizes and lengths to be that of data structures. However, and the case that prompted this change is proof of this, this situation is not really expected to be handled by most programs, which instead believe the platform's socket implementation has to account for the full memory mapping (which is something they usually do).The possible fixes for this problem are:
sin_zero
field from thelibctru
definition and more thinly wrap the kernel implementation. (might break backward and cross compatibility)sockaddr_in
for successful calls to socket functions. Since this is the solution which requires the most changes, I've taken the liberty to include such changes in this PR.This PR doesn't have to be merged or closed as-is. Please take the time to discuss the issue further if this is not what you intend on using.