[Telepathy-commits] [telepathy-gabble/master] socks5: add a timer when expecting the CONNECT reply so we don't stay blocked when connected to a bugged Gabble
Guillaume Desmottes
guillaume.desmottes at collabora.co.uk
Tue Mar 17 09:43:09 PDT 2009
---
src/bytestream-socks5.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 52 insertions(+), 0 deletions(-)
diff --git a/src/bytestream-socks5.c b/src/bytestream-socks5.c
index ecfb1bd..546dace 100644
--- a/src/bytestream-socks5.c
+++ b/src/bytestream-socks5.c
@@ -108,6 +108,8 @@ typedef enum _Socks5State Socks5State;
/* VER + CMD/REP + RSV + ATYP + DOMAIN_LEN + PORT (2) */
#define SOCKS5_MIN_LENGTH 7
+#define CONNECT_REPLY_TIMEOUT 30
+
struct _Streamhost
{
gchar *jid;
@@ -169,6 +171,7 @@ struct _GabbleBytestreamSocks5Private
gboolean write_blocked;
gboolean read_blocked;
GibberListener *listener;
+ guint timer_id;
GString *read_buffer;
@@ -197,6 +200,19 @@ gabble_bytestream_socks5_init (GabbleBytestreamSocks5 *self)
}
static void
+stop_timer (GabbleBytestreamSocks5 *self)
+{
+ GabbleBytestreamSocks5Private *priv = GABBLE_BYTESTREAM_SOCKS5_GET_PRIVATE (
+ self);
+
+ if (priv->timer_id == 0)
+ return;
+
+ g_source_remove (priv->timer_id);
+ priv->timer_id = 0;
+}
+
+static void
gabble_bytestream_socks5_dispose (GObject *object)
{
GabbleBytestreamSocks5 *self = GABBLE_BYTESTREAM_SOCKS5 (object);
@@ -210,6 +226,8 @@ gabble_bytestream_socks5_dispose (GObject *object)
priv->dispose_has_run = TRUE;
+ stop_timer (self);
+
tp_handle_unref (contact_repo, priv->peer_handle);
if (priv->bytestream_state != GABBLE_BYTESTREAM_STATE_CLOSED)
@@ -589,6 +607,8 @@ socks5_error (GabbleBytestreamSocks5 *self)
GABBLE_BYTESTREAM_SOCKS5_GET_PRIVATE (self);
Socks5State previous_state;
+ stop_timer (self);
+
previous_state = priv->socks5_state;
priv->socks5_state = SOCKS5_STATE_ERROR;
@@ -664,6 +684,29 @@ check_domain (const gchar *domain,
return TRUE;
}
+static gboolean
+socks5_timer_cb (gpointer data)
+{
+ GabbleBytestreamSocks5 *self = GABBLE_BYTESTREAM_SOCKS5 (data);
+
+ DEBUG ("Timed out; closing SOCKS5 connection");
+
+ socks5_error (self);
+ return FALSE;
+}
+
+static void
+start_timer (GabbleBytestreamSocks5 *self,
+ guint seconds)
+{
+ GabbleBytestreamSocks5Private *priv = GABBLE_BYTESTREAM_SOCKS5_GET_PRIVATE (
+ self);
+
+ g_assert (priv->timer_id == 0);
+
+ priv->timer_id = g_timeout_add_seconds (seconds, socks5_timer_cb, self);
+}
+
/* Process the received data and returns the number of bytes that have been
* used */
static gsize
@@ -721,6 +764,13 @@ socks5_handle_received_data (GabbleBytestreamSocks5 *self,
priv->socks5_state = SOCKS5_STATE_CONNECT_REQUESTED;
+ /* Older version of Gabble (pre 0.7.22) are bugged and just send 2
+ * bytes as CONNECT reply. We set a timer to not wait the full reply
+ * forever if we are connected to such Gabble.
+ * Once timed out, the SOCKS5 negotiation will fail and Gabble
+ * will switch to IBB as a fallback. */
+ start_timer (self, CONNECT_REPLY_TIMEOUT);
+
return 2;
case SOCKS5_STATE_CONNECT_REQUESTED:
@@ -733,6 +783,8 @@ socks5_handle_received_data (GabbleBytestreamSocks5 *self,
/* We didn't receive the full packet yet */
return 0;
+ stop_timer (self);
+
if (string->str[0] != SOCKS5_VERSION ||
string->str[1] != SOCKS5_STATUS_OK ||
string->str[2] != SOCKS5_RESERVED ||
--
1.5.6.5
More information about the telepathy-commits
mailing list