From 8bba4da4329038e1e4348ec9e5f0933dacc97397 Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Thu, 29 Aug 2002 16:59:46 +0000 Subject: [PATCH] add support for ignoring requests from certain addresses --- src/cas/io/bsdSocket/casDGIntfIO.cc | 120 ++++++++++++++++++---------- src/cas/io/bsdSocket/casIOD.h | 56 +++++++++---- src/cas/io/bsdSocket/casIODIL.h | 22 ++++- 3 files changed, 141 insertions(+), 57 deletions(-) diff --git a/src/cas/io/bsdSocket/casDGIntfIO.cc b/src/cas/io/bsdSocket/casDGIntfIO.cc index 80996db6b..9c5ee9dd3 100644 --- a/src/cas/io/bsdSocket/casDGIntfIO.cc +++ b/src/cas/io/bsdSocket/casDGIntfIO.cc @@ -21,7 +21,7 @@ #include "server.h" #include "addrList.h" - +#include "casIODIL.h" /* * forcePort () @@ -130,17 +130,17 @@ casDGIntfIO::casDGIntfIO (caServerI &serverIn, const caNetAddr &addr, } status = bind ( this->sock, &serverAddr.sa, sizeof (serverAddr) ); - if (status<0) { + if ( status < 0 ) { char buf[64]; int errnoCpy = SOCKERRNO; - ipAddrToA (&serverAddr.ia, buf, sizeof(buf)); - errPrintf (S_cas_bindFail, __FILE__, __LINE__, - "- bind UDP IP addr=%s failed because %s", buf, SOCKERRSTR(errnoCpy) ); + ipAddrToA ( &serverAddr.ia, buf, sizeof ( buf ) ); + errPrintf ( S_cas_bindFail, __FILE__, __LINE__, + "- bind UDP IP addr=%s failed because %s", buf, SOCKERRSTR ( errnoCpy ) ); socket_close (this->sock); throw S_cas_bindFail; } - if (addConfigBeaconAddr) { + if ( addConfigBeaconAddr ) { // // by default use EPICS_CA_ADDR_LIST for the @@ -148,22 +148,45 @@ casDGIntfIO::casDGIntfIO (caServerI &serverIn, const caNetAddr &addr, // const ENV_PARAM *pParam; - if (envGetConfigParamPtr(&EPICS_CAS_INTF_ADDR_LIST) || - envGetConfigParamPtr(&EPICS_CAS_BEACON_ADDR_LIST)) { - pParam = &EPICS_CAS_BEACON_ADDR_LIST; + if ( envGetConfigParamPtr ( & EPICS_CAS_INTF_ADDR_LIST ) || + envGetConfigParamPtr ( & EPICS_CAS_BEACON_ADDR_LIST ) ) { + pParam = & EPICS_CAS_BEACON_ADDR_LIST; } else { - pParam = &EPICS_CA_ADDR_LIST; + pParam = & EPICS_CA_ADDR_LIST; } // // add in the configured addresses // addAddrToChannelAccessAddressList ( - &BCastAddrList, pParam, beaconPort); + & BCastAddrList, pParam, beaconPort ); } - removeDuplicateAddresses ( &this->beaconAddrList, &BCastAddrList, 0 ); + removeDuplicateAddresses ( & this->beaconAddrList, & BCastAddrList, 0 ); + + { + ELLLIST parsed, filtered; + ellInit ( & parsed ); + ellInit ( & filtered ); + // we dont care what port they are coming from + addAddrToChannelAccessAddressList ( & parsed, & EPICS_CAS_IGNORE_ADDR_LIST, 0 ); + removeDuplicateAddresses ( & filtered, & parsed, true ); + + while ( ELLNODE * pRawNode = ellGet ( & filtered ) ) { + assert ( offsetof (osiSockAddrNode, node) == 0 ); + osiSockAddrNode * pNode = reinterpret_cast < osiSockAddrNode * > ( pRawNode ); + if ( pNode->addr.sa.sa_family == AF_INET ) { + ipIgnoreEntry * pIPI = new ipIgnoreEntry ( pNode->addr.ia.sin_addr.s_addr ); + this->ignoreTable.add ( * pIPI ); + } + else { + errlogPrintf ( + "Expected IP V4 address - EPICS_CAS_IGNORE_ADDR_LIST entry ignored\n" ); + } + free ( pNode ); + } + } // // Solaris specific: @@ -193,17 +216,17 @@ casDGIntfIO::casDGIntfIO (caServerI &serverIn, const caNetAddr &addr, throw S_cas_internal; } - status = bind (this->bcastRecvSock, &serverBCastAddr.sa, + status = bind ( this->bcastRecvSock, &serverBCastAddr.sa, sizeof (serverBCastAddr.sa) ); if (status<0) { char buf[64]; int errnoCpy = SOCKERRNO; - ipAddrToA (&serverBCastAddr.ia, buf, sizeof(buf)); - errPrintf (S_cas_bindFail, __FILE__, __LINE__, + ipAddrToA ( & serverBCastAddr.ia, buf, sizeof ( buf ) ); + errPrintf ( S_cas_bindFail, __FILE__, __LINE__, "- bind UDP IP addr=%s failed because %s", - buf, SOCKERRSTR(errnoCpy)); - socket_close (this->sock); - socket_close (this->bcastRecvSock); + buf, SOCKERRSTR ( errnoCpy ) ); + socket_close ( this->sock ); + socket_close ( this->bcastRecvSock ); throw S_cas_bindFail; } } @@ -241,6 +264,8 @@ casDGIntfIO::~casDGIntfIO() nnode = nnode->next; free ( pnode ); } + + this->ignoreTable.traverse ( & ipIgnoreEntry::destroy ); osiSockRelease (); } @@ -276,36 +301,47 @@ void casDGIntfIO::xSetNonBlocking() // inBufClient::fillCondition casDGIntfIO::osdRecv ( char * pBufIn, bufSizeT size, // X aCC 361 - fillParameter parm, bufSizeT & actualSize, caNetAddr & fromOut ) + fillParameter parm, bufSizeT & actualSize, caNetAddr & fromOut ) { int status; osiSocklen_t addrSize; sockaddr addr; SOCKET sockThisTime; - if (parm==fpUseBroadcastInterface) { + if ( parm == fpUseBroadcastInterface ) { sockThisTime = this->bcastRecvSock; } else { sockThisTime = this->sock; } - addrSize = ( osiSocklen_t ) sizeof (addr); + addrSize = ( osiSocklen_t ) sizeof ( addr ); status = recvfrom ( sockThisTime, pBufIn, size, 0, &addr, &addrSize ); - if (status<=0) { - if (status<0) { + if ( status <= 0 ) { + if ( status < 0 ) { int errnoCpy = SOCKERRNO; - if( errnoCpy != SOCK_EWOULDBLOCK ){ - errlogPrintf("CAS: UDP recv error was %s", - SOCKERRSTR(errnoCpy)); + if ( errnoCpy != SOCK_EWOULDBLOCK ) { + errlogPrintf ( "CAS: UDP recv error was %s", + SOCKERRSTR ( errnoCpy ) ); } } return casFillNone; } else { + // filter out and discard frames received from the ignore list + if ( this->ignoreTable.numEntriesInstalled () > 0 ) { + if ( addr.sa_family == AF_INET ) { + sockaddr_in * pIP = + reinterpret_cast < sockaddr_in * > ( & addr ); + ipIgnoreEntry comapre ( pIP->sin_addr.s_addr ); + if ( this->ignoreTable.lookup ( comapre ) ) { + return casFillNone; + } + } + } fromOut = addr; - actualSize = (bufSizeT) status; + actualSize = static_cast < bufSizeT > ( status ); return casFillProgress; } } @@ -323,17 +359,17 @@ casDGIntfIO::osdSend ( const char * pBufIn, bufSizeT size, // X aCC 361 // (char *) cast below is for brain dead wrs prototype // struct sockaddr dest = to; - status = sendto (this->sock, (char *) pBufIn, size, 0, - &dest, sizeof(dest)); - if (status>=0) { + status = sendto ( this->sock, (char *) pBufIn, size, 0, + & dest, sizeof ( dest ) ); + if ( status >= 0 ) { assert ( size == (unsigned) status ); return outBufClient::flushProgress; } else { int errnoCpy = SOCKERRNO; - if (errnoCpy != SOCK_EWOULDBLOCK) { + if ( errnoCpy != SOCK_EWOULDBLOCK ) { char buf[64]; - sockAddrToA (&dest, buf, sizeof(buf)); + sockAddrToA ( & dest, buf, sizeof ( buf ) ); errlogPrintf ( "CAS: UDP socket send to \"%s\" failed because \"%s\"\n", buf, SOCKERRSTR(errnoCpy)); @@ -353,17 +389,17 @@ bufSizeT casDGIntfIO::incomingBytesPresent () const // X aCC 361 int status; osiSockIoctl_t nchars = 0; - status = socket_ioctl (this->sock, FIONREAD, &nchars); // X aCC 392 - if (status<0) { - errlogPrintf ("CAS: FIONREAD failed because \"%s\"\n", - SOCKERRSTR(SOCKERRNO)); + status = socket_ioctl ( this->sock, FIONREAD, & nchars ); // X aCC 392 + if ( status < 0 ) { + errlogPrintf ( "CAS: FIONREAD failed because \"%s\"\n", + SOCKERRSTR ( SOCKERRNO ) ); return 0u; } - else if (nchars<0) { + else if ( nchars < 0 ) { return 0u; } else { - return (bufSizeT) nchars; + return ( bufSizeT ) nchars; } } @@ -381,11 +417,11 @@ void casDGIntfIO::sendBeaconIO ( char & msg, unsigned length, portField = inetAddr.sin_port; // the TCP port - for (pAddr = reinterpret_cast (ellFirst(&this->beaconAddrList)); - pAddr; pAddr = reinterpret_cast (ellNext(&pAddr->node))) { - status = connect (this->beaconSock, &pAddr->addr.sa, sizeof(pAddr->addr.sa)); + for (pAddr = reinterpret_cast ( ellFirst ( & this->beaconAddrList ) ); + pAddr; pAddr = reinterpret_cast ( ellNext ( & pAddr->node ) ) ) { + status = connect ( this->beaconSock, &pAddr->addr.sa, sizeof ( pAddr->addr.sa ) ); if (status<0) { - ipAddrToDottedIP (&pAddr->addr.ia, buf, sizeof(buf)); + ipAddrToDottedIP ( & pAddr->addr.ia, buf, sizeof ( buf ) ); errlogPrintf ( "%s: CA beacon routing (connect to \"%s\") error was \"%s\"\n", __FILE__, buf, SOCKERRSTR(SOCKERRNO)); } diff --git a/src/cas/io/bsdSocket/casIOD.h b/src/cas/io/bsdSocket/casIOD.h index 1a6301594..a00487609 100644 --- a/src/cas/io/bsdSocket/casIOD.h +++ b/src/cas/io/bsdSocket/casIOD.h @@ -18,22 +18,50 @@ #ifndef includeCASIODH #define includeCASIODH -#undef epicsExportSharedSymbols +#ifdef epicsExportSharedSymbols +# define ipIgnoreEntryEpicsExportSharedSymbols +# undef epicsExportSharedSymbols +#endif + #include "envDefs.h" -#define epicsExportSharedSymbols +#include "resourceLib.h" +#include "epicsSingleton.h" +#include "tsFreeList.h" +#include "osiSock.h" +#include "inetAddrID.h" -void hostNameFromIPAddr (const caNetAddr *pAddr, - char *pBuf, unsigned bufSize); +#ifdef ipIgnoreEntryEpicsExportSharedSymbols +# define epicsExportSharedSymbols +# include "shareLib.h" +#endif -class casDGClient; +void hostNameFromIPAddr ( const class caNetAddr * pAddr, + char * pBuf, unsigned bufSize ); + +class ipIgnoreEntry : public tsSLNode < ipIgnoreEntry > { +public: + ipIgnoreEntry ( unsigned ipAddr ); + void destroy (); + void show ( unsigned level ) const; + void * operator new ( size_t size ); + void operator delete ( void * pCadaver, size_t size ); + bool operator == ( const ipIgnoreEntry & ) const; + resTableIndex hash () const; + +private: + unsigned ipAddr; + static epicsSingleton < tsFreeList < class ipIgnoreEntry, 1024 > > pFreeList; + ipIgnoreEntry ( const ipIgnoreEntry & ); + ipIgnoreEntry & operator = ( const ipIgnoreEntry & ); +}; // // casDGIntfIO // class casDGIntfIO : public casDGClient { public: - casDGIntfIO (caServerI &serverIn, const caNetAddr &addr, - bool autoBeaconAddr=TRUE, bool addConfigBeaconAddr=FALSE); + casDGIntfIO ( caServerI &serverIn, const caNetAddr &addr, + bool autoBeaconAddr=TRUE, bool addConfigBeaconAddr = false ); virtual ~casDGIntfIO(); int getFD () const; @@ -41,8 +69,8 @@ public: bool validBCastFD () const; void xSetNonBlocking (); - void sendBeaconIO (char &msg, bufSizeT length, - aitUint16 &portField, aitUint32 &addrField); + void sendBeaconIO ( char & msg, bufSizeT length, + aitUint16 &portField, aitUint32 & addrField ); casIOState state () const; outBufClient::flushCondition osdSend ( const char * pBuf, bufSizeT nBytesReq, @@ -57,6 +85,7 @@ public: bufSizeT incomingBytesPresent () const; private: + resTable < ipIgnoreEntry, ipIgnoreEntry > ignoreTable; ELLLIST beaconAddrList; SOCKET sock; SOCKET bcastRecvSock; // fix for solaris bug @@ -78,14 +107,14 @@ struct ioArgsToNewStreamIO { // class casStreamIO : public casStrmClient { public: - casStreamIO(caServerI &cas, const ioArgsToNewStreamIO &args); + casStreamIO ( caServerI & cas, const ioArgsToNewStreamIO & args ); ~casStreamIO(); int getFD() const; void xSetNonBlocking(); casIOState state() const; - void hostName (char *pBuf, unsigned bufSize) const; + void hostName ( char *pBuf, unsigned bufSize ) const; outBufClient::flushCondition osdSend ( const char *pBuf, bufSizeT nBytesReq, bufSizeT & nBytesActual ); @@ -98,11 +127,11 @@ public: static bufSizeT optimumBufferSize (); - void osdShow (unsigned level) const; + void osdShow ( unsigned level ) const; const caNetAddr getAddr() const { - return caNetAddr(this->addr); + return caNetAddr ( this->addr ); } private: @@ -174,7 +203,6 @@ private: bool addConfigAddr) = 0; }; - // no additions below this line #endif // includeCASIODH diff --git a/src/cas/io/bsdSocket/casIODIL.h b/src/cas/io/bsdSocket/casIODIL.h index c6f1e9c70..2e3caf0e8 100644 --- a/src/cas/io/bsdSocket/casIODIL.h +++ b/src/cas/io/bsdSocket/casIODIL.h @@ -24,7 +24,27 @@ inline int casDGIntfIO::getBCastFD() const // inline bool casDGIntfIO::validBCastFD() const { - return this->bcastRecvSock!=INVALID_SOCKET; + return this->bcastRecvSock != INVALID_SOCKET; +} + +inline void * ipIgnoreEntry::operator new ( size_t size ) +{ + return ipIgnoreEntry::pFreeList->allocate ( size ); +} + +inline void ipIgnoreEntry::operator delete ( void * pCadaver, size_t size ) +{ + ipIgnoreEntry::pFreeList->release ( pCadaver, size ); +} + +inline ipIgnoreEntry::ipIgnoreEntry ( unsigned ipAddrIn ) : + ipAddr ( ipAddrIn ) +{ +} + +inline void ipIgnoreEntry::destroy () +{ + delete this; } #endif // casIODILh