Author: LemonBoy <that.lemon@gmail.com>
Author: lime boy <thatlemon@gmail.com>
State: Final
Type: Project
Vote: Done
Created: 18-Nov-2016
Post-History:
Keywords: Tcl,socket,SO_REUSEPORT,SO_REUSEADDR
Tcl-Version: 8.7
Abstract
The Tcl_OpenTcpServer interface doesn't provide enough flexibility as experienced during the implementation of the scaffolding necessary to support the SO_REUSEPORT flag for sockets. This TIP adds that capability through a new API function, Tcl_OpenTcpServerEx, that takes extra options.
Rationale
Currently there's no way to pass extra informations to Tcl_OpenTcpServer which is the function that does the heavy lifting by wrapping the socket creation and connection phase.
For example, during the implementation of a -reuseport option for the socket command, a roadblock was hit since informing Tcl_OpenTcpServer about the presence of the new flag was only possible via hacks such as exploiting the upper unused bits of the port parameter or its sign bit.
A clean solution that also paves the way to the implementation of other switches (such as one for the SO_REUSEADDR flag) is to introduce another function named Tcl_OpenTcpServerEx whose signature closely matches the Tcl_OpenTcpServer but allows passing a set of flags to customize its behaviour.
Following the aforementioned changes to the C API the socket command is enhanced with two new options allowing the user to take advantage of the newly introduced flags.
Specification
A Tcl_OpenTcpServerEx function is introduced with the following signature:
Tcl_Channel Tcl_OpenTcpServerEx(Tcl_Interp *interp, const char * service, const char *myHost, unsigned int flags, Tcl_TcpAcceptProc *acceptProc, ClientData acceptProcData)
Most arguments are identical to Tcl_OpenTcpServer with the exception of the port parameter being replaced by the service one taking a string instead of an integer. Two entries for the flags bitset are defined by this TIP:
TCL_TCPSERVER_REUSEADDR - indicate that the socket flag SO_REUSEADDR (or equivalent) should be set.
TCL_TCPSERVER_REUSEPORT - indicate that the socket flag SO_REUSEPORT (or equivalent) should be set.
The Tcl_OpenTcpServer function is then rewritten to be an alias of Tcl_OpenTcpServerEx with the flags parameter set by default to TCL_TCPSERVER_REUSEADDR so that we keep the API and behaviour compatible with the previous Tcl versions.
As for the Tcl side, the socket command gains two new optional switches that are only valid for server sockets: ?-reuseaddr boolean? and ?-reuseport boolean?, both accepting a boolean argument to either turn off or on the selected behaviour.
Reference Implementation
Please refer to the tip-456 branch of the core Tcl repository.
Backwards Compatibility
Since Tcl_OpenTcpServer can be easily re-implemented in terms of Tcl_OpenTcpServerEx the old behaviour is retained.
The socket command defaults to -reuseaddr set to yes as it was already doing before, the user is now able to turn off this behaviour by using -reuseaddr no.
Copyright
This document has been placed in the public domain.