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

Classes

class  RPC_CLIENT_CONNECTION
 
struct  TR_FIFO
 
struct  TLS_POINTER
 

Macros

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

Functions

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

Variables

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

Detailed Description

dox dox dox


Macro Definition Documentation

◆ RPC_AL_CHECK

#define RPC_AL_CHECK   11500

Definition at line 113 of file mrpc.h.

◆ RPC_AL_TRIGGER_ALARM

#define RPC_AL_TRIGGER_ALARM   11501

Definition at line 114 of file mrpc.h.

◆ RPC_ANA_CLEAR_HISTOS

#define RPC_ANA_CLEAR_HISTOS   13000

Definition at line 118 of file mrpc.h.

◆ RPC_BM_ADD_EVENT_REQUEST

#define RPC_BM_ADD_EVENT_REQUEST   11107

Definition at line 43 of file mrpc.h.

◆ RPC_BM_CLOSE_ALL_BUFFERS

#define RPC_BM_CLOSE_ALL_BUFFERS   11102

Definition at line 38 of file mrpc.h.

◆ RPC_BM_CLOSE_BUFFER

#define RPC_BM_CLOSE_BUFFER   11101

Definition at line 37 of file mrpc.h.

◆ RPC_BM_EMPTY_BUFFERS

#define RPC_BM_EMPTY_BUFFERS   11113

Definition at line 49 of file mrpc.h.

◆ RPC_BM_FLUSH_CACHE

#define RPC_BM_FLUSH_CACHE   11110

Definition at line 46 of file mrpc.h.

◆ RPC_BM_GET_BUFFER_INFO

#define RPC_BM_GET_BUFFER_INFO   11103

Definition at line 39 of file mrpc.h.

◆ RPC_BM_GET_BUFFER_LEVEL

#define RPC_BM_GET_BUFFER_LEVEL   11104

Definition at line 40 of file mrpc.h.

◆ RPC_BM_INIT_BUFFER_COUNTERS

#define RPC_BM_INIT_BUFFER_COUNTERS   11105

Definition at line 41 of file mrpc.h.

◆ RPC_BM_MARK_READ_WAITING

#define RPC_BM_MARK_READ_WAITING   11112

Definition at line 48 of file mrpc.h.

◆ RPC_BM_OPEN_BUFFER

#define RPC_BM_OPEN_BUFFER   11100

Definition at line 36 of file mrpc.h.

◆ RPC_BM_RECEIVE_EVENT

#define RPC_BM_RECEIVE_EVENT   11111

Definition at line 47 of file mrpc.h.

◆ RPC_BM_REMOVE_EVENT_REQUEST

#define RPC_BM_REMOVE_EVENT_REQUEST   11108

Definition at line 44 of file mrpc.h.

◆ RPC_BM_SEND_EVENT

#define RPC_BM_SEND_EVENT   11109

Definition at line 45 of file mrpc.h.

◆ RPC_BM_SET_CACHE_SIZE

#define RPC_BM_SET_CACHE_SIZE   11106

Definition at line 42 of file mrpc.h.

◆ RPC_BM_SKIP_EVENT

#define RPC_BM_SKIP_EVENT   11114

Definition at line 50 of file mrpc.h.

◆ RPC_BRPC

#define RPC_BRPC   18001

Definition at line 131 of file mrpc.h.

◆ RPC_CM_ASCTIME

#define RPC_CM_ASCTIME   11007

Definition at line 28 of file mrpc.h.

◆ RPC_CM_CHECK_CLIENT

#define RPC_CM_CHECK_CLIENT   11014

Definition at line 34 of file mrpc.h.

◆ RPC_CM_CLEANUP

#define RPC_CM_CLEANUP   11002

Definition at line 23 of file mrpc.h.

◆ RPC_CM_EXECUTE

#define RPC_CM_EXECUTE   11005

Definition at line 26 of file mrpc.h.

◆ RPC_CM_EXIST

#define RPC_CM_EXIST   11011

Definition at line 31 of file mrpc.h.

◆ RPC_CM_GET_WATCHDOG_INFO

#define RPC_CM_GET_WATCHDOG_INFO   11003

Definition at line 24 of file mrpc.h.

◆ RPC_CM_MSG

#define RPC_CM_MSG   11009

Definition at line 30 of file mrpc.h.

◆ RPC_CM_MSG_LOG

#define RPC_CM_MSG_LOG   11004

Definition at line 25 of file mrpc.h.

◆ RPC_CM_MSG_LOG1

#define RPC_CM_MSG_LOG1   11013

Definition at line 33 of file mrpc.h.

◆ RPC_CM_MSG_RETRIEVE

#define RPC_CM_MSG_RETRIEVE   11012

Definition at line 32 of file mrpc.h.

◆ RPC_CM_SET_CLIENT_INFO

#define RPC_CM_SET_CLIENT_INFO   11000

routine IDs for RPC calls

Definition at line 21 of file mrpc.h.

◆ RPC_CM_SET_WATCHDOG_PARAMS

#define RPC_CM_SET_WATCHDOG_PARAMS   11001

Definition at line 22 of file mrpc.h.

◆ RPC_CM_SYNCHRONIZE

#define RPC_CM_SYNCHRONIZE   11006

Definition at line 27 of file mrpc.h.

◆ RPC_CM_TIME

#define RPC_CM_TIME   11008

Definition at line 29 of file mrpc.h.

◆ RPC_CNAF16

#define RPC_CNAF16   16000

Definition at line 125 of file mrpc.h.

◆ RPC_CNAF24

#define RPC_CNAF24   16001

Definition at line 126 of file mrpc.h.

◆ RPC_DB_ADD_OPEN_RECORD

#define RPC_DB_ADD_OPEN_RECORD   11222

Definition at line 72 of file mrpc.h.

◆ RPC_DB_CHECK_RECORD

#define RPC_DB_CHECK_RECORD   11240

Definition at line 89 of file mrpc.h.

◆ RPC_DB_CLOSE_ALL_DATABASES

#define RPC_DB_CLOSE_ALL_DATABASES   11202

Definition at line 54 of file mrpc.h.

◆ RPC_DB_CLOSE_DATABASE

#define RPC_DB_CLOSE_DATABASE   11201

Definition at line 53 of file mrpc.h.

◆ RPC_DB_COPY_XML

#define RPC_DB_COPY_XML   11249

Definition at line 98 of file mrpc.h.

◆ RPC_DB_CREATE_KEY

#define RPC_DB_CREATE_KEY   11203

Definition at line 55 of file mrpc.h.

◆ RPC_DB_CREATE_LINK

#define RPC_DB_CREATE_LINK   11204

Definition at line 56 of file mrpc.h.

◆ RPC_DB_CREATE_RECORD

#define RPC_DB_CREATE_RECORD   11230

Definition at line 80 of file mrpc.h.

◆ RPC_DB_DELETE_KEY

#define RPC_DB_DELETE_KEY   11210

Definition at line 62 of file mrpc.h.

◆ RPC_DB_ENUM_KEY

#define RPC_DB_ENUM_KEY   11211

Definition at line 63 of file mrpc.h.

◆ RPC_DB_ENUM_LINK

#define RPC_DB_ENUM_LINK   11228

Definition at line 78 of file mrpc.h.

◆ RPC_DB_FIND_KEY

#define RPC_DB_FIND_KEY   11207

Definition at line 59 of file mrpc.h.

◆ RPC_DB_FIND_LINK

#define RPC_DB_FIND_LINK   11208

Definition at line 60 of file mrpc.h.

◆ RPC_DB_FLUSH_DATABASE

#define RPC_DB_FLUSH_DATABASE   11235

Definition at line 84 of file mrpc.h.

◆ RPC_DB_GET_DATA

#define RPC_DB_GET_DATA   11213

Definition at line 65 of file mrpc.h.

◆ RPC_DB_GET_DATA1

#define RPC_DB_GET_DATA1   11238

Definition at line 87 of file mrpc.h.

◆ RPC_DB_GET_DATA_INDEX

#define RPC_DB_GET_DATA_INDEX   11231

Definition at line 81 of file mrpc.h.

◆ RPC_DB_GET_KEY

#define RPC_DB_GET_KEY   11212

Definition at line 64 of file mrpc.h.

◆ RPC_DB_GET_KEY_INFO

#define RPC_DB_GET_KEY_INFO   11237

Definition at line 86 of file mrpc.h.

◆ RPC_DB_GET_KEY_TIME

#define RPC_DB_GET_KEY_TIME   11232

Definition at line 82 of file mrpc.h.

◆ RPC_DB_GET_LINK

#define RPC_DB_GET_LINK   11242

Definition at line 91 of file mrpc.h.

◆ RPC_DB_GET_LINK_DATA

#define RPC_DB_GET_LINK_DATA   11243

Definition at line 92 of file mrpc.h.

◆ RPC_DB_GET_NEXT_LINK

#define RPC_DB_GET_NEXT_LINK   11241

Definition at line 90 of file mrpc.h.

◆ RPC_DB_GET_OPEN_RECORDS

#define RPC_DB_GET_OPEN_RECORDS   11233

Definition at line 83 of file mrpc.h.

◆ RPC_DB_GET_PARENT

#define RPC_DB_GET_PARENT   11248

Definition at line 97 of file mrpc.h.

◆ RPC_DB_GET_PATH

#define RPC_DB_GET_PATH   11209

Definition at line 61 of file mrpc.h.

◆ RPC_DB_GET_RECORD

#define RPC_DB_GET_RECORD   11220

Definition at line 70 of file mrpc.h.

◆ RPC_DB_GET_RECORD_SIZE

#define RPC_DB_GET_RECORD_SIZE   11219

Definition at line 69 of file mrpc.h.

◆ RPC_DB_GET_VALUE

#define RPC_DB_GET_VALUE   11206

Definition at line 58 of file mrpc.h.

◆ RPC_DB_LOAD

#define RPC_DB_LOAD   11225

Definition at line 75 of file mrpc.h.

◆ RPC_DB_NOTIFY_CLIENTS_ARRAY

#define RPC_DB_NOTIFY_CLIENTS_ARRAY   11247

Definition at line 96 of file mrpc.h.

◆ RPC_DB_OPEN_DATABASE

#define RPC_DB_OPEN_DATABASE   11200

Definition at line 52 of file mrpc.h.

◆ RPC_DB_REMOVE_OPEN_RECORD

#define RPC_DB_REMOVE_OPEN_RECORD   11223

Definition at line 73 of file mrpc.h.

◆ RPC_DB_RENAME_KEY

#define RPC_DB_RENAME_KEY   11227

Definition at line 77 of file mrpc.h.

◆ RPC_DB_REORDER_KEY

#define RPC_DB_REORDER_KEY   11229

Definition at line 79 of file mrpc.h.

◆ RPC_DB_SAVE

#define RPC_DB_SAVE   11224

Definition at line 74 of file mrpc.h.

◆ RPC_DB_SET_CLIENT_NAME

#define RPC_DB_SET_CLIENT_NAME   11226

Definition at line 76 of file mrpc.h.

◆ RPC_DB_SET_DATA

#define RPC_DB_SET_DATA   11214

Definition at line 66 of file mrpc.h.

◆ RPC_DB_SET_DATA1

#define RPC_DB_SET_DATA1   11246

Definition at line 95 of file mrpc.h.

◆ RPC_DB_SET_DATA_INDEX

#define RPC_DB_SET_DATA_INDEX   11215

Definition at line 67 of file mrpc.h.

◆ RPC_DB_SET_DATA_INDEX1

#define RPC_DB_SET_DATA_INDEX1   11236

Definition at line 85 of file mrpc.h.

◆ RPC_DB_SET_LINK_DATA

#define RPC_DB_SET_LINK_DATA   11244

Definition at line 93 of file mrpc.h.

◆ RPC_DB_SET_LINK_DATA_INDEX

#define RPC_DB_SET_LINK_DATA_INDEX   11245

Definition at line 94 of file mrpc.h.

◆ RPC_DB_SET_MODE

#define RPC_DB_SET_MODE   11216

Definition at line 68 of file mrpc.h.

◆ RPC_DB_SET_NUM_VALUES

#define RPC_DB_SET_NUM_VALUES   11239

Definition at line 88 of file mrpc.h.

◆ RPC_DB_SET_RECORD

#define RPC_DB_SET_RECORD   11221

Definition at line 71 of file mrpc.h.

◆ RPC_DB_SET_VALUE

#define RPC_DB_SET_VALUE   11205

Definition at line 57 of file mrpc.h.

◆ RPC_EL_SUBMIT

#define RPC_EL_SUBMIT   11400

Definition at line 111 of file mrpc.h.

◆ RPC_ID_EXIT

#define RPC_ID_EXIT   99999

Definition at line 135 of file mrpc.h.

◆ RPC_ID_SHUTDOWN

#define RPC_ID_SHUTDOWN   99998

Definition at line 134 of file mrpc.h.

◆ RPC_ID_WATCHDOG

#define RPC_ID_WATCHDOG   99997

Definition at line 133 of file mrpc.h.

◆ RPC_JRPC

#define RPC_JRPC   18000

Definition at line 130 of file mrpc.h.

◆ RPC_LOG_REWIND

#define RPC_LOG_REWIND   14000

Definition at line 120 of file mrpc.h.

◆ RPC_MANUAL_TRIG

#define RPC_MANUAL_TRIG   17000

Definition at line 128 of file mrpc.h.

◆ RPC_RC_TRANSITION

#define RPC_RC_TRANSITION   12000

Definition at line 116 of file mrpc.h.

◆ RPC_TEST

#define RPC_TEST   15000

Definition at line 122 of file mrpc.h.

◆ RPC_TEST2

#define RPC_TEST2   15001

Definition at line 123 of file mrpc.h.

Function Documentation

◆ close()

void RPC_SERVER_ACCEPTION::close ( )

Definition at line 11565 of file midas.cxx.

11566{
11567 //printf("RPC_SERVER_ACCEPTION::close: connection from %s program %s mserver %d\n", host_name.c_str(), prog_name.c_str(), is_mserver);
11568
11569 if (is_mserver) {
11570 assert(_mserver_acception == this);
11572 is_mserver = false;
11573 }
11574
11575 /* close server connection */
11576 if (recv_sock)
11578 if (send_sock)
11580 if (event_sock)
11582
11583 /* free TCP cache */
11584 if (net_buffer) {
11585 //printf("free net_buffer %p+%d\n", net_buffer, net_buffer_size);
11586 free(net_buffer);
11587 net_buffer = NULL;
11588 net_buffer_size = 0;
11589 }
11590
11591 /* mark this entry as invalid */
11592 clear();
11593}
INT ss_socket_close(int *sockp)
Definition system.cxx:5303
static RPC_SERVER_ACCEPTION * _mserver_acception
Definition midas.cxx:11525
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cm_query_transition()

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

Definition at line 14142 of file midas.cxx.

14166{
14167 std::lock_guard<std::mutex> guard(_tr_fifo_mutex);
14168
14169 if (_tr_fifo_wp == _tr_fifo_rp)
14170 return FALSE;
14171
14172 if (transition)
14174
14175 if (run_number)
14177
14178 if (trans_time)
14179 *trans_time = (int) _tr_fifo[_tr_fifo_rp].trans_time;
14180
14181 _tr_fifo_rp = (_tr_fifo_rp + 1) % 10;
14182
14183 // implicit unlock
14184 return TRUE;
14185}
#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:14076
static int _tr_fifo_wp
Definition midas.cxx:14075
static TR_FIFO _tr_fifo[10]
Definition midas.cxx:14074
static std::mutex _tr_fifo_mutex
Definition midas.cxx:14073
INT run_number[2]
Definition mana.cxx:246
#define TRUE
Definition midas.h:182
int transition
Definition midas.cxx:14067
int run_number
Definition midas.cxx:14068
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 11953 of file midas.cxx.

11953 {
11954 //printf("rpc_client_dispatch: MSG_ODB: packet size %d, expected %d\n", n, (int)(sizeof(NET_COMMAND_HEADER) + 4 * sizeof(INT)));
11955 if (n == sizeof(NET_COMMAND_HEADER) + 4 * sizeof(INT)) {
11956 /* update a changed record */
11957 HNDLE hDB = *((INT *) nc->param);
11958 HNDLE hKeyRoot = *((INT *) nc->param + 1);
11959 HNDLE hKey = *((INT *) nc->param + 2);
11960 int index = *((INT *) nc->param + 3);
11962 }
11963 return CM_VERSION_MISMATCH;
11964}
#define CM_VERSION_MISMATCH
Definition midas.h:587
INT db_update_record_local(INT hDB, INT hKeyRoot, INT hKey, int index)
Definition odb.cxx:13562
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 14409 of file midas.cxx.

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

◆ recv_net_command_realloc()

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

Definition at line 14219 of file midas.cxx.

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

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

◆ rpc_add_allowed_host()

INT rpc_add_allowed_host ( const char hostname)

Definition at line 15257 of file midas.cxx.

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

11605 {
11606 *convert_flags = 0;
11607
11608 /* big/little endian conversion */
11609 if (((remote_hw_type & DRI_BIG_ENDIAN) &&
11610 (hw_type & DRI_LITTLE_ENDIAN)) || ((remote_hw_type & DRI_LITTLE_ENDIAN)
11611 && (hw_type & DRI_BIG_ENDIAN)))
11612 *convert_flags |= CF_ENDIAN;
11613
11614 /* float conversion between IEEE and VAX G */
11615 if ((remote_hw_type & DRF_G_FLOAT) && (hw_type & DRF_IEEE))
11616 *convert_flags |= CF_VAX2IEEE;
11617
11618 /* float conversion between VAX G and IEEE */
11619 if ((remote_hw_type & DRF_IEEE) && (hw_type & DRF_G_FLOAT))
11620 *convert_flags |= CF_IEEE2VAX;
11621
11623 //if (remote_hw_type & DR_ASCII)
11624 // *convert_flags |= CF_ASCII;
11625}
#define DRI_LITTLE_ENDIAN
Definition msystem.h:48
#define DRF_G_FLOAT
Definition msystem.h:51
#define DRI_BIG_ENDIAN
Definition msystem.h:49
#define DRF_IEEE
Definition msystem.h:50
#define CF_ENDIAN
Definition midas.h:1609
#define CF_IEEE2VAX
Definition midas.h:1610
#define CF_VAX2IEEE
Definition midas.h:1611
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_call()

INT rpc_call ( DWORD  routine_id,
  ... 
)

Definition at line 13685 of file midas.cxx.

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

◆ rpc_call_decode()

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

Definition at line 13424 of file midas.cxx.

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

◆ rpc_call_encode()

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

Definition at line 13253 of file midas.cxx.

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

◆ rpc_check_allowed_host()

INT rpc_check_allowed_host ( const char hostname)

Definition at line 15286 of file midas.cxx.

15297{
15298 //printf("rpc_check_allowed_host: enabled %d, hostname [%s]\n", gAllowedHostsEnabled.load(), hostname);
15299
15301 return RPC_SUCCESS;
15302
15303 if (strcmp(hostname, "localhost") == 0)
15304 return RPC_SUCCESS;
15305
15306 if (strcmp(hostname, "localhost.localdomain") == 0)
15307 return RPC_SUCCESS;
15308
15309 if (strcmp(hostname, "localhost6") == 0) // RedHat el6, el7
15310 return RPC_SUCCESS;
15311
15312 if (strcmp(hostname, "ip6-localhost") == 0) // Ubuntu-22
15313 return RPC_SUCCESS;
15314
15316
15317 gAllowedHostsMutex.lock();
15318
15319 for (const auto& h: gAllowedHosts) {
15320 if (h == hostname) {
15322 break;
15323 }
15324 }
15325
15326 gAllowedHostsMutex.unlock();
15327
15328 //if (status != RPC_SUCCESS)
15329 // printf("rpc_check_allowed_host: enabled %d, hostname [%s] not found\n", gAllowedHostsEnabled.load(), hostname);
15330
15331 return status;
15332}
#define RPC_NOT_REGISTERED
Definition midas.h:704
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_check_channels()

INT rpc_check_channels ( void  )

Definition at line 16276 of file midas.cxx.

16294{
16295 INT status;
16296 NET_COMMAND nc;
16298 struct timeval timeout;
16299
16300 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
16301 if (_server_acceptions[idx] && _server_acceptions[idx]->recv_sock) {
16303 if (sa == NULL)
16304 continue;
16305
16306 if (sa->watchdog_timeout == 0) {
16307 continue;
16308 }
16309
16311 //printf("rpc_check_channels: idx %d, watchdog_timeout %d, last_activity %d, elapsed %d\n", idx, sa->watchdog_timeout, sa->last_activity, elapsed);
16312
16313 if (sa->watchdog_timeout && (elapsed > (DWORD)sa->watchdog_timeout)) {
16314
16315 //printf("rpc_check_channels: send watchdog message to %s on %s\n", sa->prog_name.c_str(), sa->host_name.c_str());
16316
16317 /* send a watchdog message */
16319 nc.header.param_size = 0;
16320
16321 int convert_flags = sa->convert_flags;
16322 if (convert_flags) {
16325 }
16326
16327 /* send the header to the client */
16328 int i = send_tcp(sa->send_sock, (char *) &nc, sizeof(NET_COMMAND_HEADER), 0);
16329
16330 if (i < 0) {
16331 cm_msg(MINFO, "rpc_check_channels", "client \"%s\" on host \"%s\" failed watchdog test after %d sec, send_tcp() returned %d",
16332 sa->prog_name.c_str(),
16333 sa->host_name.c_str(),
16334 sa->watchdog_timeout / 1000,
16335 i);
16336
16337 /* disconnect from experiment */
16338 if (rpc_is_mserver()) {
16340 return RPC_NET_ERROR;
16341 }
16342
16343 sa->close();
16344 return RPC_NET_ERROR;
16345 }
16346
16347 /* make some timeout checking */
16348 FD_ZERO(&readfds);
16349 FD_SET(sa->send_sock, &readfds);
16350 FD_SET(sa->recv_sock, &readfds);
16351
16352 timeout.tv_sec = sa->watchdog_timeout / 1000;
16353 timeout.tv_usec = (sa->watchdog_timeout % 1000) * 1000;
16354
16355 do {
16356 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
16357
16358 /* if an alarm signal was cought, restart select with reduced timeout */
16359 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
16360 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
16361
16362 } while (status == -1); /* dont return if an alarm signal was cought */
16363
16364 if (!FD_ISSET(sa->send_sock, &readfds) &&
16365 !FD_ISSET(sa->recv_sock, &readfds)) {
16366
16367 cm_msg(MINFO, "rpc_check_channels", "client \"%s\" on host \"%s\" failed watchdog test after %d sec",
16368 sa->prog_name.c_str(),
16369 sa->host_name.c_str(),
16370 sa->watchdog_timeout / 1000);
16371
16372 /* disconnect from experiment */
16373 if (rpc_is_mserver()) {
16375 return RPC_NET_ERROR;
16376 }
16377
16378 sa->close();
16379 return RPC_NET_ERROR;
16380 }
16381
16382 /* receive result on send socket */
16383 if (FD_ISSET(sa->send_sock, &readfds)) {
16384 i = recv_tcp(sa->send_sock, (char *) &nc, sizeof(nc), 0);
16385 if (i <= 0) {
16386 cm_msg(MINFO, "rpc_check_channels", "client \"%s\" on host \"%s\" failed watchdog test after %d sec, recv_tcp() returned %d",
16387 sa->prog_name.c_str(),
16388 sa->host_name.c_str(),
16389 sa->watchdog_timeout / 1000,
16390 i);
16391
16392 /* disconnect from experiment */
16393 if (rpc_is_mserver()) {
16395 return RPC_NET_ERROR;
16396 }
16397
16398 sa->close();
16399 return RPC_NET_ERROR;
16400 }
16401 }
16402 }
16403 }
16404 }
16405
16406 return RPC_SUCCESS;
16407}
INT cm_disconnect_experiment(void)
Definition midas.cxx:2860
#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
bool rpc_is_mserver(void)
Definition midas.cxx:12840
#define RPC_OUTGOING
Definition midas.h:1583
#define WATCHDOG_INTERVAL
Definition midas.h:288
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_clear_allowed_hosts()

INT rpc_clear_allowed_hosts ( void  )

Definition at line 15232 of file midas.cxx.

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

15641{
15642 INT i, status;
15644 std::string client_program;
15645 std::string host_name;
15646 INT convert_flags;
15647 char net_buffer[256], *p;
15648
15649 int sock = accept(lsock, NULL, NULL);
15650
15651 if (sock == -1)
15652 return RPC_NET_ERROR;
15653
15654 /* check access control list */
15657
15658 if (status != RPC_SUCCESS) {
15659 ss_socket_close(&sock);
15660 return RPC_NET_ERROR;
15661 }
15662 }
15663
15664 host_name = "(unknown)";
15665 client_program = "(unknown)";
15666
15667 /* receive string with timeout */
15668 i = recv_string(sock, net_buffer, sizeof(net_buffer), 10000);
15669 if (i <= 0) {
15670 ss_socket_close(&sock);
15671 return RPC_NET_ERROR;
15672 }
15673
15674 /* get remote computer info */
15675 p = strtok(net_buffer, " ");
15676 if (p != NULL) {
15677 client_hw_type = atoi(p);
15678 p = strtok(NULL, " ");
15679 }
15680 if (p != NULL) {
15681 //version = atoi(p);
15682 p = strtok(NULL, " ");
15683 }
15684 if (p != NULL) {
15685 client_program = p;
15686 p = strtok(NULL, " ");
15687 }
15688 if (p != NULL) {
15689 host_name = p;
15690 p = strtok(NULL, " ");
15691 }
15692
15693 //printf("rpc_client_accept: client_hw_type %d, version %d, client_name \'%s\', hostname \'%s\'\n", client_hw_type, version, client_program, host_name);
15694
15696
15697 /* save information in _server_acception structure */
15698 sa->recv_sock = sock;
15699 sa->send_sock = 0;
15700 sa->event_sock = 0;
15702 sa->host_name = host_name;
15705 sa->watchdog_timeout = 0;
15706 sa->is_mserver = FALSE;
15707
15708 /* send my own computer id */
15710 std::string str = msprintf("%d %s", hw_type, cm_get_version());
15711 status = send(sock, str.c_str(), str.length() + 1, 0);
15712 if (status != (INT) str.length() + 1)
15713 return RPC_NET_ERROR;
15714
15716 sa->convert_flags = convert_flags;
15717
15719
15720 return RPC_SUCCESS;
15721}
const char * cm_get_version()
Definition midas.cxx:1490
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:11605
static RPC_SERVER_ACCEPTION * rpc_new_server_acception()
Definition midas.cxx:11540
static INT rpc_socket_check_allowed_host(int sock)
Definition midas.cxx:15335
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 13494 of file midas.cxx.

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

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

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

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

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

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

11703 {
11704
11705 if (convert_flags & CF_ENDIAN) {
11706 if (tid == TID_UINT16 || tid == TID_INT16) WORD_SWAP(data);
11707 if (tid == TID_UINT32 || tid == TID_INT32 || tid == TID_BOOL || tid == TID_FLOAT) DWORD_SWAP(data);
11708 if (tid == TID_DOUBLE) QWORD_SWAP(data);
11709 }
11710
11711 if (((convert_flags & CF_IEEE2VAX) && !(flags & RPC_OUTGOING)) ||
11712 ((convert_flags & CF_VAX2IEEE) && (flags & RPC_OUTGOING))) {
11713 if (tid == TID_FLOAT)
11714 rpc_ieee2vax_float((float *) data);
11715 if (tid == TID_DOUBLE)
11716 rpc_ieee2vax_double((double *) data);
11717 }
11718
11719 if (((convert_flags & CF_IEEE2VAX) && (flags & RPC_OUTGOING)) ||
11720 ((convert_flags & CF_VAX2IEEE) && !(flags & RPC_OUTGOING))) {
11721 if (tid == TID_FLOAT)
11722 rpc_vax2ieee_float((float *) data);
11723 if (tid == TID_DOUBLE)
11724 rpc_vax2ieee_double((double *) data);
11725 }
11726}
#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:11648
void rpc_ieee2vax_float(float *var)
Definition midas.cxx:11633
void rpc_ieee2vax_double(double *var)
Definition midas.cxx:11683
void rpc_vax2ieee_double(double *var)
Definition midas.cxx:11664
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 13183 of file midas.cxx.

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

◆ rpc_deregister_functions()

INT rpc_deregister_functions ( void  )

dox

Definition at line 11892 of file midas.cxx.

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

◆ rpc_execute()

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

Definition at line 14672 of file midas.cxx.

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

14060 {
14061 return RPC_SUCCESS;
14062}
Here is the caller graph for this function:

◆ rpc_flush_event_socket()

int rpc_flush_event_socket ( int  timeout_msec)

Definition at line 16158 of file midas.cxx.

16172{
16174
16175 //printf("ss_event_socket_has_data() returned %d\n", has_data);
16176
16177 if (has_data) {
16178 if (timeout_msec == BM_NO_WAIT) {
16179 return BM_ASYNC_RETURN;
16180 } else if (timeout_msec == BM_WAIT) {
16181 return BM_ASYNC_RETURN;
16182 } else {
16184 if (status == SS_ABORT || status == SS_EXIT)
16185 return status;
16186 return BM_ASYNC_RETURN;
16187 }
16188 }
16189
16191
16192 //printf("rpc_server_receive_event() status %d\n", status);
16193
16194 if (status == BM_ASYNC_RETURN) {
16195 return BM_ASYNC_RETURN;
16196 }
16197
16198 if (status == SS_ABORT || status == SS_EXIT)
16199 return status;
16200
16201 return BM_SUCCESS;
16202}
#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:16003
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 11628 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 13052 of file midas.cxx.

13063{
13066 else
13067 return 0;
13068}
Here is the caller graph for this function:

◆ rpc_get_hw_type()

INT rpc_get_hw_type ( )

Definition at line 12856 of file midas.cxx.

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

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

◆ rpc_get_mserver_acception()

RPC_SERVER_ACCEPTION * rpc_get_mserver_acception ( void  )

Definition at line 11535 of file midas.cxx.

11536{
11537 return _mserver_acception;
11538}
Here is the caller graph for this function:

◆ rpc_get_mserver_hostname()

std::string rpc_get_mserver_hostname ( void  )

Definition at line 12827 of file midas.cxx.

12835{
12837}
Here is the caller graph for this function:

◆ rpc_get_mserver_path()

const char * rpc_get_mserver_path ( void  )

Definition at line 13073 of file midas.cxx.

13081{
13082 return _mserver_path.c_str();
13083}
static std::string _mserver_path
Definition midas.cxx:13070
Here is the caller graph for this function:

◆ rpc_get_name()

std::string rpc_get_name ( )

Definition at line 13106 of file midas.cxx.

13124{
13125 return _client_name;
13126}
Here is the caller graph for this function:

◆ rpc_get_opt_tcp_size()

INT rpc_get_opt_tcp_size ( void  )

Definition at line 13894 of file midas.cxx.

13894 {
13895 return _opt_tcp_size;
13896}
static int _opt_tcp_size
Definition midas.cxx:11598

◆ rpc_get_server_acception()

static RPC_SERVER_ACCEPTION * rpc_get_server_acception ( int  idx)
static

Definition at line 11527 of file midas.cxx.

11528{
11529 assert(idx >= 0);
11530 assert(idx < (int)_server_acceptions.size());
11531 assert(_server_acceptions[idx] != NULL);
11532 return _server_acceptions[idx];
11533}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_get_timeout()

INT rpc_get_timeout ( HNDLE  hConn)

dox Set RPC option

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

Definition at line 12995 of file midas.cxx.

12996{
12997 if (hConn == RPC_HNDLE_MSERVER) {
12999 } else if (hConn == RPC_HNDLE_CONNECT) {
13000 return _rpc_connect_timeout;
13001 } else {
13003 if (c) {
13004 int timeout = c->rpc_timeout;
13005 c->mutex.unlock();
13006 return timeout;
13007 }
13008 }
13009 return 0;
13010}
#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 11683 of file midas.cxx.

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

◆ rpc_ieee2vax_float()

void rpc_ieee2vax_float ( float var)

Definition at line 11633 of file midas.cxx.

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

◆ rpc_is_connected()

bool rpc_is_connected ( void  )

Definition at line 12805 of file midas.cxx.

12822{
12823 return _server_connection.send_sock != 0;
12824}
Here is the caller graph for this function:

◆ rpc_is_mserver()

bool rpc_is_mserver ( void  )

Definition at line 12840 of file midas.cxx.

12851{
12852 return _mserver_acception != NULL;
12853}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_is_remote()

bool rpc_is_remote ( void  )

Definition at line 12783 of file midas.cxx.

12800{
12801 return _rpc_is_remote;
12802}
static bool _rpc_is_remote
Definition midas.cxx:11521

◆ rpc_name_tid()

int rpc_name_tid ( const char name)

Definition at line 11800 of file midas.cxx.

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

◆ rpc_new_server_acception()

static RPC_SERVER_ACCEPTION * rpc_new_server_acception ( )
static

Definition at line 11540 of file midas.cxx.

11541{
11542 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
11543 if (_server_acceptions[idx] && (_server_acceptions[idx]->recv_sock == 0)) {
11544 //printf("rpc_new_server_acception: reuse acception in slot %d\n", idx);
11545 return _server_acceptions[idx];
11546 }
11547 }
11548
11550
11551 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
11552 if (_server_acceptions[idx] == NULL) {
11553 //printf("rpc_new_server_acception: new acception, reuse slot %d\n", idx);
11554 _server_acceptions[idx] = sa;
11555 return _server_acceptions[idx];
11556 }
11557 }
11558
11559 //printf("rpc_new_server_acception: new acception, array size %d, push_back\n", (int)_server_acceptions.size());
11560 _server_acceptions.push_back(sa);
11561
11562 return sa;
11563}
struct rpc_server_acception_struct RPC_SERVER_ACCEPTION
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_register_client()

INT rpc_register_client ( const char name,
RPC_LIST list 
)

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

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

Definition at line 11830 of file midas.cxx.

11830 {
11834
11835 return RPC_SUCCESS;
11836}
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:11849
INT rpc_set_name(const char *name)
Definition midas.cxx:13130
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 11919 of file midas.cxx.

11938{
11939 std::lock_guard<std::mutex> guard(rpc_list_mutex);
11940
11941 for (size_t i = 0; i < rpc_list.size(); i++) {
11942 if (rpc_list[i].id == id) {
11943 rpc_list[i].dispatch = func;
11944 return RPC_SUCCESS;
11945 }
11946 }
11947
11948 return RPC_INVALID_ID;
11949}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_register_functions()

INT rpc_register_functions ( const RPC_LIST new_list,
RPC_HANDLER  func 
)

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

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

Definition at line 11849 of file midas.cxx.

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

◆ rpc_register_listener()

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

Definition at line 14601 of file midas.cxx.

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

14582{
14583 int status;
14584 int lsock;
14585
14587 if (status != RPC_SUCCESS)
14588 return status;
14589
14591 if (status != SS_SUCCESS)
14592 return status;
14593
14594 if (plsock)
14595 *plsock = lsock;
14596
14597 return RPC_SUCCESS;
14598}
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:14601
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 13923 of file midas.cxx.

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

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

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

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

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

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

12747{
12749
12751 return RPC_SUCCESS;
12752
12754
12755 /* flush remaining events */
12757
12758 /* notify server about exit */
12759 if (rpc_is_connected()) {
12761 }
12762
12763 /* close sockets */
12770
12772
12773 /* remove semaphore */
12774 if (_mutex_rpc)
12776 _mutex_rpc = NULL;
12777
12779 return RPC_SUCCESS;
12780}
INT ss_mutex_delete(MUTEX_T *mutex)
Definition system.cxx:3283
bool rpc_is_connected(void)
Definition midas.cxx:12805
INT rpc_call(DWORD routine_id,...)
Definition midas.cxx:13685
INT rpc_flush_event()
Definition midas.cxx:14060
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 15865 of file midas.cxx.

15873{
15874 while (1) {
15875 int status = ss_suspend(1000, 0);
15876
15877 if (status == SS_ABORT || status == SS_EXIT)
15878 break;
15879
15881 break;
15882
15883 /* check alarms, etc */
15885
15887 }
15888
15889 return RPC_SUCCESS;
15890}
INT cm_periodic_tasks()
Definition midas.cxx:5601
INT cm_msg_flush_buffer()
Definition midas.cxx:879
INT rpc_check_channels(void)
Definition midas.cxx:16276
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 16003 of file midas.cxx.

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

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

16222{
16223 //printf("rpc_server_shutdown!\n");
16224
16225 struct linger ling;
16226
16227 /* close all open connections */
16228 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
16229 if (_server_acceptions[idx] && _server_acceptions[idx]->recv_sock != 0) {
16231 /* lingering needed for PCTCP */
16232 ling.l_onoff = 1;
16233 ling.l_linger = 0;
16234 setsockopt(sa->recv_sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
16236
16237 if (sa->send_sock) {
16238 setsockopt(sa->send_sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
16240 }
16241
16242 if (sa->event_sock) {
16243 setsockopt(sa->event_sock, SOL_SOCKET, SO_LINGER, (char *) &ling, sizeof(ling));
16245 }
16246 }
16247 }
16248
16249 /* avoid memory leak */
16250 for (unsigned idx = 0; idx < _server_acceptions.size(); idx++) {
16252 if (sa) {
16253 //printf("rpc_server_shutdown: %d %p %p\n", idx, sa, _mserver_acception);
16254 if (sa == _mserver_acception) {
16255 // do not leave behind a stale pointer!
16257 }
16258 delete sa;
16260 }
16261 }
16262
16263 if (_rpc_registered) {
16266 }
16267
16268 /* free suspend structures */
16270
16271 return RPC_SUCCESS;
16272}
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 13156 of file midas.cxx.

13176{
13177 _debug_print = func;
13178 _debug_mode = mode;
13179 return RPC_SUCCESS;
13180}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_set_mserver_path()

INT rpc_set_mserver_path ( const char path)

Definition at line 13086 of file midas.cxx.

13100{
13101 _mserver_path = path;
13102 return RPC_SUCCESS;
13103}
Here is the caller graph for this function:

◆ rpc_set_name()

INT rpc_set_name ( const char name)

Definition at line 13130 of file midas.cxx.

13148{
13150
13151 return RPC_SUCCESS;
13152}
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 13886 of file midas.cxx.

13886 {
13887 INT old;
13888
13891 return old;
13892}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_set_timeout()

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

Set RPC timeout

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

Definition at line 13020 of file midas.cxx.

13021{
13022 //printf("rpc_set_timeout: hConn %d, timeout_msec %d\n", hConn, timeout_msec);
13023
13024 if (hConn == RPC_HNDLE_MSERVER) {
13025 if (old_timeout_msec)
13028 } else if (hConn == RPC_HNDLE_CONNECT) {
13029 if (old_timeout_msec)
13032 } else {
13034 if (c) {
13035 if (old_timeout_msec)
13036 *old_timeout_msec = c->rpc_timeout;
13037 c->rpc_timeout = timeout_msec;
13038 c->mutex.unlock();
13039 } else {
13040 if (old_timeout_msec)
13041 *old_timeout_msec = 0;
13042 }
13043 }
13044 return RPC_SUCCESS;
13045}
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 15335 of file midas.cxx.

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

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

◆ rpc_tid_name()

const char * rpc_tid_name ( INT  id)

Definition at line 11786 of file midas.cxx.

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

◆ rpc_tid_name_old()

const char * rpc_tid_name_old ( INT  id)

Definition at line 11793 of file midas.cxx.

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

◆ rpc_tid_size()

INT rpc_tid_size ( INT  id)

Definition at line 11779 of file midas.cxx.

11779 {
11780 if (id >= 0 && id < TID_LAST)
11781 return tid_size[id];
11782
11783 return 0;
11784}
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 14078 of file midas.cxx.

14097{
14098 /* erase error string */
14099 *(CSTRING(2)) = 0;
14100
14101 if (idx == RPC_RC_TRANSITION) {
14102 // find registered handler
14103 // NB: this code should match same code in cm_transition_call_direct()
14104 // NB: only use the first handler, this is how MIDAS always worked
14105 // NB: we could run all handlers, but we can return the status and error string of only one of them.
14106 _trans_table_mutex.lock();
14107 size_t n = _trans_table.size();
14108 _trans_table_mutex.unlock();
14109
14110 for (size_t i = 0; i < n; i++) {
14111 _trans_table_mutex.lock();
14113 _trans_table_mutex.unlock();
14114
14115 if (tt.transition == CINT(0) && tt.sequence_number == CINT(4)) {
14116 if (tt.func) {
14117 /* execute callback if defined */
14118 return tt.func(CINT(1), CSTRING(2));
14119 } else {
14120 std::lock_guard<std::mutex> guard(_tr_fifo_mutex);
14121 /* store transition in FIFO */
14126 _tr_fifo_wp = (_tr_fifo_wp + 1) % 10;
14127 // implicit unlock
14128 return RPC_SUCCESS;
14129 }
14130 }
14131 }
14132 // no handler for this transition
14133 cm_msg(MERROR, "rpc_transition_dispatch", "no handler for transition %d with sequence number %d", CINT(0), CINT(4));
14134 return CM_SUCCESS;
14135 } else {
14136 cm_msg(MERROR, "rpc_transition_dispatch", "received unrecognized command %d", idx);
14137 return RPC_INVALID_ID;
14138 }
14139}
#define CM_SUCCESS
Definition midas.h:582
#define RPC_RC_TRANSITION
Definition mrpc.h:116
static std::vector< TRANS_TABLE > _trans_table
Definition midas.cxx:248
static std::mutex _trans_table_mutex
Definition midas.cxx:247
#define CINT(_i)
Definition midas.h:1620
#define CSTRING(_i)
Definition midas.h:1644
time_t trans_time
Definition midas.cxx:14069
int sequence_number
Definition midas.cxx:14070
INT(* func)(INT, char *)
Definition midas.cxx:244
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rpc_va_arg()

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

Definition at line 13215 of file midas.cxx.

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

◆ rpc_vax2ieee_double()

void rpc_vax2ieee_double ( double var)

Definition at line 11664 of file midas.cxx.

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

◆ rpc_vax2ieee_float()

void rpc_vax2ieee_float ( float var)

Definition at line 11648 of file midas.cxx.

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

Variable Documentation

◆ _client_connections

std::vector<RPC_CLIENT_CONNECTION*> _client_connections
static

Definition at line 11518 of file midas.cxx.

◆ _client_connections_mutex

std::mutex _client_connections_mutex
static

Definition at line 11517 of file midas.cxx.

◆ _mserver_acception

RPC_SERVER_ACCEPTION* _mserver_acception = NULL
static

Definition at line 11525 of file midas.cxx.

◆ _mserver_path

std::string _mserver_path
static

Definition at line 13070 of file midas.cxx.

◆ _opt_tcp_size

int _opt_tcp_size = OPT_TCP_SIZE
static

Definition at line 11598 of file midas.cxx.

◆ _rpc_is_remote

bool _rpc_is_remote = false
static

Definition at line 11521 of file midas.cxx.

◆ _server_acceptions

std::vector<RPC_SERVER_ACCEPTION*> _server_acceptions
static

Definition at line 11524 of file midas.cxx.

◆ _server_connection

RPC_SERVER_CONNECTION _server_connection
static

Definition at line 11520 of file midas.cxx.

◆ _tr_fifo

TR_FIFO _tr_fifo[10]
static

Definition at line 14074 of file midas.cxx.

◆ _tr_fifo_mutex

std::mutex _tr_fifo_mutex
static

Definition at line 14073 of file midas.cxx.

◆ _tr_fifo_rp

int _tr_fifo_rp = 0
static

Definition at line 14076 of file midas.cxx.

◆ _tr_fifo_wp

int _tr_fifo_wp = 0
static

Definition at line 14075 of file midas.cxx.

◆ gAllowedHosts

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

Definition at line 15228 of file midas.cxx.

◆ gAllowedHostsMutex

std::mutex gAllowedHostsMutex
static

Definition at line 15229 of file midas.cxx.

◆ rpc_list

std::vector<RPC_LIST> rpc_list
static

Definition at line 11595 of file midas.cxx.

◆ rpc_list_mutex

std::mutex rpc_list_mutex
static

Definition at line 11596 of file midas.cxx.

◆ tls_buffer

TLS_POINTER* tls_buffer = NULL
static

Definition at line 14668 of file midas.cxx.

◆ tls_size

int tls_size = 0
static

Definition at line 14669 of file midas.cxx.