Discussion:
SO_DOMAIN and SO_PROTOCOL options for getsockopt()
Xavier Roche
2014-05-17 10:21:02 UTC
Permalink
Hi folks!

POSIX has a SO_TYPE option for getsockopt() to retrieve the socket type of a given (socket) file descriptor.

The socket type is typically set when creating it through a call to:
int socket(int domain, int type, int protocol);

Unfortunately, it seems that there are no (standardized) options to fetch the first domain attribute, or the last protocol attribute.

Is there any rationale behing the fact that there are neither a SO_DOMAIN option, nor a SO_PROTOCOL option in POSIX ?

As far as I can see, Linux has such options: (http://man7.org/linux/man-pages/man7/socket.7.html)
SO_DOMAIN (since Linux 2.6.32)
Retrieves the socket domain as an integer, returning a value
such as AF_INET6. See socket(2) for details. This socket
option is read-only.

SO_PROTOCOL (since Linux 2.6.32)
Retrieves the socket protocol as an integer, returning a value
such as IPPROTO_SCTP. See socket(2) for details. This socket
option is read-only.

And Solaris has also a SO_DOMAIN option, BUT a bit different SO_PROTOTYPE one: (http://docs.oracle.com/cd/E26505_01/html/816-5170/getsockopt-3socket.html#REFMAN3Bgetsockopt-3socket)
SO_DOMAIN
get the domain used in the socket (get only)

SO_PROTOTYPE
for socket in domains PF_INET and PF_INET6, get the underlying protocol number used in the socket. For socket in domain PF_ROUTE, get the address family used in the socket.

At last, FreeBSD has a SO_PROTOCOL (but no SO_DOMAIN, strangely) (http://www.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2)
Shware Systems
2014-05-22 13:07:55 UTC
Permalink
As socket() leaves as implementation-defined which domain and protocol
values it will accept, it seems this was left as a common extension,
rather than providing these options and a list of domain's and
protocol's
required to be supported, to have known return values for getsockopt(),
in <sys/socket.h>. I wasn't there, but that looks to be the most
plausible
reason. As only <netinet/in.h> defines required protocol values, that I
see,
for other domain types the protocol value can be considered superfluous.

I believe the expectation was an application would simply inspect a
variable used in a socket() call, rather than use a hard coded value, if
other threads needed to know which value was used. As there is no
setsockopt() to change either of these while the socket is open that's
generally faster anyways than the interface call. So SO_DOMAIN may
have been considered superfluous also.

I can see where these might be useful in generic library routines,
though,
so the values don't have to be passed as arguments to an interface in
addition to the socket fd, so wouldn't mind seeing this added to Issue 8
to cover at least the AF_* domains <socket.h> does provide.

In looking this over I noticed there isn't an apparent interface or
option
to getsockopt() that allows an application to discover which specific
protocol value the implementation uses for a domain when the protocol
argument to socket() is a zero. This could also be useful in writing
library routines.

-----Original Message-----
From: Xavier Roche <roche+kml2-***@public.gmane.org>
To: austin-group-l <austin-group-l-7882/***@public.gmane.org>
Sent: Sat, May 17, 2014 5:51 am
Subject: SO_DOMAIN and SO_PROTOCOL options for getsockopt()

Hi folks!

POSIX has a SO_TYPE option for getsockopt() to retrieve the socket type
of a given (socket) file descriptor.

The socket type is typically set when creating it through a call to:
int socket(int domain, int type, int protocol);

Unfortunately, it seems that there are no (standardized) options to
fetch the first domain attribute, or the last protocol attribute.

Is there any rationale behing the fact that there are neither a
SO_DOMAIN option, nor a SO_PROTOCOL option in POSIX ?

As far as I can see, Linux has such options:
(http://man7.org/linux/man-pages/man7/socket.7.html)
SO_DOMAIN (since Linux 2.6.32)
Retrieves the socket domain as an integer, returning a
value
such as AF_INET6. See socket(2) for details. This socket
option is read-only.

SO_PROTOCOL (since Linux 2.6.32)
Retrieves the socket protocol as an integer, returning a
value
such as IPPROTO_SCTP. See socket(2) for details. This
socket
option is read-only.

And Solaris has also a SO_DOMAIN option, BUT a bit different
SO_PROTOTYPE one:
(http://docs.oracle.com/cd/E26505_01/html/816-5170/getsockopt-3socket.htm
l#REFMAN3Bgetsockopt-3socket)
SO_DOMAIN
get the domain used in the socket (get only)

SO_PROTOTYPE
for socket in domains PF_INET and PF_INET6, get the underlying
protocol number used in the socket. For socket in domain PF_ROUTE, get
the address family used in the socket.

At last, FreeBSD has a SO_PROTOCOL (but no SO_DOMAIN, strangely)
(http://www.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2)
Jilles Tjoelker
2014-05-22 19:01:07 UTC
Permalink
Post by Xavier Roche
POSIX has a SO_TYPE option for getsockopt() to retrieve the socket
type of a given (socket) file descriptor.
int socket(int domain, int type, int protocol);
Unfortunately, it seems that there are no (standardized) options to
fetch the first domain attribute, or the last protocol attribute.
Is there any rationale behing the fact that there are neither a
SO_DOMAIN option, nor a SO_PROTOCOL option in POSIX ?
As far as I can see, Linux has such options: (http://man7.org/linux/man-pages/man7/socket.7.html)
SO_DOMAIN (since Linux 2.6.32)
Retrieves the socket domain as an integer, returning a value
such as AF_INET6. See socket(2) for details. This socket
option is read-only.
SO_PROTOCOL (since Linux 2.6.32)
Retrieves the socket protocol as an integer, returning a value
such as IPPROTO_SCTP. See socket(2) for details. This socket
option is read-only.
And Solaris has also a SO_DOMAIN option, BUT a bit different
(http://docs.oracle.com/cd/E26505_01/html/816-5170/getsockopt-3socket.html#REFMAN3Bgetsockopt-3socket)
SO_DOMAIN
get the domain used in the socket (get only)
SO_PROTOTYPE
for socket in domains PF_INET and PF_INET6, get the underlying
protocol number used in the socket. For socket in domain PF_ROUTE,
get the address family used in the socket.
At last, FreeBSD has a SO_PROTOCOL (but no SO_DOMAIN, strangely)
(http://www.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2)
Note that the SO_DOMAIN and SO_PROTOCOL options are relatively recent.
People simply have not needed this capability much.

The SO_TYPE option is generally used on inherited sockets, such as from
inetd. It allows using the same command line for UDP and TCP
connections.

The SO_PROTOCOL or SO_PROTOTYPE option was likely added because of SCTP,
which can use SOCK_STREAM sockets but may require different treatment.

Many applications already call getsockname() and/or getpeername() which
will return the domain in sa_family, if the socket is in the appropriate
state (if not, the socket probably needs to be closed anyway).
Therefore, SO_DOMAIN seems rarely needed. Note that an AF_INET6 domain
does not imply that IPv6 is in use; it is also possible that IP_V6ONLY
is not in effect and the address is actually IPv4.
--
Jilles Tjoelker
Loading...