about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server_events.c10
-rw-r--r--src/server_events.h1
-rw-r--r--src/xmpp/iq.c40
3 files changed, 51 insertions, 0 deletions
diff --git a/src/server_events.c b/src/server_events.c
index e798eb9c..f2c4587a 100644
--- a/src/server_events.c
+++ b/src/server_events.c
@@ -601,3 +601,13 @@ handle_ping_result(const char * const from, int millis)
         cons_show("Ping response from %s: %dms.", from, millis);
     }
 }
+
+void
+handle_ping_error_result(const char * const from, const char * const error)
+{
+    if (error == NULL) {
+        cons_show_error("Error returned from pinging %s.", from);
+    } else {
+        cons_show_error("Error returned form pinging %s: %s.", from, error);
+    }
+}
diff --git a/src/server_events.h b/src/server_events.h
index 35fa00b5..054d39e4 100644
--- a/src/server_events.h
+++ b/src/server_events.h
@@ -95,6 +95,7 @@ void handle_presence_error(const char *from, const char * const type,
     const char *err_msg);
 void handle_xmpp_stanza(const char * const msg);
 void handle_ping_result(const char * const from, int millis);
+void handle_ping_error_result(const char * const from, const char * const error);
 void handle_room_configure(const char * const room, DataForm *form);
 void handle_room_configuration_form_error(void);
 
diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c
index 2431f151..8a85177e 100644
--- a/src/xmpp/iq.c
+++ b/src/xmpp/iq.c
@@ -286,6 +286,8 @@ static int
 _manual_pong_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza,
     void * const userdata)
 {
+    xmpp_ctx_t * const ctx = connection_get_ctx();
+
     GDateTime *sent = (GDateTime *)userdata;
     GDateTime *now = g_date_time_new_now_local();
 
@@ -296,6 +298,44 @@ _manual_pong_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza,
     g_date_time_unref(now);
 
     char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
+    char *type = xmpp_stanza_get_type(stanza);
+
+    // handle error responses
+    if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
+        xmpp_stanza_t *error = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR);
+
+        // no error stanza
+        if (error == NULL) {
+            handle_ping_error_result(from, NULL);
+            return 0;
+        }
+
+        // no children of error stanza
+        xmpp_stanza_t *error_child = xmpp_stanza_get_children(error);
+        if (error_child == NULL) {
+            handle_ping_error_result(from, NULL);
+            return 0;
+        }
+
+        // text child found
+        xmpp_stanza_t *error_text_stanza = xmpp_stanza_get_child_by_name(error, STANZA_NAME_TEXT);
+        if (error_text_stanza != NULL) {
+            char *error_text = xmpp_stanza_get_text(error_text_stanza);
+
+            // text found
+            if (error_text != NULL) {
+                handle_ping_error_result(from, error_text);
+                xmpp_free(ctx, error_text);
+                return 0;
+            }
+
+        // no text child found
+        } else {
+            char *error_child_name = xmpp_stanza_get_name(error_child);
+            handle_ping_error_result(from, error_child_name);
+            return 0;
+        }
+    }
 
     handle_ping_result(from, elapsed_millis);