diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/proxy.c | 75 | 
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);  | 
