Преглед на файлове

Fixed IPv4 address detection (net.ParseIP will always return an address in 16-byte form)

Miro Kuratczyk преди 9 години
родител
ревизия
e793e8853b
променени са 3 файла, в които са добавени 18 реда и са изтрити 13 реда
  1. 6 7
      MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/Reachability/LookupIPv6.c
  2. 6 2
      psiphon/TCPConn.go
  3. 6 4
      psiphon/TCPConn_bind.go

+ 6 - 7
MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/Reachability/LookupIPv6.c

@@ -19,9 +19,9 @@
 
 #include "LookupIPv6.h"
 
-#include <netdb.h>
 #include <arpa/inet.h>
 #include <err.h>
+#include <netdb.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -41,13 +41,12 @@ char *getIPv6ForIPv4(const char *ipv4_str) {
     }
 
     for (res = res0; res; res = res->ai_next) {
-        if (res->ai_addr->sa_family != AF_INET6) {
-            continue;
+        if (res->ai_family == AF_INET6) {
+            struct sockaddr_in6 *sockaddr = (struct sockaddr_in6*)res->ai_addr;
+            ipv6_str = (char *)malloc(sizeof(char)*(INET6_ADDRSTRLEN)); // INET6_ADDRSTRLEN includes null terminating character
+            inet_ntop(AF_INET6, &(sockaddr->sin6_addr), ipv6_str, INET6_ADDRSTRLEN);
+            break;
         }
-        struct sockaddr_in6 *sockaddr = (struct sockaddr_in6*)res->ai_addr;
-        ipv6_str = (char *)malloc(sizeof(char)*(INET6_ADDRSTRLEN)); // INET6_ADDRSTRLEN includes null terminating character
-        inet_ntop(AF_INET6, &(sockaddr->sin6_addr), ipv6_str, INET6_ADDRSTRLEN);
-        break;
     }
     
     freeaddrinfo(res0);

+ 6 - 2
psiphon/TCPConn.go

@@ -105,14 +105,18 @@ func interruptibleTCPDial(addr string, config *DialConfig) (*TCPConn, error) {
 	// call.
 	go func() {
 		if config.IPv6Synthesizer != nil {
-			// Synthesize an ipv6 address from an ipv4 one
+			// Synthesize an IPv6 address from an IPv4 one
 			// This is for compatibility on DNS64/NAT64 networks
 			host, port, err := net.SplitHostPort(addr)
 			if err != nil {
+				select {
+				case conn.dialResult <- err:
+				default:
+				}
 				return
 			}
 			ip := net.ParseIP(host)
-			if ip != nil && len(ip) == net.IPv4len {
+			if ip != nil && ip.To4() != nil {
 				synthesizedAddr := config.IPv6Synthesizer.IPv6Synthesize(host)
 				if synthesizedAddr != "" {
 					addr = net.JoinHostPort(synthesizedAddr, port)

+ 6 - 4
psiphon/TCPConn_bind.go

@@ -83,14 +83,16 @@ func tcpDial(addr string, config *DialConfig, dialResult chan error) (net.Conn,
 	ipAddr := ipAddrs[index]
 
 	// Get address type (IPv4 or IPv6)
-	if len(ipAddr) == net.IPv4len {
+	if ipAddr != nil && ipAddr.To4() != nil {
 		ip = make([]byte, 4)
-		copy(ip[:], ipAddr.To4())
+		copy(ip, ipAddr.To4())
 		domain = syscall.AF_INET
-	} else if len(ipAddr) == net.IPv6len {
+	} else if ipAddr != nil && ipAddr.To16() != nil {
 		ip = make([]byte, 16)
-		copy(ip[:], ipAddr.To16())
+		copy(ip, ipAddr.To16())
 		domain = syscall.AF_INET6
+	} else {
+		return nil, common.ContextError(fmt.Errorf("Got invalid ip address: %s", ipAddr.String()))
 	}
 
 	// Create a socket and bind to device, when configured to do so