/**************************************************************************/ /* */ /* 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. */ /* */ /**************************************************************************/ #ifndef Agent_H #define Agent_H #include <unistd.h> #include <sys/time.h> #include <sys/types.h> #include <sys/select.h> #include "Misc.h" #include "Transport.h" #include "Proxy.h" extern Proxy *proxy; #define PANIC #define WARNING #undef TEST #undef DEBUG class Agent { public: // // Must be created by passing the fake descriptor that // will be used for simulating socket communication // betwen the agent and the proxy. I/O will take place // by copying data to the agent's read and write buf- // fers. // Agent(int fd[2]); ~Agent(); AgentTransport *getTransport() const { return transport_; } void saveReadMask(fd_set *readSet) { saveRead_ = *readSet; } void saveWriteMask(fd_set *writeSet) { saveWrite_ = *writeSet; } void clearReadMask(fd_set *readSet) { FD_CLR(remoteFd_, readSet); FD_CLR(localFd_, readSet); } void clearWriteMask(fd_set *writeSet) { FD_CLR(remoteFd_, writeSet); FD_CLR(localFd_, writeSet); } void setLocalRead(fd_set *readSet, int *result) { (*result)++; FD_SET(localFd_, readSet); } void setRemoteRead(fd_set *readSet, int *result) { (*result)++; FD_SET(remoteFd_, readSet); } void setRemoteWrite(fd_set *writeSet, int *result) { (*result)++; FD_SET(remoteFd_, writeSet); } fd_set *getSavedReadMask() { return &saveRead_; } fd_set *getSavedWriteMask() { return &saveWrite_; } int getRemoteFd() const { return remoteFd_; } int getLocalFd() const { return localFd_; } int getProxyFd() const { return proxy -> getFd(); } int isValid() const { return (transport_ != NULL); } int localReadable() { return (transport_ -> readable() != 0); } // // Check if we can process more data from // the agent descriptor and cache the result // to avoid multiple calls. This must be // always called before querying the other // functions. // void saveChannelState() { canRead_ = (proxy != NULL ? proxy -> canRead(localFd_) : 0); } int remoteCanRead(const fd_set * const readSet) { // OS X 10.5 requires the second argument to be non-const, so copy readSet. // It's safe though, as FD_ISSET does not operate on it. fd_set readWorkSet = *readSet; #if defined(TEST) || defined(INFO) *logofs << "Agent: remoteCanRead() is " << (FD_ISSET(remoteFd_, &readWorkSet) && transport_ -> dequeuable() != 0) << " with FD_ISSET() " << (int) FD_ISSET(remoteFd_, &readWorkSet) << " and dequeuable " << transport_ -> dequeuable() << ".\n" << logofs_flush; #endif return (FD_ISSET(remoteFd_, &readWorkSet) && transport_ -> dequeuable() != 0); } int remoteCanWrite(const fd_set * const writeSet) { // OS X 10.5 requires the second argument to be non-const, so copy writeSet. // It's safe though, as FD_ISSET does not operate on it. fd_set writeWorkSet = *writeSet; #if defined(TEST) || defined(INFO) *logofs << "Agent: remoteCanWrite() is " << (FD_ISSET(remoteFd_, &writeWorkSet) && transport_ -> queuable() != 0 && canRead_ == 1) << " with FD_ISSET() " << (int) FD_ISSET(remoteFd_, &writeWorkSet) << " queueable " << transport_ -> queuable() << " channel can read " << canRead_ << ".\n" << logofs_flush; #endif return (FD_ISSET(remoteFd_, &writeWorkSet) && transport_ -> queuable() != 0 && canRead_ == 1); } int localCanRead() { #if defined(TEST) || defined(INFO) *logofs << "Agent: localCanRead() is " << (transport_ -> readable() != 0 && canRead_ == 1) << " with readable " << transport_ -> readable() << " channel can read " << canRead_ << ".\n" << logofs_flush; #endif return (transport_ -> readable() != 0 && canRead_ == 1); } int proxyCanRead() { #if defined(TEST) || defined(INFO) *logofs << "Agent: proxyCanRead() is " << proxy -> canRead() << ".\n" << logofs_flush; #endif return (proxy -> canRead()); } int proxyCanRead(const fd_set * const readSet) { // OS X 10.5 requires the second argument to be non-const, so copy readSet. // It's safe though, as FD_ISSET does not operate on it. fd_set readWorkSet = *readSet; #if defined(TEST) || defined(INFO) *logofs << "Agent: proxyCanRead() is " << ((int) FD_ISSET(proxy -> getFd(), &readWorkSet)) << ".\n" << logofs_flush; #endif return (FD_ISSET(proxy -> getFd(), &readWorkSet)); } int enqueueData(const char *data, const int size) const { return transport_ -> enqueue(data, size); } int dequeueData(char *data, int size) const { return transport_ -> dequeue(data, size); } int dequeuableData() const { return transport_ -> dequeuable(); } private: int remoteFd_; int localFd_; fd_set saveRead_; fd_set saveWrite_; int canRead_; AgentTransport *transport_; }; #endif /* Agent_H */