pcas: listen for mcast search request

This commit is contained in:
Michael Davidsaver
2016-01-21 12:17:02 -05:00
parent cdffcbfbae
commit cba449d53b
4 changed files with 53 additions and 0 deletions

View File

@@ -141,6 +141,38 @@ caStatus caServerI::attachInterface ( const caNetAddr & addrIn,
return S_cas_success;
}
void caServerI::addMCast(const osiSockAddr& addr)
{
#ifdef IP_ADD_MEMBERSHIP
epicsGuard < epicsMutex > locker ( this->mutex );
tsDLIter < casIntfOS > iter = this->intfList.firstIter ();
while ( iter.valid () ) {
struct ip_mreq mreq;
memset(&mreq, 0, sizeof(mreq));
mreq.imr_interface = iter->serverAddress().getSockIP().sin_addr;
mreq.imr_multiaddr = addr.ia.sin_addr;
if(setsockopt(iter->casDGIntfIO::getFD(), IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))!=0)
{
struct sockaddr_in temp;
char name[40];
char sockErrBuf[64];
temp.sin_family = AF_INET;
temp.sin_addr = mreq.imr_multiaddr;
temp.sin_port = addr.ia.sin_port;
epicsSocketConvertErrnoToString (
sockErrBuf, sizeof ( sockErrBuf ) );
ipAddrToDottedIP (&temp, name, sizeof(name));
fprintf(stderr, "CAS: Socket mcast join %s failed with \"%s\"\n",
name, sockErrBuf );
}
iter++;
}
#endif
}
void caServerI::sendBeacon ( ca_uint32_t beaconNo )
{
epicsGuard < epicsMutex > locker ( this->mutex );

View File

@@ -103,6 +103,8 @@ private:
caStatus attachInterface ( const caNetAddr & addr, bool autoBeaconAddr,
bool addConfigAddr );
virtual void addMCast(const osiSockAddr&);
void sendBeacon ( ca_uint32_t beaconNo );
caServerI ( const caServerI & );

View File

@@ -14,6 +14,7 @@
//
#include <ctype.h>
#include <list>
#include "epicsSignal.h"
#include "envDefs.h"
@@ -92,6 +93,9 @@ void caServerIO::locateInterfaces ()
autoBeaconAddr = true;
}
typedef std::list<osiSockAddr> mcastAddrs_t;
mcastAddrs_t mcastAddrs;
//
// bind to the the interfaces specified - otherwise wildcard
// with INADDR_ANY and allow clients to attach from any interface
@@ -114,6 +118,15 @@ void caServerIO::locateInterfaces ()
pToken);
continue;
}
epicsUInt32 top = ntohl(saddr.sin_addr.s_addr)>>24;
if (saddr.sin_family==AF_INET && top>=224 && top<=239) {
osiSockAddr oaddr;
oaddr.ia = saddr;
mcastAddrs.push_back(oaddr);
continue;
}
stat = this->attachInterface (caNetAddr(saddr), autoBeaconAddr, configAddrOnceFlag);
if (stat) {
errMessage(stat, "unable to attach explicit interface");
@@ -131,6 +144,10 @@ void caServerIO::locateInterfaces ()
errMessage(stat, "unable to attach any interface");
}
}
for (mcastAddrs_t::const_iterator it = mcastAddrs.begin(); it!=mcastAddrs.end(); ++it) {
this->addMCast(*it);
}
}
//

View File

@@ -47,6 +47,8 @@ private:
virtual caStatus attachInterface (
const caNetAddr & addr, bool autoBeaconAddr,
bool addConfigAddr ) = 0;
virtual void addMCast(const osiSockAddr&) = 0;
};
#endif // caServerIOh