Socket lib restyle and fixes backported from 3.0
This commit is contained in:
parent
8678445a5d
commit
e90a3d60c0
2 changed files with 128 additions and 124 deletions
132
lib/socket.cpp
132
lib/socket.cpp
|
@ -2,8 +2,8 @@
|
||||||
/// A handy Socket wrapper library.
|
/// A handy Socket wrapper library.
|
||||||
/// Written by Jaron Vietor in 2010 for DDVTech
|
/// Written by Jaron Vietor in 2010 for DDVTech
|
||||||
|
|
||||||
#include "socket.h"
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
#include "socket.h"
|
||||||
#include "timing.h"
|
#include "timing.h"
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <ifaddrs.h>
|
#include <ifaddrs.h>
|
||||||
|
@ -37,8 +37,7 @@ static std::string getIPv6BinAddr(const struct sockaddr_in6 &remoteaddr){
|
||||||
char tmpBuffer[17] = "\000\000\000\000\000\000\000\000\000\000\377\377\000\000\000\000";
|
char tmpBuffer[17] = "\000\000\000\000\000\000\000\000\000\000\377\377\000\000\000\000";
|
||||||
switch (remoteaddr.sin6_family){
|
switch (remoteaddr.sin6_family){
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
memcpy(tmpBuffer + 12, &(reinterpret_cast<const sockaddr_in *>(&remoteaddr)->sin_addr.s_addr),
|
memcpy(tmpBuffer + 12, &(reinterpret_cast<const sockaddr_in *>(&remoteaddr)->sin_addr.s_addr), 4);
|
||||||
4);
|
|
||||||
break;
|
break;
|
||||||
case AF_INET6: memcpy(tmpBuffer, &(remoteaddr.sin6_addr.s6_addr), 16); break;
|
case AF_INET6: memcpy(tmpBuffer, &(remoteaddr.sin6_addr.s6_addr), 16); break;
|
||||||
default: return ""; break;
|
default: return ""; break;
|
||||||
|
@ -58,7 +57,7 @@ bool Socket::isLocalhost(const std::string &remotehost){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
///Checks if the given file descriptor is actually socket or not.
|
/// Checks if the given file descriptor is actually socket or not.
|
||||||
bool Socket::checkTrueSocket(int sock){
|
bool Socket::checkTrueSocket(int sock){
|
||||||
struct stat sBuf;
|
struct stat sBuf;
|
||||||
if (sock != -1 && !fstat(sock, &sBuf)){return S_ISSOCK(sBuf.st_mode);}
|
if (sock != -1 && !fstat(sock, &sBuf)){return S_ISSOCK(sBuf.st_mode);}
|
||||||
|
@ -188,15 +187,25 @@ void Socket::hostBytesToStr(const char *bytes, size_t len, std::string &target){
|
||||||
target = tmpstr;
|
target = tmpstr;
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
|
if (memcmp(bytes, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 15) == 0){
|
||||||
|
if (bytes[15] == 0){
|
||||||
|
target = "::";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char tmpstr[6];
|
||||||
|
snprintf(tmpstr, 6, "::%hhu", bytes[15]);
|
||||||
|
target = tmpstr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (memcmp(bytes, "\000\000\000\000\000\000\000\000\000\000\377\377", 12) == 0){
|
if (memcmp(bytes, "\000\000\000\000\000\000\000\000\000\000\377\377", 12) == 0){
|
||||||
char tmpstr[16];
|
char tmpstr[16];
|
||||||
snprintf(tmpstr, 16, "%hhu.%hhu.%hhu.%hhu", bytes[12], bytes[13], bytes[14], bytes[15]);
|
snprintf(tmpstr, 16, "%hhu.%hhu.%hhu.%hhu", bytes[12], bytes[13], bytes[14], bytes[15]);
|
||||||
target = tmpstr;
|
target = tmpstr;
|
||||||
}else{
|
}else{
|
||||||
char tmpstr[40];
|
char tmpstr[40];
|
||||||
snprintf(tmpstr, 40, "%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x", bytes[0], bytes[1],
|
snprintf(tmpstr, 40, "%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x",
|
||||||
bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13],
|
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
|
||||||
bytes[14], bytes[15]);
|
bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15]);
|
||||||
target = tmpstr;
|
target = tmpstr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -237,8 +246,7 @@ unsigned int Socket::Buffer::bytesToSplit(){
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
for (std::deque<std::string>::reverse_iterator it = data.rbegin(); it != data.rend(); ++it){
|
for (std::deque<std::string>::reverse_iterator it = data.rbegin(); it != data.rend(); ++it){
|
||||||
i += (*it).size();
|
i += (*it).size();
|
||||||
if ((*it).size() >= splitter.size() &&
|
if ((*it).size() >= splitter.size() && (*it).substr((*it).size() - splitter.size()) == splitter){
|
||||||
(*it).substr((*it).size() - splitter.size()) == splitter){
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -293,8 +301,8 @@ void Socket::Buffer::append(const char *newdata, const unsigned int newdatasize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (data.size() > 5000){
|
if (data.size() > 5000){
|
||||||
WARN_MSG("Warning: After %d new bytes, buffer has %d parts containing over %u bytes!", newdatasize, (int)data.size(),
|
WARN_MSG("Warning: After %d new bytes, buffer has %d parts containing over %u bytes!",
|
||||||
bytes(9000));
|
newdatasize, (int)data.size(), bytes(9000));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,13 +394,11 @@ void Socket::Connection::setBoundAddr(){
|
||||||
}
|
}
|
||||||
struct sockaddr_in6 tmpaddr;
|
struct sockaddr_in6 tmpaddr;
|
||||||
socklen_t len = sizeof(tmpaddr);
|
socklen_t len = sizeof(tmpaddr);
|
||||||
if (!getsockname(sSend, (sockaddr*)&tmpaddr, &len)){
|
if (!getsockname(sSend, (sockaddr *)&tmpaddr, &len)){
|
||||||
static char addrconv[INET6_ADDRSTRLEN];
|
static char addrconv[INET6_ADDRSTRLEN];
|
||||||
if (tmpaddr.sin6_family == AF_INET6){
|
if (tmpaddr.sin6_family == AF_INET6){
|
||||||
boundaddr = inet_ntop(AF_INET6, &(tmpaddr.sin6_addr), addrconv, INET6_ADDRSTRLEN);
|
boundaddr = inet_ntop(AF_INET6, &(tmpaddr.sin6_addr), addrconv, INET6_ADDRSTRLEN);
|
||||||
if (boundaddr.substr(0, 7) == "::ffff:"){
|
if (boundaddr.substr(0, 7) == "::ffff:"){boundaddr = boundaddr.substr(7);}
|
||||||
boundaddr = boundaddr.substr(7);
|
|
||||||
}
|
|
||||||
HIGH_MSG("Local IPv6 addr [%s]", boundaddr.c_str());
|
HIGH_MSG("Local IPv6 addr [%s]", boundaddr.c_str());
|
||||||
}
|
}
|
||||||
if (tmpaddr.sin6_family == AF_INET){
|
if (tmpaddr.sin6_family == AF_INET){
|
||||||
|
@ -402,13 +408,12 @@ void Socket::Connection::setBoundAddr(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Cleans up the socket by dropping the connection.
|
// Cleans up the socket by dropping the connection.
|
||||||
//Does not call close because it calls shutdown, which would destroy any copies of this socket too.
|
// Does not call close because it calls shutdown, which would destroy any copies of this socket too.
|
||||||
Socket::Connection::~Connection(){
|
Socket::Connection::~Connection(){
|
||||||
drop();
|
drop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Create a new base socket. This is a basic constructor for converting any valid socket to a
|
/// Create a new base socket. This is a basic constructor for converting any valid socket to a
|
||||||
/// Socket::Connection. \param sockNo Integer representing the socket to convert.
|
/// Socket::Connection. \param sockNo Integer representing the socket to convert.
|
||||||
Socket::Connection::Connection(int sockNo){
|
Socket::Connection::Connection(int sockNo){
|
||||||
|
@ -452,7 +457,7 @@ void Socket::Connection::clear(){
|
||||||
isTrueSocket = false;
|
isTrueSocket = false;
|
||||||
up = 0;
|
up = 0;
|
||||||
down = 0;
|
down = 0;
|
||||||
conntime = Util::epoch();
|
conntime = Util::bootSecs();
|
||||||
Error = false;
|
Error = false;
|
||||||
Blocking = false;
|
Blocking = false;
|
||||||
skipCount = 0;
|
skipCount = 0;
|
||||||
|
@ -548,9 +553,7 @@ void Socket::Connection::drop(){
|
||||||
#ifdef SSL
|
#ifdef SSL
|
||||||
if (sslConnected){
|
if (sslConnected){
|
||||||
DONTEVEN_MSG("SSL close");
|
DONTEVEN_MSG("SSL close");
|
||||||
if (ssl){
|
if (ssl){mbedtls_ssl_close_notify(ssl);}
|
||||||
mbedtls_ssl_close_notify(ssl);
|
|
||||||
}
|
|
||||||
if (server_fd){
|
if (server_fd){
|
||||||
mbedtls_net_free(server_fd);
|
mbedtls_net_free(server_fd);
|
||||||
delete server_fd;
|
delete server_fd;
|
||||||
|
@ -653,7 +656,7 @@ void Socket::Connection::open(std::string address, bool nonblock){
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SSL
|
#ifdef SSL
|
||||||
///Local-only function for debugging SSL sockets
|
/// Local-only function for debugging SSL sockets
|
||||||
static void my_debug(void *ctx, int level, const char *file, int line, const char *str){
|
static void my_debug(void *ctx, int level, const char *file, int line, const char *str){
|
||||||
((void)level);
|
((void)level);
|
||||||
fprintf((FILE *)ctx, "%s:%04d: %s", file, line, str);
|
fprintf((FILE *)ctx, "%s:%04d: %s", file, line, str);
|
||||||
|
@ -689,15 +692,15 @@ void Socket::Connection::open(std::string host, int port, bool nonblock, bool wi
|
||||||
mbedtls_ctr_drbg_init(ctr_drbg);
|
mbedtls_ctr_drbg_init(ctr_drbg);
|
||||||
mbedtls_entropy_init(entropy);
|
mbedtls_entropy_init(entropy);
|
||||||
DONTEVEN_MSG("SSL init");
|
DONTEVEN_MSG("SSL init");
|
||||||
if (mbedtls_ctr_drbg_seed(ctr_drbg, mbedtls_entropy_func, entropy, (const unsigned char *)"meow",
|
if (mbedtls_ctr_drbg_seed(ctr_drbg, mbedtls_entropy_func, entropy, (const unsigned char *)"meow", 4) != 0){
|
||||||
4) != 0){
|
|
||||||
FAIL_MSG("SSL socket init failed");
|
FAIL_MSG("SSL socket init failed");
|
||||||
close();
|
close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DONTEVEN_MSG("SSL connect");
|
DONTEVEN_MSG("SSL connect");
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
if ((ret = mbedtls_net_connect(server_fd, host.c_str(), JSON::Value(port).asString().c_str(), MBEDTLS_NET_PROTO_TCP)) != 0){
|
if ((ret = mbedtls_net_connect(server_fd, host.c_str(), JSON::Value(port).asString().c_str(),
|
||||||
|
MBEDTLS_NET_PROTO_TCP)) != 0){
|
||||||
FAIL_MSG(" failed\n ! mbedtls_net_connect returned %d\n\n", ret);
|
FAIL_MSG(" failed\n ! mbedtls_net_connect returned %d\n\n", ret);
|
||||||
close();
|
close();
|
||||||
return;
|
return;
|
||||||
|
@ -762,7 +765,10 @@ void Socket::Connection::open(std::string host, int port, bool nonblock, bool wi
|
||||||
for (rp = result; rp != NULL; rp = rp->ai_next){
|
for (rp = result; rp != NULL; rp = rp->ai_next){
|
||||||
sSend = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
sSend = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||||
if (sSend < 0){continue;}
|
if (sSend < 0){continue;}
|
||||||
if (connect(sSend, rp->ai_addr, rp->ai_addrlen) == 0){break;}
|
if (connect(sSend, rp->ai_addr, rp->ai_addrlen) == 0){
|
||||||
|
remoteaddr = *((sockaddr_in6 *)rp->ai_addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
remotehost += strerror(errno);
|
remotehost += strerror(errno);
|
||||||
::close(sSend);
|
::close(sSend);
|
||||||
}
|
}
|
||||||
|
@ -811,13 +817,6 @@ uint64_t Socket::Connection::dataDown(){
|
||||||
return down;
|
return down;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a std::string of stats, ended by a newline.
|
|
||||||
/// Requires the current connector name as an argument.
|
|
||||||
std::string Socket::Connection::getStats(std::string C){
|
|
||||||
return "S " + getHost() + " " + C + " " + uint2string(Util::epoch() - conntime) + " " +
|
|
||||||
uint2string(up) + " " + uint2string(down) + "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Updates the downbuffer internal variable.
|
/// Updates the downbuffer internal variable.
|
||||||
/// Returns true if new data was received, false otherwise.
|
/// Returns true if new data was received, false otherwise.
|
||||||
bool Socket::Connection::spool(){
|
bool Socket::Connection::spool(){
|
||||||
|
@ -962,7 +961,10 @@ int Socket::Connection::iread(void *buffer, int len, int flags){
|
||||||
r = mbedtls_ssl_read(ssl, (unsigned char *)buffer, len);
|
r = mbedtls_ssl_read(ssl, (unsigned char *)buffer, len);
|
||||||
if (r < 0){
|
if (r < 0){
|
||||||
switch (errno){
|
switch (errno){
|
||||||
case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: close(); return 0; break;
|
case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
|
||||||
|
close();
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
case MBEDTLS_ERR_SSL_WANT_WRITE: return 0; break;
|
case MBEDTLS_ERR_SSL_WANT_WRITE: return 0; break;
|
||||||
case MBEDTLS_ERR_SSL_WANT_READ: return 0; break;
|
case MBEDTLS_ERR_SSL_WANT_READ: return 0; break;
|
||||||
case EWOULDBLOCK: return 0; break;
|
case EWOULDBLOCK: return 0; break;
|
||||||
|
@ -1092,17 +1094,18 @@ Socket::Connection::operator bool() const{
|
||||||
return connected();
|
return connected();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Copy constructor
|
// Copy constructor
|
||||||
Socket::Connection::Connection(const Connection& rhs){
|
Socket::Connection::Connection(const Connection &rhs){
|
||||||
clear();
|
clear();
|
||||||
if (!rhs){return;}
|
if (!rhs){return;}
|
||||||
#if DEBUG >= DLVL_DEVEL
|
#if DEBUG >= DLVL_DEVEL
|
||||||
HIGH_MSG("Copying %s socket", rhs.sslConnected?"SSL":"regular");
|
HIGH_MSG("Copying %s socket", rhs.sslConnected ? "SSL" : "regular");
|
||||||
#endif
|
#endif
|
||||||
conntime = rhs.conntime;
|
conntime = rhs.conntime;
|
||||||
isTrueSocket = rhs.isTrueSocket;
|
isTrueSocket = rhs.isTrueSocket;
|
||||||
remotehost = rhs.remotehost;
|
remotehost = rhs.remotehost;
|
||||||
boundaddr = rhs.boundaddr;
|
boundaddr = rhs.boundaddr;
|
||||||
|
remoteaddr = rhs.remoteaddr;
|
||||||
up = rhs.up;
|
up = rhs.up;
|
||||||
down = rhs.down;
|
down = rhs.down;
|
||||||
downbuffer = rhs.downbuffer;
|
downbuffer = rhs.downbuffer;
|
||||||
|
@ -1119,18 +1122,19 @@ Socket::Connection::Connection(const Connection& rhs){
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//Assignment constructor
|
// Assignment constructor
|
||||||
Socket::Connection& Socket::Connection::operator=(const Socket::Connection& rhs){
|
Socket::Connection &Socket::Connection::operator=(const Socket::Connection &rhs){
|
||||||
drop();
|
drop();
|
||||||
clear();
|
clear();
|
||||||
if (!rhs){return *this;}
|
if (!rhs){return *this;}
|
||||||
#if DEBUG >= DLVL_DEVEL
|
#if DEBUG >= DLVL_DEVEL
|
||||||
HIGH_MSG("Assigning %s socket", rhs.sslConnected?"SSL":"regular");
|
HIGH_MSG("Assigning %s socket", rhs.sslConnected ? "SSL" : "regular");
|
||||||
#endif
|
#endif
|
||||||
conntime = rhs.conntime;
|
conntime = rhs.conntime;
|
||||||
isTrueSocket = rhs.isTrueSocket;
|
isTrueSocket = rhs.isTrueSocket;
|
||||||
remotehost = rhs.remotehost;
|
remotehost = rhs.remotehost;
|
||||||
boundaddr = rhs.boundaddr;
|
boundaddr = rhs.boundaddr;
|
||||||
|
remoteaddr = rhs.remoteaddr;
|
||||||
up = rhs.up;
|
up = rhs.up;
|
||||||
down = rhs.down;
|
down = rhs.down;
|
||||||
downbuffer = rhs.downbuffer;
|
downbuffer = rhs.downbuffer;
|
||||||
|
@ -1160,7 +1164,6 @@ bool Socket::Connection::isLocal(){
|
||||||
return Socket::isLocal(remotehost);
|
return Socket::isLocal(remotehost);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Create a new base Server. The socket is never connected, and a placeholder for later
|
/// Create a new base Server. The socket is never connected, and a placeholder for later
|
||||||
/// connections.
|
/// connections.
|
||||||
Socket::Server::Server(){
|
Socket::Server::Server(){
|
||||||
|
@ -1378,8 +1381,7 @@ Socket::Connection Socket::Server::accept(bool nonblock){
|
||||||
HIGH_MSG("IPv6 addr [%s]", tmp.remotehost.c_str());
|
HIGH_MSG("IPv6 addr [%s]", tmp.remotehost.c_str());
|
||||||
}
|
}
|
||||||
if (tmpaddr.sin6_family == AF_INET){
|
if (tmpaddr.sin6_family == AF_INET){
|
||||||
tmp.remotehost =
|
tmp.remotehost = inet_ntop(AF_INET, &(((sockaddr_in *)&tmpaddr)->sin_addr), addrconv, INET6_ADDRSTRLEN);
|
||||||
inet_ntop(AF_INET, &(((sockaddr_in *)&tmpaddr)->sin_addr), addrconv, INET6_ADDRSTRLEN);
|
|
||||||
HIGH_MSG("IPv4 addr [%s]", tmp.remotehost.c_str());
|
HIGH_MSG("IPv4 addr [%s]", tmp.remotehost.c_str());
|
||||||
}
|
}
|
||||||
if (tmpaddr.sin6_family == AF_UNIX){
|
if (tmpaddr.sin6_family == AF_UNIX){
|
||||||
|
@ -1443,6 +1445,9 @@ int Socket::Server::getSocket(){
|
||||||
/// If both fail, prints an DLVL_FAIL debug message.
|
/// If both fail, prints an DLVL_FAIL debug message.
|
||||||
/// \param nonblock Whether the socket should be nonblocking.
|
/// \param nonblock Whether the socket should be nonblocking.
|
||||||
Socket::UDPConnection::UDPConnection(bool nonblock){
|
Socket::UDPConnection::UDPConnection(bool nonblock){
|
||||||
|
boundPort = 0;
|
||||||
|
boundAddr = "";
|
||||||
|
boundMulti = "";
|
||||||
family = AF_INET6;
|
family = AF_INET6;
|
||||||
sock = socket(AF_INET6, SOCK_DGRAM, 0);
|
sock = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||||
if (sock == -1){
|
if (sock == -1){
|
||||||
|
@ -1546,11 +1551,14 @@ void Socket::UDPConnection::SetDestination(std::string destIp, uint32_t port){
|
||||||
if (!destAddr){return;}
|
if (!destAddr){return;}
|
||||||
memcpy(destAddr, rp->ai_addr, rp->ai_addrlen);
|
memcpy(destAddr, rp->ai_addr, rp->ai_addrlen);
|
||||||
if (family != rp->ai_family){
|
if (family != rp->ai_family){
|
||||||
INFO_MSG("Socket is wrong type (%s), re-opening as %s", addrFam(family),
|
INFO_MSG("Socket is wrong type (%s), re-opening as %s", addrFam(family), addrFam(rp->ai_family));
|
||||||
addrFam(rp->ai_family));
|
|
||||||
close();
|
close();
|
||||||
family = rp->ai_family;
|
family = rp->ai_family;
|
||||||
sock = socket(family, SOCK_DGRAM, 0);
|
sock = socket(family, SOCK_DGRAM, 0);
|
||||||
|
if (boundPort){
|
||||||
|
INFO_MSG("Rebinding to %s:%d %s", boundAddr.c_str(), boundPort, boundMulti.c_str());
|
||||||
|
bind(boundPort, boundAddr, boundMulti);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
HIGH_MSG("Set UDP destination: %s:%d (%s)", destIp.c_str(), port, addrFam(family));
|
HIGH_MSG("Set UDP destination: %s:%d (%s)", destIp.c_str(), port, addrFam(family));
|
||||||
freeaddrinfo(result);
|
freeaddrinfo(result);
|
||||||
|
@ -1574,16 +1582,14 @@ void Socket::UDPConnection::GetDestination(std::string &destIp, uint32_t &port){
|
||||||
char addr_str[INET6_ADDRSTRLEN + 1];
|
char addr_str[INET6_ADDRSTRLEN + 1];
|
||||||
addr_str[INET6_ADDRSTRLEN] = 0; // set last byte to zero, to prevent walking out of the array
|
addr_str[INET6_ADDRSTRLEN] = 0; // set last byte to zero, to prevent walking out of the array
|
||||||
if (((struct sockaddr_in *)destAddr)->sin_family == AF_INET6){
|
if (((struct sockaddr_in *)destAddr)->sin_family == AF_INET6){
|
||||||
if (inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)destAddr)->sin6_addr), addr_str,
|
if (inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)destAddr)->sin6_addr), addr_str, INET6_ADDRSTRLEN) != 0){
|
||||||
INET6_ADDRSTRLEN) != 0){
|
|
||||||
destIp = addr_str;
|
destIp = addr_str;
|
||||||
port = ntohs(((struct sockaddr_in6 *)destAddr)->sin6_port);
|
port = ntohs(((struct sockaddr_in6 *)destAddr)->sin6_port);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (((struct sockaddr_in *)destAddr)->sin_family == AF_INET){
|
if (((struct sockaddr_in *)destAddr)->sin_family == AF_INET){
|
||||||
if (inet_ntop(AF_INET, &(((struct sockaddr_in *)destAddr)->sin_addr), addr_str,
|
if (inet_ntop(AF_INET, &(((struct sockaddr_in *)destAddr)->sin_addr), addr_str, INET6_ADDRSTRLEN) != 0){
|
||||||
INET6_ADDRSTRLEN) != 0){
|
|
||||||
destIp = addr_str;
|
destIp = addr_str;
|
||||||
port = ntohs(((struct sockaddr_in *)destAddr)->sin_port);
|
port = ntohs(((struct sockaddr_in *)destAddr)->sin_port);
|
||||||
return;
|
return;
|
||||||
|
@ -1647,8 +1653,7 @@ void Socket::UDPConnection::SendNow(const char *sdata, size_t len){
|
||||||
/// \arg multicastInterfaces Comma-separated list of interfaces to listen on for multicast packets.
|
/// \arg multicastInterfaces Comma-separated list of interfaces to listen on for multicast packets.
|
||||||
/// Optional, left out means automatically chosen by kernel. \return Actually bound port number, or
|
/// Optional, left out means automatically chosen by kernel. \return Actually bound port number, or
|
||||||
/// zero on error.
|
/// zero on error.
|
||||||
uint16_t Socket::UDPConnection::bind(int port, std::string iface,
|
uint16_t Socket::UDPConnection::bind(int port, std::string iface, const std::string &multicastInterfaces){
|
||||||
const std::string &multicastInterfaces){
|
|
||||||
close(); // we open a new socket for each attempt
|
close(); // we open a new socket for each attempt
|
||||||
int addr_ret;
|
int addr_ret;
|
||||||
bool multicast = false;
|
bool multicast = false;
|
||||||
|
@ -1722,6 +1727,9 @@ uint16_t Socket::UDPConnection::bind(int port, std::string iface,
|
||||||
portNo = ntohs(((struct sockaddr_in *)&fin_addr)->sin_port);
|
portNo = ntohs(((struct sockaddr_in *)&fin_addr)->sin_port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
boundAddr = iface;
|
||||||
|
boundMulti = multicastInterfaces;
|
||||||
|
boundPort = portNo;
|
||||||
INFO_MSG("UDP bind success on %s:%u (%s)", human_addr, portNo, addrFam(rp->ai_family));
|
INFO_MSG("UDP bind success on %s:%u (%s)", human_addr, portNo, addrFam(rp->ai_family));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1769,8 +1777,7 @@ uint16_t Socket::UDPConnection::bind(int port, std::string iface,
|
||||||
}else{
|
}else{
|
||||||
size_t nxtPos = std::string::npos;
|
size_t nxtPos = std::string::npos;
|
||||||
bool atLeastOne = false;
|
bool atLeastOne = false;
|
||||||
for (size_t loc = 0; loc != std::string::npos;
|
for (size_t loc = 0; loc != std::string::npos; loc = (nxtPos == std::string::npos ? nxtPos : nxtPos + 1)){
|
||||||
loc = (nxtPos == std::string::npos ? nxtPos : nxtPos + 1)){
|
|
||||||
nxtPos = multicastInterfaces.find(',', loc);
|
nxtPos = multicastInterfaces.find(',', loc);
|
||||||
std::string curIface =
|
std::string curIface =
|
||||||
multicastInterfaces.substr(loc, (nxtPos == std::string::npos ? nxtPos : nxtPos - loc));
|
multicastInterfaces.substr(loc, (nxtPos == std::string::npos ? nxtPos : nxtPos - loc));
|
||||||
|
@ -1785,25 +1792,22 @@ uint16_t Socket::UDPConnection::bind(int port, std::string iface,
|
||||||
if (family == AF_INET6){
|
if (family == AF_INET6){
|
||||||
INFO_MSG("Registering for IPv6 multicast on interface %s", curIface.c_str());
|
INFO_MSG("Registering for IPv6 multicast on interface %s", curIface.c_str());
|
||||||
if ((addr_ret = getaddrinfo(curIface.c_str(), 0, &hints, &reslocal)) != 0){
|
if ((addr_ret = getaddrinfo(curIface.c_str(), 0, &hints, &reslocal)) != 0){
|
||||||
WARN_MSG("Unable to resolve IPv6 interface address %s: %s", curIface.c_str(),
|
WARN_MSG("Unable to resolve IPv6 interface address %s: %s", curIface.c_str(), gai_strerror(addr_ret));
|
||||||
gai_strerror(addr_ret));
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
memcpy(&mreq6.ipv6mr_multiaddr, &((sockaddr_in6 *)resmulti->ai_addr)->sin6_addr,
|
memcpy(&mreq6.ipv6mr_multiaddr, &((sockaddr_in6 *)resmulti->ai_addr)->sin6_addr,
|
||||||
sizeof(mreq6.ipv6mr_multiaddr));
|
sizeof(mreq6.ipv6mr_multiaddr));
|
||||||
mreq6.ipv6mr_interface = ((sockaddr_in6 *)reslocal->ai_addr)->sin6_scope_id;
|
mreq6.ipv6mr_interface = ((sockaddr_in6 *)reslocal->ai_addr)->sin6_scope_id;
|
||||||
if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *)&mreq6, sizeof(mreq6)) != 0){
|
if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *)&mreq6, sizeof(mreq6)) != 0){
|
||||||
FAIL_MSG("Unable to register for IPv6 multicast on interface %s (%u): %s",
|
FAIL_MSG("Unable to register for IPv6 multicast on interface %s (%u): %s", curIface.c_str(),
|
||||||
curIface.c_str(), ((sockaddr_in6 *)reslocal->ai_addr)->sin6_scope_id,
|
((sockaddr_in6 *)reslocal->ai_addr)->sin6_scope_id, strerror(errno));
|
||||||
strerror(errno));
|
|
||||||
}else{
|
}else{
|
||||||
atLeastOne = true;
|
atLeastOne = true;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
INFO_MSG("Registering for IPv4 multicast on interface %s", curIface.c_str());
|
INFO_MSG("Registering for IPv4 multicast on interface %s", curIface.c_str());
|
||||||
if ((addr_ret = getaddrinfo(curIface.c_str(), 0, &hints, &reslocal)) != 0){
|
if ((addr_ret = getaddrinfo(curIface.c_str(), 0, &hints, &reslocal)) != 0){
|
||||||
WARN_MSG("Unable to resolve IPv4 interface address %s: %s", curIface.c_str(),
|
WARN_MSG("Unable to resolve IPv4 interface address %s: %s", curIface.c_str(), gai_strerror(addr_ret));
|
||||||
gai_strerror(addr_ret));
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mreq4.imr_multiaddr = ((sockaddr_in *)resmulti->ai_addr)->sin_addr;
|
mreq4.imr_multiaddr = ((sockaddr_in *)resmulti->ai_addr)->sin_addr;
|
||||||
|
@ -1815,9 +1819,7 @@ uint16_t Socket::UDPConnection::bind(int port, std::string iface,
|
||||||
atLeastOne = true;
|
atLeastOne = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!atLeastOne){
|
if (!atLeastOne){close();}
|
||||||
close();
|
|
||||||
}
|
|
||||||
freeaddrinfo(reslocal); // free resolved interface addr
|
freeaddrinfo(reslocal); // free resolved interface addr
|
||||||
}// loop over all interfaces
|
}// loop over all interfaces
|
||||||
}
|
}
|
||||||
|
@ -1831,6 +1833,7 @@ uint16_t Socket::UDPConnection::bind(int port, std::string iface,
|
||||||
/// If a packet is received, it will be placed in the "data" member, with it's length in "data_len".
|
/// If a packet is received, it will be placed in the "data" member, with it's length in "data_len".
|
||||||
/// \return True if a packet was received, false otherwise.
|
/// \return True if a packet was received, false otherwise.
|
||||||
bool Socket::UDPConnection::Receive(){
|
bool Socket::UDPConnection::Receive(){
|
||||||
|
if (sock == -1){return false;}
|
||||||
#ifdef __CYGWIN__
|
#ifdef __CYGWIN__
|
||||||
if (data_size != SOCKETSIZE){
|
if (data_size != SOCKETSIZE){
|
||||||
data = (char *)realloc(data, SOCKETSIZE);
|
data = (char *)realloc(data, SOCKETSIZE);
|
||||||
|
@ -1867,4 +1870,3 @@ bool Socket::UDPConnection::Receive(){
|
||||||
int Socket::UDPConnection::getSock(){
|
int Socket::UDPConnection::getSock(){
|
||||||
return sock;
|
return sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
120
lib/socket.h
120
lib/socket.h
|
@ -17,12 +17,12 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#ifdef SSL
|
#ifdef SSL
|
||||||
#include "mbedtls/net.h"
|
|
||||||
#include "mbedtls/ssl.h"
|
|
||||||
#include "mbedtls/entropy.h"
|
|
||||||
#include "mbedtls/ctr_drbg.h"
|
#include "mbedtls/ctr_drbg.h"
|
||||||
#include "mbedtls/debug.h"
|
#include "mbedtls/debug.h"
|
||||||
|
#include "mbedtls/entropy.h"
|
||||||
#include "mbedtls/error.h"
|
#include "mbedtls/error.h"
|
||||||
|
#include "mbedtls/net.h"
|
||||||
|
#include "mbedtls/ssl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// for being friendly with Socket::Connection down below
|
// for being friendly with Socket::Connection down below
|
||||||
|
@ -38,9 +38,9 @@ namespace Socket{
|
||||||
bool matchIPv6Addr(const std::string &A, const std::string &B, uint8_t prefix);
|
bool matchIPv6Addr(const std::string &A, const std::string &B, uint8_t prefix);
|
||||||
std::string getBinForms(std::string addr);
|
std::string getBinForms(std::string addr);
|
||||||
/// Returns true if given human-readable address (address, not hostname) is a local address.
|
/// Returns true if given human-readable address (address, not hostname) is a local address.
|
||||||
bool isLocal(const std::string & host);
|
bool isLocal(const std::string &host);
|
||||||
/// Returns true if given human-readable hostname is a local address.
|
/// Returns true if given human-readable hostname is a local address.
|
||||||
bool isLocalhost(const std::string & host);
|
bool isLocalhost(const std::string &host);
|
||||||
bool checkTrueSocket(int sock);
|
bool checkTrueSocket(int sock);
|
||||||
|
|
||||||
/// A buffer made out of std::string objects that can be efficiently read from and written to.
|
/// A buffer made out of std::string objects that can be efficiently read from and written to.
|
||||||
|
@ -49,7 +49,7 @@ namespace Socket{
|
||||||
std::deque<std::string> data;
|
std::deque<std::string> data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::string splitter;///<String to automatically split on if encountered. \n by default
|
std::string splitter; ///< String to automatically split on if encountered. \n by default
|
||||||
Buffer();
|
Buffer();
|
||||||
unsigned int size();
|
unsigned int size();
|
||||||
unsigned int bytes(unsigned int max);
|
unsigned int bytes(unsigned int max);
|
||||||
|
@ -73,83 +73,83 @@ namespace Socket{
|
||||||
protected:
|
protected:
|
||||||
void clear(); ///< Clears the internal data structure. Meant only for use in constructors.
|
void clear(); ///< Clears the internal data structure. Meant only for use in constructors.
|
||||||
bool isTrueSocket;
|
bool isTrueSocket;
|
||||||
int sSend; ///< Write end of socket.
|
int sSend; ///< Write end of socket.
|
||||||
int sRecv; ///< Read end of socket.
|
int sRecv; ///< Read end of socket.
|
||||||
std::string remotehost; ///< Stores remote host address.
|
std::string remotehost; ///< Stores remote host address.
|
||||||
std::string boundaddr; ///< Stores bound interface address.
|
std::string boundaddr; ///< Stores bound interface address.
|
||||||
struct sockaddr_in6 remoteaddr;///< Stores remote host address.
|
struct sockaddr_in6 remoteaddr; ///< Stores remote host address.
|
||||||
uint64_t up;
|
uint64_t up;
|
||||||
uint64_t down;
|
uint64_t down;
|
||||||
long long int conntime;
|
long long int conntime;
|
||||||
Buffer downbuffer; ///< Stores temporary data coming in.
|
Buffer downbuffer; ///< Stores temporary data coming in.
|
||||||
int iread(void *buffer, int len, int flags = 0); ///< Incremental read call.
|
int iread(void *buffer, int len, int flags = 0); ///< Incremental read call.
|
||||||
unsigned int iwrite(const void *buffer, int len); ///< Incremental write call.
|
unsigned int iwrite(const void *buffer, int len); ///< Incremental write call.
|
||||||
bool iread(Buffer &buffer, int flags = 0); ///< Incremental write call that is compatible with Socket::Buffer.
|
bool iread(Buffer &buffer, int flags = 0); ///< Incremental write call that is compatible with Socket::Buffer.
|
||||||
bool iwrite(std::string &buffer); ///< Write call that is compatible with std::string.
|
bool iwrite(std::string &buffer); ///< Write call that is compatible with std::string.
|
||||||
void setBoundAddr();
|
void setBoundAddr();
|
||||||
#ifdef SSL
|
#ifdef SSL
|
||||||
/// optional extension that uses mbedtls for SSL
|
/// optional extension that uses mbedtls for SSL
|
||||||
protected:
|
protected:
|
||||||
bool sslConnected;
|
bool sslConnected;
|
||||||
int ssl_iread(void *buffer, int len, int flags = 0); ///< Incremental read call.
|
int ssl_iread(void *buffer, int len, int flags = 0); ///< Incremental read call.
|
||||||
unsigned int ssl_iwrite(const void *buffer, int len); ///< Incremental write call.
|
unsigned int ssl_iwrite(const void *buffer, int len); ///< Incremental write call.
|
||||||
mbedtls_net_context * server_fd;
|
mbedtls_net_context *server_fd;
|
||||||
mbedtls_entropy_context * entropy;
|
mbedtls_entropy_context *entropy;
|
||||||
mbedtls_ctr_drbg_context * ctr_drbg;
|
mbedtls_ctr_drbg_context *ctr_drbg;
|
||||||
mbedtls_ssl_context * ssl;
|
mbedtls_ssl_context *ssl;
|
||||||
mbedtls_ssl_config * conf;
|
mbedtls_ssl_config *conf;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// friends
|
// friends
|
||||||
friend class ::Buffer::user;
|
friend class ::Buffer::user;
|
||||||
// constructors
|
// constructors
|
||||||
Connection(); ///< Create a new disconnected base socket.
|
Connection(); ///< Create a new disconnected base socket.
|
||||||
Connection(int sockNo); ///< Create a new base socket.
|
Connection(int sockNo); ///< Create a new base socket.
|
||||||
Connection(std::string hostname, int port, bool nonblock, bool with_ssl = false); ///< Create a new TCP socket.
|
Connection(std::string hostname, int port, bool nonblock, bool with_ssl = false); ///< Create a new TCP socket.
|
||||||
Connection(std::string adres, bool nonblock = false); ///< Create a new Unix Socket.
|
Connection(std::string adres, bool nonblock = false); ///< Create a new Unix Socket.
|
||||||
Connection(int write, int read); ///< Simulate a socket using two file descriptors.
|
Connection(int write, int read); ///< Simulate a socket using two file descriptors.
|
||||||
// copy/assignment constructors
|
// copy/assignment constructors
|
||||||
Connection(const Connection& rhs);
|
Connection(const Connection &rhs);
|
||||||
Connection& operator=(const Connection& rhs);
|
Connection &operator=(const Connection &rhs);
|
||||||
// destructor
|
// destructor
|
||||||
~Connection();
|
~Connection();
|
||||||
// generic methods
|
// generic methods
|
||||||
void open(int sockNo);//Open from existing socket connection.
|
void open(int sockNo); // Open from existing socket connection.
|
||||||
void open(std::string hostname, int port, bool nonblock, bool with_ssl = false);//Open TCP connection.
|
void open(std::string hostname, int port, bool nonblock, bool with_ssl = false); // Open TCP connection.
|
||||||
void open(std::string adres, bool nonblock = false);//Open Unix connection.
|
void open(std::string adres, bool nonblock = false); // Open Unix connection.
|
||||||
void open(int write, int read);//Open from two existing file descriptors.
|
void open(int write, int read); // Open from two existing file descriptors.
|
||||||
void close(); ///< Close connection.
|
void close(); ///< Close connection.
|
||||||
void drop(); ///< Close connection without shutdown.
|
void drop(); ///< Close connection without shutdown.
|
||||||
void setBlocking(bool blocking); ///< Set this socket to be blocking (true) or nonblocking (false).
|
void setBlocking(bool blocking); ///< Set this socket to be blocking (true) or nonblocking (false).
|
||||||
bool isBlocking(); ///< Check if this socket is blocking (true) or nonblocking (false).
|
bool isBlocking(); ///< Check if this socket is blocking (true) or nonblocking (false).
|
||||||
std::string getHost() const; ///< Gets hostname for connection, if available.
|
std::string getHost() const; ///< Gets hostname for connection, if available.
|
||||||
std::string getBinHost();
|
std::string getBinHost();
|
||||||
void setHost(std::string host); ///< Sets hostname for connection manually.
|
void setHost(std::string host); ///< Sets hostname for connection manually.
|
||||||
std::string getBoundAddress() const;
|
std::string getBoundAddress() const;
|
||||||
int getSocket(); ///< Returns internal socket number.
|
int getSocket(); ///< Returns internal socket number.
|
||||||
int getPureSocket(); ///< Returns non-piped internal socket number.
|
int getPureSocket(); ///< Returns non-piped internal socket number.
|
||||||
std::string getError(); ///< Returns a string describing the last error that occured.
|
std::string getError(); ///< Returns a string describing the last error that occured.
|
||||||
bool connected() const; ///< Returns the connected-state for this socket.
|
bool connected() const; ///< Returns the connected-state for this socket.
|
||||||
bool isAddress(const std::string &addr);
|
bool isAddress(const std::string &addr);
|
||||||
bool isLocal(); ///< Returns true if remote address is a local address.
|
bool isLocal(); ///< Returns true if remote address is a local address.
|
||||||
// buffered i/o methods
|
// buffered i/o methods
|
||||||
bool spool(); ///< Updates the downbufferinternal variables.
|
bool spool(); ///< Updates the downbufferinternal variables.
|
||||||
bool peek(); ///< Clears the downbuffer and fills it with peek
|
bool peek(); ///< Clears the downbuffer and fills it with peek
|
||||||
Buffer &Received(); ///< Returns a reference to the download buffer.
|
Buffer &Received(); ///< Returns a reference to the download buffer.
|
||||||
void SendNow(const std::string &data); ///< Will not buffer anything but always send right away. Blocks.
|
void SendNow(const std::string &data); ///< Will not buffer anything but always send right away. Blocks.
|
||||||
void SendNow(const char *data); ///< Will not buffer anything but always send right away. Blocks.
|
void SendNow(const char *data); ///< Will not buffer anything but always send right away. Blocks.
|
||||||
void SendNow(const char *data, size_t len); ///< Will not buffer anything but always send right away. Blocks.
|
void SendNow(const char *data,
|
||||||
|
size_t len); ///< Will not buffer anything but always send right away. Blocks.
|
||||||
void skipBytes(uint32_t byteCount);
|
void skipBytes(uint32_t byteCount);
|
||||||
uint32_t skipCount;
|
uint32_t skipCount;
|
||||||
// stats related methods
|
// stats related methods
|
||||||
unsigned int connTime(); ///< Returns the time this socket has been connected.
|
unsigned int connTime(); ///< Returns the time this socket has been connected.
|
||||||
uint64_t dataUp(); ///< Returns total amount of bytes sent.
|
uint64_t dataUp(); ///< Returns total amount of bytes sent.
|
||||||
uint64_t dataDown(); ///< Returns total amount of bytes received.
|
uint64_t dataDown(); ///< Returns total amount of bytes received.
|
||||||
void resetCounter(); ///< Resets the up/down bytes counter to zero.
|
void resetCounter(); ///< Resets the up/down bytes counter to zero.
|
||||||
void addUp(const uint32_t i);
|
void addUp(const uint32_t i);
|
||||||
void addDown(const uint32_t i);
|
void addDown(const uint32_t i);
|
||||||
std::string getStats(std::string C); ///< Returns a std::string of stats, ended by a newline.
|
|
||||||
friend class Server;
|
friend class Server;
|
||||||
bool Error; ///< Set to true if a socket error happened.
|
bool Error; ///< Set to true if a socket error happened.
|
||||||
bool Blocking; ///< Set to true if a socket is currently or wants to be blocking.
|
bool Blocking; ///< Set to true if a socket is currently or wants to be blocking.
|
||||||
|
@ -162,18 +162,18 @@ namespace Socket{
|
||||||
/// This class is for easily setting up listening socket, either TCP or Unix.
|
/// This class is for easily setting up listening socket, either TCP or Unix.
|
||||||
class Server{
|
class Server{
|
||||||
private:
|
private:
|
||||||
std::string errors; ///< Stores errors that may have occured.
|
std::string errors; ///< Stores errors that may have occured.
|
||||||
int sock; ///< Internally saved socket number.
|
int sock; ///< Internally saved socket number.
|
||||||
bool IPv6bind(int port, std::string hostname, bool nonblock); ///< Attempt to bind an IPv6 socket
|
bool IPv6bind(int port, std::string hostname, bool nonblock); ///< Attempt to bind an IPv6 socket
|
||||||
bool IPv4bind(int port, std::string hostname, bool nonblock); ///< Attempt to bind an IPv4 socket
|
bool IPv4bind(int port, std::string hostname, bool nonblock); ///< Attempt to bind an IPv4 socket
|
||||||
public:
|
public:
|
||||||
Server(); ///< Create a new base Server.
|
Server(); ///< Create a new base Server.
|
||||||
Server(int existingSock); ///< Create a new Server from existing socket.
|
Server(int existingSock); ///< Create a new Server from existing socket.
|
||||||
Server(int port, std::string hostname, bool nonblock = false); ///< Create a new TCP Server.
|
Server(int port, std::string hostname, bool nonblock = false); ///< Create a new TCP Server.
|
||||||
Server(std::string adres, bool nonblock = false); ///< Create a new Unix Server.
|
Server(std::string adres, bool nonblock = false); ///< Create a new Unix Server.
|
||||||
Connection accept(bool nonblock = false); ///< Accept any waiting connections.
|
Connection accept(bool nonblock = false); ///< Accept any waiting connections.
|
||||||
void setBlocking(bool blocking); ///< Set this socket to be blocking (true) or nonblocking (false).
|
void setBlocking(bool blocking); ///< Set this socket to be blocking (true) or nonblocking (false).
|
||||||
bool connected() const; ///< Returns the connected-state for this socket.
|
bool connected() const; ///< Returns the connected-state for this socket.
|
||||||
bool isBlocking(); ///< Check if this socket is blocking (true) or nonblocking (false).
|
bool isBlocking(); ///< Check if this socket is blocking (true) or nonblocking (false).
|
||||||
void close(); ///< Close connection.
|
void close(); ///< Close connection.
|
||||||
void drop(); ///< Close connection without shutdown.
|
void drop(); ///< Close connection without shutdown.
|
||||||
|
@ -189,7 +189,10 @@ namespace Socket{
|
||||||
unsigned int up; ///< Amount of bytes transferred up.
|
unsigned int up; ///< Amount of bytes transferred up.
|
||||||
unsigned int down; ///< Amount of bytes transferred down.
|
unsigned int down; ///< Amount of bytes transferred down.
|
||||||
unsigned int data_size; ///< The size in bytes of the allocated space in the data pointer.
|
unsigned int data_size; ///< The size in bytes of the allocated space in the data pointer.
|
||||||
int family; ///<Current socket address family
|
int family; ///< Current socket address family
|
||||||
|
std::string boundAddr, boundMulti;
|
||||||
|
int boundPort;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
char *data; ///< Holds the last received packet.
|
char *data; ///< Holds the last received packet.
|
||||||
unsigned int data_len; ///< The size in bytes of the last received packet.
|
unsigned int data_len; ///< The size in bytes of the last received packet.
|
||||||
|
@ -208,5 +211,4 @@ namespace Socket{
|
||||||
void SendNow(const char *data);
|
void SendNow(const char *data);
|
||||||
void SendNow(const char *data, size_t len);
|
void SendNow(const char *data, size_t len);
|
||||||
};
|
};
|
||||||
}
|
}// namespace Socket
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue