jabberd2
2.2.16
|
00001 /* 00002 * jabberd - Jabber Open Source Server 00003 * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney, 00004 * Ryan Eatmon, Robert Norris 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA 00019 */ 00020 00021 #ifndef INCL_SX_H 00022 #define INCL_SX_H 00023 00024 #ifdef HAVE_CONFIG_H 00025 # include <config.h> 00026 #endif 00027 00028 #include "ac-stdint.h" 00029 00030 #include <expat.h> 00031 #include <util/util.h> 00032 00033 /* jabberd2 Windows DLL */ 00034 #ifndef JABBERD2_API 00035 # ifdef _WIN32 00036 # ifdef JABBERD2_EXPORTS 00037 # define JABBERD2_API __declspec(dllexport) 00038 # else /* JABBERD2_EXPORTS */ 00039 # define JABBERD2_API __declspec(dllimport) 00040 # endif /* JABBERD2_EXPORTS */ 00041 # else /* _WIN32 */ 00042 # define JABBERD2_API extern 00043 # endif /* _WIN32 */ 00044 #endif /* JABBERD2_API */ 00045 00046 #ifdef __cplusplus 00047 extern "C" { 00048 #endif 00049 00050 /* forward declarations */ 00051 typedef struct _sx_st *sx_t; 00052 typedef struct _sx_env_st *sx_env_t; 00053 typedef struct _sx_plugin_st *sx_plugin_t; 00054 00056 typedef enum { 00057 event_WANT_READ, /* we want read actions */ 00058 event_WANT_WRITE, /* we want write actions */ 00059 event_READ, /* read some stuff for me */ 00060 event_WRITE, /* write this to the fd */ 00061 event_STREAM, /* stream is ready to go */ 00062 event_OPEN, /* normal operation */ 00063 event_PACKET, /* got a packet */ 00064 event_CLOSED, /* its over */ 00065 event_ERROR /* something's wrong */ 00066 } sx_event_t; 00067 00069 typedef enum { 00070 state_NONE, /* pre-init */ 00071 state_STREAM_RECEIVED, /* stream start received (server) */ 00072 state_STREAM_SENT, /* stream start sent (client) */ 00073 state_STREAM, /* stream established */ 00074 state_OPEN, /* auth completed (normal stream operation) */ 00075 state_CLOSING, /* ready to close (send event_CLOSED to app) */ 00076 state_CLOSED /* closed (same as NONE, but can't be used any more) */ 00077 } _sx_state_t; 00078 00080 typedef enum { 00081 type_NONE, 00082 type_CLIENT, /* we initiated the connection */ 00083 type_SERVER /* they initiated */ 00084 } _sx_type_t; 00085 00087 typedef int (*sx_callback_t)(sx_t s, sx_event_t e, void *data, void *arg); 00088 00090 typedef int (*sx_plugin_init_t)(sx_env_t env, sx_plugin_t p, va_list args); 00091 00092 /* errors */ 00093 #define SX_SUCCESS (0x00) 00094 #define SX_ERR_STREAM (0x01) 00095 #define SX_ERR_AUTH (0x02) 00096 #define SX_ERR_XML_PARSE (0x03) 00097 00099 typedef struct _sx_error_st { 00100 int code; 00101 char *generic; 00102 char *specific; 00103 } sx_error_t; 00104 00106 #define _sx_gen_error(e,c,g,s) do { e.code = c; e.generic = g; e.specific = s; } while(0); 00107 00109 typedef void (*_sx_notify_t)(sx_t s, void *arg); 00110 00112 typedef struct _sx_buf_st *sx_buf_t; 00113 struct _sx_buf_st { 00114 unsigned char *data; /* pointer to buffer's data */ 00115 unsigned int len; /* length of buffer's data */ 00116 unsigned char *heap; /* beginning of malloc() block containing data, if non-NULL */ 00117 00118 /* function to call when this buffer gets written */ 00119 _sx_notify_t notify; 00120 void *notify_arg; 00121 }; 00122 00123 /* stream errors */ 00124 #define stream_err_BAD_FORMAT (0) 00125 #define stream_err_BAD_NAMESPACE_PREFIX (1) 00126 #define stream_err_CONFLICT (2) 00127 #define stream_err_CONNECTION_TIMEOUT (3) 00128 #define stream_err_HOST_GONE (4) 00129 #define stream_err_HOST_UNKNOWN (5) 00130 #define stream_err_IMPROPER_ADDRESSING (6) 00131 #define stream_err_INTERNAL_SERVER_ERROR (7) 00132 #define stream_err_INVALID_FROM (8) 00133 #define stream_err_INVALID_ID (9) 00134 #define stream_err_INVALID_NAMESPACE (10) 00135 #define stream_err_INVALID_XML (11) 00136 #define stream_err_NOT_AUTHORIZED (12) 00137 #define stream_err_POLICY_VIOLATION (13) 00138 #define stream_err_REMOTE_CONNECTION_FAILED (14) 00139 #define stream_err_RESTRICTED_XML (15) 00140 #define stream_err_RESOURCE_CONSTRAINT (16) 00141 #define stream_err_SEE_OTHER_HOST (17) 00142 #define stream_err_SYSTEM_SHUTDOWN (18) 00143 #define stream_err_UNDEFINED_CONDITION (19) 00144 #define stream_err_UNSUPPORTED_ENCODING (20) 00145 #define stream_err_UNSUPPORTED_STANZA_TYPE (21) 00146 #define stream_err_UNSUPPORTED_VERSION (22) 00147 #define stream_err_XML_NOT_WELL_FORMED (23) 00148 #define stream_err_LAST (24) 00149 00150 /* exported functions */ 00151 00152 /* make/break */ 00153 JABBERD2_API sx_t sx_new(sx_env_t env, int tag, sx_callback_t cb, void *arg); 00154 JABBERD2_API void sx_free(sx_t s); 00155 00156 /* get things ready */ 00157 JABBERD2_API void sx_client_init(sx_t s, unsigned int flags, char *ns, char *to, char *from, char *version); 00158 JABBERD2_API void sx_server_init(sx_t s, unsigned int flags); 00159 00160 /* activity on socket, do stuff! (returns 1 if more read/write actions wanted, 0 otherwise) */ 00161 JABBERD2_API int sx_can_read(sx_t s); 00162 JABBERD2_API int sx_can_write(sx_t s); 00163 00165 JABBERD2_API void sx_nad_write_elem(sx_t s, nad_t nad, int elem); 00166 #define sx_nad_write(s,nad) sx_nad_write_elem(s, nad, 0) 00167 00169 JABBERD2_API void sx_raw_write(sx_t s, char *buf, int len); 00170 00172 JABBERD2_API void sx_auth(sx_t s, const char *auth_method, const char *auth_id); 00173 00174 /* make/break an environment */ 00175 JABBERD2_API sx_env_t sx_env_new(void); 00176 JABBERD2_API void sx_env_free(sx_env_t env); 00177 00179 JABBERD2_API sx_plugin_t sx_env_plugin(sx_env_t env, sx_plugin_init_t init, ...); 00180 00181 /* send errors and close stuff */ 00182 JABBERD2_API void sx_error(sx_t s, int err, const char *text); 00183 JABBERD2_API void sx_error_extended(sx_t s, int err, const char *content); 00184 JABBERD2_API void sx_close(sx_t s); 00185 JABBERD2_API void sx_kill(sx_t s); 00186 00187 00188 /* internal functions */ 00189 00190 /* primary expat callbacks */ 00191 JABBERD2_API void _sx_element_start(void *arg, const char *name, const char **atts); 00192 JABBERD2_API void _sx_element_end(void *arg, const char *name); 00193 JABBERD2_API void _sx_cdata(void *arg, const char *str, int len); 00194 JABBERD2_API void _sx_namespace_start(void *arg, const char *prefix, const char *uri); 00195 #ifdef HAVE_XML_STOPPARSER 00196 JABBERD2_API void _sx_entity_declaration(void *arg, const char *entityName, 00197 int is_parameter_entity, const char *value, 00198 int value_length, const char *base, 00199 const char *systemId, const char *publicId, 00200 const char *notationName); 00201 #endif 00202 00204 JABBERD2_API void _sx_process_read(sx_t s, sx_buf_t buf); 00205 00207 JABBERD2_API void _sx_nad_process(sx_t s, nad_t nad); 00208 00209 /* chain management */ 00210 JABBERD2_API void _sx_chain_io_plugin(sx_t s, sx_plugin_t p); 00211 JABBERD2_API void _sx_chain_nad_plugin(sx_t s, sx_plugin_t p); 00212 00213 /* chain running */ 00214 JABBERD2_API int _sx_chain_io_write(sx_t s, sx_buf_t buf); 00215 JABBERD2_API int _sx_chain_io_read(sx_t s, sx_buf_t buf); 00216 00217 JABBERD2_API int _sx_chain_nad_write(sx_t s, nad_t nad, int elem); 00218 JABBERD2_API int _sx_chain_nad_read(sx_t s, nad_t nad); 00219 00220 /* buffer utilities */ 00221 JABBERD2_API sx_buf_t _sx_buffer_new(const char *data, int len, _sx_notify_t notify, void *notify_arg); 00222 JABBERD2_API void _sx_buffer_free(sx_buf_t buf); 00223 JABBERD2_API void _sx_buffer_clear(sx_buf_t buf); 00224 JABBERD2_API void _sx_buffer_alloc_margin(sx_buf_t buf, int before, int after); 00225 JABBERD2_API void _sx_buffer_set(sx_buf_t buf, char *newdata, int newlength, char *newheap); 00226 00228 JABBERD2_API int _sx_nad_write(sx_t s, nad_t nad, int elem); 00229 00231 JABBERD2_API void sx_raw_write(sx_t s, char *buf, int len); 00232 00234 JABBERD2_API void _sx_reset(sx_t s); 00235 00236 /* send errors and close stuff */ 00237 JABBERD2_API void _sx_error(sx_t s, int err, const char *text); 00238 JABBERD2_API void _sx_error_extended(sx_t s, int err, const char *content); 00239 JABBERD2_API void _sx_close(sx_t s); 00240 00242 typedef struct _sx_chain_st *_sx_chain_t; 00243 struct _sx_chain_st { 00244 sx_plugin_t p; 00245 00246 _sx_chain_t wnext; /* -> write */ 00247 _sx_chain_t rnext; /* <- read */ 00248 }; 00249 00251 struct _sx_st { 00252 /* environment */ 00253 sx_env_t env; 00254 00255 /* tag, for logging */ 00256 int tag; 00257 00258 /* IP address of the connection */ 00259 /* pointing to sess.ip and owned by sess structure */ 00260 char *ip; 00261 00262 /* TCP port of the connection */ 00263 /* pointing to sess.port and owned by sess structure */ 00264 int port; 00265 00266 /* callback */ 00267 sx_callback_t cb; 00268 void *cb_arg; 00269 00270 /* type */ 00271 _sx_type_t type; 00272 00273 /* flags */ 00274 unsigned int flags; 00275 00276 /* application namespace */ 00277 char *ns; 00278 00279 /* requested stream properties */ 00280 char *req_to; 00281 char *req_from; 00282 char *req_version; 00283 00284 /* responded stream properties */ 00285 char *res_to; 00286 char *res_from; 00287 char *res_version; 00288 00289 /* stream id */ 00290 char *id; 00291 00292 /* io chain */ 00293 _sx_chain_t wio, rio; 00294 00295 /* nad chain */ 00296 _sx_chain_t wnad, rnad; 00297 00298 /* internal queues */ 00299 jqueue_t wbufq; /* buffers waiting to go to wio */ 00300 sx_buf_t wbufpending; /* buffer passed through wio but not written yet */ 00301 jqueue_t rnadq; /* completed nads waiting to go to rnad */ 00302 00303 /* do we want to read or write? */ 00304 int want_read, want_write; 00305 00306 /* bytes read from socket */ 00307 int rbytes; 00308 00309 /* read bytes maximum */ 00310 int rbytesmax; 00311 00312 /* current state */ 00313 _sx_state_t state; 00314 00315 /* parser */ 00316 XML_Parser expat; 00317 int depth; 00318 int fail; 00319 00320 /* nad currently being built */ 00321 nad_t nad; 00322 00323 /* plugin storage */ 00324 void **plugin_data; 00325 00326 /* type and id of auth */ 00327 char *auth_method; 00328 char *auth_id; 00329 00330 /* if true, then we were called from the callback */ 00331 int reentry; 00332 00333 /* this is true after a stream resets - applications should check this before doing per-stream init */ 00334 int has_reset; 00335 00336 /* security strength factor (in sasl parlance) - roughly equivalent to key strength */ 00337 int ssf; 00338 00339 /* is stream compressed */ 00340 int compressed; 00341 }; 00342 00344 struct _sx_plugin_st { 00345 sx_env_t env; 00346 00347 int magic; /* unique id so that plugins can find each other */ 00348 00349 int index; 00350 00351 void *private; 00352 00353 void (*new)(sx_t s, sx_plugin_t p); /* pre-run init */ 00354 void (*free)(sx_t s, sx_plugin_t p); /* conn being freed */ 00355 00356 void (*client)(sx_t s, sx_plugin_t p); /* client init */ 00357 void (*server)(sx_t s, sx_plugin_t p); /* server init */ 00358 00359 /* return -2 == failed (permanent), -1 == failed (temporary), 0 == handled, 1 == pass */ 00360 int (*wio)(sx_t s, sx_plugin_t p, sx_buf_t buf); /* before being written */ 00361 int (*rio)(sx_t s, sx_plugin_t p, sx_buf_t buf); /* after being read */ 00362 00363 /* return 0 == handled, 1 == pass */ 00364 int (*wnad)(sx_t s, sx_plugin_t p, nad_t nad, int elem); /* before being written */ 00365 int (*rnad)(sx_t s, sx_plugin_t p, nad_t nad); /* after being read */ 00366 00367 void (*header)(sx_t s, sx_plugin_t p, sx_buf_t buf); /* before header req/res write */ 00368 void (*stream)(sx_t s, sx_plugin_t p); /* after-stream init */ 00369 00370 void (*features)(sx_t s, sx_plugin_t p, nad_t nad); /* offer features */ 00371 00372 /* return 0 == handled, 1 == pass */ 00373 int (*process)(sx_t s, sx_plugin_t p, nad_t nad); /* process completed nads */ 00374 00375 void (*unload)(sx_plugin_t p); /* plugin unloading */ 00376 }; 00377 00379 struct _sx_env_st { 00380 sx_plugin_t *plugins; 00381 int nplugins; 00382 }; 00383 00385 #define ZONE __FILE__,__LINE__ 00386 00388 JABBERD2_API void __sx_debug(const char *file, int line, const char *msgfmt, ...); 00389 00391 JABBERD2_API int __sx_event(const char *file, int line, sx_t s, sx_event_t e, void *data); 00392 #define _sx_event(s,e,data) __sx_event(ZONE, s, e, data) 00393 00394 #ifdef SX_DEBUG 00395 00397 #define _sx_debug if(get_debug_flag()) __sx_debug 00398 00400 #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) 00401 00402 #else 00403 00404 /* clean and efficient versions */ 00405 #define _sx_debug if(0) __sx_debug 00406 #define _sx_state(s,st) s->state = st 00407 00408 #endif 00409 00410 #ifdef __cplusplus 00411 } 00412 #endif 00413 00414 /* now include sx envplugins datatypes */ 00415 #include "plugins.h" 00416 00417 #endif