Merge branch 'development' into LTS_development
# Conflicts: # lib/socket.cpp # lib/socket.h
This commit is contained in:
		
						commit
						fdb5fbad45
					
				
					 3 changed files with 539 additions and 619 deletions
				
			
		
							
								
								
									
										298
									
								
								lib/socket.cpp
									
										
									
									
									
								
							
							
						
						
									
										298
									
								
								lib/socket.cpp
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -3,15 +3,15 @@
 | 
			
		|||
/// Written by Jaron Vietor in 2010 for DDVTech
 | 
			
		||||
 | 
			
		||||
#include "socket.h"
 | 
			
		||||
#include "timing.h"
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include "timing.h"
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <poll.h>
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
 | 
			
		||||
#define BUFFER_BLOCKSIZE 4096 // set buffer blocksize to 4KiB
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -21,6 +21,32 @@
 | 
			
		|||
#define SOCKETSIZE 51200ul
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// Checks bytes (length len) containing a binary-encoded IPv4 or IPv6 IP address, and writes it in human-readable notation to target.
 | 
			
		||||
/// Writes "unknown" if it cannot decode to a sensible value.
 | 
			
		||||
void Socket::hostBytesToStr(const char *bytes, size_t len, std::string &target){
 | 
			
		||||
  switch (len){
 | 
			
		||||
  case 4:
 | 
			
		||||
    char tmpstr[16];
 | 
			
		||||
    snprintf(tmpstr, 16, "%hhu.%hhu.%hhu.%hhu", bytes[0], bytes[1], bytes[2], bytes[3]);
 | 
			
		||||
    target = tmpstr;
 | 
			
		||||
    break;
 | 
			
		||||
  case 16:
 | 
			
		||||
    if (memcmp(bytes, "\000\000\000\000\000\000\000\000\000\000\377\377", 12) == 0){
 | 
			
		||||
      char tmpstr[16];
 | 
			
		||||
      snprintf(tmpstr, 16, "%hhu.%hhu.%hhu.%hhu", bytes[12], bytes[13], bytes[14], bytes[15]);
 | 
			
		||||
      target = tmpstr;
 | 
			
		||||
    }else{
 | 
			
		||||
      char tmpstr[40];
 | 
			
		||||
      snprintf(tmpstr, 40, "%0.2x%0.2x:%0.2x%0.2x:%0.2x%0.2x:%0.2x%0.2x:%0.2x%0.2x:%0.2x%0.2x:%0.2x%0.2x:%0.2x%0.2x", bytes[0], bytes[1],
 | 
			
		||||
               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[14], bytes[15]);
 | 
			
		||||
      target = tmpstr;
 | 
			
		||||
    }
 | 
			
		||||
    break;
 | 
			
		||||
  default: target = "unknown"; break;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string uint2string(unsigned int i){
 | 
			
		||||
  std::stringstream st;
 | 
			
		||||
  st << i;
 | 
			
		||||
| 
						 | 
				
			
			@ -31,9 +57,7 @@ std::string uint2string(unsigned int i) {
 | 
			
		|||
/// The back is popped as long as it is empty, first - this way this function is
 | 
			
		||||
/// guaranteed to return 0 if the buffer is empty.
 | 
			
		||||
unsigned int Socket::Buffer::size(){
 | 
			
		||||
  while (data.size() > 0 && data.back().empty()) {
 | 
			
		||||
    data.pop_back();
 | 
			
		||||
  }
 | 
			
		||||
  while (data.size() > 0 && data.back().empty()){data.pop_back();}
 | 
			
		||||
  return data.size();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -42,9 +66,7 @@ unsigned int Socket::Buffer::bytes(unsigned int max) {
 | 
			
		|||
  unsigned int i = 0;
 | 
			
		||||
  for (std::deque<std::string>::iterator it = data.begin(); it != data.end(); ++it){
 | 
			
		||||
    i += (*it).size();
 | 
			
		||||
    if (i >= max) {
 | 
			
		||||
      return max;
 | 
			
		||||
    }
 | 
			
		||||
    if (i >= max){return max;}
 | 
			
		||||
  }
 | 
			
		||||
  return i;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -63,12 +85,9 @@ void Socket::Buffer::append(const char * newdata, const unsigned int newdatasize
 | 
			
		|||
    j = i;
 | 
			
		||||
    while (j < newdatasize && j - i <= BUFFER_BLOCKSIZE){
 | 
			
		||||
      j++;
 | 
			
		||||
      if (newdata[j - 1] == '\n') {
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      if (newdata[j - 1] == '\n'){break;}
 | 
			
		||||
    }
 | 
			
		||||
    if (i != j){
 | 
			
		||||
      DONTEVEN_MSG("Adding a block of size %d", j - i);
 | 
			
		||||
      data.push_front(std::string(newdata + i, (size_t)(j - i)));
 | 
			
		||||
      i = j;
 | 
			
		||||
    }else{
 | 
			
		||||
| 
						 | 
				
			
			@ -76,7 +95,8 @@ void Socket::Buffer::append(const char * newdata, const unsigned int newdatasize
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if (data.size() > 5000){
 | 
			
		||||
    DEBUG_MSG(DLVL_WARN, "Warning: After %d new bytes, buffer has %d parts containing over %u bytes!", newdatasize, (int)data.size(), bytes(9000));
 | 
			
		||||
    DEBUG_MSG(DLVL_WARN, "Warning: After %d new bytes, buffer has %d parts containing over %u bytes!", newdatasize, (int)data.size(),
 | 
			
		||||
              bytes(9000));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -98,9 +118,7 @@ bool Socket::Buffer::available(unsigned int count) {
 | 
			
		|||
  unsigned int i = 0;
 | 
			
		||||
  for (std::deque<std::string>::iterator it = data.begin(); it != data.end(); ++it){
 | 
			
		||||
    i += (*it).size();
 | 
			
		||||
    if (i >= count) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
    if (i >= count){return true;}
 | 
			
		||||
  }
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -109,9 +127,7 @@ bool Socket::Buffer::available(unsigned int count) {
 | 
			
		|||
/// Returns an empty string if not all count bytes are available.
 | 
			
		||||
std::string Socket::Buffer::remove(unsigned int count){
 | 
			
		||||
  size();
 | 
			
		||||
  if (!available(count)) {
 | 
			
		||||
    return "";
 | 
			
		||||
  }
 | 
			
		||||
  if (!available(count)){return "";}
 | 
			
		||||
  unsigned int i = 0;
 | 
			
		||||
  std::string ret;
 | 
			
		||||
  ret.reserve(count);
 | 
			
		||||
| 
						 | 
				
			
			@ -133,9 +149,7 @@ std::string Socket::Buffer::remove(unsigned int count) {
 | 
			
		|||
/// Returns an empty string if not all count bytes are available.
 | 
			
		||||
std::string Socket::Buffer::copy(unsigned int count){
 | 
			
		||||
  size();
 | 
			
		||||
  if (!available(count)) {
 | 
			
		||||
    return "";
 | 
			
		||||
  }
 | 
			
		||||
  if (!available(count)){return "";}
 | 
			
		||||
  unsigned int i = 0;
 | 
			
		||||
  std::string ret;
 | 
			
		||||
  ret.reserve(count);
 | 
			
		||||
| 
						 | 
				
			
			@ -207,7 +221,6 @@ Socket::Connection::Connection() {
 | 
			
		|||
  Blocking = false;
 | 
			
		||||
}// Socket::Connection basic constructor
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void Socket::Connection::resetCounter(){
 | 
			
		||||
  up = 0;
 | 
			
		||||
  down = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -232,28 +245,16 @@ bool isFDBlocking(int FD) {
 | 
			
		|||
 | 
			
		||||
/// Set this socket to be blocking (true) or nonblocking (false).
 | 
			
		||||
void Socket::Connection::setBlocking(bool blocking){
 | 
			
		||||
  if (sock >= 0) {
 | 
			
		||||
    setFDBlocking(sock, blocking);
 | 
			
		||||
  }
 | 
			
		||||
  if (pipes[0] >= 0) {
 | 
			
		||||
    setFDBlocking(pipes[0], blocking);
 | 
			
		||||
  }
 | 
			
		||||
  if (pipes[1] >= 0) {
 | 
			
		||||
    setFDBlocking(pipes[1], blocking);
 | 
			
		||||
  }
 | 
			
		||||
  if (sock >= 0){setFDBlocking(sock, blocking);}
 | 
			
		||||
  if (pipes[0] >= 0){setFDBlocking(pipes[0], blocking);}
 | 
			
		||||
  if (pipes[1] >= 0){setFDBlocking(pipes[1], blocking);}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Set this socket to be blocking (true) or nonblocking (false).
 | 
			
		||||
bool Socket::Connection::isBlocking(){
 | 
			
		||||
  if (sock >= 0) {
 | 
			
		||||
    return isFDBlocking(sock);
 | 
			
		||||
  }
 | 
			
		||||
  if (pipes[0] >= 0) {
 | 
			
		||||
    return isFDBlocking(pipes[0]);
 | 
			
		||||
  }
 | 
			
		||||
  if (pipes[1] >= 0) {
 | 
			
		||||
    return isFDBlocking(pipes[1]);
 | 
			
		||||
  }
 | 
			
		||||
  if (sock >= 0){return isFDBlocking(sock);}
 | 
			
		||||
  if (pipes[0] >= 0){return isFDBlocking(pipes[0]);}
 | 
			
		||||
  if (pipes[1] >= 0){return isFDBlocking(pipes[1]);}
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -262,9 +263,7 @@ bool Socket::Connection::isBlocking() {
 | 
			
		|||
/// This function calls shutdown, thus making the socket unusable in all other
 | 
			
		||||
/// processes as well. Do not use on shared sockets that are still in use.
 | 
			
		||||
void Socket::Connection::close(){
 | 
			
		||||
  if (sock != -1) {
 | 
			
		||||
    shutdown(sock, SHUT_RDWR);
 | 
			
		||||
  }
 | 
			
		||||
  if (sock != -1){shutdown(sock, SHUT_RDWR);}
 | 
			
		||||
  drop();
 | 
			
		||||
}// Socket::Connection::close
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -277,20 +276,17 @@ void Socket::Connection::drop() {
 | 
			
		|||
    if (sock != -1){
 | 
			
		||||
      DEBUG_MSG(DLVL_HIGH, "Socket %d closed", sock);
 | 
			
		||||
      errno = EINTR;
 | 
			
		||||
      while (::close(sock) != 0 && errno == EINTR) {
 | 
			
		||||
      }
 | 
			
		||||
      while (::close(sock) != 0 && errno == EINTR){}
 | 
			
		||||
      sock = -1;
 | 
			
		||||
    }
 | 
			
		||||
    if (pipes[0] != -1){
 | 
			
		||||
      errno = EINTR;
 | 
			
		||||
      while (::close(pipes[0]) != 0 && errno == EINTR) {
 | 
			
		||||
      }
 | 
			
		||||
      while (::close(pipes[0]) != 0 && errno == EINTR){}
 | 
			
		||||
      pipes[0] = -1;
 | 
			
		||||
    }
 | 
			
		||||
    if (pipes[1] != -1){
 | 
			
		||||
      errno = EINTR;
 | 
			
		||||
      while (::close(pipes[1]) != 0 && errno == EINTR) {
 | 
			
		||||
      }
 | 
			
		||||
      while (::close(pipes[1]) != 0 && errno == EINTR){}
 | 
			
		||||
      pipes[1] = -1;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -298,15 +294,9 @@ void Socket::Connection::drop() {
 | 
			
		|||
 | 
			
		||||
/// Returns internal socket number.
 | 
			
		||||
int Socket::Connection::getSocket(){
 | 
			
		||||
  if (sock != -1) {
 | 
			
		||||
    return sock;
 | 
			
		||||
  }
 | 
			
		||||
  if (pipes[0] != -1) {
 | 
			
		||||
    return pipes[0];
 | 
			
		||||
  }
 | 
			
		||||
  if (pipes[1] != -1) {
 | 
			
		||||
    return pipes[1];
 | 
			
		||||
  }
 | 
			
		||||
  if (sock != -1){return sock;}
 | 
			
		||||
  if (pipes[0] != -1){return pipes[0];}
 | 
			
		||||
  if (pipes[1] != -1){return pipes[1];}
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -385,12 +375,8 @@ Socket::Connection::Connection(std::string host, int port, bool nonblock) {
 | 
			
		|||
  remotehost = "";
 | 
			
		||||
  for (rp = result; rp != NULL; rp = rp->ai_next){
 | 
			
		||||
    sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
 | 
			
		||||
    if (sock < 0) {
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
    if (connect(sock, rp->ai_addr, rp->ai_addrlen) == 0) {
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    if (sock < 0){continue;}
 | 
			
		||||
    if (connect(sock, rp->ai_addr, rp->ai_addrlen) == 0){break;}
 | 
			
		||||
    remotehost += strerror(errno);
 | 
			
		||||
    ::close(sock);
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -464,16 +450,10 @@ Socket::Buffer & Socket::Connection::Received() {
 | 
			
		|||
/// Any data that could not be send will block until it can be send or the connection is severed.
 | 
			
		||||
void Socket::Connection::SendNow(const char *data, size_t len){
 | 
			
		||||
  bool bing = isBlocking();
 | 
			
		||||
  if (!bing) {
 | 
			
		||||
    setBlocking(true);
 | 
			
		||||
  }
 | 
			
		||||
  if (!bing){setBlocking(true);}
 | 
			
		||||
  unsigned int i = iwrite(data, std::min((long unsigned int)len, SOCKETSIZE));
 | 
			
		||||
  while (i < len && connected()) {
 | 
			
		||||
    i += iwrite(data + i, std::min((long unsigned int)(len - i), SOCKETSIZE));
 | 
			
		||||
  }
 | 
			
		||||
  if (!bing) {
 | 
			
		||||
    setBlocking(false);
 | 
			
		||||
  }
 | 
			
		||||
  while (i < len && connected()){i += iwrite(data + i, std::min((long unsigned int)(len - i), SOCKETSIZE));}
 | 
			
		||||
  if (!bing){setBlocking(false);}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Will not buffer anything but always send right away. Blocks.
 | 
			
		||||
| 
						 | 
				
			
			@ -495,9 +475,7 @@ void Socket::Connection::SendNow(const std::string & data) {
 | 
			
		|||
/// \param len Amount of bytes to write.
 | 
			
		||||
/// \returns The amount of bytes actually written.
 | 
			
		||||
unsigned int Socket::Connection::iwrite(const void *buffer, int len){
 | 
			
		||||
  if (!connected() || len < 1) {
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  if (!connected() || len < 1){return 0;}
 | 
			
		||||
  int r;
 | 
			
		||||
  if (sock >= 0){
 | 
			
		||||
    r = send(sock, buffer, len, 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -506,9 +484,7 @@ unsigned int Socket::Connection::iwrite(const void * buffer, int len) {
 | 
			
		|||
  }
 | 
			
		||||
  if (r < 0){
 | 
			
		||||
    switch (errno){
 | 
			
		||||
      case EWOULDBLOCK:
 | 
			
		||||
        return 0;
 | 
			
		||||
        break;
 | 
			
		||||
    case EWOULDBLOCK: return 0; break;
 | 
			
		||||
    default:
 | 
			
		||||
      Error = true;
 | 
			
		||||
      INSANE_MSG("Could not iwrite data! Error: %s", strerror(errno));
 | 
			
		||||
| 
						 | 
				
			
			@ -532,26 +508,18 @@ unsigned int Socket::Connection::iwrite(const void * buffer, int len) {
 | 
			
		|||
/// \param flags Flags to use in the recv call. Ignored on fake sockets.
 | 
			
		||||
/// \returns The amount of bytes actually read.
 | 
			
		||||
int Socket::Connection::iread(void *buffer, int len, int flags){
 | 
			
		||||
  if (!connected() || len < 1) {
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  if (!connected() || len < 1){return 0;}
 | 
			
		||||
  int r;
 | 
			
		||||
  if (sock >= 0){
 | 
			
		||||
    r = recv(sock, buffer, len, flags);
 | 
			
		||||
  }else{
 | 
			
		||||
    r = recv(pipes[1], buffer, len, flags);
 | 
			
		||||
    if (r < 0 && errno == ENOTSOCK) {
 | 
			
		||||
      r = read(pipes[1], buffer, len);
 | 
			
		||||
    }
 | 
			
		||||
    if (r < 0 && errno == ENOTSOCK){r = read(pipes[1], buffer, len);}
 | 
			
		||||
  }
 | 
			
		||||
  if (r < 0){
 | 
			
		||||
    switch (errno){
 | 
			
		||||
      case EWOULDBLOCK:
 | 
			
		||||
        return 0;
 | 
			
		||||
        break;
 | 
			
		||||
      case EINTR:
 | 
			
		||||
        return 0;
 | 
			
		||||
        break;
 | 
			
		||||
    case EWOULDBLOCK: return 0; break;
 | 
			
		||||
    case EINTR: return 0; break;
 | 
			
		||||
    default:
 | 
			
		||||
      Error = true;
 | 
			
		||||
      INSANE_MSG("Could not iread data! Error: %s", strerror(errno));
 | 
			
		||||
| 
						 | 
				
			
			@ -577,9 +545,7 @@ int Socket::Connection::iread(void * buffer, int len, int flags) {
 | 
			
		|||
bool Socket::Connection::iread(Buffer &buffer, int flags){
 | 
			
		||||
  char cbuffer[BUFFER_BLOCKSIZE];
 | 
			
		||||
  int num = iread(cbuffer, BUFFER_BLOCKSIZE, flags);
 | 
			
		||||
  if (num < 1) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
  if (num < 1){return false;}
 | 
			
		||||
  buffer.append(cbuffer, num);
 | 
			
		||||
  return true;
 | 
			
		||||
}// iread
 | 
			
		||||
| 
						 | 
				
			
			@ -590,13 +556,9 @@ bool Socket::Connection::iread(Buffer & buffer, int flags) {
 | 
			
		|||
/// \param buffer std::string to remove data from.
 | 
			
		||||
/// \return True if more data was sent, false otherwise.
 | 
			
		||||
bool Socket::Connection::iwrite(std::string &buffer){
 | 
			
		||||
  if (buffer.size() < 1) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
  if (buffer.size() < 1){return false;}
 | 
			
		||||
  unsigned int tmp = iwrite((void *)buffer.c_str(), buffer.size());
 | 
			
		||||
  if (!tmp) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
  if (!tmp){return false;}
 | 
			
		||||
  buffer = buffer.substr(tmp);
 | 
			
		||||
  return true;
 | 
			
		||||
}// iwrite
 | 
			
		||||
| 
						 | 
				
			
			@ -626,12 +588,8 @@ std::string Socket::Connection::getBinHost() {
 | 
			
		|||
    }
 | 
			
		||||
    char tmpBuffer[17] = "\000\000\000\000\000\000\000\000\000\000\377\377\000\000\000\000";
 | 
			
		||||
    for (rp = result; rp != NULL; rp = rp->ai_next){
 | 
			
		||||
      if (rp->ai_family == AF_INET) {
 | 
			
		||||
        memcpy(tmpBuffer + 12, &((sockaddr_in *)rp->ai_addr)->sin_addr.s_addr, 4);
 | 
			
		||||
      }
 | 
			
		||||
      if (rp->ai_family == AF_INET6) {
 | 
			
		||||
        memcpy(tmpBuffer, ((sockaddr_in6 *)rp->ai_addr)->sin6_addr.s6_addr, 16);
 | 
			
		||||
      }
 | 
			
		||||
      if (rp->ai_family == AF_INET){memcpy(tmpBuffer + 12, &((sockaddr_in *)rp->ai_addr)->sin_addr.s_addr, 4);}
 | 
			
		||||
      if (rp->ai_family == AF_INET6){memcpy(tmpBuffer, ((sockaddr_in6 *)rp->ai_addr)->sin6_addr.s6_addr, 16);}
 | 
			
		||||
    }
 | 
			
		||||
    freeaddrinfo(result);
 | 
			
		||||
    return std::string(tmpBuffer, 16);
 | 
			
		||||
| 
						 | 
				
			
			@ -677,28 +635,20 @@ bool Socket::Connection::isAddress(std::string addr) {
 | 
			
		|||
  hints.ai_addr = NULL;
 | 
			
		||||
  hints.ai_next = NULL;
 | 
			
		||||
  int s = getaddrinfo(addr.c_str(), 0, &hints, &result);
 | 
			
		||||
  if (s != 0) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
  if (s != 0){return false;}
 | 
			
		||||
 | 
			
		||||
  char newaddr[INET_ADDRSTRLEN];
 | 
			
		||||
  newaddr[0] = 0;
 | 
			
		||||
  for (rp = result; rp != NULL; rp = rp->ai_next){
 | 
			
		||||
    if (rp->ai_family == AF_INET && inet_ntop(rp->ai_family, &(((sockaddr_in *)rp->ai_addr)->sin_addr), newaddr, INET_ADDRSTRLEN)){
 | 
			
		||||
      DEBUG_MSG(DLVL_DEVEL, "Comparing: '%s'  to '%s'", remotehost.c_str(), newaddr);
 | 
			
		||||
      if (remotehost == newaddr) {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      if (remotehost == newaddr){return true;}
 | 
			
		||||
      DEBUG_MSG(DLVL_DEVEL, "Comparing: '%s'  to '::ffff:%s'", remotehost.c_str(), newaddr);
 | 
			
		||||
      if (remotehost == std::string("::ffff:") + newaddr) {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      if (remotehost == std::string("::ffff:") + newaddr){return true;}
 | 
			
		||||
    }
 | 
			
		||||
    if (rp->ai_family == AF_INET6 && inet_ntop(rp->ai_family, &(((sockaddr_in6 *)rp->ai_addr)->sin6_addr), newaddr, INET_ADDRSTRLEN)){
 | 
			
		||||
      DEBUG_MSG(DLVL_DEVEL, "Comparing: '%s'  to '%s'", remotehost.c_str(), newaddr);
 | 
			
		||||
      if (remotehost == newaddr) {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      if (remotehost == newaddr){return true;}
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  freeaddrinfo(result);
 | 
			
		||||
| 
						 | 
				
			
			@ -826,7 +776,8 @@ bool Socket::Server::IPv4bind(int port, std::string hostname, bool nonblock) {
 | 
			
		|||
/// Create a new Unix Server. The socket is immediately bound and set to listen.
 | 
			
		||||
/// A maximum of 100 connections will be accepted between accept() calls.
 | 
			
		||||
/// Any further connections coming in will be dropped.
 | 
			
		||||
/// The address used will first be unlinked - so it succeeds if the Unix socket already existed. Watch out for this behaviour - it will delete any file located at address!
 | 
			
		||||
/// The address used will first be unlinked - so it succeeds if the Unix socket already existed. Watch out for this behaviour - it will delete
 | 
			
		||||
/// any file located at address!
 | 
			
		||||
/// \param address The location of the Unix socket to bind to.
 | 
			
		||||
/// \param nonblock (optional) Whether accept() calls will be nonblocking. Default is false (blocking).
 | 
			
		||||
Socket::Server::Server(std::string address, bool nonblock){
 | 
			
		||||
| 
						 | 
				
			
			@ -869,9 +820,7 @@ Socket::Server::Server(std::string address, bool nonblock) {
 | 
			
		|||
/// \param nonblock (optional) Whether the newly connected socket should be nonblocking. Default is false (blocking).
 | 
			
		||||
/// \returns A Socket::Connection, which may or may not be connected, depending on settings and circumstances.
 | 
			
		||||
Socket::Connection Socket::Server::accept(bool nonblock){
 | 
			
		||||
  if (sock < 0) {
 | 
			
		||||
    return Socket::Connection(-1);
 | 
			
		||||
  }
 | 
			
		||||
  if (sock < 0){return Socket::Connection(-1);}
 | 
			
		||||
  struct sockaddr_in6 addrinfo;
 | 
			
		||||
  socklen_t len = sizeof(addrinfo);
 | 
			
		||||
  static char addrconv[INET6_ADDRSTRLEN];
 | 
			
		||||
| 
						 | 
				
			
			@ -908,16 +857,12 @@ Socket::Connection Socket::Server::accept(bool nonblock) {
 | 
			
		|||
 | 
			
		||||
/// Set this socket to be blocking (true) or nonblocking (false).
 | 
			
		||||
void Socket::Server::setBlocking(bool blocking){
 | 
			
		||||
  if (sock >= 0) {
 | 
			
		||||
    setFDBlocking(sock, blocking);
 | 
			
		||||
  }
 | 
			
		||||
  if (sock >= 0){setFDBlocking(sock, blocking);}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Set this socket to be blocking (true) or nonblocking (false).
 | 
			
		||||
bool Socket::Server::isBlocking(){
 | 
			
		||||
  if (sock >= 0) {
 | 
			
		||||
    return isFDBlocking(sock);
 | 
			
		||||
  }
 | 
			
		||||
  if (sock >= 0){return isFDBlocking(sock);}
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -926,9 +871,7 @@ bool Socket::Server::isBlocking() {
 | 
			
		|||
/// This function calls shutdown, thus making the socket unusable in all other
 | 
			
		||||
/// processes as well. Do not use on shared sockets that are still in use.
 | 
			
		||||
void Socket::Server::close(){
 | 
			
		||||
  if (sock != -1) {
 | 
			
		||||
    shutdown(sock, SHUT_RDWR);
 | 
			
		||||
  }
 | 
			
		||||
  if (sock != -1){shutdown(sock, SHUT_RDWR);}
 | 
			
		||||
  drop();
 | 
			
		||||
}// Socket::Server::close
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -941,8 +884,7 @@ void Socket::Server::drop() {
 | 
			
		|||
    if (sock != -1){
 | 
			
		||||
      DEBUG_MSG(DLVL_HIGH, "ServerSocket %d closed", sock);
 | 
			
		||||
      errno = EINTR;
 | 
			
		||||
      while (::close(sock) != 0 && errno == EINTR) {
 | 
			
		||||
      }
 | 
			
		||||
      while (::close(sock) != 0 && errno == EINTR){}
 | 
			
		||||
      sock = -1;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -973,9 +915,7 @@ Socket::UDPConnection::UDPConnection(bool nonblock) {
 | 
			
		|||
    sock = socket(AF_INET, SOCK_DGRAM, 0);
 | 
			
		||||
    family = AF_INET;
 | 
			
		||||
  }
 | 
			
		||||
  if (sock == -1) {
 | 
			
		||||
    DEBUG_MSG(DLVL_FAIL, "Could not create UDP socket: %s", strerror(errno));
 | 
			
		||||
  }
 | 
			
		||||
  if (sock == -1){DEBUG_MSG(DLVL_FAIL, "Could not create UDP socket: %s", strerror(errno));}
 | 
			
		||||
  up = 0;
 | 
			
		||||
  down = 0;
 | 
			
		||||
  destAddr = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -983,9 +923,7 @@ Socket::UDPConnection::UDPConnection(bool nonblock) {
 | 
			
		|||
  data = 0;
 | 
			
		||||
  data_size = 0;
 | 
			
		||||
  data_len = 0;
 | 
			
		||||
  if (nonblock) {
 | 
			
		||||
    setBlocking(!nonblock);
 | 
			
		||||
  }
 | 
			
		||||
  if (nonblock){setBlocking(!nonblock);}
 | 
			
		||||
}// Socket::UDPConnection UDP Contructor
 | 
			
		||||
 | 
			
		||||
/// Copies a UDP socket, re-allocating local copies of any needed structures.
 | 
			
		||||
| 
						 | 
				
			
			@ -997,16 +935,12 @@ Socket::UDPConnection::UDPConnection(const UDPConnection & o) {
 | 
			
		|||
    sock = socket(AF_INET, SOCK_DGRAM, 0);
 | 
			
		||||
    family = AF_INET;
 | 
			
		||||
  }
 | 
			
		||||
  if (sock == -1) {
 | 
			
		||||
    DEBUG_MSG(DLVL_FAIL, "Could not create UDP socket: %s", strerror(errno));
 | 
			
		||||
  }
 | 
			
		||||
  if (sock == -1){DEBUG_MSG(DLVL_FAIL, "Could not create UDP socket: %s", strerror(errno));}
 | 
			
		||||
  up = 0;
 | 
			
		||||
  down = 0;
 | 
			
		||||
  if (o.destAddr && o.destAddr_size){
 | 
			
		||||
    destAddr = malloc(o.destAddr_size);
 | 
			
		||||
    if (destAddr) {
 | 
			
		||||
      memcpy(destAddr, o.destAddr, o.destAddr_size);
 | 
			
		||||
    }
 | 
			
		||||
    if (destAddr){memcpy(destAddr, o.destAddr, o.destAddr_size);}
 | 
			
		||||
  }else{
 | 
			
		||||
    destAddr = 0;
 | 
			
		||||
    destAddr_size = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -1024,8 +958,7 @@ Socket::UDPConnection::UDPConnection(const UDPConnection & o) {
 | 
			
		|||
void Socket::UDPConnection::close(){
 | 
			
		||||
  if (sock != -1){
 | 
			
		||||
    errno = EINTR;
 | 
			
		||||
    while (::close(sock) != 0 && errno == EINTR) {
 | 
			
		||||
    }
 | 
			
		||||
    while (::close(sock) != 0 && errno == EINTR){}
 | 
			
		||||
    sock = -1;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1046,26 +979,20 @@ Socket::UDPConnection::~UDPConnection() {
 | 
			
		|||
/// Stores the properties of the receiving end of this UDP socket.
 | 
			
		||||
/// This will be the receiving end for all SendNow calls.
 | 
			
		||||
void Socket::UDPConnection::SetDestination(std::string destIp, uint32_t port){
 | 
			
		||||
  if (destAddr) {
 | 
			
		||||
    free(destAddr);
 | 
			
		||||
    destAddr = 0;
 | 
			
		||||
  //UDP sockets can switch between IPv4 and IPv6 on demand.
 | 
			
		||||
  //We change IPv4-mapped IPv6 addresses into IPv4 addresses for Windows-sillyness reasons.
 | 
			
		||||
  if (destIp.substr(0, 7) == "::ffff:"){
 | 
			
		||||
    destIp = destIp.substr(7);
 | 
			
		||||
  }
 | 
			
		||||
  destAddr = malloc(sizeof(struct sockaddr_in6));
 | 
			
		||||
  if (!destAddr) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  destAddr_size = sizeof(struct sockaddr_in6);
 | 
			
		||||
  memset(destAddr, 0, destAddr_size);
 | 
			
		||||
 | 
			
		||||
  struct addrinfo *result, *rp, hints;
 | 
			
		||||
  std::stringstream ss;
 | 
			
		||||
  ss << port;
 | 
			
		||||
 | 
			
		||||
  memset(&hints, 0, sizeof(struct addrinfo));
 | 
			
		||||
  hints.ai_family = family;
 | 
			
		||||
  hints.ai_family = AF_UNSPEC;
 | 
			
		||||
  hints.ai_socktype = SOCK_DGRAM;
 | 
			
		||||
  hints.ai_flags = AI_ADDRCONFIG;
 | 
			
		||||
  hints.ai_protocol = 0;
 | 
			
		||||
  hints.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED;
 | 
			
		||||
  hints.ai_protocol = IPPROTO_UDP;
 | 
			
		||||
  hints.ai_canonname = NULL;
 | 
			
		||||
  hints.ai_addr = NULL;
 | 
			
		||||
  hints.ai_next = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -1077,7 +1004,17 @@ void Socket::UDPConnection::SetDestination(std::string destIp, uint32_t port) {
 | 
			
		|||
 | 
			
		||||
  for (rp = result; rp != NULL; rp = rp->ai_next){
 | 
			
		||||
    // assume success
 | 
			
		||||
    if (destAddr){
 | 
			
		||||
      free(destAddr);
 | 
			
		||||
      destAddr = 0;
 | 
			
		||||
    }
 | 
			
		||||
    destAddr_size = rp->ai_addrlen;
 | 
			
		||||
    destAddr = malloc(destAddr_size);
 | 
			
		||||
    if (!destAddr){return;}
 | 
			
		||||
    memcpy(destAddr, rp->ai_addr, rp->ai_addrlen);
 | 
			
		||||
    close();
 | 
			
		||||
    family = rp->ai_family;
 | 
			
		||||
    sock = socket(family, SOCK_DGRAM, 0);
 | 
			
		||||
    freeaddrinfo(result);
 | 
			
		||||
    return;
 | 
			
		||||
    //\todo Possibly detect and handle failure
 | 
			
		||||
| 
						 | 
				
			
			@ -1121,21 +1058,15 @@ void Socket::UDPConnection::GetDestination(std::string & destIp, uint32_t & port
 | 
			
		|||
/// Returns 0 on error.
 | 
			
		||||
uint32_t Socket::UDPConnection::getDestPort() const{
 | 
			
		||||
  if (!destAddr || !destAddr_size){return 0;}
 | 
			
		||||
  if (((struct sockaddr_in *)destAddr)->sin_family == AF_INET6) {
 | 
			
		||||
    return ntohs(((struct sockaddr_in6 *)destAddr)->sin6_port);
 | 
			
		||||
  }
 | 
			
		||||
  if (((struct sockaddr_in *)destAddr)->sin_family == AF_INET) {
 | 
			
		||||
    return ntohs(((struct sockaddr_in *)destAddr)->sin_port);
 | 
			
		||||
  }
 | 
			
		||||
  if (((struct sockaddr_in *)destAddr)->sin_family == AF_INET6){return ntohs(((struct sockaddr_in6 *)destAddr)->sin6_port);}
 | 
			
		||||
  if (((struct sockaddr_in *)destAddr)->sin_family == AF_INET){return ntohs(((struct sockaddr_in *)destAddr)->sin_port);}
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Sets the socket to be blocking if the parameters is true.
 | 
			
		||||
/// Sets the socket to be non-blocking otherwise.
 | 
			
		||||
void Socket::UDPConnection::setBlocking(bool blocking){
 | 
			
		||||
  if (sock >= 0) {
 | 
			
		||||
    setFDBlocking(sock, blocking);
 | 
			
		||||
  }
 | 
			
		||||
  if (sock >= 0){setFDBlocking(sock, blocking);}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Sends a UDP datagram using the buffer sdata.
 | 
			
		||||
| 
						 | 
				
			
			@ -1156,9 +1087,7 @@ void Socket::UDPConnection::SendNow(const char * sdata) {
 | 
			
		|||
/// Does not do anything if len < 1.
 | 
			
		||||
/// Prints an DLVL_FAIL level debug message if sending failed.
 | 
			
		||||
void Socket::UDPConnection::SendNow(const char *sdata, size_t len){
 | 
			
		||||
  if (len < 1) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  if (len < 1){return;}
 | 
			
		||||
  int r = sendto(sock, sdata, len, 0, (sockaddr *)destAddr, destAddr_size);
 | 
			
		||||
  if (r > 0){
 | 
			
		||||
    up += r;
 | 
			
		||||
| 
						 | 
				
			
			@ -1171,7 +1100,8 @@ void Socket::UDPConnection::SendNow(const char * sdata, size_t len) {
 | 
			
		|||
/// If that fails, returns zero.
 | 
			
		||||
/// \arg port Port to bind to, required.
 | 
			
		||||
/// \arg iface Interface address to listen for packets on (may be multicast address)
 | 
			
		||||
/// \arg multicastInterfaces Comma-separated list of interfaces to listen on for multicast packets. Optional, left out means automatically chosen by kernel.
 | 
			
		||||
/// \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 zero on error.
 | 
			
		||||
int Socket::UDPConnection::bind(int port, std::string iface, const std::string &multicastInterfaces){
 | 
			
		||||
  close(); // we open a new socket for each attempt
 | 
			
		||||
| 
						 | 
				
			
			@ -1181,7 +1111,7 @@ int Socket::UDPConnection::bind(int port, std::string iface, const std::string &
 | 
			
		|||
  struct addrinfo hints, *addr_result, *rp;
 | 
			
		||||
  memset(&hints, 0, sizeof(hints));
 | 
			
		||||
  hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_PASSIVE;
 | 
			
		||||
  hints.ai_family = AF_UNSPEC;
 | 
			
		||||
  hints.ai_family = family;
 | 
			
		||||
  hints.ai_socktype = SOCK_DGRAM;
 | 
			
		||||
  hints.ai_protocol = IPPROTO_UDP;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1203,9 +1133,7 @@ int Socket::UDPConnection::bind(int port, std::string iface, const std::string &
 | 
			
		|||
  std::string err_str;
 | 
			
		||||
  for (rp = addr_result; rp != NULL; rp = rp->ai_next){
 | 
			
		||||
    sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
 | 
			
		||||
    if (sock == -1) {
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
    if (sock == -1){continue;}
 | 
			
		||||
    char human_addr[INET6_ADDRSTRLEN];
 | 
			
		||||
    getnameinfo(rp->ai_addr, rp->ai_addrlen, human_addr, INET6_ADDRSTRLEN, 0, 0, NI_NUMERICHOST);
 | 
			
		||||
    MEDIUM_MSG("Attempting bind to %s (%s)", human_addr, rp->ai_family == AF_INET6 ? "IPv6" : "IPv4");
 | 
			
		||||
| 
						 | 
				
			
			@ -1298,7 +1226,8 @@ int Socket::UDPConnection::bind(int port, std::string iface, const std::string &
 | 
			
		|||
          memcpy(&mreq6.ipv6mr_multiaddr, &((sockaddr_in6 *)resmulti->ai_addr)->sin6_addr, sizeof(mreq6.ipv6mr_multiaddr));
 | 
			
		||||
          mreq6.ipv6mr_interface = ((sockaddr_in6 *)reslocal->ai_addr)->sin6_scope_id;
 | 
			
		||||
          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", curIface.c_str(), ((sockaddr_in6*)reslocal->ai_addr)->sin6_scope_id, strerror(errno));
 | 
			
		||||
            FAIL_MSG("Unable to register for IPv6 multicast on interface %s (%u): %s", curIface.c_str(),
 | 
			
		||||
                     ((sockaddr_in6 *)reslocal->ai_addr)->sin6_scope_id, strerror(errno));
 | 
			
		||||
          }else{
 | 
			
		||||
            atLeastOne = true;
 | 
			
		||||
          }
 | 
			
		||||
| 
						 | 
				
			
			@ -1324,7 +1253,6 @@ int Socket::UDPConnection::bind(int port, std::string iface, const std::string &
 | 
			
		|||
      }// loop over all interfaces
 | 
			
		||||
    }
 | 
			
		||||
    freeaddrinfo(resmulti); // free resolved multicast addr
 | 
			
		||||
     
 | 
			
		||||
  }
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1342,9 +1270,7 @@ bool Socket::UDPConnection::Receive() {
 | 
			
		|||
#endif
 | 
			
		||||
  int r = recvfrom(sock, data, data_size, MSG_PEEK | MSG_TRUNC | MSG_DONTWAIT, 0, 0);
 | 
			
		||||
  if (r == -1){
 | 
			
		||||
    if (errno != EAGAIN) {
 | 
			
		||||
      INFO_MSG("UDP receive: %d (%s)", errno, strerror(errno));
 | 
			
		||||
    }
 | 
			
		||||
    if (errno != EAGAIN){INFO_MSG("UDP receive: %d (%s)", errno, strerror(errno));}
 | 
			
		||||
    data_len = 0;
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										25
									
								
								lib/socket.h
									
										
									
									
									
								
							
							
						
						
									
										25
									
								
								lib/socket.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -3,18 +3,18 @@
 | 
			
		|||
/// Written by Jaron Vietor in 2010 for DDVTech
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/un.h>
 | 
			
		||||
#include <arpa/inet.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <deque>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/un.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
// for being friendly with Socket::Connection down below
 | 
			
		||||
namespace Buffer{
 | 
			
		||||
| 
						 | 
				
			
			@ -24,10 +24,13 @@ namespace Buffer {
 | 
			
		|||
/// Holds Socket tools.
 | 
			
		||||
namespace Socket{
 | 
			
		||||
 | 
			
		||||
  void hostBytesToStr(const char *bytes, size_t len, std::string &target);
 | 
			
		||||
 | 
			
		||||
  /// A buffer made out of std::string objects that can be efficiently read from and written to.
 | 
			
		||||
  class Buffer{
 | 
			
		||||
  private:
 | 
			
		||||
    std::deque<std::string> data;
 | 
			
		||||
 | 
			
		||||
  public:
 | 
			
		||||
    unsigned int size();
 | 
			
		||||
    unsigned int bytes(unsigned int max);
 | 
			
		||||
| 
						 | 
				
			
			@ -149,5 +152,5 @@ namespace Socket {
 | 
			
		|||
    void SendNow(const char *data);
 | 
			
		||||
    void SendNow(const char *data, size_t len);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,16 +79,7 @@ std::string Controller::sessIndex::toStr(){
 | 
			
		|||
/// Initializes a sessIndex from a statExchange object, converting binary format IP addresses into strings.
 | 
			
		||||
/// This extracts the host, stream name, connector and crc field, ignoring everything else.
 | 
			
		||||
Controller::sessIndex::sessIndex(IPC::statExchange & data){
 | 
			
		||||
  std::string tHost = data.host();
 | 
			
		||||
  if (tHost.substr(0, 12) == std::string("\000\000\000\000\000\000\000\000\000\000\377\377", 12)){
 | 
			
		||||
    char tmpstr[16];
 | 
			
		||||
    snprintf(tmpstr, 16, "%hhu.%hhu.%hhu.%hhu", tHost[12], tHost[13], tHost[14], tHost[15]);
 | 
			
		||||
    host = tmpstr;
 | 
			
		||||
  }else{
 | 
			
		||||
    char tmpstr[40];
 | 
			
		||||
    snprintf(tmpstr, 40, "%0.2x%0.2x:%0.2x%0.2x:%0.2x%0.2x:%0.2x%0.2x:%0.2x%0.2x:%0.2x%0.2x:%0.2x%0.2x:%0.2x%0.2x", tHost[0], tHost[1], tHost[2], tHost[3], tHost[4], tHost[5], tHost[6], tHost[7], tHost[8], tHost[9], tHost[10], tHost[11], tHost[12], tHost[13], tHost[14], tHost[15]);
 | 
			
		||||
    host = tmpstr;
 | 
			
		||||
  }
 | 
			
		||||
  Socket::hostBytesToStr(data.host().c_str(), 16, host);
 | 
			
		||||
  streamName = data.streamName();
 | 
			
		||||
  connector = data.connector();
 | 
			
		||||
  crc = data.crc();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue