diff --git a/modules/ca/src/client/repeater.cpp b/modules/ca/src/client/repeater.cpp index 61ba33fc5..67429e659 100644 --- a/modules/ca/src/client/repeater.cpp +++ b/modules/ca/src/client/repeater.cpp @@ -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 ) {