MIDAS
Loading...
Searching...
No Matches
RPC Functions (rpc_xxx)

Classes

class  RPC_CLIENT_CONNECTION
 
struct  TR_FIFO
 
struct  TLS_POINTER
 

Macros

#define RPC_CM_SET_CLIENT_INFO   11000
 
#define RPC_CM_SET_WATCHDOG_PARAMS   11001
 
#define RPC_CM_CLEANUP   11002
 
#define RPC_CM_GET_WATCHDOG_INFO   11003
 
#define RPC_CM_MSG_LOG   11004
 
#define RPC_CM_EXECUTE   11005
 
#define RPC_CM_SYNCHRONIZE   11006
 
#define RPC_CM_ASCTIME   11007
 
#define RPC_CM_TIME   11008
 
#define RPC_CM_MSG   11009
 
#define RPC_CM_EXIST   11011
 
#define RPC_CM_MSG_RETRIEVE   11012
 
#define RPC_CM_MSG_LOG1   11013
 
#define RPC_CM_CHECK_CLIENT   11014
 
#define RPC_BM_OPEN_BUFFER   11100
 
#define RPC_BM_CLOSE_BUFFER   11101
 
#define RPC_BM_CLOSE_ALL_BUFFERS   11102
 
#define RPC_BM_GET_BUFFER_INFO   11103
 
#define RPC_BM_GET_BUFFER_LEVEL   11104
 
#define RPC_BM_INIT_BUFFER_COUNTERS   11105
 
#define RPC_BM_SET_CACHE_SIZE   11106
 
#define RPC_BM_ADD_EVENT_REQUEST   11107
 
#define RPC_BM_REMOVE_EVENT_REQUEST   11108
 
#define RPC_BM_SEND_EVENT   11109
 
#define RPC_BM_FLUSH_CACHE   11110
 
#define RPC_BM_RECEIVE_EVENT   11111
 
#define RPC_BM_MARK_READ_WAITING   11112
 
#define RPC_BM_EMPTY_BUFFERS   11113
 
#define RPC_BM_SKIP_EVENT   11114
 
#define RPC_DB_OPEN_DATABASE   11200
 
#define RPC_DB_CLOSE_DATABASE   11201
 
#define RPC_DB_CLOSE_ALL_DATABASES   11202
 
#define RPC_DB_CREATE_KEY   11203
 
#define RPC_DB_CREATE_LINK   11204
 
#define RPC_DB_SET_VALUE   11205
 
#define RPC_DB_GET_VALUE   11206
 
#define RPC_DB_FIND_KEY   11207
 
#define RPC_DB_FIND_LINK   11208
 
#define RPC_DB_GET_PATH   11209
 
#define RPC_DB_DELETE_KEY   11210
 
#define RPC_DB_ENUM_KEY   11211
 
#define RPC_DB_GET_KEY   11212
 
#define RPC_DB_GET_DATA   11213
 
#define RPC_DB_SET_DATA   11214
 
#define RPC_DB_SET_DATA_INDEX   11215
 
#define RPC_DB_SET_MODE   11216
 
#define RPC_DB_GET_RECORD_SIZE   11219
 
#define RPC_DB_GET_RECORD   11220
 
#define RPC_DB_SET_RECORD   11221
 
#define RPC_DB_ADD_OPEN_RECORD   11222
 
#define RPC_DB_REMOVE_OPEN_RECORD   11223
 
#define RPC_DB_SAVE   11224
 
#define RPC_DB_LOAD   11225
 
#define RPC_DB_SET_CLIENT_NAME   11226
 
#define RPC_DB_RENAME_KEY   11227
 
#define RPC_DB_ENUM_LINK   11228
 
#define RPC_DB_REORDER_KEY   11229
 
#define RPC_DB_CREATE_RECORD   11230
 
#define RPC_DB_GET_DATA_INDEX   11231
 
#define RPC_DB_GET_KEY_TIME   11232
 
#define RPC_DB_GET_OPEN_RECORDS   11233
 
#define RPC_DB_FLUSH_DATABASE   11235
 
#define RPC_DB_SET_DATA_INDEX1   11236
 
#define RPC_DB_GET_KEY_INFO   11237
 
#define RPC_DB_GET_DATA1   11238
 
#define RPC_DB_SET_NUM_VALUES   11239
 
#define RPC_DB_CHECK_RECORD   11240
 
#define RPC_DB_GET_NEXT_LINK   11241
 
#define RPC_DB_GET_LINK   11242
 
#define RPC_DB_GET_LINK_DATA   11243
 
#define RPC_DB_SET_LINK_DATA   11244
 
#define RPC_DB_SET_LINK_DATA_INDEX   11245
 
#define RPC_DB_SET_DATA1   11246
 
#define RPC_DB_NOTIFY_CLIENTS_ARRAY   11247
 
#define RPC_DB_GET_PARENT   11248
 
#define RPC_DB_COPY_XML   11249
 
#define RPC_EL_SUBMIT   11400
 
#define RPC_AL_CHECK   11500
 
#define RPC_AL_TRIGGER_ALARM   11501
 
#define RPC_RC_TRANSITION   12000
 
#define RPC_ANA_CLEAR_HISTOS   13000
 
#define RPC_LOG_REWIND   14000
 
#define RPC_TEST   15000
 
#define RPC_TEST2   15001
 
#define RPC_CNAF16   16000
 
#define RPC_CNAF24   16001
 
#define RPC_MANUAL_TRIG   17000
 
#define RPC_JRPC   18000
 
#define RPC_BRPC   18001
 
#define RPC_ID_WATCHDOG   99997
 
#define RPC_ID_SHUTDOWN   99998
 
#define RPC_ID_EXIT   99999
 

Functions

static RPC_SERVER_ACCEPTIONrpc_get_server_acception (int idx)
 
RPC_SERVER_ACCEPTIONrpc_get_mserver_acception ()
 
static RPC_SERVER_ACCEPTIONrpc_new_server_acception ()
 
void rpc_calc_convert_flags (INT hw_type, INT remote_hw_type, INT *convert_flags)
 
void rpc_get_convert_flags (INT *convert_flags)
 
void rpc_ieee2vax_float (float *var)
 
void rpc_vax2ieee_float (float *var)
 
void rpc_vax2ieee_double (double *var)
 
void rpc_ieee2vax_double (double *var)
 
void rpc_convert_single (void *data, INT tid, INT flags, INT convert_flags)
 
void rpc_convert_data (void *data, INT tid, INT flags, INT total_size, INT convert_flags)
 
INT rpc_tid_size (INT id)
 
const charrpc_tid_name (INT id)
 
const charrpc_tid_name_old (INT id)
 
int rpc_name_tid (const char *name)
 
INT rpc_register_client (const char *name, RPC_LIST *list)
 
INT rpc_register_functions (const RPC_LIST *new_list, RPC_HANDLER func)
 
INT rpc_deregister_functions ()
 
INT rpc_register_function (INT id, INT(*func)(INT, void **))
 
static int handle_msg_odb (int n, const NET_COMMAND *nc)
 
INT rpc_client_dispatch (int sock)
 
INT rpc_client_connect (const char *host_name, INT port, const char *client_name, HNDLE *hConnection)
 
void rpc_client_check ()
 
INT rpc_server_connect (const char *host_name, const char *exp_name)
 
static RPC_CLIENT_CONNECTIONrpc_get_locked_client_connection (HNDLE hConn)
 
INT rpc_client_disconnect (HNDLE hConn, BOOL bShutdown)
 
INT rpc_server_disconnect ()
 
bool rpc_is_remote (void)
 
bool rpc_is_connected (void)
 
std::string rpc_get_mserver_hostname (void)
 
bool rpc_is_mserver (void)
 
INT rpc_get_hw_type ()
 
INT rpc_get_timeout (HNDLE hConn)
 
INT rpc_set_timeout (HNDLE hConn, int timeout_msec, int *old_timeout_msec)
 
INT rpc_get_convert_flags (void)
 
const charrpc_get_mserver_path ()
 
INT rpc_set_mserver_path (const char *path)
 
std::string rpc_get_name ()
 
INT rpc_set_name (const char *name)
 
INT rpc_set_debug (void(*func)(const char *), INT mode)
 
void rpc_debug_printf (const char *format,...)
 
void rpc_va_arg (va_list *arg_ptr, INT arg_type, void *arg)
 
static void rpc_call_encode (va_list &ap, const RPC_LIST &rl, NET_COMMAND **nc)
 
static int rpc_call_decode (va_list &ap, const RPC_LIST &rl, const char *buf, size_t buf_size)
 
INT rpc_client_call (HNDLE hConn, DWORD routine_id,...)
 
INT rpc_call (DWORD routine_id,...)
 
INT rpc_set_opt_tcp_size (INT tcp_size)
 
INT rpc_get_opt_tcp_size ()
 
INT rpc_send_event (INT buffer_handle, const EVENT_HEADER *pevent, int unused, INT async_flag, INT mode)
 
INT rpc_send_event1 (INT buffer_handle, const EVENT_HEADER *pevent)
 
INT rpc_send_event_sg (INT buffer_handle, int sg_n, const char *const sg_ptr[], const size_t sg_len[])
 
INT rpc_flush_event ()
 
static INT rpc_transition_dispatch (INT idx, void *prpc_param[])
 
int cm_query_transition (int *transition, int *run_number, int *trans_time)
 
static int recv_net_command_realloc (INT idx, char **pbuf, int *pbufsize, INT *remaining)
 
INT recv_tcp_check (int sock)
 
static int recv_event_server_realloc (INT idx, RPC_SERVER_ACCEPTION *psa, char **pbuffer, int *pbuffer_size)
 
INT rpc_register_server (int port, int *plsock, int *pport)
 
INT rpc_register_listener (int port, RPC_HANDLER func, int *plsock, int *pport)
 
INT rpc_execute (INT sock, char *buffer, INT convert_flags)
 
int rpc_test_rpc ()
 
static std::atomic_bool gAllowedHostsEnabled (false)
 
INT rpc_clear_allowed_hosts ()
 
INT rpc_add_allowed_host (const char *hostname)
 
INT rpc_check_allowed_host (const char *hostname)
 
static INT rpc_socket_check_allowed_host (int sock)
 
INT rpc_server_accept (int lsock)
 
INT rpc_client_accept (int lsock)
 
INT rpc_server_callback (struct callback_addr *pcallback)
 
INT rpc_server_loop (void)
 
INT rpc_server_receive_rpc (int idx, RPC_SERVER_ACCEPTION *sa)
 
INT rpc_server_receive_event (int idx, RPC_SERVER_ACCEPTION *sa, int timeout_msec)
 
int rpc_flush_event_socket (int timeout_msec)
 
INT rpc_server_shutdown (void)
 
INT rpc_check_channels (void)
 
void rpc_server_acception_struct::close ()
 

Variables

static std::mutex _client_connections_mutex
 
static std::vector< RPC_CLIENT_CONNECTION * > _client_connections
 
static RPC_SERVER_CONNECTION _server_connection
 
static bool _rpc_is_remote = false
 
static std::vector< RPC_SERVER_ACCEPTION * > _server_acceptions
 
static RPC_SERVER_ACCEPTION_mserver_acception = NULL
 
static std::vector< RPC_LISTrpc_list
 
static std::mutex rpc_list_mutex
 
static int _opt_tcp_size = OPT_TCP_SIZE
 
static std::string _mserver_path
 
static std::mutex _tr_fifo_mutex
 
static TR_FIFO _tr_fifo [10]
 
static int _tr_fifo_wp = 0
 
static int _tr_fifo_rp = 0
 
static TLS_POINTERtls_buffer = NULL
 
static int tls_size = 0
 
static std::vector< std::string > gAllowedHosts
 
static std::mutex gAllowedHostsMutex
 

Detailed Description

dox dox dox


Macro Definition Documentation

◆ RPC_AL_CHECK

#define RPC_AL_CHECK   11500

Definition at line 113 of file mrpc.h.

◆ RPC_AL_TRIGGER_ALARM

#define RPC_AL_TRIGGER_ALARM   11501

Definition at line 114 of file mrpc.h.

◆ RPC_ANA_CLEAR_HISTOS

#define RPC_ANA_CLEAR_HISTOS   13000

Definition at line 118 of file mrpc.h.

◆ RPC_BM_ADD_EVENT_REQUEST

#define RPC_BM_ADD_EVENT_REQUEST   11107

Definition at line 43 of file mrpc.h.

◆ RPC_BM_CLOSE_ALL_BUFFERS

#define RPC_BM_CLOSE_ALL_BUFFERS   11102

Definition at line 38 of file mrpc.h.

◆ RPC_BM_CLOSE_BUFFER

#define RPC_BM_CLOSE_BUFFER   11101

Definition at line 37 of file mrpc.h.

◆ RPC_BM_EMPTY_BUFFERS

#define RPC_BM_EMPTY_BUFFERS   11113

Definition at line 49 of file mrpc.h.

◆ RPC_BM_FLUSH_CACHE

#define RPC_BM_FLUSH_CACHE   11110

Definition at line 46 of file mrpc.h.

◆ RPC_BM_GET_BUFFER_INFO

#define RPC_BM_GET_BUFFER_INFO   11103

Definition at line 39 of file mrpc.h.

◆ RPC_BM_GET_BUFFER_LEVEL

#define RPC_BM_GET_BUFFER_LEVEL   11104

Definition at line 40 of file mrpc.h.

◆ RPC_BM_INIT_BUFFER_COUNTERS

#define RPC_BM_INIT_BUFFER_COUNTERS   11105

Definition at line 41 of file mrpc.h.

◆ RPC_BM_MARK_READ_WAITING

#define RPC_BM_MARK_READ_WAITING   11112

Definition at line 48 of file mrpc.h.

◆ RPC_BM_OPEN_BUFFER

#define RPC_BM_OPEN_BUFFER   11100

Definition at line 36 of file mrpc.h.

◆ RPC_BM_RECEIVE_EVENT

#define RPC_BM_RECEIVE_EVENT   11111

Definition at line 47 of file mrpc.h.

◆ RPC_BM_REMOVE_EVENT_REQUEST

#define RPC_BM_REMOVE_EVENT_REQUEST   11108

Definition at line 44 of file mrpc.h.

◆ RPC_BM_SEND_EVENT

#define RPC_BM_SEND_EVENT   11109

Definition at line 45 of file mrpc.h.

◆ RPC_BM_SET_CACHE_SIZE

#define RPC_BM_SET_CACHE_SIZE   11106

Definition at line 42 of file mrpc.h.

◆ RPC_BM_SKIP_EVENT

#define RPC_BM_SKIP_EVENT   11114

Definition at line 50 of file mrpc.h.

◆ RPC_BRPC

#define RPC_BRPC   18001

Definition at line 131 of file mrpc.h.

◆ RPC_CM_ASCTIME

#define RPC_CM_ASCTIME   11007

Definition at line 28 of file mrpc.h.

◆ RPC_CM_CHECK_CLIENT

#define RPC_CM_CHECK_CLIENT   11014

Definition at line 34 of file mrpc.h.

◆ RPC_CM_CLEANUP

#define RPC_CM_CLEANUP   11002

Definition at line 23 of file mrpc.h.

◆ RPC_CM_EXECUTE

#define RPC_CM_EXECUTE   11005

Definition at line 26 of file mrpc.h.

◆ RPC_CM_EXIST

#define RPC_CM_EXIST   11011

Definition at line 31 of file mrpc.h.

◆ RPC_CM_GET_WATCHDOG_INFO

#define RPC_CM_GET_WATCHDOG_INFO   11003

Definition at line 24 of file mrpc.h.

◆ RPC_CM_MSG

#define RPC_CM_MSG   11009

Definition at line 30 of file mrpc.h.

◆ RPC_CM_MSG_LOG

#define RPC_CM_MSG_LOG   11004

Definition at line 25 of file mrpc.h.

◆ RPC_CM_MSG_LOG1

#define RPC_CM_MSG_LOG1   11013

Definition at line 33 of file mrpc.h.

◆ RPC_CM_MSG_RETRIEVE

#define RPC_CM_MSG_RETRIEVE   11012

Definition at line 32 of file mrpc.h.

◆ RPC_CM_SET_CLIENT_INFO

#define RPC_CM_SET_CLIENT_INFO   11000

routine IDs for RPC calls

Definition at line 21 of file mrpc.h.

◆ RPC_CM_SET_WATCHDOG_PARAMS

#define RPC_CM_SET_WATCHDOG_PARAMS   11001

Definition at line 22 of file mrpc.h.

◆ RPC_CM_SYNCHRONIZE

#define RPC_CM_SYNCHRONIZE   11006

Definition at line 27 of file mrpc.h.

◆ RPC_CM_TIME

#define RPC_CM_TIME   11008

Definition at line 29 of file mrpc.h.

◆ RPC_CNAF16

#define RPC_CNAF16   16000

Definition at line 125 of file mrpc.h.

◆ RPC_CNAF24

#define RPC_CNAF24   16001

Definition at line 126 of file mrpc.h.

◆ RPC_DB_ADD_OPEN_RECORD

#define RPC_DB_ADD_OPEN_RECORD   11222

Definition at line 72 of file mrpc.h.

◆ RPC_DB_CHECK_RECORD

#define RPC_DB_CHECK_RECORD   11240

Definition at line 89 of file mrpc.h.

◆ RPC_DB_CLOSE_ALL_DATABASES

#define RPC_DB_CLOSE_ALL_DATABASES   11202

Definition at line 54 of file mrpc.h.

◆ RPC_DB_CLOSE_DATABASE

#define RPC_DB_CLOSE_DATABASE   11201

Definition at line 53 of file mrpc.h.

◆ RPC_DB_COPY_XML

#define RPC_DB_COPY_XML   11249

Definition at line 98 of file mrpc.h.

◆ RPC_DB_CREATE_KEY

#define RPC_DB_CREATE_KEY   11203

Definition at line 55 of file mrpc.h.

◆ RPC_DB_CREATE_LINK

#define RPC_DB_CREATE_LINK   11204

Definition at line 56 of file mrpc.h.

◆ RPC_DB_CREATE_RECORD

#define RPC_DB_CREATE_RECORD   11230

Definition at line 80 of file mrpc.h.

◆ RPC_DB_DELETE_KEY

#define RPC_DB_DELETE_KEY   11210

Definition at line 62 of file mrpc.h.

◆ RPC_DB_ENUM_KEY

#define RPC_DB_ENUM_KEY   11211

Definition at line 63 of file mrpc.h.

◆ RPC_DB_ENUM_LINK

#define RPC_DB_ENUM_LINK   11228

Definition at line 78 of file mrpc.h.

◆ RPC_DB_FIND_KEY

#define RPC_DB_FIND_KEY   11207

Definition at line 59 of file mrpc.h.

◆ RPC_DB_FIND_LINK

#define RPC_DB_FIND_LINK   11208

Definition at line 60 of file mrpc.h.

◆ RPC_DB_FLUSH_DATABASE

#define RPC_DB_FLUSH_DATABASE   11235

Definition at line 84 of file mrpc.h.

◆ RPC_DB_GET_DATA

#define RPC_DB_GET_DATA   11213

Definition at line 65 of file mrpc.h.

◆ RPC_DB_GET_DATA1

#define RPC_DB_GET_DATA1   11238

Definition at line 87 of file mrpc.h.

◆ RPC_DB_GET_DATA_INDEX

#define RPC_DB_GET_DATA_INDEX   11231

Definition at line 81 of file mrpc.h.

◆ RPC_DB_GET_KEY

#define RPC_DB_GET_KEY   11212

Definition at line 64 of file mrpc.h.

◆ RPC_DB_GET_KEY_INFO

#define RPC_DB_GET_KEY_INFO   11237

Definition at line 86 of file mrpc.h.

◆ RPC_DB_GET_KEY_TIME

#define RPC_DB_GET_KEY_TIME   11232

Definition at line 82 of file mrpc.h.

◆ RPC_DB_GET_LINK

#define RPC_DB_GET_LINK   11242

Definition at line 91 of file mrpc.h.

◆ RPC_DB_GET_LINK_DATA

#define RPC_DB_GET_LINK_DATA   11243

Definition at line 92 of file mrpc.h.

◆ RPC_DB_GET_NEXT_LINK

#define RPC_DB_GET_NEXT_LINK   11241

Definition at line 90 of file mrpc.h.

◆ RPC_DB_GET_OPEN_RECORDS

#define RPC_DB_GET_OPEN_RECORDS   11233

Definition at line 83 of file mrpc.h.

◆ RPC_DB_GET_PARENT

#define RPC_DB_GET_PARENT   11248

Definition at line 97 of file mrpc.h.

◆ RPC_DB_GET_PATH

#define RPC_DB_GET_PATH   11209

Definition at line 61 of file mrpc.h.

◆ RPC_DB_GET_RECORD

#define RPC_DB_GET_RECORD   11220

Definition at line 70 of file mrpc.h.

◆ RPC_DB_GET_RECORD_SIZE

#define RPC_DB_GET_RECORD_SIZE   11219

Definition at line 69 of file mrpc.h.

◆ RPC_DB_GET_VALUE

#define RPC_DB_GET_VALUE   11206

Definition at line 58 of file mrpc.h.

◆ RPC_DB_LOAD

#define RPC_DB_LOAD   11225

Definition at line 75 of file mrpc.h.

◆ RPC_DB_NOTIFY_CLIENTS_ARRAY

#define RPC_DB_NOTIFY_CLIENTS_ARRAY   11247

Definition at line 96 of file mrpc.h.

◆ RPC_DB_OPEN_DATABASE

#define RPC_DB_OPEN_DATABASE   11200

Definition at line 52 of file mrpc.h.

◆ RPC_DB_REMOVE_OPEN_RECORD

#define RPC_DB_REMOVE_OPEN_RECORD   11223

Definition at line 73 of file mrpc.h.

◆ RPC_DB_RENAME_KEY

#define RPC_DB_RENAME_KEY   11227

Definition at line 77 of file mrpc.h.

◆ RPC_DB_REORDER_KEY

#define RPC_DB_REORDER_KEY   11229

Definition at line 79 of file mrpc.h.

◆ RPC_DB_SAVE

#define RPC_DB_SAVE   11224

Definition at line 74 of file mrpc.h.

◆ RPC_DB_SET_CLIENT_NAME

#define RPC_DB_SET_CLIENT_NAME   11226

Definition at line 76 of file mrpc.h.

◆ RPC_DB_SET_DATA

#define RPC_DB_SET_DATA   11214

Definition at line 66 of file mrpc.h.

◆ RPC_DB_SET_DATA1

#define RPC_DB_SET_DATA1   11246

Definition at line 95 of file mrpc.h.

◆ RPC_DB_SET_DATA_INDEX

#define RPC_DB_SET_DATA_INDEX   11215

Definition at line 67 of file mrpc.h.

◆ RPC_DB_SET_DATA_INDEX1

#define RPC_DB_SET_DATA_INDEX1   11236

Definition at line 85 of file mrpc.h.

◆ RPC_DB_SET_LINK_DATA

#define RPC_DB_SET_LINK_DATA   11244

Definition at line 93 of file mrpc.h.

◆ RPC_DB_SET_LINK_DATA_INDEX

#define RPC_DB_SET_LINK_DATA_INDEX   11245

Definition at line 94 of file mrpc.h.

◆ RPC_DB_SET_MODE

#define RPC_DB_SET_MODE   11216

Definition at line 68 of file mrpc.h.

◆ RPC_DB_SET_NUM_VALUES

#define RPC_DB_SET_NUM_VALUES   11239

Definition at line 88 of file mrpc.h.

◆ RPC_DB_SET_RECORD

#define RPC_DB_SET_RECORD   11221

Definition at line 71 of file mrpc.h.

◆ RPC_DB_SET_VALUE

#define RPC_DB_SET_VALUE   11205

Definition at line 57 of file mrpc.h.

◆ RPC_EL_SUBMIT

#define RPC_EL_SUBMIT   11400

Definition at line 111 of file mrpc.h.

◆ RPC_ID_EXIT

#define RPC_ID_EXIT   99999

Definition at line 135 of file mrpc.h.

◆ RPC_ID_SHUTDOWN

#define RPC_ID_SHUTDOWN   99998

Definition at line 134 of file mrpc.h.

◆ RPC_ID_WATCHDOG

#define RPC_ID_WATCHDOG   99997

Definition at line 133 of file mrpc.h.

◆ RPC_JRPC

#define RPC_JRPC   18000

Definition at line 130 of file mrpc.h.

◆ RPC_LOG_REWIND

#define RPC_LOG_REWIND   14000

Definition at line 120 of file mrpc.h.

◆ RPC_MANUAL_TRIG

#define RPC_MANUAL_TRIG   17000

Definition at line 128 of file mrpc.h.

◆ RPC_RC_TRANSITION

#define RPC_RC_TRANSITION   12000

Definition at line 116 of file mrpc.h.

◆ RPC_TEST

#define RPC_TEST   15000

Definition at line 122 of file mrpc.h.

◆ RPC_TEST2

#define RPC_TEST2   15001

Definition at line 123 of file mrpc.h.

Function Documentation

◆ close()

void RPC_SERVER_ACCEPTION::close ( )

Definition at line 11551 of file midas.cxx.

11552{
11553 //printf("RPC_SERVER_ACCEPTION::close: connection from %s program %s mserver %d\n", host_name.c_str(), prog_name.c_str(), is_mserver);
11554
11555 if (is_mserver) {
11556 assert(_mserver_acception == this);
11558 is_mserver = false;
11559 }
11560
11561 /* close server connection */
11562 if (recv_sock)
11564 if (send_sock)
11566 if (event_sock)
11568
11569 /* free TCP cache */
11570 if (net_buffer) {
11571 //printf("free net_buffer %p+%d\n", net_buffer, net_buffer_size);
11572 free(net_buffer);
11573 net_buffer = NULL;
11574 net_buffer_size = 0;
11575 }
11576
11577 /* mark this entry as invalid */
11578 clear();
11579}
INT ss_socket_close(int *sockp)
Definition system.cxx:5231
static RPC_SERVER_ACCEPTION * _mserver_acception
Definition midas.cxx:11511
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cm_query_transition()

int cm_query_transition ( int transition,
int run_number,
int trans_time 
)

Definition at line 14128 of file midas.cxx.

14152{
14153 std::lock_guard<std::mutex> guard(_tr_fifo_mutex);
14154
14155 if (_tr_fifo_wp == _tr_fifo_rp)
14156 return FALSE;
14157
14158 if (transition)
14160
14161 if (run_number)
14163
14164 if (trans_time)
14165 *trans_time = (int) _tr_fifo[_tr_fifo_rp].trans_time;
14166
14167 _tr_fifo_rp = (_tr_fifo_rp + 1) % 10;
14168
14169 // implicit unlock
14170 return TRUE;
14171}
#define FALSE
Definition cfortran.h:309
INT transition(INT run_number, char *error)
Definition consume.cxx:35
static int _tr_fifo_rp
Definition midas.cxx:14062
static int _tr_fifo_wp
Definition midas.cxx:14061
static TR_FIFO _tr_fifo[10]
Definition midas.cxx:14060
static std::mutex _tr_fifo_mutex
Definition midas.cxx:14059
INT run_number[2]
Definition mana.cxx:246
#define TRUE
Definition midas.h:182
int transition
Definition midas.cxx:14053
int run_number
Definition midas.cxx:14054
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gAllowedHostsEnabled()

static std::atomic_bool gAllowedHostsEnabled ( false  )
static
Here is the caller graph for this function:

◆ handle_msg_odb()

static int handle_msg_odb ( int  n,
const NET_COMMAND nc 
)
static

Definition at line 11939 of file midas.cxx.

11939 {
11940 //printf("rpc_client_dispatch: MSG_ODB: packet size %d, expected %d\n", n, (int)(sizeof(NET_COMMAND_HEADER) + 4 * sizeof(INT)));
11941 if (n == sizeof(NET_COMMAND_HEADER) + 4 * sizeof(INT)) {
11942 /* update a changed record */
11943 HNDLE hDB = *((INT *) nc->param);
11944 HNDLE hKeyRoot = *((INT *) nc->param + 1);
11945 HNDLE hKey = *((INT *) nc->param + 2);
11946 int index = *((INT *) nc->param + 3);
11948 }
11949 return CM_VERSION_MISMATCH;
11950}
#define CM_VERSION_MISMATCH
Definition midas.h:587
INT db_update_record_local(INT hDB, INT hKeyRoot, INT hKey, int index)
Definition odb.cxx:13553
HNDLE hKey
DWORD n[4]
Definition mana.cxx:247
INT index
Definition mana.cxx:271
HNDLE hDB
main ODB handle
Definition mana.cxx:207
INT HNDLE
Definition midas.h:132
int INT
Definition midas.h:129
char param[32]
Definition msystem.h:287
Here is the call graph for this function:
Here is the caller graph for this function:

◆ recv_event_server_realloc()

static int recv_event_server_realloc ( INT  idx,
RPC_SERVER_ACCEPTION psa,
char **  pbuffer,
int pbuffer_size 
)
static

Definition at line 14395 of file midas.cxx.

14417{
14418 int sock = psa->event_sock;
14419
14420 //printf("recv_event_server: idx %d, buffer %p, buffer_size %d\n", idx, buffer, buffer_size);
14421
14422 const size_t header_size = (sizeof(EVENT_HEADER) + sizeof(INT));
14423
14424 char header_buf[header_size];
14425
14426 // First read the header.
14427 //
14428 // Data format is:
14429 // INT buffer handle (4 bytes)
14430 // EVENT_HEADER (16 bytes)
14431 // event data
14432 // ALIGN8() padding
14433 // ...next event
14434
14435 int hrd = recv_tcp2(sock, header_buf, header_size, 1);
14436
14437 if (hrd == 0) {
14438 // timeout waiting for data
14439 return 0;
14440 }
14441
14442 /* abort if connection broken */
14443 if (hrd < 0) {
14444 cm_msg(MERROR, "recv_event_server", "recv_tcp2(header) returned %d", hrd);
14445 return -1;
14446 }
14447
14448 if (hrd < (int) header_size) {
14449 int hrd1 = recv_tcp2(sock, header_buf + hrd, header_size - hrd, 0);
14450
14451 /* abort if connection broken */
14452 if (hrd1 <= 0) {
14453 cm_msg(MERROR, "recv_event_server", "recv_tcp2(more header) returned %d", hrd1);
14454 return -1;
14455 }
14456
14457 hrd += hrd1;
14458 }
14459
14460 /* abort if connection broken */
14461 if (hrd != (int) header_size) {
14462 cm_msg(MERROR, "recv_event_server", "recv_tcp2(header) returned %d instead of %d", hrd, (int) header_size);
14463 return -1;
14464 }
14465
14466 INT *pbh = (INT *) header_buf;
14467 EVENT_HEADER *pevent = (EVENT_HEADER *) (((INT *) header_buf) + 1);
14468
14469 /* convert header little endian/big endian */
14470 if (psa->convert_flags) {
14471 rpc_convert_single(&pbh, TID_INT32, 0, psa->convert_flags);
14472 rpc_convert_single(&pevent->event_id, TID_INT16, 0, psa->convert_flags);
14473 rpc_convert_single(&pevent->trigger_mask, TID_INT16, 0, psa->convert_flags);
14474 rpc_convert_single(&pevent->serial_number, TID_UINT32, 0, psa->convert_flags);
14475 rpc_convert_single(&pevent->time_stamp, TID_UINT32, 0, psa->convert_flags);
14476 rpc_convert_single(&pevent->data_size, TID_UINT32, 0, psa->convert_flags);
14477 }
14478
14479 int event_size = pevent->data_size + sizeof(EVENT_HEADER);
14480 int total_size = ALIGN8(event_size);
14481
14482 //printf("recv_event_server: buffer_handle %d, event_id 0x%04x, serial 0x%08x, data_size %d, event_size %d, total_size %d\n", *pbh, pevent->event_id, pevent->serial_number, pevent->data_size, event_size, total_size);
14483
14484 if (pevent->data_size == 0) {
14485 for (int i=0; i<5; i++) {
14486 printf("recv_event_server: header[%d]: 0x%08x\n", i, pbh[i]);
14487 }
14488 abort();
14489 }
14490
14491 /* check for sane event size */
14492 if (event_size <= 0 || total_size <= 0) {
14493 cm_msg(MERROR, "recv_event_server",
14494 "received event header with invalid data_size %d: event_size %d, total_size %d", pevent->data_size,
14495 event_size, total_size);
14496 return -1;
14497 }
14498
14499 //printf("recv_event_server: idx %d, bh %d, event header: id %d, mask %d, serial %d, data_size %d, event_size %d, total_size %d\n", idx, *pbh, pevent->event_id, pevent->trigger_mask, pevent->serial_number, pevent->data_size, event_size, total_size);
14500
14501
14502 int bufsize = sizeof(INT) + total_size;
14503
14504 // Second, check that output buffer is big enough
14505
14506 /* check if data part fits in buffer */
14507 if (*pbuffer_size < bufsize) {
14508 int newsize = 1024 + ALIGN8(bufsize);
14509
14510 //printf("recv_event_server: buffer realloc %d -> %d\n", *pbuffer_size, newsize);
14511
14512 char *newbuf = (char *) realloc(*pbuffer, newsize);
14513 if (newbuf == NULL) {
14514 cm_msg(MERROR, "recv_event_server", "cannot realloc() event buffer from %d to %d bytes", *pbuffer_size,
14515 newsize);
14516 return -1;
14517 }
14518 *pbuffer = newbuf;
14520 }
14521
14522 // Third, copy header into output buffer
14523
14525
14526 // Forth, read the event data
14527
14528 int to_read = sizeof(INT) + total_size - header_size;
14529 int rptr = header_size;
14530
14531 if (to_read > 0) {
14532 int drd = recv_tcp2(sock, (*pbuffer) + rptr, to_read, 0);
14533
14534 /* abort if connection broken */
14535 if (drd <= 0) {
14536 cm_msg(MERROR, "recv_event_server", "recv_tcp2(data) returned %d instead of %d", drd, to_read);
14537 return -1;
14538 }
14539 }
14540
14541 return bufsize;
14542}
#define TID_INT32
Definition midas.h:339
#define MERROR
Definition midas.h:559
#define TID_UINT32
Definition midas.h:337
#define TID_INT16
Definition midas.h:335
#define ALIGN8(x)
Definition midas.h:522
INT recv_tcp2(int sock, char *net_buffer, int buffer_size, int timeout_ms)
Definition system.cxx:5562
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:915
void rpc_convert_single(void *data, INT tid, INT flags, INT convert_flags)
Definition midas.cxx:11689
INT i
Definition mdump.cxx:32
int event_size
Definition msysmon.cxx:527
short int event_id
Definition midas.h:852
DWORD data_size
Definition midas.h:856
DWORD serial_number
Definition midas.h:854
DWORD time_stamp
Definition midas.h:855
short int trigger_mask
Definition midas.h:853
Here is the call graph for this function:
Here is the caller graph for this function:

◆ recv_net_command_realloc()

static int recv_net_command_realloc ( INT  idx,
char **  pbuf,
int pbufsize,
INT remaining 
)
static

Definition at line 14205 of file midas.cxx.

14233{
14234 char *buffer = NULL; // buffer is changed to point to *pbuf when we receive the NET_COMMAND header
14235
14237
14238 int sock = sa->recv_sock;
14239
14240 if (!sa->net_buffer) {
14241 if (sa->is_mserver)
14243 else
14245
14246 sa->net_buffer = (char *) malloc(sa->net_buffer_size);
14247 //printf("sa %p idx %d, net_buffer %p+%d\n", sa, idx, sa->net_buffer, sa->net_buffer_size);
14248 sa->write_ptr = 0;
14249 sa->read_ptr = 0;
14250 sa->misalign = 0;
14251 }
14252 if (!sa->net_buffer) {
14253 cm_msg(MERROR, "recv_net_command", "Cannot allocate %d bytes for network buffer", sa->net_buffer_size);
14254 return -1;
14255 }
14256
14257 int copied = 0;
14258 int param_size = -1;
14259
14260 int write_ptr = sa->write_ptr;
14261 int read_ptr = sa->read_ptr;
14262 int misalign = sa->misalign;
14263 char *net_buffer = sa->net_buffer;
14264
14265 do {
14266 if (write_ptr - read_ptr >= (INT) sizeof(NET_COMMAND_HEADER) - copied) {
14267 if (param_size == -1) {
14268 if (copied > 0) {
14269 /* assemble split header */
14270 memcpy(buffer + copied, net_buffer + read_ptr, (INT) sizeof(NET_COMMAND_HEADER) - copied);
14271 NET_COMMAND *nc = (NET_COMMAND *) (buffer);
14272 param_size = (INT) nc->header.param_size;
14273 } else {
14274 NET_COMMAND *nc = (NET_COMMAND *) (net_buffer + read_ptr);
14275 param_size = (INT) nc->header.param_size;
14276 }
14277
14278 if (sa->convert_flags)
14279 rpc_convert_single(&param_size, TID_UINT32, 0, sa->convert_flags);
14280 }
14281
14282 //printf("recv_net_command: param_size %d, NET_COMMAND_HEADER %d, buffer_size %d\n", param_size, (int)sizeof(NET_COMMAND_HEADER), *pbufsize);
14283
14284 /* check if parameters fit in buffer */
14285 if (*pbufsize < (param_size + (int) sizeof(NET_COMMAND_HEADER))) {
14286 int new_size = param_size + sizeof(NET_COMMAND_HEADER) + 1024;
14287 char *p = (char *) realloc(*pbuf, new_size);
14288 //printf("recv_net_command: reallocate buffer %d -> %d, %p\n", *pbufsize, new_size, p);
14289 if (p == NULL) {
14290 cm_msg(MERROR, "recv_net_command", "cannot reallocate buffer from %d bytes to %d bytes", *pbufsize, new_size);
14291 sa->read_ptr = 0;
14292 sa->write_ptr = 0;
14293 return -1;
14294 }
14295 *pbuf = p;
14296 *pbufsize = new_size;
14297 }
14298
14299 buffer = *pbuf;
14300
14301 /* check if we have all parameters in buffer */
14302 if (write_ptr - read_ptr >= param_size + (INT) sizeof(NET_COMMAND_HEADER) - copied)
14303 break;
14304 }
14305
14306 /* not enough data, so copy partially and get new */
14307 int size = write_ptr - read_ptr;
14308
14309 if (size > 0) {
14310 memcpy(buffer + copied, net_buffer + read_ptr, size);
14311 copied += size;
14312 read_ptr = write_ptr;
14313 }
14314#ifdef OS_UNIX
14315 do {
14316 write_ptr = recv(sock, net_buffer + misalign, sa->net_buffer_size - 8, 0);
14317
14318 /* don't return if an alarm signal was cought */
14319 } while (write_ptr == -1 && errno == EINTR);
14320#else
14321 write_ptr = recv(sock, net_buffer + misalign, sa->net_buffer_size - 8, 0);
14322#endif
14323
14324 /* abort if connection broken */
14325 if (write_ptr <= 0) {
14326 if (write_ptr == 0)
14327 cm_msg(MERROR, "recv_net_command", "rpc connection from \'%s\' on \'%s\' unexpectedly closed", sa->prog_name.c_str(), sa->host_name.c_str());
14328 else
14329 cm_msg(MERROR, "recv_net_command", "recv() returned %d, errno: %d (%s)", write_ptr, errno, strerror(errno));
14330
14331 if (remaining)
14332 *remaining = 0;
14333
14334 return write_ptr;
14335 }
14336
14337 read_ptr = misalign;
14338 write_ptr += misalign;
14339
14340 misalign = write_ptr % 8;
14341 } while (TRUE);
14342
14343 /* copy rest of parameters */
14344 int size = param_size + sizeof(NET_COMMAND_HEADER) - copied;
14345 memcpy(buffer + copied, net_buffer + read_ptr, size);
14346 read_ptr += size;
14347
14348 if (remaining) {
14349 /* don't keep rpc_server_receive in an infinite loop */
14350 if (write_ptr - read_ptr < param_size)
14351 *remaining = 0;
14352 else
14353 *remaining = write_ptr - read_ptr;
14354 }
14355
14356 sa->write_ptr = write_ptr;
14357 sa->read_ptr = read_ptr;
14358 sa->misalign = misalign;
14359
14360 return size + copied;
14361}
#define NET_BUFFER_SIZE
Definition msystem.h:114
static RPC_SERVER_ACCEPTION * rpc_get_server_acception(int idx)
Definition midas.cxx:11513
#define NET_TCP_SIZE
Definition midas.h:266
NET_COMMAND_HEADER header
Definition msystem.h:286
Here is the call graph for this function:
Here is the caller graph for this function:

◆ recv_tcp_check()

INT recv_tcp_check ( int  sock)

Definition at line 14365 of file midas.cxx.

14383{
14384 /* figure out to which connection socket belongs */
14385 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++)
14386 if (_server_acceptions[idx] && _server_acceptions[idx]->recv_sock == sock) {
14387 return _server_acceptions[idx]->write_ptr - _server_acceptions[idx]->read_ptr;
14388 }
14389
14390 return 0;
14391}
static std::vector< RPC_SERVER_ACCEPTION * > _server_acceptions
Definition midas.cxx:11510
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_add_allowed_host()

INT rpc_add_allowed_host ( const char hostname)

Definition at line 15243 of file midas.cxx.

15260{
15261 //cm_msg(MINFO, "rpc_add_allowed_host", "Adding allowed host \'%s\'", hostname);
15262
15263 gAllowedHostsMutex.lock();
15264 gAllowedHosts.push_back(hostname);
15265 gAllowedHostsEnabled = true;
15266 gAllowedHostsMutex.unlock();
15267
15268 return RPC_SUCCESS;
15269}
#define RPC_SUCCESS
Definition midas.h:698
static std::atomic_bool gAllowedHostsEnabled(false)
static std::mutex gAllowedHostsMutex
Definition midas.cxx:15215
static std::vector< std::string > gAllowedHosts
Definition midas.cxx:15214
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_calc_convert_flags()

void rpc_calc_convert_flags ( INT  hw_type,
INT  remote_hw_type,
INT convert_flags 
)
  • ASCII format *‍/

Definition at line 11591 of file midas.cxx.

11591 {
11592 *convert_flags = 0;
11593
11594 /* big/little endian conversion */
11595 if (((remote_hw_type & DRI_BIG_ENDIAN) &&
11596 (hw_type & DRI_LITTLE_ENDIAN)) || ((remote_hw_type & DRI_LITTLE_ENDIAN)
11597 && (hw_type & DRI_BIG_ENDIAN)))
11598 *convert_flags |= CF_ENDIAN;
11599
11600 /* float conversion between IEEE and VAX G */
11601 if ((remote_hw_type & DRF_G_FLOAT) && (hw_type & DRF_IEEE))
11602 *convert_flags |= CF_VAX2IEEE;
11603
11604 /* float conversion between VAX G and IEEE */
11605 if ((remote_hw_type & DRF_IEEE) && (hw_type & DRF_G_FLOAT))
11606 *convert_flags |= CF_IEEE2VAX;
11607
11609 //if (remote_hw_type & DR_ASCII)
11610 // *convert_flags |= CF_ASCII;
11611}
#define DRI_LITTLE_ENDIAN
Definition msystem.h:48
#define DRF_G_FLOAT
Definition msystem.h:51
#define DRI_BIG_ENDIAN
Definition msystem.h:49
#define DRF_IEEE
Definition msystem.h:50
#define CF_ENDIAN
Definition midas.h:1609
#define CF_IEEE2VAX
Definition midas.h:1610
#define CF_VAX2IEEE
Definition midas.h:1611
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_call()

INT rpc_call ( DWORD  routine_id,
  ... 
)

Definition at line 13671 of file midas.cxx.

13695{
13696 va_list ap;
13697 INT i, status;
13698
13699 BOOL rpc_no_reply = routine_id & RPC_NO_REPLY;
13700 routine_id &= ~RPC_NO_REPLY;
13701
13702 //if (rpc_no_reply)
13703 // printf("rpc_call: routine_id %d, RPC_NO_REPLY\n", routine_id);
13704
13705 int send_sock = _server_connection.send_sock;
13706 int rpc_timeout = _server_connection.rpc_timeout;
13707
13708 if (!send_sock) {
13709 fprintf(stderr, "rpc_call(routine_id=%d) failed, no connection to mserver.\n", routine_id);
13710 return RPC_NET_ERROR;
13711 }
13712
13713 if (!_mutex_rpc) {
13714 /* create a local mutex for multi-threaded applications */
13716 }
13717
13718 status = ss_mutex_wait_for(_mutex_rpc, 10000 + rpc_timeout);
13719 if (status != SS_SUCCESS) {
13720 cm_msg(MERROR, "rpc_call", "Mutex timeout");
13721 return RPC_MUTEX_TIMEOUT;
13722 }
13723
13724 /* find rpc definition */
13725
13726 int idx = -1;
13727 const char* rpc_name = NULL;
13729
13730 rpc_list_mutex.lock();
13731
13732 for (size_t i = 0; i < rpc_list.size(); i++) {
13733 if (rpc_list[i].id == (int) routine_id) {
13734 idx = i;
13737 break;
13738 }
13739 }
13740
13741 rpc_list_mutex.unlock();
13742
13743 if (idx < 0) {
13745 cm_msg(MERROR, "rpc_call", "invalid rpc ID (%d)", routine_id);
13746 return RPC_INVALID_ID;
13747 }
13748
13749 /* prepare output buffer */
13750
13751 NET_COMMAND* nc = NULL;
13752
13753 /* examine variable argument list and convert it to parameter array */
13754 va_start(ap, routine_id);
13755
13757
13758 va_end(ap);
13759
13760 nc->header.routine_id = routine_id;
13761
13762 if (rpc_no_reply)
13764
13765 int send_size = nc->header.param_size + sizeof(NET_COMMAND_HEADER);
13766
13767 /* do not wait for reply if requested RPC_NO_REPLY */
13768 if (rpc_no_reply) {
13769 i = send_tcp(send_sock, (char *) nc, send_size, 0);
13770
13771 if (i != send_size) {
13773 cm_msg(MERROR, "rpc_call", "rpc \"%s\" error: send_tcp() failed", rpc_name);
13774 free(nc);
13775 return RPC_NET_ERROR;
13776 }
13777
13779 free(nc);
13780 return RPC_SUCCESS;
13781 }
13782
13783 /* in TCP mode, send and wait for reply on send socket */
13784 i = send_tcp(send_sock, (char *) nc, send_size, 0);
13785 if (i != send_size) {
13787 cm_msg(MERROR, "rpc_call", "rpc \"%s\" error: send_tcp() failed", rpc_name);
13788 free(nc);
13789 return RPC_NET_ERROR;
13790 }
13791
13792 free(nc);
13793 nc = NULL;
13794
13795 bool restore_watchdog_timeout = false;
13797 DWORD watchdog_timeout;
13798 cm_get_watchdog_params(&watchdog_call, &watchdog_timeout);
13799
13800 //printf("watchdog timeout: %d, rpc_timeout: %d\n", watchdog_timeout, rpc_timeout);
13801
13802 if (!rpc_is_remote()) {
13803 // if RPC is remote, we are connected to an mserver,
13804 // the mserver takes care of watchdog timeouts.
13805 // otherwise we should make sure the watchdog timeout
13806 // is longer than the RPC timeout. K.O.
13807 if (rpc_timeout >= (int) watchdog_timeout) {
13809 cm_set_watchdog_params_local(watchdog_call, rpc_timeout + 1000);
13810 }
13811 }
13812
13813 DWORD rpc_status = 0;
13814 DWORD buf_size = 0;
13815 char* buf = NULL;
13816
13817 status = ss_recv_net_command(send_sock, &rpc_status, &buf_size, &buf, rpc_timeout);
13818
13821 }
13822
13823 /* drop the mutex, we are done with the socket, argument unpacking is done from our own buffer */
13824
13826
13827 /* check for reply errors */
13828
13829 if (status == SS_TIMEOUT) {
13830 cm_msg(MERROR, "rpc_call", "routine \"%s\": timeout waiting for reply, program abort", rpc_name);
13831 if (buf)
13832 free(buf);
13833 abort(); // cannot continue - our mserver is not talking to us!
13834 return RPC_TIMEOUT;
13835 }
13836
13837 if (status != SS_SUCCESS) {
13838 cm_msg(MERROR, "rpc_call", "routine \"%s\": error, ss_recv_net_command() status %d, program abort", rpc_name, status);
13839 if (buf)
13840 free(buf);
13841 abort(); // cannot continue - something is wrong with our mserver connection
13842 return RPC_NET_ERROR;
13843 }
13844
13845 if (rpc_status == RPC_INVALID_ID) {
13846 cm_msg(MERROR, "rpc_call", "routine \"%s\": error, unknown RPC, status %d", rpc_name, rpc_status);
13847 if (buf)
13848 free(buf);
13849 return rpc_status;
13850 }
13851
13852 /* extract result variables and place it to argument list */
13853
13854 va_start(ap, routine_id);
13855
13856 status = rpc_call_decode(ap, rpc_entry, buf, buf_size);
13857
13858 if (status != RPC_SUCCESS) {
13860 }
13861
13862 va_end(ap);
13863
13864 if (buf)
13865 free(buf);
13866
13867 return rpc_status;
13868}
INT cm_get_watchdog_params(BOOL *call_watchdog, DWORD *timeout)
Definition midas.cxx:3325
INT cm_set_watchdog_params_local(BOOL call_watchdog, DWORD timeout)
Definition midas.cxx:3244
#define SS_SUCCESS
Definition midas.h:663
#define SS_TIMEOUT
Definition midas.h:674
#define RPC_INVALID_ID
Definition midas.h:706
#define RPC_MUTEX_TIMEOUT
Definition midas.h:710
#define RPC_TIMEOUT
Definition midas.h:702
#define RPC_NET_ERROR
Definition midas.h:701
unsigned int DWORD
Definition mcstd.h:51
#define RPC_NO_REPLY
Definition midas.h:396
INT ss_mutex_release(MUTEX_T *mutex)
Definition system.cxx:3157
INT ss_mutex_create(MUTEX_T **mutex, BOOL recursive)
Definition system.cxx:2941
INT ss_recv_net_command(int sock, DWORD *routine_id, DWORD *param_size, char **param_ptr, int timeout_ms)
Definition system.cxx:5635
INT send_tcp(int sock, char *buffer, DWORD buffer_size, INT flags)
Definition system.cxx:5285
INT ss_mutex_wait_for(MUTEX_T *mutex, INT timeout)
Definition system.cxx:3037
bool rpc_is_remote(void)
Definition midas.cxx:12769
static std::vector< RPC_LIST > rpc_list
Definition midas.cxx:11581
static void rpc_call_encode(va_list &ap, const RPC_LIST &rl, NET_COMMAND **nc)
Definition midas.cxx:13239
static std::mutex rpc_list_mutex
Definition midas.cxx:11582
static int rpc_call_decode(va_list &ap, const RPC_LIST &rl, const char *buf, size_t buf_size)
Definition midas.cxx:13410
static RPC_SERVER_CONNECTION _server_connection
Definition midas.cxx:11506
static MUTEX_T * _mutex_rpc
Definition midas.cxx:227
DWORD BOOL
Definition midas.h:105
DWORD status
Definition odbhist.cxx:39
const char * name
Definition midas.h:1597
Here is the call graph for this function:

◆ rpc_call_decode()

static int rpc_call_decode ( va_list ap,
const RPC_LIST rl,
const char buf,
size_t  buf_size 
)
static

Definition at line 13410 of file midas.cxx.

13411{
13412 bool debug = false;
13413
13414 if (debug)
13415 printf("decode reply to rpc_id %d \"%s\" has %d bytes\n", rl.id, rl.name, (int)buf_size);
13416
13417 /* extract result variables and place it to argument list */
13418
13419 const char* param_ptr = buf;
13420
13421 for (int i = 0; rl.param[i].tid != 0; i++) {
13422 int tid = rl.param[i].tid;
13423 int flags = rl.param[i].flags;
13424 int arg_type = 0;
13425
13426 bool bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
13427 (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
13428 tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
13429
13430 if (bpointer)
13432 else
13433 arg_type = rl.param[i].tid;
13434
13435 if (tid == TID_FLOAT && !bpointer)
13437
13438 char arg[8];
13439 rpc_va_arg(&ap, arg_type, arg);
13440
13441 if (rl.param[i].flags & RPC_OUT) {
13442
13443 if (param_ptr == NULL) {
13444 cm_msg(MERROR, "rpc_call_decode", "routine \"%s\": no data in RPC reply, needed to decode an RPC_OUT parameter. param_ptr is NULL", rl.name);
13445 return RPC_NET_ERROR;
13446 }
13447
13448 tid = rl.param[i].tid;
13449 int arg_size = rpc_tid_size(tid);
13450
13451 if (tid == TID_STRING || tid == TID_LINK)
13452 arg_size = strlen((char *) (param_ptr)) + 1;
13453
13454 if (flags & RPC_VARARRAY) {
13455 arg_size = *((INT *) param_ptr);
13456 param_ptr += ALIGN8(sizeof(INT));
13457 }
13458
13459 if (tid == TID_STRUCT || (flags & RPC_FIXARRAY))
13460 arg_size = rl.param[i].n;
13461
13462 /* parameter size is always aligned */
13463 int param_size = ALIGN8(arg_size);
13464
13465 /* return parameters are always pointers */
13466 if (*((char **) arg)) {
13467 if (debug)
13468 printf("decode param %d, flags 0x%x, tid %d, arg_type %d, arg_size %d, param_size %d, memcpy %d\n", i, flags, tid, arg_type, arg_size, param_size, arg_size);
13469 memcpy((void *) *((char **) arg), param_ptr, arg_size);
13470 }
13471
13472 param_ptr += param_size;
13473 }
13474 }
13475
13476 return RPC_SUCCESS;
13477}
#define TID_DOUBLE
Definition midas.h:343
#define TID_STRUCT
Definition midas.h:348
#define TID_LINK
Definition midas.h:350
#define TID_STRING
Definition midas.h:346
#define TID_ARRAY
Definition midas.h:347
#define TID_FLOAT
Definition midas.h:341
void rpc_va_arg(va_list *arg_ptr, INT arg_type, void *arg)
Definition midas.cxx:13201
INT rpc_tid_size(INT id)
Definition midas.cxx:11765
BOOL debug
debug printouts
Definition mana.cxx:254
#define RPC_OUT
Definition midas.h:1579
#define RPC_POINTER
Definition midas.h:1580
#define RPC_VARARRAY
Definition midas.h:1582
#define RPC_FIXARRAY
Definition midas.h:1581
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_call_encode()

static void rpc_call_encode ( va_list ap,
const RPC_LIST rl,
NET_COMMAND **  nc 
)
static

Definition at line 13239 of file midas.cxx.

13240{
13241 bool debug = false;
13242
13243 if (debug) {
13244 printf("encode rpc_id %d \"%s\"\n", rl.id, rl.name);
13245 for (int i=0; rl.param[i].tid != 0; i++) {
13246 int tid = rl.param[i].tid;
13247 int flags = rl.param[i].flags;
13248 int n = rl.param[i].n;
13249 printf("i=%d, tid %d, flags 0x%x, n %d\n", i, tid, flags, n);
13250 }
13251 }
13252
13253 char args[MAX_RPC_PARAMS][8];
13254
13255 for (int i=0; rl.param[i].tid != 0; i++) {
13256 int tid = rl.param[i].tid;
13257 int flags = rl.param[i].flags;
13258 int arg_type = 0;
13259
13260 bool bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
13261 (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
13262 tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
13263
13264 if (bpointer)
13266 else
13267 arg_type = tid;
13268
13269 /* floats are passed as doubles, at least under NT */
13270 if (tid == TID_FLOAT && !bpointer)
13272
13273 //printf("arg %d, tid %d, flags 0x%x, arg_type %d, bpointer %d\n", i, tid, flags, arg_type, bpointer);
13274
13276 }
13277
13278 size_t buf_size = sizeof(NET_COMMAND) + 4 * 1024;
13279 char* buf = (char *)malloc(buf_size);
13280 assert(buf);
13281
13282 (*nc) = (NET_COMMAND*) buf;
13283
13284 /* find out if we are on a big endian system */
13285 bool bbig = ((rpc_get_hw_type() & DRI_BIG_ENDIAN) > 0);
13286
13287 char* param_ptr = (*nc)->param;
13288
13289 for (int i=0; rl.param[i].tid != 0; i++) {
13290 int tid = rl.param[i].tid;
13291 int flags = rl.param[i].flags;
13292 int arg_type = 0;
13293
13294 bool bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
13295 (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
13296 tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
13297
13298 if (bpointer)
13300 else
13301 arg_type = tid;
13302
13303 /* floats are passed as doubles, at least under NT */
13304 if (tid == TID_FLOAT && !bpointer)
13306
13307 /* get pointer to argument */
13308 //char arg[8];
13309 //rpc_va_arg(&ap, arg_type, arg);
13310
13311 char* arg = args[i];
13312
13313 /* shift 1- and 2-byte parameters to the LSB on big endian systems */
13314 if (bbig) {
13315 if (tid == TID_UINT8 || tid == TID_CHAR || tid == TID_INT8) {
13316 arg[0] = arg[3];
13317 }
13318 if (tid == TID_UINT16 || tid == TID_INT16) {
13319 arg[0] = arg[2];
13320 arg[1] = arg[3];
13321 }
13322 }
13323
13324 if (flags & RPC_IN) {
13325 int arg_size = 0;
13326
13327 if (bpointer)
13328 arg_size = rpc_tid_size(tid);
13329 else
13331
13332 /* for strings, the argument size depends on the string length */
13333 if (tid == TID_STRING || tid == TID_LINK) {
13334 arg_size = 1 + strlen((char *) *((char **) arg));
13335 }
13336
13337 /* for varibale length arrays, the size is given by
13338 the next parameter on the stack */
13339 if (flags & RPC_VARARRAY) {
13340 //va_list aptmp;
13342 //va_copy(aptmp, ap);
13343
13344 //char arg_tmp[8];
13345 //rpc_va_arg(&aptmp, TID_ARRAY, arg_tmp);
13346
13347 const char* arg_tmp = args[i+1];
13348
13349 /* for (RPC_IN+RPC_OUT) parameters, size argument is a pointer */
13350 if (flags & RPC_OUT)
13351 arg_size = *((INT *) *((void **) arg_tmp));
13352 else
13353 arg_size = *((INT *) arg_tmp);
13354
13355 *((INT *) param_ptr) = ALIGN8(arg_size);
13356 param_ptr += ALIGN8(sizeof(INT));
13357
13358 //va_end(aptmp);
13359 }
13360
13361 if (tid == TID_STRUCT || (flags & RPC_FIXARRAY))
13362 arg_size = rl.param[i].n;
13363
13364 /* always align parameter size */
13365 int param_size = ALIGN8(arg_size);
13366
13367 {
13368 size_t param_offset = (char *) param_ptr - (char *)(*nc);
13369
13370 if (param_offset + param_size + 16 > buf_size) {
13371 size_t new_size = param_offset + param_size + 1024;
13372 //printf("resize nc %zu to %zu\n", buf_size, new_size);
13373 buf = (char *) realloc(buf, new_size);
13374 assert(buf);
13375 buf_size = new_size;
13376 (*nc) = (NET_COMMAND*) buf;
13377 param_ptr = buf + param_offset;
13378 }
13379 }
13380
13381 if (bpointer) {
13382 if (debug) {
13383 printf("encode param %d, flags 0x%x, tid %d, arg_type %d, arg_size %d, param_size %d, memcpy pointer %d\n", i, flags, tid, arg_type, arg_size, param_size, arg_size);
13384 }
13385 memcpy(param_ptr, (void *) *((void **) arg), arg_size);
13386 } else if (tid == TID_FLOAT) {
13387 if (debug) {
13388 printf("encode param %d, flags 0x%x, tid %d, arg_type %d, arg_size %d, param_size %d, double->float\n", i, flags, tid, arg_type, arg_size, param_size);
13389 }
13390 /* floats are passed as doubles on most systems */
13391 *((float *) param_ptr) = (float) *((double *) arg);
13392 } else {
13393 if (debug) {
13394 printf("encode param %d, flags 0x%x, tid %d, arg_type %d, arg_size %d, param_size %d, memcpy %d\n", i, flags, tid, arg_type, arg_size, param_size, arg_size);
13395 }
13396 memcpy(param_ptr, arg, arg_size);
13397 }
13398
13399 param_ptr += param_size;
13400 }
13401 }
13402
13403 (*nc)->header.param_size = (POINTER_T) param_ptr - (POINTER_T) (*nc)->param;
13404
13405 if (debug)
13406 printf("encode rpc_id %d \"%s\" buf_size %d, param_size %d\n", rl.id, rl.name, (int)buf_size, (*nc)->header.param_size);
13407}
#define TID_UINT8
Definition midas.h:328
#define TID_INT8
Definition midas.h:330
#define TID_CHAR
Definition midas.h:331
#define TID_UINT16
Definition midas.h:333
INT rpc_get_hw_type()
Definition midas.cxx:12842
#define RPC_IN
Definition midas.h:1578
#define MAX_RPC_PARAMS
Definition midas.h:1593
#define POINTER_T
Definition midas.h:166
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_check_allowed_host()

INT rpc_check_allowed_host ( const char hostname)

Definition at line 15272 of file midas.cxx.

15283{
15284 //printf("rpc_check_allowed_host: enabled %d, hostname [%s]\n", gAllowedHostsEnabled.load(), hostname);
15285
15287 return RPC_SUCCESS;
15288
15289 if (strcmp(hostname, "localhost") == 0)
15290 return RPC_SUCCESS;
15291
15292 if (strcmp(hostname, "localhost.localdomain") == 0)
15293 return RPC_SUCCESS;
15294
15295 if (strcmp(hostname, "localhost6") == 0) // RedHat el6, el7
15296 return RPC_SUCCESS;
15297
15298 if (strcmp(hostname, "ip6-localhost") == 0) // Ubuntu-22
15299 return RPC_SUCCESS;
15300
15302
15303 gAllowedHostsMutex.lock();
15304
15305 for (const auto& h: gAllowedHosts) {
15306 if (h == hostname) {
15308 break;
15309 }
15310 }
15311
15312 gAllowedHostsMutex.unlock();
15313
15314 //if (status != RPC_SUCCESS)
15315 // printf("rpc_check_allowed_host: enabled %d, hostname [%s] not found\n", gAllowedHostsEnabled.load(), hostname);
15316
15317 return status;
15318}
#define RPC_NOT_REGISTERED
Definition midas.h:704
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_check_channels()

INT rpc_check_channels ( void  )

Definition at line 16262 of file midas.cxx.

16280{
16281 INT status;
16282 NET_COMMAND nc;
16284 struct timeval timeout;
16285
16286 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
16287 if (_server_acceptions[idx] && _server_acceptions[idx]->recv_sock) {
16289 if (sa == NULL)
16290 continue;
16291
16292 if (sa->watchdog_timeout == 0) {
16293 continue;
16294 }
16295
16297 //printf("rpc_check_channels: idx %d, watchdog_timeout %d, last_activity %d, elapsed %d\n", idx, sa->watchdog_timeout, sa->last_activity, elapsed);
16298
16299 if (sa->watchdog_timeout && (elapsed > (DWORD)sa->watchdog_timeout)) {
16300
16301 //printf("rpc_check_channels: send watchdog message to %s on %s\n", sa->prog_name.c_str(), sa->host_name.c_str());
16302
16303 /* send a watchdog message */
16305 nc.header.param_size = 0;
16306
16307 int convert_flags = sa->convert_flags;
16308 if (convert_flags) {
16311 }
16312
16313 /* send the header to the client */
16314 int i = send_tcp(sa->send_sock, (char *) &nc, sizeof(NET_COMMAND_HEADER), 0);
16315
16316 if (i < 0) {
16317 cm_msg(MINFO, "rpc_check_channels", "client \"%s\" on host \"%s\" failed watchdog test after %d sec, send_tcp() returned %d",
16318 sa->prog_name.c_str(),
16319 sa->host_name.c_str(),
16320 sa->watchdog_timeout / 1000,
16321 i);
16322
16323 /* disconnect from experiment */
16324 if (rpc_is_mserver()) {
16326 return RPC_NET_ERROR;
16327 }
16328
16329 sa->close();
16330 return RPC_NET_ERROR;
16331 }
16332
16333 /* make some timeout checking */
16334 FD_ZERO(&readfds);
16335 FD_SET(sa->send_sock, &readfds);
16336 FD_SET(sa->recv_sock, &readfds);
16337
16338 timeout.tv_sec = sa->watchdog_timeout / 1000;
16339 timeout.tv_usec = (sa->watchdog_timeout % 1000) * 1000;
16340
16341 do {
16342 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
16343
16344 /* if an alarm signal was cought, restart select with reduced timeout */
16345 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
16346 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
16347
16348 } while (status == -1); /* dont return if an alarm signal was cought */
16349
16350 if (!FD_ISSET(sa->send_sock, &readfds) &&
16351 !FD_ISSET(sa->recv_sock, &readfds)) {
16352
16353 cm_msg(MINFO, "rpc_check_channels", "client \"%s\" on host \"%s\" failed watchdog test after %d sec",
16354 sa->prog_name.c_str(),
16355 sa->host_name.c_str(),
16356 sa->watchdog_timeout / 1000);
16357
16358 /* disconnect from experiment */
16359 if (rpc_is_mserver()) {
16361 return RPC_NET_ERROR;
16362 }
16363
16364 sa->close();
16365 return RPC_NET_ERROR;
16366 }
16367
16368 /* receive result on send socket */
16369 if (FD_ISSET(sa->send_sock, &readfds)) {
16370 i = recv_tcp(sa->send_sock, (char *) &nc, sizeof(nc), 0);
16371 if (i <= 0) {
16372 cm_msg(MINFO, "rpc_check_channels", "client \"%s\" on host \"%s\" failed watchdog test after %d sec, recv_tcp() returned %d",
16373 sa->prog_name.c_str(),
16374 sa->host_name.c_str(),
16375 sa->watchdog_timeout / 1000,
16376 i);
16377
16378 /* disconnect from experiment */
16379 if (rpc_is_mserver()) {
16381 return RPC_NET_ERROR;
16382 }
16383
16384 sa->close();
16385 return RPC_NET_ERROR;
16386 }
16387 }
16388 }
16389 }
16390 }
16391
16392 return RPC_SUCCESS;
16393}
INT cm_disconnect_experiment(void)
Definition midas.cxx:2846
#define MINFO
Definition midas.h:560
#define FD_SETSIZE
Definition msystem.h:199
#define MSG_WATCHDOG
Definition msystem.h:300
DWORD ss_millitime()
Definition system.cxx:3393
INT recv_tcp(int sock, char *net_buffer, DWORD buffer_size, INT flags)
Definition system.cxx:5454
bool rpc_is_mserver(void)
Definition midas.cxx:12826
#define RPC_OUTGOING
Definition midas.h:1583
#define WATCHDOG_INTERVAL
Definition midas.h:288
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_clear_allowed_hosts()

INT rpc_clear_allowed_hosts ( void  )

Definition at line 15218 of file midas.cxx.

15234{
15235 gAllowedHostsMutex.lock();
15236 gAllowedHosts.clear();
15237 gAllowedHostsEnabled = false;
15238 gAllowedHostsMutex.unlock();
15239 return RPC_SUCCESS;
15240}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_client_accept()

INT rpc_client_accept ( int  lsock)

Definition at line 15606 of file midas.cxx.

15627{
15628 INT i, status;
15630 std::string client_program;
15631 std::string host_name;
15632 INT convert_flags;
15633 char net_buffer[256], *p;
15634
15635 int sock = accept(lsock, NULL, NULL);
15636
15637 if (sock == -1)
15638 return RPC_NET_ERROR;
15639
15640 /* check access control list */
15643
15644 if (status != RPC_SUCCESS) {
15645 ss_socket_close(&sock);
15646 return RPC_NET_ERROR;
15647 }
15648 }
15649
15650 host_name = "(unknown)";
15651 client_program = "(unknown)";
15652
15653 /* receive string with timeout */
15654 i = recv_string(sock, net_buffer, sizeof(net_buffer), 10000);
15655 if (i <= 0) {
15656 ss_socket_close(&sock);
15657 return RPC_NET_ERROR;
15658 }
15659
15660 /* get remote computer info */
15661 p = strtok(net_buffer, " ");
15662 if (p != NULL) {
15663 client_hw_type = atoi(p);
15664 p = strtok(NULL, " ");
15665 }
15666 if (p != NULL) {
15667 //version = atoi(p);
15668 p = strtok(NULL, " ");
15669 }
15670 if (p != NULL) {
15671 client_program = p;
15672 p = strtok(NULL, " ");
15673 }
15674 if (p != NULL) {
15675 host_name = p;
15676 p = strtok(NULL, " ");
15677 }
15678
15679 //printf("rpc_client_accept: client_hw_type %d, version %d, client_name \'%s\', hostname \'%s\'\n", client_hw_type, version, client_program, host_name);
15680
15682
15683 /* save information in _server_acception structure */
15684 sa->recv_sock = sock;
15685 sa->send_sock = 0;
15686 sa->event_sock = 0;
15688 sa->host_name = host_name;
15691 sa->watchdog_timeout = 0;
15692 sa->is_mserver = FALSE;
15693
15694 /* send my own computer id */
15696 std::string str = msprintf("%d %s", hw_type, cm_get_version());
15697 status = send(sock, str.c_str(), str.length() + 1, 0);
15698 if (status != (INT) str.length() + 1)
15699 return RPC_NET_ERROR;
15700
15702 sa->convert_flags = convert_flags;
15703
15705
15706 return RPC_SUCCESS;
15707}
const char * cm_get_version()
Definition midas.cxx:1476
INT ss_suspend_set_server_acceptions(RPC_SERVER_ACCEPTION_LIST *acceptions)
Definition system.cxx:4298
INT recv_string(int sock, char *buffer, DWORD buffer_size, INT millisec)
Definition system.cxx:5399
void rpc_calc_convert_flags(INT hw_type, INT remote_hw_type, INT *convert_flags)
Definition midas.cxx:11591
static RPC_SERVER_ACCEPTION * rpc_new_server_acception()
Definition midas.cxx:11526
static INT rpc_socket_check_allowed_host(int sock)
Definition midas.cxx:15321
char host_name[HOST_NAME_LENGTH]
Definition mana.cxx:242
std::string msprintf(const char *format,...)
Definition midas.cxx:410
char str[256]
Definition odbhist.cxx:33
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_client_call()

INT rpc_client_call ( HNDLE  hConn,
DWORD  routine_id,
  ... 
)

Definition at line 13480 of file midas.cxx.

13505{
13507
13508 if (!c) {
13509 cm_msg(MERROR, "rpc_client_call", "invalid rpc connection handle %d", hConn);
13510 return RPC_NO_CONNECTION;
13511 }
13512
13513 //printf("rpc_client_call: handle %d, connection: ", hConn);
13514 //c->print();
13515 //printf("\n");
13516
13517 INT i, status;
13518
13519 BOOL rpc_no_reply = routine_id & RPC_NO_REPLY;
13520 routine_id &= ~RPC_NO_REPLY;
13521
13522 //if (rpc_no_reply)
13523 // printf("rpc_client_call: routine_id %d, RPC_NO_REPLY\n", routine_id);
13524
13525 // make local copy of the client name just in case _client_connection is erased by another thread
13526
13527 /* find rpc_index */
13528
13529 int rpc_index = -1;
13530 const char *rpc_name = NULL;
13532
13533 rpc_list_mutex.lock();
13534 for (size_t i = 0; i < rpc_list.size(); i++) {
13535 if (rpc_list[i].id == (int) routine_id) {
13536 rpc_index = i;
13539 break;
13540 }
13541 }
13542 rpc_list_mutex.unlock();
13543
13544 if (rpc_index < 0) {
13545 cm_msg(MERROR, "rpc_client_call", "call to \"%s\" on \"%s\" with invalid RPC ID %d", c->client_name.c_str(), c->host_name.c_str(), routine_id);
13546 c->mutex.unlock();
13547 return RPC_INVALID_ID;
13548 }
13549
13550 NET_COMMAND *nc = NULL;
13551
13552 /* examine variable argument list and convert it to parameter array */
13553 va_list ap;
13554 va_start(ap, routine_id);
13555
13557
13558 va_end(ap);
13559
13560 nc->header.routine_id = routine_id;
13561
13562 if (rpc_no_reply)
13564
13565 int send_size = nc->header.param_size + sizeof(NET_COMMAND_HEADER);
13566
13567 /* in FAST TCP mode, only send call and return immediately */
13568 if (rpc_no_reply) {
13569 i = send_tcp(c->send_sock, (char *) nc, send_size, 0);
13570
13571 if (i != send_size) {
13572 cm_msg(MERROR, "rpc_client_call", "call to \"%s\" on \"%s\" RPC \"%s\": send_tcp() failed", c->client_name.c_str(), c->host_name.c_str(), rpc_name);
13573 free(nc);
13574 c->mutex.unlock();
13575 return RPC_NET_ERROR;
13576 }
13577
13578 free(nc);
13579
13580 if (routine_id == RPC_ID_EXIT || routine_id == RPC_ID_SHUTDOWN) {
13581 //printf("rpc_client_call: routine_id %d is RPC_ID_EXIT %d or RPC_ID_SHUTDOWN %d, closing connection: ", routine_id, RPC_ID_EXIT, RPC_ID_SHUTDOWN);
13582 //c->print();
13583 //printf("\n");
13584 c->close_locked();
13585 }
13586
13587 c->mutex.unlock();
13588 return RPC_SUCCESS;
13589 }
13590
13591 /* in TCP mode, send and wait for reply on send socket */
13592 i = send_tcp(c->send_sock, (char *) nc, send_size, 0);
13593 if (i != send_size) {
13594 cm_msg(MERROR, "rpc_client_call", "call to \"%s\" on \"%s\" RPC \"%s\": send_tcp() failed", c->client_name.c_str(), c->host_name.c_str(), rpc_name);
13595 c->mutex.unlock();
13596 return RPC_NET_ERROR;
13597 }
13598
13599 free(nc);
13600 nc = NULL;
13601
13602 bool restore_watchdog_timeout = false;
13604 DWORD watchdog_timeout;
13605 cm_get_watchdog_params(&watchdog_call, &watchdog_timeout);
13606
13607 //printf("watchdog timeout: %d, rpc_timeout: %d\n", watchdog_timeout, c->rpc_timeout);
13608
13609 if (c->rpc_timeout >= (int) watchdog_timeout) {
13611 cm_set_watchdog_params(watchdog_call, c->rpc_timeout + 1000);
13612 }
13613
13614 DWORD rpc_status = 0;
13615 DWORD buf_size = 0;
13616 char* buf = NULL;
13617
13618 /* receive result on send socket */
13619 status = ss_recv_net_command(c->send_sock, &rpc_status, &buf_size, &buf, c->rpc_timeout);
13620
13622 cm_set_watchdog_params(watchdog_call, watchdog_timeout);
13623 }
13624
13625 if (status == SS_TIMEOUT) {
13626 cm_msg(MERROR, "rpc_client_call", "call to \"%s\" on \"%s\" RPC \"%s\": timeout waiting for reply", c->client_name.c_str(), c->host_name.c_str(), rpc_name);
13627 if (buf)
13628 free(buf);
13629 c->mutex.unlock();
13630 return RPC_TIMEOUT;
13631 }
13632
13633 if (status != SS_SUCCESS) {
13634 cm_msg(MERROR, "rpc_client_call", "call to \"%s\" on \"%s\" RPC \"%s\": error, ss_recv_net_command() status %d", c->client_name.c_str(), c->host_name.c_str(), rpc_name, status);
13635 if (buf)
13636 free(buf);
13637 c->mutex.unlock();
13638 return RPC_NET_ERROR;
13639 }
13640
13641 c->mutex.unlock();
13642
13643 if (rpc_status == RPC_INVALID_ID) {
13644 cm_msg(MERROR, "rpc_client_call", "call to \"%s\" on \"%s\" RPC \"%s\": error, unknown RPC, status %d", c->client_name.c_str(), c->host_name.c_str(), rpc_name, rpc_status);
13645 if (buf)
13646 free(buf);
13647 return rpc_status;
13648 }
13649
13650 /* extract result variables and place it to argument list */
13651
13652 va_start(ap, routine_id);
13653
13654 status = rpc_call_decode(ap, rpc_entry, buf, buf_size);
13655
13656 if (status != RPC_SUCCESS) {
13658 }
13659
13660 va_end(ap);
13661
13662 if (buf)
13663 free(buf);
13664 buf = NULL;
13665 buf_size = 0;
13666
13667 return rpc_status;
13668}
INT cm_set_watchdog_params(BOOL call_watchdog, DWORD timeout)
Definition midas.cxx:3283
#define RPC_NO_CONNECTION
Definition midas.h:700
#define RPC_ID_EXIT
Definition mrpc.h:135
#define RPC_ID_SHUTDOWN
Definition mrpc.h:134
static RPC_CLIENT_CONNECTION * rpc_get_locked_client_connection(HNDLE hConn)
Definition midas.cxx:12620
char c
Definition system.cxx:1310
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_client_check()

void rpc_client_check ( void  )

Definition at line 12278 of file midas.cxx.

12286{
12287#if 0
12288 for (i = 0; i < MAX_RPC_CONNECTION; i++)
12289 if (_client_connection[i].send_sock != 0)
12290 printf("slot %d, checking client %s socket %d, connected %d\n", i, _client_connection[i].client_name, _client_connection[i].send_sock, _client_connection[i].connected);
12291#endif
12292
12293 std::lock_guard<std::mutex> guard(_client_connections_mutex);
12294
12295 /* check for broken connections */
12296 for (unsigned i = 0; i < _client_connections.size(); i++) {
12298 if (c && c->connected) {
12299 std::lock_guard<std::mutex> cguard(c->mutex);
12300
12301 if (!c->connected) {
12302 // implicit unlock
12303 continue;
12304 }
12305
12306 //printf("rpc_client_check: connection %d: ", i);
12307 //c->print();
12308 //printf("\n");
12309
12310 int ok = 0;
12311
12313 FD_ZERO(&readfds);
12314 FD_SET(c->send_sock, &readfds);
12315
12316 struct timeval timeout;
12317 timeout.tv_sec = 0;
12318 timeout.tv_usec = 0;
12319
12320 int status;
12321
12322#ifdef OS_WINNT
12323 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
12324#else
12325 do {
12326 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
12327 } while (status == -1 && errno == EINTR); /* dont return if an alarm signal was cought */
12328#endif
12329
12330 if (!FD_ISSET(c->send_sock, &readfds)) {
12331 // implicit unlock
12332 continue;
12333 }
12334
12335 char buffer[64];
12336
12337 status = recv(c->send_sock, (char *) buffer, sizeof(buffer), MSG_PEEK);
12338 //printf("recv %d status %d, errno %d (%s)\n", sock, status, errno, strerror(errno));
12339
12340 if (status < 0) {
12341#ifndef OS_WINNT
12342 if (errno == EAGAIN) { // still connected
12343 ok = 1;
12344 } else
12345#endif
12346 {
12347 // connection error
12348 cm_msg(MERROR, "rpc_client_check",
12349 "RPC client connection to \"%s\" on host \"%s\" is broken, recv() errno %d (%s)",
12350 c->client_name.c_str(),
12351 c->host_name.c_str(),
12352 errno, strerror(errno));
12353 ok = 0;
12354 }
12355 } else if (status == 0) {
12356 // connection closed by remote end without sending an EXIT message
12357 // this can happen if the remote end has crashed, so this message
12358 // is still necessary as a useful diagnostic for unexpected crashes
12359 // of midas programs. K.O.
12360 cm_msg(MINFO, "rpc_client_check", "RPC client connection to \"%s\" on host \"%s\" unexpectedly closed", c->client_name.c_str(), c->host_name.c_str());
12361 ok = 0;
12362 } else {
12363 // read some data
12364 ok = 1;
12365 if (equal_ustring(buffer, "EXIT")) {
12366 /* normal exit */
12367 ok = 0;
12368 }
12369 }
12370
12371 if (!ok) {
12372 //printf("rpc_client_check: closing connection %d: ", i);
12373 //c->print();
12374 //printf("\n");
12375
12376 // connection lost, close the socket
12377 c->close_locked();
12378 }
12379
12380 // implicit unlock
12381 }
12382 }
12383
12384 // implicit unlock of _client_connections_mutex
12385}
BOOL equal_ustring(const char *str1, const char *str2)
Definition odb.cxx:3201
static std::mutex _client_connections_mutex
Definition midas.cxx:11503
static std::vector< RPC_CLIENT_CONNECTION * > _client_connections
Definition midas.cxx:11504
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_client_connect()

INT rpc_client_connect ( const char host_name,
INT  port,
const char client_name,
HNDLE hConnection 
)

Definition at line 12020 of file midas.cxx.

12043{
12044 INT i, status;
12045 bool debug = false;
12046
12047 /* check if cm_connect_experiment was called */
12048 if (_client_name.length() == 0) {
12049 cm_msg(MERROR, "rpc_client_connect", "cm_connect_experiment/rpc_set_name not called");
12050 return RPC_NOT_REGISTERED;
12051 }
12052
12053 /* refuse connection to port 0 */
12054 if (port == 0) {
12055 cm_msg(MERROR, "rpc_client_connect", "invalid port %d", port);
12056 return RPC_NET_ERROR;
12057 }
12058
12060
12061 static std::mutex gHostnameMutex;
12062
12063 {
12064 std::lock_guard<std::mutex> guard(_client_connections_mutex);
12065
12066 if (debug) {
12067 printf("rpc_client_connect: host \"%s\", port %d, client \"%s\"\n", host_name, port, client_name);
12068 for (size_t i = 0; i < _client_connections.size(); i++) {
12069 if (_client_connections[i]) {
12070 printf("client connection %d: ", (int)i);
12071 _client_connections[i]->print();
12072 printf("\n");
12073 }
12074 }
12075 }
12076
12077 // slot with index 0 is not used, fill it with a NULL
12078
12079 if (_client_connections.empty()) {
12080 _client_connections.push_back(NULL);
12081 }
12082
12083 bool hostname_locked = false;
12084
12085 /* check if connection already exists */
12086 for (size_t i = 1; i < _client_connections.size(); i++) {
12088 if (c && c->connected) {
12089
12090 if (!hostname_locked) {
12091 gHostnameMutex.lock();
12092 hostname_locked = true;
12093 }
12094
12095 if ((c->host_name == host_name) && (c->port == port)) {
12096 // NB: we must release the hostname lock before taking
12097 // c->mutex to avoid a locking order inversion deadlock:
12098 // later on we lock the hostname mutex while holding the c->mutex
12099 gHostnameMutex.unlock();
12100 hostname_locked = false;
12101 std::lock_guard<std::mutex> cguard(c->mutex);
12102 // check if socket is still connected
12103 if (c->connected) {
12104 // found connection slot with matching hostname and port number
12105 status = ss_socket_wait(c->send_sock, 0);
12106 if (status == SS_TIMEOUT) { // yes, still connected and empty
12107 // so reuse it connection
12108 *hConnection = c->index;
12109 if (debug) {
12110 printf("already connected: ");
12111 c->print();
12112 printf("\n");
12113 }
12114 // implicit unlock of c->mutex
12115 // gHostnameLock is not locked here
12116 return RPC_SUCCESS;
12117 }
12118 //cm_msg(MINFO, "rpc_client_connect", "Stale connection to \"%s\" on host %s is closed", _client_connection[i].client_name, _client_connection[i].host_name);
12119 c->close_locked();
12120 }
12121 // implicit unlock of c->mutex
12122 }
12123 }
12124 }
12125
12126 if (hostname_locked) {
12127 gHostnameMutex.unlock();
12128 hostname_locked = false;
12129 }
12130
12131 // only start reusing connections once we have
12132 // a good number of slots allocated.
12133 if (_client_connections.size() > 10) {
12134 static int last_reused = 0;
12135
12136 int size = _client_connections.size();
12137 for (int j = 1; j < size; j++) {
12138 int i = (last_reused + j) % size;
12139 if (_client_connections[i] && !_client_connections[i]->connected) {
12141 if (debug) {
12142 printf("last reused %d, reusing slot %d: ", last_reused, (int)i);
12143 c->print();
12144 printf("\n");
12145 }
12146 last_reused = i;
12147 break;
12148 }
12149 }
12150 }
12151
12152 // no slots to reuse, allocate a new slot.
12153 if (!c) {
12155
12156 // if empty slot not found, add to end of array
12157 c->index = _client_connections.size();
12158 _client_connections.push_back(c);
12159
12160 if (debug) {
12161 printf("new connection appended to array: ");
12162 c->print();
12163 printf("\n");
12164 }
12165 }
12166
12167 c->mutex.lock();
12168 c->connected = true; // rpc_client_connect() in another thread may try to grab this slot
12169
12170 // done with the array of connections
12171 // implicit unlock of _client_connections_mutex
12172 }
12173
12174 // locked connection slot for new connection
12175 assert(c != NULL);
12176
12177 std::string errmsg;
12178
12179 /* create a new socket for connecting to remote server */
12180 status = ss_socket_connect_tcp(host_name, port, &c->send_sock, &errmsg);
12181 if (status != SS_SUCCESS) {
12182 cm_msg(MERROR, "rpc_client_connect", "cannot connect to \"%s\" port %d: %s", host_name, port, errmsg.c_str());
12183 c->mutex.unlock();
12184 return RPC_NET_ERROR;
12185 }
12186
12187 gHostnameMutex.lock();
12188
12189 c->host_name = host_name;
12190 c->port = port;
12191
12192 gHostnameMutex.unlock();
12193
12194 c->client_name = client_name;
12195 c->rpc_timeout = DEFAULT_RPC_TIMEOUT;
12196
12197 /* set TCP_NODELAY option for better performance */
12198 i = 1;
12199 setsockopt(c->send_sock, IPPROTO_TCP, TCP_NODELAY, (char *) &i, sizeof(i));
12200
12201 /* send local computer info */
12202 std::string local_prog_name = rpc_get_name();
12203 std::string local_host_name = ss_gethostname();
12204
12205 int hw_type = rpc_get_hw_type();
12206
12207 std::string cstr = msprintf("%d %s %s %s", hw_type, cm_get_version(), local_prog_name.c_str(), local_host_name.c_str());
12208
12209 int size = cstr.length() + 1;
12210 i = send(c->send_sock, cstr.c_str(), size, 0);
12211 if (i < 0 || i != size) {
12212 cm_msg(MERROR, "rpc_client_connect", "cannot send %d bytes, send() returned %d, errno %d (%s)", size, i, errno, strerror(errno));
12213 c->mutex.unlock();
12214 return RPC_NET_ERROR;
12215 }
12216
12217 bool restore_watchdog_timeout = false;
12219 DWORD watchdog_timeout;
12220 cm_get_watchdog_params(&watchdog_call, &watchdog_timeout);
12221
12222 //printf("watchdog timeout: %d, rpc_connect_timeout: %d\n", watchdog_timeout, _rpc_connect_timeout);
12223
12224 if (_rpc_connect_timeout >= (int) watchdog_timeout) {
12227 }
12228
12229 char str[256];
12230
12231 /* receive remote computer info */
12232 i = recv_string(c->send_sock, str, sizeof(str), _rpc_connect_timeout);
12233
12235 cm_set_watchdog_params(watchdog_call, watchdog_timeout);
12236 }
12237
12238 if (i <= 0) {
12239 cm_msg(MERROR, "rpc_client_connect", "timeout waiting for server reply");
12240 c->close_locked();
12241 c->mutex.unlock();
12242 return RPC_NET_ERROR;
12243 }
12244
12245 int remote_hw_type = 0;
12246 char remote_version[32];
12247 remote_version[0] = 0;
12248 sscanf(str, "%d %s", &remote_hw_type, remote_version);
12249
12250 c->remote_hw_type = remote_hw_type;
12251
12252 /* print warning if version patch level doesn't agree */
12253 char v1[32];
12254 mstrlcpy(v1, remote_version, sizeof(v1));
12255 if (strchr(v1, '.'))
12256 if (strchr(strchr(v1, '.') + 1, '.'))
12257 *strchr(strchr(v1, '.') + 1, '.') = 0;
12258
12259 mstrlcpy(str, cm_get_version(), sizeof(str));
12260 if (strchr(str, '.'))
12261 if (strchr(strchr(str, '.') + 1, '.'))
12262 *strchr(strchr(str, '.') + 1, '.') = 0;
12263
12264 if (strcmp(v1, str) != 0) {
12265 cm_msg(MERROR, "rpc_client_connect", "remote MIDAS version \'%s\' differs from local version \'%s\'", remote_version, cm_get_version());
12266 }
12267
12268 c->connected = true;
12269
12270 *hConnection = c->index;
12271
12272 c->mutex.unlock();
12273
12274 return RPC_SUCCESS;
12275}
std::string ss_gethostname()
Definition system.cxx:5712
int ss_socket_wait(int sock, INT millisec)
Definition system.cxx:4898
INT ss_socket_connect_tcp(const char *hostname, int tcp_port, int *sockp, std::string *error_msg_p)
Definition system.cxx:4967
std::string rpc_get_name()
Definition midas.cxx:13092
static std::string _client_name
Definition midas.cxx:1459
static int _rpc_connect_timeout
Definition midas.cxx:233
#define DEFAULT_RPC_TIMEOUT
Definition midas.h:287
INT j
Definition odbhist.cxx:40
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_client_disconnect()

INT rpc_client_disconnect ( HNDLE  hConn,
BOOL  bShutdown 
)

Definition at line 12684 of file midas.cxx.

12702{
12703 /* notify server about exit */
12704
12705 /* call exit and shutdown with RPC_NO_REPLY because client will exit immediately without possibility of replying */
12706
12708
12709 return RPC_SUCCESS;
12710}
INT rpc_client_call(HNDLE hConn, DWORD routine_id,...)
Definition midas.cxx:13480
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_client_dispatch()

INT rpc_client_dispatch ( int  sock)

Definition at line 11953 of file midas.cxx.

11961{
11962 INT status = 0;
11963 char net_buffer[256];
11964
11965 int n = recv_tcp(sock, net_buffer, sizeof(net_buffer), 0);
11966 if (n <= 0)
11967 return SS_ABORT;
11968
11969 NET_COMMAND *nc = (NET_COMMAND *) net_buffer;
11970
11971 if (nc->header.routine_id == MSG_ODB) {
11972 status = handle_msg_odb(n, nc);
11973 } else if (nc->header.routine_id == MSG_WATCHDOG) {
11974 nc->header.routine_id = 1;
11975 nc->header.param_size = 0;
11976 send_tcp(sock, net_buffer, sizeof(NET_COMMAND_HEADER), 0);
11978 } else if (nc->header.routine_id == MSG_BM) {
11980 struct timeval timeout;
11981
11982 //printf("rpc_client_dispatch: received MSG_BM!\n");
11983
11984 /* receive further messages to empty TCP queue */
11985 do {
11986 FD_ZERO(&readfds);
11987 FD_SET(sock, &readfds);
11988
11989 timeout.tv_sec = 0;
11990 timeout.tv_usec = 0;
11991
11992 select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
11993
11994 if (FD_ISSET(sock, &readfds)) {
11995 n = recv_tcp(sock, net_buffer, sizeof(net_buffer), 0);
11996 if (n <= 0)
11997 return SS_ABORT;
11998
11999 if (nc->header.routine_id == MSG_ODB) {
12000 status = handle_msg_odb(n, nc);
12001 } else if (nc->header.routine_id == MSG_WATCHDOG) {
12002 nc->header.routine_id = 1;
12003 nc->header.param_size = 0;
12004 send_tcp(sock, net_buffer, sizeof(NET_COMMAND_HEADER), 0);
12006 }
12007 }
12008
12009 } while (FD_ISSET(sock, &readfds));
12010
12011 /* poll event from server */
12013 }
12014
12015 return status;
12016}
INT bm_poll_event()
Definition midas.cxx:11134
#define SS_ABORT
Definition midas.h:677
#define MSG_BM
Definition msystem.h:295
#define MSG_ODB
Definition msystem.h:296
static int handle_msg_odb(int n, const NET_COMMAND *nc)
Definition midas.cxx:11939
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_convert_data()

void rpc_convert_data ( void data,
INT  tid,
INT  flags,
INT  total_size,
INT  convert_flags 
)

Definition at line 11714 of file midas.cxx.

11742{
11743 /* convert array */
11744 if (flags & (RPC_FIXARRAY | RPC_VARARRAY)) {
11745 int single_size = rpc_tid_size(tid);
11746 /* don't convert TID_ARRAY & TID_STRUCT */
11747 if (single_size == 0)
11748 return;
11749
11750 int n = total_size / single_size;
11751
11752 for (int i = 0; i < n; i++) {
11753 char* p = (char *) data + (i * single_size);
11754 rpc_convert_single(p, tid, flags, convert_flags);
11755 }
11756 } else {
11757 rpc_convert_single(data, tid, flags, convert_flags);
11758 }
11759}
void * data
Definition mana.cxx:268
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_convert_single()

void rpc_convert_single ( void data,
INT  tid,
INT  flags,
INT  convert_flags 
)

Definition at line 11689 of file midas.cxx.

11689 {
11690
11691 if (convert_flags & CF_ENDIAN) {
11692 if (tid == TID_UINT16 || tid == TID_INT16) WORD_SWAP(data);
11693 if (tid == TID_UINT32 || tid == TID_INT32 || tid == TID_BOOL || tid == TID_FLOAT) DWORD_SWAP(data);
11694 if (tid == TID_DOUBLE) QWORD_SWAP(data);
11695 }
11696
11697 if (((convert_flags & CF_IEEE2VAX) && !(flags & RPC_OUTGOING)) ||
11698 ((convert_flags & CF_VAX2IEEE) && (flags & RPC_OUTGOING))) {
11699 if (tid == TID_FLOAT)
11700 rpc_ieee2vax_float((float *) data);
11701 if (tid == TID_DOUBLE)
11702 rpc_ieee2vax_double((double *) data);
11703 }
11704
11705 if (((convert_flags & CF_IEEE2VAX) && (flags & RPC_OUTGOING)) ||
11706 ((convert_flags & CF_VAX2IEEE) && !(flags & RPC_OUTGOING))) {
11707 if (tid == TID_FLOAT)
11708 rpc_vax2ieee_float((float *) data);
11709 if (tid == TID_DOUBLE)
11710 rpc_vax2ieee_double((double *) data);
11711 }
11712}
#define TID_BOOL
Definition midas.h:340
#define WORD_SWAP(x)
Definition msystem.h:65
#define QWORD_SWAP(x)
Definition msystem.h:86
#define DWORD_SWAP(x)
Definition msystem.h:74
void rpc_vax2ieee_float(float *var)
Definition midas.cxx:11634
void rpc_ieee2vax_float(float *var)
Definition midas.cxx:11619
void rpc_ieee2vax_double(double *var)
Definition midas.cxx:11669
void rpc_vax2ieee_double(double *var)
Definition midas.cxx:11650
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_debug_printf()

void rpc_debug_printf ( const char format,
  ... 
)

Definition at line 13169 of file midas.cxx.

13183{
13185 char str[1000];
13186
13187 if (_debug_mode) {
13188 va_start(argptr, format);
13189 vsprintf(str, (char *) format, argptr);
13190 va_end(argptr);
13191
13192 if (_debug_print) {
13193 strcat(str, "\n");
13195 } else
13196 puts(str);
13197 }
13198}
static void(* _debug_print)(const char *)
Definition midas.cxx:229
static INT _debug_mode
Definition midas.cxx:231
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_deregister_functions()

INT rpc_deregister_functions ( void  )

dox

Definition at line 11878 of file midas.cxx.

11895{
11896 rpc_list_mutex.lock();
11897 rpc_list.clear();
11898 rpc_list_mutex.unlock();
11899
11900 return RPC_SUCCESS;
11901}
Here is the caller graph for this function:

◆ rpc_execute()

INT rpc_execute ( INT  sock,
char buffer,
INT  convert_flags 
)

Definition at line 14658 of file midas.cxx.

14685{
14686 INT i, routine_id, status;
14688 INT tid, flags;
14690 INT param_size, max_size;
14691 void *prpc_param[20];
14692 char debug_line[1024], *return_buffer;
14695#ifdef FIXED_BUFFER
14697#else
14698 int initial_buffer_size = 1024;
14699#endif
14700
14701 /* return buffer must must use thread local storage multi-thread servers */
14702 if (!tls_size) {
14706 tls_buffer[tls_size].buffer = (char *) malloc(tls_buffer[tls_size].buffer_size);
14707 tls_size = 1;
14708 }
14709 for (i = 0; i < tls_size; i++)
14710 if (tls_buffer[i].thread_id == ss_gettid())
14711 break;
14712 if (i == tls_size) {
14713 /* new thread -> allocate new buffer */
14717 tls_buffer[tls_size].buffer = (char *) malloc(tls_buffer[tls_size].buffer_size);
14718 tls_size++;
14719 }
14720
14723 return_buffer = tls_buffer[i].buffer;
14724 assert(return_buffer);
14725
14726 // make valgrind happy - the RPC parameter encoder skips the alignement padding bytes
14727 // and valgrind complains that we transmit uninitialized data
14728 //memset(return_buffer, 0, return_buffer_size);
14729
14730 /* extract pointer array to parameters */
14731 nc_in = (NET_COMMAND *) buffer;
14732
14733 /* convert header format (byte swapping) */
14734 if (convert_flags) {
14735 rpc_convert_single(&nc_in->header.routine_id, TID_UINT32, 0, convert_flags);
14736 rpc_convert_single(&nc_in->header.param_size, TID_UINT32, 0, convert_flags);
14737 }
14738
14739 //if (nc_in->header.routine_id & RPC_NO_REPLY) {
14740 // printf("rpc_execute: routine_id %d, RPC_NO_REPLY\n", (int)(nc_in->header.routine_id & ~RPC_NO_REPLY));
14741 //}
14742
14743 /* no result return as requested */
14744 if (nc_in->header.routine_id & RPC_NO_REPLY)
14745 sock = 0;
14746
14747 /* find entry in rpc_list */
14748 routine_id = nc_in->header.routine_id & ~RPC_NO_REPLY;
14749
14750 int idx = -1;
14751 RPC_LIST rl;
14752
14753 rpc_list_mutex.lock();
14754
14755 for (size_t i = 0; i < rpc_list.size(); i++) {
14756 if (rpc_list[i].id == routine_id) {
14757 idx = i;
14758 rl = rpc_list[idx];
14759 break;
14760 }
14761 }
14762
14763 rpc_list_mutex.unlock();
14764
14765 if (idx < 0) {
14766 cm_msg(MERROR, "rpc_execute", "Invalid rpc ID (%d)", routine_id);
14767 return RPC_INVALID_ID;
14768 }
14769
14770 again:
14771
14772 in_param_ptr = nc_in->param;
14773
14774 nc_out = (NET_COMMAND *) return_buffer;
14775 out_param_ptr = nc_out->param;
14776
14777 sprintf(debug_line, "%s(", rl.name);
14778
14779 for (i = 0; rl.param[i].tid != 0; i++) {
14780 tid = rl.param[i].tid;
14781 flags = rl.param[i].flags;
14782
14783 if (flags & RPC_IN) {
14784 param_size = ALIGN8(rpc_tid_size(tid));
14785
14786 if (tid == TID_STRING || tid == TID_LINK)
14787 param_size = ALIGN8(1 + strlen((char *) (in_param_ptr)));
14788
14789 if (flags & RPC_VARARRAY) {
14790 /* for arrays, the size is stored as a INT in front of the array */
14791 param_size = *((INT *) in_param_ptr);
14792 if (convert_flags)
14793 rpc_convert_single(&param_size, TID_INT32, 0, convert_flags);
14794 param_size = ALIGN8(param_size);
14795
14796 in_param_ptr += ALIGN8(sizeof(INT));
14797 }
14798
14799 if (tid == TID_STRUCT)
14800 param_size = ALIGN8(rl.param[i].n);
14801
14803
14804 /* convert data format */
14805 if (convert_flags) {
14806 if (flags & RPC_VARARRAY)
14807 rpc_convert_data(in_param_ptr, tid, flags, param_size, convert_flags);
14808 else
14809 rpc_convert_data(in_param_ptr, tid, flags, rl.param[i].n * rpc_tid_size(tid),
14810 convert_flags);
14811 }
14812
14813 std::string str = db_sprintf(in_param_ptr, param_size, 0, rl.param[i].tid);
14814 if (rl.param[i].tid == TID_STRING) {
14815 /* check for long strings (db_create_record...) */
14816 if (strlen(debug_line) + str.length() + 2 < sizeof(debug_line)) {
14817 strcat(debug_line, "\"");
14818 strcat(debug_line, str.c_str());
14819 strcat(debug_line, "\"");
14820 } else
14821 strcat(debug_line, "...");
14822 } else
14823 strcat(debug_line, str.c_str());
14824
14825 in_param_ptr += param_size;
14826 }
14827
14828 if (flags & RPC_OUT) {
14829 param_size = ALIGN8(rpc_tid_size(tid));
14830
14831 if (flags & RPC_VARARRAY || tid == TID_STRING) {
14832
14833 /* save maximum array length from the value of the next argument.
14834 * this means RPC_OUT arrays and strings should always be passed like this:
14835 * rpc_call(..., array_ptr, array_max_size, ...); */
14836
14837 max_size = *((INT *) in_param_ptr);
14838
14839 if (convert_flags)
14840 rpc_convert_single(&max_size, TID_INT32, 0, convert_flags);
14842
14843 *((INT *) out_param_ptr) = max_size;
14844
14845 /* save space for return array length */
14846 out_param_ptr += ALIGN8(sizeof(INT));
14847
14848 /* use maximum array length from input */
14849 param_size = max_size;
14850 }
14851
14852 if (rl.param[i].tid == TID_STRUCT)
14853 param_size = ALIGN8(rl.param[i].n);
14854
14855 if ((POINTER_T) out_param_ptr - (POINTER_T) nc_out + param_size > return_buffer_size) {
14856#ifdef FIXED_BUFFER
14857 cm_msg(MERROR, "rpc_execute",
14858 "return parameters (%d) too large for network buffer (%d)",
14860
14861 return RPC_EXCEED_BUFFER;
14862#else
14863 int itls;
14864 int new_size = (POINTER_T) out_param_ptr - (POINTER_T) nc_out + param_size + 1024;
14865
14866#if 0
14867 cm_msg(MINFO, "rpc_execute",
14868 "rpc_execute: return parameters (%d) too large for network buffer (%d), new buffer size (%d)",
14870#endif
14871
14873
14875 tls_buffer[itls].buffer = (char *) realloc(tls_buffer[itls].buffer, new_size);
14876
14877 if (!tls_buffer[itls].buffer) {
14878 cm_msg(MERROR, "rpc_execute", "Cannot allocate return buffer of size %d", new_size);
14879 return RPC_EXCEED_BUFFER;
14880 }
14881
14883 return_buffer = tls_buffer[itls].buffer;
14884 assert(return_buffer);
14885
14886 goto again;
14887#endif
14888 }
14889
14890 /* if parameter goes both directions, copy input to output */
14891 if (rl.param[i].flags & RPC_IN)
14892 memcpy(out_param_ptr, prpc_param[i], param_size);
14893
14894 if (_debug_print && !(flags & RPC_IN))
14895 strcat(debug_line, "-");
14896
14898 out_param_ptr += param_size;
14899 }
14900
14901 if (rl.param[i + 1].tid)
14902 strcat(debug_line, ", ");
14903 }
14904
14905 //printf("predicted return size %d\n", (POINTER_T) out_param_ptr - (POINTER_T) nc_out);
14906
14907 strcat(debug_line, ")");
14909
14911
14912 /*********************************\
14913 * call dispatch function *
14914 \*********************************/
14915 if (rl.dispatch)
14916 status = rl.dispatch(routine_id, prpc_param);
14917 else
14919
14920 if (routine_id == RPC_ID_EXIT || routine_id == RPC_ID_SHUTDOWN || routine_id == RPC_ID_WATCHDOG)
14922
14923 /* return immediately for closed down client connections */
14924 if (!sock && routine_id == RPC_ID_EXIT)
14925 return SS_EXIT;
14926
14927 if (!sock && routine_id == RPC_ID_SHUTDOWN)
14928 return RPC_SHUTDOWN;
14929
14930 /* Return if TCP connection broken */
14931 if (status == SS_ABORT)
14932 return SS_ABORT;
14933
14934 /* if sock == 0, we are in FTCP mode and may not sent results */
14935 if (!sock)
14936 return RPC_SUCCESS;
14937
14938 /* compress variable length arrays */
14939 out_param_ptr = nc_out->param;
14940 for (i = 0; rl.param[i].tid != 0; i++)
14941 if (rl.param[i].flags & RPC_OUT) {
14942 tid = rl.param[i].tid;
14943 flags = rl.param[i].flags;
14944 param_size = ALIGN8(rpc_tid_size(tid));
14945
14946 if (tid == TID_STRING) {
14947 max_size = *((INT *) out_param_ptr);
14948 // note: RPC_OUT parameters may have been shifted in the output buffer by memmove()
14949 // and prpc_param() is now pointing to the wrong place. here we know our string data
14950 // starts right after max_size and we do not need to use prpc_param[] to find it. K.O.
14951 //const char* param_ptr = (char *) prpc_param[i];
14952 const char* param_ptr = ((char *) out_param_ptr) + ALIGN8(sizeof(INT));
14953 //printf("string param [%s] max_size %d\n", param_ptr, max_size);
14954 param_size = strlen(param_ptr) + 1;
14955 param_size = ALIGN8(param_size);
14956
14957 /* move string ALIGN8(sizeof(INT)) left */
14958 memmove(out_param_ptr, out_param_ptr + ALIGN8(sizeof(INT)), param_size);
14959
14960 /* move remaining parameters to end of string */
14961 memmove(out_param_ptr + param_size,
14962 out_param_ptr + max_size + ALIGN8(sizeof(INT)),
14964 }
14965
14966 if (flags & RPC_VARARRAY) {
14967 /* store array length at current out_param_ptr */
14968 max_size = *((INT *) out_param_ptr);
14969 // note: RPC_OUT parameters may have been shifted in the output buffer by memmove()
14970 // and prpc_param() is now pointing to the wrong place. instead, compute location
14971 // of next parameter using max_size. K.O.
14972 // note: RPC_IN parameters are in the input buffer and we must use the prpc_param[] pointer. K.O.
14973 if (rl.param[i+1].flags & RPC_OUT)
14974 param_size = *((INT *) (out_param_ptr + ALIGN8(sizeof(INT)) + ALIGN8(max_size)));
14975 else
14976 param_size = *((INT *) prpc_param[i + 1]);
14977 *((INT *) out_param_ptr) = param_size; // store new array size
14978 if (convert_flags)
14980
14981 out_param_ptr += ALIGN8(sizeof(INT)); // step over array size
14982
14983 param_size = ALIGN8(param_size);
14984
14985 /* move remaining parameters to end of array */
14986 memmove(out_param_ptr + param_size,
14989 }
14990
14991 if (tid == TID_STRUCT)
14992 param_size = ALIGN8(rl.param[i].n);
14993
14994 /* convert data format */
14995 if (convert_flags) {
14996 if (flags & RPC_VARARRAY)
14998 rl.param[i].flags | RPC_OUTGOING, param_size, convert_flags);
14999 else
15001 rl.param[i].flags | RPC_OUTGOING,
15002 rl.param[i].n * rpc_tid_size(tid), convert_flags);
15003 }
15004
15005 out_param_ptr += param_size;
15006 }
15007
15008 /* send return parameters */
15009 param_size = (POINTER_T) out_param_ptr - (POINTER_T) nc_out->param;
15010 nc_out->header.routine_id = status;
15011 nc_out->header.param_size = param_size;
15012
15013 //printf("actual return size %d, buffer used %d\n", (POINTER_T) out_param_ptr - (POINTER_T) nc_out, sizeof(NET_COMMAND_HEADER) + param_size);
15014
15015 /* convert header format (byte swapping) if necessary */
15016 if (convert_flags) {
15017 rpc_convert_single(&nc_out->header.routine_id, TID_UINT32, RPC_OUTGOING, convert_flags);
15018 rpc_convert_single(&nc_out->header.param_size, TID_UINT32, RPC_OUTGOING, convert_flags);
15019 }
15020
15021 // valgrind complains about sending uninitialized data, if you care about this, uncomment
15022 // the memset(return_buffer,0) call above (search for "valgrind"). K.O.
15023
15024 status = send_tcp(sock, return_buffer, sizeof(NET_COMMAND_HEADER) + param_size, 0);
15025
15026 if (status < 0) {
15027 cm_msg(MERROR, "rpc_execute", "send_tcp() failed");
15028 return RPC_NET_ERROR;
15029 }
15030
15031 /* print return buffer */
15032/*
15033 printf("Return buffer, ID %d:\n", routine_id);
15034 for (i=0; i<param_size ; i++)
15035 {
15036 status = (char) nc_out->param[i];
15037 printf("%02X ", status);
15038 if (i%8 == 7)
15039 printf("\n");
15040 }
15041*/
15042 /* return SS_EXIT if RPC_EXIT is called */
15043 if (routine_id == RPC_ID_EXIT)
15044 return SS_EXIT;
15045
15046 /* return SS_SHUTDOWN if RPC_SHUTDOWN is called */
15047 if (routine_id == RPC_ID_SHUTDOWN)
15048 return RPC_SHUTDOWN;
15049
15050 return RPC_SUCCESS;
15051}
#define SS_EXIT
Definition midas.h:678
#define RPC_SHUTDOWN
Definition midas.h:707
#define RPC_EXCEED_BUFFER
Definition midas.h:703
midas_thread_t ss_gettid(void)
Definition system.cxx:1519
INT db_sprintf(char *string, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:10843
void rpc_convert_data(void *data, INT tid, INT flags, INT total_size, INT convert_flags)
Definition midas.cxx:11714
static int tls_size
Definition midas.cxx:14655
#define RPC_ID_WATCHDOG
Definition mrpc.h:133
void rpc_debug_printf(const char *format,...)
Definition midas.cxx:13169
static TLS_POINTER * tls_buffer
Definition midas.cxx:14654
midas_thread_t thread_id
Definition midas.cxx:14649
int buffer_size
Definition midas.cxx:14650
char * buffer
Definition midas.cxx:14651
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_flush_event()

INT rpc_flush_event ( void  )

Send event residing in the TCP cache buffer filled by rpc_send_event. This routine should be called when a run is stopped.

Returns
RPC_SUCCESS, RPC_NET_ERROR

Definition at line 14046 of file midas.cxx.

14046 {
14047 return RPC_SUCCESS;
14048}
Here is the caller graph for this function:

◆ rpc_flush_event_socket()

int rpc_flush_event_socket ( int  timeout_msec)

Definition at line 16144 of file midas.cxx.

16158{
16160
16161 //printf("ss_event_socket_has_data() returned %d\n", has_data);
16162
16163 if (has_data) {
16164 if (timeout_msec == BM_NO_WAIT) {
16165 return BM_ASYNC_RETURN;
16166 } else if (timeout_msec == BM_WAIT) {
16167 return BM_ASYNC_RETURN;
16168 } else {
16170 if (status == SS_ABORT || status == SS_EXIT)
16171 return status;
16172 return BM_ASYNC_RETURN;
16173 }
16174 }
16175
16177
16178 //printf("rpc_server_receive_event() status %d\n", status);
16179
16180 if (status == BM_ASYNC_RETURN) {
16181 return BM_ASYNC_RETURN;
16182 }
16183
16184 if (status == SS_ABORT || status == SS_EXIT)
16185 return status;
16186
16187 return BM_SUCCESS;
16188}
#define BM_ASYNC_RETURN
Definition midas.h:613
#define BM_SUCCESS
Definition midas.h:605
#define BM_NO_WAIT
Definition midas.h:366
#define BM_WAIT
Definition midas.h:365
INT ss_suspend(INT millisec, INT msg)
Definition system.cxx:4543
bool ss_event_socket_has_data()
Definition system.cxx:4520
INT rpc_server_receive_event(int idx, RPC_SERVER_ACCEPTION *sa, int timeout_msec)
Definition midas.cxx:15989
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_get_convert_flags() [1/2]

void rpc_get_convert_flags ( INT convert_flags)

Definition at line 11614 of file midas.cxx.

Here is the call graph for this function:

◆ rpc_get_convert_flags() [2/2]

INT rpc_get_convert_flags ( void  )

dox

Definition at line 13038 of file midas.cxx.

13049{
13052 else
13053 return 0;
13054}
Here is the caller graph for this function:

◆ rpc_get_hw_type()

INT rpc_get_hw_type ( )

Definition at line 12842 of file midas.cxx.

12853{
12854 {
12855 {
12856 INT tmp_type, size;
12857 DWORD dummy;
12858 unsigned char *p;
12859 float f;
12860 double d;
12861
12862 tmp_type = 0;
12863
12864 /* test pointer size */
12865 size = sizeof(p);
12866 if (size == 2)
12867 tmp_type |= DRI_16;
12868 if (size == 4)
12869 tmp_type |= DRI_32;
12870 if (size == 8)
12871 tmp_type |= DRI_64;
12872
12873 /* test if little or big endian machine */
12874 dummy = 0x12345678;
12875 p = (unsigned char *) &dummy;
12876 if (*p == 0x78)
12878 else if (*p == 0x12)
12880 else
12881 cm_msg(MERROR, "rpc_get_option", "unknown byte order format");
12882
12883 /* floating point format */
12884 f = (float) 1.2345;
12885 dummy = 0;
12886 memcpy(&dummy, &f, sizeof(f));
12887 if ((dummy & 0xFF) == 0x19 &&
12888 ((dummy >> 8) & 0xFF) == 0x04 && ((dummy >> 16) & 0xFF) == 0x9E
12889 && ((dummy >> 24) & 0xFF) == 0x3F)
12890 tmp_type |= DRF_IEEE;
12891 else if ((dummy & 0xFF) == 0x9E &&
12892 ((dummy >> 8) & 0xFF) == 0x40 && ((dummy >> 16) & 0xFF) == 0x19
12893 && ((dummy >> 24) & 0xFF) == 0x04)
12895 else
12896 cm_msg(MERROR, "rpc_get_option", "unknown floating point format");
12897
12898 d = (double) 1.2345;
12899 dummy = 0;
12900 memcpy(&dummy, &d, sizeof(f));
12901 if ((dummy & 0xFF) == 0x8D && /* little endian */
12902 ((dummy >> 8) & 0xFF) == 0x97 && ((dummy >> 16) & 0xFF) == 0x6E
12903 && ((dummy >> 24) & 0xFF) == 0x12)
12904 tmp_type |= DRF_IEEE;
12905 else if ((dummy & 0xFF) == 0x83 && /* big endian */
12906 ((dummy >> 8) & 0xFF) == 0xC0 && ((dummy >> 16) & 0xFF) == 0xF3
12907 && ((dummy >> 24) & 0xFF) == 0x3F)
12908 tmp_type |= DRF_IEEE;
12909 else if ((dummy & 0xFF) == 0x13 &&
12910 ((dummy >> 8) & 0xFF) == 0x40 && ((dummy >> 16) & 0xFF) == 0x83
12911 && ((dummy >> 24) & 0xFF) == 0xC0)
12913 else if ((dummy & 0xFF) == 0x9E &&
12914 ((dummy >> 8) & 0xFF) == 0x40 && ((dummy >> 16) & 0xFF) == 0x18
12915 && ((dummy >> 24) & 0xFF) == 0x04)
12916 cm_msg(MERROR, "rpc_get_option",
12917 "MIDAS cannot handle VAX D FLOAT format. Please compile with the /g_float flag");
12918 else
12919 cm_msg(MERROR, "rpc_get_option", "unknown floating point format");
12920
12921 return tmp_type;
12922 }
12923 }
12924}
#define DRI_32
Definition msystem.h:46
#define DRI_16
Definition msystem.h:45
#define DRI_64
Definition msystem.h:47
double d
Definition system.cxx:1311
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_get_locked_client_connection()

static RPC_CLIENT_CONNECTION * rpc_get_locked_client_connection ( HNDLE  hConn)
static

Definition at line 12620 of file midas.cxx.

12621{
12623 if (hConn >= 0 && hConn < (int)_client_connections.size()) {
12625 if (c && c->connected) {
12627 c->mutex.lock();
12628 if (!c->connected) {
12629 // disconnected while we were waiting for the lock
12630 c->mutex.unlock();
12631 return NULL;
12632 }
12633 return c;
12634 }
12635 }
12637 return NULL;
12638}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_get_mserver_acception()

RPC_SERVER_ACCEPTION * rpc_get_mserver_acception ( void  )

Definition at line 11521 of file midas.cxx.

11522{
11523 return _mserver_acception;
11524}
Here is the caller graph for this function:

◆ rpc_get_mserver_hostname()

std::string rpc_get_mserver_hostname ( void  )

Definition at line 12813 of file midas.cxx.

12821{
12823}
Here is the caller graph for this function:

◆ rpc_get_mserver_path()

const char * rpc_get_mserver_path ( void  )

Definition at line 13059 of file midas.cxx.

13067{
13068 return _mserver_path.c_str();
13069}
static std::string _mserver_path
Definition midas.cxx:13056
Here is the caller graph for this function:

◆ rpc_get_name()

std::string rpc_get_name ( )

Definition at line 13092 of file midas.cxx.

13110{
13111 return _client_name;
13112}
Here is the caller graph for this function:

◆ rpc_get_opt_tcp_size()

INT rpc_get_opt_tcp_size ( void  )

Definition at line 13880 of file midas.cxx.

13880 {
13881 return _opt_tcp_size;
13882}
static int _opt_tcp_size
Definition midas.cxx:11584

◆ rpc_get_server_acception()

static RPC_SERVER_ACCEPTION * rpc_get_server_acception ( int  idx)
static

Definition at line 11513 of file midas.cxx.

11514{
11515 assert(idx >= 0);
11516 assert(idx < (int)_server_acceptions.size());
11517 assert(_server_acceptions[idx] != NULL);
11518 return _server_acceptions[idx];
11519}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_get_timeout()

INT rpc_get_timeout ( HNDLE  hConn)

dox Set RPC option

Parameters
hConnRPC connection handle, -1 for server connection, -2 for rpc connect timeout
itemOne of RPC_Oxxx
valueValue to set
Returns
RPC_SUCCESS Get RPC timeout
Parameters
hConnRPC connection handle, RPC_HNDLE_MSERVER for mserver connection, RPC_HNDLE_CONNECT for rpc connect timeout
Returns
timeout value

Definition at line 12981 of file midas.cxx.

12982{
12983 if (hConn == RPC_HNDLE_MSERVER) {
12985 } else if (hConn == RPC_HNDLE_CONNECT) {
12986 return _rpc_connect_timeout;
12987 } else {
12989 if (c) {
12990 int timeout = c->rpc_timeout;
12991 c->mutex.unlock();
12992 return timeout;
12993 }
12994 }
12995 return 0;
12996}
#define RPC_HNDLE_CONNECT
Definition midas.h:394
#define RPC_HNDLE_MSERVER
Definition midas.h:393
Here is the call graph for this function:

◆ rpc_ieee2vax_double()

void rpc_ieee2vax_double ( double var)

Definition at line 11669 of file midas.cxx.

11669 {
11670 unsigned short int i1, i2, i3, i4;
11671
11672 /* swap words */
11673 i1 = *((short int *) (var) + 3);
11674 i2 = *((short int *) (var) + 2);
11675 i3 = *((short int *) (var) + 1);
11676 i4 = *((short int *) (var));
11677
11678 /* correct exponent */
11679 if (i1 != 0)
11680 i1 += 0x20;
11681
11682 *((short int *) (var) + 3) = i4;
11683 *((short int *) (var) + 2) = i3;
11684 *((short int *) (var) + 1) = i2;
11685 *((short int *) (var)) = i1;
11686}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_ieee2vax_float()

void rpc_ieee2vax_float ( float var)

Definition at line 11619 of file midas.cxx.

11619 {
11620 unsigned short int lo, hi;
11621
11622 /* swap hi and lo word */
11623 lo = *((short int *) (var) + 1);
11624 hi = *((short int *) (var));
11625
11626 /* correct exponent */
11627 if (lo != 0)
11628 lo += 0x100;
11629
11630 *((short int *) (var) + 1) = hi;
11631 *((short int *) (var)) = lo;
11632}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_is_connected()

bool rpc_is_connected ( void  )

Definition at line 12791 of file midas.cxx.

12808{
12809 return _server_connection.send_sock != 0;
12810}
Here is the caller graph for this function:

◆ rpc_is_mserver()

bool rpc_is_mserver ( void  )

Definition at line 12826 of file midas.cxx.

12837{
12838 return _mserver_acception != NULL;
12839}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_is_remote()

bool rpc_is_remote ( void  )

Definition at line 12769 of file midas.cxx.

12786{
12787 return _rpc_is_remote;
12788}
static bool _rpc_is_remote
Definition midas.cxx:11507

◆ rpc_name_tid()

int rpc_name_tid ( const char name)

Definition at line 11786 of file midas.cxx.

11787{
11788 for (int i=0; i<TID_LAST; i++) {
11789 if (strcmp(name, tid_name[i]) == 0)
11790 return i;
11791 }
11792
11793 for (int i=0; i<TID_LAST; i++) {
11794 if (strcmp(name, tid_name_old[i]) == 0)
11795 return i;
11796 }
11797
11798 return 0;
11799}
#define TID_LAST
Definition midas.h:354
static const char * tid_name[]
Definition midas.cxx:111
static const char * tid_name_old[]
Definition midas.cxx:89
#define name(x)
Definition midas_macro.h:24
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_new_server_acception()

static RPC_SERVER_ACCEPTION * rpc_new_server_acception ( )
static

Definition at line 11526 of file midas.cxx.

11527{
11528 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
11529 if (_server_acceptions[idx] && (_server_acceptions[idx]->recv_sock == 0)) {
11530 //printf("rpc_new_server_acception: reuse acception in slot %d\n", idx);
11531 return _server_acceptions[idx];
11532 }
11533 }
11534
11536
11537 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
11538 if (_server_acceptions[idx] == NULL) {
11539 //printf("rpc_new_server_acception: new acception, reuse slot %d\n", idx);
11540 _server_acceptions[idx] = sa;
11541 return _server_acceptions[idx];
11542 }
11543 }
11544
11545 //printf("rpc_new_server_acception: new acception, array size %d, push_back\n", (int)_server_acceptions.size());
11546 _server_acceptions.push_back(sa);
11547
11548 return sa;
11549}
struct rpc_server_acception_struct RPC_SERVER_ACCEPTION
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_register_client()

INT rpc_register_client ( const char name,
RPC_LIST list 
)

Register RPC client for standalone mode (without standard midas server)

Parameters
listArray of RPC_LIST structures containing function IDs and parameter definitions. The end of the list must be indicated by a function ID of zero.
nameName of this client
Returns
RPC_SUCCESS

Definition at line 11816 of file midas.cxx.

11816 {
11820
11821 return RPC_SUCCESS;
11822}
RPC_LIST * rpc_get_internal_list(INT flag)
Definition mrpc.cxx:716
INT rpc_register_functions(const RPC_LIST *new_list, RPC_HANDLER func)
Definition midas.cxx:11835
INT rpc_set_name(const char *name)
Definition midas.cxx:13116
static te_expr * list(state *s)
Definition tinyexpr.c:567
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_register_function()

INT rpc_register_function ( INT  id,
INT(*)(INT, void **)  func 
)

Definition at line 11905 of file midas.cxx.

11924{
11925 std::lock_guard<std::mutex> guard(rpc_list_mutex);
11926
11927 for (size_t i = 0; i < rpc_list.size(); i++) {
11928 if (rpc_list[i].id == id) {
11929 rpc_list[i].dispatch = func;
11930 return RPC_SUCCESS;
11931 }
11932 }
11933
11934 return RPC_INVALID_ID;
11935}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_register_functions()

INT rpc_register_functions ( const RPC_LIST new_list,
RPC_HANDLER  func 
)

Register a set of RPC functions (both as clients or servers)

Parameters
new_listArray of RPC_LIST structures containing function IDs and parameter definitions. The end of the list must be indicated by a function ID of zero.
funcDefault dispatch function
Returns
RPC_SUCCESS, RPC_NO_MEMORY, RPC_DOUBLE_DEFINED

Definition at line 11835 of file midas.cxx.

11836{
11837 for (int i = 0; new_list[i].id != 0; i++) {
11838 /* check valid ID for user functions */
11839 if (new_list != rpc_get_internal_list(0) &&
11841 || new_list[i].id > RPC_MAX_ID)) {
11842 cm_msg(MERROR, "rpc_register_functions", "registered RPC function with invalid ID %d", new_list[i].id);
11843 }
11844 }
11845
11846 std::lock_guard<std::mutex> guard(rpc_list_mutex);
11847
11848 /* check double defined functions */
11849 for (int i = 0; new_list[i].id != 0; i++) {
11850 for (size_t j = 0; j < rpc_list.size(); j++) {
11851 if (rpc_list[j].id == new_list[i].id) {
11852 return RPC_DOUBLE_DEFINED;
11853 }
11854 }
11855 }
11856
11857 /* append new functions */
11858 for (int i = 0; new_list[i].id != 0; i++) {
11859 RPC_LIST e = new_list[i];
11860
11861 /* set default dispatcher */
11862 if (e.dispatch == NULL) {
11863 e.dispatch = func;
11864 }
11865
11866 rpc_list.push_back(e);
11867 }
11868
11869 return RPC_SUCCESS;
11870}
#define RPC_DOUBLE_DEFINED
Definition midas.h:709
#define RPC_MIN_ID
Definition midas.h:1604
#define RPC_MAX_ID
Definition midas.h:1605
RPC_HANDLER * dispatch
Definition midas.h:1599
static double e(void)
Definition tinyexpr.c:136
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_register_listener()

INT rpc_register_listener ( int  port,
RPC_HANDLER  func,
int plsock,
int pport 
)

Definition at line 14587 of file midas.cxx.

14610{
14611 /* register system functions: RPC_ID_EXIT, RPC_ID_SHUTDOWN, RPC_ID_WATCHDOG */
14613
14614 /* create a socket for listening */
14615 int lsock = 0;
14616 int lport = 0;
14617 std::string errmsg;
14618
14620
14621 if (status != SS_SUCCESS) {
14622 cm_msg(MERROR, "rpc_register_server", "cannot listen to tcp port %d: %s", port, errmsg.c_str());
14623 return RPC_NET_ERROR;
14624 }
14625
14626 /* set close-on-exec flag to prevent child mserver processes from inheriting the listen socket */
14627#if defined(F_SETFD) && defined(FD_CLOEXEC)
14629 if (status < 0) {
14630 cm_msg(MERROR, "rpc_register_server", "fcntl(F_SETFD, FD_CLOEXEC) failed, errno %d (%s)", errno, strerror(errno));
14631 return RPC_NET_ERROR;
14632 }
14633#endif
14634
14635 /* return port wich OS has choosen */
14636 if (pport) {
14637 *pport = lport;
14638 }
14639
14640 if (plsock)
14641 *plsock = lsock;
14642
14643 //printf("rpc_register_server: requested port %d, actual port %d, socket %d\n", port, *pport, *plsock);
14644
14645 return RPC_SUCCESS;
14646}
INT ss_socket_listen_tcp(bool listen_localhost, int tcp_port, int *sockp, int *tcp_port_p, std::string *error_msg_p)
Definition system.cxx:5062
static int disable_bind_rpc_to_localhost
Definition midas.cxx:237
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_register_server()

INT rpc_register_server ( int  port,
int plsock,
int pport 
)

Definition at line 14546 of file midas.cxx.

14568{
14569 int status;
14570 int lsock;
14571
14573 if (status != RPC_SUCCESS)
14574 return status;
14575
14577 if (status != SS_SUCCESS)
14578 return status;
14579
14580 if (plsock)
14581 *plsock = lsock;
14582
14583 return RPC_SUCCESS;
14584}
INT ss_suspend_set_client_listener(int listen_socket)
Definition system.cxx:4284
INT rpc_register_listener(int port, RPC_HANDLER func, int *plsock, int *pport)
Definition midas.cxx:14587
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_send_event()

INT rpc_send_event ( INT  buffer_handle,
const EVENT_HEADER pevent,
int  unused,
INT  async_flag,
INT  mode 
)

dox Fast send_event routine which bypasses the RPC layer and sends the event directly at the TCP level.

Parameters
buffer_handleHandle of the buffer to send the event to. Must be obtained via bm_open_buffer.
sourceAddress of the event to send. It must have a proper event header.
buf_sizeSize of event in bytes with header.
async_flagBM_WAIT / BM_NO_WAIT flag. In BM_NO_WAIT mode, the function returns immediately if it cannot send the event over the network. In BM_WAIT mode, it waits until the packet is sent (blocking).
modeDetermines in which mode the event is sent. If zero, use RPC socket, if one, use special event socket to bypass RPC layer on the server side.
Returns
BM_INVALID_PARAM, BM_ASYNC_RETURN, RPC_SUCCESS, RPC_NET_ERROR, RPC_NO_CONNECTION, RPC_EXCEED_BUFFER

Definition at line 13909 of file midas.cxx.

13910{
13911 if (rpc_is_remote()) {
13912 return rpc_send_event1(buffer_handle, pevent);
13913 } else {
13914 return bm_send_event(buffer_handle, pevent, unused, async_flag);
13915 }
13916}
INT bm_send_event(INT buffer_handle, const EVENT_HEADER *pevent, int unused, int timeout_msec)
Definition midas.cxx:9686
INT rpc_send_event1(INT buffer_handle, const EVENT_HEADER *pevent)
Definition midas.cxx:13927
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_send_event1()

INT rpc_send_event1 ( INT  buffer_handle,
const EVENT_HEADER pevent 
)

Send event to mserver using the event socket connection, bypassing the RPC layer

Parameters
buffer_handleHandle of the buffer to send the event to. Must be obtained via bm_open_buffer.
eventPointer to event header
Returns
RPC_SUCCESS, RPC_NET_ERROR, RPC_NO_CONNECTION

Definition at line 13927 of file midas.cxx.

13928{
13929 const size_t event_size = sizeof(EVENT_HEADER) + pevent->data_size;
13930 return rpc_send_event_sg(buffer_handle, 1, (char**)&pevent, &event_size);
13931}
INT rpc_send_event_sg(INT buffer_handle, int sg_n, const char *const sg_ptr[], const size_t sg_len[])
Definition midas.cxx:13933
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_send_event_sg()

INT rpc_send_event_sg ( INT  buffer_handle,
int  sg_n,
const char *const  sg_ptr[],
const size_t  sg_len[] 
)

Definition at line 13933 of file midas.cxx.

13934{
13935 if (sg_n < 1) {
13936 cm_msg(MERROR, "rpc_send_event_sg", "invalid sg_n %d", sg_n);
13937 return BM_INVALID_SIZE;
13938 }
13939
13940 if (sg_ptr[0] == NULL) {
13941 cm_msg(MERROR, "rpc_send_event_sg", "invalid sg_ptr[0] is NULL");
13942 return BM_INVALID_SIZE;
13943 }
13944
13945 if (sg_len[0] < sizeof(EVENT_HEADER)) {
13946 cm_msg(MERROR, "rpc_send_event_sg", "invalid sg_len[0] value %d is smaller than event header size %d", (int)sg_len[0], (int)sizeof(EVENT_HEADER));
13947 return BM_INVALID_SIZE;
13948 }
13949
13950 const EVENT_HEADER* pevent = (const EVENT_HEADER*)sg_ptr[0];
13951
13952 const DWORD MAX_DATA_SIZE = (0x7FFFFFF0 - 16); // event size computations are not 32-bit clean, limit event size to 2GB. K.O.
13953 const DWORD data_size = pevent->data_size; // 32-bit unsigned value
13954
13955 if (data_size == 0) {
13956 cm_msg(MERROR, "rpc_send_event_sg", "invalid event data size zero");
13957 return BM_INVALID_SIZE;
13958 }
13959
13960 if (data_size > MAX_DATA_SIZE) {
13961 cm_msg(MERROR, "rpc_send_event_sg", "invalid event data size %d (0x%x) maximum is %d (0x%x)", data_size, data_size, MAX_DATA_SIZE, MAX_DATA_SIZE);
13962 return BM_INVALID_SIZE;
13963 }
13964
13965 const size_t event_size = sizeof(EVENT_HEADER) + data_size;
13966 const size_t total_size = ALIGN8(event_size);
13967
13968 size_t count = 0;
13969 for (int i=0; i<sg_n; i++) {
13970 count += sg_len[i];
13971 }
13972
13973 if (count != event_size) {
13974 cm_msg(MERROR, "rpc_send_event_sg", "data size mismatch: event data_size %d, event_size %d not same as sum of sg_len %d", (int)data_size, (int)event_size, (int)count);
13975 return BM_INVALID_SIZE;
13976 }
13977
13978 // protect non-atomic access to _server_connection.event_sock. K.O.
13979
13980 std::lock_guard<std::mutex> guard(_server_connection.event_sock_mutex);
13981
13982 //printf("rpc_send_event_sg: pevent %p, event_id 0x%04x, serial 0x%08x, data_size %d, event_size %d, total_size %d\n", pevent, pevent->event_id, pevent->serial_number, (int)data_size, (int)event_size, (int)total_size);
13983
13984 if (_server_connection.event_sock == 0) {
13985 return RPC_NO_CONNECTION;
13986 }
13987
13988 //
13989 // event socket wire protocol: (see also rpc_server_receive_event() and recv_event_server_realloc())
13990 //
13991 // 4 bytes of buffer handle
13992 // 16 bytes of event header, includes data_size
13993 // ALIGN8(data_size) bytes of event data
13994 //
13995
13996 int status;
13997
13998 /* send buffer handle */
13999
14000 assert(sizeof(DWORD) == 4);
14001 DWORD bh_buf = buffer_handle;
14002
14003 status = ss_write_tcp(_server_connection.event_sock, (const char *) &bh_buf, sizeof(DWORD));
14004 if (status != SS_SUCCESS) {
14006 cm_msg(MERROR, "rpc_send_event_sg", "ss_write_tcp(buffer handle) failed, event socket is now closed");
14007 return RPC_NET_ERROR;
14008 }
14009
14010 /* send data */
14011
14012 for (int i=0; i<sg_n; i++) {
14014 if (status != SS_SUCCESS) {
14016 cm_msg(MERROR, "rpc_send_event_sg", "ss_write_tcp(event data) failed, event socket is now closed");
14017 return RPC_NET_ERROR;
14018 }
14019 }
14020
14021 /* send padding */
14022
14023 if (count < total_size) {
14024 char padding[8] = { 0,0,0,0,0,0,0,0 };
14025 size_t padlen = total_size - count;
14026 assert(padlen < 8);
14028 if (status != SS_SUCCESS) {
14030 cm_msg(MERROR, "rpc_send_event_sg", "ss_write_tcp(padding) failed, event socket is now closed");
14031 return RPC_NET_ERROR;
14032 }
14033 }
14034
14035 return RPC_SUCCESS;
14036}
#define BM_INVALID_SIZE
Definition midas.h:624
INT ss_write_tcp(int sock, const char *buffer, size_t buffer_size)
Definition system.cxx:5352
double count
Definition mdump.cxx:33
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_server_accept()

INT rpc_server_accept ( int  lsock)

Definition at line 15349 of file midas.cxx.

15370{
15371 INT i;
15372 INT sock;
15373 char version[NAME_LENGTH], v1[32];
15374 char experiment[NAME_LENGTH];
15375 INT port1, port2, port3;
15376 char *ptr;
15377 char net_buffer[256];
15378 struct linger ling;
15379
15380 static struct callback_addr callback;
15381
15382 if (lsock > 0) {
15383 sock = accept(lsock, NULL, NULL);
15384
15385 if (sock == -1)
15386 return RPC_NET_ERROR;
15387 } else {
15388 /* lsock is stdin -> already connected from inetd */
15389
15390 sock = lsock;
15391 }
15392
15393 /* check access control list */
15396
15397 if (status != RPC_SUCCESS) {
15398 ss_socket_close(&sock);
15399 return RPC_NET_ERROR;
15400 }
15401 }
15402
15403 /* receive string with timeout */
15404 i = recv_string(sock, net_buffer, 256, 10000);
15405 rpc_debug_printf("Received command: %s", net_buffer);
15406
15407 if (i > 0) {
15408 char command = (char) toupper(net_buffer[0]);
15409
15410 //printf("rpc_server_accept: command [%c]\n", command);
15411
15412 switch (command) {
15413 case 'S': {
15414
15415 /*----------- shutdown listener ----------------------*/
15416 ss_socket_close(&sock);
15417 return RPC_SHUTDOWN;
15418 }
15419 case 'I': {
15420
15421 /*----------- return available experiments -----------*/
15422#ifdef LOCAL_ROUTINES
15423 exptab_struct exptab;
15424 cm_read_exptab(&exptab); // thread safe!
15425 for (unsigned i=0; i<exptab.exptab.size(); i++) {
15426 rpc_debug_printf("Return experiment: %s", exptab.exptab[i].name.c_str());
15427 const char* str = exptab.exptab[i].name.c_str();
15428 send(sock, str, strlen(str) + 1, 0);
15429 }
15430 send(sock, "", 1, 0);
15431#endif
15432 ss_socket_close(&sock);
15433 break;
15434 }
15435 case 'C': {
15436
15437 /*----------- connect to experiment -----------*/
15438
15439 /* get callback information */
15440 callback.experiment[0] = 0;
15441 port1 = port2 = version[0] = 0;
15442
15443 //printf("rpc_server_accept: net buffer \'%s\'\n", net_buffer);
15444
15445 /* parse string in format "C port1 port2 port3 version expt" */
15446 /* example: C 51046 45838 56832 2.0.0 alpha */
15447
15448 port1 = strtoul(net_buffer + 2, &ptr, 0);
15449 port2 = strtoul(ptr, &ptr, 0);
15450 port3 = strtoul(ptr, &ptr, 0);
15451
15452 while (*ptr == ' ')
15453 ptr++;
15454
15455 i = 0;
15456 for (; *ptr != 0 && *ptr != ' ' && i < (int) sizeof(version) - 1;)
15457 version[i++] = *ptr++;
15458
15459 // ensure that we do not overwrite buffer "version"
15460 assert(i < (int) sizeof(version));
15461 version[i] = 0;
15462
15463 // skip wjatever is left from the "version" string
15464 for (; *ptr != 0 && *ptr != ' ';)
15465 ptr++;
15466
15467 while (*ptr == ' ')
15468 ptr++;
15469
15470 i = 0;
15471 for (; *ptr != 0 && *ptr != ' ' && *ptr != '\n' && *ptr != '\r' && i < (int) sizeof(experiment) - 1;)
15472 experiment[i++] = *ptr++;
15473
15474 // ensure that we do not overwrite buffer "experiment"
15475 assert(i < (int) sizeof(experiment));
15476 experiment[i] = 0;
15477
15479
15480 /* print warning if version patch level doesn't agree */
15481 mstrlcpy(v1, version, sizeof(v1));
15482 if (strchr(v1, '.'))
15483 if (strchr(strchr(v1, '.') + 1, '.'))
15484 *strchr(strchr(v1, '.') + 1, '.') = 0;
15485
15486 char str[100];
15487 mstrlcpy(str, cm_get_version(), sizeof(str));
15488 if (strchr(str, '.'))
15489 if (strchr(strchr(str, '.') + 1, '.'))
15490 *strchr(strchr(str, '.') + 1, '.') = 0;
15491
15492 if (strcmp(v1, str) != 0) {
15493 cm_msg(MERROR, "rpc_server_accept", "client MIDAS version %s differs from local version %s", version, cm_get_version());
15494 cm_msg(MERROR, "rpc_server_accept", "received string: %s", net_buffer + 2);
15495 }
15496
15501
15503
15504 if (status != SS_SUCCESS) {
15505 ss_socket_close(&sock);
15506 break;
15507 }
15508
15509#ifdef LOCAL_ROUTINES
15510 /* update experiment definition */
15511 exptab_struct exptab;
15512 cm_read_exptab(&exptab); // thread safe!
15513
15514 unsigned idx = 0;
15515 bool found = false;
15516 /* lookup experiment */
15517 if (equal_ustring(callback.experiment.c_str(), "Default")) {
15518 found = true;
15519 idx = 0;
15520 } else {
15521 for (idx = 0; idx < exptab.exptab.size(); idx++) {
15522 if (exptab.exptab[idx].name == callback.experiment) {
15523 if (ss_dir_exist(exptab.exptab[idx].directory.c_str())) {
15524 found = true;
15525 break;
15526 }
15527 }
15528 }
15529 }
15530
15531 if (!found) {
15532 cm_msg(MERROR, "rpc_server_accept", "experiment \'%s\' not defined in exptab file \'%s\'", callback.experiment.c_str(), exptab.filename.c_str());
15533
15534 send(sock, "2", 2, 0); /* 2 means exp. not found */
15535 ss_socket_close(&sock);
15536 break;
15537 }
15538
15539 callback.directory = exptab.exptab[idx].directory;
15540 callback.user = exptab.exptab[idx].user;
15541
15542 /* create a new process */
15543 char host_port1_str[30], host_port2_str[30], host_port3_str[30];
15544 char debug_str[30];
15545
15550
15551 const char *mserver_path = rpc_get_mserver_path();
15552
15553 const char *argv[10];
15554 argv[0] = mserver_path;
15555 argv[1] = callback.host_name.c_str();
15556 argv[2] = host_port1_str;
15557 argv[3] = host_port2_str;
15558 argv[4] = host_port3_str;
15559 argv[5] = debug_str;
15560 argv[6] = callback.experiment.c_str();
15561 argv[7] = callback.directory.c_str();
15562 argv[8] = callback.user.c_str();
15563 argv[9] = NULL;
15564
15565 rpc_debug_printf("Spawn: %s %s %s %s %s %s %s %s %s %s",
15566 argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8],
15567 argv[9]);
15568
15570
15571 if (status != SS_SUCCESS) {
15572 rpc_debug_printf("Cannot spawn subprocess: %s\n", strerror(errno));
15573
15574 sprintf(str, "3"); /* 3 means cannot spawn subprocess */
15575 send(sock, str, strlen(str) + 1, 0);
15576 ss_socket_close(&sock);
15577 break;
15578 }
15579
15580 sprintf(str, "1 %s", cm_get_version()); /* 1 means ok */
15581 send(sock, str, strlen(str) + 1, 0);
15582#endif // LOCAL_ROUTINES
15583 ss_socket_close(&sock);
15584
15585 break;
15586 }
15587 default: {
15588 cm_msg(MERROR, "rpc_server_accept", "received unknown command '%c' code %d", command, command);
15589 ss_socket_close(&sock);
15590 break;
15591 }
15592 }
15593 } else { /* if i>0 */
15594
15595 /* lingering needed for PCTCP */
15596 ling.l_onoff = 1;
15597 ling.l_linger = 0;
15598 setsockopt(sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
15599 ss_socket_close(&sock);
15600 }
15601
15602 return RPC_SUCCESS;
15603}
INT cm_read_exptab(exptab_struct *exptab)
Definition midas.cxx:1614
INT ss_socket_get_peer_name(int sock, std::string *hostp, int *portp)
Definition system.cxx:5246
int ss_dir_exist(const char *path)
Definition system.cxx:7192
INT ss_spawnv(INT mode, const char *cmdname, const char *const argv[])
Definition system.cxx:1630
const char * rpc_get_mserver_path()
Definition midas.cxx:13059
#define NAME_LENGTH
Definition midas.h:272
struct callback_addr callback
Definition mserver.cxx:22
unsigned short host_port1
Definition msystem.h:312
std::string user
Definition msystem.h:318
unsigned short host_port2
Definition msystem.h:313
std::string experiment
Definition msystem.h:316
unsigned short host_port3
Definition msystem.h:314
std::string directory
Definition msystem.h:317
std::string host_name
Definition msystem.h:311
std::string filename
Definition midas.cxx:1601
std::vector< exptab_entry > exptab
Definition midas.cxx:1602
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_server_callback()

INT rpc_server_callback ( struct callback_addr pcallback)

Definition at line 15710 of file midas.cxx.

15729{
15730 INT status;
15731 int recv_sock, send_sock, event_sock;
15732 char str[100];
15733 std::string client_program;
15735 INT convert_flags;
15736 char net_buffer[256];
15737 char *p;
15738 int flag;
15739
15740 /* copy callback information */
15742 //idx = callback.index;
15743
15744 std::string errmsg;
15745
15746 /* create new sockets for TCP */
15748
15749 if (status != SS_SUCCESS) {
15750 cm_msg(MERROR, "rpc_server_callback", "cannot connect receive socket, host \"%s\", port %d: %s", callback.host_name.c_str(), callback.host_port1, errmsg.c_str());
15751 ss_socket_close(&recv_sock);
15752 //ss_socket_close(&send_sock);
15753 //ss_socket_close(&event_sock);
15754 return RPC_NET_ERROR;
15755 }
15756
15758
15759 if (status != SS_SUCCESS) {
15760 cm_msg(MERROR, "rpc_server_callback", "cannot connect send socket, host \"%s\", port %d: %s", callback.host_name.c_str(), callback.host_port2, errmsg.c_str());
15761 ss_socket_close(&recv_sock);
15762 ss_socket_close(&send_sock);
15763 //ss_socket_close(&event_sock);
15764 return RPC_NET_ERROR;
15765 }
15766
15768
15769 if (status != SS_SUCCESS) {
15770 cm_msg(MERROR, "rpc_server_callback", "cannot connect event socket, host \"%s\", port %d: %s", callback.host_name.c_str(), callback.host_port2, errmsg.c_str());
15771 ss_socket_close(&recv_sock);
15772 ss_socket_close(&send_sock);
15773 ss_socket_close(&event_sock);
15774 return RPC_NET_ERROR;
15775 }
15776#ifndef OS_ULTRIX /* crashes ULTRIX... */
15777 /* increase send buffer size to 2 Mbytes, on Linux also limited by sysctl net.ipv4.tcp_rmem and net.ipv4.tcp_wmem */
15778 flag = 2 * 1024 * 1024;
15779 status = setsockopt(event_sock, SOL_SOCKET, SO_RCVBUF, (char *) &flag, sizeof(INT));
15780 if (status != 0)
15781 cm_msg(MERROR, "rpc_server_callback", "cannot setsockopt(SOL_SOCKET, SO_RCVBUF), errno %d (%s)", errno,
15782 strerror(errno));
15783#endif
15784
15785 if (recv_string(recv_sock, net_buffer, 256, _rpc_connect_timeout) <= 0) {
15786 cm_msg(MERROR, "rpc_server_callback", "timeout on receive remote computer info");
15787 ss_socket_close(&recv_sock);
15788 ss_socket_close(&send_sock);
15789 ss_socket_close(&event_sock);
15790 return RPC_NET_ERROR;
15791 }
15792 //printf("rpc_server_callback: \'%s\'\n", net_buffer);
15793
15794 /* get remote computer info */
15795 client_hw_type = strtoul(net_buffer, &p, 0);
15796
15797 while (*p == ' ')
15798 p++;
15799
15800 client_program = p;
15801
15802 //printf("hw type %d, name \'%s\'\n", client_hw_type, client_program);
15803
15804 std::string host_name;
15805
15807
15808 if (status != SS_SUCCESS)
15809 host_name = "unknown";
15810
15811 //printf("rpc_server_callback: mserver acception\n");
15812
15814
15815 /* save information in _server_acception structure */
15816 sa->recv_sock = recv_sock;
15817 sa->send_sock = send_sock;
15818 sa->event_sock = event_sock;
15820 sa->host_name = host_name;
15823 sa->watchdog_timeout = 0;
15824 sa->is_mserver = TRUE;
15825
15826 assert(_mserver_acception == NULL);
15827
15828 _mserver_acception = sa;
15829
15830 //printf("rpc_server_callback: _mserver_acception %p\n", _mserver_acception);
15831
15832 /* send my own computer id */
15834 sprintf(str, "%d", hw_type);
15835 send(recv_sock, str, strlen(str) + 1, 0);
15836
15838 sa->convert_flags = convert_flags;
15839
15841
15842 if (rpc_is_mserver()) {
15843 rpc_debug_printf("Connection to %s:%s established\n", sa->host_name.c_str(), sa->prog_name.c_str());
15844 }
15845
15846 return RPC_SUCCESS;
15847}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_server_connect()

INT rpc_server_connect ( const char host_name,
const char exp_name 
)

Definition at line 12389 of file midas.cxx.

12417{
12418 INT i, status;
12419 INT remote_hw_type, hw_type;
12420 char str[200], version[32], v1[32];
12422 struct timeval timeout;
12423 int port = MIDAS_TCP_PORT;
12424 char *s;
12425
12426#ifdef OS_WINNT
12427 {
12429
12430 /* Start windows sockets */
12431 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
12432 return RPC_NET_ERROR;
12433 }
12434#endif
12435
12436 /* check if local connection */
12437 if (host_name[0] == 0)
12438 return RPC_SUCCESS;
12439
12440 /* register system functions */
12442
12443 /* check if cm_connect_experiment was called */
12444 if (_client_name.length() == 0) {
12445 cm_msg(MERROR, "rpc_server_connect", "cm_connect_experiment/rpc_set_name not called");
12446 return RPC_NOT_REGISTERED;
12447 }
12448
12449 /* check if connection already exists */
12451 return RPC_SUCCESS;
12452
12456
12457 bool listen_localhost = false;
12458
12459 if (strcmp(host_name, "localhost") == 0)
12460 listen_localhost = true;
12461
12462 int lsock1, lport1;
12463 int lsock2, lport2;
12464 int lsock3, lport3;
12465
12466 std::string errmsg;
12467
12469
12470 if (status != SS_SUCCESS) {
12471 cm_msg(MERROR, "rpc_server_connect", "cannot create listener socket: %s", errmsg.c_str());
12472 return RPC_NET_ERROR;
12473 }
12474
12476
12477 if (status != SS_SUCCESS) {
12478 cm_msg(MERROR, "rpc_server_connect", "cannot create listener socket: %s", errmsg.c_str());
12479 return RPC_NET_ERROR;
12480 }
12481
12483
12484 if (status != SS_SUCCESS) {
12485 cm_msg(MERROR, "rpc_server_connect", "cannot create listener socket: %s", errmsg.c_str());
12486 return RPC_NET_ERROR;
12487 }
12488
12489 /* extract port number from host_name */
12490 mstrlcpy(str, host_name, sizeof(str));
12491 s = strchr(str, ':');
12492 if (s) {
12493 *s = 0;
12494 port = strtoul(s + 1, NULL, 0);
12495 }
12496
12497 int sock;
12498
12499 status = ss_socket_connect_tcp(str, port, &sock, &errmsg);
12500
12501 if (status != SS_SUCCESS) {
12502 cm_msg(MERROR, "rpc_server_connect", "cannot connect to mserver on host \"%s\" port %d: %s", str, port, errmsg.c_str());
12503 return RPC_NET_ERROR;
12504 }
12505
12506 /* connect to experiment */
12507 if (exp_name[0] == 0)
12508 sprintf(str, "C %d %d %d %s Default", lport1, lport2, lport3, cm_get_version());
12509 else
12510 sprintf(str, "C %d %d %d %s %s", lport1, lport2, lport3, cm_get_version(), exp_name);
12511
12512 send(sock, str, strlen(str) + 1, 0);
12513 i = recv_string(sock, str, sizeof(str), _rpc_connect_timeout);
12514 ss_socket_close(&sock);
12515 if (i <= 0) {
12516 cm_msg(MERROR, "rpc_server_connect", "timeout on receive status from server");
12517 return RPC_NET_ERROR;
12518 }
12519
12520 status = version[0] = 0;
12521 sscanf(str, "%d %s", &status, version);
12522
12523 if (status == 2) {
12524/* message "undefined experiment" should be displayed by application */
12525 return CM_UNDEF_EXP;
12526 }
12527
12528 /* print warning if version patch level doesn't agree */
12529 strcpy(v1, version);
12530 if (strchr(v1, '.'))
12531 if (strchr(strchr(v1, '.') + 1, '.'))
12532 *strchr(strchr(v1, '.') + 1, '.') = 0;
12533
12534 strcpy(str, cm_get_version());
12535 if (strchr(str, '.'))
12536 if (strchr(strchr(str, '.') + 1, '.'))
12537 *strchr(strchr(str, '.') + 1, '.') = 0;
12538
12539 if (strcmp(v1, str) != 0) {
12540 cm_msg(MERROR, "rpc_server_connect", "remote MIDAS version \'%s\' differs from local version \'%s\'", version,
12541 cm_get_version());
12542 }
12543
12544 /* wait for callback on send and recv socket with timeout */
12545 FD_ZERO(&readfds);
12549
12550 timeout.tv_sec = _rpc_connect_timeout / 1000;
12551 timeout.tv_usec = 0;
12552
12553 do {
12554 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
12555
12556 /* if an alarm signal was cought, restart select with reduced timeout */
12557 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
12558 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
12559
12560 } while (status == -1); /* dont return if an alarm signal was cought */
12561
12562 if (!FD_ISSET(lsock1, &readfds)) {
12563 cm_msg(MERROR, "rpc_server_connect", "mserver subprocess could not be started (check path)");
12567 return RPC_NET_ERROR;
12568 }
12569
12573
12575 cm_msg(MERROR, "rpc_server_connect", "accept() failed");
12576 return RPC_NET_ERROR;
12577 }
12578
12582
12583 /* set TCP_NODELAY option for better performance */
12584 int flag = 1;
12587
12588 /* increase send buffer size to 2 Mbytes, on Linux also limited by sysctl net.ipv4.tcp_rmem and net.ipv4.tcp_wmem */
12589 flag = 2 * 1024 * 1024;
12591 if (status != 0)
12592 cm_msg(MERROR, "rpc_server_connect", "cannot setsockopt(SOL_SOCKET, SO_SNDBUF), errno %d (%s)", errno, strerror(errno));
12593
12594 /* send local computer info */
12595 std::string local_prog_name = rpc_get_name();
12597 sprintf(str, "%d %s", hw_type, local_prog_name.c_str());
12598
12600
12601 /* receive remote computer info */
12603 if (i <= 0) {
12604 cm_msg(MERROR, "rpc_server_connect", "timeout on receive remote computer info");
12605 return RPC_NET_ERROR;
12606 }
12607
12608 sscanf(str, "%d", &remote_hw_type);
12609 _server_connection.remote_hw_type = remote_hw_type;
12610
12612
12613 _rpc_is_remote = true;
12614
12615 return RPC_SUCCESS;
12616}
#define CM_UNDEF_EXP
Definition midas.h:586
INT ss_suspend_set_client_connection(RPC_SERVER_CONNECTION *connection)
Definition system.cxx:4291
char exp_name[NAME_LENGTH]
Definition mana.cxx:243
#define MIDAS_TCP_PORT
Definition midas.h:283
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_server_disconnect()

INT rpc_server_disconnect ( void  )

Definition at line 12713 of file midas.cxx.

12733{
12735
12737 return RPC_SUCCESS;
12738
12740
12741 /* flush remaining events */
12743
12744 /* notify server about exit */
12745 if (rpc_is_connected()) {
12747 }
12748
12749 /* close sockets */
12756
12758
12759 /* remove semaphore */
12760 if (_mutex_rpc)
12762 _mutex_rpc = NULL;
12763
12765 return RPC_SUCCESS;
12766}
INT ss_mutex_delete(MUTEX_T *mutex)
Definition system.cxx:3211
bool rpc_is_connected(void)
Definition midas.cxx:12791
INT rpc_call(DWORD routine_id,...)
Definition midas.cxx:13671
INT rpc_flush_event()
Definition midas.cxx:14046
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_server_loop()

INT rpc_server_loop ( void  )

Definition at line 15851 of file midas.cxx.

15859{
15860 while (1) {
15861 int status = ss_suspend(1000, 0);
15862
15863 if (status == SS_ABORT || status == SS_EXIT)
15864 break;
15865
15867 break;
15868
15869 /* check alarms, etc */
15871
15873 }
15874
15875 return RPC_SUCCESS;
15876}
INT cm_periodic_tasks()
Definition midas.cxx:5587
INT cm_msg_flush_buffer()
Definition midas.cxx:865
INT rpc_check_channels(void)
Definition midas.cxx:16262
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_server_receive_event()

INT rpc_server_receive_event ( int  idx,
RPC_SERVER_ACCEPTION sa,
int  timeout_msec 
)

Definition at line 15989 of file midas.cxx.

16003{
16004 int status = 0;
16005
16006 DWORD start_time = ss_millitime();
16007
16008 //
16009 // THIS IS NOT THREAD SAFE!!!
16010 //
16011 // IT IS ONLY USED BY THE MSERVER
16012 // MSERVER IS SINGLE-THREADED!!!
16013 //
16014
16015 static char *xbuf = NULL;
16016 static int xbufsize = 0;
16017 static bool xbufempty = true;
16018
16019 // short cut
16020 if (sa == NULL && xbufempty)
16021 return RPC_SUCCESS;
16022
16023 static bool recurse = false;
16024
16025 if (recurse) {
16026 cm_msg(MERROR, "rpc_server_receive_event", "internal error: called recursively");
16027 // do not do anything if we are called recursively
16028 // via recursive ss_suspend() or otherwise. K.O.
16029 if (xbufempty)
16030 return RPC_SUCCESS;
16031 else
16032 return BM_ASYNC_RETURN;
16033 }
16034
16035 recurse = true;
16036
16037 do {
16038 if (xbufempty && sa) {
16040
16041 if (n_received < 0) {
16042 status = SS_ABORT;
16043 cm_msg(MERROR, "rpc_server_receive_event", "recv_event_server_realloc() returned %d, abort", n_received);
16044 goto error;
16045 }
16046
16047 if (n_received == 0) {
16048 // no more data in the tcp socket
16049 recurse = false;
16050 return RPC_SUCCESS;
16051 }
16052
16053 xbufempty = false;
16054 }
16055
16056 if (xbufempty) {
16057 // no event in xbuf buffer
16058 recurse = false;
16059 return RPC_SUCCESS;
16060 }
16061
16062 /* send event to buffer */
16063 INT *pbh = (INT *) xbuf;
16064 EVENT_HEADER *pevent = (EVENT_HEADER *) (pbh + 1);
16065
16066 status = bm_send_event(*pbh, pevent, 0, timeout_msec);
16067
16068 //printf("rpc_server_receiv: buffer_handle %d, event_id 0x%04x, serial 0x%08x, data_size %d, status %d\n", *pbh, pevent->event_id, pevent->serial_number, pevent->data_size, status);
16069
16070 if (status == SS_ABORT) {
16071 cm_msg(MERROR, "rpc_server_receive_event", "bm_send_event() error %d (SS_ABORT), abort", status);
16072 goto error;
16073 }
16074
16075 if (status == BM_ASYNC_RETURN) {
16076 //cm_msg(MERROR, "rpc_server_receive_event", "bm_send_event() error %d, event buffer is full", status);
16077 recurse = false;
16078 return status;
16079 }
16080
16081 if (status != BM_SUCCESS) {
16082 cm_msg(MERROR, "rpc_server_receive_event", "bm_send_event() error %d, mserver dropped this event", status);
16083 }
16084
16085 xbufempty = true;
16086
16087 /* repeat for maximum 0.5 sec */
16088 } while (ss_millitime() - start_time < 500);
16089
16090 recurse = false;
16091 return RPC_SUCCESS;
16092
16093 error:
16094
16095 {
16096 char str[80];
16097 mstrlcpy(str, sa->host_name.c_str(), sizeof(str));
16098 if (strchr(str, '.'))
16099 *strchr(str, '.') = 0;
16100 cm_msg(MTALK, "rpc_server_receive_event", "Program \'%s\' on host \'%s\' aborted", sa->prog_name.c_str(), str);
16101 }
16102
16103 //exit:
16104
16106
16107 /* disconnect from experiment as MIDAS server */
16108 if (rpc_is_mserver()) {
16109 HNDLE hDB, hKey;
16110
16112
16113 /* only disconnect from experiment if previously connected.
16114 Necessary for pure RPC servers (RPC_SRVR) */
16115 if (hDB) {
16119
16121
16123 }
16124 }
16125
16126 bool is_mserver = sa->is_mserver;
16127
16128 sa->close();
16129
16130 /* signal caller a shutdonw */
16131 if (status == RPC_SHUTDOWN)
16132 return status;
16133
16134 /* only the mserver should stop on server connection closure */
16135 if (!is_mserver) {
16136 return SS_SUCCESS;
16137 }
16138
16139 return status;
16140}
INT bm_close_all_buffers(void)
Definition midas.cxx:7251
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition midas.cxx:3011
INT cm_delete_client_info(HNDLE hDB, INT pid)
Definition midas.cxx:1852
INT cm_set_experiment_database(HNDLE hDB, HNDLE hKeyClient)
Definition midas.cxx:2939
#define MTALK
Definition midas.h:564
INT db_close_all_databases(void)
Definition odb.cxx:2360
static int recv_event_server_realloc(INT idx, RPC_SERVER_ACCEPTION *psa, char **pbuffer, int *pbuffer_size)
Definition midas.cxx:14395
INT rpc_deregister_functions()
Definition midas.cxx:11878
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_server_receive_rpc()

INT rpc_server_receive_rpc ( int  idx,
RPC_SERVER_ACCEPTION sa 
)

Definition at line 15879 of file midas.cxx.

15894{
15895 int status = 0;
15896 int remaining = 0;
15897
15898 char *buf = NULL;
15899 int bufsize = 0;
15900
15901 do {
15903
15904 if (n_received <= 0) {
15905 status = SS_ABORT;
15906 cm_msg(MERROR, "rpc_server_receive_rpc", "recv_net_command() returned %d, abort", n_received);
15907 goto error;
15908 }
15909
15910 status = rpc_execute(sa->recv_sock, buf, sa->convert_flags);
15911
15912 if (status == SS_ABORT) {
15913 cm_msg(MERROR, "rpc_server_receive_rpc", "rpc_execute() returned %d, abort", status);
15914 goto error;
15915 }
15916
15917 if (status == SS_EXIT || status == RPC_SHUTDOWN) {
15918 if (rpc_is_mserver())
15919 rpc_debug_printf("Connection to %s:%s closed\n", sa->host_name.c_str(), sa->prog_name.c_str());
15920 goto exit;
15921 }
15922
15923 } while (remaining);
15924
15925 if (buf) {
15926 free(buf);
15927 buf = NULL;
15928 bufsize = 0;
15929 }
15930
15931 return RPC_SUCCESS;
15932
15933 error:
15934
15935 {
15936 char str[80];
15937 mstrlcpy(str, sa->host_name.c_str(), sizeof(str));
15938 if (strchr(str, '.'))
15939 *strchr(str, '.') = 0;
15940 cm_msg(MTALK, "rpc_server_receive_rpc", "Program \'%s\' on host \'%s\' aborted", sa->prog_name.c_str(), str);
15941 }
15942
15943 exit:
15944
15946
15947 if (buf) {
15948 free(buf);
15949 buf = NULL;
15950 bufsize = 0;
15951 }
15952
15953 /* disconnect from experiment as MIDAS server */
15954 if (rpc_is_mserver()) {
15955 HNDLE hDB, hKey;
15956
15958
15959 /* only disconnect from experiment if previously connected.
15960 Necessary for pure RPC servers (RPC_SRVR) */
15961 if (hDB) {
15965
15967
15969 }
15970 }
15971
15972 bool is_mserver = sa->is_mserver;
15973
15974 sa->close();
15975
15976 /* signal caller a shutdonw */
15977 if (status == RPC_SHUTDOWN)
15978 return status;
15979
15980 /* only the mserver should stop on server connection closure */
15981 if (!is_mserver) {
15982 return SS_SUCCESS;
15983 }
15984
15985 return status;
15986}
INT rpc_execute(INT sock, char *buffer, INT convert_flags)
Definition midas.cxx:14658
static int recv_net_command_realloc(INT idx, char **pbuf, int *pbufsize, INT *remaining)
Definition midas.cxx:14205
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_server_shutdown()

INT rpc_server_shutdown ( void  )

Definition at line 16191 of file midas.cxx.

16208{
16209 //printf("rpc_server_shutdown!\n");
16210
16211 struct linger ling;
16212
16213 /* close all open connections */
16214 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
16215 if (_server_acceptions[idx] && _server_acceptions[idx]->recv_sock != 0) {
16217 /* lingering needed for PCTCP */
16218 ling.l_onoff = 1;
16219 ling.l_linger = 0;
16220 setsockopt(sa->recv_sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
16222
16223 if (sa->send_sock) {
16224 setsockopt(sa->send_sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
16226 }
16227
16228 if (sa->event_sock) {
16229 setsockopt(sa->event_sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
16231 }
16232 }
16233 }
16234
16235 /* avoid memory leak */
16236 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
16238 if (sa) {
16239 //printf("rpc_server_shutdown: %d %p %p\n", idx, sa, _mserver_acception);
16240 if (sa == _mserver_acception) {
16241 // do not leave behind a stale pointer!
16243 }
16244 delete sa;
16246 }
16247 }
16248
16249 if (_rpc_registered) {
16252 }
16253
16254 /* free suspend structures */
16256
16257 return RPC_SUCCESS;
16258}
INT ss_suspend_exit()
Definition system.cxx:4226
static BOOL _rpc_registered
Definition midas.cxx:258
static int _rpc_listen_socket
Definition midas.cxx:259
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_set_debug()

INT rpc_set_debug ( void(*)(const char *)  func,
INT  mode 
)

Definition at line 13142 of file midas.cxx.

13162{
13163 _debug_print = func;
13164 _debug_mode = mode;
13165 return RPC_SUCCESS;
13166}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_set_mserver_path()

INT rpc_set_mserver_path ( const char path)

Definition at line 13072 of file midas.cxx.

13086{
13087 _mserver_path = path;
13088 return RPC_SUCCESS;
13089}
Here is the caller graph for this function:

◆ rpc_set_name()

INT rpc_set_name ( const char name)

Definition at line 13116 of file midas.cxx.

13134{
13136
13137 return RPC_SUCCESS;
13138}
Here is the caller graph for this function:

◆ rpc_set_opt_tcp_size()

INT rpc_set_opt_tcp_size ( INT  tcp_size)

Definition at line 13872 of file midas.cxx.

13872 {
13873 INT old;
13874
13877 return old;
13878}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_set_timeout()

INT rpc_set_timeout ( HNDLE  hConn,
int  timeout_msec,
int old_timeout_msec 
)

Set RPC timeout

Parameters
hConnRPC connection handle, RPC_HNDLE_MSERVER for mserver connection, RPC_HNDLE_CONNECT for rpc connect timeout
timeout_msecRPC timeout in milliseconds
old_timeout_msecreturns old value of RPC timeout in milliseconds
Returns
RPC_SUCCESS

Definition at line 13006 of file midas.cxx.

13007{
13008 //printf("rpc_set_timeout: hConn %d, timeout_msec %d\n", hConn, timeout_msec);
13009
13010 if (hConn == RPC_HNDLE_MSERVER) {
13011 if (old_timeout_msec)
13014 } else if (hConn == RPC_HNDLE_CONNECT) {
13015 if (old_timeout_msec)
13018 } else {
13020 if (c) {
13021 if (old_timeout_msec)
13022 *old_timeout_msec = c->rpc_timeout;
13023 c->rpc_timeout = timeout_msec;
13024 c->mutex.unlock();
13025 } else {
13026 if (old_timeout_msec)
13027 *old_timeout_msec = 0;
13028 }
13029 }
13030 return RPC_SUCCESS;
13031}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_socket_check_allowed_host()

static INT rpc_socket_check_allowed_host ( int  sock)
static

Definition at line 15321 of file midas.cxx.

15322{
15323 std::string hostname;
15324
15325 int status = ss_socket_get_peer_name(sock, &hostname, NULL);
15326
15327 if (status != SS_SUCCESS)
15328 return status;
15329
15330 status = rpc_check_allowed_host(hostname.c_str());
15331
15332 if (status == RPC_SUCCESS)
15333 return RPC_SUCCESS;
15334
15335 static std::atomic_int max_report(10);
15336 if (max_report > 0) {
15337 max_report--;
15338 if (max_report == 0) {
15339 cm_msg(MERROR, "rpc_socket_check_allowed_host", "rejecting connection from unallowed host \'%s\', this message will no longer be reported", hostname.c_str());
15340 } else {
15341 cm_msg(MERROR, "rpc_socket_check_allowed_host", "rejecting connection from unallowed host \'%s\'. Add this host to \"/Experiment/Security/RPC hosts/Allowed hosts\"", hostname.c_str());
15342 }
15343 }
15344
15345 return RPC_NET_ERROR;
15346}
INT rpc_check_allowed_host(const char *hostname)
Definition midas.cxx:15272
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_test_rpc()

int rpc_test_rpc ( )

Definition at line 15054 of file midas.cxx.

15070{
15071 int status = RPC_SUCCESS;
15072
15073 printf("rpc_test_rpc!\n");
15074
15075 int int_out = 0;
15076 int int_inout = 456;
15077
15078 char string_out[32];
15079 char string2_out[48];
15080
15081 char string_inout[25];
15082 strcpy(string_inout, "string_inout");
15083
15084 KEY struct_in;
15085
15086 struct_in.type = 111;
15087 struct_in.num_values = 222;
15088 strcpy(struct_in.name, "name");
15089 struct_in.last_written = 333;
15090
15093
15094 struct_inout.type = 111111;
15095 struct_inout.num_values = 222222;
15096 strcpy(struct_inout.name, "name_name");
15097 struct_inout.last_written = 333333;
15098
15100 size_t dwordarray_inout_size = sizeof(dwordarray_inout);
15101
15102 for (int i=0; i<10; i++) {
15103 dwordarray_inout[i] = i*10;
15104 }
15105
15106 char array_in[10];
15107
15108 for (size_t i=0; i<sizeof(array_in); i++) {
15109 array_in[i] = 'a' + i;
15110 }
15111
15112 char array_out[16];
15113 size_t array_out_size = sizeof(array_out);
15114
15116 123,
15117 &int_out,
15118 &int_inout,
15119 "test string",
15120 string_out, sizeof(string_out),
15121 string2_out, sizeof(string2_out),
15122 string_inout, sizeof(string_inout),
15123 &struct_in,
15124 &struct_out,
15125 &struct_inout,
15127 array_in, sizeof(array_in),
15129 );
15130
15131 printf("rpc_call(RPC_TEST2) status %d\n", status);
15132
15133 if (int_out != 789) {
15134 printf("int_out mismatch!\n");
15135 status = 0;
15136 }
15137
15138 if (int_inout != 456*2) {
15139 printf("int_inout mismatch!\n");
15140 status = 0;
15141 }
15142
15143 if (strcmp(string_out, "string_out") != 0) {
15144 printf("string_out mismatch [%s] vs [%s]\n", string_out, "string_out");
15145 status = 0;
15146 }
15147
15148 if (strcmp(string2_out, "second string_out") != 0) {
15149 printf("string2_out mismatch [%s] vs [%s]\n", string2_out, "second string_out");
15150 status = 0;
15151 }
15152
15153 if (strcmp(string_inout, "return string_inout") != 0) {
15154 printf("string_inout mismatch [%s] vs [%s]\n", string_inout, "return string_inout");
15155 status = 0;
15156 }
15157
15158 KEY* pkey;
15159
15160 pkey = &struct_in;
15161
15162 //printf("struct_in: type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
15163
15164 pkey = &struct_out;
15165
15166 if (pkey->type != 444 || pkey->num_values != 555 || strcmp(pkey->name, "out_name") || pkey->last_written != 666) {
15167 printf("struct_out mismatch: type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
15168 status = 0;
15169 }
15170
15171 pkey = &struct_inout;
15172
15173 if (pkey->type != 444444 || pkey->num_values != 555555 || strcmp(pkey->name, "inout_name") || pkey->last_written != 666666) {
15174 printf("struct_inout mismatch: type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
15175 status = 0;
15176 }
15177
15178#if 0
15179 if (dwordarray_inout_size != 4*5) {
15180 printf("dwordarray_inout_size mismatch %d vs %d\n", (int)dwordarray_inout_size, 4*5);
15181 status = 0;
15182 }
15183
15184 for (size_t i=0; i<dwordarray_inout_size/sizeof(uint32_t); i++) {
15185 printf("dwordarray_inout[%d] is %d\n", (int)i, dwordarray_inout[i]);
15186 }
15187#endif
15188
15189#if 0
15190 {RPC_TEST_CXX, "test_cxx",
15191 {{TID_INT32, RPC_IN},
15193 {TID_STRING, RPC_IN},
15197 {TID_STRUCT, RPC_IN | RPC_CXX, sizeof(KEY)},
15198 {TID_STRUCT, RPC_OUT | RPC_CXX, sizeof(KEY)},
15199 {TID_STRUCT, RPC_IN | RPC_OUT | RPC_CXX, sizeof(KEY)},
15203 {0}}},
15204#endif
15205
15206#if 0
15208#endif
15209
15210 return status;
15211}
#define RPC_TEST2
Definition mrpc.h:123
Definition midas.h:1026
DWORD type
Definition midas.h:1027
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_tid_name()

const char * rpc_tid_name ( INT  id)

Definition at line 11772 of file midas.cxx.

11772 {
11773 if (id >= 0 && id < TID_LAST)
11774 return tid_name[id];
11775 else
11776 return "<unknown>";
11777}
Here is the caller graph for this function:

◆ rpc_tid_name_old()

const char * rpc_tid_name_old ( INT  id)

Definition at line 11779 of file midas.cxx.

11779 {
11780 if (id >= 0 && id < TID_LAST)
11781 return tid_name_old[id];
11782 else
11783 return "<unknown>";
11784}
Here is the caller graph for this function:

◆ rpc_tid_size()

INT rpc_tid_size ( INT  id)

Definition at line 11765 of file midas.cxx.

11765 {
11766 if (id >= 0 && id < TID_LAST)
11767 return tid_size[id];
11768
11769 return 0;
11770}
static const int tid_size[]
Definition midas.cxx:66
Here is the caller graph for this function:

◆ rpc_transition_dispatch()

static INT rpc_transition_dispatch ( INT  idx,
void prpc_param[] 
)
static

Definition at line 14064 of file midas.cxx.

14083{
14084 /* erase error string */
14085 *(CSTRING(2)) = 0;
14086
14087 if (idx == RPC_RC_TRANSITION) {
14088 // find registered handler
14089 // NB: this code should match same code in cm_transition_call_direct()
14090 // NB: only use the first handler, this is how MIDAS always worked
14091 // NB: we could run all handlers, but we can return the status and error string of only one of them.
14092 _trans_table_mutex.lock();
14093 size_t n = _trans_table.size();
14094 _trans_table_mutex.unlock();
14095
14096 for (size_t i = 0; i < n; i++) {
14097 _trans_table_mutex.lock();
14099 _trans_table_mutex.unlock();
14100
14101 if (tt.transition == CINT(0) && tt.sequence_number == CINT(4)) {
14102 if (tt.func) {
14103 /* execute callback if defined */
14104 return tt.func(CINT(1), CSTRING(2));
14105 } else {
14106 std::lock_guard<std::mutex> guard(_tr_fifo_mutex);
14107 /* store transition in FIFO */
14112 _tr_fifo_wp = (_tr_fifo_wp + 1) % 10;
14113 // implicit unlock
14114 return RPC_SUCCESS;
14115 }
14116 }
14117 }
14118 // no handler for this transition
14119 cm_msg(MERROR, "rpc_transition_dispatch", "no handler for transition %d with sequence number %d", CINT(0), CINT(4));
14120 return CM_SUCCESS;
14121 } else {
14122 cm_msg(MERROR, "rpc_transition_dispatch", "received unrecognized command %d", idx);
14123 return RPC_INVALID_ID;
14124 }
14125}
#define CM_SUCCESS
Definition midas.h:582
#define RPC_RC_TRANSITION
Definition mrpc.h:116
static std::vector< TRANS_TABLE > _trans_table
Definition midas.cxx:248
static std::mutex _trans_table_mutex
Definition midas.cxx:247
#define CINT(_i)
Definition midas.h:1620
#define CSTRING(_i)
Definition midas.h:1644
time_t trans_time
Definition midas.cxx:14055
int sequence_number
Definition midas.cxx:14056
INT(* func)(INT, char *)
Definition midas.cxx:244
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_va_arg()

void rpc_va_arg ( va_list arg_ptr,
INT  arg_type,
void arg 
)

Definition at line 13201 of file midas.cxx.

13201 {
13202 switch (arg_type) {
13203 /* On the stack, the minimum parameter size is sizeof(int).
13204 To avoid problems on little endian systems, treat all
13205 smaller parameters as int's */
13206 case TID_UINT8:
13207 case TID_INT8:
13208 case TID_CHAR:
13209 case TID_UINT16:
13210 case TID_INT16:
13211 *((int *) arg) = va_arg(*arg_ptr, int);
13212 break;
13213
13214 case TID_INT32:
13215 case TID_BOOL:
13216 *((INT *) arg) = va_arg(*arg_ptr, INT);
13217 break;
13218
13219 case TID_UINT32:
13220 *((DWORD *) arg) = va_arg(*arg_ptr, DWORD);
13221 break;
13222
13223 /* float variables are passed as double by the compiler */
13224 case TID_FLOAT:
13225 *((float *) arg) = (float) va_arg(*arg_ptr, double);
13226 break;
13227
13228 case TID_DOUBLE:
13229 *((double *) arg) = va_arg(*arg_ptr, double);
13230 break;
13231
13232 case TID_ARRAY:
13233 *((char **) arg) = va_arg(*arg_ptr, char *);
13234 break;
13235 }
13236}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_vax2ieee_double()

void rpc_vax2ieee_double ( double var)

Definition at line 11650 of file midas.cxx.

11650 {
11651 unsigned short int i1, i2, i3, i4;
11652
11653 /* swap words */
11654 i1 = *((short int *) (var) + 3);
11655 i2 = *((short int *) (var) + 2);
11656 i3 = *((short int *) (var) + 1);
11657 i4 = *((short int *) (var));
11658
11659 /* correct exponent */
11660 if (i4 != 0)
11661 i4 -= 0x20;
11662
11663 *((short int *) (var) + 3) = i4;
11664 *((short int *) (var) + 2) = i3;
11665 *((short int *) (var) + 1) = i2;
11666 *((short int *) (var)) = i1;
11667}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_vax2ieee_float()

void rpc_vax2ieee_float ( float var)

Definition at line 11634 of file midas.cxx.

11634 {
11635 unsigned short int lo, hi;
11636
11637 /* swap hi and lo word */
11638 lo = *((short int *) (var) + 1);
11639 hi = *((short int *) (var));
11640
11641 /* correct exponent */
11642 if (hi != 0)
11643 hi -= 0x100;
11644
11645 *((short int *) (var) + 1) = hi;
11646 *((short int *) (var)) = lo;
11647
11648}
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ _client_connections

std::vector<RPC_CLIENT_CONNECTION*> _client_connections
static

Definition at line 11504 of file midas.cxx.

◆ _client_connections_mutex

std::mutex _client_connections_mutex
static

Definition at line 11503 of file midas.cxx.

◆ _mserver_acception

RPC_SERVER_ACCEPTION* _mserver_acception = NULL
static

Definition at line 11511 of file midas.cxx.

◆ _mserver_path

std::string _mserver_path
static

Definition at line 13056 of file midas.cxx.

◆ _opt_tcp_size

int _opt_tcp_size = OPT_TCP_SIZE
static

Definition at line 11584 of file midas.cxx.

◆ _rpc_is_remote

bool _rpc_is_remote = false
static

Definition at line 11507 of file midas.cxx.

◆ _server_acceptions

std::vector<RPC_SERVER_ACCEPTION*> _server_acceptions
static

Definition at line 11510 of file midas.cxx.

◆ _server_connection

RPC_SERVER_CONNECTION _server_connection
static

Definition at line 11506 of file midas.cxx.

◆ _tr_fifo

TR_FIFO _tr_fifo[10]
static

Definition at line 14060 of file midas.cxx.

◆ _tr_fifo_mutex

std::mutex _tr_fifo_mutex
static

Definition at line 14059 of file midas.cxx.

◆ _tr_fifo_rp

int _tr_fifo_rp = 0
static

Definition at line 14062 of file midas.cxx.

◆ _tr_fifo_wp

int _tr_fifo_wp = 0
static

Definition at line 14061 of file midas.cxx.

◆ gAllowedHosts

std::vector<std::string> gAllowedHosts
static

Definition at line 15214 of file midas.cxx.

◆ gAllowedHostsMutex

std::mutex gAllowedHostsMutex
static

Definition at line 15215 of file midas.cxx.

◆ rpc_list

std::vector<RPC_LIST> rpc_list
static

Definition at line 11581 of file midas.cxx.

◆ rpc_list_mutex

std::mutex rpc_list_mutex
static

Definition at line 11582 of file midas.cxx.

◆ tls_buffer

TLS_POINTER* tls_buffer = NULL
static

Definition at line 14654 of file midas.cxx.

◆ tls_size

int tls_size = 0
static

Definition at line 14655 of file midas.cxx.