1 /* 2 * Copyright (c) 2006-2007 Niels Provos <provos (at) citi.umich.edu> 3 * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 #ifndef _EVENT2_RPC_H_ 28 #define _EVENT2_RPC_H_ 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 /** @file rpc.h 35 * 36 * This header files provides basic support for an RPC server and client. 37 * 38 * To support RPCs in a server, every supported RPC command needs to be 39 * defined and registered. 40 * 41 * EVRPC_HEADER(SendCommand, Request, Reply); 42 * 43 * SendCommand is the name of the RPC command. 44 * Request is the name of a structure generated by event_rpcgen.py. 45 * It contains all parameters relating to the SendCommand RPC. The 46 * server needs to fill in the Reply structure. 47 * Reply is the name of a structure generated by event_rpcgen.py. It 48 * contains the answer to the RPC. 49 * 50 * To register an RPC with an HTTP server, you need to first create an RPC 51 * base with: 52 * 53 * struct evrpc_base *base = evrpc_init(http); 54 * 55 * A specific RPC can then be registered with 56 * 57 * EVRPC_REGISTER(base, SendCommand, Request, Reply, FunctionCB, arg); 58 * 59 * when the server receives an appropriately formatted RPC, the user callback 60 * is invoked. The callback needs to fill in the reply structure. 61 * 62 * void FunctionCB(EVRPC_STRUCT(SendCommand)* rpc, void *arg); 63 * 64 * To send the reply, call EVRPC_REQUEST_DONE(rpc); 65 * 66 * See the regression test for an example. 67 */ 68 69 /** 70 Determines if the member has been set in the message 71 72 @param msg the message to inspect 73 @param member the member variable to test for presences 74 @return 1 if it's present or 0 otherwise. 75 */ 76 #define EVTAG_HAS(msg, member) \ 77 ((msg)->member##_set == 1) 78 79 #ifndef _EVENT2_RPC_COMPAT_H_ 80 81 /** 82 Assigns a value to the member in the message. 83 84 @param msg the message to which to assign a value 85 @param member the name of the member variable 86 @param value the value to assign 87 */ 88 #define EVTAG_ASSIGN(msg, member, value) \ 89 (*(msg)->base->member##_assign)((msg), (value)) 90 /** 91 Assigns a value to the member in the message. 92 93 @param msg the message to which to assign a value 94 @param member the name of the member variable 95 @param value the value to assign 96 @param len the length of the value 97 */ 98 #define EVTAG_ASSIGN_WITH_LEN(msg, member, value, len) \ 99 (*(msg)->base->member##_assign)((msg), (value), (len)) 100 /** 101 Returns the value for a member. 102 103 @param msg the message from which to get the value 104 @param member the name of the member variable 105 @param pvalue a pointer to the variable to hold the value 106 @return 0 on success, -1 otherwise. 107 */ 108 #define EVTAG_GET(msg, member, pvalue) \ 109 (*(msg)->base->member##_get)((msg), (pvalue)) 110 /** 111 Returns the value for a member. 112 113 @param msg the message from which to get the value 114 @param member the name of the member variable 115 @param pvalue a pointer to the variable to hold the value 116 @param plen a pointer to the length of the value 117 @return 0 on success, -1 otherwise. 118 */ 119 #define EVTAG_GET_WITH_LEN(msg, member, pvalue, plen) \ 120 (*(msg)->base->member##_get)((msg), (pvalue), (plen)) 121 122 #endif /* _EVENT2_RPC_COMPAT_H_ */ 123 124 /** 125 Adds a value to an array. 126 */ 127 #define EVTAG_ARRAY_ADD_VALUE(msg, member, value) \ 128 (*(msg)->base->member##_add)((msg), (value)) 129 /** 130 Allocates a new entry in the array and returns it. 131 */ 132 #define EVTAG_ARRAY_ADD(msg, member) \ 133 (*(msg)->base->member##_add)(msg) 134 /** 135 Gets a variable at the specified offset from the array. 136 */ 137 #define EVTAG_ARRAY_GET(msg, member, offset, pvalue) \ 138 (*(msg)->base->member##_get)((msg), (offset), (pvalue)) 139 /** 140 Returns the number of entries in the array. 141 */ 142 #define EVTAG_ARRAY_LEN(msg, member) ((msg)->member##_length) 143 144 145 struct evbuffer; 146 struct event_base; 147 struct evrpc_req_generic; 148 struct evrpc_request_wrapper; 149 struct evrpc; 150 151 /** The type of a specific RPC Message 152 * 153 * @param rpcname the name of the RPC message 154 */ 155 #define EVRPC_STRUCT(rpcname) struct evrpc_req__##rpcname 156 157 struct evhttp_request; 158 struct evrpc_status; 159 struct evrpc_hook_meta; 160 161 /** Creates the definitions and prototypes for an RPC 162 * 163 * You need to use EVRPC_HEADER to create structures and function prototypes 164 * needed by the server and client implementation. The structures have to be 165 * defined in an .rpc file and converted to source code via event_rpcgen.py 166 * 167 * @param rpcname the name of the RPC 168 * @param reqstruct the name of the RPC request structure 169 * @param replystruct the name of the RPC reply structure 170 * @see EVRPC_GENERATE() 171 */ 172 #define EVRPC_HEADER(rpcname, reqstruct, rplystruct) \ 173 EVRPC_STRUCT(rpcname) { \ 174 struct evrpc_hook_meta *hook_meta; \ 175 struct reqstruct* request; \ 176 struct rplystruct* reply; \ 177 struct evrpc* rpc; \ 178 struct evhttp_request* http_req; \ 179 struct evbuffer* rpc_data; \ 180 }; \ 181 int evrpc_send_request_##rpcname(struct evrpc_pool *, \ 182 struct reqstruct *, struct rplystruct *, \ 183 void (*)(struct evrpc_status *, \ 184 struct reqstruct *, struct rplystruct *, void *cbarg), \ 185 void *); 186 187 struct evrpc_pool; 188 189 /** use EVRPC_GENERATE instead */ 190 struct evrpc_request_wrapper *evrpc_make_request_ctx( 191 struct evrpc_pool *pool, void *request, void *reply, 192 const char *rpcname, 193 void (*req_marshal)(struct evbuffer*, void *), 194 void (*rpl_clear)(void *), 195 int (*rpl_unmarshal)(void *, struct evbuffer *), 196 void (*cb)(struct evrpc_status *, void *, void *, void *), 197 void *cbarg); 198 199 /** Creates a context structure that contains rpc specific information. 200 * 201 * EVRPC_MAKE_CTX is used to populate a RPC specific context that 202 * contains information about marshaling the RPC data types. 203 * 204 * @param rpcname the name of the RPC 205 * @param reqstruct the name of the RPC request structure 206 * @param replystruct the name of the RPC reply structure 207 * @param pool the evrpc_pool over which to make the request 208 * @param request a pointer to the RPC request structure object 209 * @param reply a pointer to the RPC reply structure object 210 * @param cb the callback function to call when the RPC has completed 211 * @param cbarg the argument to supply to the callback 212 */ 213 #define EVRPC_MAKE_CTX(rpcname, reqstruct, rplystruct, \ 214 pool, request, reply, cb, cbarg) \ 215 evrpc_make_request_ctx(pool, request, reply, \ 216 #rpcname, \ 217 (void (*)(struct evbuffer *, void *))reqstruct##_marshal, \ 218 (void (*)(void *))rplystruct##_clear, \ 219 (int (*)(void *, struct evbuffer *))rplystruct##_unmarshal, \ 220 (void (*)(struct evrpc_status *, void *, void *, void *))cb, \ 221 cbarg) 222 223 /** Generates the code for receiving and sending an RPC message 224 * 225 * EVRPC_GENERATE is used to create the code corresponding to sending 226 * and receiving a particular RPC message 227 * 228 * @param rpcname the name of the RPC 229 * @param reqstruct the name of the RPC request structure 230 * @param replystruct the name of the RPC reply structure 231 * @see EVRPC_HEADER() 232 */ 233 #define EVRPC_GENERATE(rpcname, reqstruct, rplystruct) \ 234 int evrpc_send_request_##rpcname(struct evrpc_pool *pool, \ 235 struct reqstruct *request, struct rplystruct *reply, \ 236 void (*cb)(struct evrpc_status *, \ 237 struct reqstruct *, struct rplystruct *, void *cbarg), \ 238 void *cbarg) { \ 239 return evrpc_send_request_generic(pool, request, reply, \ 240 (void (*)(struct evrpc_status *, void *, void *, void *))cb, \ 241 cbarg, \ 242 #rpcname, \ 243 (void (*)(struct evbuffer *, void *))reqstruct##_marshal, \ 244 (void (*)(void *))rplystruct##_clear, \ 245 (int (*)(void *, struct evbuffer *))rplystruct##_unmarshal); \ 246 } 247 248 /** Provides access to the HTTP request object underlying an RPC 249 * 250 * Access to the underlying http object; can be used to look at headers or 251 * for getting the remote ip address 252 * 253 * @param rpc_req the rpc request structure provided to the server callback 254 * @return an struct evhttp_request object that can be inspected for 255 * HTTP headers or sender information. 256 */ 257 #define EVRPC_REQUEST_HTTP(rpc_req) (rpc_req)->http_req 258 259 /** completes the server response to an rpc request */ 260 void evrpc_request_done(struct evrpc_req_generic *req); 261 262 /** accessors for request and reply */ 263 void *evrpc_get_request(struct evrpc_req_generic *req); 264 void *evrpc_get_reply(struct evrpc_req_generic *req); 265 266 /** Creates the reply to an RPC request 267 * 268 * EVRPC_REQUEST_DONE is used to answer a request; the reply is expected 269 * to have been filled in. The request and reply pointers become invalid 270 * after this call has finished. 271 * 272 * @param rpc_req the rpc request structure provided to the server callback 273 */ 274 #define EVRPC_REQUEST_DONE(rpc_req) do { \ 275 struct evrpc_req_generic *_req = (struct evrpc_req_generic *)(rpc_req); \ 276 evrpc_request_done(_req); \ 277 } while (0) 278 279 280 struct evrpc_base; 281 struct evhttp; 282 283 /* functions to start up the rpc system */ 284 285 /** Creates a new rpc base from which RPC requests can be received 286 * 287 * @param server a pointer to an existing HTTP server 288 * @return a newly allocated evrpc_base struct 289 * @see evrpc_free() 290 */ 291 struct evrpc_base *evrpc_init(struct evhttp *server); 292 293 /** 294 * Frees the evrpc base 295 * 296 * For now, you are responsible for making sure that no rpcs are ongoing. 297 * 298 * @param base the evrpc_base object to be freed 299 * @see evrpc_init 300 */ 301 void evrpc_free(struct evrpc_base *base); 302 303 /** register RPCs with the HTTP Server 304 * 305 * registers a new RPC with the HTTP server, each RPC needs to have 306 * a unique name under which it can be identified. 307 * 308 * @param base the evrpc_base structure in which the RPC should be 309 * registered. 310 * @param name the name of the RPC 311 * @param request the name of the RPC request structure 312 * @param reply the name of the RPC reply structure 313 * @param callback the callback that should be invoked when the RPC 314 * is received. The callback has the following prototype 315 * void (*callback)(EVRPC_STRUCT(Message)* rpc, void *arg) 316 * @param cbarg an additional parameter that can be passed to the callback. 317 * The parameter can be used to carry around state. 318 */ 319 #define EVRPC_REGISTER(base, name, request, reply, callback, cbarg) \ 320 evrpc_register_generic(base, #name, \ 321 (void (*)(struct evrpc_req_generic *, void *))callback, cbarg, \ 322 (void *(*)(void *))request##_new, NULL, \ 323 (void (*)(void *))request##_free, \ 324 (int (*)(void *, struct evbuffer *))request##_unmarshal, \ 325 (void *(*)(void *))reply##_new, NULL, \ 326 (void (*)(void *))reply##_free, \ 327 (int (*)(void *))reply##_complete, \ 328 (void (*)(struct evbuffer *, void *))reply##_marshal) 329 330 /** 331 Low level function for registering an RPC with a server. 332 333 Use EVRPC_REGISTER() instead. 334 335 @see EVRPC_REGISTER() 336 */ 337 int evrpc_register_rpc(struct evrpc_base *, struct evrpc *, 338 void (*)(struct evrpc_req_generic*, void *), void *); 339 340 /** 341 * Unregisters an already registered RPC 342 * 343 * @param base the evrpc_base object from which to unregister an RPC 344 * @param name the name of the rpc to unregister 345 * @return -1 on error or 0 when successful. 346 * @see EVRPC_REGISTER() 347 */ 348 #define EVRPC_UNREGISTER(base, name) evrpc_unregister_rpc((base), #name) 349 350 int evrpc_unregister_rpc(struct evrpc_base *base, const char *name); 351 352 /* 353 * Client-side RPC support 354 */ 355 356 struct evhttp_connection; 357 struct evrpc_status; 358 359 /** launches an RPC and sends it to the server 360 * 361 * EVRPC_MAKE_REQUEST() is used by the client to send an RPC to the server. 362 * 363 * @param name the name of the RPC 364 * @param pool the evrpc_pool that contains the connection objects over which 365 * the request should be sent. 366 * @param request a pointer to the RPC request structure - it contains the 367 * data to be sent to the server. 368 * @param reply a pointer to the RPC reply structure. It is going to be filled 369 * if the request was answered successfully 370 * @param cb the callback to invoke when the RPC request has been answered 371 * @param cbarg an additional argument to be passed to the client 372 * @return 0 on success, -1 on failure 373 */ 374 #define EVRPC_MAKE_REQUEST(name, pool, request, reply, cb, cbarg) \ 375 evrpc_send_request_##name((pool), (request), (reply), (cb), (cbarg)) 376 377 /** 378 Makes an RPC request based on the provided context. 379 380 This is a low-level function and should not be used directly 381 unless a custom context object is provided. Use EVRPC_MAKE_REQUEST() 382 instead. 383 384 @param ctx a context from EVRPC_MAKE_CTX() 385 @returns 0 on success, -1 otherwise. 386 @see EVRPC_MAKE_REQUEST(), EVRPC_MAKE_CTX() 387 */ 388 int evrpc_make_request(struct evrpc_request_wrapper *ctx); 389 390 /** creates an rpc connection pool 391 * 392 * a pool has a number of connections associated with it. 393 * rpc requests are always made via a pool. 394 * 395 * @param base a pointer to an struct event_based object; can be left NULL 396 * in singled-threaded applications 397 * @return a newly allocated struct evrpc_pool object 398 * @see evrpc_pool_free() 399 */ 400 struct evrpc_pool *evrpc_pool_new(struct event_base *base); 401 /** frees an rpc connection pool 402 * 403 * @param pool a pointer to an evrpc_pool allocated via evrpc_pool_new() 404 * @see evrpc_pool_new() 405 */ 406 void evrpc_pool_free(struct evrpc_pool *pool); 407 408 /** 409 * Adds a connection over which rpc can be dispatched to the pool. 410 * 411 * The connection object must have been newly created. 412 * 413 * @param pool the pool to which to add the connection 414 * @param evcon the connection to add to the pool. 415 */ 416 void evrpc_pool_add_connection(struct evrpc_pool *pool, 417 struct evhttp_connection *evcon); 418 419 /** 420 * Removes a connection from the pool. 421 * 422 * The connection object must have been newly created. 423 * 424 * @param pool the pool from which to remove the connection 425 * @param evcon the connection to remove from the pool. 426 */ 427 void evrpc_pool_remove_connection(struct evrpc_pool *pool, 428 struct evhttp_connection *evcon); 429 430 /** 431 * Sets the timeout in secs after which a request has to complete. The 432 * RPC is completely aborted if it does not complete by then. Setting 433 * the timeout to 0 means that it never timeouts and can be used to 434 * implement callback type RPCs. 435 * 436 * Any connection already in the pool will be updated with the new 437 * timeout. Connections added to the pool after set_timeout has be 438 * called receive the pool timeout only if no timeout has been set 439 * for the connection itself. 440 * 441 * @param pool a pointer to a struct evrpc_pool object 442 * @param timeout_in_secs the number of seconds after which a request should 443 * timeout and a failure be returned to the callback. 444 */ 445 void evrpc_pool_set_timeout(struct evrpc_pool *pool, int timeout_in_secs); 446 447 /** 448 * Hooks for changing the input and output of RPCs; this can be used to 449 * implement compression, authentication, encryption, ... 450 */ 451 452 enum EVRPC_HOOK_TYPE { 453 EVRPC_INPUT, /**< apply the function to an input hook */ 454 EVRPC_OUTPUT /**< apply the function to an output hook */ 455 }; 456 457 #ifndef WIN32 458 /** Deprecated alias for EVRPC_INPUT. Not available on windows, where it 459 * conflicts with platform headers. */ 460 #define INPUT EVRPC_INPUT 461 /** Deprecated alias for EVRPC_OUTPUT. Not available on windows, where it 462 * conflicts with platform headers. */ 463 #define OUTPUT EVRPC_OUTPUT 464 #endif 465 466 /** 467 * Return value from hook processing functions 468 */ 469 470 enum EVRPC_HOOK_RESULT { 471 EVRPC_TERMINATE = -1, /**< indicates the rpc should be terminated */ 472 EVRPC_CONTINUE = 0, /**< continue processing the rpc */ 473 EVRPC_PAUSE = 1 /**< pause processing request until resumed */ 474 }; 475 476 /** adds a processing hook to either an rpc base or rpc pool 477 * 478 * If a hook returns TERMINATE, the processing is aborted. On CONTINUE, 479 * the request is immediately processed after the hook returns. If the 480 * hook returns PAUSE, request processing stops until evrpc_resume_request() 481 * has been called. 482 * 483 * The add functions return handles that can be used for removing hooks. 484 * 485 * @param vbase a pointer to either struct evrpc_base or struct evrpc_pool 486 * @param hook_type either INPUT or OUTPUT 487 * @param cb the callback to call when the hook is activated 488 * @param cb_arg an additional argument for the callback 489 * @return a handle to the hook so it can be removed later 490 * @see evrpc_remove_hook() 491 */ 492 void *evrpc_add_hook(void *vbase, 493 enum EVRPC_HOOK_TYPE hook_type, 494 int (*cb)(void *, struct evhttp_request *, struct evbuffer *, void *), 495 void *cb_arg); 496 497 /** removes a previously added hook 498 * 499 * @param vbase a pointer to either struct evrpc_base or struct evrpc_pool 500 * @param hook_type either INPUT or OUTPUT 501 * @param handle a handle returned by evrpc_add_hook() 502 * @return 1 on success or 0 on failure 503 * @see evrpc_add_hook() 504 */ 505 int evrpc_remove_hook(void *vbase, 506 enum EVRPC_HOOK_TYPE hook_type, 507 void *handle); 508 509 /** resume a paused request 510 * 511 * @param vbase a pointer to either struct evrpc_base or struct evrpc_pool 512 * @param ctx the context pointer provided to the original hook call 513 */ 514 int 515 evrpc_resume_request(void *vbase, void *ctx, enum EVRPC_HOOK_RESULT res); 516 517 /** adds meta data to request 518 * 519 * evrpc_hook_add_meta() allows hooks to add meta data to a request. for 520 * a client request, the meta data can be inserted by an outgoing request hook 521 * and retrieved by the incoming request hook. 522 * 523 * @param ctx the context provided to the hook call 524 * @param key a NUL-terminated c-string 525 * @param data the data to be associated with the key 526 * @param data_size the size of the data 527 */ 528 void evrpc_hook_add_meta(void *ctx, const char *key, 529 const void *data, size_t data_size); 530 531 /** retrieves meta data previously associated 532 * 533 * evrpc_hook_find_meta() can be used to retrieve meta data associated to a 534 * request by a previous hook. 535 * @param ctx the context provided to the hook call 536 * @param key a NUL-terminated c-string 537 * @param data pointer to a data pointer that will contain the retrieved data 538 * @param data_size pointer to the size of the data 539 * @return 0 on success or -1 on failure 540 */ 541 int evrpc_hook_find_meta(void *ctx, const char *key, 542 void **data, size_t *data_size); 543 544 /** 545 * returns the connection object associated with the request 546 * 547 * @param ctx the context provided to the hook call 548 * @return a pointer to the evhttp_connection object 549 */ 550 struct evhttp_connection *evrpc_hook_get_connection(void *ctx); 551 552 /** 553 Function for sending a generic RPC request. 554 555 Do not call this function directly, use EVRPC_MAKE_REQUEST() instead. 556 557 @see EVRPC_MAKE_REQUEST() 558 */ 559 int evrpc_send_request_generic(struct evrpc_pool *pool, 560 void *request, void *reply, 561 void (*cb)(struct evrpc_status *, void *, void *, void *), 562 void *cb_arg, 563 const char *rpcname, 564 void (*req_marshal)(struct evbuffer *, void *), 565 void (*rpl_clear)(void *), 566 int (*rpl_unmarshal)(void *, struct evbuffer *)); 567 568 /** 569 Function for registering a generic RPC with the RPC base. 570 571 Do not call this function directly, use EVRPC_REGISTER() instead. 572 573 @see EVRPC_REGISTER() 574 */ 575 int 576 evrpc_register_generic(struct evrpc_base *base, const char *name, 577 void (*callback)(struct evrpc_req_generic *, void *), void *cbarg, 578 void *(*req_new)(void *), void *req_new_arg, void (*req_free)(void *), 579 int (*req_unmarshal)(void *, struct evbuffer *), 580 void *(*rpl_new)(void *), void *rpl_new_arg, void (*rpl_free)(void *), 581 int (*rpl_complete)(void *), 582 void (*rpl_marshal)(struct evbuffer *, void *)); 583 584 /** accessors for obscure and undocumented functionality */ 585 struct evrpc_pool* evrpc_request_get_pool(struct evrpc_request_wrapper *ctx); 586 void evrpc_request_set_pool(struct evrpc_request_wrapper *ctx, 587 struct evrpc_pool *pool); 588 void evrpc_request_set_cb(struct evrpc_request_wrapper *ctx, 589 void (*cb)(struct evrpc_status*, void *request, void *reply, void *arg), 590 void *cb_arg); 591 592 #ifdef __cplusplus 593 } 594 #endif 595 596 #endif /* _EVENT2_RPC_H_ */ 597