summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Dufresne <nicolas.dufresne@collabora.co.uk>2010-05-25 16:02:42 -0400
committerNicolas Dufresne <nicolas.dufresne@collabora.co.uk>2010-08-19 16:32:38 -0400
commitced1d0e2e7d164873d8b7e335a00cfac13785760 (patch)
treebb803cd0dccd2664640fd4c9e239ddd6d0bf7d42
parente2a90bcb5fc50f099cbf8df01a09697f7e48522d (diff)
Implemented SOCKSv4 and SOCKSv4a
-rw-r--r--gio/Makefile.am4
-rw-r--r--gio/giomodule.c4
-rw-r--r--gio/gsocks4aproxy.c495
-rw-r--r--gio/gsocks4aproxy.h55
-rw-r--r--gio/gsocks4proxy.c73
-rw-r--r--gio/gsocks4proxy.h44
-rw-r--r--po/POTFILES.in1
7 files changed, 676 insertions, 0 deletions
diff --git a/gio/Makefile.am b/gio/Makefile.am
index 61f10eb8f..6962369d1 100644
--- a/gio/Makefile.am
+++ b/gio/Makefile.am
@@ -160,6 +160,10 @@ local_sources = \
glocalfileiostream.h \
glocalvfs.c \
glocalvfs.h \
+ gsocks4proxy.c \
+ gsocks4proxy.h \
+ gsocks4aproxy.c \
+ gsocks4aproxy.h \
gsocks5proxy.c \
gsocks5proxy.h \
$(NULL)
diff --git a/gio/giomodule.c b/gio/giomodule.c
index e0abf2f9c..882e224d4 100644
--- a/gio/giomodule.c
+++ b/gio/giomodule.c
@@ -32,6 +32,8 @@
#include "gnativevolumemonitor.h"
#include "gproxyresolver.h"
#include "gproxy.h"
+#include "gsocks4proxy.h"
+#include "gsocks4aproxy.h"
#include "gsocks5proxy.h"
#include "gvfs.h"
#ifdef G_OS_UNIX
@@ -603,6 +605,8 @@ _g_io_modules_ensure_loaded (void)
#endif
_g_local_vfs_get_type ();
_g_dummy_proxy_resolver_get_type ();
+ _g_socks4a_proxy_get_type ();
+ _g_socks4_proxy_get_type ();
_g_socks5_proxy_get_type ();
}
diff --git a/gio/gsocks4aproxy.c b/gio/gsocks4aproxy.c
new file mode 100644
index 000000000..097b53465
--- /dev/null
+++ b/gio/gsocks4aproxy.c
@@ -0,0 +1,495 @@
+ /* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2010 Collabora, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
+ */
+
+#include "config.h"
+
+#include "gsocks4aproxy.h"
+
+#include <string.h>
+
+#include "gasyncresult.h"
+#include "giomodule.h"
+#include "giomodule-priv.h"
+#include "giostream.h"
+#include "ginetaddress.h"
+#include "ginputstream.h"
+#include "glibintl.h"
+#include "goutputstream.h"
+#include "gproxy.h"
+#include "gproxyaddress.h"
+#include "gsimpleasyncresult.h"
+
+#define SOCKS4_VERSION 4
+
+#define SOCKS4_CMD_CONNECT 1
+#define SOCKS4_CMD_BIND 2
+
+#define SOCKS4_MAX_LEN 255
+
+#define SOCKS4_REP_VERSION 0
+#define SOCKS4_REP_GRANTED 90
+#define SOCKS4_REP_REJECTED 91
+#define SOCKS4_REP_NO_IDENT 92
+#define SOCKS4_REP_BAD_IDENT 93
+
+static void g_socks4a_proxy_iface_init (GProxyInterface *proxy_iface);
+
+#define g_socks4a_proxy_get_type _g_socks4a_proxy_get_type
+G_DEFINE_TYPE_WITH_CODE (GSocks4aProxy, g_socks4a_proxy, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_PROXY,
+ g_socks4a_proxy_iface_init)
+ _g_io_modules_ensure_extension_points_registered ();
+ g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME,
+ g_define_type_id,
+ "socks4a",
+ 0))
+
+static void
+g_socks4a_proxy_finalize (GObject *object)
+{
+ /* must chain up */
+ G_OBJECT_CLASS (g_socks4a_proxy_parent_class)->finalize (object);
+}
+
+static void
+g_socks4a_proxy_init (GSocks4aProxy *proxy)
+{
+ proxy->supports_hostname = TRUE;
+}
+
+/* |-> SOCKSv4a only
+ * +----+----+----+----+----+----+----+----+----+----+....+----+------+....+------+
+ * | VN | CD | DSTPORT | DSTIP | USERID |NULL| HOST | | NULL |
+ * +----+----+----+----+----+----+----+----+----+----+....+----+------+....+------+
+ * 1 1 2 4 variable 1 variable
+ */
+#define SOCKS4_CONN_MSG_LEN (9 + SOCKS4_MAX_LEN * 2)
+static gint
+set_connect_msg (guint8 *msg,
+ const gchar *hostname,
+ guint16 port,
+ const char *username,
+ GError **error)
+{
+ GInetAddress *addr;
+ guint len = 0;
+ gsize addr_len;
+ gboolean is_ip;
+ const gchar *ip;
+
+ msg[len++] = SOCKS4_VERSION;
+ msg[len++] = SOCKS4_CMD_CONNECT;
+
+ {
+ guint16 hp = g_htons (port);
+ memcpy (msg + len, &hp, 2);
+ len += 2;
+ }
+
+ is_ip = g_hostname_is_ip_address (hostname);
+
+ if (is_ip)
+ ip = hostname;
+ else
+ ip = "0.0.0.1";
+
+ addr = g_inet_address_new_from_string (ip);
+ addr_len = g_inet_address_get_native_size (addr);
+
+ if (addr_len != 4)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED,
+ _("SOCKSv4 does not support IPv6 address '%s'"),
+ ip);
+ g_object_unref (addr);
+ return -1;
+ }
+
+ memcpy (msg + len, g_inet_address_to_bytes (addr), addr_len);
+ len += addr_len;
+
+ g_object_unref (addr);
+
+ if (username)
+ {
+ gsize user_len = strlen (username);
+
+ if (user_len > SOCKS4_MAX_LEN)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED,
+ _("SOCKSv4 implementation limits username to %i characters"),
+ SOCKS4_MAX_LEN);
+ return -1;
+ }
+
+ memcpy (msg + len, username, user_len);
+ len += user_len;
+ }
+
+ msg[len++] = '\0';
+
+ if (!is_ip)
+ {
+ gsize host_len = strlen (hostname);
+
+ if (host_len > SOCKS4_MAX_LEN)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED,
+ _("SOCKSv4a implementation limits hostname to %i characters"),
+ SOCKS4_MAX_LEN);
+ return -1;
+ }
+
+ memcpy (msg + len, hostname, host_len);
+ len += host_len;
+ msg[len++] = '\0';
+ }
+
+ return len;
+}
+
+/*
+ * +----+----+----+----+----+----+----+----+
+ * | VN | CD | DSTPORT | DSTIP |
+ * +----+----+----+----+----+----+----+----+
+ * 1 1 2 4
+ */
+#define SOCKS4_CONN_REP_LEN 8
+static gboolean
+parse_connect_reply (const guint8 *data, GError **error)
+{
+ if (data[0] != SOCKS4_REP_VERSION)
+ {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED,
+ _("The server is not a SOCKSv4 proxy server."));
+ return FALSE;
+ }
+
+ if (data[1] != SOCKS4_REP_GRANTED)
+ {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED,
+ _("Connection through SOCKSv4 server was rejected"));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static GIOStream *
+g_socks4a_proxy_connect (GProxy *proxy,
+ GIOStream *io_stream,
+ GProxyAddress *proxy_address,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GInputStream *in;
+ GOutputStream *out;
+ const gchar *hostname;
+ guint16 port;
+ const gchar *username;
+
+ hostname = g_proxy_address_get_destination_hostname (proxy_address);
+ port = g_proxy_address_get_destination_port (proxy_address);
+ username = g_proxy_address_get_username (proxy_address);
+
+ in = g_io_stream_get_input_stream (io_stream);
+ out = g_io_stream_get_output_stream (io_stream);
+
+ /* Send SOCKS4 connection request */
+ {
+ guint8 msg[SOCKS4_CONN_MSG_LEN];
+ gint len;
+
+ len = set_connect_msg (msg, hostname, port, username, error);
+
+ if (len < 0)
+ goto error;
+
+ if (!g_output_stream_write_all (out, msg, len, NULL,
+ cancellable, error))
+ goto error;
+ }
+
+ /* Read SOCKS4 response */
+ {
+ guint8 data[SOCKS4_CONN_REP_LEN];
+
+ if (!g_input_stream_read_all (in, data, SOCKS4_CONN_REP_LEN, NULL,
+ cancellable, error))
+ goto error;
+
+ if (!parse_connect_reply (data, error))
+ goto error;
+ }
+
+ return g_object_ref (io_stream);
+
+error:
+ return NULL;
+}
+
+
+typedef struct
+{
+ GSimpleAsyncResult *simple;
+ GIOStream *io_stream;
+ GProxyAddress *proxy_address;
+ GCancellable *cancellable;
+
+ /* For connecting */
+ guint8 *buffer;
+ gssize length;
+ gssize offset;
+
+} ConnectAsyncData;
+
+static void connect_msg_write_cb (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data);
+static void connect_reply_read_cb (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data);
+
+static void
+free_connect_data (ConnectAsyncData *data)
+{
+ if (data->io_stream)
+ g_object_unref (data->io_stream);
+
+ if (data->proxy_address)
+ g_object_unref (data->proxy_address);
+
+ if (data->cancellable)
+ g_object_unref (data->cancellable);
+
+ g_slice_free (ConnectAsyncData, data);
+}
+
+static void
+complete_async_from_error (ConnectAsyncData *data, GError *error)
+{
+ GSimpleAsyncResult *simple = data->simple;
+ g_simple_async_result_set_from_error (data->simple,
+ error);
+ g_error_free (error);
+ g_simple_async_result_set_op_res_gpointer (simple, NULL, NULL);
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+}
+
+static void
+do_read (GAsyncReadyCallback callback, ConnectAsyncData *data)
+{
+ GInputStream *in;
+ in = g_io_stream_get_input_stream (data->io_stream);
+ g_input_stream_read_async (in,
+ data->buffer + data->offset,
+ data->length - data->offset,
+ G_PRIORITY_DEFAULT, data->cancellable,
+ callback, data);
+}
+
+static void
+do_write (GAsyncReadyCallback callback, ConnectAsyncData *data)
+{
+ GOutputStream *out;
+ out = g_io_stream_get_output_stream (data->io_stream);
+ g_output_stream_write_async (out,
+ data->buffer + data->offset,
+ data->length - data->offset,
+ G_PRIORITY_DEFAULT, data->cancellable,
+ callback, data);
+}
+
+
+
+static void
+g_socks4a_proxy_connect_async (GProxy *proxy,
+ GIOStream *io_stream,
+ GProxyAddress *proxy_address,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ GSimpleAsyncResult *simple;
+ ConnectAsyncData *data;
+ const gchar *hostname;
+ guint16 port;
+ const gchar *username;
+
+ simple = g_simple_async_result_new (G_OBJECT (proxy),
+ callback, user_data,
+ g_socks4a_proxy_connect_async);
+
+ data = g_slice_new0 (ConnectAsyncData);
+
+ data->simple = simple;
+ data->io_stream = g_object_ref (io_stream);
+
+ if (cancellable)
+ data->cancellable = g_object_ref (cancellable);
+
+ g_simple_async_result_set_op_res_gpointer (simple, data,
+ (GDestroyNotify) free_connect_data);
+
+ hostname = g_proxy_address_get_destination_hostname (proxy_address);
+ port = g_proxy_address_get_destination_port (proxy_address);
+ username = g_proxy_address_get_username (proxy_address);
+
+ data->buffer = g_malloc0 (SOCKS4_CONN_MSG_LEN);
+ data->length = set_connect_msg (data->buffer,
+ hostname, port, username,
+ &error);
+ data->offset = 0;
+
+ if (data->length < 0)
+ {
+ g_simple_async_result_set_from_error (data->simple,
+ error);
+ g_error_free (error);
+ g_simple_async_result_set_op_res_gpointer (simple, NULL, NULL);
+ g_simple_async_result_complete_in_idle (simple);
+ g_object_unref (simple);
+ }
+ else
+ {
+ do_write (connect_msg_write_cb, data);
+ }
+}
+
+static void
+connect_msg_write_cb (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ ConnectAsyncData *data = user_data;
+ gssize written;
+
+ written = g_output_stream_write_finish (G_OUTPUT_STREAM (source),
+ result, &error);
+
+ if (written < 0)
+ {
+ complete_async_from_error (data, error);
+ return;
+ }
+
+ data->offset += written;
+
+ if (data->offset == data->length)
+ {
+ g_free (data->buffer);
+
+ data->buffer = g_malloc0 (SOCKS4_CONN_REP_LEN);
+ data->length = SOCKS4_CONN_REP_LEN;
+ data->offset = 0;
+
+ do_read (connect_reply_read_cb, data);
+ }
+ else
+ {
+ do_write (connect_msg_write_cb, data);
+ }
+}
+
+static void
+connect_reply_read_cb (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ ConnectAsyncData *data = user_data;
+ gssize read;
+
+ read = g_input_stream_read_finish (G_INPUT_STREAM (source),
+ result, &error);
+
+ if (read < 0)
+ {
+ complete_async_from_error (data, error);
+ return;
+ }
+
+ data->offset += read;
+
+ if (data->offset == data->length)
+ {
+ if (!parse_connect_reply (data->buffer, &error))
+ {
+ complete_async_from_error (data, error);
+ }
+ else
+ {
+ GSimpleAsyncResult *simple = data->simple;
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+ }
+ }
+ else
+ {
+ do_read (connect_reply_read_cb, data);
+ }
+}
+
+static GIOStream *g_socks4a_proxy_connect_finish (GProxy *proxy,
+ GAsyncResult *result,
+ GError **error);
+
+static GIOStream *
+g_socks4a_proxy_connect_finish (GProxy *proxy,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+ ConnectAsyncData *data = g_simple_async_result_get_op_res_gpointer (simple);
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return NULL;
+
+ return g_object_ref (data->io_stream);
+}
+
+static gboolean
+g_socks4a_proxy_supports_hostname (GProxy *proxy)
+{
+ return G_SOCKS4A_PROXY (proxy)->supports_hostname;
+}
+
+static void
+g_socks4a_proxy_class_init (GSocks4aProxyClass *class)
+{
+ GObjectClass *object_class;
+
+ object_class = (GObjectClass *) class;
+ object_class->finalize = g_socks4a_proxy_finalize;
+}
+
+static void
+g_socks4a_proxy_iface_init (GProxyInterface *proxy_iface)
+{
+ proxy_iface->connect = g_socks4a_proxy_connect;
+ proxy_iface->connect_async = g_socks4a_proxy_connect_async;
+ proxy_iface->connect_finish = g_socks4a_proxy_connect_finish;
+ proxy_iface->supports_hostname = g_socks4a_proxy_supports_hostname;
+}
diff --git a/gio/gsocks4aproxy.h b/gio/gsocks4aproxy.h
new file mode 100644
index 000000000..e6c7b04e6
--- /dev/null
+++ b/gio/gsocks4aproxy.h
@@ -0,0 +1,55 @@
+ /* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2010 Collabora, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
+ */
+
+#ifndef __G_SOCKS4A_PROXY_H__
+#define __G_SOCKS4A_PROXY_H__
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_SOCKS4A_PROXY (_g_socks4a_proxy_get_type ())
+#define G_SOCKS4A_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_SOCKS4A_PROXY, GSocks4aProxy))
+#define G_SOCKS4A_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_SOCKS4A_PROXY, GSocks4aProxyClass))
+#define G_IS_SOCKS4A_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_SOCKS4A_PROXY))
+#define G_IS_SOCKS4A_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_SOCKS4A_PROXY))
+#define G_SOCKS4A_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_SOCKS4A_PROXY, GSocks4aProxyClass))
+
+typedef struct _GSocks4aProxy GSocks4aProxy;
+typedef struct _GSocks4aProxyClass GSocks4aProxyClass;
+
+struct _GSocks4aProxy
+{
+ GObject parent;
+ gboolean supports_hostname;
+};
+
+struct _GSocks4aProxyClass
+{
+ GObjectClass parent_class;
+};
+
+GType _g_socks4a_proxy_get_type (void);
+
+G_END_DECLS
+
+#endif /* __SOCKS5_PROXY_H__ */
diff --git a/gio/gsocks4proxy.c b/gio/gsocks4proxy.c
new file mode 100644
index 000000000..4524675fd
--- /dev/null
+++ b/gio/gsocks4proxy.c
@@ -0,0 +1,73 @@
+ /* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2010 Collabora, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
+ */
+
+#include "config.h"
+
+#include "gsocks4proxy.h"
+
+#include "giomodule.h"
+#include "giomodule-priv.h"
+#include "gproxy.h"
+#include "gsocks4aproxy.h"
+
+struct _GSocks4Proxy
+{
+ GSocks4aProxy parent;
+};
+
+struct _GSocks4ProxyClass
+{
+ GSocks4aProxyClass parent_class;
+};
+
+static void g_socks4_proxy_iface_init (GProxyInterface *proxy_iface);
+
+#define g_socks4_proxy_get_type _g_socks4_proxy_get_type
+G_DEFINE_TYPE_WITH_CODE (GSocks4Proxy, g_socks4_proxy, G_TYPE_SOCKS4A_PROXY,
+ _g_io_modules_ensure_extension_points_registered ();
+ g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME,
+ g_define_type_id,
+ "socks4",
+ 0))
+
+static void
+g_socks4_proxy_finalize (GObject *object)
+{
+ /* must chain up */
+ G_OBJECT_CLASS (g_socks4_proxy_parent_class)->finalize (object);
+}
+
+static void
+g_socks4_proxy_init (GSocks4Proxy *proxy)
+{
+ G_SOCKS4A_PROXY (proxy)->supports_hostname = FALSE;
+}
+
+
+static void
+g_socks4_proxy_class_init (GSocks4ProxyClass *class)
+{
+ GObjectClass *object_class;
+
+ object_class = (GObjectClass *) class;
+ object_class->finalize = g_socks4_proxy_finalize;
+}
diff --git a/gio/gsocks4proxy.h b/gio/gsocks4proxy.h
new file mode 100644
index 000000000..5b89d2de4
--- /dev/null
+++ b/gio/gsocks4proxy.h
@@ -0,0 +1,44 @@
+ /* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2010 Collabora, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
+ */
+
+#ifndef __G_SOCKS4_PROXY_H__
+#define __G_SOCKS4_PROXY_H__
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_SOCKS4_PROXY (_g_socks4_proxy_get_type ())
+#define G_SOCKS4_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_SOCKS4_PROXY, GSocks4Proxy))
+#define G_SOCKS4_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_SOCKS4_PROXY, GSocks4ProxyClass))
+#define G_IS_SOCKS4_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_SOCKS4_PROXY))
+#define G_IS_SOCKS4_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_SOCKS4_PROXY))
+#define G_SOCKS4_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_SOCKS4_PROXY, GSocks4ProxyClass))
+
+typedef struct _GSocks4Proxy GSocks4Proxy;
+typedef struct _GSocks4ProxyClass GSocks4ProxyClass;
+
+GType _g_socks4_proxy_get_type (void);
+
+G_END_DECLS
+
+#endif /* __SOCKS5_PROXY_H__ */
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 1861177e5..c4d9a4ac8 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -102,6 +102,7 @@ gio/gsocketconnection.c
gio/gsocketinputstream.c
gio/gsocketlistener.c
gio/gsocketoutputstream.c
+gio/gsocks4aproxy.c
gio/gsocks5proxy.c
gio/gtcpconnection.c
gio/gthemedicon.c