Index: lib/proxy.c
===================================================================
--- lib/proxy.c	(revision 5756890026534ecaa0424750fa0f3fc15e42e8cb)
+++ lib/proxy.c	(revision f710673a3d6f7d602c8261789ae78a4f273fb1a9)
@@ -65,8 +65,17 @@
 static int proxy_connect_none(const char *host, unsigned short port_, struct PHB *phb);
 
-static gboolean phb_close(struct PHB *phb)
-{
-	close(phb->fd);
-	phb->func(phb->data, -1, B_EV_IO_READ);
+static gboolean phb_free(struct PHB *phb, gboolean success)
+{
+	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);
@@ -103,11 +112,14 @@
 
 	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);
 	}
 
@@ -173,5 +185,5 @@
 
 	if (fd < 0 && host) {
-		g_free(phb);
+		phb_free(phb, TRUE);
 	}
 
@@ -206,10 +218,8 @@
 	    (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_close(phb);
+		return phb_free(phb, TRUE);
+	}
+
+	return phb_free(phb, FALSE);
 }
 
@@ -226,5 +236,5 @@
 	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);
@@ -233,5 +243,5 @@
 	           phb->host, phb->port);
 	if (send(source, cmd, strlen(cmd), 0) < 0) {
-		return phb_close(phb);
+		return phb_free(phb, FALSE);
 	}
 
@@ -244,5 +254,5 @@
 		g_free(t2);
 		if (send(source, cmd, strlen(cmd), 0) < 0) {
-			return phb_close(phb);
+			return phb_free(phb, FALSE);
 		}
 	}
@@ -250,5 +260,5 @@
 	g_snprintf(cmd, sizeof(cmd), "\r\n");
 	if (send(source, cmd, strlen(cmd), 0) < 0) {
-		return phb_close(phb);
+		return phb_free(phb, FALSE);
 	}
 
@@ -281,10 +291,8 @@
 	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_close(phb);
+		return phb_free(phb, TRUE);
+	}
+
+	return phb_free(phb, FALSE);
 }
 
@@ -303,10 +311,10 @@
 	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);
 	}
 
@@ -328,5 +336,5 @@
 	packet[8] = 0;
 	if (write(source, packet, 9) != 9) {
-		return phb_close(phb);
+		return phb_free(phb, FALSE);
 	}
 
@@ -335,5 +343,5 @@
 
 		if (write(source, phb->host, host_len) != host_len) {
-			return phb_close(phb);
+			return phb_free(phb, FALSE);
 		}
 	}
@@ -365,15 +373,12 @@
 
 	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);
 }
 
@@ -394,5 +399,5 @@
 
 	if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) {
-		phb_close(phb);
+		phb_free(phb, FALSE);
 		return;
 	}
@@ -409,9 +414,9 @@
 
 	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);
 	}
 
@@ -429,9 +434,9 @@
 
 	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);
 	}
 
@@ -444,5 +449,5 @@
 		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);
 		}
 
@@ -468,5 +473,5 @@
 	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);
@@ -486,5 +491,5 @@
 
 	if (write(source, buf, i) < i) {
-		return phb_close(phb);
+		return phb_free(phb, FALSE);
 	}
 
