39#include <sys/socket.h>
77 unsigned int Instance;
79 RefInfo(
const char* hname,
unsigned int inum)
80 : destHN(hname), Instance(inum) {}
85std::map<int, RefInfo> fd2Info;
110bool XrdNetRefresh::RegFail(
const char* why)
112 eDest.Emsg(
"Refresh",
"Peer cannot be registered;", why);
122 static unsigned int INum = 0;
126 if (!Peer.
InetName)
return RegFail(
"hostname missing");
128 if (index(Peer.
InetName,
'!'))
return RegFail(
"invalid hostname");
132 if (Peer.
fd < 0)
return RegFail(
"invalid socket descriptor");
138 if (!S_ISSOCK(
Stat.st_mode))
return RegFail(
"not a socket");
141 socklen_t stLen =
sizeof(sockType);
143 if (getsockopt(Peer.
fd, SOL_SOCKET, SO_TYPE, (
void*)&sockType, &stLen)
144 || sockType != SOCK_DGRAM)
return RegFail(
"not a UDP socket");
148 RefInfo newRef(Peer.
InetName, INum++);
152 newRef.destHN.append(
":");
153 newRef.destHN.append(std::to_string(ntohs(Peer.
Inet.
v4.sin_port)));
161 auto ret = fd2Info.insert(std::pair<int, RefInfo>(Peer.
fd, newRef));
162 if (ret.second==
false)
164 snprintf(buff,
sizeof(buff),
"(%d)", Peer.
fd);
165 eDest.Emsg(
"Refresh",
"Peer cannot be registered"
166 "duplicate socket descriptor", buff);
205 if (!fd2Info.erase(fd))
207 snprintf(buff,
sizeof(buff),
"%d)", fd);
208 eDest.Emsg(
"Refresh",
"Atempt to unregisted non-existent fd:",buff);
216bool XrdNetRefresh::SetDest(
int fd,
XrdNetSockAddr& netAddr,
const char* hName,
223 {
if (connect(fd, &netAddr.
Addr,
sizeof(netAddr.
Addr)))
224 {
eDest.Emsg(
"Refresh", errno,
"set new UDP address for", hName);
232 int sFD, sProt = (netAddr.
Addr.sa_family == AF_INET6 ? PF_INET6 : PF_INET);
236 if ((sFD = XrdSysFD_Socket(sProt, SOCK_DGRAM, 0)) < 0)
237 {
eDest.
Emsg(
"Refresh",errno,
"create socket for new UDP address for",hName);
243 if (connect(sFD, &netAddr.
Addr,
sizeof(netAddr.
Addr)))
244 {
eDest.
Emsg(
"Refresh", errno,
"init new UDP address for", hName);
251 if (XrdSysFD_Dup2(sFD, fd) < 0)
252 {
eDest.
Emsg(
"Refresh", errno,
"replace old UDP address for", hName);
267void XrdNetRefresh::Update()
270 {XrdNetSockAddr destIP;
271 unsigned int Instance;
273 std::map<int, RefInfo> fd2Info_Copy;
274 std::map<int, UpdInfo> fd2Info_Updt;
279 fd2Info_Copy = fd2Info;
286 for (
auto it = fd2Info_Copy.begin(); it != fd2Info_Copy.end(); ++it)
288 const char* hName = it->second.destHN.c_str();
289 const char* eText = hAddr.
Set(hName, 0);
291 if (eText)
eDest.
Emsg(
"Refresh", hName,
"resolution failed;", eText);
292 else {
const XrdNetSockAddr* netIP = hAddr.
NetAddr();
294 eDest.
Emsg(
"Refresh",
"Unable to get addr of", hName);
295 else {UpdInfo newInfo = {*netIP, it->second.Instance};
296 fd2Info_Updt.insert(std::pair<int, UpdInfo>
297 (it->first,newInfo));
306 int numDiff = 0, numUpdt = 0, numFail = 0;
307 for (
auto itu = fd2Info_Updt.begin(); itu != fd2Info_Updt.end(); ++itu)
308 {
auto itr = fd2Info.find(itu->first);
309 if (itr != fd2Info.end()
310 && itr->second.Instance == itu->second.Instance)
311 {
const char* hName = itr->second.destHN.c_str();
312 XrdNetSockAddr curIP;
313 socklen_t cSize =
sizeof(curIP.
Addr);
314 if (getpeername(itu->first, &curIP.
Addr, &cSize))
315 {
eDest.
Emsg(
"Refresh",errno,
"get current peername of",hName);
324 {
eDest.
Emsg(
"Refresh",
"IP family exception for", hName);
329 itu->second.destIP.v6.sin6_port = curIP.
v6.sin6_port;
330 if (SetDest(itu->first,itu->second.destIP,hName,newFam)) numUpdt++;
339 snprintf(mtext,
sizeof(mtext),
"%d of %d IP changed: %d updt %d fail",
340 numDiff, (
int)fd2Info_Updt.size(), numUpdt, numFail);
341 eDest.
Emsg(
"Refresh",
"Results:", mtext);
static XrdSysError eDest(0,"crypto_")
friend class XrdScheduler
const XrdNetSockAddr * NetAddr()
const char * Set(const char *hSpec, int pNum=PortInSpec)
virtual void DoIt() override
static void Start(XrdSysLogger *logP, XrdScheduler *sP)
static bool Register(XrdNetPeer &Peer)
static void UnRegister(int fd)
static IPComp Compare(XrdNetSockAddr &ip1, XrdNetSockAddr &ip2, bool *psame=0)
void Schedule(XrdJob *jp)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
XrdNetRefresh * NetRefresh