git-svn-id: svn://db.shs.com.ru/pip@542 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5

This commit is contained in:
2017-09-05 15:20:33 +00:00
parent b67512d38c
commit 6f54f501cd
7 changed files with 324 additions and 131 deletions

View File

@@ -1,16 +1,61 @@
#include "pip.h" #include "pip.h"
#include "pivector2d.h" #include "pivector2d.h"
#include "pistring.h" #include "pistring.h"
#ifdef QNX
# include <net/if.h>
# include <net/if_dl.h>
# include <hw/nicinfo.h>
# include <netdb.h>
# include <sys/socket.h>
# include <sys/time.h>
# include <sys/types.h>
# include <sys/ioctl.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <ifaddrs.h>
# include <fcntl.h>
# ifdef BLACKBERRY
# include <netinet/in.h>
# else
# include <sys/dcmd_io-net.h>
# endif
# define ip_mreqn ip_mreq
# define imr_address imr_interface
#else
# ifdef WINDOWS
# include <io.h>
# include <winsock2.h>
# include <iphlpapi.h>
# include <psapi.h>
# include <ws2tcpip.h>
# define ip_mreqn ip_mreq
# define imr_address imr_interface
# else
# include <fcntl.h>
# include <sys/ioctl.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <sys/socket.h>
# include <net/if.h>
# include <netdb.h>
# ifndef ANDROID
# include <ifaddrs.h>
# endif
# endif
#endif
#include <errno.h>
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
PIString s = PIString::fromUTF8("hello, привет"); /*PIString s = PIString::fromUTF8("hello, привет");
piCout << s; piCout << s;
PIByteArray ba = s.toUTF8(); PIByteArray ba = s.toUTF8();
piCout << ba.toHex(); piCout << ba.toHex();
PIString s2; PIString s2;
s2 = PIString::fromUTF8(ba); s2 = PIString::fromUTF8(ba);
piCout << s2; piCout << s2;*/
PIEthernet::Address a("127.1", -1);
piCout << a << PICoutManipulators::Hex << a.ip();
return 0; return 0;
} }

View File

@@ -92,6 +92,114 @@ PIString getSockAddr(sockaddr * s) {
#endif #endif
PIEthernet::Address::Address(uint _ip, ushort _port) {
set(_ip, _port);
}
PIEthernet::Address::Address(const PIString & ip_port) {
set(ip_port);
}
PIEthernet::Address::Address(const PIString & _ip, ushort _port) {
set(_ip, _port);
}
PIString PIEthernet::Address::ipString() const {
PIString ret = PIString::fromNumber(ip_b[0]);
ret << "." << PIString::fromNumber(ip_b[1]);
ret << "." << PIString::fromNumber(ip_b[2]);
ret << "." << PIString::fromNumber(ip_b[3]);
return ret;
}
PIString PIEthernet::Address::toString() const {
return ipString() + ":" + PIString::fromNumber(port_);
}
void PIEthernet::Address::setIP(uint _ip) {
ip_ = _ip;
}
void PIEthernet::Address::setIP(const PIString & _ip) {
initIP(_ip);
}
void PIEthernet::Address::setPort(ushort _port) {
port_ = _port;
}
void PIEthernet::Address::set(const PIString & ip_port) {
PIString _ip; int p(0);
splitIPPort(ip_port, &_ip, &p);
port_ = p;
initIP(_ip);
}
void PIEthernet::Address::set(const PIString & _ip, ushort _port) {
initIP(_ip);
port_ = _port;
}
void PIEthernet::Address::set(uint _ip, ushort _port) {
ip_ = _ip;
port_ = _port;
}
void PIEthernet::Address::clear() {
ip_ = 0;
port_ = 0;
}
PIString PIEthernet::Address::resolve(const PIString & host) {
PIString ip(host), port;
int i = host.find(':');
if (i >= 0) {
ip = host.left(i);
port = host.right(host.length() - i - 1);
}
PIString ret = PIStringAscii("0.0.0.0");
if (!port.isEmpty()) ret += PIStringAscii(":") + port;
//#ifdef WINDOWS
hostent * he = gethostbyname(ip.dataAscii());
if (!he)
return ret;
struct in_addr addr;
if (he->h_addr_list[0]) {
addr.s_addr = *((uint*)(he->h_addr_list[0]));
ret = inet_ntoa(addr);
if (!port.isEmpty()) ret += PIStringAscii(":") + port;
}
//#else
//#endif
return ret;
}
void PIEthernet::Address::splitIPPort(const PIString & ipp, PIString * _ip, int * _port) {
//piCout << "parse" << ipp;
int sp = ipp.find(":");
if (_ip != 0) *_ip = (sp >= 0 ? ipp.left(sp) : ipp);
if (_port != 0 && sp >= 0) *_port = ipp.right(ipp.length() - ipp.find(":") - 1).toInt();
}
void PIEthernet::Address::initIP(const PIString & _ip) {
ip_ = inet_addr(_ip.dataAscii());
}
REGISTER_DEVICE(PIEthernet) REGISTER_DEVICE(PIEthernet)
@@ -112,7 +220,7 @@ PIEthernet::PIEthernet(): PIIODevice("", ReadWrite) {
PIEthernet::PIEthernet(PIEthernet::Type type_, const PIString & ip_port, const PIFlags<PIEthernet::Parameters> params_): PIIODevice(ip_port, ReadWrite) { PIEthernet::PIEthernet(PIEthernet::Type type_, const PIString & ip_port, const PIFlags<PIEthernet::Parameters> params_): PIIODevice(ip_port, ReadWrite) {
construct(); construct();
parseAddress(ip_port, &ip_, &port_); addr_r.set(ip_port);
setType(type_); setType(type_);
setParameters(params_); setParameters(params_);
if (type_ != UDP) init(); if (type_ != UDP) init();
@@ -121,7 +229,7 @@ PIEthernet::PIEthernet(PIEthernet::Type type_, const PIString & ip_port, const P
PIEthernet::PIEthernet(int sock_, PIString ip_port): PIIODevice("", ReadWrite) { PIEthernet::PIEthernet(int sock_, PIString ip_port): PIIODevice("", ReadWrite) {
construct(); construct();
parseAddress(ip_port, &ip_s, &port_s); addr_s.set(ip_port);
sock = sock_; sock = sock_;
opened_ = connected_ = true; opened_ = connected_ = true;
init(); init();
@@ -146,7 +254,6 @@ void PIEthernet::construct() {
setOption(BlockingWrite); setOption(BlockingWrite);
piMonitor.ethernets++; piMonitor.ethernets++;
connected_ = connecting_ = listen_threaded = server_bounded = false; connected_ = connecting_ = listen_threaded = server_bounded = false;
port_ = port_s = port_r = 0;
sock = sock_s = -1; sock = sock_s = -1;
setReadTimeout(10000.); setReadTimeout(10000.);
setWriteTimeout(10000.); setWriteTimeout(10000.);
@@ -197,13 +304,6 @@ bool PIEthernet::init() {
} }
void PIEthernet::parseAddress(const PIString & ipp, PIString * ip, int * port) {
//piCout << "parse" << ipp;
if (ip != 0) *ip = ipp.left(ipp.find(":"));
if (port != 0) *port = ipp.right(ipp.length() - ipp.find(":") - 1).toInt();
}
PIString PIEthernet::macFromBytes(const PIByteArray & mac) { PIString PIEthernet::macFromBytes(const PIByteArray & mac) {
PIString r; PIString r;
for (int i = 0; i < mac.size_s(); ++i) { for (int i = 0; i < mac.size_s(); ++i) {
@@ -230,6 +330,13 @@ PIString PIEthernet::applyMask(const PIString & ip, const PIString & mask) {
} }
PIEthernet::Address PIEthernet::applyMask(const PIEthernet::Address & ip, const PIEthernet::Address & mask) {
Address ret(ip);
ret.ip_ &= mask.ip_;
return ret;
}
PIString PIEthernet::getBroadcast(const PIString & ip, const PIString & mask) { PIString PIEthernet::getBroadcast(const PIString & ip, const PIString & mask) {
struct in_addr ia; struct in_addr ia;
ia.s_addr = inet_addr(ip.dataAscii()) | ~inet_addr(mask.dataAscii()); ia.s_addr = inet_addr(ip.dataAscii()) | ~inet_addr(mask.dataAscii());
@@ -237,21 +344,29 @@ PIString PIEthernet::getBroadcast(const PIString & ip, const PIString & mask) {
} }
PIEthernet::Address PIEthernet::getBroadcast(const PIEthernet::Address & ip, const PIEthernet::Address & mask) {
Address ret(ip);
ret.ip_ |= ~mask.ip_;
return ret;
}
bool PIEthernet::openDevice() { bool PIEthernet::openDevice() {
if (connected_) return true; if (connected_) return true;
init(); init();
if (sock == -1 || path().isEmpty()) return false; if (sock == -1 || path().isEmpty()) return false;
parseAddress(path(), &ip_, &port_); addr_r.set(path());
//Address::splitIPPort(path(), &ip_, &port_);
if (type() == TCP_Client) if (type() == TCP_Client)
connecting_ = true; connecting_ = true;
if (type() != UDP || mode() == PIIODevice::WriteOnly) if (type() != UDP || mode() == PIIODevice::WriteOnly)
return true; return true;
memset(&PRIVATE->addr_, 0, sizeof(PRIVATE->addr_)); memset(&PRIVATE->addr_, 0, sizeof(PRIVATE->addr_));
PRIVATE->addr_.sin_family = AF_INET; PRIVATE->addr_.sin_family = AF_INET;
PRIVATE->addr_.sin_port = htons(port_); PRIVATE->addr_.sin_port = htons(addr_r.port());
PIFlags<Parameters> params = parameters(); PIFlags<Parameters> params = parameters();
if (params[PIEthernet::Broadcast]) PRIVATE->addr_.sin_addr.s_addr = INADDR_ANY; if (params[PIEthernet::Broadcast]) PRIVATE->addr_.sin_addr.s_addr = INADDR_ANY;
else PRIVATE->addr_.sin_addr.s_addr = inet_addr(ip_.dataAscii()); else PRIVATE->addr_.sin_addr.s_addr = addr_r.ip();
#ifdef QNX #ifdef QNX
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_); PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
#endif #endif
@@ -262,7 +377,7 @@ bool PIEthernet::openDevice() {
tries++; tries++;
} }
if (tries == 2) { if (tries == 2) {
piCoutObj << "Can`t bind to " << ip_ << ":" << port_ << ", " << ethErrorString(); piCoutObj << "Can`t bind to " << addr_r << ", " << ethErrorString();
return false; return false;
} }
opened_ = true; opened_ = true;
@@ -271,8 +386,7 @@ bool PIEthernet::openDevice() {
//cout << "!" << endl; //cout << "!" << endl;
applyTimeouts(); applyTimeouts();
applyOptInt(IPPROTO_IP, IP_TTL, TTL()); applyOptInt(IPPROTO_IP, IP_TTL, TTL());
port_r = 0; addr_lr.clear();
ip_r.clear();
return true; return true;
} }
@@ -363,7 +477,7 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
//#ifndef QNX //#ifndef QNX
//if (!params[Broadcast]) //if (!params[Broadcast])
//;piCoutObj << "Warning: \"Broadcast\" parameter not set, \"joinMulticastGroup(\"" << group << "\")\" may be useless!"; //;piCoutObj << "Warning: \"Broadcast\" parameter not set, \"joinMulticastGroup(\"" << group << "\")\" may be useless!";
parseAddress(path(), &ip_, &port_); addr_r.set(path());
struct ip_mreqn mreq; struct ip_mreqn mreq;
memset(&mreq, 0, sizeof(mreq)); memset(&mreq, 0, sizeof(mreq));
#ifdef LINUX #ifdef LINUX
@@ -373,7 +487,7 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
if (ci != 0) mreq.imr_ifindex = ci->index;*/ if (ci != 0) mreq.imr_ifindex = ci->index;*/
#endif #endif
if (params[PIEthernet::Broadcast]) mreq.imr_address.s_addr = INADDR_ANY; if (params[PIEthernet::Broadcast]) mreq.imr_address.s_addr = INADDR_ANY;
else mreq.imr_address.s_addr = inet_addr(ip_.dataAscii()); else mreq.imr_address.s_addr = addr_r.ip();
/*#ifndef WINDOWS /*#ifndef WINDOWS
PIEthernet::InterfaceList il = interfaces(); PIEthernet::InterfaceList il = interfaces();
const PIEthernet::Interface * ci = il.getByAddress(ip_); const PIEthernet::Interface * ci = il.getByAddress(ip_);
@@ -415,11 +529,11 @@ bool PIEthernet::leaveMulticastGroup(const PIString & group) {
} }
PIFlags<Parameters> params = parameters(); PIFlags<Parameters> params = parameters();
/// TODO windows /// TODO windows
parseAddress(path(), &ip_, &port_); addr_r.set(path());
struct ip_mreqn mreq; struct ip_mreqn mreq;
memset(&mreq, 0, sizeof(mreq)); memset(&mreq, 0, sizeof(mreq));
if (params[PIEthernet::Broadcast]) mreq.imr_address.s_addr = INADDR_ANY; if (params[PIEthernet::Broadcast]) mreq.imr_address.s_addr = INADDR_ANY;
else mreq.imr_address.s_addr = inet_addr(ip_.dataAscii()); else mreq.imr_address.s_addr = addr_r.ip();
mreq.imr_multiaddr.s_addr = inet_addr(group.dataAscii()); mreq.imr_multiaddr.s_addr = inet_addr(group.dataAscii());
if (ethSetsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) { if (ethSetsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) {
piCoutObj << "Can`t leave multicast group " << group << ", " << ethErrorString(); piCoutObj << "Can`t leave multicast group " << group << ", " << ethErrorString();
@@ -468,10 +582,10 @@ bool PIEthernet::listen(bool threaded) {
return true; return true;
} }
listen_threaded = server_bounded = false; listen_threaded = server_bounded = false;
parseAddress(path(), &ip_, &port_); addr_r.set(path());
memset(&PRIVATE->addr_, 0, sizeof(PRIVATE->addr_)); memset(&PRIVATE->addr_, 0, sizeof(PRIVATE->addr_));
PRIVATE->addr_.sin_port = htons(port_); PRIVATE->addr_.sin_port = htons(addr_r.port());
PRIVATE->addr_.sin_addr.s_addr = inet_addr(ip_.dataAscii()); PRIVATE->addr_.sin_addr.s_addr = addr_r.ip();
PRIVATE->addr_.sin_family = AF_INET; PRIVATE->addr_.sin_family = AF_INET;
#ifdef QNX #ifdef QNX
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_); PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
@@ -483,11 +597,11 @@ bool PIEthernet::listen(bool threaded) {
tries++; tries++;
} }
if (tries == 2) { if (tries == 2) {
piCoutObj << "Can`t bind to " << ip_ << ":" << port_ << ", " << ethErrorString(); piCoutObj << "Can`t bind to " << addr_r << ", " << ethErrorString();
return false; return false;
} }
if (::listen(sock, 64) == -1) { if (::listen(sock, 64) == -1) {
piCoutObj << "Can`t listen on "<< ip_ << ":" << port_ << ", " << ethErrorString(); piCoutObj << "Can`t listen on "<< addr_r << ", " << ethErrorString();
return false; return false;
} }
opened_ = server_bounded = true; opened_ = server_bounded = true;
@@ -528,9 +642,9 @@ int PIEthernet::readDevice(void * read_to, int max_size) {
qDebug() << "init() in read thread";*/ qDebug() << "init() in read thread";*/
#endif #endif
memset(&PRIVATE->addr_, 0, sizeof(PRIVATE->addr_)); memset(&PRIVATE->addr_, 0, sizeof(PRIVATE->addr_));
parseAddress(path(), &ip_, &port_); addr_r.set(path());
PRIVATE->addr_.sin_port = htons(port_); PRIVATE->addr_.sin_port = htons(addr_r.port());
PRIVATE->addr_.sin_addr.s_addr = inet_addr(ip_.dataAscii()); PRIVATE->addr_.sin_addr.s_addr = addr_r.ip();
PRIVATE->addr_.sin_family = AF_INET; PRIVATE->addr_.sin_family = AF_INET;
#ifdef QNX #ifdef QNX
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_); PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
@@ -541,7 +655,7 @@ int PIEthernet::readDevice(void * read_to, int max_size) {
//piCoutObj << "connect to " << ip_ << ":" << port_ << connected_; //piCoutObj << "connect to " << ip_ << ":" << port_ << connected_;
//qDebug() << "connect to " << ip_.data() << ":" << port_ << connected_; //qDebug() << "connect to " << ip_.data() << ":" << port_ << connected_;
if (!connected_) if (!connected_)
piCoutObj << "Can`t connect to " << ip_ << ":" << port_ << ", " << ethErrorString(); piCoutObj << "Can`t connect to " << addr_r << ", " << ethErrorString();
opened_ = connected_; opened_ = connected_;
if (connected_) { if (connected_) {
connecting_ = false; connecting_ = false;
@@ -584,8 +698,7 @@ int PIEthernet::readDevice(void * read_to, int max_size) {
memset(&PRIVATE->raddr_, 0, sizeof(PRIVATE->raddr_)); memset(&PRIVATE->raddr_, 0, sizeof(PRIVATE->raddr_));
rs = ethRecvfrom(sock, read_to, max_size, 0, (sockaddr*)&PRIVATE->raddr_); rs = ethRecvfrom(sock, read_to, max_size, 0, (sockaddr*)&PRIVATE->raddr_);
if (rs > 0) { if (rs > 0) {
port_r = ntohs(PRIVATE->raddr_.sin_port); addr_lr.set(uint(PRIVATE->raddr_.sin_addr.s_addr), ntohs(PRIVATE->raddr_.sin_port));
ip_r = PIStringAscii(inet_ntoa(PRIVATE->raddr_.sin_addr));
//piCoutObj << "read from" << ip_r << ":" << port_r << rs << "bytes"; //piCoutObj << "read from" << ip_r << ":" << port_r << rs << "bytes";
//piCout << "received from" << lastReadAddress(); //piCout << "received from" << lastReadAddress();
received(read_to, rs); received(read_to, rs);
@@ -611,8 +724,8 @@ int PIEthernet::writeDevice(const void * data, int max_size) {
switch (type()) { switch (type()) {
case TCP_SingleTCP: case TCP_SingleTCP:
memset(&PRIVATE->addr_, 0, sizeof(PRIVATE->addr_)); memset(&PRIVATE->addr_, 0, sizeof(PRIVATE->addr_));
PRIVATE->addr_.sin_port = htons(port_s); PRIVATE->addr_.sin_port = htons(addr_s.port());
PRIVATE->addr_.sin_addr.s_addr = inet_addr(ip_s.dataAscii()); PRIVATE->addr_.sin_addr.s_addr = addr_s.ip();
PRIVATE->addr_.sin_family = AF_INET; PRIVATE->addr_.sin_family = AF_INET;
#ifdef QNX #ifdef QNX
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_); PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
@@ -630,9 +743,9 @@ int PIEthernet::writeDevice(const void * data, int max_size) {
init(); init();
return ret; return ret;
case UDP: case UDP:
PRIVATE->saddr_.sin_port = htons(port_s); PRIVATE->saddr_.sin_port = htons(addr_s.port());
/*if (params[PIEthernet::Broadcast]) PRIVATE->saddr_.sin_addr.s_addr = INADDR_BROADCAST; /*if (params[PIEthernet::Broadcast]) PRIVATE->saddr_.sin_addr.s_addr = INADDR_BROADCAST;
else*/ PRIVATE->saddr_.sin_addr.s_addr = inet_addr(ip_s.dataAscii()); else*/ PRIVATE->saddr_.sin_addr.s_addr = addr_s.ip();
PRIVATE->saddr_.sin_family = AF_INET; PRIVATE->saddr_.sin_family = AF_INET;
//piCoutObj << "write to" << ip_s << ":" << port_s << "socket" << sock_s << max_size << "bytes ..."; //piCoutObj << "write to" << ip_s << ":" << port_s << "socket" << sock_s << max_size << "bytes ...";
return ethSendto(sock_s, data, max_size, return ethSendto(sock_s, data, max_size,
@@ -646,9 +759,9 @@ int PIEthernet::writeDevice(const void * data, int max_size) {
case TCP_Client: case TCP_Client:
if (connecting_) { if (connecting_) {
memset(&PRIVATE->addr_, 0, sizeof(PRIVATE->addr_)); memset(&PRIVATE->addr_, 0, sizeof(PRIVATE->addr_));
parseAddress(path(), &ip_, &port_); addr_r.set(path());
PRIVATE->addr_.sin_port = htons(port_); PRIVATE->addr_.sin_port = htons(addr_r.port());
PRIVATE->addr_.sin_addr.s_addr = inet_addr(ip_.dataAscii()); PRIVATE->addr_.sin_addr.s_addr = addr_r.ip();
PRIVATE->addr_.sin_family = AF_INET; PRIVATE->addr_.sin_family = AF_INET;
#ifdef QNX #ifdef QNX
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_); PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
@@ -656,7 +769,7 @@ int PIEthernet::writeDevice(const void * data, int max_size) {
//piCoutObj << "connect to " << ip << ":" << port_; //piCoutObj << "connect to " << ip << ":" << port_;
connected_ = (::connect(sock, (sockaddr * )&PRIVATE->addr_, sizeof(PRIVATE->addr_)) == 0); connected_ = (::connect(sock, (sockaddr * )&PRIVATE->addr_, sizeof(PRIVATE->addr_)) == 0);
if (!connected_) if (!connected_)
piCoutObj << "Can`t connect to " << ip_ << ":" << port_ << ", " << ethErrorString(); piCoutObj << "Can`t connect to " << addr_r << ", " << ethErrorString();
opened_ = connected_; opened_ = connected_;
if (connected_) { if (connected_) {
connecting_ = false; connecting_ = false;
@@ -980,10 +1093,10 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
} }
PIString PIEthernet::interfaceAddress(const PIString & interface_) { PIEthernet::Address PIEthernet::interfaceAddress(const PIString & interface_) {
#ifdef WINDOWS #ifdef WINDOWS
piCout << "[PIEthernet] Not implemented on Windows, use \"PIEthernet::allAddresses\" or \"PIEthernet::interfaces\" instead"; piCout << "[PIEthernet] Not implemented on Windows, use \"PIEthernet::allAddresses\" or \"PIEthernet::interfaces\" instead";
return PIString(); return Address();
#else #else
struct ifreq ifr; struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr)); memset(&ifr, 0, sizeof(ifr));
@@ -992,13 +1105,13 @@ PIString PIEthernet::interfaceAddress(const PIString & interface_) {
ioctl(s, SIOCGIFADDR, &ifr); ioctl(s, SIOCGIFADDR, &ifr);
::close(s); ::close(s);
struct sockaddr_in * sa = (struct sockaddr_in * )&ifr.ifr_addr; struct sockaddr_in * sa = (struct sockaddr_in * )&ifr.ifr_addr;
return PIStringAscii(inet_ntoa(sa->sin_addr)); return Address(uint(sa->sin_addr));
#endif #endif
} }
PIStringList PIEthernet::allAddresses() { PIVector<PIEthernet::Address> PIEthernet::allAddresses() {
/*#ifdef WINDOWS /*#ifdef WINDOWS
PIStringList al; PIStringList al;
PIString ca; PIString ca;
@@ -1032,41 +1145,21 @@ PIStringList PIEthernet::allAddresses() {
return al; return al;
#else*/ #else*/
PIEthernet::InterfaceList il = interfaces(); PIEthernet::InterfaceList il = interfaces();
PIStringList al; PIVector<Address> ret;
piForeachC (PIEthernet::Interface & i, il) bool has_127 = false;
al << i.address; piForeachC (PIEthernet::Interface & i, il) {
if (i.address == "127.0.0.1") has_127 = true;
Address a(i.address);
if (a.ip() == 0) continue;
ret << a;
}
// piCout << "[PIEthernet::allAddresses]" << al; // piCout << "[PIEthernet::allAddresses]" << al;
if (!al.contains("127.0.0.1")) al << "127.0.0.1"; if (!has_127) ret << Address("127.0.0.1");
return al.removeStrings("0.0.0.0"); return ret;
//#endif //#endif
} }
PIString PIEthernet::resolve(const PIString & host) {
PIString ip(host), port;
int i = host.find(':');
if (i >= 0) {
ip = host.left(i);
port = host.right(host.length() - i - 1);
}
PIString ret = PIStringAscii("0.0.0.0");
if (!port.isEmpty()) ret += PIStringAscii(":") + port;
//#ifdef WINDOWS
hostent * he = gethostbyname(ip.dataAscii());
if (!he)
return ret;
struct in_addr addr;
if (he->h_addr_list[0]) {
addr.s_addr = *((uint*)(he->h_addr_list[0]));
ret = inet_ntoa(addr);
if (!port.isEmpty()) ret += PIStringAscii(":") + port;
}
//#else
//#endif
return ret;
}
// System wrap // System wrap

View File

@@ -61,6 +61,43 @@ public:
DisonnectOnTimeout /** Disconnect TCP connection on read timeout expired. Disabled by default */ = 0x20 DisonnectOnTimeout /** Disconnect TCP connection on read timeout expired. Disabled by default */ = 0x20
}; };
//! \brief IPv4 network address, ip and port
class Address {
friend class PIEthernet;
friend inline PIByteArray & operator <<(PIByteArray & s, const PIEthernet::Address & v);
friend inline PIByteArray & operator >>(PIByteArray & s, PIEthernet::Address & v);
public:
//! Contructs %Address with binary representation of ip and port
Address(uint ip = 0, ushort port = 0);
Address(const PIString & ip_port);
Address(const PIString & ip, ushort port);
uint ip() const {return ip_;}
ushort port() const {return port_;}
PIString ipString() const;
PIString toString() const;
void setIP(uint ip);
void setIP(const PIString & ip);
void setPort(ushort port);
void set(const PIString & ip_port);
void set(const PIString & ip, ushort port);
void set(uint ip, ushort port);
void clear();
//! Resolve hostname "host" and return it IPv4 address or "0.0.0.0" on error
static PIString resolve(const PIString & host);
static void splitIPPort(const PIString & ipp, PIString * ip, int * port);
private:
void initIP(const PIString & _ip);
union {
uint ip_;
uchar ip_b[4];
};
ushort port_;
};
//! Contructs %PIEthernet with type "type", read address "ip_port" and parameters "params" //! Contructs %PIEthernet with type "type", read address "ip_port" and parameters "params"
explicit PIEthernet(Type type, const PIString & ip_port = PIString(), const PIFlags<Parameters> params = PIEthernet::ReuseAddress | PIEthernet::MulticastLoop | PIEthernet::KeepConnection); explicit PIEthernet(Type type, const PIString & ip_port = PIString(), const PIFlags<Parameters> params = PIEthernet::ReuseAddress | PIEthernet::MulticastLoop | PIEthernet::KeepConnection);
@@ -68,59 +105,65 @@ public:
//! Set read address //! Set read address
void setReadAddress(const PIString & ip, int port) {setPath(ip + PIStringAscii(":") + PIString::fromNumber(port));} void setReadAddress(const PIString & ip, int port) {addr_r.set(ip, port); setPath(addr_r.toString());}
//! Set read address in format "i.i.i.i:p" //! Set read address in format "i.i.i.i:p"
void setReadAddress(const PIString & ip_port) {setPath(ip_port);} void setReadAddress(const PIString & ip_port) {addr_r.set(ip_port); setPath(addr_r.toString());}
//! Set read address
void setReadAddress(const Address & addr) {addr_r = addr; setPath(addr_r.toString());}
//! Set read IP //! Set read IP
void setReadIP(const PIString & ip) {parseAddress(path(), &ip_, &port_); setPath(ip + PIStringAscii(":") + PIString::fromNumber(port_));} void setReadIP(const PIString & ip) {addr_r.setIP(ip); setPath(addr_r.toString());}
//! Set read port //! Set read port
void setReadPort(int port) {parseAddress(path(), &ip_, &port_); setPath(ip_ + PIStringAscii(":") + PIString::fromNumber(port));} void setReadPort(int port) {addr_r.setPort(port); setPath(addr_r.toString());}
//! Set send address //! Set send address
void setSendAddress(const PIString & ip, int port) {ip_s = ip; port_s = port;} void setSendAddress(const PIString & ip, int port) {addr_s.set(ip, port);}
//! Set send address in format "i.i.i.i:p" //! Set send address in format "i.i.i.i:p"
void setSendAddress(const PIString & ip_port) {parseAddress(ip_port, &ip_s, &port_s);} void setSendAddress(const PIString & ip_port) {addr_s.set(ip_port);}
//! Set send address
void setSendAddress(const Address & addr) {addr_s = addr;}
//! Set send IP //! Set send IP
void setSendIP(const PIString & ip) {ip_s = ip;} void setSendIP(const PIString & ip) {addr_s.setIP(ip);}
//! Set send port //! Set send port
void setSendPort(int port) {port_s = port;} void setSendPort(int port) {addr_s.setPort(port);}
//! Returns read address in format "i.i.i.i:p" //! Returns read address in format "i.i.i.i:p"
PIString readAddress() const {return path();} Address readAddress() const {return addr_r;}
//! Returns read IP //! Returns read IP
PIString readIP() const {parseAddress(path(), &ip_, &port_); return ip_;} PIString readIP() const {return addr_r.ipString();}
//! Returns read port //! Returns read port
int readPort() const {parseAddress(path(), &ip_, &port_); return port_;} int readPort() const {return addr_r.port();}
//! Returns send address in format "i.i.i.i:p" //! Returns send address in format "i.i.i.i:p"
PIString sendAddress() const {return ip_s + PIStringAscii(":") + PIString::fromNumber(port_s);} Address sendAddress() const {return addr_s;}
//! Returns send IP //! Returns send IP
PIString sendIP() const {return ip_s;} PIString sendIP() const {return addr_s.ipString();}
//! Returns send port //! Returns send port
int sendPort() const {return port_s;} int sendPort() const {return addr_s.port();}
//! Returns address of last received UDP packet in format "i.i.i.i:p" //! Returns address of last received UDP packet in format "i.i.i.i:p"
PIString lastReadAddress() const {return ip_r + PIStringAscii(":") + PIString::fromNumber(port_r);} Address lastReadAddress() const {return addr_lr;}
//! Returns IP of last received UDP packet //! Returns IP of last received UDP packet
PIString lastReadIP() const {return ip_r;} PIString lastReadIP() const {return addr_lr.ipString();}
//! Returns port of last received UDP packet //! Returns port of last received UDP packet
int lastReadPort() const {return port_r;} int lastReadPort() const {return addr_lr.port();}
//! Set parameters to "parameters_". You should to reopen %PIEthernet to apply them //! Set parameters to "parameters_". You should to reopen %PIEthernet to apply them
@@ -210,19 +253,25 @@ public:
bool send(const void * data, int size, bool threaded = false) {if (threaded) {writeThreaded(data, size); return true;} return (write(data, size) == size);} bool send(const void * data, int size, bool threaded = false) {if (threaded) {writeThreaded(data, size); return true;} return (write(data, size) == size);}
//! Send data "data" with size "size" to address "ip":"port" //! Send data "data" with size "size" to address "ip":"port"
bool send(const PIString & ip, int port, const void * data, int size, bool threaded = false) {ip_s = ip; port_s = port; if (threaded) {writeThreaded(data, size); return true;} return send(data, size);} bool send(const PIString & ip, int port, const void * data, int size, bool threaded = false) {addr_s.set(ip, port); if (threaded) {writeThreaded(data, size); return true;} return send(data, size);}
//! Send data "data" with size "size" to address "ip_port" //! Send data "data" with size "size" to address "ip_port"
bool send(const PIString & ip_port, const void * data, int size, bool threaded = false) {parseAddress(ip_port, &ip_s, &port_s); if (threaded) {writeThreaded(data, size); return true;} return send(data, size);} bool send(const PIString & ip_port, const void * data, int size, bool threaded = false) {addr_s.set(ip_port); if (threaded) {writeThreaded(data, size); return true;} return send(data, size);}
//! Send data "data" with size "size" to address "addr"
bool send(const Address & addr, const void * data, int size, bool threaded = false) {addr_s = addr; if (threaded) {writeThreaded(data, size); return true;} return send(data, size);}
//! Send data "data" to address \a sendAddress() for UDP or \a readAddress() for TCP_Client //! Send data "data" to address \a sendAddress() for UDP or \a readAddress() for TCP_Client
bool send(const PIByteArray & data, bool threaded = false) {if (threaded) {writeThreaded(data); return true;} return (write(data) == data.size_s());} bool send(const PIByteArray & data, bool threaded = false) {if (threaded) {writeThreaded(data); return true;} return (write(data) == data.size_s());}
//! Send data "data" to address "ip":"port" for UDP //! Send data "data" to address "ip":"port" for UDP
bool send(const PIString & ip, int port, const PIByteArray & data, bool threaded = false) {ip_s = ip; port_s = port; if (threaded) {writeThreaded(data); return true;} return send(data);} bool send(const PIString & ip, int port, const PIByteArray & data, bool threaded = false) {addr_s.set(ip, port); if (threaded) {writeThreaded(data); return true;} return send(data);}
//! Send data "data" to address "ip_port" for UDP //! Send data "data" to address "ip_port" for UDP
bool send(const PIString & ip_port, const PIByteArray & data, bool threaded = false) {parseAddress(ip_port, &ip_s, &port_s); if (threaded) {writeThreaded(data); return true;} return (write(data) == data.size_s());} bool send(const PIString & ip_port, const PIByteArray & data, bool threaded = false) {addr_s.set(ip_port); if (threaded) {writeThreaded(data); return true;} return (write(data) == data.size_s());}
//! Send data "data" to address "addr" for UDP
bool send(const Address & addr, const PIByteArray & data, bool threaded = false) {addr_s = addr; if (threaded) {writeThreaded(data); return true;} return (write(data) == data.size_s());}
virtual bool canWrite() const {return mode() & WriteOnly;} virtual bool canWrite() const {return mode() & WriteOnly;}
@@ -317,19 +366,17 @@ public:
//! Returns all system network interfaces //! Returns all system network interfaces
static InterfaceList interfaces(); static InterfaceList interfaces();
static PIString interfaceAddress(const PIString & interface_); static PIEthernet::Address interfaceAddress(const PIString & interface_);
//! Returns all system network IP addresses //! Returns all system network IP addresses
static PIStringList allAddresses(); static PIVector<PIEthernet::Address> allAddresses();
//! Resolve hostname "host" and return it IPv4 address or "0.0.0.0" on error
static PIString resolve(const PIString & host);
static void parseAddress(const PIString & ipp, PIString * ip, int * port);
static PIString macFromBytes(const PIByteArray & mac); static PIString macFromBytes(const PIByteArray & mac);
static PIByteArray macToBytes(const PIString & mac); static PIByteArray macToBytes(const PIString & mac);
static PIString applyMask(const PIString & ip, const PIString & mask); static PIString applyMask(const PIString & ip, const PIString & mask);
static Address applyMask(const Address & ip, const Address & mask);
static PIString getBroadcast(const PIString & ip, const PIString & mask); static PIString getBroadcast(const PIString & ip, const PIString & mask);
static Address getBroadcast(const Address & ip, const Address & mask);
//! \events //! \events
//! \{ //! \{
@@ -396,9 +443,8 @@ protected:
PRIVATE_DECLARATION PRIVATE_DECLARATION
int sock, sock_s; int sock, sock_s;
mutable int port_, port_s, port_r;
bool connected_, connecting_, listen_threaded, server_bounded; bool connected_, connecting_, listen_threaded, server_bounded;
mutable PIString ip_, ip_s, ip_r; mutable Address addr_r, addr_s, addr_lr;
PIThread server_thread_; PIThread server_thread_;
PIMutex clients_mutex; PIMutex clients_mutex;
PIVector<PIEthernet * > clients_; PIVector<PIEthernet * > clients_;
@@ -425,5 +471,11 @@ private:
inline bool operator <(const PIEthernet::Interface & v0, const PIEthernet::Interface & v1) {return (v0.name < v1.name);} inline bool operator <(const PIEthernet::Interface & v0, const PIEthernet::Interface & v1) {return (v0.name < v1.name);}
inline bool operator ==(const PIEthernet::Interface & v0, const PIEthernet::Interface & v1) {return (v0.name == v1.name && v0.address == v1.address && v0.netmask == v1.netmask);} inline bool operator ==(const PIEthernet::Interface & v0, const PIEthernet::Interface & v1) {return (v0.name == v1.name && v0.address == v1.address && v0.netmask == v1.netmask);}
inline bool operator !=(const PIEthernet::Interface & v0, const PIEthernet::Interface & v1) {return (v0.name != v1.name || v0.address != v1.address || v0.netmask != v1.netmask);} inline bool operator !=(const PIEthernet::Interface & v0, const PIEthernet::Interface & v1) {return (v0.name != v1.name || v0.address != v1.address || v0.netmask != v1.netmask);}
inline PICout operator <<(PICout s, const PIEthernet::Address & v) {s.setControl(0, true); s << "Address(" << v.toString() << ")"; s.restoreControl(); return s;}
inline bool operator ==(const PIEthernet::Address & v0, const PIEthernet::Address & v1) {return (v0.ip() == v1.ip() && v0.port() == v1.port());}
inline bool operator !=(const PIEthernet::Address & v0, const PIEthernet::Address & v1) {return (v0.ip() != v1.ip() || v0.port() != v1.port());}
inline PIByteArray & operator <<(PIByteArray & s, const PIEthernet::Address & v) {s << v.ip_ << v.port_; return s;}
inline PIByteArray & operator >>(PIByteArray & s, PIEthernet::Address & v) {s >> v.ip_ >> v.port_; return s;}
#endif // PIETHERNET_H #endif // PIETHERNET_H

View File

@@ -112,7 +112,7 @@ void PIPeer::PeerData::setDist(int dist) {
PIPeer::PeerInfo::Address::Address(const PIString & a, const PIString & m): address(a), netmask(m) { PIPeer::PeerInfo::PeerAddress::PeerAddress(const PIEthernet::Address & a, const PIEthernet::Address & m): address(a), netmask(m) {
ping = -1.; ping = -1.;
wait_ping = false; wait_ping = false;
last_ping = PISystemTime::current(true); last_ping = PISystemTime::current(true);
@@ -121,7 +121,7 @@ PIPeer::PeerInfo::Address::Address(const PIString & a, const PIString & m): addr
int PIPeer::PeerInfo::ping() const { int PIPeer::PeerInfo::ping() const {
int ret = -1; int ret = -1;
piForeachC (Address & a, addresses) piForeachC (PeerAddress & a, addresses)
if (a.ping > 0.) { if (a.ping > 0.) {
if (ret < 0) ret = piRoundd(a.ping); if (ret < 0) ret = piRoundd(a.ping);
else ret = piMini(ret, piRoundd(a.ping)); else ret = piMini(ret, piRoundd(a.ping));
@@ -141,10 +141,10 @@ void PIPeer::PeerInfo::destroy() {
} }
PIString PIPeer::PeerInfo::fastestAddress() const { PIEthernet::Address PIPeer::PeerInfo::fastestAddress() const {
double mp = -1.; double mp = -1.;
PIString ret; PIEthernet::Address ret;
piForeachC (Address & a, addresses) { piForeachC (PeerAddress & a, addresses) {
if (a.ping <= 0.) continue; if (a.ping <= 0.) continue;
if ((mp < 0) || (mp > a.ping)) { if ((mp < 0) || (mp > a.ping)) {
mp = a.ping; mp = a.ping;
@@ -248,7 +248,7 @@ void PIPeer::initEths(PIStringList al) {
if (ce->open()) { if (ce->open()) {
eths_traffic << ce; eths_traffic << ce;
cint = prev_ifaces.getByAddress(a); cint = prev_ifaces.getByAddress(a);
self_info.addresses << PeerInfo::Address(ce->path(), cint == 0 ? "255.255.255.0" : cint->netmask); self_info.addresses << PeerInfo::PeerAddress(ce->path(), cint == 0 ? "255.255.255.0" : cint->netmask);
CONNECTU(ce, threadedReadEvent, this, dataRead); CONNECTU(ce, threadedReadEvent, this, dataRead);
ce->startThreadedRead(); ce->startThreadedRead();
// piCoutObj << "dc binded to" << ce->path(); // piCoutObj << "dc binded to" << ce->path();
@@ -473,7 +473,7 @@ bool PIPeer::dataRead(uchar * readed, int size) {
eth_mutex.lock(); eth_mutex.lock();
// piCout << "dataRead lock"; // piCout << "dataRead lock";
if (type == 5) { // ping request if (type == 5) { // ping request
PIString addr; PIEthernet::Address addr;
PISystemTime time; PISystemTime time;
ba >> to >> from >> addr >> time; ba >> to >> from >> addr >> time;
// piCout << "ping request" << to << from << addr; // piCout << "ping request" << to << from << addr;
@@ -485,7 +485,7 @@ bool PIPeer::dataRead(uchar * readed, int size) {
sba << int(6) << to << from << addr << time; sba << int(6) << to << from << addr << time;
// piCout << " ping from" << from << addr << ", send back to" << pi->name; // piCout << " ping from" << from << addr << ", send back to" << pi->name;
send_mutex.lock(); send_mutex.lock();
piForeachC (PeerInfo::Address & a, pi->addresses) { piForeachC (PeerInfo::PeerAddress & a, pi->addresses) {
if (eth_send.send(a.address, sba)) if (eth_send.send(a.address, sba))
diag_s.received(sba.size_s()); diag_s.received(sba.size_s());
} }
@@ -497,7 +497,7 @@ bool PIPeer::dataRead(uchar * readed, int size) {
return true; return true;
} }
if (type == 6) { // ping request if (type == 6) { // ping request
PIString addr; PIEthernet::Address addr;
PISystemTime time, ptime, ctime = PISystemTime::current(true); PISystemTime time, ptime, ctime = PISystemTime::current(true);
ba >> to >> from >> addr >> time; ba >> to >> from >> addr >> time;
// piCout << "ping reply" << to << from << addr; // piCout << "ping reply" << to << from << addr;
@@ -506,7 +506,7 @@ bool PIPeer::dataRead(uchar * readed, int size) {
piForeach (PeerInfo & p, peers) { piForeach (PeerInfo & p, peers) {
if (!p.isNeighbour()) continue; if (!p.isNeighbour()) continue;
if (p.name != from) continue; if (p.name != from) continue;
piForeach (PeerInfo::Address & a, p.addresses) { piForeach (PeerInfo::PeerAddress & a, p.addresses) {
if (a.address != addr) continue; if (a.address != addr) continue;
if (a.last_ping >= time) piBreak; if (a.last_ping >= time) piBreak;
ptime = ctime - time; ptime = ctime - time;
@@ -674,9 +674,9 @@ bool PIPeer::mbcastRead(uchar * data, int size) {
if (isPeerRecent(peer, rpeer)) { if (isPeerRecent(peer, rpeer)) {
//piCout << "synced " << peer.name; //piCout << "synced " << peer.name;
for (int z = 0; z < rpeer.addresses.size_s(); ++z) { for (int z = 0; z < rpeer.addresses.size_s(); ++z) {
PeerInfo::Address & ra(rpeer.addresses[z]); PeerInfo::PeerAddress & ra(rpeer.addresses[z]);
for (int k = 0; k < peer.addresses.size_s(); ++k) { for (int k = 0; k < peer.addresses.size_s(); ++k) {
PeerInfo::Address & a(peer.addresses[k]); PeerInfo::PeerAddress & a(peer.addresses[k]);
if (ra.address == a.address) { if (ra.address == a.address) {
ra.ping = a.ping; ra.ping = a.ping;
ra.wait_ping = a.wait_ping; ra.wait_ping = a.wait_ping;
@@ -727,7 +727,7 @@ bool PIPeer::mbcastRead(uchar * data, int size) {
bool PIPeer::sendToNeighbour(PIPeer::PeerInfo * peer, const PIByteArray & ba) { bool PIPeer::sendToNeighbour(PIPeer::PeerInfo * peer, const PIByteArray & ba) {
//if (peer->_neth == 0) return false; //if (peer->_neth == 0) return false;
PIString addr = peer->fastestAddress(); PIEthernet::Address addr = peer->fastestAddress();
//piCout << "[PIPeer] sendToNeighbour" << peer->name << addr << ba.size_s() << "bytes ..."; //piCout << "[PIPeer] sendToNeighbour" << peer->name << addr << ba.size_s() << "bytes ...";
//bool ok = peer->_neth->send(peer->_naddress, ba.data(), ba.size_s()); //bool ok = peer->_neth->send(peer->_naddress, ba.data(), ba.size_s());
send_mutex.lock(); send_mutex.lock();
@@ -828,7 +828,7 @@ void PIPeer::pingNeighbours() {
if (!p.isNeighbour()) continue; if (!p.isNeighbour()) continue;
//piCout << " ping neighbour" << p.name << p.ping(); //piCout << " ping neighbour" << p.name << p.ping();
send_mutex.lock(); send_mutex.lock();
piForeach (PeerInfo::Address & a, p.addresses) { piForeach (PeerInfo::PeerAddress & a, p.addresses) {
// piCout << " address" << a.address << a.wait_ping; // piCout << " address" << a.address << a.wait_ping;
if (a.wait_ping) { if (a.wait_ping) {
if ((PISystemTime::current(true) - a.last_ping).abs().toSeconds() <= _PIPEER_PING_TIMEOUT) if ((PISystemTime::current(true) - a.last_ping).abs().toSeconds() <= _PIPEER_PING_TIMEOUT)
@@ -1030,7 +1030,10 @@ void PIPeer::initNetwork() {
piMSleep(100); piMSleep(100);
// piCoutObj << self_info.addresses.size(); // piCoutObj << self_info.addresses.size();
self_info.addresses.clear(); self_info.addresses.clear();
PIStringList sl = PIEthernet::allAddresses(); PIVector<PIEthernet::Address> al = PIEthernet::allAddresses();
PIStringList sl;
piForeachC (PIEthernet::Address & a, al)
sl << a.ipString();
initEths(sl); initEths(sl);
// piCoutObj << sl << self_info.addresses.size(); // piCoutObj << sl << self_info.addresses.size();
sl.removeAll("127.0.0.1"); sl.removeAll("127.0.0.1");

View File

@@ -44,25 +44,25 @@ public:
PeerInfo() {dist = sync = cnt = 0; trace = -1; was_update = false; _data = 0;} PeerInfo() {dist = sync = cnt = 0; trace = -1; was_update = false; _data = 0;}
~PeerInfo() {} ~PeerInfo() {}
struct Address { struct PeerAddress {
Address(const PIString & a = PIString(), const PIString & m = "255.255.255.0"); PeerAddress(const PIEthernet::Address & a = PIEthernet::Address(), const PIEthernet::Address & m = PIEthernet::Address("255.255.255.0"));
bool isAvailable() const {return ping > 0;} bool isAvailable() const {return ping > 0;}
//inline const Address & operator =(const Address & v) {address = v.address; netmask = v.netmask; piCout << "!!!!!!!!!" << last_ping; return *this;} //inline const Address & operator =(const Address & v) {address = v.address; netmask = v.netmask; piCout << "!!!!!!!!!" << last_ping; return *this;}
PIString address; PIEthernet::Address address;
PIString netmask; PIEthernet::Address netmask;
double ping; // ms double ping; // ms
bool wait_ping; bool wait_ping;
PISystemTime last_ping; PISystemTime last_ping;
}; };
PIString name; PIString name;
PIVector<Address> addresses; PIVector<PeerAddress> addresses;
int dist; int dist;
PIStringList neighbours; PIStringList neighbours;
bool isNeighbour() const {return dist == 0;} bool isNeighbour() const {return dist == 0;}
int ping() const; int ping() const;
PIString fastestAddress() const; PIEthernet::Address fastestAddress() const;
protected: protected:
void addNeighbour(const PIString & n) {if (!neighbours.contains(n)) neighbours << n;} void addNeighbour(const PIString & n) {if (!neighbours.contains(n)) neighbours << n;}
@@ -203,11 +203,11 @@ private:
PIMutex mc_mutex, eth_mutex, peers_mutex, send_mutex, send_mc_mutex; PIMutex mc_mutex, eth_mutex, peers_mutex, send_mutex, send_mc_mutex;
}; };
inline PICout operator <<(PICout c, const PIPeer::PeerInfo::Address & v) {c.space(); c << "PeerAddress(" << v.address << ", " << v.netmask << ", " << v.ping << ")"; return c;} inline PICout operator <<(PICout c, const PIPeer::PeerInfo::PeerAddress & v) {c.space(); c << "PeerAddress(" << v.address << ", " << v.netmask << ", " << v.ping << ")"; return c;}
inline PICout operator <<(PICout c, const PIPeer::PeerInfo & v) {c.space(); c << "PeerInfo(" << v.name << ", " << v.dist << ", " << v.addresses << ")"; return c;} inline PICout operator <<(PICout c, const PIPeer::PeerInfo & v) {c.space(); c << "PeerInfo(" << v.name << ", " << v.dist << ", " << v.addresses << ")"; return c;}
inline PIByteArray & operator <<(PIByteArray & s, const PIPeer::PeerInfo::Address & v) {s << v.address << v.netmask << v.ping; return s;} inline PIByteArray & operator <<(PIByteArray & s, const PIPeer::PeerInfo::PeerAddress & v) {s << v.address << v.netmask << v.ping; return s;}
inline PIByteArray & operator >>(PIByteArray & s, PIPeer::PeerInfo::Address & v) {s >> v.address >> v.netmask >> v.ping; return s;} inline PIByteArray & operator >>(PIByteArray & s, PIPeer::PeerInfo::PeerAddress & v) {s >> v.address >> v.netmask >> v.ping; return s;}
inline PIByteArray & operator <<(PIByteArray & s, const PIPeer::PeerInfo & v) {s << v.name << v.addresses << v.dist << v.neighbours << v.cnt << v.time; return s;} inline PIByteArray & operator <<(PIByteArray & s, const PIPeer::PeerInfo & v) {s << v.name << v.addresses << v.dist << v.neighbours << v.cnt << v.time; return s;}
inline PIByteArray & operator >>(PIByteArray & s, PIPeer::PeerInfo & v) {s >> v.name >> v.addresses >> v.dist >> v.neighbours >> v.cnt >> v.time; return s;} inline PIByteArray & operator >>(PIByteArray & s, PIPeer::PeerInfo & v) {s >> v.name >> v.addresses >> v.dist >> v.neighbours >> v.cnt >> v.time; return s;}

View File

@@ -5,6 +5,6 @@
#define PIP_VERSION_MAJOR 1 #define PIP_VERSION_MAJOR 1
#define PIP_VERSION_MINOR 0 #define PIP_VERSION_MINOR 0
#define PIP_VERSION_REVISION 0 #define PIP_VERSION_REVISION 0
#define PIP_VERSION_SUFFIX "_rc5" #define PIP_VERSION_SUFFIX "_rc6"
#endif // PIVERSION_H #endif // PIVERSION_H

View File

@@ -192,8 +192,8 @@ public:
peerinfo_tl->content << TileSimple::Row("Name: " + pi.name, CellFormat()); peerinfo_tl->content << TileSimple::Row("Name: " + pi.name, CellFormat());
peerinfo_tl->content << TileSimple::Row("Addreses: " + PIString::fromNumber(pi.addresses.size()), CellFormat()); peerinfo_tl->content << TileSimple::Row("Addreses: " + PIString::fromNumber(pi.addresses.size()), CellFormat());
peerinfo_tl->content << TileSimple::Row("Neighbours: " + pi.neighbours.join(", "), CellFormat()); peerinfo_tl->content << TileSimple::Row("Neighbours: " + pi.neighbours.join(", "), CellFormat());
piForeachC(PIPeer::PeerInfo::Address &a , pi.addresses) piForeachC(PIPeer::PeerInfo::PeerAddress &a , pi.addresses)
addrs_tl->content << TileList::Row(a.address + addrs_tl->content << TileList::Row(a.address.toString() +
" | p = " + PIString::fromNumber(a.ping) + " | p = " + PIString::fromNumber(a.ping) +
" | a = " + PIString::fromBool(a.isAvailable()), CellFormat()); " | a = " + PIString::fromBool(a.isAvailable()), CellFormat());
typedef PIPair<PIString, PIVector <PIPeer::PeerInfo* > > PeerPair; typedef PIPair<PIString, PIVector <PIPeer::PeerInfo* > > PeerPair;