XRootD
Loading...
Searching...
No Matches
XrdNetIdentity.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d N e t I d e n t i t y . h h */
4/* */
5/* (c) 2021 by the Board of Trustees of the Leland Stanford, Jr., University */
6/* Produced by Andrew Hanushevsky for Stanford University under contract */
7/* DE-AC02-76-SFO0515 with the Department of Energy */
8/* */
9/* This file is part of the XRootD software suite. */
10/* */
11/* XRootD is free software: you can redistribute it and/or modify it under */
12/* the terms of the GNU Lesser General Public License as published by the */
13/* Free Software Foundation, either version 3 of the License, or (at your */
14/* option) any later version. */
15/* */
16/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
17/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
18/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
19/* License for more details. */
20/* */
21/* You should have received a copy of the GNU Lesser General Public License */
22/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
23/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
24/* */
25/* The copyright holder's institutional names and contributor's names may not */
26/* be used to endorse or promote products derived from this software without */
27/* specific prior written permission of the institution or contributor. */
28/******************************************************************************/
29
30#include <string.h>
31#include <unistd.h>
32
33#include "XrdNet/XrdNetAddr.hh"
35#include "XrdNet/XrdNetIF.hh"
36#include "XrdOuc/XrdOucTList.hh"
37#include "XrdOuc/XrdOucUtils.hh"
38#include "XrdSys/XrdSysE2T.hh"
39
40/******************************************************************************/
41/* O n e T i m e S t a t i c I n i t i a l i z a t i o n */
42/******************************************************************************/
43
44namespace
45{
46char *getMyFQN(const char *&myDom, bool &myFQN, const char *&myErr)
47{
48 XrdNetAddr theAddr;
49 XrdOucTList *ifList, *ifNow;
50 const char *dnsName, *domP;
51 char *theName[2] = {0}, *theDom[2] = {0}, *theIPA[2] = {0}, hName[1025];
52 int hnLen;
53
54// Make sure domain is set to something that is valid
55//
56 myDom = "";
57
58// The identity can be specified via an envar. In this case, it short circuits
59// all the subsequent code.
60//
61 if ((dnsName = getenv("XRDNET_IDENTITY")))
62 {if (XrdNetAddrInfo::isHostName(dnsName)
63 && !(myDom = index(dnsName, '.'))) myDom = "";
64 myFQN = false;
65 char* tmp = strdup(dnsName);
67 return tmp;
68 }
69 myFQN = true;
70
71// Obtain the host name, this is mandatory.
72//
73 if (gethostname(hName, sizeof(hName)))
74 {myErr = XrdSysE2T(errno); myDom = 0; return 0;}
75 hnLen = strlen(hName);
77
78// First step it to get all IP addresses configured on this machine
79//
80 if (!XrdNetIF::GetIF(&ifList, &myErr))
81 {myDom = ""; return strdup(hName);}
82
83// Run through the interfaces and try to get the hostname associated with
84// this machine. Note that we may have public and private addresses and
85// they may have different hostname attached. We only accept the hostname
86// that matches what is returned by gethostname().
87//
88 while((ifNow = ifList))
89 {int i = (ifNow->sval[1] ? 1 : 0); // Private | public
90
91 if (i >= 0 && theName[i] == 0 && !theAddr.Set(ifNow->text, 0)
92 && (dnsName = theAddr.Name(0,&myErr)) && (domP = index(dnsName,'.')))
93 {int n = domP - dnsName;
94 if (n == hnLen && !strncmp(hName, dnsName, n))
95 {theName[i] = strdup(dnsName);
96 theDom[i] = theName[i] + n;
97 } else {
98 if (theIPA[i]) free(theIPA[i]);
99 theIPA[i] = strdup(ifNow->text);
100 }
101 }
102 ifList = ifList->next;
103 delete ifNow;
104 }
105
106// Fix up error pointer
107//
108 if (myErr == 0) myErr = "no error";
109
110// We prefer the public name should we have it
111//
112 if (theName[0])
113 {if (theName[1]) free(theName[1]);
114 myDom = theDom[0];
115 return theName[0];
116 }
117
118// Use the private name should we have it
119//
120 if (theName[1])
121 {myDom = theDom[1];
122 return theName[1];
123 }
124
125// Concote a name using old-style DNS resolution. This may not work if DNS
126// namespaces are being used (e.g. k8s environments) or if the hostname is not
127// resolvable. We will catch that here and move on.
128//
129 if ((myErr = theAddr.Set(hName,0))) dnsName = 0;
130 else dnsName = theAddr.Name(0, &myErr);
131
132// Check if this worked
133//
134 if (dnsName)
135 {theName[0] = strdup(dnsName);
136 if (!(myDom = index(theName[0], '.'))) myDom = "";
137 return theName[0];
138 }
139
140// Prefrentially return the hostname as an address as the value of gethostname()
141// may actually fail. So, we defer naming the machine until later but we do
142// know its IP address and that can be used as an identity. Return the public
143// address first. Note that we prefrentially return the IPv6 address here.
144//
145 if (theIPA[0])
146 {if (theIPA[1]) free(theIPA[1]);
147 return theIPA[0];
148 }
149 if (theIPA[1]) return theIPA[1];
150
151// Fallback to using the simple unqualified hostname, this still may be OK but
152// this is likely to fail in certain situations where DNS is screwed up.
153//
154 theName[0] = strdup(hName);
155 myDom = theName[0] + hnLen;
156 return theName[0];
157}
158}
159
160/******************************************************************************/
161/* S t a t i c M e m b e r s */
162/******************************************************************************/
163
164// Note that we are gauranteed that this will be fully initialzed prior
165// to any method called that uses these values irrespective of static
166// initialization order, even though statically initialized.
167
168const char *XrdNetIdentity::DNS_Domain;
169const char *XrdNetIdentity::DNS_Error;
170 char *XrdNetIdentity::DNS_FQN = getMyFQN(DNS_Domain, FQN_DNS, DNS_Error);
171 bool XrdNetIdentity::FQN_DNS;
172
173/******************************************************************************/
174/* D o m a i n */
175/******************************************************************************/
176
177const char *XrdNetIdentity::Domain(const char **eText)
178{
179 if (eText) *eText = DNS_Error;
180 return DNS_Domain;
181}
182
183/******************************************************************************/
184/* F Q N */
185/******************************************************************************/
186
187const char *XrdNetIdentity::FQN(const char **eText)
188{
189 if (eText) *eText = DNS_Error;
190 return DNS_FQN;
191}
192
193/******************************************************************************/
194/* s e t F Q N */
195/******************************************************************************/
196
197void XrdNetIdentity::SetFQN(const char *fqn)
198{
199 if (DNS_FQN) free(DNS_FQN);
200 DNS_FQN = strdup(fqn);
201 if (!(DNS_Domain = index(DNS_FQN, '.'))) DNS_Domain = "";
202 FQN_DNS = false;
203}
const char * XrdSysE2T(int errcode)
Definition XrdSysE2T.cc:99
static bool isHostName(const char *name)
const char * Name(const char *eName=0, const char **eText=0)
const char * Set(const char *hSpec, int pNum=PortInSpec)
static int GetIF(XrdOucTList **ifList, const char **eText=0)
Definition XrdNetIF.cc:413
static void SetFQN(const char *fqn)
static const char * Domain(const char **eText=0)
static const char * FQN(const char **etext=0)
XrdOucTList * next
static void toLower(char *str)