Browse Source

Merge pull request #390 from rod-hynes/master

Fix: double close of file descriptors
Rod Hynes 8 years ago
parent
commit
52b93ddab7
4 changed files with 16 additions and 11 deletions
  1. 10 7
      psiphon/LookupIP.go
  2. 1 0
      psiphon/TCPConn_bind.go
  3. 3 2
      psiphon/config.go
  4. 2 2
      psiphon/server/config.go

+ 10 - 7
psiphon/LookupIP.go

@@ -95,10 +95,10 @@ func bindLookupIP(host, dnsServer string, config *DialConfig) (addrs []net.IP, e
 	if err != nil {
 		return nil, common.ContextError(err)
 	}
-	defer syscall.Close(socketFd)
 
 	err = config.DeviceBinder.BindToDevice(socketFd)
 	if err != nil {
+		syscall.Close(socketFd)
 		return nil, common.ContextError(fmt.Errorf("BindToDevice failed: %s", err))
 	}
 
@@ -112,23 +112,26 @@ func bindLookupIP(host, dnsServer string, config *DialConfig) (addrs []net.IP, e
 		err = syscall.Connect(socketFd, &sockAddr)
 	}
 	if err != nil {
+		syscall.Close(socketFd)
 		return nil, common.ContextError(err)
 	}
 
 	// Convert the syscall socket to a net.Conn, for use in the dns package
 	file := os.NewFile(uintptr(socketFd), "")
-	defer file.Close()
-	conn, err := net.FileConn(file)
+	netConn, err := net.FileConn(file) // net.FileConn() dups socketFd
+	file.Close()                       // file.Close() closes socketFd
 	if err != nil {
 		return nil, common.ContextError(err)
 	}
 
 	// Set DNS query timeouts, using the ConnectTimeout from the overall Dial
 	if config.ConnectTimeout != 0 {
-		conn.SetReadDeadline(time.Now().Add(config.ConnectTimeout))
-		conn.SetWriteDeadline(time.Now().Add(config.ConnectTimeout))
+		netConn.SetReadDeadline(time.Now().Add(config.ConnectTimeout))
+		netConn.SetWriteDeadline(time.Now().Add(config.ConnectTimeout))
 	}
 
-	addrs, _, err = ResolveIP(host, conn)
-	return
+	addrs, _, err = ResolveIP(host, netConn)
+	netConn.Close()
+
+	return addrs, err
 }

+ 1 - 0
psiphon/TCPConn_bind.go

@@ -169,6 +169,7 @@ func tcpDial(addr string, config *DialConfig) (net.Conn, error) {
 			lastErr = common.ContextError(err)
 			continue
 		}
+
 		if !fdset.IsSet(uintptr(socketFd)) {
 			syscall.Close(socketFd)
 			lastErr = common.ContextError(errors.New("connect timed out"))

+ 3 - 2
psiphon/config.go

@@ -197,8 +197,9 @@ type Config struct {
 
 	// TunnelProtocol indicates which protocol to use. Valid values include:
 	// "SSH", "OSSH", "UNFRONTED-MEEK-OSSH", "UNFRONTED-MEEK-HTTPS-OSSH",
-	// "FRONTED-MEEK-OSSH", "FRONTED-MEEK-HTTP-OSSH". For the default, "",
-	// the best performing protocol is used.
+	// "UNFRONTED-MEEK-SESSION-TICKET-OSSH", "FRONTED-MEEK-OSSH",
+	// "FRONTED-MEEK-HTTP-OSSH".
+	// For the default, "", the best performing protocol is used.
 	TunnelProtocol string
 
 	// EstablishTunnelTimeoutSeconds specifies a time limit after which to halt

+ 2 - 2
psiphon/server/config.go

@@ -123,8 +123,8 @@ type Config struct {
 	// TunnelProtocolPorts specifies which tunnel protocols to run
 	// and which ports to listen on for each protocol. Valid tunnel
 	// protocols include: "SSH", "OSSH", "UNFRONTED-MEEK-OSSH",
-	// "UNFRONTED-MEEK-HTTPS-OSSH", "FRONTED-MEEK-OSSH",
-	// "FRONTED-MEEK-HTTP-OSSH".
+	// "UNFRONTED-MEEK-HTTPS-OSSH", "UNFRONTED-MEEK-SESSION-TICKET-OSSH",
+	// "FRONTED-MEEK-OSSH", "FRONTED-MEEK-HTTP-OSSH".
 	TunnelProtocolPorts map[string]int
 
 	// SSHPrivateKey is the SSH host key. The same key is used for