66using System ;
77using System . Collections . Generic ;
88using System . Linq ;
9- using System . Net . NetworkInformation ;
109using System . Threading ;
1110using System . Threading . Tasks ;
1211using Kerberos . NET . Asn1 ;
@@ -20,26 +19,41 @@ namespace Kerberos.NET.Transport
2019{
2120 public abstract class KerberosTransportBase : IKerberosTransport2 , IDisposable
2221 {
22+ protected static readonly Random Random = new ( ) ;
23+
24+ private bool disposedValue ;
25+
2326 protected KerberosTransportBase ( ILoggerFactory logger )
2427 {
2528 this . ClientRealmService = new ClientDomainService ( logger ) ;
29+ this . Logger = logger . CreateLoggerSafe < KerberosTransportBase > ( ) ;
2630 }
2731
28- private bool disposedValue ;
29-
30- private DnsRecord fastest ;
32+ protected ILogger Logger { get ; }
3133
3234 public virtual bool TransportFailed { get ; set ; }
3335
3436 public virtual KerberosTransportException LastError { get ; set ; }
3537
3638 public bool Enabled { get ; set ; }
3739
38- public TimeSpan ConnectTimeout { get ; set ; } = TimeSpan . FromSeconds ( 2 ) ;
40+ public TimeSpan ConnectTimeout
41+ {
42+ get => this . ClientRealmService . ConnectTimeout ;
43+ set => this . ClientRealmService . ConnectTimeout = value ;
44+ }
3945
40- public TimeSpan SendTimeout { get ; set ; } = TimeSpan . FromSeconds ( 10 ) ;
46+ public TimeSpan SendTimeout
47+ {
48+ get => this . ClientRealmService . SendTimeout ;
49+ set => this . ClientRealmService . SendTimeout = value ;
50+ }
4151
42- public TimeSpan ReceiveTimeout { get ; set ; } = TimeSpan . FromSeconds ( 10 ) ;
52+ public TimeSpan ReceiveTimeout
53+ {
54+ get => this . ClientRealmService . ReceiveTimeout ;
55+ set => this . ClientRealmService . ReceiveTimeout = value ;
56+ }
4357
4458 public int MaximumAttempts { get ; set ; } = 30 ;
4559
@@ -166,58 +180,20 @@ public void Dispose()
166180 protected virtual async Task < DnsRecord > LocatePreferredKdc ( string domain , string servicePrefix )
167181 {
168182 var results = await this . LocateKdc ( domain , servicePrefix ) ;
169- return await SelectedPreferredInstance ( domain , servicePrefix , results , ClientDomainService . DefaultKerberosPort ) ;
183+ return SelectedPreferredInstance ( domain , servicePrefix , results , ClientDomainService . DefaultKerberosPort ) ;
170184 }
171185
172186 protected virtual async Task < DnsRecord > LocatePreferredKpasswd ( string domain , string servicePrefix )
173187 {
174188 var results = await this . LocateKpasswd ( domain , servicePrefix ) ;
175- return await SelectedPreferredInstance ( domain , servicePrefix , results , ClientDomainService . DefaultKpasswdPort ) ;
176- }
177-
178- protected virtual async Task < DnsRecord > SelectedPreferredInstance ( string domain , string servicePrefix , IEnumerable < DnsRecord > results , int defaultPort )
179- {
180- if ( results . Contains ( fastest , DnsRecordComparer . Instance ) )
181- {
182- return fastest ;
183- }
184-
185- fastest = await results . Where ( r => r . Name . StartsWith ( servicePrefix ) ) . GetFastestAsync ( PingAsync ) ;
186- return fastest ?? throw new KerberosTransportException ( $ "Cannot locate SRV record for { domain } ") ;
187- }
188-
189- private async Task < DnsRecord > PingAsync ( DnsRecord record , CancellationToken cancellationToken )
190- {
191- using var ping = new Ping ( ) ;
192- cancellationToken . Register ( ( ) => ping . SendAsyncCancel ( ) ) ;
193- var reply = await ping . SendPingAsync ( record . Target , Convert . ToInt32 ( ConnectTimeout . TotalMilliseconds ) ) ;
194- return reply . Status == IPStatus . Success ? record : throw new PingException ( $ "Ping { record . Target } returned { reply . Status } ") ;
189+ return SelectedPreferredInstance ( domain , servicePrefix , results , ClientDomainService . DefaultKpasswdPort ) ;
195190 }
196191
197- private class DnsRecordComparer : IEqualityComparer < DnsRecord >
192+ protected virtual DnsRecord SelectedPreferredInstance ( string domain , string servicePrefix , IEnumerable < DnsRecord > results , int defaultPort )
198193 {
199- public static readonly DnsRecordComparer Instance = new ( ) ;
200-
201- private DnsRecordComparer ( )
202- {
203- }
194+ results = results . Where ( r => r . Name . StartsWith ( servicePrefix ) ) . OrderBy ( r => r . PingResponseTime ) ;
204195
205- public bool Equals ( DnsRecord x , DnsRecord y )
206- {
207- if ( ReferenceEquals ( x , y ) ) return true ;
208- if ( x is null ) return false ;
209- if ( y is null ) return false ;
210- if ( x . GetType ( ) != y . GetType ( ) ) return false ;
211- return x . Target == y . Target && x . Port == y . Port ;
212- }
213-
214- public int GetHashCode ( DnsRecord obj )
215- {
216- unchecked
217- {
218- return ( ( obj . Target != null ? obj . Target . GetHashCode ( ) : 0 ) * 397 ) ^ obj . Port ;
219- }
220- }
196+ return results . FirstOrDefault ( ) ?? throw new KerberosTransportException ( $ "Cannot locate SRV record for { domain } ") ;
221197 }
222198 }
223199}
0 commit comments