Răsfoiți Sursa

Modify PluginProtocol interface to better handle dial interruption

Rod Hynes 8 ani în urmă
părinte
comite
ac79715420
2 a modificat fișierele cu 27 adăugiri și 27 ștergeri
  1. 17 16
      psiphon/pluginProtocol.go
  2. 10 11
      psiphon/tunnel.go

+ 17 - 16
psiphon/pluginProtocol.go

@@ -29,26 +29,28 @@ import (
 
 var registeredPluginProtocolDialer atomic.Value
 
-// PluginProtocolNetDialer is a base network dialer that's used
-// by PluginProtocolDialer to make its IP network connections. This
-// is used, for example, to create TCPConns as the base TCP
-// connections used by the plugin protocol.
-type PluginProtocolNetDialer func(network, addr string) (net.Conn, error)
-
 // PluginProtocolDialer creates a connection to addr over a
-// plugin protocol. It uses netDialer to create its base network
+// plugin protocol. It uses dialConfig to create its base network
 // connection(s) and sends its log messages to loggerOutput.
+//
+// To ensure timely interruption and shutdown, each
+// PluginProtocolDialerimplementation must:
+//
+// - Places its outer net.Conn in pendingConns and leave it
+//   there unless an error occurs
+// - Replace the dialConfig.pendingConns with its own
+//   PendingConns and use that to ensure base network
+//   connections are interrupted when Close() is invoked on
+//   the returned net.Conn.
+//
 // PluginProtocolDialer returns true if it attempts to create
 // a connection, or false if it decides not to attempt a connection.
-// PluginProtocolDialer must add its connection to pendingConns
-// before the initial dial to allow for interruption.
 type PluginProtocolDialer func(
 	config *Config,
 	loggerOutput io.Writer,
 	pendingConns *common.Conns,
-	netDialer PluginProtocolNetDialer,
-	addr string) (
-	bool, net.Conn, error)
+	addr string,
+	dialConfig *DialConfig) (bool, net.Conn, error)
 
 // RegisterPluginProtocol sets the current plugin protocol
 // dialer.
@@ -62,14 +64,13 @@ func DialPluginProtocol(
 	config *Config,
 	loggerOutput io.Writer,
 	pendingConns *common.Conns,
-	netDialer PluginProtocolNetDialer,
-	addr string) (
-	bool, net.Conn, error) {
+	addr string,
+	dialConfig *DialConfig) (bool, net.Conn, error) {
 
 	dialer := registeredPluginProtocolDialer.Load()
 	if dialer != nil {
 		return dialer.(PluginProtocolDialer)(
-			config, loggerOutput, pendingConns, netDialer, addr)
+			config, loggerOutput, pendingConns, addr, dialConfig)
 	}
 	return false, nil, nil
 }

+ 10 - 11
psiphon/tunnel.go

@@ -727,22 +727,21 @@ func dialSsh(
 
 		// For some direct connect servers, DialPluginProtocol
 		// will layer on another obfuscation protocol.
+
+		// Use a copy of DialConfig without pendingConns; the
+		// DialPluginProtocol must supply and manage its own
+		// for its base network connections.
+		pluginDialConfig := new(DialConfig)
+		*pluginDialConfig = *dialConfig
+		pluginDialConfig.PendingConns = nil
+
 		var dialedPlugin bool
 		dialedPlugin, dialConn, err = DialPluginProtocol(
 			config,
 			NewNoticeWriter("DialPluginProtocol"),
 			pendingConns,
-			func(_, addr string) (net.Conn, error) {
-
-				// Use a copy of DialConfig without pendingConns
-				// TODO: distinct pendingConns for plugins?
-				pluginDialConfig := new(DialConfig)
-				*pluginDialConfig = *dialConfig
-				pluginDialConfig.PendingConns = nil
-
-				return DialTCP(addr, pluginDialConfig)
-			},
-			directTCPDialAddress)
+			directTCPDialAddress,
+			dialConfig)
 
 		if !dialedPlugin && err != nil {
 			NoticeInfo("DialPluginProtocol intialization failed: %s", err)