//=========================================================================== // $Name: cflowd-2-1-b1 $ // $Id: CflowdFlowPortList.cc,v 1.10 1998/12/11 10:17:49 dwm Exp $ //=========================================================================== // CAIDA Copyright Notice // // By accessing this software, cflowd++, you are duly informed // of and agree to be bound by the conditions described below in this // notice: // // This software product, cflowd++, is developed by Daniel W. McRobb, and // copyrighted(C) 1998 by the University of California, San Diego // (UCSD), with all rights reserved. UCSD administers the CAIDA grant, // NCR-9711092, under which part of this code was developed. // // There is no charge for cflowd++ software. You can redistribute it // and/or modify it under the terms of the GNU General Public License, // v. 2 dated June 1991 which is incorporated by reference herein. // cflowd++ is distributed WITHOUT ANY WARRANTY, IMPLIED OR EXPRESS, OF // MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE or that the use // of it will not infringe on any third party's intellectual property // rights. // // You should have received a copy of the GNU GPL along with cflowd++. // Copies can also be obtained from: // // http://www.gnu.org/copyleft/gpl.html // // or by writing to: // // University of California, San Diego // // SDSC/CAIDA // 9500 Gilman Dr., MS-0505 // La Jolla, CA 92093 - 0505 USA // // Or contact: // // info@caida.org //=========================================================================== extern "C" { #include #include #include #include #include #include #include #include #include "aclocal.h" #ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif } #include #include "CflowdFlowPortList.hh" static const string rcsid = "@(#) $Name: cflowd-2-1-b1 $ $Id: CflowdFlowPortList.cc,v 1.10 1998/12/11 10:17:49 dwm Exp $"; //------------------------------------------------------------------------- // CflowdFlowPort::CflowdFlowPort() //......................................................................... // //------------------------------------------------------------------------- CflowdFlowPort::CflowdFlowPort() { this->fd = -1; this->portnum = 0; } //------------------------------------------------------------------------- // CflowdFlowPort::~CflowdFlowPort() //......................................................................... // //------------------------------------------------------------------------- CflowdFlowPort::~CflowdFlowPort() { (*this).Close(); } //------------------------------------------------------------------------- // void CflowdFlowPort::Close() //......................................................................... // //------------------------------------------------------------------------- void CflowdFlowPort::Close() { if (this->fd >= 0) { close(this->fd); this->fd = -1; } return; } //------------------------------------------------------------------------- // int CflowdFlowPort::Open() //......................................................................... // //------------------------------------------------------------------------- int CflowdFlowPort::Open() { if (((*this).fd = socket(AF_INET,SOCK_DGRAM,0)) < 0) { syslog(LOG_ERR,"[E] socket(AF_INET,SOCK_DGRAM,0) failed: %m {%s:%d}", __FILE__,__LINE__); return(-1); } int fdFlags = fcntl((*this).fd,F_GETFL,0); fcntl((*this).fd,F_SETFL,fdFlags|O_NONBLOCK); #ifdef SO_REUSEADDR int on = 1; setsockopt((*this).fd,SOL_SOCKET,SO_REUSEADDR,(char *)&on,sizeof(on)); #endif // SO_REUSEADDR #ifdef SO_RCVBUF int recvqsize = 131032; int prevrecvqsize = 262064; int tryval, diff; while(setsockopt((*this).fd,SOL_SOCKET,SO_RCVBUF,(char *)&recvqsize, sizeof(recvqsize)) != 0) { prevrecvqsize = recvqsize; recvqsize = recvqsize >> 1; } while ((diff = prevrecvqsize - recvqsize) > 1024) { tryval = recvqsize + diff/2; if (!setsockopt((*this).fd,SOL_SOCKET,SO_RCVBUF,(char *)&tryval, sizeof(tryval))) recvqsize = tryval; else prevrecvqsize = tryval; } if (setsockopt((*this).fd,SOL_SOCKET,SO_RCVBUF,(char *)&recvqsize, sizeof(recvqsize)) == 0) { syslog(LOG_INFO, "[I] set UDP recv queue to %d bytes for fd %d (port %d)", recvqsize,(*this).fd,(*this).portnum); } else { syslog(LOG_ERR, "[E] setsockopt(%d,SOL_SOCKET,SO_RCVBUF,%d,%d) failed: %m " "{%s:%d}", __FILE__,__LINE__,(*this).fd,recvqsize,sizeof(recvqsize)); } #endif // SO_RCVBUF struct sockaddr_in servaddr; int len; memset(&servaddr,0,sizeof(servaddr)); servaddr.sin_addr.s_addr = INADDR_ANY; servaddr.sin_port = htons((*this).portnum); servaddr.sin_family = AF_INET; len = sizeof(servaddr); if (bind((*this).fd,(struct sockaddr *)&servaddr,len) < 0) { syslog(LOG_ERR,"[E] bind(%d,%s:%hu,%d) failed: %m {%s:%d}", (*this).fd,inet_ntoa(servaddr.sin_addr), (*this).portnum,len,__FILE__,__LINE__); (*this).Close(); return(-1); } return(0); } //------------------------------------------------------------------------- // CflowdFlowPort & // CflowdFlowPort::operator = (const CflowdFlowPort & flowPort) //......................................................................... // //------------------------------------------------------------------------- CflowdFlowPort & CflowdFlowPort::operator = (const CflowdFlowPort & flowPort) { (*this).fd = flowPort.fd; (*this).portnum = portnum; return(*this); } //------------------------------------------------------------------------- // int CflowdFlowPortList::OpenAll() //......................................................................... // //------------------------------------------------------------------------- int CflowdFlowPortList::OpenAll() { CflowdFlowPortList::iterator portlIter; this->_maxFd = -1; for (portlIter = (*this).begin(); portlIter != (*this).end(); portlIter++) { if ((*portlIter).fd >= 0) { (*portlIter).Close(); } if ((*portlIter).Open() == 0) { FD_SET((*portlIter).fd,&((*this).FdSet())); if ((*portlIter).fd > this->_maxFd) { this->_maxFd = (*portlIter).fd; } } } return((*this).size()); } //------------------------------------------------------------------------- // void CloseAll() //......................................................................... // //------------------------------------------------------------------------- void CflowdFlowPortList::CloseAll() { CflowdFlowPortList::iterator portlIter; for (portlIter = (*this).begin(); portlIter != (*this).end(); portlIter++) { (*portlIter).Close(); } FD_ZERO(&((*this).FdSet())); this->_maxFd = -1; return; } //------------------------------------------------------------------------- // void CflowdFlowPortList::Clear() //......................................................................... // //------------------------------------------------------------------------- void CflowdFlowPortList::Clear() { (*this).CloseAll(); (*this).erase((*this).begin(),(*this).end()); FD_ZERO(&((*this).FdSet())); return; } //------------------------------------------------------------------------- // fd_set & CflowdFlowPortList::FdSet() //......................................................................... // //------------------------------------------------------------------------- fd_set & CflowdFlowPortList::FdSet() { return((*this)._fdSet); } //------------------------------------------------------------------------- // int CflowdFlowPortList::MaxFd() const //......................................................................... // //------------------------------------------------------------------------- int CflowdFlowPortList::MaxFd() const { return(this->_maxFd); }