
dave.smith at corpdata
Jan 22, 2004, 7:33 AM
Post #1 of 3
(1067 views)
Permalink
|
This is a multi-part message in MIME format. ------=_NextPart_000_0007_01C3E0F4.A3EBFDA0 Content-Type: multipart/alternative; boundary="----=_NextPart_001_0008_01C3E0F4.A3EBFDA0" ------=_NextPart_001_0008_01C3E0F4.A3EBFDA0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Hi, Have modified a couple of pieces of code to get NT Backhand Broadcaster to talk nicely to the moderator under the latest release. Two files changed (Attached) : NTServerStats.h - (You'll see my notes) broadcast.cpp - (transmit function - add padding for 64bit time and load old sockaddr_in data elements) I am not really a C/C++ coder, so it isn't too pretty, (be nice), it does however work. Hope this helps someone. Dave Smith ________________________________________________________________________ This e-mail has been scanned for all viruses by Star Internet. The service is powered by MessageLabs. For more information on a proactive anti-virus service working around the clock, around the globe, visit: http://www.star.net.uk ________________________________________________________________________ ------=_NextPart_001_0008_01C3E0F4.A3EBFDA0 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable <!DOCTYPE=20HTML=20PUBLIC=20"-//W3C//DTD=20HTML=204.0=20Transitional//EN">= <HTML><HEAD> <META=20http-equiv=3DContent-Type=20content=3D"text/html;=20charset=3Diso-= 8859-1"> <META=20content=3D"MSHTML=206.00.2800.1276"=20name=3DGENERATOR></HEAD> <BODY> <DIV><SPAN=20class=3D990002914-22012004><FONT=20size=3D2>Hi,</FONT></SPAN>= </DIV> <DIV><SPAN=20class=3D990002914-22012004><FONT=20size=3D2></FONT></SPAN>&nb= sp;</DIV> <DIV><SPAN=20class=3D990002914-22012004><FONT=20size=3D2>Have=20modified=20= a=20couple=20of=20 pieces=20of=20code=20to=20get=20NT=20Backhand=20Broadcaster=20to=20talk=20= nicely=20to=20the=20moderator=20 under=20the=20latest=20release.</FONT></SPAN></DIV> <DIV><SPAN=20class=3D990002914-22012004><FONT=20size=3D2></FONT></SPAN>&nb= sp;</DIV> <DIV><SPAN=20class=3D990002914-22012004><FONT=20size=3D2>Two=20files=20cha= nged=20(Attached)=20 :</FONT></SPAN></DIV> <DIV><SPAN=20class=3D990002914-22012004><FONT=20size=3D2>NTServerStats.h=20= -=20(You'll=20see=20 my=20notes)</FONT></SPAN></DIV> <DIV><SPAN=20class=3D990002914-22012004><FONT=20size=3D2>broadcast.cpp=20-= =20(transmit=20 function=20-=20add=20padding=20for=2064bit=20time=20and=20load=20old=20soc= kaddr_in=20data=20 elements)</FONT></SPAN></DIV> <DIV><SPAN=20class=3D990002914-22012004><FONT=20size=3D2></FONT></SPAN>&nb= sp;</DIV> <DIV><SPAN=20class=3D990002914-22012004><FONT=20size=3D2>I=20am=20not=20re= ally=20a=20C/C++=20coder,=20 so=20it=20isn't=20too=20pretty,=20(be=20nice),=20it=20does=20however=20wor= k.</FONT></SPAN></DIV> <DIV><SPAN=20class=3D990002914-22012004><FONT=20size=3D2></FONT></SPAN>&nb= sp;</DIV> <DIV><SPAN=20class=3D990002914-22012004><FONT=20size=3D2>Hope=20this=20hel= ps=20 someone.</FONT></SPAN></DIV> <DIV><SPAN=20class=3D990002914-22012004><FONT=20size=3D2></FONT></SPAN>&nb= sp;</DIV> <DIV><SPAN=20class=3D990002914-22012004><FONT=20size=3D2>Dave=20 Smith</FONT></SPAN></DIV> <BR> ________________________________________________________________________<B= R> This=20e-mail=20has=20been=20scanned=20for=20all=20viruses=20by=20Star=20I= nternet.=20The<BR> service=20is=20powered=20by=20MessageLabs.=20For=20more=20information=20on= =20a=20proactive<BR> anti-virus=20service=20working=20around=20the=20clock,=20around=20the=20gl= obe,=20visit:<BR> <A=20 href=3Dhttp://www.star.net.uk> http://www.star.net.uk</A><BR> ________________________________________________________________________<B= R> </BODY></HTML> ------=_NextPart_001_0008_01C3E0F4.A3EBFDA0-- ------=_NextPart_000_0007_01C3E0F4.A3EBFDA0 Content-Type: application/octet-stream; name="NTServerStats.h" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="NTServerStats.h" /*-----------------------------------------------------------------------= -------- Copyright (c) 2001 CerebraSoft Module Name: NTServerStats.h Abstract: mod backhand serverstat structure, modified for NT broadcaster. License: All rights reserved. This product includes software developed at The Center for Networking and Distributed Systems at The Johns Hopkins University for use in the Backhand project (http://www.cnds.jhu.edu/backhand). Creator: Theo Schlossnagle=20 Guidance: Yair Amir Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.=20 =20 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. =20 3. All advertising materials mentioning features or use of this software must display the following acknowledgment: "This product includes software developed by Cerebrasoft (http://www.cerebrasoft.com). Creator: Rob Butler" 4. The names "Backhand Broadcaster" and "NT Backhand Broadcaster" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact www.cerebrasoft.com. =20 5. Products derived from this software may not be called "Backhand = Broadcaster" or "NT Backhand Broadcaster" nor may "Backhand Broadcaster" or "NT Backhand Broadcaster" appear in their names without prior = written permission. For written permission, please contact = www.cerebrasoft.com. =20 6. Redistributions of any form whatsoever must retain the following acknowledgment: "This product includes software developed by Cerebrasoft (http://www.cerebrasoft.com). Creator: Rob Butler" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------= --------*/ /*-----------------------------------------------------------------------= -------- serverstat structure Borrowed from mod_backhand serverstat.h (some modifications have been made.) Original notice as in serverStat.h = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Copyright (c) 1998-1999 The Johns Hopkins University. All rights reserved. The following code was written by Theo Schlossnagle for use in the Backhand project at The Center for Networking and Distributed Systems at The Johns Hopkins University. Please refer to the LICENSE file before using this software. = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -------------------------------------------------------------------------= --------*/ #include <time.h> typedef struct { // General information concerning the server and this structure char hostname[40]; // or truncated hostname as the case may be // later this may be changed to an int 64 time_t mtime; // (always ignored by receiver, set to 0) time_t padding; // (always ignored by receiver, set to 0) /* Note to mod: contact is defined as struct sockaddr_in which is in turn is defined=20 in winsock.h and winsock2.h as: * * Socket address, internet style. * struct sockaddr_in { short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; }; This does not accord with that declared in backhand's serverstats.h = which is: struct { struct in_addr sin_addr; unsigned short sin_port; unsigned short __pad; } contact; To correct this issue I have used the serverstats.h structure */ // struct sockaddr_in contact; // inet addr + port struct in_addr sin_addr; unsigned short sin_port; unsigned short __pad; =09 // Statistics for decision making int arriba; // How fast is THIS machine. int aservers; // (always ignored by receiver, set to 0) =20 int nservers; // (always ignored by receiver, set to 0)=20 int load; // load int load_hwm; // (always ignored by receiver, set to 0)=20 int cpu; // cpu idle time int ncpu; // number of CPUs (load doesn't mean too much otherwise) int tmem; // total memory installed (in bytes) int amem; // available memory int numbacked; // (always ignored by receiver, set to 0)=20 int tatime; // (always ignored by receiver, set to 0)=20 } serverstat; //We are only broadcasting, don't waste time converting items which are = ignored anyway. #define serverstat_endian_convert(a, f) {\ (a).load =3D f((a).load);\ (a).cpu =3D f((a).cpu);\ (a).tmem =3D f((a).tmem);\ (a).amem =3D f((a).amem);\ } // no need to convert most data, it is converted to network byte = order when we load it or it is ignored. // hton(s|l) for serverstats You need to call this before sending out a = serverstat=20 #define htonss(a) serverstat_endian_convert(a,htonl) ------=_NextPart_000_0007_01C3E0F4.A3EBFDA0 Content-Type: application/octet-stream; name="broadcast.cpp" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="broadcast.cpp" /*-----------------------------------------------------------------------= -------- Copyright (c) 2001 CerebraSoft Module Name: broadcast.cpp Abstract: Functions to broadcast performance information to mod backhand server. License: All rights reserved. This product includes software developed at The Center for Networking and Distributed Systems at The Johns Hopkins University for use in the Backhand project (http://www.cnds.jhu.edu/backhand). Creator: Theo Schlossnagle=20 Guidance: Yair Amir Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.=20 =20 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. =20 3. All advertising materials mentioning features or use of this software must display the following acknowledgment: "This product includes software developed by Cerebrasoft (http://www.cerebrasoft.com). Creator: Rob Butler" 4. The names "Backhand Broadcaster" and "NT Backhand Broadcaster" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact www.cerebrasoft.com. =20 5. Products derived from this software may not be called "Backhand = Broadcaster" or "NT Backhand Broadcaster" nor may "Backhand Broadcaster" or "NT Backhand Broadcaster" appear in their names without prior = written permission. For written permission, please contact = www.cerebrasoft.com. =20 6. Redistributions of any form whatsoever must retain the following acknowledgment: "This product includes software developed by Cerebrasoft (http://www.cerebrasoft.com). Creator: Rob Butler" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------= --------*/ #include <string> using namespace std; #include <winsock2.h> #include "broadcast.h" #include "registry.h" #include "NTServerStats.h" #include "NTStats.h" #include "eventLog.h" /*-----------------------------------------------------------------------= -------- Global Defines -------------------------------------------------------------------------= --------*/ #define LoadCPU_ITERS 6666 // number of times to loop in loadCPU #define defArribaThreads 12 // default number of threads to use in = calculating arriba #define appName "NT Backhand Broadcaster" // event log app name /*-----------------------------------------------------------------------= -------- Global Variables -------------------------------------------------------------------------= --------*/ HANDLE broadcastThread; // handle to broadcast thread bool keepRunning =3D false; // flag to stop broadcast thread DWORD defDelay =3D 0; // time to delay broadcast init & start. WSAData wsData; // Holds windows socket implementation data SOCKET bcstSocket; // broadcast socket SOCKET mcstSocket; // multicast socket int sockTrue =3D 1; // setsockopt requires a pointer to an int valued = at 1 for true int sockFalse =3D 0; // setsockopt requires a pointer to an int values = at 0 for false; DWORD unUsed =3D 0; // some socket functions require an output that = we don't use. typedef struct { // simple structure to hold contact information char hostname[40]; // hostname we are referred to as sockaddr_in contact; // ip address to use in contacting us sockaddr_in sendTo; // ip address to muticast / broadcast to. int ttl; // ttl to use in multicasting stats bool isMulticast; // true if we should multicast, false otherwise. bool skip; // if true, we do not broadcast this one. } contactInfo; contactInfo *transmitTo; // pointer to an array of contact info. DWORD numTransmitTo; // how big is the above array. /*-----------------------------------------------------------------------= -------- Function Definitions -------------------------------------------------------------------------= --------*/ DWORD WINAPI loadCPU(LPVOID param); DWORD WINAPI broadcast(LPVOID param); int calcArriba(); void transmit(serverstat *stats); bool setupSockets(); void closeSockets(); /*-----------------------------------------------------------------------= -------- startBroadcasting(DWORD delay) - begins broadcasting performance data = to network delay specifies the time in seconds in which to delay broadcasting. It = is only the default delay time, and can be overridden with a registry entry for = Delay. -------------------------------------------------------------------------= --------*/ bool startBroadcasting(DWORD delay){ keepRunning =3D true; defDelay =3D delay; broadcastThread =3D CreateThread(NULL, 0, &broadcast, NULL, 0, NULL); if(broadcastThread =3D=3D NULL){ logAppMsg(appName, EVENTLOG_ERROR_TYPE, "Attempt to start broadcast = thread failed!"); keepRunning =3D false; closeStats(); closeSockets(); return false; // returns false if thread cannot be created. } return true; } /*-----------------------------------------------------------------------= -------- stopBroadcasting - stops broadcasting performance data to network -------------------------------------------------------------------------= --------*/ void stopBroadcasting(){ keepRunning =3D false; if(broadcastThread !=3D NULL) WaitForSingleObject(broadcastThread, 10000); closeStats(); closeSockets(); } /*-----------------------------------------------------------------------= -------- broadcast(LPVOID sleepTime) - Broadcast perfomance information onto the = network to mod backhand. -------------------------------------------------------------------------= --------*/ DWORD WINAPI broadcast(LPVOID param){ serverstat stats; // get delay from registry int delay =3D getRegDWORD(HKEY_LOCAL_MACHINE, regRoot, "Delay", = defDelay); // guarantee delay is not negative. if(delay < 0) delay =3D defDelay; // delay startup Sleep(delay * 1000); // get arriba from registry int arriba =3D getRegDWORD(HKEY_LOCAL_MACHINE, regRoot, "Arriba", 0); =09 // if arriba =3D=3D 0, registry didn't have it if(arriba < 1){ logAppMsg(appName, EVENTLOG_INFORMATION_TYPE, "Arriba not found in = registry. Calculating Arriba."); arriba =3D calcArriba(); // calculate arriba regSetDword(HKEY_LOCAL_MACHINE, regRoot, "Arriba", arriba); // store = in registry } // if arriba still =3D=3D 0, error in getting from reg, and could not = calculate, exit if(arriba < 1){ logAppMsg(appName, EVENTLOG_ERROR_TYPE, "Failure attempting to = calculate Arriba!"); broadcastThread =3D NULL; return 0; } // setup stats structure stats.arriba =3D htonl(arriba); // convert to network order // convert to network order stats.ncpu =3D htonl(getRegDWORD(HKEY_LOCAL_MACHINE, regRoot, "numCPU", = 1)); =20 // ignored stats, set to 0 - no need to convert network order, all = bytes 0 stats.aservers =3D 0; stats.nservers =3D 0; stats.load_hwm =3D 0; stats.mtime =3D 0; stats.numbacked =3D 0; stats.tatime =3D 0; if(setupSockets() =3D=3D false){ logAppMsg(appName, EVENTLOG_ERROR_TYPE, "CANNOT broadcast mod_backhand = statistics!"); broadcastThread =3D NULL;=09 return 0; } // initialize NT statistics if(initStats() =3D=3D false){ logAppMsg(appName, EVENTLOG_ERROR_TYPE, "Failure attempting to = initialize statistics system!"); broadcastThread =3D NULL; return 0; } logAppMsg(appName, EVENTLOG_INFORMATION_TYPE, "Broadcasting = mod_backhand stastics."); while(keepRunning){ if(getStats(&stats)){ // get performance stats. (returns true if = successful) htonss(stats); // convert to network byte order transmit(&stats); // transmit stats. } Sleep(1000); // wait 1 second and do it again } return 0; } /*-----------------------------------------------------------------------= -------- transmit(serverstat) - transmit data to network. -------------------------------------------------------------------------= --------*/ void transmit(serverstat *stats){ for(DWORD i =3D 0; i < numTransmitTo; i++){ if(transmitTo[i].skip =3D=3D false){ // Fix for change to structure of 'contact' // set the appropriate hostname and contact info. // strcpy(stats->hostname, transmitTo[i].hostname); memcpy(&stats->hostname, &transmitTo[i].hostname, 40); /* The following line has been modified - DAVE */ // memcpy(&stats->contact, &transmitTo[i].contact, = sizeof(stats->contact)); memcpy(&stats->sin_addr, &transmitTo[i].contact.sin_addr, = sizeof(stats->sin_addr)); memcpy(&stats->sin_port, &transmitTo[i].contact.sin_port, = sizeof(stats->sin_port)); memcpy(&stats->__pad, &transmitTo[i].contact.sin_zero, 2); // is it multicast, or broadcast if(transmitTo[i].isMulticast){ // multicast stats // attempt change TTL for this transmission if(WSAIoctl(mcstSocket, SIO_MULTICAST_SCOPE, &transmitTo[i].ttl, = sizeof(transmitTo[i].ttl), NULL, 0, &unUsed, NULL, NULL) =3D=3D 0){ // successful, transmit data sendto(mcstSocket, (const char *) stats, sizeof(serverstat), 0, = (LPSOCKADDR) &transmitTo[i].sendTo, sizeof(sockaddr_in)); } }else{ // broadcast stats sendto(bcstSocket, (const char *) stats, sizeof(serverstat), 0, = (LPSOCKADDR) &transmitTo[i].sendTo, sizeof(sockaddr_in)); } } // closes if(skip =3D=3D false) } // closes for loop } /*-----------------------------------------------------------------------= -------- calcArriba - Calculate the Arriba for this machine. by default the arriba is calculated for 12 threads. The number of = threads can be modified by a registry setting. returns the arriba for the machine. Returns a negative number if there = was an error -------------------------------------------------------------------------= --------*/ int calcArriba(){ time_t start, finish; // get the number of threads we should use from the registry DWORD numThreads =3D getRegDWORD(HKEY_LOCAL_MACHINE, regRoot, = "ArribaThreads", defArribaThreads); // make sure we do at least 1 thread if(numThreads < 1) numThreads =3D 1; // allocate an array to hold each threads handle HANDLE *threads =3D (HANDLE *) malloc(numThreads * sizeof(HANDLE)); // we could not allocate memory, return an error if(threads =3D=3D NULL) return -1; // store start time. time(&start); =09 // create the threads, and let em bog down the cpu(s) for(DWORD i =3D 0; i < numThreads; i++) threads[i] =3D CreateThread(NULL, 0, &loadCPU, NULL, 0, NULL); // wait for all the threads to finish WaitForMultipleObjects(numThreads, threads, true, INFINITE); // get finish time time(&finish); // calculate total time and multiply by 1000, this is the arriba. return (int) (LoadCPU_ITERS * 101 / difftime(finish, start)) * 1000; } /*-----------------------------------------------------------------------= -------- loadCPU - a long running function that loads up the cpu(s) in the system. We determine how fast a machine is by seeing how fast it can = do=20 this calculation for many threads. This function copied (and modified slightly) from mod_backhand. See Backhand_Broadcast.h for original notice. -------------------------------------------------------------------------= --------*/ DWORD WINAPI loadCPU(LPVOID param){ double z[101] =3D {0.0}; for(int i=3D0; i < LoadCPU_ITERS; i++){ for(int j=3D0; j<101; j++){ z[j] =3D (!z[j])?j: (z[(i-1)%101]+1.0)*(z[(i+1)%101]+1.0); if(z[j] > 100000000.0 || z[j]<0) z[j]=3D3.0; } } return 0; } /*-----------------------------------------------------------------------= -------- setupSockets - sets up the sockets for broadcasting stats. -------------------------------------------------------------------------= --------*/ bool setupSockets(){ char *keyName; string subKey; char *tmp; DWORD keyCnt; int structLen; // initialize winsock DLL if(WSAStartup(0x0202, &wsData) !=3D 0){ logAppMsg(appName, EVENTLOG_ERROR_TYPE, "Could not initialize = winsock!"); return false; } bcstSocket =3D WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0, = WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF); if(bcstSocket =3D=3D INVALID_SOCKET){ logAppMsg(appName, EVENTLOG_ERROR_TYPE, "Unable to create broadcast = socket!"); closeSockets(); return false; } // allow broadcasting on the socket. if(setsockopt(bcstSocket, SOL_SOCKET, SO_BROADCAST, (const char *) = &sockTrue, sizeof(int)) !=3D 0){ logAppMsg(appName, EVENTLOG_ERROR_TYPE, "Cannot enable socket for = broadcasting!"); closeSockets(); return false; } // allow the socket to be re-used. if(setsockopt(bcstSocket, SOL_SOCKET, SO_REUSEADDR, (const char *) = &sockTrue, sizeof(int)) !=3D 0){ logAppMsg(appName, EVENTLOG_ERROR_TYPE, "Cannot enable broadcast = socket re-use!"); closeSockets(); return false; } mcstSocket =3D WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0, = WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF); if(mcstSocket =3D=3D INVALID_SOCKET){ logAppMsg(appName, EVENTLOG_ERROR_TYPE, "Unable to create multicast = socket!"); closeSockets(); return false; } // allow broadcasting on the socket. if(setsockopt(mcstSocket, SOL_SOCKET, SO_BROADCAST, (const char *) = &sockTrue, sizeof(int)) !=3D 0){ logAppMsg(appName, EVENTLOG_ERROR_TYPE, "Cannot enable socket for = multicasting!"); closeSockets(); return false; } // allow the socket to be re-used. if(setsockopt(mcstSocket, SOL_SOCKET, SO_REUSEADDR, (const char *) = &sockTrue, sizeof(int)) !=3D 0){ logAppMsg(appName, EVENTLOG_ERROR_TYPE, "Cannot enable multicast = socket re-use!"); closeSockets(); return false; } =09 // disable loopback=20 if(WSAIoctl(mcstSocket, SIO_MULTIPOINT_LOOPBACK, &sockFalse, = sizeof(int), NULL, 0, &unUsed, NULL, NULL) !=3D 0){ logAppMsg(appName, EVENTLOG_ERROR_TYPE, "Cannot disable multicast = socket loopback!"); closeSockets(); return false; } // determine number of registry subkeys keyCnt =3D regSubKeyCnt(HKEY_LOCAL_MACHINE, regRoot); if(keyCnt < 1){ logAppMsg(appName, EVENTLOG_ERROR_TYPE, "No broadcast data in = registry"); closeSockets(); return false; } // allocate array to hold contact and related information transmitTo =3D (contactInfo *) malloc(keyCnt * sizeof(contactInfo)); if(transmitTo =3D=3D NULL){ logAppMsg(appName, EVENTLOG_ERROR_TYPE, "Unable to allocate memory for = transmit array!"); closeSockets(); return false; } // remember our array size numTransmitTo =3D keyCnt; // loop through all registry sub keys for(int i =3D 0; i < keyCnt; i++){ // get subkey name keyName =3D regEnumKeys(HKEY_LOCAL_MACHINE, regRoot, i); if(keyName !=3D NULL){ // create registry subkey path subKey.assign(regRoot).append("\\").append(keyName); // get registry information tmp =3D getRegString(HKEY_LOCAL_MACHINE, subKey.c_str(), "HostName", = NULL, false); if(tmp !=3D NULL){ strncpy(transmitTo[i].hostname, tmp, 39); transmitTo[i].hostname[39] =3D NULL; // make sure to null terminate = string. free(tmp); // don't need hostName anymore, get rid of it. }else{ strncpy(transmitTo[i].hostname, "NT Remote Server", 39); } // initialize some variables (as required) transmitTo[i].contact.sin_family =3D AF_INET; structLen =3D sizeof(sockaddr_in); transmitTo[i].skip =3D false; // get data from registry. No need to convert to network byte = order, WSAStringToAddress already does. tmp =3D getRegString(HKEY_LOCAL_MACHINE, subKey.c_str(), "ContactIP", = NULL, false); if(tmp !=3D NULL){ if(WSAStringToAddress(tmp, AF_INET, NULL, (LPSOCKADDR) = &transmitTo[i].contact, &structLen) =3D=3D SOCKET_ERROR){ logAppMsg(appName, EVENTLOG_ERROR_TYPE, 3, "ContactIP for ", = keyName, " incorrect format. Format should be aaa.bbb.ccc.ddd"); transmitTo[i].skip =3D true; } free(tmp); }else{ logAppMsg(appName, EVENTLOG_ERROR_TYPE, 3, "ContactIP for ", = keyName, " not found!"); transmitTo[i].skip =3D true; } // get contact port, and convert to network order. transmitTo[i].contact.sin_port =3D = htons(getRegDWORD(HKEY_LOCAL_MACHINE, subKey.c_str(), "ContactPort", = 80)); // initialize some variables (as required) transmitTo[i].sendTo.sin_family =3D AF_INET; structLen =3D sizeof(sockaddr_in); // get data from registry. No need to convert to network byte = order, WSAStringToAddress already does. tmp =3D getRegString(HKEY_LOCAL_MACHINE, subKey.c_str(), "SendIP", = NULL, false); if(tmp !=3D NULL){ if(WSAStringToAddress(tmp, AF_INET, NULL, (LPSOCKADDR) = &transmitTo[i].sendTo, &structLen) =3D=3D SOCKET_ERROR){ logAppMsg(appName, EVENTLOG_ERROR_TYPE, 3, "SendIP for ", keyName, = " incorrect format. Format should be aaa.bbb.ccc.ddd"); transmitTo[i].skip =3D true; } free(tmp); // determine if we are broadcasting or multicasting. DWORD tcm =3D transmitTo[i].sendTo.sin_addr.s_addr >> 24; if(tcm >=3D224 && tcm <=3D239){ transmitTo[i].isMulticast =3D true; }else{ transmitTo[i].isMulticast =3D false; } }else{ logAppMsg(appName, EVENTLOG_ERROR_TYPE, 3, "SendIP for ", keyName, " = not found!"); transmitTo[i].skip =3D true; } // get port & convert to network order transmitTo[i].sendTo.sin_port =3D = htons(getRegDWORD(HKEY_LOCAL_MACHINE, subKey.c_str(), "SendPort", = 4445)); // get TTL. Using locally, no need to convert to network order transmitTo[i].ttl =3D getRegDWORD(HKEY_LOCAL_MACHINE, subKey.c_str(), = "SendTTL", 1); // done with keyname, get rid of it. free(keyName); }else { // keyname was null; break; // exit loop } } // ends for loop return true; } /*-----------------------------------------------------------------------= -------- closeSockets() - returns all socket resources to the system. -------------------------------------------------------------------------= --------*/ void closeSockets(){ if(bcstSocket !=3D NULL && bcstSocket !=3D INVALID_SOCKET){ closesocket(bcstSocket); bcstSocket =3D NULL; } if(mcstSocket !=3D NULL && mcstSocket !=3D INVALID_SOCKET){ closesocket(mcstSocket); mcstSocket =3D NULL; } // DO NOT PERFORM A WSACleanup!! /* If this is running inside of IIS calling WSACleanup will cause = windows sockets DLL to be unloaded and unavailable for ALL THREADS including IIS = threads! We don't want to take down IIS (with a huge crash) if for some reason we = can't broadcast our stats. If we are not in IIS, eventually the DLL should be = unloaded and collected through normal Win32 application cleanup when this app ends. */ } ------=_NextPart_000_0007_01C3E0F4.A3EBFDA0--
|