Issue Details (XML | Word | Printable)

Key: CORE-4586
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Alexander Peshkov
Reporter: Michal Kubeček
Votes: 0
Watchers: 2
Operations

If you were logged in you would be able to see more operations.
Firebird Core

connections to FB3 in "standaloneClassic" mode (firebird -s) hang up

Created: 23/Oct/14 03:15 PM   Updated: 23/Sep/15 11:31 AM
Component/s: Engine
Affects Version/s: 3.0 Alpha 2, 3.0 Beta 1
Fix Version/s: 3.0 Beta 1

File Attachments: 1. Text File core-4586.patch (0.8 kB)
2. GZip Archive fb3-s.tar.gz (11 kB)

Environment: Linux - openSUSE 13.1

QA Status: Cannot be tested


 Description  « Hide
When the "standaloneClassic" server is started with
"/usr/sbin/firebird -s" and connection to it is created e.g. with

  echo 'show tables;' | isql -ch UTF8 '172.17.2.1:test'

The query hangs up. Without "-s" option everything works fine, as well
as in the usual "classic" mode (started via xinetd).

From the network communication and strace output (I'll attach them in a
moment), it seems that in both cases, the connection is established and
first data packet from client (428 bytes, looks like authentication) is
read. While in the multithreaded case, server reads configuration
(firebird.conf, databases.conf) and responds to the packet, forked child
in standalone case just calls poll() on connected socket again so that
from that moment on, both client and server wait for data from the other
side.


 All   Comments   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Michal Kubeček added a comment - 23/Oct/14 03:19 PM
Packet captures and strace outputs, both for the "good" (multithreaded server) and "bad" (standaloneClassic, firebird -s) case.

Michal Kubeček added a comment - 28/Oct/14 08:31 PM
Tentative fix attached.

The problem was that SRVR_multi_thread() read the 428 bytes from client into port->port_queue but then inet_getbytes() found SRVR_debug in port->port_server_flags and tried to read from the connection rather than use the queued data. The flag is set in INET_connect() when child is forked (or we don't fork a child and just exchange the socket in the same process in debug mode)


#ifdef WIN_NT
                if (flag & SRVR_debug)
#else
                if ((flag & SRVR_debug) || !fork())
#endif
                {
                        SOCLOSE(port->port_handle);
                        port->port_handle = s;
                        port->port_server_flags |= SRVR_server | SRVR_debug;
                        port->port_flags |= PORT_server;
                        return port;
                }


This is done even if SRVR_debug is not set in flags. However, as today all server code path go through SRVR_multi_thread(), inet_getbytes should always use REMOTE_getbytes() for server ports. And as this seems to be the only place where rem_port.port_server_flags is checked and it's not set for classic or superserver, I believe there is no need to set the flag in rem_port.port_server_flags at all.

Dmitry Yemanov added a comment - 29/Oct/14 07:26 AM
> today all server code path go through SRVR_multi_thread()
Not in Windows. WNET and XNET protocols still don't use SRVR_multi_thread().

Michal Kubeček added a comment - 29/Oct/14 08:21 AM
Yes, that's true. But as far as I can see, WNET and XNET servers have their own xdr_ops so that they are not using inet_getbytes() and the patch wouldn't affect them. Right?

Dmitry Yemanov added a comment - 29/Oct/14 08:27 AM
It looks right.

Michal Kubeček added a comment - 29/Oct/14 06:14 PM
Committed the fix (r60144).