jabberd2  2.3.4
sx.h
Go to the documentation of this file.
1 /*
2  * jabberd - Jabber Open Source Server
3  * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
4  * Ryan Eatmon, Robert Norris
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
19  */
20 
21 #ifndef INCL_SX_H
22 #define INCL_SX_H
23 
24 #ifdef HAVE_CONFIG_H
25 # include <config.h>
26 #endif
27 
28 #include "ac-stdint.h"
29 
30 #include <expat.h>
31 #include <util/util.h>
32 
33 /* jabberd2 Windows DLL */
34 #ifndef JABBERD2_API
35 # ifdef _WIN32
36 # ifdef JABBERD2_EXPORTS
37 # define JABBERD2_API __declspec(dllexport)
38 # else /* JABBERD2_EXPORTS */
39 # define JABBERD2_API __declspec(dllimport)
40 # endif /* JABBERD2_EXPORTS */
41 # else /* _WIN32 */
42 # define JABBERD2_API extern
43 # endif /* _WIN32 */
44 #endif /* JABBERD2_API */
45 
46 #ifdef __cplusplus
47 extern "C" {
48 #endif
49 
50 /* forward declarations */
51 typedef struct _sx_st *sx_t;
52 typedef struct _sx_env_st *sx_env_t;
53 typedef struct _sx_plugin_st *sx_plugin_t;
54 
56 typedef enum {
57  event_WANT_READ, /* we want read actions */
58  event_WANT_WRITE, /* we want write actions */
59  event_READ, /* read some stuff for me */
60  event_WRITE, /* write this to the fd */
61  event_STREAM, /* stream is ready to go */
62  event_OPEN, /* normal operation */
63  event_PACKET, /* got a packet */
64  event_CLOSED, /* its over */
65  event_ERROR /* something's wrong */
66 } sx_event_t;
67 
69 typedef enum {
70  state_NONE, /* pre-init */
71  state_STREAM_RECEIVED, /* stream start received (server) */
72  state_STREAM_SENT, /* stream start sent (client) */
73  state_STREAM, /* stream established */
74  state_OPEN, /* auth completed (normal stream operation) */
75  state_CLOSING, /* ready to close (send event_CLOSED to app) */
76  state_CLOSED /* closed (same as NONE, but can't be used any more) */
77 } _sx_state_t;
78 
80 typedef enum {
82  type_CLIENT, /* we initiated the connection */
83  type_SERVER /* they initiated */
84 } _sx_type_t;
85 
87 typedef int (*sx_callback_t)(sx_t s, sx_event_t e, void *data, void *arg);
88 
90 typedef int (*sx_plugin_init_t)(sx_env_t env, sx_plugin_t p, va_list args);
91 
92 /* errors */
93 #define SX_SUCCESS (0x00)
94 #define SX_ERR_STREAM (0x01)
95 #define SX_ERR_AUTH (0x02)
96 #define SX_ERR_XML_PARSE (0x03)
97 
99 typedef struct _sx_error_st {
100  int code;
101  const char *generic;
102  const char *specific;
103 } sx_error_t;
104 
106 #define _sx_gen_error(e,c,g,s) do { e.code = c; e.generic = g; e.specific = s; } while(0);
107 
109 typedef void (*_sx_notify_t)(sx_t s, void *arg);
110 
112 typedef struct _sx_buf_st *sx_buf_t;
113 struct _sx_buf_st {
114  char *data; /* pointer to buffer's data */
115  unsigned int len; /* length of buffer's data */
116  char *heap; /* beginning of malloc() block containing data, if non-NULL */
117 
118  /* function to call when this buffer gets written */
120  void *notify_arg;
121 };
122 
123 /* stream errors */
124 #define stream_err_BAD_FORMAT (0)
125 #define stream_err_BAD_NAMESPACE_PREFIX (1)
126 #define stream_err_CONFLICT (2)
127 #define stream_err_CONNECTION_TIMEOUT (3)
128 #define stream_err_HOST_GONE (4)
129 #define stream_err_HOST_UNKNOWN (5)
130 #define stream_err_IMPROPER_ADDRESSING (6)
131 #define stream_err_INTERNAL_SERVER_ERROR (7)
132 #define stream_err_INVALID_FROM (8)
133 #define stream_err_INVALID_ID (9)
134 #define stream_err_INVALID_NAMESPACE (10)
135 #define stream_err_INVALID_XML (11)
136 #define stream_err_NOT_AUTHORIZED (12)
137 #define stream_err_POLICY_VIOLATION (13)
138 #define stream_err_REMOTE_CONNECTION_FAILED (14)
139 #define stream_err_RESTRICTED_XML (15)
140 #define stream_err_RESOURCE_CONSTRAINT (16)
141 #define stream_err_SEE_OTHER_HOST (17)
142 #define stream_err_SYSTEM_SHUTDOWN (18)
143 #define stream_err_UNDEFINED_CONDITION (19)
144 #define stream_err_UNSUPPORTED_ENCODING (20)
145 #define stream_err_UNSUPPORTED_STANZA_TYPE (21)
146 #define stream_err_UNSUPPORTED_VERSION (22)
147 #define stream_err_XML_NOT_WELL_FORMED (23)
148 #define stream_err_LAST (24)
149 
150 /* exported functions */
151 
152 /* make/break */
153 JABBERD2_API sx_t sx_new(sx_env_t env, int tag, sx_callback_t cb, void *arg);
154 JABBERD2_API void sx_free(sx_t s);
155 
156 /* get things ready */
157 JABBERD2_API void sx_client_init(sx_t s, unsigned int flags, const char *ns, const char *to, const char *from, const char *version);
158 JABBERD2_API void sx_server_init(sx_t s, unsigned int flags);
159 
160 /* activity on socket, do stuff! (returns 1 if more read/write actions wanted, 0 otherwise) */
161 JABBERD2_API int sx_can_read(sx_t s);
162 JABBERD2_API int sx_can_write(sx_t s);
163 
165 JABBERD2_API void sx_nad_write_elem(sx_t s, nad_t nad, int elem);
166 #define sx_nad_write(s,nad) sx_nad_write_elem(s, nad, 0)
167 
169 JABBERD2_API void sx_raw_write(sx_t s, const char *buf, int len);
170 
172 JABBERD2_API void sx_auth(sx_t s, const char *auth_method, const char *auth_id);
173 
174 /* make/break an environment */
175 JABBERD2_API sx_env_t sx_env_new(void);
176 JABBERD2_API void sx_env_free(sx_env_t env);
177 
179 JABBERD2_API sx_plugin_t sx_env_plugin(sx_env_t env, sx_plugin_init_t init, ...);
180 
181 /* send errors and close stuff */
182 JABBERD2_API void sx_error(sx_t s, int err, const char *text);
183 JABBERD2_API void sx_error_extended(sx_t s, int err, const char *content);
184 JABBERD2_API void sx_close(sx_t s);
185 JABBERD2_API void sx_kill(sx_t s);
186 
187 
188 /* helper functions */
189 JABBERD2_API char* _sx_flags(sx_t s);
190 
191 /* primary expat callbacks */
192 JABBERD2_API void _sx_element_start(void *arg, const char *name, const char **atts);
193 JABBERD2_API void _sx_element_end(void *arg, const char *name);
194 JABBERD2_API void _sx_cdata(void *arg, const char *str, int len);
195 JABBERD2_API void _sx_namespace_start(void *arg, const char *prefix, const char *uri);
196 #ifdef HAVE_XML_STOPPARSER
197 JABBERD2_API void _sx_entity_declaration(void *arg, const char *entityName,
198  int is_parameter_entity, const char *value,
199  int value_length, const char *base,
200  const char *systemId, const char *publicId,
201  const char *notationName);
202 #endif
203 
205 JABBERD2_API void _sx_process_read(sx_t s, sx_buf_t buf);
206 
208 JABBERD2_API void _sx_nad_process(sx_t s, nad_t nad);
209 
210 /* chain management */
211 JABBERD2_API void _sx_chain_io_plugin(sx_t s, sx_plugin_t p);
212 JABBERD2_API void _sx_chain_nad_plugin(sx_t s, sx_plugin_t p);
213 
214 /* chain running */
215 JABBERD2_API int _sx_chain_io_write(sx_t s, sx_buf_t buf);
216 JABBERD2_API int _sx_chain_io_read(sx_t s, sx_buf_t buf);
217 
218 JABBERD2_API int _sx_chain_nad_write(sx_t s, nad_t nad, int elem);
219 JABBERD2_API int _sx_chain_nad_read(sx_t s, nad_t nad);
220 
221 /* buffer utilities */
222 JABBERD2_API sx_buf_t _sx_buffer_new(const char *data, int len, _sx_notify_t notify, void *notify_arg);
223 JABBERD2_API void _sx_buffer_free(sx_buf_t buf);
224 JABBERD2_API void _sx_buffer_clear(sx_buf_t buf);
225 JABBERD2_API void _sx_buffer_alloc_margin(sx_buf_t buf, int before, int after);
226 JABBERD2_API void _sx_buffer_set(sx_buf_t buf, char *newdata, int newlength, char *newheap);
227 
229 JABBERD2_API int _sx_nad_write(sx_t s, nad_t nad, int elem);
230 
232 JABBERD2_API void sx_raw_write(sx_t s, const char *buf, int len);
233 
235 JABBERD2_API void _sx_reset(sx_t s);
236 
237 /* send errors and close stuff */
238 JABBERD2_API void _sx_error(sx_t s, int err, const char *text);
239 JABBERD2_API void _sx_error_extended(sx_t s, int err, const char *content);
240 JABBERD2_API void _sx_close(sx_t s);
241 
243 typedef struct _sx_chain_st *_sx_chain_t;
244 struct _sx_chain_st {
245  sx_plugin_t p;
246 
247  _sx_chain_t wnext; /* -> write */
248  _sx_chain_t rnext; /* <- read */
249 };
250 
252 struct _sx_st {
253  /* environment */
254  sx_env_t env;
255 
256  /* tag, for logging */
257  int tag;
258 
259  /* IP address of the connection */
260  /* pointing to sess.ip and owned by sess structure */
261  const char *ip;
262 
263  /* TCP port of the connection */
264  /* pointing to sess.port and owned by sess structure */
265  int port;
266 
267  /* callback */
269  void *cb_arg;
270 
271  /* type */
273 
274  /* flags */
275  unsigned int flags;
276 
277  /* application namespace */
278  const char *ns;
279 
280  /* requested stream properties */
281  const char *req_to;
282  const char *req_from;
283  const char *req_version;
284 
285  /* responded stream properties */
286  const char *res_to;
287  const char *res_from;
288  const char *res_version;
289 
290  /* stream id */
291  const char *id;
292 
293  /* io chain */
294  _sx_chain_t wio, rio;
295 
296  /* nad chain */
297  _sx_chain_t wnad, rnad;
298 
299  /* internal queues */
300  jqueue_t wbufq; /* buffers waiting to go to wio */
301  sx_buf_t wbufpending; /* buffer passed through wio but not written yet */
302  jqueue_t rnadq; /* completed nads waiting to go to rnad */
303 
304  /* do we want to read or write? */
305  int want_read, want_write;
306 
307  /* bytes read from socket */
308  int rbytes;
310 
311  /* read bytes maximum */
313 
314  /* current state */
316 
317  /* parser */
318  XML_Parser expat;
319  int depth;
320  int fail;
321 
322  /* nad currently being built */
324 
325  /* plugin storage */
326  void **plugin_data;
327 
328  /* type and id of auth */
329  const char *auth_method;
330  const char *auth_id;
331 
332  /* if true, then we were called from the callback */
333  int reentry;
334 
335  /* this is true after a stream resets - applications should check this before doing per-stream init */
337 
338  /* security strength factor (in sasl parlance) - roughly equivalent to key strength */
339  int ssf;
340 };
341 
344  sx_env_t env;
345 
346  int magic; /* unique id so that plugins can find each other */
347 
348  int index;
349 
350  void *private;
351 
352  void (*new)(sx_t s, sx_plugin_t p); /* pre-run init */
353  void (*free)(sx_t s, sx_plugin_t p); /* conn being freed */
354 
355  void (*client)(sx_t s, sx_plugin_t p); /* client init */
356  void (*server)(sx_t s, sx_plugin_t p); /* server init */
357 
358  /* return -2 == failed (permanent), -1 == failed (temporary), 0 == handled, 1 == pass */
359  int (*wio)(sx_t s, sx_plugin_t p, sx_buf_t buf); /* before being written */
360  int (*rio)(sx_t s, sx_plugin_t p, sx_buf_t buf); /* after being read */
361 
362  /* return 0 == handled, 1 == pass */
363  int (*wnad)(sx_t s, sx_plugin_t p, nad_t nad, int elem); /* before being written */
364  int (*rnad)(sx_t s, sx_plugin_t p, nad_t nad); /* after being read */
365 
366  void (*header)(sx_t s, sx_plugin_t p, sx_buf_t buf); /* before header req/res write */
367  void (*stream)(sx_t s, sx_plugin_t p); /* after-stream init */
368 
369  void (*features)(sx_t s, sx_plugin_t p, nad_t nad); /* offer features */
370 
371  /* return 0 == handled, 1 == pass */
372  int (*process)(sx_t s, sx_plugin_t p, nad_t nad); /* process completed nads */
373 
374  void (*unload)(sx_plugin_t p); /* plugin unloading */
375 };
376 
378 struct _sx_env_st {
379  sx_plugin_t *plugins;
380  int nplugins;
381 };
382 
384 #define ZONE __FILE__,__LINE__
385 
387 JABBERD2_API void __sx_debug(const char *file, int line, const char *msgfmt, ...);
388 
390 JABBERD2_API int __sx_event(const char *file, int line, sx_t s, sx_event_t e, void *data);
391 #define _sx_event(s,e,data) __sx_event(ZONE, s, e, data)
392 
393 #ifdef SX_DEBUG
394 
396 #define _sx_debug if(get_debug_flag()) __sx_debug
397 
399 #define _sx_state(s,st) do { _sx_debug(ZONE, "%d state change from %d to %d", s->tag, s->state, st); s->state = st; } while(0)
400 
401 #else
402 
403 /* clean and efficient versions */
404 #define _sx_debug if(0) __sx_debug
405 #define _sx_state(s,st) s->state = st
406 
407 #endif
408 
409 #ifdef __cplusplus
410 }
411 #endif
412 
413 /* now include sx envplugins datatypes */
414 #include "plugins.h"
415 
416 #endif
const char * ip
Definition: sx.h:261
JABBERD2_API int sx_can_read(sx_t s)
we can read
Definition: io.c:196
sx_callback_t cb
Definition: sx.h:268
Definition: nad.h:93
JABBERD2_API void sx_raw_write(sx_t s, const char *buf, int len)
sending raw data
Definition: io.c:469
Definition: sx.h:113
JABBERD2_API void sx_kill(sx_t s)
Definition: io.c:513
sx_plugin_t p
Definition: sx.h:245
_sx_state_t state
Definition: sx.h:315
JABBERD2_API int _sx_chain_io_write(sx_t s, sx_buf_t buf)
Definition: chain.c:75
JABBERD2_API sx_t sx_new(sx_env_t env, int tag, sx_callback_t cb, void *arg)
Definition: sx.c:23
unsigned int flags
Definition: sx.h:275
JABBERD2_API int __sx_event(const char *file, int line, sx_t s, sx_event_t e, void *data)
helper and internal macro for firing the callback
Definition: sx.c:336
JABBERD2_API int _sx_chain_nad_write(sx_t s, nad_t nad, int elem)
Definition: chain.c:103
JABBERD2_API void _sx_nad_process(sx_t s, nad_t nad)
main nad processor
Definition: sx.h:59
const char * req_to
Definition: sx.h:281
jqueue_t wbufq
Definition: sx.h:300
_sx_chain_t wio
Definition: sx.h:294
Definition: sx.h:70
Definition: sx.h:65
an environment
Definition: sx.h:378
error info for event_ERROR
Definition: sx.h:99
int magic
Definition: sx.h:346
JABBERD2_API int sx_can_write(sx_t s)
Definition: io.c:333
int rbytesmax
Definition: sx.h:312
_sx_state_t
connection states
Definition: sx.h:69
int tag
Definition: sx.h:257
a plugin
Definition: sx.h:343
JABBERD2_API void _sx_chain_nad_plugin(sx_t s, sx_plugin_t p)
Definition: chain.c:50
JABBERD2_API void _sx_buffer_clear(sx_buf_t buf)
utility: clear out a buffer, but don't deallocate it
Definition: sx.c:252
sx_env_t env
Definition: sx.h:254
int(* sx_callback_t)(sx_t s, sx_event_t e, void *data, void *arg)
event callback
Definition: sx.h:87
_sx_chain_t wnext
Definition: sx.h:247
JABBERD2_API void sx_env_free(sx_env_t env)
Definition: env.c:31
struct _sx_error_st sx_error_t
error info for event_ERROR
const char * ns
Definition: sx.h:278
JABBERD2_API void _sx_cdata(void *arg, const char *str, int len)
Definition: callback.c:129
const char * auth_method
Definition: sx.h:329
Definition: sx.h:60
JABBERD2_API void _sx_error_extended(sx_t s, int err, const char *content)
Definition: error.c:105
sx_buf_t wbufpending
Definition: sx.h:301
JABBERD2_API void sx_client_init(sx_t s, unsigned int flags, const char *ns, const char *to, const char *from, const char *version)
Definition: client.c:111
JABBERD2_API sx_plugin_t sx_env_plugin(sx_env_t env, sx_plugin_init_t init,...)
load a plugin into the environment
Definition: env.c:48
JABBERD2_API sx_buf_t _sx_buffer_new(const char *data, int len, _sx_notify_t notify, void *notify_arg)
utility: make a new buffer if len>0 but data is NULL, the buffer will contain that many bytes of garb...
Definition: sx.c:220
JABBERD2_API void sx_error(sx_t s, int err, const char *text)
Definition: error.c:94
JABBERD2_API void _sx_close(sx_t s)
close a stream
Definition: io.c:485
holds the state for a single stream
Definition: sx.h:252
void * cb_arg
Definition: sx.h:269
int depth
Definition: sx.h:319
char * data
Definition: sx.h:114
int rbytes
Definition: sx.h:308
sx_plugin_t * plugins
Definition: sx.h:379
int fail
Definition: sx.h:320
Definition: sx.h:82
jqueue_t rnadq
Definition: sx.h:302
#define JABBERD2_API
Definition: sx.h:42
_sx_type_t
connection types
Definition: sx.h:80
JABBERD2_API int _sx_chain_io_read(sx_t s, sx_buf_t buf)
Definition: chain.c:89
int code
Definition: sx.h:100
_sx_chain_t rnext
Definition: sx.h:248
JABBERD2_API void sx_error_extended(sx_t s, int err, const char *content)
Definition: error.c:140
JABBERD2_API void _sx_namespace_start(void *arg, const char *prefix, const char *uri)
Definition: callback.c:142
const char * res_from
Definition: sx.h:287
_sx_chain_t wnad
Definition: sx.h:297
Definition: sx.h:81
const char * res_to
Definition: sx.h:286
JABBERD2_API void _sx_process_read(sx_t s, sx_buf_t buf)
processor for incoming wire data
Definition: io.c:24
const char * auth_id
Definition: sx.h:330
struct _sx_plugin_st * sx_plugin_t
Definition: sx.h:53
char * heap
Definition: sx.h:116
int rbytes_total
Definition: sx.h:309
nad_t nad
Definition: sx.h:323
JABBERD2_API char * _sx_flags(sx_t s)
show sx flags as string - for logging
Definition: sx.c:349
struct _sx_buf_st * sx_buf_t
utility: buffer
Definition: sx.h:112
_sx_type_t type
Definition: sx.h:272
_sx_notify_t notify
Definition: sx.h:119
const char * req_version
Definition: sx.h:283
const char * res_version
Definition: sx.h:288
JABBERD2_API void sx_nad_write_elem(sx_t s, nad_t nad, int elem)
sending a nad
Definition: io.c:435
int has_reset
Definition: sx.h:336
const char * req_from
Definition: sx.h:282
Definition: sx.h:83
void(* _sx_notify_t)(sx_t s, void *arg)
prototype for the write notify function
Definition: sx.h:109
int ssf
Definition: sx.h:339
JABBERD2_API void _sx_element_start(void *arg, const char *name, const char **atts)
primary expat callbacks
Definition: callback.c:24
const char * specific
Definition: sx.h:102
sx_env_t env
Definition: sx.h:344
int(* sx_plugin_init_t)(sx_env_t env, sx_plugin_t p, va_list args)
plugin init
Definition: sx.h:90
unsigned int len
Definition: sx.h:115
struct _sx_st * sx_t
Definition: sx.h:51
int reentry
Definition: sx.h:333
JABBERD2_API void _sx_buffer_set(sx_buf_t buf, char *newdata, int newlength, char *newheap)
utility: reset a sx_buf_t's contents.
Definition: sx.c:299
JABBERD2_API void sx_auth(sx_t s, const char *auth_method, const char *auth_id)
authenticate the stream and move to the auth'd state
Definition: sx.c:141
JABBERD2_API sx_env_t sx_env_new(void)
Definition: env.c:23
JABBERD2_API void _sx_chain_io_plugin(sx_t s, sx_plugin_t p)
Definition: chain.c:25
int port
Definition: sx.h:265
JABBERD2_API void _sx_buffer_free(sx_buf_t buf)
utility: kill a buffer
Definition: sx.c:244
XML_Parser expat
Definition: sx.h:318
sx_event_t
things that can happen
Definition: sx.h:56
struct _sx_env_st * sx_env_t
Definition: sx.h:52
JABBERD2_API int _sx_nad_write(sx_t s, nad_t nad, int elem)
sending a nad (internal)
Definition: io.c:403
JABBERD2_API void _sx_reset(sx_t s)
reset stream state without informing the app
Definition: sx.c:154
JABBERD2_API void __sx_debug(const char *file, int line, const char *msgfmt,...)
helper functions for macros when we're debugging
Definition: sx.c:317
Definition: sx.h:74
void * notify_arg
Definition: sx.h:120
int index
Definition: sx.h:348
JABBERD2_API void sx_close(sx_t s)
Definition: io.c:498
int nplugins
Definition: sx.h:380
Definition: sx.h:62
JABBERD2_API int _sx_chain_nad_read(sx_t s, nad_t nad)
Definition: chain.c:116
int want_write
Definition: sx.h:305
JABBERD2_API void _sx_error(sx_t s, int err, const char *text)
send an error
Definition: error.c:53
JABBERD2_API void sx_free(sx_t s)
Definition: sx.c:70
const char * id
Definition: sx.h:291
void ** plugin_data
Definition: sx.h:326
JABBERD2_API void _sx_element_end(void *arg, const char *name)
Definition: callback.c:108
JABBERD2_API void sx_server_init(sx_t s, unsigned int flags)
Definition: server.c:248
JABBERD2_API void _sx_buffer_alloc_margin(sx_buf_t buf, int before, int after)
utility: ensure a certain amount of allocated space adjacent to buf->data
Definition: sx.c:262
struct _sx_chain_st * _sx_chain_t
read/write plugin chain
Definition: sx.h:243