Annotation of libaitrpc/inc/aitrpc.h, revision 1.1.1.1.2.7
1.1 misho 1: /*************************************************************************
2: * (C) 2010 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
3: * by Michael Pounov <misho@openbsd-bg.org>
4: *
5: * $Author: misho $
1.1.1.1.2.7! misho 6: * $Id: aitrpc.h,v 1.1.1.1.2.6 2010/06/23 15:07:15 misho Exp $
1.1 misho 7: *
8: *************************************************************************/
9: #ifndef __AITRPC_H
10: #define __AITRPC_H
11:
12:
13: #include <assert.h>
14: #include <stdlib.h>
15: #include <string.h>
16: #include <sys/types.h>
17: #include <sys/param.h>
18: #include <sys/limits.h>
19: #include <sys/socket.h>
20:
21:
22: #define RPC_VERSION 1
23: #define RPC_DEFPORT 2611
24:
25:
26: /* RPC builtin registed calls */
27:
1.1.1.1.2.5 misho 28: #define CALL_BLOBSHUTDOWN "rpcBLOBServerShutdown"
29: #define CALL_BLOBCLIENTS "rpcBLOBServerClients"
30: #define CALL_BLOBVARS "rpcBLOBServerVars"
31:
1.1.1.1.2.1 misho 32: #define CALL_SRVSHUTDOWN "rpcServerShutdown"
1.1 misho 33: #define CALL_SRVCLIENTS "rpcServerClients"
34: #define CALL_SRVCALLS "rpcServerCalls"
35: #define CALL_SRVSESSIONS "rpcServerSessions"
36:
37:
38: /* RPC types */
39:
40: typedef enum {
41: empty, // empty -> variable is not set
1.1.1.1.2.3 misho 42: buffer, string, blob, // buffer -> uint8_t*; string -> int8_t*; blob -> void*(+socket);
1.1 misho 43: size, offset, datetime, // size -> size_t; offset -> off_t; datetime -> time_t;
44: real, bigreal, // real -> float; bigreal -> double;
45: u8, u16, u32, u64, // unsigned integers ...
46: i8, i16, i32, i64 // integers ...
47: } rpc_type_t;
48:
1.1.1.1.2.6 misho 49: typedef enum {
50: disable, enable,
51: get, set, unset
52: } cmd_type_t;
53:
1.1 misho 54: /* RPC value */
55:
56: typedef struct {
57: rpc_type_t val_type;
58: size_t val_len;
59: union {
60: uint8_t *buffer;
61: int8_t *string;
1.1.1.1.2.3 misho 62: void *blob;
1.1 misho 63: size_t size;
64: off_t offset;
65: time_t datetime;
66: float real;
67: double bigreal;
68: uint8_t u8;
69: uint16_t u16;
70: uint32_t u32;
71: uint64_t u64;
72: int8_t i8;
73: int16_t i16;
74: int32_t i32;
75: int64_t i64;
76: } val;
77: } __packed rpc_val_t;
78:
79: #define RPC_TYPE_VAL(vl) ((vl)->val_type)
80: #define RPC_LEN_VAL(vl) ((vl)->val_len)
1.1.1.1.2.3 misho 81: #define RPC_BLOB_CHUNKS(vl, n) ((vl)->val_len / (n) + ((vl)->val_len % (n)) ? 1 : 0)
1.1 misho 82: #define RPC_EMPTY_VAL(vl) ((vl)->val_type == empty)
83:
84: #define RPC_GET_BUF(vl) (assert((vl)->val_type == buffer), (vl)->val.buffer)
85: #define RPC_GET_STR(vl) (assert((vl)->val_type == string), (vl)->val.string)
1.1.1.1.2.3 misho 86: #define RPC_GET_BLOB(vl) (assert((vl)->val_type == blob), (vl)->val.blob)
1.1 misho 87: #define RPC_GET_SIZE(vl) (assert((vl)->val_type == size), (vl)->val.size)
88: #define RPC_GET_OFF(vl) (assert((vl)->val_type == offset), (vl)->val.offset)
89: #define RPC_GET_TIME(vl) (assert((vl)->val_type == datetime), (vl)->val.datetime)
90: #define RPC_GET_REAL(vl) (assert((vl)->val_type == real), (vl)->val.real)
91: #define RPC_GET_BREAL(vl) (assert((vl)->val_type == bigreal), (vl)->val.bigreal)
92: #define RPC_GET_U8(vl) (assert((vl)->val_type == u8), (vl)->val.u8)
93: #define RPC_GET_U16(vl) (assert((vl)->val_type == u16), (vl)->val.u16)
94: #define RPC_GET_U32(vl) (assert((vl)->val_type == u32), (vl)->val.u32)
95: #define RPC_GET_U64(vl) (assert((vl)->val_type == u64), (vl)->val.u64)
96: #define RPC_GET_I8(vl) (assert((vl)->val_type == i8), (vl)->val.i8)
97: #define RPC_GET_I16(vl) (assert((vl)->val_type == i16), (vl)->val.i16)
98: #define RPC_GET_I32(vl) (assert((vl)->val_type == i32), (vl)->val.i32)
99: #define RPC_GET_I64(vl) (assert((vl)->val_type == i64), (vl)->val.i64)
100:
101: #define RPC_SET_BUF(vl, v, l) do { rpc_val_t *val = (vl); assert(val); val->val.buffer = malloc(l); \
102: if (val->val.buffer) { \
103: val->val_type = buffer; val->val_len = l; \
104: memcpy(val->val.buffer, v, l); \
105: } } while (0)
106: #define RPC_SET_STR(vl, v) do { rpc_val_t *val = (vl); assert(val); val->val.string = (int8_t*) strdup(v); \
107: if (val->val.string) { \
108: val->val_type = string; val->val_len = strlen(v) + 1; \
109: } } while (0)
1.1.1.1.2.3 misho 110: #define RPC_SET_BLOB(vl, v, l) do { rpc_val_t *val = (vl); assert(val); val->val.blob = realloc(val->val.blob, l); \
111: if (val->val.blob) { \
112: val->val_type = blob; val->val_len = l; \
113: memcpy(val->val.blob, v, l); \
1.1 misho 114: } } while (0)
115: #define RPC_SET_SIZE(vl, v) do { rpc_val_t *val = (vl); assert(val); val->val_type = size; val->val.size = v; \
116: val->val_len = sizeof(size_t); } while (0)
117: #define RPC_SET_OFF(vl, v) do { rpc_val_t *val = (vl); assert(val); val->val_type = offset; val->val.offset = v; \
118: val->val_len = sizeof(off_t); } while (0)
119: #define RPC_SET_TIME(vl, v) do { rpc_val_t *val = (vl); assert(val); val->val_type = datetime; val->val.datetime = v; \
120: val->val_len = sizeof(time_t); } while (0)
121: #define RPC_SET_REAL(vl, v) do { rpc_val_t *val = (vl); assert(val); val->val_type = real; val->val.real = v; \
122: val->val_len = sizeof(float); } while (0)
123: #define RPC_SET_BREAL(vl, v) do { rpc_val_t *val = (vl); assert(val); val->val_type = bigreal; val->val.bigreal = v; \
124: val->val_len = sizeof(double); } while (0)
125: #define RPC_SET_U8(vl, v) do { rpc_val_t *val = (vl); assert(val); val->val_type = u8; val->val.u8 = v; \
126: val->val_len = sizeof(uint8_t); } while (0)
127: #define RPC_SET_U16(vl, v) do { rpc_val_t *val = (vl); assert(val); val->val_type = u16; val->val.u16 = v; \
128: val->val_len = sizeof(uint16_t); } while (0)
129: #define RPC_SET_U32(vl, v) do { rpc_val_t *val = (vl); assert(val); val->val_type = u32; val->val.u32 = v; \
130: val->val_len = sizeof(uint32_t); } while (0)
131: #define RPC_SET_U64(vl, v) do { rpc_val_t *val = (vl); assert(val); val->val_type = u64; val->val.u64 = v; \
132: val->val_len = sizeof(uint64_t); } while (0)
133: #define RPC_SET_I8(vl, v) do { rpc_val_t *val = (vl); assert(val); val->val_type = i8; val->val.i8 = v; \
134: val->val_len = sizeof(int8_t); } while (0)
135: #define RPC_SET_I16(vl, v) do { rpc_val_t *val = (vl); assert(val); val->val_type = i16; val->val.i16 = v; \
136: val->val_len = sizeof(int16_t); } while (0)
137: #define RPC_SET_I32(vl, v) do { rpc_val_t *val = (vl); assert(val); val->val_type = i32; val->val.i32 = v; \
138: val->val_len = sizeof(int32_t); } while (0)
139: #define RPC_SET_I64(vl, v) do { rpc_val_t *val = (vl); assert(val); val->val_type = i64; val->val.i64 = v; \
140: val->val_len = sizeof(int64_t); } while (0)
141:
142: #define RPC_FREE_VAL(vl) do { rpc_val_t *val = (vl); assert(val); \
143: if (val->val_type == buffer && val->val.buffer) { \
144: free(val->val.buffer); \
145: val->val.buffer = NULL; \
146: } \
147: if (val->val_type == string && val->val.string) { \
148: free(val->val.string); \
149: val->val.string = NULL; \
150: } \
1.1.1.1.2.4 misho 151: if (val->val_type == blob && val->val.blob) { \
152: free(val->val.blob); \
153: val->val.blob = NULL; \
1.1 misho 154: } \
155: val->val_type = val->val_len = 0; \
156: } while (0)
157:
158:
1.1.1.1.2.2 misho 159: #define RPC_CALLBACK_CHK_NUM_ARGS(f, n) do { \
1.1 misho 160: if (f->func_args != n) { \
161: rpc_SetErr(22, "Error:: different number of arguments!\n"); \
162: return -1; \
163: } \
1.1.1.1.2.1 misho 164: } while (0)
165: #define RPC_CALLBACK_CHECK_INPUT(s, f) do { \
166: if (!s || !f) { \
167: rpc_SetErr(22, "Error:: invalid callback parameters ...\n"); \
168: return -1; \
169: } \
170: } while (0)
1.1 misho 171:
172:
173: /* RPC session identification */
174:
175: typedef struct {
176: uint8_t sess_version;
177: uint32_t sess_program;
178: uint32_t sess_process;
179: } __packed rpc_sess_t;
180:
181:
182: /* Server managment RPC functions ... */
183:
184: // RPC function registration element!
185: typedef struct tagRPCFunc {
186: uint16_t func_tag;
187: uint32_t func_hash;
188: int8_t func_file[MAXPATHLEN];
189: int8_t func_name[UCHAR_MAX + 1];
190:
191: int8_t func_args;
192: rpc_val_t *func_vals;
193:
194: struct tagRPCFunc *func_next;
195: } rpc_func_t;
196:
197:
198: /* Network RPC packet - Client request */
199:
200: struct tagRPCCall {
201: rpc_sess_t call_session;
202: uint16_t call_tag;
203: uint32_t call_hash;
204: uint8_t call_argc;
205: } __packed;
206:
207: /* Network RPC packet - Server response */
208:
209: struct tagRPCRet {
210: rpc_sess_t ret_session;
211: uint16_t ret_tag;
212: uint32_t ret_hash;
213: int32_t ret_retcode;
214: int32_t ret_errno;
215: uint8_t ret_argc;
216: } __packed;
217:
1.1.1.1.2.6 misho 218: /* Network BLOB packet - Header */
219:
220: struct tagBLOBHdr {
221: rpc_sess_t hdr_session;
222: uint8_t hdr_cmd;
223: uint32_t hdr_var;
224: uint32_t hdr_seq;
225: uint32_t hdr_len;
226: } __packed;
227:
1.1 misho 228: /* Network RPC client & server elements */
229:
230: typedef struct {
231: struct sockaddr cli_sa; // host info
232: int cli_sock; // socket
233: pthread_t cli_tid; // TID of thread
234:
235: void *cli_parent; // pointer to parent rpc_srv_t for server or to rpc_sess_t for client
236: } rpc_cli_t;
237:
238:
1.1.1.1.2.5 misho 239: // BLOB registration element!
240: typedef struct tagBLOB {
1.1.1.1.2.6 misho 241: uint32_t blob_var;
242:
1.1.1.1.2.5 misho 243: size_t blob_len; // size of allocated BLOB data
244: void *blob_data; // BLOB data
245:
246: struct tagBLOB *blob_next;
247: } rpc_blob_t;
248:
249: typedef struct {
1.1 misho 250: rpc_sess_t srv_session; // RPC session registration info
1.1.1.1.2.5 misho 251: int srv_numcli; // maximum concurent client connections
1.1 misho 252:
1.1.1.1.2.5 misho 253: rpc_cli_t srv_server; // RPC server socket
254: rpc_cli_t *srv_clients; // connected rpc client sockets
1.1 misho 255:
256: rpc_func_t *srv_funcs; // registered functions list
1.1.1.1.2.5 misho 257:
258: pthread_mutex_t srv_mtx;
259:
260: struct {
261: int state; // BLOB server state: ==0 disable | !=0 enable
1.1.1.1.2.6 misho 262: char dir[UCHAR_MAX + 1];
1.1.1.1.2.5 misho 263:
264: rpc_cli_t server; // BLOB server socket
265: rpc_cli_t *clients; // connected blob client sockets
266:
267: rpc_blob_t *blobs; // registered blob variables list
268:
269: pthread_mutex_t mtx;
270: } srv_blob;
1.1 misho 271: } rpc_srv_t;
272:
273:
274: typedef int (*rpc_callback_t)(void * const, rpc_func_t *, int, rpc_val_t *);
275:
276:
277: // -----------------------------------------------------------------------
278:
279: /* Error support functions */
280:
281: // cli_GetErrno() Get error code of last operation
282: inline int cli_GetErrno();
283: // cli_GetError() Get error text of last operation
284: inline const char *cli_GetError();
285:
286:
287: /* RPC Server side functions */
288:
289: /*
290: * rpc_srv_initServer() Init & create RPC Server
291: * @regProgID = ProgramID for authentication & recognition
292: * @regProcID = ProcessID for authentication & recognition
293: * @concurentClients = Concurent clients at same time to this server
294: * @family = Family socket type, AF_INET or AF_INET6
295: * @csHost = Host name or IP address for bind server, if NULL any address
296: * @Port = Port for bind server, if Port == 0 default port is selected
297: * return: NULL == error or !=NULL bind and created RPC server instance
298: */
299: rpc_srv_t *rpc_srv_initServer(u_int regProgID, u_int regProcID, int concurentClients,
300: u_short family, const char *csHost, u_short Port);
301: /*
302: * rpc_srv_endServer() Destroy RPC server, close all opened sockets and free resources
303: * @srv = RPC Server instance
304: * return: none
305: */
306: void rpc_srv_endServer(rpc_srv_t * __restrict srv);
307: /*
308: * rpc_srv_execServer() Execute Main server loop and wait for clients requests
309: * @srv = RPC Server instance
310: * return: -1 error or 0 ok, infinite loop ...
311: */
312: int rpc_srv_execServer(rpc_srv_t * __restrict srv);
313:
314: /*
1.1.1.1.2.5 misho 315: * rpc_srv_initBLOBServer() Init & create BLOB Server
316: * @Port = Port for bind server, if Port == 0 default port is selected
1.1.1.1.2.6 misho 317: * @diskDir = Disk place for BLOB file objects
1.1.1.1.2.5 misho 318: * return: -1 == error or 0 bind and created BLOB server instance
319: */
1.1.1.1.2.6 misho 320: int rpc_srv_initBLOBServer(rpc_srv_t * __restrict srv, u_short Port, const char *diskDir);
1.1.1.1.2.5 misho 321: /*
322: * rpc_srv_endBLOBServer() Destroy BLOB server, close all opened sockets and free resources
323: * @srv = RPC Server instance
324: * return: none
325: */
326: void rpc_srv_endBLOBServer(rpc_srv_t * __restrict srv);
327: /*
328: * rpc_srv_execBLOBServer() Execute Main BLOB server loop and wait for clients requests
329: * @srv = RPC Server instance
330: * return: -1 error or 0 ok, infinite loop ...
331: */
332: int rpc_srv_execBLOBServer(rpc_srv_t * __restrict srv);
333:
334: /*
1.1.1.1.2.6 misho 335: * rpc_srv_getBLOB() Get registered BLOB
336: * @srv = RPC Server instance
337: * @var = hash for variable
338: * return: NULL not found, !=NULL return blob var
339: */
340: inline rpc_blob_t *rpc_srv_getBLOB(rpc_srv_t * __restrict srv, uint32_t var);
341:
342: /*
1.1 misho 343: * rpc_srv_registerCall() Register call to RPC server
344: * @srv = RPC Server instance
345: * @csModule = Module name, if NULL self binary
346: * @csFunc = Function name
347: * @args = Number of function arguments
348: * return: -1 error or 0 register ok
349: */
350: int rpc_srv_registerCall(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc,
351: unsigned char args);
352: /*
353: * rpc_srv_unregisterCall() Unregister call from RPC server
354: * @srv = RPC Server instance
355: * @csModule = Module name, if NULL self binary
356: * @csFunc = Function name
357: * return: -1 error, 0 not found call, 1 unregister ok
358: */
359: int rpc_srv_unregisterCall(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc);
360: /*
361: * rpc_srv_getFunc() Get registered call from RPC server by Name
362: * @srv = RPC Server instance
363: * @csModule = Module name, if NULL self binary
364: * @csFunc = Function name
365: * return: NULL not found call, !=NULL return call
366: */
367: rpc_func_t *rpc_srv_getFunc(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc);
368: /*
369: * rpc_srv_getCall() Get registered call from RPC server
370: * @srv = RPC Server instance
371: * @tag = tag for function
372: * @hash = hash for function
373: * return: NULL not found call, !=NULL return call
374: */
375: inline rpc_func_t *rpc_srv_getCall(rpc_srv_t * __restrict srv, uint16_t tag, uint32_t hash);
376: /*
377: * rpc_srv_execCall() Execute registered call from RPC server
378: * @data = RPC const data
379: * @call = Register RPC call
380: * @rpc = IN RPC call structure
381: * @args = IN RPC call array of rpc values
382: * return: -1 error, !=-1 ok
383: */
384: int rpc_srv_execCall(void * const data, rpc_func_t * __restrict call,
385: struct tagRPCCall * __restrict rpc, rpc_val_t * __restrict args);
386:
387:
388: /*
389: * rpc_srv_declValsCall() Declare return variables for RPC call
390: * @call = RPC function call
391: * @return_vals = Number of return variables
392: * return: -1 error, !=-1 ok
393: */
394: inline int rpc_srv_declValsCall(rpc_func_t * __restrict call, int return_vals);
395: /*
396: * rpc_srv_freeValsCall() Free return variables for RPC call
397: * @call = RPC function call
398: * return: none
399: */
400: inline void rpc_srv_freeValsCall(rpc_func_t * __restrict call);
401: /*
402: * rpc_srv_copyValsCall() Copy return variables for RPC call to new variable
403: * @call = RPC function call
404: * @newvals = New allocated variables array, must be free after use
405: * return: -1 error, !=-1 Returned number of copied RPC variables
406: */
407: inline int rpc_srv_copyValsCall(rpc_func_t * __restrict call, rpc_val_t ** __restrict newvals);
408: /*
409: * rpc_srv_delValsCall() Clean values from return variables of RPC call
410: * @call = RPC function call
411: * return: -1 error, !=-1 Returned number of cleaned RPC variables
412: */
413: inline int rpc_srv_delValsCall(rpc_func_t * __restrict call);
414: /*
415: * rpc_srv_getValsCall() Get return variables for RPC call
416: * @call = RPC function call
417: * @vals = Returned variables, may be NULL
418: * return: -1 error, !=-1 Number of returned variables
419: */
420: inline int rpc_srv_getValsCall(rpc_func_t * __restrict call, rpc_val_t ** __restrict vals);
421:
422:
1.1.1.1.2.7! misho 423: /*
! 424: * rpc_srv_blobMap() Map blob to memory region
! 425: * @srv = RPC Server instance
! 426: * @blob = Map to this BLOB element
! 427: * return: -1 error or 0 ok
! 428: */
! 429: inline int rpc_srv_blobMap(rpc_srv_t * __restrict srv, rpc_blob_t * __restrict blob);
! 430: /*
! 431: * rpc_srv_blobUnmap() Unmap blob memory region
! 432: * @blob = Mapped BLOB element
! 433: * return: none
! 434: */
! 435: inline void rpc_srv_blobUnmap(rpc_blob_t * __restrict blob);
! 436: /*
! 437: * rpc_srv_blobFree() Free blob from disk & memory
! 438: * @srv = RPC Server instance
! 439: * @blob = Mapped BLOB element
! 440: * return: -1 error or 0 ok
! 441: */
! 442: inline int rpc_srv_blobFree(rpc_srv_t * __restrict srv, rpc_blob_t * __restrict blob);
! 443:
! 444:
1.1 misho 445: /* RPC Client side functions */
446:
447: /*
448: * rpc_cli_openClient() Connect to RPC Server
449: * @ProgID = ProgramID for RPC session request
450: * @ProcID = ProcessID for RPC session request
451: * @family = Family socket type, AF_INET or AF_INET6
452: * @csHost = Host name or IP address for bind server
453: * @Port = Port for bind server, if Port == 0 default port is selected
454: * return: NULL == error or !=NULL connection to RPC server established
455: */
456: rpc_cli_t *rpc_cli_openClient(u_int ProgID, u_int ProcID, u_short family,
457: const char *csHost, u_short Port);
458: /*
459: * rpc_cli_closeClient() Close connection to RPC server and free resources
460: * @cli = RPC Client session
461: * return: none
462: */
463: void rpc_cli_closeClient(rpc_cli_t * __restrict cli);
464: /*
465: * rpc_cli_execCall() Execute RPC call
466: * @cli = RPC Client session
467: * @csModule = Module name, if NULL self binary
468: * @csFunc = Function name for execute
469: * @in_argc = IN count of arguments
470: * @in_vals = IN RPC call array of rpc values
471: * @out_argc = OUT returned count of arguments
472: * @out_vals = OUT returned array of rpc values, must be free after use (see rpc_cli_freeVals())
473: * return: -1 error or != -1 ok result
474: */
475: int rpc_cli_execCall(rpc_cli_t *cli, const char *csModule, const char *csFunc, int in_argc,
476: rpc_val_t * __restrict in_vals, int *out_argc, rpc_val_t ** __restrict out_vals);
477: /*
478: * rpc_cli_freeVals() Free rpc_val_t array returned from RPC call
479: * @args = Number of arguments in array
480: * @vals = Value elements
481: * return: none
482: */
483: inline void rpc_cli_freeVals(int args, rpc_val_t *vals);
484:
485:
486: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>