Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
XrdClientConn.hh
Go to the documentation of this file.
1 #ifndef XRD_CONN_H
2 #define XRD_CONN_H
3 /******************************************************************************/
4 /* */
5 /* X r d C l i e n t C o n n . h h */
6 /* */
7 /* Author: Fabrizio Furano (INFN Padova, 2004) */
8 /* Adapted from TXNetFile (root.cern.ch) originally done by */
9 /* Alvise Dorigo, Fabrizio Furano */
10 /* INFN Padova, 2003 */
11 /* */
12 /* This file is part of the XRootD software suite. */
13 /* */
14 /* XRootD is free software: you can redistribute it and/or modify it under */
15 /* the terms of the GNU Lesser General Public License as published by the */
16 /* Free Software Foundation, either version 3 of the License, or (at your */
17 /* option) any later version. */
18 /* */
19 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
20 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
21 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
22 /* License for more details. */
23 /* */
24 /* You should have received a copy of the GNU Lesser General Public License */
25 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
26 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
27 /* */
28 /* The copyright holder's institutional names and contributor's names may not */
29 /* be used to endorse or promote products derived from this software without */
30 /* specific prior written permission of the institution or contributor. */
31 /******************************************************************************/
32 
33 //////////////////////////////////////////////////////////////////////////
34 // //
35 // High level handler of connections to xrootd. //
36 // //
37 //////////////////////////////////////////////////////////////////////////
38 
40 
41 #include "time.h"
46 #include "XrdOuc/XrdOucHash.hh"
47 #include "XrdSys/XrdSysPthread.hh"
48 
49 #define ConnectionManager XrdClientConn::GetConnectionMgr()
50 
51 class XrdClientAbs;
52 class XrdSecProtocol;
53 
54 class XrdClientConn {
55 
56 public:
57 
58  enum ESrvErrorHandlerRetval {
59  kSEHRReturnMsgToCaller = 0,
60  kSEHRBreakLoop = 1,
61  kSEHRContinue = 2,
62  kSEHRReturnNoMsgToCaller = 3,
63  kSEHRRedirLimitReached = 4
64  };
65  enum EThreeStateReadHandler {
66  kTSRHReturnMex = 0,
67  kTSRHReturnNullMex = 1,
68  kTSRHContinue = 2
69  };
70 
71  // To keep info about an open session
72  struct SessionIDInfo {
73  char id[16];
74  };
75 
76  int fLastDataBytesRecv;
77  int fLastDataBytesSent;
78  XErrorCode fOpenError;
79 
80  XrdOucString fRedirOpaque; // Opaque info returned by the server when
81 
82  // redirecting. To be used in the next opens
83  XrdClientConn();
84  virtual ~XrdClientConn();
85 
86  inline bool CacheWillFit(long long bytes) {
87  if (!fMainReadCache)
88  return FALSE;
89  return fMainReadCache->WillFit(bytes);
90  }
91 
92  bool CheckHostDomain(XrdOucString hostToCheck);
93  short Connect(XrdClientUrlInfo Host2Conn,
94  XrdClientAbsUnsolMsgHandler *unsolhandler);
95  void Disconnect(bool ForcePhysicalDisc);
96  virtual bool GetAccessToSrv();
97  XReqErrorType GoBackToRedirector();
98 
99  XrdOucString GetClientHostDomain() { return fgClientHostDomain; }
100 
101 
102  static XrdClientPhyConnection *GetPhyConn(int LogConnID);
103 
104 
105  // --------- Cache related stuff
106 
107  long GetDataFromCache(const void *buffer,
108  long long begin_offs,
109  long long end_offs,
110  bool PerfCalc,
111  XrdClientIntvList &missingblks,
112  long &outstandingblks );
113 
114  bool SubmitDataToCache(XrdClientMessage *xmsg,
115  long long begin_offs,
116  long long end_offs);
117 
118  bool SubmitRawDataToCache(const void *buffer,
119  long long begin_offs,
120  long long end_offs);
121 
122  void SubmitPlaceholderToCache(long long begin_offs,
123  long long end_offs) {
124  if (fMainReadCache)
125  fMainReadCache->PutPlaceholder(begin_offs, end_offs);
126  }
127 
128 
129  void RemoveAllDataFromCache(bool keepwriteblocks=true) {
130  if (fMainReadCache)
131  fMainReadCache->RemoveItems(keepwriteblocks);
132  }
133 
134  void RemoveDataFromCache(long long begin_offs,
135  long long end_offs, bool remove_overlapped = false) {
136  if (fMainReadCache)
137  fMainReadCache->RemoveItems(begin_offs, end_offs, remove_overlapped);
138  }
139 
140  void RemovePlaceholdersFromCache() {
141  if (fMainReadCache)
142  fMainReadCache->RemovePlaceholders();
143  }
144 
145  void PrintCache() {
146  if (fMainReadCache)
147  fMainReadCache->PrintCache();
148  }
149 
150 
151  bool GetCacheInfo(
152  // The actual cache size
153  int &size,
154 
155  // The number of bytes submitted since the beginning
156  long long &bytessubmitted,
157 
158  // The number of bytes found in the cache (estimate)
159  long long &byteshit,
160 
161  // The number of reads which did not find their data
162  // (estimate)
163  long long &misscount,
164 
165  // miss/totalreads ratio (estimate)
166  float &missrate,
167 
168  // number of read requests towards the cache
169  long long &readreqcnt,
170 
171  // ratio between bytes found / bytes submitted
172  float &bytesusefulness
173  ) {
174  if (!fMainReadCache) return false;
175 
176  fMainReadCache->GetInfo(size,
177  bytessubmitted,
178  byteshit,
179  misscount,
180  missrate,
181  readreqcnt,
182  bytesusefulness);
183  return true;
184  }
185 
186 
187  void SetCacheSize(int CacheSize) {
188  if (!fMainReadCache && CacheSize)
189  fMainReadCache = new XrdClientReadCache();
190 
191  if (fMainReadCache)
192  fMainReadCache->SetSize(CacheSize);
193  }
194 
195  void SetCacheRmPolicy(int RmPolicy) {
196  if (fMainReadCache)
197  fMainReadCache->SetBlkRemovalPolicy(RmPolicy);
198  }
199 
200  void UnPinCacheBlk(long long begin_offs, long long end_offs) {
201  fMainReadCache->UnPinCacheBlk(begin_offs, end_offs);
202  // Also use this to signal the possibility to proceed for a hard checkpoint
203  fWriteWaitAck->Broadcast();
204  }
205 
206 
207  // -------------------
208 
209 
210  int GetLogConnID() const { return fLogConnID; }
211 
212  ERemoteServerType GetServerType() const { return fServerType; }
213 
214  kXR_unt16 GetStreamID() const { return fPrimaryStreamid; }
215 
216  inline XrdClientUrlInfo *GetLBSUrl() { return fLBSUrl; }
217  inline XrdClientUrlInfo *GetMetaUrl() { return fMetaUrl; }
218  inline XrdClientUrlInfo GetCurrentUrl() { return fUrl; }
219  inline XrdClientUrlInfo GetRedirUrl() { return fREQUrl; }
220 
221  XErrorCode GetOpenError() const { return fOpenError; }
222  virtual XReqErrorType GoToAnotherServer(XrdClientUrlInfo &newdest);
223  virtual XReqErrorType GoToMetaManager();
224  bool IsConnected() const { return fConnected; }
225  bool IsPhyConnConnected();
226 
227  struct ServerResponseHeader
228  LastServerResp;
229 
230  struct ServerResponseBody_Error
231  LastServerError;
232 
233  void ClearLastServerError() {
234  memset(&LastServerError, 0, sizeof(LastServerError));
235  LastServerError.errnum = kXR_noErrorYet;
236  }
237 
238  UnsolRespProcResult ProcessAsynResp(XrdClientMessage *unsolmsg);
239 
240  virtual bool SendGenCommand(ClientRequest *req,
241  const void *reqMoreData,
242  void **answMoreDataAllocated,
243  void *answMoreData, bool HasToAlloc,
244  char *CmdName, int substreamid = 0);
245 
246  int GetOpenSockFD() const { return fOpenSockFD; }
247 
248  void SetClientHostDomain(const char *src) { fgClientHostDomain = src; }
249  void SetConnected(bool conn) { fConnected = conn; }
250 
251  void SetOpenError(XErrorCode err) { fOpenError = err; }
252 
253  // Gets a parallel stream id to use to set the return path for a re
254  int GetParallelStreamToUse(int reqsperstream);
255  int GetParallelStreamCount(); // Returns the total number of connected streams
256 
257  void SetRedirHandler(XrdClientAbs *rh) { fRedirHandler = rh; }
258 
259  void SetRequestedDestHost(char *newh, kXR_int32 port) {
260  fREQUrl = fUrl;
261  fREQUrl.Host = newh;
262  fREQUrl.Port = port;
263  fREQUrl.SetAddrFromHost();
264  }
265 
266  // Puts this instance in pause state for wsec seconds.
267  // A value <= 0 revokes immediately the pause state
268  void SetREQPauseState(kXR_int32 wsec) {
269  // Lock mutex
270  fREQWait->Lock();
271 
272  if (wsec > 0)
273  fREQWaitTimeLimit = time(0) + wsec;
274  else {
275  fREQWaitTimeLimit = 0;
276  fREQWait->Broadcast();
277  }
278 
279  // UnLock mutex
280  fREQWait->UnLock();
281  }
282 
283  // Puts this instance in connect-pause state for wsec seconds.
284  // Any future connection attempt will not happen before wsec
285  // and the first one will be towards the given host
286  void SetREQDelayedConnectState(kXR_int32 wsec) {
287  // Lock mutex
288  fREQConnectWait->Lock();
289 
290  if (wsec > 0)
291  fREQConnectWaitTimeLimit = time(0) + wsec;
292  else {
293  fREQConnectWaitTimeLimit = 0;
294  fREQConnectWait->Broadcast();
295  }
296 
297  // UnLock mutex
298  fREQConnectWait->UnLock();
299  }
300 
301  void SetSID(kXR_char *sid);
302  inline void SetUrl(XrdClientUrlInfo thisUrl) { fUrl = thisUrl; }
303 
304  // Sends the request to the server, through logconn with ID LogConnID
305  // The request is sent with a streamid 'child' of the current one, then marked as pending
306  // Its answer will be caught asynchronously
307  XReqErrorType WriteToServer_Async(ClientRequest *req,
308  const void* reqMoreData,
309  int substreamid = 0);
310 
311  static XrdClientConnectionMgr *GetConnectionMgr()
312  { return fgConnectionMgr;} //Instance of the conn manager
313 
314  static void DelSessionIDRepo() {fSessionIDRMutex.Lock();
315  fSessionIDRepo.Purge();
316  fSessionIDRMutex.UnLock();
317  }
318 
319  void GetSessionID(SessionIDInfo &sess) {sess = mySessionID;}
320 
321  long GetServerProtocol() { return fServerProto; }
322 
323  short GetMaxRedirCnt() const { return fMaxGlobalRedirCnt; }
324  void SetMaxRedirCnt(short mx) {fMaxGlobalRedirCnt = mx; }
325  short GetRedirCnt() const { return fGlobalRedirCnt; }
326 
327  bool DoWriteSoftCheckPoint();
328  bool DoWriteHardCheckPoint();
329  void UnPinCacheBlk();
330 
331 
332  // To give a max number of seconds for an operation to complete, no matter what happens inside
333  // e.g. redirections, sleeps, failed connection attempts etc.
334  void SetOpTimeLimit(int delta_secs);
335  bool IsOpTimeLimitElapsed(time_t timenow);
336 
337 
338 protected:
339  void SetLogConnID(int cid) { fLogConnID = cid; }
340  void SetStreamID(kXR_unt16 sid) { fPrimaryStreamid = sid; }
341 
342 
343 
344  // The handler which first tried to connect somewhere
345  XrdClientAbsUnsolMsgHandler *fUnsolMsgHandler;
346 
347  XrdClientUrlInfo fUrl; // The current URL
348  XrdClientUrlInfo *fLBSUrl; // Needed to save the load balancer url
349  XrdClientUrlInfo fREQUrl; // For explicitly requested redirs
350 
351  short fGlobalRedirCnt; // Number of redirections
352 
353 private:
354 
355  static XrdOucString fgClientHostDomain; // Save the client's domain name
356  bool fConnected;
357  bool fGettingAccessToSrv; // To avoid recursion in desperate situations
358  time_t fGlobalRedirLastUpdateTimestamp; // Timestamp of last redirection
359 
360  int fLogConnID; // Logical connection ID used
361  kXR_unt16 fPrimaryStreamid; // Streamid used for normal communication
362  // NB it's a copy of the one contained in
363  // the logconn
364 
365  short fMaxGlobalRedirCnt;
366  XrdClientReadCache *fMainReadCache;
367 
368  // The time limit for a transaction
369  time_t fOpTimeLimit;
370 
371  XrdClientAbs *fRedirHandler; // Pointer to a class inheriting from
372  // XrdClientAbs providing methods
373  // to handle a redir at higher level
374 
375  XrdOucString fRedirInternalToken; // Token returned by the server when
376  // redirecting. To be used in the next logins
377 
378  XrdSysCondVar *fREQWaitResp; // For explicitly requested delayed async responses
379  ServerResponseBody_Attn_asynresp *
380  fREQWaitRespData; // For explicitly requested delayed async responses
381 
382  time_t fREQWaitTimeLimit; // For explicitly requested pause state
383  XrdSysCondVar *fREQWait; // For explicitly requested pause state
384  time_t fREQConnectWaitTimeLimit; // For explicitly requested delayed reconnect
385  XrdSysCondVar *fREQConnectWait; // For explicitly requested delayed reconnect
386 
387  long fServerProto; // The server protocol
388  ERemoteServerType fServerType; // Server type as returned by doHandShake()
389  SessionIDInfo mySessionID; // Login session ID
390 
391 
392  static XrdSysMutex fSessionIDRMutex; // Mutex for the Repo
393  static XrdOucHash<SessionIDInfo>
394  fSessionIDRepo; // The repository of session IDs, shared.
395  // Association between
396  // <hostname>:<port>.<user> and a SessionIDInfo struct
397 
398  int fOpenSockFD; // Descriptor of the underlying socket
399  static XrdClientConnectionMgr *fgConnectionMgr; //Instance of the Connection Manager
400 
401  XrdSysCondVar *fWriteWaitAck;
402  XrdClientVector<ClientRequest> fWriteReqsToRetry; // To store the write reqs to retry in case of a disconnection
403 
404  bool CheckErrorStatus(XrdClientMessage *, short &, char *);
405  void CheckPort(int &port);
406  void CheckREQPauseState();
407  void CheckREQConnectWaitState();
408  bool CheckResp(struct ServerResponseHeader *resp, const char *method);
409  XrdClientMessage *ClientServerCmd(ClientRequest *req,
410  const void *reqMoreData,
411  void **answMoreDataAllocated,
412  void *answMoreData,
413  bool HasToAlloc,
414  int substreamid = 0);
415  XrdSecProtocol *DoAuthentication(char *plist, int plsiz);
416 
417  ERemoteServerType DoHandShake(short log);
418 
419  bool DoLogin();
420  bool DomainMatcher(XrdOucString dom, XrdOucString domlist);
421 
422  XrdOucString GetDomainToMatch(XrdOucString hostname);
423 
424  ESrvErrorHandlerRetval HandleServerError(XReqErrorType &, XrdClientMessage *,
425  ClientRequest *);
426  bool MatchStreamid(struct ServerResponseHeader *ServerResponse);
427 
428  // Sends a close request, without waiting for an answer
429  // useful (?) to be sent just before closing a badly working stream
430  bool PanicClose();
431 
432  XrdOucString ParseDomainFromHostname(XrdOucString hostname);
433 
434  XrdClientMessage *ReadPartialAnswer(XReqErrorType &, size_t &,
435  ClientRequest *, bool, void**,
436  EThreeStateReadHandler &);
437 
438 // void ClearSessionID();
439 
440  XReqErrorType WriteToServer(ClientRequest *req,
441  const void* reqMoreData,
442  short LogConnID,
443  int substreamid = 0);
444 
445  bool WaitResp(int secsmax);
446 
447  XrdClientUrlInfo *fMetaUrl; // Meta manager url
448  bool fLBSIsMeta; // Is current redirector a meta manager?
449 
450 public:
451  XrdOucString fRedirCGI; // Same as fRedirOpaque but persistent
452 
453 };
454 #endif