00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "Bytes.h"
00024 #include "NetErrors.h"
00025 #include "TEnv.h"
00026 #include "TError.h"
00027 #include "TMessage.h"
00028 #include "TPSocket.h"
00029 #include "TPluginManager.h"
00030 #include "TROOT.h"
00031 #include "TString.h"
00032 #include "TSystem.h"
00033 #include "TUrl.h"
00034 #include "TVirtualAuth.h"
00035 #include "TStreamerInfo.h"
00036 #include "TProcessID.h"
00037
00038 ULong64_t TSocket::fgBytesSent = 0;
00039 ULong64_t TSocket::fgBytesRecv = 0;
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 Int_t TSocket::fgClientProtocol = 17;
00061
00062 TVirtualMutex *gSocketAuthMutex = 0;
00063
00064 ClassImp(TSocket)
00065
00066
00067 TSocket::TSocket(TInetAddress addr, const char *service, Int_t tcpwindowsize)
00068 : TNamed(addr.GetHostName(), service)
00069 {
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 R__ASSERT(gROOT);
00080 R__ASSERT(gSystem);
00081
00082 fService = service;
00083 fSecContext = 0;
00084 fRemoteProtocol= -1;
00085 fServType = kSOCKD;
00086 if (fService.Contains("root"))
00087 fServType = kROOTD;
00088 if (fService.Contains("proof"))
00089 fServType = kPROOFD;
00090 fAddress = addr;
00091 fAddress.fPort = gSystem->GetServiceByName(service);
00092 fBytesSent = 0;
00093 fBytesRecv = 0;
00094 fCompress = 0;
00095 fTcpWindowSize = tcpwindowsize;
00096 fUUIDs = 0;
00097 fLastUsageMtx = 0;
00098
00099 if (fAddress.GetPort() != -1) {
00100 fSocket = gSystem->OpenConnection(addr.GetHostName(), fAddress.GetPort(),
00101 tcpwindowsize);
00102
00103 if (fSocket != -1) {
00104 R__LOCKGUARD2(gROOTMutex);
00105 gROOT->GetListOfSockets()->Add(this);
00106 }
00107 } else
00108 fSocket = -1;
00109
00110 }
00111
00112
00113 TSocket::TSocket(TInetAddress addr, Int_t port, Int_t tcpwindowsize)
00114 : TNamed(addr.GetHostName(), "")
00115 {
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 R__ASSERT(gROOT);
00126 R__ASSERT(gSystem);
00127
00128 fService = gSystem->GetServiceByPort(port);
00129 fSecContext = 0;
00130 fRemoteProtocol= -1;
00131 fServType = kSOCKD;
00132 if (fService.Contains("root"))
00133 fServType = kROOTD;
00134 if (fService.Contains("proof"))
00135 fServType = kPROOFD;
00136 fAddress = addr;
00137 fAddress.fPort = port;
00138 SetTitle(fService);
00139 fBytesSent = 0;
00140 fBytesRecv = 0;
00141 fCompress = 0;
00142 fTcpWindowSize = tcpwindowsize;
00143 fUUIDs = 0;
00144 fLastUsageMtx = 0;
00145
00146 fSocket = gSystem->OpenConnection(addr.GetHostName(), fAddress.GetPort(),
00147 tcpwindowsize);
00148 if (fSocket == -1)
00149 fAddress.fPort = -1;
00150 else {
00151 R__LOCKGUARD2(gROOTMutex);
00152 gROOT->GetListOfSockets()->Add(this);
00153 }
00154 }
00155
00156
00157 TSocket::TSocket(const char *host, const char *service, Int_t tcpwindowsize)
00158 : TNamed(host, service)
00159 {
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 R__ASSERT(gROOT);
00170 R__ASSERT(gSystem);
00171
00172 fService = service;
00173 fSecContext = 0;
00174 fRemoteProtocol= -1;
00175 fServType = kSOCKD;
00176 if (fService.Contains("root"))
00177 fServType = kROOTD;
00178 if (fService.Contains("proof"))
00179 fServType = kPROOFD;
00180 fAddress = gSystem->GetHostByName(host);
00181 fAddress.fPort = gSystem->GetServiceByName(service);
00182 SetName(fAddress.GetHostName());
00183 fBytesSent = 0;
00184 fBytesRecv = 0;
00185 fCompress = 0;
00186 fTcpWindowSize = tcpwindowsize;
00187 fUUIDs = 0;
00188 fLastUsageMtx = 0;
00189
00190 if (fAddress.GetPort() != -1) {
00191 fSocket = gSystem->OpenConnection(host, fAddress.GetPort(), tcpwindowsize);
00192 if (fSocket != -1) {
00193 R__LOCKGUARD2(gROOTMutex);
00194 gROOT->GetListOfSockets()->Add(this);
00195 }
00196 } else
00197 fSocket = -1;
00198 }
00199
00200
00201 TSocket::TSocket(const char *url, Int_t port, Int_t tcpwindowsize)
00202 : TNamed(TUrl(url).GetHost(), "")
00203 {
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 R__ASSERT(gROOT);
00216 R__ASSERT(gSystem);
00217
00218 fUrl = TString(url);
00219 TString host(TUrl(fUrl).GetHost());
00220
00221 fService = gSystem->GetServiceByPort(port);
00222 fSecContext = 0;
00223 fRemoteProtocol= -1;
00224 fServType = kSOCKD;
00225 if (fUrl.Contains("root"))
00226 fServType = kROOTD;
00227 if (fUrl.Contains("proof"))
00228 fServType = kPROOFD;
00229 fAddress = gSystem->GetHostByName(host);
00230 fAddress.fPort = port;
00231 SetName(fAddress.GetHostName());
00232 SetTitle(fService);
00233 fBytesSent = 0;
00234 fBytesRecv = 0;
00235 fCompress = 0;
00236 fTcpWindowSize = tcpwindowsize;
00237 fUUIDs = 0;
00238 fLastUsageMtx = 0;
00239
00240 fSocket = gSystem->OpenConnection(host, fAddress.GetPort(), tcpwindowsize);
00241 if (fSocket == -1) {
00242 fAddress.fPort = -1;
00243 } else {
00244 R__LOCKGUARD2(gROOTMutex);
00245 gROOT->GetListOfSockets()->Add(this);
00246 }
00247 }
00248
00249
00250 TSocket::TSocket(const char *sockpath) : TNamed(sockpath, "")
00251 {
00252
00253
00254
00255
00256
00257
00258 R__ASSERT(gROOT);
00259 R__ASSERT(gSystem);
00260
00261 fUrl = sockpath;
00262
00263 fService = "unix";
00264 fSecContext = 0;
00265 fRemoteProtocol= -1;
00266 fServType = kSOCKD;
00267 fAddress.fPort = -1;
00268 fName.Form("unix:%s", sockpath);
00269 SetTitle(fService);
00270 fBytesSent = 0;
00271 fBytesRecv = 0;
00272 fCompress = 0;
00273 fTcpWindowSize = -1;
00274 fUUIDs = 0;
00275 fLastUsageMtx = 0;
00276
00277 fSocket = gSystem->OpenConnection(sockpath, -1, -1);
00278 if (fSocket > 0) {
00279 R__LOCKGUARD2(gROOTMutex);
00280 gROOT->GetListOfSockets()->Add(this);
00281 }
00282 }
00283
00284
00285 TSocket::TSocket(Int_t desc) : TNamed("", "")
00286 {
00287
00288
00289
00290 R__ASSERT(gROOT);
00291 R__ASSERT(gSystem);
00292
00293 fSecContext = 0;
00294 fRemoteProtocol = 0;
00295 fService = (char *)kSOCKD;
00296 fServType = kSOCKD;
00297 fBytesSent = 0;
00298 fBytesRecv = 0;
00299 fCompress = 0;
00300 fTcpWindowSize = -1;
00301 fUUIDs = 0;
00302 fLastUsageMtx = 0;
00303
00304 if (desc >= 0) {
00305 fSocket = desc;
00306 fAddress = gSystem->GetPeerName(fSocket);
00307 R__LOCKGUARD2(gROOTMutex);
00308 gROOT->GetListOfSockets()->Add(this);
00309 } else
00310 fSocket = -1;
00311 }
00312
00313
00314 TSocket::TSocket(Int_t desc, const char *sockpath) : TNamed(sockpath, "")
00315 {
00316
00317
00318
00319
00320 R__ASSERT(gROOT);
00321 R__ASSERT(gSystem);
00322
00323 fUrl = sockpath;
00324
00325 fService = "unix";
00326 fSecContext = 0;
00327 fRemoteProtocol= -1;
00328 fServType = kSOCKD;
00329 fAddress.fPort = -1;
00330 fName.Form("unix:%s", sockpath);
00331 SetTitle(fService);
00332 fBytesSent = 0;
00333 fBytesRecv = 0;
00334 fCompress = 0;
00335 fTcpWindowSize = -1;
00336 fUUIDs = 0;
00337 fLastUsageMtx = 0;
00338
00339 if (desc >= 0) {
00340 fSocket = desc;
00341 R__LOCKGUARD2(gROOTMutex);
00342 gROOT->GetListOfSockets()->Add(this);
00343 } else
00344 fSocket = -1;
00345 }
00346
00347
00348
00349 TSocket::TSocket(const TSocket &s) : TNamed(s)
00350 {
00351
00352
00353 fSocket = s.fSocket;
00354 fService = s.fService;
00355 fAddress = s.fAddress;
00356 fLocalAddress = s.fLocalAddress;
00357 fBytesSent = s.fBytesSent;
00358 fBytesRecv = s.fBytesRecv;
00359 fCompress = s.fCompress;
00360 fSecContext = s.fSecContext;
00361 fRemoteProtocol = s.fRemoteProtocol;
00362 fServType = s.fServType;
00363 fUUIDs = 0;
00364 fLastUsageMtx = 0;
00365
00366 if (fSocket != -1) {
00367 R__LOCKGUARD2(gROOTMutex);
00368 gROOT->GetListOfSockets()->Add(this);
00369 }
00370 }
00371
00372
00373 void TSocket::Close(Option_t *option)
00374 {
00375
00376
00377
00378
00379
00380 Bool_t force = option ? (!strcmp(option, "force") ? kTRUE : kFALSE) : kFALSE;
00381
00382 if (fSocket != -1) {
00383 gSystem->CloseConnection(fSocket, force);
00384 R__LOCKGUARD2(gROOTMutex);
00385 gROOT->GetListOfSockets()->Remove(this);
00386 }
00387 fSocket = -1;
00388
00389 SafeDelete(fUUIDs);
00390 SafeDelete(fLastUsageMtx);
00391 }
00392
00393
00394 TInetAddress TSocket::GetLocalInetAddress()
00395 {
00396
00397
00398
00399 if (IsValid()) {
00400 if (fLocalAddress.GetPort() == -1)
00401 fLocalAddress = gSystem->GetSockName(fSocket);
00402 return fLocalAddress;
00403 }
00404 return TInetAddress();
00405 }
00406
00407
00408 Int_t TSocket::GetLocalPort()
00409 {
00410
00411
00412
00413 if (IsValid()) {
00414 if (fLocalAddress.GetPort() == -1)
00415 GetLocalInetAddress();
00416 return fLocalAddress.GetPort();
00417 }
00418 return -1;
00419 }
00420
00421
00422 Int_t TSocket::Select(Int_t interest, Long_t timeout)
00423 {
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433 Int_t rc = 1;
00434
00435
00436 TFileHandler fh(fSocket, interest);
00437
00438
00439 rc = gSystem->Select(&fh, timeout);
00440
00441 return rc;
00442 }
00443
00444
00445 Int_t TSocket::Send(Int_t kind)
00446 {
00447
00448
00449
00450
00451
00452
00453 TMessage mess(kind);
00454
00455 Int_t nsent;
00456 if ((nsent = Send(mess)) < 0)
00457 return -1;
00458
00459 return nsent;
00460 }
00461
00462
00463 Int_t TSocket::Send(Int_t status, Int_t kind)
00464 {
00465
00466
00467
00468
00469
00470
00471 TMessage mess(kind);
00472 mess << status;
00473
00474 Int_t nsent;
00475 if ((nsent = Send(mess)) < 0)
00476 return -1;
00477
00478 return nsent;
00479 }
00480
00481
00482 Int_t TSocket::Send(const char *str, Int_t kind)
00483 {
00484
00485
00486
00487
00488
00489
00490 TMessage mess(kind);
00491 if (str) mess.WriteString(str);
00492
00493 Int_t nsent;
00494 if ((nsent = Send(mess)) < 0)
00495 return -1;
00496
00497 return nsent - sizeof(Int_t);
00498 }
00499
00500
00501 Int_t TSocket::Send(const TMessage &mess)
00502 {
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 TSystem::ResetErrno();
00513
00514 if (fSocket == -1) return -1;
00515
00516 if (mess.IsReading()) {
00517 Error("Send", "cannot send a message used for reading");
00518 return -1;
00519 }
00520
00521
00522 SendStreamerInfos(mess);
00523
00524
00525 SendProcessIDs(mess);
00526
00527 mess.SetLength();
00528
00529 if (fCompress > 0 && mess.GetCompressionLevel() == 0)
00530 const_cast<TMessage&>(mess).SetCompressionLevel(fCompress);
00531
00532 if (mess.GetCompressionLevel() > 0)
00533 const_cast<TMessage&>(mess).Compress();
00534
00535 char *mbuf = mess.Buffer();
00536 Int_t mlen = mess.Length();
00537 if (mess.CompBuffer()) {
00538 mbuf = mess.CompBuffer();
00539 mlen = mess.CompLength();
00540 }
00541
00542 Int_t nsent;
00543 if ((nsent = gSystem->SendRaw(fSocket, mbuf, mlen, 0)) <= 0) {
00544 if (nsent == -5) {
00545
00546 Close();
00547 }
00548 return nsent;
00549 }
00550
00551 fBytesSent += nsent;
00552 fgBytesSent += nsent;
00553
00554
00555 if (mess.What() & kMESS_ACK) {
00556 TSystem::ResetErrno();
00557 char buf[2];
00558 Int_t n = 0;
00559 if ((n = gSystem->RecvRaw(fSocket, buf, sizeof(buf), 0)) < 0) {
00560 if (n == -5) {
00561
00562 Close();
00563 } else
00564 n = -1;
00565 return n;
00566 }
00567 if (strncmp(buf, "ok", 2)) {
00568 Error("Send", "bad acknowledgement");
00569 return -1;
00570 }
00571 fBytesRecv += 2;
00572 fgBytesRecv += 2;
00573 }
00574
00575 Touch();
00576
00577 return nsent - sizeof(UInt_t);
00578 }
00579
00580
00581 Int_t TSocket::SendObject(const TObject *obj, Int_t kind)
00582 {
00583
00584
00585
00586
00587
00588
00589 TMessage mess(kind);
00590 mess.WriteObject(obj);
00591
00592
00593 Int_t nsent;
00594 if ((nsent = Send(mess)) < 0)
00595 return -1;
00596
00597 return nsent;
00598 }
00599
00600
00601 Int_t TSocket::SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt)
00602 {
00603
00604
00605
00606
00607
00608 TSystem::ResetErrno();
00609
00610 if (fSocket == -1) return -1;
00611
00612 Int_t nsent;
00613
00614 if ((nsent = gSystem->SendRaw(fSocket, buffer, length, (int) opt)) <= 0) {
00615 if (nsent == -5) {
00616
00617 Close();
00618 }
00619 return nsent;
00620 }
00621
00622 fBytesSent += nsent;
00623 fgBytesSent += nsent;
00624
00625 Touch();
00626
00627 return nsent;
00628 }
00629
00630
00631 void TSocket::SendStreamerInfos(const TMessage &mess)
00632 {
00633
00634
00635
00636
00637 if (mess.fInfos && mess.fInfos->GetEntries()) {
00638 TIter next(mess.fInfos);
00639 TStreamerInfo *info;
00640 TList *minilist = 0;
00641 while ((info = (TStreamerInfo*)next())) {
00642 Int_t uid = info->GetNumber();
00643 if (fBitsInfo.TestBitNumber(uid))
00644 continue;
00645 fBitsInfo.SetBitNumber(uid);
00646 if (!minilist)
00647 minilist = new TList();
00648 if (gDebug > 0)
00649 Info("SendStreamerInfos", "sending TStreamerInfo: %s, version = %d",
00650 info->GetName(),info->GetClassVersion());
00651 minilist->Add(info);
00652 }
00653 if (minilist) {
00654 TMessage messinfo(kMESS_STREAMERINFO);
00655 messinfo.WriteObject(minilist);
00656 delete minilist;
00657 if (messinfo.fInfos)
00658 messinfo.fInfos->Clear();
00659 Send(messinfo);
00660 }
00661 }
00662 }
00663
00664
00665 void TSocket::SendProcessIDs(const TMessage &mess)
00666 {
00667
00668
00669
00670
00671 if (mess.TestBitNumber(0)) {
00672 TObjArray *pids = TProcessID::GetPIDs();
00673 Int_t npids = pids->GetEntries();
00674 TProcessID *pid;
00675 TList *minilist = 0;
00676 for (Int_t ipid = 0; ipid < npids; ipid++) {
00677 pid = (TProcessID*)pids->At(ipid);
00678 if (!pid || !mess.TestBitNumber(pid->GetUniqueID()+1))
00679 continue;
00680
00681
00682 if (!fUUIDs) {
00683 fUUIDs = new TList();
00684 } else {
00685 if (fUUIDs->FindObject(pid->GetTitle()))
00686 continue;
00687 }
00688 fUUIDs->Add(new TObjString(pid->GetTitle()));
00689 if (!minilist)
00690 minilist = new TList();
00691 if (gDebug > 0)
00692 Info("SendProcessIDs", "sending TProcessID: %s", pid->GetTitle());
00693 minilist->Add(pid);
00694 }
00695 if (minilist) {
00696 TMessage messpid(kMESS_PROCESSID);
00697 messpid.WriteObject(minilist);
00698 delete minilist;
00699 Send(messpid);
00700 }
00701 }
00702 }
00703
00704
00705 Int_t TSocket::Recv(char *str, Int_t max)
00706 {
00707
00708
00709
00710
00711
00712
00713 Int_t n, kind;
00714
00715 if ((n = Recv(str, max, kind)) <= 0) {
00716 if (n == -5)
00717 n = -1;
00718 return n;
00719 }
00720
00721 if (kind != kMESS_STRING) {
00722 Error("Recv", "got message of wrong kind (expected %d, got %d)",
00723 kMESS_STRING, kind);
00724 return -1;
00725 }
00726
00727 return n;
00728 }
00729
00730
00731 Int_t TSocket::Recv(char *str, Int_t max, Int_t &kind)
00732 {
00733
00734
00735
00736
00737
00738 Int_t n;
00739 TMessage *mess;
00740
00741 if ((n = Recv(mess)) <= 0) {
00742 if (n == -5)
00743 n = -1;
00744 return n;
00745 }
00746
00747 kind = mess->What();
00748 if (str) {
00749 if (mess->BufferSize() > (Int_t)sizeof(Int_t))
00750 mess->ReadString(str, max);
00751 else
00752 str[0] = 0;
00753 }
00754
00755 delete mess;
00756
00757 return n;
00758 }
00759
00760
00761 Int_t TSocket::Recv(Int_t &status, Int_t &kind)
00762 {
00763
00764
00765
00766
00767
00768 Int_t n;
00769 TMessage *mess;
00770
00771 if ((n = Recv(mess)) <= 0) {
00772 if (n == -5)
00773 n = -1;
00774 return n;
00775 }
00776
00777 kind = mess->What();
00778 (*mess) >> status;
00779
00780 delete mess;
00781
00782 return n;
00783 }
00784
00785
00786 Int_t TSocket::Recv(TMessage *&mess)
00787 {
00788
00789
00790
00791
00792
00793
00794 TSystem::ResetErrno();
00795
00796 if (fSocket == -1) {
00797 mess = 0;
00798 return -1;
00799 }
00800
00801 oncemore:
00802 Int_t n;
00803 UInt_t len;
00804 if ((n = gSystem->RecvRaw(fSocket, &len, sizeof(UInt_t), 0)) <= 0) {
00805 if (n == 0 || n == -5) {
00806
00807 Close();
00808 }
00809 mess = 0;
00810 return n;
00811 }
00812 len = net2host(len);
00813
00814 char *buf = new char[len+sizeof(UInt_t)];
00815 if ((n = gSystem->RecvRaw(fSocket, buf+sizeof(UInt_t), len, 0)) <= 0) {
00816 if (n == 0 || n == -5) {
00817
00818 Close();
00819 }
00820 delete [] buf;
00821 mess = 0;
00822 return n;
00823 }
00824
00825 fBytesRecv += n + sizeof(UInt_t);
00826 fgBytesRecv += n + sizeof(UInt_t);
00827
00828 mess = new TMessage(buf, len+sizeof(UInt_t));
00829
00830
00831 if (RecvStreamerInfos(mess))
00832 goto oncemore;
00833
00834
00835 if (RecvProcessIDs(mess))
00836 goto oncemore;
00837
00838 if (mess->What() & kMESS_ACK) {
00839 char ok[2] = { 'o', 'k' };
00840 Int_t n2 = 0;
00841 if ((n2 = gSystem->SendRaw(fSocket, ok, sizeof(ok), 0)) < 0) {
00842 if (n2 == -5) {
00843
00844 Close();
00845 }
00846 delete mess;
00847 mess = 0;
00848 return n2;
00849 }
00850 mess->SetWhat(mess->What() & ~kMESS_ACK);
00851
00852 fBytesSent += 2;
00853 fgBytesSent += 2;
00854 }
00855
00856 Touch();
00857
00858 return n;
00859 }
00860
00861
00862 Int_t TSocket::RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt)
00863 {
00864
00865
00866
00867
00868
00869
00870
00871 TSystem::ResetErrno();
00872
00873 if (fSocket == -1) return -1;
00874 if (length == 0) return 0;
00875
00876 Int_t n;
00877
00878 if ((n = gSystem->RecvRaw(fSocket, buffer, length, (int) opt)) <= 0) {
00879 if (n == 0 || n == -5) {
00880
00881 Close();
00882 }
00883 return n;
00884 }
00885
00886 fBytesRecv += n;
00887 fgBytesRecv += n;
00888
00889 Touch();
00890
00891 return n;
00892 }
00893
00894
00895 Bool_t TSocket::RecvStreamerInfos(TMessage *mess)
00896 {
00897
00898
00899
00900
00901 if (mess->What() == kMESS_STREAMERINFO) {
00902 TList *list = (TList*)mess->ReadObject(TList::Class());
00903 TIter next(list);
00904 TStreamerInfo *info;
00905 TObjLink *lnk = list->FirstLink();
00906
00907 while (lnk) {
00908 info = (TStreamerInfo*)lnk->GetObject();
00909 TObject *element = info->GetElements()->UncheckedAt(0);
00910 Bool_t isstl = element && strcmp("This",element->GetName())==0;
00911 if (!isstl) {
00912 info->BuildCheck();
00913 if (gDebug > 0)
00914 Info("RecvStreamerInfos", "importing TStreamerInfo: %s, version = %d",
00915 info->GetName(), info->GetClassVersion());
00916 }
00917 lnk = lnk->Next();
00918 }
00919
00920 lnk = list->FirstLink();
00921 while (lnk) {
00922 info = (TStreamerInfo*)lnk->GetObject();
00923 TObject *element = info->GetElements()->UncheckedAt(0);
00924 Bool_t isstl = element && strcmp("This",element->GetName())==0;
00925 if (isstl) {
00926 info->BuildCheck();
00927 if (gDebug > 0)
00928 Info("RecvStreamerInfos", "importing TStreamerInfo: %s, version = %d",
00929 info->GetName(), info->GetClassVersion());
00930 }
00931 lnk = lnk->Next();
00932 }
00933 delete list;
00934 delete mess;
00935
00936 return kTRUE;
00937 }
00938 return kFALSE;
00939 }
00940
00941
00942 Bool_t TSocket::RecvProcessIDs(TMessage *mess)
00943 {
00944
00945
00946
00947
00948 if (mess->What() == kMESS_PROCESSID) {
00949 TList *list = (TList*)mess->ReadObject(TList::Class());
00950 TIter next(list);
00951 TProcessID *pid;
00952 while ((pid = (TProcessID*)next())) {
00953
00954 TObjArray *pidslist = TProcessID::GetPIDs();
00955 TIter nextpid(pidslist);
00956 TProcessID *p;
00957 while ((p = (TProcessID*)nextpid())) {
00958 if (!strcmp(p->GetTitle(), pid->GetTitle())) {
00959 delete pid;
00960 pid = 0;
00961 break;
00962 }
00963 }
00964 if (pid) {
00965 if (gDebug > 0)
00966 Info("RecvProcessIDs", "importing TProcessID: %s", pid->GetTitle());
00967 pid->IncrementCount();
00968 pidslist->Add(pid);
00969 Int_t ind = pidslist->IndexOf(pid);
00970 pid->SetUniqueID((UInt_t)ind);
00971 }
00972 }
00973 delete list;
00974 delete mess;
00975
00976 return kTRUE;
00977 }
00978 return kFALSE;
00979 }
00980
00981
00982 Int_t TSocket::SetOption(ESockOptions opt, Int_t val)
00983 {
00984
00985
00986 if (fSocket == -1) return -1;
00987
00988 return gSystem->SetSockOpt(fSocket, opt, val);
00989 }
00990
00991
00992 Int_t TSocket::GetOption(ESockOptions opt, Int_t &val)
00993 {
00994
00995
00996 if (fSocket == -1) return -1;
00997
00998 return gSystem->GetSockOpt(fSocket, opt, &val);
00999 }
01000
01001
01002 Int_t TSocket::GetErrorCode() const
01003 {
01004
01005
01006
01007
01008 if (!IsValid())
01009 return fSocket;
01010
01011 return 0;
01012 }
01013
01014
01015 void TSocket::SetCompressionLevel(Int_t level)
01016 {
01017
01018
01019
01020
01021
01022 if (level < 0) level = 0;
01023 if (level > 9) level = 9;
01024
01025 fCompress = level;
01026 }
01027
01028
01029 Bool_t TSocket::Authenticate(const char *user)
01030 {
01031
01032
01033 Bool_t rc = kFALSE;
01034
01035
01036 TString sproto = TUrl(fUrl).GetProtocol();
01037 if (sproto.Contains("sockd")) {
01038 fServType = kSOCKD;
01039 } else if (sproto.Contains("rootd")) {
01040 fServType = kROOTD;
01041 } else if (sproto.Contains("proofd")) {
01042 fServType = kPROOFD;
01043
01044 TString opt(TUrl(fUrl).GetOptions());
01045
01046 if (!strncasecmp(opt, "S", 1)) {
01047 Send("slave");
01048 } else if (!strncasecmp(opt, "M", 1)) {
01049 Send("master");
01050 } else {
01051 Warning("Authenticate",
01052 "called by TSlave: unknown option '%c' %s",
01053 opt[0], " - assuming Slave");
01054 Send("slave");
01055 }
01056 }
01057 if (gDebug > 2)
01058 Info("Authenticate","Local protocol: %s",sproto.Data());
01059
01060
01061 Int_t kind = kROOTD_PROTOCOL;
01062
01063
01064
01065 if (fRemoteProtocol == -1) {
01066 Send(Form(" %d", fgClientProtocol), kROOTD_PROTOCOL);
01067 Recv(fRemoteProtocol, kind);
01068
01069
01070
01071
01072 if (kind == kROOTD_ERR) {
01073 fRemoteProtocol = 9;
01074 return kFALSE;
01075 }
01076 }
01077
01078
01079 Bool_t runauth = kTRUE;
01080 if (fRemoteProtocol > 1000) {
01081
01082 runauth = kFALSE;
01083 fRemoteProtocol %= 1000;
01084 }
01085
01086
01087
01088 TString host = GetInetAddress().GetHostName();
01089 if (runauth) {
01090
01091
01092 TString alib = "Xrd";
01093 if (fRemoteProtocol < 100) {
01094
01095 alib = "Root";
01096 }
01097
01098
01099 TPluginHandler *h =
01100 gROOT->GetPluginManager()->FindHandler("TVirtualAuth", alib);
01101 if (!h || h->LoadPlugin() != 0) {
01102 Error("Authenticate",
01103 "could not load properly %s authentication plugin", alib.Data());
01104 return rc;
01105 }
01106
01107
01108 TVirtualAuth *auth = (TVirtualAuth *)(h->ExecPlugin(0));
01109 if (!auth) {
01110 Error("Authenticate", "could not instantiate the interface class");
01111 return rc;
01112 }
01113 if (gDebug > 1)
01114 Info("Authenticate", "class for '%s' authentication loaded", alib.Data());
01115
01116 Option_t *opts = (gROOT->IsProofServ()) ? "P" : "";
01117 if (!(auth->Authenticate(this, host, user, opts))) {
01118 Error("Authenticate",
01119 "authentication attempt failed for %s@%s", user, host.Data());
01120 } else {
01121 rc = kTRUE;
01122 }
01123 } else {
01124
01125
01126 UserGroup_t *u = gSystem->GetUserInfo();
01127 if (u) {
01128 Send(Form("%s %s", u->fUser.Data(), user), kROOTD_USER);
01129 delete u;
01130 } else
01131 Send(Form("-1 %s", user), kROOTD_USER);
01132
01133 rc = kFALSE;
01134
01135
01136 Int_t stat;
01137 if (Recv(stat, kind) > 0) {
01138
01139 if (kind == kROOTD_ERR) {
01140 if (gDebug > 0)
01141 TSocket::NetError("TSocket::Authenticate", stat);
01142 } else if (kind == kROOTD_AUTH) {
01143
01144
01145
01146 fSecContext = new TSecContext(user, host, 0, -4, 0, 0);
01147 if (gDebug > 3)
01148 Info("Authenticate", "no authentication required remotely");
01149
01150
01151 rc = 1;
01152 } else {
01153 if (gDebug > 0)
01154 Info("Authenticate", "expected message type %d, received %d",
01155 kROOTD_AUTH, kind);
01156 }
01157 } else {
01158 if (gDebug > 0)
01159 Info("Authenticate", "error receiving message");
01160 }
01161
01162 }
01163
01164 return rc;
01165 }
01166
01167
01168 TSocket *TSocket::CreateAuthSocket(const char *url, Int_t size,
01169 Int_t tcpwindowsize, TSocket *opensock)
01170 {
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219 R__LOCKGUARD2(gSocketAuthMutex);
01220
01221
01222 TString eurl(url);
01223
01224
01225 Bool_t parallel = kFALSE;
01226 TString proto(TUrl(url).GetProtocol());
01227 TString protosave = proto;
01228
01229
01230 TString asfx = "";
01231 if (proto.EndsWith("up") || proto.EndsWith("ug")) {
01232 asfx = proto;
01233 asfx.Remove(0,proto.Length()-2);
01234 proto.Resize(proto.Length()-2);
01235 } else if (proto.EndsWith("s") || proto.EndsWith("k") ||
01236 proto.EndsWith("g") || proto.EndsWith("h")) {
01237 asfx = proto;
01238 asfx.Remove(0,proto.Length()-1);
01239 proto.Resize(proto.Length()-1);
01240 }
01241
01242
01243 if (((proto.EndsWith("p") || size > 1) &&
01244 !proto.BeginsWith("proof")) ||
01245 proto.BeginsWith("root") ) {
01246 parallel = kTRUE;
01247 if (proto.EndsWith("p"))
01248 proto.Resize(proto.Length()-1);
01249 }
01250
01251
01252 if (!proto.BeginsWith("sock") && !proto.BeginsWith("proof") &&
01253 !proto.BeginsWith("root"))
01254 proto = "sockd";
01255
01256
01257 protosave += "://";
01258 proto += asfx;
01259 proto += "://";
01260 eurl.ReplaceAll(protosave,proto);
01261
01262
01263
01264 TSocket *sock = 0;
01265 if (!parallel) {
01266
01267
01268 if (opensock && opensock->IsValid())
01269 sock = opensock;
01270 else
01271 sock = new TSocket(eurl, TUrl(url).GetPort(), tcpwindowsize);
01272
01273
01274 if (sock && sock->IsValid()) {
01275 if (!sock->Authenticate(TUrl(url).GetUser())) {
01276 sock->Close();
01277 delete sock;
01278 sock = 0;
01279 }
01280 }
01281
01282 } else {
01283
01284
01285
01286
01287 if (eurl.Contains("?"))
01288 eurl.Resize(eurl.Index("?"));
01289 eurl += "?A";
01290
01291
01292 if (opensock && opensock->IsValid())
01293 sock = new TPSocket(eurl, TUrl(url).GetPort(), size, opensock);
01294 else
01295 sock = new TPSocket(eurl, TUrl(url).GetPort(), size, tcpwindowsize);
01296
01297
01298 if (sock && !sock->IsAuthenticated()) {
01299
01300 if (sock->IsValid())
01301
01302
01303
01304 delete sock;
01305 sock = 0;
01306 }
01307 }
01308
01309 return sock;
01310 }
01311
01312
01313 TSocket *TSocket::CreateAuthSocket(const char *user, const char *url,
01314 Int_t port, Int_t size, Int_t tcpwindowsize,
01315 TSocket *opensock)
01316 {
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360 R__LOCKGUARD2(gSocketAuthMutex);
01361
01362
01363 TString eurl;
01364
01365
01366 if (TString(TUrl(url).GetProtocol()).Length() > 0) {
01367 eurl += TString(TUrl(url).GetProtocol());
01368 eurl += TString("://");
01369 }
01370
01371 if (!user || strlen(user) > 0) {
01372 eurl += TString(user);
01373 eurl += TString("@");
01374 }
01375
01376 eurl += TString(TUrl(url).GetHost());
01377
01378 eurl += TString(":");
01379 eurl += (port > 0 ? port : 0);
01380
01381 if (TString(TUrl(url).GetOptions()).Length() > 0) {
01382 eurl += TString("/?");
01383 eurl += TString(TUrl(url).GetOptions());
01384 }
01385
01386
01387 return TSocket::CreateAuthSocket(eurl,size,tcpwindowsize,opensock);
01388 }
01389
01390
01391 Int_t TSocket::GetClientProtocol()
01392 {
01393
01394
01395 return fgClientProtocol;
01396 }
01397
01398
01399 void TSocket::NetError(const char *where, Int_t err)
01400 {
01401
01402
01403
01404 err = (err < kErrError) ? ((err > -1) ? err : 0) : kErrError;
01405
01406 if (gDebug > 0)
01407 ::Error(where, "%s", gRootdErrStr[err]);
01408 }
01409
01410
01411 ULong64_t TSocket::GetSocketBytesSent()
01412 {
01413
01414
01415 return fgBytesSent;
01416 }
01417
01418
01419 ULong64_t TSocket::GetSocketBytesRecv()
01420 {
01421
01422
01423 return fgBytesRecv;
01424 }