Logo ROOT   6.08/07
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"))
90  fServType = kPROOFD;
91  fAddress = addr;
92  fAddress.fPort = gSystem->GetServiceByName(service);
93  fBytesSent = 0;
94  fBytesRecv = 0;
95  fCompress = 0;
96  fTcpWindowSize = tcpwindowsize;
97  fUUIDs = 0;
98  fLastUsageMtx = 0;
99  ResetBit(TSocket::kBrokenConn);
100 
101  if (fAddress.GetPort() != -1) {
102  fSocket = gSystem->OpenConnection(addr.GetHostName(), fAddress.GetPort(),
103  tcpwindowsize);
104 
105  if (fSocket != -1) {
107  gROOT->GetListOfSockets()->Add(this);
108  }
109  } else
110  fSocket = -1;
111 
112 }
113 
114 ////////////////////////////////////////////////////////////////////////////////
115 /// Create a socket. Connect to the specified port # at address addr.
116 /// Use tcpwindowsize to specify the size of the receive buffer, it has
117 /// to be specified here to make sure the window scale option is set (for
118 /// tcpwindowsize > 65KB and for platforms supporting window scaling).
119 /// Returns when connection has been accepted by remote side. Use IsValid()
120 /// to check the validity of the socket. Every socket is added to the TROOT
121 /// sockets list which will make sure that any open sockets are properly
122 /// closed on program termination.
123 
124 TSocket::TSocket(TInetAddress addr, Int_t port, Int_t tcpwindowsize)
125  : TNamed(addr.GetHostName(), "")
126 {
127  R__ASSERT(gROOT);
129 
131  fSecContext = 0;
132  fRemoteProtocol= -1;
133  fServType = kSOCKD;
134  if (fService.Contains("root"))
135  fServType = kROOTD;
136  if (fService.Contains("proof"))
137  fServType = kPROOFD;
138  fAddress = addr;
139  fAddress.fPort = port;
141  fBytesSent = 0;
142  fBytesRecv = 0;
143  fCompress = 0;
144  fTcpWindowSize = tcpwindowsize;
145  fUUIDs = 0;
146  fLastUsageMtx = 0;
148 
150  tcpwindowsize);
151  if (fSocket == -1)
152  fAddress.fPort = -1;
153  else {
155  gROOT->GetListOfSockets()->Add(this);
156  }
157 }
158 
159 ////////////////////////////////////////////////////////////////////////////////
160 /// Create a socket. Connect to named service on the remote host.
161 /// Use tcpwindowsize to specify the size of the receive buffer, it has
162 /// to be specified here to make sure the window scale option is set (for
163 /// tcpwindowsize > 65KB and for platforms supporting window scaling).
164 /// Returns when connection has been accepted by remote side. Use IsValid()
165 /// to check the validity of the socket. Every socket is added to the TROOT
166 /// sockets list which will make sure that any open sockets are properly
167 /// closed on program termination.
168 
169 TSocket::TSocket(const char *host, const char *service, Int_t tcpwindowsize)
170  : TNamed(host, service)
171 {
172  R__ASSERT(gROOT);
174 
175  fService = service;
176  fSecContext = 0;
177  fRemoteProtocol= -1;
178  fServType = kSOCKD;
179  if (fService.Contains("root"))
180  fServType = kROOTD;
181  if (fService.Contains("proof"))
182  fServType = kPROOFD;
183  fAddress = gSystem->GetHostByName(host);
186  fBytesSent = 0;
187  fBytesRecv = 0;
188  fCompress = 0;
189  fTcpWindowSize = tcpwindowsize;
190  fUUIDs = 0;
191  fLastUsageMtx = 0;
193 
194  if (fAddress.GetPort() != -1) {
195  fSocket = gSystem->OpenConnection(host, fAddress.GetPort(), tcpwindowsize);
196  if (fSocket != -1) {
198  gROOT->GetListOfSockets()->Add(this);
199  }
200  } else
201  fSocket = -1;
202 }
203 
204 ////////////////////////////////////////////////////////////////////////////////
205 /// Create a socket; see CreateAuthSocket for the form of url.
206 /// Connect to the specified port # on the remote host.
207 /// If user is specified in url, try authentication as user.
208 /// Use tcpwindowsize to specify the size of the receive buffer, it has
209 /// to be specified here to make sure the window scale option is set (for
210 /// tcpwindowsize > 65KB and for platforms supporting window scaling).
211 /// Returns when connection has been accepted by remote side. Use IsValid()
212 /// to check the validity of the socket. Every socket is added to the TROOT
213 /// sockets list which will make sure that any open sockets are properly
214 /// closed on program termination.
215 
216 TSocket::TSocket(const char *url, Int_t port, Int_t tcpwindowsize)
217  : TNamed(TUrl(url).GetHost(), "")
218 {
219  R__ASSERT(gROOT);
221 
222  fUrl = TString(url);
223  TString host(TUrl(fUrl).GetHost());
224 
226  fSecContext = 0;
227  fRemoteProtocol= -1;
228  fServType = kSOCKD;
229  if (fUrl.Contains("root"))
230  fServType = kROOTD;
231  if (fUrl.Contains("proof"))
232  fServType = kPROOFD;
233  fAddress = gSystem->GetHostByName(host);
234  fAddress.fPort = port;
237  fBytesSent = 0;
238  fBytesRecv = 0;
239  fCompress = 0;
240  fTcpWindowSize = tcpwindowsize;
241  fUUIDs = 0;
242  fLastUsageMtx = 0;
244 
245  fSocket = gSystem->OpenConnection(host, fAddress.GetPort(), tcpwindowsize);
246  if (fSocket == -1) {
247  fAddress.fPort = -1;
248  } else {
250  gROOT->GetListOfSockets()->Add(this);
251  }
252 }
253 
254 ////////////////////////////////////////////////////////////////////////////////
255 /// Create a socket in the Unix domain on 'sockpath'.
256 /// Returns when connection has been accepted by the server. Use IsValid()
257 /// to check the validity of the socket. Every socket is added to the TROOT
258 /// sockets list which will make sure that any open sockets are properly
259 /// closed on program termination.
260 
261 TSocket::TSocket(const char *sockpath) : TNamed(sockpath, "")
262 {
263  R__ASSERT(gROOT);
265 
266  fUrl = sockpath;
267 
268  fService = "unix";
269  fSecContext = 0;
270  fRemoteProtocol= -1;
271  fServType = kSOCKD;
272  fAddress.fPort = -1;
273  fName.Form("unix:%s", sockpath);
275  fBytesSent = 0;
276  fBytesRecv = 0;
277  fCompress = 0;
278  fTcpWindowSize = -1;
279  fUUIDs = 0;
280  fLastUsageMtx = 0;
282 
283  fSocket = gSystem->OpenConnection(sockpath, -1, -1);
284  if (fSocket > 0) {
286  gROOT->GetListOfSockets()->Add(this);
287  }
288 }
289 
290 ////////////////////////////////////////////////////////////////////////////////
291 /// Create a socket. The socket will adopt previously opened TCP socket with
292 /// descriptor desc.
293 
295 {
296  R__ASSERT(gROOT);
298 
299  fSecContext = 0;
300  fRemoteProtocol = 0;
301  fService = (char *)kSOCKD;
302  fServType = kSOCKD;
303  fBytesSent = 0;
304  fBytesRecv = 0;
305  fCompress = 0;
306  fTcpWindowSize = -1;
307  fUUIDs = 0;
308  fLastUsageMtx = 0;
310 
311  if (desc >= 0) {
312  fSocket = desc;
315  gROOT->GetListOfSockets()->Add(this);
316  } else
317  fSocket = -1;
318 }
319 
320 ////////////////////////////////////////////////////////////////////////////////
321 /// Create a socket. The socket will adopt previously opened Unix socket with
322 /// descriptor desc. The sockpath arg is for info purposes only. Use
323 /// this method to adopt e.g. a socket created via socketpair().
324 
325 TSocket::TSocket(Int_t desc, const char *sockpath) : TNamed(sockpath, "")
326 {
327  R__ASSERT(gROOT);
329 
330  fUrl = sockpath;
331 
332  fService = "unix";
333  fSecContext = 0;
334  fRemoteProtocol= -1;
335  fServType = kSOCKD;
336  fAddress.fPort = -1;
337  fName.Form("unix:%s", sockpath);
339  fBytesSent = 0;
340  fBytesRecv = 0;
341  fCompress = 0;
342  fTcpWindowSize = -1;
343  fUUIDs = 0;
344  fLastUsageMtx = 0;
346 
347  if (desc >= 0) {
348  fSocket = desc;
350  gROOT->GetListOfSockets()->Add(this);
351  } else
352  fSocket = -1;
353 }
354 
355 
356 ////////////////////////////////////////////////////////////////////////////////
357 /// TSocket copy ctor.
358 
360 {
361  fSocket = s.fSocket;
362  fService = s.fService;
363  fAddress = s.fAddress;
367  fCompress = s.fCompress;
370  fServType = s.fServType;
372  fUUIDs = 0;
373  fLastUsageMtx = 0;
375 
376  if (fSocket != -1) {
378  gROOT->GetListOfSockets()->Add(this);
379  }
380 }
381 
382 ////////////////////////////////////////////////////////////////////////////////
383 /// Close the socket. If option is "force", calls shutdown(id,2) to
384 /// shut down the connection. This will close the connection also
385 /// for the parent of this process. Also called via the dtor (without
386 /// option "force", call explicitly Close("force") if this is desired).
387 
389 {
390  Bool_t force = option ? (!strcmp(option, "force") ? kTRUE : kFALSE) : kFALSE;
391 
392  if (fSocket != -1) {
395  gROOT->GetListOfSockets()->Remove(this);
396  }
397  fSocket = -1;
398 
401 }
402 
403 ////////////////////////////////////////////////////////////////////////////////
404 /// Return internet address of local host to which the socket is bound.
405 /// In case of error TInetAddress::IsValid() returns kFALSE.
406 
408 {
409  if (IsValid()) {
410  if (fLocalAddress.GetPort() == -1)
412  return fLocalAddress;
413  }
414  return TInetAddress();
415 }
416 
417 ////////////////////////////////////////////////////////////////////////////////
418 /// Return the local port # to which the socket is bound.
419 /// In case of error return -1.
420 
422 {
423  if (IsValid()) {
424  if (fLocalAddress.GetPort() == -1)
426  return fLocalAddress.GetPort();
427  }
428  return -1;
429 }
430 
431 ////////////////////////////////////////////////////////////////////////////////
432 /// Waits for this socket to change status. If interest=kRead,
433 /// the socket will be watched to see if characters become available for
434 /// reading; if interest=kWrite the socket will be watched to
435 /// see if a write will not block.
436 /// The argument 'timeout' specifies a maximum time to wait in millisec.
437 /// Default no timeout.
438 /// Returns 1 if a change of status of interest has been detected within
439 /// timeout; 0 in case of timeout; < 0 if an error occured.
440 
441 Int_t TSocket::Select(Int_t interest, Long_t timeout)
442 {
443  Int_t rc = 1;
444 
445  // Associate a TFileHandler to this socket
446  TFileHandler fh(fSocket, interest);
447 
448  // Wait for an event now
449  rc = gSystem->Select(&fh, timeout);
450 
451  return rc;
452 }
453 
454 ////////////////////////////////////////////////////////////////////////////////
455 /// Send a single message opcode. Use kind (opcode) to set the
456 /// TMessage "what" field. Returns the number of bytes that were sent
457 /// (always sizeof(Int_t)) and -1 in case of error. In case the kind has
458 /// been or'ed with kMESS_ACK, the call will only return after having
459 /// received an acknowledgement, making the sending process synchronous.
460 
462 {
463  TMessage mess(kind);
464 
465  Int_t nsent;
466  if ((nsent = Send(mess)) < 0)
467  return -1;
468 
469  return nsent;
470 }
471 
472 ////////////////////////////////////////////////////////////////////////////////
473 /// Send a status and a single message opcode. Use kind (opcode) to set the
474 /// TMessage "what" field. Returns the number of bytes that were sent
475 /// (always 2*sizeof(Int_t)) and -1 in case of error. In case the kind has
476 /// been or'ed with kMESS_ACK, the call will only return after having
477 /// received an acknowledgement, making the sending process synchronous.
478 
480 {
481  TMessage mess(kind);
482  mess << status;
483 
484  Int_t nsent;
485  if ((nsent = Send(mess)) < 0)
486  return -1;
487 
488  return nsent;
489 }
490 
491 ////////////////////////////////////////////////////////////////////////////////
492 /// Send a character string buffer. Use kind to set the TMessage "what" field.
493 /// Returns the number of bytes in the string str that were sent and -1 in
494 /// case of error. In case the kind has been or'ed with kMESS_ACK, the call
495 /// will only return after having received an acknowledgement, making the
496 /// sending process synchronous.
497 
498 Int_t TSocket::Send(const char *str, Int_t kind)
499 {
500  TMessage mess(kind);
501  if (str) mess.WriteString(str);
502 
503  Int_t nsent;
504  if ((nsent = Send(mess)) < 0)
505  return -1;
506 
507  return nsent - sizeof(Int_t); // - TMessage::What()
508 }
509 
510 ////////////////////////////////////////////////////////////////////////////////
511 /// Send a TMessage object. Returns the number of bytes in the TMessage
512 /// that were sent and -1 in case of error. In case the TMessage::What
513 /// has been or'ed with kMESS_ACK, the call will only return after having
514 /// received an acknowledgement, making the sending process synchronous.
515 /// Returns -4 in case of kNoBlock and errno == EWOULDBLOCK.
516 /// Returns -5 if pipe broken or reset by peer (EPIPE || ECONNRESET).
517 /// support for streaming TStreamerInfo added by Rene Brun May 2008
518 /// support for streaming TProcessID added by Rene Brun June 2008
519 
521 {
523 
524  if (fSocket == -1) return -1;
525 
526  if (mess.IsReading()) {
527  Error("Send", "cannot send a message used for reading");
528  return -1;
529  }
530 
531  // send streamer infos in case schema evolution is enabled in the TMessage
532  SendStreamerInfos(mess);
533 
534  // send the process id's so TRefs work
535  SendProcessIDs(mess);
536 
537  mess.SetLength(); //write length in first word of buffer
538 
539  if (GetCompressionLevel() > 0 && mess.GetCompressionLevel() == 0)
540  const_cast<TMessage&>(mess).SetCompressionSettings(fCompress);
541 
542  if (mess.GetCompressionLevel() > 0)
543  const_cast<TMessage&>(mess).Compress();
544 
545  char *mbuf = mess.Buffer();
546  Int_t mlen = mess.Length();
547  if (mess.CompBuffer()) {
548  mbuf = mess.CompBuffer();
549  mlen = mess.CompLength();
550  }
551 
553  Int_t nsent;
554  if ((nsent = gSystem->SendRaw(fSocket, mbuf, mlen, 0)) <= 0) {
555  if (nsent == -5) {
556  // Connection reset by peer or broken
558  Close();
559  }
560  return nsent;
561  }
562 
563  fBytesSent += nsent;
564  fgBytesSent += nsent;
565 
566  // If acknowledgement is desired, wait for it
567  if (mess.What() & kMESS_ACK) {
570  char buf[2];
571  Int_t n = 0;
572  if ((n = gSystem->RecvRaw(fSocket, buf, sizeof(buf), 0)) < 0) {
573  if (n == -5) {
574  // Connection reset by peer or broken
576  Close();
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 (fSocket == -1) 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  Close();
633  }
634  return nsent;
635  }
636 
637  fBytesSent += nsent;
638  fgBytesSent += nsent;
639 
640  Touch(); // update usage timestamp
641 
642  return nsent;
643 }
644 
645 ////////////////////////////////////////////////////////////////////////////////
646 /// Check if TStreamerInfo must be sent. The list of TStreamerInfo of classes
647 /// in the object in the message is in the fInfos list of the message.
648 /// We send only the TStreamerInfos not yet sent on this socket.
649 
651 {
652  if (mess.fInfos && mess.fInfos->GetEntries()) {
653  TIter next(mess.fInfos);
654  TStreamerInfo *info;
655  TList *minilist = 0;
656  while ((info = (TStreamerInfo*)next())) {
657  Int_t uid = info->GetNumber();
658  if (fBitsInfo.TestBitNumber(uid))
659  continue; //TStreamerInfo had already been sent
660  fBitsInfo.SetBitNumber(uid);
661  if (!minilist)
662  minilist = new TList();
663  if (gDebug > 0)
664  Info("SendStreamerInfos", "sending TStreamerInfo: %s, version = %d",
665  info->GetName(),info->GetClassVersion());
666  minilist->Add(info);
667  }
668  if (minilist) {
669  TMessage messinfo(kMESS_STREAMERINFO);
670  messinfo.WriteObject(minilist);
671  delete minilist;
672  if (messinfo.fInfos)
673  messinfo.fInfos->Clear();
674  if (Send(messinfo) < 0)
675  Warning("SendStreamerInfos", "problems sending TStreamerInfo's ...");
676  }
677  }
678 }
679 
680 ////////////////////////////////////////////////////////////////////////////////
681 /// Check if TProcessIDs must be sent. The list of TProcessIDs
682 /// in the object in the message is found by looking in the TMessage bits.
683 /// We send only the TProcessIDs not yet send on this socket.
684 
686 {
687  if (mess.TestBitNumber(0)) {
688  TObjArray *pids = TProcessID::GetPIDs();
689  Int_t npids = pids->GetEntries();
690  TProcessID *pid;
691  TList *minilist = 0;
692  for (Int_t ipid = 0; ipid < npids; ipid++) {
693  pid = (TProcessID*)pids->At(ipid);
694  if (!pid || !mess.TestBitNumber(pid->GetUniqueID()+1))
695  continue;
696  //check if a pid with this title has already been sent through the socket
697  //if not add it to the fUUIDs list
698  if (!fUUIDs) {
699  fUUIDs = new TList();
700  } else {
701  if (fUUIDs->FindObject(pid->GetTitle()))
702  continue;
703  }
704  fUUIDs->Add(new TObjString(pid->GetTitle()));
705  if (!minilist)
706  minilist = new TList();
707  if (gDebug > 0)
708  Info("SendProcessIDs", "sending TProcessID: %s", pid->GetTitle());
709  minilist->Add(pid);
710  }
711  if (minilist) {
712  TMessage messpid(kMESS_PROCESSID);
713  messpid.WriteObject(minilist);
714  delete minilist;
715  if (Send(messpid) < 0)
716  Warning("SendProcessIDs", "problems sending TProcessID's ...");
717  }
718  }
719 }
720 
721 ////////////////////////////////////////////////////////////////////////////////
722 /// Receive a character string message of maximum max length. The expected
723 /// message must be of type kMESS_STRING. Returns length of received string
724 /// (can be 0 if otherside of connection is closed) or -1 in case of error
725 /// or -4 in case a non-blocking socket would block (i.e. there is nothing
726 /// to be read).
727 
728 Int_t TSocket::Recv(char *str, Int_t max)
729 {
730  Int_t n, kind;
731 
733  if ((n = Recv(str, max, kind)) <= 0) {
734  if (n == -5) {
736  n = -1;
737  }
738  return n;
739  }
740 
741  if (kind != kMESS_STRING) {
742  Error("Recv", "got message of wrong kind (expected %d, got %d)",
743  kMESS_STRING, kind);
744  return -1;
745  }
746 
747  return n;
748 }
749 
750 ////////////////////////////////////////////////////////////////////////////////
751 /// Receive a character string message of maximum max length. Returns in
752 /// kind the message type. Returns length of received string+4 (can be 0 if
753 /// other side of connection is closed) or -1 in case of error or -4 in
754 /// case a non-blocking socket would block (i.e. there is nothing to be read).
755 
756 Int_t TSocket::Recv(char *str, Int_t max, Int_t &kind)
757 {
758  Int_t n;
759  TMessage *mess;
760 
762  if ((n = Recv(mess)) <= 0) {
763  if (n == -5) {
765  n = -1;
766  }
767  return n;
768  }
769 
770  kind = mess->What();
771  if (str) {
772  if (mess->BufferSize() > (Int_t)sizeof(Int_t)) // if mess contains more than kind
773  mess->ReadString(str, max);
774  else
775  str[0] = 0;
776  }
777 
778  delete mess;
779 
780  return n; // number of bytes read (len of str + sizeof(kind)
781 }
782 
783 ////////////////////////////////////////////////////////////////////////////////
784 /// Receives a status and a message type. Returns length of received
785 /// integers, 2*sizeof(Int_t) (can be 0 if other side of connection
786 /// is closed) or -1 in case of error or -4 in case a non-blocking
787 /// socket would block (i.e. there is nothing to be read).
788 
790 {
791  Int_t n;
792  TMessage *mess;
793 
795  if ((n = Recv(mess)) <= 0) {
796  if (n == -5) {
798  n = -1;
799  }
800  return n;
801  }
802 
803  kind = mess->What();
804  (*mess) >> status;
805 
806  delete mess;
807 
808  return n; // number of bytes read (2 * sizeof(Int_t)
809 }
810 
811 ////////////////////////////////////////////////////////////////////////////////
812 /// Receive a TMessage object. The user must delete the TMessage object.
813 /// Returns length of message in bytes (can be 0 if other side of connection
814 /// is closed) or -1 in case of error or -4 in case a non-blocking socket
815 /// would block (i.e. there is nothing to be read) or -5 if pipe broken
816 /// or reset by peer (EPIPE || ECONNRESET). In those case mess == 0.
817 
819 {
821 
822  if (fSocket == -1) {
823  mess = 0;
824  return -1;
825  }
826 
827 oncemore:
829  Int_t n;
830  UInt_t len;
831  if ((n = gSystem->RecvRaw(fSocket, &len, sizeof(UInt_t), 0)) <= 0) {
832  if (n == 0 || n == -5) {
833  // Connection closed, reset or broken
835  Close();
836  }
837  mess = 0;
838  return n;
839  }
840  len = net2host(len); //from network to host byte order
841 
843  char *buf = new char[len+sizeof(UInt_t)];
844  if ((n = gSystem->RecvRaw(fSocket, buf+sizeof(UInt_t), len, 0)) <= 0) {
845  if (n == 0 || n == -5) {
846  // Connection closed, reset or broken
848  Close();
849  }
850  delete [] buf;
851  mess = 0;
852  return n;
853  }
854 
855  fBytesRecv += n + sizeof(UInt_t);
856  fgBytesRecv += n + sizeof(UInt_t);
857 
858  mess = new TMessage(buf, len+sizeof(UInt_t));
859 
860  // receive any streamer infos
861  if (RecvStreamerInfos(mess))
862  goto oncemore;
863 
864  // receive any process ids
865  if (RecvProcessIDs(mess))
866  goto oncemore;
867 
868  if (mess->What() & kMESS_ACK) {
870  char ok[2] = { 'o', 'k' };
871  Int_t n2 = 0;
872  if ((n2 = gSystem->SendRaw(fSocket, ok, sizeof(ok), 0)) < 0) {
873  if (n2 == -5) {
874  // Connection reset or broken
876  Close();
877  }
878  delete mess;
879  mess = 0;
880  return n2;
881  }
882  mess->SetWhat(mess->What() & ~kMESS_ACK);
883 
884  fBytesSent += 2;
885  fgBytesSent += 2;
886  }
887 
888  Touch(); // update usage timestamp
889 
890  return n;
891 }
892 
893 ////////////////////////////////////////////////////////////////////////////////
894 /// Receive a raw buffer of specified length bytes. Using option kPeek
895 /// one can peek at incoming data. Returns number of received bytes.
896 /// Returns -1 in case of error. In case of opt == kOob: -2 means
897 /// EWOULDBLOCK and -3 EINVAL. In case of non-blocking mode (kNoBlock)
898 /// -4 means EWOULDBLOCK. Returns -5 if pipe broken or reset by
899 /// peer (EPIPE || ECONNRESET).
900 
901 Int_t TSocket::RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt)
902 {
904 
905  if (fSocket == -1) return -1;
906  if (length == 0) return 0;
907 
909  Int_t n;
910  if ((n = gSystem->RecvRaw(fSocket, buffer, length, (int) opt)) <= 0) {
911  if (n == 0 || n == -5) {
912  // Connection closed, reset or broken
914  Close();
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 (fSocket == -1) 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 (fSocket == -1) 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:47
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition: TObject.cxx:434
Bool_t IsReading() const
Definition: TBuffer.h:83
Int_t fSocket
Definition: TSocket.h:100
virtual void WriteString(const char *s)
Write string to I/O buffer.
virtual Bool_t IsValid() const
Definition: TSocket.h:162
An array of TObjects.
Definition: TObjArray.h:39
Int_t fTcpWindowSize
Definition: TSocket.h:101
Bool_t RecvStreamerInfos(TMessage *mess)
Receive a message containing streamer infos.
Definition: TSocket.cxx:932
Int_t GetCompressionLevel() const
Definition: TSocket.h:211
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:899
char * CompBuffer() const
Definition: TMessage.h:94
Int_t GetPort() const
Definition: TSocket.h:145
R__EXTERN const char * gRootdErrStr[]
Definition: NetErrors.h:74
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:32
const char Option_t
Definition: RtypesCore.h:62
const char * GetHostName() const
Definition: TInetAddress.h:75
ESockOptions
Definition: TSocket.h:52
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:520
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:41
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:635
static Int_t fgClientProtocol
Definition: TSocket.h:112
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:157
virtual Int_t Recv(TMessage *&mess)
Receive a TMessage object.
Definition: TSocket.cxx:818
const char * GetProtocol() const
Definition: TUrl.h:73
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:131
virtual TSecContext * Authenticate(TSocket *, const char *host, const char *user, Option_t *options)=0
TH1 * h
Definition: legend2.C:5
virtual Int_t GetEntries() const
Definition: TCollection.h:92
This class represents an Internet Protocol (IP) address.
Definition: TInetAddress.h:40
virtual void CloseConnection(int sock, Bool_t force=kFALSE)
Close socket connection.
Definition: TSystem.cxx:2372
This class implements a mutex interface.
Definition: TVirtualMutex.h:34
#define R__ASSERT(e)
Definition: TError.h:98
static ULong64_t GetSocketBytesRecv()
Get total number of bytes received via all sockets.
Definition: TSocket.cxx:1522
#define gROOT
Definition: TROOT.h:364
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:582
Int_t LoadPlugin()
Load the plugin library for this handler.
Basic string class.
Definition: TString.h:137
void SendStreamerInfos(const TMessage &mess)
Check if TStreamerInfo must be sent.
Definition: TSocket.cxx:650
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:63
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual Int_t SendObject(const TObject *obj, Int_t kind=kMESS_OBJECT)
Send an object.
Definition: TSocket.cxx:600
Option_t * GetOption() const
Definition: TSocket.h:128
TInetAddress fAddress
Definition: TSocket.h:90
TObject * At(Int_t idx) const
Definition: TObjArray.h:167
const char * Class
Definition: TXMLSetup.cxx:64
virtual TInetAddress GetPeerName(int sock)
Get Internet Protocol (IP) address of remote host and port #.
Definition: TSystem.cxx:2282
TInetAddress fLocalAddress
Definition: TSocket.h:94
virtual int SendRaw(int sock, const void *buffer, int length, int flag)
Send exactly length bytes from buffer.
Definition: TSystem.cxx:2391
virtual char * GetServiceByPort(int port)
Get name of internet service.
Definition: TSystem.cxx:2309
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:739
ESendRecvOptions
Definition: TSocket.h:65
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:497
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:321
virtual Int_t SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Send a raw buffer of specified length.
Definition: TSocket.cxx:620
#define SafeDelete(p)
Definition: RConfig.h:507
TVirtualMutex * fLastUsageMtx
Definition: TSocket.h:106
UShort_t net2host(UShort_t x)
Definition: Bytes.h:579
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
TString fUrl
Definition: TSocket.h:102
virtual char * ReadString(char *s, Int_t max)
Read string from I/O buffer.
TBits fBitsInfo
Definition: TSocket.h:103
char * Buffer() const
Definition: TBuffer.h:93
Int_t CompLength() const
Definition: TMessage.h:95
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:2221
virtual UserGroup_t * GetUserInfo(Int_t uid)
Returns all user info in the UserGroup_t structure.
Definition: TSystem.cxx:1564
Int_t GetPort() const
Definition: TInetAddress.h:77
virtual int RecvRaw(int sock, void *buffer, int length, int flag)
Receive exactly length bytes into buffer.
Definition: TSystem.cxx:2381
TString fService
Definition: TSocket.h:98
A TProcessID identifies a ROOT job in a unique way in time and space.
Definition: TProcessID.h:73
Bool_t TestBitNumber(UInt_t bitnumber) const
Definition: TBits.h:223
virtual TInetAddress GetHostByName(const char *server)
Get Internet Protocol (IP) address of host.
Definition: TSystem.cxx:2273
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:421
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition: TObject.cxx:750
A doubly linked list.
Definition: TList.h:47
TString fUser
Definition: TSystem.h:152
virtual void Close(Option_t *opt="")
Close the socket.
Definition: TSocket.cxx:388
virtual Int_t Select(Int_t interest=kRead, Long_t timeout=-1)
Waits for this socket to change status.
Definition: TSocket.cxx:441
R__EXTERN TSystem * gSystem
Definition: TSystem.h:549
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:558
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:2322
Int_t IncrementCount()
Increase the reference count to this object.
Definition: TProcessID.cxx:283
unsigned int UInt_t
Definition: RtypesCore.h:42
UInt_t fBytesSent
Definition: TSocket.h:92
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:925
char * Form(const char *fmt,...)
Ssiz_t Length() const
Definition: TString.h:390
TSocket()
Definition: TSocket.h:114
TList * fInfos
Definition: TMessage.h:47
void SetCompressionAlgorithm(Int_t algorithm=0)
See comments for function SetCompressionSettings.
Definition: TSocket.cxx:1050
void Touch()
Definition: TSocket.h:187
TString fName
Definition: TNamed.h:36
virtual TObjLink * FirstLink() const
Definition: TList.h:101
#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:2318
virtual int SetSockOpt(int sock, int kind, int val)
Set socket option.
Definition: TSystem.cxx:2418
virtual Int_t Select(TList *active, Long_t timeout)
Select on active file descriptors (called by TMonitor).
Definition: TSystem.cxx:450
virtual TInetAddress GetLocalInetAddress()
Return internet address of local host to which the socket is bound.
Definition: TSocket.cxx:407
UInt_t What() const
Definition: TMessage.h:80
TString & Remove(Ssiz_t pos)
Definition: TString.h:616
long Long_t
Definition: RtypesCore.h:50
TObject * UncheckedAt(Int_t i) const
Definition: TObjArray.h:91
#define ClassImp(name)
Definition: Rtypes.h:279
Int_t fCompress
Definition: TSocket.h:93
TList * fUUIDs
Definition: TSocket.h:104
Int_t IndexOf(const TObject *obj) const
Definition: TObjArray.cxx:552
unsigned long long ULong64_t
Definition: RtypesCore.h:70
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
Int_t BufferSize() const
Definition: TBuffer.h:94
virtual Bool_t IsAuthenticated() const
Definition: TSocket.h:161
virtual TInetAddress GetSockName(int sock)
Get Internet Protocol (IP) address of host and port #.
Definition: TSystem.cxx:2291
Int_t GetCompressionLevel() const
Definition: TMessage.h:112
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:349
Int_t GetPort() const
Definition: TUrl.h:87
EServiceType fServType
Definition: TSocket.h:99
Mother of all ROOT objects.
Definition: TObject.h:37
TObjArray * GetElements() const
static ULong64_t fgBytesSent
Definition: TSocket.h:110
Int_t GetClassVersion() const
void SetLength() const
Set the message length at the beginning of the message buffer.
Definition: TMessage.cxx:188
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:2300
void SendProcessIDs(const TMessage &mess)
Check if TProcessIDs must be sent.
Definition: TSocket.cxx:685
virtual void Add(TObject *obj)
Definition: TList.h:81
void WriteObject(const TObject *obj)
Write object to message buffer.
Definition: TMessage.cxx:418
static ULong64_t fgBytesRecv
Definition: TSocket.h:109
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:494
const char * proto
Definition: civetweb.c:11652
R__EXTERN Int_t gDebug
Definition: Rtypes.h:128
static Int_t GetClientProtocol()
Static method returning supported client protocol.
Definition: TSocket.cxx:1494
TInetAddress GetInetAddress() const
Definition: TSocket.h:143
Int_t fRemoteProtocol
Definition: TSocket.h:95
void Add(TObject *obj)
Definition: TObjArray.h:75
static void ResetErrno()
Static function resetting system error number.
Definition: TSystem.cxx:281
void ResetBit(UInt_t f)
Definition: TObject.h:156
Bool_t TestBitNumber(UInt_t bitnumber) const
Definition: TMessage.h:64
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:416
virtual int GetSockOpt(int sock, int kind, int *val)
Get socket option.
Definition: TSystem.cxx:2427
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:901
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:155
const Int_t n
Definition: legend1.C:16
void SetBitNumber(UInt_t bitnumber, Bool_t value=kTRUE)
Definition: TBits.h:198
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:911
TSecContext * fSecContext
Definition: TSocket.h:96
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:1059
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
UInt_t fBytesRecv
Definition: TSocket.h:91
const char * Data() const
Definition: TString.h:349