漏洞修复
This commit is contained in:
parent
5d9bdcce0c
commit
ba45facdad
@ -21,15 +21,6 @@
|
|||||||
#include "rsa.h"
|
#include "rsa.h"
|
||||||
#include "rng.hpp"
|
#include "rng.hpp"
|
||||||
|
|
||||||
|
|
||||||
//提示信息打印类函数
|
|
||||||
namespace error{
|
|
||||||
void printError(string error_info);
|
|
||||||
void printWarning(string warning_info);
|
|
||||||
void printSuccess(string succes_info);
|
|
||||||
void printRed(string red_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct instructions{
|
struct instructions{
|
||||||
int (*unpack)(string, vector<string> &, vector<string> &, vector<string> &) = NULL;
|
int (*unpack)(string, vector<string> &, vector<string> &, vector<string> &) = NULL;
|
||||||
int (*construct)(string, vector<string> &, vector<string> &, vector<string> &) = NULL;
|
int (*construct)(string, vector<string> &, vector<string> &, vector<string> &) = NULL;
|
||||||
|
@ -55,6 +55,7 @@ public :
|
|||||||
// 临时缓冲区
|
// 临时缓冲区
|
||||||
char buff[BUFSIZ];
|
char buff[BUFSIZ];
|
||||||
SocketServer(int port,bool ipv4){
|
SocketServer(int port,bool ipv4){
|
||||||
|
server_addr.SetIP("127.0.0.1");
|
||||||
server_addr.SetPort(port);
|
server_addr.SetPort(port);
|
||||||
if(ipv4){
|
if(ipv4){
|
||||||
ipptl = AF_INET;
|
ipptl = AF_INET;
|
||||||
|
@ -181,6 +181,8 @@ struct box_listener{
|
|||||||
uint16_t cnt;
|
uint16_t cnt;
|
||||||
// 接收到的分包数量
|
// 接收到的分包数量
|
||||||
uint16_t nbn;
|
uint16_t nbn;
|
||||||
|
//分包来源地址
|
||||||
|
sockaddr_in address;
|
||||||
// 储存接收到的分包的动态数组
|
// 储存接收到的分包的动态数组
|
||||||
net_box **boxs;
|
net_box **boxs;
|
||||||
// 合并分包成RawData
|
// 合并分包成RawData
|
||||||
@ -221,6 +223,7 @@ struct connection_listener{
|
|||||||
Addr client_addr;
|
Addr client_addr;
|
||||||
aes_key256 key;
|
aes_key256 key;
|
||||||
pthread_t pid;
|
pthread_t pid;
|
||||||
|
void *father_buff;
|
||||||
};
|
};
|
||||||
|
|
||||||
//通用服务器类
|
//通用服务器类
|
||||||
@ -307,6 +310,8 @@ protected:
|
|||||||
map<uint64_t,client_register *> client_lst;
|
map<uint64_t,client_register *> client_lst;
|
||||||
// 加密端对端报文
|
// 加密端对端报文
|
||||||
list<encrypt_post *>post_lst;
|
list<encrypt_post *>post_lst;
|
||||||
|
//服务器名
|
||||||
|
string name;
|
||||||
public:
|
public:
|
||||||
SQEServer(int port = 9048);
|
SQEServer(int port = 9048);
|
||||||
void ProcessPacket(void);
|
void ProcessPacket(void);
|
||||||
@ -333,7 +338,7 @@ class Client{
|
|||||||
// 回复处理列表
|
// 回复处理列表
|
||||||
list<respond *> res_lst;
|
list<respond *> res_lst;
|
||||||
// 请求监听端口
|
// 请求监听端口
|
||||||
uint32_t listen_port;
|
uint16_t listen_port;
|
||||||
SocketUDPServer socket;
|
SocketUDPServer socket;
|
||||||
SocketUDPClient send_socket;
|
SocketUDPClient send_socket;
|
||||||
// 与服务器建立的稳定链接
|
// 与服务器建立的稳定链接
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#include <rapidjson/document.h>
|
#include <rapidjson/document.h>
|
||||||
#include <rapidjson/writer.h>
|
#include <rapidjson/writer.h>
|
||||||
#include <rapidjson/stringbuffer.h>
|
#include <rapidjson/stringbuffer.h>
|
||||||
|
#include <rapidjson/prettywriter.h>
|
||||||
|
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
@ -65,4 +66,13 @@ typedef unsigned char UByte;
|
|||||||
#define RESPOND_TYPE 101
|
#define RESPOND_TYPE 101
|
||||||
#define ENCRYPT_POST_TYPE 102
|
#define ENCRYPT_POST_TYPE 102
|
||||||
|
|
||||||
|
//提示信息打印类函数
|
||||||
|
namespace error {
|
||||||
|
void printError(string error_info);
|
||||||
|
void printWarning(string warning_info);
|
||||||
|
void printSuccess(string succes_info);
|
||||||
|
void printRed(string red_info);
|
||||||
|
void printInfo(string info);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* type_h */
|
#endif /* type_h */
|
||||||
|
11
src/addr.cpp
11
src/addr.cpp
@ -14,10 +14,8 @@ Addr::Addr(string ip_addr, int port, bool ipv4){
|
|||||||
address.sin_family = AF_INET;
|
address.sin_family = AF_INET;
|
||||||
else
|
else
|
||||||
address.sin_family = AF_INET6;
|
address.sin_family = AF_INET6;
|
||||||
address.sin_port = htons(port);
|
address.sin_port = htons((uint16_t)port);
|
||||||
in_addr_t ipu = inet_addr(ip_addr.data());
|
address.sin_addr.s_addr = inet_addr(ip_addr.data());
|
||||||
memcpy(&address.sin_addr, &ipu, sizeof(in_addr_t));
|
|
||||||
|
|
||||||
addr_size = sizeof(address);
|
addr_size = sizeof(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,13 +47,12 @@ void Addr::SetSize(void){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Addr::SetPort(int port){
|
void Addr::SetPort(int port){
|
||||||
address.sin_port = htons(port);
|
address.sin_port = htons((uint16_t)port);
|
||||||
addr_size = sizeof(address);
|
addr_size = sizeof(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Addr::SetIP(string ip_addr){
|
void Addr::SetIP(string ip_addr){
|
||||||
in_addr_t ipu = inet_addr(ip_addr.data());
|
address.sin_addr.s_addr = inet_addr(ip_addr.data());
|
||||||
memcpy(&address.sin_addr, &ipu, sizeof(in_addr_t));
|
|
||||||
addr_size = sizeof(address);
|
addr_size = sizeof(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,7 +299,7 @@ static void ShiftRows(state_t* state)
|
|||||||
|
|
||||||
static uint8_t xtime(uint8_t x)
|
static uint8_t xtime(uint8_t x)
|
||||||
{
|
{
|
||||||
return ((x<<1) ^ (((x>>7) & 1) * 0x1b));
|
return (uint8_t)((x<<1) ^ (((x>>7) & 1) * 0x1b));
|
||||||
}
|
}
|
||||||
|
|
||||||
// MixColumns function mixes the columns of the state matrix
|
// MixColumns function mixes the columns of the state matrix
|
||||||
@ -558,7 +558,7 @@ void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length)
|
|||||||
ctx->Iv[bi] = 0;
|
ctx->Iv[bi] = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ctx->Iv[bi] += (uint8_t) 1;
|
ctx->Iv[bi] += 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bi = 0;
|
bi = 0;
|
||||||
|
@ -46,7 +46,6 @@ void *clientRespondDeamon(void *pvclt){
|
|||||||
if(tlen > 0){
|
if(tlen > 0){
|
||||||
// 记录有效数据包
|
// 记录有效数据包
|
||||||
if(Server::CheckRawMsg(str, tlen)){
|
if(Server::CheckRawMsg(str, tlen)){
|
||||||
|
|
||||||
raw_data *ptrdt = new raw_data();
|
raw_data *ptrdt = new raw_data();
|
||||||
Server::ProcessSignedRawMsg(str, tlen, *ptrdt);
|
Server::ProcessSignedRawMsg(str, tlen, *ptrdt);
|
||||||
ptrdt->address = *(struct sockaddr_in *)taddr.RawObj();
|
ptrdt->address = *(struct sockaddr_in *)taddr.RawObj();
|
||||||
@ -155,6 +154,7 @@ void Client::NewRequest(request **ppreq,string send_ip,int send_port,string type
|
|||||||
*ppreq = pnreq;
|
*ppreq = pnreq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//创建新的对服务器的请求
|
||||||
void Client::NewRequestListener(request *preq, int timeout, void *args, void (*callback)(respond *,void *)){
|
void Client::NewRequestListener(request *preq, int timeout, void *args, void (*callback)(respond *,void *)){
|
||||||
request_listener *pnrl = new request_listener();
|
request_listener *pnrl = new request_listener();
|
||||||
packet npkt;
|
packet npkt;
|
||||||
@ -164,17 +164,19 @@ void Client::NewRequestListener(request *preq, int timeout, void *args, void (*c
|
|||||||
pnrl->clicks = 0;
|
pnrl->clicks = 0;
|
||||||
pnrl->p_req = preq;
|
pnrl->p_req = preq;
|
||||||
pnrl->args = args;
|
pnrl->args = args;
|
||||||
|
|
||||||
SQEServer::Request2Packet(npkt, *preq);
|
SQEServer::Request2Packet(npkt, *preq);
|
||||||
Server::Packet2Rawdata(npkt, pnrl->trwd);
|
Server::Packet2Rawdata(npkt, pnrl->trwd);
|
||||||
// 检查请求是否要求加密
|
// 检查请求是否要求加密
|
||||||
if(preq->if_encrypt == true){
|
if(preq->if_encrypt == true){
|
||||||
|
|
||||||
Server::EncryptRSARawMsg(pnrl->trwd, sqe_pbc);
|
Server::EncryptRSARawMsg(pnrl->trwd, sqe_pbc);
|
||||||
Server::SignedRawdata(&pnrl->trwd,"RPKT");
|
Server::SignedRawdata(&pnrl->trwd,"RPKT");
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
Server::SignedRawdata(&pnrl->trwd,"SPKT");
|
Server::SignedRawdata(&pnrl->trwd,"SPKT");
|
||||||
}
|
}
|
||||||
|
|
||||||
send_socket.SetSendSockAddr(*pnrl->p_req->t_addr.Obj());
|
send_socket.SetSendSockAddr(*pnrl->p_req->t_addr.Obj());
|
||||||
SendRawData(&pnrl->trwd);
|
SendRawData(&pnrl->trwd);
|
||||||
req_lst.push_back(pnrl);
|
req_lst.push_back(pnrl);
|
||||||
|
@ -215,14 +215,19 @@ int set(string instruct, vector<string> &configs, vector<string> &lconfigs, vect
|
|||||||
int if_find = sqlite3_column_int(psqlsmt, 0);
|
int if_find = sqlite3_column_int(psqlsmt, 0);
|
||||||
if(if_find);
|
if(if_find);
|
||||||
else{
|
else{
|
||||||
error::printError("Couldn't SET before INIT process.");
|
error::printError("Couldn't SET before INIT.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
sqlite3_finalize(psqlsmt);
|
sqlite3_finalize(psqlsmt);
|
||||||
|
|
||||||
if(targets[0] == "server"){
|
if(targets[0] == "server"){
|
||||||
|
if (targets.size() < 3) {
|
||||||
|
error::printError("Illegal Args.\nFromat set server [server_ip] [server_port].");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
sql_quote = "UPDATE client_info SET msqes_ip = ?1, msqes_port = ?2 WHERE rowid = 1;";
|
sql_quote = "UPDATE client_info SET msqes_ip = ?1, msqes_port = ?2 WHERE rowid = 1;";
|
||||||
sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
|
sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
|
||||||
|
//检查广场服务器IP地址是否正确
|
||||||
if(!Addr::checkValidIP(targets[1])){
|
if(!Addr::checkValidIP(targets[1])){
|
||||||
error::printError("Arg(ipaddr) is abnomal.");
|
error::printError("Arg(ipaddr) is abnomal.");
|
||||||
sqlite3_finalize(psqlsmt);
|
sqlite3_finalize(psqlsmt);
|
||||||
@ -230,7 +235,7 @@ int set(string instruct, vector<string> &configs, vector<string> &lconfigs, vect
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
sqlite3_bind_text(psqlsmt, 1, targets[1].data(), -1, SQLITE_TRANSIENT);
|
sqlite3_bind_text(psqlsmt, 1, targets[1].data(), -1, SQLITE_TRANSIENT);
|
||||||
|
//获得广场服务器端口
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss<<targets[2];
|
ss<<targets[2];
|
||||||
int port;
|
int port;
|
||||||
@ -243,6 +248,8 @@ int set(string instruct, vector<string> &configs, vector<string> &lconfigs, vect
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
sqlite3_bind_int(psqlsmt, 2, port);
|
sqlite3_bind_int(psqlsmt, 2, port);
|
||||||
|
|
||||||
|
//执行数据库指令
|
||||||
int rtn = sqlite3_step(psqlsmt);
|
int rtn = sqlite3_step(psqlsmt);
|
||||||
if(rtn != SQLITE_DONE){
|
if(rtn != SQLITE_DONE){
|
||||||
sql::printError(psql);
|
sql::printError(psql);
|
||||||
@ -250,6 +257,11 @@ int set(string instruct, vector<string> &configs, vector<string> &lconfigs, vect
|
|||||||
sqlite3_finalize(psqlsmt);
|
sqlite3_finalize(psqlsmt);
|
||||||
}
|
}
|
||||||
else if (targets[0] == "key"){
|
else if (targets[0] == "key"){
|
||||||
|
if (targets.size() < 3) {
|
||||||
|
error::printError("Illegal Args.\nFromat set key [key_type] [key]");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//客户端远程管理口令
|
||||||
if(targets[1] == "admin"){
|
if(targets[1] == "admin"){
|
||||||
string hexresult;
|
string hexresult;
|
||||||
SHA1_Easy(hexresult, targets[2]);
|
SHA1_Easy(hexresult, targets[2]);
|
||||||
@ -264,6 +276,7 @@ int set(string instruct, vector<string> &configs, vector<string> &lconfigs, vect
|
|||||||
}
|
}
|
||||||
sqlite3_finalize(psqlsmt);
|
sqlite3_finalize(psqlsmt);
|
||||||
}
|
}
|
||||||
|
//广场服务器访问口令
|
||||||
else if(targets[1] == "server"){
|
else if(targets[1] == "server"){
|
||||||
sql_quote = "UPDATE client_info SET msqes_key = ?1 WHERE rowid = 1;";
|
sql_quote = "UPDATE client_info SET msqes_key = ?1 WHERE rowid = 1;";
|
||||||
sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
|
sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
|
||||||
@ -278,6 +291,10 @@ int set(string instruct, vector<string> &configs, vector<string> &lconfigs, vect
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
error::printError("Operation doesn't make sense.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
error::printSuccess("Succeed.");
|
error::printSuccess("Succeed.");
|
||||||
sqlite3_close(psql);
|
sqlite3_close(psql);
|
||||||
return 0;
|
return 0;
|
||||||
@ -287,8 +304,10 @@ int server(string instruct, vector<string> &configs, vector<string> &lconfigs, v
|
|||||||
initClock();
|
initClock();
|
||||||
setThreadsClock();
|
setThreadsClock();
|
||||||
if(targets.size() == 0){
|
if(targets.size() == 0){
|
||||||
Server nsvr;
|
//Server nsvr;
|
||||||
setServerClock(&nsvr, 3);
|
//setServerClock(&nsvr, 3);
|
||||||
|
SQEServer nsvr;
|
||||||
|
setServerClockForSquare(&nsvr, 3);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if(targets[0] == "square"){
|
if(targets[0] == "square"){
|
||||||
@ -363,37 +382,45 @@ int construct(string instruct, vector<string> &configs, vector<string> &lconfigs
|
|||||||
}
|
}
|
||||||
|
|
||||||
int client(string instruct, vector<string> &configs, vector<string> &lconfigs, vector<string> &targets){
|
int client(string instruct, vector<string> &configs, vector<string> &lconfigs, vector<string> &targets){
|
||||||
|
|
||||||
sqlite3 *psql;
|
sqlite3 *psql;
|
||||||
sqlite3_stmt *psqlsmt;
|
sqlite3_stmt *psqlsmt;
|
||||||
const char *pzTail;
|
const char *pzTail;
|
||||||
|
|
||||||
if(sqlite3_open("info.db", &psql) == SQLITE_ERROR){
|
if(sqlite3_open("info.db", &psql) == SQLITE_ERROR){
|
||||||
sql::printError(psql);
|
sql::printError(psql);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化时钟
|
// 初始化时钟
|
||||||
initClock();
|
initClock();
|
||||||
setThreadsClock();
|
setThreadsClock();
|
||||||
|
|
||||||
// 建立客户端
|
// 建立客户端
|
||||||
Client nclt(9050);
|
Client nclt(9050);
|
||||||
|
|
||||||
bool if_setip = false;
|
bool if_setip = false;
|
||||||
string set_ip;
|
string set_ip;
|
||||||
|
|
||||||
|
|
||||||
if(config_search(configs, "-p")){
|
if(config_search(configs, "-p")){
|
||||||
set_ip = targets[0];
|
set_ip = targets[0];
|
||||||
printf("Set IP: %s\n",set_ip.data());
|
printf("Set IP: %s\n",set_ip.data());
|
||||||
if_setip = true;
|
if_setip = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
setClientClock(&nclt, 3);
|
setClientClock(&nclt, 3);
|
||||||
|
|
||||||
request *preq;
|
request *preq;
|
||||||
|
|
||||||
|
|
||||||
// 获得主广场服务器的通信公钥
|
// 获得主广场服务器的通信公钥
|
||||||
string sql_quote = "select count(*) from client_info where rowid = 1 and msqes_rsa_public is null;";
|
string sql_quote = "select count(*) from client_info where rowid = 1 and msqes_rsa_public is null;";
|
||||||
sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
|
sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
|
||||||
sqlite3_step(psqlsmt);
|
sqlite3_step(psqlsmt);
|
||||||
int if_null = sqlite3_column_int(psqlsmt, 0);
|
int if_null = sqlite3_column_int(psqlsmt, 0);
|
||||||
sqlite3_finalize(psqlsmt);
|
sqlite3_finalize(psqlsmt);
|
||||||
|
|
||||||
// 获得主广场服务器的ip地址及其通信端口
|
// 获得主广场服务器的ip地址及其通信端口
|
||||||
string msqe_ip;
|
string msqe_ip;
|
||||||
int msqe_port;
|
int msqe_port;
|
||||||
@ -403,12 +430,17 @@ int client(string instruct, vector<string> &configs, vector<string> &lconfigs, v
|
|||||||
msqe_ip = (const char *)sqlite3_column_text(psqlsmt, 0);
|
msqe_ip = (const char *)sqlite3_column_text(psqlsmt, 0);
|
||||||
msqe_port = sqlite3_column_int(psqlsmt, 1);
|
msqe_port = sqlite3_column_int(psqlsmt, 1);
|
||||||
sqlite3_finalize(psqlsmt);
|
sqlite3_finalize(psqlsmt);
|
||||||
|
error::printSuccess("Main Server IP: " + msqe_ip);
|
||||||
|
error::printSuccess("Main Server Port: " + std::to_string(msqe_port));
|
||||||
|
|
||||||
// 如果本地没有主广场服务器的公钥
|
// 如果本地没有主广场服务器的公钥
|
||||||
if(if_null){
|
if(if_null){
|
||||||
|
//向广场服务器申请通信公钥
|
||||||
nclt.NewRequest(&preq, msqe_ip, msqe_port, "public request", "request for public key");
|
nclt.NewRequest(&preq, msqe_ip, msqe_port, "public request", "request for public key");
|
||||||
nclt.NewRequestListener(preq, 30, psql, getSQEPublicKey);
|
nclt.NewRequestListener(preq, 30, psql, getSQEPublicKey);
|
||||||
if_wait = 1;
|
if_wait = 1;
|
||||||
|
|
||||||
|
//等待广场服务器回应
|
||||||
while (if_wait == 1) {
|
while (if_wait == 1) {
|
||||||
sleep(10);
|
sleep(10);
|
||||||
}
|
}
|
||||||
@ -416,15 +448,18 @@ int client(string instruct, vector<string> &configs, vector<string> &lconfigs, v
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("Succeed In Getting Rsa Public Key From SQEServer.\n");
|
printf("Succeed In Getting Rsa Public Key From SQEServer.\n");
|
||||||
#endif
|
#endif
|
||||||
|
error::printSuccess("Succeed In Requesting Public Key.");
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("Error In Getting Rsa Public Key From SQEServer.\n");
|
printf("Error In Getting Rsa Public Key From SQEServer.\n");
|
||||||
#endif
|
#endif
|
||||||
|
error::printError("Fail To Request Public Key.");
|
||||||
throw "connection error";
|
throw "connection error";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获得与广场服务器的通信的公钥
|
// 获得与广场服务器的通信的公钥
|
||||||
sql_quote = "select msqes_rsa_public from client_info where rowid = 1;";
|
sql_quote = "select msqes_rsa_public from client_info where rowid = 1;";
|
||||||
sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
|
sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
|
||||||
@ -440,7 +475,8 @@ int client(string instruct, vector<string> &configs, vector<string> &lconfigs, v
|
|||||||
|
|
||||||
Document reqdata;
|
Document reqdata;
|
||||||
if(reqdata.Parse(reqstr.data()).HasParseError()) throw "fail to parse into json";
|
if(reqdata.Parse(reqstr.data()).HasParseError()) throw "fail to parse into json";
|
||||||
// key
|
|
||||||
|
// 生成并传递端对端加密报文密钥
|
||||||
reqdata["key"].SetArray();
|
reqdata["key"].SetArray();
|
||||||
Value &tmp_key = reqdata["key"];
|
Value &tmp_key = reqdata["key"];
|
||||||
const uint8_t *p_key = naeskey.GetKey();
|
const uint8_t *p_key = naeskey.GetKey();
|
||||||
@ -448,61 +484,78 @@ int client(string instruct, vector<string> &configs, vector<string> &lconfigs, v
|
|||||||
for (int idx = 0; idx <32; idx++) {
|
for (int idx = 0; idx <32; idx++) {
|
||||||
tmp_key.PushBack(p_key[idx],allocator);
|
tmp_key.PushBack(p_key[idx],allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
reqdata["name"].SetString(nclt.name.data(),(uint32_t)nclt.name.size());
|
reqdata["name"].SetString(nclt.name.data(),(uint32_t)nclt.name.size());
|
||||||
reqdata["tag"].SetString(nclt.tag.data(),(uint32_t)nclt.name.size());
|
reqdata["tag"].SetString(nclt.tag.data(),(uint32_t)nclt.tag.size());
|
||||||
reqdata["sqe_key"].SetString(nclt.sqe_key.data(), (uint32_t)nclt.sqe_key.size());
|
reqdata["sqe_key"].SetString(nclt.sqe_key.data(), (uint32_t)nclt.sqe_key.size());
|
||||||
reqdata["listen_port"].SetInt(9053);
|
//设置TCP监听端口
|
||||||
|
reqdata["listen_port"].SetInt(9052);
|
||||||
|
|
||||||
|
|
||||||
|
//如果强制指定客户端IP地址
|
||||||
string ip;
|
string ip;
|
||||||
if(if_setip) ip = set_ip;
|
if(if_setip) ip = set_ip;
|
||||||
else ip = inet_ntoa(nclt.server_cnt->GetAddr().Obj()->sin_addr);
|
else ip = "127.0.0.1";
|
||||||
|
|
||||||
reqdata["listen_ip"].SetString(ip.data(),(uint32_t)ip.size());
|
reqdata["listen_ip"].SetString(ip.data(),(uint32_t)ip.size());
|
||||||
|
|
||||||
|
|
||||||
|
//构造请求
|
||||||
StringBuffer strbuff;
|
StringBuffer strbuff;
|
||||||
Writer<StringBuffer> writer(strbuff);
|
Writer<StringBuffer> writer(strbuff);
|
||||||
reqdata.Accept(writer);
|
reqdata.Accept(writer);
|
||||||
string json_str = strbuff.GetString();
|
string json_str = strbuff.GetString();
|
||||||
printf("JSON: %s\n",json_str.data());
|
|
||||||
|
printf("Connecting...\n");
|
||||||
// 已获得主广场服务器的密钥,进行启动客户端守护进程前的准备工作
|
// 已获得主广场服务器的密钥,进行启动客户端守护进程前的准备工作
|
||||||
nclt.NewRequest(&preq, msqe_ip, msqe_port, "private request", json_str, true);
|
nclt.NewRequest(&preq, msqe_ip, msqe_port, "private request", json_str, true);
|
||||||
nclt.NewRequestListener(preq, 99, psql,registerSQECallback);
|
nclt.NewRequestListener(preq, 44, psql,registerSQECallback);
|
||||||
|
|
||||||
|
//等待主广场服务器回应
|
||||||
if_wait = 1;
|
if_wait = 1;
|
||||||
while (if_wait) {
|
while (if_wait == 1) {
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
if (!if_wait) {
|
if (!if_wait) {
|
||||||
|
|
||||||
// 成功注册
|
// 成功注册
|
||||||
printf("Wait for server to connect\n");
|
printf("Get Respond From Server.\n");
|
||||||
// 创建守护进程
|
// 创建守护进程
|
||||||
|
|
||||||
int shmid = shmget((key_t)9058, 1024, 0666|IPC_CREAT);
|
int shmid = shmget((key_t)9058, 1024, 0666|IPC_CREAT);
|
||||||
if(shmid == -1){
|
if(shmid == -1){
|
||||||
printf("SHMAT Failed.\n");
|
printf("SHMAT Failed.\n");
|
||||||
}
|
}
|
||||||
pid_t fpid = fork();
|
pid_t fpid = fork();
|
||||||
if(fpid == 0){
|
if(fpid == 0){
|
||||||
|
//守护进程
|
||||||
printf("Client Register Deamon Has Been Created.");
|
printf("Client Register Deamon Has Been Created.");
|
||||||
nclt.server_cnt = new SocketTCPCServer(9053);
|
nclt.server_cnt = new SocketTCPCServer(9052);
|
||||||
nclt.server_cnt->Listen();
|
nclt.server_cnt->Listen();
|
||||||
|
|
||||||
// 获得共享内存地址
|
// 获得共享内存地址
|
||||||
Byte *buff = (Byte *)shmat(shmid, NULL, 0);
|
Byte *buff = (Byte *)shmat(shmid, NULL, 0);
|
||||||
if(shmid == -1){
|
if(shmid == -1){
|
||||||
printf("SHMAT Failed.\n");
|
printf("SHMAT Failed.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if(!memcmp(buff, "SEND", sizeof(uint32_t))){
|
//检测父进程信号
|
||||||
printf("Get Sending Raw Data\n");
|
if(!memcmp(buff, "Exit", sizeof(uint32_t))){
|
||||||
memset(buff, 0, sizeof(uint32_t));
|
error::printInfo("get killing signal.");
|
||||||
|
//断开共享内存连接
|
||||||
|
shmdt(buff);
|
||||||
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
nclt.server_cnt->Accept();
|
nclt.server_cnt->Accept();
|
||||||
//printf("Get connection request from server.\n");
|
|
||||||
connection_listener *pncl = new connection_listener();
|
connection_listener *pncl = new connection_listener();
|
||||||
pncl->client_addr = nclt.server_cnt->GetClientAddr();
|
pncl->client_addr = nclt.server_cnt->GetClientAddr();
|
||||||
pncl->data_sfd = nclt.server_cnt->GetDataSFD();
|
pncl->data_sfd = nclt.server_cnt->GetDataSFD();
|
||||||
pncl->key = nclt.post_key;
|
pncl->key = nclt.post_key;
|
||||||
|
pncl->father_buff = buff;
|
||||||
|
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
@ -512,24 +565,35 @@ int client(string instruct, vector<string> &configs, vector<string> &lconfigs, v
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// 父进程
|
//父进程
|
||||||
|
//创建并获得共享内存地址
|
||||||
int shmid = shmget((key_t)9058, 1024, 0666|IPC_CREAT);
|
int shmid = shmget((key_t)9058, 1024, 0666|IPC_CREAT);
|
||||||
Byte *buff = (Byte *)shmat(shmid, 0, 0);
|
Byte *buff = (Byte *)shmat(shmid, 0, 0);
|
||||||
printf("Net Command line: \n");
|
while (1) {
|
||||||
|
if (!memcmp(buff, "D_OK", sizeof(uint32_t))) {
|
||||||
|
memset(buff, 0, sizeof(uint32_t));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
usleep(1000);
|
||||||
|
}
|
||||||
|
error::printSuccess("\nShell For Client: ");
|
||||||
while (1) {
|
while (1) {
|
||||||
char cmd[1024];
|
char cmd[1024];
|
||||||
printf(">");
|
printf(">");
|
||||||
scanf("%s", cmd);
|
fgets(cmd,1024,stdin);
|
||||||
string cmdstr = cmd;
|
string cmdstr = cmd;
|
||||||
|
|
||||||
if(cmdstr == "send"){
|
if(cmdstr == "Exit"){
|
||||||
memcpy(buff, "SEND", sizeof(uint32_t));
|
memcpy(buff, "Exit", sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,9 @@ namespace error {
|
|||||||
void printRed(string red_info) {
|
void printRed(string red_info) {
|
||||||
printf("\033[31m%s\n\033[0m", red_info.data());
|
printf("\033[31m%s\n\033[0m", red_info.data());
|
||||||
}
|
}
|
||||||
|
void printInfo(string info) {
|
||||||
|
printf("%s\n", info.data());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool config_search(vector<string> &configs,string tfg){
|
bool config_search(vector<string> &configs,string tfg){
|
||||||
@ -88,11 +91,11 @@ void *connectionDeamon(void *args){
|
|||||||
Server::ProcessSignedRawMsg(buff, size, *pnrwd);
|
Server::ProcessSignedRawMsg(buff, size, *pnrwd);
|
||||||
if(!memcmp(&pnrwd->info, "LCNT", sizeof(uint32_t))){
|
if(!memcmp(&pnrwd->info, "LCNT", sizeof(uint32_t))){
|
||||||
if_sm = false;
|
if_sm = false;
|
||||||
printf("Long Connection From Server\n");
|
printf("Long Connection From Server.\n");
|
||||||
}
|
}
|
||||||
else if(!memcmp(&pnrwd->info, "SCNT", sizeof(uint32_t))){
|
else if(!memcmp(&pnrwd->info, "SCNT", sizeof(uint32_t))){
|
||||||
if_sm = true;
|
if_sm = true;
|
||||||
printf("Short Connection From Server\n");
|
printf("Short Connection From Server.\n");
|
||||||
}
|
}
|
||||||
else if(!memcmp(&pnrwd->info, "CNTL", sizeof(uint32_t))){
|
else if(!memcmp(&pnrwd->info, "CNTL", sizeof(uint32_t))){
|
||||||
if_sm = true;
|
if_sm = true;
|
||||||
@ -102,14 +105,14 @@ void *connectionDeamon(void *args){
|
|||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
printf("Connection illegal\n");
|
printf("Connection illegal.\n");
|
||||||
delete pnrwd;
|
delete pnrwd;
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
printf("Connection illegal\n");
|
printf("Connection illegal.\n");
|
||||||
delete pnrwd;
|
delete pnrwd;
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
@ -132,7 +135,8 @@ void *connectionDeamon(void *args){
|
|||||||
Document ndoc;
|
Document ndoc;
|
||||||
ndoc.Parse(jres_str.data());
|
ndoc.Parse(jres_str.data());
|
||||||
if(ndoc["status"].GetString() == string("ok")){
|
if(ndoc["status"].GetString() == string("ok")){
|
||||||
printf("Register Successful.\n");
|
error::printSuccess("Register Successful.");
|
||||||
|
memcpy(pcntl->father_buff,"D_OK", sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ long long ExtEuclid(long long a, long long b)
|
|||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
long long rsa_modExp(long long b, long long e, long long m)
|
long long rsa_modExp(unsigned long long b, unsigned long long e, unsigned long long m)
|
||||||
{
|
{
|
||||||
if (b < 0 || e < 0 || m <= 0){
|
if (b < 0 || e < 0 || m <= 0){
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -164,8 +164,7 @@ unsigned char *rsa_decrypt(const uint64_t *message, const unsigned long message_
|
|||||||
unsigned char *decrypted = (unsigned char *) malloc(message_size/sizeof(uint64_t));
|
unsigned char *decrypted = (unsigned char *) malloc(message_size/sizeof(uint64_t));
|
||||||
unsigned char *temp = (unsigned char *) malloc(message_size);
|
unsigned char *temp = (unsigned char *) malloc(message_size);
|
||||||
if((decrypted == NULL) || (temp == NULL)){
|
if((decrypted == NULL) || (temp == NULL)){
|
||||||
fprintf(stderr,
|
fprintf(stderr,"Error: Heap allocation failed.\n");
|
||||||
"Error: Heap allocation failed.\n");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
// Now we go through each 8-byte chunk and decrypt it.
|
// Now we go through each 8-byte chunk and decrypt it.
|
||||||
|
@ -79,6 +79,7 @@ void setServerClockForSquare(SQEServer *psvr, int clicks){
|
|||||||
setServerClock(psvr, clicks);
|
setServerClock(psvr, clicks);
|
||||||
pthread_mutex_init(&mutex_pktreq, NULL);
|
pthread_mutex_init(&mutex_pktreq, NULL);
|
||||||
pthread_mutex_init(&mutex_cltreg, NULL);
|
pthread_mutex_init(&mutex_cltreg, NULL);
|
||||||
|
|
||||||
// 注册标准数据包处理守护时钟
|
// 注册标准数据包处理守护时钟
|
||||||
clock_register *pncr = new clock_register();
|
clock_register *pncr = new clock_register();
|
||||||
pncr->if_thread = true;
|
pncr->if_thread = true;
|
||||||
@ -98,6 +99,7 @@ void setServerClockForSquare(SQEServer *psvr, int clicks){
|
|||||||
pncr->func = requestProcessorDeamonForSquare;
|
pncr->func = requestProcessorDeamonForSquare;
|
||||||
pncr->arg = (void *)psvr;
|
pncr->arg = (void *)psvr;
|
||||||
newClock(pncr);
|
newClock(pncr);
|
||||||
|
error::printSuccess("Server Started...");
|
||||||
}
|
}
|
||||||
|
|
||||||
Server::Server(int port, string send_ip,int send_port):socket(port),send_socket(send_ip,send_port){
|
Server::Server(int port, string send_ip,int send_port):socket(port),send_socket(send_ip,send_port){
|
||||||
@ -289,6 +291,7 @@ void Client::SendRawData(raw_data *trdt){
|
|||||||
|
|
||||||
int Server::SentRawdata(struct raw_data *trdt){
|
int Server::SentRawdata(struct raw_data *trdt){
|
||||||
// 对大包进行拆分发送
|
// 对大包进行拆分发送
|
||||||
|
int rtn = 0;
|
||||||
if(trdt->msg_size > 256){
|
if(trdt->msg_size > 256){
|
||||||
uint64_t aidx = 0,bidx = 0;
|
uint64_t aidx = 0,bidx = 0;
|
||||||
int64_t alls = trdt->msg_size;
|
int64_t alls = trdt->msg_size;
|
||||||
@ -306,13 +309,15 @@ int Server::SentRawdata(struct raw_data *trdt){
|
|||||||
nnb.set(f_byte,bidx-aidx+1);
|
nnb.set(f_byte,bidx-aidx+1);
|
||||||
|
|
||||||
nnb.build();
|
nnb.build();
|
||||||
send_socket.SendRAW((Byte *)nnb.send_data, nnb.sdt_size);
|
rtn = send_socket.SendRAW((Byte *)nnb.send_data, nnb.sdt_size);
|
||||||
aidx = bidx+1;
|
aidx = bidx+1;
|
||||||
tmp_idx++;
|
tmp_idx++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else send_socket.SendRAW(trdt->msg, trdt->msg_size);
|
else {
|
||||||
return 0;
|
rtn = send_socket.SendRAW(trdt->msg, trdt->msg_size);
|
||||||
|
}
|
||||||
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
void net_box::FreeNetBox(void){
|
void net_box::FreeNetBox(void){
|
||||||
@ -397,6 +402,7 @@ void *serverDeamon(void *pvcti){
|
|||||||
|
|
||||||
if((pnbxl_itr = psvr->boxls.find(pnbx->b_id)) != psvr->boxls.end()){
|
if((pnbxl_itr = psvr->boxls.find(pnbx->b_id)) != psvr->boxls.end()){
|
||||||
box_listener *pnbxl = pnbxl_itr->second;
|
box_listener *pnbxl = pnbxl_itr->second;
|
||||||
|
|
||||||
if (pthread_mutex_lock(&mutex_box) != 0) throw "lock error";
|
if (pthread_mutex_lock(&mutex_box) != 0) throw "lock error";
|
||||||
if(pnbxl->boxs[pnbx->idx] == nullptr && pnbxl->nbn < pnbxl->cnt){
|
if(pnbxl->boxs[pnbx->idx] == nullptr && pnbxl->nbn < pnbxl->cnt){
|
||||||
pnbxl->boxs[pnbx->idx] = pnbx;
|
pnbxl->boxs[pnbx->idx] = pnbx;
|
||||||
@ -412,6 +418,7 @@ void *serverDeamon(void *pvcti){
|
|||||||
else{
|
else{
|
||||||
box_listener *pnbxl = new box_listener();
|
box_listener *pnbxl = new box_listener();
|
||||||
pnbxl->cnt = pnbx->cnt;
|
pnbxl->cnt = pnbx->cnt;
|
||||||
|
pnbxl->address = *(struct sockaddr_in *)taddr.RawObj();
|
||||||
pnbxl->boxs = (net_box **) malloc(sizeof(net_box *) * pnbxl->cnt);
|
pnbxl->boxs = (net_box **) malloc(sizeof(net_box *) * pnbxl->cnt);
|
||||||
memset(pnbxl->boxs, 0, sizeof(net_box *) * pnbxl->cnt);
|
memset(pnbxl->boxs, 0, sizeof(net_box *) * pnbxl->cnt);
|
||||||
pnbxl->boxs[pnbx->idx] = pnbx;
|
pnbxl->boxs[pnbx->idx] = pnbx;
|
||||||
@ -465,6 +472,7 @@ void *boxProcessorDeamon(void *pvcti){
|
|||||||
raw_data *pnrdt = new raw_data();
|
raw_data *pnrdt = new raw_data();
|
||||||
pboxl->TogtRawData(*pnrdt);
|
pboxl->TogtRawData(*pnrdt);
|
||||||
pnrdt->r_id = pboxl->b_id;
|
pnrdt->r_id = pboxl->b_id;
|
||||||
|
pnrdt->address = pboxl->address;
|
||||||
psvr->rawdata_in.push_back(pnrdt);
|
psvr->rawdata_in.push_back(pnrdt);
|
||||||
pboxl->clicks = -1;
|
pboxl->clicks = -1;
|
||||||
pboxl->free_boxs();
|
pboxl->free_boxs();
|
||||||
@ -632,14 +640,16 @@ void SQEServer::ProcessPacket(void){
|
|||||||
}
|
}
|
||||||
|
|
||||||
SQEServer::SQEServer(int port):Server(port){
|
SQEServer::SQEServer(int port):Server(port){
|
||||||
|
//连接数据库
|
||||||
if(sqlite3_open("info.db", &psql) == SQLITE_ERROR){
|
if(sqlite3_open("info.db", &psql) == SQLITE_ERROR){
|
||||||
sql::printError(psql);
|
sql::printError(psql);
|
||||||
throw "database is abnormal";
|
throw "database is abnormal";
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3_stmt *psqlsmt;
|
sqlite3_stmt *psqlsmt;
|
||||||
const char *pzTail;
|
const char *pzTail;
|
||||||
// 从数据库获得服务器的公私钥
|
// 从数据库获得服务器的公私钥及服务器名
|
||||||
string sql_quote = "select sqes_public,sqes_private from server_info where rowid = 1;";
|
string sql_quote = "select sqes_public,sqes_private,name from server_info where rowid = 1;";
|
||||||
sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
|
sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
|
||||||
if(sqlite3_step(psqlsmt) != SQLITE_ROW){
|
if(sqlite3_step(psqlsmt) != SQLITE_ROW){
|
||||||
sql::printError(psql);
|
sql::printError(psql);
|
||||||
@ -650,8 +660,13 @@ SQEServer::SQEServer(int port):Server(port){
|
|||||||
|
|
||||||
tbyt = (Byte *)sqlite3_column_blob(psqlsmt, 1);
|
tbyt = (Byte *)sqlite3_column_blob(psqlsmt, 1);
|
||||||
memcpy(&prc, tbyt, sizeof(private_key_class));
|
memcpy(&prc, tbyt, sizeof(private_key_class));
|
||||||
|
name = (const char *)sqlite3_column_blob(psqlsmt, 2);
|
||||||
sqlite3_finalize(psqlsmt);
|
sqlite3_finalize(psqlsmt);
|
||||||
|
|
||||||
|
//打印关键信息
|
||||||
|
error::printSuccess("Server Name: "+name);
|
||||||
|
error::printSuccess("Listen Port: " + std::to_string(port));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SQEServer::Packet2Request(packet &pkt, request &req){
|
void SQEServer::Packet2Request(packet &pkt, request &req){
|
||||||
@ -734,13 +749,13 @@ void SQEServer::ProcessRequset(void){
|
|||||||
pclr->t_addr.SetIP(jdoc["listen_ip"].GetString());
|
pclr->t_addr.SetIP(jdoc["listen_ip"].GetString());
|
||||||
pclr->t_addr.SetPort(port);
|
pclr->t_addr.SetPort(port);
|
||||||
pclr->passwd = rand64();
|
pclr->passwd = rand64();
|
||||||
// 联络进程生命周期
|
// 联络线程生命周期
|
||||||
pclr->click = 9999;
|
pclr->click = 9999;
|
||||||
//if(pthread_mutex_lock(&mutex_cltreg) != 0) throw "lock error";
|
//if(pthread_mutex_lock(&mutex_cltreg) != 0) throw "lock error";
|
||||||
client_lst.insert({pclr->client_id,pclr});
|
client_lst.insert({pclr->client_id,pclr});
|
||||||
//pthread_mutex_unlock(&mutex_cltreg);
|
//pthread_mutex_unlock(&mutex_cltreg);
|
||||||
|
|
||||||
printf("Ready to connect client %s[%s].\n",pclr->name.data(),pclr->tag.data());
|
printf("Register: %s[%s] IP: %s TCP_Port: %d\n",pclr->name.data(),pclr->tag.data(),jdoc["listen_ip"].GetString(),port);
|
||||||
// 注册客户端联络守护进程
|
// 注册客户端联络守护进程
|
||||||
clock_register *pncr = new clock_register();
|
clock_register *pncr = new clock_register();
|
||||||
pncr->if_thread = true;
|
pncr->if_thread = true;
|
||||||
@ -827,7 +842,10 @@ void Server::ProcessSendPackets(void){
|
|||||||
Packet2Rawdata(*ppkt, nrwd);
|
Packet2Rawdata(*ppkt, nrwd);
|
||||||
SignedRawdata(&nrwd, "SPKT");
|
SignedRawdata(&nrwd, "SPKT");
|
||||||
send_socket.SetSendSockAddr(ppkt->address);
|
send_socket.SetSendSockAddr(ppkt->address);
|
||||||
SentRawdata(&nrwd);
|
if (SentRawdata(&nrwd) < 0) {
|
||||||
|
error::printError("fail to send package.");
|
||||||
|
perror("sendto");
|
||||||
|
}
|
||||||
freeRawdataServer(nrwd);
|
freeRawdataServer(nrwd);
|
||||||
freePcaketServer(*ppkt);
|
freePcaketServer(*ppkt);
|
||||||
delete ppkt;
|
delete ppkt;
|
||||||
|
Loading…
Reference in New Issue
Block a user