浏览代码

Bug 416: Selection of network interface

https://winscp.net/tracker/416

Source commit: 0f460ebfd82b35e2a577b53898db3e51efd03b74
Martin Prikryl 6 年之前
父节点
当前提交
22a9f710fc

+ 1 - 0
source/core/SecureShell.cpp

@@ -402,6 +402,7 @@ Conf * __fastcall TSecureShell::StoreToConfig(TSessionData * Data, bool Simple)
 
   conf_set_int(conf, CONF_connect_timeout, Data->Timeout * MSecsPerSec);
   conf_set_int(conf, CONF_sndbuf, Data->SendBuf);
+  conf_set_str(conf, CONF_srcaddr, AnsiString(Data->SourceAddress).c_str());
 
   // permanent settings
   conf_set_bool(conf, CONF_nopty, TRUE);

+ 9 - 0
source/core/SessionData.cpp

@@ -162,6 +162,7 @@ void __fastcall TSessionData::Default()
   FPuttyProtocol = L"";
   TcpNoDelay = false;
   SendBuf = DefaultSendBuf;
+  SourceAddress = L"";
   SshSimple = true;
   HostKey = L"";
   FingerprintScan = false;
@@ -364,6 +365,7 @@ void __fastcall TSessionData::NonPersistant()
   PROPERTY(TimeDifferenceAuto); \
   PROPERTY(TcpNoDelay); \
   PROPERTY(SendBuf); \
+  PROPERTY(SourceAddress); \
   PROPERTY(SshSimple); \
   PROPERTY(AuthKI); \
   PROPERTY(AuthKIPassword); \
@@ -708,6 +710,7 @@ void __fastcall TSessionData::DoLoad(THierarchicalStorage * Storage, bool PuttyI
     TcpNoDelay = Storage->ReadBool(L"TcpNoDelay", TcpNoDelay);
   }
   SendBuf = Storage->ReadInteger(L"SendBuf", Storage->ReadInteger("SshSendBuf", SendBuf));
+  SourceAddress = Storage->ReadString(L"SourceAddress", SourceAddress);
   SshSimple = Storage->ReadBool(L"SshSimple", SshSimple);
 
   ProxyMethod = (TProxyMethod)Storage->ReadInteger(L"ProxyMethod", ProxyMethod);
@@ -1074,6 +1077,7 @@ void __fastcall TSessionData::DoSave(THierarchicalStorage * Storage,
     WRITE_DATA(Integer, InternalEditorEncoding);
     WRITE_DATA(String, S3DefaultRegion);
     WRITE_DATA(Integer, SendBuf);
+    WRITE_DATA(String, SourceAddress);
     WRITE_DATA(Bool, SshSimple);
   }
 
@@ -3623,6 +3627,11 @@ void __fastcall TSessionData::SetSendBuf(int value)
   SET_SESSION_PROPERTY(SendBuf);
 }
 //---------------------------------------------------------------------
+void __fastcall TSessionData::SetSourceAddress(const UnicodeString & value)
+{
+  SET_SESSION_PROPERTY(SourceAddress);
+}
+//---------------------------------------------------------------------
 void __fastcall TSessionData::SetSshSimple(bool value)
 {
   SET_SESSION_PROPERTY(SshSimple);

+ 3 - 0
source/core/SessionData.h

@@ -156,6 +156,7 @@ private:
   bool FIgnoreLsWarnings;
   bool FTcpNoDelay;
   int FSendBuf;
+  UnicodeString FSourceAddress;
   bool FSshSimple;
   TProxyMethod FProxyMethod;
   UnicodeString FProxyHost;
@@ -312,6 +313,7 @@ private:
   void __fastcall SetIgnoreLsWarnings(bool value);
   void __fastcall SetTcpNoDelay(bool value);
   void __fastcall SetSendBuf(int value);
+  void __fastcall SetSourceAddress(const UnicodeString & value);
   void __fastcall SetSshSimple(bool value);
   UnicodeString __fastcall GetSshProtStr();
   bool __fastcall GetUsesSsh();
@@ -578,6 +580,7 @@ public:
   __property bool IgnoreLsWarnings  = { read=FIgnoreLsWarnings, write=SetIgnoreLsWarnings };
   __property bool TcpNoDelay  = { read=FTcpNoDelay, write=SetTcpNoDelay };
   __property int SendBuf  = { read=FSendBuf, write=SetSendBuf };
+  __property UnicodeString SourceAddress = { read=FSourceAddress, write=SetSourceAddress };
   __property bool SshSimple  = { read=FSshSimple, write=SetSshSimple };
   __property UnicodeString SshProtStr  = { read=GetSshProtStr };
   __property UnicodeString CipherList  = { read=GetCipherList, write=SetCipherList };

+ 4 - 0
source/core/SessionInfo.cpp

@@ -1249,6 +1249,10 @@ void __fastcall TSessionLog::DoAddStartupInfo(TSessionData * Data)
     {
       ADF(L"Send buffer: %d", (Data->SendBuf));
     }
+    if (Data->UsesSsh && !Data->SourceAddress.IsEmpty())
+    {
+      ADF(L"Source address: %s", (Data->SourceAddress));
+    }
     if (Data->UsesSsh)
     {
       ADF(L"SSH protocol version: %s; Compression: %s",

+ 2 - 1
source/putty/network.h

@@ -151,7 +151,8 @@ Socket *sk_new(SockAddr *addr, int port, bool privport, bool oobinline,
                bool nodelay, bool keepalive, Plug *p,
 #ifdef MPEXT
               int timeout,
-              int sndbuf
+              int sndbuf,
+              const char *srcaddr
 #endif
 	      );
 

+ 4 - 2
source/putty/proxy.c

@@ -514,7 +514,8 @@ Socket *new_connection(SockAddr *addr, const char *hostname,
 				 privport, oobinline,
 				 nodelay, keepalive, &ret->plugimpl,
 				 #ifdef MPEXT
-				 conf_get_int(conf, CONF_connect_timeout), conf_get_int(conf, CONF_sndbuf)
+				 conf_get_int(conf, CONF_connect_timeout), conf_get_int(conf, CONF_sndbuf),
+				 conf_get_str(conf, CONF_srcaddr)
 				 #endif
 				 );
 	if (sk_socket_error(ret->sub_socket) != NULL)
@@ -530,7 +531,8 @@ Socket *new_connection(SockAddr *addr, const char *hostname,
     /* no proxy, so just return the direct socket */
     return sk_new(addr, port, privport, oobinline, nodelay, keepalive, plug,
       #ifdef MPEXT
-      conf_get_int(conf, CONF_connect_timeout), conf_get_int(conf, CONF_sndbuf)
+      conf_get_int(conf, CONF_connect_timeout), conf_get_int(conf, CONF_sndbuf),
+      conf_get_str(conf, CONF_srcaddr)
       #endif
       );
 }

+ 1 - 0
source/putty/putty.h

@@ -1487,6 +1487,7 @@ NORETURN void cleanup_exit(int);
     /* MPEXT BEGIN */ \
     X(INT, NONE, connect_timeout) \
     X(INT, NONE, sndbuf) \
+    X(STR, NONE, srcaddr) \
     X(BOOL, NONE, force_remote_cmd2) \
     X(BOOL, NONE, change_password) \
     /* MPEXT END */ \

+ 11 - 5
source/putty/windows/winnet.c

@@ -924,7 +924,8 @@ static Socket *sk_net_accept(accept_ctx_t ctx, Plug *plug)
 static DWORD try_connect(NetSocket *sock,
 #ifdef MPEXT
                          int timeout,
-                         int sndbuf
+                         int sndbuf,
+                         const char *srcaddr
 #endif
 )
 {
@@ -1027,7 +1028,11 @@ static DWORD try_connect(NetSocket *sock,
 #endif
 	{
 	    a.sin_family = AF_INET;
-	    a.sin_addr.s_addr = p_htonl(INADDR_ANY);
+	    if (srcaddr && srcaddr[0]) {
+	        a.sin_addr.s_addr = p_inet_addr(srcaddr);
+	    } else {
+	        a.sin_addr.s_addr = p_htonl(INADDR_ANY);
+	    }
 	    a.sin_port = p_htons(localport);
 	}
 #ifndef NO_IPV6
@@ -1185,7 +1190,8 @@ Socket *sk_new(SockAddr *addr, int port, bool privport, bool oobinline,
                bool nodelay, bool keepalive, Plug *plug,
 #ifdef MPEXT
 	      int timeout,
-	      int sndbuf
+	      int sndbuf,
+	      const char *srcaddr
 #endif
 	      )
 {
@@ -1225,7 +1231,7 @@ Socket *sk_new(SockAddr *addr, int port, bool privport, bool oobinline,
 #endif
         err = try_connect(ret
 #ifdef MPEXT
-            , timeout, sndbuf
+            , timeout, sndbuf, srcaddr
 #endif
         );
     } while (err && sk_nextaddr(ret->addr, &ret->step));
@@ -1646,7 +1652,7 @@ void select_result(WPARAM wParam, LPARAM lParam)
 	    while (err && s->addr && sk_nextaddr(s->addr, &s->step)) {
 		err = try_connect(s
 #ifdef MPEXT
-		    , 0, 0
+		    , 0, 0, NULL
 #endif
 		);
 	    }

+ 1 - 1
source/putty/x11fwd.c

@@ -313,7 +313,7 @@ struct X11Display *x11_setup_display(const char *display, Conf *conf,
 	    Socket *s = sk_new(sk_addr_dup(ux), 0, false, false,
 	                       false, false, nullplug,
 	    #ifdef MPEXT
-	    0, 0
+	    0, 0, NULL
 	    #endif
 	    );
 	    err = sk_socket_error(s);