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 11543 of file midas.cxx.

11544{
11545 //printf("RPC_SERVER_ACCEPTION::close: connection from %s program %s mserver %d\n", host_name.c_str(), prog_name.c_str(), is_mserver);
11546
11547 if (is_mserver) {
11548 assert(_mserver_acception == this);
11550 is_mserver = false;
11551 }
11552
11553 /* close server connection */
11554 if (recv_sock)
11556 if (send_sock)
11558 if (event_sock)
11560
11561 /* free TCP cache */
11562 if (net_buffer) {
11563 //printf("free net_buffer %p+%d\n", net_buffer, net_buffer_size);
11564 free(net_buffer);
11565 net_buffer = NULL;
11566 net_buffer_size = 0;
11567 }
11568
11569 /* mark this entry as invalid */
11570 clear();
11571}
INT ss_socket_close(int *sockp)
Definition system.cxx:5225
static RPC_SERVER_ACCEPTION * _mserver_acception
Definition midas.cxx:11503
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 14120 of file midas.cxx.

14144{
14145 std::lock_guard<std::mutex> guard(_tr_fifo_mutex);
14146
14147 if (_tr_fifo_wp == _tr_fifo_rp)
14148 return FALSE;
14149
14150 if (transition)
14152
14153 if (run_number)
14155
14156 if (trans_time)
14157 *trans_time = (int) _tr_fifo[_tr_fifo_rp].trans_time;
14158
14159 _tr_fifo_rp = (_tr_fifo_rp + 1) % 10;
14160
14161 // implicit unlock
14162 return TRUE;
14163}
#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:14054
static int _tr_fifo_wp
Definition midas.cxx:14053
static TR_FIFO _tr_fifo[10]
Definition midas.cxx:14052
static std::mutex _tr_fifo_mutex
Definition midas.cxx:14051
INT run_number[2]
Definition mana.cxx:246
#define TRUE
Definition midas.h:182
int transition
Definition midas.cxx:14045
int run_number
Definition midas.cxx:14046
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 11931 of file midas.cxx.

11931 {
11932 //printf("rpc_client_dispatch: MSG_ODB: packet size %d, expected %d\n", n, (int)(sizeof(NET_COMMAND_HEADER) + 4 * sizeof(INT)));
11933 if (n == sizeof(NET_COMMAND_HEADER) + 4 * sizeof(INT)) {
11934 /* update a changed record */
11935 HNDLE hDB = *((INT *) nc->param);
11936 HNDLE hKeyRoot = *((INT *) nc->param + 1);
11937 HNDLE hKey = *((INT *) nc->param + 2);
11938 int index = *((INT *) nc->param + 3);
11940 }
11941 return CM_VERSION_MISMATCH;
11942}
#define CM_VERSION_MISMATCH
Definition midas.h:587
INT db_update_record_local(INT hDB, INT hKeyRoot, INT hKey, int index)
Definition odb.cxx:13552
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 14387 of file midas.cxx.

14409{
14410 int sock = psa->event_sock;
14411
14412 //printf("recv_event_server: idx %d, buffer %p, buffer_size %d\n", idx, buffer, buffer_size);
14413
14414 const size_t header_size = (sizeof(EVENT_HEADER) + sizeof(INT));
14415
14416 char header_buf[header_size];
14417
14418 // First read the header.
14419 //
14420 // Data format is:
14421 // INT buffer handle (4 bytes)
14422 // EVENT_HEADER (16 bytes)
14423 // event data
14424 // ALIGN8() padding
14425 // ...next event
14426
14427 int hrd = recv_tcp2(sock, header_buf, header_size, 1);
14428
14429 if (hrd == 0) {
14430 // timeout waiting for data
14431 return 0;
14432 }
14433
14434 /* abort if connection broken */
14435 if (hrd < 0) {
14436 cm_msg(MERROR, "recv_event_server", "recv_tcp2(header) returned %d", hrd);
14437 return -1;
14438 }
14439
14440 if (hrd < (int) header_size) {
14441 int hrd1 = recv_tcp2(sock, header_buf + hrd, header_size - hrd, 0);
14442
14443 /* abort if connection broken */
14444 if (hrd1 <= 0) {
14445 cm_msg(MERROR, "recv_event_server", "recv_tcp2(more header) returned %d", hrd1);
14446 return -1;
14447 }
14448
14449 hrd += hrd1;
14450 }
14451
14452 /* abort if connection broken */
14453 if (hrd != (int) header_size) {
14454 cm_msg(MERROR, "recv_event_server", "recv_tcp2(header) returned %d instead of %d", hrd, (int) header_size);
14455 return -1;
14456 }
14457
14458 INT *pbh = (INT *) header_buf;
14459 EVENT_HEADER *pevent = (EVENT_HEADER *) (((INT *) header_buf) + 1);
14460
14461 /* convert header little endian/big endian */
14462 if (psa->convert_flags) {
14463 rpc_convert_single(&pbh, TID_INT32, 0, psa->convert_flags);
14464 rpc_convert_single(&pevent->event_id, TID_INT16, 0, psa->convert_flags);
14465 rpc_convert_single(&pevent->trigger_mask, TID_INT16, 0, psa->convert_flags);
14466 rpc_convert_single(&pevent->serial_number, TID_UINT32, 0, psa->convert_flags);
14467 rpc_convert_single(&pevent->time_stamp, TID_UINT32, 0, psa->convert_flags);
14468 rpc_convert_single(&pevent->data_size, TID_UINT32, 0, psa->convert_flags);
14469 }
14470
14471 int event_size = pevent->data_size + sizeof(EVENT_HEADER);
14472 int total_size = ALIGN8(event_size);
14473
14474 //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);
14475
14476 if (pevent->data_size == 0) {
14477 for (int i=0; i<5; i++) {
14478 printf("recv_event_server: header[%d]: 0x%08x\n", i, pbh[i]);
14479 }
14480 abort();
14481 }
14482
14483 /* check for sane event size */
14484 if (event_size <= 0 || total_size <= 0) {
14485 cm_msg(MERROR, "recv_event_server",
14486 "received event header with invalid data_size %d: event_size %d, total_size %d", pevent->data_size,
14487 event_size, total_size);
14488 return -1;
14489 }
14490
14491 //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);
14492
14493
14494 int bufsize = sizeof(INT) + total_size;
14495
14496 // Second, check that output buffer is big enough
14497
14498 /* check if data part fits in buffer */
14499 if (*pbuffer_size < bufsize) {
14500 int newsize = 1024 + ALIGN8(bufsize);
14501
14502 //printf("recv_event_server: buffer realloc %d -> %d\n", *pbuffer_size, newsize);
14503
14504 char *newbuf = (char *) realloc(*pbuffer, newsize);
14505 if (newbuf == NULL) {
14506 cm_msg(MERROR, "recv_event_server", "cannot realloc() event buffer from %d to %d bytes", *pbuffer_size,
14507 newsize);
14508 return -1;
14509 }
14510 *pbuffer = newbuf;
14512 }
14513
14514 // Third, copy header into output buffer
14515
14517
14518 // Forth, read the event data
14519
14520 int to_read = sizeof(INT) + total_size - header_size;
14521 int rptr = header_size;
14522
14523 if (to_read > 0) {
14524 int drd = recv_tcp2(sock, (*pbuffer) + rptr, to_read, 0);
14525
14526 /* abort if connection broken */
14527 if (drd <= 0) {
14528 cm_msg(MERROR, "recv_event_server", "recv_tcp2(data) returned %d instead of %d", drd, to_read);
14529 return -1;
14530 }
14531 }
14532
14533 return bufsize;
14534}
#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:5556
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:11681
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 14197 of file midas.cxx.

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

14375{
14376 /* figure out to which connection socket belongs */
14377 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++)
14378 if (_server_acceptions[idx] && _server_acceptions[idx]->recv_sock == sock) {
14379 return _server_acceptions[idx]->write_ptr - _server_acceptions[idx]->read_ptr;
14380 }
14381
14382 return 0;
14383}
static std::vector< RPC_SERVER_ACCEPTION * > _server_acceptions
Definition midas.cxx:11502
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 15235 of file midas.cxx.

15252{
15253 //cm_msg(MINFO, "rpc_add_allowed_host", "Adding allowed host \'%s\'", hostname);
15254
15255 gAllowedHostsMutex.lock();
15256 gAllowedHosts.push_back(hostname);
15257 gAllowedHostsEnabled = true;
15258 gAllowedHostsMutex.unlock();
15259
15260 return RPC_SUCCESS;
15261}
#define RPC_SUCCESS
Definition midas.h:698
static std::atomic_bool gAllowedHostsEnabled(false)
static std::mutex gAllowedHostsMutex
Definition midas.cxx:15207
static std::vector< std::string > gAllowedHosts
Definition midas.cxx:15206
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 11583 of file midas.cxx.

11583 {
11584 *convert_flags = 0;
11585
11586 /* big/little endian conversion */
11587 if (((remote_hw_type & DRI_BIG_ENDIAN) &&
11588 (hw_type & DRI_LITTLE_ENDIAN)) || ((remote_hw_type & DRI_LITTLE_ENDIAN)
11589 && (hw_type & DRI_BIG_ENDIAN)))
11590 *convert_flags |= CF_ENDIAN;
11591
11592 /* float conversion between IEEE and VAX G */
11593 if ((remote_hw_type & DRF_G_FLOAT) && (hw_type & DRF_IEEE))
11594 *convert_flags |= CF_VAX2IEEE;
11595
11596 /* float conversion between VAX G and IEEE */
11597 if ((remote_hw_type & DRF_IEEE) && (hw_type & DRF_G_FLOAT))
11598 *convert_flags |= CF_IEEE2VAX;
11599
11601 //if (remote_hw_type & DR_ASCII)
11602 // *convert_flags |= CF_ASCII;
11603}
#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:1611
#define CF_IEEE2VAX
Definition midas.h:1612
#define CF_VAX2IEEE
Definition midas.h:1613
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 13663 of file midas.cxx.

13687{
13688 va_list ap;
13689 INT i, status;
13690
13691 BOOL rpc_no_reply = routine_id & RPC_NO_REPLY;
13692 routine_id &= ~RPC_NO_REPLY;
13693
13694 //if (rpc_no_reply)
13695 // printf("rpc_call: routine_id %d, RPC_NO_REPLY\n", routine_id);
13696
13697 int send_sock = _server_connection.send_sock;
13698 int rpc_timeout = _server_connection.rpc_timeout;
13699
13700 if (!send_sock) {
13701 fprintf(stderr, "rpc_call(routine_id=%d) failed, no connection to mserver.\n", routine_id);
13702 return RPC_NET_ERROR;
13703 }
13704
13705 if (!_mutex_rpc) {
13706 /* create a local mutex for multi-threaded applications */
13708 }
13709
13710 status = ss_mutex_wait_for(_mutex_rpc, 10000 + rpc_timeout);
13711 if (status != SS_SUCCESS) {
13712 cm_msg(MERROR, "rpc_call", "Mutex timeout");
13713 return RPC_MUTEX_TIMEOUT;
13714 }
13715
13716 /* find rpc definition */
13717
13718 int idx = -1;
13719 const char* rpc_name = NULL;
13721
13722 rpc_list_mutex.lock();
13723
13724 for (size_t i = 0; i < rpc_list.size(); i++) {
13725 if (rpc_list[i].id == (int) routine_id) {
13726 idx = i;
13729 break;
13730 }
13731 }
13732
13733 rpc_list_mutex.unlock();
13734
13735 if (idx < 0) {
13737 cm_msg(MERROR, "rpc_call", "invalid rpc ID (%d)", routine_id);
13738 return RPC_INVALID_ID;
13739 }
13740
13741 /* prepare output buffer */
13742
13743 NET_COMMAND* nc = NULL;
13744
13745 /* examine variable argument list and convert it to parameter array */
13746 va_start(ap, routine_id);
13747
13749
13750 va_end(ap);
13751
13752 nc->header.routine_id = routine_id;
13753
13754 if (rpc_no_reply)
13756
13757 int send_size = nc->header.param_size + sizeof(NET_COMMAND_HEADER);
13758
13759 /* do not wait for reply if requested RPC_NO_REPLY */
13760 if (rpc_no_reply) {
13761 i = send_tcp(send_sock, (char *) nc, send_size, 0);
13762
13763 if (i != send_size) {
13765 cm_msg(MERROR, "rpc_call", "rpc \"%s\" error: send_tcp() failed", rpc_name);
13766 free(nc);
13767 return RPC_NET_ERROR;
13768 }
13769
13771 free(nc);
13772 return RPC_SUCCESS;
13773 }
13774
13775 /* in TCP mode, send and wait for reply on send socket */
13776 i = send_tcp(send_sock, (char *) nc, send_size, 0);
13777 if (i != send_size) {
13779 cm_msg(MERROR, "rpc_call", "rpc \"%s\" error: send_tcp() failed", rpc_name);
13780 free(nc);
13781 return RPC_NET_ERROR;
13782 }
13783
13784 free(nc);
13785 nc = NULL;
13786
13787 bool restore_watchdog_timeout = false;
13789 DWORD watchdog_timeout;
13790 cm_get_watchdog_params(&watchdog_call, &watchdog_timeout);
13791
13792 //printf("watchdog timeout: %d, rpc_timeout: %d\n", watchdog_timeout, rpc_timeout);
13793
13794 if (!rpc_is_remote()) {
13795 // if RPC is remote, we are connected to an mserver,
13796 // the mserver takes care of watchdog timeouts.
13797 // otherwise we should make sure the watchdog timeout
13798 // is longer than the RPC timeout. K.O.
13799 if (rpc_timeout >= (int) watchdog_timeout) {
13801 cm_set_watchdog_params_local(watchdog_call, rpc_timeout + 1000);
13802 }
13803 }
13804
13805 DWORD rpc_status = 0;
13806 DWORD buf_size = 0;
13807 char* buf = NULL;
13808
13809 status = ss_recv_net_command(send_sock, &rpc_status, &buf_size, &buf, rpc_timeout);
13810
13813 }
13814
13815 /* drop the mutex, we are done with the socket, argument unpacking is done from our own buffer */
13816
13818
13819 /* check for reply errors */
13820
13821 if (status == SS_TIMEOUT) {
13822 cm_msg(MERROR, "rpc_call", "routine \"%s\": timeout waiting for reply, program abort", rpc_name);
13823 if (buf)
13824 free(buf);
13825 abort(); // cannot continue - our mserver is not talking to us!
13826 return RPC_TIMEOUT;
13827 }
13828
13829 if (status != SS_SUCCESS) {
13830 cm_msg(MERROR, "rpc_call", "routine \"%s\": error, ss_recv_net_command() status %d, program abort", rpc_name, status);
13831 if (buf)
13832 free(buf);
13833 abort(); // cannot continue - something is wrong with our mserver connection
13834 return RPC_NET_ERROR;
13835 }
13836
13837 if (rpc_status == RPC_INVALID_ID) {
13838 cm_msg(MERROR, "rpc_call", "routine \"%s\": error, unknown RPC, status %d", rpc_name, rpc_status);
13839 if (buf)
13840 free(buf);
13841 return rpc_status;
13842 }
13843
13844 /* extract result variables and place it to argument list */
13845
13846 va_start(ap, routine_id);
13847
13848 status = rpc_call_decode(ap, rpc_entry, buf, buf_size);
13849
13850 if (status != RPC_SUCCESS) {
13852 }
13853
13854 va_end(ap);
13855
13856 if (buf)
13857 free(buf);
13858
13859 return rpc_status;
13860}
INT cm_get_watchdog_params(BOOL *call_watchdog, DWORD *timeout)
Definition midas.cxx:3317
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:5629
INT send_tcp(int sock, char *buffer, DWORD buffer_size, INT flags)
Definition system.cxx:5279
INT ss_mutex_wait_for(MUTEX_T *mutex, INT timeout)
Definition system.cxx:3037
bool rpc_is_remote(void)
Definition midas.cxx:12761
static std::vector< RPC_LIST > rpc_list
Definition midas.cxx:11573
static void rpc_call_encode(va_list &ap, const RPC_LIST &rl, NET_COMMAND **nc)
Definition midas.cxx:13231
static std::mutex rpc_list_mutex
Definition midas.cxx:11574
static int rpc_call_decode(va_list &ap, const RPC_LIST &rl, const char *buf, size_t buf_size)
Definition midas.cxx:13402
static RPC_SERVER_CONNECTION _server_connection
Definition midas.cxx:11498
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:1599
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 13402 of file midas.cxx.

13403{
13404 bool debug = false;
13405
13406 if (debug)
13407 printf("decode reply to rpc_id %d \"%s\" has %d bytes\n", rl.id, rl.name, (int)buf_size);
13408
13409 /* extract result variables and place it to argument list */
13410
13411 const char* param_ptr = buf;
13412
13413 for (int i = 0; rl.param[i].tid != 0; i++) {
13414 int tid = rl.param[i].tid;
13415 int flags = rl.param[i].flags;
13416 int arg_type = 0;
13417
13418 bool bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
13419 (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
13420 tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
13421
13422 if (bpointer)
13424 else
13425 arg_type = rl.param[i].tid;
13426
13427 if (tid == TID_FLOAT && !bpointer)
13429
13430 char arg[8];
13431 rpc_va_arg(&ap, arg_type, arg);
13432
13433 if (rl.param[i].flags & RPC_OUT) {
13434
13435 if (param_ptr == NULL) {
13436 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);
13437 return RPC_NET_ERROR;
13438 }
13439
13440 tid = rl.param[i].tid;
13441 int arg_size = rpc_tid_size(tid);
13442
13443 if (tid == TID_STRING || tid == TID_LINK)
13444 arg_size = strlen((char *) (param_ptr)) + 1;
13445
13446 if (flags & RPC_VARARRAY) {
13447 arg_size = *((INT *) param_ptr);
13448 param_ptr += ALIGN8(sizeof(INT));
13449 }
13450
13451 if (tid == TID_STRUCT || (flags & RPC_FIXARRAY))
13452 arg_size = rl.param[i].n;
13453
13454 /* parameter size is always aligned */
13455 int param_size = ALIGN8(arg_size);
13456
13457 /* return parameters are always pointers */
13458 if (*((char **) arg)) {
13459 if (debug)
13460 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);
13461 memcpy((void *) *((char **) arg), param_ptr, arg_size);
13462 }
13463
13464 param_ptr += param_size;
13465 }
13466 }
13467
13468 return RPC_SUCCESS;
13469}
#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:13193
INT rpc_tid_size(INT id)
Definition midas.cxx:11757
BOOL debug
debug printouts
Definition mana.cxx:254
#define RPC_OUT
Definition midas.h:1581
#define RPC_POINTER
Definition midas.h:1582
#define RPC_VARARRAY
Definition midas.h:1584
#define RPC_FIXARRAY
Definition midas.h:1583
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 13231 of file midas.cxx.

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

15275{
15276 //printf("rpc_check_allowed_host: enabled %d, hostname [%s]\n", gAllowedHostsEnabled.load(), hostname);
15277
15279 return RPC_SUCCESS;
15280
15281 if (strcmp(hostname, "localhost") == 0)
15282 return RPC_SUCCESS;
15283
15284 if (strcmp(hostname, "localhost.localdomain") == 0)
15285 return RPC_SUCCESS;
15286
15287 if (strcmp(hostname, "localhost6") == 0) // RedHat el6, el7
15288 return RPC_SUCCESS;
15289
15290 if (strcmp(hostname, "ip6-localhost") == 0) // Ubuntu-22
15291 return RPC_SUCCESS;
15292
15294
15295 gAllowedHostsMutex.lock();
15296
15297 for (const auto& h: gAllowedHosts) {
15298 if (h == hostname) {
15300 break;
15301 }
15302 }
15303
15304 gAllowedHostsMutex.unlock();
15305
15306 //if (status != RPC_SUCCESS)
15307 // printf("rpc_check_allowed_host: enabled %d, hostname [%s] not found\n", gAllowedHostsEnabled.load(), hostname);
15308
15309 return status;
15310}
#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 16254 of file midas.cxx.

16272{
16273 INT status;
16274 NET_COMMAND nc;
16276 struct timeval timeout;
16277
16278 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
16279 if (_server_acceptions[idx] && _server_acceptions[idx]->recv_sock) {
16281 if (sa == NULL)
16282 continue;
16283
16284 if (sa->watchdog_timeout == 0) {
16285 continue;
16286 }
16287
16289 //printf("rpc_check_channels: idx %d, watchdog_timeout %d, last_activity %d, elapsed %d\n", idx, sa->watchdog_timeout, sa->last_activity, elapsed);
16290
16291 if (sa->watchdog_timeout && (elapsed > (DWORD)sa->watchdog_timeout)) {
16292
16293 //printf("rpc_check_channels: send watchdog message to %s on %s\n", sa->prog_name.c_str(), sa->host_name.c_str());
16294
16295 /* send a watchdog message */
16297 nc.header.param_size = 0;
16298
16299 int convert_flags = sa->convert_flags;
16300 if (convert_flags) {
16303 }
16304
16305 /* send the header to the client */
16306 int i = send_tcp(sa->send_sock, (char *) &nc, sizeof(NET_COMMAND_HEADER), 0);
16307
16308 if (i < 0) {
16309 cm_msg(MINFO, "rpc_check_channels", "client \"%s\" on host \"%s\" failed watchdog test after %d sec, send_tcp() returned %d",
16310 sa->prog_name.c_str(),
16311 sa->host_name.c_str(),
16312 sa->watchdog_timeout / 1000,
16313 i);
16314
16315 /* disconnect from experiment */
16316 if (rpc_is_mserver()) {
16318 return RPC_NET_ERROR;
16319 }
16320
16321 sa->close();
16322 return RPC_NET_ERROR;
16323 }
16324
16325 /* make some timeout checking */
16326 FD_ZERO(&readfds);
16327 FD_SET(sa->send_sock, &readfds);
16328 FD_SET(sa->recv_sock, &readfds);
16329
16330 timeout.tv_sec = sa->watchdog_timeout / 1000;
16331 timeout.tv_usec = (sa->watchdog_timeout % 1000) * 1000;
16332
16333 do {
16334 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
16335
16336 /* if an alarm signal was cought, restart select with reduced timeout */
16337 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
16338 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
16339
16340 } while (status == -1); /* dont return if an alarm signal was cought */
16341
16342 if (!FD_ISSET(sa->send_sock, &readfds) &&
16343 !FD_ISSET(sa->recv_sock, &readfds)) {
16344
16345 cm_msg(MINFO, "rpc_check_channels", "client \"%s\" on host \"%s\" failed watchdog test after %d sec",
16346 sa->prog_name.c_str(),
16347 sa->host_name.c_str(),
16348 sa->watchdog_timeout / 1000);
16349
16350 /* disconnect from experiment */
16351 if (rpc_is_mserver()) {
16353 return RPC_NET_ERROR;
16354 }
16355
16356 sa->close();
16357 return RPC_NET_ERROR;
16358 }
16359
16360 /* receive result on send socket */
16361 if (FD_ISSET(sa->send_sock, &readfds)) {
16362 i = recv_tcp(sa->send_sock, (char *) &nc, sizeof(nc), 0);
16363 if (i <= 0) {
16364 cm_msg(MINFO, "rpc_check_channels", "client \"%s\" on host \"%s\" failed watchdog test after %d sec, recv_tcp() returned %d",
16365 sa->prog_name.c_str(),
16366 sa->host_name.c_str(),
16367 sa->watchdog_timeout / 1000,
16368 i);
16369
16370 /* disconnect from experiment */
16371 if (rpc_is_mserver()) {
16373 return RPC_NET_ERROR;
16374 }
16375
16376 sa->close();
16377 return RPC_NET_ERROR;
16378 }
16379 }
16380 }
16381 }
16382 }
16383
16384 return RPC_SUCCESS;
16385}
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:5448
bool rpc_is_mserver(void)
Definition midas.cxx:12818
#define RPC_OUTGOING
Definition midas.h:1585
#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 15210 of file midas.cxx.

15226{
15227 gAllowedHostsMutex.lock();
15228 gAllowedHosts.clear();
15229 gAllowedHostsEnabled = false;
15230 gAllowedHostsMutex.unlock();
15231 return RPC_SUCCESS;
15232}
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 15598 of file midas.cxx.

15619{
15620 INT i, status;
15622 std::string client_program;
15623 std::string host_name;
15624 INT convert_flags;
15625 char net_buffer[256], *p;
15626
15627 int sock = accept(lsock, NULL, NULL);
15628
15629 if (sock == -1)
15630 return RPC_NET_ERROR;
15631
15632 /* check access control list */
15635
15636 if (status != RPC_SUCCESS) {
15637 ss_socket_close(&sock);
15638 return RPC_NET_ERROR;
15639 }
15640 }
15641
15642 host_name = "(unknown)";
15643 client_program = "(unknown)";
15644
15645 /* receive string with timeout */
15646 i = recv_string(sock, net_buffer, sizeof(net_buffer), 10000);
15647 if (i <= 0) {
15648 ss_socket_close(&sock);
15649 return RPC_NET_ERROR;
15650 }
15651
15652 /* get remote computer info */
15653 p = strtok(net_buffer, " ");
15654 if (p != NULL) {
15655 client_hw_type = atoi(p);
15656 p = strtok(NULL, " ");
15657 }
15658 if (p != NULL) {
15659 //version = atoi(p);
15660 p = strtok(NULL, " ");
15661 }
15662 if (p != NULL) {
15663 client_program = p;
15664 p = strtok(NULL, " ");
15665 }
15666 if (p != NULL) {
15667 host_name = p;
15668 p = strtok(NULL, " ");
15669 }
15670
15671 //printf("rpc_client_accept: client_hw_type %d, version %d, client_name \'%s\', hostname \'%s\'\n", client_hw_type, version, client_program, host_name);
15672
15674
15675 /* save information in _server_acception structure */
15676 sa->recv_sock = sock;
15677 sa->send_sock = 0;
15678 sa->event_sock = 0;
15680 sa->host_name = host_name;
15683 sa->watchdog_timeout = 0;
15684 sa->is_mserver = FALSE;
15685
15686 /* send my own computer id */
15688 std::string str = msprintf("%d %s", hw_type, cm_get_version());
15689 status = send(sock, str.c_str(), str.length() + 1, 0);
15690 if (status != (INT) str.length() + 1)
15691 return RPC_NET_ERROR;
15692
15694 sa->convert_flags = convert_flags;
15695
15697
15698 return RPC_SUCCESS;
15699}
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:5393
void rpc_calc_convert_flags(INT hw_type, INT remote_hw_type, INT *convert_flags)
Definition midas.cxx:11583
static RPC_SERVER_ACCEPTION * rpc_new_server_acception()
Definition midas.cxx:11518
static INT rpc_socket_check_allowed_host(int sock)
Definition midas.cxx:15313
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 13472 of file midas.cxx.

13497{
13499
13500 if (!c) {
13501 cm_msg(MERROR, "rpc_client_call", "invalid rpc connection handle %d", hConn);
13502 return RPC_NO_CONNECTION;
13503 }
13504
13505 //printf("rpc_client_call: handle %d, connection: ", hConn);
13506 //c->print();
13507 //printf("\n");
13508
13509 INT i, status;
13510
13511 BOOL rpc_no_reply = routine_id & RPC_NO_REPLY;
13512 routine_id &= ~RPC_NO_REPLY;
13513
13514 //if (rpc_no_reply)
13515 // printf("rpc_client_call: routine_id %d, RPC_NO_REPLY\n", routine_id);
13516
13517 // make local copy of the client name just in case _client_connection is erased by another thread
13518
13519 /* find rpc_index */
13520
13521 int rpc_index = -1;
13522 const char *rpc_name = NULL;
13524
13525 rpc_list_mutex.lock();
13526 for (size_t i = 0; i < rpc_list.size(); i++) {
13527 if (rpc_list[i].id == (int) routine_id) {
13528 rpc_index = i;
13531 break;
13532 }
13533 }
13534 rpc_list_mutex.unlock();
13535
13536 if (rpc_index < 0) {
13537 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);
13538 c->mutex.unlock();
13539 return RPC_INVALID_ID;
13540 }
13541
13542 NET_COMMAND *nc = NULL;
13543
13544 /* examine variable argument list and convert it to parameter array */
13545 va_list ap;
13546 va_start(ap, routine_id);
13547
13549
13550 va_end(ap);
13551
13552 nc->header.routine_id = routine_id;
13553
13554 if (rpc_no_reply)
13556
13557 int send_size = nc->header.param_size + sizeof(NET_COMMAND_HEADER);
13558
13559 /* in FAST TCP mode, only send call and return immediately */
13560 if (rpc_no_reply) {
13561 i = send_tcp(c->send_sock, (char *) nc, send_size, 0);
13562
13563 if (i != send_size) {
13564 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);
13565 free(nc);
13566 c->mutex.unlock();
13567 return RPC_NET_ERROR;
13568 }
13569
13570 free(nc);
13571
13572 if (routine_id == RPC_ID_EXIT || routine_id == RPC_ID_SHUTDOWN) {
13573 //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);
13574 //c->print();
13575 //printf("\n");
13576 c->close_locked();
13577 }
13578
13579 c->mutex.unlock();
13580 return RPC_SUCCESS;
13581 }
13582
13583 /* in TCP mode, send and wait for reply on send socket */
13584 i = send_tcp(c->send_sock, (char *) nc, send_size, 0);
13585 if (i != send_size) {
13586 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);
13587 c->mutex.unlock();
13588 return RPC_NET_ERROR;
13589 }
13590
13591 free(nc);
13592 nc = NULL;
13593
13594 bool restore_watchdog_timeout = false;
13596 DWORD watchdog_timeout;
13597 cm_get_watchdog_params(&watchdog_call, &watchdog_timeout);
13598
13599 //printf("watchdog timeout: %d, rpc_timeout: %d\n", watchdog_timeout, c->rpc_timeout);
13600
13601 if (c->rpc_timeout >= (int) watchdog_timeout) {
13603 cm_set_watchdog_params(watchdog_call, c->rpc_timeout + 1000);
13604 }
13605
13606 DWORD rpc_status = 0;
13607 DWORD buf_size = 0;
13608 char* buf = NULL;
13609
13610 /* receive result on send socket */
13611 status = ss_recv_net_command(c->send_sock, &rpc_status, &buf_size, &buf, c->rpc_timeout);
13612
13614 cm_set_watchdog_params(watchdog_call, watchdog_timeout);
13615 }
13616
13617 if (status == SS_TIMEOUT) {
13618 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);
13619 if (buf)
13620 free(buf);
13621 c->mutex.unlock();
13622 return RPC_TIMEOUT;
13623 }
13624
13625 if (status != SS_SUCCESS) {
13626 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);
13627 if (buf)
13628 free(buf);
13629 c->mutex.unlock();
13630 return RPC_NET_ERROR;
13631 }
13632
13633 c->mutex.unlock();
13634
13635 if (rpc_status == RPC_INVALID_ID) {
13636 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);
13637 if (buf)
13638 free(buf);
13639 return rpc_status;
13640 }
13641
13642 /* extract result variables and place it to argument list */
13643
13644 va_start(ap, routine_id);
13645
13646 status = rpc_call_decode(ap, rpc_entry, buf, buf_size);
13647
13648 if (status != RPC_SUCCESS) {
13650 }
13651
13652 va_end(ap);
13653
13654 if (buf)
13655 free(buf);
13656 buf = NULL;
13657 buf_size = 0;
13658
13659 return rpc_status;
13660}
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:12612
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 12270 of file midas.cxx.

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

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

12694{
12695 /* notify server about exit */
12696
12697 /* call exit and shutdown with RPC_NO_REPLY because client will exit immediately without possibility of replying */
12698
12700
12701 return RPC_SUCCESS;
12702}
INT rpc_client_call(HNDLE hConn, DWORD routine_id,...)
Definition midas.cxx:13472
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 11945 of file midas.cxx.

11953{
11954 INT status = 0;
11955 char net_buffer[256];
11956
11957 int n = recv_tcp(sock, net_buffer, sizeof(net_buffer), 0);
11958 if (n <= 0)
11959 return SS_ABORT;
11960
11961 NET_COMMAND *nc = (NET_COMMAND *) net_buffer;
11962
11963 if (nc->header.routine_id == MSG_ODB) {
11964 status = handle_msg_odb(n, nc);
11965 } else if (nc->header.routine_id == MSG_WATCHDOG) {
11966 nc->header.routine_id = 1;
11967 nc->header.param_size = 0;
11968 send_tcp(sock, net_buffer, sizeof(NET_COMMAND_HEADER), 0);
11970 } else if (nc->header.routine_id == MSG_BM) {
11972 struct timeval timeout;
11973
11974 //printf("rpc_client_dispatch: received MSG_BM!\n");
11975
11976 /* receive further messages to empty TCP queue */
11977 do {
11978 FD_ZERO(&readfds);
11979 FD_SET(sock, &readfds);
11980
11981 timeout.tv_sec = 0;
11982 timeout.tv_usec = 0;
11983
11984 select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
11985
11986 if (FD_ISSET(sock, &readfds)) {
11987 n = recv_tcp(sock, net_buffer, sizeof(net_buffer), 0);
11988 if (n <= 0)
11989 return SS_ABORT;
11990
11991 if (nc->header.routine_id == MSG_ODB) {
11992 status = handle_msg_odb(n, nc);
11993 } else if (nc->header.routine_id == MSG_WATCHDOG) {
11994 nc->header.routine_id = 1;
11995 nc->header.param_size = 0;
11996 send_tcp(sock, net_buffer, sizeof(NET_COMMAND_HEADER), 0);
11998 }
11999 }
12000
12001 } while (FD_ISSET(sock, &readfds));
12002
12003 /* poll event from server */
12005 }
12006
12007 return status;
12008}
INT bm_poll_event()
Definition midas.cxx:11126
#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:11931
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 11706 of file midas.cxx.

11734{
11735 /* convert array */
11736 if (flags & (RPC_FIXARRAY | RPC_VARARRAY)) {
11737 int single_size = rpc_tid_size(tid);
11738 /* don't convert TID_ARRAY & TID_STRUCT */
11739 if (single_size == 0)
11740 return;
11741
11742 int n = total_size / single_size;
11743
11744 for (int i = 0; i < n; i++) {
11745 char* p = (char *) data + (i * single_size);
11746 rpc_convert_single(p, tid, flags, convert_flags);
11747 }
11748 } else {
11749 rpc_convert_single(data, tid, flags, convert_flags);
11750 }
11751}
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 11681 of file midas.cxx.

11681 {
11682
11683 if (convert_flags & CF_ENDIAN) {
11684 if (tid == TID_UINT16 || tid == TID_INT16) WORD_SWAP(data);
11685 if (tid == TID_UINT32 || tid == TID_INT32 || tid == TID_BOOL || tid == TID_FLOAT) DWORD_SWAP(data);
11686 if (tid == TID_DOUBLE) QWORD_SWAP(data);
11687 }
11688
11689 if (((convert_flags & CF_IEEE2VAX) && !(flags & RPC_OUTGOING)) ||
11690 ((convert_flags & CF_VAX2IEEE) && (flags & RPC_OUTGOING))) {
11691 if (tid == TID_FLOAT)
11692 rpc_ieee2vax_float((float *) data);
11693 if (tid == TID_DOUBLE)
11694 rpc_ieee2vax_double((double *) 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_vax2ieee_float((float *) data);
11701 if (tid == TID_DOUBLE)
11702 rpc_vax2ieee_double((double *) data);
11703 }
11704}
#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:11626
void rpc_ieee2vax_float(float *var)
Definition midas.cxx:11611
void rpc_ieee2vax_double(double *var)
Definition midas.cxx:11661
void rpc_vax2ieee_double(double *var)
Definition midas.cxx:11642
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 13161 of file midas.cxx.

13175{
13177 char str[1000];
13178
13179 if (_debug_mode) {
13180 va_start(argptr, format);
13181 vsprintf(str, (char *) format, argptr);
13182 va_end(argptr);
13183
13184 if (_debug_print) {
13185 strcat(str, "\n");
13187 } else
13188 puts(str);
13189 }
13190}
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 11870 of file midas.cxx.

11887{
11888 rpc_list_mutex.lock();
11889 rpc_list.clear();
11890 rpc_list_mutex.unlock();
11891
11892 return RPC_SUCCESS;
11893}
Here is the caller graph for this function:

◆ rpc_execute()

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

Definition at line 14650 of file midas.cxx.

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

14038 {
14039 return RPC_SUCCESS;
14040}
Here is the caller graph for this function:

◆ rpc_flush_event_socket()

int rpc_flush_event_socket ( int  timeout_msec)

Definition at line 16136 of file midas.cxx.

16150{
16152
16153 //printf("ss_event_socket_has_data() returned %d\n", has_data);
16154
16155 if (has_data) {
16156 if (timeout_msec == BM_NO_WAIT) {
16157 return BM_ASYNC_RETURN;
16158 } else if (timeout_msec == BM_WAIT) {
16159 return BM_ASYNC_RETURN;
16160 } else {
16162 if (status == SS_ABORT || status == SS_EXIT)
16163 return status;
16164 return BM_ASYNC_RETURN;
16165 }
16166 }
16167
16169
16170 //printf("rpc_server_receive_event() status %d\n", status);
16171
16172 if (status == BM_ASYNC_RETURN) {
16173 return BM_ASYNC_RETURN;
16174 }
16175
16176 if (status == SS_ABORT || status == SS_EXIT)
16177 return status;
16178
16179 return BM_SUCCESS;
16180}
#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:15981
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 11606 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 13030 of file midas.cxx.

13041{
13044 else
13045 return 0;
13046}
Here is the caller graph for this function:

◆ rpc_get_hw_type()

INT rpc_get_hw_type ( )

Definition at line 12834 of file midas.cxx.

12845{
12846 {
12847 {
12848 INT tmp_type, size;
12849 DWORD dummy;
12850 unsigned char *p;
12851 float f;
12852 double d;
12853
12854 tmp_type = 0;
12855
12856 /* test pointer size */
12857 size = sizeof(p);
12858 if (size == 2)
12859 tmp_type |= DRI_16;
12860 if (size == 4)
12861 tmp_type |= DRI_32;
12862 if (size == 8)
12863 tmp_type |= DRI_64;
12864
12865 /* test if little or big endian machine */
12866 dummy = 0x12345678;
12867 p = (unsigned char *) &dummy;
12868 if (*p == 0x78)
12870 else if (*p == 0x12)
12872 else
12873 cm_msg(MERROR, "rpc_get_option", "unknown byte order format");
12874
12875 /* floating point format */
12876 f = (float) 1.2345;
12877 dummy = 0;
12878 memcpy(&dummy, &f, sizeof(f));
12879 if ((dummy & 0xFF) == 0x19 &&
12880 ((dummy >> 8) & 0xFF) == 0x04 && ((dummy >> 16) & 0xFF) == 0x9E
12881 && ((dummy >> 24) & 0xFF) == 0x3F)
12882 tmp_type |= DRF_IEEE;
12883 else if ((dummy & 0xFF) == 0x9E &&
12884 ((dummy >> 8) & 0xFF) == 0x40 && ((dummy >> 16) & 0xFF) == 0x19
12885 && ((dummy >> 24) & 0xFF) == 0x04)
12887 else
12888 cm_msg(MERROR, "rpc_get_option", "unknown floating point format");
12889
12890 d = (double) 1.2345;
12891 dummy = 0;
12892 memcpy(&dummy, &d, sizeof(f));
12893 if ((dummy & 0xFF) == 0x8D && /* little endian */
12894 ((dummy >> 8) & 0xFF) == 0x97 && ((dummy >> 16) & 0xFF) == 0x6E
12895 && ((dummy >> 24) & 0xFF) == 0x12)
12896 tmp_type |= DRF_IEEE;
12897 else if ((dummy & 0xFF) == 0x83 && /* big endian */
12898 ((dummy >> 8) & 0xFF) == 0xC0 && ((dummy >> 16) & 0xFF) == 0xF3
12899 && ((dummy >> 24) & 0xFF) == 0x3F)
12900 tmp_type |= DRF_IEEE;
12901 else if ((dummy & 0xFF) == 0x13 &&
12902 ((dummy >> 8) & 0xFF) == 0x40 && ((dummy >> 16) & 0xFF) == 0x83
12903 && ((dummy >> 24) & 0xFF) == 0xC0)
12905 else if ((dummy & 0xFF) == 0x9E &&
12906 ((dummy >> 8) & 0xFF) == 0x40 && ((dummy >> 16) & 0xFF) == 0x18
12907 && ((dummy >> 24) & 0xFF) == 0x04)
12908 cm_msg(MERROR, "rpc_get_option",
12909 "MIDAS cannot handle VAX D FLOAT format. Please compile with the /g_float flag");
12910 else
12911 cm_msg(MERROR, "rpc_get_option", "unknown floating point format");
12912
12913 return tmp_type;
12914 }
12915 }
12916}
#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 12612 of file midas.cxx.

12613{
12615 if (hConn >= 0 && hConn < (int)_client_connections.size()) {
12617 if (c && c->connected) {
12619 c->mutex.lock();
12620 if (!c->connected) {
12621 // disconnected while we were waiting for the lock
12622 c->mutex.unlock();
12623 return NULL;
12624 }
12625 return c;
12626 }
12627 }
12629 return NULL;
12630}
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 11513 of file midas.cxx.

11514{
11515 return _mserver_acception;
11516}
Here is the caller graph for this function:

◆ rpc_get_mserver_hostname()

std::string rpc_get_mserver_hostname ( void  )

Definition at line 12805 of file midas.cxx.

12813{
12815}
Here is the caller graph for this function:

◆ rpc_get_mserver_path()

const char * rpc_get_mserver_path ( void  )

Definition at line 13051 of file midas.cxx.

13059{
13060 return _mserver_path.c_str();
13061}
static std::string _mserver_path
Definition midas.cxx:13048
Here is the caller graph for this function:

◆ rpc_get_name()

std::string rpc_get_name ( )

Definition at line 13084 of file midas.cxx.

13102{
13103 return _client_name;
13104}
Here is the caller graph for this function:

◆ rpc_get_opt_tcp_size()

INT rpc_get_opt_tcp_size ( void  )

Definition at line 13872 of file midas.cxx.

13872 {
13873 return _opt_tcp_size;
13874}
static int _opt_tcp_size
Definition midas.cxx:11576

◆ rpc_get_server_acception()

static RPC_SERVER_ACCEPTION * rpc_get_server_acception ( int  idx)
static

Definition at line 11505 of file midas.cxx.

11506{
11507 assert(idx >= 0);
11508 assert(idx < (int)_server_acceptions.size());
11509 assert(_server_acceptions[idx] != NULL);
11510 return _server_acceptions[idx];
11511}
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 12973 of file midas.cxx.

12974{
12975 if (hConn == RPC_HNDLE_MSERVER) {
12977 } else if (hConn == RPC_HNDLE_CONNECT) {
12978 return _rpc_connect_timeout;
12979 } else {
12981 if (c) {
12982 int timeout = c->rpc_timeout;
12983 c->mutex.unlock();
12984 return timeout;
12985 }
12986 }
12987 return 0;
12988}
#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 11661 of file midas.cxx.

11661 {
11662 unsigned short int i1, i2, i3, i4;
11663
11664 /* swap words */
11665 i1 = *((short int *) (var) + 3);
11666 i2 = *((short int *) (var) + 2);
11667 i3 = *((short int *) (var) + 1);
11668 i4 = *((short int *) (var));
11669
11670 /* correct exponent */
11671 if (i1 != 0)
11672 i1 += 0x20;
11673
11674 *((short int *) (var) + 3) = i4;
11675 *((short int *) (var) + 2) = i3;
11676 *((short int *) (var) + 1) = i2;
11677 *((short int *) (var)) = i1;
11678}
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 11611 of file midas.cxx.

11611 {
11612 unsigned short int lo, hi;
11613
11614 /* swap hi and lo word */
11615 lo = *((short int *) (var) + 1);
11616 hi = *((short int *) (var));
11617
11618 /* correct exponent */
11619 if (lo != 0)
11620 lo += 0x100;
11621
11622 *((short int *) (var) + 1) = hi;
11623 *((short int *) (var)) = lo;
11624}
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 12783 of file midas.cxx.

12800{
12801 return _server_connection.send_sock != 0;
12802}
Here is the caller graph for this function:

◆ rpc_is_mserver()

bool rpc_is_mserver ( void  )

Definition at line 12818 of file midas.cxx.

12829{
12830 return _mserver_acception != NULL;
12831}
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 12761 of file midas.cxx.

12778{
12779 return _rpc_is_remote;
12780}
static bool _rpc_is_remote
Definition midas.cxx:11499

◆ rpc_name_tid()

int rpc_name_tid ( const char name)

Definition at line 11778 of file midas.cxx.

11779{
11780 for (int i=0; i<TID_LAST; i++) {
11781 if (strcmp(name, tid_name[i]) == 0)
11782 return i;
11783 }
11784
11785 for (int i=0; i<TID_LAST; i++) {
11786 if (strcmp(name, tid_name_old[i]) == 0)
11787 return i;
11788 }
11789
11790 return 0;
11791}
#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 11518 of file midas.cxx.

11519{
11520 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
11521 if (_server_acceptions[idx] && (_server_acceptions[idx]->recv_sock == 0)) {
11522 //printf("rpc_new_server_acception: reuse acception in slot %d\n", idx);
11523 return _server_acceptions[idx];
11524 }
11525 }
11526
11528
11529 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
11530 if (_server_acceptions[idx] == NULL) {
11531 //printf("rpc_new_server_acception: new acception, reuse slot %d\n", idx);
11532 _server_acceptions[idx] = sa;
11533 return _server_acceptions[idx];
11534 }
11535 }
11536
11537 //printf("rpc_new_server_acception: new acception, array size %d, push_back\n", (int)_server_acceptions.size());
11538 _server_acceptions.push_back(sa);
11539
11540 return sa;
11541}
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 11808 of file midas.cxx.

11808 {
11812
11813 return RPC_SUCCESS;
11814}
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:11827
INT rpc_set_name(const char *name)
Definition midas.cxx:13108
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 11897 of file midas.cxx.

11916{
11917 std::lock_guard<std::mutex> guard(rpc_list_mutex);
11918
11919 for (size_t i = 0; i < rpc_list.size(); i++) {
11920 if (rpc_list[i].id == id) {
11921 rpc_list[i].dispatch = func;
11922 return RPC_SUCCESS;
11923 }
11924 }
11925
11926 return RPC_INVALID_ID;
11927}
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 11827 of file midas.cxx.

11828{
11829 for (int i = 0; new_list[i].id != 0; i++) {
11830 /* check valid ID for user functions */
11831 if (new_list != rpc_get_internal_list(0) &&
11833 || new_list[i].id > RPC_MAX_ID)) {
11834 cm_msg(MERROR, "rpc_register_functions", "registered RPC function with invalid ID %d", new_list[i].id);
11835 }
11836 }
11837
11838 std::lock_guard<std::mutex> guard(rpc_list_mutex);
11839
11840 /* check double defined functions */
11841 for (int i = 0; new_list[i].id != 0; i++) {
11842 for (size_t j = 0; j < rpc_list.size(); j++) {
11843 if (rpc_list[j].id == new_list[i].id) {
11844 return RPC_DOUBLE_DEFINED;
11845 }
11846 }
11847 }
11848
11849 /* append new functions */
11850 for (int i = 0; new_list[i].id != 0; i++) {
11851 RPC_LIST e = new_list[i];
11852
11853 /* set default dispatcher */
11854 if (e.dispatch == NULL) {
11855 e.dispatch = func;
11856 }
11857
11858 rpc_list.push_back(e);
11859 }
11860
11861 return RPC_SUCCESS;
11862}
#define RPC_DOUBLE_DEFINED
Definition midas.h:709
#define RPC_MIN_ID
Definition midas.h:1606
#define RPC_MAX_ID
Definition midas.h:1607
RPC_HANDLER * dispatch
Definition midas.h:1601
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 14579 of file midas.cxx.

14602{
14603 /* register system functions: RPC_ID_EXIT, RPC_ID_SHUTDOWN, RPC_ID_WATCHDOG */
14605
14606 /* create a socket for listening */
14607 int lsock = 0;
14608 int lport = 0;
14609 std::string errmsg;
14610
14612
14613 if (status != SS_SUCCESS) {
14614 cm_msg(MERROR, "rpc_register_server", "cannot listen to tcp port %d: %s", port, errmsg.c_str());
14615 return RPC_NET_ERROR;
14616 }
14617
14618 /* set close-on-exec flag to prevent child mserver processes from inheriting the listen socket */
14619#if defined(F_SETFD) && defined(FD_CLOEXEC)
14621 if (status < 0) {
14622 cm_msg(MERROR, "rpc_register_server", "fcntl(F_SETFD, FD_CLOEXEC) failed, errno %d (%s)", errno, strerror(errno));
14623 return RPC_NET_ERROR;
14624 }
14625#endif
14626
14627 /* return port wich OS has choosen */
14628 if (pport) {
14629 *pport = lport;
14630 }
14631
14632 if (plsock)
14633 *plsock = lsock;
14634
14635 //printf("rpc_register_server: requested port %d, actual port %d, socket %d\n", port, *pport, *plsock);
14636
14637 return RPC_SUCCESS;
14638}
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 14538 of file midas.cxx.

14560{
14561 int status;
14562 int lsock;
14563
14565 if (status != RPC_SUCCESS)
14566 return status;
14567
14569 if (status != SS_SUCCESS)
14570 return status;
14571
14572 if (plsock)
14573 *plsock = lsock;
14574
14575 return RPC_SUCCESS;
14576}
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:14579
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 13901 of file midas.cxx.

13902{
13903 if (rpc_is_remote()) {
13904 return rpc_send_event1(buffer_handle, pevent);
13905 } else {
13906 return bm_send_event(buffer_handle, pevent, unused, async_flag);
13907 }
13908}
INT bm_send_event(INT buffer_handle, const EVENT_HEADER *pevent, int unused, int timeout_msec)
Definition midas.cxx:9678
INT rpc_send_event1(INT buffer_handle, const EVENT_HEADER *pevent)
Definition midas.cxx:13919
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 13919 of file midas.cxx.

13920{
13921 const size_t event_size = sizeof(EVENT_HEADER) + pevent->data_size;
13922 return rpc_send_event_sg(buffer_handle, 1, (char**)&pevent, &event_size);
13923}
INT rpc_send_event_sg(INT buffer_handle, int sg_n, const char *const sg_ptr[], const size_t sg_len[])
Definition midas.cxx:13925
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 13925 of file midas.cxx.

13926{
13927 if (sg_n < 1) {
13928 cm_msg(MERROR, "rpc_send_event_sg", "invalid sg_n %d", sg_n);
13929 return BM_INVALID_SIZE;
13930 }
13931
13932 if (sg_ptr[0] == NULL) {
13933 cm_msg(MERROR, "rpc_send_event_sg", "invalid sg_ptr[0] is NULL");
13934 return BM_INVALID_SIZE;
13935 }
13936
13937 if (sg_len[0] < sizeof(EVENT_HEADER)) {
13938 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));
13939 return BM_INVALID_SIZE;
13940 }
13941
13942 const EVENT_HEADER* pevent = (const EVENT_HEADER*)sg_ptr[0];
13943
13944 const DWORD MAX_DATA_SIZE = (0x7FFFFFF0 - 16); // event size computations are not 32-bit clean, limit event size to 2GB. K.O.
13945 const DWORD data_size = pevent->data_size; // 32-bit unsigned value
13946
13947 if (data_size == 0) {
13948 cm_msg(MERROR, "rpc_send_event_sg", "invalid event data size zero");
13949 return BM_INVALID_SIZE;
13950 }
13951
13952 if (data_size > MAX_DATA_SIZE) {
13953 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);
13954 return BM_INVALID_SIZE;
13955 }
13956
13957 const size_t event_size = sizeof(EVENT_HEADER) + data_size;
13958 const size_t total_size = ALIGN8(event_size);
13959
13960 size_t count = 0;
13961 for (int i=0; i<sg_n; i++) {
13962 count += sg_len[i];
13963 }
13964
13965 if (count != event_size) {
13966 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);
13967 return BM_INVALID_SIZE;
13968 }
13969
13970 // protect non-atomic access to _server_connection.event_sock. K.O.
13971
13972 std::lock_guard<std::mutex> guard(_server_connection.event_sock_mutex);
13973
13974 //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);
13975
13976 if (_server_connection.event_sock == 0) {
13977 return RPC_NO_CONNECTION;
13978 }
13979
13980 //
13981 // event socket wire protocol: (see also rpc_server_receive_event() and recv_event_server_realloc())
13982 //
13983 // 4 bytes of buffer handle
13984 // 16 bytes of event header, includes data_size
13985 // ALIGN8(data_size) bytes of event data
13986 //
13987
13988 int status;
13989
13990 /* send buffer handle */
13991
13992 assert(sizeof(DWORD) == 4);
13993 DWORD bh_buf = buffer_handle;
13994
13995 status = ss_write_tcp(_server_connection.event_sock, (const char *) &bh_buf, sizeof(DWORD));
13996 if (status != SS_SUCCESS) {
13998 cm_msg(MERROR, "rpc_send_event_sg", "ss_write_tcp(buffer handle) failed, event socket is now closed");
13999 return RPC_NET_ERROR;
14000 }
14001
14002 /* send data */
14003
14004 for (int i=0; i<sg_n; i++) {
14006 if (status != SS_SUCCESS) {
14008 cm_msg(MERROR, "rpc_send_event_sg", "ss_write_tcp(event data) failed, event socket is now closed");
14009 return RPC_NET_ERROR;
14010 }
14011 }
14012
14013 /* send padding */
14014
14015 if (count < total_size) {
14016 char padding[8] = { 0,0,0,0,0,0,0,0 };
14017 size_t padlen = total_size - count;
14018 assert(padlen < 8);
14020 if (status != SS_SUCCESS) {
14022 cm_msg(MERROR, "rpc_send_event_sg", "ss_write_tcp(padding) failed, event socket is now closed");
14023 return RPC_NET_ERROR;
14024 }
14025 }
14026
14027 return RPC_SUCCESS;
14028}
#define BM_INVALID_SIZE
Definition midas.h:624
INT ss_write_tcp(int sock, const char *buffer, size_t buffer_size)
Definition system.cxx:5346
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 15341 of file midas.cxx.

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

15721{
15722 INT status;
15723 int recv_sock, send_sock, event_sock;
15724 char str[100];
15725 std::string client_program;
15727 INT convert_flags;
15728 char net_buffer[256];
15729 char *p;
15730 int flag;
15731
15732 /* copy callback information */
15734 //idx = callback.index;
15735
15736 std::string errmsg;
15737
15738 /* create new sockets for TCP */
15740
15741 if (status != SS_SUCCESS) {
15742 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());
15743 ss_socket_close(&recv_sock);
15744 //ss_socket_close(&send_sock);
15745 //ss_socket_close(&event_sock);
15746 return RPC_NET_ERROR;
15747 }
15748
15750
15751 if (status != SS_SUCCESS) {
15752 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());
15753 ss_socket_close(&recv_sock);
15754 ss_socket_close(&send_sock);
15755 //ss_socket_close(&event_sock);
15756 return RPC_NET_ERROR;
15757 }
15758
15760
15761 if (status != SS_SUCCESS) {
15762 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());
15763 ss_socket_close(&recv_sock);
15764 ss_socket_close(&send_sock);
15765 ss_socket_close(&event_sock);
15766 return RPC_NET_ERROR;
15767 }
15768#ifndef OS_ULTRIX /* crashes ULTRIX... */
15769 /* increase send buffer size to 2 Mbytes, on Linux also limited by sysctl net.ipv4.tcp_rmem and net.ipv4.tcp_wmem */
15770 flag = 2 * 1024 * 1024;
15771 status = setsockopt(event_sock, SOL_SOCKET, SO_RCVBUF, (char *) &flag, sizeof(INT));
15772 if (status != 0)
15773 cm_msg(MERROR, "rpc_server_callback", "cannot setsockopt(SOL_SOCKET, SO_RCVBUF), errno %d (%s)", errno,
15774 strerror(errno));
15775#endif
15776
15777 if (recv_string(recv_sock, net_buffer, 256, _rpc_connect_timeout) <= 0) {
15778 cm_msg(MERROR, "rpc_server_callback", "timeout on receive remote computer info");
15779 ss_socket_close(&recv_sock);
15780 ss_socket_close(&send_sock);
15781 ss_socket_close(&event_sock);
15782 return RPC_NET_ERROR;
15783 }
15784 //printf("rpc_server_callback: \'%s\'\n", net_buffer);
15785
15786 /* get remote computer info */
15787 client_hw_type = strtoul(net_buffer, &p, 0);
15788
15789 while (*p == ' ')
15790 p++;
15791
15792 client_program = p;
15793
15794 //printf("hw type %d, name \'%s\'\n", client_hw_type, client_program);
15795
15796 std::string host_name;
15797
15799
15800 if (status != SS_SUCCESS)
15801 host_name = "unknown";
15802
15803 //printf("rpc_server_callback: mserver acception\n");
15804
15806
15807 /* save information in _server_acception structure */
15808 sa->recv_sock = recv_sock;
15809 sa->send_sock = send_sock;
15810 sa->event_sock = event_sock;
15812 sa->host_name = host_name;
15815 sa->watchdog_timeout = 0;
15816 sa->is_mserver = TRUE;
15817
15818 assert(_mserver_acception == NULL);
15819
15820 _mserver_acception = sa;
15821
15822 //printf("rpc_server_callback: _mserver_acception %p\n", _mserver_acception);
15823
15824 /* send my own computer id */
15826 sprintf(str, "%d", hw_type);
15827 send(recv_sock, str, strlen(str) + 1, 0);
15828
15830 sa->convert_flags = convert_flags;
15831
15833
15834 if (rpc_is_mserver()) {
15835 rpc_debug_printf("Connection to %s:%s established\n", sa->host_name.c_str(), sa->prog_name.c_str());
15836 }
15837
15838 return RPC_SUCCESS;
15839}
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 12381 of file midas.cxx.

12409{
12410 INT i, status;
12411 INT remote_hw_type, hw_type;
12412 char str[200], version[32], v1[32];
12414 struct timeval timeout;
12415 int port = MIDAS_TCP_PORT;
12416 char *s;
12417
12418#ifdef OS_WINNT
12419 {
12421
12422 /* Start windows sockets */
12423 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
12424 return RPC_NET_ERROR;
12425 }
12426#endif
12427
12428 /* check if local connection */
12429 if (host_name[0] == 0)
12430 return RPC_SUCCESS;
12431
12432 /* register system functions */
12434
12435 /* check if cm_connect_experiment was called */
12436 if (_client_name.length() == 0) {
12437 cm_msg(MERROR, "rpc_server_connect", "cm_connect_experiment/rpc_set_name not called");
12438 return RPC_NOT_REGISTERED;
12439 }
12440
12441 /* check if connection already exists */
12443 return RPC_SUCCESS;
12444
12448
12449 bool listen_localhost = false;
12450
12451 if (strcmp(host_name, "localhost") == 0)
12452 listen_localhost = true;
12453
12454 int lsock1, lport1;
12455 int lsock2, lport2;
12456 int lsock3, lport3;
12457
12458 std::string errmsg;
12459
12461
12462 if (status != SS_SUCCESS) {
12463 cm_msg(MERROR, "rpc_server_connect", "cannot create listener socket: %s", errmsg.c_str());
12464 return RPC_NET_ERROR;
12465 }
12466
12468
12469 if (status != SS_SUCCESS) {
12470 cm_msg(MERROR, "rpc_server_connect", "cannot create listener socket: %s", errmsg.c_str());
12471 return RPC_NET_ERROR;
12472 }
12473
12475
12476 if (status != SS_SUCCESS) {
12477 cm_msg(MERROR, "rpc_server_connect", "cannot create listener socket: %s", errmsg.c_str());
12478 return RPC_NET_ERROR;
12479 }
12480
12481 /* extract port number from host_name */
12482 mstrlcpy(str, host_name, sizeof(str));
12483 s = strchr(str, ':');
12484 if (s) {
12485 *s = 0;
12486 port = strtoul(s + 1, NULL, 0);
12487 }
12488
12489 int sock;
12490
12491 status = ss_socket_connect_tcp(str, port, &sock, &errmsg);
12492
12493 if (status != SS_SUCCESS) {
12494 cm_msg(MERROR, "rpc_server_connect", "cannot connect to mserver on host \"%s\" port %d: %s", str, port, errmsg.c_str());
12495 return RPC_NET_ERROR;
12496 }
12497
12498 /* connect to experiment */
12499 if (exp_name[0] == 0)
12500 sprintf(str, "C %d %d %d %s Default", lport1, lport2, lport3, cm_get_version());
12501 else
12502 sprintf(str, "C %d %d %d %s %s", lport1, lport2, lport3, cm_get_version(), exp_name);
12503
12504 send(sock, str, strlen(str) + 1, 0);
12505 i = recv_string(sock, str, sizeof(str), _rpc_connect_timeout);
12506 ss_socket_close(&sock);
12507 if (i <= 0) {
12508 cm_msg(MERROR, "rpc_server_connect", "timeout on receive status from server");
12509 return RPC_NET_ERROR;
12510 }
12511
12512 status = version[0] = 0;
12513 sscanf(str, "%d %s", &status, version);
12514
12515 if (status == 2) {
12516/* message "undefined experiment" should be displayed by application */
12517 return CM_UNDEF_EXP;
12518 }
12519
12520 /* print warning if version patch level doesn't agree */
12521 strcpy(v1, version);
12522 if (strchr(v1, '.'))
12523 if (strchr(strchr(v1, '.') + 1, '.'))
12524 *strchr(strchr(v1, '.') + 1, '.') = 0;
12525
12526 strcpy(str, cm_get_version());
12527 if (strchr(str, '.'))
12528 if (strchr(strchr(str, '.') + 1, '.'))
12529 *strchr(strchr(str, '.') + 1, '.') = 0;
12530
12531 if (strcmp(v1, str) != 0) {
12532 cm_msg(MERROR, "rpc_server_connect", "remote MIDAS version \'%s\' differs from local version \'%s\'", version,
12533 cm_get_version());
12534 }
12535
12536 /* wait for callback on send and recv socket with timeout */
12537 FD_ZERO(&readfds);
12541
12542 timeout.tv_sec = _rpc_connect_timeout / 1000;
12543 timeout.tv_usec = 0;
12544
12545 do {
12546 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
12547
12548 /* if an alarm signal was cought, restart select with reduced timeout */
12549 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
12550 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
12551
12552 } while (status == -1); /* dont return if an alarm signal was cought */
12553
12554 if (!FD_ISSET(lsock1, &readfds)) {
12555 cm_msg(MERROR, "rpc_server_connect", "mserver subprocess could not be started (check path)");
12559 return RPC_NET_ERROR;
12560 }
12561
12565
12567 cm_msg(MERROR, "rpc_server_connect", "accept() failed");
12568 return RPC_NET_ERROR;
12569 }
12570
12574
12575 /* set TCP_NODELAY option for better performance */
12576 int flag = 1;
12579
12580 /* increase send buffer size to 2 Mbytes, on Linux also limited by sysctl net.ipv4.tcp_rmem and net.ipv4.tcp_wmem */
12581 flag = 2 * 1024 * 1024;
12583 if (status != 0)
12584 cm_msg(MERROR, "rpc_server_connect", "cannot setsockopt(SOL_SOCKET, SO_SNDBUF), errno %d (%s)", errno, strerror(errno));
12585
12586 /* send local computer info */
12587 std::string local_prog_name = rpc_get_name();
12589 sprintf(str, "%d %s", hw_type, local_prog_name.c_str());
12590
12592
12593 /* receive remote computer info */
12595 if (i <= 0) {
12596 cm_msg(MERROR, "rpc_server_connect", "timeout on receive remote computer info");
12597 return RPC_NET_ERROR;
12598 }
12599
12600 sscanf(str, "%d", &remote_hw_type);
12601 _server_connection.remote_hw_type = remote_hw_type;
12602
12604
12605 _rpc_is_remote = true;
12606
12607 return RPC_SUCCESS;
12608}
#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 12705 of file midas.cxx.

12725{
12727
12729 return RPC_SUCCESS;
12730
12732
12733 /* flush remaining events */
12735
12736 /* notify server about exit */
12737 if (rpc_is_connected()) {
12739 }
12740
12741 /* close sockets */
12748
12750
12751 /* remove semaphore */
12752 if (_mutex_rpc)
12754 _mutex_rpc = NULL;
12755
12757 return RPC_SUCCESS;
12758}
INT ss_mutex_delete(MUTEX_T *mutex)
Definition system.cxx:3211
bool rpc_is_connected(void)
Definition midas.cxx:12783
INT rpc_call(DWORD routine_id,...)
Definition midas.cxx:13663
INT rpc_flush_event()
Definition midas.cxx:14038
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 15843 of file midas.cxx.

15851{
15852 while (1) {
15853 int status = ss_suspend(1000, 0);
15854
15855 if (status == SS_ABORT || status == SS_EXIT)
15856 break;
15857
15859 break;
15860
15861 /* check alarms, etc */
15863
15865 }
15866
15867 return RPC_SUCCESS;
15868}
INT cm_periodic_tasks()
Definition midas.cxx:5579
INT cm_msg_flush_buffer()
Definition midas.cxx:865
INT rpc_check_channels(void)
Definition midas.cxx:16254
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 15981 of file midas.cxx.

15995{
15996 int status = 0;
15997
15998 DWORD start_time = ss_millitime();
15999
16000 //
16001 // THIS IS NOT THREAD SAFE!!!
16002 //
16003 // IT IS ONLY USED BY THE MSERVER
16004 // MSERVER IS SINGLE-THREADED!!!
16005 //
16006
16007 static char *xbuf = NULL;
16008 static int xbufsize = 0;
16009 static bool xbufempty = true;
16010
16011 // short cut
16012 if (sa == NULL && xbufempty)
16013 return RPC_SUCCESS;
16014
16015 static bool recurse = false;
16016
16017 if (recurse) {
16018 cm_msg(MERROR, "rpc_server_receive_event", "internal error: called recursively");
16019 // do not do anything if we are called recursively
16020 // via recursive ss_suspend() or otherwise. K.O.
16021 if (xbufempty)
16022 return RPC_SUCCESS;
16023 else
16024 return BM_ASYNC_RETURN;
16025 }
16026
16027 recurse = true;
16028
16029 do {
16030 if (xbufempty && sa) {
16032
16033 if (n_received < 0) {
16034 status = SS_ABORT;
16035 cm_msg(MERROR, "rpc_server_receive_event", "recv_event_server_realloc() returned %d, abort", n_received);
16036 goto error;
16037 }
16038
16039 if (n_received == 0) {
16040 // no more data in the tcp socket
16041 recurse = false;
16042 return RPC_SUCCESS;
16043 }
16044
16045 xbufempty = false;
16046 }
16047
16048 if (xbufempty) {
16049 // no event in xbuf buffer
16050 recurse = false;
16051 return RPC_SUCCESS;
16052 }
16053
16054 /* send event to buffer */
16055 INT *pbh = (INT *) xbuf;
16056 EVENT_HEADER *pevent = (EVENT_HEADER *) (pbh + 1);
16057
16058 status = bm_send_event(*pbh, pevent, 0, timeout_msec);
16059
16060 //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);
16061
16062 if (status == SS_ABORT) {
16063 cm_msg(MERROR, "rpc_server_receive_event", "bm_send_event() error %d (SS_ABORT), abort", status);
16064 goto error;
16065 }
16066
16067 if (status == BM_ASYNC_RETURN) {
16068 //cm_msg(MERROR, "rpc_server_receive_event", "bm_send_event() error %d, event buffer is full", status);
16069 recurse = false;
16070 return status;
16071 }
16072
16073 if (status != BM_SUCCESS) {
16074 cm_msg(MERROR, "rpc_server_receive_event", "bm_send_event() error %d, mserver dropped this event", status);
16075 }
16076
16077 xbufempty = true;
16078
16079 /* repeat for maximum 0.5 sec */
16080 } while (ss_millitime() - start_time < 500);
16081
16082 recurse = false;
16083 return RPC_SUCCESS;
16084
16085 error:
16086
16087 {
16088 char str[80];
16089 mstrlcpy(str, sa->host_name.c_str(), sizeof(str));
16090 if (strchr(str, '.'))
16091 *strchr(str, '.') = 0;
16092 cm_msg(MTALK, "rpc_server_receive_event", "Program \'%s\' on host \'%s\' aborted", sa->prog_name.c_str(), str);
16093 }
16094
16095 //exit:
16096
16098
16099 /* disconnect from experiment as MIDAS server */
16100 if (rpc_is_mserver()) {
16101 HNDLE hDB, hKey;
16102
16104
16105 /* only disconnect from experiment if previously connected.
16106 Necessary for pure RPC servers (RPC_SRVR) */
16107 if (hDB) {
16111
16113
16115 }
16116 }
16117
16118 bool is_mserver = sa->is_mserver;
16119
16120 sa->close();
16121
16122 /* signal caller a shutdonw */
16123 if (status == RPC_SHUTDOWN)
16124 return status;
16125
16126 /* only the mserver should stop on server connection closure */
16127 if (!is_mserver) {
16128 return SS_SUCCESS;
16129 }
16130
16131 return status;
16132}
INT bm_close_all_buffers(void)
Definition midas.cxx:7243
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:14387
INT rpc_deregister_functions()
Definition midas.cxx:11870
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 15871 of file midas.cxx.

15886{
15887 int status = 0;
15888 int remaining = 0;
15889
15890 char *buf = NULL;
15891 int bufsize = 0;
15892
15893 do {
15895
15896 if (n_received <= 0) {
15897 status = SS_ABORT;
15898 cm_msg(MERROR, "rpc_server_receive_rpc", "recv_net_command() returned %d, abort", n_received);
15899 goto error;
15900 }
15901
15902 status = rpc_execute(sa->recv_sock, buf, sa->convert_flags);
15903
15904 if (status == SS_ABORT) {
15905 cm_msg(MERROR, "rpc_server_receive_rpc", "rpc_execute() returned %d, abort", status);
15906 goto error;
15907 }
15908
15909 if (status == SS_EXIT || status == RPC_SHUTDOWN) {
15910 if (rpc_is_mserver())
15911 rpc_debug_printf("Connection to %s:%s closed\n", sa->host_name.c_str(), sa->prog_name.c_str());
15912 goto exit;
15913 }
15914
15915 } while (remaining);
15916
15917 if (buf) {
15918 free(buf);
15919 buf = NULL;
15920 bufsize = 0;
15921 }
15922
15923 return RPC_SUCCESS;
15924
15925 error:
15926
15927 {
15928 char str[80];
15929 mstrlcpy(str, sa->host_name.c_str(), sizeof(str));
15930 if (strchr(str, '.'))
15931 *strchr(str, '.') = 0;
15932 cm_msg(MTALK, "rpc_server_receive_rpc", "Program \'%s\' on host \'%s\' aborted", sa->prog_name.c_str(), str);
15933 }
15934
15935 exit:
15936
15938
15939 if (buf) {
15940 free(buf);
15941 buf = NULL;
15942 bufsize = 0;
15943 }
15944
15945 /* disconnect from experiment as MIDAS server */
15946 if (rpc_is_mserver()) {
15947 HNDLE hDB, hKey;
15948
15950
15951 /* only disconnect from experiment if previously connected.
15952 Necessary for pure RPC servers (RPC_SRVR) */
15953 if (hDB) {
15957
15959
15961 }
15962 }
15963
15964 bool is_mserver = sa->is_mserver;
15965
15966 sa->close();
15967
15968 /* signal caller a shutdonw */
15969 if (status == RPC_SHUTDOWN)
15970 return status;
15971
15972 /* only the mserver should stop on server connection closure */
15973 if (!is_mserver) {
15974 return SS_SUCCESS;
15975 }
15976
15977 return status;
15978}
INT rpc_execute(INT sock, char *buffer, INT convert_flags)
Definition midas.cxx:14650
static int recv_net_command_realloc(INT idx, char **pbuf, int *pbufsize, INT *remaining)
Definition midas.cxx:14197
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 16183 of file midas.cxx.

16200{
16201 //printf("rpc_server_shutdown!\n");
16202
16203 struct linger ling;
16204
16205 /* close all open connections */
16206 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
16207 if (_server_acceptions[idx] && _server_acceptions[idx]->recv_sock != 0) {
16209 /* lingering needed for PCTCP */
16210 ling.l_onoff = 1;
16211 ling.l_linger = 0;
16212 setsockopt(sa->recv_sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
16214
16215 if (sa->send_sock) {
16216 setsockopt(sa->send_sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
16218 }
16219
16220 if (sa->event_sock) {
16221 setsockopt(sa->event_sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
16223 }
16224 }
16225 }
16226
16227 /* avoid memory leak */
16228 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
16230 if (sa) {
16231 //printf("rpc_server_shutdown: %d %p %p\n", idx, sa, _mserver_acception);
16232 if (sa == _mserver_acception) {
16233 // do not leave behind a stale pointer!
16235 }
16236 delete sa;
16238 }
16239 }
16240
16241 if (_rpc_registered) {
16244 }
16245
16246 /* free suspend structures */
16248
16249 return RPC_SUCCESS;
16250}
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 13134 of file midas.cxx.

13154{
13155 _debug_print = func;
13156 _debug_mode = mode;
13157 return RPC_SUCCESS;
13158}
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 13064 of file midas.cxx.

13078{
13079 _mserver_path = path;
13080 return RPC_SUCCESS;
13081}
Here is the caller graph for this function:

◆ rpc_set_name()

INT rpc_set_name ( const char name)

Definition at line 13108 of file midas.cxx.

13126{
13128
13129 return RPC_SUCCESS;
13130}
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 13864 of file midas.cxx.

13864 {
13865 INT old;
13866
13869 return old;
13870}
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 12998 of file midas.cxx.

12999{
13000 //printf("rpc_set_timeout: hConn %d, timeout_msec %d\n", hConn, timeout_msec);
13001
13002 if (hConn == RPC_HNDLE_MSERVER) {
13003 if (old_timeout_msec)
13006 } else if (hConn == RPC_HNDLE_CONNECT) {
13007 if (old_timeout_msec)
13010 } else {
13012 if (c) {
13013 if (old_timeout_msec)
13014 *old_timeout_msec = c->rpc_timeout;
13015 c->rpc_timeout = timeout_msec;
13016 c->mutex.unlock();
13017 } else {
13018 if (old_timeout_msec)
13019 *old_timeout_msec = 0;
13020 }
13021 }
13022 return RPC_SUCCESS;
13023}
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 15313 of file midas.cxx.

15314{
15315 std::string hostname;
15316
15317 int status = ss_socket_get_peer_name(sock, &hostname, NULL);
15318
15319 if (status != SS_SUCCESS)
15320 return status;
15321
15322 status = rpc_check_allowed_host(hostname.c_str());
15323
15324 if (status == RPC_SUCCESS)
15325 return RPC_SUCCESS;
15326
15327 static std::atomic_int max_report(10);
15328 if (max_report > 0) {
15329 max_report--;
15330 if (max_report == 0) {
15331 cm_msg(MERROR, "rpc_socket_check_allowed_host", "rejecting connection from unallowed host \'%s\', this message will no longer be reported", hostname.c_str());
15332 } else {
15333 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());
15334 }
15335 }
15336
15337 return RPC_NET_ERROR;
15338}
INT rpc_check_allowed_host(const char *hostname)
Definition midas.cxx:15264
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 15046 of file midas.cxx.

15062{
15063 int status = RPC_SUCCESS;
15064
15065 printf("rpc_test_rpc!\n");
15066
15067 int int_out = 0;
15068 int int_inout = 456;
15069
15070 char string_out[32];
15071 char string2_out[48];
15072
15073 char string_inout[25];
15074 strcpy(string_inout, "string_inout");
15075
15076 KEY struct_in;
15077
15078 struct_in.type = 111;
15079 struct_in.num_values = 222;
15080 strcpy(struct_in.name, "name");
15081 struct_in.last_written = 333;
15082
15085
15086 struct_inout.type = 111111;
15087 struct_inout.num_values = 222222;
15088 strcpy(struct_inout.name, "name_name");
15089 struct_inout.last_written = 333333;
15090
15092 size_t dwordarray_inout_size = sizeof(dwordarray_inout);
15093
15094 for (int i=0; i<10; i++) {
15095 dwordarray_inout[i] = i*10;
15096 }
15097
15098 char array_in[10];
15099
15100 for (size_t i=0; i<sizeof(array_in); i++) {
15101 array_in[i] = 'a' + i;
15102 }
15103
15104 char array_out[16];
15105 size_t array_out_size = sizeof(array_out);
15106
15108 123,
15109 &int_out,
15110 &int_inout,
15111 "test string",
15112 string_out, sizeof(string_out),
15113 string2_out, sizeof(string2_out),
15114 string_inout, sizeof(string_inout),
15115 &struct_in,
15116 &struct_out,
15117 &struct_inout,
15119 array_in, sizeof(array_in),
15121 );
15122
15123 printf("rpc_call(RPC_TEST2) status %d\n", status);
15124
15125 if (int_out != 789) {
15126 printf("int_out mismatch!\n");
15127 status = 0;
15128 }
15129
15130 if (int_inout != 456*2) {
15131 printf("int_inout mismatch!\n");
15132 status = 0;
15133 }
15134
15135 if (strcmp(string_out, "string_out") != 0) {
15136 printf("string_out mismatch [%s] vs [%s]\n", string_out, "string_out");
15137 status = 0;
15138 }
15139
15140 if (strcmp(string2_out, "second string_out") != 0) {
15141 printf("string2_out mismatch [%s] vs [%s]\n", string2_out, "second string_out");
15142 status = 0;
15143 }
15144
15145 if (strcmp(string_inout, "return string_inout") != 0) {
15146 printf("string_inout mismatch [%s] vs [%s]\n", string_inout, "return string_inout");
15147 status = 0;
15148 }
15149
15150 KEY* pkey;
15151
15152 pkey = &struct_in;
15153
15154 //printf("struct_in: type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
15155
15156 pkey = &struct_out;
15157
15158 if (pkey->type != 444 || pkey->num_values != 555 || strcmp(pkey->name, "out_name") || pkey->last_written != 666) {
15159 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);
15160 status = 0;
15161 }
15162
15163 pkey = &struct_inout;
15164
15165 if (pkey->type != 444444 || pkey->num_values != 555555 || strcmp(pkey->name, "inout_name") || pkey->last_written != 666666) {
15166 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);
15167 status = 0;
15168 }
15169
15170#if 0
15171 if (dwordarray_inout_size != 4*5) {
15172 printf("dwordarray_inout_size mismatch %d vs %d\n", (int)dwordarray_inout_size, 4*5);
15173 status = 0;
15174 }
15175
15176 for (size_t i=0; i<dwordarray_inout_size/sizeof(uint32_t); i++) {
15177 printf("dwordarray_inout[%d] is %d\n", (int)i, dwordarray_inout[i]);
15178 }
15179#endif
15180
15181#if 0
15182 {RPC_TEST_CXX, "test_cxx",
15183 {{TID_INT32, RPC_IN},
15185 {TID_STRING, RPC_IN},
15189 {TID_STRUCT, RPC_IN | RPC_CXX, sizeof(KEY)},
15190 {TID_STRUCT, RPC_OUT | RPC_CXX, sizeof(KEY)},
15191 {TID_STRUCT, RPC_IN | RPC_OUT | RPC_CXX, sizeof(KEY)},
15195 {0}}},
15196#endif
15197
15198#if 0
15200#endif
15201
15202 return status;
15203}
#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 11764 of file midas.cxx.

11764 {
11765 if (id >= 0 && id < TID_LAST)
11766 return tid_name[id];
11767 else
11768 return "<unknown>";
11769}
Here is the caller graph for this function:

◆ rpc_tid_name_old()

const char * rpc_tid_name_old ( INT  id)

Definition at line 11771 of file midas.cxx.

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

◆ rpc_tid_size()

INT rpc_tid_size ( INT  id)

Definition at line 11757 of file midas.cxx.

11757 {
11758 if (id >= 0 && id < TID_LAST)
11759 return tid_size[id];
11760
11761 return 0;
11762}
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 14056 of file midas.cxx.

14075{
14076 /* erase error string */
14077 *(CSTRING(2)) = 0;
14078
14079 if (idx == RPC_RC_TRANSITION) {
14080 // find registered handler
14081 // NB: this code should match same code in cm_transition_call_direct()
14082 // NB: only use the first handler, this is how MIDAS always worked
14083 // NB: we could run all handlers, but we can return the status and error string of only one of them.
14084 _trans_table_mutex.lock();
14085 size_t n = _trans_table.size();
14086 _trans_table_mutex.unlock();
14087
14088 for (size_t i = 0; i < n; i++) {
14089 _trans_table_mutex.lock();
14091 _trans_table_mutex.unlock();
14092
14093 if (tt.transition == CINT(0) && tt.sequence_number == CINT(4)) {
14094 if (tt.func) {
14095 /* execute callback if defined */
14096 return tt.func(CINT(1), CSTRING(2));
14097 } else {
14098 std::lock_guard<std::mutex> guard(_tr_fifo_mutex);
14099 /* store transition in FIFO */
14104 _tr_fifo_wp = (_tr_fifo_wp + 1) % 10;
14105 // implicit unlock
14106 return RPC_SUCCESS;
14107 }
14108 }
14109 }
14110 // no handler for this transition
14111 cm_msg(MERROR, "rpc_transition_dispatch", "no handler for transition %d with sequence number %d", CINT(0), CINT(4));
14112 return CM_SUCCESS;
14113 } else {
14114 cm_msg(MERROR, "rpc_transition_dispatch", "received unrecognized command %d", idx);
14115 return RPC_INVALID_ID;
14116 }
14117}
#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:1622
#define CSTRING(_i)
Definition midas.h:1646
time_t trans_time
Definition midas.cxx:14047
int sequence_number
Definition midas.cxx:14048
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 13193 of file midas.cxx.

13193 {
13194 switch (arg_type) {
13195 /* On the stack, the minimum parameter size is sizeof(int).
13196 To avoid problems on little endian systems, treat all
13197 smaller parameters as int's */
13198 case TID_UINT8:
13199 case TID_INT8:
13200 case TID_CHAR:
13201 case TID_UINT16:
13202 case TID_INT16:
13203 *((int *) arg) = va_arg(*arg_ptr, int);
13204 break;
13205
13206 case TID_INT32:
13207 case TID_BOOL:
13208 *((INT *) arg) = va_arg(*arg_ptr, INT);
13209 break;
13210
13211 case TID_UINT32:
13212 *((DWORD *) arg) = va_arg(*arg_ptr, DWORD);
13213 break;
13214
13215 /* float variables are passed as double by the compiler */
13216 case TID_FLOAT:
13217 *((float *) arg) = (float) va_arg(*arg_ptr, double);
13218 break;
13219
13220 case TID_DOUBLE:
13221 *((double *) arg) = va_arg(*arg_ptr, double);
13222 break;
13223
13224 case TID_ARRAY:
13225 *((char **) arg) = va_arg(*arg_ptr, char *);
13226 break;
13227 }
13228}
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 11642 of file midas.cxx.

11642 {
11643 unsigned short int i1, i2, i3, i4;
11644
11645 /* swap words */
11646 i1 = *((short int *) (var) + 3);
11647 i2 = *((short int *) (var) + 2);
11648 i3 = *((short int *) (var) + 1);
11649 i4 = *((short int *) (var));
11650
11651 /* correct exponent */
11652 if (i4 != 0)
11653 i4 -= 0x20;
11654
11655 *((short int *) (var) + 3) = i4;
11656 *((short int *) (var) + 2) = i3;
11657 *((short int *) (var) + 1) = i2;
11658 *((short int *) (var)) = i1;
11659}
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 11626 of file midas.cxx.

11626 {
11627 unsigned short int lo, hi;
11628
11629 /* swap hi and lo word */
11630 lo = *((short int *) (var) + 1);
11631 hi = *((short int *) (var));
11632
11633 /* correct exponent */
11634 if (hi != 0)
11635 hi -= 0x100;
11636
11637 *((short int *) (var) + 1) = hi;
11638 *((short int *) (var)) = lo;
11639
11640}
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 11496 of file midas.cxx.

◆ _client_connections_mutex

std::mutex _client_connections_mutex
static

Definition at line 11495 of file midas.cxx.

◆ _mserver_acception

RPC_SERVER_ACCEPTION* _mserver_acception = NULL
static

Definition at line 11503 of file midas.cxx.

◆ _mserver_path

std::string _mserver_path
static

Definition at line 13048 of file midas.cxx.

◆ _opt_tcp_size

int _opt_tcp_size = OPT_TCP_SIZE
static

Definition at line 11576 of file midas.cxx.

◆ _rpc_is_remote

bool _rpc_is_remote = false
static

Definition at line 11499 of file midas.cxx.

◆ _server_acceptions

std::vector<RPC_SERVER_ACCEPTION*> _server_acceptions
static

Definition at line 11502 of file midas.cxx.

◆ _server_connection

RPC_SERVER_CONNECTION _server_connection
static

Definition at line 11498 of file midas.cxx.

◆ _tr_fifo

TR_FIFO _tr_fifo[10]
static

Definition at line 14052 of file midas.cxx.

◆ _tr_fifo_mutex

std::mutex _tr_fifo_mutex
static

Definition at line 14051 of file midas.cxx.

◆ _tr_fifo_rp

int _tr_fifo_rp = 0
static

Definition at line 14054 of file midas.cxx.

◆ _tr_fifo_wp

int _tr_fifo_wp = 0
static

Definition at line 14053 of file midas.cxx.

◆ gAllowedHosts

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

Definition at line 15206 of file midas.cxx.

◆ gAllowedHostsMutex

std::mutex gAllowedHostsMutex
static

Definition at line 15207 of file midas.cxx.

◆ rpc_list

std::vector<RPC_LIST> rpc_list
static

Definition at line 11573 of file midas.cxx.

◆ rpc_list_mutex

std::mutex rpc_list_mutex
static

Definition at line 11574 of file midas.cxx.

◆ tls_buffer

TLS_POINTER* tls_buffer = NULL
static

Definition at line 14646 of file midas.cxx.

◆ tls_size

int tls_size = 0
static

Definition at line 14647 of file midas.cxx.