// @(#)root/net:$Id$
// Author: Fons Rademakers   18/12/96

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TSocket
#define ROOT_TSocket


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TSocket                                                              //
//                                                                      //
// This class implements client sockets. A socket is an endpoint for    //
// communication between two machines.                                  //
// The actual work is done via the TSystem class (either TUnixSystem,   //
// or TWinNTSystem).                                                    //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TNamed
#include "TNamed.h"
#endif
#ifndef ROOT_TBits
#include "TBits.h"
#endif
#ifndef ROOT_TInetAddress
#include "TInetAddress.h"
#endif
#ifndef ROOT_MessageTypes
#include "MessageTypes.h"
#endif
#ifndef ROOT_TVirtualAuth
#include "TVirtualAuth.h"
#endif
#ifndef ROOT_TSecContext
#include "TSecContext.h"
#endif
#ifndef ROOT_TTimeStamp
#include "TTimeStamp.h"
#endif
#ifndef ROOT_TVirtualMutex
#include "TVirtualMutex.h"
#endif

enum ESockOptions {
   kSendBuffer,        // size of send buffer
   kRecvBuffer,        // size of receive buffer
   kOobInline,         // OOB message inline
   kKeepAlive,         // keep socket alive
   kReuseAddr,         // allow reuse of local portion of address 5-tuple
   kNoDelay,           // send without delay
   kNoBlock,           // non-blocking I/O
   kProcessGroup,      // socket process group (used for SIGURG and SIGIO)
   kAtMark,            // are we at out-of-band mark (read only)
   kBytesToRead        // get number of bytes to read, FIONREAD (read only)
};

enum ESendRecvOptions {
   kDefault,           // default option (= 0)
   kOob,               // send or receive out-of-band data
   kPeek,              // peek at incoming message (receive only)
   kDontBlock          // send/recv as much data as possible without blocking
};


class TMessage;
class THostAuth;

class TSocket : public TNamed {

friend class TServerSocket;
friend class TProofServ;   // to be able to call SetDescriptor(), RecvHostAuth()
friend class TSlave;       // to be able to call SendHostAuth()

public:
   enum EStatusBits { kIsUnix = BIT(16),    // set if unix socket
                      kBrokenConn = BIT(17) // set if conn reset by peer or broken
                    };
   enum EInterest { kRead = 1, kWrite = 2 };
   enum EServiceType { kSOCKD, kROOTD, kPROOFD };

protected:
   TInetAddress  fAddress;        // remote internet address and port #
   UInt_t        fBytesRecv;      // total bytes received over this socket
   UInt_t        fBytesSent;      // total bytes sent using this socket
   Int_t         fCompress;       // Compression level and algorithm
   TInetAddress  fLocalAddress;   // local internet address and port #
   Int_t         fRemoteProtocol; // protocol of remote daemon
   TSecContext  *fSecContext;     // after a successful Authenticate call
                                  // points to related security context
   TString       fService;        // name of service (matches remote port #)
   EServiceType  fServType;       // remote service type
   Int_t         fSocket;         // socket descriptor
   Int_t         fTcpWindowSize;  // TCP window size (default 65535);
   TString       fUrl;            // needs this for special authentication options
   TBits         fBitsInfo;       // bits array to mark TStreamerInfo classes already sent
   TList        *fUUIDs;          // list of TProcessIDs already sent through the socket

   TVirtualMutex *fLastUsageMtx;   // Protect last usage setting / reading
   TTimeStamp    fLastUsage;      // Time stamp of last usage

   static ULong64_t fgBytesRecv;  // total bytes received by all socket objects
   static ULong64_t fgBytesSent;  // total bytes sent by all socket objects

   static Int_t  fgClientProtocol; // client "protocol" version

   TSocket() : fAddress(), fBytesRecv(0), fBytesSent(0), fCompress(0),
               fLocalAddress(), fRemoteProtocol(), fSecContext(0), fService(),
               fServType(kSOCKD), fSocket(-1), fTcpWindowSize(0), fUrl(),
               fBitsInfo(), fUUIDs(0), fLastUsageMtx(0), fLastUsage() { }

   Bool_t       Authenticate(const char *user);
   void         SetDescriptor(Int_t desc) { fSocket = desc; }
   void         SendStreamerInfos(const TMessage &mess);
   Bool_t       RecvStreamerInfos(TMessage *mess);
   void         SendProcessIDs(const TMessage &mess);
   Bool_t       RecvProcessIDs(TMessage *mess);

private:
   TSocket&      operator=(const TSocket &);  // not implemented
   Option_t     *GetOption() const { return TObject::GetOption(); }

public:
   TSocket(TInetAddress address, const char *service, Int_t tcpwindowsize = -1);
   TSocket(TInetAddress address, Int_t port, Int_t tcpwindowsize = -1);
   TSocket(const char *host, const char *service, Int_t tcpwindowsize = -1);
   TSocket(const char *host, Int_t port, Int_t tcpwindowsize = -1);
   TSocket(const char *sockpath);
   TSocket(Int_t descriptor);
   TSocket(Int_t descriptor, const char *sockpath);
   TSocket(const TSocket &s);
   virtual ~TSocket() { Close(); }

   virtual void          Close(Option_t *opt="");
   virtual Int_t         GetDescriptor() const { return fSocket; }
   TInetAddress          GetInetAddress() const { return fAddress; }
   virtual TInetAddress  GetLocalInetAddress();
   Int_t                 GetPort() const { return fAddress.GetPort(); }
   const char           *GetService() const { return fService; }
   Int_t                 GetServType() const { return (Int_t)fServType; }
   virtual Int_t         GetLocalPort();
   UInt_t                GetBytesSent() const { return fBytesSent; }
   UInt_t                GetBytesRecv() const { return fBytesRecv; }
   Int_t                 GetCompressionAlgorithm() const;
   Int_t                 GetCompressionLevel() const;
   Int_t                 GetCompressionSettings() const;
   Int_t                 GetErrorCode() const;
   virtual Int_t         GetOption(ESockOptions opt, Int_t &val);
   Int_t                 GetRemoteProtocol() const { return fRemoteProtocol; }
   TSecContext          *GetSecContext() const { return fSecContext; }
   Int_t                 GetTcpWindowSize() const { return fTcpWindowSize; }
   TTimeStamp            GetLastUsage() { R__LOCKGUARD2(fLastUsageMtx); return fLastUsage; }
   const char           *GetUrl() const { return fUrl; }
   virtual Bool_t        IsAuthenticated() const { return fSecContext ? kTRUE : kFALSE; }
   virtual Bool_t        IsValid() const { return fSocket < 0 ? kFALSE : kTRUE; }
   virtual Int_t         Recv(TMessage *&mess);
   virtual Int_t         Recv(Int_t &status, Int_t &kind);
   virtual Int_t         Recv(char *mess, Int_t max);
   virtual Int_t         Recv(char *mess, Int_t max, Int_t &kind);
   virtual Int_t         RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt = kDefault);
   virtual Int_t         Reconnect() { return -1; }
   virtual Int_t         Select(Int_t interest = kRead, Long_t timeout = -1);
   virtual Int_t         Send(const TMessage &mess);
   virtual Int_t         Send(Int_t kind);
   virtual Int_t         Send(Int_t status, Int_t kind);
   virtual Int_t         Send(const char *mess, Int_t kind = kMESS_STRING);
   virtual Int_t         SendObject(const TObject *obj, Int_t kind = kMESS_OBJECT);
   virtual Int_t         SendRaw(const void *buffer, Int_t length,
                                 ESendRecvOptions opt = kDefault);
   void                  SetCompressionAlgorithm(Int_t algorithm=0);
   void                  SetCompressionLevel(Int_t level=1);
   void                  SetCompressionSettings(Int_t settings=1);
   virtual Int_t         SetOption(ESockOptions opt, Int_t val);
   void                  SetRemoteProtocol(Int_t rproto) { fRemoteProtocol = rproto; }
   void                  SetSecContext(TSecContext *ctx) { fSecContext = ctx; }
   void                  SetService(const char *service) { fService = service; }
   void                  SetServType(Int_t st) { fServType = (EServiceType)st; }
   void                  SetUrl(const char *url) { fUrl = url; }

   void                  Touch() { R__LOCKGUARD2(fLastUsageMtx); fLastUsage.Set(); }

   static Int_t          GetClientProtocol();

   static ULong64_t      GetSocketBytesSent();
   static ULong64_t      GetSocketBytesRecv();

   static TSocket       *CreateAuthSocket(const char *user, const char *host,
                                          Int_t port, Int_t size = 0,
                                          Int_t tcpwindowsize = -1, TSocket *s = 0, Int_t *err = 0);
   static TSocket       *CreateAuthSocket(const char *url, Int_t size = 0,
                                          Int_t tcpwindowsize = -1, TSocket *s = 0, Int_t *err = 0);
   static void           NetError(const char *where, Int_t error);

   ClassDef(TSocket,0)  //This class implements client sockets
};

//______________________________________________________________________________
inline Int_t TSocket::GetCompressionAlgorithm() const
{
   return (fCompress < 0) ? -1 : fCompress / 100;
}

//______________________________________________________________________________
inline Int_t TSocket::GetCompressionLevel() const
{
   return (fCompress < 0) ? -1 : fCompress % 100;
}

//______________________________________________________________________________
inline Int_t TSocket::GetCompressionSettings() const
{
   return (fCompress < 0) ? -1 : fCompress;
}

#endif
 TSocket.h:1
 TSocket.h:2
 TSocket.h:3
 TSocket.h:4
 TSocket.h:5
 TSocket.h:6
 TSocket.h:7
 TSocket.h:8
 TSocket.h:9
 TSocket.h:10
 TSocket.h:11
 TSocket.h:12
 TSocket.h:13
 TSocket.h:14
 TSocket.h:15
 TSocket.h:16
 TSocket.h:17
 TSocket.h:18
 TSocket.h:19
 TSocket.h:20
 TSocket.h:21
 TSocket.h:22
 TSocket.h:23
 TSocket.h:24
 TSocket.h:25
 TSocket.h:26
 TSocket.h:27
 TSocket.h:28
 TSocket.h:29
 TSocket.h:30
 TSocket.h:31
 TSocket.h:32
 TSocket.h:33
 TSocket.h:34
 TSocket.h:35
 TSocket.h:36
 TSocket.h:37
 TSocket.h:38
 TSocket.h:39
 TSocket.h:40
 TSocket.h:41
 TSocket.h:42
 TSocket.h:43
 TSocket.h:44
 TSocket.h:45
 TSocket.h:46
 TSocket.h:47
 TSocket.h:48
 TSocket.h:49
 TSocket.h:50
 TSocket.h:51
 TSocket.h:52
 TSocket.h:53
 TSocket.h:54
 TSocket.h:55
 TSocket.h:56
 TSocket.h:57
 TSocket.h:58
 TSocket.h:59
 TSocket.h:60
 TSocket.h:61
 TSocket.h:62
 TSocket.h:63
 TSocket.h:64
 TSocket.h:65
 TSocket.h:66
 TSocket.h:67
 TSocket.h:68
 TSocket.h:69
 TSocket.h:70
 TSocket.h:71
 TSocket.h:72
 TSocket.h:73
 TSocket.h:74
 TSocket.h:75
 TSocket.h:76
 TSocket.h:77
 TSocket.h:78
 TSocket.h:79
 TSocket.h:80
 TSocket.h:81
 TSocket.h:82
 TSocket.h:83
 TSocket.h:84
 TSocket.h:85
 TSocket.h:86
 TSocket.h:87
 TSocket.h:88
 TSocket.h:89
 TSocket.h:90
 TSocket.h:91
 TSocket.h:92
 TSocket.h:93
 TSocket.h:94
 TSocket.h:95
 TSocket.h:96
 TSocket.h:97
 TSocket.h:98
 TSocket.h:99
 TSocket.h:100
 TSocket.h:101
 TSocket.h:102
 TSocket.h:103
 TSocket.h:104
 TSocket.h:105
 TSocket.h:106
 TSocket.h:107
 TSocket.h:108
 TSocket.h:109
 TSocket.h:110
 TSocket.h:111
 TSocket.h:112
 TSocket.h:113
 TSocket.h:114
 TSocket.h:115
 TSocket.h:116
 TSocket.h:117
 TSocket.h:118
 TSocket.h:119
 TSocket.h:120
 TSocket.h:121
 TSocket.h:122
 TSocket.h:123
 TSocket.h:124
 TSocket.h:125
 TSocket.h:126
 TSocket.h:127
 TSocket.h:128
 TSocket.h:129
 TSocket.h:130
 TSocket.h:131
 TSocket.h:132
 TSocket.h:133
 TSocket.h:134
 TSocket.h:135
 TSocket.h:136
 TSocket.h:137
 TSocket.h:138
 TSocket.h:139
 TSocket.h:140
 TSocket.h:141
 TSocket.h:142
 TSocket.h:143
 TSocket.h:144
 TSocket.h:145
 TSocket.h:146
 TSocket.h:147
 TSocket.h:148
 TSocket.h:149
 TSocket.h:150
 TSocket.h:151
 TSocket.h:152
 TSocket.h:153
 TSocket.h:154
 TSocket.h:155
 TSocket.h:156
 TSocket.h:157
 TSocket.h:158
 TSocket.h:159
 TSocket.h:160
 TSocket.h:161
 TSocket.h:162
 TSocket.h:163
 TSocket.h:164
 TSocket.h:165
 TSocket.h:166
 TSocket.h:167
 TSocket.h:168
 TSocket.h:169
 TSocket.h:170
 TSocket.h:171
 TSocket.h:172
 TSocket.h:173
 TSocket.h:174
 TSocket.h:175
 TSocket.h:176
 TSocket.h:177
 TSocket.h:178
 TSocket.h:179
 TSocket.h:180
 TSocket.h:181
 TSocket.h:182
 TSocket.h:183
 TSocket.h:184
 TSocket.h:185
 TSocket.h:186
 TSocket.h:187
 TSocket.h:188
 TSocket.h:189
 TSocket.h:190
 TSocket.h:191
 TSocket.h:192
 TSocket.h:193
 TSocket.h:194
 TSocket.h:195
 TSocket.h:196
 TSocket.h:197
 TSocket.h:198
 TSocket.h:199
 TSocket.h:200
 TSocket.h:201
 TSocket.h:202
 TSocket.h:203
 TSocket.h:204
 TSocket.h:205
 TSocket.h:206
 TSocket.h:207
 TSocket.h:208
 TSocket.h:209
 TSocket.h:210
 TSocket.h:211
 TSocket.h:212
 TSocket.h:213
 TSocket.h:214
 TSocket.h:215
 TSocket.h:216
 TSocket.h:217
 TSocket.h:218
 TSocket.h:219
 TSocket.h:220
 TSocket.h:221
 TSocket.h:222