Skip to content
Snippets Groups Projects
Commit 8136448d authored by Nicolas Pope's avatar Nicolas Pope
Browse files

Add handshake protocol checks and add a tempory fix to nested wait problem

parent 3f92ca5c
No related branches found
No related tags found
No related merge requests found
......@@ -105,7 +105,6 @@ class Dispatcher {
args_type args_real;
args.convert(args_real);
auto z = std::make_unique<msgpack::zone>();
std::cout << "CALL " << ftl::internal::call(func, args_real) << std::endl;
auto result = msgpack::object(ftl::internal::call(func, args_real), *z);
return std::make_unique<msgpack::object_handle>(result, std::move(z));
}));
......
......@@ -64,12 +64,18 @@ template <typename R, typename... Args> struct func_traits<R (*)(Args...)> {
using args_type = std::tuple<typename std::decay<Args>::type...>;
};
//template <typename T>
//auto bindThis(F f, T t) { return [f,t]()t.f(42, std::forward<decltype(arg)>(arg)); }
template <typename T>
struct func_kind_info : func_kind_info<decltype(&T::operator())> {};
template <typename C, typename R, typename... Args>
struct func_kind_info<R (C::*)(Args...)> : func_kind_info<R (*)(Args...)> {};
//template <typename R, typename... Args>
//struct func_kind_info<std::_Bind<R(Args...)>> : func_kind_info<R(*)(Args...)> {};
template <typename C, typename R, typename... Args>
struct func_kind_info<R (C::*)(Args...) const>
: func_kind_info<R (*)(Args...)> {};
......
......@@ -9,4 +9,41 @@
#define FTL_PROTOCOL_P2P 0x1000
namespace ftl {
namespace net {
static const uint32_t MAGIC = 0x23995621;
static const uint8_t PATCH = 0;
static const uint8_t MINOR = 0;
static const uint8_t MAJOR = 1;
inline uint32_t version(int maj, int min, int pat) {
return (maj << 16) | (min << 8) | pat;
}
inline uint32_t version() {
return version(MAJOR, MINOR, PATCH);
}
#pragma pack(push,1)
struct Header {
uint32_t size;
uint32_t service;
};
struct Handshake {
uint32_t magic;
uint32_t version;
char peerid[16];
};
#pragma pack(pop)
};
};
#endif // _FTL_NET_PROTOCOL_HPP_
......@@ -22,13 +22,6 @@
namespace ftl {
namespace net {
#pragma pack(push,1)
struct Header {
uint32_t size;
uint32_t service;
};
#pragma pack(pop)
class Socket {
public:
Socket(const char *uri);
......@@ -139,6 +132,8 @@ class Socket {
bool connected_;
std::map<int, std::function<void(msgpack::object&)>> callbacks_;
ftl::net::Dispatcher disp_;
uint32_t version_;
std::string peerid_;
void _connected();
void _updateURI();
......
......@@ -111,8 +111,10 @@ Listener::~Listener() {
}
void Listener::connection(shared_ptr<Socket> &s) {
std::string hs1("HELLO");
s->send(FTL_PROTOCOL_HS1, hs1);
ftl::net::Handshake hs1;
hs1.magic = ftl::net::MAGIC;
hs1.version = ftl::net::version();
s->send(FTL_PROTOCOL_HS1, std::string((char*)&hs1, sizeof(hs1)));
LOG(INFO) << "Handshake initiated with " << s->getURI();
for (auto h : handler_connect_) h(s);
}
......
......@@ -119,10 +119,13 @@ bool _run(bool blocking, bool nodelay) {
active = blocking;
//Some kind of error occured, it is usually possible to recover from this.
if (selres <= 0) {
//std::cout << "SELECT ERROR" << std::endl;
if (selres < 0) {
std::cout << "SELECT ERROR " << selres << std::endl;
//return false;
continue;
} else if (selres == 0) {
// Timeout, nothing to do...
continue;
}
//If connection request is waiting
......
......@@ -201,6 +201,7 @@ void Socket::error() {
bool Socket::data() {
//Read data from socket
size_t n = 0;
int c = 0;
uint32_t len = 0;
if (pos_ < 4) {
......@@ -230,18 +231,25 @@ bool Socket::data() {
}
} else if (rc == EWOULDBLOCK || rc == 0) {
// Data not yet available
if (c == 0) {
LOG(INFO) << "Socket disconnected " << uri_;
close();
}
return false;
} else {
LOG(ERROR) << "Socket: " << uri_ << " - error " << rc;
close();
return false;
}
c++;
}
// Route the message...
uint32_t service = ((uint32_t*)buffer_)[1];
auto d = std::string(buffer_+8, len-4);
pos_ = 0; // DODGY, processing messages inside handlers is dangerous.
if (service == FTL_PROTOCOL_HS1 && !connected_) {
handshake1(d);
} else if (service == FTL_PROTOCOL_HS2 && !connected_) {
......@@ -257,23 +265,59 @@ bool Socket::data() {
} else {
LOG(ERROR) << "Unrecognised service request (" << service << ") from " << uri_;
}
}
pos_ = 0;
}
return true;
}
void Socket::handshake1(const std::string &d) {
// TODO Verify data
std::string hs2("HELLO");
send(FTL_PROTOCOL_HS2, hs2);
LOG(INFO) << "Handshake confirmed from " << uri_;
ftl::net::Handshake *hs;
if (d.size() != sizeof(ftl::net::Handshake)) {
LOG(ERROR) << "Handshake failed for " << uri_;
close();
return;
}
hs = (ftl::net::Handshake*)d.data();
if (hs->magic != ftl::net::MAGIC) {
LOG(ERROR) << "Handshake magic failed for " << uri_;
close();
return;
}
version_ = (hs->version > ftl::net::version()) ?
ftl::net::version() :
hs->version;
peerid_ = std::string(&hs->peerid[0],16);
ftl::net::Handshake hs2;
hs2.magic = ftl::net::MAGIC;
hs2.version = version_;
// TODO Set peerid;
send(FTL_PROTOCOL_HS2, std::string((char*)&hs2, sizeof(hs2)));
LOG(INFO) << "Handshake v" << version_ << " confirmed from " << uri_;
_connected();
}
void Socket::handshake2(const std::string &d) {
// TODO Verify data
ftl::net::Handshake *hs;
if (d.size() != sizeof(ftl::net::Handshake)) {
LOG(ERROR) << "Handshake failed for " << uri_;
close();
return;
}
hs = (ftl::net::Handshake*)d.data();
if (hs->magic != ftl::net::MAGIC) {
LOG(ERROR) << "Handshake magic failed for " << uri_;
close();
return;
}
version_ = (hs->version > ftl::net::version()) ?
ftl::net::version() :
hs->version;
peerid_ = std::string(&hs->peerid[0],16);
LOG(INFO) << "Handshake finalised for " << uri_;
_connected();
}
......
......@@ -186,7 +186,11 @@ void accept_connection() {
//Finally accept this client connection.
csock = accept(ssock, (sockaddr*)&addr, (socklen_t*)&rsize);
mocksend(csock, FTL_PROTOCOL_HS1, "HELLO");
ftl::net::Handshake hs1;
hs1.magic = ftl::net::MAGIC;
hs1.version = ftl::net::version();
mocksend(csock, FTL_PROTOCOL_HS1, std::string((char*)&hs1, sizeof(hs1)));
} else {
}
......@@ -340,8 +344,8 @@ TEST_CASE("Socket.bind(int)", "[net]") {
msg++;
});
ftl::net::wait();
ftl::net::wait();
ftl::net::wait(); // MSG 1
ftl::net::wait(); // MSG 2
REQUIRE(msg == 2);
}
......
......@@ -48,6 +48,7 @@ extern ssize_t recv(int sd, void *buf, size_t n, int f) {
}
extern ssize_t writev(int sd, const struct iovec *v, int cnt) {
// TODO Use count incase more sources exist...
size_t len = v[0].iov_len+v[1].iov_len;
char buf[len];
std::memcpy(&buf[0],v[0].iov_base,v[0].iov_len);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment