Move crystallised network wrapper to libgim

This commit is contained in:
Danny Robson 2012-06-25 16:54:26 +10:00
parent 481f55a9c4
commit 419c1d48f6
9 changed files with 1095 additions and 0 deletions

View File

@ -64,6 +64,14 @@ UTIL_FILES = \
matrix.hpp \
memory.cpp \
memory.hpp \
net/address.cpp \
net/address.hpp \
net/except.cpp \
net/except.hpp \
net/types.cpp \
net/types.hpp \
net/socket.cpp \
net/socket.hpp \
nocopy.hpp \
noise.cpp \
noise.hpp \

139
net/address.cpp Normal file
View File

@ -0,0 +1,139 @@
/*
* This file is part of libgim.
*
* libgim 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 (at your option) any later
* version.
*
* libgim 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 libgim. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2011 Danny Robson <danny@nerdcruft.net>
*/
#include "address.hpp"
#include "except.hpp"
#include "../debug.hpp"
#include "../endian.hpp"
#include "../types.hpp"
#ifdef __WIN32
#else
#include <arpa/inet.h>
#endif
//-----------------------------------------------------------------------------
using namespace net;
using namespace std;
//-----------------------------------------------------------------------------
#ifdef __WIN32
const char* inet_ntop(int af, const void* src, char* dst, int size){
struct sockaddr_in srcaddr;
memset(&srcaddr, 0, sizeof(struct sockaddr_in));
memcpy(&(srcaddr.sin_addr), src, sizeof(srcaddr.sin_addr));
srcaddr.sin_family = af;
if (WSAAddressToString ((struct sockaddr*) &srcaddr, sizeof (struct sockaddr_in), 0, dst, (LPDWORD) &size) != 0)
net::error::throw_code ();
return dst;
}
#endif
//-----------------------------------------------------------------------------
namespace net {
template <>
address<domain::INET>::address (const sockaddr_type &addr):
m_ip (addr.sin_addr.s_addr),
m_mask (0),
m_port (ntoh (addr.sin_port))
{
CHECK (addr.sin_family == (int)domain::INET);
}
template <domain D>
address<D>::address (const std::string &_ip,
port_type _port):
m_ip (_ip),
m_mask ( 0),
m_port (_port)
{ ; }
template <>
address<domain::INET>::sockaddr_type
address<domain::INET>::to_sockaddr (void) const {
sockaddr_type addr;
addr.sin_family = (int)domain::INET;
addr.sin_port = hton (m_port);
addr.sin_addr.s_addr = m_ip.m_integer;
return addr;
}
template <>
std::string
address<domain::INET>::to_string (void) const {
char dest[INET_ADDRSTRLEN + 1];
sockaddr_type addr = to_sockaddr ();
if (NULL == inet_ntop ((int)domain::INET, &addr.sin_addr, dest, sizeof (dest)))
net::error::throw_code ();
return dest;
}
template <>
bool
address<domain::INET>::operator ==(const address<domain::INET> &rhs) {
return m_ip == rhs.m_ip &&
m_mask == rhs.m_mask &&
m_port == rhs.m_port;
}
}
//-----------------------------------------------------------------------------
std::ostream&
net::operator<< (std::ostream &os, const address<net::domain::INET> &addr) {
os << addr.to_string () << ":" << addr.port ();
return os;
}
//-----------------------------------------------------------------------------
template <>
const address<domain::INET>
address<domain::INET>::LOOPBACK ("127.0.0.1", 0);
template <>
const address<domain::INET>
address<domain::INET>::ANY ("0.0.0.0", 0);
template <>
const address<domain::INET6>
address<domain::INET6>::LOOPBACK ("::1", 0);
template <>
const address<domain::INET6>
address<domain::INET6>::ANY ("::0", 0);
template class address<domain::INET>;
template class address<domain::INET6>;

109
net/address.hpp Normal file
View File

@ -0,0 +1,109 @@
/*
* This file is part of libgim.
*
* libgim 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 (at your option) any later
* version.
*
* libgim 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 libgim. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2011 Danny Robson <danny@nerdcruft.net>
*/
#ifndef __NET_ADDRESS_HPP
#define __NET_ADDRESS_HPP
#include "types.hpp"
#include "../ip.hpp"
#if defined(HAVE_WINSOCK2_H)
#include "ws2tcpip.h"
#endif
#include <iostream>
#include <string>
//-----------------------------------------------------------------------------
namespace net {
/// Supporting types used for defining addresses in various domains
template <domain D>
struct address_types;
template <>
struct address_types <domain::INET> {
typedef ipv4::ip ip;
typedef ipv4::mask mask;
typedef ipv4::port port;
typedef sockaddr_in sockaddr;
};
template <>
struct address_types <domain::INET6> {
typedef ipv6::ip ip;
typedef ipv6::mask mask;
typedef ipv6::port port;
typedef sockaddr_in6 sockaddr;
};
/// A full endpoint specification for a domain. Must be usable for bind/listen and send/recv.
template <domain D>
class address {
public:
typedef typename address_types<D>::ip ip_type;
typedef typename address_types<D>::mask mask_type;
typedef typename address_types<D>::port port_type;
typedef typename address_types<D>::sockaddr sockaddr_type;
protected:
ip_type m_ip;
mask_type m_mask;
port_type m_port;
public:
static const address<D> LOOPBACK;
static const address<D> ANY;
address (const sockaddr_type &);
address (const std::string&,
port_type);
port_type
port (void) const
{ return m_port; }
void
set_port (const port_type &_port)
{ m_port = _port; }
ip_type
ip (void) const
{ return m_ip; }
sockaddr_type
to_sockaddr (void) const;
std::string
to_string (void) const;
bool operator ==(const address<D> &rhs);
};
std::ostream&
operator<< (std::ostream &os, const net::address<net::domain::INET> &addr);
}
#endif // __NET_ADDRESS_HPP

119
net/except.cpp Normal file
View File

@ -0,0 +1,119 @@
/*
* This file is part of libgim.
*
* libgim 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 (at your option) any later
* version.
*
* libgim 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 libgim. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2011 Danny Robson <danny@nerdcruft.net>
*/
#include "except.hpp"
#include "../debug.hpp"
//-----------------------------------------------------------------------------
using namespace std;
using namespace net;
//-----------------------------------------------------------------------------
net::error::error (const std::string &_what):
runtime_error (_what)
{ ; }
net::error::error (int _code):
runtime_error (strerror (_code))
{ CHECK (_code != 0); }
std::string
net::error::code_to_string (int code) {
#ifdef __WIN32
char message[256];
int output = FormatMessage (0, NULL, code, 0, message, sizeof (message), NULL);
CHECK_HARD (output != 0);
return std::string (message);
#else
return strerror (code);
#endif
}
void
net::error::throw_code (int code) {
#ifdef __WIN32
throw net::error (code);
#else
CHECK (code != 0);
switch (code) {
#define ERROR_CODE(c) \
case c: \
throw net::error_code<c> (); \
break;
ERROR_CODE(ECONNREFUSED);
ERROR_CODE(ECONNRESET);
ERROR_CODE(EINVAL);
ERROR_CODE(ENOTCONN);
default:
unreachable ();
#undef ERROR_CODE
}
#endif
}
void
net::error::try_code (int err) {
if (err == 0)
return;
throw_code (err);
}
void
net::error::try_code (void)
{ try_code (last_code ()); }
void
net::error::throw_code (void)
{ throw_code (last_code ()); }
int
net::error::last_code (void) {
#ifdef __WIN32
return WSAGetLastError ();
#else
return errno;
#endif
}
template <int CODE>
net::error_code<CODE>::error_code (void):
net::error (CODE)
{ ; }
template <int CODE>
int
net::error_code<CODE>::code (void) const
{ return CODE; }

79
net/except.hpp Normal file
View File

@ -0,0 +1,79 @@
/*
* This file is part of libgim.
*
* libgim 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 (at your option) any later
* version.
*
* libgim 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 libgim. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2011 Danny Robson <danny@nerdcruft.net>
*/
#ifndef __NET_EXCEPT_HPP
#define __NET_EXCEPT_HPP
#if defined(HAVE_WINSOCK2_H)
#include <winsock2.h>
#else
#include <cerrno>
#include <cstring>
#endif
#include <string>
#include <stdexcept>
#include "../annotations.hpp"
//-----------------------------------------------------------------------------
namespace net {
class error : public std::runtime_error {
protected:
error (const std::string &);
error (int code);
static std::string
code_to_string (int code);
public:
/// Throw an error corresponding the a given code. Code must be a valid error code,
/// not success otherwise the application will (at best) abort.
static void
throw_code (int code) terminal;
/// Throw an error corresponding to the most recent error condition. This will check
/// the current error condition in a platform agnostic manner, and pass on to
/// throw_code(int). This should be used whenever an error has been detected, rather
/// than the more normal try_code(errno) due to Windows error reporting quirks.
static void
throw_code (void) terminal;
static void
try_code (int code);
static void
try_code (void);
static int
last_code (void);
};
template <int CODE>
class error_code : public error {
public:
error_code ();
int code (void) const;
};
}
#endif // __NET_EXCEPT_HPP

297
net/socket.cpp Normal file
View File

@ -0,0 +1,297 @@
/*
* This file is part of libgim.
*
* libgim 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 (at your option) any later
* version.
*
* libgim 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 libgim. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2011 Danny Robson <danny@nerdcruft.net>
*/
#include "socket.hpp"
#include "../debug.hpp"
#include "../except.hpp"
#include "../types/casts.hpp"
#include "../log.hpp"
#include "except.hpp"
#if !defined(HAVE_WINSOCK2_H)
#include <sys/socket.h>
#endif
#include <sys/types.h>
#include <unistd.h>
using namespace net;
//-----------------------------------------------------------------------------
template <domain D>
socket_domain<D>::socket_domain (socket_t _fd):
m_fd (_fd)
{
#ifdef __WIN32
#else
CHECK_HARD (m_fd >= 0);
#endif
}
#if defined(HAVE_WINSOCK2_H)
// TODO: Make this not retarded. Fucking Windows.
#define dup(X) (X)
static_assert(sizeof(int) == sizeof(ssize_t), "int != ssize_t");
static_assert(sizeof(int) == sizeof( size_t), "int != size_t");
ssize_t recv(socket_t _socket, void *_buf, size_t _len, int _flags)
{ return (ssize_t)::recv(_socket, (char*)_buf, (int)_len, _flags); }
ssize_t recvfrom(socket_t _socket, void *_buf, size_t _len, int _flags, struct sockaddr *_sockaddr, socklen_t *_socklen)
{ return (ssize_t)::recvfrom(_socket, (char*)_buf, (int)_len, _flags, _sockaddr, (int*)_socklen); }
ssize_t sendto(socket_t _socket, const void *_buf, size_t _len, int _flags, const struct sockaddr *_sockaddr, socklen_t _socklen)
{ return (ssize_t)::sendto(_socket, (const char*)_buf, (int)_len, _flags, _sockaddr, (int)_socklen); }
ssize_t send(socket_t _socket, const void *_buf, size_t _len, int _flags)
{ return (ssize_t)::send(_socket, (const char*)_buf, (int)_len, _flags); }
#else
#define closesocket(X) close(X)
#endif
template <domain D>
socket_domain<D>::socket_domain (const socket_domain<D> &rhs):
m_fd (dup (rhs.m_fd))
{ ; }
template <domain D>
socket_domain<D>::~socket_domain () {
if (closesocket (m_fd) < 0) {
LOG_DEBUG ("closesocket: %s", strerror (errno));
}
}
template <domain D>
socket_t
socket_domain<D>::native (void) const
{ return m_fd; }
template <domain D>
void
socket_domain<D>::shutdown (void) {
#if defined(HAVE_WINSOCK2_H)
#define SHUT_SEND SD_SEND
#define SHUT_RECV SD_RECEIVE
#define SHUT_RDWR SD_BOTH
#endif
if (::shutdown (m_fd, SHUT_RDWR) < 0)
net::error::throw_code ();
}
template <domain D>
template <typename T>
T
socket_domain<D>::get_option (level, option) {
not_implemented ();
return T ();
}
template <domain D>
void
socket_domain<D>::set_option (level _level, option _option) {
if (setsockopt (this->m_fd, (int)_level, (int)_option, NULL, 0))
net::error::throw_code ();
}
template <domain D>
template <typename T>
void
socket_domain<D>::set_option (level _level, option _option, const T &value) {
if (setsockopt (this->m_fd, (int)_level, (int)_option, (const char*)&value, sizeof (value)))
net::error::throw_code ();
}
template <domain D>
void
socket_domain<D>::bind (const address_type &addr) {
typename address_type::sockaddr_type addr_in = addr.to_sockaddr ();
if (::bind (m_fd, (sockaddr *)&addr_in, sizeof (addr_in)) != 0)
net::error::throw_code ();
}
//-----------------------------------------------------------------------------
template <domain D>
net::socket<D, type::STREAM>::socket (socket_t _fd):
net::socket_domain<D> (_fd)
{ ; }
template <domain D>
net::socket<D, type::STREAM>::socket ():
net::socket_domain<D> (::socket ((int)D, (int)type::STREAM, (int)protocol::DEFAULT))
{ ; }
template <domain D>
net::socket<D, type::STREAM>::socket (const socket_type &rhs):
socket_domain<D> (rhs)
{ ; }
template <domain D>
void
net::socket<D, type::STREAM>::send (const uint8_t *restrict data, size_t len) {
CHECK_HARD (data != NULL);
CHECK (len > 0);
for (size_t sent = 0; sent < len; ) {
ssize_t result = ::send (this->m_fd, static_cast<const void *>(data + sent), len - sent, 0);
if (result < 0)
net::error::throw_code ();
sent += sign_cast<size_t> (result);
}
}
template <domain D>
size_t
net::socket<D, type::STREAM>::recv (uint8_t *restrict data, size_t len) {
CHECK_HARD (data != NULL);
CHECK (len > 0);
ssize_t received = ::recv (this->m_fd, data, len, 0);
if (received < 0)
net::error::throw_code ();
return sign_cast<size_t> (received);
}
template <domain D>
void
net::socket<D, type::STREAM>::connect (const address_type &_addr) {
typename address_type::sockaddr_type addr (_addr.to_sockaddr ());
if (::connect (this->m_fd, reinterpret_cast<sockaddr *> (&addr), sizeof (addr)) < 0)
net::error::throw_code ();
}
template <domain D>
void
net::socket<D, type::STREAM>::listen (const address_type &_addr, unsigned int _backlog) {
this->bind (_addr);
if (::listen (this->m_fd, sign_cast<int>(_backlog)) != 0)
net::error::throw_code ();
}
template <domain D>
typename net::socket<D, type::STREAM>::socket_ptr
net::socket<D, type::STREAM>::accept (void) {
int newfd = ::accept (this->m_fd, NULL, 0);
if (newfd < 0)
net::error::throw_code ();
return socket_ptr(new socket<D, type::STREAM> (newfd));
}
template <domain D>
typename net::socket<D, type::STREAM>::address_type
net::socket<D, type::STREAM>::get_peer (void) const {
typename address_type::sockaddr_type addr;
socklen_t addr_len;
if (getpeername (this->m_fd, (sockaddr*)&addr, &addr_len))
net::error::throw_code ();
CHECK (addr_len == sizeof (addr));
return addr;
}
//-----------------------------------------------------------------------------
template <domain D>
net::socket<D, type::DGRAM>::socket (socket_t _fd):
net::socket_domain<D> (_fd)
{ ; }
template <domain D>
net::socket<D, type::DGRAM>::socket ():
net::socket_domain<D> (::socket ((int)D, (int)type::DGRAM, (int)protocol::DEFAULT))
{ ; }
template <domain D>
net::socket<D, type::DGRAM>::socket (const socket_type &rhs):
net::socket_domain<D> (rhs)
{ ; }
template <domain D>
void
net::socket<D, type::DGRAM>::send_addr (const address_type &addr,
const uint8_t *restrict data,
size_t len) {
CHECK_HARD (data != NULL);
CHECK (len > 0);
typename address_type::sockaddr_type addr_in = addr.to_sockaddr ();
ssize_t sent = ::sendto (this->m_fd, data, len, 0, (sockaddr *)&addr_in, sizeof (addr_in));
if (sent < 0)
net::error::throw_code ();
CHECK_HARD (sign_cast<size_t>(sent) == len);
}
template <domain D>
typename net::socket<D, type::DGRAM>::address_type
net::socket<D, type::DGRAM>::recv_addr (uint8_t *restrict data,
size_t len) {
CHECK_HARD (data != NULL);
CHECK (len > 0);
typename address_type::sockaddr_type addr_in;
socklen_t addr_len = sizeof (addr_in);
ssize_t recvd = recvfrom (this->m_fd, data, len, 0, (sockaddr *)&addr_in, &addr_len);
CHECK_HARD (sizeof (addr_in) == addr_len);
if (recvd < 0)
net::error::throw_code ();
return addr_in;
}
//-----------------------------------------------------------------------------
template class net::socket_domain<domain::INET>;
template void net::socket_domain<domain::INET>::set_option<int>(level, option, const int&);
template class net::socket<domain::INET, type::STREAM>;
template class net::socket<domain::INET, type::DGRAM>;

109
net/socket.hpp Normal file
View File

@ -0,0 +1,109 @@
/*
* This file is part of libgim.
*
* libgim 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 (at your option) any later
* version.
*
* libgim 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 libgim. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2011 Danny Robson <danny@nerdcruft.net>
*/
#ifndef __NET_SOCKET_HPP
#define __NET_SOCKET_HPP
#include "types.hpp"
#include "address.hpp"
//-----------------------------------------------------------------------------
namespace net {
template <domain D>
class socket_domain {
public:
typedef address<D> address_type;
protected:
socket_t m_fd;
socket_domain (socket_t _fd);
socket_domain (const socket_domain<D>&);
~socket_domain ();
public:
socket_t native (void) const;
void shutdown (void);
template <typename T>
T get_option (level, option);
void set_option (level, option);
template <typename T>
void set_option (level, option, const T &value);
protected:
void bind (const address_type&);
};
template <domain D, type T>
class socket;
template <domain D>
class socket<D, type::STREAM>: public socket_domain<D> {
public:
typedef socket<D, type::STREAM> socket_type;
typedef std::unique_ptr<socket_type> socket_ptr;
typedef address<D> address_type;
protected:
static const unsigned int DEFAULT_BACKLOG = 5;
socket (socket_t _fd);
public:
socket ();
socket (const socket_type &);
void send (const uint8_t *restrict, size_t);
size_t recv (uint8_t *restrict, size_t);
void connect (const address_type&);
void listen (const address_type&, unsigned int backlog = DEFAULT_BACKLOG);
socket_ptr accept (void);
address_type get_peer (void) const;
};
template <domain D>
class socket<D, type::DGRAM> : public socket_domain<D> {
public:
typedef socket<D, type::DGRAM> socket_type;
typedef address<D> address_type;
socket (socket_t _fd);
public:
socket ();
socket (const socket_type &);
void send_addr (const address_type&, const uint8_t *restrict, size_t);
address_type recv_addr (uint8_t *restrict, size_t);
};
}
#endif // __NET_SOCKET_HPP

53
net/types.cpp Normal file
View File

@ -0,0 +1,53 @@
/*
* This file is part of libgim.
*
* libgim 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 (at your option) any later
* version.
*
* libgim 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 libgim. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2011 Danny Robson <danny@nerdcruft.net>
*/
#include "types.hpp"
#include "../debug.hpp"
#if defined(HAVE_WINSOCK2_H)
#else
#include <netdb.h>
#endif
//-----------------------------------------------------------------------------
using namespace net;
//-----------------------------------------------------------------------------
protocol
net::string_to_protocol (const std::string &_name)
{ return net::string_to_protocol (_name.c_str ()); }
protocol
net::string_to_protocol (const char *_name) {
struct protoent *entry = getprotobyname (_name);
// TODO: Throw an exception...
CHECK_HARD (entry);
return (protocol)entry->p_proto;
}
std::string
net::protocol_to_string (protocol _protocol) {
struct protoent *entry = getprotobynumber ((int)_protocol);
CHECK_HARD (entry);
return entry->p_name;
}

182
net/types.hpp Normal file
View File

@ -0,0 +1,182 @@
/*
* This file is part of libgim.
*
* libgim 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 (at your option) any later
* version.
*
* libgim 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 libgim. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2011 Danny Robson <danny@nerdcruft.net>
*/
#ifndef __NET_TYPES_HPP
#define __NET_TYPES_HPP
#if defined(HAVE_WINSOCK2_H)
#include <winsock2.h>
#else
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <cstring>
#endif
#include <string>
#include <stdexcept>
namespace net {
/// Cross platform socket type to deal with Winsock2
#if defined(HAVE_WINSOCK2_H)
typedef SOCKET socket_t;
#else
typedef int socket_t;
#endif
/// Defines the protocol family, or communication domain of a socket (see `man socket').
enum class domain : int {
#define DEFINE_DOMAIN(V) \
V = AF_##V
DEFINE_DOMAIN(UNIX),
//DEFINE_DOMAIN(LOCAL),
DEFINE_DOMAIN(INET),
DEFINE_DOMAIN(INET6),
DEFINE_DOMAIN(IPX),
//DEFINE_DOMAIN(NETLINK),
//DEFINE_DOMAIN(X25),
//DEFINE_DOMAIN(AX25),
//DEFINE_DOMAIN(ATMPVC),
DEFINE_DOMAIN(APPLETALK)
//DEFINE_DOMAIN(PACKET)
#undef DEFINE_DOMAIN
};
/// Specifies the communication semantics of a socket; how a socket deals with data.
enum class type : int {
#define DEFINE_TYPE(V) \
V = SOCK_##V
DEFINE_TYPE(STREAM),
DEFINE_TYPE(DGRAM),
DEFINE_TYPE(SEQPACKET),
DEFINE_TYPE(RAW),
DEFINE_TYPE(RDM)
//DEFINE_TYPE(PACKET)
#undef DEFINE_TYPE
};
/// Indicates the wire transmission protocol to use.
///
/// This DOES NOT mean what you think it does! It is included for completeness sake, and unless
/// you're doing something funky with the C API you really just want DEFAULT.
/// Values retrieved from /etc/protocols
enum class protocol : int {
DEFAULT = 0,
IP = 0,
ICMP = 1,
TCP = 6,
UDP = 17,
IPV6 = 41
};
protocol
string_to_protocol (const std::string&);
protocol
string_to_protocol (const char *name);
std::string
protocol_to_string (protocol);
enum class option : int {
#define DEFINE_OPTION(V) \
V = SO_##V
DEFINE_OPTION(DEBUG),
DEFINE_OPTION(REUSEADDR),
DEFINE_OPTION(TYPE),
//DEFINE_OPTION(ERROR),
DEFINE_OPTION(DONTROUTE),
DEFINE_OPTION(BROADCAST),
//DEFINE_OPTION(SNDBUF),
DEFINE_OPTION(RCVBUF),
//DEFINE_OPTION(SNDBUFFORCE),
//DEFINE_OPTION(RCVBUFFORCE),
DEFINE_OPTION(KEEPALIVE),
DEFINE_OPTION(OOBINLINE),
//DEFINE_OPTION(NO_CHECK),
//DEFINE_OPTION(PRIORITY),
DEFINE_OPTION(LINGER),
//DEFINE_OPTION(BSDCOMPAT),
//DEFINE_OPTION(PASSCRED),
//DEFINE_OPTION(PEERCRED),
DEFINE_OPTION(RCVLOWAT),
DEFINE_OPTION(SNDLOWAT),
DEFINE_OPTION(RCVTIMEO),
DEFINE_OPTION(SNDTIMEO),
//DEFINE_OPTION(BINDTODEVICE),
//DEFINE_OPTION(ATTACH_FILTER),
//DEFINE_OPTION(DETACH_FILTER),
//DEFINE_OPTION(PEERNAME),
//DEFINE_OPTION(TIMESTAMP),
DEFINE_OPTION(ACCEPTCONN),
//DEFINE_OPTION(PEERSEC),
//DEFINE_OPTION(PASSSEC),
//DEFINE_OPTION(TIMESTAMPNS),
//DEFINE_OPTION(MARK),
//DEFINE_OPTION(TIMESTAMPING)
#undef DEFINE_OPTION
#define DEFINE_OPTION(V) \
V = TCP_##V
//DEFINE_OPTION(CORK),
//DEFINE_OPTION(DEFER_ACCEPT),
//DEFINE_OPTION(INFO),
//DEFINE_OPTION(KEEPCNT),
//DEFINE_OPTION(KEEPIDLE),
//DEFINE_OPTION(KEEPINTVL),
//DEFINE_OPTION(LINGER2),
//DEFINE_OPTION(MAXSEG),
DEFINE_OPTION(NODELAY)
//DEFINE_OPTION(QUICKACK),
//DEFINE_OPTION(SYNCNT),
//DEFINE_OPTION(WINDOW_CLAMP)
#undef DEFINE_OPTION
};
enum class level : int {
SOCKET = SOL_SOCKET,
TCP = IPPROTO_TCP
};
}
#endif // __NET_TYPES_HPP