views:

79

answers:

1

I have stumbled on a peculiar difference between Solaris 10 sockets and other Linux/*NIX sockets. Example:

int temp1, rc;
temp1 = 16*1024*1024;  /* from config, a value greater than system limit */
rc = setsockopt( sd, SOL_SOCKET, SO_RCVBUF, &temp1, sizeof(temp1);

The code above will have rc == 0 on all systems - Linux, HP-UX and AIX - except the Solaris 10. Other systems silently truncate supplied value to the allowed maximum. Solaris 10 rightfully fails with the errno == ENOBUFS indicating the configuration error.

After some deliberation, it was decided that since the particular application is critical instead of failing it should continue working as gracefully as possible:

  1. Produce a warning in the log file about configuration mismatch (easy, add a check with getsockopt()) and
  2. Try to set the maximum buffer size (to get whatever performance possible).

The #2 is were I have stuck. On all non-Solaris systems I do not need to do anything: the sockets already do it for me.

But on Solaris I'm at loss what to do. I have implemented some trivial dichotomy around (setsockopt(...) == -1 && errno == ENOBUFS) condition to find the max buffer size, but it looks ugly. (Neither I have a context to save the results of lookup: the search would have to be repeated for every connection with such bad configuration. Global variables are problematic since the code is inside a shared library and it is used from MT application.)

Is there any better way on Solaris 10 to detect max allowed buffer size using sockets API?

Is there any way to tell Solaris' sockets API to truncate the value like other systems do it?

+2  A: 

I don't have access to a Solaris 10 system at the moment, but according to the Oracle documentation, you can use the ndd utility to query (and set) the configured buffer size maximums for TCP and UDP:

$ ndd -get /dev/tcp tcp_max_buf
$ ndd -get /dev/udp udp_max_buf

I'm not aware of a C API, but maybe what ndd uses is exposed?

llasram
I have `truss`-ed it and it goes to `/dev/tcp` and then fires couple of STREAMS specific `ioctl()` calls: I_CANPUT and I_STR. And the I_STR is apparently used to send a message to a stream module. And that is were POSIX ends - and something totally Solaris specific and under-documented starts (failed to find any documentation).
Dummy00001
The [source code here shows](http://fxr.watson.org/fxr/source/common/inet/ip/ip_if.c?v=OPENSOLARIS;im=bigexcerpts#L8820) that it is not a public interface. E.g. `mod_prop_info_t` isn't even declared under `/usr/include`. At the moment seems to be not doable.
Dummy00001