@@ -64,11 +64,16 @@ public static string UnpackString(byte[] compressedBytes)
6464 return Encoding . UTF8 . GetString ( compressedBytes , 0 , compressedBytes . Length ) ;
6565 }
6666
67- public struct OnAuth
67+ public struct OnAuth : IEquatable < OnAuth >
6868 {
6969 public ReadyMessage ReadyMessage ;
7070 public Challenge Challenge ;
7171 public Did Did ;
72+ public NetPeer Peer ;
73+
74+ public bool Equals ( OnAuth other ) => ReferenceEquals ( Peer , other . Peer ) ;
75+ public override bool Equals ( object obj ) => obj is OnAuth other && Equals ( other ) ;
76+ public override int GetHashCode ( ) => Peer ? . GetHashCode ( ) ?? 0 ;
7277 }
7378 public int CheckForDuplicates ( Did Did )
7479 {
@@ -133,6 +138,12 @@ public void ProcessConnection(Configuration Configuration, ConnectionRequest Con
133138 }
134139 return ;
135140 }
141+ if ( AuthIdentity . TryGetValue ( newPeer . Id , out OnAuth Stale ) && ! ReferenceEquals ( Stale . Peer , newPeer ) )
142+ {
143+ BNL . Log ( $ "Auth slot { newPeer . Id } still held by a stale connection; releasing it for the incoming peer.") ;
144+ RemoveConnection ( newPeer . Id , Stale . Peer ) ;
145+ }
146+
136147 if ( Configuration . HowManyDuplicateAuthCanExist <= CheckForDuplicates ( playerDid ) )
137148 {
138149 BasisServerHandleEvents . RejectWithReason ( newPeer , "To Many Auths From this DID!" ) ;
@@ -143,7 +154,8 @@ public void ProcessConnection(Configuration Configuration, ConnectionRequest Con
143154 {
144155 Did = playerDid ,
145156 Challenge = MakeChallenge ( playerDid ) ,
146- ReadyMessage = readyMessage
157+ ReadyMessage = readyMessage ,
158+ Peer = newPeer
147159 } ;
148160
149161 if ( AuthIdentity . TryAdd ( newPeer . Id , OnAuth ) )
@@ -206,16 +218,12 @@ public async Task TimeOut(NetPeer newPeer, string UUID, CancellationTokenSource
206218 try
207219 {
208220 await Task . Delay ( GetAuthTimeoutMs ( NetworkServer . Server ? . ConnectedPeersCount ?? 0 ) , cts . Token ) ;
209- if ( ! _timeouts . ContainsKey ( newPeer . Id ) ) return ;
210- if ( AuthIdentity . TryRemove ( newPeer . Id , out OnAuth TimedOut ) )
221+ if ( ! RemoveConnection ( newPeer . Id , newPeer ) )
211222 {
212- ReleaseDid ( TimedOut . Did ) ;
223+ return ;
213224 }
214- _timeouts . TryRemove ( newPeer . Id , out _ ) ;
215- cts . Dispose ( ) ;
216225 BNL . Log ( $ "Authentication timeout for { UUID } .") ;
217226 BasisServerHandleEvents . RejectWithReason ( newPeer , "Authentication timeout" ) ;
218- newPeer . Disconnect ( ) ;
219227 }
220228 catch ( TaskCanceledException ) { }
221229 }
@@ -295,15 +303,37 @@ public async Task<bool> RecvChallengeResponse(Response response, Challenge Chall
295303
296304 public void RemoveConnection ( int NetPeer )
297305 {
298- if ( AuthIdentity . TryRemove ( NetPeer , out var authIdentity ) )
306+ RemoveConnection ( NetPeer , null ) ;
307+ }
308+
309+ public bool RemoveConnection ( int Id , NetPeer Expected )
310+ {
311+ bool Removed ;
312+ OnAuth Entry ;
313+ if ( Expected == null )
299314 {
300- ReleaseDid ( authIdentity . Did ) ;
315+ Removed = AuthIdentity . TryRemove ( Id , out Entry ) ;
301316 }
302- if ( _timeouts . TryRemove ( NetPeer , out var cts ) )
317+ else
318+ {
319+ Removed = AuthIdentity . TryGetValue ( Id , out Entry )
320+ && ReferenceEquals ( Entry . Peer , Expected )
321+ && ( ( ICollection < KeyValuePair < int , OnAuth > > ) AuthIdentity )
322+ . Remove ( new KeyValuePair < int , OnAuth > ( Id , Entry ) ) ;
323+ }
324+
325+ if ( ! Removed )
326+ {
327+ return false ;
328+ }
329+
330+ ReleaseDid ( Entry . Did ) ;
331+ if ( _timeouts . TryRemove ( Id , out var cts ) )
303332 {
304333 try { cts . Cancel ( ) ; } catch { }
305334 cts . Dispose ( ) ;
306335 }
336+ return true ;
307337 }
308338 public bool IsNetPeerAdmin ( string UUID )
309339 {
@@ -391,7 +421,7 @@ static string[] LoadAdmins(string filePath)
391421
392422 public bool NetIDToUUID ( NetPeer Peer , out string UUID )
393423 {
394- if ( AuthIdentity . TryGetValue ( Peer . Id , out OnAuth OnAuth ) )
424+ if ( Peer != null && AuthIdentity . TryGetValue ( Peer . Id , out OnAuth OnAuth ) && ReferenceEquals ( OnAuth . Peer , Peer ) )
395425 {
396426 UUID = OnAuth . Did . V ;
397427 return true ;
0 commit comments