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