XRootD
Loading...
Searching...
No Matches
XrdCmsManList.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d C m s M a n L i s t . c c */
4/* */
5/* (c) 2011 by the Board of Trustees of the Leland Stanford, Jr., University */
6/* All Rights Reserved */
7/* Produced by Andrew Hanushevsky for Stanford University under contract */
8/* DE-AC02-76-SFO0515 with the Department of Energy */
9/* */
10/* This file is part of the XRootD software suite. */
11/* */
12/* XRootD is free software: you can redistribute it and/or modify it under */
13/* the terms of the GNU Lesser General Public License as published by the */
14/* Free Software Foundation, either version 3 of the License, or (at your */
15/* option) any later version. */
16/* */
17/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20/* License for more details. */
21/* */
22/* You should have received a copy of the GNU Lesser General Public License */
23/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25/* */
26/* The copyright holder's institutional names and contributor's names may not */
27/* be used to endorse or promote products derived from this software without */
28/* specific prior written permission of the institution or contributor. */
29/******************************************************************************/
30
31#include <cctype>
32#include <cstdio>
33#include <unistd.h>
34
36#include "XrdNet/XrdNetAddr.hh"
37#include "XrdOuc/XrdOucTList.hh"
40
41/******************************************************************************/
42/* L o c a l C l a s s e s */
43/******************************************************************************/
44
46{
47public:
48
50char *Manager;
51unsigned int ManRef;
54
55 XrdCmsManRef(unsigned int ref, char *name, int port, int lvl)
56 : Next(0), Manager(name), ManRef(ref),
57 ManPort(port), ManLvl(lvl) {};
58
60};
61
62/******************************************************************************/
63/* D e s t r u c t o r */
64/******************************************************************************/
65
67{
68 XrdCmsManRef *prp, *mrp = allMans;
69
70 while(mrp) {prp = mrp; mrp = mrp->Next; delete prp;}
71}
72
73
74/******************************************************************************/
75/* A d d */
76/******************************************************************************/
77
78void XrdCmsManList::Add(const XrdNetAddr *netAddr, char *redList,
79 int manPort, int lvl)
80{
81 XrdOucTokenizer hList((char *)redList);
82 char *hP;
83 int theRef;
84
85// Get the manager's reference number and if exists, delete existing entries
86//
87 if ((theRef = getRef(netAddr)) >= 0) Del(theRef);
88 else theRef = -theRef;
89
90// Add eeach redirect target in the list
91//
92 hP = hList.GetLine();
93 while((hP = hList.GetToken())) Add(theRef, hP, manPort, lvl);
94}
95
96/******************************************************************************/
97
98void XrdCmsManList::Add(int ref, char *manp, int manport, int lvl)
99{
100 XrdCmsManRef *prp = 0, *mrp;
101 char *cp, *ipname;
102 int port;
103
104// Find the colon in the host name
105//
106 if (*manp != '[') cp = index(manp, int(':'));
107 else if ((cp = index(manp+1, ']'))) cp = index(cp+1, int(':'));
108 if (!cp) port = manport;
109 else {if (!(port=atoi(cp+1)) || port > 0xffff) port=manport;
110 *cp = '\0';
111 }
112
113// Get the full name of the host target unless it is an actual address
114//
115 if (XrdNetAddrInfo::isHostName(manp)) ipname = strdup(manp);
116 else {XrdNetAddr redAddr;
117 const char *redName;
118 if (redAddr.Set(manp,0) || !(redName = redAddr.Name())) return;
119 ipname = strdup(redName);
120 }
121 if (cp) *cp = ':';
122
123// Start up
124//
125 mlMutex.Lock();
126 mrp = allMans;
127
128// Chck if this is a duplicate
129//
130 while(mrp)
131 {if (!strcmp(mrp->Manager, ipname) && mrp->ManPort == port)
132 {mlMutex.UnLock(); free(ipname); return;}
133 if (mrp->Next)
134 {if (mrp->Next->ManLvl > lvl) prp = mrp;}
135 else if (!prp) prp = mrp;
136 mrp = mrp->Next;
137 }
138
139// Create new entry
140//
141 mrp = new XrdCmsManRef(ref, ipname, port, lvl);
142 if (!prp) nextMan = allMans = mrp;
143 else {mrp->Next = prp->Next; prp->Next = mrp;
144 if (nextMan->ManLvl > lvl) nextMan = mrp;
145 }
146 mlMutex.UnLock();
147}
148
149/******************************************************************************/
150/* D e l */
151/******************************************************************************/
152
154{
155 XrdCmsManRef *nrp, *prp = 0, *mrp;
156
157// If mistakingly called for a newly added reference, do nothing
158//
159 if (ref < 0) return;
160
161// Start up
162//
163 mlMutex.Lock();
164 mrp = allMans;
165
166// Delete all ref entries
167//
168 while(mrp)
169 {if (mrp->ManRef == (unsigned int)ref)
170 {nrp = mrp->Next;
171 if (!prp) allMans = nrp;
172 else {prp->Next = nrp;
173 if (mrp == allMans) allMans = nrp;
174 }
175 if (mrp == nextMan) nextMan = nrp;
176 delete mrp;
177 mrp = nrp;
178 } else {prp = mrp; mrp = mrp->Next;}
179 }
180
181// All done
182//
183 mlMutex.UnLock();
184}
185
186/******************************************************************************/
187/* g e t R e f */
188/******************************************************************************/
189
191{
192 static int refNum = 1;
193 XrdNetAddr theAddr = *netAddr;
194 XrdOucTList *tP;
195 char buff[128];
196 int theNum;
197
198// Convert address to text
199//
200 theAddr.Format(buff,sizeof(buff),XrdNetAddr::fmtAdv6,XrdNetAddr::old6Map4);
201
202// Find the entry in this list
203//
204 refMutex.Lock();
205 tP = refList;
206 while(tP && strcmp(buff, tP->text)) tP = tP->next;
207
208// If we didn't find one, add it
209//
210 if (tP) theNum = tP->val;
211 else {refList = new XrdOucTList(buff, refNum, refList);
212 theNum = -refNum++;
213 }
214
215// Return the number
216//
217 refMutex.UnLock();
218 return theNum;
219}
220
221/******************************************************************************/
222/* N e x t */
223/******************************************************************************/
224
225int XrdCmsManList::Next(int &port, char *buff, int bsz)
226{
227 XrdCmsManRef *np;
228 int lvl;
229
230 mlMutex.Lock();
231 if (!(np = nextMan)) nextMan = allMans;
232 else {strlcpy(buff, np->Manager, bsz);
233 port = np->ManPort;
234 nextMan = np->Next;
235 }
236 lvl = (np ? np->ManLvl : 0);
237 mlMutex.UnLock();
238 return lvl;
239}
size_t strlcpy(char *dst, const char *src, size_t sz)
void Del(const XrdNetAddr *refP)
void Add(const XrdNetAddr *netAddr, char *redList, int manport, int lvl)
int getRef(const XrdNetAddr *refP)
int Next(int &port, char *buff, int bsz)
XrdCmsManRef * Next
unsigned int ManRef
XrdCmsManRef(unsigned int ref, char *name, int port, int lvl)
static const int old6Map4
Use deprecated IPV6 mapped format.
static bool isHostName(const char *name)
int Format(char *bAddr, int bLen, fmtUse fmtType=fmtAuto, int fmtOpts=0)
const char * Name(const char *eName=0, const char **eText=0)
const char * Set(const char *hSpec, int pNum=PortInSpec)
XrdOucTList * next
char * GetToken(char **rest=0, int lowcase=0)