Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
XrdProofPhyConn.cxx
Go to the documentation of this file.
1// @(#)root/proofd:$Id$
2// Author: Gerardo Ganis 12/12/2005
3
4/*************************************************************************
5 * Copyright (C) 1995-2005, 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// XrdProofPhyConn //
15// //
16// Authors: G. Ganis, CERN, 2005 //
17// //
18// XrdProofConn implementation using a simple physical connection //
19// (Unix or Tcp) //
20//////////////////////////////////////////////////////////////////////////
21
22#include "XrdProofPhyConn.h"
23#include "XpdSysDNS.h"
24
25#include "XrdVersion.hh"
31#include "XrdSec/XrdSecInterface.hh"
32
33#ifndef WIN32
34#ifndef ROOT_XrdFour
35# include <sys/socket.h>
36#endif
37#include <sys/types.h>
38#include <netdb.h>
39#include <pwd.h>
40#else
41#include <Winsock2.h>
42#endif
43
44// Tracing utils
45#include "XrdProofdTrace.h"
46
47#define URLTAG "["<<fUrl.Host<<":"<<fUrl.Port<<"]"
48
49////////////////////////////////////////////////////////////////////////////////
50/// Constructor. Open a direct connection (Unix or Tcp) to a remote
51/// XrdProofd instance. Does not use the connection manager.
52
53XrdProofPhyConn::XrdProofPhyConn(const char *url, int psid, char capver,
54 XrdClientAbsUnsolMsgHandler *uh, bool tcp, int fd)
55 : XrdProofConn(0, 'i', psid, capver, uh)
56{
57 XPDLOC(ALL, "PhyConn")
58
59 fTcp = tcp;
60
61 // Mutex
62 fMutex = new XrdSysRecMutex();
63
64 // Initialization
65 if (url && !Init(url, fd)) {
66 TRACE(XERR, "severe error occurred while"
67 " opening a connection" << " to server "<<URLTAG);
68 return;
69 }
70}
71
72////////////////////////////////////////////////////////////////////////////////
73/// Initialization
74
75bool XrdProofPhyConn::Init(const char *url, int fd)
76{
77 XPDLOC(ALL, "PhyConn::Init")
78
79 // Save url
80 fUrl.TakeUrl(XrdOucString(url));
81
82 // Get user
83 fUser = fUrl.User.c_str();
84 if (fUser.length() <= 0) {
85 // Use local username, if not specified
86#ifndef WIN32
87 struct passwd *pw = getpwuid(getuid());
88 fUser = pw ? pw->pw_name : "";
89#else
90 char lname[256];
91 DWORD length = sizeof (lname);
92 ::GetUserName(lname, &length);
93 fUser = lname;
94#endif
95 }
96
97 // Host and Port
98 if (!fTcp) {
99 char *hn = XrdSysDNS::getHostName(((fUrl.Host.length() > 0) ?
100 fUrl.Host.c_str() : "localhost"));
101 fHost = hn;
102 free(hn);
103 fPort = -1;
104 fUrl.Host = "";
105 fUrl.User = "";
106 } else {
107
108 fHost = fUrl.Host.c_str();
109 fPort = fUrl.Port;
110 // Check port
111 if (fPort <= 0) {
112 struct servent *sent = getservbyname("proofd", "tcp");
113 if (!sent) {
114 TRACE(XERR, "service 'proofd' not found by getservbyname" <<
115 ": using default IANA assigned tcp port 1093");
116 fPort = 1093;
117 } else {
118 fPort = (int)ntohs(sent->s_port);
119 // Update port in url
120 fUrl.Port = fPort;
121 TRACE(XERR, "getservbyname found tcp port " << fPort <<
122 " for service 'proofd'");
123 }
124 }
125 }
126
127 // Run the connection attempts: the result is stored in fConnected
128 Connect(fd);
129
130 // We are done
131 return fConnected;
132}
133
134////////////////////////////////////////////////////////////////////////////////
135/// Run the connection attempts: the result is stored in fConnected
136
138{
139 XPDLOC(ALL, "PhyConn::Connect")
140
141 int maxTry = -1, timeWait = -1;
142 // Max number of tries and timeout; use current settings, if any
143 XrdProofConn::GetRetryParam(maxTry, timeWait);
144 maxTry = (maxTry > -1) ? maxTry : EnvGetLong(NAME_FIRSTCONNECTMAXCNT);
145 timeWait = (timeWait > -1) ? timeWait : EnvGetLong(NAME_CONNECTTIMEOUT);
146
147 int logid = -1;
148 int i = 0;
149 for (; (i < maxTry) && (!fConnected); i++) {
150
151 // Try connection
152 logid = TryConnect(fd);
153
154 // We are connected to a host. Let's handshake with it.
155 if (fConnected) {
156
157 // Now the have the logical Connection ID, that we can use as streamid for
158 // communications with the server
159 TRACE(DBG, "new logical connection ID: "<<logid);
160
161 // Get access to server
162 if (!GetAccessToSrv()) {
163 if (fLastErr == kXR_NotAuthorized) {
164 // Authentication error: does not make much sense to retry
165 Close("P");
166 XrdOucString msg = fLastErrMsg;
167 msg.erase(msg.rfind(":"));
168 TRACE(XERR, "authentication failure: " << msg);
169 return;
170 } else {
171 TRACE(XERR, "access to server failed (" << fLastErrMsg << ")");
172 }
173 continue;
174 } else {
175
176 // Manager call in client: no need to create or attach: just notify
177 TRACE(DBG, "access to server granted.");
178 break;
179 }
180 }
181
182 // We force a physical disconnection in this special case
183 TRACE(DBG, "disconnecting");
184 Close("P");
185
186 // And we wait a bit before retrying
187 TRACE(DBG, "connection attempt failed: sleep " << timeWait << " secs");
188#ifndef WIN32
189 sleep(timeWait);
190#else
191 Sleep(timeWait * 1000);
192#endif
193
194 } //for connect try
195}
196
197////////////////////////////////////////////////////////////////////////////////
198/// Connect to remote server
199
201{
202 XPDLOC(ALL, "PhyConn::TryConnect")
203
204 const char *ctype[2] = {"UNIX", "TCP"};
205
206 // Create physical connection
207 fPhyConn = new XrdClientPhyConnection(this, 0);
208
209 // Connect
210 bool isUnix = (fTcp) ? 0 : 1;
211#if ROOTXRDVERS <= ROOT_PhyConnNoReuse
212 if (fd > 0) {
213 TRACE(XERR, "Reusing an existing connection (descriptor "<<fd<<
214 ") not supported by the xroot client version (requires xrootd >= 3.0.3)");
215 fLogConnID = -1;
216 fConnected = 0;
217 return -1;
218 }
219 if (!(fPhyConn->Connect(fUrl, isUnix))) {
220#else
221 if (!(fPhyConn->Connect(fUrl, isUnix, fd))) {
222#endif
223 TRACE(XERR, "creating "<<ctype[fTcp]<<" connection to "<<URLTAG);
224 fLogConnID = -1;
225 fConnected = 0;
226 return -1;
227 }
228 TRACE(DBG, ctype[fTcp]<<"-connected to "<<URLTAG);
229
230 // Set some vars
231 fLogConnID = 0;
232 fStreamid = 1;
233 fConnected = 1;
234
235 // Replies are processed asynchronously
237
238 // We are done
239 return fLogConnID;
240}
241
242////////////////////////////////////////////////////////////////////////////////
243/// Close the connection.
244
245void XrdProofPhyConn::Close(const char *)
246{
247 // Make sure we are connected
248 if (!fConnected)
249 return;
250
251 // Close connection
252 if (fPhyConn)
254
255 // Flag this action
256 fConnected = 0;
257
258 // We are done
259 return;
260}
261
262////////////////////////////////////////////////////////////////////////////////
263/// Set handler of unsolicited responses
264
266 XrdProofConnSender_t, void *)
267{
268 if (fPhyConn)
270}
271
272////////////////////////////////////////////////////////////////////////////////
273/// Pickup message from the queue
274
276{
278}
279
280////////////////////////////////////////////////////////////////////////////////
281/// Gets access to the connected server.
282/// The login and authorization steps are performed here.
283
285{
286 XPDLOC(ALL, "PhyConn::GetAccessToSrv")
287
288 // Now we are connected and we ask for the kind of the server
291 }
292
293 switch (fServerType) {
294
295 case kSTXProofd:
296 TRACE(DBG, "found server at "<<URLTAG);
297
298 // Now we can start the reader thread in the physical connection, if needed
301 break;
302
303 case kSTError:
304 TRACE(XERR, "handshake failed with server "<<URLTAG);
305 Close();
306 return 0;
307
308 case kSTProofd:
309 case kSTNone:
310 default:
311 TRACE(XERR, "server at "<<URLTAG<< " is unknown : protocol error");
312 Close();
313 return 0;
314 }
315
316 // Execute a login
317 if (fPhyConn->IsLogged() != kNo) {
318 TRACE(XERR, "client already logged-in at "<<URLTAG<<" (!): protocol error!");
319 return 0;
320 }
321
322 // Login
323 return Login();
324}
325
326
327////////////////////////////////////////////////////////////////////////////////
328/// Low level write call
329
330int XrdProofPhyConn::WriteRaw(const void *buf, int len, XrdClientPhyConnection *)
331{
332 if (fPhyConn)
333 return fPhyConn->WriteRaw(buf, len);
334
335 // No connection open
336 return -1;
337}
338
339////////////////////////////////////////////////////////////////////////////////
340/// Low level write call
341
343{
344 if (fPhyConn)
345 return fPhyConn->ReadRaw(buf, len);
346
347 // No connection open
348 return -1;
349}
#define TRACE(Flag, Args)
Definition TGHtml.h:121
R__EXTERN C unsigned int sleep(unsigned int seconds)
#define NAME_CONNECTTIMEOUT
#define NAME_FIRSTCONNECTMAXCNT
#define EnvGetLong(x)
#define URLTAG
int(* XrdProofConnSender_t)(const char *, int, void *)
#define XPDLOC(d, x)
#define free
Definition civetweb.c:1539
int ReadRaw(void *buffer, int BufferLength, int substreamid=-1, int *usedsubstreamid=0)
int WriteRaw(const void *buffer, int BufferLength, int substreamid=0)
ELoginState IsLogged()
XrdClientMessage * ReadMessage(int streamid)
bool Connect(XrdClientUrlInfo RemoteHost, bool isUnix=0)
XrdClientAbsUnsolMsgHandler * UnsolicitedMsgHandler
void TakeUrl(XrdOucString url)
ESrvType DoHandShake(XrdClientPhyConnection *p=0)
Performs initial hand-shake with the server in order to understand which kind of server is there at t...
static void GetRetryParam(int &maxtry, int &timewait)
Retrieve current values of the retry control parameters, numer of retries and wait time between attem...
XrdClientPhyConnection * fPhyConn
ESrvType fServerType
friend class XrdProofPhyConn
XrdClientAbsUnsolMsgHandler * fUnsolMsgHandler
XErrorCode fLastErr
XrdSysRecMutex * fMutex
XrdClientUrlInfo fUrl
kXR_unt16 fStreamid
XrdOucString fUser
XrdOucString fLastErrMsg
bool Login()
This method perform the loggin-in into the server just after the hand-shake.
XrdOucString fHost
XrdClientMessage * ReadMsg()
Pickup message from the queue.
bool Init(const char *url, int fd=-1)
Initialization.
void Connect(int fd=-1)
Run the connection attempts: the result is stored in fConnected.
int TryConnect(int fd=-1)
Connect to remote server.
int ReadRaw(void *buf, int len, XrdClientPhyConnection *=0)
Low level write call.
void Close(const char *opt="")
Close the connection.
void SetAsync(XrdClientAbsUnsolMsgHandler *uh, XrdProofConnSender_t=0, void *=0)
Set handler of unsolicited responses.
int WriteRaw(const void *buf, int len, XrdClientPhyConnection *=0)
Low level write call.
bool GetAccessToSrv(XrdClientPhyConnection *=0)
Gets access to the connected server.
char * pw_name