Added multithreaded unit tests to selftest, standardization pass: conditional statement spacing
This commit is contained in:
@@ -249,17 +249,17 @@ namespace ZeroTier {
|
|||||||
Mutex::Lock _l(_multicastGroups_m);
|
Mutex::Lock _l(_multicastGroups_m);
|
||||||
// TODO: get multicast subscriptions
|
// TODO: get multicast subscriptions
|
||||||
std::vector<InetAddress> allIps(ips());
|
std::vector<InetAddress> allIps(ips());
|
||||||
for(std::vector<InetAddress>::iterator ip(allIps.begin());ip!=allIps.end();++ip)
|
for (std::vector<InetAddress>::iterator ip(allIps.begin());ip!=allIps.end();++ip)
|
||||||
newGroups.push_back(MulticastGroup::deriveMulticastGroupForAddressResolution(*ip));
|
newGroups.push_back(MulticastGroup::deriveMulticastGroupForAddressResolution(*ip));
|
||||||
|
|
||||||
std::sort(newGroups.begin(),newGroups.end());
|
std::sort(newGroups.begin(),newGroups.end());
|
||||||
std::unique(newGroups.begin(),newGroups.end());
|
std::unique(newGroups.begin(),newGroups.end());
|
||||||
|
|
||||||
for(std::vector<MulticastGroup>::iterator m(newGroups.begin());m!=newGroups.end();++m) {
|
for (std::vector<MulticastGroup>::iterator m(newGroups.begin());m!=newGroups.end();++m) {
|
||||||
if (!std::binary_search(_multicastGroups.begin(),_multicastGroups.end(),*m))
|
if (!std::binary_search(_multicastGroups.begin(),_multicastGroups.end(),*m))
|
||||||
added.push_back(*m);
|
added.push_back(*m);
|
||||||
}
|
}
|
||||||
for(std::vector<MulticastGroup>::iterator m(_multicastGroups.begin());m!=_multicastGroups.end();++m) {
|
for (std::vector<MulticastGroup>::iterator m(_multicastGroups.begin());m!=_multicastGroups.end();++m) {
|
||||||
if (!std::binary_search(newGroups.begin(),newGroups.end(),*m))
|
if (!std::binary_search(newGroups.begin(),newGroups.end(),*m))
|
||||||
removed.push_back(*m);
|
removed.push_back(*m);
|
||||||
}
|
}
|
||||||
@@ -388,7 +388,7 @@ namespace ZeroTier {
|
|||||||
void VirtualTap::removeVirtualSocket(VirtualSocket *vs)
|
void VirtualTap::removeVirtualSocket(VirtualSocket *vs)
|
||||||
{
|
{
|
||||||
Mutex::Lock _l(_tcpconns_m);
|
Mutex::Lock _l(_tcpconns_m);
|
||||||
for(int i=0; i<_VirtualSockets.size(); i++) {
|
for (int i=0; i<_VirtualSockets.size(); i++) {
|
||||||
if (vs == _VirtualSockets[i]) {
|
if (vs == _VirtualSockets[i]) {
|
||||||
_VirtualSockets.erase(_VirtualSockets.begin() + i);
|
_VirtualSockets.erase(_VirtualSockets.begin() + i);
|
||||||
break;
|
break;
|
||||||
@@ -733,12 +733,12 @@ namespace ZeroTier {
|
|||||||
char ipbuf[INET6_ADDRSTRLEN], ipbuf2[INET6_ADDRSTRLEN], ipbuf3[INET6_ADDRSTRLEN];
|
char ipbuf[INET6_ADDRSTRLEN], ipbuf2[INET6_ADDRSTRLEN], ipbuf3[INET6_ADDRSTRLEN];
|
||||||
// TODO: Rework this when we have time
|
// TODO: Rework this when we have time
|
||||||
// check if pushed route exists in tap (add)
|
// check if pushed route exists in tap (add)
|
||||||
for(int i=0; i<ZT_MAX_NETWORK_ROUTES; i++) {
|
for (int i=0; i<ZT_MAX_NETWORK_ROUTES; i++) {
|
||||||
found = false;
|
found = false;
|
||||||
target_addr = managed_routes->at(i).target;
|
target_addr = managed_routes->at(i).target;
|
||||||
via_addr = managed_routes->at(i).via;
|
via_addr = managed_routes->at(i).via;
|
||||||
nm = target_addr.netmask();
|
nm = target_addr.netmask();
|
||||||
for(int j=0; j<routes.size(); j++) {
|
for (int j=0; j<routes.size(); j++) {
|
||||||
if (via_addr.ipsEqual(null_addr) || target_addr.ipsEqual(null_addr)) {
|
if (via_addr.ipsEqual(null_addr) || target_addr.ipsEqual(null_addr)) {
|
||||||
found=true;
|
found=true;
|
||||||
continue;
|
continue;
|
||||||
@@ -756,9 +756,9 @@ namespace ZeroTier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check if route exists in tap but not in pushed routes (remove)
|
// check if route exists in tap but not in pushed routes (remove)
|
||||||
for(int i=0; i<routes.size(); i++) {
|
for (int i=0; i<routes.size(); i++) {
|
||||||
found = false;
|
found = false;
|
||||||
for(int j=0; j<ZT_MAX_NETWORK_ROUTES; j++) {
|
for (int j=0; j<ZT_MAX_NETWORK_ROUTES; j++) {
|
||||||
target_addr = managed_routes->at(j).target;
|
target_addr = managed_routes->at(j).target;
|
||||||
via_addr = managed_routes->at(j).via;
|
via_addr = managed_routes->at(j).via;
|
||||||
nm = target_addr.netmask();
|
nm = target_addr.netmask();
|
||||||
|
|||||||
@@ -141,10 +141,10 @@ void zts_start(const char *path)
|
|||||||
void zts_simple_start(const char *path, const char *nwid)
|
void zts_simple_start(const char *path, const char *nwid)
|
||||||
{
|
{
|
||||||
zts_start(path);
|
zts_start(path);
|
||||||
while(zts_running() == false) {
|
while (zts_running() == false) {
|
||||||
nanosleep((const struct timespec[]) {{0, (ZT_API_CHECK_INTERVAL * 1000000)}}, NULL);
|
nanosleep((const struct timespec[]) {{0, (ZT_API_CHECK_INTERVAL * 1000000)}}, NULL);
|
||||||
}
|
}
|
||||||
while(true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
zts_join(nwid);
|
zts_join(nwid);
|
||||||
break;
|
break;
|
||||||
@@ -154,7 +154,7 @@ void zts_simple_start(const char *path, const char *nwid)
|
|||||||
handle_general_failure();
|
handle_general_failure();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while(zts_has_address(nwid) == false) {
|
while (zts_has_address(nwid) == false) {
|
||||||
nanosleep((const struct timespec[]) {{0, (ZT_API_CHECK_INTERVAL * 1000000)}}, NULL);
|
nanosleep((const struct timespec[]) {{0, (ZT_API_CHECK_INTERVAL * 1000000)}}, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,7 +181,7 @@ void zts_join(const char * nwid) {
|
|||||||
}
|
}
|
||||||
// provide ZTO service reference to virtual taps
|
// provide ZTO service reference to virtual taps
|
||||||
// TODO: This might prove to be unreliable, but it works for now
|
// TODO: This might prove to be unreliable, but it works for now
|
||||||
for(int i=0;i<ZeroTier::vtaps.size(); i++) {
|
for (int i=0;i<ZeroTier::vtaps.size(); i++) {
|
||||||
ZeroTier::VirtualTap *s = (ZeroTier::VirtualTap*)ZeroTier::vtaps[i];
|
ZeroTier::VirtualTap *s = (ZeroTier::VirtualTap*)ZeroTier::vtaps[i];
|
||||||
s->zt1ServiceRef=(void*)ZeroTier::zt1Service;
|
s->zt1ServiceRef=(void*)ZeroTier::zt1Service;
|
||||||
}
|
}
|
||||||
@@ -283,7 +283,7 @@ void zts_get_ipv4_address(const char *nwid, char *addrstr, const int addrlen)
|
|||||||
uint64_t nwid_int = strtoull(nwid, NULL, 16);
|
uint64_t nwid_int = strtoull(nwid, NULL, 16);
|
||||||
ZeroTier::VirtualTap *tap = getTapByNWID(nwid_int);
|
ZeroTier::VirtualTap *tap = getTapByNWID(nwid_int);
|
||||||
if (tap && tap->_ips.size()) {
|
if (tap && tap->_ips.size()) {
|
||||||
for(int i=0; i<tap->_ips.size(); i++) {
|
for (int i=0; i<tap->_ips.size(); i++) {
|
||||||
if (tap->_ips[i].isV4()) {
|
if (tap->_ips[i].isV4()) {
|
||||||
char ipbuf[INET_ADDRSTRLEN];
|
char ipbuf[INET_ADDRSTRLEN];
|
||||||
std::string addr = tap->_ips[i].toString(ipbuf);
|
std::string addr = tap->_ips[i].toString(ipbuf);
|
||||||
@@ -305,7 +305,7 @@ void zts_get_ipv6_address(const char *nwid, char *addrstr, const int addrlen)
|
|||||||
uint64_t nwid_int = strtoull(nwid, NULL, 16);
|
uint64_t nwid_int = strtoull(nwid, NULL, 16);
|
||||||
ZeroTier::VirtualTap *tap = getTapByNWID(nwid_int);
|
ZeroTier::VirtualTap *tap = getTapByNWID(nwid_int);
|
||||||
if (tap && tap->_ips.size()) {
|
if (tap && tap->_ips.size()) {
|
||||||
for(int i=0; i<tap->_ips.size(); i++) {
|
for (int i=0; i<tap->_ips.size(); i++) {
|
||||||
if (tap->_ips[i].isV6()) {
|
if (tap->_ips[i].isV6()) {
|
||||||
char ipbuf[INET6_ADDRSTRLEN];
|
char ipbuf[INET6_ADDRSTRLEN];
|
||||||
std::string addr = tap->_ips[i].toString(ipbuf);
|
std::string addr = tap->_ips[i].toString(ipbuf);
|
||||||
@@ -350,7 +350,7 @@ int zts_get_peer_address(char *peer, const char *devID) {
|
|||||||
if (ZeroTier::zt1Service) {
|
if (ZeroTier::zt1Service) {
|
||||||
ZT_PeerList *pl = ZeroTier::zt1Service->getNode()->peers();
|
ZT_PeerList *pl = ZeroTier::zt1Service->getNode()->peers();
|
||||||
// uint64_t addr;
|
// uint64_t addr;
|
||||||
for(int i=0; i<pl->peerCount; i++) {
|
for (int i=0; i<pl->peerCount; i++) {
|
||||||
// ZT_Peer *p = &(pl->peers[i]);
|
// ZT_Peer *p = &(pl->peers[i]);
|
||||||
// DEBUG_INFO("peer[%d] = %lx", i, p->address);
|
// DEBUG_INFO("peer[%d] = %lx", i, p->address);
|
||||||
}
|
}
|
||||||
@@ -395,6 +395,7 @@ Darwin:
|
|||||||
|
|
||||||
// int socket_family, int socket_type, int protocol
|
// int socket_family, int socket_type, int protocol
|
||||||
int zts_socket(ZT_SOCKET_SIG) {
|
int zts_socket(ZT_SOCKET_SIG) {
|
||||||
|
DEBUG_EXTRA();
|
||||||
int err = errno = 0;
|
int err = errno = 0;
|
||||||
if (socket_family < 0 || socket_type < 0 || protocol < 0) {
|
if (socket_family < 0 || socket_type < 0 || protocol < 0) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
@@ -599,12 +600,12 @@ int zts_connect(ZT_CONNECT_SIG) {
|
|||||||
}
|
}
|
||||||
if (blocking == true) {
|
if (blocking == true) {
|
||||||
bool complete = false;
|
bool complete = false;
|
||||||
while(true) {
|
while (true) {
|
||||||
// FIXME: locking and unlocking so often might cause significant performance overhead while outgoing VirtualSockets
|
// FIXME: locking and unlocking so often might cause significant performance overhead while outgoing VirtualSockets
|
||||||
// are being established (also applies to accept())
|
// are being established (also applies to accept())
|
||||||
nanosleep((const struct timespec[]) {{0, (ZT_CONNECT_RECHECK_DELAY * 1000000)}}, NULL);
|
nanosleep((const struct timespec[]) {{0, (ZT_CONNECT_RECHECK_DELAY * 1000000)}}, NULL);
|
||||||
tap->_tcpconns_m.lock();
|
tap->_tcpconns_m.lock();
|
||||||
for(int i=0; i<tap->_VirtualSockets.size(); i++) {
|
for (int i=0; i<tap->_VirtualSockets.size(); i++) {
|
||||||
#if defined(STACK_PICO)
|
#if defined(STACK_PICO)
|
||||||
if (tap->_VirtualSockets[i]->state == PICO_ERR_ECONNRESET) {
|
if (tap->_VirtualSockets[i]->state == PICO_ERR_ECONNRESET) {
|
||||||
errno = ECONNRESET;
|
errno = ECONNRESET;
|
||||||
@@ -821,7 +822,7 @@ int zts_accept(ZT_ACCEPT_SIG) {
|
|||||||
accepted_vs = tap->Accept(vs);
|
accepted_vs = tap->Accept(vs);
|
||||||
}
|
}
|
||||||
else { // blocking
|
else { // blocking
|
||||||
while(true) {
|
while (true) {
|
||||||
nanosleep((const struct timespec[]) {{0, (ZT_ACCEPT_RECHECK_DELAY * 1000000)}}, NULL);
|
nanosleep((const struct timespec[]) {{0, (ZT_ACCEPT_RECHECK_DELAY * 1000000)}}, NULL);
|
||||||
accepted_vs = tap->Accept(vs);
|
accepted_vs = tap->Accept(vs);
|
||||||
if (accepted_vs)
|
if (accepted_vs)
|
||||||
@@ -1097,7 +1098,7 @@ Linux / Darwin:
|
|||||||
|
|
||||||
int zts_close(ZT_CLOSE_SIG)
|
int zts_close(ZT_CLOSE_SIG)
|
||||||
{
|
{
|
||||||
//DEBUG_EXTRA("fd=%d", fd);
|
DEBUG_EXTRA("fd=%d", fd);
|
||||||
int err = errno = 0;
|
int err = errno = 0;
|
||||||
if (fd < 0 || fd >= ZT_MAX_SOCKETS) {
|
if (fd < 0 || fd >= ZT_MAX_SOCKETS) {
|
||||||
errno = EBADF;
|
errno = EBADF;
|
||||||
@@ -1667,7 +1668,7 @@ int zts_read(ZT_READ_SIG) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int zts_write(ZT_WRITE_SIG) {
|
int zts_write(ZT_WRITE_SIG) {
|
||||||
//DEBUG_TRANS("fd=%d", fd);
|
DEBUG_TRANS("fd=%d", fd);
|
||||||
return write(fd, buf, len);
|
return write(fd, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2085,7 +2086,7 @@ ZeroTier::VirtualTap *getTapByNWID(uint64_t nwid)
|
|||||||
{
|
{
|
||||||
ZeroTier::_vtaps_lock.lock();
|
ZeroTier::_vtaps_lock.lock();
|
||||||
ZeroTier::VirtualTap *s, *tap = nullptr;
|
ZeroTier::VirtualTap *s, *tap = nullptr;
|
||||||
for(int i=0; i<ZeroTier::vtaps.size(); i++) {
|
for (int i=0; i<ZeroTier::vtaps.size(); i++) {
|
||||||
s = (ZeroTier::VirtualTap*)ZeroTier::vtaps[i];
|
s = (ZeroTier::VirtualTap*)ZeroTier::vtaps[i];
|
||||||
if (s->_nwid == nwid) { tap = s; }
|
if (s->_nwid == nwid) { tap = s; }
|
||||||
}
|
}
|
||||||
@@ -2098,19 +2099,19 @@ ZeroTier::VirtualTap *getTapByAddr(ZeroTier::InetAddress *addr)
|
|||||||
ZeroTier::_vtaps_lock.lock();
|
ZeroTier::_vtaps_lock.lock();
|
||||||
ZeroTier::VirtualTap *s, *tap = nullptr;
|
ZeroTier::VirtualTap *s, *tap = nullptr;
|
||||||
//char ipbuf[64], ipbuf2[64], ipbuf3[64];
|
//char ipbuf[64], ipbuf2[64], ipbuf3[64];
|
||||||
for(int i=0; i<ZeroTier::vtaps.size(); i++) {
|
for (int i=0; i<ZeroTier::vtaps.size(); i++) {
|
||||||
s = (ZeroTier::VirtualTap*)ZeroTier::vtaps[i];
|
s = (ZeroTier::VirtualTap*)ZeroTier::vtaps[i];
|
||||||
// check address schemes
|
// check address schemes
|
||||||
for(int j=0; j<s->_ips.size(); j++) {
|
for (int j=0; j<s->_ips.size(); j++) {
|
||||||
if ((s->_ips[j].isV4() && addr->isV4()) || (s->_ips[j].isV6() && addr->isV6())) {
|
if ((s->_ips[j].isV4() && addr->isV4()) || (s->_ips[j].isV6() && addr->isV6())) {
|
||||||
//DEBUG_INFO("looking at tap %s, <addr=%s> --- for <%s>", s->_dev.c_str(), s->_ips[j].toString(ipbuf), addr->toIpString(ipbuf2));
|
//DEBUG_EXTRA("looking at tap %s, <addr=%s> --- for <%s>", s->_dev.c_str(), s->_ips[j].toString(ipbuf), addr->toIpString(ipbuf2));
|
||||||
if (s->_ips[j].isEqualPrefix(addr)
|
if (s->_ips[j].isEqualPrefix(addr)
|
||||||
|| s->_ips[j].ipsEqual(addr)
|
|| s->_ips[j].ipsEqual(addr)
|
||||||
|| s->_ips[j].containsAddress(addr)
|
|| s->_ips[j].containsAddress(addr)
|
||||||
|| (addr->isV6() && ipv6_in_subnet(&s->_ips[j], addr))
|
|| (addr->isV6() && ipv6_in_subnet(&s->_ips[j], addr))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//DEBUG_INFO("selected tap %s, <addr=%s>", s->_dev.c_str(), s->_ips[j].toString(ipbuf));
|
//DEBUG_EXTRA("selected tap %s, <addr=%s>", s->_dev.c_str(), s->_ips[j].toString(ipbuf));
|
||||||
ZeroTier::_vtaps_lock.unlock();
|
ZeroTier::_vtaps_lock.unlock();
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@@ -2120,12 +2121,12 @@ ZeroTier::VirtualTap *getTapByAddr(ZeroTier::InetAddress *addr)
|
|||||||
if (tap == NULL) {
|
if (tap == NULL) {
|
||||||
std::vector<ZT_VirtualNetworkRoute> *managed_routes = ZeroTier::zt1Service->getRoutes(s->_nwid);
|
std::vector<ZT_VirtualNetworkRoute> *managed_routes = ZeroTier::zt1Service->getRoutes(s->_nwid);
|
||||||
ZeroTier::InetAddress target, nm, via;
|
ZeroTier::InetAddress target, nm, via;
|
||||||
for(int i=0; i<managed_routes->size(); i++) {
|
for (int i=0; i<managed_routes->size(); i++) {
|
||||||
target = managed_routes->at(i).target;
|
target = managed_routes->at(i).target;
|
||||||
nm = target.netmask();
|
nm = target.netmask();
|
||||||
via = managed_routes->at(i).via;
|
via = managed_routes->at(i).via;
|
||||||
if (target.containsAddress(addr)) {
|
if (target.containsAddress(addr)) {
|
||||||
// DEBUG_INFO("chose tap with route <target=%s, nm=%s, via=%s>", target.toString(ipbuf), nm.toString(ipbuf2), via.toString(ipbuf3));
|
//DEBUG_EXTRA("chose tap with route <target=%s, nm=%s, via=%s>", target.toString(ipbuf), nm.toString(ipbuf2), via.toString(ipbuf3));
|
||||||
ZeroTier::_vtaps_lock.unlock();
|
ZeroTier::_vtaps_lock.unlock();
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@@ -2140,7 +2141,7 @@ ZeroTier::VirtualTap *getTapByName(char *ifname)
|
|||||||
{
|
{
|
||||||
ZeroTier::_vtaps_lock.lock();
|
ZeroTier::_vtaps_lock.lock();
|
||||||
ZeroTier::VirtualTap *s, *tap = nullptr;
|
ZeroTier::VirtualTap *s, *tap = nullptr;
|
||||||
for(int i=0; i<ZeroTier::vtaps.size(); i++) {
|
for (int i=0; i<ZeroTier::vtaps.size(); i++) {
|
||||||
s = (ZeroTier::VirtualTap*)ZeroTier::vtaps[i];
|
s = (ZeroTier::VirtualTap*)ZeroTier::vtaps[i];
|
||||||
if (strcmp(s->_dev.c_str(), ifname) == false) {
|
if (strcmp(s->_dev.c_str(), ifname) == false) {
|
||||||
tap = s;
|
tap = s;
|
||||||
@@ -2154,7 +2155,7 @@ ZeroTier::VirtualTap *getTapByIndex(int index)
|
|||||||
{
|
{
|
||||||
ZeroTier::_vtaps_lock.lock();
|
ZeroTier::_vtaps_lock.lock();
|
||||||
ZeroTier::VirtualTap *s, *tap = nullptr;
|
ZeroTier::VirtualTap *s, *tap = nullptr;
|
||||||
for(int i=0; i<ZeroTier::vtaps.size(); i++) {
|
for (int i=0; i<ZeroTier::vtaps.size(); i++) {
|
||||||
s = (ZeroTier::VirtualTap*)ZeroTier::vtaps[i];
|
s = (ZeroTier::VirtualTap*)ZeroTier::vtaps[i];
|
||||||
if (s->ifindex == index) {
|
if (s->ifindex == index) {
|
||||||
tap = s;
|
tap = s;
|
||||||
@@ -2318,7 +2319,7 @@ std::pair<ZeroTier::VirtualSocket*, ZeroTier::VirtualTap*> *get_assigned_virtual
|
|||||||
void disableTaps()
|
void disableTaps()
|
||||||
{
|
{
|
||||||
ZeroTier::_vtaps_lock.lock();
|
ZeroTier::_vtaps_lock.lock();
|
||||||
for(int i=0; i<ZeroTier::vtaps.size(); i++) {
|
for (int i=0; i<ZeroTier::vtaps.size(); i++) {
|
||||||
DEBUG_EXTRA("vt=%p", ZeroTier::vtaps[i]);
|
DEBUG_EXTRA("vt=%p", ZeroTier::vtaps[i]);
|
||||||
((ZeroTier::VirtualTap*)ZeroTier::vtaps[i])->_enabled = false;
|
((ZeroTier::VirtualTap*)ZeroTier::vtaps[i])->_enabled = false;
|
||||||
}
|
}
|
||||||
@@ -2351,7 +2352,7 @@ void *zts_start_service(void *thread_id)
|
|||||||
if (ZeroTier::homeDir[0] == ZT_PATH_SEPARATOR) {
|
if (ZeroTier::homeDir[0] == ZT_PATH_SEPARATOR) {
|
||||||
ptmp.push_back(ZT_PATH_SEPARATOR);
|
ptmp.push_back(ZT_PATH_SEPARATOR);
|
||||||
}
|
}
|
||||||
for(std::vector<std::string>::iterator pi(hpsp.begin());pi!=hpsp.end();++pi) {
|
for (std::vector<std::string>::iterator pi(hpsp.begin());pi!=hpsp.end();++pi) {
|
||||||
if (ptmp.length() > 0) {
|
if (ptmp.length() > 0) {
|
||||||
ptmp.push_back(ZT_PATH_SEPARATOR);
|
ptmp.push_back(ZT_PATH_SEPARATOR);
|
||||||
}
|
}
|
||||||
@@ -2376,7 +2377,7 @@ void *zts_start_service(void *thread_id)
|
|||||||
ZeroTier::Utils::getSecureRandom(&randp,sizeof(randp));
|
ZeroTier::Utils::getSecureRandom(&randp,sizeof(randp));
|
||||||
// TODO: Better port random range selection
|
// TODO: Better port random range selection
|
||||||
int servicePort = 9000 + (randp % 1000);
|
int servicePort = 9000 + (randp % 1000);
|
||||||
for(;;) {
|
for (;;) {
|
||||||
ZeroTier::zt1Service = ZeroTier::OneService::newInstance(ZeroTier::homeDir.c_str(),servicePort);
|
ZeroTier::zt1Service = ZeroTier::OneService::newInstance(ZeroTier::homeDir.c_str(),servicePort);
|
||||||
switch(ZeroTier::zt1Service->run()) {
|
switch(ZeroTier::zt1Service->run()) {
|
||||||
case ZeroTier::OneService::ONE_STILL_RUNNING:
|
case ZeroTier::OneService::ONE_STILL_RUNNING:
|
||||||
|
|||||||
20
src/lwIP.cpp
20
src/lwIP.cpp
@@ -70,7 +70,7 @@ err_t lwip_eth_tx(struct netif *netif, struct pbuf *p)
|
|||||||
|
|
||||||
ZeroTier::VirtualTap *tap = (ZeroTier::VirtualTap*)netif->state;
|
ZeroTier::VirtualTap *tap = (ZeroTier::VirtualTap*)netif->state;
|
||||||
bufptr = buf;
|
bufptr = buf;
|
||||||
for(q = p; q != NULL; q = q->next) {
|
for (q = p; q != NULL; q = q->next) {
|
||||||
memcpy(bufptr, q->payload, q->len);
|
memcpy(bufptr, q->payload, q->len);
|
||||||
bufptr += q->len;
|
bufptr += q->len;
|
||||||
totalLength += q->len;
|
totalLength += q->len;
|
||||||
@@ -196,24 +196,24 @@ namespace ZeroTier
|
|||||||
// TODO: These will likely need some sort of locking protection
|
// TODO: These will likely need some sort of locking protection
|
||||||
int count = 0;
|
int count = 0;
|
||||||
struct tcp_pcb *pcb_ptr = tcp_active_pcbs; // PCBs that can RX/TX data
|
struct tcp_pcb *pcb_ptr = tcp_active_pcbs; // PCBs that can RX/TX data
|
||||||
while(pcb_ptr) {
|
while (pcb_ptr) {
|
||||||
pcb_ptr = pcb_ptr->next;
|
pcb_ptr = pcb_ptr->next;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
pcb_ptr = tcp_tw_pcbs; // PCBs in TIME-WAIT state
|
pcb_ptr = tcp_tw_pcbs; // PCBs in TIME-WAIT state
|
||||||
while(pcb_ptr) {
|
while (pcb_ptr) {
|
||||||
pcb_ptr = pcb_ptr->next;
|
pcb_ptr = pcb_ptr->next;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
/* TODO
|
/* TODO
|
||||||
pcb_ptr = tcp_listen_pcbs;
|
pcb_ptr = tcp_listen_pcbs;
|
||||||
while(pcb_ptr) {
|
while (pcb_ptr) {
|
||||||
pcb_ptr = pcb_ptr->next;
|
pcb_ptr = pcb_ptr->next;
|
||||||
count++;
|
count++;
|
||||||
DEBUG_ERROR("FOUND --- tcp_listen_pcbs PCB COUNT = %d", count);
|
DEBUG_ERROR("FOUND --- tcp_listen_pcbs PCB COUNT = %d", count);
|
||||||
}*/
|
}*/
|
||||||
pcb_ptr = tcp_bound_pcbs; // PCBs in a bound state
|
pcb_ptr = tcp_bound_pcbs; // PCBs in a bound state
|
||||||
while(pcb_ptr) {
|
while (pcb_ptr) {
|
||||||
pcb_ptr = pcb_ptr->next;
|
pcb_ptr = pcb_ptr->next;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@@ -225,7 +225,7 @@ namespace ZeroTier
|
|||||||
// TODO: These will likely need some sort of locking protection
|
// TODO: These will likely need some sort of locking protection
|
||||||
int count = 0;
|
int count = 0;
|
||||||
struct udp_pcb *pcb_ptr = udp_pcbs;
|
struct udp_pcb *pcb_ptr = udp_pcbs;
|
||||||
while(pcb_ptr) {
|
while (pcb_ptr) {
|
||||||
pcb_ptr = pcb_ptr->next;
|
pcb_ptr = pcb_ptr->next;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@@ -238,7 +238,7 @@ namespace ZeroTier
|
|||||||
/*
|
/*
|
||||||
int count = 0;
|
int count = 0;
|
||||||
struct raw_pcb *pcb_ptr = raw_pcbs;
|
struct raw_pcb *pcb_ptr = raw_pcbs;
|
||||||
while(pcb_ptr) {
|
while (pcb_ptr) {
|
||||||
pcb_ptr = pcb_ptr->next;
|
pcb_ptr = pcb_ptr->next;
|
||||||
count++;
|
count++;
|
||||||
DEBUG_ERROR("FOUND --- raw_pcbs PCB COUNT = %d", count);
|
DEBUG_ERROR("FOUND --- raw_pcbs PCB COUNT = %d", count);
|
||||||
@@ -266,7 +266,7 @@ namespace ZeroTier
|
|||||||
void lwIP::lwip_loop(VirtualTap *tap)
|
void lwIP::lwip_loop(VirtualTap *tap)
|
||||||
{
|
{
|
||||||
uint64_t prev_tcp_time = 0, prev_discovery_time = 0;
|
uint64_t prev_tcp_time = 0, prev_discovery_time = 0;
|
||||||
while(tap->_run)
|
while (tap->_run)
|
||||||
{
|
{
|
||||||
uint64_t now = OSUtils::now();
|
uint64_t now = OSUtils::now();
|
||||||
uint64_t since_tcp = now - prev_tcp_time;
|
uint64_t since_tcp = now - prev_tcp_time;
|
||||||
@@ -745,7 +745,7 @@ namespace ZeroTier
|
|||||||
vs->tap->_tcpconns_m.lock();
|
vs->tap->_tcpconns_m.lock();
|
||||||
vs->_rx_m.lock();
|
vs->_rx_m.lock();
|
||||||
// cycle through pbufs and write them to the RX buffer
|
// cycle through pbufs and write them to the RX buffer
|
||||||
while(p != NULL) {
|
while (p != NULL) {
|
||||||
if (p->len <= 0) {
|
if (p->len <= 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -853,7 +853,7 @@ namespace ZeroTier
|
|||||||
memset(udp_payload_buf, 0, sizeof(ZT_SOCKET_MSG_BUF_SZ));
|
memset(udp_payload_buf, 0, sizeof(ZT_SOCKET_MSG_BUF_SZ));
|
||||||
char *msg_ptr = udp_payload_buf;
|
char *msg_ptr = udp_payload_buf;
|
||||||
int tot_len = 0;
|
int tot_len = 0;
|
||||||
while(p != NULL) {
|
while (p != NULL) {
|
||||||
if (p->len <= 0) {
|
if (p->len <= 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ namespace ZeroTier {
|
|||||||
|
|
||||||
void picoTCP::pico_loop(VirtualTap *tap)
|
void picoTCP::pico_loop(VirtualTap *tap)
|
||||||
{
|
{
|
||||||
while(tap->_run)
|
while (tap->_run)
|
||||||
{
|
{
|
||||||
tap->_phy.poll(ZT_PHY_POLL_INTERVAL);
|
tap->_phy.poll(ZT_PHY_POLL_INTERVAL);
|
||||||
//_picostack_driver_lock.lock();
|
//_picostack_driver_lock.lock();
|
||||||
@@ -297,7 +297,7 @@ namespace ZeroTier {
|
|||||||
handle_general_failure();
|
handle_general_failure();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while(r > 0);
|
while (r > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// from stack socket to app socket
|
// from stack socket to app socket
|
||||||
|
|||||||
@@ -24,8 +24,6 @@
|
|||||||
* of your own application.
|
* of your own application.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Comprehensive stress test for socket-like API
|
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
@@ -51,14 +49,15 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#include "libzt.h"
|
#include "libzt.h"
|
||||||
|
#include "Utils.hpp"
|
||||||
|
|
||||||
#define EXIT_ON_FAIL false
|
#define EXIT_ON_FAIL false
|
||||||
|
|
||||||
#define PASSED 1
|
#define PASSED 1
|
||||||
#define FAILED 0
|
#define FAILED 0
|
||||||
|
|
||||||
#define ECHO_INTERVAL 1000000 // us
|
#define ECHO_INTERVAL 1000000 // microseconds
|
||||||
#define SLAM_INTERVAL 500000
|
#define SLAM_INTERVAL 500000 // microseconds
|
||||||
|
|
||||||
#define WAIT_FOR_TEST_TO_CONCLUDE 0
|
#define WAIT_FOR_TEST_TO_CONCLUDE 0
|
||||||
#define WAIT_FOR_TRANSMISSION_TO_COMPLETE 5
|
#define WAIT_FOR_TRANSMISSION_TO_COMPLETE 5
|
||||||
@@ -80,12 +79,15 @@
|
|||||||
#define MIN_PORT 5000
|
#define MIN_PORT 5000
|
||||||
#define MAX_PORT 50000
|
#define MAX_PORT 50000
|
||||||
|
|
||||||
#define TCP_UNIT_TEST_SIG_4 struct sockaddr_in *addr, int op, int cnt, char *details, bool *passed
|
#define TCP_UNIT_TEST_SIG_4 struct sockaddr_in *addr, int op, int cnt, char *details, \
|
||||||
#define UDP_UNIT_TEST_SIG_4 struct sockaddr_in *local_addr, struct sockaddr_in *remote_addr, int op, int cnt, char *details, bool *passed
|
bool *passed
|
||||||
|
#define UDP_UNIT_TEST_SIG_4 struct sockaddr_in *local_addr, struct sockaddr_in *remote_addr, \
|
||||||
#define TCP_UNIT_TEST_SIG_6 struct sockaddr_in6 *addr, int op, int cnt, char *details, bool *passed
|
int op, int cnt, char *details, bool *passed
|
||||||
#define UDP_UNIT_TEST_SIG_6 struct sockaddr_in6 *local_addr, struct sockaddr_in6 *remote_addr, int op, int cnt, char *details, bool *passed
|
|
||||||
|
|
||||||
|
#define TCP_UNIT_TEST_SIG_6 struct sockaddr_in6 *addr, int op, int cnt, char *details, \
|
||||||
|
bool *passed
|
||||||
|
#define UDP_UNIT_TEST_SIG_6 struct sockaddr_in6 *local_addr, struct sockaddr_in6 *remote_addr, \
|
||||||
|
int op, int cnt, char *details, bool *passed
|
||||||
|
|
||||||
#define ECHOTEST_MODE_RX 333
|
#define ECHOTEST_MODE_RX 333
|
||||||
#define ECHOTEST_MODE_TX 666
|
#define ECHOTEST_MODE_TX 666
|
||||||
@@ -192,9 +194,10 @@ std::map<std::string, std::string> testConf;
|
|||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
void displayResults(int *results, int size) {
|
void displayResults(int *results, int size)
|
||||||
|
{
|
||||||
int success = 0, failure = 0;
|
int success = 0, failure = 0;
|
||||||
for(int i=0; i<size; i++) {
|
for (int i=0; i<size; i++) {
|
||||||
if (results[i] == 0) {
|
if (results[i] == 0) {
|
||||||
success++;
|
success++;
|
||||||
}
|
}
|
||||||
@@ -207,7 +210,8 @@ void displayResults(int *results, int size) {
|
|||||||
std::cout << " - failure = " << (float)failure / (float)size << std::endl;
|
std::cout << " - failure = " << (float)failure / (float)size << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadTestConfigFile(std::string filepath) {
|
void loadTestConfigFile(std::string filepath)
|
||||||
|
{
|
||||||
std::string key, value, prefix;
|
std::string key, value, prefix;
|
||||||
std::ifstream testFile;
|
std::ifstream testFile;
|
||||||
testFile.open(filepath.c_str());
|
testFile.open(filepath.c_str());
|
||||||
@@ -224,19 +228,22 @@ void loadTestConfigFile(std::string filepath) {
|
|||||||
testFile.close();
|
testFile.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
long int get_now_ts() {
|
long int get_now_ts()
|
||||||
|
{
|
||||||
struct timeval tp;
|
struct timeval tp;
|
||||||
gettimeofday(&tp, NULL);
|
gettimeofday(&tp, NULL);
|
||||||
return tp.tv_sec * 1000 + tp.tv_usec / 1000;
|
return tp.tv_sec * 1000 + tp.tv_usec / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for syncronizing tests
|
// for syncronizing tests
|
||||||
void wait_until_tplus(long int original_time, int tplus_ms) {
|
void wait_until_tplus(long int original_time, int tplus_ms)
|
||||||
while(original_time + tplus_ms > get_now_ts()) {
|
{
|
||||||
|
while (original_time + tplus_ms > get_now_ts()) {
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void wait_until_tplus_s(long int original_time, int tplus_s) {
|
void wait_until_tplus_s(long int original_time, int tplus_s)
|
||||||
|
{
|
||||||
int current_time_offset = (get_now_ts() - original_time) / 1000;
|
int current_time_offset = (get_now_ts() - original_time) / 1000;
|
||||||
fprintf(stderr, "\n\n--- WAITING FOR T+%d --- (current: T+%d)\n\n", tplus_s, current_time_offset);
|
fprintf(stderr, "\n\n--- WAITING FOR T+%d --- (current: T+%d)\n\n", tplus_s, current_time_offset);
|
||||||
if (current_time_offset > tplus_s) {
|
if (current_time_offset > tplus_s) {
|
||||||
@@ -249,15 +256,24 @@ void wait_until_tplus_s(long int original_time, int tplus_s) {
|
|||||||
wait_until_tplus(original_time, tplus_s * 1000);
|
wait_until_tplus(original_time, tplus_s * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void generate_random_data(void *buf, size_t n, int min, int max) {
|
int rand_in_range(int min, int max)
|
||||||
|
{
|
||||||
|
unsigned int seed;
|
||||||
|
ZeroTier::Utils::getSecureRandom((void*)&seed,sizeof(seed));
|
||||||
|
srand(seed);
|
||||||
|
return min + rand() % static_cast<int>(max - min + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void generate_random_data(void *buf, size_t n, int min, int max)
|
||||||
|
{
|
||||||
char *b = (char*)buf;
|
char *b = (char*)buf;
|
||||||
srand((unsigned)time(0));
|
for (int i=0; i<n; i++) {
|
||||||
for(int i=0; i<n; i++) {
|
b[i] = rand_in_range(min, max);
|
||||||
b[i] = min + (rand() % static_cast<int>(max - min + 1));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void str2addr(std::string ipstr, int port, int ipv, struct sockaddr *saddr) {
|
void str2addr(std::string ipstr, int port, int ipv, struct sockaddr *saddr)
|
||||||
|
{
|
||||||
if (ipv == 4) {
|
if (ipv == 4) {
|
||||||
struct sockaddr_in *in4 = (struct sockaddr_in*)saddr;
|
struct sockaddr_in *in4 = (struct sockaddr_in*)saddr;
|
||||||
in4->sin_port = htons(port);
|
in4->sin_port = htons(port);
|
||||||
@@ -556,7 +572,7 @@ void udp_client_4(UDP_UNIT_TEST_SIG_4)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct sockaddr_storage saddr;
|
struct sockaddr_storage saddr;
|
||||||
while(true) {
|
while (true) {
|
||||||
sleep(1);
|
sleep(1);
|
||||||
// tx
|
// tx
|
||||||
if ((w = SENDTO(fd, msg.c_str(), strlen(msg.c_str()), 0, (struct sockaddr *)remote_addr, sizeof(*remote_addr))) < 0) {
|
if ((w = SENDTO(fd, msg.c_str(), strlen(msg.c_str()), 0, (struct sockaddr *)remote_addr, sizeof(*remote_addr))) < 0) {
|
||||||
@@ -622,7 +638,7 @@ void udp_server_4(UDP_UNIT_TEST_SIG_4)
|
|||||||
DEBUG_TEST("sending DGRAM(s) to %s : %d", inet_ntoa(remote_addr->sin_addr), ntohs(remote_addr->sin_port));
|
DEBUG_TEST("sending DGRAM(s) to %s : %d", inet_ntoa(remote_addr->sin_addr), ntohs(remote_addr->sin_port));
|
||||||
// tx
|
// tx
|
||||||
long int tx_ti = get_now_ts();
|
long int tx_ti = get_now_ts();
|
||||||
while(true) {
|
while (true) {
|
||||||
sleep(1);
|
sleep(1);
|
||||||
if ((w = SENDTO(fd, msg.c_str(), len, 0, (struct sockaddr *)remote_addr, sizeof(*remote_addr))) < 0) {
|
if ((w = SENDTO(fd, msg.c_str(), len, 0, (struct sockaddr *)remote_addr, sizeof(*remote_addr))) < 0) {
|
||||||
DEBUG_ERROR("error sending packet, err=%d", errno);
|
DEBUG_ERROR("error sending packet, err=%d", errno);
|
||||||
@@ -676,7 +692,7 @@ void udp_client_6(UDP_UNIT_TEST_SIG_6)
|
|||||||
|
|
||||||
// start sending UDP packets in the hopes that at least one will be picked up by the server
|
// start sending UDP packets in the hopes that at least one will be picked up by the server
|
||||||
struct sockaddr_storage saddr;
|
struct sockaddr_storage saddr;
|
||||||
while(true) {
|
while (true) {
|
||||||
// tx
|
// tx
|
||||||
if ((w = SENDTO(fd, msg.c_str(), len, 0, (struct sockaddr *)remote_addr, sizeof(*remote_addr))) < 0) {
|
if ((w = SENDTO(fd, msg.c_str(), len, 0, (struct sockaddr *)remote_addr, sizeof(*remote_addr))) < 0) {
|
||||||
DEBUG_ERROR("error sending packet, err=%d", errno);
|
DEBUG_ERROR("error sending packet, err=%d", errno);
|
||||||
@@ -745,7 +761,7 @@ void udp_server_6(UDP_UNIT_TEST_SIG_6)
|
|||||||
// once we receive a UDP packet, spend 10 seconds sending responses in the hopes that the client will see
|
// once we receive a UDP packet, spend 10 seconds sending responses in the hopes that the client will see
|
||||||
// tx
|
// tx
|
||||||
long int tx_ti = get_now_ts();
|
long int tx_ti = get_now_ts();
|
||||||
while(true) {
|
while (true) {
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
//DEBUG_TEST("sending UDP packet");
|
//DEBUG_TEST("sending UDP packet");
|
||||||
if ((w = SENDTO(fd, msg.c_str(), len, 0, (struct sockaddr *)remote_addr, sizeof(*remote_addr))) < 0) {
|
if ((w = SENDTO(fd, msg.c_str(), len, 0, (struct sockaddr *)remote_addr, sizeof(*remote_addr))) < 0) {
|
||||||
@@ -805,7 +821,7 @@ void tcp_client_sustained_4(TCP_UNIT_TEST_SIG_4)
|
|||||||
int wrem = cnt, rrem = cnt;
|
int wrem = cnt, rrem = cnt;
|
||||||
// TX
|
// TX
|
||||||
long int tx_ti = get_now_ts();
|
long int tx_ti = get_now_ts();
|
||||||
while(wrem) {
|
while (wrem) {
|
||||||
int next_write = std::min(4096, wrem);
|
int next_write = std::min(4096, wrem);
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
n = WRITE(fd, &txbuf[w], next_write);
|
n = WRITE(fd, &txbuf[w], next_write);
|
||||||
@@ -820,7 +836,7 @@ void tcp_client_sustained_4(TCP_UNIT_TEST_SIG_4)
|
|||||||
DEBUG_TEST("wrote=%d, reading next...", w);
|
DEBUG_TEST("wrote=%d, reading next...", w);
|
||||||
// RX
|
// RX
|
||||||
long int rx_ti = 0;
|
long int rx_ti = 0;
|
||||||
while(rrem) {
|
while (rrem) {
|
||||||
n = READ(fd, &rxbuf[r], rrem);
|
n = READ(fd, &rxbuf[r], rrem);
|
||||||
if (rx_ti == 0) { // wait for first message
|
if (rx_ti == 0) { // wait for first message
|
||||||
rx_ti = get_now_ts();
|
rx_ti = get_now_ts();
|
||||||
@@ -837,7 +853,7 @@ void tcp_client_sustained_4(TCP_UNIT_TEST_SIG_4)
|
|||||||
err = CLOSE(fd);
|
err = CLOSE(fd);
|
||||||
// Compare RX and TX buffer and detect mismatches
|
// Compare RX and TX buffer and detect mismatches
|
||||||
bool match = true;
|
bool match = true;
|
||||||
for(int i=0; i<cnt; i++) {
|
for (int i=0; i<cnt; i++) {
|
||||||
if (rxbuf[i] != txbuf[i]) {
|
if (rxbuf[i] != txbuf[i]) {
|
||||||
DEBUG_ERROR("buffer mismatch found at idx=%d", i);
|
DEBUG_ERROR("buffer mismatch found at idx=%d", i);
|
||||||
match=false;
|
match=false;
|
||||||
@@ -887,7 +903,7 @@ void tcp_client_sustained_6(TCP_UNIT_TEST_SIG_6)
|
|||||||
int wrem = cnt, rrem = cnt;
|
int wrem = cnt, rrem = cnt;
|
||||||
// TX
|
// TX
|
||||||
long int tx_ti = get_now_ts();
|
long int tx_ti = get_now_ts();
|
||||||
while(wrem) {
|
while (wrem) {
|
||||||
int next_write = std::min(4096, wrem);
|
int next_write = std::min(4096, wrem);
|
||||||
n = WRITE(fd, &txbuf[w], next_write);
|
n = WRITE(fd, &txbuf[w], next_write);
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
@@ -900,7 +916,7 @@ void tcp_client_sustained_6(TCP_UNIT_TEST_SIG_6)
|
|||||||
DEBUG_TEST("wrote=%d", w);
|
DEBUG_TEST("wrote=%d", w);
|
||||||
// RX
|
// RX
|
||||||
long int rx_ti = 0;
|
long int rx_ti = 0;
|
||||||
while(rrem) {
|
while (rrem) {
|
||||||
n = READ(fd, &rxbuf[r], rrem);
|
n = READ(fd, &rxbuf[r], rrem);
|
||||||
if (rx_ti == 0) { // wait for first message
|
if (rx_ti == 0) { // wait for first message
|
||||||
rx_ti = get_now_ts();
|
rx_ti = get_now_ts();
|
||||||
@@ -917,7 +933,7 @@ void tcp_client_sustained_6(TCP_UNIT_TEST_SIG_6)
|
|||||||
err = CLOSE(fd);
|
err = CLOSE(fd);
|
||||||
// Compare RX and TX buffer and detect mismatches
|
// Compare RX and TX buffer and detect mismatches
|
||||||
bool match = true;
|
bool match = true;
|
||||||
for(int i=0; i<cnt; i++) {
|
for (int i=0; i<cnt; i++) {
|
||||||
if (rxbuf[i] != txbuf[i]) {
|
if (rxbuf[i] != txbuf[i]) {
|
||||||
DEBUG_ERROR("buffer mismatch found at idx=%d", i);
|
DEBUG_ERROR("buffer mismatch found at idx=%d", i);
|
||||||
match=false;
|
match=false;
|
||||||
@@ -979,7 +995,7 @@ void tcp_server_sustained_4(TCP_UNIT_TEST_SIG_4)
|
|||||||
if (op == TEST_OP_N_BYTES) {
|
if (op == TEST_OP_N_BYTES) {
|
||||||
int wrem = cnt, rrem = cnt;
|
int wrem = cnt, rrem = cnt;
|
||||||
long int rx_ti = 0;
|
long int rx_ti = 0;
|
||||||
while(rrem) {
|
while (rrem) {
|
||||||
n = READ(client_fd, &rxbuf[r], rrem);
|
n = READ(client_fd, &rxbuf[r], rrem);
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
if (rx_ti == 0) { // wait for first message
|
if (rx_ti == 0) { // wait for first message
|
||||||
@@ -994,7 +1010,7 @@ void tcp_server_sustained_4(TCP_UNIT_TEST_SIG_4)
|
|||||||
long int rx_tf = get_now_ts();
|
long int rx_tf = get_now_ts();
|
||||||
DEBUG_TEST("read=%d, writing next...", r);
|
DEBUG_TEST("read=%d, writing next...", r);
|
||||||
long int tx_ti = get_now_ts();
|
long int tx_ti = get_now_ts();
|
||||||
while(wrem) {
|
while (wrem) {
|
||||||
int next_write = std::min(1024, wrem);
|
int next_write = std::min(1024, wrem);
|
||||||
n = WRITE(client_fd, &rxbuf[w], next_write);
|
n = WRITE(client_fd, &rxbuf[w], next_write);
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
@@ -1067,7 +1083,7 @@ void tcp_server_sustained_6(TCP_UNIT_TEST_SIG_6)
|
|||||||
if (op == TEST_OP_N_BYTES) {
|
if (op == TEST_OP_N_BYTES) {
|
||||||
int wrem = cnt, rrem = cnt;
|
int wrem = cnt, rrem = cnt;
|
||||||
long int rx_ti = 0;
|
long int rx_ti = 0;
|
||||||
while(rrem) {
|
while (rrem) {
|
||||||
n = READ(client_fd, &rxbuf[r], rrem);
|
n = READ(client_fd, &rxbuf[r], rrem);
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
if (rx_ti == 0) { // wait for first message
|
if (rx_ti == 0) { // wait for first message
|
||||||
@@ -1081,7 +1097,7 @@ void tcp_server_sustained_6(TCP_UNIT_TEST_SIG_6)
|
|||||||
long int rx_tf = get_now_ts();
|
long int rx_tf = get_now_ts();
|
||||||
DEBUG_TEST("read=%d", r);
|
DEBUG_TEST("read=%d", r);
|
||||||
long int tx_ti = get_now_ts();
|
long int tx_ti = get_now_ts();
|
||||||
while(wrem) {
|
while (wrem) {
|
||||||
int next_write = std::min(1024, wrem);
|
int next_write = std::min(1024, wrem);
|
||||||
n = WRITE(client_fd, &rxbuf[w], next_write);
|
n = WRITE(client_fd, &rxbuf[w], next_write);
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
@@ -1140,7 +1156,7 @@ void udp_client_sustained_4(UDP_UNIT_TEST_SIG_4)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int num_to_send = 10;
|
int num_to_send = 10;
|
||||||
for(int i=0; i<num_to_send; i++) {
|
for (int i=0; i<num_to_send; i++) {
|
||||||
// tx
|
// tx
|
||||||
if ((w = SENDTO(fd, msg.c_str(), strlen(msg.c_str()), 0, (struct sockaddr *)remote_addr, sizeof(*remote_addr))) < 0) {
|
if ((w = SENDTO(fd, msg.c_str(), strlen(msg.c_str()), 0, (struct sockaddr *)remote_addr, sizeof(*remote_addr))) < 0) {
|
||||||
DEBUG_ERROR("error sending packet, err=%d", errno);
|
DEBUG_ERROR("error sending packet, err=%d", errno);
|
||||||
@@ -1182,7 +1198,7 @@ void udp_server_sustained_4(UDP_UNIT_TEST_SIG_4)
|
|||||||
}
|
}
|
||||||
int num_to_recv = 3;
|
int num_to_recv = 3;
|
||||||
DEBUG_TEST("waiting for UDP packet...");
|
DEBUG_TEST("waiting for UDP packet...");
|
||||||
for(int i=0; i<num_to_recv; i++) {
|
for (int i=0; i<num_to_recv; i++) {
|
||||||
// rx
|
// rx
|
||||||
struct sockaddr_storage saddr;
|
struct sockaddr_storage saddr;
|
||||||
struct sockaddr_in *in4 = (struct sockaddr_in*)&saddr;
|
struct sockaddr_in *in4 = (struct sockaddr_in*)&saddr;
|
||||||
@@ -1237,7 +1253,7 @@ void udp_client_sustained_6(UDP_UNIT_TEST_SIG_6)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int num_to_send = 10;
|
int num_to_send = 10;
|
||||||
for(int i=0; i<num_to_send; i++) {
|
for (int i=0; i<num_to_send; i++) {
|
||||||
sleep(1);
|
sleep(1);
|
||||||
// tx
|
// tx
|
||||||
if ((w = SENDTO(fd, msg.c_str(), strlen(msg.c_str()), 0, (struct sockaddr *)remote_addr, sizeof(*remote_addr))) < 0) {
|
if ((w = SENDTO(fd, msg.c_str(), strlen(msg.c_str()), 0, (struct sockaddr *)remote_addr, sizeof(*remote_addr))) < 0) {
|
||||||
@@ -1280,7 +1296,7 @@ void udp_server_sustained_6(UDP_UNIT_TEST_SIG_6)
|
|||||||
}
|
}
|
||||||
int num_to_recv = 3;
|
int num_to_recv = 3;
|
||||||
DEBUG_TEST("waiting for UDP packet...");
|
DEBUG_TEST("waiting for UDP packet...");
|
||||||
for(int i=0; i<num_to_recv; i++) {
|
for (int i=0; i<num_to_recv; i++) {
|
||||||
// rx
|
// rx
|
||||||
struct sockaddr_storage saddr;
|
struct sockaddr_storage saddr;
|
||||||
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)&saddr;
|
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)&saddr;
|
||||||
@@ -1331,7 +1347,7 @@ void tcp_client_perf_4(TCP_UNIT_TEST_SIG_4)
|
|||||||
w = 0;
|
w = 0;
|
||||||
|
|
||||||
// TX
|
// TX
|
||||||
while(w < total_test_sz)
|
while (w < total_test_sz)
|
||||||
w += WRITE(fd, rbuf, chunk_sz);
|
w += WRITE(fd, rbuf, chunk_sz);
|
||||||
|
|
||||||
long int end_time = get_now_ts();
|
long int end_time = get_now_ts();
|
||||||
@@ -1374,7 +1390,7 @@ void tcp_server_perf_4(TCP_UNIT_TEST_SIG_4)
|
|||||||
r = 0;
|
r = 0;
|
||||||
|
|
||||||
// RX
|
// RX
|
||||||
while(r < total_test_sz)
|
while (r < total_test_sz)
|
||||||
r += READ(client_fd, rbuf, chunk_sz);
|
r += READ(client_fd, rbuf, chunk_sz);
|
||||||
|
|
||||||
long int end_time = get_now_ts();
|
long int end_time = get_now_ts();
|
||||||
@@ -1437,7 +1453,7 @@ void tcp_perf_tx_echo_4(TCP_UNIT_TEST_SIG_4)
|
|||||||
|
|
||||||
// begin
|
// begin
|
||||||
DEBUG_TEST("beginning test, sending test byte stream...");
|
DEBUG_TEST("beginning test, sending test byte stream...");
|
||||||
while(tot < cnt) {
|
while (tot < cnt) {
|
||||||
if ((w = WRITE(fd, tbuf, sizeof tbuf)) < 0) {
|
if ((w = WRITE(fd, tbuf, sizeof tbuf)) < 0) {
|
||||||
DEBUG_ERROR("error while sending test byte stream to echotest (err=%d)", w);
|
DEBUG_ERROR("error while sending test byte stream to echotest (err=%d)", w);
|
||||||
return;
|
return;
|
||||||
@@ -1517,7 +1533,7 @@ void tcp_perf_rx_echo_4(TCP_UNIT_TEST_SIG_4)
|
|||||||
long int start_time = get_now_ts();
|
long int start_time = get_now_ts();
|
||||||
DEBUG_TEST("Received first set of bytes in test stream. now keeping time");
|
DEBUG_TEST("Received first set of bytes in test stream. now keeping time");
|
||||||
|
|
||||||
while(tot < cnt) {
|
while (tot < cnt) {
|
||||||
if ((r = read(fd, tbuf, sizeof tbuf)) < 0) {
|
if ((r = read(fd, tbuf, sizeof tbuf)) < 0) {
|
||||||
DEBUG_ERROR("there was an error reading the test stream. aborting (err=%d)", r);
|
DEBUG_ERROR("there was an error reading the test stream. aborting (err=%d)", r);
|
||||||
return;
|
return;
|
||||||
@@ -1544,7 +1560,8 @@ void tcp_perf_rx_echo_4(TCP_UNIT_TEST_SIG_4)
|
|||||||
|
|
||||||
int obscure_api_test(bool *passed)
|
int obscure_api_test(bool *passed)
|
||||||
{
|
{
|
||||||
DEBUG_TEST("obscure_api_test");
|
fprintf(stderr, "\n\nobscure API test\n\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// ---
|
// ---
|
||||||
// getpeername()
|
// getpeername()
|
||||||
@@ -1595,14 +1612,14 @@ int obscure_api_test(bool *passed)
|
|||||||
socklen_t flag_len = sizeof(optval);
|
socklen_t flag_len = sizeof(optval);
|
||||||
int fd = SOCKET(AF_INET, SOCK_STREAM, 0);
|
int fd = SOCKET(AF_INET, SOCK_STREAM, 0);
|
||||||
DEBUG_TEST("setting level=%d, optname=%d, optval=%d...", level, optname, optval);
|
DEBUG_TEST("setting level=%d, optname=%d, optval=%d...", level, optname, optval);
|
||||||
int err = SETSOCKOPT(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&optval, sizeof(int));
|
int err = SETSOCKOPT(fd, level, optname, (char *)&optval, sizeof(int));
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
DEBUG_ERROR("error while setting optval on socket");
|
DEBUG_ERROR("error while setting optval on socket");
|
||||||
*passed = false;
|
*passed = false;
|
||||||
err = -1;
|
err = -1;
|
||||||
}
|
}
|
||||||
optval = -99; // set junk value to test against
|
optval = -99; // set junk value to test against
|
||||||
if ((err = GETSOCKOPT(fd, IPPROTO_TCP, TCP_NODELAY, &optval, &flag_len)) < 0) {
|
if ((err = GETSOCKOPT(fd, level, optname, &optval, &flag_len)) < 0) {
|
||||||
DEBUG_ERROR("error while getting the optval");
|
DEBUG_ERROR("error while getting the optval");
|
||||||
*passed = false;
|
*passed = false;
|
||||||
err = -1;
|
err = -1;
|
||||||
@@ -1617,7 +1634,7 @@ int obscure_api_test(bool *passed)
|
|||||||
if (optval > 0) { // TODO: what should be expected for each platform? Should this mirror them?
|
if (optval > 0) { // TODO: what should be expected for each platform? Should this mirror them?
|
||||||
optval = 0;
|
optval = 0;
|
||||||
DEBUG_TEST("setting level=%d, optname=%d, optval=%d...", level, optname, optval);
|
DEBUG_TEST("setting level=%d, optname=%d, optval=%d...", level, optname, optval);
|
||||||
if ((err = SETSOCKOPT(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &optval, (socklen_t)sizeof(int))) < 0) {
|
if ((err = SETSOCKOPT(fd, level, optname, (char *) &optval, (socklen_t)sizeof(int))) < 0) {
|
||||||
DEBUG_ERROR("error while setting on socket");
|
DEBUG_ERROR("error while setting on socket");
|
||||||
*passed = false;
|
*passed = false;
|
||||||
err = -1;
|
err = -1;
|
||||||
@@ -1661,12 +1678,12 @@ int slam_api_test()
|
|||||||
if (false)
|
if (false)
|
||||||
{
|
{
|
||||||
// open and close SLAM_NUMBER*SLAM_REPEAT sockets
|
// open and close SLAM_NUMBER*SLAM_REPEAT sockets
|
||||||
for(int j=0; j<SLAM_REPEAT; j++) {
|
for (int j=0; j<SLAM_REPEAT; j++) {
|
||||||
std::cout << "slamming " << j << " time(s)" << std::endl;
|
std::cout << "slamming " << j << " time(s)" << std::endl;
|
||||||
usleep(SLAM_INTERVAL);
|
usleep(SLAM_INTERVAL);
|
||||||
// create sockets
|
// create sockets
|
||||||
int fds[SLAM_NUMBER];
|
int fds[SLAM_NUMBER];
|
||||||
for(int i = 0; i<SLAM_NUMBER; i++) {
|
for (int i = 0; i<SLAM_NUMBER; i++) {
|
||||||
if ((err = SOCKET(AF_INET, SOCK_STREAM, 0)) < 0) {
|
if ((err = SOCKET(AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||||
std::cout << "error creating socket (errno = " << strerror(errno) << ")" << std::endl;
|
std::cout << "error creating socket (errno = " << strerror(errno) << ")" << std::endl;
|
||||||
if (errno == EMFILE)
|
if (errno == EMFILE)
|
||||||
@@ -1680,7 +1697,7 @@ int slam_api_test()
|
|||||||
|
|
||||||
}
|
}
|
||||||
// close sockets
|
// close sockets
|
||||||
for(int i = 0; i<SLAM_NUMBER; i++) {
|
for (int i = 0; i<SLAM_NUMBER; i++) {
|
||||||
//std::cout << "\tclosing " << i << " socket(s)" << std::endl;
|
//std::cout << "\tclosing " << i << " socket(s)" << std::endl;
|
||||||
if ((err = CLOSE(fds[i])) < 0) {
|
if ((err = CLOSE(fds[i])) < 0) {
|
||||||
std::cout << "error closing socket (errno = " << strerror(errno) << ")" << std::endl;
|
std::cout << "error closing socket (errno = " << strerror(errno) << ")" << std::endl;
|
||||||
@@ -1709,11 +1726,11 @@ int slam_api_test()
|
|||||||
int sock = 0;
|
int sock = 0;
|
||||||
std::vector<int> used_ports;
|
std::vector<int> used_ports;
|
||||||
|
|
||||||
for(int j=0; j<SLAM_REPEAT; j++) {
|
for (int j=0; j<SLAM_REPEAT; j++) {
|
||||||
std::cout << "slamming " << j << " time(s)" << std::endl;
|
std::cout << "slamming " << j << " time(s)" << std::endl;
|
||||||
usleep(SLAM_INTERVAL);
|
usleep(SLAM_INTERVAL);
|
||||||
|
|
||||||
for(int i = 0; i<SLAM_NUMBER; i++) {
|
for (int i = 0; i<SLAM_NUMBER; i++) {
|
||||||
if ((sock = SOCKET(AF_INET, SOCK_STREAM, 0)) < 0) {
|
if ((sock = SOCKET(AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||||
std::cout << "error creating socket (errno = " << strerror(errno) << ")" << std::endl;
|
std::cout << "error creating socket (errno = " << strerror(errno) << ")" << std::endl;
|
||||||
if (errno == EMFILE)
|
if (errno == EMFILE)
|
||||||
@@ -1725,7 +1742,7 @@ int slam_api_test()
|
|||||||
usleep(SLAM_INTERVAL);
|
usleep(SLAM_INTERVAL);
|
||||||
|
|
||||||
int port;
|
int port;
|
||||||
while((std::find(used_ports.begin(),used_ports.end(),port) == used_ports.end()) == false) {
|
while ((std::find(used_ports.begin(),used_ports.end(),port) == used_ports.end()) == false) {
|
||||||
port = MIN_PORT + (rand() % (int)(MAX_PORT - MIN_PORT + 1));
|
port = MIN_PORT + (rand() % (int)(MAX_PORT - MIN_PORT + 1));
|
||||||
}
|
}
|
||||||
used_ports.push_back(port);
|
used_ports.push_back(port);
|
||||||
@@ -1774,13 +1791,13 @@ int slam_api_test()
|
|||||||
// (3) close()
|
// (3) close()
|
||||||
int num_times = zts_maxsockets(SOCK_STREAM);
|
int num_times = zts_maxsockets(SOCK_STREAM);
|
||||||
std::cout << "socket/connect/close - " << num_times << " times" << std::endl;
|
std::cout << "socket/connect/close - " << num_times << " times" << std::endl;
|
||||||
for(int i=0;i<(SLAM_NUMBER*SLAM_REPEAT); i++) { results[i] = 0; }
|
for (int i=0;i<(SLAM_NUMBER*SLAM_REPEAT); i++) { results[i] = 0; }
|
||||||
if (true)
|
if (true)
|
||||||
{
|
{
|
||||||
int port = 4545;
|
int port = 4545;
|
||||||
|
|
||||||
// open, bind, listen, accept, close
|
// open, bind, listen, accept, close
|
||||||
for(int j=0; j<num_times; j++) {
|
for (int j=0; j<num_times; j++) {
|
||||||
int sock = 0;
|
int sock = 0;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
@@ -1842,7 +1859,7 @@ void get_network_routes(char *nwid)
|
|||||||
// Retreive managed routes for a given ZeroTier network
|
// Retreive managed routes for a given ZeroTier network
|
||||||
std::vector<ZT_VirtualNetworkRoute> *routes = zts_get_network_routes(nwid);
|
std::vector<ZT_VirtualNetworkRoute> *routes = zts_get_network_routes(nwid);
|
||||||
|
|
||||||
for(int i=0; i<routes->size(); i++) {
|
for (int i=0; i<routes->size(); i++) {
|
||||||
struct sockaddr_in *target = (struct sockaddr_in*)&(routes->at(i).target);
|
struct sockaddr_in *target = (struct sockaddr_in*)&(routes->at(i).target);
|
||||||
struct sockaddr_in *via = (struct sockaddr_in*)&(routes->at(i).via);
|
struct sockaddr_in *via = (struct sockaddr_in*)&(routes->at(i).via);
|
||||||
char target_str[INET6_ADDRSTRLEN];
|
char target_str[INET6_ADDRSTRLEN];
|
||||||
@@ -1882,7 +1899,7 @@ int random_api_test()
|
|||||||
int num_operations = 100;
|
int num_operations = 100;
|
||||||
char *opbuf = (char*)malloc(num_operations*sizeof(char));
|
char *opbuf = (char*)malloc(num_operations*sizeof(char));
|
||||||
generate_random_data(opbuf, num_operations, 0, 9);
|
generate_random_data(opbuf, num_operations, 0, 9);
|
||||||
for(int i=0; i<num_operations; i++) {
|
for (int i=0; i<num_operations; i++) {
|
||||||
sleep(1);
|
sleep(1);
|
||||||
DEBUG_TEST("[i=%d, op=%d] calling X", i, opbuf[i]);
|
DEBUG_TEST("[i=%d, op=%d] calling X", i, opbuf[i]);
|
||||||
|
|
||||||
@@ -2001,9 +2018,9 @@ void test_bad_args()
|
|||||||
DEBUG_TEST("testing bad arguments for socket()");
|
DEBUG_TEST("testing bad arguments for socket()");
|
||||||
|
|
||||||
// Try all plausible argument combinations
|
// Try all plausible argument combinations
|
||||||
for(int i=0; i<num_proto_families; i++) {
|
for (int i=0; i<num_proto_families; i++) {
|
||||||
for(int j=0; j<num_socket_types; j++) {
|
for (int j=0; j<num_socket_types; j++) {
|
||||||
for(int k=0; k<max; k++) {
|
for (int k=0; k<max; k++) {
|
||||||
|
|
||||||
int protocol_family = proto_families[i];
|
int protocol_family = proto_families[i];
|
||||||
int socket_type = socket_types[j];
|
int socket_type = socket_types[j];
|
||||||
@@ -2059,48 +2076,147 @@ void close_while_writing_test()
|
|||||||
// TODO: Close a socket while another thread is writing to it or reading from it
|
// TODO: Close a socket while another thread is writing to it or reading from it
|
||||||
}
|
}
|
||||||
|
|
||||||
void* create_socket(void *arg)
|
/****************************************************************************/
|
||||||
|
/* test thread model, and locking */
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
#define CONCURRENCY_LEVEL 8 // how many threads we want to test with
|
||||||
|
#define TIME_GRANULARITY 10000 // multiple in microseconds
|
||||||
|
#define TIME_MULTIPLIER_MIN 1 //
|
||||||
|
#define TIME_MULTIPLIER_MAX 10 //
|
||||||
|
#define WORKER_ITERATIONS 100 // number of times a worker shall do its task
|
||||||
|
#define MASTER_ITERATIONS 10 // number of times we will create a set of workers
|
||||||
|
|
||||||
|
// for passing info to worker threads
|
||||||
|
struct fd_addr_pair {
|
||||||
|
int fd;
|
||||||
|
struct sockaddr_in *remote_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
pthread_t tid[CONCURRENCY_LEVEL];
|
||||||
|
|
||||||
|
// over num_iterations, wait a random time, create a socket, wait a random time, and close the socket
|
||||||
|
void* worker_create_socket(void *arg)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
unsigned long i = 0;
|
|
||||||
pthread_t id = pthread_self();
|
pthread_t id = pthread_self();
|
||||||
|
int fd, rs, rc;
|
||||||
if (pthread_equal(id,tid[0]))
|
// if (pthread_equal(id,tid[0])) { }
|
||||||
{
|
for (int i=0; i<WORKER_ITERATIONS; i++) {
|
||||||
printf("\n First thread processing\n");
|
rs = rand_in_range(TIME_MULTIPLIER_MIN, TIME_MULTIPLIER_MAX);
|
||||||
|
rc = rand_in_range(TIME_MULTIPLIER_MIN, TIME_MULTIPLIER_MAX);
|
||||||
|
fprintf(stderr, "id=%d, rs = %d, rc = %d\n", id, rs, rc);
|
||||||
|
usleep(rs * TIME_GRANULARITY);
|
||||||
|
fd = SOCKET(AF_INET, SOCK_STREAM, 0);
|
||||||
|
usleep(rc * TIME_GRANULARITY);
|
||||||
|
CLOSE(fd);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("\n Second thread processing\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i=0; i<(0xFFFFFFFF);i++);
|
|
||||||
*/
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test the core locking logic by creating large numbers of threads and performing random operations over an extended period of time
|
||||||
void multithread_socket_creation()
|
void multithread_test(int num_iterations, bool *passed)
|
||||||
{
|
{
|
||||||
|
int err = 0, i = 0;
|
||||||
fprintf(stderr, "\n\nmultithread_socket_creation\n\n");
|
fprintf(stderr, "\n\nmultithread_socket_creation\n\n");
|
||||||
/*
|
// test zts_socket() and zts_close()
|
||||||
pthread_t tid[2];
|
for (int j=0; j<num_iterations; j++) {
|
||||||
|
fprintf(stderr, "iteration=%d\n", j);
|
||||||
err = pthread_create(&(tid[i]), NULL, &create_socket, NULL);
|
// create threads
|
||||||
if (err != 0)
|
for (int i=0; i<CONCURRENCY_LEVEL; i++) {
|
||||||
printf("\ncan't create thread :[%s]", strerror(err));
|
fprintf(stderr,"creating thread [%d]\n", i);
|
||||||
else
|
if ((err = pthread_create(&(tid[i]), NULL, &worker_create_socket, NULL)) < 0) {
|
||||||
printf("\n Thread created successfully\n");
|
fprintf(stderr, "there was a problem while creating thread [%d]\n", i);
|
||||||
*/
|
*passed = false;
|
||||||
// TODO:
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// join all threads
|
||||||
|
char *b;
|
||||||
|
for (int i=0; i<CONCURRENCY_LEVEL; i++) {
|
||||||
|
if ((err = pthread_join(tid[i],(void**)&b)) < 0) {
|
||||||
|
fprintf(stderr, "error while joining thread [%d]\n", i);
|
||||||
|
*passed = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*passed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void multithread_rw()
|
// write a simple string message to a SOCK_DGRAM socket
|
||||||
|
void* worker_write_to_udp_socket(void *arg) {
|
||||||
|
fprintf(stderr, "\n\n\nwrite_to_udp_socket\n\n\n");
|
||||||
|
struct fd_addr_pair *fdp = (struct fd_addr_pair*)arg;
|
||||||
|
int fd = fdp->fd;
|
||||||
|
struct sockaddr_in *remote_addr = fdp->remote_addr;
|
||||||
|
//fprintf(stderr, "fd=%d\n", fd);
|
||||||
|
int w = 0;
|
||||||
|
for (int i=0; i<WORKER_ITERATIONS; i++) {
|
||||||
|
int r = rand_in_range(TIME_MULTIPLIER_MIN, TIME_MULTIPLIER_MAX);
|
||||||
|
usleep(r * TIME_GRANULARITY);
|
||||||
|
if ((w = SENDTO(fd, "hello", 5, 0, (struct sockaddr *)remote_addr, sizeof(*remote_addr))) < 0) {
|
||||||
|
DEBUG_ERROR("error sending packet, err=%d", errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a single socket and many threads to write to that single socket
|
||||||
|
void multithread_udp_write(struct sockaddr_in *local_addr, struct sockaddr_in *remote_addr, bool *passed)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "\n\nmultithread_rw\n\n");
|
fprintf(stderr, "\n\nmultithread_udp_broadcast\n\n");
|
||||||
|
int fd, err;
|
||||||
|
if((fd = SOCKET(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||||
|
DEBUG_ERROR("error while creating socket");
|
||||||
|
*passed = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((err = BIND(fd, (struct sockaddr *)local_addr, sizeof(struct sockaddr_in)) < 0)) {
|
||||||
|
DEBUG_ERROR("error binding to interface (%d)", err);
|
||||||
|
perror("bind");
|
||||||
|
*passed = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// params to send to new threads
|
||||||
|
struct fd_addr_pair fdp;
|
||||||
|
fdp.fd = fd;
|
||||||
|
fdp.remote_addr = remote_addr;
|
||||||
|
|
||||||
|
for (int i=0; i<CONCURRENCY_LEVEL; i++) {
|
||||||
|
fprintf(stderr,"creating thread [%d]\n", i);
|
||||||
|
if ((err = pthread_create(&(tid[i]), NULL, &worker_write_to_udp_socket, (void*)&fdp)) < 0) {
|
||||||
|
fprintf(stderr, "there was a problem while creating thread [%d]\n", i);
|
||||||
|
*passed = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// join all threads
|
||||||
|
char *b;
|
||||||
|
for (int i=0; i<CONCURRENCY_LEVEL; i++) {
|
||||||
|
if ((err = pthread_join(tid[i],(void**)&b)) < 0) {
|
||||||
|
fprintf(stderr, "error while joining thread [%d]\n", i);
|
||||||
|
*passed = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CLOSE(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void multithread_rw_server()
|
||||||
|
{
|
||||||
|
fprintf(stderr, "\n\nmultithread_rw_server\n\n");
|
||||||
// TODO: Test read/writes from multiple threads
|
// TODO: Test read/writes from multiple threads
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void multithread_rw_client()
|
||||||
|
{
|
||||||
|
fprintf(stderr, "\n\nmultithread_rw_client\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/* close() */
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
// Tests rapid opening and closure of sockets
|
// Tests rapid opening and closure of sockets
|
||||||
void close_test(struct sockaddr *bind_addr)
|
void close_test(struct sockaddr *bind_addr)
|
||||||
{
|
{
|
||||||
@@ -2111,7 +2227,7 @@ void close_test(struct sockaddr *bind_addr)
|
|||||||
bool extended = false;
|
bool extended = false;
|
||||||
int tries = !extended ? 8 : 1024;
|
int tries = !extended ? 8 : 1024;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
for(int i=0; i<tries; i++)
|
for (int i=0; i<tries; i++)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
if ((fd = SOCKET(AF_INET, SOCK_STREAM, 0)) < 0) {
|
if ((fd = SOCKET(AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||||
@@ -2297,28 +2413,29 @@ int main(int argc , char *argv[])
|
|||||||
/*
|
/*
|
||||||
zts_start(path.c_str());
|
zts_start(path.c_str());
|
||||||
printf("waiting for service to start...\n");
|
printf("waiting for service to start...\n");
|
||||||
while(zts_running() == false)
|
while (zts_running() == false)
|
||||||
sleep(1);
|
sleep(1);
|
||||||
printf("joining network...\n");
|
printf("joining network...\n");
|
||||||
zts_join(nwid.c_str());
|
zts_join(nwid.c_str());
|
||||||
printf("waiting for address assignment...\n");
|
printf("waiting for address assignment...\n");
|
||||||
while(zts_has_address(nwid.c_str()) == false)
|
while (zts_has_address(nwid.c_str()) == false)
|
||||||
sleep(1);
|
sleep(1);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for(int i=0; i<num_repeats; i++)
|
for (int i=0; i<num_repeats; i++)
|
||||||
{
|
{
|
||||||
DEBUG_TEST("\n\n\n --- COMPREHENSIVE TEST ITERATION: %d out of %d ---\n\n\n", i, num_repeats);
|
DEBUG_TEST("\n\n\n --- COMPREHENSIVE TEST ITERATION: %d out of %d ---\n\n\n", i, num_repeats);
|
||||||
|
|
||||||
// closure test
|
#if defined(__SELFTEST__)
|
||||||
|
if (false) {
|
||||||
#if defined(__SELFTEST__)
|
|
||||||
port = 1000;
|
port = 1000;
|
||||||
|
// closure test
|
||||||
struct sockaddr_in in4;
|
struct sockaddr_in in4;
|
||||||
DEBUG_TEST("testing closures by binding to: %s", local_ipstr.c_str());
|
DEBUG_TEST("testing closures by binding to: %s", local_ipstr.c_str());
|
||||||
str2addr(local_ipstr, port, 4, (struct sockaddr *)&in4);
|
str2addr(local_ipstr, port, 4, (struct sockaddr *)&in4);
|
||||||
close_test((struct sockaddr*)&in4);
|
close_test((struct sockaddr*)&in4);
|
||||||
port++;
|
port++;
|
||||||
|
}
|
||||||
|
|
||||||
// Test adding, resolving, and removing a DNS server
|
// Test adding, resolving, and removing a DNS server
|
||||||
|
|
||||||
@@ -2344,9 +2461,20 @@ for(int i=0; i<num_repeats; i++)
|
|||||||
//test_bad_args();
|
//test_bad_args();
|
||||||
|
|
||||||
// OBSCURE API TEST
|
// OBSCURE API TEST
|
||||||
obscure_api_test(&passed);
|
//obscure_api_test(&passed);
|
||||||
|
|
||||||
#endif // __SELFTEST__
|
//
|
||||||
|
ipv = 4;
|
||||||
|
port = start_port;
|
||||||
|
str2addr(local_ipstr, port, ipv, (struct sockaddr *)&local_addr);
|
||||||
|
str2addr(remote_ipstr, port, ipv, (struct sockaddr *)&remote_addr);
|
||||||
|
multithread_udp_write((struct sockaddr_in *)&local_addr, (struct sockaddr_in *)&remote_addr, &passed);
|
||||||
|
|
||||||
|
//
|
||||||
|
multithread_test(10, &passed);
|
||||||
|
//exit(0);
|
||||||
|
|
||||||
|
#endif // __SELFTEST__
|
||||||
|
|
||||||
port = start_port+(100*i); // arbitrary
|
port = start_port+(100*i); // arbitrary
|
||||||
cnt = 1024*3;
|
cnt = 1024*3;
|
||||||
@@ -2688,7 +2816,7 @@ for(int i=0; i<num_repeats; i++)
|
|||||||
|
|
||||||
// Print results of all tests
|
// Print results of all tests
|
||||||
printf("--------------------------------------------------------------------------------\n");
|
printf("--------------------------------------------------------------------------------\n");
|
||||||
for(int i=0;i<results.size(); i++) {
|
for (int i=0;i<results.size(); i++) {
|
||||||
fprintf(stderr, "%s\n", results[i].c_str());
|
fprintf(stderr, "%s\n", results[i].c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user