Logo ROOT   6.14/05
Reference Guide
TSocket.cxx
Go to the documentation of this file.
1 // @(#)root/net:$Id$
2 // Author: Fons Rademakers 18/12/96
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 //////////////////////////////////////////////////////////////////////////
13 // //
14 // TSocket //
15 // //
16 // This class implements client sockets. A socket is an endpoint for //
17 // communication between two machines. //
18 // The actual work is done via the TSystem class (either TUnixSystem //
19 // or TWinNTSystem). //
20 // //
21 //////////////////////////////////////////////////////////////////////////
22 
23 #include "Bytes.h"
24 #include "Compression.h"
25 #include "NetErrors.h"
26 #include "TEnv.h"
27 #include "TError.h"
28 #include "TMessage.h"
29 #include "TPSocket.h"
30 #include "TPluginManager.h"
31 #include "TROOT.h"
32 #include "TString.h"
33 #include "TSystem.h"
34 #include "TUrl.h"
35 #include "TVirtualAuth.h"
36 #include "TStreamerInfo.h"
37 #include "TProcessID.h"
38 
41 
42 //
43 // Client "protocol changes"
44 //
45 // This was in TNetFile and TAuthenticate before, but after the introduction
46 // of TSocket::CreateAuthSocket the common place for all the clients is TSocket,
47 // so this seems to be the right place for a version number
48 //
49 // 7: added support for ReOpen(), kROOTD_BYE and kROOTD_PROTOCOL2
50 // 8: added support for update being a create (open stat = 2 and not 1)
51 // 9: added new authentication features (see README.AUTH)
52 // 10: added support for authenticated socket via TSocket::CreateAuthSocket(...)
53 // 11: modified SSH protocol + support for server 'no authentication' mode
54 // 12: add random tags to avoid reply attacks (password+token)
55 // 13: authentication re-organization; cleanup in PROOF
56 // 14: support for SSH authentication via SSH tunnel
57 // 15: cope with fixes in TUrl::GetFile
58 // 16: add env setup message exchange
59 // 17: optmized Globus/GSI protocol exchange
60 //
61 Int_t TSocket::fgClientProtocol = 17; // increase when client protocol changes
62 
64 
66 
67 ////////////////////////////////////////////////////////////////////////////////
68 /// Create a socket. Connect to the named service at address addr.
69 /// Use tcpwindowsize to specify the size of the receive buffer, it has
70 /// to be specified here to make sure the window scale option is set (for
71 /// tcpwindowsize > 65KB and for platforms supporting window scaling).
72 /// Returns when connection has been accepted by remote side. Use IsValid()
73 /// to check the validity of the socket. Every socket is added to the TROOT
74 /// sockets list which will make sure that any open sockets are properly
75 /// closed on program termination.
76 
77 TSocket::TSocket(TInetAddress addr, const char *service, Int_t tcpwindowsize)
78  : TNamed(addr.GetHostName(), service)
79 {
82 
83  fService = service;
84  fSecContext = 0;
85  fRemoteProtocol= -1;
86  fServType = kSOCKD;
87  if (fService.Contains("root"))
88  fServType = kROOTD;
89  if (fService.Contains("proof"))
91  fAddress = addr;
93  fBytesSent = 0;
94  fBytesRecv = 0;
95  fCompress = 0;
96  fTcpWindowSize = tcpwindowsize;
97  fUUIDs = 0;
98  fLastUsageMtx = 0;
100 
101  if (fAddress.GetPort() != -1) {
103  tcpwindowsize);
104 
105  if (fSocket != kInvalid) {
106  gROOT->GetListOfSockets()->Add(this);
107  }
108  } else
109  fSocket = kInvalid;
110 
111 }
112 
113 ////////////////////////////////////////////////////////////////////////////////
114 /// Create a socket. Connect to the specified port # at address addr.
115 /// Use tcpwindowsize to specify the size of the receive buffer, it has
116 /// to be specified here to make sure the window scale option is set (for
117 /// tcpwindowsize > 65KB and for platforms supporting window scaling).
118 /// Returns when connection has been accepted by remote side. Use IsValid()
119 /// to check the validity of the socket. Every socket is added to the TROOT
120 /// sockets list which will make sure that any open sockets are properly
121 /// closed on program termination.
122 
123 TSocket::TSocket(TInetAddress addr, Int_t port, Int_t tcpwindowsize)
124  : TNamed(addr.GetHostName(), "")
125 {
126  R__ASSERT(gROOT);
128 
130  fSecContext = 0;
131  fRemoteProtocol= -1;
132  fServType = kSOCKD;
133  if (fService.Contains("root"))
134  fServType = kROOTD;
135  if (fService.Contains("proof"))
136  fServType = kPROOFD;
137  fAddress = addr;
138  fAddress.fPort = port;
140  fBytesSent = 0;
141  fBytesRecv = 0;
142  fCompress = 0;
143  fTcpWindowSize = tcpwindowsize;
144  fUUIDs = 0;
145  fLastUsageMtx = 0;
147 
149  tcpwindowsize);
150  if (fSocket == kInvalid)
151  fAddress.fPort = -1;
152  else {
153  gROOT->GetListOfSockets()->Add(this);
154  }
155 }
156 
157 ////////////////////////////////////////////////////////////////////////////////
158 /// Create a socket. Connect to named service on the remote host.
159 /// Use tcpwindowsize to specify the size of the receive buffer, it has
160 /// to be specified here to make sure the window scale option is set (for
161 /// tcpwindowsize > 65KB and for platforms supporting window scaling).
162 /// Returns when connection has been accepted by remote side. Use IsValid()
163 /// to check the validity of the socket. Every socket is added to the TROOT
164 /// sockets list which will make sure that any open sockets are properly
165 /// closed on program termination.
166 
167 TSocket::TSocket(const char *host, const char *service, Int_t tcpwindowsize)
168  : TNamed(host, service)
169 {
170  R__ASSERT(gROOT);
172 
173  fService = service;
174  fSecContext = 0;
175  fRemoteProtocol= -1;
176  fServType = kSOCKD;
177  if (fService.Contains("root"))
178  fServType = kROOTD;
179  if (fService.Contains("proof"))
180  fServType = kPROOFD;
181  fAddress = gSystem->GetHostByName(host);
184  fBytesSent = 0;
185  fBytesRecv = 0;
186  fCompress = 0;
187  fTcpWindowSize = tcpwindowsize;
188  fUUIDs = 0;
189  fLastUsageMtx = 0;
191 
192  if (fAddress.GetPort() != -1) {
193  fSocket = gSystem->OpenConnection(host, fAddress.GetPort(), tcpwindowsize);
194  if (fSocket != kInvalid) {
195  gROOT->GetListOfSockets()->Add(this);
196  }
197  } else
198  fSocket = kInvalid;
199 }
200 
201 ////////////////////////////////////////////////////////////////////////////////
202 /// Create a socket; see CreateAuthSocket for the form of url.
203 /// Connect to the specified port # on the remote host.
204 /// If user is specified in url, try authentication as user.
205 /// Use tcpwindowsize to specify the size of the receive buffer, it has
206 /// to be specified here to make sure the window scale option is set (for
207 /// tcpwindowsize > 65KB and for platforms supporting window scaling).
208 /// Returns when connection has been accepted by remote side. Use IsValid()
209 /// to check the validity of the socket. Every socket is added to the TROOT
210 /// sockets list which will make sure that any open sockets are properly
211 /// closed on program termination.
212 
213 TSocket::TSocket(const char *url, Int_t port, Int_t tcpwindowsize)
214  : TNamed(TUrl(url).GetHost(), "")
215 {
216  R__ASSERT(gROOT);
218 
219  fUrl = TString(url);
220  TString host(TUrl(fUrl).GetHost());
221 
223  fSecContext = 0;
224  fRemoteProtocol= -1;
225  fServType = kSOCKD;
226  if (fUrl.Contains("root"))
227  fServType = kROOTD;
228  if (fUrl.Contains("proof"))
229  fServType = kPROOFD;
230  fAddress = gSystem->GetHostByName(host);
231  fAddress.fPort = port;
234  fBytesSent = 0;
235  fBytesRecv = 0;
236  fCompress = 0;
237  fTcpWindowSize = tcpwindowsize;
238  fUUIDs = 0;
239  fLastUsageMtx = 0;
241 
242  fSocket = gSystem->OpenConnection(host, fAddress.GetPort(), tcpwindowsize);
243  if (fSocket == kInvalid) {
245  } else {
246  gROOT->GetListOfSockets()->Add(this);
247  }
248 }
249 
250 ////////////////////////////////////////////////////////////////////////////////
251 /// Create a socket in the Unix domain on 'sockpath'.
252 /// Returns when connection has been accepted by the server. Use IsValid()
253 /// to check the validity of the socket. Every socket is added to the TROOT
254 /// sockets list which will make sure that any open sockets are properly
255 /// closed on program termination.
256 
257 TSocket::TSocket(const char *sockpath) : TNamed(sockpath, "")
258 {
259  R__ASSERT(gROOT);
261 
262  fUrl = sockpath;
263 
264  fService = "unix";
265  fSecContext = 0;
266  fRemoteProtocol= -1;
267  fServType = kSOCKD;
268  fAddress.fPort = -1;
269  fName.Form("unix:%s", sockpath);
271  fBytesSent = 0;
272  fBytesRecv = 0;
273  fCompress = 0;
274  fTcpWindowSize = -1;
275  fUUIDs = 0;
276  fLastUsageMtx = 0;
278 
279  fSocket = gSystem->OpenConnection(sockpath, -1, -1);
280  if (fSocket > 0) {
281  gROOT->GetListOfSockets()->Add(this);
282  }
283 }
284 
285 ////////////////////////////////////////////////////////////////////////////////
286 /// Create a socket. The socket will adopt previously opened TCP socket with
287 /// descriptor desc.
288 
290 {
291  R__ASSERT(gROOT);
293 
294  fSecContext = 0;
295  fRemoteProtocol = 0;
296  fService = (char *)kSOCKD;
297  fServType = kSOCKD;
298  fBytesSent = 0;
299  fBytesRecv = 0;
300  fCompress = 0;
301  fTcpWindowSize = -1;
302  fUUIDs = 0;
303  fLastUsageMtx = 0;
305 
306  if (desc >= 0) {
307  fSocket = desc;
309  gROOT->GetListOfSockets()->Add(this);
310  } else
311  fSocket = kInvalid;
312 }
313 
314 ////////////////////////////////////////////////////////////////////////////////
315 /// Create a socket. The socket will adopt previously opened Unix socket with
316 /// descriptor desc. The sockpath arg is for info purposes only. Use
317 /// this method to adopt e.g. a socket created via socketpair().
318 
319 TSocket::TSocket(Int_t desc, const char *sockpath) : TNamed(sockpath, "")
320 {
321  R__ASSERT(gROOT);
323 
324  fUrl = sockpath;
325 
326  fService = "unix";
327  fSecContext = 0;
328  fRemoteProtocol= -1;
329  fServType = kSOCKD;
330  fAddress.fPort = -1;
331  fName.Form("unix:%s", sockpath);
333  fBytesSent = 0;
334  fBytesRecv = 0;
335  fCompress = 0;
336  fTcpWindowSize = -1;
337  fUUIDs = 0;
338  fLastUsageMtx = 0;
340 
341  if (desc >= 0) {
342  fSocket = desc;
343  gROOT->GetListOfSockets()->Add(this);
344  } else
345  fSocket = kInvalid;
346 }
347 
348 
349 ////////////////////////////////////////////////////////////////////////////////
350 /// TSocket copy ctor.
351 
353 {
354  fSocket = s.fSocket;
355  fService = s.fService;
356  fAddress = s.fAddress;
360  fCompress = s.fCompress;
363  fServType = s.fServType;
365  fUUIDs = 0;
366  fLastUsageMtx = 0;
368 
369  if (fSocket != kInvalid) {
370  gROOT->GetListOfSockets()->Add(this);
371  }
372 }
373 ////////////////////////////////////////////////////////////////////////////////
374 /// Close the socket and mark as due to a broken connection.
375 
377 {
379  if (IsValid()) {
382  }
383 
386 }
387 
388 ////////////////////////////////////////////////////////////////////////////////
389 /// Close the socket. If option is "force", calls shutdown(id,2) to
390 /// shut down the connection. This will close the connection also
391 /// for the parent of this process. Also called via the dtor (without
392 /// option "force", call explicitly Close("force") if this is desired).
393 
395 {
396  Bool_t force = option ? (!strcmp(option, "force") ? kTRUE : kFALSE) : kFALSE;
397 
398  if (fSocket != kInvalid) {
399  if (IsValid()) { // Filter out kInvalidStillInList case (disconnected but not removed from list)
401  }
402  gROOT->GetListOfSockets()->Remove(this);
403  }
404  fSocket = kInvalid;
405 
408 }
409 
410 ////////////////////////////////////////////////////////////////////////////////
411 /// Return internet address of local host to which the socket is bound.
412 /// In case of error TInetAddress::IsValid() returns kFALSE.
413 
415 {
416  if (IsValid()) {
417  if (fLocalAddress.GetPort() == -1)
419  return fLocalAddress;
420  }
421  return TInetAddress();
422 }
423 
424 ////////////////////////////////////////////////////////////////////////////////
425 /// Return the local port # to which the socket is bound.
426 /// In case of error return -1.
427 
429 {
430  if (IsValid()) {
431  if (fLocalAddress.GetPort() == -1)
433  return fLocalAddress.GetPort();
434  }
435  return -1;
436 }
437 
438 ////////////////////////////////////////////////////////////////////////////////
439 /// Waits for this socket to change status. If interest=kRead,
440 /// the socket will be watched to see if characters become available for
441 /// reading; if interest=kWrite the socket will be watched to
442 /// see if a write will not block.
443 /// The argument 'timeout' specifies a maximum time to wait in millisec.
444 /// Default no timeout.
445 /// Returns 1 if a change of status of interest has been detected within
446 /// timeout; 0 in case of timeout; < 0 if an error occured.
447 
448 Int_t TSocket::Select(Int_t interest, Long_t timeout)
449 {
450  Int_t rc = 1;
451 
452  // Associate a TFileHandler to this socket
453  TFileHandler fh(fSocket, interest);
454 
455  // Wait for an event now
456  rc = gSystem->Select(&fh, timeout);
457 
458  return rc;
459 }
460 
461 ////////////////////////////////////////////////////////////////////////////////
462 /// Send a single message opcode. Use kind (opcode) to set the
463 /// TMessage "what" field. Returns the number of bytes that were sent
464 /// (always sizeof(Int_t)) and -1 in case of error. In case the kind has
465 /// been or'ed with kMESS_ACK, the call will only return after having
466 /// received an acknowledgement, making the sending process synchronous.
467 
469 {
470  TMessage mess(kind);
471 
472  Int_t nsent;
473  if ((nsent = Send(mess)) < 0)
474  return -1;
475 
476  return nsent;
477 }
478 
479 ////////////////////////////////////////////////////////////////////////////////
480 /// Send a status and a single message opcode. Use kind (opcode) to set the
481 /// TMessage "what" field. Returns the number of bytes that were sent
482 /// (always 2*sizeof(Int_t)) and -1 in case of error. In case the kind has
483 /// been or'ed with kMESS_ACK, the call will only return after having
484 /// received an acknowledgement, making the sending process synchronous.
485 
487 {
488  TMessage mess(kind);
489  mess << status;
490 
491  Int_t nsent;
492  if ((nsent = Send(mess)) < 0)
493  return -1;
494 
495  return nsent;
496 }
497 
498 ////////////////////////////////////////////////////////////////////////////////
499 /// Send a character string buffer. Use kind to set the TMessage "what" field.
500 /// Returns the number of bytes in the string str that were sent and -1 in
501 /// case of error. In case the kind has been or'ed with kMESS_ACK, the call
502 /// will only return after having received an acknowledgement, making the
503 /// sending process synchronous.
504 
505 Int_t TSocket::Send(const char *str, Int_t kind)
506 {
507  TMessage mess(kind);
508  if (str) mess.WriteString(str);
509 
510  Int_t nsent;
511  if ((nsent = Send(mess)) < 0)
512  return -1;
513 
514  return nsent - sizeof(Int_t); // - TMessage::What()
515 }
516 
517 ////////////////////////////////////////////////////////////////////////////////
518 /// Send a TMessage object. Returns the number of bytes in the TMessage
519 /// that were sent and -1 in case of error. In case the TMessage::What
520 /// has been or'ed with kMESS_ACK, the call will only return after having
521 /// received an acknowledgement, making the sending process synchronous.
522 /// Returns -4 in case of kNoBlock and errno == EWOULDBLOCK.
523 /// Returns -5 if pipe broken or reset by peer (EPIPE || ECONNRESET).
524 /// support for streaming TStreamerInfo added by Rene Brun May 2008
525 /// support for streaming TProcessID added by Rene Brun June 2008
526 
528 {
530 
531  if (!IsValid()) return -1;
532 
533  if (mess.IsReading()) {
534  Error("Send", "cannot send a message used for reading");
535  return -1;
536  }
537 
538  // send streamer infos in case schema evolution is enabled in the TMessage
539  SendStreamerInfos(mess);
540 
541  // send the process id's so TRefs work
542  SendProcessIDs(mess);
543 
544  mess.SetLength(); //write length in first word of buffer
545 
546  if (GetCompressionLevel() > 0 && mess.GetCompressionLevel() == 0)
547  const_cast<TMessage&>(mess).SetCompressionSettings(fCompress);
548 
549  if (mess.GetCompressionLevel() > 0)
550  const_cast<TMessage&>(mess).Compress();
551 
552  char *mbuf = mess.Buffer();
553  Int_t mlen = mess.Length();
554  if (mess.CompBuffer()) {
555  mbuf = mess.CompBuffer();
556  mlen = mess.CompLength();
557  }
558 
560  Int_t nsent;
561  if ((nsent = gSystem->SendRaw(fSocket, mbuf, mlen, 0)) <= 0) {
562  if (nsent == -5) {
563  // Connection reset by peer or broken
565  }
566  return nsent;
567  }
568 
569  fBytesSent += nsent;
570  fgBytesSent += nsent;
571 
572  // If acknowledgement is desired, wait for it
573  if (mess.What() & kMESS_ACK) {
576  char buf[2];
577  Int_t n = 0;
578  if ((n = gSystem->RecvRaw(fSocket, buf, sizeof(buf), 0)) < 0) {
579  if (n == -5) {
580  // Connection reset by peer or broken
582  } else
583  n = -1;
584  return n;
585  }
586  if (strncmp(buf, "ok", 2)) {
587  Error("Send", "bad acknowledgement");
588  return -1;
589  }
590  fBytesRecv += 2;
591  fgBytesRecv += 2;
592  }
593 
594  Touch(); // update usage timestamp
595 
596  return nsent - sizeof(UInt_t); //length - length header
597 }
598 
599 ////////////////////////////////////////////////////////////////////////////////
600 /// Send an object. Returns the number of bytes sent and -1 in case of error.
601 /// In case the "kind" has been or'ed with kMESS_ACK, the call will only
602 /// return after having received an acknowledgement, making the sending
603 /// synchronous.
604 
606 {
607  //stream object to message buffer
608  TMessage mess(kind);
609  mess.WriteObject(obj);
610 
611  //now sending the object itself
612  Int_t nsent;
613  if ((nsent = Send(mess)) < 0)
614  return -1;
615 
616  return nsent;
617 }
618 
619 ////////////////////////////////////////////////////////////////////////////////
620 /// Send a raw buffer of specified length. Using option kOob one can send
621 /// OOB data. Returns the number of bytes sent or -1 in case of error.
622 /// Returns -4 in case of kNoBlock and errno == EWOULDBLOCK.
623 /// Returns -5 if pipe broken or reset by peer (EPIPE || ECONNRESET).
624 
625 Int_t TSocket::SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt)
626 {
628 
629  if (!IsValid()) return -1;
630 
632  Int_t nsent;
633  if ((nsent = gSystem->SendRaw(fSocket, buffer, length, (int) opt)) <= 0) {
634  if (nsent == -5) {
635  // Connection reset or broken: close
637  }
638  return nsent;
639  }
640 
641  fBytesSent += nsent;
642  fgBytesSent += nsent;
643 
644  Touch(); // update usage timestamp
645 
646  return nsent;
647 }
648 
649 ////////////////////////////////////////////////////////////////////////////////
650 /// Check if TStreamerInfo must be sent. The list of TStreamerInfo of classes
651 /// in the object in the message is in the fInfos list of the message.
652 /// We send only the TStreamerInfos not yet sent on this socket.
653 
655 {
656  if (mess.fInfos && mess.fInfos->GetEntries()) {
657  TIter next(mess.fInfos);
658  TStreamerInfo *info;
659  TList *minilist = 0;
660  while ((info = (TStreamerInfo*)next())) {
661  Int_t uid = info->GetNumber();
662  if (fBitsInfo.TestBitNumber(uid))
663  continue; //TStreamerInfo had already been sent
664  fBitsInfo.SetBitNumber(uid);
665  if (!minilist)
666  minilist = new TList();
667  if (gDebug > 0)
668  Info("SendStreamerInfos", "sending TStreamerInfo: %s, version = %d",
669  info->GetName(),info->GetClassVersion());
670  minilist->Add(info);
671  }
672  if (minilist) {
673  TMessage messinfo(kMESS_STREAMERINFO);
674  messinfo.WriteObject(minilist);
675  delete minilist;
676  if (messinfo.fInfos)
677  messinfo.fInfos->Clear();
678  if (Send(messinfo) < 0)
679  Warning("SendStreamerInfos", "problems sending TStreamerInfo's ...");
680  }
681  }
682 }
683 
684 ////////////////////////////////////////////////////////////////////////////////
685 /// Check if TProcessIDs must be sent. The list of TProcessIDs
686 /// in the object in the message is found by looking in the TMessage bits.
687 /// We send only the TProcessIDs not yet send on this socket.
688 
690 {
691  if (mess.TestBitNumber(0)) {
692  TObjArray *pids = TProcessID::GetPIDs();
693  Int_t npids = pids->GetEntries();
694  TProcessID *pid;
695  TList *minilist = 0;
696  for (Int_t ipid = 0; ipid < npids; ipid++) {
697  pid = (TProcessID*)pids->At(ipid);
698  if (!pid || !mess.TestBitNumber(pid->GetUniqueID()+1))
699  continue;
700  //check if a pid with this title has already been sent through the socket
701  //if not add it to the fUUIDs list
702  if (!fUUIDs) {
703  fUUIDs = new TList();
704  } else {
705  if (fUUIDs->FindObject(pid->GetTitle()))
706  continue;
707  }
708  fUUIDs->Add(new TObjString(pid->GetTitle()));
709  if (!minilist)
710  minilist = new TList();
711  if (gDebug > 0)
712  Info("SendProcessIDs", "sending TProcessID: %s", pid->GetTitle());
713  minilist->Add(pid);
714  }
715  if (minilist) {
716  TMessage messpid(kMESS_PROCESSID);
717  messpid.WriteObject(minilist);
718  delete minilist;
719  if (Send(messpid) < 0)
720  Warning("SendProcessIDs", "problems sending TProcessID's ...");
721  }
722  }
723 }
724 
725 ////////////////////////////////////////////////////////////////////////////////
726 /// Receive a character string message of maximum max length. The expected
727 /// message must be of type kMESS_STRING. Returns length of received string
728 /// (can be 0 if otherside of connection is closed) or -1 in case of error
729 /// or -4 in case a non-blocking socket would block (i.e. there is nothing
730 /// to be read).
731 
732 Int_t TSocket::Recv(char *str, Int_t max)
733 {
734  Int_t n, kind;
735 
737  if ((n = Recv(str, max, kind)) <= 0) {
738  if (n == -5) {
740  n = -1;
741  }
742  return n;
743  }
744 
745  if (kind != kMESS_STRING) {
746  Error("Recv", "got message of wrong kind (expected %d, got %d)",
747  kMESS_STRING, kind);
748  return -1;
749  }
750 
751  return n;
752 }
753 
754 ////////////////////////////////////////////////////////////////////////////////
755 /// Receive a character string message of maximum max length. Returns in
756 /// kind the message type. Returns length of received string+4 (can be 0 if
757 /// other side of connection is closed) or -1 in case of error or -4 in
758 /// case a non-blocking socket would block (i.e. there is nothing to be read).
759 
760 Int_t TSocket::Recv(char *str, Int_t max, Int_t &kind)
761 {
762  Int_t n;
763  TMessage *mess;
764 
766  if ((n = Recv(mess)) <= 0) {
767  if (n == -5) {
769  n = -1;
770  }
771  return n;
772  }
773 
774  kind = mess->What();
775  if (str) {
776  if (mess->BufferSize() > (Int_t)sizeof(Int_t)) // if mess contains more than kind
777  mess->ReadString(str, max);
778  else
779  str[0] = 0;
780  }
781 
782  delete mess;
783 
784  return n; // number of bytes read (len of str + sizeof(kind)
785 }
786 
787 ////////////////////////////////////////////////////////////////////////////////
788 /// Receives a status and a message type. Returns length of received
789 /// integers, 2*sizeof(Int_t) (can be 0 if other side of connection
790 /// is closed) or -1 in case of error or -4 in case a non-blocking
791 /// socket would block (i.e. there is nothing to be read).
792 
794 {
795  Int_t n;
796  TMessage *mess;
797 
799  if ((n = Recv(mess)) <= 0) {
800  if (n == -5) {
802  n = -1;
803  }
804  return n;
805  }
806 
807  kind = mess->What();
808  (*mess) >> status;
809 
810  delete mess;
811 
812  return n; // number of bytes read (2 * sizeof(Int_t)
813 }
814 
815 ////////////////////////////////////////////////////////////////////////////////
816 /// Receive a TMessage object. The user must delete the TMessage object.
817 /// Returns length of message in bytes (can be 0 if other side of connection
818 /// is closed) or -1 in case of error or -4 in case a non-blocking socket
819 /// would block (i.e. there is nothing to be read) or -5 if pipe broken
820 /// or reset by peer (EPIPE || ECONNRESET). In those case mess == 0.
821 
823 {
825 
826  if (!IsValid()) {
827  mess = 0;
828  return -1;
829  }
830 
831 oncemore:
833  Int_t n;
834  UInt_t len;
835  if ((n = gSystem->RecvRaw(fSocket, &len, sizeof(UInt_t), 0)) <= 0) {
836  if (n == 0 || n == -5) {
837  // Connection closed, reset or broken
839  }
840  mess = 0;
841  return n;
842  }
843  len = net2host(len); //from network to host byte order
844 
846  char *buf = new char[len+sizeof(UInt_t)];
847  if ((n = gSystem->RecvRaw(fSocket, buf+sizeof(UInt_t), len, 0)) <= 0) {
848  if (n == 0 || n == -5) {
849  // Connection closed, reset or broken
851  }
852  delete [] buf;
853  mess = 0;
854  return n;
855  }
856 
857  fBytesRecv += n + sizeof(UInt_t);
858  fgBytesRecv += n + sizeof(UInt_t);
859 
860  mess = new TMessage(buf, len+sizeof(UInt_t));
861 
862  // receive any streamer infos
863  if (RecvStreamerInfos(mess))
864  goto oncemore;
865 
866  // receive any process ids
867  if (RecvProcessIDs(mess))
868  goto oncemore;
869 
870  if (mess->What() & kMESS_ACK) {
872  char ok[2] = { 'o', 'k' };
873  Int_t n2 = 0;
874  if ((n2 = gSystem->SendRaw(fSocket, ok, sizeof(ok), 0)) < 0) {
875  if (n2 == -5) {
876  // Connection reset or broken
878  }
879  delete mess;
880  mess = 0;
881  return n2;
882  }
883  mess->SetWhat(mess->What() & ~kMESS_ACK);
884 
885  fBytesSent += 2;
886  fgBytesSent += 2;
887  }
888 
889  Touch(); // update usage timestamp
890 
891  return n;
892 }
893 
894 ////////////////////////////////////////////////////////////////////////////////
895 /// Receive a raw buffer of specified length bytes. Using option kPeek
896 /// one can peek at incoming data. Returns number of received bytes.
897 /// Returns -1 in case of error. In case of opt == kOob: -2 means
898 /// EWOULDBLOCK and -3 EINVAL. In case of non-blocking mode (kNoBlock)
899 /// -4 means EWOULDBLOCK. Returns -5 if pipe broken or reset by
900 /// peer (EPIPE || ECONNRESET).
901 
902 Int_t TSocket::RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt)
903 {
905 
906  if (!IsValid()) return -1;
907  if (length == 0) return 0;
908 
910  Int_t n;
911  if ((n = gSystem->RecvRaw(fSocket, buffer, length, (int) opt)) <= 0) {
912  if (n == 0 || n == -5) {
913  // Connection closed, reset or broken
915  }
916  return n;
917  }
918 
919  fBytesRecv += n;
920  fgBytesRecv += n;
921 
922  Touch(); // update usage timestamp
923 
924  return n;
925 }
926 
927 ////////////////////////////////////////////////////////////////////////////////
928 /// Receive a message containing streamer infos. In case the message contains
929 /// streamer infos they are imported, the message will be deleted and the
930 /// method returns kTRUE.
931 
933 {
934  if (mess->What() == kMESS_STREAMERINFO) {
935  TList *list = (TList*)mess->ReadObject(TList::Class());
936  TIter next(list);
937  TStreamerInfo *info;
938  TObjLink *lnk = list->FirstLink();
939  // First call BuildCheck for regular class
940  while (lnk) {
941  info = (TStreamerInfo*)lnk->GetObject();
942  TObject *element = info->GetElements()->UncheckedAt(0);
943  Bool_t isstl = element && strcmp("This",element->GetName())==0;
944  if (!isstl) {
945  info->BuildCheck();
946  if (gDebug > 0)
947  Info("RecvStreamerInfos", "importing TStreamerInfo: %s, version = %d",
948  info->GetName(), info->GetClassVersion());
949  }
950  lnk = lnk->Next();
951  }
952  // Then call BuildCheck for stl class
953  lnk = list->FirstLink();
954  while (lnk) {
955  info = (TStreamerInfo*)lnk->GetObject();
956  TObject *element = info->GetElements()->UncheckedAt(0);
957  Bool_t isstl = element && strcmp("This",element->GetName())==0;
958  if (isstl) {
959  info->BuildCheck();
960  if (gDebug > 0)
961  Info("RecvStreamerInfos", "importing TStreamerInfo: %s, version = %d",
962  info->GetName(), info->GetClassVersion());
963  }
964  lnk = lnk->Next();
965  }
966  delete list;
967  delete mess;
968 
969  return kTRUE;
970  }
971  return kFALSE;
972 }
973 
974 ////////////////////////////////////////////////////////////////////////////////
975 /// Receive a message containing process ids. In case the message contains
976 /// process ids they are imported, the message will be deleted and the
977 /// method returns kTRUE.
978 
980 {
981  if (mess->What() == kMESS_PROCESSID) {
982  TList *list = (TList*)mess->ReadObject(TList::Class());
983  TIter next(list);
984  TProcessID *pid;
985  while ((pid = (TProcessID*)next())) {
986  // check that a similar pid is not already registered in fgPIDs
987  TObjArray *pidslist = TProcessID::GetPIDs();
988  TIter nextpid(pidslist);
989  TProcessID *p;
990  while ((p = (TProcessID*)nextpid())) {
991  if (!strcmp(p->GetTitle(), pid->GetTitle())) {
992  delete pid;
993  pid = 0;
994  break;
995  }
996  }
997  if (pid) {
998  if (gDebug > 0)
999  Info("RecvProcessIDs", "importing TProcessID: %s", pid->GetTitle());
1000  pid->IncrementCount();
1001  pidslist->Add(pid);
1002  Int_t ind = pidslist->IndexOf(pid);
1003  pid->SetUniqueID((UInt_t)ind);
1004  }
1005  }
1006  delete list;
1007  delete mess;
1008 
1009  return kTRUE;
1010  }
1011  return kFALSE;
1012 }
1013 
1014 ////////////////////////////////////////////////////////////////////////////////
1015 /// Set socket options.
1016 
1018 {
1019  if (!IsValid()) return -1;
1020 
1021  return gSystem->SetSockOpt(fSocket, opt, val);
1022 }
1023 
1024 ////////////////////////////////////////////////////////////////////////////////
1025 /// Get socket options. Returns -1 in case of error.
1026 
1028 {
1029  if (!IsValid()) return -1;
1030 
1031  return gSystem->GetSockOpt(fSocket, opt, &val);
1032 }
1033 
1034 ////////////////////////////////////////////////////////////////////////////////
1035 /// Returns error code. Meaning depends on context where it is called.
1036 /// If no error condition returns 0 else a value < 0.
1037 /// For example see TServerSocket ctor.
1038 
1040 {
1041  if (!IsValid())
1042  return fSocket;
1043 
1044  return 0;
1045 }
1046 
1047 ////////////////////////////////////////////////////////////////////////////////
1048 /// See comments for function SetCompressionSettings
1049 
1051 {
1052  if (algorithm < 0 || algorithm >= ROOT::kUndefinedCompressionAlgorithm) algorithm = 0;
1053  if (fCompress < 0) {
1054  // if the level is not defined yet use 1 as a default
1055  fCompress = 100 * algorithm + 1;
1056  } else {
1057  int level = fCompress % 100;
1058  fCompress = 100 * algorithm + level;
1059  }
1060 }
1061 
1062 ////////////////////////////////////////////////////////////////////////////////
1063 /// See comments for function SetCompressionSettings
1064 
1066 {
1067  if (level < 0) level = 0;
1068  if (level > 99) level = 99;
1069  if (fCompress < 0) {
1070  // if the algorithm is not defined yet use 0 as a default
1071  fCompress = level;
1072  } else {
1073  int algorithm = fCompress / 100;
1074  if (algorithm >= ROOT::kUndefinedCompressionAlgorithm) algorithm = 0;
1075  fCompress = 100 * algorithm + level;
1076  }
1077 }
1078 
1079 ////////////////////////////////////////////////////////////////////////////////
1080 /// Used to specify the compression level and algorithm:
1081 /// settings = 100 * algorithm + level
1082 ///
1083 /// level = 0, objects written to this file will not be compressed.
1084 /// level = 1, minimal compression level but fast.
1085 /// ....
1086 /// level = 9, maximal compression level but slower and might use more memory.
1087 /// (For the currently supported algorithms, the maximum level is 9)
1088 /// If compress is negative it indicates the compression level is not set yet.
1089 ///
1090 /// The enumeration ROOT::ECompressionAlgorithm associates each
1091 /// algorithm with a number. There is a utility function to help
1092 /// to set the value of the argument. For example,
1093 /// ROOT::CompressionSettings(ROOT::kLZMA, 1)
1094 /// will build an integer which will set the compression to use
1095 /// the LZMA algorithm and compression level 1. These are defined
1096 /// in the header file Compression.h.
1097 ///
1098 /// Note that the compression settings may be changed at any time.
1099 /// The new compression settings will only apply to branches created
1100 /// or attached after the setting is changed and other objects written
1101 /// after the setting is changed.
1102 
1104 {
1105  fCompress = settings;
1106 }
1107 
1108 ////////////////////////////////////////////////////////////////////////////////
1109 /// Authenticated the socket with specified user.
1110 
1112 {
1113  Bool_t rc = kFALSE;
1114 
1115  // Parse protocol name, for PROOF, send message with server role
1116  TString sproto = TUrl(fUrl).GetProtocol();
1117  if (sproto.Contains("sockd")) {
1118  fServType = kSOCKD;
1119  } else if (sproto.Contains("rootd")) {
1120  fServType = kROOTD;
1121  } else if (sproto.Contains("proofd")) {
1122  fServType = kPROOFD;
1123  // Parse options
1124  TString opt(TUrl(fUrl).GetOptions());
1125  //First letter in Opt describes type of proofserv to invoke
1126  if (!strncasecmp(opt, "S", 1)) {
1127  if (Send("slave") < 0) return rc;
1128  } else if (!strncasecmp(opt, "M", 1)) {
1129  if (Send("master") < 0) return rc;
1130  } else {
1131  Warning("Authenticate",
1132  "called by TSlave: unknown option '%c' %s",
1133  opt[0], " - assuming Slave");
1134  if (Send("slave") < 0) return rc;
1135  }
1136  }
1137  if (gDebug > 2)
1138  Info("Authenticate","Local protocol: %s",sproto.Data());
1139 
1140  // Get server protocol level
1141  Int_t kind = kROOTD_PROTOCOL;
1142  // Warning: for backward compatibility reasons here we have to
1143  // send exactly 4 bytes: for fgClientClientProtocol > 99
1144  // the space in the format must be dropped
1145  if (fRemoteProtocol == -1) {
1146  if (Send(Form(" %d", fgClientProtocol), kROOTD_PROTOCOL) < 0) {
1147  return rc;
1148  }
1149  if (Recv(fRemoteProtocol, kind) < 0) {
1150  return rc;
1151  }
1152  //
1153  // If we are talking to an old rootd server we get a fatal
1154  // error here and we need to reopen the connection,
1155  // communicating first the size of the parallel socket
1156  if (kind == kROOTD_ERR) {
1157  fRemoteProtocol = 9;
1158  return kFALSE;
1159  }
1160  }
1161 
1162  // Find out whether authentication is required
1163  Bool_t runauth = kTRUE;
1164  if (fRemoteProtocol > 1000) {
1165  // Authentication not required by the remote server
1166  runauth = kFALSE;
1167  fRemoteProtocol %= 1000;
1168  }
1169 
1170  // If authentication is required, we need to find out which library
1171  // has to be loaded (preparation for near future, 9/7/05)
1172  TString host = GetInetAddress().GetHostName();
1173  if (runauth) {
1174 
1175  // Default (future)
1176  TString alib = "Xrd";
1177  if (fRemoteProtocol < 100) {
1178  // Standard Authentication lib
1179  alib = "Root";
1180  }
1181 
1182  // Load the plugin
1183  TPluginHandler *h =
1184  gROOT->GetPluginManager()->FindHandler("TVirtualAuth", alib);
1185  if (!h || h->LoadPlugin() != 0) {
1186  Error("Authenticate",
1187  "could not load properly %s authentication plugin", alib.Data());
1188  return rc;
1189  }
1190 
1191  // Get an instance of the interface class
1192  TVirtualAuth *auth = (TVirtualAuth *)(h->ExecPlugin(0));
1193  if (!auth) {
1194  Error("Authenticate", "could not instantiate the interface class");
1195  return rc;
1196  }
1197  if (gDebug > 1)
1198  Info("Authenticate", "class for '%s' authentication loaded", alib.Data());
1199 
1200  Option_t *opts = (gROOT->IsProofServ()) ? "P" : "";
1201  if (!(auth->Authenticate(this, host, user, opts))) {
1202  Error("Authenticate",
1203  "authentication attempt failed for %s@%s", user, host.Data());
1204  } else {
1205  rc = kTRUE;
1206  }
1207  } else {
1208 
1209  // Communicate who we are and our target user
1211  if (u) {
1212  if (Send(Form("%s %s", u->fUser.Data(), user), kROOTD_USER) < 0)
1213  Warning("Authenticate", "problem sending kROOTD_USER (%s,%s)", u->fUser.Data(), user);
1214  delete u;
1215  } else
1216  if (Send(Form("-1 %s", user), kROOTD_USER) < 0)
1217  Warning("Authenticate", "problem sending kROOTD_USER (-1,%s)", user);
1218 
1219  rc = kFALSE;
1220 
1221  // Receive confirmation that everything went well
1222  Int_t stat;
1223  if (Recv(stat, kind) > 0) {
1224 
1225  if (kind == kROOTD_ERR) {
1226  if (gDebug > 0)
1227  TSocket::NetError("TSocket::Authenticate", stat);
1228  } else if (kind == kROOTD_AUTH) {
1229 
1230  // Authentication was not required: create inactive
1231  // security context for consistency
1232  fSecContext = new TSecContext(user, host, 0, -4, 0, 0);
1233  if (gDebug > 3)
1234  Info("Authenticate", "no authentication required remotely");
1235 
1236  // Set return flag;
1237  rc = 1;
1238  } else {
1239  if (gDebug > 0)
1240  Info("Authenticate", "expected message type %d, received %d",
1241  kROOTD_AUTH, kind);
1242  }
1243  } else {
1244  if (gDebug > 0)
1245  Info("Authenticate", "error receiving message");
1246  }
1247 
1248  }
1249 
1250  return rc;
1251 }
1252 
1253 ////////////////////////////////////////////////////////////////////////////////
1254 /// Creates a socket or a parallel socket and authenticates to the
1255 /// remote server.
1256 ///
1257 /// url: [[proto][p][auth]://][user@]host[:port][/service][?options]
1258 ///
1259 /// where proto = "sockd", "rootd", "proofd"
1260 /// indicates the type of remote server;
1261 /// if missing "sockd" is assumed ("sockd" indicates
1262 /// any remote server session using TServerSocket)
1263 /// [p] = for parallel sockets (forced internally for
1264 /// rootd; ignored for proofd)
1265 /// [auth] = "up", "s", "k", "g", "h", "ug" to force UsrPwd,
1266 /// SRP, Krb5, Globus, SSH or UidGid authentication
1267 /// [port] = is the remote port number
1268 /// [service] = service name used to determine the port
1269 /// (for backward compatibility, specification of
1270 /// port as priority)
1271 /// options = "m" or "s", when proto=proofd indicates whether
1272 /// we are master or slave (used internally by
1273 /// TSlave)
1274 ///
1275 /// An already opened connection can be used by passing its socket
1276 /// in opensock.
1277 ///
1278 /// If 'err' is defined, '*err' on return from a failed call contains an error
1279 /// code (see NetErrors.h).
1280 ///
1281 /// Example:
1282 ///
1283 /// TSocket::CreateAuthSocket("rootds://qwerty@machine.fq.dn:5051")
1284 ///
1285 /// creates an authenticated socket to a rootd server running
1286 /// on remote machine machine.fq.dn on port 5051; "parallel" sockets
1287 /// are forced internally because rootd expects
1288 /// parallel sockets; however a simple socket will be created
1289 /// in this case because the size is 0 (the default);
1290 /// authentication will attempt protocol SRP first.
1291 ///
1292 /// TSocket::CreateAuthSocket("pk://qwerty@machine.fq.dn:5052",3)
1293 ///
1294 /// creates an authenticated parallel socket of size 3 to a sockd
1295 /// server running on remote machine machine.fq.dn on port 5052;
1296 /// authentication will attempt protocol Kerberos first.
1297 ///
1298 /// NB: may hang if the remote server is not of the correct type;
1299 /// at present TSocket has no way to find out the type of the
1300 /// remote server automatically
1301 ///
1302 /// Returns pointer to an authenticated socket or 0 if creation or
1303 /// authentication is unsuccessful.
1304 
1305 TSocket *TSocket::CreateAuthSocket(const char *url, Int_t size, Int_t tcpwindowsize,
1306  TSocket *opensock, Int_t *err)
1307 {
1308  R__LOCKGUARD2(gSocketAuthMutex);
1309 
1310  // Url to be passed to chosen constructor
1311  TString eurl(url);
1312 
1313  // Parse protocol, if any
1314  Bool_t parallel = kFALSE;
1315  TString proto(TUrl(url).GetProtocol());
1316  TString protosave = proto;
1317 
1318  // Get rid of authentication suffix
1319  TString asfx = "";
1320  if (proto.EndsWith("up") || proto.EndsWith("ug")) {
1321  asfx = proto;
1322  asfx.Remove(0,proto.Length()-2);
1323  proto.Resize(proto.Length()-2);
1324  } else if (proto.EndsWith("s") || proto.EndsWith("k") ||
1325  proto.EndsWith("g") || proto.EndsWith("h")) {
1326  asfx = proto;
1327  asfx.Remove(0,proto.Length()-1);
1328  proto.Resize(proto.Length()-1);
1329  }
1330 
1331  // Find out if parallel (ignore if proofd, force if rootd)
1332  if (((proto.EndsWith("p") || size > 1) &&
1333  !proto.BeginsWith("proof")) ||
1334  proto.BeginsWith("root") ) {
1335  parallel = kTRUE;
1336  if (proto.EndsWith("p"))
1337  proto.Resize(proto.Length()-1);
1338  }
1339 
1340  // Force "sockd" if the rest is not recognized
1341  if (!proto.BeginsWith("sock") && !proto.BeginsWith("proof") &&
1342  !proto.BeginsWith("root"))
1343  proto = "sockd";
1344 
1345  // Substitute this for original proto in eurl
1346  protosave += "://";
1347  proto += asfx;
1348  proto += "://";
1349  eurl.ReplaceAll(protosave,proto);
1350 
1351  // Create the socket now
1352 
1353  TSocket *sock = 0;
1354  if (!parallel) {
1355 
1356  // Simple socket
1357  if (opensock && opensock->IsValid())
1358  sock = opensock;
1359  else
1360  sock = new TSocket(eurl, TUrl(url).GetPort(), tcpwindowsize);
1361 
1362  // Authenticate now
1363  if (sock && sock->IsValid()) {
1364  if (!sock->Authenticate(TUrl(url).GetUser())) {
1365  // Nothing to do except setting the error code (if required) and sock to NULL
1366  if (err) {
1367  *err = (Int_t)kErrAuthNotOK;
1369  }
1370  sock->Close();
1371  delete sock;
1372  sock = 0;
1373  }
1374  }
1375 
1376  } else {
1377 
1378  // Tell TPSocket that we want authentication, which has to
1379  // be done using the original socket before creation of set
1380  // of parallel sockets
1381  if (eurl.Contains("?"))
1382  eurl.Resize(eurl.Index("?"));
1383  eurl += "?A";
1384 
1385  // Parallel socket
1386  if (opensock && opensock->IsValid())
1387  sock = new TPSocket(eurl, TUrl(url).GetPort(), size, opensock);
1388  else
1389  sock = new TPSocket(eurl, TUrl(url).GetPort(), size, tcpwindowsize);
1390 
1391  // Cleanup if failure ...
1392  if (sock && !sock->IsAuthenticated()) {
1393  // Nothing to do except setting the error code (if required) and sock to NULL
1394  if (err) {
1395  *err = (Int_t)kErrAuthNotOK;
1397  }
1398  if (sock->IsValid())
1399  // And except when the sock is valid; this typically
1400  // happens when talking to a old server, because the
1401  // the parallel socket system is open before authentication
1402  delete sock;
1403  sock = 0;
1404  }
1405  }
1406 
1407  return sock;
1408 }
1409 
1410 ////////////////////////////////////////////////////////////////////////////////
1411 /// Creates a socket or a parallel socket and authenticates to the
1412 /// remote server specified in 'url' on remote 'port' as 'user'.
1413 ///
1414 /// url: [[proto][p][auth]://]host[/?options]
1415 ///
1416 /// where proto = "sockd", "rootd", "proofd"
1417 /// indicates the type of remote server
1418 /// if missing "sockd" is assumed ("sockd" indicates
1419 /// any remote server session using TServerSocket)
1420 /// [p] = for parallel sockets (forced internally for
1421 /// rootd)
1422 /// [auth] = "up", "s", "k", "g", "h", "ug" to force UsrPwd,
1423 /// SRP, Krb5, Globus, SSH or UidGid authentication
1424 /// [options] = "m" or "s", when proto=proofd indicates whether
1425 /// we are master or slave (used internally by TSlave)
1426 ///
1427 /// An already opened connection can be used by passing its socket
1428 /// in opensock.
1429 ///
1430 /// If 'err' is defined, '*err' on return from a failed call contains an error
1431 /// code (see NetErrors.h).
1432 ///
1433 /// Example:
1434 ///
1435 /// TSocket::CreateAuthSocket("qwerty","rootdps://machine.fq.dn",5051)
1436 ///
1437 /// creates an authenticated socket to a rootd server running
1438 /// on remote machine machine.fq.dn on port 5051; "parallel"
1439 /// sockets are forced internally because rootd expects
1440 /// parallel sockets; however a simple socket will be created
1441 /// in this case because the size is 0 (the default);
1442 /// authentication will attempt protocol SRP first.
1443 ///
1444 /// TSocket::CreateAuthSocket("qwerty","pk://machine.fq.dn:5052",3)
1445 ///
1446 /// creates an authenticated parallel socket of size 3 to a sockd
1447 /// server running on remote machine machine.fq.dn on port 5052;
1448 /// authentication will attempt protocol Kerberos first.
1449 ///
1450 /// NB: may hang if the remote server is not of the correct type;
1451 /// at present TSocket has no way to find out the type of the
1452 /// remote server automatically
1453 ///
1454 /// Returns pointer to an authenticated socket or 0 if creation or
1455 /// authentication is unsuccessful.
1456 
1457 TSocket *TSocket::CreateAuthSocket(const char *user, const char *url,
1458  Int_t port, Int_t size, Int_t tcpwindowsize,
1459  TSocket *opensock, Int_t *err)
1460 {
1461  R__LOCKGUARD2(gSocketAuthMutex);
1462 
1463  // Extended url to be passed to base call
1464  TString eurl;
1465 
1466  // Add protocol, if any
1467  if (TString(TUrl(url).GetProtocol()).Length() > 0) {
1468  eurl += TString(TUrl(url).GetProtocol());
1469  eurl += TString("://");
1470  }
1471  // Add user, if any
1472  if (!user || strlen(user) > 0) {
1473  eurl += TString(user);
1474  eurl += TString("@");
1475  }
1476  // Add host
1477  eurl += TString(TUrl(url).GetHost());
1478  // Add port
1479  eurl += TString(":");
1480  eurl += (port > 0 ? port : 0);
1481  // Add options, if any
1482  if (TString(TUrl(url).GetOptions()).Length() > 0) {
1483  eurl += TString("/?");
1484  eurl += TString(TUrl(url).GetOptions());
1485  }
1486 
1487  // Create the socket and return it
1488  return TSocket::CreateAuthSocket(eurl,size,tcpwindowsize,opensock,err);
1489 }
1490 
1491 ////////////////////////////////////////////////////////////////////////////////
1492 /// Static method returning supported client protocol.
1493 
1495 {
1496  return fgClientProtocol;
1497 }
1498 
1499 ////////////////////////////////////////////////////////////////////////////////
1500 /// Print error string depending on error code.
1501 
1502 void TSocket::NetError(const char *where, Int_t err)
1503 {
1504  // Make sure it is in range
1505  err = (err < kErrError) ? ((err > -1) ? err : 0) : kErrError;
1506 
1507  if (gDebug > 0)
1508  ::Error(where, "%s", gRootdErrStr[err]);
1509 }
1510 
1511 ////////////////////////////////////////////////////////////////////////////////
1512 /// Get total number of bytes sent via all sockets.
1513 
1515 {
1516  return fgBytesSent;
1517 }
1518 
1519 ////////////////////////////////////////////////////////////////////////////////
1520 /// Get total number of bytes received via all sockets.
1521 
1523 {
1524  return fgBytesRecv;
1525 }
Describe Streamer information for one class version.
Definition: TStreamerInfo.h:43
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition: TObject.cxx:375
Bool_t IsReading() const
Definition: TBuffer.h:83
Int_t fSocket
Definition: TSocket.h:88
virtual void WriteString(const char *s)
Write string to I/O buffer.
virtual Bool_t IsValid() const
Definition: TSocket.h:151
An array of TObjects.
Definition: TObjArray.h:37
Int_t fTcpWindowSize
Definition: TSocket.h:89
Bool_t RecvStreamerInfos(TMessage *mess)
Receive a message containing streamer infos.
Definition: TSocket.cxx:932
Int_t GetCompressionLevel() const
Definition: TSocket.h:200
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
char * CompBuffer() const
Definition: TMessage.h:88
Int_t GetPort() const
Definition: TSocket.h:134
R__EXTERN const char * gRootdErrStr[]
Definition: NetErrors.h:72
void SetCompressionSettings(Int_t settings=1)
Used to specify the compression level and algorithm: settings = 100 * algorithm + level...
Definition: TSocket.cxx:1103
Collectable string class.
Definition: TObjString.h:28
const char Option_t
Definition: RtypesCore.h:62
const char * GetHostName() const
Definition: TInetAddress.h:71
ESockOptions
Definition: TSocket.h:36
Bool_t RecvProcessIDs(TMessage *mess)
Receive a message containing process ids.
Definition: TSocket.cxx:979
virtual Int_t Send(const TMessage &mess)
Send a TMessage object.
Definition: TSocket.cxx:527
virtual Int_t SetOption(ESockOptions opt, Int_t val)
Set socket options.
Definition: TSocket.cxx:1017
This class represents a WWW compatible URL.
Definition: TUrl.h:35
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
static Int_t fgClientProtocol
Definition: TSocket.h:100
virtual Int_t Recv(TMessage *&mess)
Receive a TMessage object.
Definition: TSocket.cxx:822
const char * GetProtocol() const
Definition: TUrl.h:67
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
virtual TSecContext * Authenticate(TSocket *, const char *host, const char *user, Option_t *options)=0
virtual Int_t GetEntries() const
Definition: TCollection.h:177
This class represents an Internet Protocol (IP) address.
Definition: TInetAddress.h:36
virtual void CloseConnection(int sock, Bool_t force=kFALSE)
Close socket connection.
Definition: TSystem.cxx:2419
This class implements a mutex interface.
Definition: TVirtualMutex.h:34
#define R__ASSERT(e)
Definition: TError.h:96
static ULong64_t GetSocketBytesRecv()
Get total number of bytes received via all sockets.
Definition: TSocket.cxx:1522
#define gROOT
Definition: TROOT.h:410
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
Int_t LoadPlugin()
Load the plugin library for this handler.
Basic string class.
Definition: TString.h:131
void SendStreamerInfos(const TMessage &mess)
Check if TStreamerInfo must be sent.
Definition: TSocket.cxx:654
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
virtual Int_t SendObject(const TObject *obj, Int_t kind=kMESS_OBJECT)
Send an object.
Definition: TSocket.cxx:605
Option_t * GetOption() const
Definition: TSocket.h:117
TInetAddress fAddress
Definition: TSocket.h:78
TObject * At(Int_t idx) const
Definition: TObjArray.h:165
virtual TInetAddress GetPeerName(int sock)
Get Internet Protocol (IP) address of remote host and port #.
Definition: TSystem.cxx:2329
TInetAddress fLocalAddress
Definition: TSocket.h:82
virtual int SendRaw(int sock, const void *buffer, int length, int flag)
Send exactly length bytes from buffer.
Definition: TSystem.cxx:2438
virtual char * GetServiceByPort(int port)
Get name of internet service.
Definition: TSystem.cxx:2356
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
ESendRecvOptions
Definition: TSocket.h:49
virtual TObject * FindObject(const char *name) const
Delete a TObjLink object.
Definition: TList.cxx:574
Int_t Length() const
Definition: TBuffer.h:96
virtual TObject * ReadObject(const TClass *cl)
Read object from I/O buffer.
static TObjArray * GetPIDs()
static: returns array of TProcessIDs
Definition: TProcessID.cxx:349
virtual Int_t SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Send a raw buffer of specified length.
Definition: TSocket.cxx:625
TVirtualMutex * fLastUsageMtx
Definition: TSocket.h:94
UShort_t net2host(UShort_t x)
Definition: Bytes.h:577
void Class()
Definition: Class.C:29
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
TString fUrl
Definition: TSocket.h:90
virtual char * ReadString(char *s, Int_t max)
Read string from I/O buffer.
TBits fBitsInfo
Definition: TSocket.h:91
char * Buffer() const
Definition: TBuffer.h:93
Int_t CompLength() const
Definition: TMessage.h:89
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)
Creates a socket or a parallel socket and authenticates to the remote server specified in &#39;url&#39; on re...
Definition: TSocket.cxx:1457
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2152
virtual UserGroup_t * GetUserInfo(Int_t uid)
Returns all user info in the UserGroup_t structure.
Definition: TSystem.cxx:1574
Int_t GetPort() const
Definition: TInetAddress.h:73
virtual int RecvRaw(int sock, void *buffer, int length, int flag)
Receive exactly length bytes into buffer.
Definition: TSystem.cxx:2428
TString fService
Definition: TSocket.h:86
A TProcessID identifies a ROOT job in a unique way in time and space.
Definition: TProcessID.h:69
Bool_t TestBitNumber(UInt_t bitnumber) const
Definition: TBits.h:226
virtual TInetAddress GetHostByName(const char *server)
Get Internet Protocol (IP) address of host.
Definition: TSystem.cxx:2320
void SetCompressionLevel(Int_t level=1)
See comments for function SetCompressionSettings.
Definition: TSocket.cxx:1065
virtual Int_t GetLocalPort()
Return the local port # to which the socket is bound.
Definition: TSocket.cxx:428
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition: TObject.cxx:705
A doubly linked list.
Definition: TList.h:44
TString fUser
Definition: TSystem.h:142
virtual void Close(Option_t *opt="")
Close the socket.
Definition: TSocket.cxx:394
virtual Int_t Select(Int_t interest=kRead, Long_t timeout=-1)
Waits for this socket to change status.
Definition: TSocket.cxx:448
R__EXTERN TSystem * gSystem
Definition: TSystem.h:540
Long_t ExecPlugin(int nargs, const T &... params)
static void NetError(const char *where, Int_t error)
Print error string depending on error code.
Definition: TSocket.cxx:1502
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:610
static ULong64_t GetSocketBytesSent()
Get total number of bytes sent via all sockets.
Definition: TSocket.cxx:1514
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2264
Int_t IncrementCount()
Increase the reference count to this object.
Definition: TProcessID.cxx:311
unsigned int UInt_t
Definition: RtypesCore.h:42
UInt_t fBytesSent
Definition: TSocket.h:80
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
char * Form(const char *fmt,...)
Ssiz_t Length() const
Definition: TString.h:405
TSocket()
Definition: TSocket.h:102
TList * fInfos
Definition: TMessage.h:41
void SetCompressionAlgorithm(Int_t algorithm=0)
See comments for function SetCompressionSettings.
Definition: TSocket.cxx:1050
void MarkBrokenConnection()
Close the socket and mark as due to a broken connection.
Definition: TSocket.cxx:376
void Touch()
Definition: TSocket.h:176
TString fName
Definition: TNamed.h:32
virtual void WriteObject(const TObject *obj, Bool_t cacheReuse=kTRUE)
Write object to I/O buffer.
Definition: TBufferIO.cxx:530
virtual TObjLink * FirstLink() const
Definition: TList.h:108
#define h(i)
Definition: RSha256.hxx:106
#define R__LOCKGUARD2(mutex)
virtual int OpenConnection(const char *server, int port, int tcpwindowsize=-1, const char *protocol="tcp")
Open a connection to another host.
Definition: TSystem.cxx:2365
const Bool_t kFALSE
Definition: RtypesCore.h:88
virtual int SetSockOpt(int sock, int kind, int val)
Set socket option.
Definition: TSystem.cxx:2465
virtual Int_t Select(TList *active, Long_t timeout)
Select on active file descriptors (called by TMonitor).
Definition: TSystem.cxx:453
virtual TInetAddress GetLocalInetAddress()
Return internet address of local host to which the socket is bound.
Definition: TSocket.cxx:414
UInt_t What() const
Definition: TMessage.h:74
#define SafeDelete(p)
Definition: RConfig.h:529
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
long Long_t
Definition: RtypesCore.h:50
TObject * UncheckedAt(Int_t i) const
Definition: TObjArray.h:89
#define ClassImp(name)
Definition: Rtypes.h:359
Int_t fCompress
Definition: TSocket.h:81
TList * fUUIDs
Definition: TSocket.h:92
Int_t IndexOf(const TObject *obj) const
Definition: TObjArray.cxx:589
unsigned long long ULong64_t
Definition: RtypesCore.h:70
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
static constexpr double s
Int_t BufferSize() const
Definition: TBuffer.h:94
virtual Bool_t IsAuthenticated() const
Definition: TSocket.h:150
virtual TInetAddress GetSockName(int sock)
Get Internet Protocol (IP) address of host and port #.
Definition: TSystem.cxx:2338
Int_t GetCompressionLevel() const
Definition: TMessage.h:105
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:399
Int_t GetPort() const
Definition: TUrl.h:81
EServiceType fServType
Definition: TSocket.h:87
Mother of all ROOT objects.
Definition: TObject.h:37
TObjArray * GetElements() const
static ULong64_t fgBytesSent
Definition: TSocket.h:98
Int_t GetClassVersion() const
void SetLength() const
Set the message length at the beginning of the message buffer.
Definition: TMessage.cxx:201
void BuildCheck(TFile *file=0)
Check if built and consistent with the class dictionary.
Int_t GetErrorCode() const
Returns error code.
Definition: TSocket.cxx:1039
virtual int GetServiceByName(const char *service)
Get port # of internet service.
Definition: TSystem.cxx:2347
void SendProcessIDs(const TMessage &mess)
Check if TProcessIDs must be sent.
Definition: TSocket.cxx:689
virtual void Add(TObject *obj)
Definition: TList.h:87
static ULong64_t fgBytesRecv
Definition: TSocket.h:97
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:522
const char * proto
Definition: civetweb.c:15049
R__EXTERN Int_t gDebug
Definition: Rtypes.h:86
static Int_t GetClientProtocol()
Static method returning supported client protocol.
Definition: TSocket.cxx:1494
TInetAddress GetInetAddress() const
Definition: TSocket.h:132
Int_t fRemoteProtocol
Definition: TSocket.h:83
void Add(TObject *obj)
Definition: TObjArray.h:73
static void ResetErrno()
Static function resetting system error number.
Definition: TSystem.cxx:284
Undefined compression algorithm (must be kept the last of the list in case a new algorithm is added)...
Definition: Compression.h:55
void ResetBit(UInt_t f)
Definition: TObject.h:171
Bool_t TestBitNumber(UInt_t bitnumber) const
Definition: TMessage.h:58
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
virtual int GetSockOpt(int sock, int kind, int *val)
Get socket option.
Definition: TSystem.cxx:2474
Int_t GetNumber() const
virtual Int_t RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Receive a raw buffer of specified length bytes.
Definition: TSocket.cxx:902
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
const Bool_t kTRUE
Definition: RtypesCore.h:87
const Int_t n
Definition: legend1.C:16
void SetBitNumber(UInt_t bitnumber, Bool_t value=kTRUE)
Definition: TBits.h:210
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
TSecContext * fSecContext
Definition: TSocket.h:84
Bool_t Authenticate(const char *user)
Authenticated the socket with specified user.
Definition: TSocket.cxx:1111
TVirtualMutex * gSocketAuthMutex
Definition: TSocket.cxx:63
void Resize(Ssiz_t n)
Resize the string. Truncate or add blanks as necessary.
Definition: TString.cxx:1070
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
UInt_t fBytesRecv
Definition: TSocket.h:79
const char * Data() const
Definition: TString.h:364