@ -1,147 +0,0 @@ | |||||
#pragma once | |||||
#include <stdint.h> | |||||
#include <iostream> | |||||
#include <stddef.h> | |||||
#include <gp/math.hpp> | |||||
#include <gp/array.hpp> | |||||
#include <gp/algorithm/rotate.hpp> | |||||
// BUG: A proper investigation is required to fix this file so that it gives the correct output. | |||||
template<typename word_t = uint32_t, size_t r = 20, size_t b = 128, word_t P = 0xb7e15163, word_t Q = 0x9e3779b9> | |||||
class RC6 { | |||||
static constexpr size_t word_size = 8*sizeof(word_t); | |||||
constexpr static word_t r_l(const word_t& w, size_t v) { | |||||
return (w << v) | ( w >> (word_size-v)); | |||||
} | |||||
constexpr static word_t r_r(const word_t& w, size_t v) { | |||||
return (w >> v) | ( w << (word_size-v)); | |||||
} | |||||
class RC6_KeySched { | |||||
using sched_t = gp::array<word_t, 2*r+4>; | |||||
public: | |||||
static constexpr size_t c = (b+word_size-1)/word_size; | |||||
static constexpr size_t v_3 = gp::max(c, 2*r+4); | |||||
static constexpr size_t v = v_3*3; | |||||
private: | |||||
sched_t S{}; | |||||
public: | |||||
constexpr RC6_KeySched(gp::array<word_t, c> L) | |||||
{ | |||||
static_assert(r_l(r_r(13,13),13) == 13); | |||||
auto it = S.begin(); | |||||
*(it++) = P; | |||||
for(; it != S.end(); ++it) | |||||
{ | |||||
*it = *(it-1) + Q; | |||||
} | |||||
word_t A = 0; | |||||
word_t B = 0; | |||||
word_t i = 0; | |||||
word_t j = 0; | |||||
size_t s = 0; | |||||
while(true) | |||||
{ | |||||
A = S[i] = r_l( S[i] + A + B, 3 ); | |||||
B += A; | |||||
B = L[j] = r_l( L[j] + B, B%(word_size)); | |||||
++s; | |||||
if(s >= v) break; | |||||
i = s % S.size(); | |||||
j = s % L.size(); | |||||
} | |||||
} | |||||
const auto cbegin() | |||||
{ | |||||
return S.cbegin(); | |||||
} | |||||
const auto cend() | |||||
{ | |||||
return S.cend(); | |||||
} | |||||
const auto crbegin() | |||||
{ | |||||
return S.crbegin(); | |||||
} | |||||
const auto crend() | |||||
{ | |||||
return S.crend(); | |||||
} | |||||
}; | |||||
RC6_KeySched S; | |||||
public: | |||||
typedef gp::array<word_t, RC6_KeySched::c> key_type; | |||||
typedef gp::array<word_t, 4> block_type; | |||||
constexpr RC6(const key_type& key) | |||||
: S(key) | |||||
{} | |||||
constexpr block_type&& encrypt(block_type plaintext) { | |||||
using namespace gp::math; | |||||
auto& A = plaintext[0]; | |||||
auto& B = plaintext[1]; | |||||
auto& C = plaintext[2]; | |||||
auto& D = plaintext[3]; | |||||
auto it = S.cbegin(); | |||||
B += *(it++); | |||||
D += *(it++); | |||||
for(size_t i = 0; i < r; ++i) | |||||
{ | |||||
auto u = r_l( D * ( 2 * D + 1 ), msb(word_size)); | |||||
auto t = r_l( B * ( 2 * B + 1 ), msb(word_size)); | |||||
A = r_l((A ^ t), u % word_size) + *(it++); | |||||
C = r_l((C ^ u), t % word_size) + *(it++); | |||||
gp::rotate(plaintext.begin(), plaintext.begin()+1, plaintext.end()); | |||||
} | |||||
A += *(it++); | |||||
C += *(it++); | |||||
assert(it == S.cend()); | |||||
return std::move(plaintext); | |||||
} | |||||
constexpr block_type decrypt(block_type plaintext) { | |||||
using namespace gp::math; | |||||
auto& A = plaintext[0]; | |||||
auto& B = plaintext[1]; | |||||
auto& C = plaintext[2]; | |||||
auto& D = plaintext[3]; | |||||
auto it = S.crbegin(); | |||||
C -= *(it++); | |||||
A -= *(it++); | |||||
for(size_t i = 0; i < r; ++i) | |||||
{ | |||||
gp::rotate(plaintext.begin(), plaintext.end()-1, plaintext.end()); | |||||
auto u = r_l( D * ( 2 * D + 1 ), msb(word_size)); | |||||
auto t = r_l( B * ( 2 * B + 1 ), msb(word_size)); | |||||
C = r_r( (C - *(it++)) , t % word_size) ^ u ; | |||||
A = r_r( (A - *(it++)) , u % word_size) ^ t ; | |||||
} | |||||
D -= *(it++); | |||||
B -= *(it++); | |||||
assert(it == S.crend()); | |||||
return std::move(plaintext); | |||||
} | |||||
}; |
@ -1,2 +0,0 @@ | |||||
#pragma once | |||||
// UNIMPLEMENTED: see filename |
@ -1,383 +0,0 @@ | |||||
#pragma once | |||||
#include <fcntl.h> | |||||
#include <unistd.h> | |||||
#include <sys/mman.h> | |||||
#include <sys/stat.h> | |||||
#include <sys/types.h> | |||||
#include <sys/socket.h> | |||||
#include <netinet/in.h> | |||||
#include <sys/un.h> | |||||
#include <string> | |||||
#include <sstream> | |||||
#include <atomic> | |||||
#include <array> | |||||
#include <variant> | |||||
#include <cassert> | |||||
// TODO: Scavenge for useful parts and discard | |||||
namespace gp{ | |||||
using open_opt_flags = int; | |||||
enum class open_options : open_opt_flags { | |||||
append = O_APPEND, | |||||
create = O_CREAT, | |||||
async = O_ASYNC, | |||||
direct = O_DIRECT, | |||||
data_sync = O_DSYNC, | |||||
file_sync = O_SYNC, | |||||
exclusive = O_EXCL, | |||||
no_access_time = O_NOATIME, | |||||
no_follow = O_NOFOLLOW, | |||||
read = O_RDONLY, | |||||
write = O_WRONLY, | |||||
#ifdef O_TEMP | |||||
temporary = O_TEMP, | |||||
#endif | |||||
#ifdef O_TRUC | |||||
truncate = O_TRUC, | |||||
#endif | |||||
}; | |||||
using open_opt_mode = int; | |||||
enum class open_modes : open_opt_mode { | |||||
user_read = S_IRUSR, | |||||
user_write = S_IWUSR, | |||||
user_exec = S_IXUSR, | |||||
group_read = S_IRGRP, | |||||
group_write = S_IWGRP, | |||||
group_exec = S_IXGRP, | |||||
other_read = S_IROTH, | |||||
other_write = S_IWOTH, | |||||
other_exec = S_IXOTH, | |||||
set_uid = S_ISUID, | |||||
set_gid = S_ISGID, | |||||
sticky_bit = S_ISVTX, | |||||
}; | |||||
enum class socket_domain : int { | |||||
ip4 = AF_INET, | |||||
ip6 = AF_INET6, | |||||
unix = AF_UNIX | |||||
}; | |||||
enum class socket_protocol : int { | |||||
tcp_like = SOCK_STREAM, | |||||
udp_like = SOCK_DGRAM | |||||
}; | |||||
using socket_opt_flags = int; | |||||
enum class net_socket_opt_flags : socket_opt_flags { | |||||
non_blocking = SOCK_NONBLOCK, | |||||
close_on_exec = SOCK_CLOEXEC, | |||||
}; | |||||
using socket_opt_flags = int; | |||||
enum class unix_socket_opt_flags : socket_opt_flags { | |||||
non_blocking = SOCK_NONBLOCK, | |||||
close_on_exec = SOCK_CLOEXEC, | |||||
}; | |||||
using address = std::variant<sockaddr_in, sockaddr_in6, sockaddr_un>; | |||||
template<typename T> | |||||
struct stream_expect{ | |||||
const T v; | |||||
stream_expect(T value) | |||||
: v(value) | |||||
{} | |||||
}; | |||||
template<typename T> | |||||
std::istream& operator>>(std::istream& in, const stream_expect<T>& expector) | |||||
{ | |||||
T vin; | |||||
in >> vin; | |||||
if(vin != expector.v) | |||||
throw std::runtime_error("Expector failed"); | |||||
return in; | |||||
} | |||||
address make_ipv4(const std::string_view addr, const uint16_t port) | |||||
{ | |||||
std::stringstream din; | |||||
din<<addr; | |||||
std::array<uint8_t, 4> address{0}; | |||||
int ex; | |||||
din>>ex | |||||
>>stream_expect<char>('.'); | |||||
address[0]=ex; | |||||
din>>ex | |||||
>>stream_expect<char>('.'); | |||||
address[1]=ex; | |||||
din>>ex | |||||
>>stream_expect<char>('.'); | |||||
address[2]=ex; | |||||
din>>ex; | |||||
address[3]=ex; | |||||
sockaddr_in ret; | |||||
in_addr ret_addr; | |||||
ret_addr.s_addr = *((uint32_t*)&address); | |||||
ret.sin_family = AF_INET; | |||||
ret.sin_addr = ret_addr; | |||||
ret.sin_port = htons(port); | |||||
return ret; | |||||
} | |||||
// TODO: make an IPv6 parser | |||||
//address make_ipv6(const std::string_view addr, const uint16_t port){} | |||||
address make_unix(const std::string_view filename) | |||||
{ | |||||
sockaddr_un ret; | |||||
if(filename.size()>(sizeof(ret.sun_path)-1)) | |||||
throw std::runtime_error("Filename too long"); | |||||
ret.sun_family = AF_UNIX; | |||||
*std::copy(filename.begin(), filename.end(), ret.sun_path) = '\0'; | |||||
return ret; | |||||
} | |||||
class shared_fd { | |||||
int fd; | |||||
std::atomic_int* guard; | |||||
int last_error; | |||||
shared_fd(int fd_v) | |||||
: fd(fd_v) | |||||
, guard(new std::atomic_int{1}) | |||||
, last_error(0) | |||||
{} | |||||
public: | |||||
shared_fd() | |||||
: fd(-1) | |||||
, guard(nullptr) | |||||
, last_error(0) | |||||
{} | |||||
shared_fd(const shared_fd& oth) | |||||
: fd(oth.fd) | |||||
, guard(oth.guard) | |||||
, last_error(0) | |||||
{ | |||||
if(guard) | |||||
guard->fetch_add(1, std::memory_order_acq_rel); | |||||
} | |||||
shared_fd(shared_fd&& oth) | |||||
: last_error(0) | |||||
{ | |||||
fd=oth.fd; | |||||
guard=oth.guard; | |||||
oth.fd=-1; | |||||
oth.guard=nullptr; | |||||
} | |||||
const int get() const { | |||||
return fd; | |||||
} | |||||
void operator=(const shared_fd& oth) | |||||
{ | |||||
this->~shared_fd(); | |||||
fd = oth.fd; | |||||
guard = oth.guard; | |||||
if(guard) | |||||
guard->fetch_add(1, std::memory_order_acq_rel); | |||||
} | |||||
void operator=(shared_fd&& oth) | |||||
{ | |||||
std::swap(fd,oth.fd); | |||||
std::swap(guard,oth.guard); | |||||
} | |||||
static shared_fd open(const std::string& filename, const open_opt_flags& flags, const open_opt_mode& mode = 0) | |||||
{ | |||||
shared_fd ret{::open(filename.c_str(), flags, mode)}; | |||||
return ret; | |||||
} | |||||
static shared_fd create(const std::string& filename, const open_opt_mode& mode) | |||||
{ | |||||
shared_fd ret{::creat(filename.c_str(), mode)}; | |||||
return ret; | |||||
} | |||||
static shared_fd tcp_socket() | |||||
{ | |||||
shared_fd ret; | |||||
auto res = ::socket(AF_INET, SOCK_STREAM, 0); | |||||
if(res >= 0) | |||||
{ | |||||
ret = shared_fd{res}; | |||||
fcntl(res, F_SETFL, O_NONBLOCK); | |||||
} | |||||
else | |||||
ret.last_error = errno; | |||||
return ret; | |||||
} | |||||
static shared_fd socket(const socket_domain& dom, const socket_protocol& proto)//, const net_socket_opt_flags& flags) | |||||
{ | |||||
shared_fd ret; | |||||
auto res = ::socket((int)dom, (int)proto, (int)0); | |||||
if(res >= 0) | |||||
{ | |||||
ret = shared_fd{res}; | |||||
} | |||||
else | |||||
ret.last_error = errno; | |||||
return ret; | |||||
} | |||||
static shared_fd unix_socket(const socket_protocol& proto, const socket_opt_flags flags) { | |||||
shared_fd ret; | |||||
auto res = ::socket((int)AF_UNIX, (int)proto, (int)flags); | |||||
if(res >= 0) | |||||
ret = shared_fd{res}; | |||||
return ret; | |||||
} | |||||
static std::pair<shared_fd,shared_fd> unix_socket_pair(const socket_protocol& proto, const net_socket_opt_flags flags) { | |||||
std::pair<gp::shared_fd, gp::shared_fd> ret; | |||||
int fds[2]; | |||||
auto result = ::socketpair((int)AF_UNIX, (int)proto, (int)flags, fds); | |||||
if(result != 0) | |||||
return ret; | |||||
ret.first = shared_fd(fds[0]); | |||||
ret.second = shared_fd(fds[1]); | |||||
return ret; | |||||
} | |||||
bool is_valid() const { | |||||
return guard && (fd>=0); | |||||
} | |||||
bool has_failed() const { | |||||
return last_error; | |||||
} | |||||
bool was_connection_refused() const { | |||||
return last_error==ECONNREFUSED; | |||||
} | |||||
bool in_progress() const { | |||||
return last_error==EINPROGRESS; | |||||
} | |||||
bool must_retry() const { | |||||
return last_error==EAGAIN; | |||||
} | |||||
int error() const { | |||||
return last_error; | |||||
} | |||||
void bind(const address& addr) | |||||
{ | |||||
int ret; | |||||
std::visit([&](const auto& v){ | |||||
ret = ::bind(fd, (struct sockaddr*)&v, sizeof(v)); | |||||
}, addr); | |||||
if(ret==0) | |||||
{ | |||||
last_error = 0; | |||||
return; | |||||
} | |||||
else | |||||
last_error = errno; | |||||
} | |||||
void connect(const address& addr) | |||||
{ | |||||
int ret; | |||||
std::visit([&](const auto& v){ | |||||
ret = ::connect(fd, (struct sockaddr*)&v, sizeof(v)); | |||||
}, addr); | |||||
if(ret!=0) | |||||
{ | |||||
last_error = errno; | |||||
return; | |||||
} | |||||
last_error = 0; | |||||
} | |||||
void listen(const int& backlog = 16) | |||||
{ | |||||
int ret = 0; | |||||
std::visit([&](){ | |||||
ret = ::listen(fd, backlog); | |||||
}); | |||||
if(ret!=0) | |||||
{ | |||||
last_error = errno; | |||||
return; | |||||
} | |||||
last_error = 0; | |||||
} | |||||
shared_fd accept() | |||||
{ | |||||
int ret = 0; | |||||
std::array<uint8_t, 256> buffer; | |||||
socklen_t len; | |||||
ret = ::accept(fd,(sockaddr*)buffer.begin(), &len); | |||||
if(ret!=0) | |||||
{ | |||||
last_error = errno; | |||||
return shared_fd{}; | |||||
} | |||||
last_error = 0; | |||||
return shared_fd{ret}; | |||||
} | |||||
std::string_view read(const std::string_view buffer) | |||||
{ | |||||
int sz = ::read(fd, (void*)(buffer.begin()), buffer.size()); | |||||
if(sz<0) | |||||
last_error = errno; | |||||
else | |||||
last_error = 0; | |||||
sz = sz<0?0:sz; | |||||
return std::string_view(buffer.begin(), sz); | |||||
} | |||||
std::string_view write(const std::string_view buffer) | |||||
{ | |||||
int sz = ::write(fd, (void*)(buffer.begin()), buffer.size()); | |||||
if(sz<0) | |||||
last_error = errno; | |||||
else | |||||
last_error = 0; | |||||
sz = sz<0?0:sz; | |||||
return std::string_view(buffer.begin()+sz, buffer.size()-sz); | |||||
} | |||||
~shared_fd() | |||||
{ | |||||
if(guard) | |||||
if(guard->fetch_sub(1, std::memory_order_acq_rel) == 1) | |||||
{ | |||||
assert(guard->load() == 0); | |||||
assert(fd >= 0); | |||||
delete guard; | |||||
guard = nullptr; | |||||
if(fd >= 0) | |||||
{ | |||||
::close(fd); | |||||
} | |||||
} | |||||
} | |||||
}; | |||||
} |
@ -1,2 +0,0 @@ | |||||
#pragma once | |||||
// UNIMPLEMENTED: see filename |
@ -1,2 +0,0 @@ | |||||
#pragma once | |||||
// UNIMPLEMENTED: see filename |
@ -1,2 +0,0 @@ | |||||
#pragma once | |||||
// UNIMPLEMENTED: see filename |
@ -1,2 +0,0 @@ | |||||
#pragma once | |||||
// UNIMPLEMENTED: see filename |
@ -1,2 +0,0 @@ | |||||
#pragma once | |||||
// UNIMPLEMENTED: see filename |
@ -1,56 +0,0 @@ | |||||
#include "rc6_generic.hpp" | |||||
#include "test_scaffold.h" | |||||
#include <iostream> | |||||
#include <ios> | |||||
struct RC6test : public test_scaffold { | |||||
RC6test() { | |||||
name = __FILE__ ":1"; | |||||
} | |||||
virtual int run() { | |||||
using rc = RC6<>; | |||||
auto test = [](rc::key_type key, rc::block_type plaintext, rc::block_type expected) -> bool { | |||||
auto cipher = rc{key}; | |||||
plaintext = cipher.encrypt(plaintext); | |||||
return plaintext != expected; | |||||
}; | |||||
auto res = 0; | |||||
res += test( | |||||
{0, 0, 0, 0}, | |||||
{0,0,0,0}, | |||||
{0x8fc3a536,0x56b1f778,0xc129df4e,0x9848a41e} | |||||
); | |||||
res += test( | |||||
{0x80000000, 0x00000000, 0x00000000, 0x00000000}, | |||||
{0,0,0,0}, | |||||
{0x1AD578A0, 0x2A081628, 0x50A15A15, 0x52A17AD4} | |||||
); | |||||
return res; | |||||
} | |||||
}; | |||||
append_test dummy_szfhu5463(new RC6test{}); | |||||
struct RC6test2 : public test_scaffold { | |||||
RC6test2() { | |||||
name = __FILE__ ":2"; | |||||
} | |||||
virtual int run() { | |||||
using rc = RC6<>; | |||||
rc::key_type key{0,0,0,0}; | |||||
rc::block_type plaintext{0,0,0,0}; | |||||
rc::block_type expected{0,0,0,0}; | |||||
auto cipher = rc{key}; | |||||
auto plaintext2 = cipher.encrypt(plaintext); | |||||
auto plaintext3 = cipher.decrypt(plaintext2); | |||||
return plaintext3 != expected; | |||||
} | |||||
}; | |||||
append_test dummy_szmltz63(new RC6test2{}); |
@ -1,286 +0,0 @@ | |||||
#include "shared_fd.hpp" | |||||
#include "test_scaffold.h" | |||||
#include <thread> | |||||
#include <chrono> | |||||
#include <iostream> | |||||
#include <iomanip> | |||||
struct create_test : public test_scaffold { | |||||
create_test() { | |||||
name = __FILE__ ":1"; | |||||
} | |||||
virtual int run() { | |||||
auto fd = gp::shared_fd::create("./bin/test_n", int(gp::open_modes::user_read) | int(gp::open_modes::user_write)); | |||||
return fd.is_valid()?0:1; | |||||
} | |||||
}; | |||||
append_test dummy_sdfhuisd3(new create_test{}); | |||||
struct open_test : public test_scaffold { | |||||
open_test() { | |||||
name = __FILE__ ":2"; | |||||
} | |||||
virtual int run() { | |||||
auto fd = gp::shared_fd::open("./bin/test_n", int(gp::open_options::append)); | |||||
return fd.is_valid()?0:1; | |||||
} | |||||
}; | |||||
append_test dummy_sdf564dd3(new open_test{}); | |||||
struct manip_test : public test_scaffold { | |||||
manip_test() { | |||||
name = __FILE__ ":3"; | |||||
} | |||||
virtual int run() { | |||||
auto fd = gp::shared_fd::open("./bin/test_n", int(gp::open_options::append)); | |||||
int error = fd.is_valid()?0:1; | |||||
error += !(fd.get()>=0); | |||||
auto fd_cpy = fd; | |||||
error += fd_cpy.is_valid()?0:1; | |||||
gp::shared_fd constr_cpy(fd_cpy); | |||||
error += constr_cpy.is_valid()?0:1; | |||||
gp::shared_fd constr_mv(std::move(constr_cpy)); | |||||
error += constr_mv.is_valid()?0:1; | |||||
gp::shared_fd assign_cpy; | |||||
assign_cpy.operator=(fd_cpy); | |||||
error += assign_cpy.is_valid()?0:1; | |||||
gp::shared_fd assign_mv; | |||||
assign_mv.operator=(std::move(assign_cpy)); | |||||
error += assign_mv.is_valid()?0:1; | |||||
error += (!assign_cpy.is_valid())?0:1; | |||||
return error; | |||||
} | |||||
}; | |||||
append_test dummy_lkjs64dd3(new manip_test{}); | |||||
struct rw_test : public test_scaffold { | |||||
rw_test() { | |||||
name = __FILE__ ":4"; | |||||
} | |||||
virtual int run() { | |||||
auto fd = gp::shared_fd::open("./bin/test_n", int(gp::open_options::write)); | |||||
int error = fd.is_valid()?0:1; | |||||
fd.write("potatoes"); | |||||
error += fd.has_failed(); | |||||
fd = gp::shared_fd::open("./bin/test_n", int(gp::open_options::read)); | |||||
std::array<char,8> buffer; | |||||
auto str = fd.read(std::string_view(buffer.begin(), buffer.size())); | |||||
error += fd.has_failed(); | |||||
error += (str != "potatoes"); | |||||
return error; | |||||
} | |||||
}; | |||||
append_test dummy_l6z5e4rdd3(new rw_test{}); | |||||
struct rw_err_test : public test_scaffold { | |||||
rw_err_test() { | |||||
name = __FILE__ ":5"; | |||||
} | |||||
virtual int run() { | |||||
auto fd = gp::shared_fd::create("./bin/test_n", int(gp::open_modes::user_read) | int(gp::open_modes::user_write)); | |||||
fd = gp::shared_fd::open("./bin/test_n", int(gp::open_options::read)); | |||||
int error = fd.is_valid()?0:1; | |||||
fd.write("potatoes"); | |||||
error += fd.has_failed(); | |||||
fd = gp::shared_fd::open("./bin/test_n", int(gp::open_options::write)); | |||||
error += fd.is_valid()?0:1; | |||||
std::array<char,8> buffer; | |||||
auto str = fd.read(std::string_view(buffer.begin(), buffer.size())); | |||||
error += fd.has_failed(); | |||||
return error == 2 ? 0 : 1; | |||||
} | |||||
}; | |||||
append_test dummy_l6987erd3(new rw_err_test{}); | |||||
/* | |||||
struct make_address_test : public test_scaffold { | |||||
make_address_test() { | |||||
name = __FILE__ ":6"; | |||||
} | |||||
virtual int run() { | |||||
int error = 0; | |||||
gp::address ipv4 = gp::make_ipv4("127.0.0.1", 0x1234); | |||||
auto p = std::get<sockaddr_in>(ipv4); | |||||
error += (p.sin_family != AF_INET); | |||||
error += (p.sin_addr.s_addr != htonl(0x7F000001)); | |||||
error += (p.sin_port != htons(0x1234)); | |||||
try{ | |||||
gp::make_ipv4("not an IP", 1234); | |||||
error += 1; | |||||
}catch(...){} | |||||
std::string filename = "/tmp/my_socket"; | |||||
gp::address unix = gp::make_unix(filename); | |||||
auto q = std::get<sockaddr_un>(unix); | |||||
error += (q.sun_family != AF_UNIX); | |||||
error += strcmp(filename.c_str(), q.sun_path); | |||||
try{ | |||||
std::string long_str(1024, 'p'); | |||||
gp::make_unix(long_str); | |||||
error += 1; | |||||
}catch(...){} | |||||
return error; | |||||
} | |||||
}; | |||||
append_test dummy_l6923ml3(new make_address_test{}); | |||||
struct sockets_test : public test_scaffold { | |||||
sockets_test() { | |||||
name = __FILE__ ":7"; | |||||
} | |||||
virtual int run() { | |||||
int error = 0; | |||||
auto v = gp::shared_fd::socket(gp::socket_domain::ip4, gp::socket_protocol::tcp_like); | |||||
error += !(v.is_valid()); | |||||
v = gp::shared_fd::socket(gp::socket_domain::ip4, gp::socket_protocol::tcp_like); | |||||
error += !(v.is_valid()); | |||||
auto pair_v = gp::shared_fd::unix_socket_pair(gp::socket_protocol::tcp_like, (gp::net_socket_opt_flags)0); | |||||
error += !(pair_v.first.is_valid()); | |||||
error += !(pair_v.second.is_valid()); | |||||
pair_v = gp::shared_fd::unix_socket_pair(gp::socket_protocol::tcp_like, (gp::net_socket_opt_flags)-1); | |||||
error += pair_v.first.is_valid(); | |||||
error += pair_v.second.is_valid(); | |||||
auto u_v = gp::shared_fd::unix_socket(gp::socket_protocol::tcp_like, (gp::socket_opt_flags)0); | |||||
error += !(u_v.is_valid()); | |||||
u_v = gp::shared_fd::unix_socket(gp::socket_protocol::tcp_like, (gp::socket_opt_flags)-1); | |||||
error += u_v.is_valid(); | |||||
return error; | |||||
} | |||||
}; | |||||
append_test dummy_r3321443(new sockets_test{}); | |||||
using namespace std::chrono_literals; | |||||
struct sockets_co_test : public test_scaffold { | |||||
sockets_co_test() { | |||||
name = __FILE__ ":8"; | |||||
} | |||||
virtual int run() { | |||||
std::atomic_int error = 0; | |||||
{ | |||||
auto v2 = gp::shared_fd::tcp_socket(); | |||||
error += !(v2.is_valid()); | |||||
std::thread sside([&](){ | |||||
auto v1 = gp::shared_fd::tcp_socket(); | |||||
v1.bind(gp::make_ipv4("0.0.0.0",1235)); | |||||
error += v1.has_failed(); | |||||
v1.listen(); | |||||
std::cout << "listens?:" << v1.is_valid()<<std::endl; | |||||
error += !(v1.is_valid()); | |||||
gp::shared_fd listener = v1; | |||||
gp::shared_fd v3; | |||||
do | |||||
{ | |||||
v3 = listener.accept(); | |||||
std::this_thread::sleep_for(500ms); | |||||
std::cout << "accept_attempt:" << v3.error()<<std::endl; | |||||
}while(listener.must_retry()); | |||||
puts("accepted"); | |||||
error += !(listener.has_failed()); | |||||
do | |||||
{ | |||||
v3.write("potatoes"); | |||||
std::this_thread::sleep_for(1ms); | |||||
}while(v3.must_retry()); | |||||
puts("sent"); | |||||
error += !(v3.has_failed()); | |||||
return; | |||||
}); | |||||
std::this_thread::sleep_for(6ms); | |||||
v2.connect(gp::make_ipv4("255.255.255.255",1235)); | |||||
error += v2.has_failed(); | |||||
do{ | |||||
v2.connect(gp::make_ipv4("127.0.0.1",1235)); | |||||
std::this_thread::sleep_for(500ms); | |||||
std::cout << "connect_attempt:" << v2.is_valid() << " with " << v2.error()<<std::endl; | |||||
}while(v2.error() != EISCONN); | |||||
std::this_thread::sleep_for(1ms); | |||||
auto status = v2.was_connection_refused(); | |||||
error += status; | |||||
if(!status) | |||||
{ | |||||
puts("connected"); | |||||
std::array<char, 32> buffer; | |||||
std::string_view retstr; | |||||
do | |||||
{ | |||||
retstr = v2.read(std::string_view(buffer.begin(), buffer.size())); | |||||
std::this_thread::sleep_for(1ms); | |||||
} | |||||
while(v2.must_retry()); | |||||
puts("received"); | |||||
std::cout<< "out:" << std::quoted(retstr) << std::endl; | |||||
error += !(v2.has_failed()); | |||||
error += retstr != "potatoes"; | |||||
if(sside.joinable()) | |||||
sside.join(); | |||||
} | |||||
return error; | |||||
} | |||||
return error; | |||||
} | |||||
}; | |||||
// append_test dummy_polmdf43(new sockets_co_test{}); | |||||
*/ |