A little utility for checking socket settings

David Collier-Brown davecb at canada.sun.com
Thu Sep 30 20:03:40 GMT 1999


David Collier-Brown wrote:
>  I've been in discussion with a colleague who had to reduce (!)
> SO_SNDBUF to get decent performance


	The program needed some #ifdef's for Linux (thanks, tridge!)
	so here's a re-write and a Linux result from 2.2.12:
Default SO_BROADCAST, broadcast allowed = 0
Default SO_REUSEADDR, address recycling = 0
Default SO_KEEPALIVE, send keepalive packets = 0
Default SO_OOBINLINE, oob data folded inline = 0
Default SO_SNDBUF, send buffer size = 65535 
Default SO_RCVLOWAT, receive low-water mark = 1
Default SO_SNDLOWAT, send low-water mark = 1
Default SO_RCVTIMEO, receive timeout = 0
Default SO_SNDTIMEO, send timeout = 0
Default SO_RCVBUF, receive buffer size = 65535
Default SO_ERROR, error status = 0
Default SO_TYPE, socket type = 1
Default TCP_MAXSEG, maximum segment size (mss) = 0
Default TCP_NODELAY, send even tiny packets = 0

--dave
-------------- next part --------------
/*
 * getsocketopts -- get the defaults
 *
 * This (on a Solaris 7 system) should say:
 * % su root -c ./getsockopts
 * Default SO_ACCEPTCON: accepting connections = 0
 * Default SO_BROADCAST, broadcast allowed = 0
 * Default SO_REUSEADDR, address recycling = 0
 * Default SO_KEEPALIVE, send keepalive packets = 0
 * Default SO_OOBINLINE, oob data folded inline = 0
 * Default SO_SNDBUF, send buffer size = 8192
 * getsocketopts: could not test SO_RCVLOWAT, receive low-water mark
 * getsocketopts: could not test SO_SNDLOWAT, send low-water mark
 * getsocketopts: could not test SO_RCVTIMEO, receive timeout
 * getsocketopts: could not test SO_SNDTIMEO, send timeout
 * Default SO_RCVBUF, receive buffer size = 32768
 * Default SO_ERROR, error status = 0
 * Default SO_TYPE, socket type = 2
 * Default TCP_MAXSEG, maximum segment size (mss) = 536
 * Default TCP_NODELAY, send even tiny packets = 0
 */


#include <stdio.h>
#include <stdlib.h> /* For defn' of exit(). */
#include <sys/types.h> /* for getuid() */
#include <unistd.h>
#include <sys/socket.h> /* For socket() */
#include <netinet/in.h> /* For protocol numbers. */
#include <netinet/tcp.h>   /* For options. */

typedef struct option_t {
	int name;
	char *printable;
} OPTION;

void query(int, int, OPTION *);

OPTION so_option[] = {
#ifdef SO_ACCEPTCONN
	{ SO_ACCEPTCONN, "SO_ACCEPTCON: accepting connections" },
#endif
#ifdef SO_BROADCAST
	{ SO_BROADCAST, "SO_BROADCAST, broadcast allowed" },
#endif
#ifdef SO_REUSEADDR
	{ SO_REUSEADDR, "SO_REUSEADDR, address recycling" },
#endif
#ifdef SO_KEEPALIVE
	{ SO_KEEPALIVE, "SO_KEEPALIVE, send keepalive packets" },
#endif
	/* { SO_LINGER, "SO_LINGER, lingers on close"}, */
#ifdef SO_OOBINLINE
	{ SO_OOBINLINE, "SO_OOBINLINE, oob data folded inline"},
#endif
#ifdef SO_SNDBUF
	{ SO_SNDBUF, "SO_SNDBUF, send buffer size" },
#endif
#ifdef SO_RCVLOWAT
	{ SO_RCVLOWAT, "SO_RCVLOWAT, receive low-water mark"},
#endif
#ifdef SO_SNDLOWAT
	{ SO_SNDLOWAT, "SO_SNDLOWAT, send low-water mark"},
#endif
#ifdef SO_RCVTIMEO
	{ SO_RCVTIMEO, "SO_RCVTIMEO, receive timeout"},
#endif
#ifdef SO_SNDTIMEO
	{ SO_SNDTIMEO, "SO_SNDTIMEO, send timeout"},
#endif
#ifdef SO_RCVBUF
	{ SO_RCVBUF, "SO_RCVBUF, receive buffer size"},
#endif
#ifdef SO_ERROR
	{ SO_ERROR, "SO_ERROR, error status"},
#endif
#ifdef SO_TYPE
	{ SO_TYPE, "SO_TYPE, socket type"},
#endif
	{ 0, NULL }
};

OPTION tcp_option[] = {
#ifdef TCP_MAXSEG
	  { TCP_MAXSEG, "TCP_MAXSEG, maximum segment size (mss)"},
#endif
#ifdef TCP_NODELAY
	  { TCP_NODELAY, "TCP_NODELAY, send even tiny packets"},
#endif
	  { 0, NULL}
};



main() {
	int s;
	if ((getuid()) != 0) {
		(void) fprintf(stderr,"getsocketopts: you must be root first.\n");
		(void) exit(1);
	}

	if ((s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1) {
		perror("failed in socket call,");
		(void) exit(1);
	}
	query(s, SOL_SOCKET, so_option);
	query(s, IPPROTO_TCP, tcp_option);

	(void) close(s);
	(void) exit(0);
	/*NOTREACHED*/
}

/*
 * query -- see about one option
 */
 void
query(int s, int type, OPTION *p) {
	int value, vlen = 4;

	for (; p->printable != NULL; p++) {
		if (getsockopt(s, type, p->name, (void *)&value, &vlen) == -1) {
			(void) fprintf(stderr,"getsocketopts: could not test %s\n",
		       p->printable);
		}
		else {
			(void) printf("Default %s = %d\n",p->printable,value);
		}
	}
}


More information about the samba mailing list