jabberd2  2.3.1
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 /* internal functions */
189 
190 /* primary expat callbacks */
191 JABBERD2_API void _sx_element_start(void *arg, const char *name, const char **atts);
192 JABBERD2_API void _sx_element_end(void *arg, const char *name);
193 JABBERD2_API void _sx_cdata(void *arg, const char *str, int len);
194 JABBERD2_API void _sx_namespace_start(void *arg, const char *prefix, const char *uri);
195 #ifdef HAVE_XML_STOPPARSER
196 JABBERD2_API void _sx_entity_declaration(void *arg, const char *entityName,
197  int is_parameter_entity, const char *value,
198  int value_length, const char *base,
199  const char *systemId, const char *publicId,
200  const char *notationName);
201 #endif
202 
204 JABBERD2_API void _sx_process_read(sx_t s, sx_buf_t buf);
205 
207 JABBERD2_API void _sx_nad_process(sx_t s, nad_t nad);
208 
209 /* chain management */
210 JABBERD2_API void _sx_chain_io_plugin(sx_t s, sx_plugin_t p);
211 JABBERD2_API void _sx_chain_nad_plugin(sx_t s, sx_plugin_t p);
212 
213 /* chain running */
214 JABBERD2_API int _sx_chain_io_write(sx_t s, sx_buf_t buf);
215 JABBERD2_API int _sx_chain_io_read(sx_t s, sx_buf_t buf);
216 
217 JABBERD2_API int _sx_chain_nad_write(sx_t s, nad_t nad, int elem);
218 JABBERD2_API int _sx_chain_nad_read(sx_t s, nad_t nad);
219 
220 /* buffer utilities */
221 JABBERD2_API sx_buf_t _sx_buffer_new(const char *data, int len, _sx_notify_t notify, void *notify_arg);
222 JABBERD2_API void _sx_buffer_free(sx_buf_t buf);
223 JABBERD2_API void _sx_buffer_clear(sx_buf_t buf);
224 JABBERD2_API void _sx_buffer_alloc_margin(sx_buf_t buf, int before, int after);
225 JABBERD2_API void _sx_buffer_set(sx_buf_t buf, char *newdata, int newlength, char *newheap);
226 
228 JABBERD2_API int _sx_nad_write(sx_t s, nad_t nad, int elem);
229 
231 JABBERD2_API void sx_raw_write(sx_t s, const char *buf, int len);
232 
234 JABBERD2_API void _sx_reset(sx_t s);
235 
236 /* send errors and close stuff */
237 JABBERD2_API void _sx_error(sx_t s, int err, const char *text);
238 JABBERD2_API void _sx_error_extended(sx_t s, int err, const char *content);
239 JABBERD2_API void _sx_close(sx_t s);
240 
242 typedef struct _sx_chain_st *_sx_chain_t;
243 struct _sx_chain_st {
244  sx_plugin_t p;
245 
246  _sx_chain_t wnext; /* -> write */
247  _sx_chain_t rnext; /* <- read */
248 };
249 
251 struct _sx_st {
252  /* environment */
253  sx_env_t env;
254 
255  /* tag, for logging */
256  int tag;
257 
258  /* IP address of the connection */
259  /* pointing to sess.ip and owned by sess structure */
260  const char *ip;
261 
262  /* TCP port of the connection */
263  /* pointing to sess.port and owned by sess structure */
264  int port;
265 
266  /* callback */
268  void *cb_arg;
269 
270  /* type */
272 
273  /* flags */
274  unsigned int flags;
275 
276  /* application namespace */
277  const char *ns;
278 
279  /* requested stream properties */
280  const char *req_to;
281  const char *req_from;
282  const char *req_version;
283 
284  /* responded stream properties */
285  const char *res_to;
286  const char *res_from;
287  const char *res_version;
288 
289  /* stream id */
290  const char *id;
291 
292  /* io chain */
293  _sx_chain_t wio, rio;
294 
295  /* nad chain */
296  _sx_chain_t wnad, rnad;
297 
298  /* internal queues */
299  jqueue_t wbufq; /* buffers waiting to go to wio */
300  sx_buf_t wbufpending; /* buffer passed through wio but not written yet */
301  jqueue_t rnadq; /* completed nads waiting to go to rnad */
302 
303  /* do we want to read or write? */
304  int want_read, want_write;
305 
306  /* bytes read from socket */
307  int rbytes;
308 
309  /* read bytes maximum */
311 
312  /* current state */
314 
315  /* parser */
316  XML_Parser expat;
317  int depth;
318  int fail;
319 
320  /* nad currently being built */
322 
323  /* plugin storage */
324  void **plugin_data;
325 
326  /* type and id of auth */
327  const char *auth_method;
328  const char *auth_id;
329 
330  /* if true, then we were called from the callback */
331  int reentry;
332 
333  /* this is true after a stream resets - applications should check this before doing per-stream init */
335 
336  /* security strength factor (in sasl parlance) - roughly equivalent to key strength */
337  int ssf;
338 
339  /* is stream compressed */
341 };
342 
345  sx_env_t env;
346 
347  int magic; /* unique id so that plugins can find each other */
348 
349  int index;
350 
351  void *private;
352 
353  void (*new)(sx_t s, sx_plugin_t p); /* pre-run init */
354  void (*free)(sx_t s, sx_plugin_t p); /* conn being freed */
355 
356  void (*client)(sx_t s, sx_plugin_t p); /* client init */
357  void (*server)(sx_t s, sx_plugin_t p); /* server init */
358 
359  /* return -2 == failed (permanent), -1 == failed (temporary), 0 == handled, 1 == pass */
360  int (*wio)(sx_t s, sx_plugin_t p, sx_buf_t buf); /* before being written */
361  int (*rio)(sx_t s, sx_plugin_t p, sx_buf_t buf); /* after being read */
362 
363  /* return 0 == handled, 1 == pass */
364  int (*wnad)(sx_t s, sx_plugin_t p, nad_t nad, int elem); /* before being written */
365  int (*rnad)(sx_t s, sx_plugin_t p, nad_t nad); /* after being read */
366 
367  void (*header)(sx_t s, sx_plugin_t p, sx_buf_t buf); /* before header req/res write */
368  void (*stream)(sx_t s, sx_plugin_t p); /* after-stream init */
369 
370  void (*features)(sx_t s, sx_plugin_t p, nad_t nad); /* offer features */
371 
372  /* return 0 == handled, 1 == pass */
373  int (*process)(sx_t s, sx_plugin_t p, nad_t nad); /* process completed nads */
374 
375  void (*unload)(sx_plugin_t p); /* plugin unloading */
376 };
377 
379 struct _sx_env_st {
380  sx_plugin_t *plugins;
381  int nplugins;
382 };
383 
385 #define ZONE __FILE__,__LINE__
386 
388 JABBERD2_API void __sx_debug(const char *file, int line, const char *msgfmt, ...);
389 
391 JABBERD2_API int __sx_event(const char *file, int line, sx_t s, sx_event_t e, void *data);
392 #define _sx_event(s,e,data) __sx_event(ZONE, s, e, data)
393 
394 #ifdef SX_DEBUG
395 
397 #define _sx_debug if(get_debug_flag()) __sx_debug
398 
400 #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)
401 
402 #else
403 
404 /* clean and efficient versions */
405 #define _sx_debug if(0) __sx_debug
406 #define _sx_state(s,st) s->state = st
407 
408 #endif
409 
410 #ifdef __cplusplus
411 }
412 #endif
413 
414 /* now include sx envplugins datatypes */
415 #include "plugins.h"
416 
417 #endif
const char * ip
Definition: sx.h:260
sx_callback_t cb
Definition: sx.h:267
int _sx_chain_nad_write(sx_t s, nad_t nad, int elem)
Definition: chain.c:103
int _sx_chain_io_write(sx_t s, sx_buf_t buf)
Definition: chain.c:75
Definition: nad.h:93
Definition: sx.h:113
sx_plugin_t p
Definition: sx.h:244
_sx_state_t state
Definition: sx.h:313
unsigned int flags
Definition: sx.h:274
void sx_nad_write_elem(sx_t s, nad_t nad, int elem)
app version
Definition: io.c:420
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:280
jqueue_t wbufq
Definition: sx.h:299
_sx_chain_t wio
Definition: sx.h:293
Definition: sx.h:70
void _sx_error_extended(sx_t s, int err, const char *content)
Definition: error.c:99
Definition: sx.h:65
void _sx_chain_nad_plugin(sx_t s, sx_plugin_t p)
Definition: chain.c:50
an environment
Definition: sx.h:379
error info for event_ERROR
Definition: sx.h:99
int magic
Definition: sx.h:347
int rbytesmax
Definition: sx.h:310
sx_t sx_new(sx_env_t env, int tag, sx_callback_t cb, void *arg)
Definition: sx.c:23
_sx_state_t
connection states
Definition: sx.h:69
int tag
Definition: sx.h:256
int sx_can_write(sx_t s)
Definition: io.c:318
a plugin
Definition: sx.h:344
sx_env_t env
Definition: sx.h:253
void sx_server_init(sx_t s, unsigned int flags)
Definition: server.c:228
void sx_raw_write(sx_t s, const char *buf, int len)
app version
Definition: io.c:454
_sx_chain_t wnext
Definition: sx.h:246
void _sx_chain_io_plugin(sx_t s, sx_plugin_t p)
Definition: chain.c:25
int(* sx_plugin_init_t)(sx_env_t env, sx_plugin_t p, va_list args)
plugin init
Definition: sx.h:90
struct _sx_error_st sx_error_t
error info for event_ERROR
const char * ns
Definition: sx.h:277
const char * auth_method
Definition: sx.h:327
sx_env_t sx_env_new(void)
Definition: env.c:23
Definition: sx.h:60
int(* sx_callback_t)(sx_t s, sx_event_t e, void *data, void *arg)
event callback
Definition: sx.h:87
void(* _sx_notify_t)(sx_t s, void *arg)
prototype for the write notify function
Definition: sx.h:109
sx_buf_t wbufpending
Definition: sx.h:300
int sx_can_read(sx_t s)
we can read
Definition: io.c:181
void _sx_buffer_alloc_margin(sx_buf_t buf, int before, int after)
utility: ensure a certain amount of allocated space adjacent to buf-&gt;data
Definition: sx.c:264
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
holds the state for a single stream
Definition: sx.h:251
void * cb_arg
Definition: sx.h:268
int depth
Definition: sx.h:317
char * data
Definition: sx.h:114
void _sx_element_end(void *arg, const char *name)
Definition: callback.c:108
int rbytes
Definition: sx.h:307
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
sx_plugin_t * plugins
Definition: sx.h:380
int fail
Definition: sx.h:318
Definition: sx.h:82
jqueue_t rnadq
Definition: sx.h:301
void _sx_buffer_free(sx_buf_t buf)
utility: kill a buffer
Definition: sx.c:246
#define JABBERD2_API
Definition: sx.h:42
int compressed
Definition: sx.h:340
_sx_type_t
connection types
Definition: sx.h:80
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&gt;0 but data is NULL, the buffer will contain that many bytes of garb...
Definition: sx.c:222
int code
Definition: sx.h:100
_sx_chain_t rnext
Definition: sx.h:247
void sx_error_extended(sx_t s, int err, const char *content)
Definition: error.c:134
const char * res_from
Definition: sx.h:286
_sx_chain_t wnad
Definition: sx.h:296
void sx_free(sx_t s)
Definition: sx.c:70
void sx_close(sx_t s)
Definition: io.c:480
Definition: sx.h:81
const char * res_to
Definition: sx.h:285
const char * auth_id
Definition: sx.h:328
void _sx_process_read(sx_t s, sx_buf_t buf)
handler for read data
Definition: io.c:24
struct _sx_plugin_st * sx_plugin_t
Definition: sx.h:53
char * heap
Definition: sx.h:116
nad_t nad
Definition: sx.h:321
struct _sx_buf_st * sx_buf_t
utility: buffer
Definition: sx.h:112
void sx_error(sx_t s, int err, const char *text)
Definition: error.c:88
_sx_type_t type
Definition: sx.h:271
_sx_notify_t notify
Definition: sx.h:119
void _sx_reset(sx_t s)
utility; reset stream state
Definition: sx.c:154
const char * req_version
Definition: sx.h:282
const char * res_version
Definition: sx.h:287
void _sx_namespace_start(void *arg, const char *prefix, const char *uri)
Definition: callback.c:142
int has_reset
Definition: sx.h:334
void _sx_close(sx_t s)
close a stream
Definition: io.c:470
void _sx_cdata(void *arg, const char *str, int len)
Definition: callback.c:129
const char * req_from
Definition: sx.h:281
Definition: sx.h:83
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:338
int ssf
Definition: sx.h:337
int _sx_chain_nad_read(sx_t s, nad_t nad)
Definition: chain.c:116
int _sx_chain_io_read(sx_t s, sx_buf_t buf)
Definition: chain.c:89
const char * specific
Definition: sx.h:102
sx_env_t env
Definition: sx.h:345
unsigned int len
Definition: sx.h:115
struct _sx_st * sx_t
Definition: sx.h:51
void _sx_buffer_clear(sx_buf_t buf)
utility: clear out a buffer, but don&#39;t deallocate it
Definition: sx.c:254
int reentry
Definition: sx.h:331
void _sx_error(sx_t s, int err, const char *text)
send an error
Definition: error.c:53
void sx_kill(sx_t s)
Definition: io.c:495
void _sx_element_start(void *arg, const char *name, const char **atts)
primary expat callbacks
Definition: callback.c:24
int port
Definition: sx.h:264
XML_Parser expat
Definition: sx.h:316
sx_event_t
things that can happen
Definition: sx.h:56
struct _sx_env_st * sx_env_t
Definition: sx.h:52
void _sx_buffer_set(sx_buf_t buf, char *newdata, int newlength, char *newheap)
utility: reset a sx_buf_t&#39;s contents.
Definition: sx.c:301
Definition: sx.h:74
void * notify_arg
Definition: sx.h:120
int index
Definition: sx.h:349
int _sx_nad_write(sx_t s, nad_t nad, int elem)
send a new nad out
Definition: io.c:388
void sx_env_free(sx_env_t env)
Definition: env.c:31
void __sx_debug(const char *file, int line, const char *msgfmt,...)
debug macro helpers
Definition: sx.c:319
int nplugins
Definition: sx.h:381
Definition: sx.h:62
void sx_auth(sx_t s, const char *auth_method, const char *auth_id)
force advance into auth state
Definition: sx.c:141
int want_write
Definition: sx.h:304
const char * id
Definition: sx.h:290
void ** plugin_data
Definition: sx.h:324
struct _sx_chain_st * _sx_chain_t
read/write plugin chain
Definition: sx.h:242