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