Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 28 Feb 2003 13:06:21 +0200
From:      Alexey Zelkin <phantom@FreeBSD.org.ua>
To:        freebsd-net@freebsd.org
Subject:   maxsockbuf is useless value {?|:-(}
Message-ID:  <20030228130621.A16504@phantom.cris.net>

next in thread | raw e-mail | index | archive | help
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 majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030228130621.A16504>