aboutsummaryrefslogtreecommitdiffstats
path: root/lib/proxy.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/proxy.c')
-rw-r--r--lib/proxy.c75
1 files changed, 40 insertions, 35 deletions
diff --git a/lib/proxy.c b/lib/proxy.c
index 65b7c367..88649d4e 100644
--- a/lib/proxy.c
+++ b/lib/proxy.c
@@ -64,10 +64,19 @@ typedef int (*proxy_connect_func)(const char *host, unsigned short port_, struct
static int proxy_connect_none(const char *host, unsigned short port_, struct PHB *phb);
-static gboolean phb_close(struct PHB *phb)
+static gboolean phb_free(struct PHB *phb, gboolean success)
{
- close(phb->fd);
- phb->func(phb->data, -1, B_EV_IO_READ);
+ if (!success) {
+ if (phb->fd > 0) {
+ closesocket(phb->fd);
+ }
+ if (phb->func) {
+ phb->func(phb->data, -1, B_EV_IO_READ);
+ }
+ }
+ if (phb->gai) {
+ freeaddrinfo(phb->gai);
+ }
g_free(phb->host);
g_free(phb);
return FALSE;
@@ -102,13 +111,16 @@ static gboolean proxy_connected(gpointer data, gint source, b_input_condition co
}
freeaddrinfo(phb->gai);
+ phb->gai = NULL;
+
b_event_remove(phb->inpa);
phb->inpa = 0;
+
if (phb->proxy_func) {
phb->proxy_func(phb->proxy_data, source, B_EV_IO_READ);
} else {
phb->func(phb->data, source, B_EV_IO_READ);
- g_free(phb);
+ phb_free(phb, TRUE);
}
return FALSE;
@@ -172,7 +184,7 @@ static int proxy_connect_none(const char *host, unsigned short port_, struct PHB
}
if (fd < 0 && host) {
- g_free(phb);
+ phb_free(phb, TRUE);
}
return fd;
@@ -205,12 +217,10 @@ static gboolean http_canread(gpointer data, gint source, b_input_condition cond)
if ((memcmp(HTTP_GOODSTRING, inputline, strlen(HTTP_GOODSTRING)) == 0) ||
(memcmp(HTTP_GOODSTRING2, inputline, strlen(HTTP_GOODSTRING2)) == 0)) {
phb->func(phb->data, source, B_EV_IO_READ);
- g_free(phb->host);
- g_free(phb);
- return FALSE;
+ return phb_free(phb, TRUE);
}
- return phb_close(phb);
+ return phb_free(phb, FALSE);
}
static gboolean http_canwrite(gpointer data, gint source, b_input_condition cond)
@@ -225,14 +235,14 @@ static gboolean http_canwrite(gpointer data, gint source, b_input_condition cond
}
len = sizeof(error);
if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
- return phb_close(phb);
+ return phb_free(phb, FALSE);
}
sock_make_blocking(source);
g_snprintf(cmd, sizeof(cmd), "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", phb->host, phb->port,
phb->host, phb->port);
if (send(source, cmd, strlen(cmd), 0) < 0) {
- return phb_close(phb);
+ return phb_free(phb, FALSE);
}
if (strlen(proxyuser) > 0) {
@@ -243,13 +253,13 @@ static gboolean http_canwrite(gpointer data, gint source, b_input_condition cond
g_snprintf(cmd, sizeof(cmd), "Proxy-Authorization: Basic %s\r\n", t2);
g_free(t2);
if (send(source, cmd, strlen(cmd), 0) < 0) {
- return phb_close(phb);
+ return phb_free(phb, FALSE);
}
}
g_snprintf(cmd, sizeof(cmd), "\r\n");
if (send(source, cmd, strlen(cmd), 0) < 0) {
- return phb_close(phb);
+ return phb_free(phb, FALSE);
}
phb->inpa = b_input_add(source, B_EV_IO_READ, http_canread, phb);
@@ -280,12 +290,10 @@ static gboolean s4_canread(gpointer data, gint source, b_input_condition cond)
memset(packet, 0, sizeof(packet));
if (read(source, packet, 9) >= 4 && packet[1] == 90) {
phb->func(phb->data, source, B_EV_IO_READ);
- g_free(phb->host);
- g_free(phb);
- return FALSE;
+ return phb_free(phb, TRUE);
}
- return phb_close(phb);
+ return phb_free(phb, FALSE);
}
static gboolean s4_canwrite(gpointer data, gint source, b_input_condition cond)
@@ -302,12 +310,12 @@ static gboolean s4_canwrite(gpointer data, gint source, b_input_condition cond)
}
len = sizeof(error);
if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
- return phb_close(phb);
+ return phb_free(phb, FALSE);
}
sock_make_blocking(source);
if (!is_socks4a && !(hp = gethostbyname(phb->host))) {
- return phb_close(phb);
+ return phb_free(phb, FALSE);
}
packet[0] = 4;
@@ -327,14 +335,14 @@ static gboolean s4_canwrite(gpointer data, gint source, b_input_condition cond)
}
packet[8] = 0;
if (write(source, packet, 9) != 9) {
- return phb_close(phb);
+ return phb_free(phb, FALSE);
}
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);
+ return phb_free(phb, FALSE);
}
}
@@ -364,17 +372,14 @@ static gboolean s5_canread_again(gpointer data, gint source, b_input_condition c
b_event_remove(phb->inpa);
if (read(source, buf, 10) < 10) {
- return phb_close(phb);
+ return phb_free(phb, FALSE);
}
if ((buf[0] != 0x05) || (buf[1] != 0x00)) {
- return phb_close(phb);
+ return phb_free(phb, FALSE);
}
phb->func(phb->data, source, B_EV_IO_READ);
- g_free(phb->host);
- g_free(phb);
-
- return FALSE;
+ return phb_free(phb, TRUE);
}
static void s5_sendconnect(gpointer data, gint source)
@@ -393,7 +398,7 @@ static void s5_sendconnect(gpointer data, gint source)
buf[5 + strlen(phb->host) + 1] = phb->port & 0xff;
if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) {
- phb_close(phb);
+ phb_free(phb, FALSE);
return;
}
@@ -408,11 +413,11 @@ static gboolean s5_readauth(gpointer data, gint source, b_input_condition cond)
b_event_remove(phb->inpa);
if (read(source, buf, 2) < 2) {
- return phb_close(phb);
+ return phb_free(phb, FALSE);
}
if ((buf[0] != 0x01) || (buf[1] != 0x00)) {
- return phb_close(phb);
+ return phb_free(phb, FALSE);
}
s5_sendconnect(phb, source);
@@ -428,11 +433,11 @@ static gboolean s5_canread(gpointer data, gint source, b_input_condition cond)
b_event_remove(phb->inpa);
if (read(source, buf, 2) < 2) {
- return phb_close(phb);
+ return phb_free(phb, FALSE);
}
if ((buf[0] != 0x05) || (buf[1] == 0xff)) {
- return phb_close(phb);
+ return phb_free(phb, FALSE);
}
if (buf[1] == 0x02) {
@@ -443,7 +448,7 @@ static gboolean s5_canread(gpointer data, gint source, b_input_condition cond)
buf[2 + i] = j;
memcpy(buf + 2 + i + 1, proxypass, j);
if (write(source, buf, 3 + i + j) < 3 + i + j) {
- return phb_close(phb);
+ return phb_free(phb, FALSE);
}
phb->inpa = b_input_add(source, B_EV_IO_READ, s5_readauth, phb);
@@ -467,7 +472,7 @@ static gboolean s5_canwrite(gpointer data, gint source, b_input_condition cond)
}
len = sizeof(error);
if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
- return phb_close(phb);
+ return phb_free(phb, FALSE);
}
sock_make_blocking(source);
@@ -485,7 +490,7 @@ static gboolean s5_canwrite(gpointer data, gint source, b_input_condition cond)
}
if (write(source, buf, i) < i) {
- return phb_close(phb);
+ return phb_free(phb, FALSE);
}
phb->inpa = b_input_add(source, B_EV_IO_READ, s5_canread, phb);