jonEbird

November 15, 2010

Socket Option Defaults

Filed under: linux,python — jonEbird @ 10:02 pm

Working closely with the operating system, as an engineer or administrator, you often get odd questions about what particular OS settings were used. Often times, the oddest questions come from application owners which don’t have a solid handle on their app and are looking for excuses for why their application is misbehaving. Naturally their knowledge of the operating system is equally lacking if not more so.

Today’s question: What is the default OS setting for the SO_LINGER socket option?

I started off by explaining that there were no operating system configuration files where you go and adjust default socket option values and that if they were concerned with how the specific SO_LINGER option was being used that they need to keep their focus on the application. Should they be concerned with particular values being set, it’s going to be the application applying that setting via the setsockopt() system call. Their application is Java based running on top of a application server, so there are several layers of abstraction involved here. I do not mean to piss off any Java developers here, but more times than not they are not intimate with the lower level interactions of their JVMs within the OS.

Having adequately quelled that line of questioning, in terms of troubleshooting their application, I started to think why not go ahead and produce the values for all of the socket options? How about a python script for the answer?

#!/usr/bin/env python

import socket

s = socket.socket()
socket_options = [ (getattr(socket, opt), opt) for opt in dir(socket) if opt.startswith('SO_') ]
socket_options.sort()
for num, opt in socket_options:
    try:
        val = s.getsockopt(socket.SOL_SOCKET, num)
        print '%s(%d) defaults to %d' % (opt, num, val)
    except (socket.error), e:
        print '%s(%d) can\'t help you out there: %s' % (opt, num, str(e))

Running that on my Fedora Core 13 build, I get:

$ ./getsockopt.py
SO_DEBUG(1) defaults to 0
SO_REUSEADDR(2) defaults to 0
SO_TYPE(3) defaults to 1
SO_ERROR(4) defaults to 0
SO_DONTROUTE(5) defaults to 0
SO_BROADCAST(6) defaults to 0
SO_SNDBUF(7) defaults to 16384
SO_RCVBUF(8) defaults to 87380
SO_KEEPALIVE(9) defaults to 0
SO_OOBINLINE(10) defaults to 0
SO_NO_CHECK(11) defaults to 0
SO_PRIORITY(12) defaults to 0
SO_LINGER(13) defaults to 0
SO_BSDCOMPAT(14) defaults to 0
SO_PASSCRED(16) defaults to 0
SO_PEERCRED(17) defaults to 0
SO_RCVLOWAT(18) defaults to 1
SO_SNDLOWAT(19) defaults to 1
SO_RCVTIMEO(20) defaults to 0
SO_SNDTIMEO(21) defaults to 0
SO_SECURITY_AUTHENTICATION(22) can't help you out there: [Errno 92] Protocol not available
SO_SECURITY_ENCRYPTION_TRANSPORT(23) can't help you out there: [Errno 92] Protocol not available
SO_SECURITY_ENCRYPTION_NETWORK(24) can't help you out there: [Errno 92] Protocol not available
SO_BINDTODEVICE(25) can't help you out there: [Errno 92] Protocol not available
SO_ATTACH_FILTER(26) can't help you out there: [Errno 92] Protocol not available
SO_DETACH_FILTER(27) can't help you out there: [Errno 92] Protocol not available
SO_PEERNAME(28) can't help you out there: [Errno 107] Transport endpoint is not connected
SO_TIMESTAMP(29) defaults to 0
SO_ACCEPTCONN(30) defaults to 0
SO_PEERSEC(31) can't help you out there: [Errno 34] Numerical result out of range
SO_SNDBUFFORCE(32) can't help you out there: [Errno 92] Protocol not available
SO_RCVBUFFORCE(33) can't help you out there: [Errno 92] Protocol not available
SO_PASSSEC(34) defaults to 0
SO_TIMESTAMPNS(35) defaults to 0

And I like to show the actual system calls being performed since I didn’t write the program in C.

$ strace -vall -f ./getsockopt.py 2>&1 | egrep '^(socket|getsock|setsock)'
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
getsockopt(3, SOL_SOCKET, SO_DEBUG, [0], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_REUSEADDR, [0], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_TYPE, [1], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_DONTROUTE, [0], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_BROADCAST, [0], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_SNDBUF, [16384], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_RCVBUF, [87380], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_KEEPALIVE, [0], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_OOBINLINE, [0], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_NO_CHECK, [0], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_PRIORITY, [0], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_LINGER, [0], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_BSDCOMPAT, [0], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_PASSCRED, [0], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_PEERCRED, [0], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_RCVLOWAT, [1], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_SNDLOWAT, [1], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_RCVTIMEO, [0], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_SNDTIMEO, [0], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_SECURITY_AUTHENTICATION, 0xbfd0fb0c, 0xbfd0fb08) = -1 ENOPROTOOPT (Protocol not available)
getsockopt(3, SOL_SOCKET, SO_SECURITY_ENCRYPTION_TRANSPORT, 0xbfd0fb0c, 0xbfd0fb08) = -1 ENOPROTOOPT (Protocol not available)
getsockopt(3, SOL_SOCKET, SO_SECURITY_ENCRYPTION_NETWORK, 0xbfd0fb0c, 0xbfd0fb08) = -1 ENOPROTOOPT (Protocol not available)
getsockopt(3, SOL_SOCKET, SO_BINDTODEVICE, 0xbfd0fb0c, 0xbfd0fb08) = -1 ENOPROTOOPT (Protocol not available)
getsockopt(3, SOL_SOCKET, SO_ATTACH_FILTER, 0xbfd0fb0c, 0xbfd0fb08) = -1 ENOPROTOOPT (Protocol not available)
getsockopt(3, SOL_SOCKET, SO_DETACH_FILTER, 0xbfd0fb0c, 0xbfd0fb08) = -1 ENOPROTOOPT (Protocol not available)
getsockopt(3, SOL_SOCKET, SO_PEERNAME, 0xbfd0fb0c, 0xbfd0fb08) = -1 ENOTCONN (Transport endpoint is not connected)
getsockopt(3, SOL_SOCKET, SO_TIMESTAMP, [0], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_ACCEPTCONN, [0], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_PEERSEC, 0xbfd0fb0c, 0xbfd0fb08) = -1 ERANGE (Numerical result out of range)
getsockopt(3, SOL_SOCKET, 0x20 /* SO_??? */, 0xbfd0fb0c, 0xbfd0fb08) = -1 ENOPROTOOPT (Protocol not available)
getsockopt(3, SOL_SOCKET, 0x21 /* SO_??? */, 0xbfd0fb0c, 0xbfd0fb08) = -1 ENOPROTOOPT (Protocol not available)
getsockopt(3, SOL_SOCKET, 0x22 /* SO_??? */, [0], [4]) = 0
getsockopt(3, SOL_SOCKET, 0x23 /* SO_??? */, [0], [4]) = 0

That’s a whole lot of answers when I just needed to say, the operating system doesn’t automatically apply a SO_LINGER value by default on your newly created sockets but it was fun.

Viewing 5 Comments

 
close Reblog this comment
blog comments powered by Disqus