mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 20:03:02 +01:00
Reworked the remote protocol analyzing logic.
In particular, it resolves the possible problems with the local access to databases on network shares. Also, it removes any dependencies from EMBEDDED to simplify Alex's cleanup. Finally, it adds the initial implementation of the Vlad's suggestion (for testing purposes).
This commit is contained in:
parent
de33a15195
commit
1b732a3579
@ -34,9 +34,9 @@ enum iscProtocol {ISC_PROTOCOL_LOCAL, ISC_PROTOCOL_TCPIP, ISC_PROTOCOL_WLAN};
|
|||||||
#ifndef NO_NFS
|
#ifndef NO_NFS
|
||||||
bool ISC_analyze_nfs(Firebird::PathName&, Firebird::PathName&);
|
bool ISC_analyze_nfs(Firebird::PathName&, Firebird::PathName&);
|
||||||
#endif
|
#endif
|
||||||
|
bool ISC_analyze_protocol(const char*, Firebird::PathName&, Firebird::PathName&);
|
||||||
bool ISC_analyze_pclan(Firebird::PathName&, Firebird::PathName&);
|
bool ISC_analyze_pclan(Firebird::PathName&, Firebird::PathName&);
|
||||||
bool ISC_analyze_tcp(Firebird::PathName&, Firebird::PathName&);
|
bool ISC_analyze_tcp(Firebird::PathName&, Firebird::PathName&);
|
||||||
bool ISC_analyze_xnet(Firebird::PathName&, Firebird::PathName&);
|
|
||||||
bool ISC_check_if_remote(const Firebird::PathName&, bool);
|
bool ISC_check_if_remote(const Firebird::PathName&, bool);
|
||||||
iscProtocol ISC_extract_host(Firebird::PathName&, Firebird::PathName&, bool);
|
iscProtocol ISC_extract_host(Firebird::PathName&, Firebird::PathName&, bool);
|
||||||
bool ISC_expand_filename(Firebird::PathName&, bool);
|
bool ISC_expand_filename(Firebird::PathName&, bool);
|
||||||
|
@ -295,6 +295,40 @@ bool ISC_analyze_nfs(tstring& expanded_filename, tstring& node_name)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool ISC_analyze_protocol(const char* protocol, tstring& expanded_name, tstring& node_name)
|
||||||
|
{
|
||||||
|
/**************************************
|
||||||
|
*
|
||||||
|
* I S C _ a n a l y z e _ p r o t o c o l
|
||||||
|
*
|
||||||
|
**************************************
|
||||||
|
*
|
||||||
|
* Functional description
|
||||||
|
* Analyze a filename for a known protocol prefix.
|
||||||
|
* If one is found, extract the node name, compute the residual
|
||||||
|
* file name, and return true. Otherwise return false.
|
||||||
|
*
|
||||||
|
**************************************/
|
||||||
|
node_name.erase();
|
||||||
|
|
||||||
|
const PathName prefix = PathName(protocol) + "://";
|
||||||
|
if (expanded_name.find(prefix) != 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
expanded_name.erase(0, prefix.length());
|
||||||
|
const size p = expanded_name.find_first_of('/');
|
||||||
|
if (p != npos)
|
||||||
|
{
|
||||||
|
node_name = expanded_name.substr(0, p);
|
||||||
|
expanded_name.erase(0, node_name.length() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(WIN_NT)
|
#if defined(WIN_NT)
|
||||||
bool ISC_analyze_pclan(tstring& expanded_name, tstring& node_name)
|
bool ISC_analyze_pclan(tstring& expanded_name, tstring& node_name)
|
||||||
{
|
{
|
||||||
|
@ -76,9 +76,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(WIN_NT)
|
#if defined(WIN_NT)
|
||||||
#if !defined(EMBEDDED)
|
|
||||||
#define USE_XNET
|
|
||||||
#endif
|
|
||||||
#include "../jrd/isc_proto.h"
|
#include "../jrd/isc_proto.h"
|
||||||
#include "../remote/os/win32/wnet_proto.h"
|
#include "../remote/os/win32/wnet_proto.h"
|
||||||
#include "../remote/xnet_proto.h"
|
#include "../remote/xnet_proto.h"
|
||||||
@ -89,6 +86,14 @@
|
|||||||
#endif // WIN_NT
|
#endif // WIN_NT
|
||||||
|
|
||||||
|
|
||||||
|
const char* const PROTOCOL_INET = "inet";
|
||||||
|
const char* const PROTOCOL_WNET = "wnet";
|
||||||
|
const char* const PROTOCOL_XNET = "xnet";
|
||||||
|
|
||||||
|
const char* const INET_LOCALHOST = "localhost";
|
||||||
|
const char* const WNET_LOCALHOST = "\\\\.";
|
||||||
|
|
||||||
|
|
||||||
using namespace Firebird;
|
using namespace Firebird;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -4569,98 +4574,90 @@ static rem_port* analyze(PathName& file_name,
|
|||||||
* NOTE: The file name must have been expanded prior to this call.
|
* NOTE: The file name must have been expanded prior to this call.
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
#if defined(WIN_NT)
|
|
||||||
ISC_expand_share(file_name);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
rem_port* port = NULL;
|
rem_port* port = NULL;
|
||||||
|
|
||||||
// Analyze the file name to see if a remote connection is required. If not,
|
// Analyze the file name to see if a remote connection is required. If not,
|
||||||
// quietly (sic) return.
|
// quietly (sic) return.
|
||||||
|
|
||||||
#if defined(WIN_NT)
|
|
||||||
if (ISC_analyze_pclan(file_name, node_name)) {
|
|
||||||
return WNET_analyze(file_name, status_vector, node_name.c_str(), /*user_string,*/ uv_flag);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!port)
|
|
||||||
{
|
|
||||||
if (ISC_analyze_tcp(file_name, node_name))
|
|
||||||
{
|
|
||||||
port = INET_analyze(file_name, status_vector,
|
|
||||||
node_name.c_str(), user_string, uv_flag, dpb);
|
|
||||||
|
|
||||||
if (!port)
|
|
||||||
{
|
|
||||||
// retry in case multiclient inet server not forked yet
|
|
||||||
sleep(2);
|
|
||||||
port = INET_analyze(file_name, status_vector,
|
|
||||||
node_name.c_str(), user_string, uv_flag, dpb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifndef NO_NFS
|
|
||||||
if (!port)
|
|
||||||
{
|
|
||||||
if (ISC_analyze_nfs(file_name, node_name))
|
|
||||||
{
|
|
||||||
port = INET_analyze(file_name, status_vector,
|
|
||||||
node_name.c_str(), user_string, uv_flag, dpb);
|
|
||||||
if (!port)
|
|
||||||
{
|
|
||||||
// retry in case multiclient inet server not forked yet
|
|
||||||
|
|
||||||
sleep(2);
|
|
||||||
port = INET_analyze(file_name, status_vector,
|
|
||||||
node_name.c_str(), user_string, uv_flag, dpb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(USE_XNET)
|
|
||||||
|
|
||||||
// all remote attempts have failed, so access locally through the interprocess server
|
|
||||||
|
|
||||||
if (!port && node_name.isEmpty())
|
|
||||||
{
|
|
||||||
return XNET_analyze(file_name, status_vector, /*node_name.c_str(), user_string,*/ uv_flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // USE_XNET
|
|
||||||
|
|
||||||
#if defined(SUPERCLIENT) && !defined(EMBEDDED)
|
|
||||||
// Coerce host connections to loopback
|
|
||||||
|
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
if (!port && node_name.isEmpty())
|
if (ISC_analyze_protocol(PROTOCOL_XNET, file_name, node_name))
|
||||||
{
|
{
|
||||||
file_name.insert(0, "\\\\.\\");
|
return XNET_analyze(file_name, status_vector, uv_flag);
|
||||||
if (ISC_analyze_pclan(file_name, node_name))
|
|
||||||
return WNET_analyze(file_name, status_vector, node_name.c_str(), /*user_string,*/ uv_flag);
|
|
||||||
}
|
}
|
||||||
#endif // WIN_NT
|
|
||||||
|
|
||||||
#ifdef UNIX
|
if (ISC_analyze_protocol(PROTOCOL_WNET, file_name, node_name) ||
|
||||||
|
ISC_analyze_pclan(file_name, node_name))
|
||||||
|
{
|
||||||
|
if (node_name.isEmpty())
|
||||||
|
{
|
||||||
|
node_name = WNET_LOCALHOST;
|
||||||
|
}
|
||||||
|
return WNET_analyze(file_name, status_vector, node_name.c_str(), uv_flag);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!port && node_name.isEmpty())
|
if (ISC_analyze_protocol(PROTOCOL_INET, file_name, node_name) ||
|
||||||
|
ISC_analyze_tcp(file_name, node_name))
|
||||||
{
|
{
|
||||||
file_name.insert(0, "localhost:");
|
if (node_name.isEmpty())
|
||||||
if (ISC_analyze_tcp(file_name, node_name))
|
|
||||||
{
|
{
|
||||||
|
node_name = INET_LOCALHOST;
|
||||||
|
}
|
||||||
return INET_analyze(file_name, status_vector,
|
return INET_analyze(file_name, status_vector,
|
||||||
node_name.c_str(), user_string, uv_flag, dpb);
|
node_name.c_str(), user_string, uv_flag, dpb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We have a local connection string. If it's a file on a network share,
|
||||||
|
// try to connect to the corresponding host remotely.
|
||||||
|
|
||||||
|
#ifdef WIN_NT
|
||||||
|
PathName expanded_name = file_name;
|
||||||
|
ISC_expand_share(expanded_name);
|
||||||
|
|
||||||
|
if (ISC_analyze_pclan(expanded_name, node_name))
|
||||||
|
{
|
||||||
|
port = WNET_analyze(expanded_name, status_vector, node_name.c_str(), uv_flag);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NO_NFS
|
||||||
|
PathName expanded_name = file_name;
|
||||||
|
if (ISC_analyze_nfs(expanded_name, node_name))
|
||||||
|
{
|
||||||
|
port = INET_analyze(expanded_name, status_vector,
|
||||||
|
node_name.c_str(), user_string, uv_flag, dpb);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// We still have a local connection string but failed to connect so far.
|
||||||
|
// If we're a pure client, attempt connect to the localhost.
|
||||||
|
|
||||||
|
#ifdef SUPERCLIENT
|
||||||
|
|
||||||
|
if (node_name.isEmpty())
|
||||||
|
{
|
||||||
|
#ifdef WIN_NT
|
||||||
|
if (!port)
|
||||||
|
{
|
||||||
|
port = XNET_analyze(file_name, status_vector, uv_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // UNIX
|
if (!port)
|
||||||
|
{
|
||||||
|
port = WNET_analyze(file_name, status_vector,
|
||||||
|
WNET_LOCALHOST, uv_flag);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!port)
|
||||||
|
{
|
||||||
|
port = INET_analyze(file_name, status_vector,
|
||||||
|
INET_LOCALHOST, user_string, uv_flag, dpb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // SUPERCLIENT
|
#endif // SUPERCLIENT
|
||||||
|
|
||||||
|
|
||||||
if (port || status_vector[1])
|
if (port || status_vector[1])
|
||||||
{
|
{
|
||||||
return port;
|
return port;
|
||||||
@ -4698,45 +4695,61 @@ static rem_port* analyze_service(PathName& service_name,
|
|||||||
// quietly (sic) return.
|
// quietly (sic) return.
|
||||||
|
|
||||||
#if defined(WIN_NT)
|
#if defined(WIN_NT)
|
||||||
if (ISC_analyze_pclan(service_name, node_name)) {
|
if (ISC_analyze_protocol(PROTOCOL_XNET, service_name, node_name))
|
||||||
return WNET_analyze(service_name, status_vector, node_name.c_str(), /*user_string,*/ uv_flag);
|
{
|
||||||
|
return XNET_analyze(service_name, status_vector, uv_flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ISC_analyze_protocol(PROTOCOL_WNET, service_name, node_name) ||
|
||||||
|
ISC_analyze_pclan(service_name, node_name))
|
||||||
|
{
|
||||||
|
if (node_name.isEmpty())
|
||||||
|
{
|
||||||
|
node_name = WNET_LOCALHOST;
|
||||||
|
}
|
||||||
|
return WNET_analyze(service_name, status_vector, node_name.c_str(), uv_flag);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ISC_analyze_protocol(PROTOCOL_INET, service_name, node_name) ||
|
||||||
|
ISC_analyze_tcp(service_name, node_name))
|
||||||
|
{
|
||||||
|
if (node_name.isEmpty())
|
||||||
|
{
|
||||||
|
node_name = INET_LOCALHOST;
|
||||||
|
}
|
||||||
|
return INET_analyze(service_name, status_vector,
|
||||||
|
node_name.c_str(), user_string, uv_flag, spb);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have a local connection string. If we're a pure client,
|
||||||
|
// attempt connect to a localhost.
|
||||||
|
|
||||||
|
#ifdef SUPERCLIENT
|
||||||
|
|
||||||
|
if (node_name.isEmpty())
|
||||||
|
{
|
||||||
|
#if defined(WIN_NT)
|
||||||
|
if (!port)
|
||||||
|
{
|
||||||
|
port = XNET_analyze(service_name, status_vector, uv_flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!port)
|
||||||
|
{
|
||||||
|
port = WNET_analyze(service_name, status_vector,
|
||||||
|
WNET_LOCALHOST, uv_flag);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!port)
|
if (!port)
|
||||||
{
|
|
||||||
if (ISC_analyze_tcp(service_name, node_name))
|
|
||||||
{
|
{
|
||||||
port = INET_analyze(service_name, status_vector,
|
port = INET_analyze(service_name, status_vector,
|
||||||
node_name.c_str(), user_string, uv_flag, spb);
|
INET_LOCALHOST, user_string, uv_flag, spb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(USE_XNET)
|
|
||||||
|
|
||||||
// all remote attempts have failed, so access locally through the
|
|
||||||
// interprocess server
|
|
||||||
|
|
||||||
if (!port && node_name.isEmpty()) {
|
|
||||||
port = XNET_analyze(service_name, status_vector, /*node_name.c_str(), user_string,*/ uv_flag);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SUPERCLIENT
|
|
||||||
#ifdef UNIX
|
|
||||||
|
|
||||||
if (!port && node_name.isEmpty())
|
|
||||||
{
|
|
||||||
service_name.insert(0, "localhost:");
|
|
||||||
if (ISC_analyze_tcp(service_name, node_name))
|
|
||||||
{
|
|
||||||
return INET_analyze(service_name, status_vector,
|
|
||||||
node_name.c_str(), user_string, uv_flag, spb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // UNIX
|
|
||||||
#endif // SUPERCLIENT
|
#endif // SUPERCLIENT
|
||||||
|
|
||||||
|
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user