Example #1
0
    void Socket::SetNonBlocking(bool enabled)
    {
        if (_socket == NET_INVALID_SOCKET)
            /* throw invalid socket */
            throw InvalidSocketException{ LOGIC_EXCEPT("Invalid socket") };

#if defined(OS_WINDOWS)
        u_long isEnabled = enabled ? 1 : 0;

        if (NET_SOCKET_ERROR == ioctlsocket(_socket, FIONBIO, &isEnabled))
            OnSocketError();
#else
        auto rc = ::fcntl(_socket, F_GETFL);
        if (rc == -1) OnSocketError();

        if (enabled)
        {
            rc |= O_NONBLOCK;
        }
        else
        {
            rc &= ~O_NONBLOCK;
        }

        (void)fcntl(F_SETFL, rc);
#endif
    }
Example #2
0
    std::uint32_t UDPSocket::ReceiveFrom(SocketAddress& address, std::uint8_t* buffer, std::uint32_t length, std::uint32_t flags)
    {
        if (!_socket.IsValid())
            throw InvalidSocketException{ LOGIC_EXCEPT("Invalid socket") };

        auto rc = 0;

        /* raw address */
        SocketAddress::RawAddresss rawAddr;
        net_socketlen_t len = sizeof(rawAddr);

        do
        {
            rc = ::recvfrom(_socket, reinterpret_cast<char*>(buffer), length, flags, reinterpret_cast<struct sockaddr *>(&rawAddr), &len);
        } 
        while (rc < 0 && Socket::LastError() == NETERRNO(EINTR));

        if (rc < 0)
        {
            OnSocketError();
            rc = 0;
        }
        else
        {
            address = rawAddr;
        }

        return static_cast<std::uint32_t>(rc);
    }
Example #3
0
    void Socket::Shutdown()
    {
        if (_socket == NET_INVALID_SOCKET)
            return;

        auto rc = ::shutdown(_socket, 2);

        if (rc == NET_SOCKET_ERROR)
            OnSocketError();
    }
Example #4
0
    void Socket::GetOption(std::int32_t level, std::int32_t option, std::int8_t * optval, std::int32_t *optlen) const
    {
        if (_socket == NET_INVALID_SOCKET)
            /* throw invalid socket */
            throw InvalidSocketException{ LOGIC_EXCEPT("Invalid socket") };

        auto rc = ::getsockopt(_socket, level, option, reinterpret_cast<char*>(optval), optlen);

        if (rc == NET_SOCKET_ERROR)
            OnSocketError();
    }
Example #5
0
/**
 * \fn bool SocketIO::Read(const Flux::string &buf) const
 * \brief Read from a socket for the IRC processor
 * \param buffer Raw socket buffer
 */
bool SocketIO::Read(const Flux::string &buf) const
{
  if(buf.search_ci("ERROR :Closing link:"))
  {
    FOREACH_MOD(I_OnSocketError, OnSocketError(buf));
    return false;
  }
  
  Log(LOG_RAWIO) << "Received: " << Flux::Sanitize(buf);
  process(buf); /* Process the buffer for navn */
  return true;
}
Example #6
0
    SocketAddress Socket::Address() const
    {
        if (_socket == NET_INVALID_SOCKET)
            /* throw invalid socket */
            throw InvalidSocketException{ LOGIC_EXCEPT("Invalid socket") };

        SocketAddress::RawAddresss rawAddr;
        net_socketlen_t len = sizeof(rawAddr);

        auto rc = ::getsockname(_socket, reinterpret_cast<struct sockaddr *>(&rawAddr), &len);

        if (rc == NET_SOCKET_ERROR)
            OnSocketError();

        return rawAddr;
    }
Example #7
0
    void TCPSocket::Connect(const SocketAddress& address)
    {
        if (!_socket.IsValid())
            /* throw invalid socket */
            throw InvalidSocketException{ LOGIC_EXCEPT("Invalid socket") };

        auto rc = 0;

        do
        {
            rc = ::connect(_socket, address.GetRawAddress(), address.RawLength());
        }
        while (rc == NET_SOCKET_ERROR && Socket::LastError() == NETERRNO(EINTR));

        if (rc == NET_SOCKET_ERROR)
            OnSocketError();
    }
Example #8
0
    std::uint32_t Socket::Available() const
    {
        if (_socket == NET_INVALID_SOCKET)
            /* throw invalid socket */
            throw InvalidSocketException{ LOGIC_EXCEPT("Invalid socket") };

#if defined(OS_WINDOWS)
        u_long avail = 0;
        auto rc = ioctlsocket(_socket, FIONREAD, reinterpret_cast<u_long*>(&avail));
#else
        std::int32_t avail = 0;
        auto rc = ::ioctl(_socket, FIONREAD, &avail);
#endif

        if (rc == NET_SOCKET_ERROR)
            OnSocketError();

        return static_cast<std::uint32_t>(avail);
    }
Example #9
0
    std::uint32_t TCPSocket::Receive(std::uint8_t* buffer, std::uint32_t length, std::uint32_t flags)
    {
        if (!_socket.IsValid())
            throw InvalidSocketException{ LOGIC_EXCEPT("Invalid socket") };

        auto rc = 0;

        do
        {
            rc = ::recv(_socket, reinterpret_cast<char *>(buffer), length, flags);
        } while (rc < 0 && Socket::LastError() == NETERRNO(EINTR));

        if (rc < 0)
        {
            OnSocketError();
            rc = 0;
        }

        return static_cast<std::uint32_t>(rc);
    }
Example #10
0
    std::uint32_t UDPSocket::SendTo(const SocketAddress& address, const std::uint8_t*buffer, std::uint32_t length, std::uint32_t flags)
    {
        if (!_socket.IsValid())
            throw InvalidSocketException{ LOGIC_EXCEPT("Invalid socket") };

        auto rc = 0;

        do
        {
            rc = ::sendto(_socket, reinterpret_cast<const char*>(buffer), length, flags, address.GetRawAddress(), address.RawLength());
        } 
        while (rc < 0 && Socket::LastError() == NETERRNO(EINTR));

        if (rc < 0)
        {
            OnSocketError();
            rc = 0;
        }

        return static_cast<std::uint32_t>(rc);
    }
Example #11
0
void SocketIO::Process()
{
  SET_SEGV_LOCATION();
  timeval timeout;
  timeout.tv_sec = Config->SockWait;
  timeout.tv_usec = 0; //this timeout keeps the bot from being a CPU hog for no reason :)
  fd_set read = ReadFD, write = WriteFD, except = ExceptFD;

  FD_ZERO(&read);
  FD_SET(this->GetFD(), &read);

  int sres = select(this->GetFD() + 1, &read, &write, &except, &timeout);
  if(sres == -1 && errno != EINTR)
  {
    Log(LOG_DEBUG) << "Select() error: " << strerror(errno);
    return;
  }

  if(throwex) //throw a socket exception if we want to. mainly used for ping timeouts.
    throw SocketException(throwmsg);

  bool has_read = FD_ISSET(this->GetFD(), &read);
  bool has_write = FD_ISSET(this->GetFD(), &write);
  bool has_error = FD_ISSET(this->GetFD(), &except);

  if(has_error)
  {
    int optval = 0;
    socklen_t optlen = sizeof(optval);
    getsockopt(this->GetFD(), SOL_SOCKET, SO_ERROR, reinterpret_cast<char *>(&optval), &optlen);
    errno = optval;
    FOREACH_MOD(I_OnSocketError, OnSocketError(optval ? strerror(errno) : "Unknown socket error"));
    throw SocketException("Socket error");
  }
  
  if(has_read)
  {
    char tbuf[BUFSIZE + 1] = "\0";
    size_t i = recv(this->GetFD(), tbuf, BUFSIZE, 0);
    
    if(i <= 0)
      throw SocketException(printfify("Socket Error: %s", strerror(errno)));
    
    sepstream sep(tbuf, '\n');
    Flux::string buf;
    while(sep.GetToken(buf))
    {
      this->LastBuf.clear();
      this->LastBuf = buf;
      if(!this->Read(buf))
	throw SocketException("Error reading socket");
    }

    FD_CLR(this->GetFD(), &ReadFD);
  }

  if(has_write)
  {
    Flux::string buf;
    while(!this->WriteBuffer.empty())
    {
      buf = this->WriteBuffer.front();
      this->WriteBuffer.pop();

      int i = ::send(this->GetFD(), buf.c_str(), buf.size(), MSG_NOSIGNAL);

      if(i <= -1 && !quitting)
	throw SocketException(printfify("Error writing \"%s\" to socket: %s", buf.c_str(), strerror(errno)));

      Log(LOG_RAWIO) << "Sent: " << buf << " | " << buf.size() << " bytes";
      
      this->LastBuf.clear();
      this->LastBuf = buf;

      buf.clear();
    }

    FD_CLR(this->GetFD(), &WriteFD);
  }
}