Skip to content

Commit

Permalink
[Server] Proide fallback when an IPv6 address is missing a ptr record.
Browse files Browse the repository at this point in the history
  • Loading branch information
abh3 committed Dec 20, 2019
1 parent 23aaf99 commit 2b15e49
Show file tree
Hide file tree
Showing 9 changed files with 184 additions and 4 deletions.
9 changes: 9 additions & 0 deletions src/Xrd/XrdLink.cc
Expand Up @@ -285,6 +285,15 @@ int XrdLink::RecvAll(char *Buff, int Blen, int timeout)
return linkXQ.RecvAll (Buff, Blen, timeout);
}

/******************************************************************************/
/* R e g i s t e r */
/******************************************************************************/

bool XrdLink::Register(const char *hName)
{
return linkXQ.Register(hName);
}

/******************************************************************************/
/* S e n d */
/******************************************************************************/
Expand Down
12 changes: 12 additions & 0 deletions src/Xrd/XrdLink.hh
Expand Up @@ -326,6 +326,18 @@ int Recv(char *buff, int blen, int timeout);

int RecvAll(char *buff, int blen, int timeout=-1);

//------------------------------------------------------------------------------
//! Register a host name with this IP address. This is not MT-safe!
//!
//! @param hName -> to a true host name which should be fully qualified.
//! One of the IP addresses registered to this name must
//! match the IP address associated with this object.
//!
//! @return True: Specified name is now associated with this link.
//! False: Nothing changed, registration could not be verified.
//------------------------------------------------------------------------------

bool Register(const char *hName);
//-----------------------------------------------------------------------------
//! Send data on a link. This calls may block unless the socket was marked
//! nonblocking. If a block would occur, the data is copied for later sending.
Expand Down
19 changes: 19 additions & 0 deletions src/Xrd/XrdLinkXeq.cc
Expand Up @@ -454,6 +454,25 @@ int XrdLinkXeq::RecvAll(char *Buff, int Blen, int timeout)
return -1;
}

/******************************************************************************/
/* R e g i s t e r */
/******************************************************************************/

bool XrdLinkXeq::Register(const char *hName)
{

// First see if we can register this name with the address object
//
if (!Addr.Register(hName)) return false;

// Make appropriate changes here
//
if (HostName) free(HostName);
HostName = strdup(hName);
strlcpy(Lname, hName, sizeof(Lname));
return true;
}

/******************************************************************************/
/* S e n d */
/******************************************************************************/
Expand Down
2 changes: 2 additions & 0 deletions src/Xrd/XrdLinkXeq.hh
Expand Up @@ -91,6 +91,8 @@ int Recv(char *buff, int blen, int timeout);

int RecvAll(char *buff, int blen, int timeout=-1);

bool Register(const char *hName);

int Send(const char *buff, int blen);
int Send(const struct iovec *iov, int iocnt, int bytes=0);

Expand Down
12 changes: 11 additions & 1 deletion src/XrdCms/XrdCmsClientMan.cc
Expand Up @@ -323,7 +323,8 @@ int XrdCmsClientMan::Hookup()
EPNAME("Hookup");
CmsLoginData Data;
XrdLink *lp;
char buff[256];
char buff[256], hnBuff[264];
kXR_char *envData = 0;
int rc, oldWait, tries = 12, opts = 0;

// Turn off our debugging and version flags
Expand All @@ -332,6 +333,14 @@ int XrdCmsClientMan::Hookup()
doDebug &= ~manMask;
manMutex.UnLock();

// Report our hostname (there are better ways of doing this)
//
const char *hn = getenv("XRDHOST");
if (hn)
{snprintf(hnBuff, sizeof(hnBuff), "myHN=%s", hn);
envData = (kXR_char *)hnBuff;
}

// Keep trying to connect to the manager. Note that we bind the link to this
// thread to make sure we get notified should another thread close the socket.
//
Expand All @@ -343,6 +352,7 @@ int XrdCmsClientMan::Hookup()
}
// lp->Bind(XrdSysThread::ID());
memset(&Data, 0, sizeof(Data));
Data.envCGI = envData;
Data.Mode = CmsLoginData::kYR_director;
Data.HoldTime = static_cast<int>(getpid());
if (!(rc = XrdCmsLogin::Login(lp, Data))) break;
Expand Down
7 changes: 6 additions & 1 deletion src/XrdCms/XrdCmsConfig.cc
Expand Up @@ -369,6 +369,11 @@ int XrdCmsConfig::Configure2()
char *p, buff[512];
std::string envData;

// Add our host name to the env
//
envData += "myHN=";
envData += myName;

// Print herald
//
sprintf(buff, " phase 2 %s initialization started.", myRole);
Expand Down Expand Up @@ -414,7 +419,7 @@ int XrdCmsConfig::Configure2()
else {if (QTRACE(Debug))
Say.Say("Config ", "Global System Identification: ", mySID);
if (Config.mySite)
{envData += "site=";
{envData += "&site=";
envData += mySite;
}
}
Expand Down
78 changes: 76 additions & 2 deletions src/XrdCms/XrdCmsProtocol.cc
Expand Up @@ -365,6 +365,23 @@ void XrdCmsProtocol::Pander(const char *manager, int mport)
}
Netopts = 0; tries = waits = 6;

// Verify that this node has the real DNS name if it's IPv6
//
if (!(Link->AddrInfo()->isRegistered())
&& Link->AddrInfo()->isIPType(XrdNetAddrInfo::IPv6))
{char *oldName = strdup(Link->Host());
Say.Emsg("Protocol", oldName, "is missing an IPv6 ptr record; "
"attempting local registration as", manp);
if (!(Link->Register(manp)))
{Say.Emsg("Protocol", oldName,
"registration failed; address mismatch.");
} else {
Say.Emsg("Protocol", oldName,
"is now locally registered as", manp);
}
free(oldName);
}

// Obtain a new node object for this connection
//
if (!(myNode = Manager->Add(Link, Lvl+1, terminate)))
Expand Down Expand Up @@ -557,7 +574,30 @@ int XrdCmsProtocol::Stats(char *buff, int blen, int do_sync)
/******************************************************************************/
/* A d m i t */
/******************************************************************************/


namespace
{
char *getAltName(char *sid, char *buff, int blen)
{
char *atsign, *spacec, *retval = 0;
int n;
if (sid)
if ((atsign = index(sid, '@')))
{atsign++;
if ((spacec = index(atsign, ' ')))
{*spacec = 0;
n = strlen(atsign);
if (n > 3 && n < blen)
{strcpy(buff, atsign);
retval = buff;
}
*spacec = ' ';
}
}
return retval;
}
}

XrdCmsRouting *XrdCmsProtocol::Admit()
{
EPNAME("Admit");
Expand Down Expand Up @@ -590,6 +630,41 @@ XrdCmsRouting *XrdCmsProtocol::Admit()
//
if (!Source.Admit(Link, Data, Config.mySID, envP)) return 0;

// Construct environment for incomming node
//
XrdOucEnv cgiEnv((const char *)Data.envCGI);

// We have this problem hat many times the IPv6 address is missing the ptr
// record in DNS. If this node is IPv6 unregistered and the incomming node
// supplied it's host name then we can attempt to register it locally.
//
if (!(Link->AddrInfo()->isRegistered())
&& Link->AddrInfo()->isIPType(XrdNetAddrInfo::IPv6))
{const char *altName = cgiEnv.Get("myHN");
const char *altType = "stated mapping";
char hBF[256], *oldName = strdup(Link->Host());
if (!altName) {altName = getAltName((char *)Data.SID, hBF, sizeof(hBF));
altType = "inferred mapping";
}
Say.Emsg("Protocol", "DNS lookup for", oldName, "failed; "
"IPv6 ptr record missing!");
if (!altName)
{Say.Emsg("Protocol", oldName, "did not supply a fallback "
"mapping; using IPv6 address.");
} else {
char buff[512];
snprintf(buff, sizeof(buff), "%s -> %s", oldName, altName);
Say.Emsg("Protocol", "Attempting to use", altType, buff);
if (!(Link->Register(altName)))
{Say.Emsg("Protocol", buff, altType,"failed; address mismatch.");
} else {
Say.Emsg("Protocol", oldName,
"is now locally registered as", altName);
}
}
free(oldName);
}

// Handle Redirectors here (minimal stuff to do)
//
if (Data.Mode & CmsLoginData::kYR_director)
Expand Down Expand Up @@ -736,7 +811,6 @@ XrdCmsRouting *XrdCmsProtocol::Admit()

// Document the login
//
XrdOucEnv cgiEnv((const char *)Data.envCGI);
const char *sname = cgiEnv.Get("site");
const char *lfmt = (myNode->isMan > 1 ? "Standby%s%s" : "Primary%s%s");
snprintf(envBuff,sizeof(envBuff),lfmt,(sname ? " ":""),(sname ? sname : ""));
Expand Down
36 changes: 36 additions & 0 deletions src/XrdNet/XrdNetAddr.cc
Expand Up @@ -164,6 +164,42 @@ int XrdNetAddr::Port(int pNum)
return pNum;
}

/******************************************************************************/
/* R e g i s t e r */
/******************************************************************************/

bool XrdNetAddr::Register(const char *hName)
{
XrdNetAddr *aListVec = 0;
int i, aListNum;

// Step one is to make sure the incomming name is not an address
//
if (!isHostName(hName)) return false;

// The next step is to get all of the IP addresses registered for this name
//
if (XrdNetUtils::GetAddrs(hName, &aListVec, aListNum,
XrdNetUtils::allIPMap, XrdNetUtils::NoPortRaw))
return false;

// In order to use the given name, one of the IP addresses in the list must
// match our address. This is about as secure we can get.
//
for (i = 0; i < aListNum; i++) {if (Same(&aListVec[i])) break;}
delete [] aListVec;

// If we didn't find a match, report it
//
if (i >= aListNum) return false;

// Replace current hostname with the wanted one
//
if (hostName) free(hostName);
hostName = strdup(hName);
return true;
}

/******************************************************************************/
/* S e t */
/******************************************************************************/
Expand Down
13 changes: 13 additions & 0 deletions src/XrdNet/XrdNetAddr.hh
Expand Up @@ -72,6 +72,19 @@ static bool IPV4Set() {return useIPV4;}

int Port(int pNum=-1);

//------------------------------------------------------------------------------
//! Register a host name with this IP address. This is not MT-safe!
//!
//! @param hName -> to a true host name which should be fully qualified.
//! One of the IP addresses registered to this name must
//! match the IP address associated with this object.
//!
//! @return True: Specified name is now associated with this address.
//! False: Nothing changed, registration could not be verified.
//------------------------------------------------------------------------------

bool Register(const char *hName);

//------------------------------------------------------------------------------
//! Set the IP address and possibly the port number.
//!
Expand Down

0 comments on commit 2b15e49

Please sign in to comment.