Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

gdp / gdp / gdp_priv.h @ master

History | View | Annotate | Download (33 KB)

1 4e425382 Eric Allman
/* vim: set ai sw=4 sts=4 ts=4 : */
2 b041e64c Eric Allman
3
/*
4 055d3009 Eric Allman
**  ----- BEGIN LICENSE BLOCK -----
5
**        GDP: Global Data Plane Support Library
6
**        From the Ubiquitous Swarm Lab, 490 Cory Hall, U.C. Berkeley.
7
**
8 c87dd166 Eric Allman
**        Copyright (c) 2015-2019, Regents of the University of California.
9 6bd5476b Eric Allman
**        All rights reserved.
10 055d3009 Eric Allman
**
11 6bd5476b Eric Allman
**        Permission is hereby granted, without written agreement and without
12
**        license or royalty fees, to use, copy, modify, and distribute this
13
**        software and its documentation for any purpose, provided that the above
14
**        copyright notice and the following two paragraphs appear in all copies
15
**        of this software.
16 055d3009 Eric Allman
**
17 6bd5476b Eric Allman
**        IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
18
**        SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
19
**        PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
20
**        EVEN IF REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21 055d3009 Eric Allman
**
22 6bd5476b Eric Allman
**        REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
23 055d3009 Eric Allman
**        LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 6bd5476b Eric Allman
**        FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION,
25
**        IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO
26
**        OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
27
**        OR MODIFICATIONS.
28 055d3009 Eric Allman
**  ----- END LICENSE BLOCK -----
29
*/
30
31
/*
32 4e425382 Eric Allman
**        These headers are not intended for external use.
33 174e9f6d Eric Allman
*/
34 b041e64c Eric Allman
35 f0313e1d Eric Allman
#ifndef _GDP_PRIV_H_
36
#define _GDP_PRIV_H_
37
38 85b68a8f Eric Allman
#include <ep/ep.h>
39 47d57c57 Eric Allman
#include <ep/ep_assert.h>
40 f80ae9c0 Eric Allman
#include <ep/ep_crypto.h>
41 ed3580ca Siqi Lin
#include <ep/ep_thr.h>
42 21ab3878 Eric Allman
43
#include <event2/buffer.h>
44 f0313e1d Eric Allman
45 d65c01e2 Eric Allman
#include "gdp.pb-c.h"
46
47 85b68a8f Eric Allman
#if EP_OSCF_USE_VALGRIND
48
# include <valgrind/helgrind.h>
49
#else
50
# define VALGRIND_HG_CLEAN_MEMORY(a, b)
51
#endif
52
53 80da996e Eric Allman
#ifndef GDP_COMPAT_OLD_LOG_NAMES
54
# define GDP_COMPAT_OLD_LOG_NAMES                1        // assume old style SHA(human) names
55
#endif
56
#ifndef GDP_COMPAT_OLD_PUBKEYS
57
# define GDP_COMPAT_OLD_PUBKEYS                        1        // try old public key metadata name
58
#endif
59
#ifndef GDP_DEFAULT_CREATION_SERVICE
60 c9a90ca9 Eric Allman
//# define GDP_DEFAULT_CREATION_SERVICE        "edu.berkeley.eecs.gdp.service.creation"
61 80da996e Eric Allman
#endif
62 92adefd5 Eric Allman
#ifndef GDP_DEFAULT_DATA_ROOT
63
# define GDP_DEFAULT_DATA_ROOT                        "/var/swarm/gdp"
64
#endif
65 80da996e Eric Allman
66 34e502ee Eric Allman
typedef struct gdp_chan                gdp_chan_t;                // should be in gdp_chan.h?
67
typedef uint16_t                        gdp_seqno_t;        // should be in gdp_chan.h?
68 ca3929c7 Eric Allman
typedef struct gdp_req                gdp_req_t;
69 fec93aac Eric Allman
typedef struct gdp_gob                gdp_gob_t;
70
typedef struct gdp_gin                gdp_gin_t;
71 34e502ee Eric Allman
typedef struct gdp_pdu                gdp_pdu_t;                // should be in gdp_pdu.h?
72 d65c01e2 Eric Allman
typedef GdpMessage                        gdp_msg_t;
73 4a89fdda Eric Allman
typedef GdpMsgCode                        gdp_cmd_t;
74 3bc20136 Eric Allman
typedef struct event_base        event_base_t;
75 caa69652 Eric Allman
TAILQ_HEAD(gev_list, gdp_event);
76 9509f13b Eric Allman
77 34e502ee Eric Allman
#include "gdp_pdu.h"
78
79 7f867a4a Eric Allman
extern EP_THR                _GdpIoEventLoopThread;
80 5a73c6ad Eric Allman
extern event_base_t        *_GdpIoEventBase;        // for all I/O events
81 fa419c23 Eric Allman
extern gdp_chan_t        *_GdpChannel;                // our primary app-level protocol port
82
extern gdp_name_t        _GdpMyRoutingName;        // source name for PDUs
83 866c2ca2 Eric Allman
extern int                        _GdpInitState;                // initialization state, see below
84
85
#define GDP_INIT_NONE                0        // uninitialized
86
#define GDP_INIT_PHASE_0        10        // phase 0 complete
87
#define GDP_INIT_LIB                20        // gdp_init_lib done
88
#define GDP_INIT_COMPLETE        99        // all initialization complete
89 b8c5e7c8 Eric Allman
90
#define GDP_CHECK_INITIALIZED                                                                                        \
91 866c2ca2 Eric Allman
                                        ((_GdpInitState >= GDP_INIT_COMPLETE)                                \
92
                                                                                ? EP_STAT_OK                                        \
93 a749564b Eric Allman
                                                                                : gdp_init(NULL))
94 9509f13b Eric Allman
95 006cd152 Eric Allman
#ifndef GDP_OPT_EXTENDED_CACHE_CHECK                //XXX DEBUG TEMPORARY
96
# define GDP_OPT_EXTENDED_CACHE_CHECK        1        //XXX DEBUG TEMPORARY
97
#endif                                                                                //XXX DEBUG TEMPORARY
98 7816b117 Eric Allman
#if GDP_OPT_EXTENDED_CACHE_CHECK
99
#define IF_LIST_CHECK_OK(list, item, chain, type)                                                \
100
        type *_x_ ## item;                                                                                                        \
101 54ef7d04 Eric Allman
        if (ep_dbg_test(Dbg, 10))                                                                                        \
102 7816b117 Eric Allman
        {                                                                                                                                        \
103
                LIST_FOREACH(_x_ ## item, list, chain)                                                        \
104
                {                                                                                                                                \
105
                        EP_ASSERT_ELSE(_x_ ## item != item, break);                                        \
106
                }                                                                                                                                \
107
        }                                                                                                                                        \
108
        else                                                                                                                                \
109
                _x_ ## item = NULL;                                                                                                \
110
        if (_x_ ## item == NULL)
111
#else
112 f52acd4d Nitesh Mor
#define IF_LIST_CHECK_OK(list, item, chain, type)                                                \
113 7816b117 Eric Allman
        if (true)
114
#endif
115
116 d65c01e2 Eric Allman
// helper to do sanity checks
117
#define GDP_MSG_CHECK(pdu, recovery)                                                                                \
118
                        EP_ASSERT_ELSE(pdu != NULL, recovery);                                                        \
119 4a89fdda Eric Allman
                        EP_ASSERT_ELSE(pdu->msg != NULL, recovery);
120 d65c01e2 Eric Allman
121 837e94b0 Eric Allman
// declare the type of the gdp_req linked list (used multiple places)
122 0314a7a7 Eric Allman
LIST_HEAD(req_head, gdp_req);
123 cd2ef2a6 Eric Allman
124 e5d36455 Eric Allman
125 636b52e2 Eric Allman
/*
126 4102ad3a Eric Allman
**  Some generic constants
127
*/
128
129 8cc28925 Eric Allman
// "dump" routine detail parameters (XXX should these be public?)
130
#define GDP_PR_PRETTY                0                // suitable for end users
131 ada5f328 Eric Allman
#define GDP_PR_BASIC                8                // basic debug information
132 4102ad3a Eric Allman
#define GDP_PR_DETAILED                16                // detailed information
133
#define GDP_PR_RECURSE                32                // recurse into substructures
134
                                                                        // add N to recurse N+1 levels deep
135
136
137
/*
138 92243bf4 Eric Allman
**  Basic data types
139
*/
140
141 fa7cfdb9 Eric Allman
// hashes
142
//struct gdp_hash
143
//{
144
//        int                                        alg;                // hash algorithm to use
145
//        gdp_buf_t                        *buf;                // the hash value itself
146
//};
147
gdp_buf_t                *_gdp_hash_getbuf(gdp_hash_t *hash);
148
149 92243bf4 Eric Allman
150 fa7cfdb9 Eric Allman
// signatures
151
//struct gdp_sig
152
//{
153
//        XXX;
154
//};
155
gdp_buf_t                *_gdp_sig_getbuf(gdp_sig_t *sig);
156 92243bf4 Eric Allman
157
158
/*
159 e5d36455 Eric Allman
**         Datums
160 eae1d3ec Eric Allman
**                These are the underlying data unit that is passed through a GOB.
161 e5d36455 Eric Allman
**
162 636b52e2 Eric Allman
**                The timestamp here is the database commit timestamp; any sample
163
**                timestamp must be added by the sensor itself as part of the data.
164 fa7cfdb9 Eric Allman
**
165
**                dhash = H(dbuf)
166
**                datum hash = H(recno || ts || prevhash || dhash)
167
**                prevhash = hash of previous datum
168 e5d36455 Eric Allman
*/
169
170
struct gdp_datum
171
{
172 636b52e2 Eric Allman
        EP_THR_MUTEX                mutex;                        // locking mutex (mostly for dbuf)
173
        struct gdp_datum        *next;                        // next in free list
174 59fe1e09 Eric Allman
        uint32_t                        flags;                        // see below
175 636b52e2 Eric Allman
        gdp_recno_t                        recno;                        // the record number
176
        EP_TIME_SPEC                ts;                                // commit timestamp
177
        gdp_buf_t                        *dbuf;                        // data buffer
178 fa7cfdb9 Eric Allman
        gdp_sig_t                        *sig;                        // signature (may be NULL)
179
        gdp_hash_t                        *prevhash;                // hash of previous datum
180 e5d36455 Eric Allman
};
181
182 59fe1e09 Eric Allman
#define GDP_DF_INUSE                0x00000001        // datum is in use
183 e1c055ad Eric Allman
#define GDP_DF_GOODSIG                0x00000002        // signature is good
184 59fe1e09 Eric Allman
185 8701c522 Eric Allman
#define GDP_DATUM_ISGOOD(datum)                                                                                        \
186
                                ((datum) != NULL &&                                                                                \
187 d65c01e2 Eric Allman
                                 (datum)->dbuf != NULL &&                                                                        \
188 59fe1e09 Eric Allman
                                 EP_UT_BITSET(GDP_DF_INUSE, (datum)->flags))
189 8701c522 Eric Allman
190 fa7cfdb9 Eric Allman
gdp_datum_t                *_gdp_datum_new_gob(        // generate new datum from GOB
191 2e65953f Eric Allman
                                                void);
192 fa7cfdb9 Eric Allman
193
gdp_datum_t                *gdp_datum_dup(                        // duplicate a datum
194
                                                const gdp_datum_t *datum);
195
196 f2bf61a4 Eric Allman
void                        _gdp_datum_dump(                // dump data record (for debugging)
197
                                                const gdp_datum_t *datum,        // message to print
198
                                                FILE *fp);                                        // file to print it to
199 ca3929c7 Eric Allman
200 8cfe4117 Eric Allman
gdp_hash_t                *_gdp_datum_hash(                // compute hash of datum
201
                                                gdp_datum_t *datum,
202 c9f4745b Eric Allman
                                                gdp_gob_t *gob);                        // enclosing GOB
203 8cfe4117 Eric Allman
204
bool                        _gdp_datum_hash_equal(        // check that a hash matches the datum
205
                                                gdp_datum_t *datum,                        // the datum to check
206 c9f4745b Eric Allman
                                                gdp_gob_t *gob,                                // enclosing GOB
207 8cfe4117 Eric Allman
                                                const gdp_hash_t *hash);        // the hash to check against
208 fa7cfdb9 Eric Allman
209 1042a70f Eric Allman
EP_STAT                        _gdp_datum_digest(                // add datum to existing digest
210 fa7cfdb9 Eric Allman
                                                gdp_datum_t *datum,                        // the datum to include
211
                                                EP_CRYPTO_MD *md);                        // the existing digest
212
213 d65c01e2 Eric Allman
void                        _gdp_datum_to_pb(                // convert datum to protobuf form
214
                                                const gdp_datum_t *datum,
215 7f74c3b3 Eric Allman
                                                GdpMessage *msg,
216 d65c01e2 Eric Allman
                                                GdpDatum *pb);
217
218
void                        _gdp_datum_from_pb(                // convert protobuf form to datum
219
                                                gdp_datum_t *datum,
220 9f6be413 Eric Allman
                                                const GdpDatum *pb,
221
                                                const GdpSignature *sig);
222 d65c01e2 Eric Allman
223 fa7cfdb9 Eric Allman
EP_STAT                        _gdp_datum_sign(                // sign a datum
224
                                                gdp_datum_t *datum,                        // the datum to sign
225
                                                gdp_gob_t *gob);                        // the object storing it
226 e7b2a80c Eric Allman
227 c9f4745b Eric Allman
EP_STAT                        _gdp_datum_vrfy_gob(        // verify a datum signature
228
                                                gdp_datum_t *datum,
229
                                                gdp_gob_t *gob);
230
231 bd278f2e Eric Allman
void                        _gdp_timestamp_from_pb(        // convert protobuf form to EP_TIME_SPEC
232
                                                EP_TIME_SPEC *ts,
233
                                                const GdpTimestamp *pbd);
234
235 ca3929c7 Eric Allman
236 e5d36455 Eric Allman
237
/*
238 fec93aac Eric Allman
**  GDP Objects
239
**
240 eae1d3ec Eric Allman
**                There are two data structures around GOBs.
241 fec93aac Eric Allman
**
242 eae1d3ec Eric Allman
**                The gdp_gin is an open handle on a GDP Object Instance.
243 fec93aac Eric Allman
**                Client-side subscriptions are associated with this so
244
**                that gdp_event_next can deliver the correct information.
245
**                Read and append filters are also considered "external".
246 eae1d3ec Eric Allman
**                It is not used at all by gdplogd.
247 d65c01e2 Eric Allman
**                Mostly implemented in gdp_api.c.
248 fec93aac Eric Allman
**
249 eae1d3ec Eric Allman
**                The gdp_gob is the internal representation of a potentially
250
**                shared GOB.  This is what is in the cache.
251
**                It has the request list representing
252 fec93aac Eric Allman
**                server-side subscriptions.  It is used both by the
253 d65c01e2 Eric Allman
**                GDP library and by gdplogd.  Mostly implemented in
254
**                gdp_gob_ops.c.
255 e5d36455 Eric Allman
*/
256
257 fec93aac Eric Allman
SLIST_HEAD(gcl_head, gdp_gcl);
258
259
260
// application per-open-instance information (unused in gdplogd)
261
struct gdp_gin
262 f0313e1d Eric Allman
{
263 ed3580ca Siqi Lin
        EP_THR_MUTEX                mutex;                        // lock on this data structure
264 fec93aac Eric Allman
        gdp_gob_t                        *gob;                        // internal GDP object
265
        SLIST_ENTRY(gdp_gin)
266
                                                next;                        // chain for freelist
267
        uint16_t                        flags;                        // see below
268 4e425382 Eric Allman
        gdp_iomode_t                iomode;                        // read only or append only
269 eae1d3ec Eric Allman
        void                                (*closefunc)(gdp_gin_t *);
270 fec93aac Eric Allman
                                                                                // called when this is closed
271 34612550 Eric Allman
        EP_STAT                                (*apndfilter)(        // append filter function
272
                                                        gdp_datum_t *,
273
                                                        void *);
274
        void                                *apndfpriv;                // private data for apndfilter
275
        EP_STAT                                (*readfilter)(        // read filter function
276
                                                        gdp_datum_t *,
277
                                                        void *);
278
        void                                *readfpriv;                // private data for readfilter
279 f0313e1d Eric Allman
};
280
281 c9f4745b Eric Allman
#define GINF_INUSE                        0x0001                // GIN is allocated
282
#define GINF_ISLOCKED                0x0002                // GIN is locked
283 caef25cd Eric Allman
#define GINF_SIG_VRFY                0x0004                // verify returned data if possible
284
#define GINF_SIG_VRFY_REQ        0x0008                // signature verification required
285 c9f4745b Eric Allman
286 fec93aac Eric Allman
// internal GDP object, shared between open instances, used in gdplogd
287
struct gdp_gob
288
{
289
        EP_THR_MUTEX                mutex;                        // lock on this data structure
290
        time_t                                utime;                        // last time used (seconds only)
291
        LIST_ENTRY(gdp_gob)        ulist;                        // list sorted by use time
292
        struct req_head                reqs;                        // list of outstanding requests
293
        gdp_name_t                        name;                        // the internal name
294
        gdp_pname_t                        pname;                        // printable name (for debugging)
295
        uint16_t                        flags;                        // flag bits, see below
296 9f6be413 Eric Allman
        uint16_t                        hashalg;                // hash algorithm
297 fec93aac Eric Allman
        int                                        refcnt;                        // reference counter
298
        void                                (*freefunc)(gdp_gob_t *);
299
                                                                                // called when this is freed
300
        gdp_recno_t                        nrecs;                        // # of records (actually last recno)
301 eae1d3ec Eric Allman
        gdp_md_t                        *gob_md;                // metadata
302 c9f4745b Eric Allman
        EP_CRYPTO_MD                *sign_ctx;                // base digest for signature
303
        EP_CRYPTO_MD                *vrfy_ctx;                // base digest for verification
304 fec93aac Eric Allman
        struct gdp_gob_xtra        *x;                                // for use by gdplogd, gdp-rest
305
};
306
307 c9f4745b Eric Allman
// flags for GDP objects
308 caef25cd Eric Allman
#define GOBF_INUSE                        0x0001                // handle is allocated
309
#define GOBF_ISLOCKED                0x0002                // GOB is locked
310 c9f4745b Eric Allman
#define GOBF_DROPPING                0x0004                // handle is being deallocated
311
#define GOBF_INCACHE                0x0008                // handle is in cache
312 eae1d3ec Eric Allman
#define GOBF_DEFER_FREE                0x0010                // defer actual free until reclaim
313
#define GOBF_KEEPLOCKED                0x0020                // don't unlock in _gdp_gob_decref
314
#define GOBF_PENDING                0x0040                // not yet fully open
315 1c4fea03 Eric Allman
#define GOBF_SIGNING                0x0080                // we are signing records
316 c9f4745b Eric Allman
#define GOBF_VERIFYING                0x0100                // we are verifying records
317
#define GOBF_VRFY_WARN                0x0200                // verification fail is a warning only
318 3c6bebb0 Eric Allman
319 d65c01e2 Eric Allman
320
/*
321
**  GOB functions
322
*/
323
324 c70b1607 Eric Allman
// Used to avoid compiler warnings on some versions of gcc ("value computed is
325
// not used").  If "inline" doesn't work, use #define _gdp_bool_null(b) (b).
326
static inline bool _gdp_bool_null(bool b) { return b; }
327
328 fec93aac Eric Allman
#define GDP_GOB_ISGOOD(gob)                                                                                                \
329
                                ((gob) != NULL &&                                                                                \
330 eae1d3ec Eric Allman
                                 EP_UT_BITSET(GOBF_INUSE, (gob)->flags))
331 fec93aac Eric Allman
#define GDP_GOB_ASSERT_ISLOCKED(gob)                                                                        \
332 c70b1607 Eric Allman
                        _gdp_bool_null(                                                                                                \
333 fec93aac Eric Allman
                                EP_ASSERT(GDP_GOB_ISGOOD(gob)) &&                                                \
334 eae1d3ec Eric Allman
                                EP_ASSERT(EP_UT_BITSET(GOBF_ISLOCKED, (gob)->flags)) &&        \
335 fec93aac Eric Allman
                                EP_THR_MUTEX_ASSERT_ISLOCKED(&(gob)->mutex)                                \
336 1b7c480e Eric Allman
                        )
337 21ab3878 Eric Allman
338 11029b9c Eric Allman
339 d65c01e2 Eric Allman
EP_STAT                        _gdp_gob_new(                                // create new in-mem handle
340
                                                gdp_name_t name,
341
                                                gdp_gob_t **gobhp);
342 21ab3878 Eric Allman
343 d65c01e2 Eric Allman
void                        _gdp_gob_free(                                // free in-memory handle
344
                                                gdp_gob_t **gob);                // GOB to free
345 f2bf1027 Eric Allman
346 fec93aac Eric Allman
#define _gdp_gob_lock(g)                _gdp_gob_lock_trace(g, __FILE__, __LINE__, #g)
347
#define _gdp_gob_unlock(g)                _gdp_gob_unlock_trace(g, __FILE__, __LINE__, #g)
348 c9f8e411 Eric Allman
#define _gdp_gob_incref(g)                _gdp_gob_incref_trace(g, __FILE__, __LINE__, #g)
349 fec93aac Eric Allman
#define _gdp_gob_decref(g, k)        _gdp_gob_decref_trace(g, k, __FILE__, __LINE__, #g)
350
351 eae1d3ec Eric Allman
void                        _gdp_gob_lock_trace(                // lock the GOB mutex
352 fec93aac Eric Allman
                                                gdp_gob_t *gob,
353 3e98a709 Eric Allman
                                                const char *file,
354
                                                int line,
355
                                                const char *id);
356 9ed4e670 Eric Allman
357 eae1d3ec Eric Allman
void                        _gdp_gob_unlock_trace(                // unlock the GOB mutex
358 fec93aac Eric Allman
                                                gdp_gob_t *gob,
359 3e98a709 Eric Allman
                                                const char *file,
360
                                                int line,
361
                                                const char *id);
362
363 fa7cfdb9 Eric Allman
gdp_gob_t                *_gdp_gob_incref_trace(                // increase reference count (trace)
364 c9f8e411 Eric Allman
                                                gdp_gob_t *gob,
365
                                                const char *file,
366
                                                int line,
367
                                                const char *id);
368 69afe7ee Eric Allman
369 fec93aac Eric Allman
void                        _gdp_gob_decref_trace(                // decrease reference count (trace)
370
                                                gdp_gob_t **gobp,
371 b8f93c05 Eric Allman
                                                bool keeplocked,
372 3e98a709 Eric Allman
                                                const char *file,
373
                                                int line,
374
                                                const char *id);
375
376 fec93aac Eric Allman
EP_STAT                        _gdp_gob_newname(                        // create new name based on metadata
377
                                                gdp_gob_t *gob);
378 504103dc Eric Allman
379 fec93aac Eric Allman
void                        _gdp_gob_dump(                                // dump for debugging
380
                                                const gdp_gob_t *gob,        // GOB to print
381 4102ad3a Eric Allman
                                                FILE *fp,                                // where to print it
382
                                                int detail,                                // how much to print
383
                                                int indent);                        // unused at this time
384
385 ee0cddb9 Eric Allman
EP_STAT                        _gdp_gob_init_vrfy_ctx(                // initialize for proof verification
386
                                                gdp_gob_t *gob);
387
388 fec93aac Eric Allman
EP_STAT                        _gdp_gob_create(                        // create a new GDP object
389 eae1d3ec Eric Allman
                                                gdp_md_t *gmd,
390 80da996e Eric Allman
                                                gdp_name_t logdname,
391 fec93aac Eric Allman
                                                gdp_gob_t **pgob);
392 a7ab7f37 Eric Allman
393 eae1d3ec Eric Allman
EP_STAT                        _gdp_gob_open(                                // open a GOB
394 fec93aac Eric Allman
                                                gdp_gob_t *gob,
395 f67d0170 Eric Allman
                                                gdp_cmd_t cmd,
396 eae1d3ec Eric Allman
                                                gdp_open_info_t *open_info,
397 a7ab7f37 Eric Allman
                                                gdp_chan_t *chan,
398
                                                uint32_t reqflags);
399
400 eae1d3ec Eric Allman
EP_STAT                        _gdp_gob_close(                                // close a GOB (handle)
401 4a6db795 Eric Allman
                                                gdp_gob_t *gob,
402
                                                gdp_chan_t *chan,
403
                                                uint32_t reqflags);
404
405 eae1d3ec Eric Allman
EP_STAT                        _gdp_gob_delete(                        // delete and close a GOB (handle)
406 4a6db795 Eric Allman
                                                gdp_gob_t *gob,
407 a7ab7f37 Eric Allman
                                                gdp_chan_t *chan,
408
                                                uint32_t reqflags);
409
410 eae1d3ec Eric Allman
EP_STAT                        _gdp_gob_read_by_recno(                        // read GOB record based on datum
411 fec93aac Eric Allman
                                                gdp_gob_t *gob,
412 d65c01e2 Eric Allman
                                                gdp_recno_t recno,
413 a7ab7f37 Eric Allman
                                                gdp_chan_t *chan,
414 d65c01e2 Eric Allman
                                                uint32_t reqflags,
415
                                                gdp_datum_t *datum);
416 a7ab7f37 Eric Allman
417 d65c01e2 Eric Allman
EP_STAT                        _gdp_gob_read_by_recno_async(        // read asynchronously
418 fec93aac Eric Allman
                                                gdp_gob_t *gob,
419 4aa32996 Eric Allman
                                                gdp_gin_t *gin,
420 8204d4b2 Eric Allman
                                                gdp_recno_t recno,
421 d65c01e2 Eric Allman
                                                uint32_t nrecs,
422 e2682ba9 Eric Allman
                                                gdp_event_cbfunc_t cbfunc,
423
                                                void *cbarg,
424 8204d4b2 Eric Allman
                                                gdp_chan_t *chan);
425 e2682ba9 Eric Allman
426 4aa32996 Eric Allman
EP_STAT                        _gdp_gob_append_sync(                // append a record (gdpd shared)
427 fec93aac Eric Allman
                                                gdp_gob_t *gob,
428 fa7cfdb9 Eric Allman
                                                int n_datums,
429
                                                gdp_datum_t **datums,
430
                                                gdp_hash_t *prevhash,
431 a7ab7f37 Eric Allman
                                                gdp_chan_t *chan,
432
                                                uint32_t reqflags);
433
434 fec93aac Eric Allman
EP_STAT                        _gdp_gob_append_async(                // append asynchronously
435
                                                gdp_gob_t *gob,
436 4aa32996 Eric Allman
                                                gdp_gin_t *gin,
437 fa7cfdb9 Eric Allman
                                                int n_datums,
438
                                                gdp_datum_t **datums,
439
                                                gdp_hash_t *prevhash,
440 e2682ba9 Eric Allman
                                                gdp_event_cbfunc_t cbfunc,
441
                                                void *cbarg,
442
                                                gdp_chan_t *chan,
443
                                                uint32_t reqflags);
444
445 eae1d3ec Eric Allman
EP_STAT                        _gdp_gin_subscribe(                        // subscribe to data
446 d65c01e2 Eric Allman
                                                gdp_gin_t *gin,
447 f67d0170 Eric Allman
                                                gdp_cmd_t cmd,
448 d65c01e2 Eric Allman
                                                gdp_recno_t start,
449 a7ab7f37 Eric Allman
                                                int32_t numrecs,
450 10125206 Eric Allman
                                                gdp_sub_qos_t *qos,
451 e2682ba9 Eric Allman
                                                gdp_event_cbfunc_t cbfunc,
452 d2647d1f Eric Allman
                                                void *cbarg);
453 a7ab7f37 Eric Allman
454 eae1d3ec Eric Allman
EP_STAT                        _gdp_gin_unsubscribe(                // delete subscriptions
455 fec93aac Eric Allman
                                                gdp_gin_t *gin,
456 9c515e64 Eric Allman
                                                gdp_event_cbfunc_t cbfunc,
457
                                                void *cbarg,
458
                                                uint32_t reqflags);
459
460 fec93aac Eric Allman
EP_STAT                        _gdp_gob_getmetadata(                // retrieve metadata
461
                                                gdp_gob_t *gob,
462 eae1d3ec Eric Allman
                                                gdp_md_t **gmdp,
463 a7ab7f37 Eric Allman
                                                gdp_chan_t *chan,
464
                                                uint32_t reqflags);
465
466 fec93aac Eric Allman
EP_STAT                        _gdp_gob_newsegment(                // create a new physical segment
467
                                                gdp_gob_t *gob,
468 f9b45862 Eric Allman
                                                gdp_chan_t *chan,
469
                                                uint32_t reqflags);
470
471 fec93aac Eric Allman
EP_STAT                        _gdp_gob_fwd_append(                // forward APPEND (replication)
472
                                                gdp_gob_t *gob,
473 8cc28925 Eric Allman
                                                gdp_datum_t *datum,
474 a35262c1 Eric Allman
                                                gdp_name_t to_server,
475
                                                gdp_event_cbfunc_t cbfunc,
476
                                                void *cbarg,
477 8cc28925 Eric Allman
                                                gdp_chan_t *chan,
478 a35262c1 Eric Allman
                                                uint32_t reqflags);
479 ca3929c7 Eric Allman
480 a7ab7f37 Eric Allman
/*
481 d65c01e2 Eric Allman
**  GIN functions
482
*/
483
484
#define GDP_GIN_ISGOOD(gin)                                                                                                \
485
                                ((gin) != NULL &&                                                                                \
486 eae1d3ec Eric Allman
                                 EP_UT_BITSET(GOBF_INUSE, (gin)->flags) &&                                \
487 d65c01e2 Eric Allman
                                 GDP_GOB_ISGOOD((gin)->gob))
488
#define GDP_GIN_ASSERT_ISLOCKED(gin)                                                                        \
489 c70b1607 Eric Allman
                        _gdp_bool_null(                                                                                                \
490 d65c01e2 Eric Allman
                                EP_ASSERT(GDP_GIN_ISGOOD(gin)) &&                                                \
491 eae1d3ec Eric Allman
                                EP_ASSERT(EP_UT_BITSET(GOBF_ISLOCKED, (gin)->flags)) &&        \
492 d65c01e2 Eric Allman
                                EP_THR_MUTEX_ASSERT_ISLOCKED(&(gin)->mutex) &&                        \
493
                                GDP_GOB_ASSERT_ISLOCKED((gin)->gob)                                                \
494
                        )
495
#define GDP_GIN_CHECK_RETURN_STAT(gin)                                                                        \
496
                        do                                                                                                                        \
497
                        {                                                                                                                        \
498
                                if (!EP_ASSERT((gin) != NULL))                                                        \
499 eae1d3ec Eric Allman
                                                return GDP_STAT_NULL_GOB;                                                \
500
                                if (!EP_ASSERT(EP_UT_BITSET(GOBF_INUSE, (gin)->flags)))        \
501 92243bf4 Eric Allman
                                                return GDP_STAT_LOG_NOT_OPEN;                                        \
502 d65c01e2 Eric Allman
                        } while (false)
503
#define GDP_GIN_CHECK_RETURN_NULL(gin)                                                                        \
504
                        do                                                                                                                        \
505
                        {                                                                                                                        \
506
                                if (!EP_ASSERT((gin) != NULL))                                                        \
507
                                                return NULL;                                                                        \
508 eae1d3ec Eric Allman
                                if (!EP_ASSERT(EP_UT_BITSET(GOBF_INUSE, (gin)->flags)))        \
509 d65c01e2 Eric Allman
                                                return NULL;                                                                        \
510
                        } while (false)
511
512 80da996e Eric Allman
gdp_gin_t                *_gdp_gin_new(                                // create new GIN from GOB
513
                                                gdp_gob_t *gob);
514
515
void                        _gdp_gin_free(                                // free a GIN
516
                                                gdp_gin_t *gin);
517 d65c01e2 Eric Allman
518
void                        _gdp_gin_lock_trace(                // lock the GIN mutex
519
                                                gdp_gin_t *gin,
520
                                                const char *file,
521
                                                int line,
522
                                                const char *id);
523 80da996e Eric Allman
#define _gdp_gin_lock(g)                _gdp_gin_lock_trace(g, __FILE__, __LINE__, #g)
524 d65c01e2 Eric Allman
525
void                        _gdp_gin_unlock_trace(                // unlock the GIN mutex
526
                                                gdp_gin_t *gin,
527
                                                const char *file,
528
                                                int line,
529
                                                const char *id);
530 80da996e Eric Allman
#define _gdp_gin_unlock(g)                _gdp_gin_unlock_trace(g, __FILE__, __LINE__, #g)
531 d65c01e2 Eric Allman
532
533
/*
534
**  GOB cache.
535
**
536
**                Implemented in gdp/gdp_gob_cache.c.
537
*/
538
539
EP_STAT                        _gdp_gob_cache_init(void);        // initialize cache
540
541
void                        _gdp_gob_cache_dump(                // print cache (for debugging)
542
                                                int plev,
543
                                                FILE *fp);
544
545
typedef EP_STAT        gcl_open_func(
546 eae1d3ec Eric Allman
                                                gdp_gin_t *gcl,
547 d65c01e2 Eric Allman
                                                void *open_info);
548
549
EP_STAT                        _gdp_gob_cache_get(                // get entry from cache
550
                                                gdp_name_t gcl_name,
551
                                                uint32_t flags,
552
                                                gdp_gob_t **pgob);
553
554
#define GGCF_NOCREATE                0                        // dummy
555
#define GGCF_CREATE                        0x00000001        // create cache entry if non existent
556
#define GGCF_GET_PENDING        0x00000002        // return "pending" entries
557
#define GGCF_PEEK                        0x00000004        // don't update cache usage time
558
559
void                        _gdp_gob_cache_add(                        // add entry to cache
560
                                                gdp_gob_t *gob);
561
562 eae1d3ec Eric Allman
void                        _gdp_gob_cache_changename(        // update the name of a cached GOB
563 d65c01e2 Eric Allman
                                                gdp_gob_t *gob,
564
                                                gdp_name_t newname);
565
566
void                        _gdp_gob_cache_drop(                // drop entry from cache
567 eae1d3ec Eric Allman
                                                gdp_gob_t *gob,                        // GOB to drop
568 d65c01e2 Eric Allman
                                                bool cleanup);                        // set if doing cache cleanup
569
570
void                        _gdp_gob_cache_reclaim(                // flush old entries
571
                                                time_t maxage);
572
573
void                        _gdp_gob_cache_shutdown(        // immediately shut down cache
574
                                                void (*shutdownfunc)(gdp_req_t *));
575
576
void                        _gdp_gob_touch(                                // move to front of LRU list
577
                                                gdp_gob_t *gob);
578
579 eae1d3ec Eric Allman
void                        _gdp_gob_cache_foreach(                // run over all cached GOBs
580 d65c01e2 Eric Allman
                                                void (*f)(gdp_gob_t *));
581
582
void                        _gdp_gob_pr_stats(                        // print (debug) GOB statistics
583
                                                FILE *fp);
584
585
586 2bd9199f Eric Allman
587 d65c01e2 Eric Allman
/*
588 eae1d3ec Eric Allman
**  GOB Open Information
589 c9f4745b Eric Allman
**
590
**                Passed from application into library to allow for all the
591
**                parameters we didn't think of when we first defined the API.
592 7d83fa37 Eric Allman
*/
593
594 eae1d3ec Eric Allman
struct gdp_open_info
595 7d83fa37 Eric Allman
{
596 ee6b5440 Eric Allman
        EP_CRYPTO_KEY                *signkey;                        // signing key
597 32dc12ee Eric Allman
        gdp_signkey_cb_t        *signkey_cb;                // callback to get signing key
598 c9f4745b Eric Allman
        void                                *signkey_udata;                // passed to signkey_cb
599
        uint32_t                        flags;                                // see below
600 7d83fa37 Eric Allman
};
601
602 c9f4745b Eric Allman
// flags values
603
#define GOIF_KEEP_IN_CACHE                0x00000001        // defer GOB free
604
#define GOIF_VERIFY_PROOF                0x00000002        // when reading, verify datum
605 49d76189 Eric Allman
#define GOIF_NO_SKEY_NONFATAL        0x00000004        // missing secret key not fatal
606 c9f4745b Eric Allman
607 7d83fa37 Eric Allman
608
/*
609 ca3929c7 Eric Allman
**  A Work Request (and associated Response)
610
**
611
**                A GDP request is packaged up in one of these things and
612
**                submitted.  Responses are returned in the same structure.
613
**
614 a104a10f Eric Allman
**                There are two PDU pointers:
615
**                * cpdu is the PDU with the command.  Generally this is
616
**                        kept around until the response is read in case you
617
**                        need to retransmit the command PDU.
618
**                * rpdu is the PDU with the response.
619
**
620
**                PDUs have an associated gdp_buf_t to store the actual
621
**                data.  That buffer does not have a write callback, so
622
**                it can be used without having any side effects.
623
**
624
**                The PDU includes the command/response code, the rid,
625
**                the record number, the timestamp, the data buffer,
626
**                and an optional signature buffer.
627 ca3929c7 Eric Allman
**
628 eae1d3ec Eric Allman
**                There can be mulitple requests active on a single GOB at
629 ca3929c7 Eric Allman
**                any time, but they should have unique rids.  Rids can be
630
**                reused if desired once an operation is complete.  Note:
631
**                some operations (e.g., subscriptions) can return multiple
632
**                results, but they will have the same rid.
633
**
634
**                Requests are potentially linked on lists.  Every request
635
**                that is active on a channel is linked to that channel
636
**                (with the GDP_REQ_ON_CHAN_LIST flag set); this is so that
637
**                requests can be cleaned up if the channel goes away.  At
638
**                this point we try to recover the channel, so this should
639
**                be rare, but that list is also used to find requests that
640
**                need to be timed out.
641
**
642
**                For active requests --- that is, requests that are either
643
**                waiting for a response (in _gdp_invoke) or represent
644
**                potential points for subscriptions --- are also linked to
645 eae1d3ec Eric Allman
**                the corresponding GOB, and will have the GDP_REQ_ON_GOB_LIST
646 ca3929c7 Eric Allman
**                flag set.  Subscription listeners also have the
647
**                GDP_REQ_CLT_SUBSCR flag set.  GDP_REQ_SRV_SUBSCR is used
648
**                by gdplogd to find the other end of the subscription, i.e,
649
**                subscription data producers.
650
**
651
**                In both the case of applications and gdplogd, requests may
652
**                get passed between threads.  To prevent someone from finding
653
**                a request on one of these lists and using it at the same time
654
**                someone else has it in use, you would like to lock the data
655
**                structure while it is active.  But you can't pass a mutex
656
**                between threads.  This is a particular problem if subscription
657
**                or multiread data comes in faster than it can be processed;
658
**                since the I/O thread is separate from the processing thread
659
**                things can clobber each other.
660
**
661
**                We solve this by assigning a state to each request:
662
**
663
**                FREE means that this request is on the free list.  It
664
**                        should never appear in any other context.
665
**                ACTIVE means that there is currently an operation taking
666
**                        place on the request, and no one other than the owner
667
**                        should use it.  If you need it, you can wait on the
668
**                        condition variable.
669
**                WAITING means that the request has been sent from a client
670
**                        to a server but hasn't gotten the response yet.  It
671
**                        shouldn't be possible for a WAITING request to also
672 eae1d3ec Eric Allman
**                        have an active subscription, but it will be in the GOB
673 ca3929c7 Eric Allman
**                        list.
674
**                IDLE means that the request is not free, but there is no
675
**                        operation in process on it.  This will generally be
676
**                        because it is a subscription that does not have any
677
**                        currently active data.
678
**
679
**                If you want to deliver data to a subscription, you have to
680
**                first make sure the req is in IDLE state, turn it to ACTIVE
681
**                state, and then process it.  If it is not in IDLE state you
682
**                sleep on the condition variable and try again.
683
**
684
**                Passing a request to another thread is basically the same.
685
**                The invariant is that any req being passed between threads
686
**                should always be ACTIVE.
687
**
688 4d6ff457 Eric Allman
**                In some cases requests may have pending events.  This
689
**                occurs for commands such as SUBSCRIBE or MULTIREAD when
690
**                the first data return appears before the ack for the
691
**                initial command has finished processing.  To avoid confusing
692
**                applications you have to defer these events until the app
693 e6319882 Eric Allman
**                knows that the command succeeded.  This list is sorted by
694
**                seqno (that is, the sequence number of the PDU as issued
695
**                by the sender).  The next expected seqno is stored in
696
**                seqnext.
697 4d6ff457 Eric Allman
**
698 ca3929c7 Eric Allman
**                Implemented in gdp_req.c.
699 a7ab7f37 Eric Allman
*/
700 39783844 Siqi Lin
701 ca3929c7 Eric Allman
struct gdp_req
702
{
703
        EP_THR_MUTEX                mutex;                // lock on this data structure
704
        EP_THR_COND                        cond;                // pthread wakeup condition variable
705 fec93aac Eric Allman
        uint16_t                        state;                // see below
706
        LIST_ENTRY(gdp_req)        goblist;        // linked list for cache management
707 ca3929c7 Eric Allman
        LIST_ENTRY(gdp_req)        chanlist;        // reqs associated with a given channel
708 fec93aac Eric Allman
        gdp_gob_t                        *gob;                // associated GDP Object handle
709 a104a10f Eric Allman
        gdp_pdu_t                        *cpdu;                // PDU for commands
710 08be4c9c Eric Allman
        gdp_pdu_t                        *rpdu;                // PDU for ack/nak responses
711 ca3929c7 Eric Allman
        gdp_chan_t                        *chan;                // the network channel for this req
712
        EP_STAT                                stat;                // status code from last operation
713 02de7463 Eric Allman
        gdp_recno_t                        nextrec;        // next record to return (subscriptions)
714 e95fef13 Eric Allman
        int64_t                                s_results;        // number of results sent
715 ca3929c7 Eric Allman
        int32_t                                numrecs;        // remaining number of records to return
716
        uint32_t                        flags;                // see below
717
        void                                (*postproc)(struct gdp_req *);
718
                                                                        // do post processing after ack sent
719 94e663bc Eric Allman
        EP_TIME_SPEC                act_ts;                // timestamp of last successful activity
720
        EP_TIME_SPEC                sub_ts;                // time of current subscription lease start
721 9c515e64 Eric Allman
        gdp_event_cbfunc_t        sub_cbfunc;        // callback function (subscribe & async I/O)
722
        void                                *sub_cbarg;        // user-supplied opaque data to cb
723 fec93aac Eric Allman
724
        // these are only of interest in clients, never in gdplogd
725 4aa32996 Eric Allman
        gdp_gin_t                        *gin;                // GIN handle (client only, may be NULL)
726 e95fef13 Eric Allman
        int64_t                                r_results;        // number of results received so far
727 4d6ff457 Eric Allman
        struct gev_list                events;                // pending events (see above)
728 e6319882 Eric Allman
        gdp_seqno_t                        seqnext;        // next expected seqno
729 e95fef13 Eric Allman
        struct event                *ev_to;                // event timeout (to scan pending events)
730 ca3929c7 Eric Allman
};
731 174e9f6d Eric Allman
732 ca3929c7 Eric Allman
// states
733
#define GDP_REQ_FREE                        0                        // request is free
734
#define GDP_REQ_ACTIVE                        1                        // currently being processed
735
#define GDP_REQ_WAITING                        2                        // waiting on cond variable
736
#define GDP_REQ_IDLE                        3                        // subscription waiting for data
737 71eb3fe4 Eric Allman
738 ca3929c7 Eric Allman
// flags
739
#define GDP_REQ_ASYNCIO                        0x00000001        // async I/O operation
740
#define GDP_REQ_DONE                        0x00000002        // operation complete
741
#define GDP_REQ_CLT_SUBSCR                0x00000004        // client-side subscription
742
#define GDP_REQ_SRV_SUBSCR                0x00000008        // server-side subscription
743
#define GDP_REQ_PERSIST                        0x00000010        // request persists after response
744
#define GDP_REQ_SUBUPGRADE                0x00000020        // can upgrade to subscription
745
#define GDP_REQ_ALLOC_RID                0x00000040        // force allocation of new rid
746 fec93aac Eric Allman
#define GDP_REQ_ON_GOB_LIST                0x00000080        // this is on a GOB list
747 ca3929c7 Eric Allman
#define GDP_REQ_ON_CHAN_LIST        0x00000100        // this is on a channel list
748 ee0cddb9 Eric Allman
#define GDP_REQ_VRFY_CONTENT        0x00000200        // verify content proof
749 29f683eb Eric Allman
#define GDP_REQ_ROUTEFAIL                0x00000400        // fail immediately on route failure
750 a7ab7f37 Eric Allman
751 b912063e Eric Allman
EP_STAT                        _gdp_req_new(                                // create new request
752 f67d0170 Eric Allman
                                                gdp_cmd_t cmd,
753 fec93aac Eric Allman
                                                gdp_gob_t *gob,
754 9509f13b Eric Allman
                                                gdp_chan_t *chan,
755 7a52336b Eric Allman
                                                gdp_pdu_t *pdu,
756 0314a7a7 Eric Allman
                                                uint32_t flags,
757
                                                gdp_req_t **reqp);
758 cd2ef2a6 Eric Allman
759 b912063e Eric Allman
void                        _gdp_req_free(                                // free old request
760 283110f2 Eric Allman
                                                gdp_req_t **reqp);
761 0314a7a7 Eric Allman
762 18624361 Eric Allman
EP_STAT                        _gdp_req_lock(                                // lock a request mutex
763 ca3929c7 Eric Allman
                                                gdp_req_t *);
764
765
void                        _gdp_req_unlock(                        // unlock a request mutex
766
                                                gdp_req_t *);
767
768 eae1d3ec Eric Allman
gdp_req_t                *_gdp_req_find(                                // find a request in a GOB
769 fec93aac Eric Allman
                                                gdp_gob_t *gob, gdp_rid_t rid);
770 ca3929c7 Eric Allman
771
gdp_rid_t                _gdp_rid_new(                                // create new request id
772 fec93aac Eric Allman
                                                gdp_gob_t *gob, gdp_chan_t *chan);
773 ca3929c7 Eric Allman
774 8cc28925 Eric Allman
EP_STAT                        _gdp_req_send(                                // send request to daemon (async)
775 ca3929c7 Eric Allman
                                                gdp_req_t *req);
776
777 eae1d3ec Eric Allman
EP_STAT                        _gdp_req_unsend(                        // pull failed request off GOB list
778 ca3929c7 Eric Allman
                                                gdp_req_t *req);
779
780 b912063e Eric Allman
EP_STAT                        _gdp_req_dispatch(                        // do local req processing
781 a104a10f Eric Allman
                                                gdp_req_t *req,
782
                                                int cmd);
783 0314a7a7 Eric Allman
784 8cc28925 Eric Allman
EP_STAT                        _gdp_invoke(                                // send request to daemon (sync)
785 b912063e Eric Allman
                                                gdp_req_t *req);
786 cd2ef2a6 Eric Allman
787 eae1d3ec Eric Allman
void                        _gdp_req_freeall(                        // free all requests in GOB list
788 fec93aac Eric Allman
                                                gdp_gob_t *gob,
789
                                                gdp_gin_t *gin,
790 cf71c5ea Eric Allman
                                                void (*shutdownfunc)(gdp_req_t *));
791 51775f02 Eric Allman
792 b912063e Eric Allman
void                        _gdp_req_dump(                                // print (debug) request
793 0d8c13e8 Eric Allman
                                                const gdp_req_t *req,
794 4102ad3a Eric Allman
                                                FILE *fp,
795
                                                int detail,
796
                                                int indent);
797 8dd98fb6 Eric Allman
798 a08413a6 Eric Allman
void                        _gdp_req_pr_stats(                        // print (debug) statistics
799
                                                FILE *fp);
800
801 2bd9199f Eric Allman
EP_STAT                        _gdp_req_ack_resp(                        // helper: create ACK response
802
                                                gdp_req_t *req,                        // active request
803
                                                gdp_cmd_t ack_type);        // actual ACK command
804
805
EP_STAT                        _gdp_req_nak_resp(                        // helper: create NAK response
806
                                                gdp_req_t *req,                        // active request
807
                                                gdp_cmd_t nak_type,                // actual NAK command
808
                                                const char *detail,                // text detail
809
                                                EP_STAT estat);                        // status code detail
810
811 5a73c6ad Eric Allman
812
/*
813
**  Channel and I/O Event support
814
*/
815
816 6c983368 Eric Allman
// extended channel information (passed as channel "cdata")
817 5a73c6ad Eric Allman
struct gdp_chan_x
818
{
819
        struct req_head                reqs;                        // reqs associated with this channel
820
        EP_STAT                                (*connect_cb)(        // called on connection established
821
                                                        gdp_chan_t *chan);
822 b6fd1b13 Eric Allman
        long                                adv_intvl;                // advertising interval
823
        struct event                *adv_timer;                // re-advertise event (gdplogd only)
824 5a73c6ad Eric Allman
};
825
826
// functions used internally related to channel I/O
827
EP_STAT                        _gdp_io_recv(
828 d65c01e2 Eric Allman
                                                gdp_chan_t *chan,
829
                                                gdp_name_t src,
830
                                                gdp_name_t dst,
831 5edf4ad2 Eric Allman
                                                gdp_seqno_t seqno,
832 d65c01e2 Eric Allman
                                                gdp_buf_t *payload_buf,
833
                                                size_t payload_len);
834 5a73c6ad Eric Allman
835
EP_STAT                        _gdp_io_event(
836
                                                gdp_chan_t *chan,
837
                                                uint32_t flags);
838
839 d65c01e2 Eric Allman
// router control information
840
EP_STAT                        _gdp_router_event(
841
                                                gdp_chan_t *chan,
842
                                                gdp_name_t src,
843
                                                gdp_name_t dst,
844
                                                size_t payload_len,
845
                                                EP_STAT estat);
846
847 5a73c6ad Eric Allman
// I/O event handling
848
struct event_loop_info
849
{
850
        const char                *where;
851
};
852
853
void                        *_gdp_run_event_loop(
854
                                                void *eli_);
855 39783844 Siqi Lin
856 a1e5eca3 Eric Allman
void                        _gdp_stop_event_loop(void);
857
858 e95fef13 Eric Allman
typedef void        libevent_event_t(
859
                                                evutil_socket_t sock,
860
                                                short what,
861
                                                void *cbarg);
862
863 e6319882 Eric Allman
void                        _gdp_evloop_timer_set(
864
                                                uint32_t timeout,                        // in timeout usec
865 e95fef13 Eric Allman
                                                libevent_event_t *cbfunc,        // ... call cbfunc
866 e6319882 Eric Allman
                                                void *cbarg,                                // ... with this arg
867
                                                struct event **pev);                // ... stored here
868
869
void                        _gdp_evloop_timer_clr(
870
                                                struct event **pev);
871 e95fef13 Eric Allman
872 cf71c5ea Eric Allman
873
/*
874 d65c01e2 Eric Allman
**  Protobuf message handling.  These are only for the unpacked
875
**  (in memory, unserialized) version; the rest is hidden in
876
**  gdp_pdu.[ch].
877
*/
878
879
gdp_msg_t                *_gdp_msg_new(                                // create new message
880
                                        gdp_cmd_t cmd,
881
                                        gdp_rid_t rid,
882 e6319882 Eric Allman
                                        gdp_l5seqno_t l5seqno);
883 d65c01e2 Eric Allman
884
void                        _gdp_msg_free(                                // free a message
885
                                        gdp_msg_t **pmsg);
886
887
void                        _gdp_msg_dump(                                // print a message for debugging
888
                                        const gdp_msg_t *msg,
889 4a89fdda Eric Allman
                                        FILE *fp,
890
                                        int indent);
891 d65c01e2 Eric Allman
892
893
/*
894 ca3929c7 Eric Allman
**  Structure used for registering command functions
895
**
896
**                The names are already known to the GDP library, so this is just
897
**                to bind functions that implement the individual commands.
898
*/
899
900
typedef EP_STAT        cmdfunc_t(                        // per command dispatch entry
901
                                        gdp_req_t *req);        // the request to be processed
902
903
struct cmdfuncs
904
{
905
        int                        cmd;                                // command number
906
        cmdfunc_t        *func;                                // pointer to implementing function
907
};
908
909
void                        _gdp_register_cmdfuncs(
910
                                                struct cmdfuncs *);
911
912
const char                *_gdp_proto_cmd_name(                // return printable cmd name
913
                                                uint8_t cmd);
914
915 ee6b5440 Eric Allman
#define GDP_RECLAIM_AGE_DEF                300L                // default reclaim age (sec)
916
917 ca3929c7 Eric Allman
918
/*
919 cf71c5ea Eric Allman
**  Advertising.
920
*/
921
922 08709feb Eric Allman
EP_STAT                        _gdp_advertise_me(                        // advertise me only
923 5a73c6ad Eric Allman
                                                gdp_chan_t *chan,
924 0c9fce43 Eric Allman
                                                int cmd,
925
                                                void *ctx);
926 08709feb Eric Allman
927 a7ab7f37 Eric Allman
/*
928 1440421a Eric Allman
**  Subscriptions.
929 a7ab7f37 Eric Allman
*/
930
931 b068acef Eric Allman
#define GDP_SUBSCR_REFRESH_DEF        60L                        // default refresh interval (sec)
932
#define GDP_SUBSCR_TIMEOUT_DEF        180L                // default timeout (sec)
933
934 3bc20136 Eric Allman
extern EP_THR_MUTEX                _GdpSubscriptionMutex;
935 44a5b0ef Eric Allman
extern struct req_head        _GdpSubscriptionRequests;
936 3bc20136 Eric Allman
937 1440421a Eric Allman
void                        _gdp_subscr_lost(                        // subscription disappeared
938
                                                gdp_req_t *req);
939
940
void                        _gdp_subscr_poke(                        // test subscriptions still alive
941
                                                gdp_chan_t *chan);
942
943
/*
944 5a73c6ad Eric Allman
**  Initialization and Maintenance.
945
*/
946
947
void                        _gdp_newname(gdp_name_t gname,
948 eae1d3ec Eric Allman
                                                gdp_md_t *gmd);
949 5a73c6ad Eric Allman
950
void                        _gdp_reclaim_resources(                // reclaim system resources
951
                                                void *);                                // unused
952
953
void                        _gdp_reclaim_resources_init(
954
                                                void (*f)(int, short, void *));
955
956
void                        _gdp_dump_state(int plev);
957
958 f67d0170 Eric Allman
gdp_cmd_t                _gdp_acknak_from_estat(                // produce acknak code from status
959 d65c01e2 Eric Allman
                                                EP_STAT estat,                        // status to evaluate
960 f67d0170 Eric Allman
                                                gdp_cmd_t def);                        // use this if nothing better...
961 d65c01e2 Eric Allman
962 5a73c6ad Eric Allman
/*
963 f80ae9c0 Eric Allman
**  Cryptography support
964
*/
965
966 9a47c6c7 Eric Allman
EP_CRYPTO_KEY        *_gdp_crypto_skey_read(                // read a secret key
967 32dc12ee Eric Allman
                                                const char *searchpath,
968
                                                const char *filename);
969 fa7cfdb9 Eric Allman
void                        _gdp_sign_metadata(                        // sign the metadata
970 eae1d3ec Eric Allman
                                                gdp_gin_t *gin);
971 f80ae9c0 Eric Allman
972 4102ad3a Eric Allman
973 a257266f Eric Allman
/*
974 a72e8d44 Eric Allman
**  Orders for lock acquisition
975
**                Lower numbered locks should be acquired before higher numbered locks.
976
*/
977
978 fec93aac Eric Allman
#define GDP_MUTEX_LORDER_GIN                6
979
#define GDP_MUTEX_LORDER_GOBCACHE        8
980
#define GDP_MUTEX_LORDER_GOB                10
981
#define GDP_MUTEX_LORDER_REQ                12
982
#define GDP_MUTEX_LORDER_CHAN                14
983 59f6ff3f Eric Allman
#define GDP_MUTEX_LORDER_DATUM                18
984 7882a3b0 Eric Allman
#define GDP_MUTEX_LORDER_LEAF                31        // freelists, etc.
985 a72e8d44 Eric Allman
986
987
/*
988 4a89fdda Eric Allman
**  Utility routines
989
*/
990
991
const char                *_gdp_pr_indent(                        // return indenting for debug output
992
                                                int indent);
993
994 92adefd5 Eric Allman
void                        _gdp_adm_readparams(                // read admin params w/ versioning
995
                                                const char *name);                // base of config name
996
997
EP_STAT                        _gdp_adm_path_find(                        // find file in path via getstrparam
998
                                                const char *dir_param,
999
                                                const char *dir_def,
1000
                                                const char *file_param,
1001
                                                const char *file_def,
1002
                                                char *path_buf,
1003
                                                size_t path_buf_len);
1004
1005 3e95a6ed Eric Allman
void                        _gdp_show_elapsed(                        // show elapsed time
1006
                                                const char *func,                // function name
1007 21a05dde Eric Allman
                                                gdp_cmd_t cmd,                        // associated command
1008 3e95a6ed Eric Allman
                                                EP_TIME_SPEC *start);        // starting time
1009
1010 4a89fdda Eric Allman
1011
/*
1012 a257266f Eric Allman
**  Convenience macros
1013
*/
1014
1015
#define MICROSECONDS        * INT64_C(1000)
1016
#define MILLISECONDS        * INT64_C(1000000)
1017
#define SECONDS                        * INT64_C(1000000000)
1018
1019
1020 fa7cfdb9 Eric Allman
/*
1021
**  Low level support for cracking protocol, computing hashes, etc.
1022
*/
1023
1024
#define PUT8(v) \
1025
                { \
1026
                        *pbp++ = ((v) & 0xff); \
1027
                }
1028
#define PUT16(v) \
1029
                { \
1030
                        *pbp++ = ((v) >> 8) & 0xff; \
1031
                        *pbp++ = ((v) & 0xff); \
1032
                }
1033
#define PUT24(v) \
1034
                { \
1035
                        *pbp++ = ((v) >> 16) & 0xff; \
1036
                        *pbp++ = ((v) >> 8) & 0xff; \
1037
                        *pbp++ = ((v) & 0xff); \
1038
                }
1039
#define PUT32(v) \
1040
                { \
1041
                        *pbp++ = ((v) >> 24) & 0xff; \
1042
                        *pbp++ = ((v) >> 16) & 0xff; \
1043
                        *pbp++ = ((v) >> 8) & 0xff; \
1044
                        *pbp++ = ((v) & 0xff); \
1045
                }
1046
#define PUT48(v) \
1047
                { \
1048
                        *pbp++ = ((v) >> 40) & 0xff; \
1049
                        *pbp++ = ((v) >> 32) & 0xff; \
1050
                        *pbp++ = ((v) >> 24) & 0xff; \
1051
                        *pbp++ = ((v) >> 16) & 0xff; \
1052
                        *pbp++ = ((v) >> 8) & 0xff; \
1053
                        *pbp++ = ((v) & 0xff); \
1054
                }
1055
#define PUT64(v) \
1056
                { \
1057
                        *pbp++ = ((v) >> 56) & 0xff; \
1058
                        *pbp++ = ((v) >> 48) & 0xff; \
1059
                        *pbp++ = ((v) >> 40) & 0xff; \
1060
                        *pbp++ = ((v) >> 32) & 0xff; \
1061
                        *pbp++ = ((v) >> 24) & 0xff; \
1062
                        *pbp++ = ((v) >> 16) & 0xff; \
1063
                        *pbp++ = ((v) >> 8) & 0xff; \
1064
                        *pbp++ = ((v) & 0xff); \
1065
                }
1066
1067
#define GET8(v) \
1068
                { \
1069
                                v  = *pbp++; \
1070
                }
1071
#define GET16(v) \
1072
                { \
1073
                                v  = *pbp++ << 8; \
1074
                                v |= *pbp++; \
1075
                }
1076
#define GET24(v) \
1077
                { \
1078
                                v  = *pbp++ << 16; \
1079
                                v |= *pbp++ << 8; \
1080
                                v |= *pbp++; \
1081
                }
1082
#define GET32(v) \
1083
                { \
1084
                                v  = *pbp++ << 24; \
1085
                                v |= *pbp++ << 16; \
1086
                                v |= *pbp++ << 8; \
1087
                                v |= *pbp++; \
1088
                }
1089
#define GET48(v) \
1090
                { \
1091
                                v  = ((uint64_t) *pbp++) << 40; \
1092
                                v |= ((uint64_t) *pbp++) << 32; \
1093
                                v |= ((uint64_t) *pbp++) << 24; \
1094
                                v |= ((uint64_t) *pbp++) << 16; \
1095
                                v |= ((uint64_t) *pbp++) << 8; \
1096
                                v |= ((uint64_t) *pbp++); \
1097
                }
1098
#define GET64(v) \
1099
                { \
1100
                                v  = ((uint64_t) *pbp++) << 56; \
1101
                                v |= ((uint64_t) *pbp++) << 48; \
1102
                                v |= ((uint64_t) *pbp++) << 40; \
1103
                                v |= ((uint64_t) *pbp++) << 32; \
1104
                                v |= ((uint64_t) *pbp++) << 24; \
1105
                                v |= ((uint64_t) *pbp++) << 16; \
1106
                                v |= ((uint64_t) *pbp++) << 8; \
1107
                                v |= ((uint64_t) *pbp++); \
1108
                }
1109
1110
1111 f0313e1d Eric Allman
#endif // _GDP_PRIV_H_