Added Multicast to caRepeater

Modifications to allow for CA multicast listening by adding multicast address
from EPICS_CA_BEACON_ADDR_LIST (or EPICS_CA_ADDR_LIST if beacon list is empty).
Original modifications from Jim Smedinghoff, with further changes by Pierrick Hanlet.
This commit is contained in:
hanlet
2020-02-12 08:56:27 -06:00
committed by Michael Davidsaver
parent bf533ac195
commit 97bf9171c6

View File

@@ -74,6 +74,7 @@
#include "caProto.h"
#include "udpiiu.h"
#include "repeaterClient.h"
#include "addrList.h"
/*
@@ -92,7 +93,7 @@ static int makeSocket ( unsigned short port, bool reuseAddr, SOCKET * pSock )
SOCKET sock = epicsSocketCreate ( AF_INET, SOCK_DGRAM, 0 );
if ( sock == INVALID_SOCKET ) {
*pSock = sock;
*pSock = sock;
return SOCKERRNO;
}
@@ -517,6 +518,56 @@ void ca_repeater ()
return;
}
#ifdef IP_ADD_MEMBERSHIP
/*
* join UDP socket to any multicast groups
*/
{
ELLLIST casBeaconAddrList = ELLLIST_INIT;
ELLLIST casMergeAddrList = ELLLIST_INIT;
/*
* collect user specified beacon address list;
* check BEACON_ADDR_LIST list first; if no result, take CA_ADDR_LIST
*/
if(!addAddrToChannelAccessAddressList(&casMergeAddrList,&EPICS_CAS_BEACON_ADDR_LIST,port,0)) {
addAddrToChannelAccessAddressList(&casMergeAddrList,&EPICS_CA_ADDR_LIST,port,0);
}
/* First clean up */
removeDuplicateAddresses(&casBeaconAddrList, &casMergeAddrList , 0);
osiSockAddrNode *pNode;
for(pNode = (osiSockAddrNode*)ellFirst(&casBeaconAddrList);
pNode;
pNode = (osiSockAddrNode*)ellNext(&pNode->node))
{
if(pNode->addr.ia.sin_family==AF_INET) {
epicsUInt32 top = ntohl(pNode->addr.ia.sin_addr.s_addr)>>24;
if(top>=224 && top<=239) {
/* This is a multi-cast address */
struct ip_mreq mreq;
memset(&mreq, 0, sizeof(mreq));
mreq.imr_multiaddr = pNode->addr.ia.sin_addr;
mreq.imr_interface.s_addr = INADDR_ANY;
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(char *) &mreq, sizeof(mreq)) != 0) {
char name[40];
char sockErrBuf[64];
epicsSocketConvertErrnoToString (sockErrBuf, sizeof ( sockErrBuf ) );
ipAddrToDottedIP (&pNode->addr.ia, name, sizeof(name));
errlogPrintf("caR: Socket mcast join to %s failed: %s\n", name, sockErrBuf );
}
}
}
}
}
#endif
debugPrintf ( ( "CA Repeater: Attached and initialized\n" ) );
while ( true ) {