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
		Add a link
		
	
		Reference in a new issue