dante   Frontpage - Dante - Download - Status - Support - Modules - Docs - Links - Survey
 

Socket options

This page describes how to configure options related to socket options on incoming and outgoing traffic.

Most operating systems provide a wide range of socket options that can be used to control different aspects related to TCP and UDP traffic behavior. Many socket options control behavior that it might be desirable to have control over, but applications generally need to have explicit support for a given option to be able to change socket options.

To make it easier to use the OS functionality provided via socket options, Dante has generic support for socket options that allows a wide range of options to be set or changed via the Dante configuration file. This is integrated into the ACL rules, allowing socket options to be set both globally as defaults and for specific types of traffic.

A note of warning: An attempt has been made to make the functionality in Dante related to socket options as flexible as possible. It is possible to set a large number of socket options, but the ultimate responsibility for ensuring that this is done in a way that does not result in undesirable behavior is that of the operator. Some options that are known to be incompatible with what Dante does are disabled, but this should not be relied on.

An overview of some socket options are listed below, support for other socket options should be considered experimental.

Our recommendation is that these options are only used by experts; normally there will be no need to set any of these options.

Configuration of socket options

The socket options that are available vary between platforms, so during configuration and building of the server, the options that are available on a system will be determined. Currently, at least the following options should be detected when available, for the specified protocol levels:

  • SOCKET
    • so_bindany, so_broadcast, so_debug, so_dontroute, so_jumbo, so_keepalive, so_oobinline, so_priority, so_rcvbuf, so_rcvbufforce, so_rcvlowat, so_sndbuf, so_sndbufforce, so_sndlowat, so_useloopback
  • TCP
    • tcp_cork, tcp_cwnd, tcp_init_cwnd, tcp_keepcnt, tcp_keepidle, tcp_keepintvl, tcp_linger2, tcp_maxrt, tcp_maxseg, tcp_md5sig, tcp_nodelay, tcp_noopt, tcp_nopush, tcp_sack_enable, tcp_stdurg, tcp_syncnt, tcp_window_clamp
  • UDP
    • udp_cork
  • IP
    • ip_auth_level, ip_dontfrag, ip_esp_network_level, ip_esp_trans_level, ip_freebind, ip_ipcomp_level, ip_minttl, ip_mtu_discover, ip_portrange, ip_recvtos, ip_tos, ip_ttl

To list the options supported by a compiled Dante server, run the server binary with the -vv option.

The syntax for setting socket options is as follows:

<direction>.<level>.<option>: <value>

The value field corresponds to the value that the socket option should be set to. For many socket options this is an integer value. The level and option values correspond to the socket names and protocol levels listed above. Both should be in lower-case.

The direction keyword is used to specify whether the socket option should be set for traffic on the internal or the external interface and can have the values internal and external. For example, to set the IP_TOS socket option on outgoing traffic, the following expression can be used:

external.ip.ip_tos: 0x10

In this example, the argument value (0x10) is specified as a hex value. For some of the socket options the option value can also be set symbolically. Currently this is possible for at least the following options, with the listed values:

  • ip_portrange
    • ip_portrange_default, ip_portrange_low, ip_portrange_high

The IP_TOS socket option also supports this, but handling this option is somewhat complicated by some of the same bits having different meanings in different RFCs. A subfield can be set for this option to indicate the RFC variant that should be used. The following subfields are defined and should be added to the name of the socket option as specified below:

  • ip_tos.dscp
    • af11 af12 af13 af21 af22 af23 af31 af32 af33 af41 af42 af43 cs0 cs1 cs2 cs3 cs4 cs5 cs6 cs7 ef
  • ip_tos.prec
    • netcontrol internetcontrol critic_ecp flashoverride flash immediate priority routine
  • ip_tos.tos
    • lowdelay throughput reliability

When numerical arguments are given to subfields, the values are shifted to apply only to the subfield bit range. The following example shows the different ways of setting IP_TOS to lowdelay on external traffic:

external.ip.ip_tos:     0x10       #base value, specified numerically
external.ip.ip_tos.tos: 0x08       #subfield, specified numerically
external.ip.ip_tos.tos: lowdelay   #subfield, specified symbolically

The first value sets the value directly, the second sets only the TOS bits, which are shifted relative to the base value. The final line sets the TOS value symbolically.

Socket options that are not listed above can also be set by specifying the socket option name numerically, for example:

external.ip.10:     0x12

In this example the socket option corresponding to the value 10 will be set. These numbers are platform dependent but can typically be determined by looking at the appropriate system header files. Specifying options numerically might result in some warnings, but allows any socket option to be specified, as long as it takes a numerical argument. This is not the recommended approach for setting socket options, but represents a simple way of setting socket options that are not directly supported by Dante, such as local kernel extensions.

Socket option evaluation procedure

The socket option syntax gives a large amount of control over socket options, but this functionality should not be used without some understanding of how the kernel allows the socket option to be set, and the limitations that apply when the socket options are set as either defaults or in rules.

Setting a socket option in a client pass or socks-rules will cause any defaults to be overridden. Global options are set before bind() is called on internal sockets, or before connect() is called on external sockets. Options set in client rules are also applied before bind() is called on the internal socket, but cannot be set for the external socket. For socks-rules, both external and internal options can be set, but because the socks-request must be interpreted before the rules can be evaluated, socket options can only be set on internal sockets after the connection has been received.

Some socket options must be set before a connection has been established, while others can only be set after a connection has been established. Others can be set at any time.

TOS/DSCP usage example

The examples below show how the TOS/DSCP value of traffic can be set. The first example shows how to directly specify the value that should be given as an argument to setsockopt() when the ip.ip_tos keyword is used directly:

socks pass {
    from: 0.0.0.0/0 to: www.example.com

    #set IP_TOS for connections to www.example.com
    external.ip.ip_tos: 0x58

    #also set IP_TOS for connection between client and proxy
    internal.ip.ip_tos: 0x08
}

socks pass {
    from: 0.0.0.0/0 to: 0.0.0.0/0

    #no options set for others.
}

The values for the different subfields can also be specified numerically. The following example shows how a DSCP value can be set both symbolically and numerically:

socks pass {
    from: 0.0.0.0/0 to: www.example.com

    #set 'af11' dscp value for connections to www.example.com
    external.ip.ip_tos.dscp: af11
}

socks pass {
    from: 0.0.0.0/0 to: 0.0.0.0/0

    #'af11' specified numerically
    external.ip.ip_tos.dscp: 10
}

TCP_CWND usage example

The following example shows how the TCP_CWND option can be used. This option requires a patch for the Linux kernel, see the entry for TCP_CWND below for details).

external.tcp.tcp_cwnd: 12  #global, default for outgoing connections
internal.tcp.tcp_cwnd: 12  #global, default for incoming connections

socks pass {
    from: 0.0.0.0/0 to: www.example.com

    #override defaults for connections related to www.example.com
    external.tcp.tcp_cwnd: 15
    internal.tcp.tcp_cwnd: 15
}

socks pass {
    from: 0.0.0.0/0 to: 0.0.0.0/0

    #use global defaults
}

The above example will cause the initial congestion window to be set for both internal connections from clients and outgoing connections. A value of 15 will be used for sessions related to the host www.example.com, while all other sessions will use the global default value of 12.

Socket option notes

Some additional information about specific socket options can be found below. Socket options are placed into four categories, supported, unsupported, experimental and disabled.

The supported options are well tested and should work, unsupported options typically require a non-numerical argument, for which there is currently not support.

The experimental options might work, but have not been extensively tested. Feedback would be appreciated should any of these options be found to have problems.

The disabled options cannot be used.

Supported options

  • IP_TOS - This IP-level option can be used to set the TOS value of matching traffic.
  • TCP_CWND -This option requires requires a patch for the Linux kernel by Tom Herbert. The original posting with the patch can be found on the Linux netdev mailing list. When supported in the kernel, the socket option can be used to change the initial congestion window of TCP connections.

Unsupported options

The following options are unsupported:

  • SO_LINGER SO_RCVTIMEO SO_SNDTIMEO

Disabled options

The following options are currently disabled:

  • SO_REUSEADDR SO_REUSEPORT IP_HDRINCL IP_MULTICAST_IF IP_MULTICAST_LOOP IP_MULTICAST_TTL IP_OPTIONS IP_RECVDSTADDR IP_RECVIF

Experimental options

All other options are currently considered to be experimental.


Copyright © 1998-2016 Inferno Nettverk A/S