8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 06:03:02 +01:00

CLIENT_ADDRESS and NETWORK_PROTOCOL variables support

This commit is contained in:
skidder 2004-11-26 01:01:27 +00:00
parent 4e7a45d022
commit 55c4e0ac85
9 changed files with 223 additions and 45 deletions

View File

@ -59,6 +59,8 @@ static const char
// System variables names // System variables names
static const char static const char
NETWORK_PROTOCOL_NAME[] = "NETWORK_PROTOCOL",
CLIENT_ADDRESS_NAME[] = "CLIENT_ADDRESS",
DATABASE_NAME[] = "DB_NAME", DATABASE_NAME[] = "DB_NAME",
ISOLATION_LEVEL_NAME[] = "ISOLATION_LEVEL", ISOLATION_LEVEL_NAME[] = "ISOLATION_LEVEL",
TRANSACTION_ID_NAME[] = "TRANSACTION_ID", TRANSACTION_ID_NAME[] = "TRANSACTION_ID",
@ -171,6 +173,22 @@ vary* get_context(const vary* ns_vary, const vary* name_vary)
// Handle system variables // Handle system variables
if (ns_str == SYSTEM_NAMESPACE) if (ns_str == SYSTEM_NAMESPACE)
{ {
if (name_str == NETWORK_PROTOCOL_NAME)
{
if (att->att_network_protocol.isEmpty())
return NULL;
return make_result_str(att->att_network_protocol);
}
if (name_str == CLIENT_ADDRESS_NAME)
{
if (att->att_remote_address.isEmpty())
return NULL;
return make_result_str(att->att_remote_address);
}
if (name_str == DATABASE_NAME) if (name_str == DATABASE_NAME)
{ {
return make_result_str(dbb->dbb_database_name.c_str(), return make_result_str(dbb->dbb_database_name.c_str(),

View File

@ -33,7 +33,7 @@
* *
*/ */
/* /*
$Id: ibase.h,v 1.95 2004-11-07 14:50:31 alexpeshkoff Exp $ $Id: ibase.h,v 1.96 2004-11-26 01:00:42 skidder Exp $
*/ */
#ifndef JRD_IBASE_H #ifndef JRD_IBASE_H
@ -1238,10 +1238,54 @@ int ISC_EXPORT isc_get_client_minor_version ();
#define isc_dpb_sql_dialect 63 #define isc_dpb_sql_dialect 63
#define isc_dpb_set_db_readonly 64 #define isc_dpb_set_db_readonly 64
#define isc_dpb_set_db_sql_dialect 65 #define isc_dpb_set_db_sql_dialect 65
#define isc_dpb_gfix_attach 66 #define isc_dpb_gfix_attach 66
#define isc_dpb_gstat_attach 67 #define isc_dpb_gstat_attach 67
#define isc_dpb_set_db_charset 68 #define isc_dpb_set_db_charset 68
#define isc_dpb_gsec_attach 69 #define isc_dpb_gsec_attach 69
#define isc_dpb_address_path 70
/**************************************************/
/* clumplet tags used inside isc_dpb_address_path */
/**************************************************/
/* Format of this clumplet is the following:
<address-path-clumplet> ::=
isc_dpb_address_path <byte-clumplet-length> <address-stack>
<address-stack> ::=
<address-descriptor> |
<address-stack> <address-descriptor>
<address-descriptor> ::=
isc_dpb_address <byte-clumplet-length> <address-elements>
<address-elements> ::=
<address-element> |
<address-elements> <address-element>
<address-element> ::=
isc_dpb_addr_protocol <byte-clumplet-length> <protocol-string> |
isc_dpb_addr_endpoint <byte-clumplet-length> <remote-endpoint-string>
<protocol-string> ::=
"TCPv4" |
"TCPv6" |
"XNET" |
"WNET" |
....
<remote-endpoint-string> ::=
<IPv4-address> | // such as "172.20.1.1"
<IPv6-address> | // such as "2001:0:13FF:09FF::1"
<xnet-process-id> | // such as "17864"
...
*/
#define isc_dpb_address 1
#define isc_dpb_addr_protocol 1
#define isc_dpb_addr_endpoint 2
/*********************************/ /*********************************/
/* isc_dpb_verify specific flags */ /* isc_dpb_verify specific flags */

View File

@ -330,6 +330,8 @@ public:
Firebird::string dpb_gbak_attach; Firebird::string dpb_gbak_attach;
Firebird::PathName dpb_working_directory; Firebird::PathName dpb_working_directory;
Firebird::string dpb_set_db_charset; Firebird::string dpb_set_db_charset;
Firebird::string dpb_network_protocol;
Firebird::string dpb_remote_address;
public: public:
DatabaseOptions() DatabaseOptions()
{ {
@ -692,6 +694,8 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
tdbb->tdbb_attachment = attachment = FB_NEW(*dbb->dbb_permanent) Attachment(dbb); tdbb->tdbb_attachment = attachment = FB_NEW(*dbb->dbb_permanent) Attachment(dbb);
attachment->att_filename = expanded_name; attachment->att_filename = expanded_name;
attachment->att_network_protocol = options.dpb_network_protocol;
attachment->att_remote_address = options.dpb_remote_address;
attachment->att_next = dbb->dbb_attachments; attachment->att_next = dbb->dbb_attachments;
dbb->dbb_attachments = attachment; dbb->dbb_attachments = attachment;
@ -1802,6 +1806,8 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
tdbb->tdbb_attachment = attachment = FB_NEW(*dbb->dbb_permanent) Attachment(dbb); tdbb->tdbb_attachment = attachment = FB_NEW(*dbb->dbb_permanent) Attachment(dbb);
attachment->att_filename = expanded_name; attachment->att_filename = expanded_name;
attachment->att_network_protocol = options.dpb_network_protocol;
attachment->att_remote_address = options.dpb_remote_address;
attachment->att_next = dbb->dbb_attachments; attachment->att_next = dbb->dbb_attachments;
dbb->dbb_attachments = attachment; dbb->dbb_attachments = attachment;
dbb->dbb_flags &= ~DBB_being_opened; dbb->dbb_flags &= ~DBB_being_opened;
@ -5198,6 +5204,34 @@ void DatabaseOptions::get(const UCHAR* dpb, USHORT dpb_length)
rdr.getString(dpb_set_db_charset); rdr.getString(dpb_set_db_charset);
break; break;
case isc_dpb_address_path: {
Firebird::ClumpletReader address_stack(false,
rdr.getBytes(), rdr.getClumpLength());
while (!address_stack.isEof()) {
if (address_stack.getClumpTag() != isc_dpb_address) {
address_stack.moveNext();
continue;
}
Firebird::ClumpletReader address(false,
address_stack.getBytes(), address_stack.getClumpLength());
while (!address.isEof()) {
switch (address.getClumpTag()) {
case isc_dpb_addr_protocol:
address.getString(dpb_network_protocol);
break;
case isc_dpb_addr_endpoint:
address.getString(dpb_remote_address);
break;
default:
break;
}
address.moveNext();
}
break;
}
break;
}
default: default:
break; break;
} }

View File

@ -433,7 +433,9 @@ public:
att_lc_messages(*dbb->dbb_permanent), att_lc_messages(*dbb->dbb_permanent),
att_working_directory(*dbb->dbb_permanent), att_working_directory(*dbb->dbb_permanent),
att_filename(*dbb->dbb_permanent), att_filename(*dbb->dbb_permanent),
att_context_vars(*dbb->dbb_permanent) { } att_context_vars(*dbb->dbb_permanent),
att_network_protocol(*dbb->dbb_permanent),
att_remote_address(*dbb->dbb_permanent) { }
/* Attachment() /* Attachment()
: att_database(0), : att_database(0),
att_next(0), att_next(0),
@ -495,6 +497,8 @@ public:
Firebird::PathName att_filename; // alias used to attach the database Firebird::PathName att_filename; // alias used to attach the database
Firebird::TimeStamp att_timestamp; // connection date and time Firebird::TimeStamp att_timestamp; // connection date and time
Firebird::StringMap att_context_vars; // Context variables for the connection Firebird::StringMap att_context_vars; // Context variables for the connection
Firebird::string att_network_protocol; // Network protocol used by client for connection
Firebird::string att_remote_address; // Protocol-specific addess of remote client
}; };

View File

@ -41,7 +41,7 @@
* *
*/ */
/* /*
$Id: inet.cpp,v 1.128 2004-11-16 06:16:19 robocop Exp $ $Id: inet.cpp,v 1.129 2004-11-26 01:01:16 skidder Exp $
*/ */
#include "firebird.h" #include "firebird.h"
#include <stdio.h> #include <stdio.h>
@ -1274,6 +1274,25 @@ static int accept_connection(rem_port* port,
temp.printf("%s.%ld.%ld", name, eff_gid, eff_uid); temp.printf("%s.%ld.%ld", name, eff_gid, eff_uid);
port->port_user_name = REMOTE_make_string(temp.c_str()); port->port_user_name = REMOTE_make_string(temp.c_str());
port->port_protocol_str = REMOTE_make_string("TCPv4");
struct sockaddr_in address;
socklen_t l = sizeof(address);
inet_zero((SCHAR *) &address, sizeof(address));
int status = getpeername((SOCKET) port->port_handle, (struct sockaddr *) &address, &l);
if (status == 0) {
Firebird::string addr_str;
UCHAR* ip = (UCHAR*) &address.sin_addr;
addr_str.printf(
"%d.%d.%d.%d",
static_cast<int>(ip[0]),
static_cast<int>(ip[1]),
static_cast<int>(ip[2]),
static_cast<int>(ip[3]) );
port->port_address_str = REMOTE_make_string(addr_str.c_str());
}
return TRUE; return TRUE;
} }
@ -1883,6 +1902,12 @@ static void cleanup_port( rem_port* port)
if (port->port_object_vector) if (port->port_object_vector)
ALLR_free((UCHAR *) port->port_object_vector); ALLR_free((UCHAR *) port->port_object_vector);
if (port->port_protocol_str)
ALLR_free((UCHAR *) port->port_protocol_str);
if (port->port_address_str)
ALLR_free((UCHAR *) port->port_address_str);
#ifdef DEBUG_XDR_MEMORY #ifdef DEBUG_XDR_MEMORY
if (port->port_packet_vector) if (port->port_packet_vector)
ALLR_free((UCHAR *) port->port_packet_vector); ALLR_free((UCHAR *) port->port_packet_vector);

View File

@ -621,6 +621,10 @@ static int accept_connection( rem_port* port, P_CNCT * cnct)
id += *id + 1; id += *id + 1;
} }
// NS: Put in connection address. I have no good idea where to get an
// address of the remote end of named pipe so let's live without it for now
port->port_protocol_str = REMOTE_make_string("WNET");
return TRUE; return TRUE;
} }
@ -914,6 +918,12 @@ static void cleanup_port( rem_port* port)
if (port->port_user_name) if (port->port_user_name)
ALLR_free((UCHAR *) port->port_user_name); ALLR_free((UCHAR *) port->port_user_name);
if (port->port_protocol_str)
ALLR_free((UCHAR *) port->port_protocol_str);
if (port->port_address_str)
ALLR_free((UCHAR *) port->port_address_str);
if (port->port_host) if (port->port_host)
ALLR_free((UCHAR *) port->port_host); ALLR_free((UCHAR *) port->port_host);

View File

@ -416,6 +416,8 @@ struct rem_port
rem_str* port_connection; /* Name of connection */ rem_str* port_connection; /* Name of connection */
rem_str* port_user_name; rem_str* port_user_name;
rem_str* port_passwd; rem_str* port_passwd;
rem_str* port_protocol_str; // String containing protocol name for this port
rem_str* port_address_str; // Protocol-specific address string for the port
rpr* port_rpr; /* port stored procedure reference */ rpr* port_rpr; /* port stored procedure reference */
rsr* port_statement; /* Statement for execute immediate */ rsr* port_statement; /* Statement for execute immediate */
rmtque* port_receive_rmtque; /* for client, responses waiting */ rmtque* port_receive_rmtque; /* for client, responses waiting */

View File

@ -54,6 +54,7 @@
#include "../jrd/thread_proto.h" #include "../jrd/thread_proto.h"
#include "../jrd/why_proto.h" #include "../jrd/why_proto.h"
#include "../common/classes/semaphore.h" #include "../common/classes/semaphore.h"
#include "../common/classes/ClumpletWriter.h"
#ifdef DEBUG #ifdef DEBUG
#include "gen/iberror.h" #include "gen/iberror.h"
#endif #endif
@ -750,57 +751,79 @@ static ISC_STATUS attach_database(
* Process an attach or create packet. * Process an attach or create packet.
* *
**************************************/ **************************************/
UCHAR new_dpb_buffer[512];
ISC_STATUS_ARRAY status_vector; ISC_STATUS_ARRAY status_vector;
send->p_operation = op_accept; send->p_operation = op_accept;
FB_API_HANDLE handle = 0; FB_API_HANDLE handle = 0;
const char* file = reinterpret_cast<const char*>(attach->p_atch_file.cstr_address); const char* file = reinterpret_cast<const char*>(attach->p_atch_file.cstr_address);
const USHORT l = attach->p_atch_file.cstr_length; const USHORT l = attach->p_atch_file.cstr_length;
// CVC: A false sense of constness is worse than no const at all. // CVC: A false sense of constness is worse than no const at all.
// Make "dpb" non const until we fix this instead of throwing constness later. // Make "dpb" non const until we fix this instead of throwing constness later.
UCHAR* dpb = attach->p_atch_dpb.cstr_address; // NS: Claudio, could you please remove the comment if it doesn't apply anymore?
const UCHAR* dpb = attach->p_atch_dpb.cstr_address;
USHORT dl = attach->p_atch_dpb.cstr_length; USHORT dl = attach->p_atch_dpb.cstr_length;
/* If we have user identification, append it to database parameter block */
Firebird::ClumpletWriter dpb_buffer(true, MAX_SSHORT);
UCHAR* new_dpb = new_dpb_buffer; if (dl)
dpb_buffer.reset(dpb, dl);
else
dpb_buffer.reset(isc_dpb_version1);
// If we have user identification, append it to database parameter block
rem_str* string = port->port_user_name; rem_str* string = port->port_user_name;
if (string) { if (string) {
if ((size_t)(dl + 3 + string->str_length) > sizeof(new_dpb_buffer)) dpb_buffer.setCurOffset(dpb_buffer.getBufferLength());
new_dpb = ALLR_alloc((SLONG) (dl + 3 + string->str_length)); dpb_buffer.insertString(isc_dpb_sys_user_name,
UCHAR* p = new_dpb; string->str_data, string->str_length);
if (dl) {
for (const UCHAR* const end = dpb + dl; dpb < end;)
*p++ = *dpb++;
}
else
*p++ = isc_dpb_version1;
*p++ = isc_dpb_sys_user_name;
*p++ = (UCHAR) string->str_length;
dpb = (UCHAR *) string->str_data;
for (const UCHAR* const end = dpb + string->str_length; dpb < end;)
*p++ = *dpb++;
dpb = new_dpb;
dl = p - new_dpb;
} }
// Now, insert remote endpoint data into DPB address stack
dpb_buffer.setCurOffset(1);
while (!dpb_buffer.isEof() && dpb_buffer.getClumpTag() != isc_dpb_address_path)
dpb_buffer.moveNext();
Firebird::ClumpletWriter address_stack_buffer(false, MAX_UCHAR - 2);
if (!dpb_buffer.isEof()) {
address_stack_buffer.reset(dpb_buffer.getBytes(), dpb_buffer.getClumpLength());
dpb_buffer.deleteClumplet();
}
Firebird::ClumpletWriter address_record(false, MAX_UCHAR - 2);
if (port->port_protocol_str)
address_record.insertString(isc_dpb_addr_protocol,
port->port_protocol_str->str_data, port->port_protocol_str->str_length);
if (port->port_address_str)
address_record.insertString(isc_dpb_addr_endpoint,
port->port_address_str->str_data, port->port_address_str->str_length);
// We always insert remote address descriptor as a first element
// of appropriate clumplet so user cannot fake it and engine may somewhat trust it.
fb_assert(address_stack_buffer.getCurOffset() == 0);
address_stack_buffer.insertBytes(isc_dpb_address,
address_record.getBuffer(), address_record.getBufferLength());
dpb_buffer.insertBytes(isc_dpb_address_path,
address_stack_buffer.getBuffer(), address_stack_buffer.getBufferLength());
/* Disable remote gsec attachments */
for (dpb_buffer.setCurOffset(1); !dpb_buffer.isEof(); ) {
if (dpb_buffer.getClumpTag() == isc_dpb_gsec_attach)
dpb_buffer.deleteClumplet();
else
dpb_buffer.moveNext();
}
dpb = dpb_buffer.getBuffer();
dl = dpb_buffer.getBufferLength();
/* See if user has specified parameters relevant to the connection, /* See if user has specified parameters relevant to the connection,
they will be stuffed in the DPB if so. */ they will be stuffed in the DPB if so. */
REMOTE_get_timeout_params(port, dpb, dl); REMOTE_get_timeout_params(port, dpb, dl);
/* Disable remote gsec attachments */
UCHAR* p = dpb;
const UCHAR* const end = dpb + dl;
while (p < end)
{
if (p[0] == isc_dpb_gsec_attach && p[1])
{
p[2] = 0;
}
p += (2 + p[1]);
}
THREAD_EXIT(); THREAD_EXIT();
if (operation == op_attach) if (operation == op_attach)
{ {
@ -814,10 +837,6 @@ static ISC_STATUS attach_database(
} }
THREAD_ENTER(); THREAD_ENTER();
if (new_dpb != new_dpb_buffer) {
ALLR_free(new_dpb);
}
if (!status_vector[1]) if (!status_vector[1])
{ {
RDB rdb = (RDB) ALLR_block(type_rdb, 0); RDB rdb = (RDB) ALLR_block(type_rdb, 0);
@ -3228,10 +3247,10 @@ bool process_packet(rem_port* port,
ThreadData::restoreSpecific(); ThreadData::restoreSpecific();
} // try } // try
catch (const std::exception&) { catch (const std::exception& ex) {
/* There must be something better to do here. BUT WHAT? */ Firebird::stuff_exception(tdrdb->trdb_status_vector, ex);
gds__log("SERVER/process_packet: out of memory", 0); gds__log_status("unknown, SERVER/process_packet", tdrdb->trdb_status_vector);
/* It would be nice to log an error to the user, instead of just terminating them! */ /* It would be nice to log an error to the user, instead of just terminating them! */
port->send_response(sendL, 0, 0, tdrdb->trdb_status_vector); port->send_response(sendL, 0, 0, tdrdb->trdb_status_vector);

View File

@ -40,6 +40,7 @@
#include "../jrd/isc_proto.h" #include "../jrd/isc_proto.h"
#include "../jrd/sch_proto.h" #include "../jrd/sch_proto.h"
#include "../jrd/thread_proto.h" #include "../jrd/thread_proto.h"
#include "fb_string.h"
#include <time.h> #include <time.h>
#ifdef WIN_NT #ifdef WIN_NT
@ -825,6 +826,19 @@ static int accept_connection(rem_port* port, P_CNCT * cnct)
* Accept an incoming request for connection. * Accept an incoming request for connection.
* *
**************************************/ **************************************/
port->port_protocol_str = REMOTE_make_string("XNET");
// Use client process ID as remote address for XNET protocol
XCC xcc = (XCC) port->port_xcc;
if (xcc) {
XPS xps = (XPS) xcc->xcc_mapped_addr;
if (xps) {
Firebird::string address;
address.printf("%u", xps->xps_client_proc_id);
port->port_address_str = REMOTE_make_string(address.c_str());
}
}
return TRUE; return TRUE;
} }
@ -1300,6 +1314,14 @@ static void xnet_cleanup_port(rem_port* port)
ALLR_free((UCHAR *) port->port_object_vector); ALLR_free((UCHAR *) port->port_object_vector);
} }
if (port->port_protocol_str) {
ALLR_free((UCHAR *) port->port_protocol_str);
}
if (port->port_address_str) {
ALLR_free((UCHAR *) port->port_address_str);
}
#ifdef SUPERSERVER #ifdef SUPERSERVER
if (port->port_status_vector) { if (port->port_status_vector) {
ALLR_free(port->port_status_vector); ALLR_free(port->port_status_vector);