net: remove networking code
this now forms a separate library, libcruft-net.
This commit is contained in:
parent
ead926bed2
commit
b8c88c1292
15
Makefile.am
15
Makefile.am
@ -165,8 +165,6 @@ UTIL_FILES = \
|
||||
io.cpp \
|
||||
io.hpp \
|
||||
io.ipp \
|
||||
ip.cpp \
|
||||
ip.hpp \
|
||||
iterator.hpp \
|
||||
json/fwd.hpp \
|
||||
json/except.cpp \
|
||||
@ -277,14 +275,6 @@ UTIL_FILES = \
|
||||
|
||||
|
||||
POSIX_FILES = \
|
||||
net/address.cpp \
|
||||
net/address.hpp \
|
||||
net/except.cpp \
|
||||
net/except.hpp \
|
||||
net/socket.cpp \
|
||||
net/socket.hpp \
|
||||
net/types.cpp \
|
||||
net/types.hpp \
|
||||
memory/buffer/circular.cpp \
|
||||
memory/buffer/circular.hpp \
|
||||
memory/buffer/paged.cpp \
|
||||
@ -349,8 +339,8 @@ BACKTRACE_FILES=$(firstword $(__BACKTRACE_FILES) backtrace_null.cpp)
|
||||
|
||||
###############################################################################
|
||||
## Local build rules
|
||||
CLEANFILES = json.cpp version.cpp ip.cpp uri.cpp
|
||||
EXTRA_DIST = json/flat.cpp.rl version.cpp.rl ip.cpp.rl uri.cpp.rl
|
||||
CLEANFILES = json.cpp version.cpp uri.cpp
|
||||
EXTRA_DIST = json/flat.cpp.rl version.cpp.rl uri.cpp.rl
|
||||
|
||||
RAGELFLAGS = -F1
|
||||
SUFFIXES = .cpp .cpp.rl
|
||||
@ -427,7 +417,6 @@ TEST_BIN = \
|
||||
test/hash/sha2 \
|
||||
test/hton \
|
||||
test/introspection \
|
||||
test/ip \
|
||||
test/json_types \
|
||||
test/maths \
|
||||
test/matrix \
|
||||
|
@ -83,8 +83,6 @@ AC_SEARCH_LIBS([clock_gettime], [rt c], [], [
|
||||
|
||||
AC_SEARCH_LIBS([cos], [m], [], [AC_MSG_ERROR([unable to find the maths library])])
|
||||
|
||||
AC_SEARCH_LIBS([htons], [ws2_32], [], [AC_MSG_ERROR([unable to find htons library])])
|
||||
|
||||
|
||||
###############################################################################
|
||||
## Debug features
|
||||
|
128
ip.cpp.rl
128
ip.cpp.rl
@ -1,128 +0,0 @@
|
||||
/*
|
||||
* 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-2016 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
|
||||
#include "ip.hpp"
|
||||
|
||||
#include "cast.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
const ipv4::ip ipv4::ip::LOOPBACK (127, 0, 0, 1);
|
||||
const ipv4::ip ipv4::ip::ANY ( 0, 0, 0, 0);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
const util::range<ipv4::port_t> ipv4::WELL_KNOWN_PORT ( 0, 1023),
|
||||
ipv4::REGISTERED_PORT ( 1024, 49151),
|
||||
ipv4::PRIVATE_PORT (49152, 65535);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
ipv4::ip::ip (uint32_t _integer):
|
||||
m_integer (_integer)
|
||||
{ ; }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
ipv4::ip::ip (uint8_t a, uint8_t b, uint8_t c, uint8_t d)
|
||||
{
|
||||
m_octets[0] = a;
|
||||
m_octets[1] = b;
|
||||
m_octets[2] = c;
|
||||
m_octets[3] = d;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
bool
|
||||
ipv4::ip::operator== (const ipv4::ip &rhs) const
|
||||
{
|
||||
return m_integer == rhs.m_integer;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RFC 3986
|
||||
%%{
|
||||
machine ipv4;
|
||||
octet = ( [0-9][0-9]? |
|
||||
'1'[0-9][0-9] |
|
||||
'2'[0-4][0-9] |
|
||||
'25'[0-5])
|
||||
> {
|
||||
octetstart = fpc;
|
||||
}
|
||||
% {
|
||||
octetend = fpc;
|
||||
__octet = 0;
|
||||
|
||||
for (auto i = octetstart; i < octetend; ++i)
|
||||
__octet = __octet * 10u + sign_cast<unsigned> (*i - '0');
|
||||
};
|
||||
|
||||
ipv4 := (octet %{ __octets[0] = __octet; } '.'
|
||||
octet %{ __octets[1] = __octet; } '.'
|
||||
octet %{ __octets[2] = __octet; } '.'
|
||||
octet %{ __octets[3] = __octet; })
|
||||
> { __success = false; }
|
||||
% { __success = true; }
|
||||
$!{ __success = false; };
|
||||
}%%
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
%%write data;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
ipv4::ip::ip (const std::string &data)
|
||||
{
|
||||
bool __success = true;
|
||||
uint8_t __octets[4] = { 0, 0, 0, 0 };
|
||||
const char *octetstart = data.data ();
|
||||
const char *octetend = nullptr;
|
||||
uint8_t __octet;
|
||||
|
||||
int cs = 0;
|
||||
const char *p = data.data (),
|
||||
*pe = p + data.size (),
|
||||
*eof = pe;
|
||||
|
||||
%%write init;
|
||||
%%write exec;
|
||||
|
||||
if (!__success)
|
||||
throw ipv4::error ();
|
||||
|
||||
m_octets[0] = __octets[0];
|
||||
m_octets[1] = __octets[1];
|
||||
m_octets[2] = __octets[2];
|
||||
m_octets[3] = __octets[3];
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
ipv4::ip
|
||||
ipv4::ip::parse (const std::string &data)
|
||||
{ return ipv4::ip (data); }
|
||||
|
79
ip.hpp
79
ip.hpp
@ -1,79 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2011-2016 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#ifndef __UTIL_IP_HPP
|
||||
#define __UTIL_IP_HPP
|
||||
|
||||
#include "range.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace ipv4 {
|
||||
struct ip {
|
||||
union {
|
||||
uint8_t m_octets[4];
|
||||
uint32_t m_integer;
|
||||
};
|
||||
|
||||
explicit ip (const std::string &);
|
||||
explicit ip (uint32_t i);
|
||||
ip (uint8_t a, uint8_t b, uint8_t c, uint8_t d);
|
||||
|
||||
bool operator== (const ip &) const;
|
||||
|
||||
explicit operator uint32_t (void);
|
||||
|
||||
static ip parse (const std::string &);
|
||||
|
||||
static const ip LOOPBACK;
|
||||
static const ip ANY;
|
||||
};
|
||||
|
||||
|
||||
typedef uint16_t port_t;
|
||||
typedef uint32_t mask_t;
|
||||
|
||||
extern const util::range<port_t> WELL_KNOWN_PORT,
|
||||
REGISTERED_PORT,
|
||||
PRIVATE_PORT;
|
||||
|
||||
class error : public std::exception { };
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace ipv6 {
|
||||
struct ip {
|
||||
uint32_t m_quads[4];
|
||||
|
||||
explicit ip (const std::string&) { ; }
|
||||
};
|
||||
|
||||
typedef uint16_t port_t;
|
||||
|
||||
struct mask_t {
|
||||
uint32_t m_quads[4];
|
||||
|
||||
explicit mask_t (uint32_t) { ; }
|
||||
};
|
||||
|
||||
class error : public std::exception { };
|
||||
}
|
||||
|
||||
|
||||
#endif // __UTIL_IP_HPP
|
167
net/address.cpp
167
net/address.cpp
@ -1,167 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2011 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#include "address.hpp"
|
||||
|
||||
#include "except.hpp"
|
||||
#include "../debug.hpp"
|
||||
#include "../endian.hpp"
|
||||
#include "../types.hpp"
|
||||
#include "../raii.hpp"
|
||||
|
||||
|
||||
#ifdef __WIN32
|
||||
#else
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
using net::address;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#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
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <net::domain D>
|
||||
typename address<D>::port_type
|
||||
address<D>::port (void) const
|
||||
{ return m_port; }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <net::domain D>
|
||||
void
|
||||
address<D>::set_port (const port_type &_port)
|
||||
{ m_port = _port; }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <net::domain D>
|
||||
typename address<D>::ip_type
|
||||
address<D>::resolve (const std::string &str) {
|
||||
addrinfo hint;
|
||||
memset (&hint, 0, sizeof (hint));
|
||||
hint.ai_family = static_cast<int> (D);
|
||||
|
||||
addrinfo* resolved;
|
||||
int err = getaddrinfo (str.c_str (), nullptr, nullptr, &resolved);
|
||||
if (err)
|
||||
net::error::throw_code ();
|
||||
|
||||
auto deletor = [] (addrinfo *a) { freeaddrinfo (a); };
|
||||
std::unique_ptr<addrinfo, decltype(deletor)> raii(resolved, deletor);
|
||||
return ip_type (reinterpret_cast<sockaddr_type*> (resolved->ai_addr)->sin_addr.s_addr);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace net {
|
||||
template <>
|
||||
address<net::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)net::domain::INET);
|
||||
}
|
||||
|
||||
|
||||
template <net::domain D>
|
||||
address<D>::address (const std::string &_addr,
|
||||
port_type _port):
|
||||
m_ip (resolve (_addr)),
|
||||
m_mask ( 0),
|
||||
m_port (_port)
|
||||
{ ; }
|
||||
|
||||
|
||||
template <>
|
||||
address<net::domain::INET>::sockaddr_type
|
||||
address<net::domain::INET>::to_sockaddr (void) const {
|
||||
sockaddr_type addr;
|
||||
|
||||
addr.sin_family = (int)net::domain::INET;
|
||||
addr.sin_port = hton (m_port);
|
||||
addr.sin_addr.s_addr = m_ip.m_integer;
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
std::string
|
||||
address<net::domain::INET>::to_string (void) const {
|
||||
char dest[INET_ADDRSTRLEN + 1];
|
||||
sockaddr_type addr = to_sockaddr ();
|
||||
|
||||
if (NULL == inet_ntop ((int)net::domain::INET, &addr.sin_addr, dest, sizeof (dest)))
|
||||
net::error::throw_code ();
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
bool
|
||||
address<net::domain::INET>::operator ==(const address<net::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<net::domain::INET>
|
||||
address<net::domain::INET>::LOOPBACK ("127.0.0.1", 0);
|
||||
|
||||
template <> const address<net::domain::INET>
|
||||
address<net::domain::INET>::ANY ("0.0.0.0", 0);
|
||||
|
||||
namespace net {
|
||||
template class address<net::domain::INET>;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//template <> const address<net::domain::INET6>
|
||||
//address<net::domain::INET6>::LOOPBACK ("::1", 0);
|
||||
//
|
||||
//template <> const address<net::domain::INET6>
|
||||
//address<net::domain::INET6>::ANY ("::0", 0);
|
||||
//
|
||||
//template class address<net::domain::INET6>;
|
||||
|
@ -1,97 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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 <ostream>
|
||||
#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_t mask_t;
|
||||
typedef ipv4::port_t port_t;
|
||||
typedef sockaddr_in sockaddr;
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
struct address_types <domain::INET6> {
|
||||
typedef ipv6::ip ip;
|
||||
typedef ipv6::mask_t mask_t;
|
||||
typedef ipv6::port_t port_t;
|
||||
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_t mask_type;
|
||||
typedef typename address_types<D>::port_t 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;
|
||||
|
||||
explicit address (const sockaddr_type &);
|
||||
address (const std::string &address, port_type);
|
||||
|
||||
port_type port (void) const;
|
||||
void set_port (const port_type &);
|
||||
|
||||
ip_type ip (void) const { return m_ip; }
|
||||
|
||||
sockaddr_type to_sockaddr (void) const;
|
||||
std::string to_string (void) const;
|
||||
|
||||
static ip_type resolve (const std::string &);
|
||||
|
||||
bool operator ==(const address<D> &rhs);
|
||||
};
|
||||
|
||||
std::ostream&
|
||||
operator<< (std::ostream &os, const net::address<net::domain::INET> &addr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // __NET_ADDRESS_HPP
|
||||
|
122
net/except.cpp
122
net/except.cpp
@ -1,122 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2011 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#include "except.hpp"
|
||||
|
||||
#include "../debug.hpp"
|
||||
#include "../cast.hpp"
|
||||
|
||||
|
||||
using net::error;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
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];
|
||||
|
||||
// It should be fine to signcast the code here as Windows guarantees all
|
||||
// error messages are positive but appears to use int for compatibility
|
||||
DWORD output = FormatMessage (0, NULL, sign_cast<unsigned> (code), 0, message, sizeof (message), NULL);
|
||||
CHECK_NEQ (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::throw_code (void)
|
||||
{ throw_code (last_code ()); }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
net::error::try_code (int err) {
|
||||
if (__builtin_expect (err != 0, false))
|
||||
throw_code (err);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
net::error::try_code (void)
|
||||
{ try_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; }
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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>
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace net {
|
||||
class error : public std::runtime_error {
|
||||
protected:
|
||||
explicit error (const std::string &);
|
||||
explicit 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 [[noreturn]] (int code);
|
||||
|
||||
/// 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 [[noreturn]] (void);
|
||||
|
||||
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
|
300
net/socket.cpp
300
net/socket.cpp
@ -1,300 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2011 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#include "socket.hpp"
|
||||
|
||||
#include "../debug.hpp"
|
||||
#include "../except.hpp"
|
||||
#include "../cast.hpp"
|
||||
#include "../log.hpp"
|
||||
#include "except.hpp"
|
||||
|
||||
#if defined(HAVE_WINSOCK2_H)
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#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_GE (m_fd, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if defined(HAVE_WINSOCK2_H)
|
||||
// TODO: Make this not retarded. Fucking Windows.
|
||||
#define dup(X) (X)
|
||||
|
||||
// Winsock has incorrect return and parameter types (according to POSIX)
|
||||
// so we need some wrappers around the system implementations that casts
|
||||
// to expected types. Mainly int vs ssize_t returns, and int vs size_t
|
||||
// parameters.
|
||||
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 (data != NULL);
|
||||
CHECK_GT (len, 0u);
|
||||
|
||||
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 (data != NULL);
|
||||
CHECK_GT (len, 0u);
|
||||
|
||||
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) {
|
||||
socket_t newfd = ::accept (this->m_fd, NULL, 0);
|
||||
if (newfd == INVALID_SOCKET)
|
||||
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 typename net::socket<D,type::STREAM>::address_type (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 (data != NULL);
|
||||
CHECK_GT (len, 0u);
|
||||
|
||||
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_EQ (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 (data != NULL);
|
||||
CHECK_GT (len, 0u);
|
||||
|
||||
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_EQ (sizeof (addr_in), addr_len);
|
||||
if (recvd < 0)
|
||||
net::error::throw_code ();
|
||||
|
||||
return net::socket<D,type::DGRAM>::address_type (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>;
|
||||
|
108
net/socket.hpp
108
net/socket.hpp
@ -1,108 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2011 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#ifndef __NET_SOCKET_HPP
|
||||
#define __NET_SOCKET_HPP
|
||||
|
||||
#include <memory>
|
||||
|
||||
#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
|
||||
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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 (entry);
|
||||
return (protocol)entry->p_proto;
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
net::protocol_to_string (protocol _protocol) {
|
||||
struct protoent *entry = getprotobynumber ((int)_protocol);
|
||||
CHECK (entry);
|
||||
return entry->p_name;
|
||||
}
|
||||
|
180
net/types.hpp
180
net/types.hpp
@ -1,180 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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;
|
||||
const socket_t INVALID_SOCKET = -1;
|
||||
#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
|
||||
|
Loading…
Reference in New Issue
Block a user