/**************************************************************************/ /* */ /* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ /* Copyright (c) 2008-2017 Oleksandr Shneyder */ /* Copyright (c) 2014-2022 Ulrich Sibiller */ /* Copyright (c) 2014-2019 Mihai Moldovan */ /* Copyright (c) 2011-2022 Mike Gabriel */ /* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ /* */ /* NXCOMP, NX protocol compression and NX extensions to this software */ /* are copyright of the aforementioned persons and companies. */ /* */ /* Redistribution and use of the present software is allowed according */ /* to terms specified in the file LICENSE.nxcomp which comes in the */ /* source distribution. */ /* */ /* All rights reserved. */ /* */ /* NOTE: This software has received contributions from various other */ /* contributors, only the core maintainers and supporters are listed as */ /* copyright holders. Please contact us, if you feel you should be listed */ /* as copyright holder, as well. */ /* */ /**************************************************************************/ #ifndef ClientChannel_H #define ClientChannel_H #include "List.h" #include "Channel.h" #include "SequenceQueue.h" #include "ClientReadBuffer.h" // // Set the verbosity level. // #define PANIC #define WARNING #undef TEST #undef DEBUG // // If defined, the client channel will // have the chance of suppressing more // opcodes for test purposes. // #undef LAME // // Define this to log a line when a // channel is created or destroyed. // #undef REFERENCES // // This class implements the X client // side compression of the protocol. // class ClientChannel : public Channel { public: ClientChannel(Transport *transport, StaticCompressor *compressor); virtual ~ClientChannel(); virtual int handleRead(EncodeBuffer &encodeBuffer, const unsigned char *message, unsigned int length); virtual int handleWrite(const unsigned char *message, unsigned int length); virtual int handleSplit(EncodeBuffer &encodeBuffer, MessageStore *store, T_store_action action, int position, const unsigned char opcode, const unsigned char *buffer, const unsigned int size); virtual int handleSplit(DecodeBuffer &decodeBuffer, MessageStore *store, T_store_action action, int position, unsigned char &opcode, unsigned char *&buffer, unsigned int &size) { return 0; } virtual int handleSplit(EncodeBuffer &encodeBuffer); virtual int handleSplit(DecodeBuffer &decodeBuffer) { return 0; } virtual int handleSplitEvent(EncodeBuffer &encodeBuffer, Split *split); virtual int handleSplitEvent(DecodeBuffer &decodeBuffer); virtual int handleMotion(EncodeBuffer &encodeBuffer) { return 0; } virtual int handleCompletion(EncodeBuffer &encodeBuffer) { return 0; } virtual int handleConfiguration(); virtual int handleFinish(); virtual int handleAsyncEvents() { return 0; } virtual int needSplit() const { #if defined(TEST) || defined(SPLIT) *logofs << "needSplit: SPLIT! Returning pending split " << "flag " << splitState_.pending << " with " << clientStore_ -> getSplitTotalSize() << " splits in the split stores.\n" << logofs_flush; #endif return splitState_.pending; } virtual int needMotion() const { return 0; } virtual T_channel_type getType() const { return channel_x11; } int setBigEndian(int flag); // // Initialize the static members. // static int setReferences(); private: int handleFastReadRequest(EncodeBuffer &encodeBuffer, const unsigned char &opcode, const unsigned char *&buffer, const unsigned int &size); int handleFastWriteReply(DecodeBuffer &decodeBuffer, unsigned char &opcode, unsigned char *&buffer, unsigned int &size); int handleFastWriteEvent(DecodeBuffer &decodeBuffer, unsigned char &opcode, unsigned char *&buffer, unsigned int &size); // // Intercept the request before the opcode // is encoded. // int handleTaintRequest(unsigned char &opcode, const unsigned char *&buffer, unsigned int &size) { if (control -> TaintReplies > 0 && opcode == X_GetInputFocus) { return handleTaintSyncRequest(opcode, buffer, size); } #ifdef LAME return handleTaintLameRequest(opcode, buffer, size); #endif return 0; } int handleTaintLameRequest(unsigned char &opcode, const unsigned char *&buffer, unsigned int &size); int handleTaintSyncRequest(unsigned char &opcode, const unsigned char *&buffer, unsigned int &size); int handleTaintSyncError(unsigned char opcode); // // How to handle sequence counter // in notification event. // enum T_sequence_mode { sequence_immediate, sequence_deferred }; // // Send split notifications to the // agent. // int handleRestart(T_sequence_mode mode, int resource); int handleNotify(T_notification_type type, T_sequence_mode mode, int resource, int request, int position); // // Other utility functions used in // handling of the image streaming. // int mustSplitMessage(int resource) { return (clientStore_ -> getSplitStore(resource) -> getSize() != 0); } int canSplitMessage(T_split_mode mode, unsigned int size) { return ((int) size >= control -> SplitDataThreshold && (clientStore_ -> getSplitTotalStorageSize() < control -> SplitTotalStorageSize && clientStore_ -> getSplitTotalSize() < control -> SplitTotalSize)); } int canSendSplit(Split *split) { return (split -> getMode() != split_sync || split -> getState() == split_missed || split -> getState() == split_loaded); } int handleSplitSend(EncodeBuffer &encodeBuffer, int resource, int &total, int &bytes); Split *handleSplitFind(T_checksum checksum, int resource); int handleSplitChecksum(EncodeBuffer &encodeBuffer, T_checksum checksum); void handleSplitPending(int resource) { if (splitState_.pending == 0) { if (clientStore_ -> getSplitStore(resource) != NULL && clientStore_ -> getSplitStore(resource) -> getFirstSplit() != NULL) { splitState_.pending = canSendSplit(clientStore_ -> getSplitStore(resource) -> getFirstSplit()); #if defined(TEST) || defined(SPLIT) *logofs << "handleSplitPending: SPLIT! Set the pending " << "split flag to " << splitState_.pending << " with " << clientStore_ -> getSplitTotalSize() << " splits in the split stores.\n" << logofs_flush; #endif } } } // // Scan all the split stores to find // if there is any split to send. // void handleSplitPending(); // // Handle the MIT-SHM initialization // messages exchanged with the remote // proxy. // int handleShmemRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, const unsigned char *buffer, const unsigned int size); int handleShmemReply(DecodeBuffer &decodeBuffer, unsigned char &opcode, unsigned char *&buffer, unsigned int &size); // // Query the port used to tunnel // the font server connections. // int handleFontRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, const unsigned char *buffer, const unsigned int size); int handleFontReply(DecodeBuffer &decodeBuffer, unsigned char &opcode, unsigned char *&buffer, unsigned int &size); // // Let the agent set the cache // policy for image requests. // int handleCacheRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, const unsigned char *buffer, const unsigned int size); // // Encode the start and end split // requests. // int handleStartSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, const unsigned char *buffer, const unsigned int size); int handleEndSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, const unsigned char *buffer, const unsigned int size); // // Empty a split store and send the // restart event. // int handleAbortSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, const unsigned char *buffer, const unsigned int size); // // Force the proxy to finalize all // the pending split operations and // restart a resource. // int handleFinishSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, const unsigned char *buffer, const unsigned int size); // // Tell the remote peer to send the // split requests to the X server. // int handleCommitSplitRequest(EncodeBuffer &encodeBuffer, const unsigned char opcode, const unsigned char *buffer, const unsigned int size); // // Other utilities. // void handleDecodeCharInfo(DecodeBuffer &, unsigned char *); // // Own read buffer. It is able to identify // full messages read from the X descriptor. // ClientReadBuffer readBuffer_; // // Sequence number of last request coming // from the X client or the X server. // unsigned int clientSequence_; unsigned int serverSequence_; // // Last sequence number known by client. It can // be the real sequence generated by server or // the one of the last auto-generated event. // unsigned int lastSequence_; // // Used to identify replies based on sequence // number of original request. // SequenceQueue sequenceQueue_; // // This is used to test the synchronous flush // in the proxy. // int lastRequest_; // // Current resource id selected as target and // other information related to the image split. // The pending and abort flags are set when we // want the proxy to give us a chance to send // more split data. We also save the position // of the last commit operation performed by // channel so we can differentially encode the // position of next message to commit. // typedef struct { int resource; int pending; int commit; T_split_mode mode; } T_split_state; T_split_state splitState_; // // List of agent resources. // List splitResources_; // // How many sync requests we // have tainted so far. // int taintCounter_; private: // // Keep track of object // creation and deletion. // #ifdef REFERENCES static int references_; #endif }; #endif /* ClientChannel_H */