Esempio n. 1
0
IPAddress::IPAddress(const std::string& addr)
{
	IPv4AddressImpl empty4 = IPv4AddressImpl();
	if (addr.empty() || trim(addr) == "0.0.0.0")
	{
		newIPv4(empty4.addr());
		return;
	}

	IPv4AddressImpl addr4(IPv4AddressImpl::parse(addr));
	if (addr4 != empty4)
	{
		newIPv4(addr4.addr());
		return;
	}

#if defined(POCO_HAVE_IPv6)
	IPv6AddressImpl empty6 = IPv6AddressImpl();
	if (addr.empty() || trim(addr) == "::")
	{
		newIPv6(empty6.addr());
		return;
	}

	IPv6AddressImpl addr6(IPv6AddressImpl::parse(addr));
	if (addr6 != IPv6AddressImpl())
	{
		newIPv6(addr6.addr(), addr6.scope());
		return;
	}
#endif

	throw InvalidAddressException(addr);
}
Esempio n. 2
0
 /**
  * `Socket` Constructor.
  *
  * Constructs a `Socket` object given a listening address/port and begins
  * listening for clients.
  *
  * @param addr `std::string` object containing the listen address
  * @param port `int` containing the port number to listen on
  */
 Socket::Socket(const std::string& addr, int port) {
   // Ensure the validity of the provided port
   if (port < 1 || port > 65535)
     throw InvalidArgument{"The provided port number is out of range."};
   // Fetch a finalized sockaddr_storage for the given address
   struct sockaddr_storage address  = parseAddress(addr);
   // Use the appropriate setup helper depending on the address family
   if (address.ss_family == AF_INET || address.ss_family == AF_INET6) {
     // Assign the appropriate address family to describe the `Connection`
     this->family = (address.ss_family == AF_INET ?
       SocketFamily::IPv4 : SocketFamily::IPv6);
     // Determine the appropriate pointer type for the remote address
     auto addrPtr = (address.ss_family == AF_INET ?
       addr4(address) : addr6(address));
     // Store a text-based representation of the remote address
     char addressString[INET6_ADDRSTRLEN + 1] = {};
     this->host = inet_ntop(address.ss_family, addrPtr, addressString,
       INET6_ADDRSTRLEN);
     // Assign the port to the sockaddr struct
     *(this->family == SocketFamily::IPv4 ? port4(address) : port6(address)) =
       htons(this->port = port);
   }
   else {
     // Remote address has an unexpected address family
     throw InvalidArgument{"The remote address has an unexpected address "
       "family."};
   }
   // Setup the socket using the appropriate address family and type
   this->socket = ::socket(address.ss_family, SOCK_STREAM, 0);
   // Attempt to bind the socket to the listening address
   if (bind(this->socket, addr_(address), this->family == SocketFamily::IPv4 ?
       sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)) < 0) {
     // A problem occurred, close the socket and throw an exception
     close(this->socket);
     throw UnexpectedError{"Couldn't bind to [" + this->host + "]:" +
       std::to_string(this->port)};
   }
   else {
     // Allow reusing the socket
     int reuse = 1;
     setsockopt(this->socket, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int));
     // Listen with a backlog of 16 clients
     listen(this->socket, 16);
   }
 }
Esempio n. 3
0
IPAddress::IPAddress(const std::string& addr, Family family)
{
	if (family == IPv4)
	{
		IPv4AddressImpl addr4(IPv4AddressImpl::parse(addr));
		newIPv4(addr4.addr());
		return;
	}
#if defined(POCO_HAVE_IPv6)
	else if (family == IPv6)
	{
		IPv6AddressImpl addr6(IPv6AddressImpl::parse(addr));
		newIPv6(addr6.addr(), addr6.scope());
		return;
	}
#endif
	else throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()");
}
Esempio n. 4
0
  /**
   * Accepts an incoming client and creates a `Connection` object for it.
   *
   * This method blocks execution until a client is accepted.
   *
   * @return `Connection` object representing the accepted client.
   */
  std::shared_ptr<Connection> Socket::accept() const {
    // Create storage to accept and capture the client's remote address
    std::string raddress{};
    struct sockaddr_storage cli_addr = {};
    socklen_t cli_addr_len = sizeof(struct sockaddr);
    int cli_fd = -1;

    // Check if the Socket is valid
    if (this->valid()) {
      // Accept an incoming client
      cli_fd = ::accept(this->socket, (struct sockaddr*)&cli_addr,
        &cli_addr_len);
      // Store a text-based representation of the remote address
      if (cli_addr.ss_family == AF_INET || cli_addr.ss_family == AF_INET6) {
        // Determine the appropriate pointer type for the remote address
        auto addrPtr = (cli_addr.ss_family == AF_INET ?
          addr4(cli_addr) : addr6(cli_addr));
        // Assign the resulting address to the raddress string
        char addressString[INET6_ADDRSTRLEN + 1] = {};
        raddress = inet_ntop(cli_addr.ss_family, addrPtr, addressString,
          INET6_ADDRSTRLEN);
      }
      // If cli_fd is negative, an error occurred
      if (cli_fd < 0) {
        throw UnexpectedError{"Couldn't accept client on [" + this->host +
          "]:" + std::to_string(this->port) + " - Invalid client file "
          "descriptor"};
      }
    }
    else {
      // Cannot accept a client on an invalid Socket
      throw UnexpectedError{"Couldn't accept client on [" + this->host +
        "]:" + std::to_string(this->port) + " - Invalid socket"};
    }
    // Return a shared_ptr to the newly created Connection object
    return std::shared_ptr<Connection>{
      new Connection{this->host, raddress, this->port, cli_fd}
    };
  }
Esempio n. 5
0
void test()
{
  namespace ip = std::experimental::net::ip;

  try
  {
    std::error_code ec;
    std::string string_value;

    // address constructors.

    ip::address addr1;
    const ip::address_v4 const_addr_v4;
    ip::address addr2(const_addr_v4);
    const ip::address_v6 const_addr_v6;
    ip::address addr3(const_addr_v6);
    ip::address addr4("127.0.0.1");
    ip::address addr5("127.0.0.1", ec);
    ip::address addr6(string_value);
    ip::address addr7(string_value, ec);

    // address functions.

    bool b = addr1.is_v4();
    (void)b;

    b = addr1.is_v6();
    (void)b;

    b = addr1.is_loopback();
    (void)b;

    b = addr1.is_unspecified();
    (void)b;

    b = addr1.is_multicast();
    (void)b;

    ip::address_v4 addr_v4_value = ip::address_cast<ip::address_v4>(addr1);
    (void)addr_v4_value;

    ip::address_v6 addr_v6_value = ip::address_cast<ip::address_v6>(addr1);
    (void)addr_v6_value;

    string_value = addr1.to_string();
    string_value = addr1.to_string(ec);

    // address comparisons.

    b = (addr1 == addr2);
    (void)b;

    b = (addr1 != addr2);
    (void)b;

    b = (addr1 < addr2);
    (void)b;

    b = (addr1 > addr2);
    (void)b;

    b = (addr1 <= addr2);
    (void)b;

    b = (addr1 >= addr2);
    (void)b;

    // address creation functions.

    addr1 = ip::make_address("127.0.0.1");
    addr1 = ip::make_address("127.0.0.1", ec);
    addr1 = ip::make_address(string_value);
    addr1 = ip::make_address(string_value, ec);

    // address I/O.

    std::ostringstream os;
    os << addr1;

    std::wostringstream wos;
    wos << addr1;
  }
  catch (std::exception&)
  {
  }
}