37 char *ns = NULL, *to = NULL, *from = NULL, *version = NULL;
55 _sx_debug(
ZONE,
"compress requested on already compressed channel, dropping packet");
78 if(s->
ns != NULL) ns = strdup(s->
ns);
93 if(ns != NULL) free(ns);
94 if(to != NULL) free(to);
95 if(from != NULL) free(from);
96 if(version != NULL) free(version);
105 _sx_debug(
ZONE,
"server can't handle compression, business as usual");
151 memcpy(sc->wbuf->data + sc->wbuf->len, buf->
data, buf->
len);
152 sc->wbuf->len += buf->
len;
158 if(sc->wbuf->len > 0) {
159 sc->wstrm.avail_in = sc->wbuf->len;
160 sc->wstrm.next_in = (Bytef*)sc->wbuf->data;
166 sc->wstrm.avail_out = sc->wbuf->len + SX_COMPRESS_CHUNK;
167 sc->wstrm.next_out = (Bytef*)(buf->
data + buf->
len);
169 ret = deflate(&(sc->wstrm), Z_SYNC_FLUSH);
170 assert(ret != Z_STREAM_ERROR);
172 buf->
len += sc->wbuf->len + SX_COMPRESS_CHUNK - sc->wstrm.avail_out;
174 }
while (sc->wstrm.avail_out == 0);
176 if(ret != Z_OK || sc->wstrm.avail_in != 0) {
187 sc->wbuf->len = sc->wstrm.avail_in;
188 sc->wbuf->data = (
char*)sc->wstrm.next_in;
191 _sx_debug(
ZONE,
"passing %d bytes from zlib write buffer", buf->len);
212 memcpy(sc->rbuf->data + sc->rbuf->len, buf->
data, buf->
len);
213 sc->rbuf->len += buf->
len;
219 if(sc->rbuf->len > 0) {
220 sc->rstrm.avail_in = sc->rbuf->len;
221 sc->rstrm.next_in = (Bytef*)sc->rbuf->data;
227 sc->rstrm.avail_out = SX_COMPRESS_CHUNK;
228 sc->rstrm.next_out = (Bytef*)(buf->
data + buf->
len);
230 ret = inflate(&(sc->rstrm), Z_SYNC_FLUSH);
231 assert(ret != Z_STREAM_ERROR);
246 buf->
len += SX_COMPRESS_CHUNK - sc->rstrm.avail_out;
248 }
while (sc->rstrm.avail_out == 0);
250 sc->rbuf->len = sc->rstrm.avail_in;
251 sc->rbuf->data = (
char*)sc->rstrm.next_in;
254 _sx_debug(
ZONE,
"passing %d bytes from zlib read buffer", buf->len);
257 if(sc->rbuf->len > 0)
267 _sx_compress_conn_t sc;
275 sc = (_sx_compress_conn_t) calloc(1,
sizeof(
struct _sx_compress_conn_st));
278 sc->rstrm.zalloc = Z_NULL;
279 sc->rstrm.zfree = Z_NULL;
280 sc->rstrm.opaque = Z_NULL;
281 sc->rstrm.avail_in = 0;
282 sc->rstrm.next_in = Z_NULL;
283 inflateInit(&(sc->rstrm));
285 sc->wstrm.zalloc = Z_NULL;
286 sc->wstrm.zfree = Z_NULL;
287 sc->wstrm.opaque = Z_NULL;
288 deflateInit(&(sc->wstrm), Z_DEFAULT_COMPRESSION);
318 inflateEnd(&(sc->rstrm));
319 deflateEnd(&(sc->wstrm));
347 assert((
int) (p != NULL));
348 assert((
int) (s != NULL));
352 _sx_debug(
ZONE,
"wrong conn type or state for client compress");
#define _sx_event(s, e, data)
static int _sx_compress_process(sx_t s, sx_plugin_t p, nad_t nad)
static void _sx_compress_new(sx_t s, sx_plugin_t p)
void nad_append_cdata(nad_t nad, const char *cdata, int len, int depth)
append new cdata to the last elem
#define stream_err_INTERNAL_SERVER_ERROR
error info for event_ERROR
static void _sx_compress_free(sx_t s, sx_plugin_t p)
cleanup
int nad_add_namespace(nad_t nad, const char *uri, const char *prefix)
bring a new namespace into scope
void sx_server_init(sx_t s, unsigned int flags)
void _sx_chain_io_plugin(sx_t s, sx_plugin_t p)
void(* free)(sx_t s, sx_plugin_t p)
static int _sx_compress_rio(sx_t s, sx_plugin_t p, sx_buf_t buf)
int nad_append_elem(nad_t nad, int ns, const char *name, int depth)
create a new elem on the list
void nad_free(nad_t nad)
free that nad
#define SX_COMPRESS_OFFER
void(* features)(sx_t s, sx_plugin_t p, nad_t nad)
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
holds the state for a single stream
void sx_client_init(sx_t s, unsigned int flags, const char *ns, const char *to, const char *from, const char *version)
#define NAD_ENAME_L(N, E)
void jqueue_push(jqueue_t q, void *data, int priority)
#define NAD_NURI_L(N, NS)
void _sx_buffer_free(sx_buf_t buf)
utility: kill a buffer
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...
#define uri_COMPRESS_FEATURE
#define SX_SSL_STARTTLS_REQUIRE
void(* server)(sx_t s, sx_plugin_t p)
void sx_error(sx_t s, int err, const char *text)
#define stream_err_INVALID_XML
void _sx_reset(sx_t s)
utility; reset stream state
int(* rio)(sx_t s, sx_plugin_t p, sx_buf_t buf)
static void _sx_compress_features(sx_t s, sx_plugin_t p, nad_t nad)
void _sx_buffer_clear(sx_buf_t buf)
utility: clear out a buffer, but don't deallocate it
int sx_compress_init(sx_env_t env, sx_plugin_t p, va_list args)
args: none
static void _sx_compress_notify_compress(sx_t s, void *arg)
this plugin implements the XEP-0138: Stream Compression
int(* wio)(sx_t s, sx_plugin_t p, sx_buf_t buf)
#define _sx_gen_error(e, c, g, s)
helper macro to populate this struct
#define SX_ERR_COMPRESS_FAILURE
static int _sx_compress_wio(sx_t s, sx_plugin_t p, sx_buf_t buf)
void(* client)(sx_t s, sx_plugin_t p)
int(* process)(sx_t s, sx_plugin_t p, nad_t nad)
int sx_compress_client_compress(sx_plugin_t p, sx_t s, const char *pemfile)
#define SX_COMPRESS_WRAPPER