GUAC-1101: Do not release connections more than once.

This commit is contained in:
Michael Jumper
2015-03-01 21:52:14 -08:00
parent 3f22026c9e
commit feaa2fd63a

View File

@@ -29,6 +29,7 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser; import org.glyptodon.guacamole.auth.jdbc.user.AuthenticatedUser;
import org.glyptodon.guacamole.auth.jdbc.connection.ModeledConnection; import org.glyptodon.guacamole.auth.jdbc.connection.ModeledConnection;
import org.glyptodon.guacamole.auth.jdbc.connectiongroup.ModeledConnectionGroup; import org.glyptodon.guacamole.auth.jdbc.connectiongroup.ModeledConnectionGroup;
@@ -173,6 +174,7 @@ public abstract class AbstractGuacamoleSocketService implements GuacamoleSocketS
final ActiveConnectionRecord activeConnection = new ActiveConnectionRecord(user); final ActiveConnectionRecord activeConnection = new ActiveConnectionRecord(user);
// Get relevant identifiers // Get relevant identifiers
final AtomicBoolean released = new AtomicBoolean(false);
final String identifier = connection.getIdentifier(); final String identifier = connection.getIdentifier();
final String parentIdentifier = connection.getParentIdentifier(); final String parentIdentifier = connection.getParentIdentifier();
@@ -217,25 +219,30 @@ public abstract class AbstractGuacamoleSocketService implements GuacamoleSocketS
// Attempt to close connection // Attempt to close connection
super.close(); super.close();
// Release connection upon close // Release connection upon close, if not already released
activeConnections.remove(identifier, activeConnection); if (released.compareAndSet(false, true)) {
activeConnectionGroups.remove(parentIdentifier, activeConnection);
release(user, connection);
UserModel userModel = user.getUser().getModel(); // Release connection
ConnectionRecordModel recordModel = new ConnectionRecordModel(); activeConnections.remove(identifier, activeConnection);
activeConnectionGroups.remove(parentIdentifier, activeConnection);
release(user, connection);
// Copy user information and timestamps into new record UserModel userModel = user.getUser().getModel();
recordModel.setUserID(userModel.getObjectID()); ConnectionRecordModel recordModel = new ConnectionRecordModel();
recordModel.setUsername(userModel.getIdentifier());
recordModel.setConnectionIdentifier(identifier);
recordModel.setStartDate(activeConnection.getStartDate());
recordModel.setEndDate(new Date());
// Insert connection record // Copy user information and timestamps into new record
connectionRecordMapper.insert(recordModel); recordModel.setUserID(userModel.getObjectID());
recordModel.setUsername(userModel.getIdentifier());
recordModel.setConnectionIdentifier(identifier);
recordModel.setStartDate(activeConnection.getStartDate());
recordModel.setEndDate(new Date());
// Insert connection record
connectionRecordMapper.insert(recordModel);
}
} } // end close()
}; };
@@ -244,10 +251,12 @@ public abstract class AbstractGuacamoleSocketService implements GuacamoleSocketS
// Release connection in case of error // Release connection in case of error
catch (GuacamoleException e) { catch (GuacamoleException e) {
// Atomically release access to connection // Release connection if not already released
activeConnections.remove(identifier, activeConnection); if (released.compareAndSet(false, true)) {
activeConnectionGroups.remove(parentIdentifier, activeConnection); activeConnections.remove(identifier, activeConnection);
release(user, connection); activeConnectionGroups.remove(parentIdentifier, activeConnection);
release(user, connection);
}
throw e; throw e;