From 032e8ec89d126eaf22ebcd35ee860fa1c8a142a4 Mon Sep 17 00:00:00 2001 From: Ilya Orlov Date: Mon, 4 Sep 2017 11:46:09 +0300 Subject: [PATCH] Added new stanza for error responce, libstrophe now will be responce if parser failed --- src/conn.c | 9 ++++ src/event.c | 6 +-- src/hash.c | 2 +- src/resolver.c | 2 +- src/stanza.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++ strophe.h | 2 + 6 files changed, 132 insertions(+), 6 deletions(-) diff --git a/src/conn.c b/src/conn.c index 8ccda34..361b0b3 100644 --- a/src/conn.c +++ b/src/conn.c @@ -73,6 +73,15 @@ static int _conn_connect(xmpp_conn_t * const conn, xmpp_conn_handler callback, void * const userdata); +void xmpp_send_error(xmpp_conn_t * const conn, xmpp_error_type_t const type, char * const text) +{ + xmpp_stanza_t *error = xmpp_error_new(conn->ctx, type, text); + + xmpp_send(conn, error); + + xmpp_stanza_release(error); +} + /** Create a new Strophe connection object. * * @param ctx a Strophe context object diff --git a/src/event.c b/src/event.c index 068e432..390d5a1 100644 --- a/src/event.c +++ b/src/event.c @@ -262,10 +262,8 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) if (ret > 0) { ret = parser_feed(conn->parser, buf, ret); if (!ret) { - /* parse error, we need to shut down */ - /* FIXME */ - xmpp_debug(ctx, "xmpp", "parse error, disconnecting"); - conn_disconnect(conn); + xmpp_debug(ctx, "xmpp", "parse error [%s]", buf); + xmpp_send_error(conn, XMPP_SE_INVALID_XML, "parse error"); } } else { if (conn->tls) { diff --git a/src/hash.c b/src/hash.c index d7b8959..a524f5b 100644 --- a/src/hash.c +++ b/src/hash.c @@ -241,7 +241,7 @@ void hash_iter_release(hash_iterator_t *iter) iter->ref--; - if (iter->ref <= 0) { + if (iter->ref == 0) { // ref is unsigned!!! hash_release(iter->table); xmpp_free(ctx, iter); } diff --git a/src/resolver.c b/src/resolver.c index 1ded962..d998053 100644 --- a/src/resolver.c +++ b/src/resolver.c @@ -517,7 +517,7 @@ static int resolver_win32_srv_query(const char *fulldomain, unsigned char *buf, size_t len) { int set = 0; - int insize; + int insize = 0; /* if dnsapi didn't work/isn't there, try querying the dns server manually */ if (!set) diff --git a/src/stanza.c b/src/stanza.c index ecfc8f1..cb4f72d 100644 --- a/src/stanza.c +++ b/src/stanza.c @@ -1218,3 +1218,120 @@ xmpp_stanza_t *xmpp_presence_new(xmpp_ctx_t *ctx) { return _stanza_new_with_attrs(ctx, "presence", NULL, NULL, NULL); } + +/** Create an stanza object with given type and error text. + * iError text are optional and may be NULL. + * + * @param ctx a Strophe context object + * @param type enum of xmpp_error_type_t + * @param text content of a 'text' + * + * @return a new Strophe stanza object + * + * @ingroup Stanza + */ +xmpp_stanza_t *xmpp_error_new(xmpp_ctx_t *ctx, xmpp_error_type_t const type, char * const text) +{ + xmpp_stanza_t *error = _stanza_new_with_attrs(ctx, "stream:error", NULL, NULL, NULL); + + xmpp_stanza_t *error_type = xmpp_stanza_new(ctx); + switch(type) + { + case XMPP_SE_BAD_FORMAT: + xmpp_stanza_set_name(error_type, "bad-format"); + break; + case XMPP_SE_BAD_NS_PREFIX: + xmpp_stanza_set_name(error_type, "bad-namespace-prefix"); + break; + case XMPP_SE_CONFLICT: + xmpp_stanza_set_name(error_type, "conflict"); + break; + case XMPP_SE_CONN_TIMEOUT: + xmpp_stanza_set_name(error_type, "connection-timeout"); + break; + case XMPP_SE_HOST_GONE: + xmpp_stanza_set_name(error_type, "host-gone"); + break; + case XMPP_SE_HOST_UNKNOWN: + xmpp_stanza_set_name(error_type, "host-unknown"); + break; + case XMPP_SE_IMPROPER_ADDR: + xmpp_stanza_set_name(error_type, "improper-addressing"); + break; + case XMPP_SE_INTERNAL_SERVER_ERROR: + xmpp_stanza_set_name(error_type, "internal-server-error"); + break; + case XMPP_SE_INVALID_FROM: + xmpp_stanza_set_name(error_type, "invalid-from"); + break; + case XMPP_SE_INVALID_ID: + xmpp_stanza_set_name(error_type, "invalid-id"); + break; + case XMPP_SE_INVALID_NS: + xmpp_stanza_set_name(error_type, "invalid-namespace"); + break; + case XMPP_SE_INVALID_XML: + xmpp_stanza_set_name(error_type, "invalid-xml"); + break; + case XMPP_SE_NOT_AUTHORIZED: + xmpp_stanza_set_name(error_type, "not-authorized"); + break; + case XMPP_SE_POLICY_VIOLATION: + xmpp_stanza_set_name(error_type, "policy-violation"); + break; + case XMPP_SE_REMOTE_CONN_FAILED: + xmpp_stanza_set_name(error_type, "remote-connection-failed"); + break; + case XMPP_SE_RESOURCE_CONSTRAINT: + xmpp_stanza_set_name(error_type, "resource-constraint"); + break; + case XMPP_SE_RESTRICTED_XML: + xmpp_stanza_set_name(error_type, "restricted-xml"); + break; + case XMPP_SE_SEE_OTHER_HOST: + xmpp_stanza_set_name(error_type, "see-other-host"); + break; + case XMPP_SE_SYSTEM_SHUTDOWN: + xmpp_stanza_set_name(error_type, "system-shutdown"); + break; + case XMPP_SE_UNDEFINED_CONDITION: + xmpp_stanza_set_name(error_type, "undefined-condition"); + break; + case XMPP_SE_UNSUPPORTED_ENCODING: + xmpp_stanza_set_name(error_type, "unsupported-encoding"); + break; + case XMPP_SE_UNSUPPORTED_STANZA_TYPE: + xmpp_stanza_set_name(error_type, "unsupported-stanza-type"); + break; + case XMPP_SE_UNSUPPORTED_VERSION: + xmpp_stanza_set_name(error_type, "unsupported-version"); + break; + case XMPP_SE_XML_NOT_WELL_FORMED: + xmpp_stanza_set_name(error_type, "xml-not-well-formed"); + break; + default: + xmpp_stanza_set_name(error_type, "internal-server-error"); + break; + } + + xmpp_stanza_set_ns(error_type, XMPP_NS_STREAMS_IETF); + xmpp_stanza_add_child(error, error_type); + xmpp_stanza_release(error_type); + + if(text) + { + xmpp_stanza_t *error_text = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(error_text, "text"); + xmpp_stanza_set_ns(error_text, XMPP_NS_STREAMS_IETF); + xmpp_stanza_set_text(error_text, text); + xmpp_stanza_add_child(error, error_text); + xmpp_stanza_release(error_text); + + xmpp_stanza_t *content = xmpp_stanza_new(ctx); + xmpp_stanza_set_text(content, text); + xmpp_stanza_add_child(error_text, content); + xmpp_stanza_release(content); + } + + return error; +} diff --git a/strophe.h b/strophe.h index 8ca53fd..9a81c3c 100644 --- a/strophe.h +++ b/strophe.h @@ -217,6 +217,7 @@ typedef void (*xmpp_conn_handler)(xmpp_conn_t * const conn, xmpp_stream_error_t * const stream_error, void * const userdata); +void xmpp_send_error(xmpp_conn_t * const conn, xmpp_error_type_t const type, char * const text); xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx); xmpp_conn_t *xmpp_conn_clone(xmpp_conn_t * const conn); int xmpp_conn_release(xmpp_conn_t * const conn); @@ -381,6 +382,7 @@ int xmpp_message_set_body(xmpp_stanza_t *msg, const char * const text); xmpp_stanza_t *xmpp_iq_new(xmpp_ctx_t *ctx, const char * const type, const char * const id); xmpp_stanza_t *xmpp_presence_new(xmpp_ctx_t *ctx); +xmpp_stanza_t *xmpp_error_new(xmpp_ctx_t *ctx, xmpp_error_type_t const type, char * const text); /* jid */