Skip to content

Commit

Permalink
Merge pull request #190 from KarloX2/master
Browse files Browse the repository at this point in the history
CORE-6004: Add a switch to disable the "TCP Loopback Fast Path" option
  • Loading branch information
hvlad committed Feb 21, 2019
2 parents d31495b + a0692f4 commit 88f799a
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 14 deletions.
8 changes: 8 additions & 0 deletions builds/install/misc/firebird.conf.in
Expand Up @@ -768,6 +768,14 @@
#
#TcpNoNagle = 1

#
# Either enables or disables the "TCP Loopback Fast Path" feature (SIO_LOOPBACK_FAST_PATH).
# Applies to Windows (version 8/2012 or higher) only.
#
# Type: Boolean, default 1 (true)
#
#TcpLoopbackFastPath = 1

#
# Allows setting of IPV6_V6ONLY socket option. If enabled, IPv6 sockets
# allow only IPv6 communication and separate sockets must be used for
Expand Down
1 change: 1 addition & 0 deletions doc/Firebird_conf.txt
Expand Up @@ -124,6 +124,7 @@ Only meaningful for Windows SS on SMP systems.
OldParameterOrdering boolean default false
TcpRemoteBufferSize integer default 8192 (bytes)
TcpNoNagle boolean default false
TcpLoopbackFastPath boolean default true
IpcMapSize integer default 4096 (bytes)
DefaultDbCachePages integer default SS: 2048. CS: 75
ConnectionTimeout integer default 180 (seconds)
Expand Down
6 changes: 6 additions & 0 deletions src/common/config/config.cpp
Expand Up @@ -148,6 +148,7 @@ const Config::ConfigEntry Config::entries[MAX_CONFIG_KEY] =
{TYPE_INTEGER, "CpuAffinityMask", (ConfigValue) 0},
{TYPE_INTEGER, "TcpRemoteBufferSize", (ConfigValue) 8192}, // bytes
{TYPE_BOOLEAN, "TcpNoNagle", (ConfigValue) true},
{TYPE_BOOLEAN, "TcpLoopbackFastPath", (ConfigValue) true},
{TYPE_INTEGER, "DefaultDbCachePages", (ConfigValue) -1}, // pages
{TYPE_INTEGER, "ConnectionTimeout", (ConfigValue) 180}, // seconds
{TYPE_INTEGER, "DummyPacketInterval", (ConfigValue) 0}, // seconds
Expand Down Expand Up @@ -492,6 +493,11 @@ bool Config::getTcpNoNagle() const
return get<bool>(KEY_TCP_NO_NAGLE);
}

bool Config::getTcpLoopbackFastPath() const
{
return get<bool>(KEY_TCP_LOOPBACK_FAST_PATH);
}

bool Config::getIPv6V6Only() const
{
return get<bool>(KEY_IPV6_V6ONLY);
Expand Down
4 changes: 4 additions & 0 deletions src/common/config/config.h
Expand Up @@ -95,6 +95,7 @@ class Config : public Firebird::RefCounted, public Firebird::GlobalStorage
KEY_CPU_AFFINITY_MASK,
KEY_TCP_REMOTE_BUFFER_SIZE,
KEY_TCP_NO_NAGLE,
KEY_TCP_LOOPBACK_FAST_PATH,
KEY_DEFAULT_DB_CACHE_PAGES,
KEY_CONNECTION_TIMEOUT,
KEY_DUMMY_PACKET_INTERVAL,
Expand Down Expand Up @@ -252,6 +253,9 @@ class Config : public Firebird::RefCounted, public Firebird::GlobalStorage
// Disable Nagle algorithm
bool getTcpNoNagle() const;

// Enable or disable the TCP Loopback Fast Path option
bool getTcpLoopbackFastPath() const;

// Let IPv6 socket accept only IPv6 packets
bool getIPv6V6Only() const;

Expand Down
33 changes: 19 additions & 14 deletions src/remote/inet.cpp
Expand Up @@ -481,7 +481,7 @@ static int send_partial(rem_port*, PACKET *);

static int xdrinet_create(XDR*, rem_port*, UCHAR *, USHORT, enum xdr_op);
static bool setNoNagleOption(rem_port*);
static bool setFastLoopbackOption(SOCKET s);
static bool setFastLoopbackOption(rem_port*, SOCKET s = 0);
static FPTR_INT tryStopMainThread = 0;


Expand Down Expand Up @@ -940,7 +940,7 @@ rem_port* INET_connect(const TEXT* name,
goto err_close;
}

setFastLoopbackOption(port->port_handle);
setFastLoopbackOption(port);

n = connect(port->port_handle, pai->ai_addr, pai->ai_addrlen);
if (n != -1)
Expand Down Expand Up @@ -1068,7 +1068,7 @@ static rem_port* listener_socket(rem_port* port, USHORT flag, const addrinfo* pa
inet_error(false, port, "listen", isc_net_connect_listen_err, INET_ERRNO);
}

setFastLoopbackOption(port->port_handle);
setFastLoopbackOption(port);

inet_ports->registerPort(port);

Expand Down Expand Up @@ -1492,10 +1492,11 @@ static rem_port* aux_connect(rem_port* port, PACKET* packet)
port->auxAcceptError(packet);
inet_error(false, port, "socket", isc_net_event_connect_err, savedError);
}
new_port->port_handle = n;

int optval = 1;
setsockopt(n, SOL_SOCKET, SO_KEEPALIVE, (SCHAR*) &optval, sizeof(optval));
setFastLoopbackOption(n);
setFastLoopbackOption(new_port);

status = address.connect(n);
if (status < 0)
Expand All @@ -1506,7 +1507,6 @@ static rem_port* aux_connect(rem_port* port, PACKET* packet)
inet_error(false, port, "connect", isc_net_event_connect_err, savedError);
}

new_port->port_handle = n;

new_port->port_peer_name = port->port_peer_name;
get_peer_info(new_port);
Expand Down Expand Up @@ -1577,7 +1577,6 @@ static rem_port* aux_request( rem_port* port, PACKET* packet)
inet_error(false, port, "listen", isc_net_event_listen_err, INET_ERRNO);
}

setFastLoopbackOption(n);

rem_port* const new_port = alloc_port(port->port_parent,
(port->port_flags & PORT_no_oob) | PORT_async | PORT_connecting);
Expand All @@ -1588,6 +1587,8 @@ static rem_port* aux_request( rem_port* port, PACKET* packet)
new_port->port_server_flags = port->port_server_flags;
new_port->port_channel = (int) n;

setFastLoopbackOption(new_port, n);

P_RESP* response = &packet->p_resp;

SockAddr port_address;
Expand Down Expand Up @@ -3239,19 +3240,23 @@ static bool setNoNagleOption(rem_port* port)
return true;
}

bool setFastLoopbackOption(SOCKET s)
bool setFastLoopbackOption(rem_port* port, SOCKET s /*= 0*/)
{
#ifdef WIN_NT
int optval = 1;
DWORD bytes = 0;
if (port->getPortConfig()->getTcpLoopbackFastPath())
{
if (s == 0)
s = port->port_handle;
int optval = 1;
DWORD bytes = 0;

int ret = WSAIoctl(s, SIO_LOOPBACK_FAST_PATH, &optval, sizeof(optval),
NULL, 0, &bytes, 0, 0);
int ret = WSAIoctl(s, SIO_LOOPBACK_FAST_PATH, &optval, sizeof(optval),
NULL, 0, &bytes, 0, 0);

return (ret == 0);
#else
return false;
return (ret == 0);
}
#endif
return false;
}

void setStopMainThread(FPTR_INT func)
Expand Down

0 comments on commit 88f799a

Please sign in to comment.