Folks,

Working with Sun JDK network code I have realized a need to provide some
range checking wrapper for setsockopt() in SO_{SND,RCV}BUF cases.  Short
walk over documentation shown that maximum buffer size is exported via
kern.ipc.maxsockbuf sysctl.  But attempt to use this value as maximum
buffer size was not successful -- it is too large for kernel.

Short analyzis of kernel code shown that failing checks (around sbreserve())
are done against $sb_max_adj instead of $sb_max which is reflected to sysctl.
$sb_max_adj is always less then $sb_max, therefore we will _always_
fail in attempt to use $sb_max.  Testcase is below.

Any suggestions how to workaround this case ?  Additionally, I think that
such behaviour is incorrect and should be fixed in kernel as well.

----------------------------------------------------------------------------

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/errno.h>
#include <stdio.h>

/*
 * Demonstrates problem with attempt to set documented (i.e. exported via
 * kern.ipc.maxsockbuf sysctl) maximum SO_SNDBUF buffer size.
 * Same applied to SO_RCVBUF.
 */
int
main()
{
    int mib[3] = { CTL_KERN, KERN_IPC, KIPC_MAXSOCKBUF };
    size_t rlen;

    int s;
    socklen_t sz;
    int maxsockbuf;

    int status;

    rlen = sizeof(maxsockbuf);
    if (sysctl(mib, 3, &maxsockbuf, &rlen, NULL, 0) < 0)
        perror("sysctl");

    printf("kern.ipc.maxsockbuf = %d\n", maxsockbuf);

    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        perror("socket");

    sz = sizeof(maxsockbuf);
    status = setsockopt(s, SOL_SOCKET, SO_SNDBUF, &maxsockbuf, sz);
    if (status == 0) {
        printf("setsockopt: OK\n");
    } else if (errno == ENOBUFS) {
        printf("setsockopt: KABOOM (ENOBUFS returned)\n");
    } else {
        perror("getsockopt");
    }

}


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-net" in the body of the message

Reply via email to