the boob will swarm your flat lands
This commit is contained in:
parent
4d1894066c
commit
8310d31ae2
6 changed files with 127 additions and 19 deletions
20
protocol.md
20
protocol.md
|
@ -185,8 +185,18 @@ Communication between the master server and clients will be done over a WebSocke
|
|||
</thead>
|
||||
<tr>
|
||||
<td class="center">1</td>
|
||||
<td>Client Key</td>
|
||||
<td>Big Int</td>
|
||||
<td>Server Name</td>
|
||||
<td>Text</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="center">2</td>
|
||||
<td>License</td>
|
||||
<td>Text</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="center">3</td>
|
||||
<td>Secret</td>
|
||||
<td>Blob (512b)</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
@ -472,9 +482,11 @@ TODO: MAKE THIS SECTION NOT LOOK LIKE SHIT
|
|||
0x02: COULD NOT PARSE KEY
|
||||
|
||||
#### M -> S (ID 4)
|
||||
0x01: LICENSE DATA INCORRECT
|
||||
0x01: MAX AUTH ATTEMPTS REACHED
|
||||
|
||||
0x02: LICENSE LIMIT REACHED
|
||||
0x02: LICENSE DATA INCORRECT
|
||||
|
||||
0x03: LICENSE LIMIT REACHED
|
||||
|
||||
### Master / Client
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace sosc {
|
|||
namespace db {
|
||||
|
||||
class Query;
|
||||
typedef std::vector<Query*> QueryList;
|
||||
|
||||
class ResultSet {
|
||||
public:
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
#include "../db/database.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace sosc {
|
||||
/** MASTER -> CLIENT **/
|
||||
|
||||
|
@ -36,7 +38,7 @@ protected:
|
|||
class MasterIntra {
|
||||
public:
|
||||
explicit MasterIntra(const IntraClient& client);
|
||||
bool Process();
|
||||
bool Process(const db::QueryList* queries);
|
||||
|
||||
bool Close();
|
||||
bool Close(const Packet& message);
|
||||
|
@ -45,6 +47,9 @@ private:
|
|||
bool Authentication(Packet& pck);
|
||||
bool StatusUpdate(Packet& pck);
|
||||
|
||||
bool AuthenticationFailure
|
||||
(const std::string& packetId, uint16_t errorCode);
|
||||
|
||||
enum SlaveToMasterId {
|
||||
kInitAttempt = 1,
|
||||
kAuthentication,
|
||||
|
@ -66,13 +71,21 @@ private:
|
|||
int auth_attempts;
|
||||
const int MAX_AUTH_ATTEMPTS = 3;
|
||||
std::string license;
|
||||
|
||||
const db::QueryList* queries;
|
||||
};
|
||||
|
||||
class MasterIntraPool : public Pool<MasterIntra> {
|
||||
public:
|
||||
MasterIntraPool();
|
||||
protected:
|
||||
bool ProcessClient(MasterIntra& client) override {
|
||||
return client.Process();
|
||||
return client.Process(&this->queries);
|
||||
}
|
||||
|
||||
void Stop() override;
|
||||
private:
|
||||
db::QueryList queries;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,43 @@
|
|||
#include "master.hpp"
|
||||
#include "../db/database.hpp"
|
||||
#include <mutex>
|
||||
|
||||
static struct {
|
||||
std::mutex license_check_mtx;
|
||||
} _ctx;
|
||||
|
||||
/** MASTERINTRAPOOL CODE **/
|
||||
|
||||
sosc::MasterIntraPool::MasterIntraPool() {
|
||||
#define QRY_LICENSE_CHECK 0
|
||||
this->queries.push_back(new db::Query(
|
||||
"SELECT COUNT(*) FROM SERVER_LICENSES "
|
||||
"WHERE KEY_ID = ? AND SECRET = ?"
|
||||
));
|
||||
|
||||
#define QRY_LICENSE_LIMIT 1
|
||||
this->queries.push_back(new db::Query(
|
||||
"SELECT ALLOWANCE FROM SERVER_LICENSES WHERE KEY_ID = ?"
|
||||
));
|
||||
|
||||
#define QRY_LICENSE_ACTIVE_COUNT 2
|
||||
this->queries.push_back(new db::Query(
|
||||
"SELECT COUNT(*) FROM SERVER_LIST WHERE LICENSE = ?"
|
||||
, DB_USE_MEMORY));
|
||||
|
||||
#define QRY_LICENSE_
|
||||
}
|
||||
|
||||
void sosc::MasterIntraPool::Stop() {
|
||||
Pool<MasterIntra>::Stop();
|
||||
|
||||
for(auto& query : this->queries) {
|
||||
query->Close();
|
||||
delete query;
|
||||
}
|
||||
}
|
||||
|
||||
/** MASTERINTRA CODE **/
|
||||
|
||||
sosc::MasterIntra::MasterIntra(const IntraClient& client) {
|
||||
this->sock = client;
|
||||
|
@ -7,7 +45,7 @@ sosc::MasterIntra::MasterIntra(const IntraClient& client) {
|
|||
this->auth_attempts = 0;
|
||||
}
|
||||
|
||||
bool sosc::MasterIntra::Process() {
|
||||
bool sosc::MasterIntra::Process(const db::QueryList* queries) {
|
||||
Packet pck;
|
||||
int status = this->sock.Receive(&pck);
|
||||
if(status == PCK_ERR)
|
||||
|
@ -15,6 +53,7 @@ bool sosc::MasterIntra::Process() {
|
|||
else if(status == PCK_MORE)
|
||||
return true;
|
||||
|
||||
this->queries = queries;
|
||||
switch(pck.GetId()) {
|
||||
case kInitAttempt:
|
||||
return this->InitAttempt(pck);
|
||||
|
@ -27,7 +66,8 @@ bool sosc::MasterIntra::Process() {
|
|||
}
|
||||
}
|
||||
|
||||
bool sosc::MasterIntra::InitAttempt(sosc::Packet &pck) {
|
||||
bool sosc::MasterIntra::InitAttempt(sosc::Packet &pck)
|
||||
{
|
||||
if(!pck.Check(1, key.key_size_bytes))
|
||||
return this->Close(Packet(kEncryptionError, { "\x01" }));
|
||||
|
||||
|
@ -38,24 +78,62 @@ bool sosc::MasterIntra::InitAttempt(sosc::Packet &pck) {
|
|||
this->sock.Send(response);
|
||||
}
|
||||
|
||||
bool sosc::MasterIntra::Authentication(sosc::Packet &pck) {
|
||||
bool sosc::MasterIntra::Authentication(sosc::Packet &pck)
|
||||
{
|
||||
if(this->authed)
|
||||
return true;
|
||||
|
||||
if(!pck.Check(2, PCK_ANY, 512))
|
||||
return this->Close(Packet(kNegativeAck, { "\x01" }));
|
||||
std::string packetId = BYTESTR(kAuthentication);
|
||||
if(!pck.Check(3, PCK_ANY, PCK_ANY, 512))
|
||||
return this->Close();
|
||||
|
||||
db::Query = db::Query::ScalarInt32(
|
||||
"SELECT COUNT(*) FROM SERVER_LICENSES "
|
||||
"WHERE KEY_ID = ? AND SECRET = ?"
|
||||
);
|
||||
db::Query* query = this->queries->at(QRY_LICENSE_CHECK);
|
||||
query->Reset();
|
||||
query->BindText(pck[1], 0);
|
||||
query->BindBlob(pck[2], 1);
|
||||
if(query->ScalarInt32() == 0)
|
||||
return AuthenticationFailure(packetId, 2);
|
||||
|
||||
if(isValid > 0) {
|
||||
_ctx.license_check_mtx.lock();
|
||||
|
||||
int limit;
|
||||
query = this->queries->at(QRY_LICENSE_LIMIT);
|
||||
query->Reset();
|
||||
query->BindText(pck[1], 0);
|
||||
if((limit = query->ScalarInt32()) != 0) {
|
||||
query = this->queries->at(QRY_LICENSE_ACTIVE_COUNT);
|
||||
query->Reset();
|
||||
query->BindText(pck[1], 0);
|
||||
if(query->ScalarInt32() < limit) {
|
||||
_ctx.license_check_mtx.unlock();
|
||||
return AuthenticationFailure(packetId, 3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_ctx.license_check_mtx.unlock();
|
||||
|
||||
this->authed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sosc::MasterIntra::AuthenticationFailure
|
||||
(const std::string& packetId, uint16_t errorCode)
|
||||
{
|
||||
if(++this->auth_attempts < MAX_AUTH_ATTEMPTS) {
|
||||
this->sock.Send(
|
||||
Packet(kNegativeAck, { packetId , net::htonv(errorCode) })
|
||||
);
|
||||
return true;
|
||||
} else {
|
||||
return this->Close(
|
||||
Packet(kNegativeAck, { packetId, net::htonv<uint16_t>(1) })
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
bool sosc::MasterIntra::StatusUpdate(sosc::Packet &pck) {
|
||||
bool sosc::MasterIntra::StatusUpdate(sosc::Packet &pck)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
@ -67,4 +145,4 @@ bool sosc::MasterIntra::Close() {
|
|||
bool sosc::MasterIntra::Close(const Packet &message) {
|
||||
this->sock.Send(message);
|
||||
this->Close();
|
||||
}
|
||||
}
|
|
@ -40,7 +40,7 @@ public:
|
|||
return this->is_open;
|
||||
}
|
||||
|
||||
void Stop();
|
||||
virtual void Stop();
|
||||
protected:
|
||||
virtual bool ProcessClient(T& client) = 0;
|
||||
private:
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
#undef TOSTR
|
||||
#define TOSTR(X) std::to_string(X)
|
||||
|
||||
#undef bytestr
|
||||
#undef BYTESTR
|
||||
#define BYTESTR(X) std::string(1, X)
|
||||
|
||||
namespace sosc {
|
||||
namespace str {
|
||||
std::string trim (std::string str);
|
||||
|
|
Loading…
Reference in a new issue