@@ -14,13 +14,17 @@ public class MultiplexSocketFactory : SocketFactory
1414 [ Header ( "Sockets to use in order of priority" ) ]
1515 public List < SocketFactory > Factories ;
1616
17+ // once we find a SocketFactory that works on client, we want to keep using it
18+ private SocketFactory _clientFactory ;
19+
1720 // pick lowest size, so that mirage can be configured to work with any of them
1821 public override int MaxPacketSize => Factories . Min ( x => x . MaxPacketSize ) ;
1922
2023 public override ISocket CreateServerSocket ( )
2124 {
2225 ThrowIfNoFactories ( ) ;
2326
27+ // server needs to listen on all sockets
2428 var sockets = new ISocket [ Factories . Count ] ;
2529 for ( int i = 0 ; i < Factories . Count ; i ++ )
2630 {
@@ -34,6 +38,7 @@ public override IEndPoint GetBindEndPoint()
3438 {
3539 ThrowIfNoFactories ( ) ;
3640
41+ // server needs to listen on all sockets
3742 var endPoints = new IEndPoint [ Factories . Count ] ;
3843 for ( int i = 0 ; i < Factories . Count ; i ++ )
3944 {
@@ -43,42 +48,50 @@ public override IEndPoint GetBindEndPoint()
4348 return new BindEndPoint ( endPoints ) ;
4449 }
4550
46- public override ISocket CreateClientSocket ( )
51+ private SocketFactory FindSupportedFactory ( )
4752 {
48- ThrowIfNoFactories ( ) ;
49-
5053 // try each factory and return the first one that is supported
5154 // SocketFactory are expected to throw NotSupportedException when they are not supported for the current platform
5255 foreach ( SocketFactory factory in Factories )
5356 {
5457 try
5558 {
56- return factory . CreateClientSocket ( ) ;
59+ // see if factory is supported by creating a socket
60+ // socket should not do anything until bind/connect is called, so we can just discard it
61+ _ = factory . CreateClientSocket ( ) ;
62+ // we found a socket that works, store it so we can use it later
63+ return factory ;
5764 }
5865 catch ( NotSupportedException ) { }
5966 }
6067
6168 throw new NotSupportedException ( "No Socket supported" ) ;
6269 }
70+
71+ public override ISocket CreateClientSocket ( )
72+ {
73+ ThrowIfNoFactories ( ) ;
74+
75+ // if we have already found a good factory, keep using it
76+ if ( _clientFactory == null )
77+ _clientFactory = FindSupportedFactory ( ) ;
78+
79+ return _clientFactory . CreateClientSocket ( ) ;
80+
81+
82+ }
6383 public override IEndPoint GetConnectEndPoint ( string address = null , ushort ? port = null )
6484 {
6585 ThrowIfNoFactories ( ) ;
6686
67- // try each factory and return the first one that is supported
68- // SocketFactory are expected to throw NotSupportedException when they are not supported for the current platform
69- foreach ( SocketFactory factory in Factories )
70- {
71- try
72- {
73- return factory . GetConnectEndPoint ( address , port ) ;
74- }
75- catch ( NotSupportedException ) { }
76- }
87+ // if we have already found a good factory, keep using it
88+ if ( _clientFactory == null )
89+ _clientFactory = FindSupportedFactory ( ) ;
7790
78- throw new NotSupportedException ( "No Socket supported" ) ;
91+ return _clientFactory . GetConnectEndPoint ( address , port ) ;
7992 }
8093
81- void ThrowIfNoFactories ( )
94+ private void ThrowIfNoFactories ( )
8295 {
8396 if ( Factories . Count == 0 )
8497 throw new InvalidOperationException ( "Factories list empty, add atleast 2 SocketFactory to list to use MultiplexSocketFactory correctly" ) ;
0 commit comments