00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "XrdProofPhyConn.h"
00023
00024 #include "XrdVersion.hh"
00025 #include "XrdClient/XrdClientEnv.hh"
00026 #include "XrdClient/XrdClientConnMgr.hh"
00027 #include "XrdClient/XrdClientConst.hh"
00028 #include "XrdClient/XrdClientLogConnection.hh"
00029 #include "XrdClient/XrdClientMessage.hh"
00030 #include "XrdNet/XrdNetDNS.hh"
00031 #include "XrdSec/XrdSecInterface.hh"
00032
00033 #ifndef WIN32
00034 #include <sys/socket.h>
00035 #include <sys/types.h>
00036 #include <pwd.h>
00037 #else
00038 #include <Winsock2.h>
00039 #endif
00040
00041
00042 #include "XrdProofdTrace.h"
00043
00044 #define URLTAG "["<<fUrl.Host<<":"<<fUrl.Port<<"]"
00045
00046
00047 XrdProofPhyConn::XrdProofPhyConn(const char *url, int psid, char capver,
00048 XrdClientAbsUnsolMsgHandler *uh, bool tcp)
00049 : XrdProofConn(0, 'i', psid, capver, uh)
00050 {
00051
00052
00053 XPDLOC(ALL, "PhyConn")
00054
00055 fTcp = tcp;
00056
00057
00058 fMutex = new XrdSysRecMutex();
00059
00060
00061 if (url && !Init(url)) {
00062 TRACE(XERR, "severe error occurred while"
00063 " opening a connection" << " to server "<<URLTAG);
00064 return;
00065 }
00066 }
00067
00068
00069 bool XrdProofPhyConn::Init(const char *url)
00070 {
00071
00072 XPDLOC(ALL, "PhyConn::Init")
00073
00074
00075 fUrl.TakeUrl(XrdOucString(url));
00076
00077
00078 fUser = fUrl.User.c_str();
00079 if (fUser.length() <= 0) {
00080
00081 #ifndef WIN32
00082 struct passwd *pw = getpwuid(getuid());
00083 fUser = pw ? pw->pw_name : "";
00084 #else
00085 char lname[256];
00086 DWORD length = sizeof (lname);
00087 ::GetUserName(lname, &length);
00088 fUser = lname;
00089 #endif
00090 }
00091
00092
00093 if (!fTcp) {
00094 fHost = XrdNetDNS::getHostName(((fUrl.Host.length() > 0) ?
00095 fUrl.Host.c_str() : "localhost"));
00096 fPort = -1;
00097 fUrl.Host = "";
00098 fUrl.User = "";
00099 } else {
00100
00101 fHost = fUrl.Host.c_str();
00102 fPort = fUrl.Port;
00103
00104 if (fPort <= 0) {
00105 struct servent *sent = getservbyname("proofd", "tcp");
00106 if (!sent) {
00107 TRACE(XERR, "service 'proofd' not found by getservbyname" <<
00108 ": using default IANA assigned tcp port 1093");
00109 fPort = 1093;
00110 } else {
00111 fPort = (int)ntohs(sent->s_port);
00112
00113 fUrl.Port = fPort;
00114 TRACE(XERR, "getservbyname found tcp port " << fPort <<
00115 " for service 'proofd'");
00116 }
00117 }
00118 }
00119
00120
00121 Connect();
00122
00123
00124 return fConnected;
00125 }
00126
00127
00128 void XrdProofPhyConn::Connect()
00129 {
00130
00131 XPDLOC(ALL, "PhyConn::Connect")
00132
00133 int maxTry = -1, timeWait = -1;
00134
00135 XrdProofConn::GetRetryParam(maxTry, timeWait);
00136 maxTry = (maxTry > -1) ? maxTry : EnvGetLong(NAME_FIRSTCONNECTMAXCNT);
00137 timeWait = (timeWait > -1) ? timeWait : EnvGetLong(NAME_CONNECTTIMEOUT);
00138
00139 int logid = -1;
00140 int i = 0;
00141 for (; (i < maxTry) && (!fConnected); i++) {
00142
00143
00144 logid = TryConnect();
00145
00146
00147 if (fConnected) {
00148
00149
00150
00151 TRACE(DBG, "new logical connection ID: "<<logid);
00152
00153
00154 if (!GetAccessToSrv()) {
00155 if (fLastErr == kXR_NotAuthorized) {
00156
00157 Close("P");
00158 XrdOucString msg = fLastErrMsg;
00159 msg.erase(msg.rfind(":"));
00160 TRACE(XERR, "authentication failure: " << msg);
00161 return;
00162 } else {
00163 TRACE(XERR, "access to server failed (" << fLastErrMsg << ")");
00164 }
00165 continue;
00166 } else {
00167
00168
00169 TRACE(DBG, "access to server granted.");
00170 break;
00171 }
00172 }
00173
00174
00175 TRACE(DBG, "disconnecting");
00176 Close("P");
00177
00178
00179 TRACE(DBG, "connection attempt failed: sleep " << timeWait << " secs");
00180 #ifndef WIN32
00181 sleep(timeWait);
00182 #else
00183 Sleep(timeWait * 1000);
00184 #endif
00185
00186 }
00187 }
00188
00189
00190 int XrdProofPhyConn::TryConnect()
00191 {
00192
00193 XPDLOC(ALL, "PhyConn::TryConnect")
00194
00195 const char *ctype[2] = {"UNIX", "TCP"};
00196
00197
00198 #ifdef OLDXRCPHYCONN
00199 fPhyConn = new XrdClientPhyConnection(this);
00200 #else
00201 fPhyConn = new XrdClientPhyConnection(this, 0);
00202 #endif
00203
00204
00205 bool isUnix = (fTcp) ? 0 : 1;
00206 if (!(fPhyConn->Connect(fUrl, isUnix))) {
00207 TRACE(XERR, "creating "<<ctype[fTcp]<<" connection to "<<URLTAG);
00208 fLogConnID = -1;
00209 fConnected = 0;
00210 return -1;
00211 }
00212 TRACE(DBG, ctype[fTcp]<<"-connected to "<<URLTAG);
00213
00214
00215 fLogConnID = 0;
00216 fStreamid = 1;
00217 fConnected = 1;
00218
00219
00220 SetAsync(fUnsolMsgHandler);
00221
00222
00223 return fLogConnID;
00224 }
00225
00226
00227 void XrdProofPhyConn::Close(const char *)
00228 {
00229
00230
00231
00232 if (!fConnected)
00233 return;
00234
00235
00236 if (fPhyConn)
00237 fPhyConn->Disconnect();
00238
00239
00240 fConnected = 0;
00241
00242
00243 return;
00244 }
00245
00246
00247 void XrdProofPhyConn::SetAsync(XrdClientAbsUnsolMsgHandler *uh,
00248 XrdProofConnSender_t, void *)
00249 {
00250
00251
00252 if (fPhyConn)
00253 fPhyConn->UnsolicitedMsgHandler = uh;
00254 }
00255
00256
00257 XrdClientMessage *XrdProofPhyConn::ReadMsg()
00258 {
00259
00260
00261 return (fPhyConn ? fPhyConn->ReadMessage(fStreamid) : (XrdClientMessage *)0);
00262 }
00263
00264
00265 bool XrdProofPhyConn::GetAccessToSrv()
00266 {
00267
00268
00269 XPDLOC(ALL, "PhyConn::GetAccessToSrv")
00270
00271
00272 { XrdClientPhyConnLocker pcl(fPhyConn);
00273 fServerType = DoHandShake();
00274 }
00275
00276 switch (fServerType) {
00277
00278 case kSTXProofd:
00279 TRACE(DBG, "found server at "<<URLTAG);
00280
00281
00282 fPhyConn->StartReader();
00283 fPhyConn->fServerType = kSTBaseXrootd;
00284 break;
00285
00286 case kSTError:
00287 TRACE(XERR, "handShake failed with server "<<URLTAG);
00288 Close();
00289 return 0;
00290
00291 case kSTProofd:
00292 case kSTNone:
00293 default:
00294 TRACE(XERR, "server at "<<URLTAG<< " is unknown : protocol error");
00295 Close();
00296 return 0;
00297 }
00298
00299
00300 if (fPhyConn->IsLogged() != kNo) {
00301 TRACE(XERR, "client already logged-in at "<<URLTAG<<" (!): protocol error!");
00302 return 0;
00303 }
00304
00305
00306 return Login();
00307 }
00308
00309
00310
00311 int XrdProofPhyConn::WriteRaw(const void *buf, int len)
00312 {
00313
00314
00315 if (fPhyConn)
00316 return fPhyConn->WriteRaw(buf, len);
00317
00318
00319 return -1;
00320 }
00321
00322
00323 int XrdProofPhyConn::ReadRaw(void *buf, int len)
00324 {
00325
00326
00327 if (fPhyConn)
00328 return fPhyConn->ReadRaw(buf, len);
00329
00330
00331 return -1;
00332 }