A little utility for checking socket settings

David Collier-Brown davecb at canada.sun.com
Thu Sep 30 13:05:24 GMT 1999


  I've been in discussion with a colleague who had to reduce (!)
SO_SNDBUF to get decent performance, and so wrote this little tool.
  It tells you the system default for most of the settable socket
options.  It can't do linger, as the value is a struct instead of
an int, but that's probably uninteresting to Samba folks.

  Run this to see what you'd have if you didn't set any tcp options.

  Written from Stevens TCP/IP Illustrated and man pages, so it's
probably
portable, but only tested on Solaris 7.

--dave




/*
 * 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 <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;


main() {
        int s;
        OPTION so_option[] = {
                { SO_ACCEPTCONN, "SO_ACCEPTCON: accepting connections"
},
                { SO_BROADCAST, "SO_BROADCAST, broadcast allowed" },
                { SO_REUSEADDR, "SO_REUSEADDR, address recycling" },
                { SO_KEEPALIVE, "SO_KEEPALIVE, send keepalive packets"
},
                /* { SO_LINGER, "SO_LINGER, lingers on close"}, */
                { SO_OOBINLINE, "SO_OOBINLINE, oob data folded
inline"},
                { SO_SNDBUF, "SO_SNDBUF, send buffer size" },
                { SO_RCVLOWAT, "SO_RCVLOWAT, receive low-water mark"},
                { SO_SNDLOWAT, "SO_SNDLOWAT, send low-water mark"},
                { SO_RCVTIMEO, "SO_RCVTIMEO, receive timeout"},
                { SO_SNDTIMEO, "SO_SNDTIMEO, send timeout"},
                { SO_RCVBUF, "SO_RCVBUF, receive buffer size"},
                { SO_ERROR, "SO_ERROR, error status"},
                { SO_TYPE, "SO_TYPE, socket type"},
                { 0, NULL }
        };
        OPTION tcp_option[] = {
                  { TCP_MAXSEG, "TCP_MAXSEG, maximum segment size
(mss)"},
                  { TCP_NODELAY, "TCP_NODELAY, send even tiny
packets"},
                  { 0, NULL}
        };

        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);
}

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