Added disconnect error for resource conflict. Fixes LM-55.
Added a disconnection reason for resource conflict (when another client
connects with the same resourc).
Patch from Martyn Russell.
--- a/loudmouth/lm-connection.c Sun Apr 29 13:22:36 2007 +0200
+++ b/loudmouth/lm-connection.c Sun Apr 29 14:16:02 2007 +0200
@@ -100,6 +100,8 @@
LmConnectData *connect_data;
+ LmDisconnectReason disconnect_reason;
+
gint ref_count;
};
@@ -156,6 +158,8 @@
LmMessage *m,
gpointer user_data);
+static void connection_stream_error (LmConnection *connection,
+ LmMessage *m);
static void connection_stream_received (LmConnection *connection,
LmMessage *m);
@@ -279,6 +283,10 @@
connection_stream_received (connection, m);
goto out;
}
+ else if (lm_message_get_type (m) == LM_MESSAGE_TYPE_STREAM_ERROR) {
+ connection_stream_error (connection, m);
+ goto out;
+ }
id = lm_message_node_get_attribute (m->node, "id");
@@ -591,6 +599,9 @@
_lm_connection_succeeded (connect_data);
}
+ /* set the default disconnect reason to unknown */
+ connection->disconnect_reason = LM_DISCONNECT_REASON_UNKNOWN;
+
return TRUE;
}
@@ -1108,16 +1119,23 @@
switch (status) {
case G_IO_STATUS_EOF:
reason = LM_DISCONNECT_REASON_HUP;
+ lm_verbose ("Disconnect reason: %d\n", reason);
break;
case G_IO_STATUS_AGAIN:
/* No data readable but we didn't hangup */
return FALSE;
break;
case G_IO_STATUS_ERROR:
- reason = LM_DISCONNECT_REASON_ERROR;
- break;
+ /* If no reason set, we set it to ERROR here,
+ * otherwise it might already have been set by
+ * the stream error handler.
+ */
+ if (connection->disconnect_reason == LM_DISCONNECT_REASON_UNKNOWN) {
+ connection->disconnect_reason = LM_DISCONNECT_REASON_ERROR;
+ }
default:
- reason = LM_DISCONNECT_REASON_UNKNOWN;
+ reason = connection->disconnect_reason;
+ lm_verbose ("Disconnect reason: %d\n", reason);
}
connection_do_close (connection);
@@ -1440,6 +1458,35 @@
return LM_HANDLER_RESULT_REMOVE_MESSAGE;
}
+static void
+connection_stream_error (LmConnection *connection, LmMessage *m)
+{
+ LmMessageNode *node;
+
+ g_return_if_fail (connection != NULL);
+ g_return_if_fail (m != NULL);
+
+ node = m->node;
+
+ /* Resource conflict */
+ node = lm_message_node_get_child (node, "conflict");
+ if (node) {
+ lm_verbose ("Stream error: Conflict (resource connected elsewhere)\n");
+ connection->disconnect_reason = LM_DISCONNECT_REASON_RESOURCE_CONFLICT;
+ return;
+ }
+
+ /* XML is crack */
+ node = lm_message_node_get_child (node, "xml-not-well-formed");
+ if (node) {
+ lm_verbose ("Stream error: XML not well formed\n");
+ connection->disconnect_reason = LM_DISCONNECT_REASON_INVALID_XML;
+ return;
+ }
+
+ lm_verbose ("Stream error: Unrecognised error\n");
+ connection->disconnect_reason = LM_DISCONNECT_REASON_ERROR;
+}
static void
connection_stream_received (LmConnection *connection, LmMessage *m)
@@ -1585,6 +1632,7 @@
g_str_equal,
g_free,
(GDestroyNotify) lm_message_handler_unref);
+ connection->disconnect_reason = LM_DISCONNECT_REASON_UNKNOWN;
connection->ref_count = 1;
for (i = 0; i < LM_MESSAGE_TYPE_UNKNOWN; ++i) {
--- a/loudmouth/lm-connection.h Sun Apr 29 13:22:36 2007 +0200
+++ b/loudmouth/lm-connection.h Sun Apr 29 14:16:02 2007 +0200
@@ -56,7 +56,9 @@
LM_DISCONNECT_REASON_PING_TIME_OUT,
LM_DISCONNECT_REASON_HUP,
LM_DISCONNECT_REASON_ERROR,
- LM_DISCONNECT_REASON_UNKNOWN
+ LM_DISCONNECT_REASON_UNKNOWN,
+ LM_DISCONNECT_REASON_RESOURCE_CONFLICT,
+ LM_DISCONNECT_REASON_INVALID_XML
} LmDisconnectReason;
typedef enum {