[evolution-data-server] Function to connect to a SOCKS4 proxy
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Function to connect to a SOCKS4 proxy
- Date: Wed, 2 Jun 2010 22:50:13 +0000 (UTC)
commit dbc72b58fddef22b3599b46dad99453985aa9695
Author: Federico Mena Quintero <federico novell com>
Date: Tue May 25 16:18:21 2010 -0500
Function to connect to a SOCKS4 proxy
Signed-off-by: Federico Mena Quintero <federico novell com>
camel/camel-tcp-stream-raw.c | 73 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 73 insertions(+), 0 deletions(-)
---
diff --git a/camel/camel-tcp-stream-raw.c b/camel/camel-tcp-stream-raw.c
index 153d008..2058afe 100644
--- a/camel/camel-tcp-stream-raw.c
+++ b/camel/camel-tcp-stream-raw.c
@@ -33,6 +33,7 @@
#include <sys/types.h>
#include "camel-file-utils.h"
+#include "camel-net-utils.h"
#include "camel-operation.h"
#include "camel-tcp-stream-raw.h"
@@ -372,6 +373,78 @@ tcp_stream_raw_close (CamelStream *stream)
return 0;
}
+/* Returns the FD of a socket, already connected to and validated by the SOCKS4
+ * proxy that is configured in the stream. Otherwise returns -1. Assumes that
+ * a proxy *is* configured with camel_tcp_stream_set_socks_proxy().
+ */
+static gint
+connect_to_socks4_proxy (CamelTcpStreamRaw *raw, struct addrinfo *connect_addr)
+{
+ const gchar *host;
+ gint port;
+ struct addrinfo *ai, hints;
+ gchar serv[16];
+ gint fd;
+ gchar request[9];
+ struct sockaddr_in *sin;
+ guint32 network_address;
+ gchar reply[8];
+
+ camel_tcp_stream_peek_socks_proxy (CAMEL_TCP_STREAM (raw), &host, &port);
+
+ g_assert (host != NULL);
+
+ sprintf (serv, "%d", port);
+
+ memset (&hints, 0, sizeof (hints));
+ hints.ai_socktype = SOCK_STREAM;
+
+ ai = camel_getaddrinfo (host, serv, &hints, NULL);
+ if (!ai)
+ return -1;
+
+ fd = socket_connect (ai);
+
+ camel_freeaddrinfo (ai);
+
+ if (fd == -1)
+ goto error;
+
+ g_assert (connect_addr->ai_addr->sa_family == AF_INET); /* FIXME: what to do about IPv6? Are we just screwed with SOCKS4? */
+ sin = (struct sockaddr_in *) connect_addr->ai_addr;
+ network_address = sin->sin_addr.s_addr;
+ network_address = htonl (network_address);
+
+ request[0] = 0x04; /* SOCKS4 */
+ request[1] = 0x01; /* CONNECT */
+ request[2] = sin->sin_port >> 8; /* high byte of port */
+ request[3] = sin->sin_port & 0x00ff; /* low byte of port */
+ memcpy (request + 4, &network_address, 4); /* address in network byte order */
+ request[8] = 0x00; /* terminator */
+
+ if (camel_write_socket (fd, request, sizeof (request)) != sizeof (request))
+ goto error;
+
+ if (camel_read_socket (fd, reply, sizeof (reply)) != sizeof (reply))
+ goto error;
+
+ if (!(reply[0] == 0 /* first byte of reply is 0 */
+ && reply[1] != 90)) /* 90 means "request granted" */
+ goto error;
+
+ goto out;
+
+error:
+ if (fd != -1) {
+ SOCKET_CLOSE (fd);
+ fd = -1;
+ }
+
+out:
+
+ return fd;
+}
+
static gint
tcp_stream_raw_connect (CamelTcpStream *stream,
struct addrinfo *host)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]