|Anonymous | Login||2023-12-01 07:15 UTC|
|Main | My View | View Issues | Change Log | Docs|
|Viewing Issue Simple Details|
|ID||Category||Severity||Type||Date Submitted||Last Update|
|0001068||[1003.1(2013)/Issue7+TC1] Base Definitions and Headers||Objection||Omission||2016-08-22 03:14||2022-08-05 09:31|
|Priority||normal||Resolution||Accepted As Marked|
|Section||Base Definition, Headers <netinet/in.h>|
|Final Accepted Text||Note: 0005902|
|Summary||0001068: Binding to a system-assigned port.|
There are times when developers don't have a registered port and wishes to use a port in the private range.
After surfing the web instead of reading POSIX, I came across this method to bind to a private system-assigned port: binding to port 0.
I'm not sure if all systems support it, but if so, these texts may be worth adding to the standard.
Add the following after line 10260 on page 307:
When a pointer to sockaddr_in or sockaddr_in6 is passed to bind, and the value of sin_port or sin6_port is htons(0), then system dynamically assign a ephemeral port to be bound to the socket.
I agree this functionality is useful, but as proposed there are difficulties. As a "works for me" decision it's fine, but isn't portable taking IETF requirements into account. As I read the standard, it glosses over as implementation-defined or protocol-defined the effects if an in_port_t is left in it's default initialization state. The UDP protocol specifies it as a "don't care" source, for one. TCP appears to consider it illegal so the bind should fail. It expects the application to set it to a valid nonzero assigned value before use for normal operation with a particular protocol.
Those systems are nominally in error, as a result. Port 0, and others, is reserved to IETF for all higher layer protocols of IPV4 or IPV6 so the suggested usage is precluded. For Experimentation this applies:
RFC 6335 Service Name and Port Number Procedures August 2011
6.1. Service Names and Port Numbers for Experimentation
Of the System Ports, two TCP and UDP port numbers (1021 and 1022),
together with their respective service names ("exp1" and "exp2"),
have been assigned for experimentation with new applications and
application-layer protocols that require a port number in the
assigned ports range [RFC4727].
Please refer to Sections 1 and 1.1 of "Assigning Experimental and
Testing Numbers Considered Useful" [RFC3692] for how these
experimental port numbers are to be used.
This document assigns the same two service names and port numbers for
experimentation with new application-layer protocols over SCTP and
DCCP in Section 10.2.
Unfortunately, it can be difficult to limit access to these ports.
Users SHOULD take measures to ensure that experimental ports are
connecting to the intended process. For example, users of these
experimental ports might include a 64-bit nonce, once on each segment
of a message-oriented channel (e.g., UDP), or once at the beginning
of a byte-stream (e.g., TCP), which is used to confirm that the port
is being used as intended. Such confirmation of intended use is
especially important when these ports are associated with privileged
(e.g., system or administrator) processes.
IMO this should be expanded to include ports in the User and Dynamic ranges, guaranteed to not cause conflicts with other processes at runtime for an associated destination address. Whether the data structures associated with these would include guard nonces or similar would be a quality of implementation issue. Limiting the assignments to the 2 ports of the RFC may be inadequate for some development scenarios on multi-user server platforms as well.
I see this more as the province of setsockopt() before bind to be robust, whatever the address family, but isn't currently implemented. It would indicate an error if a family didn't use ports or no port in a desired range is available, and as input would specify which port assignment range should be used for the connection where the family does use them. This separates the functionality from any possible conflict using tag values in sockaddr_t initializations, and ensures the socket data can be setup to associate privately with the calling process.
The biggest reason I propose to add it to the standard, is because it's been taught as standard practice.
Here quotes "UNIX Network Programming", by W. Richard Stevens et.al.
Section 4.4 bind Function.
..., but it is rare for a TCP server to let the kernel choose an ephemeral port, since servers are known by their well-known port.
Exception to this rule are Remote Procedure Call (RPC) servers.
If we specify a port number of 0, the kernel chooses an ephemeral port when bind is called.
That teaching practice is faulty; in that any platform where it applies has overloaded the IETF reserved value, and subsequent protocol-specific usages, by arbitrarily assigning this specific function to it. It is therefore imho a platform-specific, not standard, practice. The place to propose this is more in an IETF RFC as explicit currently unused port values, with my suggested expansions. As some ports are already reserved for similar use it shouldn't be considered too controversial, I imagine, for STD/BCP status as an amendment of RFC 6335.
This way POSIX and all other platforms can defer to that, going forward, and stay compatible with each other. Existing systems and applications that might break due to the change at least can reuse most of their code; for some it may be as simple as a single line header patch and recompile.
Changing get/setsockopt() as suggested doesn't require an RFC, as it doesn't lock down any value assignments, but would be more complex for an application to make use of in a safe manner. It would also be limited to use across a known LAN setup of POSIX conforming systems, as across a WAN or the WWW it couldn't be guaranteed addressable platforms are compatible with all aspects of how the new functionality may be implemented.
On D2.1 page 298 line 10373 section <netinet/in.h>, after:
The sin_port and sin_addr members shall be in network byte order.add:
If the sin_port value passed to bind() is zero, the port number bound to the socket shall be one chosen by the implementation from an implementation-defined port range to produce an unused local address.
On D2.1 page 298 line 10393 section <netinet/in.h>, after:
The sin6_port and sin6_addr members shall be in network byte order.add:
If the sin6_port value passed to bind() is zero, the port number bound to the socket shall be one chosen by the implementation from an implementation-defined port range to produce an unused local address.
On D2.1 page 301 line 10510 section <netinet/in.h>, add bind() to SEE ALSO
|UDP Source Ports require a different functionality than above when it's set to zero. As the above text does not account for this, or IETF may define other conflicting usages at any time for various protocols I cannot see making the above a requirement on all implementations.|
|Re Note: 0005904 You are talking about the port number contained in UDP packets. There is no conflict. When sin_port=0 is used to bind an ephemeral UDP port, it is the (non-zero) ephemeral port number that is contained in the UDP packets.|
Re Note: 0005904
What Geoff said in Note: 0005905, plus, the IETF does not write standards
for OS interfaces to the protocols they design, that's someone else's business,
like ours for POSIX.
When the IETF decides to define some use for port number 0, in either
UDP or TCP, beyond what is defined now, and that is for some use which a
normal (as opposed to special system dependent) application might want to
use, we can apply for special dispensation to the purple unicorn emperor
of the soviet states of america to permit us to add a new option which will
allow applications to actually bind to port 0. In the meantime, what this
is adding is what systems actually implement, which is what the standard is
supposed to say.
|2016-08-22 03:14||dannyniu||New Issue|
|2016-08-22 03:14||dannyniu||Name||=> DannyNiu/NJF|
|2016-08-22 03:14||dannyniu||Section||=> Base Definition, Headers <netinet/in.h>|
|2016-08-22 03:14||dannyniu||Page Number||=> 307|
|2016-08-22 03:14||dannyniu||Line Number||=> 10260|
|2016-08-22 16:45||shware_systems||Note Added: 0003354|
|2017-02-19 05:28||dannyniu||Note Added: 0003561|
|2017-02-19 16:18||shware_systems||Note Added: 0003562|
|2022-07-21 15:36||geoffclare||Note Added: 0005902|
|2022-07-21 15:37||geoffclare||Interp Status||=> ---|
|2022-07-21 15:37||geoffclare||Final Accepted Text||=> Note: 0005902|
|2022-07-21 15:37||geoffclare||Status||New => Resolved|
|2022-07-21 15:37||geoffclare||Resolution||Open => Accepted As Marked|
|2022-07-21 15:37||geoffclare||Tag Attached: issue8|
|2022-07-21 16:37||shware_systems||Note Added: 0005904|
|2022-07-21 16:43||geoffclare||Note Added: 0005905|
|2022-07-22 08:21||kre||Note Added: 0005906|
|2022-08-05 09:31||geoffclare||Status||Resolved => Applied|
|Mantis 1.1.6[^] Copyright © 2000 - 2008 Mantis Group|