summaryrefslogtreecommitdiffstats
path: root/raul/Socket.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'raul/Socket.hpp')
-rw-r--r--raul/Socket.hpp262
1 files changed, 0 insertions, 262 deletions
diff --git a/raul/Socket.hpp b/raul/Socket.hpp
deleted file mode 100644
index 579a5cd..0000000
--- a/raul/Socket.hpp
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- This file is part of Raul.
- Copyright 2007-2015 David Robillard <http://drobilla.net>
-
- Raul is free software: you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation, either version 3 of the License, or any later version.
-
- Raul is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Raul. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef RAUL_SOCKET_HPP
-#define RAUL_SOCKET_HPP
-
-#include "raul/Noncopyable.hpp"
-
-#include <netdb.h>
-#include <netinet/in.h>
-#include <poll.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include <cerrno>
-#include <cstdint>
-#include <cstdlib>
-#include <cstring>
-#include <memory>
-#include <string>
-
-namespace Raul {
-
-/** A safe and simple interface for UNIX or TCP sockets. */
-class Socket : public Raul::Noncopyable {
-public:
- enum class Type {
- UNIX,
- TCP
- };
-
- /** Create a new unbound/unconnected socket of a given type. */
- explicit Socket(Type t);
-
- /** Wrap an existing open socket. */
- Socket(Type t,
- std::string uri,
- struct sockaddr* addr,
- socklen_t addr_len,
- int fd);
-
- Socket(const Socket&) = delete;
- Socket& operator=(const Socket&) = delete;
-
- ~Socket();
-
- /** Bind a server socket to an address.
- * @param uri Address URI, e.g. unix:///tmp/foo, or tcp://hostname:1234.
- * Use "*" as hostname to listen on all interfaces.
- * @return True on success.
- */
- bool bind(const std::string& uri);
-
- /** Connect a client socket to a server address.
- * @param uri Address URI, e.g. unix:///tmp/foo or tcp://somehost:1234
- * @return True on success.
- */
- bool connect(const std::string& uri);
-
- /** Mark server socket as passive to listen for incoming connections.
- * @return True on success.
- */
- bool listen();
-
- /** Accept a connection.
- * @return An new open socket for the connection.
- */
- std::shared_ptr<Socket> accept();
-
- /** Return the file descriptor for the socket. */
- int fd() const { return _sock; }
-
- const std::string& uri() const { return _uri; }
-
- /** Close the socket. */
- void close();
-
- /** Shut down the socket.
- * This terminates any connections associated with the sockets, and will
- * (unlike close()) cause a poll on the socket to return.
- */
- void shutdown();
-
-private:
- bool set_addr(const std::string& uri);
-
- std::string _uri;
- struct sockaddr* _addr;
- socklen_t _addr_len;
- Type _type;
- int _sock;
-};
-
-#ifndef NI_MAXHOST
-# define NI_MAXHOST 1025
-#endif
-
-inline
-Socket::Socket(Type t)
- : _uri(t == Type::UNIX ? "unix:" : "tcp:")
- , _addr(nullptr)
- , _addr_len(0)
- , _type(t)
- , _sock(-1)
-{
- switch (t) {
- case Type::UNIX:
- _sock = socket(AF_UNIX, SOCK_STREAM, 0);
- break;
- case Type::TCP:
- _sock = socket(AF_INET, SOCK_STREAM, 0);
- break;
- }
-}
-
-inline
-Socket::Socket(Type t,
- std::string uri,
- struct sockaddr* addr,
- socklen_t addr_len,
- int fd)
- : _uri(std::move(uri))
- , _addr(addr)
- , _addr_len(addr_len)
- , _type(t)
- , _sock(fd)
-{
-}
-
-inline
-Socket::~Socket()
-{
- free(_addr);
- close();
-}
-
-inline bool
-Socket::set_addr(const std::string& uri)
-{
- free(_addr);
- if (_type == Type::UNIX && uri.substr(0, strlen("unix://")) == "unix://") {
- const std::string path = uri.substr(strlen("unix://"));
- auto* uaddr = static_cast<struct sockaddr_un*>(
- calloc(1, sizeof(struct sockaddr_un)));
- uaddr->sun_family = AF_UNIX;
- strncpy(uaddr->sun_path, path.c_str(), sizeof(uaddr->sun_path) - 1);
- _uri = uri;
- _addr = reinterpret_cast<sockaddr*>(uaddr);
- _addr_len = sizeof(struct sockaddr_un);
- return true;
- } else if (_type == Type::TCP && uri.find("://") != std::string::npos) {
- const std::string authority = uri.substr(uri.find("://") + 3);
- const size_t port_sep = authority.find(':');
- if (port_sep == std::string::npos) {
- return false;
- }
-
- std::string host = authority.substr(0, port_sep);
- const std::string port = authority.substr(port_sep + 1);
- if (host.empty() || host == "*") {
- host = "0.0.0.0"; // INADDR_ANY
- }
-
- struct addrinfo* ainfo = nullptr;
- if (getaddrinfo(host.c_str(), port.c_str(), nullptr, &ainfo)) {
- return false;
- }
-
- _uri = uri;
- _addr = static_cast<struct sockaddr*>(malloc(ainfo->ai_addrlen));
- _addr_len = ainfo->ai_addrlen;
- memcpy(_addr, ainfo->ai_addr, ainfo->ai_addrlen);
- freeaddrinfo(ainfo);
- return true;
- }
- return false;
-}
-
-inline bool
-Socket::bind(const std::string& uri)
-{
- return set_addr(uri) && ::bind(_sock, _addr, _addr_len) != -1;
-}
-
-inline bool
-Socket::connect(const std::string& uri)
-{
- return set_addr(uri) && ::connect(_sock, _addr, _addr_len) != -1;
-}
-
-inline bool
-Socket::listen()
-{
- if (::listen(_sock, 64) == -1) {
- return false;
- } else {
- return true;
- }
-}
-
-inline std::shared_ptr<Socket>
-Socket::accept()
-{
- socklen_t client_addr_len = _addr_len;
- auto* const client_addr =
- static_cast<struct sockaddr*>(calloc(1, client_addr_len));
-
- const int conn = ::accept(_sock, client_addr, &client_addr_len);
- if (conn == -1) {
- free(client_addr);
- return std::shared_ptr<Socket>();
- }
-
- std::string client_uri = _uri;
- if (_type != Type::UNIX) {
- char host[NI_MAXHOST];
- char serv[NI_MAXSERV];
- if (!getnameinfo(client_addr, client_addr_len,
- host, sizeof(host), serv, sizeof(serv), 0)) {
- const std::string scheme = _uri.substr(0, _uri.find(':'));
- client_uri = scheme + "://" + host + ":" + serv;
- }
- }
-
- return std::make_shared<Socket>(
- _type, client_uri, client_addr, client_addr_len, conn);
-}
-
-inline void
-Socket::close()
-{
- if (_sock != -1) {
- ::close(_sock);
- _sock = -1;
- }
-}
-
-inline void
-Socket::shutdown()
-{
- if (_sock != -1) {
- ::shutdown(_sock, SHUT_RDWR);
- }
-}
-
-} // namespace Raul
-
-#endif // RAUL_SOCKET_HPP