aboutsummaryrefslogtreecommitdiffstats
path: root/lib/proxy.c
diff options
context:
space:
mode:
authordequis <dx@dxzone.com.ar>2015-10-21 10:14:17 -0300
committerdequis <dx@dxzone.com.ar>2015-10-21 10:14:17 -0300
commit12f041de930a20a3df91f9f90c4fd518162ea82c (patch)
treebfe4f8b160ea4707d2600b73eb0e28d3b5f505c8 /lib/proxy.c
parent3314ced0efff64ce4f92caf24b9272f5249c3a17 (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.c29
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);