Skip to content

Commit

Permalink
Fixed CORE-5902 - Add Firebird Event fails with error (#232)
Browse files Browse the repository at this point in the history
* Fixed CORE-5902 - Add Firebird Event fails with error
"While isc_que_events - Failed to establish a secondary connection for event processing".
  • Loading branch information
asfernandes committed Nov 13, 2019
1 parent 5005bfc commit c8a8ad6
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 4 deletions.
33 changes: 33 additions & 0 deletions src/remote/SockAddr.h
Expand Up @@ -48,17 +48,33 @@
class SockAddr
{
private:
struct SockAddrPrefixPosixWindows
{
uint16_t sa_family;
};

struct SockAddrPrefixMacOs
{
uint8_t sa_len;
uint8_t sa_family;
};

union sa_data {
struct sockaddr sock;
struct sockaddr_in inet;
struct sockaddr_in6 inet6;

SockAddrPrefixPosixWindows posixWindowsPrefix;
SockAddrPrefixMacOs macOsPrefix;
} data;
socklen_t len;
static const unsigned MAX_LEN = sizeof(sa_data);

void checkAndFixFamily();

public:
void convertFromMacOsToPosixWindows();
void convertFromPosixWindowsToMacOs();
void clear();
const SockAddr& operator = (const SockAddr& x);

Expand Down Expand Up @@ -120,6 +136,23 @@ inline void SockAddr::checkAndFixFamily()
}
}

inline void SockAddr::convertFromMacOsToPosixWindows()
{
SockAddrPrefixMacOs macOsPrefix;
macOsPrefix = data.macOsPrefix;

data.posixWindowsPrefix.sa_family = macOsPrefix.sa_family;
}

inline void SockAddr::convertFromPosixWindowsToMacOs()
{
SockAddrPrefixPosixWindows posixWindowsPrefix;
posixWindowsPrefix = data.posixWindowsPrefix;

data.macOsPrefix.sa_family = posixWindowsPrefix.sa_family;
data.macOsPrefix.sa_len = length();
}


inline void SockAddr::clear()
{
Expand Down
26 changes: 23 additions & 3 deletions src/remote/inet.cpp
Expand Up @@ -1480,6 +1480,7 @@ static rem_port* aux_connect(rem_port* port, PACKET* packet)
port->auxAcceptError(packet);
inet_error(false, port, "socket", isc_net_event_connect_err, savedError);
}

SockAddr resp_address(response->p_resp_data.cstr_address, response->p_resp_data.cstr_length);
address.setPort(resp_address.port());

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


rem_port* const new_port = alloc_port(port->port_parent,
(port->port_flags & PORT_no_oob) | PORT_async | PORT_connecting);
port->port_async = new_port;
Expand All @@ -1592,12 +1592,32 @@ static rem_port* aux_request( rem_port* port, PACKET* packet)
P_RESP* response = &packet->p_resp;

SockAddr port_address;

if (port_address.getsockname(port->port_handle) < 0)
{
inet_error(false, port, "getsockname", isc_net_event_listen_err, INET_ERRNO);
}

port_address.setPort(our_address.port());

// CORE-5902: MacOS has sockaddr struct layout different than one found in POSIX/Windows.
// This prevent usage of events when client or server is MacOS but the other end is not.
// Here we try to make this case work. However it's not bullet-proof for others platforms and architectures.
// A proper solution would be to just send the port number in a protocol friendly way.

bool macOsClient =
port->port_client_arch == arch_darwin_ppc ||
port->port_client_arch == arch_darwin_x64 ||
port->port_client_arch == arch_darwin_ppc64;

bool macOsServer =
ARCHITECTURE == arch_darwin_ppc ||
ARCHITECTURE == arch_darwin_x64 ||
ARCHITECTURE == arch_darwin_ppc64;

if (macOsServer && !macOsClient)
port_address.convertFromMacOsToPosixWindows();
else if (!macOsServer && macOsClient)
port_address.convertFromPosixWindowsToMacOs();

response->p_resp_data.cstr_length = (ULONG) port_address.length();
memcpy(response->p_resp_data.cstr_address, port_address.ptr(), port_address.length());

Expand Down
3 changes: 2 additions & 1 deletion src/remote/remote.h
Expand Up @@ -1014,6 +1014,7 @@ struct rem_port : public Firebird::GlobalStorage, public Firebird::RefCounted
rem_str* port_version;
rem_str* port_host; // Our name
rem_str* port_connection; // Name of connection
P_ARCH port_client_arch;
Firebird::string port_login;
Firebird::string port_user_name;
Firebird::string port_peer_name;
Expand Down Expand Up @@ -1078,7 +1079,7 @@ struct rem_port : public Firebird::GlobalStorage, public Firebird::RefCounted
port_packet_vector(0),
#endif
port_objects(getPool()), port_version(0), port_host(0),
port_connection(0), port_login(getPool()),
port_connection(0), port_client_arch(arch_generic), port_login(getPool()),
port_user_name(getPool()), port_peer_name(getPool()),
port_protocol_id(getPool()), port_address(getPool()),
port_rpr(0), port_statement(0), port_receive_rmtque(0),
Expand Down
1 change: 1 addition & 0 deletions src/remote/server/server.cpp
Expand Up @@ -1884,6 +1884,7 @@ static bool accept_connection(rem_port* port, P_CNCT* connect, PACKET* send)
if (type == ptype_lazy_send)
port->port_flags |= PORT_lazy;

port->port_client_arch = connect->p_cnct_client;

Firebird::ClumpletReader id(Firebird::ClumpletReader::UnTagged,
connect->p_cnct_user_id.cstr_address,
Expand Down

0 comments on commit c8a8ad6

Please sign in to comment.