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

Classes

class  RPC_CLIENT_CONNECTION
 
struct  TR_FIFO
 
struct  TLS_POINTER
 

Macros

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

Functions

static RPC_SERVER_ACCEPTIONrpc_get_server_acception (int idx)
 
RPC_SERVER_ACCEPTIONrpc_get_mserver_acception ()
 
static RPC_SERVER_ACCEPTIONrpc_new_server_acception ()
 
void rpc_calc_convert_flags (INT hw_type, INT remote_hw_type, INT *convert_flags)
 
void rpc_get_convert_flags (INT *convert_flags)
 
void rpc_ieee2vax_float (float *var)
 
void rpc_vax2ieee_float (float *var)
 
void rpc_vax2ieee_double (double *var)
 
void rpc_ieee2vax_double (double *var)
 
void rpc_convert_single (void *data, INT tid, INT flags, INT convert_flags)
 
void rpc_convert_data (void *data, INT tid, INT flags, INT total_size, INT convert_flags)
 
INT rpc_tid_size (INT id)
 
const 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 11568 of file midas.cxx.

11569{
11570 //printf("RPC_SERVER_ACCEPTION::close: connection from %s program %s mserver %d\n", host_name.c_str(), prog_name.c_str(), is_mserver);
11571
11572 if (is_mserver) {
11573 assert(_mserver_acception == this);
11574 _mserver_acception = NULL;
11575 is_mserver = false;
11576 }
11577
11578 /* close server connection */
11579 if (recv_sock)
11581 if (send_sock)
11583 if (event_sock)
11585
11586 /* free TCP cache */
11587 if (net_buffer) {
11588 //printf("free net_buffer %p+%d\n", net_buffer, net_buffer_size);
11589 free(net_buffer);
11590 net_buffer = NULL;
11591 net_buffer_size = 0;
11592 }
11593
11594 /* mark this entry as invalid */
11595 clear();
11596}
INT ss_socket_close(int *sockp)
Definition system.cxx:5303
static RPC_SERVER_ACCEPTION * _mserver_acception
Definition midas.cxx:11528
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 14145 of file midas.cxx.

14169{
14170 std::lock_guard<std::mutex> guard(_tr_fifo_mutex);
14171
14172 if (_tr_fifo_wp == _tr_fifo_rp)
14173 return FALSE;
14174
14175 if (transition)
14177
14178 if (run_number)
14180
14181 if (trans_time)
14182 *trans_time = (int) _tr_fifo[_tr_fifo_rp].trans_time;
14183
14184 _tr_fifo_rp = (_tr_fifo_rp + 1) % 10;
14185
14186 // implicit unlock
14187 return TRUE;
14188}
#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:14079
static int _tr_fifo_wp
Definition midas.cxx:14078
static TR_FIFO _tr_fifo[10]
Definition midas.cxx:14077
static std::mutex _tr_fifo_mutex
Definition midas.cxx:14076
INT run_number[2]
Definition mana.cxx:246
#define TRUE
Definition midas.h:182
int transition
Definition midas.cxx:14070
int run_number
Definition midas.cxx:14071
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 11956 of file midas.cxx.

11956 {
11957 //printf("rpc_client_dispatch: MSG_ODB: packet size %d, expected %d\n", n, (int)(sizeof(NET_COMMAND_HEADER) + 4 * sizeof(INT)));
11958 if (n == sizeof(NET_COMMAND_HEADER) + 4 * sizeof(INT)) {
11959 /* update a changed record */
11960 HNDLE hDB = *((INT *) nc->param);
11961 HNDLE hKeyRoot = *((INT *) nc->param + 1);
11962 HNDLE hKey = *((INT *) nc->param + 2);
11963 int index = *((INT *) nc->param + 3);
11964 return db_update_record_local(hDB, hKeyRoot, hKey, index);
11965 }
11966 return CM_VERSION_MISMATCH;
11967}
#define CM_VERSION_MISMATCH
Definition midas.h:587
INT db_update_record_local(INT hDB, INT hKeyRoot, INT hKey, int index)
Definition odb.cxx:13331
HNDLE hKey
DWORD n[4]
Definition mana.cxx:247
INT index
Definition mana.cxx:271
HNDLE hDB
main ODB handle
Definition mana.cxx:207
INT HNDLE
Definition midas.h:132
int INT
Definition midas.h:129
char param[32]
Definition msystem.h:294
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 14412 of file midas.cxx.

14434{
14435 int sock = psa->event_sock;
14436
14437 //printf("recv_event_server: idx %d, buffer %p, buffer_size %d\n", idx, buffer, buffer_size);
14438
14439 const size_t header_size = (sizeof(EVENT_HEADER) + sizeof(INT));
14440
14441 char header_buf[header_size];
14442
14443 // First read the header.
14444 //
14445 // Data format is:
14446 // INT buffer handle (4 bytes)
14447 // EVENT_HEADER (16 bytes)
14448 // event data
14449 // ALIGN8() padding
14450 // ...next event
14451
14452 int hrd = recv_tcp2(sock, header_buf, header_size, 1);
14453
14454 if (hrd == 0) {
14455 // timeout waiting for data
14456 return 0;
14457 }
14458
14459 /* abort if connection broken */
14460 if (hrd < 0) {
14461 cm_msg(MERROR, "recv_event_server", "recv_tcp2(header) returned %d", hrd);
14462 return -1;
14463 }
14464
14465 if (hrd < (int) header_size) {
14466 int hrd1 = recv_tcp2(sock, header_buf + hrd, header_size - hrd, 0);
14467
14468 /* abort if connection broken */
14469 if (hrd1 <= 0) {
14470 cm_msg(MERROR, "recv_event_server", "recv_tcp2(more header) returned %d", hrd1);
14471 return -1;
14472 }
14473
14474 hrd += hrd1;
14475 }
14476
14477 /* abort if connection broken */
14478 if (hrd != (int) header_size) {
14479 cm_msg(MERROR, "recv_event_server", "recv_tcp2(header) returned %d instead of %d", hrd, (int) header_size);
14480 return -1;
14481 }
14482
14483 INT *pbh = (INT *) header_buf;
14484 EVENT_HEADER *pevent = (EVENT_HEADER *) (((INT *) header_buf) + 1);
14485
14486 /* convert header little endian/big endian */
14487 if (psa->convert_flags) {
14494 }
14495
14496 int event_size = pevent->data_size + sizeof(EVENT_HEADER);
14497 int total_size = ALIGN8(event_size);
14498
14499 //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);
14500
14501 if (pevent->data_size == 0) {
14502 for (int i=0; i<5; i++) {
14503 printf("recv_event_server: header[%d]: 0x%08x\n", i, pbh[i]);
14504 }
14505 abort();
14506 }
14507
14508 /* check for sane event size */
14509 if (event_size <= 0 || total_size <= 0) {
14510 cm_msg(MERROR, "recv_event_server",
14511 "received event header with invalid data_size %d: event_size %d, total_size %d", pevent->data_size,
14512 event_size, total_size);
14513 return -1;
14514 }
14515
14516 //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);
14517
14518
14519 int bufsize = sizeof(INT) + total_size;
14520
14521 // Second, check that output buffer is big enough
14522
14523 /* check if data part fits in buffer */
14524 if (*pbuffer_size < bufsize) {
14525 int newsize = 1024 + ALIGN8(bufsize);
14526
14527 //printf("recv_event_server: buffer realloc %d -> %d\n", *pbuffer_size, newsize);
14528
14529 char *newbuf = (char *) realloc(*pbuffer, newsize);
14530 if (newbuf == NULL) {
14531 cm_msg(MERROR, "recv_event_server", "cannot realloc() event buffer from %d to %d bytes", *pbuffer_size,
14532 newsize);
14533 return -1;
14534 }
14535 *pbuffer = newbuf;
14536 *pbuffer_size = newsize;
14537 }
14538
14539 // Third, copy header into output buffer
14540
14541 memcpy(*pbuffer, header_buf, header_size);
14542
14543 // Forth, read the event data
14544
14545 int to_read = sizeof(INT) + total_size - header_size;
14546 int rptr = header_size;
14547
14548 if (to_read > 0) {
14549 int drd = recv_tcp2(sock, (*pbuffer) + rptr, to_read, 0);
14550
14551 /* abort if connection broken */
14552 if (drd <= 0) {
14553 cm_msg(MERROR, "recv_event_server", "recv_tcp2(data) returned %d instead of %d", drd, to_read);
14554 return -1;
14555 }
14556 }
14557
14558 return bufsize;
14559}
#define TID_INT32
Definition midas.h:339
#define MERROR
Definition midas.h:559
#define TID_UINT32
Definition midas.h:337
#define TID_INT16
Definition midas.h:335
#define ALIGN8(x)
Definition midas.h:522
INT recv_tcp2(int sock, char *net_buffer, int buffer_size, int timeout_ms)
Definition system.cxx:5634
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:930
void rpc_convert_single(void *data, INT tid, INT flags, INT convert_flags)
Definition midas.cxx:11706
INT i
Definition mdump.cxx:32
int event_size
Definition msysmon.cxx:527
short int event_id
Definition midas.h:853
DWORD data_size
Definition midas.h:857
DWORD serial_number
Definition midas.h:855
DWORD time_stamp
Definition midas.h:856
short int trigger_mask
Definition midas.h:854
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 14222 of file midas.cxx.

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

14400{
14401 /* figure out to which connection socket belongs */
14402 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++)
14403 if (_server_acceptions[idx] && _server_acceptions[idx]->recv_sock == sock) {
14404 return _server_acceptions[idx]->write_ptr - _server_acceptions[idx]->read_ptr;
14405 }
14406
14407 return 0;
14408}
static std::vector< RPC_SERVER_ACCEPTION * > _server_acceptions
Definition midas.cxx:11527
Here is the caller graph for this function:

◆ rpc_add_allowed_host()

INT rpc_add_allowed_host ( const char *  hostname)

Definition at line 15260 of file midas.cxx.

15277{
15278 //cm_msg(MINFO, "rpc_add_allowed_host", "Adding allowed host \'%s\'", hostname);
15279
15280 gAllowedHostsMutex.lock();
15281 gAllowedHosts.push_back(hostname);
15282 gAllowedHostsEnabled = true;
15283 gAllowedHostsMutex.unlock();
15284
15285 return RPC_SUCCESS;
15286}
#define RPC_SUCCESS
Definition midas.h:699
static std::atomic_bool gAllowedHostsEnabled(false)
static std::mutex gAllowedHostsMutex
Definition midas.cxx:15232
static std::vector< std::string > gAllowedHosts
Definition midas.cxx:15231
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 11608 of file midas.cxx.

11608 {
11609 *convert_flags = 0;
11610
11611 /* big/little endian conversion */
11612 if (((remote_hw_type & DRI_BIG_ENDIAN) &&
11613 (hw_type & DRI_LITTLE_ENDIAN)) || ((remote_hw_type & DRI_LITTLE_ENDIAN)
11614 && (hw_type & DRI_BIG_ENDIAN)))
11615 *convert_flags |= CF_ENDIAN;
11616
11617 /* float conversion between IEEE and VAX G */
11618 if ((remote_hw_type & DRF_G_FLOAT) && (hw_type & DRF_IEEE))
11619 *convert_flags |= CF_VAX2IEEE;
11620
11621 /* float conversion between VAX G and IEEE */
11622 if ((remote_hw_type & DRF_IEEE) && (hw_type & DRF_G_FLOAT))
11623 *convert_flags |= CF_IEEE2VAX;
11624
11626 //if (remote_hw_type & DR_ASCII)
11627 // *convert_flags |= CF_ASCII;
11628}
#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:1610
#define CF_IEEE2VAX
Definition midas.h:1611
#define CF_VAX2IEEE
Definition midas.h:1612
Here is the caller graph for this function:

◆ rpc_call()

INT rpc_call ( DWORD  routine_id,
  ... 
)

Definition at line 13688 of file midas.cxx.

13712{
13713 va_list ap;
13714 INT i, status;
13715
13716 BOOL rpc_no_reply = routine_id & RPC_NO_REPLY;
13717 routine_id &= ~RPC_NO_REPLY;
13718
13719 //if (rpc_no_reply)
13720 // printf("rpc_call: routine_id %d, RPC_NO_REPLY\n", routine_id);
13721
13722 int send_sock = _server_connection.send_sock;
13723 int rpc_timeout = _server_connection.rpc_timeout;
13724
13725 if (!send_sock) {
13726 fprintf(stderr, "rpc_call(routine_id=%d) failed, no connection to mserver.\n", routine_id);
13727 return RPC_NET_ERROR;
13728 }
13729
13730 if (!_mutex_rpc) {
13731 /* create a local mutex for multi-threaded applications */
13733 }
13734
13735 status = ss_mutex_wait_for(_mutex_rpc, 10000 + rpc_timeout);
13736 if (status != SS_SUCCESS) {
13737 cm_msg(MERROR, "rpc_call", "Mutex timeout");
13738 return RPC_MUTEX_TIMEOUT;
13739 }
13740
13741 /* find rpc definition */
13742
13743 int idx = -1;
13744 const char* rpc_name = NULL;
13745 RPC_LIST rpc_entry;
13746
13747 rpc_list_mutex.lock();
13748
13749 for (size_t i = 0; i < rpc_list.size(); i++) {
13750 if (rpc_list[i].id == (int) routine_id) {
13751 idx = i;
13752 rpc_name = rpc_list[idx].name;
13753 rpc_entry = rpc_list[idx];
13754 break;
13755 }
13756 }
13757
13758 rpc_list_mutex.unlock();
13759
13760 if (idx < 0) {
13762 cm_msg(MERROR, "rpc_call", "invalid rpc ID (%d)", routine_id);
13763 return RPC_INVALID_ID;
13764 }
13765
13766 /* prepare output buffer */
13767
13768 NET_COMMAND* nc = NULL;
13769
13770 /* examine variable argument list and convert it to parameter array */
13771 va_start(ap, routine_id);
13772
13773 rpc_call_encode(ap, rpc_entry, &nc);
13774
13775 va_end(ap);
13776
13777 nc->header.routine_id = routine_id;
13778
13779 if (rpc_no_reply)
13781
13782 int send_size = nc->header.param_size + sizeof(NET_COMMAND_HEADER);
13783
13784 /* do not wait for reply if requested RPC_NO_REPLY */
13785 if (rpc_no_reply) {
13786 i = send_tcp(send_sock, (char *) nc, send_size, 0);
13787
13788 if (i != send_size) {
13790 cm_msg(MERROR, "rpc_call", "rpc \"%s\" error: send_tcp() failed", rpc_name);
13791 free(nc);
13792 return RPC_NET_ERROR;
13793 }
13794
13796 free(nc);
13797 return RPC_SUCCESS;
13798 }
13799
13800 /* in TCP mode, send and wait for reply on send socket */
13801 i = send_tcp(send_sock, (char *) nc, send_size, 0);
13802 if (i != send_size) {
13804 cm_msg(MERROR, "rpc_call", "rpc \"%s\" error: send_tcp() failed", rpc_name);
13805 free(nc);
13806 return RPC_NET_ERROR;
13807 }
13808
13809 free(nc);
13810 nc = NULL;
13811
13812 bool restore_watchdog_timeout = false;
13813 BOOL watchdog_call;
13814 DWORD watchdog_timeout;
13815 cm_get_watchdog_params(&watchdog_call, &watchdog_timeout);
13816
13817 //printf("watchdog timeout: %d, rpc_timeout: %d\n", watchdog_timeout, rpc_timeout);
13818
13819 if (!rpc_is_remote()) {
13820 // if RPC is remote, we are connected to an mserver,
13821 // the mserver takes care of watchdog timeouts.
13822 // otherwise we should make sure the watchdog timeout
13823 // is longer than the RPC timeout. K.O.
13824 if (rpc_timeout >= (int) watchdog_timeout) {
13825 restore_watchdog_timeout = true;
13826 cm_set_watchdog_params_local(watchdog_call, rpc_timeout + 1000);
13827 }
13828 }
13829
13830 DWORD rpc_status = 0;
13831 DWORD buf_size = 0;
13832 char* buf = NULL;
13833
13834 status = ss_recv_net_command(send_sock, &rpc_status, &buf_size, &buf, rpc_timeout);
13835
13836 if (restore_watchdog_timeout) {
13837 cm_set_watchdog_params_local(watchdog_call, watchdog_timeout);
13838 }
13839
13840 /* drop the mutex, we are done with the socket, argument unpacking is done from our own buffer */
13841
13843
13844 /* check for reply errors */
13845
13846 if (status == SS_TIMEOUT) {
13847 cm_msg(MERROR, "rpc_call", "routine \"%s\": timeout waiting for reply, program abort", rpc_name);
13848 if (buf)
13849 free(buf);
13850 abort(); // cannot continue - our mserver is not talking to us!
13851 return RPC_TIMEOUT;
13852 }
13853
13854 if (status != SS_SUCCESS) {
13855 cm_msg(MERROR, "rpc_call", "routine \"%s\": error, ss_recv_net_command() status %d, program abort", rpc_name, status);
13856 if (buf)
13857 free(buf);
13858 abort(); // cannot continue - something is wrong with our mserver connection
13859 return RPC_NET_ERROR;
13860 }
13861
13862 if (rpc_status == RPC_INVALID_ID) {
13863 cm_msg(MERROR, "rpc_call", "routine \"%s\": error, unknown RPC, status %d", rpc_name, rpc_status);
13864 if (buf)
13865 free(buf);
13866 return rpc_status;
13867 }
13868
13869 /* extract result variables and place it to argument list */
13870
13871 va_start(ap, routine_id);
13872
13873 status = rpc_call_decode(ap, rpc_entry, buf, buf_size);
13874
13875 if (status != RPC_SUCCESS) {
13876 rpc_status = status;
13877 }
13878
13879 va_end(ap);
13880
13881 if (buf)
13882 free(buf);
13883
13884 return rpc_status;
13885}
INT cm_get_watchdog_params(BOOL *call_watchdog, DWORD *timeout)
Definition midas.cxx:3340
INT cm_set_watchdog_params_local(BOOL call_watchdog, DWORD timeout)
Definition midas.cxx:3259
#define SS_SUCCESS
Definition midas.h:664
#define SS_TIMEOUT
Definition midas.h:675
#define RPC_INVALID_ID
Definition midas.h:707
#define RPC_MUTEX_TIMEOUT
Definition midas.h:711
#define RPC_TIMEOUT
Definition midas.h:703
#define RPC_NET_ERROR
Definition midas.h:702
unsigned int DWORD
Definition mcstd.h:51
#define RPC_NO_REPLY
Definition midas.h:396
INT ss_mutex_release(MUTEX_T *mutex)
Definition system.cxx:3229
INT ss_mutex_create(MUTEX_T **mutex, BOOL recursive)
Definition system.cxx:3013
INT ss_recv_net_command(int sock, DWORD *routine_id, DWORD *param_size, char **param_ptr, int timeout_ms)
Definition system.cxx:5707
INT send_tcp(int sock, char *buffer, DWORD buffer_size, INT flags)
Definition system.cxx:5357
INT ss_mutex_wait_for(MUTEX_T *mutex, INT timeout)
Definition system.cxx:3109
bool rpc_is_remote(void)
Definition midas.cxx:12786
static std::vector< RPC_LIST > rpc_list
Definition midas.cxx:11598
static void rpc_call_encode(va_list &ap, const RPC_LIST &rl, NET_COMMAND **nc)
Definition midas.cxx:13256
static std::mutex rpc_list_mutex
Definition midas.cxx:11599
static int rpc_call_decode(va_list &ap, const RPC_LIST &rl, const char *buf, size_t buf_size)
Definition midas.cxx:13427
static RPC_SERVER_CONNECTION _server_connection
Definition midas.cxx:11523
static MUTEX_T * _mutex_rpc
Definition midas.cxx:227
DWORD BOOL
Definition midas.h:105
DWORD status
Definition odbhist.cxx:39
const char * name
Definition midas.h:1598
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 13427 of file midas.cxx.

13428{
13429 bool debug = false;
13430
13431 if (debug)
13432 printf("decode reply to rpc_id %d \"%s\" has %d bytes\n", rl.id, rl.name, (int)buf_size);
13433
13434 /* extract result variables and place it to argument list */
13435
13436 const char* param_ptr = buf;
13437
13438 for (int i = 0; rl.param[i].tid != 0; i++) {
13439 int tid = rl.param[i].tid;
13440 int flags = rl.param[i].flags;
13441 int arg_type = 0;
13442
13443 bool bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
13444 (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
13445 tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
13446
13447 if (bpointer)
13448 arg_type = TID_ARRAY;
13449 else
13450 arg_type = rl.param[i].tid;
13451
13452 if (tid == TID_FLOAT && !bpointer)
13453 arg_type = TID_DOUBLE;
13454
13455 char arg[8];
13456 rpc_va_arg(&ap, arg_type, arg);
13457
13458 if (rl.param[i].flags & RPC_OUT) {
13459
13460 if (param_ptr == NULL) {
13461 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);
13462 return RPC_NET_ERROR;
13463 }
13464
13465 tid = rl.param[i].tid;
13466 int arg_size = rpc_tid_size(tid);
13467
13468 if (tid == TID_STRING || tid == TID_LINK)
13469 arg_size = strlen((char *) (param_ptr)) + 1;
13470
13471 if (flags & RPC_VARARRAY) {
13472 arg_size = *((INT *) param_ptr);
13473 param_ptr += ALIGN8(sizeof(INT));
13474 }
13475
13476 if (tid == TID_STRUCT || (flags & RPC_FIXARRAY))
13477 arg_size = rl.param[i].n;
13478
13479 /* parameter size is always aligned */
13480 int param_size = ALIGN8(arg_size);
13481
13482 /* return parameters are always pointers */
13483 if (*((char **) arg)) {
13484 if (debug)
13485 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);
13486 memcpy((void *) *((char **) arg), param_ptr, arg_size);
13487 }
13488
13489 param_ptr += param_size;
13490 }
13491 }
13492
13493 return RPC_SUCCESS;
13494}
#define TID_DOUBLE
Definition midas.h:343
#define TID_STRUCT
Definition midas.h:348
#define TID_LINK
Definition midas.h:350
#define TID_STRING
Definition midas.h:346
#define TID_ARRAY
Definition midas.h:347
#define TID_FLOAT
Definition midas.h:341
void rpc_va_arg(va_list *arg_ptr, INT arg_type, void *arg)
Definition midas.cxx:13218
INT rpc_tid_size(INT id)
Definition midas.cxx:11782
BOOL debug
debug printouts
Definition mana.cxx:254
#define RPC_OUT
Definition midas.h:1580
#define RPC_POINTER
Definition midas.h:1581
#define RPC_VARARRAY
Definition midas.h:1583
#define RPC_FIXARRAY
Definition midas.h:1582
RPC_PARAM param[MAX_RPC_PARAMS]
Definition midas.h:1599
INT id
Definition midas.h:1597
WORD flags
Definition midas.h:1590
WORD tid
Definition midas.h:1589
INT n
Definition midas.h:1591
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 13256 of file midas.cxx.

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

15300{
15301 //printf("rpc_check_allowed_host: enabled %d, hostname [%s]\n", gAllowedHostsEnabled.load(), hostname);
15302
15304 return RPC_SUCCESS;
15305
15306 if (strcmp(hostname, "localhost") == 0)
15307 return RPC_SUCCESS;
15308
15309 if (strcmp(hostname, "localhost.localdomain") == 0)
15310 return RPC_SUCCESS;
15311
15312 if (strcmp(hostname, "localhost6") == 0) // RedHat el6, el7
15313 return RPC_SUCCESS;
15314
15315 if (strcmp(hostname, "ip6-localhost") == 0) // Ubuntu-22
15316 return RPC_SUCCESS;
15317
15319
15320 gAllowedHostsMutex.lock();
15321
15322 for (const auto& h: gAllowedHosts) {
15323 if (h == hostname) {
15325 break;
15326 }
15327 }
15328
15329 gAllowedHostsMutex.unlock();
15330
15331 //if (status != RPC_SUCCESS)
15332 // printf("rpc_check_allowed_host: enabled %d, hostname [%s] not found\n", gAllowedHostsEnabled.load(), hostname);
15333
15334 return status;
15335}
#define RPC_NOT_REGISTERED
Definition midas.h:705
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 16279 of file midas.cxx.

16297{
16298 INT status;
16299 NET_COMMAND nc;
16300 fd_set readfds;
16301 struct timeval timeout;
16302
16303 //printf("rpc_check_channels!\n");
16304
16305 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
16306 if (_server_acceptions[idx] && _server_acceptions[idx]->recv_sock) {
16308 if (sa == NULL)
16309 continue;
16310
16311 if (sa->watchdog_timeout == 0) {
16312 continue;
16313 }
16314
16315 DWORD elapsed = ss_millitime() - sa->last_activity;
16316
16317 //printf("rpc_check_channels: idx %d, watchdog_timeout %d, last_activity %d, elapsed %d\n", idx, sa->watchdog_timeout, sa->last_activity, elapsed);
16318
16319 if (sa->watchdog_timeout && (elapsed > (DWORD)sa->watchdog_timeout)) {
16320
16321 //printf("rpc_check_channels: send watchdog message to %s on %s\n", sa->prog_name.c_str(), sa->host_name.c_str());
16322
16323 /* send a watchdog message */
16325 nc.header.param_size = 0;
16326
16327 int convert_flags = sa->convert_flags;
16328 if (convert_flags) {
16331 }
16332
16333 /* send the header to the client */
16334 int i = send_tcp(sa->send_sock, (char *) &nc, sizeof(NET_COMMAND_HEADER), 0);
16335
16336 if (i < 0) {
16337 cm_msg(MINFO, "rpc_check_channels", "client \"%s\" on host \"%s\" failed watchdog test after %d sec, send_tcp() returned %d",
16338 sa->prog_name.c_str(),
16339 sa->host_name.c_str(),
16340 sa->watchdog_timeout / 1000,
16341 i);
16342
16343 /* disconnect from experiment */
16344 if (rpc_is_mserver()) {
16346 return RPC_NET_ERROR;
16347 }
16348
16349 sa->close();
16350 return RPC_NET_ERROR;
16351 }
16352
16353 DWORD timeout_end_ms = ss_millitime() + sa->watchdog_timeout;
16354
16355 while (1) {
16356 FD_ZERO(&readfds);
16357 FD_SET(sa->send_sock, &readfds);
16358 FD_SET(sa->recv_sock, &readfds);
16359
16360 timeout.tv_sec = 1;
16361 timeout.tv_usec = 0;
16362
16363 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
16364
16365 DWORD now = ss_millitime();
16366
16367 //printf("waiting for reply: %d %d, diff %d, select() status %d\n", now, timeout_end_ms, timeout_end_ms - now, status);
16368
16369 if (now > timeout_end_ms) // timeout
16370 break;
16371
16372 if (status > 0) // select has something to read
16373 break;
16374
16375 // select() returned 0, timeout
16376 // select() returned -1, error, likely EAGAIN or EINTR
16377
16380 }
16381
16382 if (!FD_ISSET(sa->send_sock, &readfds) &&
16383 !FD_ISSET(sa->recv_sock, &readfds)) {
16384
16385 cm_msg(MERROR, "rpc_check_channels", "client \"%s\" on host \"%s\" failed watchdog test after %d sec",
16386 sa->prog_name.c_str(),
16387 sa->host_name.c_str(),
16388 sa->watchdog_timeout / 1000);
16389
16390 /* disconnect from experiment */
16391 if (rpc_is_mserver()) {
16393 return RPC_NET_ERROR;
16394 }
16395
16396 sa->close();
16397 return RPC_NET_ERROR;
16398 }
16399
16400 /* receive result on send socket */
16401 if (FD_ISSET(sa->send_sock, &readfds)) {
16402 i = recv_tcp(sa->send_sock, (char *) &nc, sizeof(nc), 0);
16403 if (i <= 0) {
16404 cm_msg(MERROR, "rpc_check_channels", "client \"%s\" on host \"%s\" failed watchdog test after %d sec, recv_tcp() returned %d",
16405 sa->prog_name.c_str(),
16406 sa->host_name.c_str(),
16407 sa->watchdog_timeout / 1000,
16408 i);
16409
16410 /* disconnect from experiment */
16411 if (rpc_is_mserver()) {
16413 return RPC_NET_ERROR;
16414 }
16415
16416 sa->close();
16417 return RPC_NET_ERROR;
16418 }
16419 }
16420 }
16421 }
16422 }
16423
16424 return RPC_SUCCESS;
16425}
INT cm_periodic_tasks()
Definition midas.cxx:5596
INT cm_disconnect_experiment(void)
Definition midas.cxx:2861
#define MINFO
Definition midas.h:560
#define FD_SETSIZE
Definition msystem.h:206
#define MSG_WATCHDOG
Definition msystem.h:307
DWORD ss_millitime()
Definition system.cxx:3465
INT recv_tcp(int sock, char *net_buffer, DWORD buffer_size, INT flags)
Definition system.cxx:5526
INT cm_msg_flush_buffer()
Definition midas.cxx:880
bool rpc_is_mserver(void)
Definition midas.cxx:12843
#define RPC_OUTGOING
Definition midas.h:1584
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 15235 of file midas.cxx.

15251{
15252 gAllowedHostsMutex.lock();
15253 gAllowedHosts.clear();
15254 gAllowedHostsEnabled = false;
15255 gAllowedHostsMutex.unlock();
15256 return RPC_SUCCESS;
15257}
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 15623 of file midas.cxx.

15644{
15645 INT i, status;
15646 INT client_hw_type = 0, hw_type;
15647 std::string client_program;
15648 std::string host_name;
15649 INT convert_flags;
15650 char net_buffer[256], *p;
15651
15652 int sock = accept(lsock, NULL, NULL);
15653
15654 if (sock == -1)
15655 return RPC_NET_ERROR;
15656
15657 /* check access control list */
15660
15661 if (status != RPC_SUCCESS) {
15662 ss_socket_close(&sock);
15663 return RPC_NET_ERROR;
15664 }
15665 }
15666
15667 host_name = "(unknown)";
15668 client_program = "(unknown)";
15669
15670 /* receive string with timeout */
15671 i = recv_string(sock, net_buffer, sizeof(net_buffer), 10000);
15672 if (i <= 0) {
15673 ss_socket_close(&sock);
15674 return RPC_NET_ERROR;
15675 }
15676
15677 /* get remote computer info */
15678 p = strtok(net_buffer, " ");
15679 if (p != NULL) {
15680 client_hw_type = atoi(p);
15681 p = strtok(NULL, " ");
15682 }
15683 if (p != NULL) {
15684 //version = atoi(p);
15685 p = strtok(NULL, " ");
15686 }
15687 if (p != NULL) {
15688 client_program = p;
15689 p = strtok(NULL, " ");
15690 }
15691 if (p != NULL) {
15692 host_name = p;
15693 p = strtok(NULL, " ");
15694 }
15695
15696 //printf("rpc_client_accept: client_hw_type %d, version %d, client_name \'%s\', hostname \'%s\'\n", client_hw_type, version, client_program, host_name);
15697
15699
15700 /* save information in _server_acception structure */
15701 sa->recv_sock = sock;
15702 sa->send_sock = 0;
15703 sa->event_sock = 0;
15704 sa->remote_hw_type = client_hw_type;
15705 sa->host_name = host_name;
15706 sa->prog_name = client_program;
15708 sa->watchdog_timeout = 0;
15709 sa->is_mserver = FALSE;
15710
15711 /* send my own computer id */
15712 hw_type = rpc_get_hw_type();
15713 std::string str = msprintf("%d %s", hw_type, cm_get_version());
15714 status = send(sock, str.c_str(), str.length() + 1, 0);
15715 if (status != (INT) str.length() + 1)
15716 return RPC_NET_ERROR;
15717
15718 rpc_calc_convert_flags(hw_type, client_hw_type, &convert_flags);
15719 sa->convert_flags = convert_flags;
15720
15722
15723 return RPC_SUCCESS;
15724}
const char * cm_get_version()
Definition midas.cxx:1491
INT ss_suspend_set_server_acceptions(RPC_SERVER_ACCEPTION_LIST *acceptions)
Definition system.cxx:4370
INT recv_string(int sock, char *buffer, DWORD buffer_size, INT millisec)
Definition system.cxx:5471
void rpc_calc_convert_flags(INT hw_type, INT remote_hw_type, INT *convert_flags)
Definition midas.cxx:11608
static RPC_SERVER_ACCEPTION * rpc_new_server_acception()
Definition midas.cxx:11543
static INT rpc_socket_check_allowed_host(int sock)
Definition midas.cxx:15338
char host_name[HOST_NAME_LENGTH]
Definition mana.cxx:242
std::string msprintf(const char *format,...)
Definition midas.cxx:419
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 13497 of file midas.cxx.

13522{
13524
13525 if (!c) {
13526 cm_msg(MERROR, "rpc_client_call", "invalid rpc connection handle %d", hConn);
13527 return RPC_NO_CONNECTION;
13528 }
13529
13530 //printf("rpc_client_call: handle %d, connection: ", hConn);
13531 //c->print();
13532 //printf("\n");
13533
13534 INT i, status;
13535
13536 BOOL rpc_no_reply = routine_id & RPC_NO_REPLY;
13537 routine_id &= ~RPC_NO_REPLY;
13538
13539 //if (rpc_no_reply)
13540 // printf("rpc_client_call: routine_id %d, RPC_NO_REPLY\n", routine_id);
13541
13542 // make local copy of the client name just in case _client_connection is erased by another thread
13543
13544 /* find rpc_index */
13545
13546 int rpc_index = -1;
13547 const char *rpc_name = NULL;
13548 RPC_LIST rpc_entry;
13549
13550 rpc_list_mutex.lock();
13551 for (size_t i = 0; i < rpc_list.size(); i++) {
13552 if (rpc_list[i].id == (int) routine_id) {
13553 rpc_index = i;
13554 rpc_name = rpc_list[rpc_index].name;
13555 rpc_entry = rpc_list[rpc_index];
13556 break;
13557 }
13558 }
13559 rpc_list_mutex.unlock();
13560
13561 if (rpc_index < 0) {
13562 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);
13563 c->mutex.unlock();
13564 return RPC_INVALID_ID;
13565 }
13566
13567 NET_COMMAND *nc = NULL;
13568
13569 /* examine variable argument list and convert it to parameter array */
13570 va_list ap;
13571 va_start(ap, routine_id);
13572
13573 rpc_call_encode(ap, rpc_entry, &nc);
13574
13575 va_end(ap);
13576
13577 nc->header.routine_id = routine_id;
13578
13579 if (rpc_no_reply)
13581
13582 int send_size = nc->header.param_size + sizeof(NET_COMMAND_HEADER);
13583
13584 /* in FAST TCP mode, only send call and return immediately */
13585 if (rpc_no_reply) {
13586 i = send_tcp(c->send_sock, (char *) nc, send_size, 0);
13587
13588 if (i != send_size) {
13589 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);
13590 free(nc);
13591 c->mutex.unlock();
13592 return RPC_NET_ERROR;
13593 }
13594
13595 free(nc);
13596
13597 if (routine_id == RPC_ID_EXIT || routine_id == RPC_ID_SHUTDOWN) {
13598 //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);
13599 //c->print();
13600 //printf("\n");
13601 c->close_locked();
13602 }
13603
13604 c->mutex.unlock();
13605 return RPC_SUCCESS;
13606 }
13607
13608 /* in TCP mode, send and wait for reply on send socket */
13609 i = send_tcp(c->send_sock, (char *) nc, send_size, 0);
13610 if (i != send_size) {
13611 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);
13612 c->mutex.unlock();
13613 return RPC_NET_ERROR;
13614 }
13615
13616 free(nc);
13617 nc = NULL;
13618
13619 bool restore_watchdog_timeout = false;
13620 BOOL watchdog_call;
13621 DWORD watchdog_timeout;
13622 cm_get_watchdog_params(&watchdog_call, &watchdog_timeout);
13623
13624 //printf("watchdog timeout: %d, rpc_timeout: %d\n", watchdog_timeout, c->rpc_timeout);
13625
13626 if (c->rpc_timeout >= (int) watchdog_timeout) {
13627 restore_watchdog_timeout = true;
13628 cm_set_watchdog_params(watchdog_call, c->rpc_timeout + 1000);
13629 }
13630
13631 DWORD rpc_status = 0;
13632 DWORD buf_size = 0;
13633 char* buf = NULL;
13634
13635 /* receive result on send socket */
13636 status = ss_recv_net_command(c->send_sock, &rpc_status, &buf_size, &buf, c->rpc_timeout);
13637
13638 if (restore_watchdog_timeout) {
13639 cm_set_watchdog_params(watchdog_call, watchdog_timeout);
13640 }
13641
13642 if (status == SS_TIMEOUT) {
13643 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);
13644 if (buf)
13645 free(buf);
13646 c->mutex.unlock();
13647 return RPC_TIMEOUT;
13648 }
13649
13650 if (status != SS_SUCCESS) {
13651 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);
13652 if (buf)
13653 free(buf);
13654 c->mutex.unlock();
13655 return RPC_NET_ERROR;
13656 }
13657
13658 c->mutex.unlock();
13659
13660 if (rpc_status == RPC_INVALID_ID) {
13661 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);
13662 if (buf)
13663 free(buf);
13664 return rpc_status;
13665 }
13666
13667 /* extract result variables and place it to argument list */
13668
13669 va_start(ap, routine_id);
13670
13671 status = rpc_call_decode(ap, rpc_entry, buf, buf_size);
13672
13673 if (status != RPC_SUCCESS) {
13674 rpc_status = status;
13675 }
13676
13677 va_end(ap);
13678
13679 if (buf)
13680 free(buf);
13681 buf = NULL;
13682 buf_size = 0;
13683
13684 return rpc_status;
13685}
INT cm_set_watchdog_params(BOOL call_watchdog, DWORD timeout)
Definition midas.cxx:3298
#define RPC_NO_CONNECTION
Definition midas.h:701
#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:12637
char c
Definition system.cxx:1312
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 12295 of file midas.cxx.

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

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

◆ rpc_client_disconnect()

INT rpc_client_disconnect ( HNDLE  hConn,
BOOL  bShutdown 
)

Definition at line 12701 of file midas.cxx.

12719{
12720 /* notify server about exit */
12721
12722 /* call exit and shutdown with RPC_NO_REPLY because client will exit immediately without possibility of replying */
12723
12725
12726 return RPC_SUCCESS;
12727}
INT rpc_client_call(HNDLE hConn, DWORD routine_id,...)
Definition midas.cxx:13497
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 11970 of file midas.cxx.

11978{
11979 INT status = 0;
11980 char net_buffer[256];
11981
11982 int n = recv_tcp(sock, net_buffer, sizeof(net_buffer), 0);
11983 if (n <= 0)
11984 return SS_ABORT;
11985
11986 NET_COMMAND *nc = (NET_COMMAND *) net_buffer;
11987
11988 if (nc->header.routine_id == MSG_ODB) {
11989 status = handle_msg_odb(n, nc);
11990 } else if (nc->header.routine_id == MSG_WATCHDOG) {
11991 nc->header.routine_id = 1;
11992 nc->header.param_size = 0;
11993 send_tcp(sock, net_buffer, sizeof(NET_COMMAND_HEADER), 0);
11995 } else if (nc->header.routine_id == MSG_BM) {
11996 fd_set readfds;
11997 struct timeval timeout;
11998
11999 //printf("rpc_client_dispatch: received MSG_BM!\n");
12000
12001 /* receive further messages to empty TCP queue */
12002 do {
12003 FD_ZERO(&readfds);
12004 FD_SET(sock, &readfds);
12005
12006 timeout.tv_sec = 0;
12007 timeout.tv_usec = 0;
12008
12009 select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
12010
12011 if (FD_ISSET(sock, &readfds)) {
12012 n = recv_tcp(sock, net_buffer, sizeof(net_buffer), 0);
12013 if (n <= 0)
12014 return SS_ABORT;
12015
12016 if (nc->header.routine_id == MSG_ODB) {
12017 status = handle_msg_odb(n, nc);
12018 } else if (nc->header.routine_id == MSG_WATCHDOG) {
12019 nc->header.routine_id = 1;
12020 nc->header.param_size = 0;
12021 send_tcp(sock, net_buffer, sizeof(NET_COMMAND_HEADER), 0);
12023 }
12024 }
12025
12026 } while (FD_ISSET(sock, &readfds));
12027
12028 /* poll event from server */
12030 }
12031
12032 return status;
12033}
INT bm_poll_event()
Definition midas.cxx:11151
#define SS_ABORT
Definition midas.h:678
#define MSG_BM
Definition msystem.h:302
#define MSG_ODB
Definition msystem.h:303
static int handle_msg_odb(int n, const NET_COMMAND *nc)
Definition midas.cxx:11956
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 11731 of file midas.cxx.

11759{
11760 /* convert array */
11761 if (flags & (RPC_FIXARRAY | RPC_VARARRAY)) {
11762 int single_size = rpc_tid_size(tid);
11763 /* don't convert TID_ARRAY & TID_STRUCT */
11764 if (single_size == 0)
11765 return;
11766
11767 int n = total_size / single_size;
11768
11769 for (int i = 0; i < n; i++) {
11770 char* p = (char *) data + (i * single_size);
11771 rpc_convert_single(p, tid, flags, convert_flags);
11772 }
11773 } else {
11774 rpc_convert_single(data, tid, flags, convert_flags);
11775 }
11776}
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 11706 of file midas.cxx.

11706 {
11707
11708 if (convert_flags & CF_ENDIAN) {
11709 if (tid == TID_UINT16 || tid == TID_INT16) WORD_SWAP(data);
11710 if (tid == TID_UINT32 || tid == TID_INT32 || tid == TID_BOOL || tid == TID_FLOAT) DWORD_SWAP(data);
11711 if (tid == TID_DOUBLE) QWORD_SWAP(data);
11712 }
11713
11714 if (((convert_flags & CF_IEEE2VAX) && !(flags & RPC_OUTGOING)) ||
11715 ((convert_flags & CF_VAX2IEEE) && (flags & RPC_OUTGOING))) {
11716 if (tid == TID_FLOAT)
11717 rpc_ieee2vax_float((float *) data);
11718 if (tid == TID_DOUBLE)
11719 rpc_ieee2vax_double((double *) data);
11720 }
11721
11722 if (((convert_flags & CF_IEEE2VAX) && (flags & RPC_OUTGOING)) ||
11723 ((convert_flags & CF_VAX2IEEE) && !(flags & RPC_OUTGOING))) {
11724 if (tid == TID_FLOAT)
11725 rpc_vax2ieee_float((float *) data);
11726 if (tid == TID_DOUBLE)
11727 rpc_vax2ieee_double((double *) data);
11728 }
11729}
#define TID_BOOL
Definition midas.h:340
#define WORD_SWAP(x)
Definition msystem.h:65
#define QWORD_SWAP(x)
Definition msystem.h:86
#define DWORD_SWAP(x)
Definition msystem.h:74
void rpc_vax2ieee_float(float *var)
Definition midas.cxx:11651
void rpc_ieee2vax_float(float *var)
Definition midas.cxx:11636
void rpc_ieee2vax_double(double *var)
Definition midas.cxx:11686
void rpc_vax2ieee_double(double *var)
Definition midas.cxx:11667
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 13186 of file midas.cxx.

13200{
13201 va_list argptr;
13202 char str[1000];
13203
13204 if (_debug_mode) {
13205 va_start(argptr, format);
13206 vsprintf(str, (char *) format, argptr);
13207 va_end(argptr);
13208
13209 if (_debug_print) {
13210 strcat(str, "\n");
13212 } else
13213 puts(str);
13214 }
13215}
static void(* _debug_print)(const char *)
Definition midas.cxx:229
static INT _debug_mode
Definition midas.cxx:231
Here is the caller graph for this function:

◆ rpc_deregister_functions()

INT rpc_deregister_functions ( void  )

dox

Definition at line 11895 of file midas.cxx.

11912{
11913 rpc_list_mutex.lock();
11914 rpc_list.clear();
11915 rpc_list_mutex.unlock();
11916
11917 return RPC_SUCCESS;
11918}
Here is the caller graph for this function:

◆ rpc_execute()

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

Definition at line 14675 of file midas.cxx.

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

14063 {
14064 return RPC_SUCCESS;
14065}
Here is the caller graph for this function:

◆ rpc_flush_event_socket()

int rpc_flush_event_socket ( int  timeout_msec)

Definition at line 16161 of file midas.cxx.

16175{
16176 bool has_data = ss_event_socket_has_data();
16177
16178 //printf("ss_event_socket_has_data() returned %d\n", has_data);
16179
16180 if (has_data) {
16181 if (timeout_msec == BM_NO_WAIT) {
16182 return BM_ASYNC_RETURN;
16183 } else if (timeout_msec == BM_WAIT) {
16184 return BM_ASYNC_RETURN;
16185 } else {
16186 int status = ss_suspend(timeout_msec, MSG_BM);
16187 if (status == SS_ABORT || status == SS_EXIT)
16188 return status;
16189 return BM_ASYNC_RETURN;
16190 }
16191 }
16192
16193 int status = rpc_server_receive_event(0, NULL, timeout_msec);
16194
16195 //printf("rpc_server_receive_event() status %d\n", status);
16196
16197 if (status == BM_ASYNC_RETURN) {
16198 return BM_ASYNC_RETURN;
16199 }
16200
16201 if (status == SS_ABORT || status == SS_EXIT)
16202 return status;
16203
16204 return BM_SUCCESS;
16205}
#define BM_ASYNC_RETURN
Definition midas.h:613
#define BM_SUCCESS
Definition midas.h:605
#define BM_NO_WAIT
Definition midas.h:366
#define BM_WAIT
Definition midas.h:365
INT ss_suspend(INT millisec, INT msg)
Definition system.cxx:4615
bool ss_event_socket_has_data()
Definition system.cxx:4592
INT rpc_server_receive_event(int idx, RPC_SERVER_ACCEPTION *sa, int timeout_msec)
Definition midas.cxx:16006
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 11631 of file midas.cxx.

Here is the call graph for this function:

◆ rpc_get_convert_flags() [2/2]

INT rpc_get_convert_flags ( void  )

dox

Definition at line 13055 of file midas.cxx.

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

◆ rpc_get_hw_type()

INT rpc_get_hw_type ( )

Definition at line 12859 of file midas.cxx.

12870{
12871 {
12872 {
12873 INT tmp_type, size;
12874 DWORD dummy;
12875 unsigned char *p;
12876 float f;
12877 double d;
12878
12879 tmp_type = 0;
12880
12881 /* test pointer size */
12882 size = sizeof(p);
12883 if (size == 2)
12884 tmp_type |= DRI_16;
12885 if (size == 4)
12886 tmp_type |= DRI_32;
12887 if (size == 8)
12888 tmp_type |= DRI_64;
12889
12890 /* test if little or big endian machine */
12891 dummy = 0x12345678;
12892 p = (unsigned char *) &dummy;
12893 if (*p == 0x78)
12894 tmp_type |= DRI_LITTLE_ENDIAN;
12895 else if (*p == 0x12)
12896 tmp_type |= DRI_BIG_ENDIAN;
12897 else
12898 cm_msg(MERROR, "rpc_get_option", "unknown byte order format");
12899
12900 /* floating point format */
12901 f = (float) 1.2345;
12902 dummy = 0;
12903 memcpy(&dummy, &f, sizeof(f));
12904 if ((dummy & 0xFF) == 0x19 &&
12905 ((dummy >> 8) & 0xFF) == 0x04 && ((dummy >> 16) & 0xFF) == 0x9E
12906 && ((dummy >> 24) & 0xFF) == 0x3F)
12907 tmp_type |= DRF_IEEE;
12908 else if ((dummy & 0xFF) == 0x9E &&
12909 ((dummy >> 8) & 0xFF) == 0x40 && ((dummy >> 16) & 0xFF) == 0x19
12910 && ((dummy >> 24) & 0xFF) == 0x04)
12911 tmp_type |= DRF_G_FLOAT;
12912 else
12913 cm_msg(MERROR, "rpc_get_option", "unknown floating point format");
12914
12915 d = (double) 1.2345;
12916 dummy = 0;
12917 memcpy(&dummy, &d, sizeof(f));
12918 if ((dummy & 0xFF) == 0x8D && /* little endian */
12919 ((dummy >> 8) & 0xFF) == 0x97 && ((dummy >> 16) & 0xFF) == 0x6E
12920 && ((dummy >> 24) & 0xFF) == 0x12)
12921 tmp_type |= DRF_IEEE;
12922 else if ((dummy & 0xFF) == 0x83 && /* big endian */
12923 ((dummy >> 8) & 0xFF) == 0xC0 && ((dummy >> 16) & 0xFF) == 0xF3
12924 && ((dummy >> 24) & 0xFF) == 0x3F)
12925 tmp_type |= DRF_IEEE;
12926 else if ((dummy & 0xFF) == 0x13 &&
12927 ((dummy >> 8) & 0xFF) == 0x40 && ((dummy >> 16) & 0xFF) == 0x83
12928 && ((dummy >> 24) & 0xFF) == 0xC0)
12929 tmp_type |= DRF_G_FLOAT;
12930 else if ((dummy & 0xFF) == 0x9E &&
12931 ((dummy >> 8) & 0xFF) == 0x40 && ((dummy >> 16) & 0xFF) == 0x18
12932 && ((dummy >> 24) & 0xFF) == 0x04)
12933 cm_msg(MERROR, "rpc_get_option",
12934 "MIDAS cannot handle VAX D FLOAT format. Please compile with the /g_float flag");
12935 else
12936 cm_msg(MERROR, "rpc_get_option", "unknown floating point format");
12937
12938 return tmp_type;
12939 }
12940 }
12941}
#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:1313
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 12637 of file midas.cxx.

12638{
12640 if (hConn >= 0 && hConn < (int)_client_connections.size()) {
12642 if (c && c->connected) {
12644 c->mutex.lock();
12645 if (!c->connected) {
12646 // disconnected while we were waiting for the lock
12647 c->mutex.unlock();
12648 return NULL;
12649 }
12650 return c;
12651 }
12652 }
12654 return NULL;
12655}
Here is the caller graph for this function:

◆ rpc_get_mserver_acception()

RPC_SERVER_ACCEPTION * rpc_get_mserver_acception ( void  )

Definition at line 11538 of file midas.cxx.

11539{
11540 return _mserver_acception;
11541}
Here is the caller graph for this function:

◆ rpc_get_mserver_hostname()

std::string rpc_get_mserver_hostname ( void  )

Definition at line 12830 of file midas.cxx.

12838{
12840}
Here is the caller graph for this function:

◆ rpc_get_mserver_path()

const char * rpc_get_mserver_path ( void  )

Definition at line 13076 of file midas.cxx.

13084{
13085 return _mserver_path.c_str();
13086}
static std::string _mserver_path
Definition midas.cxx:13073
Here is the caller graph for this function:

◆ rpc_get_name()

std::string rpc_get_name ( )

Definition at line 13109 of file midas.cxx.

13127{
13128 return _client_name;
13129}
Here is the caller graph for this function:

◆ rpc_get_opt_tcp_size()

INT rpc_get_opt_tcp_size ( void  )

Definition at line 13897 of file midas.cxx.

13897 {
13898 return _opt_tcp_size;
13899}
static int _opt_tcp_size
Definition midas.cxx:11601

◆ rpc_get_server_acception()

static RPC_SERVER_ACCEPTION * rpc_get_server_acception ( int  idx)
static

Definition at line 11530 of file midas.cxx.

11531{
11532 assert(idx >= 0);
11533 assert(idx < (int)_server_acceptions.size());
11534 assert(_server_acceptions[idx] != NULL);
11535 return _server_acceptions[idx];
11536}
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 12998 of file midas.cxx.

12999{
13000 if (hConn == RPC_HNDLE_MSERVER) {
13002 } else if (hConn == RPC_HNDLE_CONNECT) {
13003 return _rpc_connect_timeout;
13004 } else {
13006 if (c) {
13007 int timeout = c->rpc_timeout;
13008 c->mutex.unlock();
13009 return timeout;
13010 }
13011 }
13012 return 0;
13013}
#define RPC_HNDLE_CONNECT
Definition midas.h:394
#define RPC_HNDLE_MSERVER
Definition midas.h:393
Here is the call graph for this function:

◆ rpc_ieee2vax_double()

void rpc_ieee2vax_double ( double *  var)

Definition at line 11686 of file midas.cxx.

11686 {
11687 unsigned short int i1, i2, i3, i4;
11688
11689 /* swap words */
11690 i1 = *((short int *) (var) + 3);
11691 i2 = *((short int *) (var) + 2);
11692 i3 = *((short int *) (var) + 1);
11693 i4 = *((short int *) (var));
11694
11695 /* correct exponent */
11696 if (i1 != 0)
11697 i1 += 0x20;
11698
11699 *((short int *) (var) + 3) = i4;
11700 *((short int *) (var) + 2) = i3;
11701 *((short int *) (var) + 1) = i2;
11702 *((short int *) (var)) = i1;
11703}
Here is the caller graph for this function:

◆ rpc_ieee2vax_float()

void rpc_ieee2vax_float ( float *  var)

Definition at line 11636 of file midas.cxx.

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

◆ rpc_is_connected()

bool rpc_is_connected ( void  )

Definition at line 12808 of file midas.cxx.

12825{
12826 return _server_connection.send_sock != 0;
12827}
Here is the caller graph for this function:

◆ rpc_is_mserver()

bool rpc_is_mserver ( void  )

Definition at line 12843 of file midas.cxx.

12854{
12855 return _mserver_acception != NULL;
12856}
Here is the caller graph for this function:

◆ rpc_is_remote()

bool rpc_is_remote ( void  )

Definition at line 12786 of file midas.cxx.

12803{
12804 return _rpc_is_remote;
12805}
static bool _rpc_is_remote
Definition midas.cxx:11524

◆ rpc_name_tid()

int rpc_name_tid ( const char *  name)

Definition at line 11803 of file midas.cxx.

11804{
11805 for (int i=0; i<TID_LAST; i++) {
11806 if (strcmp(name, tid_name[i]) == 0)
11807 return i;
11808 }
11809
11810 for (int i=0; i<TID_LAST; i++) {
11811 if (strcmp(name, tid_name_old[i]) == 0)
11812 return i;
11813 }
11814
11815 return 0;
11816}
#define TID_LAST
Definition midas.h:354
static const char * tid_name[]
Definition midas.cxx:111
static const char * tid_name_old[]
Definition midas.cxx:89
#define name(x)
Definition midas_macro.h:24
Here is the caller graph for this function:

◆ rpc_new_server_acception()

static RPC_SERVER_ACCEPTION * rpc_new_server_acception ( )
static

Definition at line 11543 of file midas.cxx.

11544{
11545 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
11546 if (_server_acceptions[idx] && (_server_acceptions[idx]->recv_sock == 0)) {
11547 //printf("rpc_new_server_acception: reuse acception in slot %d\n", idx);
11548 return _server_acceptions[idx];
11549 }
11550 }
11551
11553
11554 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
11555 if (_server_acceptions[idx] == NULL) {
11556 //printf("rpc_new_server_acception: new acception, reuse slot %d\n", idx);
11557 _server_acceptions[idx] = sa;
11558 return _server_acceptions[idx];
11559 }
11560 }
11561
11562 //printf("rpc_new_server_acception: new acception, array size %d, push_back\n", (int)_server_acceptions.size());
11563 _server_acceptions.push_back(sa);
11564
11565 return sa;
11566}
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 11833 of file midas.cxx.

11833 {
11837
11838 return RPC_SUCCESS;
11839}
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:11852
INT rpc_set_name(const char *name)
Definition midas.cxx:13133
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 11922 of file midas.cxx.

11941{
11942 std::lock_guard<std::mutex> guard(rpc_list_mutex);
11943
11944 for (size_t i = 0; i < rpc_list.size(); i++) {
11945 if (rpc_list[i].id == id) {
11946 rpc_list[i].dispatch = func;
11947 return RPC_SUCCESS;
11948 }
11949 }
11950
11951 return RPC_INVALID_ID;
11952}
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 11852 of file midas.cxx.

11853{
11854 for (int i = 0; new_list[i].id != 0; i++) {
11855 /* check valid ID for user functions */
11856 if (new_list != rpc_get_internal_list(0) &&
11857 new_list != rpc_get_internal_list(1) && (new_list[i].id < RPC_MIN_ID
11858 || new_list[i].id > RPC_MAX_ID)) {
11859 cm_msg(MERROR, "rpc_register_functions", "registered RPC function with invalid ID %d", new_list[i].id);
11860 }
11861 }
11862
11863 std::lock_guard<std::mutex> guard(rpc_list_mutex);
11864
11865 /* check double defined functions */
11866 for (int i = 0; new_list[i].id != 0; i++) {
11867 for (size_t j = 0; j < rpc_list.size(); j++) {
11868 if (rpc_list[j].id == new_list[i].id) {
11869 return RPC_DOUBLE_DEFINED;
11870 }
11871 }
11872 }
11873
11874 /* append new functions */
11875 for (int i = 0; new_list[i].id != 0; i++) {
11876 RPC_LIST e = new_list[i];
11877
11878 /* set default dispatcher */
11879 if (e.dispatch == NULL) {
11880 e.dispatch = func;
11881 }
11882
11883 rpc_list.push_back(e);
11884 }
11885
11886 return RPC_SUCCESS;
11887}
#define RPC_DOUBLE_DEFINED
Definition midas.h:710
#define RPC_MIN_ID
Definition midas.h:1605
#define RPC_MAX_ID
Definition midas.h:1606
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 14604 of file midas.cxx.

14627{
14628 /* register system functions: RPC_ID_EXIT, RPC_ID_SHUTDOWN, RPC_ID_WATCHDOG */
14630
14631 /* create a socket for listening */
14632 int lsock = 0;
14633 int lport = 0;
14634 std::string errmsg;
14635
14636 int status = ss_socket_listen_tcp(!disable_bind_rpc_to_localhost, port, &lsock, &lport, &errmsg);
14637
14638 if (status != SS_SUCCESS) {
14639 cm_msg(MERROR, "rpc_register_server", "cannot listen to tcp port %d: %s", port, errmsg.c_str());
14640 return RPC_NET_ERROR;
14641 }
14642
14643 /* set close-on-exec flag to prevent child mserver processes from inheriting the listen socket */
14644#if defined(F_SETFD) && defined(FD_CLOEXEC)
14645 status = fcntl(lsock, F_SETFD, fcntl(lsock, F_GETFD) | FD_CLOEXEC);
14646 if (status < 0) {
14647 cm_msg(MERROR, "rpc_register_server", "fcntl(F_SETFD, FD_CLOEXEC) failed, errno %d (%s)", errno, strerror(errno));
14648 return RPC_NET_ERROR;
14649 }
14650#endif
14651
14652 /* return port wich OS has choosen */
14653 if (pport) {
14654 *pport = lport;
14655 }
14656
14657 if (plsock)
14658 *plsock = lsock;
14659
14660 //printf("rpc_register_server: requested port %d, actual port %d, socket %d\n", port, *pport, *plsock);
14661
14662 return RPC_SUCCESS;
14663}
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:5134
static int disable_bind_rpc_to_localhost
Definition midas.cxx:237
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_register_server()

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

Definition at line 14563 of file midas.cxx.

14585{
14586 int status;
14587 int lsock;
14588
14589 status = rpc_register_listener(port, NULL, &lsock, pport);
14590 if (status != RPC_SUCCESS)
14591 return status;
14592
14594 if (status != SS_SUCCESS)
14595 return status;
14596
14597 if (plsock)
14598 *plsock = lsock;
14599
14600 return RPC_SUCCESS;
14601}
INT ss_suspend_set_client_listener(int listen_socket)
Definition system.cxx:4356
INT rpc_register_listener(int port, RPC_HANDLER func, int *plsock, int *pport)
Definition midas.cxx:14604
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 13926 of file midas.cxx.

13927{
13928 if (rpc_is_remote()) {
13929 return rpc_send_event1(buffer_handle, pevent);
13930 } else {
13931 return bm_send_event(buffer_handle, pevent, unused, async_flag);
13932 }
13933}
INT bm_send_event(INT buffer_handle, const EVENT_HEADER *pevent, int unused, int timeout_msec)
Definition midas.cxx:9688
INT rpc_send_event1(INT buffer_handle, const EVENT_HEADER *pevent)
Definition midas.cxx:13944
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 13944 of file midas.cxx.

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

13951{
13952 if (sg_n < 1) {
13953 cm_msg(MERROR, "rpc_send_event_sg", "invalid sg_n %d", sg_n);
13954 return BM_INVALID_SIZE;
13955 }
13956
13957 if (sg_ptr[0] == NULL) {
13958 cm_msg(MERROR, "rpc_send_event_sg", "invalid sg_ptr[0] is NULL");
13959 return BM_INVALID_SIZE;
13960 }
13961
13962 if (sg_len[0] < sizeof(EVENT_HEADER)) {
13963 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));
13964 return BM_INVALID_SIZE;
13965 }
13966
13967 const EVENT_HEADER* pevent = (const EVENT_HEADER*)sg_ptr[0];
13968
13969 const DWORD MAX_DATA_SIZE = (0x7FFFFFF0 - 16); // event size computations are not 32-bit clean, limit event size to 2GB. K.O.
13970 const DWORD data_size = pevent->data_size; // 32-bit unsigned value
13971
13972 if (data_size == 0) {
13973 cm_msg(MERROR, "rpc_send_event_sg", "invalid event data size zero");
13974 return BM_INVALID_SIZE;
13975 }
13976
13977 if (data_size > MAX_DATA_SIZE) {
13978 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);
13979 return BM_INVALID_SIZE;
13980 }
13981
13982 const size_t event_size = sizeof(EVENT_HEADER) + data_size;
13983 const size_t total_size = ALIGN8(event_size);
13984
13985 size_t count = 0;
13986 for (int i=0; i<sg_n; i++) {
13987 count += sg_len[i];
13988 }
13989
13990 if (count != event_size) {
13991 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);
13992 return BM_INVALID_SIZE;
13993 }
13994
13995 // protect non-atomic access to _server_connection.event_sock. K.O.
13996
13997 std::lock_guard<std::mutex> guard(_server_connection.event_sock_mutex);
13998
13999 //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);
14000
14001 if (_server_connection.event_sock == 0) {
14002 return RPC_NO_CONNECTION;
14003 }
14004
14005 //
14006 // event socket wire protocol: (see also rpc_server_receive_event() and recv_event_server_realloc())
14007 //
14008 // 4 bytes of buffer handle
14009 // 16 bytes of event header, includes data_size
14010 // ALIGN8(data_size) bytes of event data
14011 //
14012
14013 int status;
14014
14015 /* send buffer handle */
14016
14017 assert(sizeof(DWORD) == 4);
14018 DWORD bh_buf = buffer_handle;
14019
14020 status = ss_write_tcp(_server_connection.event_sock, (const char *) &bh_buf, sizeof(DWORD));
14021 if (status != SS_SUCCESS) {
14023 cm_msg(MERROR, "rpc_send_event_sg", "ss_write_tcp(buffer handle) failed, event socket is now closed");
14024 return RPC_NET_ERROR;
14025 }
14026
14027 /* send data */
14028
14029 for (int i=0; i<sg_n; i++) {
14030 status = ss_write_tcp(_server_connection.event_sock, sg_ptr[i], sg_len[i]);
14031 if (status != SS_SUCCESS) {
14033 cm_msg(MERROR, "rpc_send_event_sg", "ss_write_tcp(event data) failed, event socket is now closed");
14034 return RPC_NET_ERROR;
14035 }
14036 }
14037
14038 /* send padding */
14039
14040 if (count < total_size) {
14041 char padding[8] = { 0,0,0,0,0,0,0,0 };
14042 size_t padlen = total_size - count;
14043 assert(padlen < 8);
14045 if (status != SS_SUCCESS) {
14047 cm_msg(MERROR, "rpc_send_event_sg", "ss_write_tcp(padding) failed, event socket is now closed");
14048 return RPC_NET_ERROR;
14049 }
14050 }
14051
14052 return RPC_SUCCESS;
14053}
#define BM_INVALID_SIZE
Definition midas.h:624
INT ss_write_tcp(int sock, const char *buffer, size_t buffer_size)
Definition system.cxx:5424
double count
Definition mdump.cxx:33
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_server_accept()

INT rpc_server_accept ( int  lsock)

Definition at line 15366 of file midas.cxx.

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

15746{
15747 INT status;
15748 int recv_sock, send_sock, event_sock;
15749 char str[100];
15750 std::string client_program;
15751 INT client_hw_type, hw_type;
15752 INT convert_flags;
15753 char net_buffer[256];
15754 char *p;
15755 int flag;
15756
15757 /* copy callback information */
15758 struct callback_addr callback = *pcallback;
15759 //idx = callback.index;
15760
15761 std::string errmsg;
15762
15763 /* create new sockets for TCP */
15764 status = ss_socket_connect_tcp(callback.host_name.c_str(), callback.host_port1, &recv_sock, &errmsg);
15765
15766 if (status != SS_SUCCESS) {
15767 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());
15768 ss_socket_close(&recv_sock);
15769 //ss_socket_close(&send_sock);
15770 //ss_socket_close(&event_sock);
15771 return RPC_NET_ERROR;
15772 }
15773
15774 status = ss_socket_connect_tcp(callback.host_name.c_str(), callback.host_port2, &send_sock, &errmsg);
15775
15776 if (status != SS_SUCCESS) {
15777 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());
15778 ss_socket_close(&recv_sock);
15779 ss_socket_close(&send_sock);
15780 //ss_socket_close(&event_sock);
15781 return RPC_NET_ERROR;
15782 }
15783
15784 status = ss_socket_connect_tcp(callback.host_name.c_str(), callback.host_port3, &event_sock, &errmsg);
15785
15786 if (status != SS_SUCCESS) {
15787 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());
15788 ss_socket_close(&recv_sock);
15789 ss_socket_close(&send_sock);
15790 ss_socket_close(&event_sock);
15791 return RPC_NET_ERROR;
15792 }
15793#ifndef OS_ULTRIX /* crashes ULTRIX... */
15794 /* increase send buffer size to 2 Mbytes, on Linux also limited by sysctl net.ipv4.tcp_rmem and net.ipv4.tcp_wmem */
15795 flag = 2 * 1024 * 1024;
15796 status = setsockopt(event_sock, SOL_SOCKET, SO_RCVBUF, (char *) &flag, sizeof(INT));
15797 if (status != 0)
15798 cm_msg(MERROR, "rpc_server_callback", "cannot setsockopt(SOL_SOCKET, SO_RCVBUF), errno %d (%s)", errno,
15799 strerror(errno));
15800#endif
15801
15802 if (recv_string(recv_sock, net_buffer, 256, _rpc_connect_timeout) <= 0) {
15803 cm_msg(MERROR, "rpc_server_callback", "timeout on receive remote computer info");
15804 ss_socket_close(&recv_sock);
15805 ss_socket_close(&send_sock);
15806 ss_socket_close(&event_sock);
15807 return RPC_NET_ERROR;
15808 }
15809 //printf("rpc_server_callback: \'%s\'\n", net_buffer);
15810
15811 /* get remote computer info */
15812 client_hw_type = strtoul(net_buffer, &p, 0);
15813
15814 while (*p == ' ')
15815 p++;
15816
15817 client_program = p;
15818
15819 //printf("hw type %d, name \'%s\'\n", client_hw_type, client_program);
15820
15821 std::string host_name;
15822
15823 status = ss_socket_get_peer_name(recv_sock, &host_name, NULL);
15824
15825 if (status != SS_SUCCESS)
15826 host_name = "unknown";
15827
15828 //printf("rpc_server_callback: mserver acception\n");
15829
15831
15832 /* save information in _server_acception structure */
15833 sa->recv_sock = recv_sock;
15834 sa->send_sock = send_sock;
15835 sa->event_sock = event_sock;
15836 sa->remote_hw_type = client_hw_type;
15837 sa->host_name = host_name;
15838 sa->prog_name = client_program;
15840 sa->watchdog_timeout = 0;
15841 sa->is_mserver = TRUE;
15842
15843 assert(_mserver_acception == NULL);
15844
15845 _mserver_acception = sa;
15846
15847 //printf("rpc_server_callback: _mserver_acception %p\n", _mserver_acception);
15848
15849 /* send my own computer id */
15850 hw_type = rpc_get_hw_type();
15851 sprintf(str, "%d", hw_type);
15852 send(recv_sock, str, strlen(str) + 1, 0);
15853
15854 rpc_calc_convert_flags(hw_type, client_hw_type, &convert_flags);
15855 sa->convert_flags = convert_flags;
15856
15858
15859 if (rpc_is_mserver()) {
15860 rpc_debug_printf("Connection to %s:%s established\n", sa->host_name.c_str(), sa->prog_name.c_str());
15861 }
15862
15863 return RPC_SUCCESS;
15864}
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 12406 of file midas.cxx.

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

12750{
12751 static int rpc_server_disconnect_recursion_level = 0;
12752
12753 if (rpc_server_disconnect_recursion_level)
12754 return RPC_SUCCESS;
12755
12756 rpc_server_disconnect_recursion_level = 1;
12757
12758 /* flush remaining events */
12760
12761 /* notify server about exit */
12762 if (rpc_is_connected()) {
12764 }
12765
12766 /* close sockets */
12773
12775
12776 /* remove semaphore */
12777 if (_mutex_rpc)
12779 _mutex_rpc = NULL;
12780
12781 rpc_server_disconnect_recursion_level = 0;
12782 return RPC_SUCCESS;
12783}
INT ss_mutex_delete(MUTEX_T *mutex)
Definition system.cxx:3283
bool rpc_is_connected(void)
Definition midas.cxx:12808
INT rpc_call(DWORD routine_id,...)
Definition midas.cxx:13688
INT rpc_flush_event()
Definition midas.cxx:14063
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 15868 of file midas.cxx.

15876{
15877 while (1) {
15878 int status = ss_suspend(1000, 0);
15879
15880 if (status == SS_ABORT || status == SS_EXIT)
15881 break;
15882
15884 break;
15885
15886 /* check alarms, etc */
15888
15890 }
15891
15892 return RPC_SUCCESS;
15893}
INT rpc_check_channels(void)
Definition midas.cxx:16279
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 16006 of file midas.cxx.

16020{
16021 int status = 0;
16022
16023 DWORD start_time = ss_millitime();
16024
16025 //
16026 // THIS IS NOT THREAD SAFE!!!
16027 //
16028 // IT IS ONLY USED BY THE MSERVER
16029 // MSERVER IS SINGLE-THREADED!!!
16030 //
16031
16032 static char *xbuf = NULL;
16033 static int xbufsize = 0;
16034 static bool xbufempty = true;
16035
16036 // short cut
16037 if (sa == NULL && xbufempty)
16038 return RPC_SUCCESS;
16039
16040 static bool recurse = false;
16041
16042 if (recurse) {
16043 cm_msg(MERROR, "rpc_server_receive_event", "internal error: called recursively");
16044 // do not do anything if we are called recursively
16045 // via recursive ss_suspend() or otherwise. K.O.
16046 if (xbufempty)
16047 return RPC_SUCCESS;
16048 else
16049 return BM_ASYNC_RETURN;
16050 }
16051
16052 recurse = true;
16053
16054 do {
16055 if (xbufempty && sa) {
16056 int n_received = recv_event_server_realloc(idx, sa, &xbuf, &xbufsize);
16057
16058 if (n_received < 0) {
16059 status = SS_ABORT;
16060 cm_msg(MERROR, "rpc_server_receive_event", "recv_event_server_realloc() returned %d, abort", n_received);
16061 goto error;
16062 }
16063
16064 if (n_received == 0) {
16065 // no more data in the tcp socket
16066 recurse = false;
16067 return RPC_SUCCESS;
16068 }
16069
16070 xbufempty = false;
16071 }
16072
16073 if (xbufempty) {
16074 // no event in xbuf buffer
16075 recurse = false;
16076 return RPC_SUCCESS;
16077 }
16078
16079 /* send event to buffer */
16080 INT *pbh = (INT *) xbuf;
16081 EVENT_HEADER *pevent = (EVENT_HEADER *) (pbh + 1);
16082
16083 status = bm_send_event(*pbh, pevent, 0, timeout_msec);
16084
16085 //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);
16086
16087 if (status == SS_ABORT) {
16088 cm_msg(MERROR, "rpc_server_receive_event", "bm_send_event() error %d (SS_ABORT), abort", status);
16089 goto error;
16090 }
16091
16092 if (status == BM_ASYNC_RETURN) {
16093 //cm_msg(MERROR, "rpc_server_receive_event", "bm_send_event() error %d, event buffer is full", status);
16094 recurse = false;
16095 return status;
16096 }
16097
16098 if (status != BM_SUCCESS) {
16099 cm_msg(MERROR, "rpc_server_receive_event", "bm_send_event() error %d, mserver dropped this event", status);
16100 }
16101
16102 xbufempty = true;
16103
16104 /* repeat for maximum 0.5 sec */
16105 } while (ss_millitime() - start_time < 500);
16106
16107 recurse = false;
16108 return RPC_SUCCESS;
16109
16110 error:
16111
16112 {
16113 char str[80];
16114 mstrlcpy(str, sa->host_name.c_str(), sizeof(str));
16115 if (strchr(str, '.'))
16116 *strchr(str, '.') = 0;
16117 cm_msg(MTALK, "rpc_server_receive_event", "Program \'%s\' on host \'%s\' aborted", sa->prog_name.c_str(), str);
16118 }
16119
16120 //exit:
16121
16123
16124 /* disconnect from experiment as MIDAS server */
16125 if (rpc_is_mserver()) {
16126 HNDLE hDB, hKey;
16127
16129
16130 /* only disconnect from experiment if previously connected.
16131 Necessary for pure RPC servers (RPC_SRVR) */
16132 if (hDB) {
16136
16138
16140 }
16141 }
16142
16143 bool is_mserver = sa->is_mserver;
16144
16145 sa->close();
16146
16147 /* signal caller a shutdonw */
16148 if (status == RPC_SHUTDOWN)
16149 return status;
16150
16151 /* only the mserver should stop on server connection closure */
16152 if (!is_mserver) {
16153 return SS_SUCCESS;
16154 }
16155
16156 return status;
16157}
INT bm_close_all_buffers(void)
Definition midas.cxx:7253
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition midas.cxx:3026
INT cm_delete_client_info(HNDLE hDB, INT pid)
Definition midas.cxx:1867
INT cm_set_experiment_database(HNDLE hDB, HNDLE hKeyClient)
Definition midas.cxx:2954
#define MTALK
Definition midas.h:564
INT db_close_all_databases(void)
Definition odb.cxx:2398
static int recv_event_server_realloc(INT idx, RPC_SERVER_ACCEPTION *psa, char **pbuffer, int *pbuffer_size)
Definition midas.cxx:14412
INT rpc_deregister_functions()
Definition midas.cxx:11895
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 15896 of file midas.cxx.

15911{
15912 int status = 0;
15913 int remaining = 0;
15914
15915 char *buf = NULL;
15916 int bufsize = 0;
15917
15918 do {
15919 int n_received = recv_net_command_realloc(idx, &buf, &bufsize, &remaining);
15920
15921 if (n_received <= 0) {
15922 status = SS_ABORT;
15923 cm_msg(MERROR, "rpc_server_receive_rpc", "recv_net_command() returned %d, abort", n_received);
15924 goto error;
15925 }
15926
15927 status = rpc_execute(sa->recv_sock, buf, sa->convert_flags);
15928
15929 if (status == SS_ABORT) {
15930 cm_msg(MERROR, "rpc_server_receive_rpc", "rpc_execute() returned %d, abort", status);
15931 goto error;
15932 }
15933
15934 if (status == SS_EXIT || status == RPC_SHUTDOWN) {
15935 if (rpc_is_mserver())
15936 rpc_debug_printf("Connection to %s:%s closed\n", sa->host_name.c_str(), sa->prog_name.c_str());
15937 goto exit;
15938 }
15939
15940 } while (remaining);
15941
15942 if (buf) {
15943 free(buf);
15944 buf = NULL;
15945 bufsize = 0;
15946 }
15947
15948 return RPC_SUCCESS;
15949
15950 error:
15951
15952 {
15953 char str[80];
15954 mstrlcpy(str, sa->host_name.c_str(), sizeof(str));
15955 if (strchr(str, '.'))
15956 *strchr(str, '.') = 0;
15957 cm_msg(MTALK, "rpc_server_receive_rpc", "Program \'%s\' on host \'%s\' aborted", sa->prog_name.c_str(), str);
15958 }
15959
15960 exit:
15961
15963
15964 if (buf) {
15965 free(buf);
15966 buf = NULL;
15967 bufsize = 0;
15968 }
15969
15970 /* disconnect from experiment as MIDAS server */
15971 if (rpc_is_mserver()) {
15972 HNDLE hDB, hKey;
15973
15975
15976 /* only disconnect from experiment if previously connected.
15977 Necessary for pure RPC servers (RPC_SRVR) */
15978 if (hDB) {
15982
15984
15986 }
15987 }
15988
15989 bool is_mserver = sa->is_mserver;
15990
15991 sa->close();
15992
15993 /* signal caller a shutdonw */
15994 if (status == RPC_SHUTDOWN)
15995 return status;
15996
15997 /* only the mserver should stop on server connection closure */
15998 if (!is_mserver) {
15999 return SS_SUCCESS;
16000 }
16001
16002 return status;
16003}
INT rpc_execute(INT sock, char *buffer, INT convert_flags)
Definition midas.cxx:14675
static int recv_net_command_realloc(INT idx, char **pbuf, int *pbufsize, INT *remaining)
Definition midas.cxx:14222
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 16208 of file midas.cxx.

16225{
16226 //printf("rpc_server_shutdown!\n");
16227
16228 struct linger ling;
16229
16230 /* close all open connections */
16231 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
16232 if (_server_acceptions[idx] && _server_acceptions[idx]->recv_sock != 0) {
16234 /* lingering needed for PCTCP */
16235 ling.l_onoff = 1;
16236 ling.l_linger = 0;
16237 setsockopt(sa->recv_sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
16239
16240 if (sa->send_sock) {
16241 setsockopt(sa->send_sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
16243 }
16244
16245 if (sa->event_sock) {
16246 setsockopt(sa->event_sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
16248 }
16249 }
16250 }
16251
16252 /* avoid memory leak */
16253 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
16255 if (sa) {
16256 //printf("rpc_server_shutdown: %d %p %p\n", idx, sa, _mserver_acception);
16257 if (sa == _mserver_acception) {
16258 // do not leave behind a stale pointer!
16259 _mserver_acception = NULL;
16260 }
16261 delete sa;
16262 _server_acceptions[idx] = NULL;
16263 }
16264 }
16265
16266 if (_rpc_registered) {
16269 }
16270
16271 /* free suspend structures */
16273
16274 return RPC_SUCCESS;
16275}
INT ss_suspend_exit()
Definition system.cxx:4298
static BOOL _rpc_registered
Definition midas.cxx:258
static int _rpc_listen_socket
Definition midas.cxx:259
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_set_debug()

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

Definition at line 13159 of file midas.cxx.

13179{
13180 _debug_print = func;
13181 _debug_mode = mode;
13182 return RPC_SUCCESS;
13183}
Here is the caller graph for this function:

◆ rpc_set_mserver_path()

INT rpc_set_mserver_path ( const char *  path)

Definition at line 13089 of file midas.cxx.

13103{
13104 _mserver_path = path;
13105 return RPC_SUCCESS;
13106}
Here is the caller graph for this function:

◆ rpc_set_name()

INT rpc_set_name ( const char *  name)

Definition at line 13133 of file midas.cxx.

13151{
13153
13154 return RPC_SUCCESS;
13155}
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 13889 of file midas.cxx.

13889 {
13890 INT old;
13891
13892 old = _opt_tcp_size;
13893 _opt_tcp_size = tcp_size;
13894 return old;
13895}
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 13023 of file midas.cxx.

13024{
13025 //printf("rpc_set_timeout: hConn %d, timeout_msec %d\n", hConn, timeout_msec);
13026
13027 if (hConn == RPC_HNDLE_MSERVER) {
13028 if (old_timeout_msec)
13029 *old_timeout_msec = _server_connection.rpc_timeout;
13030 _server_connection.rpc_timeout = timeout_msec;
13031 } else if (hConn == RPC_HNDLE_CONNECT) {
13032 if (old_timeout_msec)
13033 *old_timeout_msec = _rpc_connect_timeout;
13034 _rpc_connect_timeout = timeout_msec;
13035 } else {
13037 if (c) {
13038 if (old_timeout_msec)
13039 *old_timeout_msec = c->rpc_timeout;
13040 c->rpc_timeout = timeout_msec;
13041 c->mutex.unlock();
13042 } else {
13043 if (old_timeout_msec)
13044 *old_timeout_msec = 0;
13045 }
13046 }
13047 return RPC_SUCCESS;
13048}
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 15338 of file midas.cxx.

15339{
15340 std::string hostname;
15341
15342 int status = ss_socket_get_peer_name(sock, &hostname, NULL);
15343
15344 if (status != SS_SUCCESS)
15345 return status;
15346
15347 status = rpc_check_allowed_host(hostname.c_str());
15348
15349 if (status == RPC_SUCCESS)
15350 return RPC_SUCCESS;
15351
15352 static std::atomic_int max_report(10);
15353 if (max_report > 0) {
15354 max_report--;
15355 if (max_report == 0) {
15356 cm_msg(MERROR, "rpc_socket_check_allowed_host", "rejecting connection from unallowed host \'%s\', this message will no longer be reported", hostname.c_str());
15357 } else {
15358 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());
15359 }
15360 }
15361
15362 return RPC_NET_ERROR;
15363}
INT rpc_check_allowed_host(const char *hostname)
Definition midas.cxx:15289
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 15071 of file midas.cxx.

15087{
15088 int status = RPC_SUCCESS;
15089
15090 printf("rpc_test_rpc!\n");
15091
15092 int int_out = 0;
15093 int int_inout = 456;
15094
15095 char string_out[32];
15096 char string2_out[48];
15097
15098 char string_inout[25];
15099 strcpy(string_inout, "string_inout");
15100
15101 KEY struct_in;
15102
15103 struct_in.type = 111;
15104 struct_in.num_values = 222;
15105 strcpy(struct_in.name, "name");
15106 struct_in.last_written = 333;
15107
15108 KEY struct_out;
15109 KEY struct_inout;
15110
15111 struct_inout.type = 111111;
15112 struct_inout.num_values = 222222;
15113 strcpy(struct_inout.name, "name_name");
15114 struct_inout.last_written = 333333;
15115
15116 uint32_t dwordarray_inout[10];
15117 size_t dwordarray_inout_size = sizeof(dwordarray_inout);
15118
15119 for (int i=0; i<10; i++) {
15120 dwordarray_inout[i] = i*10;
15121 }
15122
15123 char array_in[10];
15124
15125 for (size_t i=0; i<sizeof(array_in); i++) {
15126 array_in[i] = 'a' + i;
15127 }
15128
15129 char array_out[16];
15130 size_t array_out_size = sizeof(array_out);
15131
15133 123,
15134 &int_out,
15135 &int_inout,
15136 "test string",
15137 string_out, sizeof(string_out),
15138 string2_out, sizeof(string2_out),
15139 string_inout, sizeof(string_inout),
15140 &struct_in,
15141 &struct_out,
15142 &struct_inout,
15143 dwordarray_inout, &dwordarray_inout_size,
15144 array_in, sizeof(array_in),
15145 array_out, &array_out_size
15146 );
15147
15148 printf("rpc_call(RPC_TEST2) status %d\n", status);
15149
15150 if (int_out != 789) {
15151 printf("int_out mismatch!\n");
15152 status = 0;
15153 }
15154
15155 if (int_inout != 456*2) {
15156 printf("int_inout mismatch!\n");
15157 status = 0;
15158 }
15159
15160 if (strcmp(string_out, "string_out") != 0) {
15161 printf("string_out mismatch [%s] vs [%s]\n", string_out, "string_out");
15162 status = 0;
15163 }
15164
15165 if (strcmp(string2_out, "second string_out") != 0) {
15166 printf("string2_out mismatch [%s] vs [%s]\n", string2_out, "second string_out");
15167 status = 0;
15168 }
15169
15170 if (strcmp(string_inout, "return string_inout") != 0) {
15171 printf("string_inout mismatch [%s] vs [%s]\n", string_inout, "return string_inout");
15172 status = 0;
15173 }
15174
15175 KEY* pkey;
15176
15177 pkey = &struct_in;
15178
15179 //printf("struct_in: type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
15180
15181 pkey = &struct_out;
15182
15183 if (pkey->type != 444 || pkey->num_values != 555 || strcmp(pkey->name, "out_name") || pkey->last_written != 666) {
15184 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);
15185 status = 0;
15186 }
15187
15188 pkey = &struct_inout;
15189
15190 if (pkey->type != 444444 || pkey->num_values != 555555 || strcmp(pkey->name, "inout_name") || pkey->last_written != 666666) {
15191 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);
15192 status = 0;
15193 }
15194
15195#if 0
15196 if (dwordarray_inout_size != 4*5) {
15197 printf("dwordarray_inout_size mismatch %d vs %d\n", (int)dwordarray_inout_size, 4*5);
15198 status = 0;
15199 }
15200
15201 for (size_t i=0; i<dwordarray_inout_size/sizeof(uint32_t); i++) {
15202 printf("dwordarray_inout[%d] is %d\n", (int)i, dwordarray_inout[i]);
15203 }
15204#endif
15205
15206#if 0
15207 {RPC_TEST_CXX, "test_cxx",
15208 {{TID_INT32, RPC_IN},
15209 {TID_INT32, RPC_IN | RPC_OUT | RPC_VARARRAY | RPC_CXX},
15210 {TID_STRING, RPC_IN},
15211 {TID_STRING, RPC_IN | RPC_CXX},
15212 {TID_STRING, RPC_OUT | RPC_CXX},
15213 {TID_STRING, RPC_IN | RPC_OUT | RPC_CXX},
15214 {TID_STRUCT, RPC_IN | RPC_CXX, sizeof(KEY)},
15215 {TID_STRUCT, RPC_OUT | RPC_CXX, sizeof(KEY)},
15216 {TID_STRUCT, RPC_IN | RPC_OUT | RPC_CXX, sizeof(KEY)},
15217 {TID_ARRAY, RPC_IN | RPC_VARARRAY | RPC_CXX},
15218 {TID_ARRAY, RPC_OUT | RPC_VARARRAY | RPC_CXX},
15219 {TID_ARRAY, RPC_IN | RPC_OUT | RPC_VARARRAY | RPC_CXX},
15220 {0}}},
15221#endif
15222
15223#if 0
15224 status = rpc_call(RPC_TEST_CXX, ...);
15225#endif
15226
15227 return status;
15228}
#define RPC_TEST2
Definition mrpc.h:123
Definition midas.h:1027
INT num_values
Definition midas.h:1029
DWORD type
Definition midas.h:1028
INT last_written
Definition midas.h:1038
char name[NAME_LENGTH]
Definition midas.h:1030
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 11789 of file midas.cxx.

11789 {
11790 if (id >= 0 && id < TID_LAST)
11791 return tid_name[id];
11792 else
11793 return "<unknown>";
11794}
Here is the caller graph for this function:

◆ rpc_tid_name_old()

const char * rpc_tid_name_old ( INT  id)

Definition at line 11796 of file midas.cxx.

11796 {
11797 if (id >= 0 && id < TID_LAST)
11798 return tid_name_old[id];
11799 else
11800 return "<unknown>";
11801}
Here is the caller graph for this function:

◆ rpc_tid_size()

INT rpc_tid_size ( INT  id)

Definition at line 11782 of file midas.cxx.

11782 {
11783 if (id >= 0 && id < TID_LAST)
11784 return tid_size[id];
11785
11786 return 0;
11787}
static const int tid_size[]
Definition midas.cxx:66
Here is the caller graph for this function:

◆ rpc_transition_dispatch()

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

Definition at line 14081 of file midas.cxx.

14100{
14101 /* erase error string */
14102 *(CSTRING(2)) = 0;
14103
14104 if (idx == RPC_RC_TRANSITION) {
14105 // find registered handler
14106 // NB: this code should match same code in cm_transition_call_direct()
14107 // NB: only use the first handler, this is how MIDAS always worked
14108 // NB: we could run all handlers, but we can return the status and error string of only one of them.
14109 _trans_table_mutex.lock();
14110 size_t n = _trans_table.size();
14111 _trans_table_mutex.unlock();
14112
14113 for (size_t i = 0; i < n; i++) {
14114 _trans_table_mutex.lock();
14116 _trans_table_mutex.unlock();
14117
14118 if (tt.transition == CINT(0) && tt.sequence_number == CINT(4)) {
14119 if (tt.func) {
14120 /* execute callback if defined */
14121 return tt.func(CINT(1), CSTRING(2));
14122 } else {
14123 std::lock_guard<std::mutex> guard(_tr_fifo_mutex);
14124 /* store transition in FIFO */
14127 _tr_fifo[_tr_fifo_wp].trans_time = time(NULL);
14129 _tr_fifo_wp = (_tr_fifo_wp + 1) % 10;
14130 // implicit unlock
14131 return RPC_SUCCESS;
14132 }
14133 }
14134 }
14135 // no handler for this transition
14136 cm_msg(MERROR, "rpc_transition_dispatch", "no handler for transition %d with sequence number %d", CINT(0), CINT(4));
14137 return CM_SUCCESS;
14138 } else {
14139 cm_msg(MERROR, "rpc_transition_dispatch", "received unrecognized command %d", idx);
14140 return RPC_INVALID_ID;
14141 }
14142}
#define CM_SUCCESS
Definition midas.h:582
#define RPC_RC_TRANSITION
Definition mrpc.h:116
static std::vector< TRANS_TABLE > _trans_table
Definition midas.cxx:248
static std::mutex _trans_table_mutex
Definition midas.cxx:247
#define CINT(_i)
Definition midas.h:1621
#define CSTRING(_i)
Definition midas.h:1645
time_t trans_time
Definition midas.cxx:14072
int sequence_number
Definition midas.cxx:14073
INT sequence_number
Definition midas.cxx:243
INT(* func)(INT, char *)
Definition midas.cxx:244
INT transition
Definition midas.cxx:242
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 13218 of file midas.cxx.

13218 {
13219 switch (arg_type) {
13220 /* On the stack, the minimum parameter size is sizeof(int).
13221 To avoid problems on little endian systems, treat all
13222 smaller parameters as int's */
13223 case TID_UINT8:
13224 case TID_INT8:
13225 case TID_CHAR:
13226 case TID_UINT16:
13227 case TID_INT16:
13228 *((int *) arg) = va_arg(*arg_ptr, int);
13229 break;
13230
13231 case TID_INT32:
13232 case TID_BOOL:
13233 *((INT *) arg) = va_arg(*arg_ptr, INT);
13234 break;
13235
13236 case TID_UINT32:
13237 *((DWORD *) arg) = va_arg(*arg_ptr, DWORD);
13238 break;
13239
13240 /* float variables are passed as double by the compiler */
13241 case TID_FLOAT:
13242 *((float *) arg) = (float) va_arg(*arg_ptr, double);
13243 break;
13244
13245 case TID_DOUBLE:
13246 *((double *) arg) = va_arg(*arg_ptr, double);
13247 break;
13248
13249 case TID_ARRAY:
13250 *((char **) arg) = va_arg(*arg_ptr, char *);
13251 break;
13252 }
13253}
Here is the caller graph for this function:

◆ rpc_vax2ieee_double()

void rpc_vax2ieee_double ( double *  var)

Definition at line 11667 of file midas.cxx.

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

◆ rpc_vax2ieee_float()

void rpc_vax2ieee_float ( float *  var)

Definition at line 11651 of file midas.cxx.

11651 {
11652 unsigned short int lo, hi;
11653
11654 /* swap hi and lo word */
11655 lo = *((short int *) (var) + 1);
11656 hi = *((short int *) (var));
11657
11658 /* correct exponent */
11659 if (hi != 0)
11660 hi -= 0x100;
11661
11662 *((short int *) (var) + 1) = hi;
11663 *((short int *) (var)) = lo;
11664
11665}
Here is the caller graph for this function:

Variable Documentation

◆ _client_connections

std::vector<RPC_CLIENT_CONNECTION*> _client_connections
static

Definition at line 11521 of file midas.cxx.

◆ _client_connections_mutex

std::mutex _client_connections_mutex
static

Definition at line 11520 of file midas.cxx.

◆ _mserver_acception

RPC_SERVER_ACCEPTION* _mserver_acception = NULL
static

Definition at line 11528 of file midas.cxx.

◆ _mserver_path

std::string _mserver_path
static

Definition at line 13073 of file midas.cxx.

◆ _opt_tcp_size

int _opt_tcp_size = OPT_TCP_SIZE
static

Definition at line 11601 of file midas.cxx.

◆ _rpc_is_remote

bool _rpc_is_remote = false
static

Definition at line 11524 of file midas.cxx.

◆ _server_acceptions

std::vector<RPC_SERVER_ACCEPTION*> _server_acceptions
static

Definition at line 11527 of file midas.cxx.

◆ _server_connection

RPC_SERVER_CONNECTION _server_connection
static

Definition at line 11523 of file midas.cxx.

◆ _tr_fifo

TR_FIFO _tr_fifo[10]
static

Definition at line 14077 of file midas.cxx.

◆ _tr_fifo_mutex

std::mutex _tr_fifo_mutex
static

Definition at line 14076 of file midas.cxx.

◆ _tr_fifo_rp

int _tr_fifo_rp = 0
static

Definition at line 14079 of file midas.cxx.

◆ _tr_fifo_wp

int _tr_fifo_wp = 0
static

Definition at line 14078 of file midas.cxx.

◆ gAllowedHosts

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

Definition at line 15231 of file midas.cxx.

◆ gAllowedHostsMutex

std::mutex gAllowedHostsMutex
static

Definition at line 15232 of file midas.cxx.

◆ rpc_list

std::vector<RPC_LIST> rpc_list
static

Definition at line 11598 of file midas.cxx.

◆ rpc_list_mutex

std::mutex rpc_list_mutex
static

Definition at line 11599 of file midas.cxx.

◆ tls_buffer

TLS_POINTER* tls_buffer = NULL
static

Definition at line 14671 of file midas.cxx.

◆ tls_size

int tls_size = 0
static

Definition at line 14672 of file midas.cxx.