diff options
author | dequis <dx@dxzone.com.ar> | 2015-10-21 10:14:17 -0300 |
---|---|---|
committer | dequis <dx@dxzone.com.ar> | 2015-10-21 10:14:17 -0300 |
commit | 12f041de930a20a3df91f9f90c4fd518162ea82c (patch) | |
tree | bfe4f8b160ea4707d2600b73eb0e28d3b5f505c8 /lib/proxy.c | |
parent | 3314ced0efff64ce4f92caf24b9272f5249c3a17 (diff) |
socks4a proxy support (like socks4 with remote DNS)
Fixes trac ticket 995 https://bugs.bitlbee.org/bitlbee/ticket/995
This is slightly pointless for the suggested use case (tor), since with
socks5 we already send a hostname instead of an IP address.
Either way, it was easy to implement, so I hope it helps.
Diffstat (limited to 'lib/proxy.c')
-rw-r--r-- | lib/proxy.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/lib/proxy.c b/lib/proxy.c index 4028f750..c4f75772 100644 --- a/lib/proxy.c +++ b/lib/proxy.c @@ -293,6 +293,7 @@ static gboolean s4_canwrite(gpointer data, gint source, b_input_condition cond) struct PHB *phb = data; socklen_t len; int error = ETIMEDOUT; + gboolean is_socks4a = (proxytype == PROXY_SOCKS4A); if (phb->inpa > 0) { b_event_remove(phb->inpa); @@ -303,8 +304,7 @@ static gboolean s4_canwrite(gpointer data, gint source, b_input_condition cond) } sock_make_blocking(source); - /* XXX does socks4 not support host name lookups by the proxy? */ - if (!(hp = gethostbyname(phb->host))) { + if (!is_socks4a && !(hp = gethostbyname(phb->host))) { return phb_close(phb); } @@ -312,15 +312,30 @@ static gboolean s4_canwrite(gpointer data, gint source, b_input_condition cond) packet[1] = 1; packet[2] = phb->port >> 8; packet[3] = phb->port & 0xff; - packet[4] = (unsigned char) (hp->h_addr_list[0])[0]; - packet[5] = (unsigned char) (hp->h_addr_list[0])[1]; - packet[6] = (unsigned char) (hp->h_addr_list[0])[2]; - packet[7] = (unsigned char) (hp->h_addr_list[0])[3]; + if (is_socks4a) { + packet[4] = 0; + packet[5] = 0; + packet[6] = 0; + packet[7] = 1; + } else { + packet[4] = (unsigned char) (hp->h_addr_list[0])[0]; + packet[5] = (unsigned char) (hp->h_addr_list[0])[1]; + packet[6] = (unsigned char) (hp->h_addr_list[0])[2]; + packet[7] = (unsigned char) (hp->h_addr_list[0])[3]; + } packet[8] = 0; if (write(source, packet, 9) != 9) { return phb_close(phb); } + if (is_socks4a) { + size_t host_len = strlen(phb->host) + 1; /* include the \0 */ + + if (write(source, phb->host, host_len) != host_len) { + return phb_close(phb); + } + } + phb->inpa = b_input_add(source, B_EV_IO_READ, s4_canread, phb); return FALSE; @@ -505,7 +520,7 @@ int proxy_connect(const char *host, int port, b_event_handler func, gpointer dat return proxy_connect_none(host, port, phb); } else if (proxytype == PROXY_HTTP) { return proxy_connect_http(host, port, phb); - } else if (proxytype == PROXY_SOCKS4) { + } else if (proxytype == PROXY_SOCKS4 || proxytype == PROXY_SOCKS4A) { return proxy_connect_socks4(host, port, phb); } else if (proxytype == PROXY_SOCKS5) { return proxy_connect_socks5(host, port, phb); |