154 lines
3.4 KiB
C++
154 lines
3.4 KiB
C++
/************************************************************************************
|
|
*
|
|
* D++, A Lightweight C++ library for Discord
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
* Copyright 2021 Craig Edwards and D++ contributors
|
|
* (https://github.com/brainboxdotcc/DPP/graphs/contributors)
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
************************************************************************************/
|
|
#pragma once
|
|
|
|
#include <dpp/export.h>
|
|
#ifdef _WIN32
|
|
#include <WinSock2.h>
|
|
#include <WS2tcpip.h>
|
|
#include <io.h>
|
|
#define poll(fds, nfds, timeout) WSAPoll(fds, nfds, timeout)
|
|
#define pollfd WSAPOLLFD
|
|
#else
|
|
#include <netinet/in.h>
|
|
#include <sys/socket.h>
|
|
#include <arpa/inet.h>
|
|
#endif
|
|
#include <string_view>
|
|
#include <cstdint>
|
|
|
|
|
|
namespace dpp
|
|
{
|
|
/**
|
|
* @brief Represents a socket file descriptor.
|
|
* This is used to ensure parity between windows and unix-like systems.
|
|
*/
|
|
#ifndef _WIN32
|
|
using socket = int;
|
|
#else
|
|
using socket = SOCKET;
|
|
#endif
|
|
|
|
#ifndef SOCKET_ERROR
|
|
/**
|
|
* @brief Represents a socket in error state
|
|
*/
|
|
#define SOCKET_ERROR -1
|
|
#endif
|
|
|
|
#ifndef INVALID_SOCKET
|
|
/**
|
|
* @brief Represents a socket which is not yet assigned
|
|
*/
|
|
#define INVALID_SOCKET ~0
|
|
#endif
|
|
|
|
/**
|
|
* @brief Represents an IPv4 address for use with socket functions such as
|
|
* bind().
|
|
*
|
|
* Avoids type punning with C style casts from sockaddr_in to sockaddr pointers.
|
|
*/
|
|
class DPP_EXPORT address_t {
|
|
/**
|
|
* @brief Internal sockaddr struct
|
|
*/
|
|
sockaddr socket_addr{};
|
|
|
|
public:
|
|
|
|
/**
|
|
* @brief Create a new address_t
|
|
* @param ip IPv4 address
|
|
* @param port Port number
|
|
* @note Leave both as defaults to create a default bind-to-any setting
|
|
*/
|
|
address_t(const std::string_view ip = "0.0.0.0", uint16_t port = 0);
|
|
|
|
/**
|
|
* @brief Get sockaddr
|
|
* @return sockaddr pointer
|
|
*/
|
|
[[nodiscard]] sockaddr *get_socket_address();
|
|
|
|
/**
|
|
* @brief Returns size of sockaddr_in
|
|
* @return sockaddr_in size
|
|
* @note It is important the size this returns is sizeof(sockaddr_in) not
|
|
* sizeof(sockaddr), this is NOT a bug but requirement of C socket functions.
|
|
*/
|
|
[[nodiscard]] size_t size();
|
|
|
|
/**
|
|
* @brief Get the port bound to a file descriptor
|
|
* @param fd File descriptor
|
|
* @return Port number, or 0 if no port bound
|
|
*/
|
|
[[nodiscard]] uint16_t get_port(socket fd);
|
|
};
|
|
|
|
/**
|
|
* @brief Allocates a dpp::socket, closing it on destruction
|
|
*/
|
|
struct DPP_EXPORT raii_socket {
|
|
/**
|
|
* @brief File descriptor
|
|
*/
|
|
socket fd;
|
|
|
|
/**
|
|
* @brief Construct a socket.
|
|
* Calls socket() and returns a new file descriptor
|
|
*/
|
|
raii_socket();
|
|
|
|
/**
|
|
* @brief Non-copyable
|
|
*/
|
|
raii_socket(raii_socket&) = delete;
|
|
|
|
/**
|
|
* @brief Non-movable
|
|
*/
|
|
raii_socket(raii_socket&&) = delete;
|
|
|
|
/**
|
|
* @brief Non-copyable
|
|
*/
|
|
raii_socket operator=(raii_socket&) = delete;
|
|
|
|
/**
|
|
* @brief Non-movable
|
|
*/
|
|
raii_socket operator=(raii_socket&&) = delete;
|
|
|
|
/**
|
|
* @brief Destructor
|
|
* Frees the socket by closing it
|
|
*/
|
|
~raii_socket();
|
|
};
|
|
|
|
|
|
}
|