libasyncd
ad_server.h
Go to the documentation of this file.
1 /******************************************************************************
2  * LibAsyncd
3  *
4  * Copyright (c) 2014 Seungyoung Kim.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  *****************************************************************************/
28 
29 /**
30  * ad_server header file
31  *
32  * @file ad_server.h
33  */
34 
35 #ifndef _AD_SERVER_H
36 #define _AD_SERVER_H
37 
38 #include <event2/event.h>
39 #include <event2/buffer.h>
40 #include <event2/bufferevent.h>
41 #include <openssl/ssl.h>
42 #include "qlibc/qlibc.h"
43 
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47 
48 /*---------------------------------------------------------------------------*\
49 | TYPEDEFS |
50 \*---------------------------------------------------------------------------*/
51 typedef struct ad_server_s ad_server_t;
52 typedef struct ad_conn_s ad_conn_t;
54 typedef struct ad_hook_s ad_hook_t;
55 
56 /**
57  * These flags are used for ad_log_level();
58  */
59 enum ad_log_e{
66 };
67 
68 /*---------------------------------------------------------------------------*\
69 | SERVER OPTIONS |
70 \*---------------------------------------------------------------------------*/
71 
72 /**
73  * Server option names and default values.
74  */
75 #define AD_SERVER_OPTIONS { \
76  { "server.port", "8080" }, \
77  \
78  /* Addr format IPv4="1.2.3.4", IPv6="1:2:3:4:5:6", Unix="/path" */ \
79  { "server.addr", "0.0.0.0" }, \
80  \
81  { "server.backlog", "128" }, \
82  \
83  /* Set read timeout seconds. 0 means no timeout. */ \
84  { "server.timeout", "0" }, \
85  \
86  /* SSL options */ \
87  { "server.enable_ssl", "0" }, \
88  { "server.ssl_cert", "/usr/local/etc/ad_server/ad_server.crt" }, \
89  { "server.ssl_pkey", "/usr/local/etc/ad_server/ad_server.key" }, \
90  \
91  /* Enable or disable request pipelining, this change AD_DONE's behavior */ \
92  { "server.request_pipelining", "1" }, \
93  \
94  /* Run server in a separate thread */ \
95  { "server.daemon", "0" }, \
96  \
97  /* Collect resources after stop */ \
98  { "server.free_on_stop", "1" }, \
99  \
100  /* End of array marker. Do not remove */ \
101  { "", "_END_" } \
102 };
103 
104 /*---------------------------------------------------------------------------*\
105 | USER-CALLBACK |
106 \*---------------------------------------------------------------------------*/
107 
108 /**
109  * User callback(hook) prototype.
110  */
111 typedef int (*ad_callback)(short event, ad_conn_t *conn, void *userdata);
112 typedef void (*ad_userdata_free_cb)(ad_conn_t *conn, void *userdata);
113 
114 /**
115  * Return values of user callback.
116  */
118  /*!< I'm done with this request. Escalate to other hooks. */
119  AD_OK = 0,
120  /*!< I'll handle the buffer directly this time, skip next hook */
122  /*!< We're done with this request but keep the connection open. */
124  /*!< We're done with this request. Close as soon as we sent all data out. */
126 };
127 
128 /**
129  * Event types
130  */
131 #define AD_EVENT_INIT (1) /*!< Call once upon new connection. */
132 #define AD_EVENT_READ (1 << 1) /*!< Call on read */
133 #define AD_EVENT_WRITE (1 << 2) /*!< Call on write. */
134 #define AD_EVENT_CLOSE (1 << 3) /*!< Call before closing. */
135 #define AD_EVENT_TIMEOUT (1 << 4) /*!< Timeout indicator, this flag will be set with AD_EVENT_CLOSE. */
136 #define AD_EVENT_SHUTDOWN (1 << 5) /*!< Shutdown indicator, this flag will be set with AD_EVENT_CLOSE. */
137 
138 /**
139  * Defaults
140  */
141 #define AD_NUM_USERDATA (2) /*!< Number of userdata. Currently 0 is for userdata, 1 is for extra. */
142 
143 /*---------------------------------------------------------------------------*\
144 | DATA STRUCTURES |
145 \*---------------------------------------------------------------------------*/
146 
147 /**
148  * Server info container.
149  */
150 struct ad_server_s {
151  int errcode; /*!< exit status. 0 for normal exit, non zero for error. */
152  pthread_t *thread; /*!< thread object. not null if server runs as a thread */
153 
154  qhashtbl_t *options; /*!< server options */
155  qhashtbl_t *stats; /*!< internal statistics */
156  qlist_t *hooks; /*!< list of registered hooks */
157  struct evconnlistener *listener; /*!< listener */
158  struct event_base *evbase; /*!< event base */
159  SSL_CTX *sslctx; /*!< SSL connection support */
160 
161  struct bufferevent *notify_buffer; /*!< internal notification channel */
162 };
163 
164 /**
165  * Connection structure.
166  */
167 struct ad_conn_s {
168  ad_server_t *server; /*!< reference pointer to server */
169  struct bufferevent *buffer; /*!< reference pointer to buffer */
170  struct evbuffer *in; /*!< in buffer */
171  struct evbuffer *out; /*!< out buffer */
172  int status; /*!< hook status such as AD_OK */
173 
174  void *userdata[2]; /*!< userdata[0] for end user, userdata[1] for extra */
175  ad_userdata_free_cb userdata_free_cb[2]; /*!< callback to release user data */
176  char *method; /*!< request method. set by protocol handler */
177 };
178 
179 /*----------------------------------------------------------------------------*\
180 | PUBLIC FUNCTIONS |
181 \*----------------------------------------------------------------------------*/
182 enum ad_log_e ad_log_level(enum ad_log_e log_level);
183 
184 extern ad_server_t *ad_server_new(void);
185 extern int ad_server_start(ad_server_t *server);
186 extern void ad_server_stop(ad_server_t *server);
187 extern void ad_server_free(ad_server_t *server);
188 extern void ad_server_global_free(void);
189 
190 extern void ad_server_set_option(ad_server_t *server, const char *key, const char *value);
191 extern char *ad_server_get_option(ad_server_t *server, const char *key);
192 extern int ad_server_get_option_int(ad_server_t *server, const char *key);
193 extern SSL_CTX *ad_server_get_ssl_ctx(ad_server_t *server);
194 extern qhashtbl_t *ad_server_get_stats(ad_server_t *server, const char *key);
195 
196 extern void ad_server_register_hook(ad_server_t *server, ad_callback cb, void *userdata);
197 extern void ad_server_register_hook_on_method(ad_server_t *server, const char *method,
198  ad_callback cb, void *userdata);
199 
200 extern void *ad_conn_set_userdata(ad_conn_t *conn, const void *userdata, ad_userdata_free_cb free_cb);
201 extern void *ad_conn_get_userdata(ad_conn_t *conn);
202 extern void *ad_conn_set_extra(ad_conn_t *conn, const void *extra, ad_userdata_free_cb free_cb);
203 extern void *ad_conn_get_extra(ad_conn_t *conn);
204 extern char *ad_conn_set_method(ad_conn_t *conn, char *method);
205 
206 /*---------------------------------------------------------------------------*\
207 | INTERNAL USE ONLY |
208 \*---------------------------------------------------------------------------*/
209 #ifndef _DOXYGEN_SKIP
210 #endif /* _DOXYGEN_SKIP */
211 
212 #ifdef __cplusplus
213 }
214 #endif
215 
216 #endif /*_AD_SERVER_H */