jabberd2  2.6.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 
151 /* exported functions */
152 
153 /* make/break */
154 JABBERD2_API sx_t sx_new(sx_env_t env, int tag, sx_callback_t cb, void *arg);
155 JABBERD2_API void sx_free(sx_t s);
156 
157 /* get things ready */
158 JABBERD2_API void sx_client_init(sx_t s, unsigned int flags, const char *ns, const char *to, const char *from, const char *version);
159 JABBERD2_API void sx_server_init(sx_t s, unsigned int flags);
160 
161 /* activity on socket, do stuff! (returns 1 if more read/write actions wanted, 0 otherwise) */
162 JABBERD2_API int sx_can_read(sx_t s);
163 JABBERD2_API int sx_can_write(sx_t s);
164 
166 JABBERD2_API void sx_nad_write_elem(sx_t s, nad_t nad, int elem);
167 #define sx_nad_write(s,nad) sx_nad_write_elem(s, nad, 0)
168 
170 JABBERD2_API void sx_raw_write(sx_t s, const char *buf, int len);
171 
173 JABBERD2_API void sx_auth(sx_t s, const char *auth_method, const char *auth_id);
174 
175 /* make/break an environment */
176 JABBERD2_API sx_env_t sx_env_new(void);
177 JABBERD2_API void sx_env_free(sx_env_t env);
178 
180 JABBERD2_API sx_plugin_t sx_env_plugin(sx_env_t env, sx_plugin_init_t init, ...);
181 
182 /* send errors and close stuff */
183 JABBERD2_API void sx_error(sx_t s, int err, const char *text);
184 JABBERD2_API void sx_error_extended(sx_t s, int err, const char *content);
185 JABBERD2_API void sx_close(sx_t s);
186 JABBERD2_API void sx_kill(sx_t s);
187 
188 
189 /* helper functions */
190 JABBERD2_API char* _sx_flags(sx_t s);
191 
192 /* primary expat callbacks */
193 JABBERD2_API void _sx_element_start(void *arg, const char *name, const char **atts);
194 JABBERD2_API void _sx_element_end(void *arg, const char *name);
195 JABBERD2_API void _sx_cdata(void *arg, const char *str, int len);
196 JABBERD2_API void _sx_namespace_start(void *arg, const char *prefix, const char *uri);
197 #ifdef HAVE_XML_STOPPARSER
198 JABBERD2_API void _sx_entity_declaration(void *arg, const char *entityName,
199  int is_parameter_entity, const char *value,
200  int value_length, const char *base,
201  const char *systemId, const char *publicId,
202  const char *notationName);
203 #endif
204 
206 JABBERD2_API void _sx_process_read(sx_t s, sx_buf_t buf);
207 
209 JABBERD2_API void _sx_nad_process(sx_t s, nad_t nad);
210 
211 /* chain management */
212 JABBERD2_API void _sx_chain_io_plugin(sx_t s, sx_plugin_t p);
213 JABBERD2_API void _sx_chain_nad_plugin(sx_t s, sx_plugin_t p);
214 
215 /* chain running */
216 JABBERD2_API int _sx_chain_io_write(sx_t s, sx_buf_t buf);
217 JABBERD2_API int _sx_chain_io_read(sx_t s, sx_buf_t buf);
218 
219 JABBERD2_API int _sx_chain_nad_write(sx_t s, nad_t nad, int elem);
220 JABBERD2_API int _sx_chain_nad_read(sx_t s, nad_t nad);
221 
222 /* buffer utilities */
223 JABBERD2_API sx_buf_t _sx_buffer_new(const char *data, int len, _sx_notify_t notify, void *notify_arg);
224 JABBERD2_API void _sx_buffer_free(sx_buf_t buf);
225 JABBERD2_API void _sx_buffer_clear(sx_buf_t buf);
226 JABBERD2_API void _sx_buffer_alloc_margin(sx_buf_t buf, int before, int after);
227 JABBERD2_API void _sx_buffer_set(sx_buf_t buf, char *newdata, int newlength, char *newheap);
228 
230 JABBERD2_API int _sx_nad_write(sx_t s, nad_t nad, int elem);
231 
233 JABBERD2_API void sx_raw_write(sx_t s, const char *buf, int len);
234 
236 JABBERD2_API void _sx_reset(sx_t s);
237 
238 /* send errors and close stuff */
239 JABBERD2_API void _sx_error(sx_t s, int err, const char *text);
240 JABBERD2_API void _sx_error_extended(sx_t s, int err, const char *content);
241 JABBERD2_API void _sx_close(sx_t s);
242 
244 typedef struct _sx_chain_st *_sx_chain_t;
245 struct _sx_chain_st {
246  sx_plugin_t p;
247 
248  _sx_chain_t wnext; /* -> write */
249  _sx_chain_t rnext; /* <- read */
250 };
251 
253 struct _sx_st {
254  /* environment */
255  sx_env_t env;
256 
257  /* tag, for logging */
258  int tag;
259 
260  /* IP address of the connection */
261  /* pointing to sess.ip and owned by sess structure */
262  const char *ip;
263 
264  /* TCP port of the connection */
265  /* pointing to sess.port and owned by sess structure */
266  int port;
267 
268  /* callback */
270  void *cb_arg;
271 
272  /* type */
273  _sx_type_t type;
274 
275  /* flags */
276  unsigned int flags;
277 
278  /* application namespace */
279  const char *ns;
280 
281  /* requested stream properties */
282  const char *req_to;
283  const char *req_from;
284  const char *req_version;
285 
286  /* responded stream properties */
287  const char *res_to;
288  const char *res_from;
289  const char *res_version;
290 
291  /* stream id */
292  const char *id;
293 
294  /* io chain */
295  _sx_chain_t wio, rio;
296 
297  /* nad chain */
298  _sx_chain_t wnad, rnad;
299 
300  /* internal queues */
301  jqueue_t wbufq; /* buffers waiting to go to wio */
302  sx_buf_t wbufpending; /* buffer passed through wio but not written yet */
303  jqueue_t rnadq; /* completed nads waiting to go to rnad */
304 
305  /* do we want to read or write? */
306  int want_read, want_write;
307 
308  /* bytes read from socket */
309  int rbytes;
310  /* bytes parsed by parser */
311  int pbytes;
312  /* total bytes processed */
313  int tbytes;
314 
315  /* read bytes maximum */
317 
318  /* current state */
319  _sx_state_t state;
320 
321  /* parser */
322  XML_Parser expat;
323  int depth;
324  int fail;
325 
326  /* nad currently being built */
328 
329  /* plugin storage */
330  void **plugin_data;
331 
332  /* type and id of auth */
333  const char *auth_method;
334  const char *auth_id;
335 
336  /* if true, then we were called from the callback */
337  int reentry;
338 
339  /* this is true after a stream resets - applications should check this before doing per-stream init */
341 
342  /* security strength factor (in sasl parlance) - roughly equivalent to key strength */
343  int ssf;
344 };
345 
348  sx_env_t env;
349 
350  int magic; /* unique id so that plugins can find each other */
351 
352  int index;
353 
354  void *private;
355 
356  void (*new)(sx_t s, sx_plugin_t p); /* pre-run init */
357  void (*free)(sx_t s, sx_plugin_t p); /* conn being freed */
358 
359  void (*client)(sx_t s, sx_plugin_t p); /* client init */
360  void (*server)(sx_t s, sx_plugin_t p); /* server init */
361 
362  /* return -2 == failed (permanent), -1 == failed (temporary), 0 == handled, 1 == pass */
363  int (*wio)(sx_t s, sx_plugin_t p, sx_buf_t buf); /* before being written */
364  int (*rio)(sx_t s, sx_plugin_t p, sx_buf_t buf); /* after being read */
365 
366  /* return 0 == handled, 1 == pass */
367  int (*wnad)(sx_t s, sx_plugin_t p, nad_t nad, int elem); /* before being written */
368  int (*rnad)(sx_t s, sx_plugin_t p, nad_t nad); /* after being read */
369 
370  void (*header)(sx_t s, sx_plugin_t p, sx_buf_t buf); /* before header req/res write */
371  void (*stream)(sx_t s, sx_plugin_t p); /* after-stream init */
372 
373  void (*features)(sx_t s, sx_plugin_t p, nad_t nad); /* offer features */
374 
375  /* return 0 == handled, 1 == pass */
376  int (*process)(sx_t s, sx_plugin_t p, nad_t nad); /* process completed nads */
377 
378  void (*unload)(sx_plugin_t p); /* plugin unloading */
379 };
380 
382 struct _sx_env_st {
383  sx_plugin_t *plugins;
384  int nplugins;
385 };
386 
388 #define ZONE __FILE__,__LINE__
389 
391 JABBERD2_API void __sx_debug(const char *file, int line, const char *msgfmt, ...);
392 
394 JABBERD2_API int __sx_event(const char *file, int line, sx_t s, sx_event_t e, void *data);
395 #define _sx_event(s,e,data) __sx_event(ZONE, s, e, data)
396 
397 #ifdef SX_DEBUG
398 
400 #define _sx_debug if(get_debug_flag()) __sx_debug
401 
403 #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)
404 
405 #else
406 
407 /* clean and efficient versions */
408 #define _sx_debug if(0) __sx_debug
409 #define _sx_state(s,st) s->state = st
410 
411 #endif
412 
413 #ifdef __cplusplus
414 }
415 #endif
416 
417 /* now include sx envplugins datatypes */
418 #include "plugins.h"
419 
420 #endif
const char * ip
Definition: sx.h:262
JABBERD2_API int sx_can_read(sx_t s)
we can read
Definition: io.c:196
sx_callback_t cb
Definition: sx.h:269
Definition: nad.h:93
JABBERD2_API void sx_raw_write(sx_t s, const char *buf, int len)
sending raw data
Definition: io.c:483
Definition: sx.h:113
JABBERD2_API void sx_kill(sx_t s)
Definition: io.c:527
sx_plugin_t p
Definition: sx.h:246
_sx_state_t state
Definition: sx.h:319
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)
if you change these, reflect your changes in the table in error.c
Definition: sx.c:23
unsigned int flags
Definition: sx.h:276
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:282
jqueue_t wbufq
Definition: sx.h:301
_sx_chain_t wio
Definition: sx.h:295
Definition: sx.h:70
Definition: sx.h:65
an environment
Definition: sx.h:382
error info for event_ERROR
Definition: sx.h:99
int magic
Definition: sx.h:350
JABBERD2_API int sx_can_write(sx_t s)
Definition: io.c:347
int rbytesmax
Definition: sx.h:316
_sx_state_t
connection states
Definition: sx.h:69
int tag
Definition: sx.h:258
a plugin
Definition: sx.h:347
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&#39;t deallocate it
Definition: sx.c:252
sx_env_t env
Definition: sx.h:255
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:248
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:279
JABBERD2_API void _sx_cdata(void *arg, const char *str, int len)
Definition: callback.c:130
const char * auth_method
Definition: sx.h:333
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:302
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:499
holds the state for a single stream
Definition: sx.h:253
void * cb_arg
Definition: sx.h:270
int depth
Definition: sx.h:323
char * data
Definition: sx.h:114
int rbytes
Definition: sx.h:309
sx_plugin_t * plugins
Definition: sx.h:383
int fail
Definition: sx.h:324
Definition: sx.h:82
jqueue_t rnadq
Definition: sx.h:303
#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:249
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:143
const char * res_from
Definition: sx.h:288
_sx_chain_t wnad
Definition: sx.h:298
Definition: sx.h:81
const char * res_to
Definition: sx.h:287
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:334
struct _sx_plugin_st * sx_plugin_t
Definition: sx.h:53
char * heap
Definition: sx.h:116
nad_t nad
Definition: sx.h:327
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:273
_sx_notify_t notify
Definition: sx.h:119
const char * req_version
Definition: sx.h:284
const char * res_version
Definition: sx.h:289
JABBERD2_API void sx_nad_write_elem(sx_t s, nad_t nad, int elem)
sending a nad
Definition: io.c:449
int has_reset
Definition: sx.h:340
const char * req_from
Definition: sx.h:283
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:343
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:348
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:337
JABBERD2_API 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: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&#39;d state
Definition: sx.c:141
int tbytes
Definition: sx.h:313
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:266
JABBERD2_API void _sx_buffer_free(sx_buf_t buf)
utility: kill a buffer
Definition: sx.c:244
XML_Parser expat
Definition: sx.h:322
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:417
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&#39;re debugging
Definition: sx.c:317
Definition: sx.h:74
void * notify_arg
Definition: sx.h:120
int index
Definition: sx.h:352
int pbytes
Definition: sx.h:311
JABBERD2_API void sx_close(sx_t s)
Definition: io.c:512
int nplugins
Definition: sx.h:384
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:306
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:292
void ** plugin_data
Definition: sx.h:330
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:244