MIDAS
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 char * rpc_tid_name (INT id)
 
const char * rpc_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 char * rpc_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 11510 of file midas.cxx.

11511 {
11512  //printf("RPC_SERVER_ACCEPTION::close: connection from %s program %s mserver %d\n", host_name.c_str(), prog_name.c_str(), is_mserver);
11513 
11514  if (is_mserver) {
11515  assert(_mserver_acception == this);
11516  _mserver_acception = NULL;
11517  is_mserver = false;
11518  }
11519 
11520  /* close server connection */
11521  if (recv_sock)
11523  if (send_sock)
11525  if (event_sock)
11527 
11528  /* free TCP cache */
11529  if (net_buffer) {
11530  //printf("free net_buffer %p+%d\n", net_buffer, net_buffer_size);
11531  free(net_buffer);
11532  net_buffer = NULL;
11533  net_buffer_size = 0;
11534  }
11535 
11536  /* mark this entry as invalid */
11537  clear();
11538 }
INT ss_socket_close(int *sockp)
Definition: system.cxx:5164
static RPC_SERVER_ACCEPTION * _mserver_acception
Definition: midas.cxx:11470
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 14087 of file midas.cxx.

14111 {
14112  std::lock_guard<std::mutex> guard(_tr_fifo_mutex);
14113 
14114  if (_tr_fifo_wp == _tr_fifo_rp)
14115  return FALSE;
14116 
14117  if (transition)
14119 
14120  if (run_number)
14122 
14123  if (trans_time)
14124  *trans_time = (int) _tr_fifo[_tr_fifo_rp].trans_time;
14125 
14126  _tr_fifo_rp = (_tr_fifo_rp + 1) % 10;
14127 
14128  // implicit unlock
14129  return TRUE;
14130 }
#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:14021
static int _tr_fifo_wp
Definition: midas.cxx:14020
static TR_FIFO _tr_fifo[10]
Definition: midas.cxx:14019
static std::mutex _tr_fifo_mutex
Definition: midas.cxx:14018
INT run_number[2]
Definition: mana.cxx:246
#define TRUE
Definition: midas.h:182
int transition
Definition: midas.cxx:14012
int run_number
Definition: midas.cxx:14013
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 11898 of file midas.cxx.

11898  {
11899  //printf("rpc_client_dispatch: MSG_ODB: packet size %d, expected %d\n", n, (int)(sizeof(NET_COMMAND_HEADER) + 4 * sizeof(INT)));
11900  if (n == sizeof(NET_COMMAND_HEADER) + 4 * sizeof(INT)) {
11901  /* update a changed record */
11902  HNDLE hDB = *((INT *) nc->param);
11903  HNDLE hKeyRoot = *((INT *) nc->param + 1);
11904  HNDLE hKey = *((INT *) nc->param + 2);
11905  int index = *((INT *) nc->param + 3);
11906  return db_update_record_local(hDB, hKeyRoot, hKey, index);
11907  }
11908  return CM_VERSION_MISMATCH;
11909 }
#define CM_VERSION_MISMATCH
Definition: midas.h:593
INT db_update_record_local(INT hDB, INT hKeyRoot, INT hKey, int index)
Definition: odb.cxx:13556
HNDLE hKey
Definition: lazylogger.cxx:207
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 14354 of file midas.cxx.

14376 {
14377  int sock = psa->event_sock;
14378 
14379  //printf("recv_event_server: idx %d, buffer %p, buffer_size %d\n", idx, buffer, buffer_size);
14380 
14381  const size_t header_size = (sizeof(EVENT_HEADER) + sizeof(INT));
14382 
14383  char header_buf[header_size];
14384 
14385  // First read the header.
14386  //
14387  // Data format is:
14388  // INT buffer handle (4 bytes)
14389  // EVENT_HEADER (16 bytes)
14390  // event data
14391  // ALIGN8() padding
14392  // ...next event
14393 
14394  int hrd = recv_tcp2(sock, header_buf, header_size, 1);
14395 
14396  if (hrd == 0) {
14397  // timeout waiting for data
14398  return 0;
14399  }
14400 
14401  /* abort if connection broken */
14402  if (hrd < 0) {
14403  cm_msg(MERROR, "recv_event_server", "recv_tcp2(header) returned %d", hrd);
14404  return -1;
14405  }
14406 
14407  if (hrd < (int) header_size) {
14408  int hrd1 = recv_tcp2(sock, header_buf + hrd, header_size - hrd, 0);
14409 
14410  /* abort if connection broken */
14411  if (hrd1 <= 0) {
14412  cm_msg(MERROR, "recv_event_server", "recv_tcp2(more header) returned %d", hrd1);
14413  return -1;
14414  }
14415 
14416  hrd += hrd1;
14417  }
14418 
14419  /* abort if connection broken */
14420  if (hrd != (int) header_size) {
14421  cm_msg(MERROR, "recv_event_server", "recv_tcp2(header) returned %d instead of %d", hrd, (int) header_size);
14422  return -1;
14423  }
14424 
14425  INT *pbh = (INT *) header_buf;
14426  EVENT_HEADER *pevent = (EVENT_HEADER *) (((INT *) header_buf) + 1);
14427 
14428  /* convert header little endian/big endian */
14429  if (psa->convert_flags) {
14430  rpc_convert_single(&pbh, TID_INT32, 0, psa->convert_flags);
14431  rpc_convert_single(&pevent->event_id, TID_INT16, 0, psa->convert_flags);
14436  }
14437 
14438  int event_size = pevent->data_size + sizeof(EVENT_HEADER);
14439  int total_size = ALIGN8(event_size);
14440 
14441  //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);
14442 
14443  if (pevent->data_size == 0) {
14444  for (int i=0; i<5; i++) {
14445  printf("recv_event_server: header[%d]: 0x%08x\n", i, pbh[i]);
14446  }
14447  abort();
14448  }
14449 
14450  /* check for sane event size */
14451  if (event_size <= 0 || total_size <= 0) {
14452  cm_msg(MERROR, "recv_event_server",
14453  "received event header with invalid data_size %d: event_size %d, total_size %d", pevent->data_size,
14454  event_size, total_size);
14455  return -1;
14456  }
14457 
14458  //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);
14459 
14460 
14461  int bufsize = sizeof(INT) + total_size;
14462 
14463  // Second, check that output buffer is big enough
14464 
14465  /* check if data part fits in buffer */
14466  if (*pbuffer_size < bufsize) {
14467  int newsize = 1024 + ALIGN8(bufsize);
14468 
14469  //printf("recv_event_server: buffer realloc %d -> %d\n", *pbuffer_size, newsize);
14470 
14471  char *newbuf = (char *) realloc(*pbuffer, newsize);
14472  if (newbuf == NULL) {
14473  cm_msg(MERROR, "recv_event_server", "cannot realloc() event buffer from %d to %d bytes", *pbuffer_size,
14474  newsize);
14475  return -1;
14476  }
14477  *pbuffer = newbuf;
14478  *pbuffer_size = newsize;
14479  }
14480 
14481  // Third, copy header into output buffer
14482 
14483  memcpy(*pbuffer, header_buf, header_size);
14484 
14485  // Forth, read the event data
14486 
14487  int to_read = sizeof(INT) + total_size - header_size;
14488  int rptr = header_size;
14489 
14490  if (to_read > 0) {
14491  int drd = recv_tcp2(sock, (*pbuffer) + rptr, to_read, 0);
14492 
14493  /* abort if connection broken */
14494  if (drd <= 0) {
14495  cm_msg(MERROR, "recv_event_server", "recv_tcp2(data) returned %d instead of %d", drd, to_read);
14496  return -1;
14497  }
14498  }
14499 
14500  return bufsize;
14501 }
#define TID_INT32
Definition: midas.h:346
#define MERROR
Definition: midas.h:565
#define TID_UINT32
Definition: midas.h:344
#define TID_INT16
Definition: midas.h:342
#define ALIGN8(x)
Definition: midas.h:528
INT recv_tcp2(int sock, char *net_buffer, int buffer_size, int timeout_ms)
Definition: system.cxx:5495
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition: midas.cxx:917
void rpc_convert_single(void *data, INT tid, INT flags, INT convert_flags)
Definition: midas.cxx:11648
INT i
Definition: mdump.cxx:35
int event_size
Definition: msysmon.cxx:526
short int event_id
Definition: midas.h:858
DWORD data_size
Definition: midas.h:862
DWORD serial_number
Definition: midas.h:860
DWORD time_stamp
Definition: midas.h:861
short int trigger_mask
Definition: midas.h:859
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 14164 of file midas.cxx.

14192 {
14193  char *buffer = NULL; // buffer is changed to point to *pbuf when we receive the NET_COMMAND header
14194 
14196 
14197  int sock = sa->recv_sock;
14198 
14199  if (!sa->net_buffer) {
14200  if (sa->is_mserver)
14202  else
14204 
14205  sa->net_buffer = (char *) malloc(sa->net_buffer_size);
14206  //printf("sa %p idx %d, net_buffer %p+%d\n", sa, idx, sa->net_buffer, sa->net_buffer_size);
14207  sa->write_ptr = 0;
14208  sa->read_ptr = 0;
14209  sa->misalign = 0;
14210  }
14211  if (!sa->net_buffer) {
14212  cm_msg(MERROR, "recv_net_command", "Cannot allocate %d bytes for network buffer", sa->net_buffer_size);
14213  return -1;
14214  }
14215 
14216  int copied = 0;
14217  int param_size = -1;
14218 
14219  int write_ptr = sa->write_ptr;
14220  int read_ptr = sa->read_ptr;
14221  int misalign = sa->misalign;
14222  char *net_buffer = sa->net_buffer;
14223 
14224  do {
14225  if (write_ptr - read_ptr >= (INT) sizeof(NET_COMMAND_HEADER) - copied) {
14226  if (param_size == -1) {
14227  if (copied > 0) {
14228  /* assemble split header */
14229  memcpy(buffer + copied, net_buffer + read_ptr, (INT) sizeof(NET_COMMAND_HEADER) - copied);
14230  NET_COMMAND *nc = (NET_COMMAND *) (buffer);
14231  param_size = (INT) nc->header.param_size;
14232  } else {
14233  NET_COMMAND *nc = (NET_COMMAND *) (net_buffer + read_ptr);
14234  param_size = (INT) nc->header.param_size;
14235  }
14236 
14237  if (sa->convert_flags)
14238  rpc_convert_single(&param_size, TID_UINT32, 0, sa->convert_flags);
14239  }
14240 
14241  //printf("recv_net_command: param_size %d, NET_COMMAND_HEADER %d, buffer_size %d\n", param_size, (int)sizeof(NET_COMMAND_HEADER), *pbufsize);
14242 
14243  /* check if parameters fit in buffer */
14244  if (*pbufsize < (param_size + (int) sizeof(NET_COMMAND_HEADER))) {
14245  int new_size = param_size + sizeof(NET_COMMAND_HEADER) + 1024;
14246  char *p = (char *) realloc(*pbuf, new_size);
14247  //printf("recv_net_command: reallocate buffer %d -> %d, %p\n", *pbufsize, new_size, p);
14248  if (p == NULL) {
14249  cm_msg(MERROR, "recv_net_command", "cannot reallocate buffer from %d bytes to %d bytes", *pbufsize, new_size);
14250  sa->read_ptr = 0;
14251  sa->write_ptr = 0;
14252  return -1;
14253  }
14254  *pbuf = p;
14255  *pbufsize = new_size;
14256  }
14257 
14258  buffer = *pbuf;
14259 
14260  /* check if we have all parameters in buffer */
14261  if (write_ptr - read_ptr >= param_size + (INT) sizeof(NET_COMMAND_HEADER) - copied)
14262  break;
14263  }
14264 
14265  /* not enough data, so copy partially and get new */
14266  int size = write_ptr - read_ptr;
14267 
14268  if (size > 0) {
14269  memcpy(buffer + copied, net_buffer + read_ptr, size);
14270  copied += size;
14271  read_ptr = write_ptr;
14272  }
14273 #ifdef OS_UNIX
14274  do {
14275  write_ptr = recv(sock, net_buffer + misalign, sa->net_buffer_size - 8, 0);
14276 
14277  /* don't return if an alarm signal was cought */
14278  } while (write_ptr == -1 && errno == EINTR);
14279 #else
14280  write_ptr = recv(sock, net_buffer + misalign, sa->net_buffer_size - 8, 0);
14281 #endif
14282 
14283  /* abort if connection broken */
14284  if (write_ptr <= 0) {
14285  if (write_ptr == 0)
14286  cm_msg(MERROR, "recv_net_command", "rpc connection from \'%s\' on \'%s\' unexpectedly closed", sa->prog_name.c_str(), sa->host_name.c_str());
14287  else
14288  cm_msg(MERROR, "recv_net_command", "recv() returned %d, errno: %d (%s)", write_ptr, errno, strerror(errno));
14289 
14290  if (remaining)
14291  *remaining = 0;
14292 
14293  return write_ptr;
14294  }
14295 
14296  read_ptr = misalign;
14297  write_ptr += misalign;
14298 
14299  misalign = write_ptr % 8;
14300  } while (TRUE);
14301 
14302  /* copy rest of parameters */
14303  int size = param_size + sizeof(NET_COMMAND_HEADER) - copied;
14304  memcpy(buffer + copied, net_buffer + read_ptr, size);
14305  read_ptr += size;
14306 
14307  if (remaining) {
14308  /* don't keep rpc_server_receive in an infinite loop */
14309  if (write_ptr - read_ptr < param_size)
14310  *remaining = 0;
14311  else
14312  *remaining = write_ptr - read_ptr;
14313  }
14314 
14315  sa->write_ptr = write_ptr;
14316  sa->read_ptr = read_ptr;
14317  sa->misalign = misalign;
14318 
14319  return size + copied;
14320 }
#define NET_BUFFER_SIZE
Definition: msystem.h:114
static RPC_SERVER_ACCEPTION * rpc_get_server_acception(int idx)
Definition: midas.cxx:11472
#define NET_TCP_SIZE
Definition: midas.h:273
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 14324 of file midas.cxx.

14342 {
14343  /* figure out to which connection socket belongs */
14344  for (unsigned idx = 0; idx < _server_acceptions.size(); idx++)
14345  if (_server_acceptions[idx] && _server_acceptions[idx]->recv_sock == sock) {
14346  return _server_acceptions[idx]->write_ptr - _server_acceptions[idx]->read_ptr;
14347  }
14348 
14349  return 0;
14350 }
static std::vector< RPC_SERVER_ACCEPTION * > _server_acceptions
Definition: midas.cxx:11469
Here is the caller graph for this function:

◆ rpc_add_allowed_host()

INT rpc_add_allowed_host ( const char *  hostname)

Definition at line 15202 of file midas.cxx.

15219 {
15220  //cm_msg(MINFO, "rpc_add_allowed_host", "Adding allowed host \'%s\'", hostname);
15221 
15222  gAllowedHostsMutex.lock();
15223  gAllowedHosts.push_back(hostname);
15224  gAllowedHostsEnabled = true;
15225  gAllowedHostsMutex.unlock();
15226 
15227  return RPC_SUCCESS;
15228 }
#define RPC_SUCCESS
Definition: midas.h:704
static std::atomic_bool gAllowedHostsEnabled(false)
static std::mutex gAllowedHostsMutex
Definition: midas.cxx:15174
static std::vector< std::string > gAllowedHosts
Definition: midas.cxx:15173
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 11550 of file midas.cxx.

11550  {
11551  *convert_flags = 0;
11552 
11553  /* big/little endian conversion */
11554  if (((remote_hw_type & DRI_BIG_ENDIAN) &&
11555  (hw_type & DRI_LITTLE_ENDIAN)) || ((remote_hw_type & DRI_LITTLE_ENDIAN)
11556  && (hw_type & DRI_BIG_ENDIAN)))
11557  *convert_flags |= CF_ENDIAN;
11558 
11559  /* float conversion between IEEE and VAX G */
11560  if ((remote_hw_type & DRF_G_FLOAT) && (hw_type & DRF_IEEE))
11561  *convert_flags |= CF_VAX2IEEE;
11562 
11563  /* float conversion between VAX G and IEEE */
11564  if ((remote_hw_type & DRF_IEEE) && (hw_type & DRF_G_FLOAT))
11565  *convert_flags |= CF_IEEE2VAX;
11566 
11568  //if (remote_hw_type & DR_ASCII)
11569  // *convert_flags |= CF_ASCII;
11570 }
#define DRI_LITTLE_ENDIAN
Definition: msystem.h:48
#define DRF_G_FLOAT
Definition: msystem.h:51
#define DRI_BIG_ENDIAN
Definition: msystem.h:49
#define DRF_IEEE
Definition: msystem.h:50
#define CF_ENDIAN
Definition: midas.h:1609
#define CF_IEEE2VAX
Definition: midas.h:1610
#define CF_VAX2IEEE
Definition: midas.h:1611
Here is the caller graph for this function:

◆ rpc_call()

INT rpc_call ( DWORD  routine_id,
  ... 
)

Definition at line 13630 of file midas.cxx.

13654 {
13655  va_list ap;
13656  INT i, status;
13657 
13658  BOOL rpc_no_reply = routine_id & RPC_NO_REPLY;
13659  routine_id &= ~RPC_NO_REPLY;
13660 
13661  //if (rpc_no_reply)
13662  // printf("rpc_call: routine_id %d, RPC_NO_REPLY\n", routine_id);
13663 
13664  int send_sock = _server_connection.send_sock;
13665  int rpc_timeout = _server_connection.rpc_timeout;
13666 
13667  if (!send_sock) {
13668  fprintf(stderr, "rpc_call(routine_id=%d) failed, no connection to mserver.\n", routine_id);
13669  return RPC_NET_ERROR;
13670  }
13671 
13672  if (!_mutex_rpc) {
13673  /* create a local mutex for multi-threaded applications */
13675  }
13676 
13677  status = ss_mutex_wait_for(_mutex_rpc, 10000 + rpc_timeout);
13678  if (status != SS_SUCCESS) {
13679  cm_msg(MERROR, "rpc_call", "Mutex timeout");
13680  return RPC_MUTEX_TIMEOUT;
13681  }
13682 
13683  /* find rpc definition */
13684 
13685  int idx = -1;
13686  const char* rpc_name = NULL;
13687  RPC_LIST rpc_entry;
13688 
13689  rpc_list_mutex.lock();
13690 
13691  for (size_t i = 0; i < rpc_list.size(); i++) {
13692  if (rpc_list[i].id == (int) routine_id) {
13693  idx = i;
13694  rpc_name = rpc_list[idx].name;
13695  rpc_entry = rpc_list[idx];
13696  break;
13697  }
13698  }
13699 
13700  rpc_list_mutex.unlock();
13701 
13702  if (idx < 0) {
13704  cm_msg(MERROR, "rpc_call", "invalid rpc ID (%d)", routine_id);
13705  return RPC_INVALID_ID;
13706  }
13707 
13708  /* prepare output buffer */
13709 
13710  NET_COMMAND* nc = NULL;
13711 
13712  /* examine variable argument list and convert it to parameter array */
13713  va_start(ap, routine_id);
13714 
13715  rpc_call_encode(ap, rpc_entry, &nc);
13716 
13717  va_end(ap);
13718 
13719  nc->header.routine_id = routine_id;
13720 
13721  if (rpc_no_reply)
13723 
13724  int send_size = nc->header.param_size + sizeof(NET_COMMAND_HEADER);
13725 
13726  /* do not wait for reply if requested RPC_NO_REPLY */
13727  if (rpc_no_reply) {
13728  i = send_tcp(send_sock, (char *) nc, send_size, 0);
13729 
13730  if (i != send_size) {
13732  cm_msg(MERROR, "rpc_call", "rpc \"%s\" error: send_tcp() failed", rpc_name);
13733  free(nc);
13734  return RPC_NET_ERROR;
13735  }
13736 
13738  free(nc);
13739  return RPC_SUCCESS;
13740  }
13741 
13742  /* in TCP mode, send and wait for reply on send socket */
13743  i = send_tcp(send_sock, (char *) nc, send_size, 0);
13744  if (i != send_size) {
13746  cm_msg(MERROR, "rpc_call", "rpc \"%s\" error: send_tcp() failed", rpc_name);
13747  free(nc);
13748  return RPC_NET_ERROR;
13749  }
13750 
13751  free(nc);
13752  nc = NULL;
13753 
13754  bool restore_watchdog_timeout = false;
13755  BOOL watchdog_call;
13756  DWORD watchdog_timeout;
13757  cm_get_watchdog_params(&watchdog_call, &watchdog_timeout);
13758 
13759  //printf("watchdog timeout: %d, rpc_timeout: %d\n", watchdog_timeout, rpc_timeout);
13760 
13761  if (!rpc_is_remote()) {
13762  // if RPC is remote, we are connected to an mserver,
13763  // the mserver takes care of watchdog timeouts.
13764  // otherwise we should make sure the watchdog timeout
13765  // is longer than the RPC timeout. K.O.
13766  if (rpc_timeout >= (int) watchdog_timeout) {
13767  restore_watchdog_timeout = true;
13768  cm_set_watchdog_params_local(watchdog_call, rpc_timeout + 1000);
13769  }
13770  }
13771 
13772  DWORD rpc_status = 0;
13773  DWORD buf_size = 0;
13774  char* buf = NULL;
13775 
13776  status = ss_recv_net_command(send_sock, &rpc_status, &buf_size, &buf, rpc_timeout);
13777 
13778  if (restore_watchdog_timeout) {
13779  cm_set_watchdog_params_local(watchdog_call, watchdog_timeout);
13780  }
13781 
13782  /* drop the mutex, we are done with the socket, argument unpacking is done from our own buffer */
13783 
13785 
13786  /* check for reply errors */
13787 
13788  if (status == SS_TIMEOUT) {
13789  cm_msg(MERROR, "rpc_call", "routine \"%s\": timeout waiting for reply, program abort", rpc_name);
13790  if (buf)
13791  free(buf);
13792  abort(); // cannot continue - our mserver is not talking to us!
13793  return RPC_TIMEOUT;
13794  }
13795 
13796  if (status != SS_SUCCESS) {
13797  cm_msg(MERROR, "rpc_call", "routine \"%s\": error, ss_recv_net_command() status %d, program abort", rpc_name, status);
13798  if (buf)
13799  free(buf);
13800  abort(); // cannot continue - something is wrong with our mserver connection
13801  return RPC_NET_ERROR;
13802  }
13803 
13804  if (rpc_status == RPC_INVALID_ID) {
13805  cm_msg(MERROR, "rpc_call", "routine \"%s\": error, unknown RPC, status %d", rpc_name, rpc_status);
13806  if (buf)
13807  free(buf);
13808  return rpc_status;
13809  }
13810 
13811  /* extract result variables and place it to argument list */
13812 
13813  va_start(ap, routine_id);
13814 
13815  status = rpc_call_decode(ap, rpc_entry, buf, buf_size);
13816 
13817  if (status != RPC_SUCCESS) {
13818  rpc_status = status;
13819  }
13820 
13821  va_end(ap);
13822 
13823  if (buf)
13824  free(buf);
13825 
13826  return rpc_status;
13827 }
INT cm_get_watchdog_params(BOOL *call_watchdog, DWORD *timeout)
Definition: midas.cxx:3313
INT cm_set_watchdog_params_local(BOOL call_watchdog, DWORD timeout)
Definition: midas.cxx:3239
#define SS_SUCCESS
Definition: midas.h:669
#define SS_TIMEOUT
Definition: midas.h:680
#define RPC_INVALID_ID
Definition: midas.h:712
#define RPC_MUTEX_TIMEOUT
Definition: midas.h:716
#define RPC_TIMEOUT
Definition: midas.h:708
#define RPC_NET_ERROR
Definition: midas.h:707
unsigned int DWORD
Definition: mcstd.h:51
#define RPC_NO_REPLY
Definition: midas.h:403
INT ss_mutex_release(MUTEX_T *mutex)
Definition: system.cxx:3096
INT ss_mutex_create(MUTEX_T **mutex, BOOL recursive)
Definition: system.cxx:2880
INT ss_recv_net_command(int sock, DWORD *routine_id, DWORD *param_size, char **param_ptr, int timeout_ms)
Definition: system.cxx:5568
INT send_tcp(int sock, char *buffer, DWORD buffer_size, INT flags)
Definition: system.cxx:5218
INT ss_mutex_wait_for(MUTEX_T *mutex, INT timeout)
Definition: system.cxx:2976
bool rpc_is_remote(void)
Definition: midas.cxx:12728
static std::vector< RPC_LIST > rpc_list
Definition: midas.cxx:11540
static void rpc_call_encode(va_list &ap, const RPC_LIST &rl, NET_COMMAND **nc)
Definition: midas.cxx:13198
static std::mutex rpc_list_mutex
Definition: midas.cxx:11541
static int rpc_call_decode(va_list &ap, const RPC_LIST &rl, const char *buf, size_t buf_size)
Definition: midas.cxx:13369
static RPC_SERVER_CONNECTION _server_connection
Definition: midas.cxx:11465
static MUTEX_T * _mutex_rpc
Definition: midas.cxx:229
DWORD BOOL
Definition: midas.h:105
DWORD status
Definition: odbhist.cxx:39
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 13369 of file midas.cxx.

13370 {
13371  bool debug = false;
13372 
13373  if (debug)
13374  printf("decode reply to rpc_id %d \"%s\" has %d bytes\n", rl.id, rl.name, (int)buf_size);
13375 
13376  /* extract result variables and place it to argument list */
13377 
13378  const char* param_ptr = buf;
13379 
13380  for (int i = 0; rl.param[i].tid != 0; i++) {
13381  int tid = rl.param[i].tid;
13382  int flags = rl.param[i].flags;
13383  int arg_type = 0;
13384 
13385  bool bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
13386  (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
13387  tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
13388 
13389  if (bpointer)
13390  arg_type = TID_ARRAY;
13391  else
13392  arg_type = rl.param[i].tid;
13393 
13394  if (tid == TID_FLOAT && !bpointer)
13395  arg_type = TID_DOUBLE;
13396 
13397  char arg[8];
13398  rpc_va_arg(&ap, arg_type, arg);
13399 
13400  if (rl.param[i].flags & RPC_OUT) {
13401 
13402  if (param_ptr == NULL) {
13403  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);
13404  return RPC_NET_ERROR;
13405  }
13406 
13407  tid = rl.param[i].tid;
13408  int arg_size = rpc_tid_size(tid);
13409 
13410  if (tid == TID_STRING || tid == TID_LINK)
13411  arg_size = strlen((char *) (param_ptr)) + 1;
13412 
13413  if (flags & RPC_VARARRAY) {
13414  arg_size = *((INT *) param_ptr);
13415  param_ptr += ALIGN8(sizeof(INT));
13416  }
13417 
13418  if (tid == TID_STRUCT || (flags & RPC_FIXARRAY))
13419  arg_size = rl.param[i].n;
13420 
13421  /* parameter size is always aligned */
13422  int param_size = ALIGN8(arg_size);
13423 
13424  /* return parameters are always pointers */
13425  if (*((char **) arg)) {
13426  if (debug)
13427  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);
13428  memcpy((void *) *((char **) arg), param_ptr, arg_size);
13429  }
13430 
13431  param_ptr += param_size;
13432  }
13433  }
13434 
13435  return RPC_SUCCESS;
13436 }
#define TID_DOUBLE
Definition: midas.h:350
#define TID_STRUCT
Definition: midas.h:355
#define TID_LINK
Definition: midas.h:357
#define TID_STRING
Definition: midas.h:353
#define TID_ARRAY
Definition: midas.h:354
#define TID_FLOAT
Definition: midas.h:348
void rpc_va_arg(va_list *arg_ptr, INT arg_type, void *arg)
Definition: midas.cxx:13160
INT rpc_tid_size(INT id)
Definition: midas.cxx:11724
BOOL debug
debug printouts
Definition: mana.cxx:254
#define RPC_OUT
Definition: midas.h:1579
#define RPC_POINTER
Definition: midas.h:1580
#define RPC_VARARRAY
Definition: midas.h:1582
#define RPC_FIXARRAY
Definition: midas.h:1581
RPC_PARAM param[MAX_RPC_PARAMS]
Definition: midas.h:1598
INT id
Definition: midas.h:1596
const char * name
Definition: midas.h:1597
WORD flags
Definition: midas.h:1589
WORD tid
Definition: midas.h:1588
INT n
Definition: midas.h:1590
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 13198 of file midas.cxx.

13199 {
13200  bool debug = false;
13201 
13202  if (debug) {
13203  printf("encode rpc_id %d \"%s\"\n", rl.id, rl.name);
13204  for (int i=0; rl.param[i].tid != 0; i++) {
13205  int tid = rl.param[i].tid;
13206  int flags = rl.param[i].flags;
13207  int n = rl.param[i].n;
13208  printf("i=%d, tid %d, flags 0x%x, n %d\n", i, tid, flags, n);
13209  }
13210  }
13211 
13212  char args[MAX_RPC_PARAMS][8];
13213 
13214  for (int i=0; rl.param[i].tid != 0; i++) {
13215  int tid = rl.param[i].tid;
13216  int flags = rl.param[i].flags;
13217  int arg_type = 0;
13218 
13219  bool bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
13220  (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
13221  tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
13222 
13223  if (bpointer)
13224  arg_type = TID_ARRAY;
13225  else
13226  arg_type = tid;
13227 
13228  /* floats are passed as doubles, at least under NT */
13229  if (tid == TID_FLOAT && !bpointer)
13230  arg_type = TID_DOUBLE;
13231 
13232  //printf("arg %d, tid %d, flags 0x%x, arg_type %d, bpointer %d\n", i, tid, flags, arg_type, bpointer);
13233 
13234  rpc_va_arg(&ap, arg_type, args[i]);
13235  }
13236 
13237  size_t buf_size = sizeof(NET_COMMAND) + 4 * 1024;
13238  char* buf = (char *)malloc(buf_size);
13239  assert(buf);
13240 
13241  (*nc) = (NET_COMMAND*) buf;
13242 
13243  /* find out if we are on a big endian system */
13244  bool bbig = ((rpc_get_hw_type() & DRI_BIG_ENDIAN) > 0);
13245 
13246  char* param_ptr = (*nc)->param;
13247 
13248  for (int i=0; rl.param[i].tid != 0; i++) {
13249  int tid = rl.param[i].tid;
13250  int flags = rl.param[i].flags;
13251  int arg_type = 0;
13252 
13253  bool bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
13254  (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
13255  tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
13256 
13257  if (bpointer)
13258  arg_type = TID_ARRAY;
13259  else
13260  arg_type = tid;
13261 
13262  /* floats are passed as doubles, at least under NT */
13263  if (tid == TID_FLOAT && !bpointer)
13264  arg_type = TID_DOUBLE;
13265 
13266  /* get pointer to argument */
13267  //char arg[8];
13268  //rpc_va_arg(&ap, arg_type, arg);
13269 
13270  char* arg = args[i];
13271 
13272  /* shift 1- and 2-byte parameters to the LSB on big endian systems */
13273  if (bbig) {
13274  if (tid == TID_UINT8 || tid == TID_CHAR || tid == TID_INT8) {
13275  arg[0] = arg[3];
13276  }
13277  if (tid == TID_UINT16 || tid == TID_INT16) {
13278  arg[0] = arg[2];
13279  arg[1] = arg[3];
13280  }
13281  }
13282 
13283  if (flags & RPC_IN) {
13284  int arg_size = 0;
13285 
13286  if (bpointer)
13287  arg_size = rpc_tid_size(tid);
13288  else
13289  arg_size = rpc_tid_size(arg_type);
13290 
13291  /* for strings, the argument size depends on the string length */
13292  if (tid == TID_STRING || tid == TID_LINK) {
13293  arg_size = 1 + strlen((char *) *((char **) arg));
13294  }
13295 
13296  /* for varibale length arrays, the size is given by
13297  the next parameter on the stack */
13298  if (flags & RPC_VARARRAY) {
13299  //va_list aptmp;
13301  //va_copy(aptmp, ap);
13302 
13303  //char arg_tmp[8];
13304  //rpc_va_arg(&aptmp, TID_ARRAY, arg_tmp);
13305 
13306  const char* arg_tmp = args[i+1];
13307 
13308  /* for (RPC_IN+RPC_OUT) parameters, size argument is a pointer */
13309  if (flags & RPC_OUT)
13310  arg_size = *((INT *) *((void **) arg_tmp));
13311  else
13312  arg_size = *((INT *) arg_tmp);
13313 
13314  *((INT *) param_ptr) = ALIGN8(arg_size);
13315  param_ptr += ALIGN8(sizeof(INT));
13316 
13317  //va_end(aptmp);
13318  }
13319 
13320  if (tid == TID_STRUCT || (flags & RPC_FIXARRAY))
13321  arg_size = rl.param[i].n;
13322 
13323  /* always align parameter size */
13324  int param_size = ALIGN8(arg_size);
13325 
13326  {
13327  size_t param_offset = (char *) param_ptr - (char *)(*nc);
13328 
13329  if (param_offset + param_size + 16 > buf_size) {
13330  size_t new_size = param_offset + param_size + 1024;
13331  //printf("resize nc %zu to %zu\n", buf_size, new_size);
13332  buf = (char *) realloc(buf, new_size);
13333  assert(buf);
13334  buf_size = new_size;
13335  (*nc) = (NET_COMMAND*) buf;
13336  param_ptr = buf + param_offset;
13337  }
13338  }
13339 
13340  if (bpointer) {
13341  if (debug) {
13342  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);
13343  }
13344  memcpy(param_ptr, (void *) *((void **) arg), arg_size);
13345  } else if (tid == TID_FLOAT) {
13346  if (debug) {
13347  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);
13348  }
13349  /* floats are passed as doubles on most systems */
13350  *((float *) param_ptr) = (float) *((double *) arg);
13351  } else {
13352  if (debug) {
13353  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);
13354  }
13355  memcpy(param_ptr, arg, arg_size);
13356  }
13357 
13358  param_ptr += param_size;
13359  }
13360  }
13361 
13362  (*nc)->header.param_size = (POINTER_T) param_ptr - (POINTER_T) (*nc)->param;
13363 
13364  if (debug)
13365  printf("encode rpc_id %d \"%s\" buf_size %d, param_size %d\n", rl.id, rl.name, (int)buf_size, (*nc)->header.param_size);
13366 }
#define TID_UINT8
Definition: midas.h:335
#define TID_INT8
Definition: midas.h:337
#define TID_CHAR
Definition: midas.h:338
#define TID_UINT16
Definition: midas.h:340
INT rpc_get_hw_type()
Definition: midas.cxx:12801
#define RPC_IN
Definition: midas.h:1578
#define MAX_RPC_PARAMS
Definition: midas.h:1593
#define POINTER_T
Definition: midas.h:166
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_check_allowed_host()

INT rpc_check_allowed_host ( const char *  hostname)

Definition at line 15231 of file midas.cxx.

15242 {
15243  //printf("rpc_check_allowed_host: enabled %d, hostname [%s]\n", gAllowedHostsEnabled.load(), hostname);
15244 
15245  if (!gAllowedHostsEnabled)
15246  return RPC_SUCCESS;
15247 
15248  if (strcmp(hostname, "localhost") == 0)
15249  return RPC_SUCCESS;
15250 
15251  if (strcmp(hostname, "localhost.localdomain") == 0)
15252  return RPC_SUCCESS;
15253 
15254  if (strcmp(hostname, "localhost6") == 0) // RedHat el6, el7
15255  return RPC_SUCCESS;
15256 
15257  if (strcmp(hostname, "ip6-localhost") == 0) // Ubuntu-22
15258  return RPC_SUCCESS;
15259 
15260  int status = RPC_NOT_REGISTERED;
15261 
15262  gAllowedHostsMutex.lock();
15263 
15264  for (const auto& h: gAllowedHosts) {
15265  if (h == hostname) {
15266  status = RPC_SUCCESS;
15267  break;
15268  }
15269  }
15270 
15271  gAllowedHostsMutex.unlock();
15272 
15273  //if (status != RPC_SUCCESS)
15274  // printf("rpc_check_allowed_host: enabled %d, hostname [%s] not found\n", gAllowedHostsEnabled.load(), hostname);
15275 
15276  return status;
15277 }
#define RPC_NOT_REGISTERED
Definition: midas.h:710
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 16221 of file midas.cxx.

16239 {
16240  INT status;
16241  NET_COMMAND nc;
16242  fd_set readfds;
16243  struct timeval timeout;
16244 
16245  for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
16246  if (_server_acceptions[idx] && _server_acceptions[idx]->recv_sock) {
16248  if (sa == NULL)
16249  continue;
16250 
16251  if (sa->watchdog_timeout == 0) {
16252  continue;
16253  }
16254 
16255  DWORD elapsed = ss_millitime() - sa->last_activity;
16256  //printf("rpc_check_channels: idx %d, watchdog_timeout %d, last_activity %d, elapsed %d\n", idx, sa->watchdog_timeout, sa->last_activity, elapsed);
16257 
16258  if (sa->watchdog_timeout && (elapsed > (DWORD)sa->watchdog_timeout)) {
16259 
16260  //printf("rpc_check_channels: send watchdog message to %s on %s\n", sa->prog_name.c_str(), sa->host_name.c_str());
16261 
16262  /* send a watchdog message */
16264  nc.header.param_size = 0;
16265 
16266  int convert_flags = sa->convert_flags;
16267  if (convert_flags) {
16270  }
16271 
16272  /* send the header to the client */
16273  int i = send_tcp(sa->send_sock, (char *) &nc, sizeof(NET_COMMAND_HEADER), 0);
16274 
16275  if (i < 0) {
16276  cm_msg(MINFO, "rpc_check_channels", "client \"%s\" on host \"%s\" failed watchdog test after %d sec, send_tcp() returned %d",
16277  sa->prog_name.c_str(),
16278  sa->host_name.c_str(),
16279  sa->watchdog_timeout / 1000,
16280  i);
16281 
16282  /* disconnect from experiment */
16283  if (rpc_is_mserver()) {
16285  return RPC_NET_ERROR;
16286  }
16287 
16288  sa->close();
16289  return RPC_NET_ERROR;
16290  }
16291 
16292  /* make some timeout checking */
16293  FD_ZERO(&readfds);
16294  FD_SET(sa->send_sock, &readfds);
16295  FD_SET(sa->recv_sock, &readfds);
16296 
16297  timeout.tv_sec = sa->watchdog_timeout / 1000;
16298  timeout.tv_usec = (sa->watchdog_timeout % 1000) * 1000;
16299 
16300  do {
16301  status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
16302 
16303  /* if an alarm signal was cought, restart select with reduced timeout */
16304  if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
16305  timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
16306 
16307  } while (status == -1); /* dont return if an alarm signal was cought */
16308 
16309  if (!FD_ISSET(sa->send_sock, &readfds) &&
16310  !FD_ISSET(sa->recv_sock, &readfds)) {
16311 
16312  cm_msg(MINFO, "rpc_check_channels", "client \"%s\" on host \"%s\" failed watchdog test after %d sec",
16313  sa->prog_name.c_str(),
16314  sa->host_name.c_str(),
16315  sa->watchdog_timeout / 1000);
16316 
16317  /* disconnect from experiment */
16318  if (rpc_is_mserver()) {
16320  return RPC_NET_ERROR;
16321  }
16322 
16323  sa->close();
16324  return RPC_NET_ERROR;
16325  }
16326 
16327  /* receive result on send socket */
16328  if (FD_ISSET(sa->send_sock, &readfds)) {
16329  i = recv_tcp(sa->send_sock, (char *) &nc, sizeof(nc), 0);
16330  if (i <= 0) {
16331  cm_msg(MINFO, "rpc_check_channels", "client \"%s\" on host \"%s\" failed watchdog test after %d sec, recv_tcp() returned %d",
16332  sa->prog_name.c_str(),
16333  sa->host_name.c_str(),
16334  sa->watchdog_timeout / 1000,
16335  i);
16336 
16337  /* disconnect from experiment */
16338  if (rpc_is_mserver()) {
16340  return RPC_NET_ERROR;
16341  }
16342 
16343  sa->close();
16344  return RPC_NET_ERROR;
16345  }
16346  }
16347  }
16348  }
16349  }
16350 
16351  return RPC_SUCCESS;
16352 }
INT cm_disconnect_experiment(void)
Definition: midas.cxx:2840
#define MINFO
Definition: midas.h:566
#define FD_SETSIZE
Definition: msystem.h:199
#define MSG_WATCHDOG
Definition: msystem.h:300
DWORD ss_millitime()
Definition: system.cxx:3332
INT recv_tcp(int sock, char *net_buffer, DWORD buffer_size, INT flags)
Definition: system.cxx:5387
bool rpc_is_mserver(void)
Definition: midas.cxx:12785
#define RPC_OUTGOING
Definition: midas.h:1583
#define WATCHDOG_INTERVAL
Definition: midas.h:295
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 15177 of file midas.cxx.

15193 {
15194  gAllowedHostsMutex.lock();
15195  gAllowedHosts.clear();
15196  gAllowedHostsEnabled = false;
15197  gAllowedHostsMutex.unlock();
15198  return RPC_SUCCESS;
15199 }
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 15565 of file midas.cxx.

15586 {
15587  INT i, status;
15588  INT client_hw_type = 0, hw_type;
15589  std::string client_program;
15590  std::string host_name;
15591  INT convert_flags;
15592  char net_buffer[256], *p;
15593 
15594  int sock = accept(lsock, NULL, NULL);
15595 
15596  if (sock == -1)
15597  return RPC_NET_ERROR;
15598 
15599  /* check access control list */
15600  if (gAllowedHostsEnabled) {
15602 
15603  if (status != RPC_SUCCESS) {
15604  ss_socket_close(&sock);
15605  return RPC_NET_ERROR;
15606  }
15607  }
15608 
15609  host_name = "(unknown)";
15610  client_program = "(unknown)";
15611 
15612  /* receive string with timeout */
15613  i = recv_string(sock, net_buffer, sizeof(net_buffer), 10000);
15614  if (i <= 0) {
15615  ss_socket_close(&sock);
15616  return RPC_NET_ERROR;
15617  }
15618 
15619  /* get remote computer info */
15620  p = strtok(net_buffer, " ");
15621  if (p != NULL) {
15622  client_hw_type = atoi(p);
15623  p = strtok(NULL, " ");
15624  }
15625  if (p != NULL) {
15626  //version = atoi(p);
15627  p = strtok(NULL, " ");
15628  }
15629  if (p != NULL) {
15630  client_program = p;
15631  p = strtok(NULL, " ");
15632  }
15633  if (p != NULL) {
15634  host_name = p;
15635  p = strtok(NULL, " ");
15636  }
15637 
15638  //printf("rpc_client_accept: client_hw_type %d, version %d, client_name \'%s\', hostname \'%s\'\n", client_hw_type, version, client_program, host_name);
15639 
15641 
15642  /* save information in _server_acception structure */
15643  sa->recv_sock = sock;
15644  sa->send_sock = 0;
15645  sa->event_sock = 0;
15646  sa->remote_hw_type = client_hw_type;
15647  sa->host_name = host_name;
15648  sa->prog_name = client_program;
15649  sa->last_activity = ss_millitime();
15650  sa->watchdog_timeout = 0;
15651  sa->is_mserver = FALSE;
15652 
15653  /* send my own computer id */
15654  hw_type = rpc_get_hw_type();
15655  std::string str = msprintf("%d %s", hw_type, cm_get_version());
15656  status = send(sock, str.c_str(), str.length() + 1, 0);
15657  if (status != (INT) str.length() + 1)
15658  return RPC_NET_ERROR;
15659 
15660  rpc_calc_convert_flags(hw_type, client_hw_type, &convert_flags);
15661  sa->convert_flags = convert_flags;
15662 
15664 
15665  return RPC_SUCCESS;
15666 }
const char * cm_get_version()
Definition: midas.cxx:1478
INT ss_suspend_set_server_acceptions(RPC_SERVER_ACCEPTION_LIST *acceptions)
Definition: system.cxx:4237
INT recv_string(int sock, char *buffer, DWORD buffer_size, INT millisec)
Definition: system.cxx:5332
static RPC_SERVER_ACCEPTION * rpc_new_server_acception()
Definition: midas.cxx:11485
void rpc_calc_convert_flags(INT hw_type, INT remote_hw_type, INT *convert_flags)
Definition: midas.cxx:11550
static INT rpc_socket_check_allowed_host(int sock)
Definition: midas.cxx:15280
char host_name[HOST_NAME_LENGTH]
Definition: mana.cxx:242
std::string msprintf(const char *format,...)
Definition: midas.cxx:412
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 13439 of file midas.cxx.

13464 {
13466 
13467  if (!c) {
13468  cm_msg(MERROR, "rpc_client_call", "invalid rpc connection handle %d", hConn);
13469  return RPC_NO_CONNECTION;
13470  }
13471 
13472  //printf("rpc_client_call: handle %d, connection: ", hConn);
13473  //c->print();
13474  //printf("\n");
13475 
13476  INT i, status;
13477 
13478  BOOL rpc_no_reply = routine_id & RPC_NO_REPLY;
13479  routine_id &= ~RPC_NO_REPLY;
13480 
13481  //if (rpc_no_reply)
13482  // printf("rpc_client_call: routine_id %d, RPC_NO_REPLY\n", routine_id);
13483 
13484  // make local copy of the client name just in case _client_connection is erased by another thread
13485 
13486  /* find rpc_index */
13487 
13488  int rpc_index = -1;
13489  const char *rpc_name = NULL;
13490  RPC_LIST rpc_entry;
13491 
13492  rpc_list_mutex.lock();
13493  for (size_t i = 0; i < rpc_list.size(); i++) {
13494  if (rpc_list[i].id == (int) routine_id) {
13495  rpc_index = i;
13496  rpc_name = rpc_list[rpc_index].name;
13497  rpc_entry = rpc_list[rpc_index];
13498  break;
13499  }
13500  }
13501  rpc_list_mutex.unlock();
13502 
13503  if (rpc_index < 0) {
13504  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);
13505  c->mutex.unlock();
13506  return RPC_INVALID_ID;
13507  }
13508 
13509  NET_COMMAND *nc = NULL;
13510 
13511  /* examine variable argument list and convert it to parameter array */
13512  va_list ap;
13513  va_start(ap, routine_id);
13514 
13515  rpc_call_encode(ap, rpc_entry, &nc);
13516 
13517  va_end(ap);
13518 
13519  nc->header.routine_id = routine_id;
13520 
13521  if (rpc_no_reply)
13523 
13524  int send_size = nc->header.param_size + sizeof(NET_COMMAND_HEADER);
13525 
13526  /* in FAST TCP mode, only send call and return immediately */
13527  if (rpc_no_reply) {
13528  i = send_tcp(c->send_sock, (char *) nc, send_size, 0);
13529 
13530  if (i != send_size) {
13531  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);
13532  free(nc);
13533  c->mutex.unlock();
13534  return RPC_NET_ERROR;
13535  }
13536 
13537  free(nc);
13538 
13539  if (routine_id == RPC_ID_EXIT || routine_id == RPC_ID_SHUTDOWN) {
13540  //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);
13541  //c->print();
13542  //printf("\n");
13543  c->close_locked();
13544  }
13545 
13546  c->mutex.unlock();
13547  return RPC_SUCCESS;
13548  }
13549 
13550  /* in TCP mode, send and wait for reply on send socket */
13551  i = send_tcp(c->send_sock, (char *) nc, send_size, 0);
13552  if (i != send_size) {
13553  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);
13554  c->mutex.unlock();
13555  return RPC_NET_ERROR;
13556  }
13557 
13558  free(nc);
13559  nc = NULL;
13560 
13561  bool restore_watchdog_timeout = false;
13562  BOOL watchdog_call;
13563  DWORD watchdog_timeout;
13564  cm_get_watchdog_params(&watchdog_call, &watchdog_timeout);
13565 
13566  //printf("watchdog timeout: %d, rpc_timeout: %d\n", watchdog_timeout, c->rpc_timeout);
13567 
13568  if (c->rpc_timeout >= (int) watchdog_timeout) {
13569  restore_watchdog_timeout = true;
13570  cm_set_watchdog_params(watchdog_call, c->rpc_timeout + 1000);
13571  }
13572 
13573  DWORD rpc_status = 0;
13574  DWORD buf_size = 0;
13575  char* buf = NULL;
13576 
13577  /* receive result on send socket */
13578  status = ss_recv_net_command(c->send_sock, &rpc_status, &buf_size, &buf, c->rpc_timeout);
13579 
13580  if (restore_watchdog_timeout) {
13581  cm_set_watchdog_params(watchdog_call, watchdog_timeout);
13582  }
13583 
13584  if (status == SS_TIMEOUT) {
13585  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);
13586  if (buf)
13587  free(buf);
13588  c->mutex.unlock();
13589  return RPC_TIMEOUT;
13590  }
13591 
13592  if (status != SS_SUCCESS) {
13593  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);
13594  if (buf)
13595  free(buf);
13596  c->mutex.unlock();
13597  return RPC_NET_ERROR;
13598  }
13599 
13600  c->mutex.unlock();
13601 
13602  if (rpc_status == RPC_INVALID_ID) {
13603  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);
13604  if (buf)
13605  free(buf);
13606  return rpc_status;
13607  }
13608 
13609  /* extract result variables and place it to argument list */
13610 
13611  va_start(ap, routine_id);
13612 
13613  status = rpc_call_decode(ap, rpc_entry, buf, buf_size);
13614 
13615  if (status != RPC_SUCCESS) {
13616  rpc_status = status;
13617  }
13618 
13619  va_end(ap);
13620 
13621  if (buf)
13622  free(buf);
13623  buf = NULL;
13624  buf_size = 0;
13625 
13626  return rpc_status;
13627 }
INT cm_set_watchdog_params(BOOL call_watchdog, DWORD timeout)
Definition: midas.cxx:3279
#define RPC_NO_CONNECTION
Definition: midas.h:706
#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:12579
char c
Definition: system.cxx:1316
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 12237 of file midas.cxx.

12245 {
12246 #if 0
12247  for (i = 0; i < MAX_RPC_CONNECTION; i++)
12248  if (_client_connection[i].send_sock != 0)
12249  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);
12250 #endif
12251 
12252  std::lock_guard<std::mutex> guard(_client_connections_mutex);
12253 
12254  /* check for broken connections */
12255  for (unsigned i = 0; i < _client_connections.size(); i++) {
12257  if (c && c->connected) {
12258  std::lock_guard<std::mutex> cguard(c->mutex);
12259 
12260  if (!c->connected) {
12261  // implicit unlock
12262  continue;
12263  }
12264 
12265  //printf("rpc_client_check: connection %d: ", i);
12266  //c->print();
12267  //printf("\n");
12268 
12269  int ok = 0;
12270 
12271  fd_set readfds;
12272  FD_ZERO(&readfds);
12273  FD_SET(c->send_sock, &readfds);
12274 
12275  struct timeval timeout;
12276  timeout.tv_sec = 0;
12277  timeout.tv_usec = 0;
12278 
12279  int status;
12280 
12281 #ifdef OS_WINNT
12282  status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
12283 #else
12284  do {
12285  status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
12286  } while (status == -1 && errno == EINTR); /* dont return if an alarm signal was cought */
12287 #endif
12288 
12289  if (!FD_ISSET(c->send_sock, &readfds)) {
12290  // implicit unlock
12291  continue;
12292  }
12293 
12294  char buffer[64];
12295 
12296  status = recv(c->send_sock, (char *) buffer, sizeof(buffer), MSG_PEEK);
12297  //printf("recv %d status %d, errno %d (%s)\n", sock, status, errno, strerror(errno));
12298 
12299  if (status < 0) {
12300 #ifndef OS_WINNT
12301  if (errno == EAGAIN) { // still connected
12302  ok = 1;
12303  } else
12304 #endif
12305  {
12306  // connection error
12307  cm_msg(MERROR, "rpc_client_check",
12308  "RPC client connection to \"%s\" on host \"%s\" is broken, recv() errno %d (%s)",
12309  c->client_name.c_str(),
12310  c->host_name.c_str(),
12311  errno, strerror(errno));
12312  ok = 0;
12313  }
12314  } else if (status == 0) {
12315  // connection closed by remote end without sending an EXIT message
12316  // this can happen if the remote end has crashed, so this message
12317  // is still necessary as a useful diagnostic for unexpected crashes
12318  // of midas programs. K.O.
12319  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());
12320  ok = 0;
12321  } else {
12322  // read some data
12323  ok = 1;
12324  if (equal_ustring(buffer, "EXIT")) {
12325  /* normal exit */
12326  ok = 0;
12327  }
12328  }
12329 
12330  if (!ok) {
12331  //printf("rpc_client_check: closing connection %d: ", i);
12332  //c->print();
12333  //printf("\n");
12334 
12335  // connection lost, close the socket
12336  c->close_locked();
12337  }
12338 
12339  // implicit unlock
12340  }
12341  }
12342 
12343  // implicit unlock of _client_connections_mutex
12344 }
BOOL equal_ustring(const char *str1, const char *str2)
Definition: odb.cxx:3191
static std::mutex _client_connections_mutex
Definition: midas.cxx:11462
static std::vector< RPC_CLIENT_CONNECTION * > _client_connections
Definition: midas.cxx:11463
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 11979 of file midas.cxx.

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

12661 {
12662  /* notify server about exit */
12663 
12664  /* call exit and shutdown with RPC_NO_REPLY because client will exit immediately without possibility of replying */
12665 
12667 
12668  return RPC_SUCCESS;
12669 }
INT rpc_client_call(HNDLE hConn, DWORD routine_id,...)
Definition: midas.cxx:13439
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 11912 of file midas.cxx.

11920 {
11921  INT status = 0;
11922  char net_buffer[256];
11923 
11924  int n = recv_tcp(sock, net_buffer, sizeof(net_buffer), 0);
11925  if (n <= 0)
11926  return SS_ABORT;
11927 
11928  NET_COMMAND *nc = (NET_COMMAND *) net_buffer;
11929 
11930  if (nc->header.routine_id == MSG_ODB) {
11931  status = handle_msg_odb(n, nc);
11932  } else if (nc->header.routine_id == MSG_WATCHDOG) {
11933  nc->header.routine_id = 1;
11934  nc->header.param_size = 0;
11935  send_tcp(sock, net_buffer, sizeof(NET_COMMAND_HEADER), 0);
11936  status = RPC_SUCCESS;
11937  } else if (nc->header.routine_id == MSG_BM) {
11938  fd_set readfds;
11939  struct timeval timeout;
11940 
11941  //printf("rpc_client_dispatch: received MSG_BM!\n");
11942 
11943  /* receive further messages to empty TCP queue */
11944  do {
11945  FD_ZERO(&readfds);
11946  FD_SET(sock, &readfds);
11947 
11948  timeout.tv_sec = 0;
11949  timeout.tv_usec = 0;
11950 
11951  select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
11952 
11953  if (FD_ISSET(sock, &readfds)) {
11954  n = recv_tcp(sock, net_buffer, sizeof(net_buffer), 0);
11955  if (n <= 0)
11956  return SS_ABORT;
11957 
11958  if (nc->header.routine_id == MSG_ODB) {
11959  status = handle_msg_odb(n, nc);
11960  } else if (nc->header.routine_id == MSG_WATCHDOG) {
11961  nc->header.routine_id = 1;
11962  nc->header.param_size = 0;
11963  send_tcp(sock, net_buffer, sizeof(NET_COMMAND_HEADER), 0);
11964  status = RPC_SUCCESS;
11965  }
11966  }
11967 
11968  } while (FD_ISSET(sock, &readfds));
11969 
11970  /* poll event from server */
11971  status = bm_poll_event();
11972  }
11973 
11974  return status;
11975 }
INT bm_poll_event()
Definition: midas.cxx:11093
#define SS_ABORT
Definition: midas.h:683
#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:11898
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 11673 of file midas.cxx.

11701 {
11702  /* convert array */
11703  if (flags & (RPC_FIXARRAY | RPC_VARARRAY)) {
11704  int single_size = rpc_tid_size(tid);
11705  /* don't convert TID_ARRAY & TID_STRUCT */
11706  if (single_size == 0)
11707  return;
11708 
11709  int n = total_size / single_size;
11710 
11711  for (int i = 0; i < n; i++) {
11712  char* p = (char *) data + (i * single_size);
11713  rpc_convert_single(p, tid, flags, convert_flags);
11714  }
11715  } else {
11716  rpc_convert_single(data, tid, flags, convert_flags);
11717  }
11718 }
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 11648 of file midas.cxx.

11648  {
11649 
11650  if (convert_flags & CF_ENDIAN) {
11651  if (tid == TID_UINT16 || tid == TID_INT16) WORD_SWAP(data);
11652  if (tid == TID_UINT32 || tid == TID_INT32 || tid == TID_BOOL || tid == TID_FLOAT) DWORD_SWAP(data);
11653  if (tid == TID_DOUBLE) QWORD_SWAP(data);
11654  }
11655 
11656  if (((convert_flags & CF_IEEE2VAX) && !(flags & RPC_OUTGOING)) ||
11657  ((convert_flags & CF_VAX2IEEE) && (flags & RPC_OUTGOING))) {
11658  if (tid == TID_FLOAT)
11659  rpc_ieee2vax_float((float *) data);
11660  if (tid == TID_DOUBLE)
11661  rpc_ieee2vax_double((double *) data);
11662  }
11663 
11664  if (((convert_flags & CF_IEEE2VAX) && (flags & RPC_OUTGOING)) ||
11665  ((convert_flags & CF_VAX2IEEE) && !(flags & RPC_OUTGOING))) {
11666  if (tid == TID_FLOAT)
11667  rpc_vax2ieee_float((float *) data);
11668  if (tid == TID_DOUBLE)
11669  rpc_vax2ieee_double((double *) data);
11670  }
11671 }
#define TID_BOOL
Definition: midas.h:347
#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:11593
void rpc_ieee2vax_float(float *var)
Definition: midas.cxx:11578
void rpc_ieee2vax_double(double *var)
Definition: midas.cxx:11628
void rpc_vax2ieee_double(double *var)
Definition: midas.cxx:11609
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 13128 of file midas.cxx.

13142 {
13143  va_list argptr;
13144  char str[1000];
13145 
13146  if (_debug_mode) {
13147  va_start(argptr, format);
13148  vsprintf(str, (char *) format, argptr);
13149  va_end(argptr);
13150 
13151  if (_debug_print) {
13152  strcat(str, "\n");
13153  _debug_print(str);
13154  } else
13155  puts(str);
13156  }
13157 }
static void(* _debug_print)(const char *)
Definition: midas.cxx:231
static INT _debug_mode
Definition: midas.cxx:233
Here is the caller graph for this function:

◆ rpc_deregister_functions()

INT rpc_deregister_functions ( void  )

dox

Definition at line 11837 of file midas.cxx.

11854 {
11855  rpc_list_mutex.lock();
11856  rpc_list.clear();
11857  rpc_list_mutex.unlock();
11858 
11859  return RPC_SUCCESS;
11860 }
Here is the caller graph for this function:

◆ rpc_execute()

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

Definition at line 14617 of file midas.cxx.

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

14005  {
14006  return RPC_SUCCESS;
14007 }
Here is the caller graph for this function:

◆ rpc_flush_event_socket()

int rpc_flush_event_socket ( int  timeout_msec)

Definition at line 16103 of file midas.cxx.

16117 {
16118  bool has_data = ss_event_socket_has_data();
16119 
16120  //printf("ss_event_socket_has_data() returned %d\n", has_data);
16121 
16122  if (has_data) {
16123  if (timeout_msec == BM_NO_WAIT) {
16124  return BM_ASYNC_RETURN;
16125  } else if (timeout_msec == BM_WAIT) {
16126  return BM_ASYNC_RETURN;
16127  } else {
16128  int status = ss_suspend(timeout_msec, MSG_BM);
16129  if (status == SS_ABORT || status == SS_EXIT)
16130  return status;
16131  return BM_ASYNC_RETURN;
16132  }
16133  }
16134 
16135  int status = rpc_server_receive_event(0, NULL, timeout_msec);
16136 
16137  //printf("rpc_server_receive_event() status %d\n", status);
16138 
16139  if (status == BM_ASYNC_RETURN) {
16140  return BM_ASYNC_RETURN;
16141  }
16142 
16143  if (status == SS_ABORT || status == SS_EXIT)
16144  return status;
16145 
16146  return BM_SUCCESS;
16147 }
#define BM_ASYNC_RETURN
Definition: midas.h:619
#define BM_SUCCESS
Definition: midas.h:611
#define BM_NO_WAIT
Definition: midas.h:373
#define BM_WAIT
Definition: midas.h:372
INT ss_suspend(INT millisec, INT msg)
Definition: system.cxx:4482
bool ss_event_socket_has_data()
Definition: system.cxx:4459
INT rpc_server_receive_event(int idx, RPC_SERVER_ACCEPTION *sa, int timeout_msec)
Definition: midas.cxx:15948
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 11573 of file midas.cxx.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_get_convert_flags() [2/2]

INT rpc_get_convert_flags ( void  )

dox

Definition at line 12997 of file midas.cxx.

13008 {
13009  if (_mserver_acception)
13011  else
13012  return 0;
13013 }

◆ rpc_get_hw_type()

INT rpc_get_hw_type ( )

Definition at line 12801 of file midas.cxx.

12812 {
12813  {
12814  {
12815  INT tmp_type, size;
12816  DWORD dummy;
12817  unsigned char *p;
12818  float f;
12819  double d;
12820 
12821  tmp_type = 0;
12822 
12823  /* test pointer size */
12824  size = sizeof(p);
12825  if (size == 2)
12826  tmp_type |= DRI_16;
12827  if (size == 4)
12828  tmp_type |= DRI_32;
12829  if (size == 8)
12830  tmp_type |= DRI_64;
12831 
12832  /* test if little or big endian machine */
12833  dummy = 0x12345678;
12834  p = (unsigned char *) &dummy;
12835  if (*p == 0x78)
12836  tmp_type |= DRI_LITTLE_ENDIAN;
12837  else if (*p == 0x12)
12838  tmp_type |= DRI_BIG_ENDIAN;
12839  else
12840  cm_msg(MERROR, "rpc_get_option", "unknown byte order format");
12841 
12842  /* floating point format */
12843  f = (float) 1.2345;
12844  dummy = 0;
12845  memcpy(&dummy, &f, sizeof(f));
12846  if ((dummy & 0xFF) == 0x19 &&
12847  ((dummy >> 8) & 0xFF) == 0x04 && ((dummy >> 16) & 0xFF) == 0x9E
12848  && ((dummy >> 24) & 0xFF) == 0x3F)
12849  tmp_type |= DRF_IEEE;
12850  else if ((dummy & 0xFF) == 0x9E &&
12851  ((dummy >> 8) & 0xFF) == 0x40 && ((dummy >> 16) & 0xFF) == 0x19
12852  && ((dummy >> 24) & 0xFF) == 0x04)
12853  tmp_type |= DRF_G_FLOAT;
12854  else
12855  cm_msg(MERROR, "rpc_get_option", "unknown floating point format");
12856 
12857  d = (double) 1.2345;
12858  dummy = 0;
12859  memcpy(&dummy, &d, sizeof(f));
12860  if ((dummy & 0xFF) == 0x8D && /* little endian */
12861  ((dummy >> 8) & 0xFF) == 0x97 && ((dummy >> 16) & 0xFF) == 0x6E
12862  && ((dummy >> 24) & 0xFF) == 0x12)
12863  tmp_type |= DRF_IEEE;
12864  else if ((dummy & 0xFF) == 0x83 && /* big endian */
12865  ((dummy >> 8) & 0xFF) == 0xC0 && ((dummy >> 16) & 0xFF) == 0xF3
12866  && ((dummy >> 24) & 0xFF) == 0x3F)
12867  tmp_type |= DRF_IEEE;
12868  else if ((dummy & 0xFF) == 0x13 &&
12869  ((dummy >> 8) & 0xFF) == 0x40 && ((dummy >> 16) & 0xFF) == 0x83
12870  && ((dummy >> 24) & 0xFF) == 0xC0)
12871  tmp_type |= DRF_G_FLOAT;
12872  else if ((dummy & 0xFF) == 0x9E &&
12873  ((dummy >> 8) & 0xFF) == 0x40 && ((dummy >> 16) & 0xFF) == 0x18
12874  && ((dummy >> 24) & 0xFF) == 0x04)
12875  cm_msg(MERROR, "rpc_get_option",
12876  "MIDAS cannot handle VAX D FLOAT format. Please compile with the /g_float flag");
12877  else
12878  cm_msg(MERROR, "rpc_get_option", "unknown floating point format");
12879 
12880  return tmp_type;
12881  }
12882  }
12883 }
#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:1317
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 12579 of file midas.cxx.

12580 {
12582  if (hConn >= 0 && hConn < (int)_client_connections.size()) {
12584  if (c && c->connected) {
12585  _client_connections_mutex.unlock();
12586  c->mutex.lock();
12587  if (!c->connected) {
12588  // disconnected while we were waiting for the lock
12589  c->mutex.unlock();
12590  return NULL;
12591  }
12592  return c;
12593  }
12594  }
12595  _client_connections_mutex.unlock();
12596  return NULL;
12597 }
Here is the caller graph for this function:

◆ rpc_get_mserver_acception()

RPC_SERVER_ACCEPTION* rpc_get_mserver_acception ( void  )

Definition at line 11480 of file midas.cxx.

11481 {
11482  return _mserver_acception;
11483 }
Here is the caller graph for this function:

◆ rpc_get_mserver_hostname()

std::string rpc_get_mserver_hostname ( void  )

Definition at line 12772 of file midas.cxx.

12780 {
12782 }
Here is the caller graph for this function:

◆ rpc_get_mserver_path()

const char* rpc_get_mserver_path ( void  )

Definition at line 13018 of file midas.cxx.

13026 {
13027  return _mserver_path.c_str();
13028 }
static std::string _mserver_path
Definition: midas.cxx:13015
Here is the caller graph for this function:

◆ rpc_get_name()

std::string rpc_get_name ( )

Definition at line 13051 of file midas.cxx.

13069 {
13070  return _client_name;
13071 }
Here is the caller graph for this function:

◆ rpc_get_opt_tcp_size()

INT rpc_get_opt_tcp_size ( void  )

Definition at line 13839 of file midas.cxx.

13839  {
13840  return _opt_tcp_size;
13841 }
static int _opt_tcp_size
Definition: midas.cxx:11543

◆ rpc_get_server_acception()

static RPC_SERVER_ACCEPTION* rpc_get_server_acception ( int  idx)
static

Definition at line 11472 of file midas.cxx.

11473 {
11474  assert(idx >= 0);
11475  assert(idx < (int)_server_acceptions.size());
11476  assert(_server_acceptions[idx] != NULL);
11477  return _server_acceptions[idx];
11478 }
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 12940 of file midas.cxx.

12941 {
12942  if (hConn == RPC_HNDLE_MSERVER) {
12944  } else if (hConn == RPC_HNDLE_CONNECT) {
12945  return _rpc_connect_timeout;
12946  } else {
12948  if (c) {
12949  int timeout = c->rpc_timeout;
12950  c->mutex.unlock();
12951  return timeout;
12952  }
12953  }
12954  return 0;
12955 }
#define RPC_HNDLE_CONNECT
Definition: midas.h:401
#define RPC_HNDLE_MSERVER
Definition: midas.h:400
Here is the call graph for this function:

◆ rpc_ieee2vax_double()

void rpc_ieee2vax_double ( double *  var)

Definition at line 11628 of file midas.cxx.

11628  {
11629  unsigned short int i1, i2, i3, i4;
11630 
11631  /* swap words */
11632  i1 = *((short int *) (var) + 3);
11633  i2 = *((short int *) (var) + 2);
11634  i3 = *((short int *) (var) + 1);
11635  i4 = *((short int *) (var));
11636 
11637  /* correct exponent */
11638  if (i1 != 0)
11639  i1 += 0x20;
11640 
11641  *((short int *) (var) + 3) = i4;
11642  *((short int *) (var) + 2) = i3;
11643  *((short int *) (var) + 1) = i2;
11644  *((short int *) (var)) = i1;
11645 }
Here is the caller graph for this function:

◆ rpc_ieee2vax_float()

void rpc_ieee2vax_float ( float *  var)

Definition at line 11578 of file midas.cxx.

11578  {
11579  unsigned short int lo, hi;
11580 
11581  /* swap hi and lo word */
11582  lo = *((short int *) (var) + 1);
11583  hi = *((short int *) (var));
11584 
11585  /* correct exponent */
11586  if (lo != 0)
11587  lo += 0x100;
11588 
11589  *((short int *) (var) + 1) = hi;
11590  *((short int *) (var)) = lo;
11591 }
Here is the caller graph for this function:

◆ rpc_is_connected()

bool rpc_is_connected ( void  )

Definition at line 12750 of file midas.cxx.

12767 {
12768  return _server_connection.send_sock != 0;
12769 }
Here is the caller graph for this function:

◆ rpc_is_mserver()

bool rpc_is_mserver ( void  )

Definition at line 12785 of file midas.cxx.

12796 {
12797  return _mserver_acception != NULL;
12798 }
Here is the caller graph for this function:

◆ rpc_is_remote()

bool rpc_is_remote ( void  )

Definition at line 12728 of file midas.cxx.

12745 {
12746  return _rpc_is_remote;
12747 }
static bool _rpc_is_remote
Definition: midas.cxx:11466

◆ rpc_name_tid()

int rpc_name_tid ( const char *  name)

Definition at line 11745 of file midas.cxx.

11746 {
11747  for (int i=0; i<TID_LAST; i++) {
11748  if (strcmp(name, tid_name[i]) == 0)
11749  return i;
11750  }
11751 
11752  for (int i=0; i<TID_LAST; i++) {
11753  if (strcmp(name, tid_name_old[i]) == 0)
11754  return i;
11755  }
11756 
11757  return 0;
11758 }
#define TID_LAST
Definition: midas.h:361
static const char * tid_name[]
Definition: midas.cxx:113
static const char * tid_name_old[]
Definition: midas.cxx:91
#define name(x)
Definition: midas_macro.h:24
Here is the caller graph for this function:

◆ rpc_new_server_acception()

static RPC_SERVER_ACCEPTION* rpc_new_server_acception ( )
static

Definition at line 11485 of file midas.cxx.

11486 {
11487  for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
11488  if (_server_acceptions[idx] && (_server_acceptions[idx]->recv_sock == 0)) {
11489  //printf("rpc_new_server_acception: reuse acception in slot %d\n", idx);
11490  return _server_acceptions[idx];
11491  }
11492  }
11493 
11495 
11496  for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
11497  if (_server_acceptions[idx] == NULL) {
11498  //printf("rpc_new_server_acception: new acception, reuse slot %d\n", idx);
11499  _server_acceptions[idx] = sa;
11500  return _server_acceptions[idx];
11501  }
11502  }
11503 
11504  //printf("rpc_new_server_acception: new acception, array size %d, push_back\n", (int)_server_acceptions.size());
11505  _server_acceptions.push_back(sa);
11506 
11507  return sa;
11508 }
struct rpc_server_acception_struct RPC_SERVER_ACCEPTION
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 11775 of file midas.cxx.

11775  {
11776  rpc_set_name(name);
11779 
11780  return RPC_SUCCESS;
11781 }
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:11794
INT rpc_set_name(const char *name)
Definition: midas.cxx:13075
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 11864 of file midas.cxx.

11883 {
11884  std::lock_guard<std::mutex> guard(rpc_list_mutex);
11885 
11886  for (size_t i = 0; i < rpc_list.size(); i++) {
11887  if (rpc_list[i].id == id) {
11888  rpc_list[i].dispatch = func;
11889  return RPC_SUCCESS;
11890  }
11891  }
11892 
11893  return RPC_INVALID_ID;
11894 }
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 11794 of file midas.cxx.

11795 {
11796  for (int i = 0; new_list[i].id != 0; i++) {
11797  /* check valid ID for user functions */
11798  if (new_list != rpc_get_internal_list(0) &&
11799  new_list != rpc_get_internal_list(1) && (new_list[i].id < RPC_MIN_ID
11800  || new_list[i].id > RPC_MAX_ID)) {
11801  cm_msg(MERROR, "rpc_register_functions", "registered RPC function with invalid ID %d", new_list[i].id);
11802  }
11803  }
11804 
11805  std::lock_guard<std::mutex> guard(rpc_list_mutex);
11806 
11807  /* check double defined functions */
11808  for (int i = 0; new_list[i].id != 0; i++) {
11809  for (size_t j = 0; j < rpc_list.size(); j++) {
11810  if (rpc_list[j].id == new_list[i].id) {
11811  return RPC_DOUBLE_DEFINED;
11812  }
11813  }
11814  }
11815 
11816  /* append new functions */
11817  for (int i = 0; new_list[i].id != 0; i++) {
11818  RPC_LIST e = new_list[i];
11819 
11820  /* set default dispatcher */
11821  if (e.dispatch == NULL) {
11822  e.dispatch = func;
11823  }
11824 
11825  rpc_list.push_back(e);
11826  }
11827 
11828  return RPC_SUCCESS;
11829 }
#define RPC_DOUBLE_DEFINED
Definition: midas.h:715
#define RPC_MIN_ID
Definition: midas.h:1604
#define RPC_MAX_ID
Definition: midas.h:1605
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 14546 of file midas.cxx.

14569 {
14570  /* register system functions: RPC_ID_EXIT, RPC_ID_SHUTDOWN, RPC_ID_WATCHDOG */
14572 
14573  /* create a socket for listening */
14574  int lsock = 0;
14575  int lport = 0;
14576  std::string errmsg;
14577 
14578  int status = ss_socket_listen_tcp(!disable_bind_rpc_to_localhost, port, &lsock, &lport, &errmsg);
14579 
14580  if (status != SS_SUCCESS) {
14581  cm_msg(MERROR, "rpc_register_server", "cannot listen to tcp port %d: %s", port, errmsg.c_str());
14582  return RPC_NET_ERROR;
14583  }
14584 
14585  /* set close-on-exec flag to prevent child mserver processes from inheriting the listen socket */
14586 #if defined(F_SETFD) && defined(FD_CLOEXEC)
14587  status = fcntl(lsock, F_SETFD, fcntl(lsock, F_GETFD) | FD_CLOEXEC);
14588  if (status < 0) {
14589  cm_msg(MERROR, "rpc_register_server", "fcntl(F_SETFD, FD_CLOEXEC) failed, errno %d (%s)", errno, strerror(errno));
14590  return RPC_NET_ERROR;
14591  }
14592 #endif
14593 
14594  /* return port wich OS has choosen */
14595  if (pport) {
14596  *pport = lport;
14597  }
14598 
14599  if (plsock)
14600  *plsock = lsock;
14601 
14602  //printf("rpc_register_server: requested port %d, actual port %d, socket %d\n", port, *pport, *plsock);
14603 
14604  return RPC_SUCCESS;
14605 }
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:5001
static int disable_bind_rpc_to_localhost
Definition: midas.cxx:239
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 14505 of file midas.cxx.

14527 {
14528  int status;
14529  int lsock;
14530 
14531  status = rpc_register_listener(port, NULL, &lsock, pport);
14532  if (status != RPC_SUCCESS)
14533  return status;
14534 
14536  if (status != SS_SUCCESS)
14537  return status;
14538 
14539  if (plsock)
14540  *plsock = lsock;
14541 
14542  return RPC_SUCCESS;
14543 }
INT ss_suspend_set_client_listener(int listen_socket)
Definition: system.cxx:4223
INT rpc_register_listener(int port, RPC_HANDLER func, int *plsock, int *pport)
Definition: midas.cxx:14546
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 13868 of file midas.cxx.

13869 {
13870  if (rpc_is_remote()) {
13871  return rpc_send_event1(buffer_handle, pevent);
13872  } else {
13873  return bm_send_event(buffer_handle, pevent, unused, async_flag);
13874  }
13875 }
INT bm_send_event(INT buffer_handle, const EVENT_HEADER *pevent, int unused, int timeout_msec)
Definition: midas.cxx:9645
INT rpc_send_event1(INT buffer_handle, const EVENT_HEADER *pevent)
Definition: midas.cxx:13886
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 13886 of file midas.cxx.

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

13893 {
13894  if (sg_n < 1) {
13895  cm_msg(MERROR, "rpc_send_event_sg", "invalid sg_n %d", sg_n);
13896  return BM_INVALID_SIZE;
13897  }
13898 
13899  if (sg_ptr[0] == NULL) {
13900  cm_msg(MERROR, "rpc_send_event_sg", "invalid sg_ptr[0] is NULL");
13901  return BM_INVALID_SIZE;
13902  }
13903 
13904  if (sg_len[0] < sizeof(EVENT_HEADER)) {
13905  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));
13906  return BM_INVALID_SIZE;
13907  }
13908 
13909  const EVENT_HEADER* pevent = (const EVENT_HEADER*)sg_ptr[0];
13910 
13911  const DWORD MAX_DATA_SIZE = (0x7FFFFFF0 - 16); // event size computations are not 32-bit clean, limit event size to 2GB. K.O.
13912  const DWORD data_size = pevent->data_size; // 32-bit unsigned value
13913 
13914  if (data_size == 0) {
13915  cm_msg(MERROR, "rpc_send_event_sg", "invalid event data size zero");
13916  return BM_INVALID_SIZE;
13917  }
13918 
13919  if (data_size > MAX_DATA_SIZE) {
13920  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);
13921  return BM_INVALID_SIZE;
13922  }
13923 
13924  const size_t event_size = sizeof(EVENT_HEADER) + data_size;
13925  const size_t total_size = ALIGN8(event_size);
13926 
13927  size_t count = 0;
13928  for (int i=0; i<sg_n; i++) {
13929  count += sg_len[i];
13930  }
13931 
13932  if (count != event_size) {
13933  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);
13934  return BM_INVALID_SIZE;
13935  }
13936 
13937  // protect non-atomic access to _server_connection.event_sock. K.O.
13938 
13939  std::lock_guard<std::mutex> guard(_server_connection.event_sock_mutex);
13940 
13941  //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);
13942 
13943  if (_server_connection.event_sock == 0) {
13944  return RPC_NO_CONNECTION;
13945  }
13946 
13947  //
13948  // event socket wire protocol: (see also rpc_server_receive_event() and recv_event_server_realloc())
13949  //
13950  // 4 bytes of buffer handle
13951  // 16 bytes of event header, includes data_size
13952  // ALIGN8(data_size) bytes of event data
13953  //
13954 
13955  int status;
13956 
13957  /* send buffer handle */
13958 
13959  assert(sizeof(DWORD) == 4);
13960  DWORD bh_buf = buffer_handle;
13961 
13962  status = ss_write_tcp(_server_connection.event_sock, (const char *) &bh_buf, sizeof(DWORD));
13963  if (status != SS_SUCCESS) {
13965  cm_msg(MERROR, "rpc_send_event_sg", "ss_write_tcp(buffer handle) failed, event socket is now closed");
13966  return RPC_NET_ERROR;
13967  }
13968 
13969  /* send data */
13970 
13971  for (int i=0; i<sg_n; i++) {
13972  status = ss_write_tcp(_server_connection.event_sock, sg_ptr[i], sg_len[i]);
13973  if (status != SS_SUCCESS) {
13975  cm_msg(MERROR, "rpc_send_event_sg", "ss_write_tcp(event data) failed, event socket is now closed");
13976  return RPC_NET_ERROR;
13977  }
13978  }
13979 
13980  /* send padding */
13981 
13982  if (count < total_size) {
13983  char padding[8] = { 0,0,0,0,0,0,0,0 };
13984  size_t padlen = total_size - count;
13985  assert(padlen < 8);
13986  status = ss_write_tcp(_server_connection.event_sock, padding, padlen);
13987  if (status != SS_SUCCESS) {
13989  cm_msg(MERROR, "rpc_send_event_sg", "ss_write_tcp(padding) failed, event socket is now closed");
13990  return RPC_NET_ERROR;
13991  }
13992  }
13993 
13994  return RPC_SUCCESS;
13995 }
#define BM_INVALID_SIZE
Definition: midas.h:630
INT ss_write_tcp(int sock, const char *buffer, size_t buffer_size)
Definition: system.cxx:5285
double count
Definition: mdump.cxx:36
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 15308 of file midas.cxx.

15329 {
15330  INT i;
15331  INT sock;
15332  char version[NAME_LENGTH], v1[32];
15333  char experiment[NAME_LENGTH];
15334  INT port1, port2, port3;
15335  char *ptr;
15336  char net_buffer[256];
15337  struct linger ling;
15338 
15339  static struct callback_addr callback;
15340 
15341  if (lsock > 0) {
15342  sock = accept(lsock, NULL, NULL);
15343 
15344  if (sock == -1)
15345  return RPC_NET_ERROR;
15346  } else {
15347  /* lsock is stdin -> already connected from inetd */
15348 
15349  sock = lsock;
15350  }
15351 
15352  /* check access control list */
15353  if (gAllowedHostsEnabled) {
15355 
15356  if (status != RPC_SUCCESS) {
15357  ss_socket_close(&sock);
15358  return RPC_NET_ERROR;
15359  }
15360  }
15361 
15362  /* receive string with timeout */
15363  i = recv_string(sock, net_buffer, 256, 10000);
15364  rpc_debug_printf("Received command: %s", net_buffer);
15365 
15366  if (i > 0) {
15367  char command = (char) toupper(net_buffer[0]);
15368 
15369  //printf("rpc_server_accept: command [%c]\n", command);
15370 
15371  switch (command) {
15372  case 'S': {
15373 
15374  /*----------- shutdown listener ----------------------*/
15375  ss_socket_close(&sock);
15376  return RPC_SHUTDOWN;
15377  }
15378  case 'I': {
15379 
15380  /*----------- return available experiments -----------*/
15381 #ifdef LOCAL_ROUTINES
15382  exptab_struct exptab;
15383  cm_read_exptab(&exptab); // thread safe!
15384  for (unsigned i=0; i<exptab.exptab.size(); i++) {
15385  rpc_debug_printf("Return experiment: %s", exptab.exptab[i].name.c_str());
15386  const char* str = exptab.exptab[i].name.c_str();
15387  send(sock, str, strlen(str) + 1, 0);
15388  }
15389  send(sock, "", 1, 0);
15390 #endif
15391  ss_socket_close(&sock);
15392  break;
15393  }
15394  case 'C': {
15395 
15396  /*----------- connect to experiment -----------*/
15397 
15398  /* get callback information */
15399  callback.experiment[0] = 0;
15400  port1 = port2 = version[0] = 0;
15401 
15402  //printf("rpc_server_accept: net buffer \'%s\'\n", net_buffer);
15403 
15404  /* parse string in format "C port1 port2 port3 version expt" */
15405  /* example: C 51046 45838 56832 2.0.0 alpha */
15406 
15407  port1 = strtoul(net_buffer + 2, &ptr, 0);
15408  port2 = strtoul(ptr, &ptr, 0);
15409  port3 = strtoul(ptr, &ptr, 0);
15410 
15411  while (*ptr == ' ')
15412  ptr++;
15413 
15414  i = 0;
15415  for (; *ptr != 0 && *ptr != ' ' && i < (int) sizeof(version) - 1;)
15416  version[i++] = *ptr++;
15417 
15418  // ensure that we do not overwrite buffer "version"
15419  assert(i < (int) sizeof(version));
15420  version[i] = 0;
15421 
15422  // skip wjatever is left from the "version" string
15423  for (; *ptr != 0 && *ptr != ' ';)
15424  ptr++;
15425 
15426  while (*ptr == ' ')
15427  ptr++;
15428 
15429  i = 0;
15430  for (; *ptr != 0 && *ptr != ' ' && *ptr != '\n' && *ptr != '\r' && i < (int) sizeof(experiment) - 1;)
15431  experiment[i++] = *ptr++;
15432 
15433  // ensure that we do not overwrite buffer "experiment"
15434  assert(i < (int) sizeof(experiment));
15435  experiment[i] = 0;
15436 
15438 
15439  /* print warning if version patch level doesn't agree */
15440  strlcpy(v1, version, sizeof(v1));
15441  if (strchr(v1, '.'))
15442  if (strchr(strchr(v1, '.') + 1, '.'))
15443  *strchr(strchr(v1, '.') + 1, '.') = 0;
15444 
15445  char str[100];
15446  strlcpy(str, cm_get_version(), sizeof(str));
15447  if (strchr(str, '.'))
15448  if (strchr(strchr(str, '.') + 1, '.'))
15449  *strchr(strchr(str, '.') + 1, '.') = 0;
15450 
15451  if (strcmp(v1, str) != 0) {
15452  cm_msg(MERROR, "rpc_server_accept", "client MIDAS version %s differs from local version %s", version, cm_get_version());
15453  cm_msg(MERROR, "rpc_server_accept", "received string: %s", net_buffer + 2);
15454  }
15455 
15456  callback.host_port1 = (short) port1;
15457  callback.host_port2 = (short) port2;
15458  callback.host_port3 = (short) port3;
15460 
15461  int status = ss_socket_get_peer_name(sock, &callback.host_name, NULL);
15462 
15463  if (status != SS_SUCCESS) {
15464  ss_socket_close(&sock);
15465  break;
15466  }
15467 
15468 #ifdef LOCAL_ROUTINES
15469  /* update experiment definition */
15470  exptab_struct exptab;
15471  cm_read_exptab(&exptab); // thread safe!
15472 
15473  unsigned idx = 0;
15474  bool found = false;
15475  /* lookup experiment */
15476  if (equal_ustring(callback.experiment.c_str(), "Default")) {
15477  found = true;
15478  idx = 0;
15479  } else {
15480  for (idx = 0; idx < exptab.exptab.size(); idx++) {
15481  if (exptab.exptab[idx].name == callback.experiment) {
15482  if (ss_dir_exist(exptab.exptab[idx].directory.c_str())) {
15483  found = true;
15484  break;
15485  }
15486  }
15487  }
15488  }
15489 
15490  if (!found) {
15491  cm_msg(MERROR, "rpc_server_accept", "experiment \'%s\' not defined in exptab file \'%s\'", callback.experiment.c_str(), exptab.filename.c_str());
15492 
15493  send(sock, "2", 2, 0); /* 2 means exp. not found */
15494  ss_socket_close(&sock);
15495  break;
15496  }
15497 
15498  callback.directory = exptab.exptab[idx].directory;
15499  callback.user = exptab.exptab[idx].user;
15500 
15501  /* create a new process */
15502  char host_port1_str[30], host_port2_str[30], host_port3_str[30];
15503  char debug_str[30];
15504 
15505  sprintf(host_port1_str, "%d", callback.host_port1);
15506  sprintf(host_port2_str, "%d", callback.host_port2);
15507  sprintf(host_port3_str, "%d", callback.host_port3);
15508  sprintf(debug_str, "%d", callback.debug);
15509 
15510  const char *mserver_path = rpc_get_mserver_path();
15511 
15512  const char *argv[10];
15513  argv[0] = mserver_path;
15514  argv[1] = callback.host_name.c_str();
15515  argv[2] = host_port1_str;
15516  argv[3] = host_port2_str;
15517  argv[4] = host_port3_str;
15518  argv[5] = debug_str;
15519  argv[6] = callback.experiment.c_str();
15520  argv[7] = callback.directory.c_str();
15521  argv[8] = callback.user.c_str();
15522  argv[9] = NULL;
15523 
15524  rpc_debug_printf("Spawn: %s %s %s %s %s %s %s %s %s %s",
15525  argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8],
15526  argv[9]);
15527 
15528  status = ss_spawnv(P_NOWAIT, mserver_path, argv);
15529 
15530  if (status != SS_SUCCESS) {
15531  rpc_debug_printf("Cannot spawn subprocess: %s\n", strerror(errno));
15532 
15533  sprintf(str, "3"); /* 3 means cannot spawn subprocess */
15534  send(sock, str, strlen(str) + 1, 0);
15535  ss_socket_close(&sock);
15536  break;
15537  }
15538 
15539  sprintf(str, "1 %s", cm_get_version()); /* 1 means ok */
15540  send(sock, str, strlen(str) + 1, 0);
15541 #endif // LOCAL_ROUTINES
15542  ss_socket_close(&sock);
15543 
15544  break;
15545  }
15546  default: {
15547  cm_msg(MERROR, "rpc_server_accept", "received unknown command '%c' code %d", command, command);
15548  ss_socket_close(&sock);
15549  break;
15550  }
15551  }
15552  } else { /* if i>0 */
15553 
15554  /* lingering needed for PCTCP */
15555  ling.l_onoff = 1;
15556  ling.l_linger = 0;
15557  setsockopt(sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
15558  ss_socket_close(&sock);
15559  }
15560 
15561  return RPC_SUCCESS;
15562 }
INT cm_read_exptab(exptab_struct *exptab)
Definition: midas.cxx:1616
INT ss_socket_get_peer_name(int sock, std::string *hostp, int *portp)
Definition: system.cxx:5179
int ss_dir_exist(const char *path)
Definition: system.cxx:7125
INT ss_spawnv(INT mode, const char *cmdname, const char *const argv[])
Definition: system.cxx:1601
const char * rpc_get_mserver_path()
Definition: midas.cxx:13018
#define NAME_LENGTH
Definition: midas.h:279
struct callback_addr callback
Definition: mserver.cxx:25
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:1603
std::vector< exptab_entry > exptab
Definition: midas.cxx:1604
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 15669 of file midas.cxx.

15688 {
15689  INT status;
15690  int recv_sock, send_sock, event_sock;
15691  char str[100];
15692  std::string client_program;
15693  INT client_hw_type, hw_type;
15694  INT convert_flags;
15695  char net_buffer[256];
15696  char *p;
15697  int flag;
15698 
15699  /* copy callback information */
15700  struct callback_addr callback = *pcallback;
15701  //idx = callback.index;
15702 
15703  std::string errmsg;
15704 
15705  /* create new sockets for TCP */
15706  status = ss_socket_connect_tcp(callback.host_name.c_str(), callback.host_port1, &recv_sock, &errmsg);
15707 
15708  if (status != SS_SUCCESS) {
15709  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());
15710  ss_socket_close(&recv_sock);
15711  //ss_socket_close(&send_sock);
15712  //ss_socket_close(&event_sock);
15713  return RPC_NET_ERROR;
15714  }
15715 
15716  status = ss_socket_connect_tcp(callback.host_name.c_str(), callback.host_port2, &send_sock, &errmsg);
15717 
15718  if (status != SS_SUCCESS) {
15719  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());
15720  ss_socket_close(&recv_sock);
15721  ss_socket_close(&send_sock);
15722  //ss_socket_close(&event_sock);
15723  return RPC_NET_ERROR;
15724  }
15725 
15726  status = ss_socket_connect_tcp(callback.host_name.c_str(), callback.host_port3, &event_sock, &errmsg);
15727 
15728  if (status != SS_SUCCESS) {
15729  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());
15730  ss_socket_close(&recv_sock);
15731  ss_socket_close(&send_sock);
15732  ss_socket_close(&event_sock);
15733  return RPC_NET_ERROR;
15734  }
15735 #ifndef OS_ULTRIX /* crashes ULTRIX... */
15736  /* increase send buffer size to 2 Mbytes, on Linux also limited by sysctl net.ipv4.tcp_rmem and net.ipv4.tcp_wmem */
15737  flag = 2 * 1024 * 1024;
15738  status = setsockopt(event_sock, SOL_SOCKET, SO_RCVBUF, (char *) &flag, sizeof(INT));
15739  if (status != 0)
15740  cm_msg(MERROR, "rpc_server_callback", "cannot setsockopt(SOL_SOCKET, SO_RCVBUF), errno %d (%s)", errno,
15741  strerror(errno));
15742 #endif
15743 
15744  if (recv_string(recv_sock, net_buffer, 256, _rpc_connect_timeout) <= 0) {
15745  cm_msg(MERROR, "rpc_server_callback", "timeout on receive remote computer info");
15746  ss_socket_close(&recv_sock);
15747  ss_socket_close(&send_sock);
15748  ss_socket_close(&event_sock);
15749  return RPC_NET_ERROR;
15750  }
15751  //printf("rpc_server_callback: \'%s\'\n", net_buffer);
15752 
15753  /* get remote computer info */
15754  client_hw_type = strtoul(net_buffer, &p, 0);
15755 
15756  while (*p == ' ')
15757  p++;
15758 
15759  client_program = p;
15760 
15761  //printf("hw type %d, name \'%s\'\n", client_hw_type, client_program);
15762 
15763  std::string host_name;
15764 
15765  status = ss_socket_get_peer_name(recv_sock, &host_name, NULL);
15766 
15767  if (status != SS_SUCCESS)
15768  host_name = "unknown";
15769 
15770  //printf("rpc_server_callback: mserver acception\n");
15771 
15773 
15774  /* save information in _server_acception structure */
15775  sa->recv_sock = recv_sock;
15776  sa->send_sock = send_sock;
15777  sa->event_sock = event_sock;
15778  sa->remote_hw_type = client_hw_type;
15779  sa->host_name = host_name;
15780  sa->prog_name = client_program;
15781  sa->last_activity = ss_millitime();
15782  sa->watchdog_timeout = 0;
15783  sa->is_mserver = TRUE;
15784 
15785  assert(_mserver_acception == NULL);
15786 
15787  _mserver_acception = sa;
15788 
15789  //printf("rpc_server_callback: _mserver_acception %p\n", _mserver_acception);
15790 
15791  /* send my own computer id */
15792  hw_type = rpc_get_hw_type();
15793  sprintf(str, "%d", hw_type);
15794  send(recv_sock, str, strlen(str) + 1, 0);
15795 
15796  rpc_calc_convert_flags(hw_type, client_hw_type, &convert_flags);
15797  sa->convert_flags = convert_flags;
15798 
15800 
15801  if (rpc_is_mserver()) {
15802  rpc_debug_printf("Connection to %s:%s established\n", sa->host_name.c_str(), sa->prog_name.c_str());
15803  }
15804 
15805  return RPC_SUCCESS;
15806 }
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 12348 of file midas.cxx.

12376 {
12377  INT i, status;
12378  INT remote_hw_type, hw_type;
12379  char str[200], version[32], v1[32];
12380  fd_set readfds;
12381  struct timeval timeout;
12382  int port = MIDAS_TCP_PORT;
12383  char *s;
12384 
12385 #ifdef OS_WINNT
12386  {
12387  WSADATA WSAData;
12388 
12389  /* Start windows sockets */
12390  if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
12391  return RPC_NET_ERROR;
12392  }
12393 #endif
12394 
12395  /* check if local connection */
12396  if (host_name[0] == 0)
12397  return RPC_SUCCESS;
12398 
12399  /* register system functions */
12401 
12402  /* check if cm_connect_experiment was called */
12403  if (_client_name.length() == 0) {
12404  cm_msg(MERROR, "rpc_server_connect", "cm_connect_experiment/rpc_set_name not called");
12405  return RPC_NOT_REGISTERED;
12406  }
12407 
12408  /* check if connection already exists */
12409  if (_server_connection.send_sock != 0)
12410  return RPC_SUCCESS;
12411 
12415 
12416  bool listen_localhost = false;
12417 
12418  if (strcmp(host_name, "localhost") == 0)
12419  listen_localhost = true;
12420 
12421  int lsock1, lport1;
12422  int lsock2, lport2;
12423  int lsock3, lport3;
12424 
12425  std::string errmsg;
12426 
12427  status = ss_socket_listen_tcp(listen_localhost, 0, &lsock1, &lport1, &errmsg);
12428 
12429  if (status != SS_SUCCESS) {
12430  cm_msg(MERROR, "rpc_server_connect", "cannot create listener socket: %s", errmsg.c_str());
12431  return RPC_NET_ERROR;
12432  }
12433 
12434  status = ss_socket_listen_tcp(listen_localhost, 0, &lsock2, &lport2, &errmsg);
12435 
12436  if (status != SS_SUCCESS) {
12437  cm_msg(MERROR, "rpc_server_connect", "cannot create listener socket: %s", errmsg.c_str());
12438  return RPC_NET_ERROR;
12439  }
12440 
12441  status = ss_socket_listen_tcp(listen_localhost, 0, &lsock3, &lport3, &errmsg);
12442 
12443  if (status != SS_SUCCESS) {
12444  cm_msg(MERROR, "rpc_server_connect", "cannot create listener socket: %s", errmsg.c_str());
12445  return RPC_NET_ERROR;
12446  }
12447 
12448  /* extract port number from host_name */
12449  strlcpy(str, host_name, sizeof(str));
12450  s = strchr(str, ':');
12451  if (s) {
12452  *s = 0;
12453  port = strtoul(s + 1, NULL, 0);
12454  }
12455 
12456  int sock;
12457 
12458  status = ss_socket_connect_tcp(str, port, &sock, &errmsg);
12459 
12460  if (status != SS_SUCCESS) {
12461  cm_msg(MERROR, "rpc_server_connect", "cannot connect to mserver on host \"%s\" port %d: %s", str, port, errmsg.c_str());
12462  return RPC_NET_ERROR;
12463  }
12464 
12465  /* connect to experiment */
12466  if (exp_name[0] == 0)
12467  sprintf(str, "C %d %d %d %s Default", lport1, lport2, lport3, cm_get_version());
12468  else
12469  sprintf(str, "C %d %d %d %s %s", lport1, lport2, lport3, cm_get_version(), exp_name);
12470 
12471  send(sock, str, strlen(str) + 1, 0);
12472  i = recv_string(sock, str, sizeof(str), _rpc_connect_timeout);
12473  ss_socket_close(&sock);
12474  if (i <= 0) {
12475  cm_msg(MERROR, "rpc_server_connect", "timeout on receive status from server");
12476  return RPC_NET_ERROR;
12477  }
12478 
12479  status = version[0] = 0;
12480  sscanf(str, "%d %s", &status, version);
12481 
12482  if (status == 2) {
12483 /* message "undefined experiment" should be displayed by application */
12484  return CM_UNDEF_EXP;
12485  }
12486 
12487  /* print warning if version patch level doesn't agree */
12488  strcpy(v1, version);
12489  if (strchr(v1, '.'))
12490  if (strchr(strchr(v1, '.') + 1, '.'))
12491  *strchr(strchr(v1, '.') + 1, '.') = 0;
12492 
12493  strcpy(str, cm_get_version());
12494  if (strchr(str, '.'))
12495  if (strchr(strchr(str, '.') + 1, '.'))
12496  *strchr(strchr(str, '.') + 1, '.') = 0;
12497 
12498  if (strcmp(v1, str) != 0) {
12499  cm_msg(MERROR, "rpc_server_connect", "remote MIDAS version \'%s\' differs from local version \'%s\'", version,
12500  cm_get_version());
12501  }
12502 
12503  /* wait for callback on send and recv socket with timeout */
12504  FD_ZERO(&readfds);
12505  FD_SET(lsock1, &readfds);
12506  FD_SET(lsock2, &readfds);
12507  FD_SET(lsock3, &readfds);
12508 
12509  timeout.tv_sec = _rpc_connect_timeout / 1000;
12510  timeout.tv_usec = 0;
12511 
12512  do {
12513  status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
12514 
12515  /* if an alarm signal was cought, restart select with reduced timeout */
12516  if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
12517  timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
12518 
12519  } while (status == -1); /* dont return if an alarm signal was cought */
12520 
12521  if (!FD_ISSET(lsock1, &readfds)) {
12522  cm_msg(MERROR, "rpc_server_connect", "mserver subprocess could not be started (check path)");
12523  ss_socket_close(&lsock1);
12524  ss_socket_close(&lsock2);
12525  ss_socket_close(&lsock3);
12526  return RPC_NET_ERROR;
12527  }
12528 
12529  _server_connection.send_sock = accept(lsock1, NULL, NULL);
12530  _server_connection.recv_sock = accept(lsock2, NULL, NULL);
12531  _server_connection.event_sock = accept(lsock3, NULL, NULL);
12532 
12534  cm_msg(MERROR, "rpc_server_connect", "accept() failed");
12535  return RPC_NET_ERROR;
12536  }
12537 
12538  ss_socket_close(&lsock1);
12539  ss_socket_close(&lsock2);
12540  ss_socket_close(&lsock3);
12541 
12542  /* set TCP_NODELAY option for better performance */
12543  int flag = 1;
12544  setsockopt(_server_connection.send_sock, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag));
12545  setsockopt(_server_connection.event_sock, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag));
12546 
12547  /* increase send buffer size to 2 Mbytes, on Linux also limited by sysctl net.ipv4.tcp_rmem and net.ipv4.tcp_wmem */
12548  flag = 2 * 1024 * 1024;
12549  status = setsockopt(_server_connection.event_sock, SOL_SOCKET, SO_SNDBUF, (char *) &flag, sizeof(flag));
12550  if (status != 0)
12551  cm_msg(MERROR, "rpc_server_connect", "cannot setsockopt(SOL_SOCKET, SO_SNDBUF), errno %d (%s)", errno, strerror(errno));
12552 
12553  /* send local computer info */
12554  std::string local_prog_name = rpc_get_name();
12555  hw_type = rpc_get_hw_type();
12556  sprintf(str, "%d %s", hw_type, local_prog_name.c_str());
12557 
12558  send(_server_connection.send_sock, str, strlen(str) + 1, 0);
12559 
12560  /* receive remote computer info */
12562  if (i <= 0) {
12563  cm_msg(MERROR, "rpc_server_connect", "timeout on receive remote computer info");
12564  return RPC_NET_ERROR;
12565  }
12566 
12567  sscanf(str, "%d", &remote_hw_type);
12568  _server_connection.remote_hw_type = remote_hw_type;
12569 
12571 
12572  _rpc_is_remote = true;
12573 
12574  return RPC_SUCCESS;
12575 }
#define CM_UNDEF_EXP
Definition: midas.h:592
INT ss_suspend_set_client_connection(RPC_SERVER_CONNECTION *connection)
Definition: system.cxx:4230
char exp_name[NAME_LENGTH]
Definition: mana.cxx:243
#define MIDAS_TCP_PORT
Definition: midas.h:290
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 12672 of file midas.cxx.

12692 {
12693  static int rpc_server_disconnect_recursion_level = 0;
12694 
12695  if (rpc_server_disconnect_recursion_level)
12696  return RPC_SUCCESS;
12697 
12698  rpc_server_disconnect_recursion_level = 1;
12699 
12700  /* flush remaining events */
12701  rpc_flush_event();
12702 
12703  /* notify server about exit */
12704  if (rpc_is_connected()) {
12706  }
12707 
12708  /* close sockets */
12715 
12717 
12718  /* remove semaphore */
12719  if (_mutex_rpc)
12721  _mutex_rpc = NULL;
12722 
12723  rpc_server_disconnect_recursion_level = 0;
12724  return RPC_SUCCESS;
12725 }
INT ss_mutex_delete(MUTEX_T *mutex)
Definition: system.cxx:3150
bool rpc_is_connected(void)
Definition: midas.cxx:12750
INT rpc_call(DWORD routine_id,...)
Definition: midas.cxx:13630
INT rpc_flush_event()
Definition: midas.cxx:14005
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 15810 of file midas.cxx.

15818 {
15819  while (1) {
15820  int status = ss_suspend(1000, 0);
15821 
15822  if (status == SS_ABORT || status == SS_EXIT)
15823  break;
15824 
15826  break;
15827 
15828  /* check alarms, etc */
15830 
15832  }
15833 
15834  return RPC_SUCCESS;
15835 }
INT cm_periodic_tasks()
Definition: midas.cxx:5575
INT cm_msg_flush_buffer()
Definition: midas.cxx:867
INT rpc_check_channels(void)
Definition: midas.cxx:16221
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 15948 of file midas.cxx.

15962 {
15963  int status = 0;
15964 
15965  DWORD start_time = ss_millitime();
15966 
15967  //
15968  // THIS IS NOT THREAD SAFE!!!
15969  //
15970  // IT IS ONLY USED BY THE MSERVER
15971  // MSERVER IS SINGLE-THREADED!!!
15972  //
15973 
15974  static char *xbuf = NULL;
15975  static int xbufsize = 0;
15976  static bool xbufempty = true;
15977 
15978  // short cut
15979  if (sa == NULL && xbufempty)
15980  return RPC_SUCCESS;
15981 
15982  static bool recurse = false;
15983 
15984  if (recurse) {
15985  cm_msg(MERROR, "rpc_server_receive_event", "internal error: called recursively");
15986  // do not do anything if we are called recursively
15987  // via recursive ss_suspend() or otherwise. K.O.
15988  if (xbufempty)
15989  return RPC_SUCCESS;
15990  else
15991  return BM_ASYNC_RETURN;
15992  }
15993 
15994  recurse = true;
15995 
15996  do {
15997  if (xbufempty && sa) {
15998  int n_received = recv_event_server_realloc(idx, sa, &xbuf, &xbufsize);
15999 
16000  if (n_received < 0) {
16001  status = SS_ABORT;
16002  cm_msg(MERROR, "rpc_server_receive_event", "recv_event_server_realloc() returned %d, abort", n_received);
16003  goto error;
16004  }
16005 
16006  if (n_received == 0) {
16007  // no more data in the tcp socket
16008  recurse = false;
16009  return RPC_SUCCESS;
16010  }
16011 
16012  xbufempty = false;
16013  }
16014 
16015  if (xbufempty) {
16016  // no event in xbuf buffer
16017  recurse = false;
16018  return RPC_SUCCESS;
16019  }
16020 
16021  /* send event to buffer */
16022  INT *pbh = (INT *) xbuf;
16023  EVENT_HEADER *pevent = (EVENT_HEADER *) (pbh + 1);
16024 
16025  status = bm_send_event(*pbh, pevent, 0, timeout_msec);
16026 
16027  //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);
16028 
16029  if (status == SS_ABORT) {
16030  cm_msg(MERROR, "rpc_server_receive_event", "bm_send_event() error %d (SS_ABORT), abort", status);
16031  goto error;
16032  }
16033 
16034  if (status == BM_ASYNC_RETURN) {
16035  //cm_msg(MERROR, "rpc_server_receive_event", "bm_send_event() error %d, event buffer is full", status);
16036  recurse = false;
16037  return status;
16038  }
16039 
16040  if (status != BM_SUCCESS) {
16041  cm_msg(MERROR, "rpc_server_receive_event", "bm_send_event() error %d, mserver dropped this event", status);
16042  }
16043 
16044  xbufempty = true;
16045 
16046  /* repeat for maximum 0.5 sec */
16047  } while (ss_millitime() - start_time < 500);
16048 
16049  recurse = false;
16050  return RPC_SUCCESS;
16051 
16052  error:
16053 
16054  {
16055  char str[80];
16056  strlcpy(str, sa->host_name.c_str(), sizeof(str));
16057  if (strchr(str, '.'))
16058  *strchr(str, '.') = 0;
16059  cm_msg(MTALK, "rpc_server_receive_event", "Program \'%s\' on host \'%s\' aborted", sa->prog_name.c_str(), str);
16060  }
16061 
16062  //exit:
16063 
16065 
16066  /* disconnect from experiment as MIDAS server */
16067  if (rpc_is_mserver()) {
16068  HNDLE hDB, hKey;
16069 
16071 
16072  /* only disconnect from experiment if previously connected.
16073  Necessary for pure RPC servers (RPC_SRVR) */
16074  if (hDB) {
16078 
16080 
16082  }
16083  }
16084 
16085  bool is_mserver = sa->is_mserver;
16086 
16087  sa->close();
16088 
16089  /* signal caller a shutdonw */
16090  if (status == RPC_SHUTDOWN)
16091  return status;
16092 
16093  /* only the mserver should stop on server connection closure */
16094  if (!is_mserver) {
16095  return SS_SUCCESS;
16096  }
16097 
16098  return status;
16099 }
INT bm_close_all_buffers(void)
Definition: midas.cxx:7207
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition: midas.cxx:3005
INT cm_delete_client_info(HNDLE hDB, INT pid)
Definition: midas.cxx:1854
INT cm_set_experiment_database(HNDLE hDB, HNDLE hKeyClient)
Definition: midas.cxx:2933
#define MTALK
Definition: midas.h:570
INT db_close_all_databases(void)
Definition: odb.cxx:2351
static int recv_event_server_realloc(INT idx, RPC_SERVER_ACCEPTION *psa, char **pbuffer, int *pbuffer_size)
Definition: midas.cxx:14354
INT rpc_deregister_functions()
Definition: midas.cxx:11837
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 15838 of file midas.cxx.

15853 {
15854  int status = 0;
15855  int remaining = 0;
15856 
15857  char *buf = NULL;
15858  int bufsize = 0;
15859 
15860  do {
15861  int n_received = recv_net_command_realloc(idx, &buf, &bufsize, &remaining);
15862 
15863  if (n_received <= 0) {
15864  status = SS_ABORT;
15865  cm_msg(MERROR, "rpc_server_receive_rpc", "recv_net_command() returned %d, abort", n_received);
15866  goto error;
15867  }
15868 
15869  status = rpc_execute(sa->recv_sock, buf, sa->convert_flags);
15870 
15871  if (status == SS_ABORT) {
15872  cm_msg(MERROR, "rpc_server_receive_rpc", "rpc_execute() returned %d, abort", status);
15873  goto error;
15874  }
15875 
15876  if (status == SS_EXIT || status == RPC_SHUTDOWN) {
15877  if (rpc_is_mserver())
15878  rpc_debug_printf("Connection to %s:%s closed\n", sa->host_name.c_str(), sa->prog_name.c_str());
15879  goto exit;
15880  }
15881 
15882  } while (remaining);
15883 
15884  if (buf) {
15885  free(buf);
15886  buf = NULL;
15887  bufsize = 0;
15888  }
15889 
15890  return RPC_SUCCESS;
15891 
15892  error:
15893 
15894  {
15895  char str[80];
15896  strlcpy(str, sa->host_name.c_str(), sizeof(str));
15897  if (strchr(str, '.'))
15898  *strchr(str, '.') = 0;
15899  cm_msg(MTALK, "rpc_server_receive_rpc", "Program \'%s\' on host \'%s\' aborted", sa->prog_name.c_str(), str);
15900  }
15901 
15902  exit:
15903 
15905 
15906  if (buf) {
15907  free(buf);
15908  buf = NULL;
15909  bufsize = 0;
15910  }
15911 
15912  /* disconnect from experiment as MIDAS server */
15913  if (rpc_is_mserver()) {
15914  HNDLE hDB, hKey;
15915 
15917 
15918  /* only disconnect from experiment if previously connected.
15919  Necessary for pure RPC servers (RPC_SRVR) */
15920  if (hDB) {
15924 
15926 
15928  }
15929  }
15930 
15931  bool is_mserver = sa->is_mserver;
15932 
15933  sa->close();
15934 
15935  /* signal caller a shutdonw */
15936  if (status == RPC_SHUTDOWN)
15937  return status;
15938 
15939  /* only the mserver should stop on server connection closure */
15940  if (!is_mserver) {
15941  return SS_SUCCESS;
15942  }
15943 
15944  return status;
15945 }
INT rpc_execute(INT sock, char *buffer, INT convert_flags)
Definition: midas.cxx:14617
static int recv_net_command_realloc(INT idx, char **pbuf, int *pbufsize, INT *remaining)
Definition: midas.cxx:14164
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 16150 of file midas.cxx.

16167 {
16168  //printf("rpc_server_shutdown!\n");
16169 
16170  struct linger ling;
16171 
16172  /* close all open connections */
16173  for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
16174  if (_server_acceptions[idx] && _server_acceptions[idx]->recv_sock != 0) {
16176  /* lingering needed for PCTCP */
16177  ling.l_onoff = 1;
16178  ling.l_linger = 0;
16179  setsockopt(sa->recv_sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
16180  ss_socket_close(&sa->recv_sock);
16181 
16182  if (sa->send_sock) {
16183  setsockopt(sa->send_sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
16184  ss_socket_close(&sa->send_sock);
16185  }
16186 
16187  if (sa->event_sock) {
16188  setsockopt(sa->event_sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
16190  }
16191  }
16192  }
16193 
16194  /* avoid memory leak */
16195  for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
16197  if (sa) {
16198  //printf("rpc_server_shutdown: %d %p %p\n", idx, sa, _mserver_acception);
16199  if (sa == _mserver_acception) {
16200  // do not leave behind a stale pointer!
16201  _mserver_acception = NULL;
16202  }
16203  delete sa;
16204  _server_acceptions[idx] = NULL;
16205  }
16206  }
16207 
16208  if (_rpc_registered) {
16211  }
16212 
16213  /* free suspend structures */
16214  ss_suspend_exit();
16215 
16216  return RPC_SUCCESS;
16217 }
INT ss_suspend_exit()
Definition: system.cxx:4165
static BOOL _rpc_registered
Definition: midas.cxx:260
static int _rpc_listen_socket
Definition: midas.cxx:261
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 13101 of file midas.cxx.

13121 {
13122  _debug_print = func;
13123  _debug_mode = mode;
13124  return RPC_SUCCESS;
13125 }
Here is the caller graph for this function:

◆ rpc_set_mserver_path()

INT rpc_set_mserver_path ( const char *  path)

Definition at line 13031 of file midas.cxx.

13045 {
13046  _mserver_path = path;
13047  return RPC_SUCCESS;
13048 }
Here is the caller graph for this function:

◆ rpc_set_name()

INT rpc_set_name ( const char *  name)

Definition at line 13075 of file midas.cxx.

13093 {
13094  _client_name = name;
13095 
13096  return RPC_SUCCESS;
13097 }
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 13831 of file midas.cxx.

13831  {
13832  INT old;
13833 
13834  old = _opt_tcp_size;
13835  _opt_tcp_size = tcp_size;
13836  return old;
13837 }
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 12965 of file midas.cxx.

12966 {
12967  //printf("rpc_set_timeout: hConn %d, timeout_msec %d\n", hConn, timeout_msec);
12968 
12969  if (hConn == RPC_HNDLE_MSERVER) {
12970  if (old_timeout_msec)
12971  *old_timeout_msec = _server_connection.rpc_timeout;
12972  _server_connection.rpc_timeout = timeout_msec;
12973  } else if (hConn == RPC_HNDLE_CONNECT) {
12974  if (old_timeout_msec)
12975  *old_timeout_msec = _rpc_connect_timeout;
12976  _rpc_connect_timeout = timeout_msec;
12977  } else {
12979  if (c) {
12980  if (old_timeout_msec)
12981  *old_timeout_msec = c->rpc_timeout;
12982  c->rpc_timeout = timeout_msec;
12983  c->mutex.unlock();
12984  } else {
12985  if (old_timeout_msec)
12986  *old_timeout_msec = 0;
12987  }
12988  }
12989  return RPC_SUCCESS;
12990 }
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 15280 of file midas.cxx.

15281 {
15282  std::string hostname;
15283 
15284  int status = ss_socket_get_peer_name(sock, &hostname, NULL);
15285 
15286  if (status != SS_SUCCESS)
15287  return status;
15288 
15289  status = rpc_check_allowed_host(hostname.c_str());
15290 
15291  if (status == RPC_SUCCESS)
15292  return RPC_SUCCESS;
15293 
15294  static std::atomic_int max_report(10);
15295  if (max_report > 0) {
15296  max_report--;
15297  if (max_report == 0) {
15298  cm_msg(MERROR, "rpc_socket_check_allowed_host", "rejecting connection from unallowed host \'%s\', this message will no longer be reported", hostname.c_str());
15299  } else {
15300  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());
15301  }
15302  }
15303 
15304  return RPC_NET_ERROR;
15305 }
INT rpc_check_allowed_host(const char *hostname)
Definition: midas.cxx:15231
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 15013 of file midas.cxx.

15029 {
15030  int status = RPC_SUCCESS;
15031 
15032  printf("rpc_test_rpc!\n");
15033 
15034  int int_out = 0;
15035  int int_inout = 456;
15036 
15037  char string_out[32];
15038  char string2_out[48];
15039 
15040  char string_inout[25];
15041  strcpy(string_inout, "string_inout");
15042 
15043  KEY struct_in;
15044 
15045  struct_in.type = 111;
15046  struct_in.num_values = 222;
15047  strcpy(struct_in.name, "name");
15048  struct_in.last_written = 333;
15049 
15050  KEY struct_out;
15051  KEY struct_inout;
15052 
15053  struct_inout.type = 111111;
15054  struct_inout.num_values = 222222;
15055  strcpy(struct_inout.name, "name_name");
15056  struct_inout.last_written = 333333;
15057 
15058  uint32_t dwordarray_inout[10];
15059  size_t dwordarray_inout_size = sizeof(dwordarray_inout);
15060 
15061  for (int i=0; i<10; i++) {
15062  dwordarray_inout[i] = i*10;
15063  }
15064 
15065  char array_in[10];
15066 
15067  for (size_t i=0; i<sizeof(array_in); i++) {
15068  array_in[i] = 'a' + i;
15069  }
15070 
15071  char array_out[16];
15072  size_t array_out_size = sizeof(array_out);
15073 
15075  123,
15076  &int_out,
15077  &int_inout,
15078  "test string",
15079  string_out, sizeof(string_out),
15080  string2_out, sizeof(string2_out),
15081  string_inout, sizeof(string_inout),
15082  &struct_in,
15083  &struct_out,
15084  &struct_inout,
15085  dwordarray_inout, &dwordarray_inout_size,
15086  array_in, sizeof(array_in),
15087  array_out, &array_out_size
15088  );
15089 
15090  printf("rpc_call(RPC_TEST2) status %d\n", status);
15091 
15092  if (int_out != 789) {
15093  printf("int_out mismatch!\n");
15094  status = 0;
15095  }
15096 
15097  if (int_inout != 456*2) {
15098  printf("int_inout mismatch!\n");
15099  status = 0;
15100  }
15101 
15102  if (strcmp(string_out, "string_out") != 0) {
15103  printf("string_out mismatch [%s] vs [%s]\n", string_out, "string_out");
15104  status = 0;
15105  }
15106 
15107  if (strcmp(string2_out, "second string_out") != 0) {
15108  printf("string2_out mismatch [%s] vs [%s]\n", string2_out, "second string_out");
15109  status = 0;
15110  }
15111 
15112  if (strcmp(string_inout, "return string_inout") != 0) {
15113  printf("string_inout mismatch [%s] vs [%s]\n", string_inout, "return string_inout");
15114  status = 0;
15115  }
15116 
15117  KEY* pkey;
15118 
15119  pkey = &struct_in;
15120 
15121  //printf("struct_in: type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
15122 
15123  pkey = &struct_out;
15124 
15125  if (pkey->type != 444 || pkey->num_values != 555 || strcmp(pkey->name, "out_name") || pkey->last_written != 666) {
15126  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);
15127  status = 0;
15128  }
15129 
15130  pkey = &struct_inout;
15131 
15132  if (pkey->type != 444444 || pkey->num_values != 555555 || strcmp(pkey->name, "inout_name") || pkey->last_written != 666666) {
15133  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);
15134  status = 0;
15135  }
15136 
15137 #if 0
15138  if (dwordarray_inout_size != 4*5) {
15139  printf("dwordarray_inout_size mismatch %d vs %d\n", (int)dwordarray_inout_size, 4*5);
15140  status = 0;
15141  }
15142 
15143  for (size_t i=0; i<dwordarray_inout_size/sizeof(uint32_t); i++) {
15144  printf("dwordarray_inout[%d] is %d\n", (int)i, dwordarray_inout[i]);
15145  }
15146 #endif
15147 
15148 #if 0
15149  {RPC_TEST_CXX, "test_cxx",
15150  {{TID_INT32, RPC_IN},
15151  {TID_INT32, RPC_IN | RPC_OUT | RPC_VARARRAY | RPC_CXX},
15152  {TID_STRING, RPC_IN},
15153  {TID_STRING, RPC_IN | RPC_CXX},
15154  {TID_STRING, RPC_OUT | RPC_CXX},
15155  {TID_STRING, RPC_IN | RPC_OUT | RPC_CXX},
15156  {TID_STRUCT, RPC_IN | RPC_CXX, sizeof(KEY)},
15157  {TID_STRUCT, RPC_OUT | RPC_CXX, sizeof(KEY)},
15158  {TID_STRUCT, RPC_IN | RPC_OUT | RPC_CXX, sizeof(KEY)},
15159  {TID_ARRAY, RPC_IN | RPC_VARARRAY | RPC_CXX},
15160  {TID_ARRAY, RPC_OUT | RPC_VARARRAY | RPC_CXX},
15161  {TID_ARRAY, RPC_IN | RPC_OUT | RPC_VARARRAY | RPC_CXX},
15162  {0}}},
15163 #endif
15164 
15165 #if 0
15166  status = rpc_call(RPC_TEST_CXX, ...);
15167 #endif
15168 
15169  return status;
15170 }
#define RPC_TEST2
Definition: mrpc.h:123
Definition: midas.h:1032
INT num_values
Definition: midas.h:1034
DWORD type
Definition: midas.h:1033
INT last_written
Definition: midas.h:1043
char name[NAME_LENGTH]
Definition: midas.h:1035
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 11731 of file midas.cxx.

11731  {
11732  if (id >= 0 && id < TID_LAST)
11733  return tid_name[id];
11734  else
11735  return "<unknown>";
11736 }
Here is the caller graph for this function:

◆ rpc_tid_name_old()

const char* rpc_tid_name_old ( INT  id)

Definition at line 11738 of file midas.cxx.

11738  {
11739  if (id >= 0 && id < TID_LAST)
11740  return tid_name_old[id];
11741  else
11742  return "<unknown>";
11743 }
Here is the caller graph for this function:

◆ rpc_tid_size()

INT rpc_tid_size ( INT  id)

Definition at line 11724 of file midas.cxx.

11724  {
11725  if (id >= 0 && id < TID_LAST)
11726  return tid_size[id];
11727 
11728  return 0;
11729 }
static const int tid_size[]
Definition: midas.cxx:68
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 14023 of file midas.cxx.

14042 {
14043  /* erase error string */
14044  *(CSTRING(2)) = 0;
14045 
14046  if (idx == RPC_RC_TRANSITION) {
14047  // find registered handler
14048  // NB: this code should match same code in cm_transition_call_direct()
14049  // NB: only use the first handler, this is how MIDAS always worked
14050  // NB: we could run all handlers, but we can return the status and error string of only one of them.
14051  _trans_table_mutex.lock();
14052  size_t n = _trans_table.size();
14053  _trans_table_mutex.unlock();
14054 
14055  for (size_t i = 0; i < n; i++) {
14056  _trans_table_mutex.lock();
14057  TRANS_TABLE tt = _trans_table[i];
14058  _trans_table_mutex.unlock();
14059 
14060  if (tt.transition == CINT(0) && tt.sequence_number == CINT(4)) {
14061  if (tt.func) {
14062  /* execute callback if defined */
14063  return tt.func(CINT(1), CSTRING(2));
14064  } else {
14065  std::lock_guard<std::mutex> guard(_tr_fifo_mutex);
14066  /* store transition in FIFO */
14069  _tr_fifo[_tr_fifo_wp].trans_time = time(NULL);
14071  _tr_fifo_wp = (_tr_fifo_wp + 1) % 10;
14072  // implicit unlock
14073  return RPC_SUCCESS;
14074  }
14075  }
14076  }
14077  // no handler for this transition
14078  cm_msg(MERROR, "rpc_transition_dispatch", "no handler for transition %d with sequence number %d", CINT(0), CINT(4));
14079  return CM_SUCCESS;
14080  } else {
14081  cm_msg(MERROR, "rpc_transition_dispatch", "received unrecognized command %d", idx);
14082  return RPC_INVALID_ID;
14083  }
14084 }
#define CM_SUCCESS
Definition: midas.h:588
#define RPC_RC_TRANSITION
Definition: mrpc.h:116
static std::vector< TRANS_TABLE > _trans_table
Definition: midas.cxx:250
static std::mutex _trans_table_mutex
Definition: midas.cxx:249
#define CINT(_i)
Definition: midas.h:1653
#define CSTRING(_i)
Definition: midas.h:1677
time_t trans_time
Definition: midas.cxx:14014
int sequence_number
Definition: midas.cxx:14015
INT sequence_number
Definition: midas.cxx:245
INT(* func)(INT, char *)
Definition: midas.cxx:246
INT transition
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 13160 of file midas.cxx.

13160  {
13161  switch (arg_type) {
13162  /* On the stack, the minimum parameter size is sizeof(int).
13163  To avoid problems on little endian systems, treat all
13164  smaller parameters as int's */
13165  case TID_UINT8:
13166  case TID_INT8:
13167  case TID_CHAR:
13168  case TID_UINT16:
13169  case TID_INT16:
13170  *((int *) arg) = va_arg(*arg_ptr, int);
13171  break;
13172 
13173  case TID_INT32:
13174  case TID_BOOL:
13175  *((INT *) arg) = va_arg(*arg_ptr, INT);
13176  break;
13177 
13178  case TID_UINT32:
13179  *((DWORD *) arg) = va_arg(*arg_ptr, DWORD);
13180  break;
13181 
13182  /* float variables are passed as double by the compiler */
13183  case TID_FLOAT:
13184  *((float *) arg) = (float) va_arg(*arg_ptr, double);
13185  break;
13186 
13187  case TID_DOUBLE:
13188  *((double *) arg) = va_arg(*arg_ptr, double);
13189  break;
13190 
13191  case TID_ARRAY:
13192  *((char **) arg) = va_arg(*arg_ptr, char *);
13193  break;
13194  }
13195 }
Here is the caller graph for this function:

◆ rpc_vax2ieee_double()

void rpc_vax2ieee_double ( double *  var)

Definition at line 11609 of file midas.cxx.

11609  {
11610  unsigned short int i1, i2, i3, i4;
11611 
11612  /* swap words */
11613  i1 = *((short int *) (var) + 3);
11614  i2 = *((short int *) (var) + 2);
11615  i3 = *((short int *) (var) + 1);
11616  i4 = *((short int *) (var));
11617 
11618  /* correct exponent */
11619  if (i4 != 0)
11620  i4 -= 0x20;
11621 
11622  *((short int *) (var) + 3) = i4;
11623  *((short int *) (var) + 2) = i3;
11624  *((short int *) (var) + 1) = i2;
11625  *((short int *) (var)) = i1;
11626 }
Here is the caller graph for this function:

◆ rpc_vax2ieee_float()

void rpc_vax2ieee_float ( float *  var)

Definition at line 11593 of file midas.cxx.

11593  {
11594  unsigned short int lo, hi;
11595 
11596  /* swap hi and lo word */
11597  lo = *((short int *) (var) + 1);
11598  hi = *((short int *) (var));
11599 
11600  /* correct exponent */
11601  if (hi != 0)
11602  hi -= 0x100;
11603 
11604  *((short int *) (var) + 1) = hi;
11605  *((short int *) (var)) = lo;
11606 
11607 }
Here is the caller graph for this function:

Variable Documentation

◆ _client_connections

std::vector<RPC_CLIENT_CONNECTION*> _client_connections
static

Definition at line 11463 of file midas.cxx.

◆ _client_connections_mutex

std::mutex _client_connections_mutex
static

Definition at line 11462 of file midas.cxx.

◆ _mserver_acception

RPC_SERVER_ACCEPTION* _mserver_acception = NULL
static

Definition at line 11470 of file midas.cxx.

◆ _mserver_path

std::string _mserver_path
static

Definition at line 13015 of file midas.cxx.

◆ _opt_tcp_size

int _opt_tcp_size = OPT_TCP_SIZE
static

Definition at line 11543 of file midas.cxx.

◆ _rpc_is_remote

bool _rpc_is_remote = false
static

Definition at line 11466 of file midas.cxx.

◆ _server_acceptions

std::vector<RPC_SERVER_ACCEPTION*> _server_acceptions
static

Definition at line 11469 of file midas.cxx.

◆ _server_connection

RPC_SERVER_CONNECTION _server_connection
static

Definition at line 11465 of file midas.cxx.

◆ _tr_fifo

TR_FIFO _tr_fifo[10]
static

Definition at line 14019 of file midas.cxx.

◆ _tr_fifo_mutex

std::mutex _tr_fifo_mutex
static

Definition at line 14018 of file midas.cxx.

◆ _tr_fifo_rp

int _tr_fifo_rp = 0
static

Definition at line 14021 of file midas.cxx.

◆ _tr_fifo_wp

int _tr_fifo_wp = 0
static

Definition at line 14020 of file midas.cxx.

◆ gAllowedHosts

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

Definition at line 15173 of file midas.cxx.

◆ gAllowedHostsMutex

std::mutex gAllowedHostsMutex
static

Definition at line 15174 of file midas.cxx.

◆ rpc_list

std::vector<RPC_LIST> rpc_list
static

Definition at line 11540 of file midas.cxx.

◆ rpc_list_mutex

std::mutex rpc_list_mutex
static

Definition at line 11541 of file midas.cxx.

◆ tls_buffer

TLS_POINTER* tls_buffer = NULL
static

Definition at line 14613 of file midas.cxx.

◆ tls_size

int tls_size = 0
static

Definition at line 14614 of file midas.cxx.