diff options
Diffstat (limited to 'lib/proxy.c')
| -rw-r--r-- | lib/proxy.c | 167 | 
1 files changed, 85 insertions, 82 deletions
| diff --git a/lib/proxy.c b/lib/proxy.c index e52837fe..0b1866ea 100644 --- a/lib/proxy.c +++ b/lib/proxy.c @@ -57,27 +57,6 @@ struct PHB {  	gint inpa;  }; - - -static struct sockaddr_in *gaim_gethostbyname(const char *host, int port) -{ -	static struct sockaddr_in sin; - -	if (!inet_aton(host, &sin.sin_addr)) { -		struct hostent *hp; -		if (!(hp = gethostbyname(host))) { -			return NULL; -		} -		memset(&sin, 0, sizeof(struct sockaddr_in)); -		memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); -		sin.sin_family = hp->h_addrtype; -	} else -		sin.sin_family = AF_INET; -	sin.sin_port = htons(port); - -	return &sin; -} -  static gboolean gaim_io_connected(gpointer data, gint source, b_input_condition cond)  {  	struct PHB *phb = data; @@ -90,9 +69,9 @@ static gboolean gaim_io_connected(gpointer data, gint source, b_input_condition  		closesocket(source);  		b_event_remove(phb->inpa);  		if( phb->proxy_func ) -			phb->proxy_func(phb->proxy_data, -1, GAIM_INPUT_READ); +			phb->proxy_func(phb->proxy_data, -1, B_EV_IO_READ);  		else { -			phb->func(phb->data, -1, GAIM_INPUT_READ); +			phb->func(phb->data, -1, B_EV_IO_READ);  			g_free(phb);  		}  		return FALSE; @@ -101,56 +80,80 @@ static gboolean gaim_io_connected(gpointer data, gint source, b_input_condition  	sock_make_blocking(source);  	b_event_remove(phb->inpa);  	if( phb->proxy_func ) -		phb->proxy_func(phb->proxy_data, source, GAIM_INPUT_READ); +		phb->proxy_func(phb->proxy_data, source, B_EV_IO_READ);  	else { -		phb->func(phb->data, source, GAIM_INPUT_READ); +		phb->func(phb->data, source, B_EV_IO_READ);  		g_free(phb);  	}  	return FALSE;  } -static int proxy_connect_none(const char *host, unsigned short port, struct PHB *phb) +static int proxy_connect_none(const char *host, unsigned short port_, struct PHB *phb)  { -	struct sockaddr_in *sin;  	struct sockaddr_in me;  	int fd = -1; +	int ret; +	char port[6]; +	struct addrinfo hints; +	struct addrinfo* result; -	if (!(sin = gaim_gethostbyname(host, port))) { -		g_free(phb); -		return -1; -	} +	g_snprintf(port, sizeof(port), "%d", port_); -	if ((fd = socket(sin->sin_family, SOCK_STREAM, 0)) < 0) { -		g_free(phb); -		return -1; -	} +	memset(&hints, 0, sizeof(struct addrinfo)); +	hints.ai_family = AF_UNSPEC; +	hints.ai_socktype = SOCK_STREAM; +	hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV; -	sock_make_nonblocking(fd); +	if (!(ret = getaddrinfo(host, port, &hints, &result))) +	{ +		struct addrinfo* rp; + +		for (rp = result; rp; rp = rp->ai_next) +		{ +			if ((fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) < 0) { +				event_debug( "socket failed: %d\n", errno); +				continue; +			} + +			sock_make_nonblocking(fd); + +			if (global.conf->iface_out) +			{ +				me.sin_family = AF_INET; +				me.sin_port = 0; +				me.sin_addr.s_addr = inet_addr( global.conf->iface_out ); +				 +				if (bind(fd, (struct sockaddr *) &me, sizeof(me)) != 0) +					event_debug("bind( %d, \"%s\" ) failure\n", fd, global.conf->iface_out); +			} + +			event_debug("proxy_connect_none( \"%s\", %d ) = %d\n", host, port, fd); -	if( global.conf->iface_out ) +			if (connect(fd, rp->ai_addr, rp->ai_addrlen) < 0 && !sockerr_again()) { +				event_debug( "connect failed: %s\n", strerror(errno)); +				closesocket(fd); +				fd = -1; +				continue; +			} else { +				phb->inpa = b_input_add(fd, B_EV_IO_WRITE, gaim_io_connected, phb); +				phb->fd = fd; +				 +				break; +			} +		} + +		freeaddrinfo(result); +	} +	else  	{ -		me.sin_family = AF_INET; -		me.sin_port = 0; -		me.sin_addr.s_addr = inet_addr( global.conf->iface_out ); -		 -		if( bind( fd, (struct sockaddr *) &me, sizeof( me ) ) != 0 ) -			event_debug( "bind( %d, \"%s\" ) failure\n", fd, global.conf->iface_out ); +		event_debug("gai(): %s\n", gai_strerror(ret));  	} -	event_debug("proxy_connect_none( \"%s\", %d ) = %d\n", host, port, fd); -	 -	if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0 && !sockerr_again()) { -		closesocket(fd); +	if(fd < 0)  		g_free(phb); -		 -		return -1; -	} else { -		phb->inpa = b_input_add(fd, GAIM_INPUT_WRITE, gaim_io_connected, phb); -		phb->fd = fd; -		 -		return fd; -	} + +	return fd;  } @@ -178,14 +181,14 @@ 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, GAIM_INPUT_READ); +		phb->func(phb->data, source, B_EV_IO_READ);  		g_free(phb->host);  		g_free(phb);  		return FALSE;  	}  	close(source); -	phb->func(phb->data, -1, GAIM_INPUT_READ); +	phb->func(phb->data, -1, B_EV_IO_READ);  	g_free(phb->host);  	g_free(phb); @@ -203,7 +206,7 @@ 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) {  		close(source); -		phb->func(phb->data, -1, GAIM_INPUT_READ); +		phb->func(phb->data, -1, B_EV_IO_READ);  		g_free(phb->host);  		g_free(phb);  		return FALSE; @@ -214,7 +217,7 @@ static gboolean http_canwrite(gpointer data, gint source, b_input_condition cond  		   phb->host, phb->port);  	if (send(source, cmd, strlen(cmd), 0) < 0) {  		close(source); -		phb->func(phb->data, -1, GAIM_INPUT_READ); +		phb->func(phb->data, -1, B_EV_IO_READ);  		g_free(phb->host);  		g_free(phb);  		return FALSE; @@ -229,7 +232,7 @@ static gboolean http_canwrite(gpointer data, gint source, b_input_condition cond  		g_free(t2);  		if (send(source, cmd, strlen(cmd), 0) < 0) {  			close(source); -			phb->func(phb->data, -1, GAIM_INPUT_READ); +			phb->func(phb->data, -1, B_EV_IO_READ);  			g_free(phb->host);  			g_free(phb);  			return FALSE; @@ -239,13 +242,13 @@ static gboolean http_canwrite(gpointer data, gint source, b_input_condition cond  	g_snprintf(cmd, sizeof(cmd), "\r\n");  	if (send(source, cmd, strlen(cmd), 0) < 0) {  		close(source); -		phb->func(phb->data, -1, GAIM_INPUT_READ); +		phb->func(phb->data, -1, B_EV_IO_READ);  		g_free(phb->host);  		g_free(phb);  		return FALSE;  	} -	phb->inpa = b_input_add(source, GAIM_INPUT_READ, http_canread, phb); +	phb->inpa = b_input_add(source, B_EV_IO_READ, http_canread, phb);  	return FALSE;  } @@ -272,14 +275,14 @@ 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, GAIM_INPUT_READ); +		phb->func(phb->data, source, B_EV_IO_READ);  		g_free(phb->host);  		g_free(phb);  		return FALSE;  	}  	close(source); -	phb->func(phb->data, -1, GAIM_INPUT_READ); +	phb->func(phb->data, -1, B_EV_IO_READ);  	g_free(phb->host);  	g_free(phb); @@ -298,7 +301,7 @@ 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) {  		close(source); -		phb->func(phb->data, -1, GAIM_INPUT_READ); +		phb->func(phb->data, -1, B_EV_IO_READ);  		g_free(phb->host);  		g_free(phb);  		return FALSE; @@ -308,7 +311,7 @@ static gboolean s4_canwrite(gpointer data, gint source, b_input_condition cond)  	/* XXX does socks4 not support host name lookups by the proxy? */  	if (!(hp = gethostbyname(phb->host))) {  		close(source); -		phb->func(phb->data, -1, GAIM_INPUT_READ); +		phb->func(phb->data, -1, B_EV_IO_READ);  		g_free(phb->host);  		g_free(phb);  		return FALSE; @@ -325,13 +328,13 @@ static gboolean s4_canwrite(gpointer data, gint source, b_input_condition cond)  	packet[8] = 0;  	if (write(source, packet, 9) != 9) {  		close(source); -		phb->func(phb->data, -1, GAIM_INPUT_READ); +		phb->func(phb->data, -1, B_EV_IO_READ);  		g_free(phb->host);  		g_free(phb);  		return FALSE;  	} -	phb->inpa = b_input_add(source, GAIM_INPUT_READ, s4_canread, phb); +	phb->inpa = b_input_add(source, B_EV_IO_READ, s4_canread, phb);  	return FALSE;  } @@ -358,20 +361,20 @@ static gboolean s5_canread_again(gpointer data, gint source, b_input_condition c  	if (read(source, buf, 10) < 10) {  		close(source); -		phb->func(phb->data, -1, GAIM_INPUT_READ); +		phb->func(phb->data, -1, B_EV_IO_READ);  		g_free(phb->host);  		g_free(phb);  		return FALSE;  	}  	if ((buf[0] != 0x05) || (buf[1] != 0x00)) {  		close(source); -		phb->func(phb->data, -1, GAIM_INPUT_READ); +		phb->func(phb->data, -1, B_EV_IO_READ);  		g_free(phb->host);  		g_free(phb);  		return FALSE;  	} -	phb->func(phb->data, source, GAIM_INPUT_READ); +	phb->func(phb->data, source, B_EV_IO_READ);  	g_free(phb->host);  	g_free(phb); @@ -395,13 +398,13 @@ static void s5_sendconnect(gpointer data, gint source)  	if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) {  		close(source); -		phb->func(phb->data, -1, GAIM_INPUT_READ); +		phb->func(phb->data, -1, B_EV_IO_READ);  		g_free(phb->host);  		g_free(phb);  		return;  	} -	phb->inpa = b_input_add(source, GAIM_INPUT_READ, s5_canread_again, phb); +	phb->inpa = b_input_add(source, B_EV_IO_READ, s5_canread_again, phb);  }  static gboolean s5_readauth(gpointer data, gint source, b_input_condition cond) @@ -413,7 +416,7 @@ static gboolean s5_readauth(gpointer data, gint source, b_input_condition cond)  	if (read(source, buf, 2) < 2) {  		close(source); -		phb->func(phb->data, -1, GAIM_INPUT_READ); +		phb->func(phb->data, -1, B_EV_IO_READ);  		g_free(phb->host);  		g_free(phb);  		return FALSE; @@ -421,7 +424,7 @@ static gboolean s5_readauth(gpointer data, gint source, b_input_condition cond)  	if ((buf[0] != 0x01) || (buf[1] != 0x00)) {  		close(source); -		phb->func(phb->data, -1, GAIM_INPUT_READ); +		phb->func(phb->data, -1, B_EV_IO_READ);  		g_free(phb->host);  		g_free(phb);  		return FALSE; @@ -441,7 +444,7 @@ static gboolean s5_canread(gpointer data, gint source, b_input_condition cond)  	if (read(source, buf, 2) < 2) {  		close(source); -		phb->func(phb->data, -1, GAIM_INPUT_READ); +		phb->func(phb->data, -1, B_EV_IO_READ);  		g_free(phb->host);  		g_free(phb);  		return FALSE; @@ -449,7 +452,7 @@ static gboolean s5_canread(gpointer data, gint source, b_input_condition cond)  	if ((buf[0] != 0x05) || (buf[1] == 0xff)) {  		close(source); -		phb->func(phb->data, -1, GAIM_INPUT_READ); +		phb->func(phb->data, -1, B_EV_IO_READ);  		g_free(phb->host);  		g_free(phb);  		return FALSE; @@ -464,13 +467,13 @@ static gboolean s5_canread(gpointer data, gint source, b_input_condition cond)  		memcpy(buf + 2 + i + 1, proxypass, j);  		if (write(source, buf, 3 + i + j) < 3 + i + j) {  			close(source); -			phb->func(phb->data, -1, GAIM_INPUT_READ); +			phb->func(phb->data, -1, B_EV_IO_READ);  			g_free(phb->host);  			g_free(phb);  			return FALSE;  		} -		phb->inpa = b_input_add(source, GAIM_INPUT_READ, s5_readauth, phb); +		phb->inpa = b_input_add(source, B_EV_IO_READ, s5_readauth, phb);  	} else {  		s5_sendconnect(phb, source);  	} @@ -490,7 +493,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) {  		close(source); -		phb->func(phb->data, -1, GAIM_INPUT_READ); +		phb->func(phb->data, -1, B_EV_IO_READ);  		g_free(phb->host);  		g_free(phb);  		return FALSE; @@ -512,13 +515,13 @@ static gboolean s5_canwrite(gpointer data, gint source, b_input_condition cond)  	if (write(source, buf, i) < i) {  		close(source); -		phb->func(phb->data, -1, GAIM_INPUT_READ); +		phb->func(phb->data, -1, B_EV_IO_READ);  		g_free(phb->host);  		g_free(phb);  		return FALSE;  	} -	phb->inpa = b_input_add(source, GAIM_INPUT_READ, s5_canread, phb); +	phb->inpa = b_input_add(source, B_EV_IO_READ, s5_canread, phb);  	return FALSE;  } | 
