Beispiel #1
0
Socket::Status UdpSocket::receive(void* data, std::size_t size, std::size_t& received, IpAddress& remoteAddress, unsigned short& remotePort)
{
    // First clear the variables to fill
    received      = 0;
    remoteAddress = IpAddress();
    remotePort    = 0;

    // Check the destination buffer
    if (!data)
    {
        err() << "Cannot receive data from the network (the destination buffer is invalid)" << std::endl;
        return Error;
    }

    // Data that will be filled with the other computer's address
    sockaddr_in address = priv::SocketImpl::createAddress(INADDR_ANY, 0);

    // Receive a chunk of bytes
    priv::SocketImpl::AddrLength addressSize = sizeof(address);
    int sizeReceived = recvfrom(getHandle(), static_cast<char*>(data), static_cast<int>(size), 0, reinterpret_cast<sockaddr*>(&address), &addressSize);

    // Check for errors
    if (sizeReceived < 0)
        return priv::SocketImpl::getErrorStatus();

    // Fill the sender informations
    received      = static_cast<std::size_t>(sizeReceived);
    remoteAddress = IpAddress(ntohl(address.sin_addr.s_addr));
    remotePort    = ntohs(address.sin_port);

    return Done;
}
void ClusterMembership::Tick()
{
	// Called every 1s or so to time out
	// to handle expired nodes etc
	struct timeval now;
	gettimeofday(&now, 0);
	// Set the local node effective weight.
	int timesincestart = timevalSub(now, starttime);
	if (timesincestart < ZeroWeightTime) {
		effectiveWeight = 0;
	} else {
		effectiveWeight = weight;
	}
	// Store the effective weight so we can take it into account
	// determining if we are to be master or not
	nodes[localaddr].weight = effectiveWeight;

	// Calculate IP of the new master, to see if it's
	// us.
	IpAddress newMaster;
	IpNodeMap::iterator nodeToForget(0);
	for (IpNodeMap::iterator i=nodes.begin(); i != nodes.end(); i++) {
		const IpAddress & ip = (*i).first;
		NodeInfo &ni = (*i).second;
		int age = timevalSub(now, ni.lastheard);
		if (ni.isup && ! ni.isme) {
			if (age > MaxNodeAge) {
				std::cout << "Node down:" << ip << std::endl;
				ni.isup = false;
			}
		}
		if (ni.isup && (ni.weight > 0)) {
			if (newMaster == IpAddress()) {
				newMaster = ip;
			}
		}
		if ((age > ForgetNodeAge) && ! (ni.isup || ni.isme)) {
			nodeToForget = i;
		}
	}
	// If we have a node which has timed out, and needs to
	// be "forgotten", forget it.
	if (nodeToForget != IpNodeMap::iterator(0)) {
		std::cout << "Forgetting node: " << nodeToForget->first 
			<< std::endl;
		nodes.erase(nodeToForget);
	}
       	if (newMaster != master) {
		master = newMaster;
		std::cout << "New master: " << master << std::endl;
		if (newMaster == IpAddress()) {
			// no master at all, oh dear.
			// set our own boundaries to 0 so we don't handle anything.
			setNewLocalBoundaries(0,0);
		}
	}
	SendAnnouncement();
}
    void initializeTransportFactories()
    {

#ifdef RCF_USE_IPV6
        const bool compileTimeIpv6 = true;
        ExceptionPtr ePtr;
        IpAddress("::1").resolve(ePtr);
        const bool runTimeIpv6 = (ePtr.get() == NULL);
#else
        const bool compileTimeIpv6 = false;
        const bool runTimeIpv6 = false;
#endif

#if defined(BOOST_WINDOWS)

        getTransportFactories().push_back(
            TransportFactoryPtr( new Win32NamedPipeTransportFactory()));

#endif

        getTransportFactories().push_back(
            TransportFactoryPtr( new TcpAsioTransportFactory(IpAddress::V4)));

        getIpTransportFactories().push_back(
            TransportFactoryPtr( new TcpAsioTransportFactory(IpAddress::V4)));

        if (compileTimeIpv6 && runTimeIpv6)
        {
            getTransportFactories().push_back(
                TransportFactoryPtr( new TcpAsioTransportFactory(IpAddress::V6)));

            getIpTransportFactories().push_back(
                TransportFactoryPtr( new TcpAsioTransportFactory(IpAddress::V6)));
        }

#ifdef RCF_HAS_LOCAL_SOCKETS
        getTransportFactories().push_back(
            TransportFactoryPtr( new UnixLocalTransportFactory()));
#endif

#ifndef RCF_TEST_NO_UDP

        getTransportFactories().push_back(
            TransportFactoryPtr( new UdpTransportFactory(IpAddress::V4)));

        getIpTransportFactories().push_back(
            TransportFactoryPtr( new UdpTransportFactory(IpAddress::V4)));

        if (compileTimeIpv6 && runTimeIpv6)
        {
            getTransportFactories().push_back(
                TransportFactoryPtr( new UdpTransportFactory(IpAddress::V6)));

            getIpTransportFactories().push_back(
                TransportFactoryPtr( new UdpTransportFactory(IpAddress::V6)));
        }

#endif

    }
    void runTest() {
        m_strategy = new OpenConnectionStrategy(this);

        m_client_listener = new ClientTcpListener(this);
        m_server_listener = new ServerTcpListener(this);

        m_evmanager = new EventManager();
        m_client = new TcpConnection(IpAddress("127.0.0.1", 9999));
        m_listener = new TcpListener();

        m_listener->listen(9999);
        m_listener->setListener(this);

        m_client->setEventManager(m_evmanager);
        m_client->setListener(m_client_listener);
        m_client->open();

        m_evmanager->registerClient(m_listener);
        m_evmanager->registerClient(m_client);

        m_evmanager->execute();

        delete m_strategy;

        delete m_client_listener;
        delete m_server_listener;

        delete m_client;
        delete m_server;
        delete m_listener;
        delete m_evmanager;
    }
Beispiel #5
0
	IpAddress SocketImpl::QuerySocketAddress(SocketHandle handle, SocketError* error)
	{
		NazaraAssert(handle != InvalidHandle, "Invalid handle");

		IpAddressImpl::SockAddrBuffer nameBuffer;
		int bufferLength = static_cast<int>(nameBuffer.size());

		if (getsockname(handle, reinterpret_cast<sockaddr*>(nameBuffer.data()), &bufferLength) == SOCKET_ERROR)
		{
			if (error)
			{
				int errorCode = WSAGetLastError();
				if (errorCode == WSAEINVAL)
					*error = SocketError_NoError;
				else
					*error = TranslateWSAErrorToSocketError(errorCode);
			}

			return IpAddress();
		}

		if (error)
			*error = SocketError_NoError;

		return IpAddressImpl::FromSockAddr(reinterpret_cast<sockaddr*>(nameBuffer.data()));
	}
    TransportPair UdpTransportFactory::createTransports()
    {
        typedef boost::shared_ptr<UdpServerTransport> UdpServerTransportPtr;
        UdpServerTransportPtr udpServerTransportPtr(
            new UdpServerTransport( IpAddress(mLoopback, 0) ));

        udpServerTransportPtr->open();
        int port = udpServerTransportPtr->getPort();

        ClientTransportAutoPtrPtr clientTransportAutoPtrPtr(
            new ClientTransportAutoPtr(
                new UdpClientTransport( IpAddress(mLoopback, port) )));

        return std::make_pair(
            ServerTransportPtr(udpServerTransportPtr), 
            clientTransportAutoPtrPtr);
    }
Beispiel #7
0
IpAddress IpAddress::getPublicAddress(Time timeout)
{
    // The trick here is more complicated, because the only way
    // to get our public IP address is to get it from a distant computer.
    // Here we get the web page from http://www.sfml-dev.org/ip-provider.php
    // and parse the result to extract our IP address
    // (not very hard: the web page contains only our IP address).

    Http server("www.sfml-dev.org");
    Http::Request request("/ip-provider.php", Http::Request::Get);
    Http::Response page = server.sendRequest(request, timeout);
    if (page.getStatus() == Http::Response::Ok)
        return IpAddress(page.getBody());

    // Something failed: return an invalid address
    return IpAddress();
}
    TransportPair TcpAsioTransportFactory::createTransports()
    {
        typedef boost::shared_ptr<TcpAsioServerTransport> TcpAsioServerTransportPtr;
        TcpAsioServerTransportPtr tcpServerTransportPtr(
            new TcpAsioServerTransport( IpAddress(mLoopback, 0)));

        tcpServerTransportPtr->open();
        int port = tcpServerTransportPtr->getPort();

        ClientTransportAutoPtrPtr clientTransportAutoPtrPtr(
            new ClientTransportAutoPtr(
                new TcpClientTransport( IpAddress(mLoopback, port))));

        return std::make_pair(
            ServerTransportPtr(tcpServerTransportPtr), 
            clientTransportAutoPtrPtr);
    }
void CShdrEchoInstance::Init(std::string devicesxmlfilename, 
									 std::string shdrfilename, 
									 int ipport, 
									 double dOverride,
									 std::string devicename)
{
	DevicesXmlFilename()=devicesxmlfilename;
	ShdrFilename() =shdrfilename;
	IpAddress() ="127.0.0.1"; // really cant be anything else
	IpPort()=ipport;
	DeviceName() = devicename;
	Override()=dOverride;
	_bFaultThread=false;

	if(DevicesXmlFilename().empty())
		DevicesXmlFilename()=ExeDirectory() + "devices.xml";

	_bRepeat=true;

	_backend = new CoComMTCShdrBackEnd();
	_backend->Init(_bstr_t(IpAddress().c_str()), IpPort(), _bstr_t(DeviceName().c_str()));
	_backend->MyLogger().AddListener(boost::bind(&CShdrEchoInstance::EchoShdr, this,_1));

	_dict = _deviceparser.ReadDeviceDescription(DevicesXmlFilename());
	std::string storemap,itemlist, typelist;
	int i=0;
	for(DataDictionary::iterator it = _dict.begin(); it!=_dict.end(); it++, i++)
	{
		if((*it).first.empty())
		{
			i--;
			continue;
		}
		if(i>0) itemlist+=",";
		if(i>0) typelist+=",";
		storemap+=(*it).first+"="+(*it).first+"\n";  // isomorphic: alias = name
		itemlist+=(*it).first;
		typelist+=_dict[(*it).first];
	}
	_backend->StoreTagMap(_bstr_t(storemap.c_str()));
	_backend->StoreTypeMap(_bstr_t(itemlist.c_str()),bstr_t(typelist.c_str()));

	Open();
	_state=Ready;
}
Beispiel #10
0
 IpAddress SocketBase::getLocalAddr() const
 {
     socket_details::sockaddr_t addr;
     ::memset(&addr, 0, sizeof addr);
     socklen_t addrlen = static_cast<socklen_t>(sizeof addr);
     if (getsockname(mHandle, reinterpret_cast<sockaddr*>(&addr), &addrlen) < 0) {
         Debug::Log("SOCKET","getsockname error: %d\n", socket_details::getError());
     }
     return IpAddress(addr);
 }
IpAddress IpAddress::getLocalAddress()
{
#ifdef OS_WINDOWS
std::cerr << "IpAddress::getLocalAddress() : Win32Implementation is broken" << std::endl;
#elif defined OS_UNIX
std::cerr << "IpAddress::getLocalAddress() : UNIXImplementation is broken" << std::endl;
#else
#error "Unknown Operating System on IpAddress::getLocalAddress()"
#endif
    return (IpAddress());
}
Beispiel #12
0
 IpAddress TcpSocket::getRemoteAddr() const
 {
     socket_details::sockaddr_t addr;
     ::memset(&addr, 0, sizeof addr);
     socklen_t addrlen = static_cast<socklen_t>(sizeof addr);
     if (getpeername(mHandle, reinterpret_cast<sockaddr*>(&addr), &addrlen) < 0)
     {
         Debug::Error("SOCKET","getpeername error: %d\n", socket_details::getError());
     }
     return IpAddress(addr);
 }
bool StatStore::recordStart(VERMONT::IpfixRecord::SourceID sourceId) {

    if (beginMonitoring != true)
	return false;

    packet_nb = byte_nb = 0;
    e_source = e_dest = EndPoint(IpAddress(0,0,0,0),0,0);

    return true;

}
Beispiel #14
0
int Interpreteur( char *Buffer, struct Global *g)
{
  char arg0[80],arg1[80],arg2[80],arg3[80],arg4[80] ;
  int rc ;
  bzero(arg0,sizeof(arg1));
  bzero(arg1,sizeof(arg1));
  bzero(arg2,sizeof(arg2));
  bzero(arg3,sizeof(arg3));
  bzero(arg4,sizeof(arg4));
  fprintf(stderr,"Interpreteur ;") ;
  sscanf(Buffer,"%s %s %s %s %s\n",arg0,arg1,arg2,arg3,arg4) ;
  fprintf(stderr,"arg0 %s \n",arg0 ) ;

  /* ATTENTIO? NE PAS OUBLIER ELSE SINON ERREUR DE SYTAXE */
  if (strcmp(arg0,"connexion")==0)  rc=Connexion(Buffer,arg1,arg2,arg3, arg4,g) ;
  else 
  if (strcmp(arg0,"ip")==0 &&( strcmp(arg1,"address")==0) ) rc=IpAddress(Buffer,arg1,arg2,arg3, arg4,g) ;
  else
  if (strcmp(arg0,"netmask")==0 ) rc = Netmask(Buffer,arg1,arg2,arg3, arg4,g) ;
  else 
 if (strcmp(arg0,"gateway")==0 ) rc = Gateway(Buffer,arg1,arg2,arg3, arg4,g) ;
  else
 if (strcmp(arg0,"dns")==0 ) rc = Dns(Buffer,arg1,arg2,arg3, arg4,g) ;
 else
 if (strcmp(arg0,"ports")==0 ) rc = Ports(Buffer,arg1,arg2,arg3, arg4,g) ;
 else
 if (strcmp(arg0,"ping")==0 ) rc = Ping(Buffer,arg1,arg2,arg3, arg4,g) ;
 else
 if (strcmp(arg0,"send")==0 ) rc = Send(Buffer,arg1,arg2,arg3, arg4,g) ;
 else
 if (strcmp(arg0,"bind")==0)  rc = Bind(Buffer,arg1,arg2,arg3, arg4,g) ;
 else
 if (strcmp(arg0,"nslookup")==0 )  rc= NsLookup(Buffer,arg1,arg2,arg3, arg4,g) ;
 else
 if (strcmp(arg0,"waitreceive")==0 ) rc=WaitReceive(g) ;
 else
 if (strcmp(arg0,"read")==0) rc = LireMessage( g ) ;
 else
 if (strcmp(arg0,"exit")==0) exit(0);
 else
 if (strcmp(arg0,"ipconfig")==0) rc = AfficherParametres( g ) ;
 else
 if (strcmp(arg0,"help")==0) rc = Help() ;
 else
 if (Blanc1013(Buffer))
    {
     fprintf(stderr,"Ligne vide \n" ) ;
     rc =  1 ;
    }
 else
    rc = 0 ;
 fprintf(stderr,"fin Interpeteur\n") ;
 return(rc) ;
}
Beispiel #15
0
bool Configurator::readIp (std::istream &stream, IpAddress &address)
{
	int family;
	if (!readInt(stream, family))
		return false;

	unsigned int size = IpAddress::familySize(family);
	if (size > 0)
	{
		std::uint8_t *buffer = new std::uint8_t[size];
		if (stream.readsome(reinterpret_cast<char *>(buffer), size) != size || !stream.good())
		{
			delete[] buffer;
			return false;
		}

		address = IpAddress(buffer, family);
		delete[] buffer;
	}
	else
		address = IpAddress();

	return true;
}
Beispiel #16
0
IpAddress TcpSocket::getRemoteAddress() const
{
    if (getHandle() != priv::SocketImpl::invalidSocket())
    {
        // Retrieve informations about the remote end of the socket
        sockaddr_in address;
        priv::SocketImpl::AddrLength size = sizeof(address);
        if (getpeername(getHandle(), reinterpret_cast<sockaddr*>(&address), &size) != -1)
        {
            return IpAddress(ntohl(address.sin_addr.s_addr));
        }
    }

    // We failed to retrieve the address
    return IpAddress::None;
}
/*
 * Destructor:
 * 1. If our previous effective weight was more than 0, and
 * there was at least one other node, send out a packet with zero
 * weight so that the other nodes know we're off.
 * 2. Clean up sockets etc
 */
ClusterMembership::~ClusterMembership()
{
	std::cout << "ClusterMembership destructor" << std::endl;
	if (effectiveWeight > 0) {
		weight = 0;
		effectiveWeight = 0;
		// If the master was us, make sure it isn't any more.
		master = IpAddress();
		// We need to ensure we don't throw in the destructor,
		// as if we did, it would terminate()
		try {
			SendAnnouncement();
		} catch (std::runtime_error &err) {
			// Ingore this error.
		}
	}
	close(sock);
}
void ClusterMembership::HandleMessage()
{
	char buf[1024];
	// Read message from sock
	struct sockaddr_in sender;
	socklen_t senderlen = sizeof(sender);
	int len = recvfrom(sock, buf, sizeof(buf),
			0 /* flags */ ,
			(struct sockaddr *) &sender, &senderlen);
	// If we get EAGAIN, ignore
	if (len == -1) {
		if (errno == EAGAIN) {
			return;
		}
		throw std::runtime_error("recv failed");
	}
	// decide what to do with it etc
	decodePacket(buf,len, IpAddress(& sender.sin_addr));
}
Beispiel #19
0
IpAddress IpAddress::getLocalAddress()
{
    // The method here is to connect a UDP socket to anyone (here to localhost),
    // and get the local socket address with the getsockname function.
    // UDP connection will not send anything to the network, so this function won't cause any overhead.

    IpAddress localAddress;

    // Create the socket
    SocketHandle sock = socket(PF_INET, SOCK_DGRAM, 0);
    if (sock == priv::SocketImpl::invalidSocket())
        return localAddress;

    // Connect the socket to localhost on any port
    sockaddr_in address = priv::SocketImpl::createAddress(ntohl(INADDR_LOOPBACK), 0);
    if (connect(sock, reinterpret_cast<sockaddr*>(&address), sizeof(address)) == -1)
    {
        priv::SocketImpl::close(sock);
        return localAddress;
    }

    // Get the local address of the socket connection
    priv::SocketImpl::AddrLength size = sizeof(address);
    int temp = size;
    if (getsockname(sock, reinterpret_cast<sockaddr*>(&address), &temp) == -1)
    {
        priv::SocketImpl::close(sock);
        return localAddress;
    }

    // Close the socket
    priv::SocketImpl::close(sock);

    // Finally build the IP address
    localAddress = IpAddress(ntohl(address.sin_addr.s_addr));

    return localAddress;
}
Beispiel #20
0
SnmpSocket CNotifyEventQueue::get_notify_fd(const UdpAddress match_addr) const
{
  SnmpSocket found_fd = INVALID_SOCKET;
  int max_bits_matched = 0;
  IpAddress ip_match = IpAddress(match_addr);

  for (int i = 0; i < m_notify_fd_count; i++)
  {
    IpAddress ip = m_notify_addrs[i];
    int bits = ip_match.get_match_bits(ip);

    debugprintf(5, "Compared %s to %s, bits %d", 
		ip.get_printable(), ip_match.get_printable(), bits);

    if (bits > max_bits_matched)
    {
	max_bits_matched = bits;
	found_fd = m_notify_fds[i];
    }
  }

  return found_fd;
}
void StatStore::addFieldData(int id, uint8_t* fieldData, int fieldDataLength, VERMONT::IpfixRecord::FieldInfo::Type::EnterpriseNo eid) {
    // we subscribed to: see Stat::init_*()-functions
    // addFieldData will be executed until there are no more fieldData
    // in the current IPFIX record; so we are sure to get everything
    // we subscribed to (so don't get worried because of
    // the "breaks" in the "switch" loop hereafter)

    IpAddress SourceIP = IpAddress(0,0,0,0);
    IpAddress DestIP = IpAddress(0,0,0,0);

    switch (id) {

	case IPFIX_TYPEID_protocolIdentifier:

	    if (fieldDataLength != IPFIX_LENGTH_protocolIdentifier) {
		msgStr << MsgStream::ERROR << "Got IPFIX field (id=" << id << ") with unsupported length " << fieldDataLength << ". Skipping record." << MsgStream::endl;
		return;
	    }

	    e_source.setProtocolID(*fieldData);
	    e_dest.setProtocolID(*fieldData);

	    break;


	case IPFIX_TYPEID_sourceIPv4Address:

	    if (fieldDataLength != IPFIX_LENGTH_sourceIPv4Address) {
		msgStr << MsgStream::ERROR << "Got IPFIX field (id=" << id << ") with unsupported length " << fieldDataLength << ". Skipping record." << MsgStream::endl;
		return;
	    }

	    SourceIP.setAddress(fieldData[0],fieldData[1],fieldData[2],fieldData[3]);
	    SourceIP.remanent_mask(netmask);
	    e_source.setIpAddress(SourceIP);

	    break;


	case IPFIX_TYPEID_destinationIPv4Address:

	    if (fieldDataLength != IPFIX_LENGTH_destinationIPv4Address) {
		msgStr << MsgStream::ERROR << "Got IPFIX field (id=" << id << ") with unsupported length " << fieldDataLength << ". Skipping record." << MsgStream::endl;
		return;
	    }

	    DestIP.setAddress(fieldData[0],fieldData[1],fieldData[2],fieldData[3]);
	    DestIP.remanent_mask(netmask);
	    e_dest.setIpAddress(DestIP);

	    break;

	    // Ports do only matter, if endpoint_key contains "port"
	    // AND (endpoint_key contains "protocol" AND TCP and/or UDP are selected
	    // OR protocols dont matter)
	case IPFIX_TYPEID_sourceTransportPort:

	    if (fieldDataLength != IPFIX_LENGTH_sourceTransportPort
		    && fieldDataLength != IPFIX_LENGTH_sourceTransportPort-1) {
		msgStr << MsgStream::ERROR << "Got IPFIX field (id=" << id << ") with unsupported length " << fieldDataLength << ". Skipping record." << MsgStream::endl;
		return;
	    }

	    e_source.setPortNr((int)fieldToInt(fieldData, fieldDataLength));
	    break;


	case IPFIX_TYPEID_destinationTransportPort:

	    if (fieldDataLength != IPFIX_LENGTH_destinationTransportPort
		    && fieldDataLength != IPFIX_LENGTH_destinationTransportPort-1) {
		std::cerr << "Error! Got invalid IPFIX field data (destination port)! "
		    << "Skipping record.\n";
		return;
	    }

	    e_dest.setPortNr((int)fieldToInt(fieldData, fieldDataLength));
	    break;


	case IPFIX_TYPEID_packetDeltaCount:

	    if (fieldDataLength != IPFIX_LENGTH_packetDeltaCount) {
		std::cerr << "Error! Got invalid IPFIX field data (#packets)! "
		    << "Skipping record.\n";
		return;
	    }
	    packet_nb = ntohll(*(uint64_t*)fieldData);

	    break;


	case IPFIX_TYPEID_octetDeltaCount:

	    if (fieldDataLength != IPFIX_LENGTH_octetDeltaCount) {
		std::cerr << "Error! Got invalid IPFIX field data (#octets)! "
		    << "Skipping record.\n";
		return;
	    }
	    byte_nb = ntohll(*(uint64_t*)fieldData);

	    break;


	default:

	    std::cerr
		<<"Warning! Got unknown record in StatStore::addFieldData(...)!\n"
		<<"A programmer has probably added some record type in Stat::init()\n"
		<<"but has forgotten to ensure its support in StatStore::addFieldData().\n"
		<<"I'll try to keep working, but I can't tell for sure I won't crash.\n";
    }

    return;
}
Beispiel #22
0
IpAddress TcpSocket::peerAddress()const
{
	return IpAddress();
}
    void UdpServerTransport::cycle(
        int timeoutMs,
        const volatile bool &) //stopFlag
    {
        // poll the UDP socket for messages, and read a message if one is available

        fd_set fdSet;
        FD_ZERO(&fdSet);
        FD_SET( static_cast<SOCKET>(mFd), &fdSet);
        timeval timeout;
        timeout.tv_sec = timeoutMs/1000;
        timeout.tv_usec = 1000*(timeoutMs%1000);

        int ret = Platform::OS::BsdSockets::select(
            mFd+1,
            &fdSet,
            NULL,
            NULL,
            timeoutMs < 0 ? NULL : &timeout);

        int err = Platform::OS::BsdSockets::GetLastError();
        if (ret == 1)
        {
            SessionStatePtr sessionStatePtr = getCurrentUdpSessionStatePtr();
            if (sessionStatePtr.get() == NULL)
            {
                sessionStatePtr = SessionStatePtr(new SessionState(*this));
                SessionPtr sessionPtr = getSessionManager().createSession();
                sessionPtr->setSessionState(*sessionStatePtr);
                sessionStatePtr->mSessionPtr = sessionPtr;
                setCurrentUdpSessionStatePtr(sessionStatePtr);
            }

            {
                // read a message

                ReallocBufferPtr &readVecPtr =
                    sessionStatePtr->mReadVecPtr;

                if (readVecPtr.get() == NULL || !readVecPtr.unique())
                {
                    readVecPtr.reset( new ReallocBuffer());
                }
                ReallocBuffer &buffer = *readVecPtr;

                SockAddrStorage from;
                int fromlen = sizeof(from);
                memset(&from, 0, sizeof(from));
                buffer.resize(4);

                int len = Platform::OS::BsdSockets::recvfrom(
                    mFd,
                    &buffer[0],
                    4,
                    MSG_PEEK,
                    (sockaddr *) &from,
                    &fromlen);

                err = Platform::OS::BsdSockets::GetLastError();

                sessionStatePtr->mRemoteAddress = IpAddress(
                    (sockaddr&) from, 
                    fromlen, 
                    mIpAddress.getType());

                if (!isIpAllowed(sessionStatePtr->mRemoteAddress))
                {
                    RCF_LOG_2()(sessionStatePtr->mRemoteAddress.getIp()) 
                        << "Client IP does not match server's IP access rules. Closing connection.";

                    discardPacket(mFd);
                }
                else if (   len == 4 
                        ||  (len == -1 && err == Platform::OS::BsdSockets::ERR_EMSGSIZE))
                {
                    unsigned int dataLength = 0;
                    memcpy(&dataLength, &buffer[0], 4);
                    networkToMachineOrder(&dataLength, 4, 1);
                    if (    0 < dataLength 
                        &&  dataLength <= static_cast<unsigned int>(getMaxMessageLength()))
                    {
                        buffer.resize(4+dataLength);
                        memset(&from, 0, sizeof(from));
                        fromlen = sizeof(from);

                        len = Platform::OS::BsdSockets::recvfrom(
                            mFd,
                            &buffer[0],
                            4+dataLength,
                            0,
                            (sockaddr *) &from,
                            &fromlen);

                        if (static_cast<unsigned int>(len) == 4+dataLength)
                        {
                            getSessionManager().onReadCompleted(sessionStatePtr->mSessionPtr);
                        }
                    }
                    else
                    {
                        ByteBuffer byteBuffer;
                        encodeServerError(getSessionManager(), byteBuffer, RcfError_ServerMessageLength);
                        byteBuffer.expandIntoLeftMargin(4);

                        * (boost::uint32_t *) ( byteBuffer.getPtr() ) =
                            static_cast<boost::uint32_t>(byteBuffer.getLength()-4);

                        RCF::machineToNetworkOrder(byteBuffer.getPtr(), 4, 1);

                        char *buffer = byteBuffer.getPtr();
                        std::size_t bufferLen = byteBuffer.getLength();

                        sockaddr * pRemoteAddr = NULL;
                        Platform::OS::BsdSockets::socklen_t remoteAddrSize = 0;
                        sessionStatePtr->mRemoteAddress.getSockAddr(pRemoteAddr, remoteAddrSize);

                        int len = sendto(
                            mFd,
                            buffer,
                            static_cast<int>(bufferLen),
                            0,
                            pRemoteAddr,
                            remoteAddrSize);

                        RCF_UNUSED_VARIABLE(len);
                        discardPacket(mFd);
                    }
                }
                else
                {
                    discardPacket(mFd);
                }
            }
        }
        else if (ret == 0)
        {
            //RCF_LOG_4()(mFd)(mPort)(timeoutMs) << "UdpServerTransport - no messages received within polling interval.";
        }
        else if (ret == -1)
        {
            Exception e(
                _RcfError_Socket(),
                err,
                RcfSubsystem_Os,
                "udp server select() failed ");

            RCF_THROW(e)(mFd)(mIpAddress.string())(err);
        }

    }
Beispiel #24
0
 UdpEndpoint & UdpEndpoint::listenOnMulticast(const std::string & multicastIp)
 {
     return listenOnMulticast(IpAddress(multicastIp));
 }
    void UdpClientTransport::connect(
        I_ClientTransportCallback &clientStub, 
        unsigned int timeoutMs)
    {
        RCF_LOG_4()(mSock)(mDestIp.string()) << "UdpClientTransport - creating socket.";

        RCF_UNUSED_VARIABLE(timeoutMs);

        RCF_ASSERT(!mAsync);

        // TODO: replace throw with return value
        if (mSock == -1)
        {
            int ret = 0;
            int err = 0;

            // remote address
            mDestIp.resolve();

            // local address
            if (mLocalIp.empty())
            {
                std::string localIp = mDestIp.getType() == IpAddress::V4 ?
                    "0.0.0.0" :
                    "::0" ;

                mSrcIp = IpAddress(localIp, 0);             
            }
            else
            {
                mSrcIp = mLocalIp;
            }

            mSrcIp.resolve();
            
            mSock = mSrcIp.createSocket(SOCK_DGRAM, IPPROTO_UDP);

            sockaddr * pSrcAddr = NULL;
            Platform::OS::BsdSockets::socklen_t srcAddrSize = 0;
            mSrcIp.getSockAddr(pSrcAddr, srcAddrSize);

            ret = ::bind(mSock, pSrcAddr, srcAddrSize);
            err = Platform::OS::BsdSockets::GetLastError();

            RCF_VERIFY(
                ret == 0,
                Exception(
                    _RcfError_Socket("bind()"), err, RcfSubsystem_Os));

            mAssignedLocalIp = IpAddress(mSock, mSrcIp.getType());

#if defined(BOOST_WINDOWS) && defined(SIO_UDP_CONNRESET)

            // On Windows XP and later, disable the SIO_UDP_CONNRESET socket option.
            BOOL enable = FALSE;
            DWORD dwBytesRet = 0;
            DWORD dwStatus = WSAIoctl(mSock, SIO_UDP_CONNRESET, &enable, sizeof(enable), NULL, 0, &dwBytesRet, NULL, NULL);
            err = Platform::OS::BsdSockets::GetLastError();

            RCF_VERIFY(
                dwStatus == 0,
                Exception(
                    _RcfError_Socket("WSAIoctl() with SIO_UDP_CONNRESET"),
                    err,
                    RcfSubsystem_Os));

#endif // BOOST_WINDOWS

            if (mDestIp.isBroadcast())
            {
                // set socket option to allow transmission of broadcast messages
                int enable = 1;
                int ret = setsockopt(mSock, SOL_SOCKET, SO_BROADCAST, (char *) &enable, sizeof(enable));
                int err = Platform::OS::BsdSockets::GetLastError();

                RCF_VERIFY(
                    ret ==  0,
                    Exception(
                        _RcfError_Socket("setsockopt() with SO_BROADCAST"),
                        err,
                        RcfSubsystem_Os));
            }

            if (mDestIp.isMulticast())
            {
                // char for Solaris, int for everyone else.
#if defined(__SVR4) && defined(__sun)
                char hops = 16;
#else
                int hops = 16;
#endif
                int ret = setsockopt(mSock, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &hops, sizeof (hops));
                int err = Platform::OS::BsdSockets::GetLastError();

                RCF_VERIFY(
                    ret ==  0,
                    Exception(
                        _RcfError_Socket("setsockopt() with IPPROTO_IP/IP_MULTICAST_TTL"),
                        err,
                        RcfSubsystem_Os))(hops);
            }
        }

        clientStub.onConnectCompleted();
    }
Beispiel #26
0
void TunnelDecapOrch::doTask(Consumer& consumer)
{
    SWSS_LOG_ENTER();

    if (!gPortsOrch->isInitDone())
    {
        return;
    }

    auto it = consumer.m_toSync.begin();
    while (it != consumer.m_toSync.end())
    {
        KeyOpFieldsValuesTuple t = it->second;

        string key = kfvKey(t);
        string op = kfvOp(t);

        IpAddresses ip_addresses;
        IpAddress src_ip;
        string tunnel_type;
        string dscp_mode;
        string ecn_mode;
        string ttl_mode;
        bool valid = true;

        // checking to see if the tunnel already exists
        bool exists = (tunnelTable.find(key) != tunnelTable.end());

        if (op == SET_COMMAND)
        {

            for (auto i : kfvFieldsValues(t))
            {
                if (fvField(i) == "tunnel_type")
                {
                    tunnel_type = fvValue(i);
                    if (tunnel_type != "IPINIP")
                    {
                        SWSS_LOG_ERROR("Invalid tunnel type %s", tunnel_type.c_str());
                        valid = false;
                        break;
                    }
                }
                else if (fvField(i) == "dst_ip")
                {
                    try
                    {
                        ip_addresses = IpAddresses(fvValue(i));
                    }
                    catch (const std::invalid_argument &e)
                    {
                        SWSS_LOG_ERROR("%s", e.what());
                        valid = false;
                        break;
                    }
                    if (exists)
                    {
                        setIpAttribute(key, ip_addresses, tunnelTable.find(key)->second.tunnel_id);
                    }
                }
                else if (fvField(i) == "src_ip")
                {
                    try
                    {
                        src_ip = IpAddress(fvValue(i));
                    }
                    catch (const std::invalid_argument &e)
                    {
                        SWSS_LOG_ERROR("%s", e.what());
                        valid = false;
                        break;
                    }
                    if (exists)
                    {
                        SWSS_LOG_ERROR("cannot modify src ip for existing tunnel");
                    }
                }
                else if (fvField(i) == "dscp_mode")
                {
                    dscp_mode = fvValue(i);
                    if (dscp_mode != "uniform" && dscp_mode != "pipe")
                    {
                        SWSS_LOG_ERROR("Invalid dscp mode %s\n", dscp_mode.c_str());
                        valid = false;
                        break;
                    }
                    if (exists)
                    {
                        setTunnelAttribute(fvField(i), dscp_mode, tunnelTable.find(key)->second.tunnel_id);
                    }
                }
                else if (fvField(i) == "ecn_mode")
                {
                    ecn_mode = fvValue(i);
                    if (ecn_mode != "copy_from_outer" && ecn_mode != "standard")
                    {
                        SWSS_LOG_ERROR("Invalid ecn mode %s\n", ecn_mode.c_str());
                        valid = false;
                        break;
                    }
                    if (exists)
                    {
                        setTunnelAttribute(fvField(i), ecn_mode, tunnelTable.find(key)->second.tunnel_id);
                    }
                }
                else if (fvField(i) == "ttl_mode")
                {
                    ttl_mode = fvValue(i);
                    if (ttl_mode != "uniform" && ttl_mode != "pipe")
                    {
                        SWSS_LOG_ERROR("Invalid ttl mode %s\n", ttl_mode.c_str());
                        valid = false;
                        break;
                    }
                    if (exists)
                    {
                        setTunnelAttribute(fvField(i), ttl_mode, tunnelTable.find(key)->second.tunnel_id);
                    }
                }
            }

            // create new tunnel if it doesn't exists already
            if (valid && !exists)
            {
                if (addDecapTunnel(key, tunnel_type, ip_addresses, src_ip, dscp_mode, ecn_mode, ttl_mode))
                {
                    SWSS_LOG_NOTICE("Tunnel(s) added to ASIC_DB.");
                }
                else
                {
                    SWSS_LOG_ERROR("Failed to add tunnels to ASIC_DB.");
                }
            }
        }

        if (op == DEL_COMMAND)
        {
            if (exists)
            {
                removeDecapTunnel(key);
            }
            else
            {
                SWSS_LOG_ERROR("Tunnel cannot be removed since it doesn't exist.");
            }
        }

        it = consumer.m_toSync.erase(it);
    }
}
int CNotifyEventQueue::AddEntry(Snmp *snmp,
                                const OidCollection &trapids,
                                const TargetCollection &targets)
{
  SnmpSynchronize _synchronize(*this); // instead of REENTRANT()

  if (snmp != m_snmpSession)
  {
    debugprintf(0, "WARNING: Adding notification event for other Snmp object");
  }

  if (!m_msgCount)
  {
    m_notify_addr = snmp->get_listen_address();
    m_notify_addr.set_port(m_listen_port);

    int status = SNMP_CLASS_SUCCESS;

    // This is the first request to receive notifications
    // Set up the socket for the snmp trap port (162) or the
    // specified port through set_listen_port()
    bool is_v4_address = (m_notify_addr.get_ip_version() == Address::version_ipv4);
    if (is_v4_address)
    {
      struct sockaddr_in mgr_addr;

      // open a socket to be used for the session
      if ((m_notify_fd = socket(AF_INET, SOCK_DGRAM,0)) < 0)
      {
#ifdef WIN32
        int werr = WSAGetLastError();
        if (EMFILE == werr ||WSAENOBUFS == werr || ENFILE == werr)
          status = SNMP_CLASS_RESOURCE_UNAVAIL;
        else if (WSAEHOSTDOWN == werr)
          status = SNMP_CLASS_TL_FAILED;
        else
          status = SNMP_CLASS_TL_UNSUPPORTED;
#else
        if (EMFILE == errno || ENOBUFS == errno || ENFILE == errno)
          status = SNMP_CLASS_RESOURCE_UNAVAIL;
        else if (EHOSTDOWN == errno)
          status = SNMP_CLASS_TL_FAILED;
        else
          status = SNMP_CLASS_TL_UNSUPPORTED;
#endif
        cleanup();
        return status;
      }

      // set up the manager socket attributes
      unsigned long inaddr = inet_addr(IpAddress(m_notify_addr).get_printable());
      memset(&mgr_addr, 0, sizeof(mgr_addr));
      mgr_addr.sin_family = AF_INET;
      mgr_addr.sin_addr.s_addr = inaddr; // was htonl( INADDR_ANY);
      mgr_addr.sin_port = htons(m_notify_addr.get_port());
#ifdef CYGPKG_NET_OPENBSD_STACK
      mgr_addr.sin_len = sizeof(mgr_addr);
#endif

      // bind the socket
      if (bind(m_notify_fd, (struct sockaddr *) &mgr_addr,
               sizeof(mgr_addr)) < 0)
      {
#ifdef WIN32
        int werr = WSAGetLastError();
        if (WSAEADDRINUSE  == werr)
          status = SNMP_CLASS_TL_IN_USE;
        else if (WSAENOBUFS == werr)
          status = SNMP_CLASS_RESOURCE_UNAVAIL;
        else if (werr == WSAEAFNOSUPPORT)
          status = SNMP_CLASS_TL_UNSUPPORTED;
        else if (werr == WSAENETUNREACH)
          status = SNMP_CLASS_TL_FAILED;
        else if (werr == EACCES)
          status = SNMP_CLASS_TL_ACCESS_DENIED;
        else
          status = SNMP_CLASS_INTERNAL_ERROR;
#else
        if (EADDRINUSE  == errno)
          status = SNMP_CLASS_TL_IN_USE;
        else if (ENOBUFS == errno)
          status = SNMP_CLASS_RESOURCE_UNAVAIL;
        else if (errno == EAFNOSUPPORT)
          status = SNMP_CLASS_TL_UNSUPPORTED;
        else if (errno == ENETUNREACH)
          status = SNMP_CLASS_TL_FAILED;
        else if (errno == EACCES)
          status = SNMP_CLASS_TL_ACCESS_DENIED;
        else
        {
          debugprintf(0, "Uncatched errno value %d, returning internal error.",
                      errno);
          status = SNMP_CLASS_INTERNAL_ERROR;
        }
#endif
        debugprintf(0, "Fatal: could not bind to %s",
                    m_notify_addr.get_printable());
        cleanup();
        return status;
      }

      debugprintf(3, "Bind to %s for notifications, fd %d.",
                  m_notify_addr.get_printable(), m_notify_fd);
    } // is_v4_address
    else
    {
      // not is_v4_address
#ifdef SNMP_PP_IPv6
      // open a socket to be used for the session
      if ((m_notify_fd = socket(AF_INET6, SOCK_DGRAM,0)) < 0)
      {
#ifdef WIN32
        int werr = WSAGetLastError();
        if (EMFILE == werr ||WSAENOBUFS == werr || ENFILE == werr)
          status = SNMP_CLASS_RESOURCE_UNAVAIL;
        else if (WSAEHOSTDOWN == werr)
          status = SNMP_CLASS_TL_FAILED;
        else
          status = SNMP_CLASS_TL_UNSUPPORTED;
#else
        if (EMFILE == errno || ENOBUFS == errno || ENFILE == errno)
          status = SNMP_CLASS_RESOURCE_UNAVAIL;
        else if (EHOSTDOWN == errno)
          status = SNMP_CLASS_TL_FAILED;
        else
          status = SNMP_CLASS_TL_UNSUPPORTED;
#endif
        cleanup();
        return status;
      }

#ifdef NOTIFY_SET_IPV6_V6ONLY
      int on = 1;
      if (setsockopt(m_notify_fd, IPPROTO_IPV6, IPV6_V6ONLY,
		     (char *)&on, sizeof(on)) == -1)
      {
        LOG_BEGIN(loggerModuleName, WARNING_LOG | 1);
        LOG("Could not set option IPV6_V6ONLY on notify socket (errno)");
        LOG(errno);
        LOG_END;
      }
      else
      {
        LOG_BEGIN(loggerModuleName, INFO_LOG | 3);
        LOG("Have set IPV6_V6ONLY option on notify socket");
        LOG_END;
      }
#endif

      // set up the manager socket attributes
      struct sockaddr_in6 mgr_addr;
      memset(&mgr_addr, 0, sizeof(mgr_addr));

      unsigned int scope = 0;

      OctetStr addrstr = ((IpAddress &)m_notify_addr).IpAddress::get_printable();

      if (m_notify_addr.has_ipv6_scope())
      {
        scope = m_notify_addr.get_scope();

        int y = addrstr.len() - 1;
        while ((y>0) && (addrstr[y] != '%'))
        {
          addrstr.set_len(addrstr.len() - 1);
          y--;
        }
        if (addrstr[y] == '%')
          addrstr.set_len(addrstr.len() - 1);
      }

      if (inet_pton(AF_INET6, addrstr.get_printable(),
                    &mgr_addr.sin6_addr) < 0)
      {
	LOG_BEGIN(loggerModuleName, ERROR_LOG | 1);
        LOG("Notify transport: inet_pton returns (errno) (str)");
        LOG(errno);
        LOG(strerror(errno));
        LOG_END;
        cleanup();
        return SNMP_CLASS_INVALID_ADDRESS;
      }

      mgr_addr.sin6_family = AF_INET6;
      mgr_addr.sin6_port = htons(m_notify_addr.get_port());
      mgr_addr.sin6_scope_id = scope;

      // bind the socket
      if (bind(m_notify_fd, (struct sockaddr *) &mgr_addr,
               sizeof(mgr_addr)) < 0)
      {
#ifdef WIN32
        int werr = WSAGetLastError();
        if (WSAEADDRINUSE  == werr)
          status = SNMP_CLASS_TL_IN_USE;
        else if (WSAENOBUFS == werr)
          status = SNMP_CLASS_RESOURCE_UNAVAIL;
        else if (werr == WSAEAFNOSUPPORT)
          status = SNMP_CLASS_TL_UNSUPPORTED;
        else if (werr == WSAENETUNREACH)
          status = SNMP_CLASS_TL_FAILED;
        else if (werr == EACCES)
          status = SNMP_CLASS_TL_ACCESS_DENIED;
        else
          status = SNMP_CLASS_INTERNAL_ERROR;
#else
        if (EADDRINUSE  == errno)
          status = SNMP_CLASS_TL_IN_USE;
        else if (ENOBUFS == errno)
          status = SNMP_CLASS_RESOURCE_UNAVAIL;
        else if (errno == EAFNOSUPPORT)
          status = SNMP_CLASS_TL_UNSUPPORTED;
        else if (errno == ENETUNREACH)
          status = SNMP_CLASS_TL_FAILED;
        else if (errno == EACCES)
          status = SNMP_CLASS_TL_ACCESS_DENIED;
        else
        {
          debugprintf(0, "Uncatched errno value %d, returning internal error.",
                      errno);
          status = SNMP_CLASS_INTERNAL_ERROR;
        }
#endif
        debugprintf(0, "Fatal: could not bind to %s",
                    m_notify_addr.get_printable());
        cleanup();
        return status;
      }
      debugprintf(3, "Bind to %s for notifications, fd %d.",
                  m_notify_addr.get_printable(), m_notify_fd);
#else
      debugprintf(0, "User error: Enable IPv6 and recompile snmp++.");
      cleanup();
      return SNMP_CLASS_TL_UNSUPPORTED;
#endif
    } // not is_v4_address
  }

  CNotifyEvent *newEvent = new CNotifyEvent(snmp, trapids, targets);

  /*---------------------------------------------------------*/
  /* Insert entry at head of list, done automagically by the */
  /* constructor function, so don't use the return value.    */
  /*---------------------------------------------------------*/
  (void) new CNotifyEventQueueElt(newEvent, m_head.GetNext(), &m_head);
  m_msgCount++;

  return SNMP_CLASS_SUCCESS;
}
    void initializeTransportFactories()
    {

#if RCF_FEATURE_IPV6==1
        const bool compileTimeIpv6 = true;
        ExceptionPtr ePtr;
        IpAddress("::1").resolve(ePtr);
        const bool runTimeIpv6 = (ePtr.get() == NULL);
#else
        const bool compileTimeIpv6 = false;
        const bool runTimeIpv6 = false;
#endif

#if RCF_FEATURE_NAMEDPIPE==1

        getTransportFactories().push_back(
            TransportFactoryPtr( new Win32NamedPipeTransportFactory()));

#endif

#if RCF_FEATURE_TCP==1

        getTransportFactories().push_back(
            TransportFactoryPtr( new TcpAsioTransportFactory(IpAddress::V4)));

        getIpTransportFactories().push_back(
            TransportFactoryPtr( new TcpAsioTransportFactory(IpAddress::V4)));

        if (compileTimeIpv6 && runTimeIpv6)
        {
            getTransportFactories().push_back(
                TransportFactoryPtr( new TcpAsioTransportFactory(IpAddress::V6)));

            getIpTransportFactories().push_back(
                TransportFactoryPtr( new TcpAsioTransportFactory(IpAddress::V6)));
        }

#endif

#if RCF_FEATURE_LOCALSOCKET==1

        getTransportFactories().push_back(
            TransportFactoryPtr( new UnixLocalTransportFactory()));

#endif

#if RCF_FEATURE_UDP==1

        getTransportFactories().push_back(
            TransportFactoryPtr( new UdpTransportFactory(IpAddress::V4)));

        getIpTransportFactories().push_back(
            TransportFactoryPtr( new UdpTransportFactory(IpAddress::V4)));

        if (compileTimeIpv6 && runTimeIpv6)
        {
            getTransportFactories().push_back(
                TransportFactoryPtr( new UdpTransportFactory(IpAddress::V6)));

            getIpTransportFactories().push_back(
                TransportFactoryPtr( new UdpTransportFactory(IpAddress::V6)));
        }

#endif

    }
 TransportPair UdpTransportFactory::createNonListeningTransports()
 {
     return std::make_pair(
         ServerTransportPtr( new UdpServerTransport( IpAddress(mLoopback, 0) ) ),
         ClientTransportAutoPtrPtr());
 }
 TransportPair createNonListeningTransports()
 {
     return std::make_pair(
         ServerTransportPtr( new TcpAsioServerTransport( IpAddress(mLoopback, 0)) ),
         ClientTransportAutoPtrPtr());
 }