diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLGuacamoleSocket.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLGuacamoleSocket.java index 1b75690fb..f46035195 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLGuacamoleSocket.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/MySQLGuacamoleSocket.java @@ -39,7 +39,7 @@ public class MySQLGuacamoleSocket implements GuacamoleSocket { * Injected ActiveConnectionMap which will contain all active connections. */ @Inject - private ActiveConnectionMap activeConnectionSet; + private ActiveConnectionMap activeConnectionMap; /** * The wrapped socket. @@ -67,7 +67,7 @@ public class MySQLGuacamoleSocket implements GuacamoleSocket { * @param connectionGroupID The ID of the balancing connection group that is * being connected to; null if not used. */ - public void init(GuacamoleSocket socket, int connectionID, int userID, + public void init(GuacamoleSocket socket, int historyID, Integer connectionGroupID) { this.socket = socket; this.historyID = historyID; @@ -91,7 +91,10 @@ public class MySQLGuacamoleSocket implements GuacamoleSocket { socket.close(); // Mark this connection as inactive - activeConnectionSet.closeConnection(historyID, connectionGroupID); + synchronized (activeConnectionMap) { + activeConnectionMap.closeConnection(historyID, connectionGroupID); + } + } @Override diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionGroupService.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionGroupService.java index 4640091e9..ba34e5052 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionGroupService.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionGroupService.java @@ -176,7 +176,7 @@ public class ConnectionGroupService { * Connect to the connection within the given group with the lowest number * of currently active users. * - * @param connection The group to load balance across. + * @param group The group to load balance across. * @param info The information to use when performing the connection * handshake. * @param userID The ID of the user who is connecting to the socket. @@ -186,36 +186,41 @@ public class ConnectionGroupService { */ public GuacamoleSocket connect(MySQLConnectionGroup group, GuacamoleClientInformation info, int userID) throws GuacamoleException { - + // Get all connections in the group. List connectionIDs = connectionService.getAllConnectionIDs (group.getConnectionGroupID()); - // Get the least used connection. - Integer leastUsedConnectionID = - activeConnectionMap.getLeastUsedConnection(connectionIDs); - - if(leastUsedConnectionID == null) - throw new GuacamoleResourceNotFoundException("No connections found in group."); - - if(GuacamoleProperties.getProperty( - MySQLGuacamoleProperties.MYSQL_DISALLOW_SIMULTANEOUS_CONNECTIONS, false) - && activeConnectionMap.isActive(leastUsedConnectionID)) - throw new GuacamoleServerBusyException - ("Cannot connect. All connections are in use."); - - if(GuacamoleProperties.getProperty( - MySQLGuacamoleProperties.MYSQL_DISALLOW_DUPLICATE_CONNECTIONS, true) - && activeConnectionMap.isConnectionGroupUserActive(group.getConnectionGroupID(), userID)) - throw new GuacamoleClientTooManyException - ("Cannot connect. Connection group already in use by this user."); - - // Get the connection - MySQLConnection connection = connectionService - .retrieveConnection(leastUsedConnectionID, userID); - - // Connect to the connection - return connectionService.connect(connection, info, userID, group.getConnectionGroupID()); + synchronized (activeConnectionMap) { + + // Get the least used connection. + Integer leastUsedConnectionID = + activeConnectionMap.getLeastUsedConnection(connectionIDs); + + if(leastUsedConnectionID == null) + throw new GuacamoleResourceNotFoundException("No connections found in group."); + + if(GuacamoleProperties.getProperty( + MySQLGuacamoleProperties.MYSQL_DISALLOW_SIMULTANEOUS_CONNECTIONS, false) + && activeConnectionMap.isActive(leastUsedConnectionID)) + throw new GuacamoleServerBusyException + ("Cannot connect. All connections are in use."); + + if(GuacamoleProperties.getProperty( + MySQLGuacamoleProperties.MYSQL_DISALLOW_DUPLICATE_CONNECTIONS, true) + && activeConnectionMap.isConnectionGroupUserActive(group.getConnectionGroupID(), userID)) + throw new GuacamoleClientTooManyException + ("Cannot connect. Connection group already in use by this user."); + + // Get the connection + MySQLConnection connection = connectionService + .retrieveConnection(leastUsedConnectionID, userID); + + // Connect to the connection + return connectionService.connect(connection, info, userID, group.getConnectionGroupID()); + + } + } /** diff --git a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionService.java b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionService.java index ad402570f..a31e3f949 100644 --- a/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionService.java +++ b/extensions/guacamole-auth-mysql/src/main/java/net/sourceforge/guacamole/net/auth/mysql/service/ConnectionService.java @@ -322,46 +322,49 @@ public class ConnectionService { GuacamoleClientInformation info, int userID, Integer connectionGroupID) throws GuacamoleException { - // If the given connection is active, and multiple simultaneous - // connections are not allowed, disallow connection - if(GuacamoleProperties.getProperty( - MySQLGuacamoleProperties.MYSQL_DISALLOW_SIMULTANEOUS_CONNECTIONS, false) - && activeConnectionMap.isActive(connection.getConnectionID())) - throw new GuacamoleResourceConflictException("Cannot connect. This connection is in use."); - - if(GuacamoleProperties.getProperty( - MySQLGuacamoleProperties.MYSQL_DISALLOW_DUPLICATE_CONNECTIONS, true) - && activeConnectionMap.isConnectionUserActive(connection.getConnectionID(), userID)) - throw new GuacamoleClientTooManyException - ("Cannot connect. Connection already in use by this user."); + synchronized (activeConnectionMap) { - // Get guacd connection information - String host = GuacamoleProperties.getRequiredProperty(GuacamoleProperties.GUACD_HOSTNAME); - int port = GuacamoleProperties.getRequiredProperty(GuacamoleProperties.GUACD_PORT); + // If the given connection is active, and multiple simultaneous + // connections are not allowed, disallow connection + if(GuacamoleProperties.getProperty( + MySQLGuacamoleProperties.MYSQL_DISALLOW_SIMULTANEOUS_CONNECTIONS, false) + && activeConnectionMap.isActive(connection.getConnectionID())) + throw new GuacamoleResourceConflictException("Cannot connect. This connection is in use."); + + if(GuacamoleProperties.getProperty( + MySQLGuacamoleProperties.MYSQL_DISALLOW_DUPLICATE_CONNECTIONS, true) + && activeConnectionMap.isConnectionUserActive(connection.getConnectionID(), userID)) + throw new GuacamoleClientTooManyException + ("Cannot connect. Connection already in use by this user."); - // Get socket - GuacamoleSocket socket; - if (GuacamoleProperties.getProperty(GuacamoleProperties.GUACD_SSL, false)) - socket = new ConfiguredGuacamoleSocket( - new SSLGuacamoleSocket(host, port), - connection.getConfiguration(), info - ); - else - socket = new ConfiguredGuacamoleSocket( - new InetGuacamoleSocket(host, port), - connection.getConfiguration(), info - ); + // Get guacd connection information + String host = GuacamoleProperties.getRequiredProperty(GuacamoleProperties.GUACD_HOSTNAME); + int port = GuacamoleProperties.getRequiredProperty(GuacamoleProperties.GUACD_PORT); - // Mark this connection as active - int historyID = activeConnectionMap.openConnection(connection.getConnectionID(), - userID, connectionGroupID); + // Get socket + GuacamoleSocket socket; + if (GuacamoleProperties.getProperty(GuacamoleProperties.GUACD_SSL, false)) + socket = new ConfiguredGuacamoleSocket( + new SSLGuacamoleSocket(host, port), + connection.getConfiguration(), info + ); + else + socket = new ConfiguredGuacamoleSocket( + new InetGuacamoleSocket(host, port), + connection.getConfiguration(), info + ); - // Return new MySQLGuacamoleSocket - MySQLGuacamoleSocket mySQLGuacamoleSocket = mySQLGuacamoleSocketProvider.get(); - mySQLGuacamoleSocket.init(socket, connection.getConnectionID(), userID, - historyID, connectionGroupID); - - return mySQLGuacamoleSocket; + // Mark this connection as active + int historyID = activeConnectionMap.openConnection(connection.getConnectionID(), + userID, connectionGroupID); + + // Return new MySQLGuacamoleSocket + MySQLGuacamoleSocket mySQLGuacamoleSocket = mySQLGuacamoleSocketProvider.get(); + mySQLGuacamoleSocket.init(socket, historyID, connectionGroupID); + + return mySQLGuacamoleSocket; + + } }