@@ -94,7 +94,9 @@ public class ZeroconfServer implements Closeable {
9494 private final DiffieHellman keys ;
9595 private final List <SessionListener > sessionListeners ;
9696 private final Zeroconf zeroconf ;
97+ private final Object connectionLock = new Object ();
9798 private volatile Session session ;
99+ private String connectingUsername = null ;
98100
99101 private ZeroconfServer (Session .Inner inner , Configuration conf ) throws IOException {
100102 this .inner = inner ;
@@ -230,14 +232,17 @@ private boolean hasValidSession() {
230232 }
231233 }
232234
233- private synchronized void handleGetInfo (OutputStream out , String httpVersion ) throws IOException {
235+ private void handleGetInfo (OutputStream out , String httpVersion ) throws IOException {
234236 JsonObject info = DEFAULT_GET_INFO_FIELDS .deepCopy ();
235- info .addProperty ("activeUser" , hasValidSession () ? session .username () : "" );
236237 info .addProperty ("deviceID" , inner .deviceId );
237238 info .addProperty ("remoteName" , inner .deviceName );
238239 info .addProperty ("publicKey" , Base64 .getEncoder ().encodeToString (keys .publicKeyArray ()));
239240 info .addProperty ("deviceType" , inner .deviceType .name ().toUpperCase ());
240241
242+ synchronized (connectionLock ) {
243+ info .addProperty ("activeUser" , connectingUsername != null ? connectingUsername : (hasValidSession () ? session .username () : "" ));
244+ }
245+
241246 out .write (httpVersion .getBytes ());
242247 out .write (" 200 OK" .getBytes ());
243248 out .write (EOL );
@@ -252,7 +257,7 @@ private synchronized void handleGetInfo(OutputStream out, String httpVersion) th
252257 out .flush ();
253258 }
254259
255- private synchronized void handleAddUser (OutputStream out , Map <String , String > params , String httpVersion ) throws GeneralSecurityException , IOException {
260+ private void handleAddUser (OutputStream out , Map <String , String > params , String httpVersion ) throws GeneralSecurityException , IOException {
256261 String username = params .get ("userName" );
257262 if (username == null || username .isEmpty ()) {
258263 LOGGER .fatal ("Missing userName!" );
@@ -271,6 +276,13 @@ private synchronized void handleAddUser(OutputStream out, Map<String, String> pa
271276 return ;
272277 }
273278
279+ synchronized (connectionLock ) {
280+ if (username .equals (connectingUsername )) {
281+ LOGGER .info ("{} is already trying to connect." , username );
282+ return ;
283+ }
284+ }
285+
274286 byte [] sharedKey = Utils .toByteArray (keys .computeSharedKey (Base64 .getDecoder ().decode (clientKeyStr )));
275287 byte [] blobBytes = Base64 .getDecoder ().decode (blobStr );
276288 byte [] iv = Arrays .copyOfRange (blobBytes , 0 , 16 );
@@ -306,6 +318,10 @@ private synchronized void handleAddUser(OutputStream out, Map<String, String> pa
306318 byte [] decrypted = aes .doFinal (encrypted );
307319
308320 try {
321+ synchronized (connectionLock ) {
322+ connectingUsername = username ;
323+ }
324+
309325 Authentication .LoginCredentials credentials = inner .decryptBlob (username , decrypted );
310326
311327 session = Session .from (inner );
@@ -314,7 +330,9 @@ private synchronized void handleAddUser(OutputStream out, Map<String, String> pa
314330 session .connect ();
315331 session .authenticate (credentials );
316332
317- sessionListeners .forEach (l -> l .sessionChanged (session ));
333+ synchronized (connectionLock ) {
334+ connectingUsername = null ;
335+ }
318336
319337 // Sending response
320338 String resp = DEFAULT_SUCCESSFUL_ADD_USER .toString ();
@@ -329,9 +347,15 @@ private synchronized void handleAddUser(OutputStream out, Map<String, String> pa
329347 out .write (EOL );
330348 out .write (resp .getBytes ());
331349 out .flush ();
350+
351+ sessionListeners .forEach (l -> l .sessionChanged (session ));
332352 } catch (Session .SpotifyAuthenticationException | MercuryClient .MercuryException ex ) {
333353 LOGGER .fatal ("Couldn't establish a new session." , ex );
334354
355+ synchronized (connectionLock ) {
356+ connectingUsername = null ;
357+ }
358+
335359 out .write (httpVersion .getBytes ());
336360 out .write (" 500 Internal Server Error" .getBytes ()); // I don't think this is the Spotify way
337361 out .write (EOL );
0 commit comments