/**************************************************************************/ /* */ /* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/. */ /* */ /* NXCOMP, NX protocol compression and NX extensions to this software */ /* are copyright of NoMachine. Redistribution and use of the present */ /* software is allowed according to terms specified in the file LICENSE */ /* which comes in the source distribution. */ /* */ /* Check http://www.nomachine.com/licensing.html for applicability. */ /* */ /* NX and NoMachine are trademarks of Medialogic S.p.A. */ /* */ /* All rights reserved. */ /* */ /**************************************************************************/ #include "NX.h" #include "NXpack.h" #include "Control.h" #define PANIC #define WARNING #undef TEST #undef DEBUG // // Flush immediately on prioritized messages. // #define FLUSH_PRIORITY 0 // // Maximum number of bytes sent for each token. // #define TOKEN_SIZE 1536 // // Maximum number of tokens that can be spent // by the client proxy before having to block // waiting for a token reply. // #define TOKEN_LIMIT 24 // // By default assume the proxy is running as a // standalone program. // #define LINK_ENCRYPTED 0 // // Maximum number of pids the proxy will record // and kill at shutdown. // #define KILL_LIMIT 16 // // Allocate on the NX client side channels whose // ids are a multiple of 8 (starting from 0). All // the other ids can be used to allocate channels // at the NX server side (X client side). // #define CHANNEL_MASK 0x07 // // Kill session if control parameters cannot be // negotiated before this timeout. // #define INIT_TIMEOUT 60000 // // Enter the congestion state if the remote does // not reply to a ping within the given amount // of time. // #define PING_TIMEOUT 5000 // // Only send one motion event any N milliseconds. // #define MOTION_TIMEOUT 0 // // Force an update of the congestion counter if // the proxy is idle for this time. // #define IDLE_TIMEOUT 50 // // Close X connection if can't write before this // timeout. // #define CHANNEL_TIMEOUT 10000 // // Warn user (or close proxy connection) if don't // receive any data before this timeout. // #define PROXY_TIMEOUT 120000 // // How many milliseconds to wait for the shared // memory completion event to become available. // #define SHMEM_TIMEOUT 200 // // Before closing down the proxy, wait for the // given amount of miliseconds to let all the // running applications to close down their // connections. // // A null timeout will cause the proxy to wait // indefinitely, until the watchdog process is // killed. This is usually the way the proxy is // started by the NX server. If on the other // hand a timeout is given and there no channel // is remaining, the proxy will be closed down // using a small timeout, presently of 500 ms. // #define CLEANUP_TIMEOUT 3000 // // Wait this amount of milliseconds after any // iteration of the house-keeping process. // #define KEEPER_TIMEOUT 60000 // // In case of timeout, select can return control // to program earlier or later of this amount of // ms. Consider this when calculating if timeout // is elapsed. // #define LATENCY_TIMEOUT 1 // // Control memory allocation in transport // and other classes. // #define TRANSPORT_X_BUFFER_SIZE 131072 #define TRANSPORT_PROXY_BUFFER_SIZE 65536 #define TRANSPORT_GENERIC_BUFFER_SIZE 16384 #define TRANSPORT_X_BUFFER_THRESHOLD 262144 #define TRANSPORT_PROXY_BUFFER_THRESHOLD 131072 #define TRANSPORT_GENERIC_BUFFER_THRESHOLD 32768 // // Never allow buffers to exceed this limit. // #define TRANSPORT_MAXIMUM_BUFFER_SIZE 393216 // // Immediately flush the accumulated data to // the X server if the write buffer exceeds // this size. // #define TRANSPORT_FLUSH_BUFFER_SIZE 16384 // // Defaults used for socket options. // #define OPTION_PROXY_KEEP_ALIVE 0 #define OPTION_PROXY_LOW_DELAY 1 #define OPTION_PROXY_CLIENT_NO_DELAY 1 #define OPTION_PROXY_SERVER_NO_DELAY 1 #define OPTION_CLIENT_NO_DELAY 1 #define OPTION_SERVER_NO_DELAY 1 #define OPTION_PROXY_RECEIVE_BUFFER -1 #define OPTION_CLIENT_RECEIVE_BUFFER -1 #define OPTION_SERVER_RECEIVE_BUFFER -1 #define OPTION_PROXY_SEND_BUFFER -1 #define OPTION_CLIENT_SEND_BUFFER -1 #define OPTION_SERVER_SEND_BUFFER -1 #define OPTION_PROXY_RETRY_CONNECT 30 #define OPTION_PROXY_RETRY_ACCEPT 3 #define OPTION_SERVER_RETRY_CONNECT 3 // // Defaults used for cache persistence. // #define PERSISTENT_CACHE_THRESHOLD 102400 #define PERSISTENT_CACHE_ENABLE_LOAD 1 #define PERSISTENT_CACHE_ENABLE_SAVE 1 #define PERSISTENT_CACHE_CHECK_ON_SHUTDOWN 0 #define PERSISTENT_CACHE_LOAD_PACKED 1 #define PERSISTENT_CACHE_LOAD_RENDER 1 #define PERSISTENT_CACHE_DISK_LIMIT 33554432 // // Defaults used for image cache. // #define IMAGE_CACHE_ENABLE_LOAD 0 #define IMAGE_CACHE_ENABLE_SAVE 0 #define IMAGE_CACHE_DISK_LIMIT 33554432 // // Suggested defaults for read length parameters // used by read buffer classes. // #define CLIENT_INITIAL_READ_SIZE 8192 #define CLIENT_MAXIMUM_BUFFER_SIZE 262144 #define SERVER_INITIAL_READ_SIZE 8192 #define SERVER_MAXIMUM_BUFFER_SIZE 65536 #define PROXY_INITIAL_READ_SIZE 65536 #define PROXY_MAXIMUM_BUFFER_SIZE 262144 + 1024 #define GENERIC_INITIAL_READ_SIZE 8192 #define GENERIC_MAXIMUM_BUFFER_SIZE 8192 // // Calculate bitrate in given time frames. // Values are in milliseconds. // #define SHORT_BITRATE_TIME_FRAME 5000 #define LONG_BITRATE_TIME_FRAME 30000 // // Bandwidth control. A value of 0 means no // limit. Values are stored internally in // bytes per second. // #define CLIENT_BITRATE_LIMIT 0 #define SERVER_BITRATE_LIMIT 0 // // Default values for cache control. We limit // the maximum size of a request to 262144 but // we need to consider the replies, whose size // may be up to 4MB. // #define MINIMUM_MESSAGE_SIZE 4 #define MAXIMUM_MESSAGE_SIZE 4194304 #define MAXIMUM_REQUEST_SIZE 262144 #define CLIENT_TOTAL_STORAGE_SIZE 8388608 #define SERVER_TOTAL_STORAGE_SIZE 8388608 #define STORE_TIME_LIMIT 3600 #define STORE_HITS_LOAD_BONUS 10 #define STORE_HITS_ADD_BONUS 20 #define STORE_HITS_LIMIT 100 #define STORE_HITS_TOUCH 1 #define STORE_HITS_UNTOUCH 2 // // Default parameters for message splitting. // #define SPLIT_MODE 1 #define SPLIT_TIMEOUT 50 #define SPLIT_TOTAL_SIZE 128 #define SPLIT_TOTAL_STORAGE_SIZE 1048576 #define SPLIT_DATA_THRESHOLD 65536 #define SPLIT_DATA_PACKET_LIMIT 24576 // // Agent related parameters. // #define PACK_METHOD 63 #define PACK_QUALITY 9 #define HIDE_RENDER 0 #define TAINT_REPLIES 1 #define TAINT_THRESHOLD 8 // // In current version only X server support is // implemented. Note that use of shared memory // is negotiated according to options provided // by the user. // #define SHMEM_CLIENT 0 #define SHMEM_SERVER 1 // // Default size of shared memory segments used // in MIT-SHM support. // #define SHMEM_CLIENT_SIZE 0 #define SHMEM_SERVER_SIZE 2097152 // // What do we do at the end of session? If this // flag is set, we launch a new client letting // the user run a new NX session. // #define ENABLE_RESTART_ON_SHUTDOWN 0 // // Do we produce a core dump on fatal errors? // #define ENABLE_CORE_DUMP_ON_ABORT 0 // // Reopen the log file if it exceeds this size. // #define FILE_SIZE_LIMIT 60000000 // // Check periodically if we need to truncate the // log file. By default check every minute. // #define FILE_SIZE_CHECK_TIMEOUT 60000 // // Protocol version compatibility values // const int Control::NX_MIN_PROTO_STEP = 10; const int Control::NX_MAX_PROTO_STEP = 10; const char* const Control::NXPROXY_COMPATIBILITY_VERSION = "3.5.0"; // // Set defaults for control. They should be what // you get in case of 'local' connection. // Control::Control() { ProxyMode = proxy_undefined; ProxyStage = stage_undefined; SessionMode = session_undefined; FlushPolicy = policy_undefined; LinkMode = link_undefined; LinkEncrypted = LINK_ENCRYPTED; FlushPriority = FLUSH_PRIORITY; TokenSize = TOKEN_SIZE; TokenLimit = TOKEN_LIMIT; ChannelMask = CHANNEL_MASK; InitTimeout = INIT_TIMEOUT; PingTimeout = PING_TIMEOUT; MotionTimeout = MOTION_TIMEOUT; IdleTimeout = IDLE_TIMEOUT; ChannelTimeout = CHANNEL_TIMEOUT; ProxyTimeout = PROXY_TIMEOUT; ShmemTimeout = SHMEM_TIMEOUT; CleanupTimeout = CLEANUP_TIMEOUT; KeeperTimeout = KEEPER_TIMEOUT; LatencyTimeout = LATENCY_TIMEOUT; FileSizeLimit = FILE_SIZE_LIMIT; FileSizeCheckTimeout = FILE_SIZE_CHECK_TIMEOUT; EnableRestartOnShutdown = ENABLE_RESTART_ON_SHUTDOWN; KillDaemonOnShutdownLimit = KILL_LIMIT; KillDaemonOnShutdown = new int[KillDaemonOnShutdownLimit]; for (int i = 0; i < KILL_LIMIT; i++) { KillDaemonOnShutdown[i] = -1; } KillDaemonOnShutdownNumber = 0; EnableCoreDumpOnAbort = ENABLE_CORE_DUMP_ON_ABORT; // // Collect statistics by default. // EnableStatistics = 1; // // Memory restrictions if any. // LocalMemoryLevel = -1; // // Compression must be negotiated between proxies. // LocalDeltaCompression = -1; RemoteDeltaCompression = -1; LocalDataCompression = -1; LocalStreamCompression = -1; RemoteDataCompression = -1; RemoteStreamCompression = -1; LocalDataCompressionLevel = -1; LocalDataCompressionThreshold = -1; LocalStreamCompressionLevel = -1; RemoteDataCompressionLevel = -1; RemoteStreamCompressionLevel = -1; // // Transport buffers' allocation parameters. // TransportXBufferSize = TRANSPORT_X_BUFFER_SIZE; TransportProxyBufferSize = TRANSPORT_PROXY_BUFFER_SIZE; TransportGenericBufferSize = TRANSPORT_GENERIC_BUFFER_SIZE; TransportXBufferThreshold = TRANSPORT_X_BUFFER_THRESHOLD; TransportProxyBufferThreshold = TRANSPORT_PROXY_BUFFER_THRESHOLD; TransportGenericBufferThreshold = TRANSPORT_GENERIC_BUFFER_THRESHOLD; TransportMaximumBufferSize = TRANSPORT_MAXIMUM_BUFFER_SIZE; // // Flush the write buffer if it exceeds // this size. // TransportFlushBufferSize = TRANSPORT_FLUSH_BUFFER_SIZE; // // Socket options. // OptionProxyKeepAlive = OPTION_PROXY_KEEP_ALIVE; OptionProxyLowDelay = OPTION_PROXY_LOW_DELAY; OptionProxyClientNoDelay = OPTION_PROXY_CLIENT_NO_DELAY; OptionProxyServerNoDelay = OPTION_PROXY_SERVER_NO_DELAY; OptionClientNoDelay = OPTION_CLIENT_NO_DELAY; OptionServerNoDelay = OPTION_SERVER_NO_DELAY; OptionProxyReceiveBuffer = OPTION_PROXY_RECEIVE_BUFFER; OptionClientReceiveBuffer = OPTION_CLIENT_RECEIVE_BUFFER; OptionServerReceiveBuffer = OPTION_SERVER_RECEIVE_BUFFER; OptionProxySendBuffer = OPTION_PROXY_SEND_BUFFER; OptionClientSendBuffer = OPTION_CLIENT_SEND_BUFFER; OptionServerSendBuffer = OPTION_SERVER_SEND_BUFFER; OptionProxyRetryAccept = OPTION_PROXY_RETRY_ACCEPT; OptionProxyRetryConnect = OPTION_PROXY_RETRY_CONNECT; OptionServerRetryConnect = OPTION_SERVER_RETRY_CONNECT; // // Base NX directories. // HomePath = NULL; RootPath = NULL; SystemPath = NULL; TempPath = NULL; ClientPath = NULL; // // Set defaults for handling persistent cache. // PersistentCachePath = NULL; PersistentCacheName = NULL; PersistentCacheThreshold = PERSISTENT_CACHE_THRESHOLD; PersistentCacheEnableLoad = PERSISTENT_CACHE_ENABLE_LOAD; PersistentCacheEnableSave = PERSISTENT_CACHE_ENABLE_SAVE; PersistentCacheCheckOnShutdown = PERSISTENT_CACHE_CHECK_ON_SHUTDOWN; PersistentCacheLoadPacked = PERSISTENT_CACHE_LOAD_PACKED; PersistentCacheLoadRender = PERSISTENT_CACHE_LOAD_RENDER; PersistentCacheDiskLimit = PERSISTENT_CACHE_DISK_LIMIT; // // Set defaults for image cache. // ImageCachePath = NULL; ImageCacheEnableLoad = IMAGE_CACHE_ENABLE_LOAD; ImageCacheEnableSave = IMAGE_CACHE_ENABLE_SAVE; ImageCacheDiskLimit = IMAGE_CACHE_DISK_LIMIT; // // Set defaults for the read buffers. // ClientInitialReadSize = CLIENT_INITIAL_READ_SIZE; ClientMaximumBufferSize = CLIENT_MAXIMUM_BUFFER_SIZE; ServerInitialReadSize = SERVER_INITIAL_READ_SIZE; ServerMaximumBufferSize = SERVER_MAXIMUM_BUFFER_SIZE; ProxyInitialReadSize = PROXY_INITIAL_READ_SIZE; ProxyMaximumBufferSize = PROXY_MAXIMUM_BUFFER_SIZE; GenericInitialReadSize = GENERIC_INITIAL_READ_SIZE; GenericMaximumBufferSize = GENERIC_MAXIMUM_BUFFER_SIZE; ShortBitrateTimeFrame = SHORT_BITRATE_TIME_FRAME; LongBitrateTimeFrame = LONG_BITRATE_TIME_FRAME; // // Bandwidth control. // LocalBitrateLimit = -1; ClientBitrateLimit = CLIENT_BITRATE_LIMIT; ServerBitrateLimit = SERVER_BITRATE_LIMIT; // // Default parameters for message handling. // ClientTotalStorageSize = CLIENT_TOTAL_STORAGE_SIZE; ServerTotalStorageSize = SERVER_TOTAL_STORAGE_SIZE; LocalTotalStorageSize = -1; RemoteTotalStorageSize = -1; StoreTimeLimit = STORE_TIME_LIMIT; StoreHitsLoadBonus = STORE_HITS_LOAD_BONUS; StoreHitsAddBonus = STORE_HITS_ADD_BONUS; StoreHitsLimit = STORE_HITS_LIMIT; StoreHitsTouch = STORE_HITS_TOUCH; StoreHitsUntouch = STORE_HITS_UNTOUCH; MinimumMessageSize = MINIMUM_MESSAGE_SIZE; MaximumMessageSize = MAXIMUM_MESSAGE_SIZE; MaximumRequestSize = MAXIMUM_REQUEST_SIZE; SplitMode = SPLIT_MODE; SplitTimeout = SPLIT_TIMEOUT; SplitTotalSize = SPLIT_TOTAL_SIZE; SplitTotalStorageSize = SPLIT_TOTAL_STORAGE_SIZE; SplitDataThreshold = SPLIT_DATA_THRESHOLD; SplitDataPacketLimit = SPLIT_DATA_PACKET_LIMIT; PackMethod = PACK_METHOD; PackQuality = PACK_QUALITY; HideRender = HIDE_RENDER; TaintReplies = TAINT_REPLIES; TaintThreshold = TAINT_THRESHOLD; ShmemClient = SHMEM_CLIENT; ShmemServer = SHMEM_SERVER; ShmemClientSize = SHMEM_CLIENT_SIZE; ShmemServerSize = SHMEM_SERVER_SIZE; // // Get local version number from compile time // settings. Version of remote proxy will be // checked at connection time. // RemoteVersionMajor = -1; RemoteVersionMinor = -1; RemoteVersionPatch = -1; RemoteVersionMaintenancePatch = -1; CompatVersionMajor = -1; CompatVersionMinor = -1; CompatVersionPatch = -1; CompatVersionMaintenancePatch = -1; LocalVersionMajor = NXMajorVersion(); LocalVersionMinor = NXMinorVersion(); LocalVersionPatch = NXPatchVersion(); LocalVersionMaintenancePatch = NXMaintenancePatchVersion(); #ifdef TEST *logofs << "Control: Major version is " << LocalVersionMajor << " minor is " << LocalVersionMinor << " patch is " << LocalVersionPatch << ".\n" << logofs_flush; #endif // // Initialize local implemented methods later // and negotiate remote methods at connection // time. // LocalUnpackMethods = NULL; RemoteUnpackMethods = NULL; // // Set to 1 those methods which are implemented. // setLocalUnpackMethods(); // // Set the protocol version at the // time the session is negotiated. // protoStep_ = 0; } Control::~Control() { if (KillDaemonOnShutdown != NULL) { delete [] KillDaemonOnShutdown; } if (HomePath != NULL) { delete [] HomePath; } if (RootPath != NULL) { delete [] RootPath; } if (SystemPath != NULL) { delete [] SystemPath; } if (TempPath != NULL) { delete [] TempPath; } if (ClientPath != NULL) { delete [] ClientPath; } if (PersistentCachePath != NULL) { delete [] PersistentCachePath; } if (PersistentCacheName != NULL) { delete [] PersistentCacheName; } if (LocalUnpackMethods != NULL) { delete [] LocalUnpackMethods; } if (RemoteUnpackMethods != NULL) { delete [] RemoteUnpackMethods; } if (ImageCachePath != NULL) { delete [] ImageCachePath; } } // // Set the protocol step based on the // remote version. // void Control::setProtoStep(int step) { if (isValidProtoStep(step)) { protoStep_ = step; } else { #ifdef PANIC *logofs << "Control: PANIC! Invalid protocol step " << "with value " << step << ".\n" << logofs_flush; #endif HandleCleanup(); } } int Control::getProtoStep() { if (isValidProtoStep(protoStep_)) { return protoStep_; } else { #ifdef PANIC *logofs << "Control: PANIC! Can't identify the " << "protocol step.\n" << logofs_flush; #endif HandleCleanup(); } } // // Set here the pack/unpack methods that are // implemented by this NX proxy. // void Control::setLocalUnpackMethods() { LocalUnpackMethods = new unsigned char[PACK_METHOD_LIMIT]; RemoteUnpackMethods = new unsigned char[PACK_METHOD_LIMIT]; for (int i = 0; i < PACK_METHOD_LIMIT; i++) { LocalUnpackMethods[i] = 0; RemoteUnpackMethods[i] = 0; } LocalUnpackMethods[NO_PACK] = 1; LocalUnpackMethods[PACK_MASKED_8_COLORS] = 1; LocalUnpackMethods[PACK_MASKED_64_COLORS] = 1; LocalUnpackMethods[PACK_MASKED_256_COLORS] = 1; LocalUnpackMethods[PACK_MASKED_512_COLORS] = 1; LocalUnpackMethods[PACK_MASKED_4K_COLORS] = 1; LocalUnpackMethods[PACK_MASKED_32K_COLORS] = 1; LocalUnpackMethods[PACK_MASKED_64K_COLORS] = 1; LocalUnpackMethods[PACK_MASKED_256K_COLORS] = 1; LocalUnpackMethods[PACK_MASKED_2M_COLORS] = 1; LocalUnpackMethods[PACK_MASKED_16M_COLORS] = 1; LocalUnpackMethods[PACK_RAW_8_BITS] = 1; LocalUnpackMethods[PACK_RAW_16_BITS] = 1; LocalUnpackMethods[PACK_RAW_24_BITS] = 1; LocalUnpackMethods[PACK_COLORMAP_256_COLORS] = 1; LocalUnpackMethods[PACK_JPEG_8_COLORS] = 1; LocalUnpackMethods[PACK_JPEG_64_COLORS] = 1; LocalUnpackMethods[PACK_JPEG_256_COLORS] = 1; LocalUnpackMethods[PACK_JPEG_512_COLORS] = 1; LocalUnpackMethods[PACK_JPEG_4K_COLORS] = 1; LocalUnpackMethods[PACK_JPEG_32K_COLORS] = 1; LocalUnpackMethods[PACK_JPEG_64K_COLORS] = 1; LocalUnpackMethods[PACK_JPEG_256K_COLORS] = 1; LocalUnpackMethods[PACK_JPEG_2M_COLORS] = 1; LocalUnpackMethods[PACK_JPEG_16M_COLORS] = 1; LocalUnpackMethods[PACK_PNG_8_COLORS] = 1; LocalUnpackMethods[PACK_PNG_64_COLORS] = 1; LocalUnpackMethods[PACK_PNG_256_COLORS] = 1; LocalUnpackMethods[PACK_PNG_512_COLORS] = 1; LocalUnpackMethods[PACK_PNG_4K_COLORS] = 1; LocalUnpackMethods[PACK_PNG_32K_COLORS] = 1; LocalUnpackMethods[PACK_PNG_64K_COLORS] = 1; LocalUnpackMethods[PACK_PNG_256K_COLORS] = 1; LocalUnpackMethods[PACK_PNG_2M_COLORS] = 1; LocalUnpackMethods[PACK_PNG_16M_COLORS] = 1; LocalUnpackMethods[PACK_RGB_16M_COLORS] = 1; LocalUnpackMethods[PACK_RLE_16M_COLORS] = 1; LocalUnpackMethods[PACK_ALPHA] = 1; LocalUnpackMethods[PACK_COLORMAP] = 1; LocalUnpackMethods[PACK_BITMAP_16M_COLORS] = 1; }