1 /* distcache, Distributed Session Caching technology
2  * Copyright (C) 2000-2003  Geoff Thorpe, and Cryptographic Appliances, Inc.
3  * Copyright (C) 2004       The Distcache.org project
4  *
5  * This library is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU Lesser General Public License as published by the Free
7  * Software Foundation; using version 2.1 of the License. The copyright holders
8  * may elect to allow the application of later versions of the License to this
9  * software, please contact the author (geoff@distcache.org) if you wish us to
10  * review any later version released by the Free Software Foundation.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
15  * details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation, Inc.,
19  * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21 #ifndef HEADER_DISTCACHE_DC_SERVER_H
22 #define HEADER_DISTCACHE_DC_SERVER_H
23 
24 /* Boundaries on input. Function callers should observe these limits as the
25  * functions often test these with assert() statements (so they disapper in
26  * non-debug builds, and in debug builds they blow up error situations rather
27  * suddenly). */
28 
29 /* The minimum/maximum size of a cache (in terms of sessions). NB: the maximum
30  * allows for a cache that will be over 8Mb, even if filled with small sessions.
31  * If filled with large sessions, this could be much larger still. */
32 #define DC_CACHE_MIN_SIZE		64
33 #define DC_CACHE_MAX_SIZE		60000
34 /* The maximum number of milli-seconds we let sessions live for */
35 #define DC_MAX_EXPIRY			(unsigned long)604800000 /* 7 days */
36 /* The largest session object we allow. For SSL/TLS, if architectures encode
37  * peer certificates raw into sessions (rather than clipping them to the
38  * essentials) and client certs start containing photos or mpegs, this might be
39  * a problem. Otherwise it should be more than enough! */
40 #define DC_MAX_DATA_LEN			32768
41 
42 /* Our black-box types */
43 typedef struct st_DC_SERVER DC_SERVER;
44 typedef struct st_DC_CLIENT DC_CLIENT;
45 typedef struct st_DC_CACHE  DC_CACHE;
46 
47 /* This structure holds the "cache" implementation. It allows callers to provide
48  * their own form of cache storage (or otherwise, in the case of proxies). */
49 typedef struct st_DC_CACHE_cb {
50 	DC_CACHE *	(*cache_new)(unsigned int max_sessions);
51 	void		(*cache_free)(DC_CACHE *cache);
52 	int		(*cache_add)(DC_CACHE *cache,
53 				const struct timeval *now,
54 				unsigned long timeout_msecs,
55 				const unsigned char *session_id,
56 				unsigned int session_id_len,
57 				const unsigned char *data,
58 				unsigned int data_len);
59 	/* If 'store' is NULL, this returns the length of a session without
60 	 * copying it. */
61 	unsigned int	(*cache_get)(DC_CACHE *cache,
62 				const struct timeval *now,
63 				const unsigned char *session_id,
64 				unsigned int session_id_len,
65 				unsigned char *store,
66 				unsigned int store_size);
67 	int		(*cache_remove)(DC_CACHE *cache,
68 				const struct timeval *now,
69 				const unsigned char *session_id,
70 				unsigned int session_id_len);
71 	int		(*cache_have)(DC_CACHE *cache,
72 				const struct timeval *now,
73 				const unsigned char *session_id,
74 				unsigned int session_id_len);
75 	unsigned int	(*cache_num_items)(DC_CACHE *cache,
76 				const struct timeval *now);
77 } DC_CACHE_cb;
78 
79 /* Flags for use in DC_SERVER_new_client() */
80 #define DC_CLIENT_FLAG_NOFREE_CONN		(unsigned int)0x0001
81 #define DC_CLIENT_FLAG_IN_SERVER		(unsigned int)0x0002
82 
83 /* Create a new session cache server. NB: DC_SERVER_set_[default_]cache()
84  * must have been called prior to creating a server with this function. */
85 DC_SERVER *DC_SERVER_new(unsigned int max_sessions);
86 
87 /* Destroy a session cache server (NB: all clients that aren't created with
88  * DC_CLIENT_FLAG_IN_SERVER should be destroyed in advance). */
89 void DC_SERVER_free(DC_SERVER *ctx);
90 
91 /* This function causes the builtin session cache implementation to be used in
92  * all "DC_SERVER"s created. Implemented in sess_serve_cache.c, so that if
93  * the following function is used rather than this one, the builtin cache
94  * implementation won't be linked into the application. */
95 int DC_SERVER_set_default_cache(void);
96 
97 /* This function causes a custom cache implementation to be used in all
98  * "DC_SERVER"s created. */
99 int DC_SERVER_set_cache(const DC_CACHE_cb *impl);
100 
101 /* Find out the number of session items currently stored in the server.
102  * Automatically flushes expired cache items before deciding the result. */
103 unsigned int DC_SERVER_items_stored(DC_SERVER *ctx,
104 				const struct timeval *now);
105 
106 /* Reset the server's counter of cache operations to zero. */
107 void DC_SERVER_reset_operations(DC_SERVER *ctx);
108 
109 /* Count the number of cache operations (successful or otherwise) since the last
110  * call to 'DC_SERVER_reset_operations'. */
111 unsigned long DC_SERVER_num_operations(DC_SERVER *ctx);
112 
113 /* Create a new client for a server */
114 DC_CLIENT *DC_SERVER_new_client(DC_SERVER *ctx,
115 				NAL_CONNECTION *conn,
116 				unsigned int flags);
117 
118 /* Remove a client from a server */
119 int DC_SERVER_del_client(DC_CLIENT *clnt);
120 
121 /* Do logical processing of a client. A zero return value indicates a fatal
122  * error (eg. data corruption) and that the client should be destroyed by the
123  * caller. */
124 int DC_SERVER_process_client(DC_CLIENT *clnt,
125 				const struct timeval *now);
126 
127 /* This function is only useful for clients created with the
128  * DC_CLIENT_FLAG_IN_SERVER flag. It handles the post-processing for such
129  * clients (including closing dead connections, etc). */
130 int DC_SERVER_clients_io(DC_SERVER *ctx, const struct timeval *now);
131 
132 /* Boolean */
133 int DC_SERVER_clients_empty(const DC_SERVER *ctx);
134 
135 #endif /* !defined(HEADER_DISTCACHE_DC_SERVER_H) */
136