Added hostBytesToStr function to socket library, fixed code style, fixed UDP Cygwin support
This commit is contained in:
parent
567759ce26
commit
629b24853a
3 changed files with 544 additions and 617 deletions
302
lib/socket.cpp
302
lib/socket.cpp
|
@ -3,15 +3,15 @@
|
||||||
/// Written by Jaron Vietor in 2010 for DDVTech
|
/// Written by Jaron Vietor in 2010 for DDVTech
|
||||||
|
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
#include "timing.h"
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include <sys/stat.h>
|
#include "timing.h"
|
||||||
#include <sys/socket.h>
|
#include <cstdlib>
|
||||||
|
#include <netdb.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <netdb.h>
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <cstdlib>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#define BUFFER_BLOCKSIZE 4096 // set buffer blocksize to 4KiB
|
#define BUFFER_BLOCKSIZE 4096 // set buffer blocksize to 4KiB
|
||||||
|
|
||||||
|
@ -21,6 +21,32 @@
|
||||||
#define SOCKETSIZE 51200ul
|
#define SOCKETSIZE 51200ul
|
||||||
#endif
|
#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::string uint2string(unsigned int i){
|
||||||
std::stringstream st;
|
std::stringstream st;
|
||||||
st << i;
|
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
|
/// 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.
|
/// guaranteed to return 0 if the buffer is empty.
|
||||||
unsigned int Socket::Buffer::size(){
|
unsigned int Socket::Buffer::size(){
|
||||||
while (data.size() > 0 && data.back().empty()) {
|
while (data.size() > 0 && data.back().empty()){data.pop_back();}
|
||||||
data.pop_back();
|
|
||||||
}
|
|
||||||
return data.size();
|
return data.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,9 +66,7 @@ unsigned int Socket::Buffer::bytes(unsigned int max) {
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
for (std::deque<std::string>::iterator it = data.begin(); it != data.end(); ++it){
|
for (std::deque<std::string>::iterator it = data.begin(); it != data.end(); ++it){
|
||||||
i += (*it).size();
|
i += (*it).size();
|
||||||
if (i >= max) {
|
if (i >= max){return max;}
|
||||||
return max;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -63,12 +85,9 @@ void Socket::Buffer::append(const char * newdata, const unsigned int newdatasize
|
||||||
j = i;
|
j = i;
|
||||||
while (j < newdatasize && j - i <= BUFFER_BLOCKSIZE){
|
while (j < newdatasize && j - i <= BUFFER_BLOCKSIZE){
|
||||||
j++;
|
j++;
|
||||||
if (newdata[j - 1] == '\n') {
|
if (newdata[j - 1] == '\n'){break;}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (i != j){
|
if (i != j){
|
||||||
DONTEVEN_MSG("Adding a block of size %d", j - i);
|
|
||||||
data.push_front(std::string(newdata + i, (size_t)(j - i)));
|
data.push_front(std::string(newdata + i, (size_t)(j - i)));
|
||||||
i = j;
|
i = j;
|
||||||
}else{
|
}else{
|
||||||
|
@ -76,7 +95,8 @@ void Socket::Buffer::append(const char * newdata, const unsigned int newdatasize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (data.size() > 5000){
|
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;
|
unsigned int i = 0;
|
||||||
for (std::deque<std::string>::iterator it = data.begin(); it != data.end(); ++it){
|
for (std::deque<std::string>::iterator it = data.begin(); it != data.end(); ++it){
|
||||||
i += (*it).size();
|
i += (*it).size();
|
||||||
if (i >= count) {
|
if (i >= count){return true;}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -109,9 +127,7 @@ bool Socket::Buffer::available(unsigned int count) {
|
||||||
/// Returns an empty string if not all count bytes are available.
|
/// Returns an empty string if not all count bytes are available.
|
||||||
std::string Socket::Buffer::remove(unsigned int count){
|
std::string Socket::Buffer::remove(unsigned int count){
|
||||||
size();
|
size();
|
||||||
if (!available(count)) {
|
if (!available(count)){return "";}
|
||||||
return "";
|
|
||||||
}
|
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
std::string ret;
|
std::string ret;
|
||||||
ret.reserve(count);
|
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.
|
/// Returns an empty string if not all count bytes are available.
|
||||||
std::string Socket::Buffer::copy(unsigned int count){
|
std::string Socket::Buffer::copy(unsigned int count){
|
||||||
size();
|
size();
|
||||||
if (!available(count)) {
|
if (!available(count)){return "";}
|
||||||
return "";
|
|
||||||
}
|
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
std::string ret;
|
std::string ret;
|
||||||
ret.reserve(count);
|
ret.reserve(count);
|
||||||
|
@ -207,6 +221,11 @@ Socket::Connection::Connection() {
|
||||||
Blocking = false;
|
Blocking = false;
|
||||||
}// Socket::Connection basic constructor
|
}// Socket::Connection basic constructor
|
||||||
|
|
||||||
|
void Socket::Connection::resetCounter(){
|
||||||
|
up = 0;
|
||||||
|
down = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// Internally used call to make an file descriptor blocking or not.
|
/// Internally used call to make an file descriptor blocking or not.
|
||||||
void setFDBlocking(int FD, bool blocking){
|
void setFDBlocking(int FD, bool blocking){
|
||||||
int flags = fcntl(FD, F_GETFL, 0);
|
int flags = fcntl(FD, F_GETFL, 0);
|
||||||
|
@ -226,28 +245,16 @@ bool isFDBlocking(int FD) {
|
||||||
|
|
||||||
/// Set this socket to be blocking (true) or nonblocking (false).
|
/// Set this socket to be blocking (true) or nonblocking (false).
|
||||||
void Socket::Connection::setBlocking(bool blocking){
|
void Socket::Connection::setBlocking(bool blocking){
|
||||||
if (sock >= 0) {
|
if (sock >= 0){setFDBlocking(sock, blocking);}
|
||||||
setFDBlocking(sock, blocking);
|
if (pipes[0] >= 0){setFDBlocking(pipes[0], blocking);}
|
||||||
}
|
if (pipes[1] >= 0){setFDBlocking(pipes[1], 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).
|
/// Set this socket to be blocking (true) or nonblocking (false).
|
||||||
bool Socket::Connection::isBlocking(){
|
bool Socket::Connection::isBlocking(){
|
||||||
if (sock >= 0) {
|
if (sock >= 0){return isFDBlocking(sock);}
|
||||||
return isFDBlocking(sock);
|
if (pipes[0] >= 0){return isFDBlocking(pipes[0]);}
|
||||||
}
|
if (pipes[1] >= 0){return isFDBlocking(pipes[1]);}
|
||||||
if (pipes[0] >= 0) {
|
|
||||||
return isFDBlocking(pipes[0]);
|
|
||||||
}
|
|
||||||
if (pipes[1] >= 0) {
|
|
||||||
return isFDBlocking(pipes[1]);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,9 +263,7 @@ bool Socket::Connection::isBlocking() {
|
||||||
/// This function calls shutdown, thus making the socket unusable in all other
|
/// 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.
|
/// processes as well. Do not use on shared sockets that are still in use.
|
||||||
void Socket::Connection::close(){
|
void Socket::Connection::close(){
|
||||||
if (sock != -1) {
|
if (sock != -1){shutdown(sock, SHUT_RDWR);}
|
||||||
shutdown(sock, SHUT_RDWR);
|
|
||||||
}
|
|
||||||
drop();
|
drop();
|
||||||
}// Socket::Connection::close
|
}// Socket::Connection::close
|
||||||
|
|
||||||
|
@ -271,20 +276,17 @@ void Socket::Connection::drop() {
|
||||||
if (sock != -1){
|
if (sock != -1){
|
||||||
DEBUG_MSG(DLVL_HIGH, "Socket %d closed", sock);
|
DEBUG_MSG(DLVL_HIGH, "Socket %d closed", sock);
|
||||||
errno = EINTR;
|
errno = EINTR;
|
||||||
while (::close(sock) != 0 && errno == EINTR) {
|
while (::close(sock) != 0 && errno == EINTR){}
|
||||||
}
|
|
||||||
sock = -1;
|
sock = -1;
|
||||||
}
|
}
|
||||||
if (pipes[0] != -1){
|
if (pipes[0] != -1){
|
||||||
errno = EINTR;
|
errno = EINTR;
|
||||||
while (::close(pipes[0]) != 0 && errno == EINTR) {
|
while (::close(pipes[0]) != 0 && errno == EINTR){}
|
||||||
}
|
|
||||||
pipes[0] = -1;
|
pipes[0] = -1;
|
||||||
}
|
}
|
||||||
if (pipes[1] != -1){
|
if (pipes[1] != -1){
|
||||||
errno = EINTR;
|
errno = EINTR;
|
||||||
while (::close(pipes[1]) != 0 && errno == EINTR) {
|
while (::close(pipes[1]) != 0 && errno == EINTR){}
|
||||||
}
|
|
||||||
pipes[1] = -1;
|
pipes[1] = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -292,15 +294,9 @@ void Socket::Connection::drop() {
|
||||||
|
|
||||||
/// Returns internal socket number.
|
/// Returns internal socket number.
|
||||||
int Socket::Connection::getSocket(){
|
int Socket::Connection::getSocket(){
|
||||||
if (sock != -1) {
|
if (sock != -1){return sock;}
|
||||||
return sock;
|
if (pipes[0] != -1){return pipes[0];}
|
||||||
}
|
if (pipes[1] != -1){return pipes[1];}
|
||||||
if (pipes[0] != -1) {
|
|
||||||
return pipes[0];
|
|
||||||
}
|
|
||||||
if (pipes[1] != -1) {
|
|
||||||
return pipes[1];
|
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,12 +375,8 @@ Socket::Connection::Connection(std::string host, int port, bool nonblock) {
|
||||||
remotehost = "";
|
remotehost = "";
|
||||||
for (rp = result; rp != NULL; rp = rp->ai_next){
|
for (rp = result; rp != NULL; rp = rp->ai_next){
|
||||||
sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||||
if (sock < 0) {
|
if (sock < 0){continue;}
|
||||||
continue;
|
if (connect(sock, rp->ai_addr, rp->ai_addrlen) == 0){break;}
|
||||||
}
|
|
||||||
if (connect(sock, rp->ai_addr, rp->ai_addrlen) == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
remotehost += strerror(errno);
|
remotehost += strerror(errno);
|
||||||
::close(sock);
|
::close(sock);
|
||||||
}
|
}
|
||||||
|
@ -458,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.
|
/// 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){
|
void Socket::Connection::SendNow(const char *data, size_t len){
|
||||||
bool bing = isBlocking();
|
bool bing = isBlocking();
|
||||||
if (!bing) {
|
if (!bing){setBlocking(true);}
|
||||||
setBlocking(true);
|
|
||||||
}
|
|
||||||
unsigned int i = iwrite(data, std::min((long unsigned int)len, SOCKETSIZE));
|
unsigned int i = iwrite(data, std::min((long unsigned int)len, SOCKETSIZE));
|
||||||
while (i < len && connected()) {
|
while (i < len && connected()){i += iwrite(data + i, std::min((long unsigned int)(len - i), SOCKETSIZE));}
|
||||||
i += iwrite(data + i, std::min((long unsigned int)(len - i), SOCKETSIZE));
|
if (!bing){setBlocking(false);}
|
||||||
}
|
|
||||||
if (!bing) {
|
|
||||||
setBlocking(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Will not buffer anything but always send right away. Blocks.
|
/// Will not buffer anything but always send right away. Blocks.
|
||||||
|
@ -489,9 +475,7 @@ void Socket::Connection::SendNow(const std::string & data) {
|
||||||
/// \param len Amount of bytes to write.
|
/// \param len Amount of bytes to write.
|
||||||
/// \returns The amount of bytes actually written.
|
/// \returns The amount of bytes actually written.
|
||||||
unsigned int Socket::Connection::iwrite(const void *buffer, int len){
|
unsigned int Socket::Connection::iwrite(const void *buffer, int len){
|
||||||
if (!connected() || len < 1) {
|
if (!connected() || len < 1){return 0;}
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int r;
|
int r;
|
||||||
if (sock >= 0){
|
if (sock >= 0){
|
||||||
r = send(sock, buffer, len, 0);
|
r = send(sock, buffer, len, 0);
|
||||||
|
@ -500,9 +484,7 @@ unsigned int Socket::Connection::iwrite(const void * buffer, int len) {
|
||||||
}
|
}
|
||||||
if (r < 0){
|
if (r < 0){
|
||||||
switch (errno){
|
switch (errno){
|
||||||
case EWOULDBLOCK:
|
case EWOULDBLOCK: return 0; break;
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
Error = true;
|
Error = true;
|
||||||
INSANE_MSG("Could not iwrite data! Error: %s", strerror(errno));
|
INSANE_MSG("Could not iwrite data! Error: %s", strerror(errno));
|
||||||
|
@ -526,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.
|
/// \param flags Flags to use in the recv call. Ignored on fake sockets.
|
||||||
/// \returns The amount of bytes actually read.
|
/// \returns The amount of bytes actually read.
|
||||||
int Socket::Connection::iread(void *buffer, int len, int flags){
|
int Socket::Connection::iread(void *buffer, int len, int flags){
|
||||||
if (!connected() || len < 1) {
|
if (!connected() || len < 1){return 0;}
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int r;
|
int r;
|
||||||
if (sock >= 0){
|
if (sock >= 0){
|
||||||
r = recv(sock, buffer, len, flags);
|
r = recv(sock, buffer, len, flags);
|
||||||
}else{
|
}else{
|
||||||
r = recv(pipes[1], buffer, len, flags);
|
r = recv(pipes[1], buffer, len, flags);
|
||||||
if (r < 0 && errno == ENOTSOCK) {
|
if (r < 0 && errno == ENOTSOCK){r = read(pipes[1], buffer, len);}
|
||||||
r = read(pipes[1], buffer, len);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (r < 0){
|
if (r < 0){
|
||||||
switch (errno){
|
switch (errno){
|
||||||
case EWOULDBLOCK:
|
case EWOULDBLOCK: return 0; break;
|
||||||
return 0;
|
case EINTR: return 0; break;
|
||||||
break;
|
|
||||||
case EINTR:
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
Error = true;
|
Error = true;
|
||||||
INSANE_MSG("Could not iread data! Error: %s", strerror(errno));
|
INSANE_MSG("Could not iread data! Error: %s", strerror(errno));
|
||||||
|
@ -571,9 +545,7 @@ int Socket::Connection::iread(void * buffer, int len, int flags) {
|
||||||
bool Socket::Connection::iread(Buffer &buffer, int flags){
|
bool Socket::Connection::iread(Buffer &buffer, int flags){
|
||||||
char cbuffer[BUFFER_BLOCKSIZE];
|
char cbuffer[BUFFER_BLOCKSIZE];
|
||||||
int num = iread(cbuffer, BUFFER_BLOCKSIZE, flags);
|
int num = iread(cbuffer, BUFFER_BLOCKSIZE, flags);
|
||||||
if (num < 1) {
|
if (num < 1){return false;}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
buffer.append(cbuffer, num);
|
buffer.append(cbuffer, num);
|
||||||
return true;
|
return true;
|
||||||
}// iread
|
}// iread
|
||||||
|
@ -584,13 +556,9 @@ bool Socket::Connection::iread(Buffer & buffer, int flags) {
|
||||||
/// \param buffer std::string to remove data from.
|
/// \param buffer std::string to remove data from.
|
||||||
/// \return True if more data was sent, false otherwise.
|
/// \return True if more data was sent, false otherwise.
|
||||||
bool Socket::Connection::iwrite(std::string &buffer){
|
bool Socket::Connection::iwrite(std::string &buffer){
|
||||||
if (buffer.size() < 1) {
|
if (buffer.size() < 1){return false;}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
unsigned int tmp = iwrite((void *)buffer.c_str(), buffer.size());
|
unsigned int tmp = iwrite((void *)buffer.c_str(), buffer.size());
|
||||||
if (!tmp) {
|
if (!tmp){return false;}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
buffer = buffer.substr(tmp);
|
buffer = buffer.substr(tmp);
|
||||||
return true;
|
return true;
|
||||||
}// iwrite
|
}// iwrite
|
||||||
|
@ -620,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";
|
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){
|
for (rp = result; rp != NULL; rp = rp->ai_next){
|
||||||
if (rp->ai_family == AF_INET) {
|
if (rp->ai_family == AF_INET){memcpy(tmpBuffer + 12, &((sockaddr_in *)rp->ai_addr)->sin_addr.s_addr, 4);}
|
||||||
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_INET6) {
|
|
||||||
memcpy(tmpBuffer, ((sockaddr_in6 *)rp->ai_addr)->sin6_addr.s6_addr, 16);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
freeaddrinfo(result);
|
freeaddrinfo(result);
|
||||||
return std::string(tmpBuffer, 16);
|
return std::string(tmpBuffer, 16);
|
||||||
|
@ -671,28 +635,20 @@ bool Socket::Connection::isAddress(std::string addr) {
|
||||||
hints.ai_addr = NULL;
|
hints.ai_addr = NULL;
|
||||||
hints.ai_next = NULL;
|
hints.ai_next = NULL;
|
||||||
int s = getaddrinfo(addr.c_str(), 0, &hints, &result);
|
int s = getaddrinfo(addr.c_str(), 0, &hints, &result);
|
||||||
if (s != 0) {
|
if (s != 0){return false;}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char newaddr[INET_ADDRSTRLEN];
|
char newaddr[INET_ADDRSTRLEN];
|
||||||
newaddr[0] = 0;
|
newaddr[0] = 0;
|
||||||
for (rp = result; rp != NULL; rp = rp->ai_next){
|
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)){
|
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);
|
DEBUG_MSG(DLVL_DEVEL, "Comparing: '%s' to '%s'", remotehost.c_str(), newaddr);
|
||||||
if (remotehost == newaddr) {
|
if (remotehost == newaddr){return true;}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
DEBUG_MSG(DLVL_DEVEL, "Comparing: '%s' to '::ffff:%s'", remotehost.c_str(), newaddr);
|
DEBUG_MSG(DLVL_DEVEL, "Comparing: '%s' to '::ffff:%s'", remotehost.c_str(), newaddr);
|
||||||
if (remotehost == std::string("::ffff:") + newaddr) {
|
if (remotehost == std::string("::ffff:") + newaddr){return true;}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (rp->ai_family == AF_INET6 && inet_ntop(rp->ai_family, &(((sockaddr_in6 *)rp->ai_addr)->sin6_addr), newaddr, INET_ADDRSTRLEN)){
|
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);
|
DEBUG_MSG(DLVL_DEVEL, "Comparing: '%s' to '%s'", remotehost.c_str(), newaddr);
|
||||||
if (remotehost == newaddr) {
|
if (remotehost == newaddr){return true;}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
freeaddrinfo(result);
|
freeaddrinfo(result);
|
||||||
|
@ -820,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.
|
/// 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.
|
/// A maximum of 100 connections will be accepted between accept() calls.
|
||||||
/// Any further connections coming in will be dropped.
|
/// 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 address The location of the Unix socket to bind to.
|
||||||
/// \param nonblock (optional) Whether accept() calls will be nonblocking. Default is false (blocking).
|
/// \param nonblock (optional) Whether accept() calls will be nonblocking. Default is false (blocking).
|
||||||
Socket::Server::Server(std::string address, bool nonblock){
|
Socket::Server::Server(std::string address, bool nonblock){
|
||||||
|
@ -863,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).
|
/// \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.
|
/// \returns A Socket::Connection, which may or may not be connected, depending on settings and circumstances.
|
||||||
Socket::Connection Socket::Server::accept(bool nonblock){
|
Socket::Connection Socket::Server::accept(bool nonblock){
|
||||||
if (sock < 0) {
|
if (sock < 0){return Socket::Connection(-1);}
|
||||||
return Socket::Connection(-1);
|
|
||||||
}
|
|
||||||
struct sockaddr_in6 addrinfo;
|
struct sockaddr_in6 addrinfo;
|
||||||
socklen_t len = sizeof(addrinfo);
|
socklen_t len = sizeof(addrinfo);
|
||||||
static char addrconv[INET6_ADDRSTRLEN];
|
static char addrconv[INET6_ADDRSTRLEN];
|
||||||
|
@ -902,16 +857,12 @@ Socket::Connection Socket::Server::accept(bool nonblock) {
|
||||||
|
|
||||||
/// Set this socket to be blocking (true) or nonblocking (false).
|
/// Set this socket to be blocking (true) or nonblocking (false).
|
||||||
void Socket::Server::setBlocking(bool blocking){
|
void Socket::Server::setBlocking(bool blocking){
|
||||||
if (sock >= 0) {
|
if (sock >= 0){setFDBlocking(sock, blocking);}
|
||||||
setFDBlocking(sock, blocking);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set this socket to be blocking (true) or nonblocking (false).
|
/// Set this socket to be blocking (true) or nonblocking (false).
|
||||||
bool Socket::Server::isBlocking(){
|
bool Socket::Server::isBlocking(){
|
||||||
if (sock >= 0) {
|
if (sock >= 0){return isFDBlocking(sock);}
|
||||||
return isFDBlocking(sock);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -920,9 +871,7 @@ bool Socket::Server::isBlocking() {
|
||||||
/// This function calls shutdown, thus making the socket unusable in all other
|
/// 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.
|
/// processes as well. Do not use on shared sockets that are still in use.
|
||||||
void Socket::Server::close(){
|
void Socket::Server::close(){
|
||||||
if (sock != -1) {
|
if (sock != -1){shutdown(sock, SHUT_RDWR);}
|
||||||
shutdown(sock, SHUT_RDWR);
|
|
||||||
}
|
|
||||||
drop();
|
drop();
|
||||||
}// Socket::Server::close
|
}// Socket::Server::close
|
||||||
|
|
||||||
|
@ -935,8 +884,7 @@ void Socket::Server::drop() {
|
||||||
if (sock != -1){
|
if (sock != -1){
|
||||||
DEBUG_MSG(DLVL_HIGH, "ServerSocket %d closed", sock);
|
DEBUG_MSG(DLVL_HIGH, "ServerSocket %d closed", sock);
|
||||||
errno = EINTR;
|
errno = EINTR;
|
||||||
while (::close(sock) != 0 && errno == EINTR) {
|
while (::close(sock) != 0 && errno == EINTR){}
|
||||||
}
|
|
||||||
sock = -1;
|
sock = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -967,9 +915,7 @@ Socket::UDPConnection::UDPConnection(bool nonblock) {
|
||||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
family = AF_INET;
|
family = AF_INET;
|
||||||
}
|
}
|
||||||
if (sock == -1) {
|
if (sock == -1){DEBUG_MSG(DLVL_FAIL, "Could not create UDP socket: %s", strerror(errno));}
|
||||||
DEBUG_MSG(DLVL_FAIL, "Could not create UDP socket: %s", strerror(errno));
|
|
||||||
}
|
|
||||||
up = 0;
|
up = 0;
|
||||||
down = 0;
|
down = 0;
|
||||||
destAddr = 0;
|
destAddr = 0;
|
||||||
|
@ -977,9 +923,7 @@ Socket::UDPConnection::UDPConnection(bool nonblock) {
|
||||||
data = 0;
|
data = 0;
|
||||||
data_size = 0;
|
data_size = 0;
|
||||||
data_len = 0;
|
data_len = 0;
|
||||||
if (nonblock) {
|
if (nonblock){setBlocking(!nonblock);}
|
||||||
setBlocking(!nonblock);
|
|
||||||
}
|
|
||||||
}// Socket::UDPConnection UDP Contructor
|
}// Socket::UDPConnection UDP Contructor
|
||||||
|
|
||||||
/// Copies a UDP socket, re-allocating local copies of any needed structures.
|
/// Copies a UDP socket, re-allocating local copies of any needed structures.
|
||||||
|
@ -991,16 +935,12 @@ Socket::UDPConnection::UDPConnection(const UDPConnection & o) {
|
||||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
family = AF_INET;
|
family = AF_INET;
|
||||||
}
|
}
|
||||||
if (sock == -1) {
|
if (sock == -1){DEBUG_MSG(DLVL_FAIL, "Could not create UDP socket: %s", strerror(errno));}
|
||||||
DEBUG_MSG(DLVL_FAIL, "Could not create UDP socket: %s", strerror(errno));
|
|
||||||
}
|
|
||||||
up = 0;
|
up = 0;
|
||||||
down = 0;
|
down = 0;
|
||||||
if (o.destAddr && o.destAddr_size){
|
if (o.destAddr && o.destAddr_size){
|
||||||
destAddr = malloc(o.destAddr_size);
|
destAddr = malloc(o.destAddr_size);
|
||||||
if (destAddr) {
|
if (destAddr){memcpy(destAddr, o.destAddr, o.destAddr_size);}
|
||||||
memcpy(destAddr, o.destAddr, o.destAddr_size);
|
|
||||||
}
|
|
||||||
}else{
|
}else{
|
||||||
destAddr = 0;
|
destAddr = 0;
|
||||||
destAddr_size = 0;
|
destAddr_size = 0;
|
||||||
|
@ -1018,8 +958,7 @@ Socket::UDPConnection::UDPConnection(const UDPConnection & o) {
|
||||||
void Socket::UDPConnection::close(){
|
void Socket::UDPConnection::close(){
|
||||||
if (sock != -1){
|
if (sock != -1){
|
||||||
errno = EINTR;
|
errno = EINTR;
|
||||||
while (::close(sock) != 0 && errno == EINTR) {
|
while (::close(sock) != 0 && errno == EINTR){}
|
||||||
}
|
|
||||||
sock = -1;
|
sock = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1040,26 +979,20 @@ Socket::UDPConnection::~UDPConnection() {
|
||||||
/// Stores the properties of the receiving end of this UDP socket.
|
/// Stores the properties of the receiving end of this UDP socket.
|
||||||
/// This will be the receiving end for all SendNow calls.
|
/// This will be the receiving end for all SendNow calls.
|
||||||
void Socket::UDPConnection::SetDestination(std::string destIp, uint32_t port){
|
void Socket::UDPConnection::SetDestination(std::string destIp, uint32_t port){
|
||||||
if (destAddr) {
|
//UDP sockets can switch between IPv4 and IPv6 on demand.
|
||||||
free(destAddr);
|
//We change IPv4-mapped IPv6 addresses into IPv4 addresses for Windows-sillyness reasons.
|
||||||
destAddr = 0;
|
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;
|
struct addrinfo *result, *rp, hints;
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << port;
|
ss << port;
|
||||||
|
|
||||||
memset(&hints, 0, sizeof(struct addrinfo));
|
memset(&hints, 0, sizeof(struct addrinfo));
|
||||||
hints.ai_family = family;
|
hints.ai_family = AF_UNSPEC;
|
||||||
hints.ai_socktype = SOCK_DGRAM;
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
hints.ai_flags = AI_ADDRCONFIG;
|
hints.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED;
|
||||||
hints.ai_protocol = 0;
|
hints.ai_protocol = IPPROTO_UDP;
|
||||||
hints.ai_canonname = NULL;
|
hints.ai_canonname = NULL;
|
||||||
hints.ai_addr = NULL;
|
hints.ai_addr = NULL;
|
||||||
hints.ai_next = NULL;
|
hints.ai_next = NULL;
|
||||||
|
@ -1071,7 +1004,17 @@ void Socket::UDPConnection::SetDestination(std::string destIp, uint32_t port) {
|
||||||
|
|
||||||
for (rp = result; rp != NULL; rp = rp->ai_next){
|
for (rp = result; rp != NULL; rp = rp->ai_next){
|
||||||
// assume success
|
// 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);
|
memcpy(destAddr, rp->ai_addr, rp->ai_addrlen);
|
||||||
|
close();
|
||||||
|
family = rp->ai_family;
|
||||||
|
sock = socket(family, SOCK_DGRAM, 0);
|
||||||
freeaddrinfo(result);
|
freeaddrinfo(result);
|
||||||
return;
|
return;
|
||||||
//\todo Possibly detect and handle failure
|
//\todo Possibly detect and handle failure
|
||||||
|
@ -1115,21 +1058,15 @@ void Socket::UDPConnection::GetDestination(std::string & destIp, uint32_t & port
|
||||||
/// Returns 0 on error.
|
/// Returns 0 on error.
|
||||||
uint32_t Socket::UDPConnection::getDestPort() const{
|
uint32_t Socket::UDPConnection::getDestPort() const{
|
||||||
if (!destAddr || !destAddr_size){return 0;}
|
if (!destAddr || !destAddr_size){return 0;}
|
||||||
if (((struct sockaddr_in *)destAddr)->sin_family == AF_INET6) {
|
if (((struct sockaddr_in *)destAddr)->sin_family == AF_INET6){return ntohs(((struct sockaddr_in6 *)destAddr)->sin6_port);}
|
||||||
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_INET) {
|
|
||||||
return ntohs(((struct sockaddr_in *)destAddr)->sin_port);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the socket to be blocking if the parameters is true.
|
/// Sets the socket to be blocking if the parameters is true.
|
||||||
/// Sets the socket to be non-blocking otherwise.
|
/// Sets the socket to be non-blocking otherwise.
|
||||||
void Socket::UDPConnection::setBlocking(bool blocking){
|
void Socket::UDPConnection::setBlocking(bool blocking){
|
||||||
if (sock >= 0) {
|
if (sock >= 0){setFDBlocking(sock, blocking);}
|
||||||
setFDBlocking(sock, blocking);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends a UDP datagram using the buffer sdata.
|
/// Sends a UDP datagram using the buffer sdata.
|
||||||
|
@ -1150,9 +1087,7 @@ void Socket::UDPConnection::SendNow(const char * sdata) {
|
||||||
/// Does not do anything if len < 1.
|
/// Does not do anything if len < 1.
|
||||||
/// Prints an DLVL_FAIL level debug message if sending failed.
|
/// Prints an DLVL_FAIL level debug message if sending failed.
|
||||||
void Socket::UDPConnection::SendNow(const char *sdata, size_t len){
|
void Socket::UDPConnection::SendNow(const char *sdata, size_t len){
|
||||||
if (len < 1) {
|
if (len < 1){return;}
|
||||||
return;
|
|
||||||
}
|
|
||||||
int r = sendto(sock, sdata, len, 0, (sockaddr *)destAddr, destAddr_size);
|
int r = sendto(sock, sdata, len, 0, (sockaddr *)destAddr, destAddr_size);
|
||||||
if (r > 0){
|
if (r > 0){
|
||||||
up += r;
|
up += r;
|
||||||
|
@ -1165,7 +1100,8 @@ void Socket::UDPConnection::SendNow(const char * sdata, size_t len) {
|
||||||
/// If that fails, returns zero.
|
/// If that fails, returns zero.
|
||||||
/// \arg port Port to bind to, required.
|
/// \arg port Port to bind to, required.
|
||||||
/// \arg iface Interface address to listen for packets on (may be multicast address)
|
/// \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.
|
/// \return Actually bound port number, or zero on error.
|
||||||
int Socket::UDPConnection::bind(int port, std::string iface, const std::string &multicastInterfaces){
|
int Socket::UDPConnection::bind(int port, std::string iface, const std::string &multicastInterfaces){
|
||||||
close(); // we open a new socket for each attempt
|
close(); // we open a new socket for each attempt
|
||||||
|
@ -1175,7 +1111,7 @@ int Socket::UDPConnection::bind(int port, std::string iface, const std::string &
|
||||||
struct addrinfo hints, *addr_result, *rp;
|
struct addrinfo hints, *addr_result, *rp;
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_PASSIVE;
|
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_socktype = SOCK_DGRAM;
|
||||||
hints.ai_protocol = IPPROTO_UDP;
|
hints.ai_protocol = IPPROTO_UDP;
|
||||||
|
|
||||||
|
@ -1197,9 +1133,7 @@ int Socket::UDPConnection::bind(int port, std::string iface, const std::string &
|
||||||
std::string err_str;
|
std::string err_str;
|
||||||
for (rp = addr_result; rp != NULL; rp = rp->ai_next){
|
for (rp = addr_result; rp != NULL; rp = rp->ai_next){
|
||||||
sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||||
if (sock == -1) {
|
if (sock == -1){continue;}
|
||||||
continue;
|
|
||||||
}
|
|
||||||
char human_addr[INET6_ADDRSTRLEN];
|
char human_addr[INET6_ADDRSTRLEN];
|
||||||
getnameinfo(rp->ai_addr, rp->ai_addrlen, human_addr, INET6_ADDRSTRLEN, 0, 0, NI_NUMERICHOST);
|
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");
|
MEDIUM_MSG("Attempting bind to %s (%s)", human_addr, rp->ai_family == AF_INET6 ? "IPv6" : "IPv4");
|
||||||
|
@ -1292,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));
|
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;
|
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", 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{
|
}else{
|
||||||
atLeastOne = true;
|
atLeastOne = true;
|
||||||
}
|
}
|
||||||
|
@ -1318,7 +1253,6 @@ int Socket::UDPConnection::bind(int port, std::string iface, const std::string &
|
||||||
}// loop over all interfaces
|
}// loop over all interfaces
|
||||||
}
|
}
|
||||||
freeaddrinfo(resmulti); // free resolved multicast addr
|
freeaddrinfo(resmulti); // free resolved multicast addr
|
||||||
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1336,9 +1270,7 @@ bool Socket::UDPConnection::Receive() {
|
||||||
#endif
|
#endif
|
||||||
int r = recvfrom(sock, data, data_size, MSG_PEEK | MSG_TRUNC | MSG_DONTWAIT, 0, 0);
|
int r = recvfrom(sock, data, data_size, MSG_PEEK | MSG_TRUNC | MSG_DONTWAIT, 0, 0);
|
||||||
if (r == -1){
|
if (r == -1){
|
||||||
if (errno != EAGAIN) {
|
if (errno != EAGAIN){INFO_MSG("UDP receive: %d (%s)", errno, strerror(errno));}
|
||||||
INFO_MSG("UDP receive: %d (%s)", errno, strerror(errno));
|
|
||||||
}
|
|
||||||
data_len = 0;
|
data_len = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
26
lib/socket.h
26
lib/socket.h
|
@ -3,18 +3,18 @@
|
||||||
/// Written by Jaron Vietor in 2010 for DDVTech
|
/// Written by Jaron Vietor in 2010 for DDVTech
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
|
||||||
#include <sstream>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/un.h>
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <deque>
|
#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
|
// for being friendly with Socket::Connection down below
|
||||||
namespace Buffer{
|
namespace Buffer{
|
||||||
|
@ -24,10 +24,13 @@ namespace Buffer {
|
||||||
/// Holds Socket tools.
|
/// Holds Socket tools.
|
||||||
namespace Socket{
|
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.
|
/// A buffer made out of std::string objects that can be efficiently read from and written to.
|
||||||
class Buffer{
|
class Buffer{
|
||||||
private:
|
private:
|
||||||
std::deque<std::string> data;
|
std::deque<std::string> data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
unsigned int size();
|
unsigned int size();
|
||||||
unsigned int bytes(unsigned int max);
|
unsigned int bytes(unsigned int max);
|
||||||
|
@ -90,6 +93,7 @@ namespace Socket {
|
||||||
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.
|
||||||
std::string getStats(std::string C); ///< Returns a std::string of stats, ended by a newline.
|
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.
|
||||||
|
@ -148,5 +152,5 @@ 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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,16 +49,7 @@ std::string Controller::sessIndex::toStr(){
|
||||||
/// Initializes a sessIndex from a statExchange object, converting binary format IP addresses into strings.
|
/// 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.
|
/// This extracts the host, stream name, connector and crc field, ignoring everything else.
|
||||||
Controller::sessIndex::sessIndex(IPC::statExchange & data){
|
Controller::sessIndex::sessIndex(IPC::statExchange & data){
|
||||||
std::string tHost = data.host();
|
Socket::hostBytesToStr(data.host().c_str(), 16, 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;
|
|
||||||
}
|
|
||||||
streamName = data.streamName();
|
streamName = data.streamName();
|
||||||
connector = data.connector();
|
connector = data.connector();
|
||||||
crc = data.crc();
|
crc = data.crc();
|
||||||
|
|
Loading…
Add table
Reference in a new issue