| 
					
				 | 
			
			
				@@ -4,7 +4,6 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /* See LICENSE for licensing information */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "orconfig.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "compat.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "../common/util.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "address.h" 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -187,7 +186,7 @@ do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            int reverse, int version, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            tor_addr_t *result_addr, char **result_hostname) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  int s; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int s = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   struct sockaddr_in socksaddr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   char *req = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   ssize_t len = 0; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -202,7 +201,7 @@ do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   s = tor_open_socket(PF_INET,SOCK_STREAM,IPPROTO_TCP); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (s<0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     log_sock_error("creating_socket", -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    goto err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   memset(&socksaddr, 0, sizeof(socksaddr)); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -211,28 +210,28 @@ do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   socksaddr.sin_addr.s_addr = htonl(sockshost); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (connect(s, (struct sockaddr*)&socksaddr, sizeof(socksaddr))) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     log_sock_error("connecting to SOCKS host", s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    goto err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (version == 5) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     char method_buf[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (write_all(s, "\x05\x01\x00", 3, 1) != 3) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       log_err(LD_NET, "Error sending SOCKS5 method list."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      goto err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (read_all(s, method_buf, 2, 1) != 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       log_err(LD_NET, "Error reading SOCKS5 methods."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      goto err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (method_buf[0] != '\x05') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       log_err(LD_NET, "Unrecognized socks version: %u", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               (unsigned)method_buf[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      goto err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (method_buf[1] != '\x00') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       log_err(LD_NET, "Unrecognized socks authentication method: %u", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               (unsigned)method_buf[1]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      goto err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -240,12 +239,12 @@ do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                          version))<0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     log_err(LD_BUG,"Error generating SOCKS request"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     tor_assert(!req); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    goto err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (write_all(s, req, len, 1) != len) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     log_sock_error("sending SOCKS request", s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     tor_free(req); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    goto err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_free(req); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -253,22 +252,22 @@ do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     char reply_buf[RESPONSE_LEN_4]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (read_all(s, reply_buf, RESPONSE_LEN_4, 1) != RESPONSE_LEN_4) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       log_err(LD_NET, "Error reading SOCKS4 response."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      goto err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (parse_socks4a_resolve_response(hostname, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                        reply_buf, RESPONSE_LEN_4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                        result_addr)<0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      goto err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     char reply_buf[16]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (read_all(s, reply_buf, 4, 1) != 4) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       log_err(LD_NET, "Error reading SOCKS5 response."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      goto err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (reply_buf[0] != 5) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       log_err(LD_NET, "Bad SOCKS5 reply version."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      goto err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /* Give a user some useful feedback about SOCKS5 errors */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (reply_buf[1] != 0) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -282,20 +281,20 @@ do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             "to Tor; we suggest an application that uses SOCKS 4a.", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             hostname); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      goto err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (reply_buf[3] == 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       /* IPv4 address */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       if (read_all(s, reply_buf, 4, 1) != 4) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         log_err(LD_NET, "Error reading address in socks5 response."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       tor_addr_from_ipv4n(result_addr, get_uint32(reply_buf)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } else if (reply_buf[3] == 4) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       /* IPv6 address */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       if (read_all(s, reply_buf, 16, 1) != 16) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         log_err(LD_NET, "Error reading address in socks5 response."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       tor_addr_from_ipv6_bytes(result_addr, reply_buf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } else if (reply_buf[3] == 3) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -303,19 +302,23 @@ do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       size_t result_len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       if (read_all(s, reply_buf, 1, 1) != 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         log_err(LD_NET, "Error reading address_length in socks5 response."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       result_len = *(uint8_t*)(reply_buf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       *result_hostname = tor_malloc(result_len+1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       if (read_all(s, *result_hostname, result_len, 1) != (int) result_len) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         log_err(LD_NET, "Error reading hostname in socks5 response."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       (*result_hostname)[result_len] = '\0'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tor_close_socket(s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ err: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tor_close_socket(s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** Print a usage message and exit. */ 
			 |