ROOT logo
// @(#)root/net:$Id: TPSocket.cxx 24480 2008-06-23 13:29:34Z rdm $
// Author: Fons Rademakers   22/1/2001

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

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TPSocket                                                             //
//                                                                      //
// This class implements parallel client sockets. A parallel socket is  //
// an endpoint for communication between two machines. It is parallel   //
// because several TSockets are open at the same time to the same       //
// destination. This especially speeds up communication over Big Fat    //
// Pipes (i.e. high bandwidth, high latency WAN connections).           //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TPSocket.h"
#include "TUrl.h"
#include "TServerSocket.h"
#include "TMonitor.h"
#include "TSystem.h"
#include "TMessage.h"
#include "Bytes.h"
#include "TROOT.h"
#include "TError.h"
#include "TVirtualMutex.h"

ClassImp(TPSocket)

//______________________________________________________________________________
TPSocket::TPSocket(TInetAddress addr, const char *service, Int_t size,
                   Int_t tcpwindowsize) : TSocket(addr, service)
{
   // Create a parallel socket. Connect to the named service at address addr.
   // Use tcpwindowsize to specify the size of the receive buffer, it has
   // to be specified here to make sure the window scale option is set (for
   // tcpwindowsize > 65KB and for platforms supporting window scaling).
   // Returns when connection has been accepted by remote side. Use IsValid()
   // to check the validity of the socket. Every socket is added to the TROOT
   // sockets list which will make sure that any open sockets are properly
   // closed on program termination.

   fSize = size;
   Init(tcpwindowsize);
}

//______________________________________________________________________________
TPSocket::TPSocket(TInetAddress addr, Int_t port, Int_t size,
                   Int_t tcpwindowsize) : TSocket(addr, port)
{
   // Create a parallel socket. Connect to the specified port # at address addr.
   // Use tcpwindowsize to specify the size of the receive buffer, it has
   // to be specified here to make sure the window scale option is set (for
   // tcpwindowsize > 65KB and for platforms supporting window scaling).
   // Returns when connection has been accepted by remote side. Use IsValid()
   // to check the validity of the socket. Every socket is added to the TROOT
   // sockets list which will make sure that any open sockets are properly
   // closed on program termination.

   fSize = size;
   Init(tcpwindowsize);
}

//______________________________________________________________________________
TPSocket::TPSocket(const char *host, const char *service, Int_t size,
                   Int_t tcpwindowsize) : TSocket(host, service)
{
   // Create a parallel socket. Connect to named service on the remote host.
   // Use tcpwindowsize to specify the size of the receive buffer, it has
   // to be specified here to make sure the window scale option is set (for
   // tcpwindowsize > 65KB and for platforms supporting window scaling).
   // Returns when connection has been accepted by remote side. Use IsValid()
   // to check the validity of the socket. Every socket is added to the TROOT
   // sockets list which will make sure that any open sockets are properly
   // closed on program termination.

   fSize = size;
   Init(tcpwindowsize);
}

//______________________________________________________________________________
TPSocket::TPSocket(const char *host, Int_t port, Int_t size,
                   Int_t tcpwindowsize)
                  : TSocket(host, port, (Int_t)(size > 1 ? -1 : tcpwindowsize))
{
   // Create a parallel socket. Connect to specified port # on the remote host.
   // Use tcpwindowsize to specify the size of the receive buffer, it has
   // to be specified here to make sure the window scale option is set (for
   // tcpwindowsize > 65KB and for platforms supporting window scaling).
   // Returns when connection has been accepted by remote side. Use IsValid()
   // to check the validity of the socket. Every socket is added to the TROOT
   // sockets list which will make sure that any open sockets are properly
   // closed on program termination.

   // To avoid uninitialization problems when Init is not called ...
   fSockets        = 0;
   fWriteMonitor   = 0;
   fReadMonitor    = 0;
   fWriteBytesLeft = 0;
   fReadBytesLeft  = 0;
   fWritePtr       = 0;
   fReadPtr        = 0;

   // set to the real value only at end (except for old servers)
   fSize           = 1;

   // to control the flow
   Bool_t valid = TSocket::IsValid();

   // check if we are called from CreateAuthSocket()
   Bool_t authreq = kFALSE;
   char *pauth = (char *)strstr(host, "?A");
   if (pauth) {
      authreq = kTRUE;
   }

   // perhaps we can use fServType here ... to be checked
   Bool_t rootdSrv = (strstr(host,"rootd")) ? kTRUE : kFALSE;

   // try authentication , if required
   if (authreq) {
      if (valid) {
         if (!Authenticate(TUrl(host).GetUser())) {
            if (rootdSrv && fRemoteProtocol < 10) {
               // We failed because we are talking to an old
               // server: we need to re-open the connection
               // and communicate the size first
               Int_t tcpw = (size > 1 ? -1 : tcpwindowsize);
               TSocket *ns = new TSocket(host, port, tcpw);
               if (ns->IsValid()) {
                  R__LOCKGUARD2(gROOTMutex);
                  gROOT->GetListOfSockets()->Remove(ns);
                  fSocket = ns->GetDescriptor();
                  fSize = size;
                  Init(tcpwindowsize);
               }
               if ((valid = IsValid())) {
                  if (!Authenticate(TUrl(host).GetUser())) {
                     TSocket::Close();
                     valid = kFALSE;
                  }
               }
            } else {
               TSocket::Close();
               valid = kFALSE;
            }
         }
      }
      // reset url to the original state
      *pauth = '\0';
      SetUrl(host);
   }

   // open the sockets ...
   if (!rootdSrv || fRemoteProtocol > 9) {
      if (valid) {
         fSize = size;
         Init(tcpwindowsize);
      }
   }
}

//______________________________________________________________________________
TPSocket::TPSocket(const char *host, Int_t port, Int_t size, TSocket *sock)
{
   // Create a parallel socket on a connection already opened via
   // TSocket sock.
   // This constructor is provided to optimize TNetFile opening when
   // instatiated via a call to TXNetFile.
   // Returns when connection has been accepted by remote side. Use IsValid()
   // to check the validity of the socket. Every socket is added to the TROOT
   // sockets list which will make sure that any open sockets are properly
   // closed on program termination.

   // To avoid uninitialization problems when Init is not called ...
   fSockets        = 0;
   fWriteMonitor   = 0;
   fReadMonitor    = 0;
   fWriteBytesLeft = 0;
   fReadBytesLeft  = 0;
   fWritePtr       = 0;
   fReadPtr        = 0;

   // set to the real value only at end (except for old servers)
   fSize           = 1;

   // We need a opened connection
   if (!sock) return;

   // Now import existing socket info
   fSocket         = sock->GetDescriptor();
   fService        = sock->GetService();
   fAddress        = sock->GetInetAddress();
   fLocalAddress   = sock->GetLocalInetAddress();
   fBytesSent      = sock->GetBytesSent();
   fBytesRecv      = sock->GetBytesRecv();
   fCompress       = sock->GetCompressionLevel();
   fSecContext     = sock->GetSecContext();
   fRemoteProtocol = sock->GetRemoteProtocol();
   fServType       = (TSocket::EServiceType)sock->GetServType();
   fTcpWindowSize  = sock->GetTcpWindowSize();

   // to control the flow
   Bool_t valid = sock->IsValid();

   // check if we are called from CreateAuthSocket()
   Bool_t authreq = kFALSE;
   char *pauth = (char *)strstr(host, "?A");
   if (pauth) {
      authreq = kTRUE;
   }

   // perhaps we can use fServType here ... to be checked
   Bool_t rootdSrv = (strstr(host,"rootd")) ? kTRUE : kFALSE;

   // try authentication , if required
   if (authreq) {
      if (valid) {
         if (!Authenticate(TUrl(host).GetUser())) {
            if (rootdSrv && fRemoteProtocol < 10) {
               // We failed because we are talking to an old
               // server: we need to re-open the connection
               // and communicate the size first
               Int_t tcpw = (size > 1 ? -1 : fTcpWindowSize);
               TSocket *ns = new TSocket(host, port, tcpw);
               if (ns->IsValid()) {
                  R__LOCKGUARD2(gROOTMutex);
                  gROOT->GetListOfSockets()->Remove(ns);
                  fSocket = ns->GetDescriptor();
                  fSize = size;
                  Init(fTcpWindowSize);
               }
               if ((valid = IsValid())) {
                  if (!Authenticate(TUrl(host).GetUser())) {
                     TSocket::Close();
                     valid = kFALSE;
                  }
               }
            } else {
               TSocket::Close();
               valid = kFALSE;
            }
         }
      }
      // reset url to the original state
      *pauth = '\0';
      SetUrl(host);
   }

   // open the sockets ...
   if (!rootdSrv || fRemoteProtocol > 9) {
      if (valid) {
         fSize = size;
         Init(fTcpWindowSize, sock);
      }
   }

   // Add to the list if everything OK
   if (IsValid()) {
      R__LOCKGUARD2(gROOTMutex);
      gROOT->GetListOfSockets()->Add(this);
   }
}

//______________________________________________________________________________
TPSocket::TPSocket(TSocket *pSockets[], Int_t size)
{
   // Create a parallel socket. This ctor is called by TPServerSocket.

   fSockets = pSockets;
   fSize    = size;

   // set descriptor if simple socket (needed when created
   // by TPServerSocket)
   if (fSize <= 1)
      fSocket = fSockets[0]->GetDescriptor();

   // set socket options (no blocking and no delay)
   SetOption(kNoDelay, 1);
   if (fSize > 1)
      SetOption(kNoBlock, 1);

   fWriteMonitor   = new TMonitor;
   fReadMonitor    = new TMonitor;
   fWriteBytesLeft = new Int_t[fSize];
   fReadBytesLeft  = new Int_t[fSize];
   fWritePtr       = new char*[fSize];
   fReadPtr        = new char*[fSize];

   for (int i = 0; i < fSize; i++) {
      fWriteMonitor->Add(fSockets[i], TMonitor::kWrite);
      fReadMonitor->Add(fSockets[i], TMonitor::kRead);
   }
   fWriteMonitor->DeActivateAll();
   fReadMonitor->DeActivateAll();

   SetName(fSockets[0]->GetName());
   SetTitle(fSockets[0]->GetTitle());
   fAddress = fSockets[0]->GetInetAddress();

   {
      R__LOCKGUARD2(gROOTMutex);
      gROOT->GetListOfSockets()->Add(this);
   }
}

//______________________________________________________________________________
TPSocket::~TPSocket()
{
   // Cleanup the parallel socket.

   Close();

   delete fWriteMonitor;
   delete fReadMonitor;
   delete [] fWriteBytesLeft;
   delete [] fReadBytesLeft;
   delete [] fWritePtr;
   delete [] fReadPtr;
}

//______________________________________________________________________________
void TPSocket::Close(Option_t *option)
{
   // Close a parallel socket. If option is "force", calls shutdown(id,2) to
   // shut down the connection. This will close the connection also
   // for the parent of this process. Also called via the dtor (without
   // option "force", call explicitely Close("force") if this is desired).


   if (!IsValid()) {
      // if closing happens too early (e.g. timeout) the underlying
      // socket may still be open
      TSocket::Close(option);
      return;
   }

   if (fSize <= 1) {
      TSocket::Close(option);
   } else {
      for (int i = 0; i < fSize; i++) {
         fSockets[i]->Close(option);
         delete fSockets[i];
      }
   }
   delete [] fSockets;
   fSockets = 0;

   {
      R__LOCKGUARD2(gROOTMutex);
      gROOT->GetListOfSockets()->Remove(this);
   }
}

//______________________________________________________________________________
void TPSocket::Init(Int_t tcpwindowsize, TSocket *sock)
{
   // Create a parallel socket to the specified host.

   fSockets        = 0;
   fWriteMonitor   = 0;
   fReadMonitor    = 0;
   fWriteBytesLeft = 0;
   fReadBytesLeft  = 0;
   fWritePtr       = 0;
   fReadPtr        = 0;

   if ((sock && !sock->IsValid()) || !TSocket::IsValid())
      return;

   Int_t i = 0;

   if (fSize <= 1) {
      // check if single mode
      fSize = 1;

      // set socket options (no delay)
      if (sock)
         sock->SetOption(kNoDelay, 1);
      else
         TSocket::SetOption(kNoDelay, 1);

      // if yes, communicate this to server
      // (size = 0 for backward compatibility)
      if (sock)
         sock->Send((Int_t)0, (Int_t)0);
      else
         TSocket::Send((Int_t)0, (Int_t)0);

      // needs to fill additional private members
      fSockets = new TSocket*[1];
      fSockets[0]= (TSocket *)this;

   } else {

      // create server that will be used to accept the parallel sockets from
      // the remote host, use port=0 to scan for a free port
      TServerSocket ss(0, kFALSE, fSize, tcpwindowsize);

      // send the local port number of the just created server socket and the
      // number of desired parallel sockets
      if (sock)
         sock->Send(ss.GetLocalPort(), fSize);
      else
         TSocket::Send(ss.GetLocalPort(), fSize);

      fSockets = new TSocket*[fSize];

      // establish fSize parallel socket connections between client and server
      for (i = 0; i < fSize; i++) {
         fSockets[i] = ss.Accept();
         R__LOCKGUARD2(gROOTMutex);
         gROOT->GetListOfSockets()->Remove(fSockets[i]);
      }

      // set socket options (no blocking and no delay)
      SetOption(kNoDelay, 1);
      SetOption(kNoBlock, 1);

      // close original socket
      if (sock)
         sock->Close();
      else
         gSystem->CloseConnection(fSocket, kFALSE);
      fSocket = -1;
   }

   fWriteMonitor   = new TMonitor;
   fReadMonitor    = new TMonitor;
   fWriteBytesLeft = new Int_t[fSize];
   fReadBytesLeft  = new Int_t[fSize];
   fWritePtr       = new char*[fSize];
   fReadPtr        = new char*[fSize];

   for (i = 0; i < fSize; i++) {
      fWriteMonitor->Add(fSockets[i], TMonitor::kWrite);
      fReadMonitor->Add(fSockets[i], TMonitor::kRead);
   }
   fWriteMonitor->DeActivateAll();
   fReadMonitor->DeActivateAll();
}

//______________________________________________________________________________
TInetAddress TPSocket::GetLocalInetAddress()
{
   // Return internet address of local host to which the socket is bound.
   // In case of error TInetAddress::IsValid() returns kFALSE.

   if (fSize<= 1)
      return TSocket::GetLocalInetAddress();

   if (IsValid()) {
      if (fLocalAddress.GetPort() == -1)
         fLocalAddress = gSystem->GetSockName(fSockets[0]->GetDescriptor());
      return fLocalAddress;
   }
   return TInetAddress();
}

//______________________________________________________________________________
Int_t TPSocket::GetDescriptor() const
{
   // Return socket descriptor

   if (fSize <= 1)
      return TSocket::GetDescriptor();

   return fSockets ? fSockets[0]->GetDescriptor() : -1;

}

//______________________________________________________________________________
Int_t TPSocket::Send(const TMessage &mess)
{
   // Send a TMessage object. Returns the number of bytes in the TMessage
   // that were sent and -1 in case of error. In case the TMessage::What
   // has been or'ed with kMESS_ACK, the call will only return after having
   // received an acknowledgement, making the sending process synchronous.
   // Returns -4 in case of kNoBlock and errno == EWOULDBLOCK.

   if (!fSockets || fSize <= 1)
      return TSocket::Send(mess);  // only the case when called via Init()

   if (!IsValid()) {
      return -1;
   }

   if (mess.IsReading()) {
      Error("Send", "cannot send a message used for reading");
      return -1;
   }

   // send streamer infos in case schema evolution is enabled in the TMessage
   SendStreamerInfos(mess);

   // send the process id's so TRefs work
   SendProcessIDs(mess);

   mess.SetLength();   //write length in first word of buffer

   if (fCompress > 0 && mess.GetCompressionLevel() == 0)
      const_cast<TMessage&>(mess).SetCompressionLevel(fCompress);

   if (mess.GetCompressionLevel() > 0)
      const_cast<TMessage&>(mess).Compress();

   char *mbuf = mess.Buffer();
   Int_t mlen = mess.Length();
   if (mess.CompBuffer()) {
      mbuf = mess.CompBuffer();
      mlen = mess.CompLength();
   }

   Int_t nsent, ulen = (Int_t) sizeof(UInt_t);
   // send length
   if ((nsent = SendRaw(mbuf, ulen, kDefault)) <= 0)
      return nsent;

   // send buffer (this might go in parallel)
   if ((nsent = SendRaw(mbuf+ulen, mlen-ulen, kDefault)) <= 0)
      return nsent;

   // if acknowledgement is desired, wait for it
   if (mess.What() & kMESS_ACK) {
      char buf[2];
      if (RecvRaw(buf, sizeof(buf), kDefault) < 0)
         return -1;
      if (strncmp(buf, "ok", 2)) {
         Error("Send", "bad acknowledgement");
         return -1;
      }
   }

   return nsent;  //length - length header
}

//______________________________________________________________________________
Int_t TPSocket::SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt)
{
   // Send a raw buffer of specified length. Returns the number of bytes
   // send and -1 in case of error.

   if (fSize == 1)
      return TSocket::SendRaw(buffer,length,opt);

   if (!fSockets) return -1;

   // if data buffer size < 4K use only one socket
   Int_t i, nsocks = fSize, len = length;
   if (len < 4096)
      nsocks = 1;

   ESendRecvOptions sendopt = kDontBlock;
   if (nsocks == 1)
      sendopt = kDefault;

   if (opt != kDefault) {
      nsocks  = 1;
      sendopt = opt;
   }

   if (nsocks == 1)
      fSockets[0]->SetOption(kNoBlock, 0);
   else
      fSockets[0]->SetOption(kNoBlock, 1);

   // setup pointer appropriately for transferring data equally on the
   // parallel sockets
   for (i = 0; i < nsocks; i++) {
      fWriteBytesLeft[i] = len/nsocks;
      fWritePtr[i] = (char *)buffer + (i*fWriteBytesLeft[i]);
      fWriteMonitor->Activate(fSockets[i]);
   }
   fWriteBytesLeft[nsocks-1] += len%nsocks;

   // send the data on the parallel sockets
   while (len > 0) {
      TSocket *s = fWriteMonitor->Select();
      for (int is = 0; is < nsocks; is++) {
         if (s == fSockets[is]) {
            if (fWriteBytesLeft[is] > 0) {
               Int_t nsent;
again:
               if ((nsent = fSockets[is]->SendRaw(fWritePtr[is],
                                                  fWriteBytesLeft[is],
                                                  sendopt)) <= 0) {
                  if (nsent == -4) {
                     // got EAGAIN/EWOULDBLOCK error, keep trying...
                     goto again;
                  }
                  fWriteMonitor->DeActivateAll();
                  if (nsent == -5) {
                     // connection reset by peer or broken ...
                     Close();
                  }
                  return -1;
               }
               if (opt == kDontBlock) {
                  fWriteMonitor->DeActivateAll();
                  return nsent;
               }
               fWriteBytesLeft[is] -= nsent;
               fWritePtr[is] += nsent;
               len -= nsent;
            }
         }
      }
   }
   fWriteMonitor->DeActivateAll();

   return length;
}

//______________________________________________________________________________
Int_t TPSocket::Recv(TMessage *&mess)
{
   // Receive a TMessage object. The user must delete the TMessage object.
   // Returns length of message in bytes (can be 0 if other side of connection
   // is closed) or -1 in case of error or -4 in case a non-blocking socket would
   // block (i.e. there is nothing to be read). In those case mess == 0.

   if (fSize <= 1)
      return TSocket::Recv(mess);

   if (!IsValid()) {
      mess = 0;
      return -1;
   }

oncemore:
   Int_t  n;
   UInt_t len;
   if ((n = RecvRaw(&len, sizeof(UInt_t), kDefault)) <= 0) {
      mess = 0;
      return n;
   }
   len = net2host(len);  //from network to host byte order

   char *buf = new char[len+sizeof(UInt_t)];
   if ((n = RecvRaw(buf+sizeof(UInt_t), len, kDefault)) <= 0) {
      delete [] buf;
      mess = 0;
      return n;
   }

   mess = new TMessage(buf, len+sizeof(UInt_t));

   // receive any streamer infos
   if (RecvStreamerInfos(mess))
      goto oncemore;

   // receive any process ids
   if (RecvProcessIDs(mess))
      goto oncemore;

   if (mess->What() & kMESS_ACK) {
      char ok[2] = { 'o', 'k' };
      if (SendRaw(ok, sizeof(ok), kDefault) < 0) {
         delete mess;
         mess = 0;
         return -1;
      }
      mess->SetWhat(mess->What() & ~kMESS_ACK);
   }

   return n;
}

//______________________________________________________________________________
Int_t TPSocket::RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt)
{
   // Send a raw buffer of specified length. Returns the number of bytes
   // sent or -1 in case of error.

   if (fSize <= 1)
      return TSocket::RecvRaw(buffer,length,opt);

   if (!fSockets) return -1;

   // if data buffer size < 4K use only one socket
   Int_t i, nsocks = fSize, len = length;
   if (len < 4096)
      nsocks = 1;

   ESendRecvOptions recvopt = kDontBlock;
   if (nsocks == 1)
      recvopt = kDefault;

   if (opt != kDefault) {
      nsocks  = 1;
      recvopt = opt;
   }

   if (nsocks == 1)
      fSockets[0]->SetOption(kNoBlock, 0);
   else
      fSockets[0]->SetOption(kNoBlock, 1);

   // setup pointer appropriately for transferring data equally on the
   // parallel sockets
   for (i = 0; i < nsocks; i++) {
      fReadBytesLeft[i] = len/nsocks;
      fReadPtr[i] = (char *)buffer + (i*fReadBytesLeft[i]);
      fReadMonitor->Activate(fSockets[i]);
   }
   fReadBytesLeft[nsocks-1] += len%nsocks;

   // start receiving data on all sockets. Receive data as and when
   // they are available on a socket by by using select.
   // Exit the loop as soon as all data has been received.
   while (len > 0) {
      TSocket *s = fReadMonitor->Select();
      for (int is = 0; is < nsocks; is++) {
         if (s == fSockets[is]) {
            if (fReadBytesLeft[is] > 0) {
               Int_t nrecv;
               if ((nrecv = fSockets[is]->RecvRaw(fReadPtr[is],
                                                  fReadBytesLeft[is],
                                                  recvopt)) <= 0) {
                  fReadMonitor->DeActivateAll();
                  if (nrecv == -5) {
                     // connection reset by peer or broken ...
                     Close();
                  }
                  return -1;
               }
               if (opt == kDontBlock) {
                  fReadMonitor->DeActivateAll();
                  return nrecv;
               }
               fReadBytesLeft[is] -= nrecv;
               fReadPtr[is] += nrecv;
               len -= nrecv;
            }
         }
      }
   }
   fReadMonitor->DeActivateAll();

   return length;
}

//______________________________________________________________________________
Int_t TPSocket::SetOption(ESockOptions opt, Int_t val)
{
   // Set socket options.

   if (fSize <= 1)
      return TSocket::SetOption(opt,val);

   Int_t ret = 0;
   for (int i = 0; i < fSize; i++)
      ret = fSockets[i]->SetOption(opt, val);
   return ret;
}

//______________________________________________________________________________
Int_t TPSocket::GetOption(ESockOptions opt, Int_t &val)
{
   // Get socket options. Returns -1 in case of error.

   if (fSize <= 1)
      return TSocket::GetOption(opt,val);

   Int_t ret = 0;
   for (int i = 0; i < fSize; i++)
      ret = fSockets[i]->GetOption(opt, val);
   return ret;
}

//______________________________________________________________________________
Int_t TPSocket::GetErrorCode() const
{
   // Returns error code. Meaning depends on context where it is called.
   // If no error condition returns 0 else a value < 0.

   if (fSize <= 1)
      return TSocket::GetErrorCode();

   return fSockets[0] ? fSockets[0]->GetErrorCode() : 0;
}
 TPSocket.cxx:1
 TPSocket.cxx:2
 TPSocket.cxx:3
 TPSocket.cxx:4
 TPSocket.cxx:5
 TPSocket.cxx:6
 TPSocket.cxx:7
 TPSocket.cxx:8
 TPSocket.cxx:9
 TPSocket.cxx:10
 TPSocket.cxx:11
 TPSocket.cxx:12
 TPSocket.cxx:13
 TPSocket.cxx:14
 TPSocket.cxx:15
 TPSocket.cxx:16
 TPSocket.cxx:17
 TPSocket.cxx:18
 TPSocket.cxx:19
 TPSocket.cxx:20
 TPSocket.cxx:21
 TPSocket.cxx:22
 TPSocket.cxx:23
 TPSocket.cxx:24
 TPSocket.cxx:25
 TPSocket.cxx:26
 TPSocket.cxx:27
 TPSocket.cxx:28
 TPSocket.cxx:29
 TPSocket.cxx:30
 TPSocket.cxx:31
 TPSocket.cxx:32
 TPSocket.cxx:33
 TPSocket.cxx:34
 TPSocket.cxx:35
 TPSocket.cxx:36
 TPSocket.cxx:37
 TPSocket.cxx:38
 TPSocket.cxx:39
 TPSocket.cxx:40
 TPSocket.cxx:41
 TPSocket.cxx:42
 TPSocket.cxx:43
 TPSocket.cxx:44
 TPSocket.cxx:45
 TPSocket.cxx:46
 TPSocket.cxx:47
 TPSocket.cxx:48
 TPSocket.cxx:49
 TPSocket.cxx:50
 TPSocket.cxx:51
 TPSocket.cxx:52
 TPSocket.cxx:53
 TPSocket.cxx:54
 TPSocket.cxx:55
 TPSocket.cxx:56
 TPSocket.cxx:57
 TPSocket.cxx:58
 TPSocket.cxx:59
 TPSocket.cxx:60
 TPSocket.cxx:61
 TPSocket.cxx:62
 TPSocket.cxx:63
 TPSocket.cxx:64
 TPSocket.cxx:65
 TPSocket.cxx:66
 TPSocket.cxx:67
 TPSocket.cxx:68
 TPSocket.cxx:69
 TPSocket.cxx:70
 TPSocket.cxx:71
 TPSocket.cxx:72
 TPSocket.cxx:73
 TPSocket.cxx:74
 TPSocket.cxx:75
 TPSocket.cxx:76
 TPSocket.cxx:77
 TPSocket.cxx:78
 TPSocket.cxx:79
 TPSocket.cxx:80
 TPSocket.cxx:81
 TPSocket.cxx:82
 TPSocket.cxx:83
 TPSocket.cxx:84
 TPSocket.cxx:85
 TPSocket.cxx:86
 TPSocket.cxx:87
 TPSocket.cxx:88
 TPSocket.cxx:89
 TPSocket.cxx:90
 TPSocket.cxx:91
 TPSocket.cxx:92
 TPSocket.cxx:93
 TPSocket.cxx:94
 TPSocket.cxx:95
 TPSocket.cxx:96
 TPSocket.cxx:97
 TPSocket.cxx:98
 TPSocket.cxx:99
 TPSocket.cxx:100
 TPSocket.cxx:101
 TPSocket.cxx:102
 TPSocket.cxx:103
 TPSocket.cxx:104
 TPSocket.cxx:105
 TPSocket.cxx:106
 TPSocket.cxx:107
 TPSocket.cxx:108
 TPSocket.cxx:109
 TPSocket.cxx:110
 TPSocket.cxx:111
 TPSocket.cxx:112
 TPSocket.cxx:113
 TPSocket.cxx:114
 TPSocket.cxx:115
 TPSocket.cxx:116
 TPSocket.cxx:117
 TPSocket.cxx:118
 TPSocket.cxx:119
 TPSocket.cxx:120
 TPSocket.cxx:121
 TPSocket.cxx:122
 TPSocket.cxx:123
 TPSocket.cxx:124
 TPSocket.cxx:125
 TPSocket.cxx:126
 TPSocket.cxx:127
 TPSocket.cxx:128
 TPSocket.cxx:129
 TPSocket.cxx:130
 TPSocket.cxx:131
 TPSocket.cxx:132
 TPSocket.cxx:133
 TPSocket.cxx:134
 TPSocket.cxx:135
 TPSocket.cxx:136
 TPSocket.cxx:137
 TPSocket.cxx:138
 TPSocket.cxx:139
 TPSocket.cxx:140
 TPSocket.cxx:141
 TPSocket.cxx:142
 TPSocket.cxx:143
 TPSocket.cxx:144
 TPSocket.cxx:145
 TPSocket.cxx:146
 TPSocket.cxx:147
 TPSocket.cxx:148
 TPSocket.cxx:149
 TPSocket.cxx:150
 TPSocket.cxx:151
 TPSocket.cxx:152
 TPSocket.cxx:153
 TPSocket.cxx:154
 TPSocket.cxx:155
 TPSocket.cxx:156
 TPSocket.cxx:157
 TPSocket.cxx:158
 TPSocket.cxx:159
 TPSocket.cxx:160
 TPSocket.cxx:161
 TPSocket.cxx:162
 TPSocket.cxx:163
 TPSocket.cxx:164
 TPSocket.cxx:165
 TPSocket.cxx:166
 TPSocket.cxx:167
 TPSocket.cxx:168
 TPSocket.cxx:169
 TPSocket.cxx:170
 TPSocket.cxx:171
 TPSocket.cxx:172
 TPSocket.cxx:173
 TPSocket.cxx:174
 TPSocket.cxx:175
 TPSocket.cxx:176
 TPSocket.cxx:177
 TPSocket.cxx:178
 TPSocket.cxx:179
 TPSocket.cxx:180
 TPSocket.cxx:181
 TPSocket.cxx:182
 TPSocket.cxx:183
 TPSocket.cxx:184
 TPSocket.cxx:185
 TPSocket.cxx:186
 TPSocket.cxx:187
 TPSocket.cxx:188
 TPSocket.cxx:189
 TPSocket.cxx:190
 TPSocket.cxx:191
 TPSocket.cxx:192
 TPSocket.cxx:193
 TPSocket.cxx:194
 TPSocket.cxx:195
 TPSocket.cxx:196
 TPSocket.cxx:197
 TPSocket.cxx:198
 TPSocket.cxx:199
 TPSocket.cxx:200
 TPSocket.cxx:201
 TPSocket.cxx:202
 TPSocket.cxx:203
 TPSocket.cxx:204
 TPSocket.cxx:205
 TPSocket.cxx:206
 TPSocket.cxx:207
 TPSocket.cxx:208
 TPSocket.cxx:209
 TPSocket.cxx:210
 TPSocket.cxx:211
 TPSocket.cxx:212
 TPSocket.cxx:213
 TPSocket.cxx:214
 TPSocket.cxx:215
 TPSocket.cxx:216
 TPSocket.cxx:217
 TPSocket.cxx:218
 TPSocket.cxx:219
 TPSocket.cxx:220
 TPSocket.cxx:221
 TPSocket.cxx:222
 TPSocket.cxx:223
 TPSocket.cxx:224
 TPSocket.cxx:225
 TPSocket.cxx:226
 TPSocket.cxx:227
 TPSocket.cxx:228
 TPSocket.cxx:229
 TPSocket.cxx:230
 TPSocket.cxx:231
 TPSocket.cxx:232
 TPSocket.cxx:233
 TPSocket.cxx:234
 TPSocket.cxx:235
 TPSocket.cxx:236
 TPSocket.cxx:237
 TPSocket.cxx:238
 TPSocket.cxx:239
 TPSocket.cxx:240
 TPSocket.cxx:241
 TPSocket.cxx:242
 TPSocket.cxx:243
 TPSocket.cxx:244
 TPSocket.cxx:245
 TPSocket.cxx:246
 TPSocket.cxx:247
 TPSocket.cxx:248
 TPSocket.cxx:249
 TPSocket.cxx:250
 TPSocket.cxx:251
 TPSocket.cxx:252
 TPSocket.cxx:253
 TPSocket.cxx:254
 TPSocket.cxx:255
 TPSocket.cxx:256
 TPSocket.cxx:257
 TPSocket.cxx:258
 TPSocket.cxx:259
 TPSocket.cxx:260
 TPSocket.cxx:261
 TPSocket.cxx:262
 TPSocket.cxx:263
 TPSocket.cxx:264
 TPSocket.cxx:265
 TPSocket.cxx:266
 TPSocket.cxx:267
 TPSocket.cxx:268
 TPSocket.cxx:269
 TPSocket.cxx:270
 TPSocket.cxx:271
 TPSocket.cxx:272
 TPSocket.cxx:273
 TPSocket.cxx:274
 TPSocket.cxx:275
 TPSocket.cxx:276
 TPSocket.cxx:277
 TPSocket.cxx:278
 TPSocket.cxx:279
 TPSocket.cxx:280
 TPSocket.cxx:281
 TPSocket.cxx:282
 TPSocket.cxx:283
 TPSocket.cxx:284
 TPSocket.cxx:285
 TPSocket.cxx:286
 TPSocket.cxx:287
 TPSocket.cxx:288
 TPSocket.cxx:289
 TPSocket.cxx:290
 TPSocket.cxx:291
 TPSocket.cxx:292
 TPSocket.cxx:293
 TPSocket.cxx:294
 TPSocket.cxx:295
 TPSocket.cxx:296
 TPSocket.cxx:297
 TPSocket.cxx:298
 TPSocket.cxx:299
 TPSocket.cxx:300
 TPSocket.cxx:301
 TPSocket.cxx:302
 TPSocket.cxx:303
 TPSocket.cxx:304
 TPSocket.cxx:305
 TPSocket.cxx:306
 TPSocket.cxx:307
 TPSocket.cxx:308
 TPSocket.cxx:309
 TPSocket.cxx:310
 TPSocket.cxx:311
 TPSocket.cxx:312
 TPSocket.cxx:313
 TPSocket.cxx:314
 TPSocket.cxx:315
 TPSocket.cxx:316
 TPSocket.cxx:317
 TPSocket.cxx:318
 TPSocket.cxx:319
 TPSocket.cxx:320
 TPSocket.cxx:321
 TPSocket.cxx:322
 TPSocket.cxx:323
 TPSocket.cxx:324
 TPSocket.cxx:325
 TPSocket.cxx:326
 TPSocket.cxx:327
 TPSocket.cxx:328
 TPSocket.cxx:329
 TPSocket.cxx:330
 TPSocket.cxx:331
 TPSocket.cxx:332
 TPSocket.cxx:333
 TPSocket.cxx:334
 TPSocket.cxx:335
 TPSocket.cxx:336
 TPSocket.cxx:337
 TPSocket.cxx:338
 TPSocket.cxx:339
 TPSocket.cxx:340
 TPSocket.cxx:341
 TPSocket.cxx:342
 TPSocket.cxx:343
 TPSocket.cxx:344
 TPSocket.cxx:345
 TPSocket.cxx:346
 TPSocket.cxx:347
 TPSocket.cxx:348
 TPSocket.cxx:349
 TPSocket.cxx:350
 TPSocket.cxx:351
 TPSocket.cxx:352
 TPSocket.cxx:353
 TPSocket.cxx:354
 TPSocket.cxx:355
 TPSocket.cxx:356
 TPSocket.cxx:357
 TPSocket.cxx:358
 TPSocket.cxx:359
 TPSocket.cxx:360
 TPSocket.cxx:361
 TPSocket.cxx:362
 TPSocket.cxx:363
 TPSocket.cxx:364
 TPSocket.cxx:365
 TPSocket.cxx:366
 TPSocket.cxx:367
 TPSocket.cxx:368
 TPSocket.cxx:369
 TPSocket.cxx:370
 TPSocket.cxx:371
 TPSocket.cxx:372
 TPSocket.cxx:373
 TPSocket.cxx:374
 TPSocket.cxx:375
 TPSocket.cxx:376
 TPSocket.cxx:377
 TPSocket.cxx:378
 TPSocket.cxx:379
 TPSocket.cxx:380
 TPSocket.cxx:381
 TPSocket.cxx:382
 TPSocket.cxx:383
 TPSocket.cxx:384
 TPSocket.cxx:385
 TPSocket.cxx:386
 TPSocket.cxx:387
 TPSocket.cxx:388
 TPSocket.cxx:389
 TPSocket.cxx:390
 TPSocket.cxx:391
 TPSocket.cxx:392
 TPSocket.cxx:393
 TPSocket.cxx:394
 TPSocket.cxx:395
 TPSocket.cxx:396
 TPSocket.cxx:397
 TPSocket.cxx:398
 TPSocket.cxx:399
 TPSocket.cxx:400
 TPSocket.cxx:401
 TPSocket.cxx:402
 TPSocket.cxx:403
 TPSocket.cxx:404
 TPSocket.cxx:405
 TPSocket.cxx:406
 TPSocket.cxx:407
 TPSocket.cxx:408
 TPSocket.cxx:409
 TPSocket.cxx:410
 TPSocket.cxx:411
 TPSocket.cxx:412
 TPSocket.cxx:413
 TPSocket.cxx:414
 TPSocket.cxx:415
 TPSocket.cxx:416
 TPSocket.cxx:417
 TPSocket.cxx:418
 TPSocket.cxx:419
 TPSocket.cxx:420
 TPSocket.cxx:421
 TPSocket.cxx:422
 TPSocket.cxx:423
 TPSocket.cxx:424
 TPSocket.cxx:425
 TPSocket.cxx:426
 TPSocket.cxx:427
 TPSocket.cxx:428
 TPSocket.cxx:429
 TPSocket.cxx:430
 TPSocket.cxx:431
 TPSocket.cxx:432
 TPSocket.cxx:433
 TPSocket.cxx:434
 TPSocket.cxx:435
 TPSocket.cxx:436
 TPSocket.cxx:437
 TPSocket.cxx:438
 TPSocket.cxx:439
 TPSocket.cxx:440
 TPSocket.cxx:441
 TPSocket.cxx:442
 TPSocket.cxx:443
 TPSocket.cxx:444
 TPSocket.cxx:445
 TPSocket.cxx:446
 TPSocket.cxx:447
 TPSocket.cxx:448
 TPSocket.cxx:449
 TPSocket.cxx:450
 TPSocket.cxx:451
 TPSocket.cxx:452
 TPSocket.cxx:453
 TPSocket.cxx:454
 TPSocket.cxx:455
 TPSocket.cxx:456
 TPSocket.cxx:457
 TPSocket.cxx:458
 TPSocket.cxx:459
 TPSocket.cxx:460
 TPSocket.cxx:461
 TPSocket.cxx:462
 TPSocket.cxx:463
 TPSocket.cxx:464
 TPSocket.cxx:465
 TPSocket.cxx:466
 TPSocket.cxx:467
 TPSocket.cxx:468
 TPSocket.cxx:469
 TPSocket.cxx:470
 TPSocket.cxx:471
 TPSocket.cxx:472
 TPSocket.cxx:473
 TPSocket.cxx:474
 TPSocket.cxx:475
 TPSocket.cxx:476
 TPSocket.cxx:477
 TPSocket.cxx:478
 TPSocket.cxx:479
 TPSocket.cxx:480
 TPSocket.cxx:481
 TPSocket.cxx:482
 TPSocket.cxx:483
 TPSocket.cxx:484
 TPSocket.cxx:485
 TPSocket.cxx:486
 TPSocket.cxx:487
 TPSocket.cxx:488
 TPSocket.cxx:489
 TPSocket.cxx:490
 TPSocket.cxx:491
 TPSocket.cxx:492
 TPSocket.cxx:493
 TPSocket.cxx:494
 TPSocket.cxx:495
 TPSocket.cxx:496
 TPSocket.cxx:497
 TPSocket.cxx:498
 TPSocket.cxx:499
 TPSocket.cxx:500
 TPSocket.cxx:501
 TPSocket.cxx:502
 TPSocket.cxx:503
 TPSocket.cxx:504
 TPSocket.cxx:505
 TPSocket.cxx:506
 TPSocket.cxx:507
 TPSocket.cxx:508
 TPSocket.cxx:509
 TPSocket.cxx:510
 TPSocket.cxx:511
 TPSocket.cxx:512
 TPSocket.cxx:513
 TPSocket.cxx:514
 TPSocket.cxx:515
 TPSocket.cxx:516
 TPSocket.cxx:517
 TPSocket.cxx:518
 TPSocket.cxx:519
 TPSocket.cxx:520
 TPSocket.cxx:521
 TPSocket.cxx:522
 TPSocket.cxx:523
 TPSocket.cxx:524
 TPSocket.cxx:525
 TPSocket.cxx:526
 TPSocket.cxx:527
 TPSocket.cxx:528
 TPSocket.cxx:529
 TPSocket.cxx:530
 TPSocket.cxx:531
 TPSocket.cxx:532
 TPSocket.cxx:533
 TPSocket.cxx:534
 TPSocket.cxx:535
 TPSocket.cxx:536
 TPSocket.cxx:537
 TPSocket.cxx:538
 TPSocket.cxx:539
 TPSocket.cxx:540
 TPSocket.cxx:541
 TPSocket.cxx:542
 TPSocket.cxx:543
 TPSocket.cxx:544
 TPSocket.cxx:545
 TPSocket.cxx:546
 TPSocket.cxx:547
 TPSocket.cxx:548
 TPSocket.cxx:549
 TPSocket.cxx:550
 TPSocket.cxx:551
 TPSocket.cxx:552
 TPSocket.cxx:553
 TPSocket.cxx:554
 TPSocket.cxx:555
 TPSocket.cxx:556
 TPSocket.cxx:557
 TPSocket.cxx:558
 TPSocket.cxx:559
 TPSocket.cxx:560
 TPSocket.cxx:561
 TPSocket.cxx:562
 TPSocket.cxx:563
 TPSocket.cxx:564
 TPSocket.cxx:565
 TPSocket.cxx:566
 TPSocket.cxx:567
 TPSocket.cxx:568
 TPSocket.cxx:569
 TPSocket.cxx:570
 TPSocket.cxx:571
 TPSocket.cxx:572
 TPSocket.cxx:573
 TPSocket.cxx:574
 TPSocket.cxx:575
 TPSocket.cxx:576
 TPSocket.cxx:577
 TPSocket.cxx:578
 TPSocket.cxx:579
 TPSocket.cxx:580
 TPSocket.cxx:581
 TPSocket.cxx:582
 TPSocket.cxx:583
 TPSocket.cxx:584
 TPSocket.cxx:585
 TPSocket.cxx:586
 TPSocket.cxx:587
 TPSocket.cxx:588
 TPSocket.cxx:589
 TPSocket.cxx:590
 TPSocket.cxx:591
 TPSocket.cxx:592
 TPSocket.cxx:593
 TPSocket.cxx:594
 TPSocket.cxx:595
 TPSocket.cxx:596
 TPSocket.cxx:597
 TPSocket.cxx:598
 TPSocket.cxx:599
 TPSocket.cxx:600
 TPSocket.cxx:601
 TPSocket.cxx:602
 TPSocket.cxx:603
 TPSocket.cxx:604
 TPSocket.cxx:605
 TPSocket.cxx:606
 TPSocket.cxx:607
 TPSocket.cxx:608
 TPSocket.cxx:609
 TPSocket.cxx:610
 TPSocket.cxx:611
 TPSocket.cxx:612
 TPSocket.cxx:613
 TPSocket.cxx:614
 TPSocket.cxx:615
 TPSocket.cxx:616
 TPSocket.cxx:617
 TPSocket.cxx:618
 TPSocket.cxx:619
 TPSocket.cxx:620
 TPSocket.cxx:621
 TPSocket.cxx:622
 TPSocket.cxx:623
 TPSocket.cxx:624
 TPSocket.cxx:625
 TPSocket.cxx:626
 TPSocket.cxx:627
 TPSocket.cxx:628
 TPSocket.cxx:629
 TPSocket.cxx:630
 TPSocket.cxx:631
 TPSocket.cxx:632
 TPSocket.cxx:633
 TPSocket.cxx:634
 TPSocket.cxx:635
 TPSocket.cxx:636
 TPSocket.cxx:637
 TPSocket.cxx:638
 TPSocket.cxx:639
 TPSocket.cxx:640
 TPSocket.cxx:641
 TPSocket.cxx:642
 TPSocket.cxx:643
 TPSocket.cxx:644
 TPSocket.cxx:645
 TPSocket.cxx:646
 TPSocket.cxx:647
 TPSocket.cxx:648
 TPSocket.cxx:649
 TPSocket.cxx:650
 TPSocket.cxx:651
 TPSocket.cxx:652
 TPSocket.cxx:653
 TPSocket.cxx:654
 TPSocket.cxx:655
 TPSocket.cxx:656
 TPSocket.cxx:657
 TPSocket.cxx:658
 TPSocket.cxx:659
 TPSocket.cxx:660
 TPSocket.cxx:661
 TPSocket.cxx:662
 TPSocket.cxx:663
 TPSocket.cxx:664
 TPSocket.cxx:665
 TPSocket.cxx:666
 TPSocket.cxx:667
 TPSocket.cxx:668
 TPSocket.cxx:669
 TPSocket.cxx:670
 TPSocket.cxx:671
 TPSocket.cxx:672
 TPSocket.cxx:673
 TPSocket.cxx:674
 TPSocket.cxx:675
 TPSocket.cxx:676
 TPSocket.cxx:677
 TPSocket.cxx:678
 TPSocket.cxx:679
 TPSocket.cxx:680
 TPSocket.cxx:681
 TPSocket.cxx:682
 TPSocket.cxx:683
 TPSocket.cxx:684
 TPSocket.cxx:685
 TPSocket.cxx:686
 TPSocket.cxx:687
 TPSocket.cxx:688
 TPSocket.cxx:689
 TPSocket.cxx:690
 TPSocket.cxx:691
 TPSocket.cxx:692
 TPSocket.cxx:693
 TPSocket.cxx:694
 TPSocket.cxx:695
 TPSocket.cxx:696
 TPSocket.cxx:697
 TPSocket.cxx:698
 TPSocket.cxx:699
 TPSocket.cxx:700
 TPSocket.cxx:701
 TPSocket.cxx:702
 TPSocket.cxx:703
 TPSocket.cxx:704
 TPSocket.cxx:705
 TPSocket.cxx:706
 TPSocket.cxx:707
 TPSocket.cxx:708
 TPSocket.cxx:709
 TPSocket.cxx:710
 TPSocket.cxx:711
 TPSocket.cxx:712
 TPSocket.cxx:713
 TPSocket.cxx:714
 TPSocket.cxx:715
 TPSocket.cxx:716
 TPSocket.cxx:717
 TPSocket.cxx:718
 TPSocket.cxx:719
 TPSocket.cxx:720
 TPSocket.cxx:721
 TPSocket.cxx:722
 TPSocket.cxx:723
 TPSocket.cxx:724
 TPSocket.cxx:725
 TPSocket.cxx:726
 TPSocket.cxx:727
 TPSocket.cxx:728
 TPSocket.cxx:729
 TPSocket.cxx:730
 TPSocket.cxx:731
 TPSocket.cxx:732
 TPSocket.cxx:733
 TPSocket.cxx:734
 TPSocket.cxx:735
 TPSocket.cxx:736
 TPSocket.cxx:737
 TPSocket.cxx:738
 TPSocket.cxx:739
 TPSocket.cxx:740
 TPSocket.cxx:741
 TPSocket.cxx:742
 TPSocket.cxx:743
 TPSocket.cxx:744
 TPSocket.cxx:745
 TPSocket.cxx:746
 TPSocket.cxx:747
 TPSocket.cxx:748
 TPSocket.cxx:749
 TPSocket.cxx:750
 TPSocket.cxx:751
 TPSocket.cxx:752
 TPSocket.cxx:753
 TPSocket.cxx:754
 TPSocket.cxx:755
 TPSocket.cxx:756
 TPSocket.cxx:757
 TPSocket.cxx:758
 TPSocket.cxx:759
 TPSocket.cxx:760
 TPSocket.cxx:761
 TPSocket.cxx:762
 TPSocket.cxx:763
 TPSocket.cxx:764
 TPSocket.cxx:765
 TPSocket.cxx:766
 TPSocket.cxx:767
 TPSocket.cxx:768
 TPSocket.cxx:769
 TPSocket.cxx:770
 TPSocket.cxx:771
 TPSocket.cxx:772
 TPSocket.cxx:773
 TPSocket.cxx:774
 TPSocket.cxx:775
 TPSocket.cxx:776
 TPSocket.cxx:777
 TPSocket.cxx:778
 TPSocket.cxx:779
 TPSocket.cxx:780
 TPSocket.cxx:781
 TPSocket.cxx:782
 TPSocket.cxx:783
 TPSocket.cxx:784
 TPSocket.cxx:785
 TPSocket.cxx:786
 TPSocket.cxx:787
 TPSocket.cxx:788