📄 osptnprobe.c
字号:
* - go into a select() loop, waiting for replies * - as each reply arrives, note its time * - calculate the difference between request and reply */ /* assume every host will respond */ uHostsLeft = uNumHosts; /* start the echo on each socket */ for (uHost=0; uHost<uNumHosts; uHost++) { if(pProbeList[uHost].ospmSocket >= 0) { /* transmit the datagram */ OSPM_SEND(pProbeList[uHost].ospmSocket, uSent, tnBuffer, sizeof(tnBuffer), uErr); if (uSent != sizeof(tnBuffer)) { /* if the send didn't succeed, ... */ uHostsLeft--; /* there's one less host that will respond */ } else { pProbeList[uHost].ospmPrStatus = OSPE_PRSENT; } /* remember the current time */ pProbeList[uHost].ospmTime = OSPPTNProbeTimerMS(); /* reset uSent */ uSent = 0; } else { /* invalid socket; decrement number of hosts that will respond */ uHostsLeft--; } } /* * At this point, we've sent the requests to each host. Now we wait * for their replies. Before starting the wait loop, we need to set * up time variables. uTimeLeft keeps track of how long the caller * is allowing us to wait, so we start by setting that to uMaxWait. * After each call to select, we'll update that variable with the * remaining time. We also need to initialize uTime1, which marks * the time of the call to select. After select returns successfully, * we'll use uTime2 to note the current time, so that the difference * between uTime2 and uTime1 indicates how long select took. * * Also, notice that the wait loop is officially gated by uHostsLeft, * which is the number of hosts from whom we're still expecting to * hear a response. There are, however, several ways to break out * of the loop without uHostsLeft reaching zero. In particular, * select errors, select timeouts, or exhausting the time alotted * while outside of select. */ uTimeLeft = uMaxWait; /* to start out, we've got the full time */ uTime1 = OSPPTNProbeTimerMS(); /* remember starting time */ while (uHostsLeft > 0) { /* make a working copy of our socket set */ memcpy(&fdReadSet, pSockets, sizeof(fdReadSet)); /* convert time left into appropriate structure */ timeout.tv_sec = uTimeLeft / 1000; timeout.tv_usec = (uTimeLeft % 1000) * 1000; /* call select and wait for replies */ nRetVal = select( nMaxFd+1, /* Higest FD to test for */ &fdReadSet, /* set for reading */ (fd_set *)0, /* set for writing */ (fd_set *)0, /* set for exceptions */ &timeout ); /* time to wait */ /* CHECK FOR ERRORS/TIMEOUT */ if (nRetVal <= 0) { /* * Time ran out or Error Occurred; */ break; } /* There wasn't an error or timeout, so remember the current time */ uTime2 = OSPPTNProbeTimerMS(); /* check to see if timer has rolled over and make adjustment */ if (uTime2 < uTime1) { uTime2 = (OSPC_TNPROBE_MAXTIMER - uTime1) + uTime2; } /* Now see who replied */ for ( nCnt=nRetVal, fdSocket=nMinFd; ((nCnt > 0) && (fdSocket <= nMaxFd)); ++fdSocket) { if (FD_ISSET(fdSocket, &fdReadSet)) { /* which host responded? */ for (uHost=0; uHost<uNumHosts; uHost++) { if (pProbeList[uHost].ospmSocket == (fdSocket)) { break; } } /* make sure we found a host */ if (uHost < uNumHosts) { if (!(pProbeList[uHost].ospmPrStatus == OSPE_PRSENT)) { break; } /* receive the datagram */ nRecv = recv(fdSocket, recvbuf, sizeof(recvbuf), 0); if (nRecv <= 0) { break; } else if(memcmp(tnBuffer, recvbuf, nRecv) != 0) { break; } /* calculate how long it took */ pProbeList[uHost].ospmTime = uTime2 - pProbeList[uHost].ospmTime; /* update the status of the current socket */ pProbeList[uHost].ospmPrStatus = OSPE_PRDONE; } /* * Now that we've finished with this socket, clear it from * the read set, and decrement the number of pending sockets * left to check as well as the number of hosts on which * we're still waiting. */ FD_CLR((unsigned)fdSocket, pSockets); nCnt--; uHostsLeft--; } } /* update the time left */ if ((uTime2 - uTime1) < uTimeLeft) { /* * Note that we have to check to make sure the delta time is * greater than the time left; we can't simply subtract the * delta. That's because uTimeLeft is unsigned. */ uTimeLeft -= (uTime2 - uTime1); uTime1 = uTime2; } else { /* * In this case, our allotted time has expired. This is probably * pretty unlikely, as we'd expect most expirations to happen * while in the select call. It is a loose end that has to be * checked, however. */ break; } } } while (0); return;}/*-----------------------------------------------------------------------*//* OSPPTNProbeTimerMS - current time in milliseconds */unsigned long /* returns current time in ms */OSPPTNProbeTimerMS(void){ unsigned long millisecs = 0; int errcode = 0;#ifndef _WIN32 /* UNIX */ struct timeb timenow; OSPM_MEMSET(&timenow, 0, sizeof(struct timeb)); errcode = ftime(&timenow);#else struct _timeb timenow; OSPM_MEMSET(&timenow, 0, sizeof(struct _timeb)); _ftime(&timenow);#endif if(errcode != -1) { millisecs = ((timenow.time % OSPC_TNPROBE_TIMERMOD) * OSPC_TNPROBE_TIMERMULT) + timenow.millitm; } return(millisecs);}voidOSPPTNProbePruneList( OSPTLIST *ospvDests, OSPT_TN_PROBE *ospvProbes, unsigned ospvDelayLimit, unsigned *ospvNumDests){ OSPT_TN_PROBE *tmpprobelist = ospvProbes; unsigned probecnt = 0, deccnt = 0, numleft = *ospvNumDests; OSPTDEST *dest = OSPC_OSNULL; OSPTSVCPT *svcpt = OSPC_OSNULL; while(probecnt < *ospvNumDests) { if(tmpprobelist->ospmTime > ospvDelayLimit) { /* find specific node in destlist that matches ipaddr * in probelist and remove it */ for(dest = (OSPTDEST *)OSPPListFirst(ospvDests); dest != OSPC_OSNULL; dest = (OSPTDEST *)OSPPListNext(ospvDests, dest)) { (void)OSPPCommParseSvcPt((const char *)OSPPDestGetAddr(dest), &svcpt, 0); if (svcpt != (OSPTSVCPT *)OSPC_OSNULL) { if(svcpt->IpAddr == tmpprobelist->ospmipaddr) { OSPPListRemoveSpecificItem(ospvDests, dest); if (svcpt->HostName) OSPM_FREE(svcpt->HostName); if (svcpt->URI) OSPM_FREE(svcpt->URI); OSPM_FREE(svcpt); OSPPDestDelete(&dest); break; } if (svcpt->HostName) OSPM_FREE(svcpt->HostName); if (svcpt->URI) OSPM_FREE(svcpt->URI); OSPM_FREE(svcpt); } } numleft--; deccnt = probecnt; /* now remove that node from probelist */ while(deccnt < numleft) { ospvProbes[deccnt] = ospvProbes[deccnt + 1]; deccnt++; } } else { /* move probe pointer only if copy has not been done */ tmpprobelist++; } probecnt++; } /* reset NumDests */ *ospvNumDests = numleft; return;}int OSPPTNProbeCompare( const void *probeptr1, const void *probeptr2){ return ((OSPT_TN_PROBE *)probeptr1)->ospmTime - ((OSPT_TN_PROBE *)probeptr2)->ospmTime;}void OSPPTNProbeArrangeList( OSPTLIST *ospvDests, OSPT_TN_PROBE *ospvProbes, unsigned ospvNumDests){ OSPTLIST newlist = OSPC_OSNULL; unsigned probecnt = 0; OSPTDEST *dest = OSPC_OSNULL; OSPTSVCPT *svcpt = OSPC_OSNULL; qsort((void *)ospvProbes, (size_t)ospvNumDests, sizeof(OSPT_TN_PROBE), OSPPTNProbeCompare); OSPPListNew(&newlist); for(probecnt = 0; probecnt < ospvNumDests; probecnt++) { /* find specific node in destlist that matches ipaddr * in probelist, remove it and add to new list */ for(dest = (OSPTDEST *)OSPPListFirst(ospvDests); dest != OSPC_OSNULL; dest = (OSPTDEST *)OSPPListNext(ospvDests, dest)) { (void)OSPPCommParseSvcPt((const char *)OSPPDestGetAddr(dest), &svcpt, 0); if (svcpt != (OSPTSVCPT *)OSPC_OSNULL) { if(svcpt->IpAddr == ospvProbes[probecnt].ospmipaddr) { OSPPListRemoveSpecificItem(ospvDests, dest); OSPPListAppend(&newlist, dest); dest = OSPC_OSNULL; if (svcpt->HostName) OSPM_FREE(svcpt->HostName); if (svcpt->URI) OSPM_FREE(svcpt->URI); OSPM_FREE(svcpt); break; } else { if (svcpt->HostName) OSPM_FREE(svcpt->HostName); if (svcpt->URI) OSPM_FREE(svcpt->URI); OSPM_FREE(svcpt); } } } } *ospvDests = newlist; return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -