diff options
Diffstat (limited to '')
| -rw-r--r-- | src/conns.c | 8 | ||||
| -rw-r--r-- | src/conns.h | 10 | ||||
| -rw-r--r-- | src/grammar.y | 9 | ||||
| -rw-r--r-- | src/reqs.c | 29 | ||||
| -rw-r--r-- | src/scanner.l | 3 | ||||
| -rw-r--r-- | src/sock.c | 48 | ||||
| -rw-r--r-- | src/sock.h | 9 | ||||
| -rw-r--r-- | src/tinyproxy.h | 3 | 
8 files changed, 87 insertions, 32 deletions
| diff --git a/src/conns.c b/src/conns.c index c7091a3..c94b245 100644 --- a/src/conns.c +++ b/src/conns.c @@ -1,4 +1,4 @@ -/* $Id: conns.c,v 1.21 2004-02-13 21:27:42 rjkaes Exp $ +/* $Id: conns.c,v 1.22 2004-04-27 18:53:14 rjkaes Exp $   *   * Create and free the connection structure. One day there could be   * other connection related tasks put here, but for now the header @@ -27,7 +27,8 @@  #include "stats.h"  struct conn_s * -initialize_conn(int client_fd, const char* ipaddr, const char* string_addr) +initialize_conn(int client_fd, const char* ipaddr, const char* string_addr, +		const char* sock_ipaddr)  {  	struct conn_s *connptr;  	struct buffer_s *cbuffer, *sbuffer; @@ -71,6 +72,7 @@ initialize_conn(int client_fd, const char* ipaddr, const char* string_addr)  	/* There is _no_ content length initially */  	connptr->content_length.server = connptr->content_length.client = -1; +	connptr->server_ip_addr = sock_ipaddr ? safestrdup(sock_ipaddr) : 0;  	connptr->client_ip_addr = safestrdup(ipaddr);  	connptr->client_string_addr = safestrdup(string_addr); @@ -122,6 +124,8 @@ destroy_conn(struct conn_s *connptr)  	if (connptr->error_string)  		safefree(connptr->error_string); +	if (connptr->server_ip_addr) +		safefree(connptr->server_ip_addr);  	if (connptr->client_ip_addr)  		safefree(connptr->client_ip_addr);  	if (connptr->client_string_addr) diff --git a/src/conns.h b/src/conns.h index 5d0422a..8b6f69e 100644 --- a/src/conns.h +++ b/src/conns.h @@ -1,4 +1,4 @@ -/* $Id: conns.h,v 1.16 2004-01-26 19:11:51 rjkaes Exp $ +/* $Id: conns.h,v 1.17 2004-04-27 18:53:14 rjkaes Exp $   *   * See 'conns.c' for a detailed description.   * @@ -54,6 +54,11 @@ struct conn_s {  	} content_length;  	/* +	 * Store the server's IP (for BindSame) +	 */ +	char* server_ip_addr; + +	/*  	 * Store the client's IP and hostname information  	 */  	char* client_ip_addr; @@ -79,7 +84,8 @@ struct conn_s {   * Functions for the creation and destruction of a connection structure.   */  extern struct conn_s* initialize_conn(int client_fd, const char* ipaddr, -				      const char* string_addr); +				      const char* string_addr, +				      const char* sock_ipaddr);  extern void destroy_conn(struct conn_s *connptr);  #endif diff --git a/src/grammar.y b/src/grammar.y index 9f3a74c..72d51b8 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -1,4 +1,4 @@ -/* $Id: grammar.y,v 1.24 2004-01-26 19:11:51 rjkaes Exp $ +/* $Id: grammar.y,v 1.25 2004-04-27 18:53:14 rjkaes Exp $   *   * This is the grammar for tinyproxy's configuration file. It needs to be   * in sync with scanner.l. If you know more about yacc and lex than I do @@ -51,7 +51,7 @@ int yylex(void);  %token KW_FILTER_CASESENSITIVE  %token KW_UPSTREAM  %token KW_REVERSEPATH KW_REVERSEONLY KW_REVERSEMAGIC KW_REVERSEBASEURL -%token KW_CONNECTPORT KW_BIND +%token KW_CONNECTPORT KW_BIND KW_BINDSAME  %token KW_STATHOST  %token KW_ALLOW KW_DENY  %token KW_ERRORPAGE KW_DEFAULT_ERRORPAGE @@ -250,6 +250,11 @@ statement  		  log_message(LOG_WARNING, "The 'Bind' directive can not be used with transparent proxy support.  Ignoring the directive.");  #endif            } +	| KW_BINDSAME yesno +	  { +		  log_message(LOG_INFO, "Binding outgoing connections to incoming IP"); +		  config.bindsame = $2; +	  }          | KW_VIA_PROXY_NAME string            {  		  log_message(LOG_INFO, "Setting \"Via\" proxy name to: %s", $2); @@ -1,4 +1,4 @@ -/* $Id: reqs.c,v 1.111 2004-02-13 21:27:42 rjkaes Exp $ +/* $Id: reqs.c,v 1.112 2004-04-27 18:53:14 rjkaes Exp $   *   * This is where all the work in tinyproxy is actually done. Incoming   * connections have a new child created for them. The child then @@ -645,7 +645,8 @@ process_request(struct conn_s *connptr, hashmap_t hashofheaders)  		free_request_struct(request);  		return NULL; -	} +	} else if (ret == 2) +		request->protocol[0] = 0;  	/*   	 * FIXME: We need to add code for the simple HTTP/0.9 style GET @@ -1111,7 +1112,7 @@ remove_connection_headers(hashmap_t hashofheaders)  			/* Advance ptr to the next token */  			ptr += strlen(ptr) + 1; -			while (*ptr == '\0') +			while (ptr < data + len && *ptr == '\0')  				ptr++;  		} @@ -1609,7 +1610,7 @@ connect_to_upstream(struct conn_s *connptr, struct request_s *request)  	}  	connptr->server_fd = -	    opensock(cur_upstream->host, cur_upstream->port); +	    opensock(cur_upstream->host, cur_upstream->port, connptr->server_ip_addr);  	if (connptr->server_fd < 0) {  		log_message(LOG_WARNING, @@ -1674,15 +1675,22 @@ handle_connection(int fd)  	struct request_s *request = NULL;  	hashmap_t hashofheaders = NULL; -	char peer_ipaddr[PEER_IP_LENGTH]; -	char peer_string[PEER_STRING_LENGTH]; +	char sock_ipaddr[IP_LENGTH]; +	char peer_ipaddr[IP_LENGTH]; +	char peer_string[HOSTNAME_LENGTH];  	getpeer_information(fd, peer_ipaddr, peer_string); -	log_message(LOG_CONN, "Connect (file descriptor %d): %s [%s]", -		    fd, peer_string, peer_ipaddr); +	if (config.bindsame) +		getsock_ip(fd, sock_ipaddr); + +	log_message(LOG_CONN, config.bindsame ? +		    "Connect (file descriptor %d): %s [%s] at [%s]" : +		    "Connect (file descriptor %d): %s [%s]", +		    fd, peer_string, peer_ipaddr, sock_ipaddr); -	connptr = initialize_conn(fd, peer_ipaddr, peer_string); +	connptr = initialize_conn(fd, peer_ipaddr, peer_string, +				  config.bindsame ? sock_ipaddr : 0);  	if (!connptr) {  		close(fd);  		return; @@ -1748,7 +1756,8 @@ handle_connection(int fd)  			goto send_error;  		}  	} else { -		connptr->server_fd = opensock(request->host, request->port); +		connptr->server_fd = opensock(request->host, request->port, +					      connptr->server_ip_addr);  		if (connptr->server_fd < 0) {  			indicate_http_error(connptr, 500, "Unable to connect",  					    "detail", PACKAGE " was unable to connect to the remote web server.", diff --git a/src/scanner.l b/src/scanner.l index 8418ca0..3107b31 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -1,4 +1,4 @@ -/* $Id: scanner.l,v 1.23 2004-01-26 19:11:51 rjkaes Exp $ +/* $Id: scanner.l,v 1.24 2004-04-27 18:53:14 rjkaes Exp $   *   * This builds the scanner for the tinyproxy configuration file. This   * file needs to stay in sync with grammar.y. If someone knows lex and yacc @@ -58,6 +58,7 @@ static struct keyword keywords[] = {  	{ "deny",                KW_DENY },  	{ "connectport",         KW_CONNECTPORT },  	{ "bind",                KW_BIND }, +	{ "bindsame",            KW_BINDSAME },  	{ "viaproxyname",        KW_VIA_PROXY_NAME },  	{ "stathost",            KW_STATHOST },  	{ "errorfile",	         KW_ERRORPAGE }, @@ -1,4 +1,4 @@ -/* $Id: sock.c,v 1.40 2004-02-18 20:18:53 rjkaes Exp $ +/* $Id: sock.c,v 1.41 2004-04-27 18:53:14 rjkaes Exp $   *   * Sockets are created and destroyed here. When a new connection comes in from   * a client, we need to copy the socket and the create a second socket to the @@ -71,7 +71,7 @@ bind_socket(int sockfd, const char* addr)   * independent implementation (mostly for IPv4 and IPv6 addresses.)   */  int -opensock(const char* host, int port) +opensock(const char* host, int port, const char* bind_to)  {  	int sockfd, n;  	struct addrinfo hints, *res, *ressave; @@ -100,7 +100,12 @@ opensock(const char* host, int port)  			continue; /* ignore this one */  		/* Bind to the specified address */ -		if (config.bind_address) { +		if (bind_to) { +			if (bind_socket(sockfd, bind_to) < 0) { +				close(sockfd); +				continue; /* can't bind, so try again */ +			} +		} else if (config.bind_address) {  			if (bind_socket(sockfd, config.bind_address) < 0) {  				close(sockfd);  				continue; /* can't bind, so try again */ @@ -199,13 +204,36 @@ listen_sock(uint16_t port, socklen_t* addrlen)  }  /* + * Takes a socket descriptor and returns the socket's IP address. + */ +int +getsock_ip(int fd, char* ipaddr) +{ +	struct sockaddr_storage name; +	int namelen = sizeof(name); + +	assert(fd >= 0); + +	if (getsockname(fd, (struct sockaddr *) &name, &namelen) != 0) { +		log_message(LOG_ERR, "getsock_ip: getsockname() error: %s", +			    strerror(errno)); +		return -1; +	} + +	if (get_ip_string((struct sockaddr *)&name, ipaddr, IP_LENGTH) == NULL) +		return -1; + +	return 0; +} + +/*   * Return the peer's socket information.   */  int  getpeer_information(int fd, char* ipaddr, char* string_addr)  { -	struct sockaddr sa; -	size_t salen = sizeof(struct sockaddr); +	struct sockaddr_storage sa; +	size_t salen = sizeof(sa);  	assert(fd >= 0);  	assert(ipaddr != NULL); @@ -213,17 +241,17 @@ getpeer_information(int fd, char* ipaddr, char* string_addr)  	/* Set the strings to default values */  	ipaddr[0] = '\0'; -	strlcpy(string_addr, "[unknown]", PEER_STRING_LENGTH); +	strlcpy(string_addr, "[unknown]", HOSTNAME_LENGTH);  	/* Look up the IP address */ -	if (getpeername(fd, &sa, &salen) != 0) +	if (getpeername(fd, (struct sockaddr *)&sa, &salen) != 0)  		return -1; -	if (get_ip_string(&sa, ipaddr, PEER_IP_LENGTH) == NULL) +	if (get_ip_string((struct sockaddr *)&sa, ipaddr, IP_LENGTH) == NULL)  		return -1;  	/* Get the full host name */ -	return getnameinfo(&sa, salen, -			   string_addr, PEER_STRING_LENGTH, +	return getnameinfo((struct sockaddr *)&sa, salen, +			   string_addr, HOSTNAME_LENGTH,  			   NULL, 0, 0);  } @@ -1,4 +1,4 @@ -/* $Id: sock.h,v 1.12 2004-02-18 20:18:53 rjkaes Exp $ +/* $Id: sock.h,v 1.13 2004-04-27 18:53:14 rjkaes Exp $   *   * See 'sock.c' for a detailed description.   * @@ -20,17 +20,18 @@  #define TINYPROXY_SOCK_H  /* The IP length is set to 48, since IPv6 can be that long */ -#define PEER_IP_LENGTH          48 -#define PEER_STRING_LENGTH	1024 +#define IP_LENGTH		48 +#define HOSTNAME_LENGTH		1024  #define MAXLINE (1024 * 4) -extern int opensock(const char* host, int port); +extern int opensock(const char* host, int port, const char* bind_to);  extern int listen_sock(uint16_t port, socklen_t* addrlen);  extern int socket_nonblocking(int sock);  extern int socket_blocking(int sock); +extern int getsock_ip(int fd, char* ipaddr);  extern int getpeer_information(int fd, char* ipaddr, char* string_addr);  #endif diff --git a/src/tinyproxy.h b/src/tinyproxy.h index ad02120..256b9e7 100644 --- a/src/tinyproxy.h +++ b/src/tinyproxy.h @@ -1,4 +1,4 @@ -/* $Id: tinyproxy.h,v 1.43 2004-01-26 19:11:51 rjkaes Exp $ +/* $Id: tinyproxy.h,v 1.44 2004-04-27 18:53:14 rjkaes Exp $   *   * See 'tinyproxy.c' for a detailed description.   * @@ -80,6 +80,7 @@ struct config_s {  	char *pidpath;  	unsigned int idletimeout;  	char* bind_address; +	unsigned int bindsame;  	/*  	 * The configured name to use in the HTTP "Via" header field. | 
