Mailing List Archive

NT Backhand Broadcaster
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--
NT Backhand Broadcaster [ In reply to ]
On Thu, 2004-01-22 at 09:33, Dave Smith wrote:
> 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.

I'll apply these with Rob's go ahead.

--
// Theo Schlossnagle
// Principal Engineer -- http://www.omniti.com/~jesus/
// Postal Engine -- http://www.postalengine.com/
// Ecelerity: fastest MTA on earth
NT Backhand Broadcaster [ In reply to ]
The patches look good, you can apply them. I would prefer if some of the
extra un-needed comments were removed.

I double checked and the broadcast structure in mod_backhand did change
between version 1.2.1 and 1.2.2, and this is what caused NTBHB to have the
problem. It would be nice if there were notes added to the mod_backhand
serverstat.h file to remind future developers that changes to that structure
should be replicated in NTServerStats.h, and also related NT BHB code should
be modified too.

Thanks for the contrib Dave.

Later
Rob


> On Thu, 2004-01-22 at 09:33, Dave Smith wrote:
> > 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.
>
> I'll apply these with Rob's go ahead.
>
> --
> // Theo Schlossnagle
> // Principal Engineer -- http://www.omniti.com/~jesus/
> // Postal Engine -- http://www.postalengine.com/
> // Ecelerity: fastest MTA on earth
>
>
>
> _______________________________________________
> backhand-users mailing list
> backhand-users@lists.backhand.org
> http://lists.backhand.org/mailman/listinfo/backhand-users