All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.filesys.smb.server.VirtualCircuit Maven / Gradle / Ivy

Go to download

Java file server with SMB, FTP/FTPS and NFS support, virtual filesystems, database filesystems

The newest version!
/*
 * Copyright (C) 2006-2010 Alfresco Software Limited.
 * Copyright (C) 2018 GK Spencer
 *
 * This file is part of Alfresco
 *
 * Alfresco is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Alfresco is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Alfresco. If not, see .
 */

package org.filesys.smb.server;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.filesys.debug.Debug;
import org.filesys.server.SrvSession;
import org.filesys.server.auth.ClientInfo;
import org.filesys.server.core.DeviceInterface;
import org.filesys.server.core.SharedDevice;
import org.filesys.server.filesys.*;

/**
 * Virtual Circuit Class
 *
 * 

Represents an authenticated circuit on an SMB session. There may be multiple virtual circuits opened * on a single session/socket connection. * * @author gkspencer */ public class VirtualCircuit { // Default and maximum number of connection slots public static final int DefaultConnections = 4; public static final int MaxConnections = 16; // Tree ids are 16bit values private static final int TreeIdMask = 0x0000FFFF; // Default and maximum number of search slots private static final int DefaultSearches = 8; private static final int MaxSearches = 256; // Invalid id value public static final int InvalidID = -1; // Search slot marker object, indicates a search slot is in use before the actual search context // is stored in the slot public static final SearchContextAdapter SearchSlotMarker = new SearchContextAdapter(); // Virtual circuit id value // // Allocated by the server and sent by the client to identify the virtual circuit private int m_vcId = -1; // Virtual circuit number private int m_vcNum; // Client information for this virtual circuit private ClientInfo m_clientInfo; // Active tree connections private Map m_connections; private int m_treeId = 1; // List of active searches private SearchMap m_search; // Active SMB transaction details private SrvTransactBuffer m_transact; // Flag to indicate if the virtual circuit is logged on/off private boolean m_loggedOn; // Time of last I/O on this virtual circuit private long m_lastIO; /** * Class constructor * * @param vcNum int * @param cInfo ClientInfo */ public VirtualCircuit(int vcNum, ClientInfo cInfo) { m_vcNum = vcNum; m_clientInfo = cInfo; m_loggedOn = true; } /** * Return the virtual circuit id * * @return int */ public final int getId() { return m_vcId; } /** * Return the virtual circuit number * * @return int */ public final int getVCNumber() { return m_vcNum; } /** * Return the client information * * @return ClientInfo */ public final ClientInfo getClientInformation() { return m_clientInfo; } /** * Return the time of the last I/o on this virtual circuit * * @return long */ public final long getLastIOTime() { return m_lastIO; } /** * Set the time of the last I/O on this virtual circuit * * @param ioTime long */ public final void setLastIOTime(long ioTime) { m_lastIO = ioTime; } /** * Add a new connection to this virtual circuit. Return the allocated tree id for the new * connection. * * @param shrDev SharedDevice * @return int Allocated tree id (connection id). * @exception TooManyConnectionsException No more connections available */ public synchronized int addConnection(SharedDevice shrDev) throws TooManyConnectionsException { // Check if the connection array has been allocated if (m_connections == null) m_connections = new HashMap(DefaultConnections); // Allocate an id for the tree connection int treeId = 0; // Check if the tree connection table is full if (m_connections.size() == MaxConnections) throw new TooManyConnectionsException(); // Find a free slot in the connection array treeId = (m_treeId++ & TreeIdMask); while (m_connections.containsKey(treeId)) { // Try another tree id for the new connection treeId = (m_treeId++ & TreeIdMask); } // Store the new tree connection m_connections.put(treeId, new TreeConnection(shrDev, treeId)); // Return the allocated tree id return treeId; } /** * Return the tree connection details for the specified tree id. * * @param treeId int * @return TreeConnection */ public synchronized final TreeConnection findConnection(int treeId) { // Check if the tree id and connection array are valid if (m_connections == null) return null; // Get the required tree connection details return m_connections.get(treeId); } /** * Iterate the tree connection ids * * @return Iterator<Integer> */ public final Iterator iterateConnections() { // Check if the tree id and connection array are valid if (m_connections == null) return null; // Iterate the tree connection ids return m_connections.keySet().iterator(); } /** * Remove the specified tree connection from the active connection list. * * @param treeId int * @param sess SrvSession */ public synchronized void removeConnection(int treeId, SrvSession sess) { // Check if the tree id is valid if (m_connections == null) return; TreeConnection tree = m_connections.get(treeId); // Close the connection, release resources if (tree != null) { // Close the connection tree.closeConnection(sess); // Remove the connection from the connection list m_connections.remove(treeId); } } /** * Remove all tree connections from the active connection list * * @param sess SrvSession */ public synchronized void removeAllConnections(SrvSession sess) { // Check if the tree id is valid if (m_connections == null) return; // Remove the tree connections Iterator iterId = m_connections.keySet().iterator(); while ( iterId.hasNext()) { // Get the current tree connection Integer treeId = iterId.next(); TreeConnection tree = m_connections.get( treeId); // Close the connection, release resources if (tree != null) { // Close the connection tree.closeConnection(sess); // Remove the connection from the connection list iterId.remove(); } } } /** * Return the active tree connection count * * @return int */ public synchronized final int getConnectionCount() { return m_connections != null ? m_connections.size() : 0; } /** * Allocate a slot in the active searches list for a new search. * * @return int Search slot id, or -1 if there are no more search slots available. * @exception TooManySearchesException No more search slots available */ public synchronized final int allocateSearchSlot() throws TooManySearchesException { if ( m_search == null) m_search = new SequentialSearchMap(); return m_search.allocateSearchSlot(); } /** * Allocate a slot in the active searches list for a new search. * * @param searchId int * @return boolean true if the searchId is unique and a slot has been allocated, false if there are no more * search slots or the searchId is already in use * @exception TooManySearchesException No more search slots available */ public synchronized final boolean allocateSearchSlotWithId(int searchId) throws TooManySearchesException { if ( m_search == null) m_search = new SequentialSearchMap(); return m_search.allocateSearchSlotWithId( searchId); } /** * Deallocate the specified search context/slot. * * @param ctxId int */ public synchronized final void deallocateSearchSlot(int ctxId) { if ( m_search != null) m_search.deallocateSearchSlot( ctxId); } /** * Return the search context for the specified search id. * * @param srchId int * @return SearchContext */ public synchronized final SearchContext getSearchContext(int srchId) { if ( m_search == null) return null; return m_search.findSearchContext( srchId); } /** * Store the seach context in the specified slot. * * @param slot Slot to store the search context. * @param srch SearchContext */ public synchronized final void setSearchContext(int slot, SearchContext srch) { if ( m_search != null) m_search.setSearchContext( slot, srch); } /** * Return the number of active tree searches. * * @return int */ protected synchronized final int getSearchCount() { if ( m_search == null) return 0; return m_search.numberOfSearches(); } /** * Check if there is an active transaction * * @return boolean */ public synchronized final boolean hasTransaction() { return m_transact != null ? true : false; } /** * Return the active transaction buffer * * @return TransactBuffer */ public synchronized final SrvTransactBuffer getTransaction() { return m_transact; } /** * Set the active transaction buffer * * @param buf TransactBuffer */ public synchronized final void setTransaction(SrvTransactBuffer buf) { m_transact = buf; } /** * Set the id for the circuit * * @param id int */ public final void setId(int id) { m_vcId = id; } /** * Close the virtual circuit, close active tree connections * * @param sess SrvSession */ public synchronized final void closeCircuit(SrvSession sess) { // Notify the session that the virtual circuit is closing if ( sess instanceof SMBSrvSession) { SMBSrvSession smbSess = (SMBSrvSession) sess; smbSess.closeVirtualCircuit(this); } // Debug if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.Dbg.STATE)) sess.debugPrintln("Cleanup vc=" + getVCNumber() + ", id=" + getId() + ", searches=" + getSearchCount() + ", treeConns=" + getConnectionCount()); // Check if there are any active searches if (m_search != null && m_search.numberOfSearches() > 0) { // Close all active searches synchronized (this) { m_search.closeAllSearches(); } } // Check if there are open tree connections if (m_connections != null) { for (TreeConnection tree : m_connections.values()) { // Get the current tree connection DeviceInterface devIface = tree.getInterface(); // Check if there are open files on the share tree.closeConnection(sess); // Inform the driver that the connection has been closed if (devIface != null) devIface.treeClosed(sess, tree); } // Clear the tree connection list m_connections.clear(); } } /** * Check if the virtual circuit has a valid user logged on * * @return boolean */ public synchronized final boolean isLoggedOn() { return m_loggedOn; } /** * Set the logged on status for the virtual circuit * * @param loggedOn boolean */ public synchronized final void setLoggedOn(boolean loggedOn) { m_loggedOn = loggedOn; } /** * Clear the client information from the virtual circuit */ public final void clearClientInformation() { m_clientInfo = null; } /** * Return the virtual circuit details as a string * * @return String */ public String toString() { StringBuilder str = new StringBuilder(); str.append("["); str.append(getVCNumber()); str.append(":"); str.append(getId()); str.append(","); str.append(getClientInformation()); str.append(",Tree="); str.append(getConnectionCount()); str.append(",Searches="); str.append(getSearchCount()); str.append(",lastIO="); str.append( System.currentTimeMillis() - getLastIOTime()); str.append("ms"); str.append("]"); return str.toString(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy