12b15cb3dSCy Schubert /* 22b15cb3dSCy Schubert * Copyright (c) 2006-2007 Niels Provos <provos@citi.umich.edu> 32b15cb3dSCy Schubert * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson 42b15cb3dSCy Schubert * 52b15cb3dSCy Schubert * Redistribution and use in source and binary forms, with or without 62b15cb3dSCy Schubert * modification, are permitted provided that the following conditions 72b15cb3dSCy Schubert * are met: 82b15cb3dSCy Schubert * 1. Redistributions of source code must retain the above copyright 92b15cb3dSCy Schubert * notice, this list of conditions and the following disclaimer. 102b15cb3dSCy Schubert * 2. Redistributions in binary form must reproduce the above copyright 112b15cb3dSCy Schubert * notice, this list of conditions and the following disclaimer in the 122b15cb3dSCy Schubert * documentation and/or other materials provided with the distribution. 132b15cb3dSCy Schubert * 3. The name of the author may not be used to endorse or promote products 142b15cb3dSCy Schubert * derived from this software without specific prior written permission. 152b15cb3dSCy Schubert * 162b15cb3dSCy Schubert * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 172b15cb3dSCy Schubert * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 182b15cb3dSCy Schubert * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 192b15cb3dSCy Schubert * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 202b15cb3dSCy Schubert * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 212b15cb3dSCy Schubert * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 222b15cb3dSCy Schubert * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 232b15cb3dSCy Schubert * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 242b15cb3dSCy Schubert * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 252b15cb3dSCy Schubert * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 262b15cb3dSCy Schubert */ 272b15cb3dSCy Schubert #ifndef EVRPC_INTERNAL_H_INCLUDED_ 282b15cb3dSCy Schubert #define EVRPC_INTERNAL_H_INCLUDED_ 292b15cb3dSCy Schubert 30*a25439b6SCy Schubert #include "event2/http.h" 312b15cb3dSCy Schubert #include "http-internal.h" 322b15cb3dSCy Schubert 332b15cb3dSCy Schubert struct evrpc; 342b15cb3dSCy Schubert struct evrpc_request_wrapper; 352b15cb3dSCy Schubert 362b15cb3dSCy Schubert #define EVRPC_URI_PREFIX "/.rpc." 372b15cb3dSCy Schubert 382b15cb3dSCy Schubert struct evrpc_hook { 392b15cb3dSCy Schubert TAILQ_ENTRY(evrpc_hook) next; 402b15cb3dSCy Schubert 412b15cb3dSCy Schubert /* returns EVRPC_TERMINATE; if the rpc should be aborted. 422b15cb3dSCy Schubert * a hook is is allowed to rewrite the evbuffer 432b15cb3dSCy Schubert */ 442b15cb3dSCy Schubert int (*process)(void *, struct evhttp_request *, 452b15cb3dSCy Schubert struct evbuffer *, void *); 462b15cb3dSCy Schubert void *process_arg; 472b15cb3dSCy Schubert }; 482b15cb3dSCy Schubert 492b15cb3dSCy Schubert TAILQ_HEAD(evrpc_hook_list, evrpc_hook); 502b15cb3dSCy Schubert 512b15cb3dSCy Schubert /* 522b15cb3dSCy Schubert * this is shared between the base and the pool, so that we can reuse 532b15cb3dSCy Schubert * the hook adding functions; we alias both evrpc_pool and evrpc_base 542b15cb3dSCy Schubert * to this common structure. 552b15cb3dSCy Schubert */ 562b15cb3dSCy Schubert 572b15cb3dSCy Schubert struct evrpc_hook_ctx; 582b15cb3dSCy Schubert TAILQ_HEAD(evrpc_pause_list, evrpc_hook_ctx); 592b15cb3dSCy Schubert 602b15cb3dSCy Schubert struct evrpc_hooks_ { 612b15cb3dSCy Schubert /* hooks for processing outbound and inbound rpcs */ 622b15cb3dSCy Schubert struct evrpc_hook_list in_hooks; 632b15cb3dSCy Schubert struct evrpc_hook_list out_hooks; 642b15cb3dSCy Schubert 652b15cb3dSCy Schubert struct evrpc_pause_list pause_requests; 662b15cb3dSCy Schubert }; 672b15cb3dSCy Schubert 682b15cb3dSCy Schubert #define input_hooks common.in_hooks 692b15cb3dSCy Schubert #define output_hooks common.out_hooks 702b15cb3dSCy Schubert #define paused_requests common.pause_requests 712b15cb3dSCy Schubert 722b15cb3dSCy Schubert struct evrpc_base { 732b15cb3dSCy Schubert struct evrpc_hooks_ common; 742b15cb3dSCy Schubert 752b15cb3dSCy Schubert /* the HTTP server under which we register our RPC calls */ 762b15cb3dSCy Schubert struct evhttp* http_server; 772b15cb3dSCy Schubert 782b15cb3dSCy Schubert /* a list of all RPCs registered with us */ 792b15cb3dSCy Schubert TAILQ_HEAD(evrpc_list, evrpc) registered_rpcs; 802b15cb3dSCy Schubert }; 812b15cb3dSCy Schubert 822b15cb3dSCy Schubert struct evrpc_req_generic; 832b15cb3dSCy Schubert void evrpc_reqstate_free_(struct evrpc_req_generic* rpc_state); 842b15cb3dSCy Schubert 852b15cb3dSCy Schubert /* A pool for holding evhttp_connection objects */ 862b15cb3dSCy Schubert struct evrpc_pool { 872b15cb3dSCy Schubert struct evrpc_hooks_ common; 882b15cb3dSCy Schubert 892b15cb3dSCy Schubert struct event_base *base; 902b15cb3dSCy Schubert 912b15cb3dSCy Schubert struct evconq connections; 922b15cb3dSCy Schubert 932b15cb3dSCy Schubert int timeout; 942b15cb3dSCy Schubert 952b15cb3dSCy Schubert TAILQ_HEAD(evrpc_requestq, evrpc_request_wrapper) (requests); 962b15cb3dSCy Schubert }; 972b15cb3dSCy Schubert 982b15cb3dSCy Schubert struct evrpc_hook_ctx { 992b15cb3dSCy Schubert TAILQ_ENTRY(evrpc_hook_ctx) next; 1002b15cb3dSCy Schubert 1012b15cb3dSCy Schubert void *ctx; 1022b15cb3dSCy Schubert void (*cb)(void *, enum EVRPC_HOOK_RESULT); 1032b15cb3dSCy Schubert }; 1042b15cb3dSCy Schubert 1052b15cb3dSCy Schubert struct evrpc_meta { 1062b15cb3dSCy Schubert TAILQ_ENTRY(evrpc_meta) next; 1072b15cb3dSCy Schubert char *key; 1082b15cb3dSCy Schubert 1092b15cb3dSCy Schubert void *data; 1102b15cb3dSCy Schubert size_t data_size; 1112b15cb3dSCy Schubert }; 1122b15cb3dSCy Schubert 1132b15cb3dSCy Schubert TAILQ_HEAD(evrpc_meta_list, evrpc_meta); 1142b15cb3dSCy Schubert 1152b15cb3dSCy Schubert struct evrpc_hook_meta { 1162b15cb3dSCy Schubert struct evrpc_meta_list meta_data; 1172b15cb3dSCy Schubert struct evhttp_connection *evcon; 1182b15cb3dSCy Schubert }; 1192b15cb3dSCy Schubert 1202b15cb3dSCy Schubert /* allows association of meta data with a request */ 1212b15cb3dSCy Schubert static void evrpc_hook_associate_meta_(struct evrpc_hook_meta **pctx, 1222b15cb3dSCy Schubert struct evhttp_connection *evcon); 1232b15cb3dSCy Schubert 1242b15cb3dSCy Schubert /* creates a new meta data store */ 1252b15cb3dSCy Schubert static struct evrpc_hook_meta *evrpc_hook_meta_new_(void); 1262b15cb3dSCy Schubert 1272b15cb3dSCy Schubert /* frees the meta data associated with a request */ 1282b15cb3dSCy Schubert static void evrpc_hook_context_free_(struct evrpc_hook_meta *ctx); 1292b15cb3dSCy Schubert 1302b15cb3dSCy Schubert /* the server side of an rpc */ 1312b15cb3dSCy Schubert 1322b15cb3dSCy Schubert /* We alias the RPC specific structs to this voided one */ 1332b15cb3dSCy Schubert struct evrpc_req_generic { 1342b15cb3dSCy Schubert /* 1352b15cb3dSCy Schubert * allows association of meta data via hooks - needs to be 1362b15cb3dSCy Schubert * synchronized with evrpc_request_wrapper 1372b15cb3dSCy Schubert */ 1382b15cb3dSCy Schubert struct evrpc_hook_meta *hook_meta; 1392b15cb3dSCy Schubert 1402b15cb3dSCy Schubert /* the unmarshaled request object */ 1412b15cb3dSCy Schubert void *request; 1422b15cb3dSCy Schubert 1432b15cb3dSCy Schubert /* the empty reply object that needs to be filled in */ 1442b15cb3dSCy Schubert void *reply; 1452b15cb3dSCy Schubert 1462b15cb3dSCy Schubert /* 1472b15cb3dSCy Schubert * the static structure for this rpc; that can be used to 1482b15cb3dSCy Schubert * automatically unmarshal and marshal the http buffers. 1492b15cb3dSCy Schubert */ 1502b15cb3dSCy Schubert struct evrpc *rpc; 1512b15cb3dSCy Schubert 1522b15cb3dSCy Schubert /* 1532b15cb3dSCy Schubert * the http request structure on which we need to answer. 1542b15cb3dSCy Schubert */ 1552b15cb3dSCy Schubert struct evhttp_request* http_req; 1562b15cb3dSCy Schubert 1572b15cb3dSCy Schubert /* 1582b15cb3dSCy Schubert * Temporary data store for marshaled data 1592b15cb3dSCy Schubert */ 1602b15cb3dSCy Schubert struct evbuffer* rpc_data; 1612b15cb3dSCy Schubert }; 1622b15cb3dSCy Schubert 1632b15cb3dSCy Schubert /* the client side of an rpc request */ 1642b15cb3dSCy Schubert struct evrpc_request_wrapper { 1652b15cb3dSCy Schubert /* 1662b15cb3dSCy Schubert * allows association of meta data via hooks - needs to be 1672b15cb3dSCy Schubert * synchronized with evrpc_req_generic. 1682b15cb3dSCy Schubert */ 1692b15cb3dSCy Schubert struct evrpc_hook_meta *hook_meta; 1702b15cb3dSCy Schubert 1712b15cb3dSCy Schubert TAILQ_ENTRY(evrpc_request_wrapper) next; 1722b15cb3dSCy Schubert 1732b15cb3dSCy Schubert /* pool on which this rpc request is being made */ 1742b15cb3dSCy Schubert struct evrpc_pool *pool; 1752b15cb3dSCy Schubert 1762b15cb3dSCy Schubert /* connection on which the request is being sent */ 1772b15cb3dSCy Schubert struct evhttp_connection *evcon; 1782b15cb3dSCy Schubert 1792b15cb3dSCy Schubert /* the actual request */ 1802b15cb3dSCy Schubert struct evhttp_request *req; 1812b15cb3dSCy Schubert 1822b15cb3dSCy Schubert /* event for implementing request timeouts */ 1832b15cb3dSCy Schubert struct event ev_timeout; 1842b15cb3dSCy Schubert 1852b15cb3dSCy Schubert /* the name of the rpc */ 1862b15cb3dSCy Schubert char *name; 1872b15cb3dSCy Schubert 1882b15cb3dSCy Schubert /* callback */ 1892b15cb3dSCy Schubert void (*cb)(struct evrpc_status*, void *request, void *reply, void *arg); 1902b15cb3dSCy Schubert void *cb_arg; 1912b15cb3dSCy Schubert 1922b15cb3dSCy Schubert void *request; 1932b15cb3dSCy Schubert void *reply; 1942b15cb3dSCy Schubert 1952b15cb3dSCy Schubert /* unmarshals the buffer into the proper request structure */ 1962b15cb3dSCy Schubert void (*request_marshal)(struct evbuffer *, void *); 1972b15cb3dSCy Schubert 1982b15cb3dSCy Schubert /* removes all stored state in the reply */ 1992b15cb3dSCy Schubert void (*reply_clear)(void *); 2002b15cb3dSCy Schubert 2012b15cb3dSCy Schubert /* marshals the reply into a buffer */ 2022b15cb3dSCy Schubert int (*reply_unmarshal)(void *, struct evbuffer*); 2032b15cb3dSCy Schubert }; 2042b15cb3dSCy Schubert 2052b15cb3dSCy Schubert #endif /* EVRPC_INTERNAL_H_INCLUDED_ */ 206