1*e985b929SDavid van Moolenbroek /* $NetBSD: evrpc-internal.h,v 1.1.1.2 2013/04/11 16:43:20 christos Exp $ */ 2*e985b929SDavid van Moolenbroek /* 3*e985b929SDavid van Moolenbroek * Copyright (c) 2006-2007 Niels Provos <provos@citi.umich.edu> 4*e985b929SDavid van Moolenbroek * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson 5*e985b929SDavid van Moolenbroek * 6*e985b929SDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without 7*e985b929SDavid van Moolenbroek * modification, are permitted provided that the following conditions 8*e985b929SDavid van Moolenbroek * are met: 9*e985b929SDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright 10*e985b929SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer. 11*e985b929SDavid van Moolenbroek * 2. Redistributions in binary form must reproduce the above copyright 12*e985b929SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer in the 13*e985b929SDavid van Moolenbroek * documentation and/or other materials provided with the distribution. 14*e985b929SDavid van Moolenbroek * 3. The name of the author may not be used to endorse or promote products 15*e985b929SDavid van Moolenbroek * derived from this software without specific prior written permission. 16*e985b929SDavid van Moolenbroek * 17*e985b929SDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18*e985b929SDavid van Moolenbroek * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19*e985b929SDavid van Moolenbroek * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20*e985b929SDavid van Moolenbroek * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21*e985b929SDavid van Moolenbroek * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22*e985b929SDavid van Moolenbroek * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23*e985b929SDavid van Moolenbroek * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24*e985b929SDavid van Moolenbroek * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25*e985b929SDavid van Moolenbroek * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26*e985b929SDavid van Moolenbroek * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27*e985b929SDavid van Moolenbroek */ 28*e985b929SDavid van Moolenbroek #ifndef _EVRPC_INTERNAL_H_ 29*e985b929SDavid van Moolenbroek #define _EVRPC_INTERNAL_H_ 30*e985b929SDavid van Moolenbroek 31*e985b929SDavid van Moolenbroek #include "http-internal.h" 32*e985b929SDavid van Moolenbroek 33*e985b929SDavid van Moolenbroek struct evrpc; 34*e985b929SDavid van Moolenbroek struct evrpc_request_wrapper; 35*e985b929SDavid van Moolenbroek 36*e985b929SDavid van Moolenbroek #define EVRPC_URI_PREFIX "/.rpc." 37*e985b929SDavid van Moolenbroek 38*e985b929SDavid van Moolenbroek struct evrpc_hook { 39*e985b929SDavid van Moolenbroek TAILQ_ENTRY(evrpc_hook) next; 40*e985b929SDavid van Moolenbroek 41*e985b929SDavid van Moolenbroek /* returns EVRPC_TERMINATE; if the rpc should be aborted. 42*e985b929SDavid van Moolenbroek * a hook is is allowed to rewrite the evbuffer 43*e985b929SDavid van Moolenbroek */ 44*e985b929SDavid van Moolenbroek int (*process)(void *, struct evhttp_request *, 45*e985b929SDavid van Moolenbroek struct evbuffer *, void *); 46*e985b929SDavid van Moolenbroek void *process_arg; 47*e985b929SDavid van Moolenbroek }; 48*e985b929SDavid van Moolenbroek 49*e985b929SDavid van Moolenbroek TAILQ_HEAD(evrpc_hook_list, evrpc_hook); 50*e985b929SDavid van Moolenbroek 51*e985b929SDavid van Moolenbroek /* 52*e985b929SDavid van Moolenbroek * this is shared between the base and the pool, so that we can reuse 53*e985b929SDavid van Moolenbroek * the hook adding functions; we alias both evrpc_pool and evrpc_base 54*e985b929SDavid van Moolenbroek * to this common structure. 55*e985b929SDavid van Moolenbroek */ 56*e985b929SDavid van Moolenbroek 57*e985b929SDavid van Moolenbroek struct evrpc_hook_ctx; 58*e985b929SDavid van Moolenbroek TAILQ_HEAD(evrpc_pause_list, evrpc_hook_ctx); 59*e985b929SDavid van Moolenbroek 60*e985b929SDavid van Moolenbroek struct _evrpc_hooks { 61*e985b929SDavid van Moolenbroek /* hooks for processing outbound and inbound rpcs */ 62*e985b929SDavid van Moolenbroek struct evrpc_hook_list in_hooks; 63*e985b929SDavid van Moolenbroek struct evrpc_hook_list out_hooks; 64*e985b929SDavid van Moolenbroek 65*e985b929SDavid van Moolenbroek struct evrpc_pause_list pause_requests; 66*e985b929SDavid van Moolenbroek }; 67*e985b929SDavid van Moolenbroek 68*e985b929SDavid van Moolenbroek #define input_hooks common.in_hooks 69*e985b929SDavid van Moolenbroek #define output_hooks common.out_hooks 70*e985b929SDavid van Moolenbroek #define paused_requests common.pause_requests 71*e985b929SDavid van Moolenbroek 72*e985b929SDavid van Moolenbroek struct evrpc_base { 73*e985b929SDavid van Moolenbroek struct _evrpc_hooks common; 74*e985b929SDavid van Moolenbroek 75*e985b929SDavid van Moolenbroek /* the HTTP server under which we register our RPC calls */ 76*e985b929SDavid van Moolenbroek struct evhttp* http_server; 77*e985b929SDavid van Moolenbroek 78*e985b929SDavid van Moolenbroek /* a list of all RPCs registered with us */ 79*e985b929SDavid van Moolenbroek TAILQ_HEAD(evrpc_list, evrpc) registered_rpcs; 80*e985b929SDavid van Moolenbroek }; 81*e985b929SDavid van Moolenbroek 82*e985b929SDavid van Moolenbroek struct evrpc_req_generic; 83*e985b929SDavid van Moolenbroek void evrpc_reqstate_free(struct evrpc_req_generic* rpc_state); 84*e985b929SDavid van Moolenbroek 85*e985b929SDavid van Moolenbroek /* A pool for holding evhttp_connection objects */ 86*e985b929SDavid van Moolenbroek struct evrpc_pool { 87*e985b929SDavid van Moolenbroek struct _evrpc_hooks common; 88*e985b929SDavid van Moolenbroek 89*e985b929SDavid van Moolenbroek struct event_base *base; 90*e985b929SDavid van Moolenbroek 91*e985b929SDavid van Moolenbroek struct evconq connections; 92*e985b929SDavid van Moolenbroek 93*e985b929SDavid van Moolenbroek int timeout; 94*e985b929SDavid van Moolenbroek 95*e985b929SDavid van Moolenbroek TAILQ_HEAD(evrpc_requestq, evrpc_request_wrapper) (requests); 96*e985b929SDavid van Moolenbroek }; 97*e985b929SDavid van Moolenbroek 98*e985b929SDavid van Moolenbroek struct evrpc_hook_ctx { 99*e985b929SDavid van Moolenbroek TAILQ_ENTRY(evrpc_hook_ctx) next; 100*e985b929SDavid van Moolenbroek 101*e985b929SDavid van Moolenbroek void *ctx; 102*e985b929SDavid van Moolenbroek void (*cb)(void *, enum EVRPC_HOOK_RESULT); 103*e985b929SDavid van Moolenbroek }; 104*e985b929SDavid van Moolenbroek 105*e985b929SDavid van Moolenbroek struct evrpc_meta { 106*e985b929SDavid van Moolenbroek TAILQ_ENTRY(evrpc_meta) next; 107*e985b929SDavid van Moolenbroek char *key; 108*e985b929SDavid van Moolenbroek 109*e985b929SDavid van Moolenbroek void *data; 110*e985b929SDavid van Moolenbroek size_t data_size; 111*e985b929SDavid van Moolenbroek }; 112*e985b929SDavid van Moolenbroek 113*e985b929SDavid van Moolenbroek TAILQ_HEAD(evrpc_meta_list, evrpc_meta); 114*e985b929SDavid van Moolenbroek 115*e985b929SDavid van Moolenbroek struct evrpc_hook_meta { 116*e985b929SDavid van Moolenbroek struct evrpc_meta_list meta_data; 117*e985b929SDavid van Moolenbroek struct evhttp_connection *evcon; 118*e985b929SDavid van Moolenbroek }; 119*e985b929SDavid van Moolenbroek 120*e985b929SDavid van Moolenbroek /* allows association of meta data with a request */ 121*e985b929SDavid van Moolenbroek static void evrpc_hook_associate_meta(struct evrpc_hook_meta **pctx, 122*e985b929SDavid van Moolenbroek struct evhttp_connection *evcon); 123*e985b929SDavid van Moolenbroek 124*e985b929SDavid van Moolenbroek /* creates a new meta data store */ 125*e985b929SDavid van Moolenbroek static struct evrpc_hook_meta *evrpc_hook_meta_new(void); 126*e985b929SDavid van Moolenbroek 127*e985b929SDavid van Moolenbroek /* frees the meta data associated with a request */ 128*e985b929SDavid van Moolenbroek static void evrpc_hook_context_free(struct evrpc_hook_meta *ctx); 129*e985b929SDavid van Moolenbroek 130*e985b929SDavid van Moolenbroek /* the server side of an rpc */ 131*e985b929SDavid van Moolenbroek 132*e985b929SDavid van Moolenbroek /* We alias the RPC specific structs to this voided one */ 133*e985b929SDavid van Moolenbroek struct evrpc_req_generic { 134*e985b929SDavid van Moolenbroek /* 135*e985b929SDavid van Moolenbroek * allows association of meta data via hooks - needs to be 136*e985b929SDavid van Moolenbroek * synchronized with evrpc_request_wrapper 137*e985b929SDavid van Moolenbroek */ 138*e985b929SDavid van Moolenbroek struct evrpc_hook_meta *hook_meta; 139*e985b929SDavid van Moolenbroek 140*e985b929SDavid van Moolenbroek /* the unmarshaled request object */ 141*e985b929SDavid van Moolenbroek void *request; 142*e985b929SDavid van Moolenbroek 143*e985b929SDavid van Moolenbroek /* the empty reply object that needs to be filled in */ 144*e985b929SDavid van Moolenbroek void *reply; 145*e985b929SDavid van Moolenbroek 146*e985b929SDavid van Moolenbroek /* 147*e985b929SDavid van Moolenbroek * the static structure for this rpc; that can be used to 148*e985b929SDavid van Moolenbroek * automatically unmarshal and marshal the http buffers. 149*e985b929SDavid van Moolenbroek */ 150*e985b929SDavid van Moolenbroek struct evrpc *rpc; 151*e985b929SDavid van Moolenbroek 152*e985b929SDavid van Moolenbroek /* 153*e985b929SDavid van Moolenbroek * the http request structure on which we need to answer. 154*e985b929SDavid van Moolenbroek */ 155*e985b929SDavid van Moolenbroek struct evhttp_request* http_req; 156*e985b929SDavid van Moolenbroek 157*e985b929SDavid van Moolenbroek /* 158*e985b929SDavid van Moolenbroek * Temporary data store for marshaled data 159*e985b929SDavid van Moolenbroek */ 160*e985b929SDavid van Moolenbroek struct evbuffer* rpc_data; 161*e985b929SDavid van Moolenbroek }; 162*e985b929SDavid van Moolenbroek 163*e985b929SDavid van Moolenbroek /* the client side of an rpc request */ 164*e985b929SDavid van Moolenbroek struct evrpc_request_wrapper { 165*e985b929SDavid van Moolenbroek /* 166*e985b929SDavid van Moolenbroek * allows association of meta data via hooks - needs to be 167*e985b929SDavid van Moolenbroek * synchronized with evrpc_req_generic. 168*e985b929SDavid van Moolenbroek */ 169*e985b929SDavid van Moolenbroek struct evrpc_hook_meta *hook_meta; 170*e985b929SDavid van Moolenbroek 171*e985b929SDavid van Moolenbroek TAILQ_ENTRY(evrpc_request_wrapper) next; 172*e985b929SDavid van Moolenbroek 173*e985b929SDavid van Moolenbroek /* pool on which this rpc request is being made */ 174*e985b929SDavid van Moolenbroek struct evrpc_pool *pool; 175*e985b929SDavid van Moolenbroek 176*e985b929SDavid van Moolenbroek /* connection on which the request is being sent */ 177*e985b929SDavid van Moolenbroek struct evhttp_connection *evcon; 178*e985b929SDavid van Moolenbroek 179*e985b929SDavid van Moolenbroek /* the actual request */ 180*e985b929SDavid van Moolenbroek struct evhttp_request *req; 181*e985b929SDavid van Moolenbroek 182*e985b929SDavid van Moolenbroek /* event for implementing request timeouts */ 183*e985b929SDavid van Moolenbroek struct event ev_timeout; 184*e985b929SDavid van Moolenbroek 185*e985b929SDavid van Moolenbroek /* the name of the rpc */ 186*e985b929SDavid van Moolenbroek char *name; 187*e985b929SDavid van Moolenbroek 188*e985b929SDavid van Moolenbroek /* callback */ 189*e985b929SDavid van Moolenbroek void (*cb)(struct evrpc_status*, void *request, void *reply, void *arg); 190*e985b929SDavid van Moolenbroek void *cb_arg; 191*e985b929SDavid van Moolenbroek 192*e985b929SDavid van Moolenbroek void *request; 193*e985b929SDavid van Moolenbroek void *reply; 194*e985b929SDavid van Moolenbroek 195*e985b929SDavid van Moolenbroek /* unmarshals the buffer into the proper request structure */ 196*e985b929SDavid van Moolenbroek void (*request_marshal)(struct evbuffer *, void *); 197*e985b929SDavid van Moolenbroek 198*e985b929SDavid van Moolenbroek /* removes all stored state in the reply */ 199*e985b929SDavid van Moolenbroek void (*reply_clear)(void *); 200*e985b929SDavid van Moolenbroek 201*e985b929SDavid van Moolenbroek /* marshals the reply into a buffer */ 202*e985b929SDavid van Moolenbroek int (*reply_unmarshal)(void *, struct evbuffer*); 203*e985b929SDavid van Moolenbroek }; 204*e985b929SDavid van Moolenbroek 205*e985b929SDavid van Moolenbroek #endif /* _EVRPC_INTERNAL_H_ */ 206