1275970Scy/* 2275970Scy * Copyright (c) 2006-2007 Niels Provos <provos@citi.umich.edu> 3275970Scy * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson 4275970Scy * 5275970Scy * Redistribution and use in source and binary forms, with or without 6275970Scy * modification, are permitted provided that the following conditions 7275970Scy * are met: 8275970Scy * 1. Redistributions of source code must retain the above copyright 9275970Scy * notice, this list of conditions and the following disclaimer. 10275970Scy * 2. Redistributions in binary form must reproduce the above copyright 11275970Scy * notice, this list of conditions and the following disclaimer in the 12275970Scy * documentation and/or other materials provided with the distribution. 13275970Scy * 3. The name of the author may not be used to endorse or promote products 14275970Scy * derived from this software without specific prior written permission. 15275970Scy * 16275970Scy * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17275970Scy * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18275970Scy * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19275970Scy * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20275970Scy * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21275970Scy * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22275970Scy * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23275970Scy * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24275970Scy * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25275970Scy * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26275970Scy */ 27275970Scy#ifndef EVENT2_RPC_H_INCLUDED_ 28275970Scy#define EVENT2_RPC_H_INCLUDED_ 29275970Scy 30275970Scy#ifdef __cplusplus 31275970Scyextern "C" { 32275970Scy#endif 33275970Scy 34275970Scy/** @file rpc.h 35275970Scy * 36275970Scy * This header files provides basic support for an RPC server and client. 37275970Scy * 38275970Scy * To support RPCs in a server, every supported RPC command needs to be 39275970Scy * defined and registered. 40275970Scy * 41275970Scy * EVRPC_HEADER(SendCommand, Request, Reply); 42275970Scy * 43275970Scy * SendCommand is the name of the RPC command. 44275970Scy * Request is the name of a structure generated by event_rpcgen.py. 45275970Scy * It contains all parameters relating to the SendCommand RPC. The 46275970Scy * server needs to fill in the Reply structure. 47275970Scy * Reply is the name of a structure generated by event_rpcgen.py. It 48275970Scy * contains the answer to the RPC. 49275970Scy * 50275970Scy * To register an RPC with an HTTP server, you need to first create an RPC 51275970Scy * base with: 52275970Scy * 53275970Scy * struct evrpc_base *base = evrpc_init(http); 54275970Scy * 55275970Scy * A specific RPC can then be registered with 56275970Scy * 57275970Scy * EVRPC_REGISTER(base, SendCommand, Request, Reply, FunctionCB, arg); 58275970Scy * 59275970Scy * when the server receives an appropriately formatted RPC, the user callback 60275970Scy * is invoked. The callback needs to fill in the reply structure. 61275970Scy * 62275970Scy * void FunctionCB(EVRPC_STRUCT(SendCommand)* rpc, void *arg); 63275970Scy * 64275970Scy * To send the reply, call EVRPC_REQUEST_DONE(rpc); 65275970Scy * 66275970Scy * See the regression test for an example. 67275970Scy */ 68275970Scy 69275970Scy/** 70275970Scy Determines if the member has been set in the message 71275970Scy 72275970Scy @param msg the message to inspect 73275970Scy @param member the member variable to test for presences 74275970Scy @return 1 if it's present or 0 otherwise. 75275970Scy*/ 76275970Scy#define EVTAG_HAS(msg, member) \ 77275970Scy ((msg)->member##_set == 1) 78275970Scy 79275970Scy#ifndef EVENT2_RPC_COMPAT_H_INCLUDED_ 80275970Scy 81275970Scy/** 82275970Scy Assigns a value to the member in the message. 83275970Scy 84275970Scy @param msg the message to which to assign a value 85275970Scy @param member the name of the member variable 86275970Scy @param value the value to assign 87275970Scy*/ 88275970Scy#define EVTAG_ASSIGN(msg, member, value) \ 89275970Scy (*(msg)->base->member##_assign)((msg), (value)) 90275970Scy/** 91275970Scy Assigns a value to the member in the message. 92275970Scy 93275970Scy @param msg the message to which to assign a value 94275970Scy @param member the name of the member variable 95275970Scy @param value the value to assign 96275970Scy @param len the length of the value 97275970Scy*/ 98275970Scy#define EVTAG_ASSIGN_WITH_LEN(msg, member, value, len) \ 99275970Scy (*(msg)->base->member##_assign)((msg), (value), (len)) 100275970Scy/** 101275970Scy Returns the value for a member. 102275970Scy 103275970Scy @param msg the message from which to get the value 104275970Scy @param member the name of the member variable 105275970Scy @param pvalue a pointer to the variable to hold the value 106275970Scy @return 0 on success, -1 otherwise. 107275970Scy*/ 108275970Scy#define EVTAG_GET(msg, member, pvalue) \ 109275970Scy (*(msg)->base->member##_get)((msg), (pvalue)) 110275970Scy/** 111275970Scy Returns the value for a member. 112275970Scy 113275970Scy @param msg the message from which to get the value 114275970Scy @param member the name of the member variable 115275970Scy @param pvalue a pointer to the variable to hold the value 116275970Scy @param plen a pointer to the length of the value 117275970Scy @return 0 on success, -1 otherwise. 118275970Scy*/ 119275970Scy#define EVTAG_GET_WITH_LEN(msg, member, pvalue, plen) \ 120275970Scy (*(msg)->base->member##_get)((msg), (pvalue), (plen)) 121275970Scy 122275970Scy#endif /* EVENT2_RPC_COMPAT_H_INCLUDED_ */ 123275970Scy 124275970Scy/** 125275970Scy Adds a value to an array. 126275970Scy*/ 127275970Scy#define EVTAG_ARRAY_ADD_VALUE(msg, member, value) \ 128275970Scy (*(msg)->base->member##_add)((msg), (value)) 129275970Scy/** 130275970Scy Allocates a new entry in the array and returns it. 131275970Scy*/ 132275970Scy#define EVTAG_ARRAY_ADD(msg, member) \ 133275970Scy (*(msg)->base->member##_add)(msg) 134275970Scy/** 135275970Scy Gets a variable at the specified offset from the array. 136275970Scy*/ 137275970Scy#define EVTAG_ARRAY_GET(msg, member, offset, pvalue) \ 138275970Scy (*(msg)->base->member##_get)((msg), (offset), (pvalue)) 139275970Scy/** 140275970Scy Returns the number of entries in the array. 141275970Scy*/ 142275970Scy#define EVTAG_ARRAY_LEN(msg, member) ((msg)->member##_length) 143275970Scy 144275970Scy 145275970Scystruct evbuffer; 146275970Scystruct event_base; 147275970Scystruct evrpc_req_generic; 148275970Scystruct evrpc_request_wrapper; 149275970Scystruct evrpc; 150275970Scy 151275970Scy/** The type of a specific RPC Message 152275970Scy * 153275970Scy * @param rpcname the name of the RPC message 154275970Scy */ 155275970Scy#define EVRPC_STRUCT(rpcname) struct evrpc_req__##rpcname 156275970Scy 157275970Scystruct evhttp_request; 158275970Scystruct evrpc_status; 159275970Scystruct evrpc_hook_meta; 160275970Scy 161275970Scy/** Creates the definitions and prototypes for an RPC 162275970Scy * 163275970Scy * You need to use EVRPC_HEADER to create structures and function prototypes 164275970Scy * needed by the server and client implementation. The structures have to be 165275970Scy * defined in an .rpc file and converted to source code via event_rpcgen.py 166275970Scy * 167275970Scy * @param rpcname the name of the RPC 168275970Scy * @param reqstruct the name of the RPC request structure 169275970Scy * @param replystruct the name of the RPC reply structure 170275970Scy * @see EVRPC_GENERATE() 171275970Scy */ 172275970Scy#define EVRPC_HEADER(rpcname, reqstruct, rplystruct) \ 173275970ScyEVRPC_STRUCT(rpcname) { \ 174275970Scy struct evrpc_hook_meta *hook_meta; \ 175275970Scy struct reqstruct* request; \ 176275970Scy struct rplystruct* reply; \ 177275970Scy struct evrpc* rpc; \ 178275970Scy struct evhttp_request* http_req; \ 179275970Scy struct evbuffer* rpc_data; \ 180275970Scy}; \ 181275970Scyint evrpc_send_request_##rpcname(struct evrpc_pool *, \ 182275970Scy struct reqstruct *, struct rplystruct *, \ 183275970Scy void (*)(struct evrpc_status *, \ 184275970Scy struct reqstruct *, struct rplystruct *, void *cbarg), \ 185275970Scy void *); 186275970Scy 187275970Scystruct evrpc_pool; 188275970Scy 189275970Scy/** use EVRPC_GENERATE instead */ 190275970Scystruct evrpc_request_wrapper *evrpc_make_request_ctx( 191275970Scy struct evrpc_pool *pool, void *request, void *reply, 192275970Scy const char *rpcname, 193275970Scy void (*req_marshal)(struct evbuffer*, void *), 194275970Scy void (*rpl_clear)(void *), 195275970Scy int (*rpl_unmarshal)(void *, struct evbuffer *), 196275970Scy void (*cb)(struct evrpc_status *, void *, void *, void *), 197275970Scy void *cbarg); 198275970Scy 199275970Scy/** Creates a context structure that contains rpc specific information. 200275970Scy * 201275970Scy * EVRPC_MAKE_CTX is used to populate a RPC specific context that 202275970Scy * contains information about marshaling the RPC data types. 203275970Scy * 204275970Scy * @param rpcname the name of the RPC 205275970Scy * @param reqstruct the name of the RPC request structure 206275970Scy * @param replystruct the name of the RPC reply structure 207275970Scy * @param pool the evrpc_pool over which to make the request 208275970Scy * @param request a pointer to the RPC request structure object 209275970Scy * @param reply a pointer to the RPC reply structure object 210275970Scy * @param cb the callback function to call when the RPC has completed 211275970Scy * @param cbarg the argument to supply to the callback 212275970Scy */ 213275970Scy#define EVRPC_MAKE_CTX(rpcname, reqstruct, rplystruct, \ 214275970Scy pool, request, reply, cb, cbarg) \ 215275970Scy evrpc_make_request_ctx(pool, request, reply, \ 216275970Scy #rpcname, \ 217275970Scy (void (*)(struct evbuffer *, void *))reqstruct##_marshal, \ 218275970Scy (void (*)(void *))rplystruct##_clear, \ 219275970Scy (int (*)(void *, struct evbuffer *))rplystruct##_unmarshal, \ 220275970Scy (void (*)(struct evrpc_status *, void *, void *, void *))cb, \ 221275970Scy cbarg) 222275970Scy 223275970Scy/** Generates the code for receiving and sending an RPC message 224275970Scy * 225275970Scy * EVRPC_GENERATE is used to create the code corresponding to sending 226275970Scy * and receiving a particular RPC message 227275970Scy * 228275970Scy * @param rpcname the name of the RPC 229275970Scy * @param reqstruct the name of the RPC request structure 230275970Scy * @param replystruct the name of the RPC reply structure 231275970Scy * @see EVRPC_HEADER() 232275970Scy */ 233275970Scy#define EVRPC_GENERATE(rpcname, reqstruct, rplystruct) \ 234275970Scy int evrpc_send_request_##rpcname(struct evrpc_pool *pool, \ 235275970Scy struct reqstruct *request, struct rplystruct *reply, \ 236275970Scy void (*cb)(struct evrpc_status *, \ 237275970Scy struct reqstruct *, struct rplystruct *, void *cbarg), \ 238275970Scy void *cbarg) { \ 239275970Scy return evrpc_send_request_generic(pool, request, reply, \ 240275970Scy (void (*)(struct evrpc_status *, void *, void *, void *))cb, \ 241275970Scy cbarg, \ 242275970Scy #rpcname, \ 243275970Scy (void (*)(struct evbuffer *, void *))reqstruct##_marshal, \ 244275970Scy (void (*)(void *))rplystruct##_clear, \ 245275970Scy (int (*)(void *, struct evbuffer *))rplystruct##_unmarshal); \ 246275970Scy} 247275970Scy 248275970Scy/** Provides access to the HTTP request object underlying an RPC 249275970Scy * 250275970Scy * Access to the underlying http object; can be used to look at headers or 251275970Scy * for getting the remote ip address 252275970Scy * 253275970Scy * @param rpc_req the rpc request structure provided to the server callback 254275970Scy * @return an struct evhttp_request object that can be inspected for 255275970Scy * HTTP headers or sender information. 256275970Scy */ 257275970Scy#define EVRPC_REQUEST_HTTP(rpc_req) (rpc_req)->http_req 258275970Scy 259275970Scy/** completes the server response to an rpc request */ 260275970Scyvoid evrpc_request_done(struct evrpc_req_generic *req); 261275970Scy 262275970Scy/** accessors for request and reply */ 263275970Scyvoid *evrpc_get_request(struct evrpc_req_generic *req); 264275970Scyvoid *evrpc_get_reply(struct evrpc_req_generic *req); 265275970Scy 266275970Scy/** Creates the reply to an RPC request 267275970Scy * 268275970Scy * EVRPC_REQUEST_DONE is used to answer a request; the reply is expected 269275970Scy * to have been filled in. The request and reply pointers become invalid 270275970Scy * after this call has finished. 271275970Scy * 272275970Scy * @param rpc_req the rpc request structure provided to the server callback 273275970Scy */ 274275970Scy#define EVRPC_REQUEST_DONE(rpc_req) do { \ 275275970Scy struct evrpc_req_generic *req_ = (struct evrpc_req_generic *)(rpc_req); \ 276275970Scy evrpc_request_done(req_); \ 277275970Scy} while (0) 278275970Scy 279275970Scy 280275970Scystruct evrpc_base; 281275970Scystruct evhttp; 282275970Scy 283275970Scy/* functions to start up the rpc system */ 284275970Scy 285275970Scy/** Creates a new rpc base from which RPC requests can be received 286275970Scy * 287275970Scy * @param server a pointer to an existing HTTP server 288275970Scy * @return a newly allocated evrpc_base struct 289275970Scy * @see evrpc_free() 290275970Scy */ 291275970Scystruct evrpc_base *evrpc_init(struct evhttp *server); 292275970Scy 293275970Scy/** 294275970Scy * Frees the evrpc base 295275970Scy * 296275970Scy * For now, you are responsible for making sure that no rpcs are ongoing. 297275970Scy * 298275970Scy * @param base the evrpc_base object to be freed 299275970Scy * @see evrpc_init 300275970Scy */ 301275970Scyvoid evrpc_free(struct evrpc_base *base); 302275970Scy 303275970Scy/** register RPCs with the HTTP Server 304275970Scy * 305275970Scy * registers a new RPC with the HTTP server, each RPC needs to have 306275970Scy * a unique name under which it can be identified. 307275970Scy * 308275970Scy * @param base the evrpc_base structure in which the RPC should be 309275970Scy * registered. 310275970Scy * @param name the name of the RPC 311275970Scy * @param request the name of the RPC request structure 312275970Scy * @param reply the name of the RPC reply structure 313275970Scy * @param callback the callback that should be invoked when the RPC 314275970Scy * is received. The callback has the following prototype 315275970Scy * void (*callback)(EVRPC_STRUCT(Message)* rpc, void *arg) 316275970Scy * @param cbarg an additional parameter that can be passed to the callback. 317275970Scy * The parameter can be used to carry around state. 318275970Scy */ 319275970Scy#define EVRPC_REGISTER(base, name, request, reply, callback, cbarg) \ 320275970Scy evrpc_register_generic(base, #name, \ 321275970Scy (void (*)(struct evrpc_req_generic *, void *))callback, cbarg, \ 322275970Scy (void *(*)(void *))request##_new, NULL, \ 323275970Scy (void (*)(void *))request##_free, \ 324275970Scy (int (*)(void *, struct evbuffer *))request##_unmarshal, \ 325275970Scy (void *(*)(void *))reply##_new, NULL, \ 326275970Scy (void (*)(void *))reply##_free, \ 327275970Scy (int (*)(void *))reply##_complete, \ 328275970Scy (void (*)(struct evbuffer *, void *))reply##_marshal) 329275970Scy 330275970Scy/** 331275970Scy Low level function for registering an RPC with a server. 332275970Scy 333275970Scy Use EVRPC_REGISTER() instead. 334275970Scy 335275970Scy @see EVRPC_REGISTER() 336275970Scy*/ 337275970Scyint evrpc_register_rpc(struct evrpc_base *, struct evrpc *, 338275970Scy void (*)(struct evrpc_req_generic*, void *), void *); 339275970Scy 340275970Scy/** 341275970Scy * Unregisters an already registered RPC 342275970Scy * 343275970Scy * @param base the evrpc_base object from which to unregister an RPC 344275970Scy * @param name the name of the rpc to unregister 345275970Scy * @return -1 on error or 0 when successful. 346275970Scy * @see EVRPC_REGISTER() 347275970Scy */ 348275970Scy#define EVRPC_UNREGISTER(base, name) evrpc_unregister_rpc((base), #name) 349275970Scy 350275970Scyint evrpc_unregister_rpc(struct evrpc_base *base, const char *name); 351275970Scy 352275970Scy/* 353275970Scy * Client-side RPC support 354275970Scy */ 355275970Scy 356275970Scystruct evhttp_connection; 357275970Scystruct evrpc_status; 358275970Scy 359275970Scy/** launches an RPC and sends it to the server 360275970Scy * 361275970Scy * EVRPC_MAKE_REQUEST() is used by the client to send an RPC to the server. 362275970Scy * 363275970Scy * @param name the name of the RPC 364275970Scy * @param pool the evrpc_pool that contains the connection objects over which 365275970Scy * the request should be sent. 366275970Scy * @param request a pointer to the RPC request structure - it contains the 367275970Scy * data to be sent to the server. 368275970Scy * @param reply a pointer to the RPC reply structure. It is going to be filled 369275970Scy * if the request was answered successfully 370275970Scy * @param cb the callback to invoke when the RPC request has been answered 371275970Scy * @param cbarg an additional argument to be passed to the client 372275970Scy * @return 0 on success, -1 on failure 373275970Scy */ 374275970Scy#define EVRPC_MAKE_REQUEST(name, pool, request, reply, cb, cbarg) \ 375275970Scy evrpc_send_request_##name((pool), (request), (reply), (cb), (cbarg)) 376275970Scy 377275970Scy/** 378275970Scy Makes an RPC request based on the provided context. 379275970Scy 380275970Scy This is a low-level function and should not be used directly 381275970Scy unless a custom context object is provided. Use EVRPC_MAKE_REQUEST() 382275970Scy instead. 383275970Scy 384275970Scy @param ctx a context from EVRPC_MAKE_CTX() 385275970Scy @returns 0 on success, -1 otherwise. 386275970Scy @see EVRPC_MAKE_REQUEST(), EVRPC_MAKE_CTX() 387275970Scy*/ 388275970Scyint evrpc_make_request(struct evrpc_request_wrapper *ctx); 389275970Scy 390275970Scy/** creates an rpc connection pool 391275970Scy * 392275970Scy * a pool has a number of connections associated with it. 393275970Scy * rpc requests are always made via a pool. 394275970Scy * 395275970Scy * @param base a pointer to an struct event_based object; can be left NULL 396275970Scy * in singled-threaded applications 397275970Scy * @return a newly allocated struct evrpc_pool object 398275970Scy * @see evrpc_pool_free() 399275970Scy */ 400275970Scystruct evrpc_pool *evrpc_pool_new(struct event_base *base); 401275970Scy/** frees an rpc connection pool 402275970Scy * 403275970Scy * @param pool a pointer to an evrpc_pool allocated via evrpc_pool_new() 404275970Scy * @see evrpc_pool_new() 405275970Scy */ 406275970Scyvoid evrpc_pool_free(struct evrpc_pool *pool); 407275970Scy 408275970Scy/** 409275970Scy * Adds a connection over which rpc can be dispatched to the pool. 410275970Scy * 411275970Scy * The connection object must have been newly created. 412275970Scy * 413275970Scy * @param pool the pool to which to add the connection 414275970Scy * @param evcon the connection to add to the pool. 415275970Scy */ 416275970Scyvoid evrpc_pool_add_connection(struct evrpc_pool *pool, 417275970Scy struct evhttp_connection *evcon); 418275970Scy 419275970Scy/** 420275970Scy * Removes a connection from the pool. 421275970Scy * 422275970Scy * The connection object must have been newly created. 423275970Scy * 424275970Scy * @param pool the pool from which to remove the connection 425275970Scy * @param evcon the connection to remove from the pool. 426275970Scy */ 427275970Scyvoid evrpc_pool_remove_connection(struct evrpc_pool *pool, 428275970Scy struct evhttp_connection *evcon); 429275970Scy 430275970Scy/** 431275970Scy * Sets the timeout in secs after which a request has to complete. The 432275970Scy * RPC is completely aborted if it does not complete by then. Setting 433275970Scy * the timeout to 0 means that it never timeouts and can be used to 434275970Scy * implement callback type RPCs. 435275970Scy * 436275970Scy * Any connection already in the pool will be updated with the new 437275970Scy * timeout. Connections added to the pool after set_timeout has be 438275970Scy * called receive the pool timeout only if no timeout has been set 439275970Scy * for the connection itself. 440275970Scy * 441275970Scy * @param pool a pointer to a struct evrpc_pool object 442275970Scy * @param timeout_in_secs the number of seconds after which a request should 443275970Scy * timeout and a failure be returned to the callback. 444275970Scy */ 445275970Scyvoid evrpc_pool_set_timeout(struct evrpc_pool *pool, int timeout_in_secs); 446275970Scy 447275970Scy/** 448275970Scy * Hooks for changing the input and output of RPCs; this can be used to 449275970Scy * implement compression, authentication, encryption, ... 450275970Scy */ 451275970Scy 452275970Scyenum EVRPC_HOOK_TYPE { 453275970Scy EVRPC_INPUT, /**< apply the function to an input hook */ 454275970Scy EVRPC_OUTPUT /**< apply the function to an output hook */ 455275970Scy}; 456275970Scy 457275970Scy#ifndef _WIN32 458275970Scy/** Deprecated alias for EVRPC_INPUT. Not available on windows, where it 459275970Scy * conflicts with platform headers. */ 460275970Scy#define INPUT EVRPC_INPUT 461275970Scy/** Deprecated alias for EVRPC_OUTPUT. Not available on windows, where it 462275970Scy * conflicts with platform headers. */ 463275970Scy#define OUTPUT EVRPC_OUTPUT 464275970Scy#endif 465275970Scy 466275970Scy/** 467275970Scy * Return value from hook processing functions 468275970Scy */ 469275970Scy 470275970Scyenum EVRPC_HOOK_RESULT { 471275970Scy EVRPC_TERMINATE = -1, /**< indicates the rpc should be terminated */ 472275970Scy EVRPC_CONTINUE = 0, /**< continue processing the rpc */ 473275970Scy EVRPC_PAUSE = 1 /**< pause processing request until resumed */ 474275970Scy}; 475275970Scy 476275970Scy/** adds a processing hook to either an rpc base or rpc pool 477275970Scy * 478275970Scy * If a hook returns TERMINATE, the processing is aborted. On CONTINUE, 479275970Scy * the request is immediately processed after the hook returns. If the 480275970Scy * hook returns PAUSE, request processing stops until evrpc_resume_request() 481275970Scy * has been called. 482275970Scy * 483275970Scy * The add functions return handles that can be used for removing hooks. 484275970Scy * 485275970Scy * @param vbase a pointer to either struct evrpc_base or struct evrpc_pool 486275970Scy * @param hook_type either INPUT or OUTPUT 487275970Scy * @param cb the callback to call when the hook is activated 488275970Scy * @param cb_arg an additional argument for the callback 489275970Scy * @return a handle to the hook so it can be removed later 490275970Scy * @see evrpc_remove_hook() 491275970Scy */ 492275970Scyvoid *evrpc_add_hook(void *vbase, 493275970Scy enum EVRPC_HOOK_TYPE hook_type, 494275970Scy int (*cb)(void *, struct evhttp_request *, struct evbuffer *, void *), 495275970Scy void *cb_arg); 496275970Scy 497275970Scy/** removes a previously added hook 498275970Scy * 499275970Scy * @param vbase a pointer to either struct evrpc_base or struct evrpc_pool 500275970Scy * @param hook_type either INPUT or OUTPUT 501275970Scy * @param handle a handle returned by evrpc_add_hook() 502275970Scy * @return 1 on success or 0 on failure 503275970Scy * @see evrpc_add_hook() 504275970Scy */ 505275970Scyint evrpc_remove_hook(void *vbase, 506275970Scy enum EVRPC_HOOK_TYPE hook_type, 507275970Scy void *handle); 508275970Scy 509275970Scy/** resume a paused request 510275970Scy * 511275970Scy * @param vbase a pointer to either struct evrpc_base or struct evrpc_pool 512275970Scy * @param ctx the context pointer provided to the original hook call 513275970Scy */ 514275970Scyint 515275970Scyevrpc_resume_request(void *vbase, void *ctx, enum EVRPC_HOOK_RESULT res); 516275970Scy 517275970Scy/** adds meta data to request 518275970Scy * 519275970Scy * evrpc_hook_add_meta() allows hooks to add meta data to a request. for 520275970Scy * a client request, the meta data can be inserted by an outgoing request hook 521275970Scy * and retrieved by the incoming request hook. 522275970Scy * 523275970Scy * @param ctx the context provided to the hook call 524275970Scy * @param key a NUL-terminated c-string 525275970Scy * @param data the data to be associated with the key 526275970Scy * @param data_size the size of the data 527275970Scy */ 528275970Scyvoid evrpc_hook_add_meta(void *ctx, const char *key, 529275970Scy const void *data, size_t data_size); 530275970Scy 531275970Scy/** retrieves meta data previously associated 532275970Scy * 533275970Scy * evrpc_hook_find_meta() can be used to retrieve meta data associated to a 534275970Scy * request by a previous hook. 535275970Scy * @param ctx the context provided to the hook call 536275970Scy * @param key a NUL-terminated c-string 537275970Scy * @param data pointer to a data pointer that will contain the retrieved data 538275970Scy * @param data_size pointer to the size of the data 539275970Scy * @return 0 on success or -1 on failure 540275970Scy */ 541275970Scyint evrpc_hook_find_meta(void *ctx, const char *key, 542275970Scy void **data, size_t *data_size); 543275970Scy 544275970Scy/** 545275970Scy * returns the connection object associated with the request 546275970Scy * 547275970Scy * @param ctx the context provided to the hook call 548275970Scy * @return a pointer to the evhttp_connection object 549275970Scy */ 550275970Scystruct evhttp_connection *evrpc_hook_get_connection(void *ctx); 551275970Scy 552275970Scy/** 553275970Scy Function for sending a generic RPC request. 554275970Scy 555275970Scy Do not call this function directly, use EVRPC_MAKE_REQUEST() instead. 556275970Scy 557275970Scy @see EVRPC_MAKE_REQUEST() 558275970Scy */ 559275970Scyint evrpc_send_request_generic(struct evrpc_pool *pool, 560275970Scy void *request, void *reply, 561275970Scy void (*cb)(struct evrpc_status *, void *, void *, void *), 562275970Scy void *cb_arg, 563275970Scy const char *rpcname, 564275970Scy void (*req_marshal)(struct evbuffer *, void *), 565275970Scy void (*rpl_clear)(void *), 566275970Scy int (*rpl_unmarshal)(void *, struct evbuffer *)); 567275970Scy 568275970Scy/** 569275970Scy Function for registering a generic RPC with the RPC base. 570275970Scy 571275970Scy Do not call this function directly, use EVRPC_REGISTER() instead. 572275970Scy 573275970Scy @see EVRPC_REGISTER() 574275970Scy */ 575275970Scyint 576275970Scyevrpc_register_generic(struct evrpc_base *base, const char *name, 577275970Scy void (*callback)(struct evrpc_req_generic *, void *), void *cbarg, 578275970Scy void *(*req_new)(void *), void *req_new_arg, void (*req_free)(void *), 579275970Scy int (*req_unmarshal)(void *, struct evbuffer *), 580275970Scy void *(*rpl_new)(void *), void *rpl_new_arg, void (*rpl_free)(void *), 581275970Scy int (*rpl_complete)(void *), 582275970Scy void (*rpl_marshal)(struct evbuffer *, void *)); 583275970Scy 584275970Scy/** accessors for obscure and undocumented functionality */ 585275970Scystruct evrpc_pool* evrpc_request_get_pool(struct evrpc_request_wrapper *ctx); 586275970Scyvoid evrpc_request_set_pool(struct evrpc_request_wrapper *ctx, 587275970Scy struct evrpc_pool *pool); 588275970Scyvoid evrpc_request_set_cb(struct evrpc_request_wrapper *ctx, 589275970Scy void (*cb)(struct evrpc_status*, void *request, void *reply, void *arg), 590275970Scy void *cb_arg); 591275970Scy 592275970Scy#ifdef __cplusplus 593275970Scy} 594275970Scy#endif 595275970Scy 596275970Scy#endif /* EVENT2_RPC_H_INCLUDED_ */ 597