修正与添加

利用UDP与TCP双协议,添加了广场服务器与网络节点建立注册关系的功能,在此之上实现了网络节点的长短TCP连接管理。为端对端加密报文通信功能的完善打下了基础。
This commit is contained in:
Saturneic 2019-02-17 18:40:37 +08:00
parent 743ceef54f
commit e1453765a4
10 changed files with 682 additions and 66 deletions

View File

@ -50,5 +50,6 @@ int set(string instruct, vector<string> &configs, vector<string> &lconfigs, vect
bool config_search(vector<string> &configs,string tfg);
void getSQEPublicKey(respond *pres,void *args);
void registerSQECallback(respond *pres,void *args);
void* connectionDeamon(void *args);
#endif /* instruct_h */

View File

@ -45,7 +45,7 @@ public:
//服务器套接字类
class SocketServer{
protected:
public :
// 套接字操作柄
int server_sfd;
// 服务器IP及端口管理类
@ -54,7 +54,6 @@ protected:
int ipptl;
// 临时缓冲区
char buff[BUFSIZ];
public :
SocketServer(int port,bool ipv4){
server_addr.SetPort(port);
if(ipv4){
@ -66,6 +65,9 @@ public :
server_addr.SetIpv6();
}
}
SocketServer(void){
server_sfd = -1;
}
~SocketServer(){
//close(server_sfd);
}
@ -77,7 +79,7 @@ public :
//客户端套接字类
class SocketClient{
protected:
public :
// 目标服务器IP地址及端口管理类
Addr send_addr;
// 套接字操作柄
@ -86,7 +88,7 @@ protected:
int ipptl;
// 临时缓冲区
char buff[BUFSIZ];
public :
SocketClient(string ip,int port,bool ipv4){
send_addr.SetIP(ip);
send_addr.SetPort(port);
@ -99,13 +101,24 @@ public :
send_addr.SetIpv6();
}
}
SocketClient(sockaddr_in &taddr,bool ipv4){
send_addr.SetSockAddr(taddr);
if(ipv4){
ipptl = PF_INET;
send_addr.SetIpv4();
}
else{
ipptl = PF_INET6;
send_addr.SetIpv6();
}
}
~SocketClient(){
//close(client_sfd);
}
// 接受储存简单字符串
virtual void Send(string buff) = 0;
// 接受储存二进制串
virtual void SendRAW(char *buff, unsigned long size) = 0;
virtual ssize_t SendRAW(char *buff, unsigned long size) = 0;
// 重新设置发送目的地的端口
void SetSendPort(int port);
// 重新设置发送目的地的IP地址
@ -124,8 +137,10 @@ public :
//TCP服务器套接字类
class SocketTCPCServer:public SocketServer{
// 连接操作柄
int ctn_sfd;
int data_sfd;
void (*func)(class Socket &,int ,Addr);
Addr client_addr;
public:
SocketTCPCServer(int port):SocketServer(port,true){
// 获得套接字操作柄
@ -133,20 +148,34 @@ public:
if(!~server_sfd) throw "fail to get server sfd";
// 绑定IP地址与端口
if(!~bind(server_sfd, server_addr.RawObj(), server_addr.Size())) throw "fail to bind";
// 设置接受信息非阻塞
}
SocketTCPCServer(void):SocketServer(){
data_sfd = -1;
}
// 监听端口
void Listen(int connection, void (*func)(class Socket &,int ,Addr) = NULL);
int Listen(void);
// 接受连接
void Accept(void);
Addr &GetAddr(void);
Addr &GetClientAddr(void);
int GetDataSFD(void);
void SetDataSFD(int tdata_sfd);
void SetClientAddr(Addr &caddr);
void CloseConnection(void);
// 接收简单字符串数据
ssize_t Recv(string &str);
// 接受储存二进制串
ssize_t RecvRAW(char **p_rdt, Addr &taddr);
ssize_t RecvRAW_SM(char **p_rdt, Addr &taddr);
void SendRespond(string &str);
};
//TCP客户端套接字类
class SocketTCPClient:public SocketClient{
public:
// 连接操作柄
int ctn_sfd;
public:
SocketTCPClient(string ip,int port):SocketClient(ip,port,true){
// 获得套接字操作柄
client_sfd = socket(ipptl,SOCK_STREAM,0);
@ -154,8 +183,25 @@ public:
// 建立TCP连接
if(!~connect(client_sfd,send_addr.RawObj(),send_addr.Size())) throw "fail to connect";
}
SocketTCPClient(sockaddr_in &taddr):SocketClient(taddr,true){
// 获得套接字操作柄
client_sfd = socket(ipptl,SOCK_STREAM,0);
if(!~client_sfd) throw "fail to get client sfd";
//send_addr.SetIP("127.0.0.1");
//send_addr.SetPort(9053);
// 建立TCP连接
if(connect(client_sfd,send_addr.RawObj(),send_addr.Size()) < 0) throw "fail to connect";
}
// 发送简单字符串数据
void Send(string str);
void Reconnect(void);
Addr &GetAddr(void);
void SetAddr(Addr &);
ssize_t SendRAW(char *buff, unsigned long size);
ssize_t RecvRAW(char **p_rdt, Addr &taddr);
void GetRespond(string &str);
void Close(void);
};
@ -173,6 +219,10 @@ public:
if(!~server_sfd) throw "fail to get server sfd";
// 绑定IP地址与端口
if(!~bind(server_sfd, server_addr.RawObj(), server_addr.Size())) throw "fail to bind";
// 设置非阻塞
//int flags = fcntl(server_sfd, F_GETFL, 0);
//fcntl(server_sfd, F_SETFL, flags | O_NONBLOCK);
}
// 接受储存简单字符串信息的数据包
ssize_t Recv(string &str);
@ -193,7 +243,7 @@ public:
// 发送简单字符串数据
void Send(string buff);
// 发送一个带有二进制原始信息的数据包
void SendRAW(char *buff, unsigned long size);
ssize_t SendRAW(char *buff, unsigned long size);
};
#endif /* net_h */

View File

@ -57,18 +57,19 @@ struct request {
struct encrypt_post{
// 注册客户端id
uint64_t client_id;
// 目标ip
string ip;
// 目标端口
int port;
// 目标地址信息
Addr t_addr;
// 匹配id
uint64_t p_id;
// 类型
uint32_t type;
// 内容
Byte *buff;
Byte *buff = nullptr;
// 内容长度
uint32_t buff_size;
uint32_t buff_size = 0;
void SetBuff(Byte *buff, uint32_t size);
void FreeBuff(void);
~encrypt_post(void);
};
//回复数据包
@ -141,8 +142,13 @@ struct server_info{
struct aes_key256{
uint64_t key[4];
uint64_t iv[4];
// 生成新的随机密钥
aes_key256();
void MakeIV(void);
// 获得初始化向量
const uint8_t *GetIV(void);
const uint8_t *GetKey(void);
};
@ -191,7 +197,30 @@ struct client_register{
aes_key256 key;
string name;
string tag;
uint32_t clicks;
// 服务器资源租用时间
uint32_t click;
// 认证口令
uint64_t passwd;
// 目标地址信息
Addr t_addr;
// 守护线程ID
pthread_t tid;
};
struct client_listen{
bool if_get;
bool if_connected = true;
pthread_t pid;
SocketTCPClient *ptcps;
encrypt_post *pcryp;
client_register *pcltr;
};
struct connection_listener{
int data_sfd;
Addr client_addr;
aes_key256 key;
pthread_t pid;
};
//通用服务器类
@ -201,6 +230,7 @@ protected:
list<packet *> packets_in;
// 缓存带标签的二进制串管理结构
list<raw_data *> rawdata_in;
map<uint64_t, client_register *> rids;
// 输出的数据包列表
list<packet *> packets_out;
map<uint64_t,box_listener *> boxls;
@ -285,7 +315,10 @@ public:
static void Request2Packet(packet &pkt, request &req);
static void Respond2Packet(packet &pkt, respond &res);
static void Packet2Respond(packet &pkt, respond &res);
static void BuildBeatsRawData(raw_data &rwd);
static void BuildSmallRawData(raw_data &rwd, const char *info);
static void Post2SignedRawData(void *buff, uint32_t buff_size, const char *info, aes_key256 &key, raw_data &rw);
static void SignedRawData2Post(raw_data &rwd, encrypt_post &pst, aes_key256 &key);
static void Post2Packet(packet &pkt, encrypt_post &pst, aes_key256 &key);
static void Packet2Post(packet &pkt, encrypt_post &pst, aes_key256 &key);
static void GetPostInfo(packet &pkt, encrypt_post &pst);
@ -295,12 +328,16 @@ public:
class Client{
// 请求监听列表
list<request_listener *> req_lst;
list<raw_data *> rwd_lst;
// 回复处理列表
list<respond *> res_lst;
// 请求监听端口
uint32_t listen_port;
SocketUDPServer socket;
SocketUDPClient send_socket;
// 与服务器建立的稳定链接
SocketTCPCServer *server_cnt;
// 广场服务器通信公钥
public_key_class sqe_pbc;
// 报文密钥

View File

@ -15,8 +15,9 @@ Addr::Addr(string ip_addr, int port, bool ipv4){
else
address.sin_family = AF_INET6;
address.sin_port = htons(port);
in_addr_t ipu = inet_addr(ip_addr.data());
memcpy(&address.sin_addr, &ipu, sizeof(in_addr_t));
address.sin_addr.s_addr = inet_addr(ip_addr.data());
addr_size = sizeof(address);
}
@ -53,7 +54,8 @@ void Addr::SetPort(int port){
}
void Addr::SetIP(string ip_addr){
address.sin_addr.s_addr = inet_addr(ip_addr.data());
in_addr_t ipu = inet_addr(ip_addr.data());
memcpy(&address.sin_addr, &ipu, sizeof(in_addr_t));
addr_size = sizeof(address);
}

View File

@ -44,7 +44,6 @@ void *clientRespondDeamon(void *pvclt){
do{
tlen = pclient->socket.RecvRAW(&str,taddr);
if(tlen > 0){
// 记录有效数据包
if(Server::CheckRawMsg(str, tlen)){

View File

@ -53,7 +53,7 @@ void threadsClock(int n){
// 删除到期时钟
if(clock_erase == 0){
printf("Cleaning clocks.\n");
//printf("Cleaning clocks.\n");
clocks_list.remove_if([](clock_register *pclock){return pclock == NULL;});
// 重设总滴答数
clock_erase = CLOCKESE;

View File

@ -217,7 +217,7 @@ int server(string instruct, vector<string> &configs, vector<string> &lconfigs, v
setServerClockForSquare(&nsvr, 3);
}
}
while(1) usleep(10000);
while(1) sleep(1);
return 0;
}
@ -319,7 +319,7 @@ int client(string instruct, vector<string> &configs, vector<string> &lconfigs, v
// 如果本地没有主广场服务器的公钥
if(if_null){
nclt.NewRequest(&preq, msqe_ip, msqe_port, "client-square request", "request for public key");
nclt.NewRequest(&preq, msqe_ip, msqe_port, "public request", "request for public key");
nclt.NewRequestListener(preq, 30, psql, getSQEPublicKey);
if_wait = 1;
while (if_wait == 1) {
@ -349,7 +349,7 @@ int client(string instruct, vector<string> &configs, vector<string> &lconfigs, v
aes_key256 naeskey;
nclt.SetAESKey(naeskey);
string reqstr = " {\"key\":null, \"name\":null, \"tag\":null, \"sqe_key\":null}";
string reqstr = " {\"key\":null, \"name\":null, \"tag\":null, \"sqe_key\":null, \"listen_port\": null,\"listen_ip\":null}";
Document reqdata;
if(reqdata.Parse(reqstr.data()).HasParseError()) throw "fail to parse into json";
@ -365,6 +365,10 @@ int client(string instruct, vector<string> &configs, vector<string> &lconfigs, v
reqdata["name"].SetString(nclt.name.data(),(uint32_t)nclt.name.size());
reqdata["tag"].SetString(nclt.tag.data(),(uint32_t)nclt.name.size());
reqdata["sqe_key"].SetString(nclt.sqe_key.data(), (uint32_t)nclt.sqe_key.size());
reqdata["listen_port"].SetInt(9053);
string ip = inet_ntoa(nclt.server_cnt->GetAddr().Obj()->sin_addr);
reqdata["listen_ip"].SetString(ip.data(),(uint32_t)ip.size());
StringBuffer strbuff;
Writer<StringBuffer> writer(strbuff);
@ -372,13 +376,34 @@ int client(string instruct, vector<string> &configs, vector<string> &lconfigs, v
string json_str = strbuff.GetString();
printf("JSON: %s\n",json_str.data());
// 已获得主广场服务器的密钥,进行启动客户端守护进程前的准备工作
nclt.NewRequest(&preq, msqe_ip, msqe_port, "client-register request", json_str, true);
nclt.NewRequestListener(preq, 9999, psql,registerSQECallback);
nclt.NewRequest(&preq, msqe_ip, msqe_port, "private request", json_str, true);
nclt.NewRequestListener(preq, 99, psql,registerSQECallback);
if_wait = 1;
while (1) {
sleep(10);
while (if_wait) {
sleep(1);
}
if (!if_wait) {
// 成功注册
printf("Wait for server to connect\n");
nclt.server_cnt = new SocketTCPCServer(9053);
nclt.server_cnt->Listen();
while (1) {
nclt.server_cnt->Accept();
printf("Get connection request from server.\n");
connection_listener *pncl = new connection_listener();
pncl->client_addr = nclt.server_cnt->GetClientAddr();
pncl->data_sfd = nclt.server_cnt->GetDataSFD();
pncl->key = nclt.post_key;
pthread_create(&pncl->pid, NULL, connectionDeamon, pncl);
}
}
return 0;
}

View File

@ -47,12 +47,105 @@ void getSQEPublicKey(respond *pres,void *args){
void registerSQECallback(respond *pres,void *args){
if(pres != nullptr){
string resjson = string(pres->buff,pres->buff_size);
Document resdoc;
resdoc.Parse(resjson.data());
string status = resdoc["status"].GetString();
if(status == "ok"){
printf("Register succeed.\n");
if_wait = 0;
}
else{
printf("Register Fail.\n");
if_wait = -1;
}
}
else{
if_wait = -1;
printf("request timeout.\n");
printf("Request timeout.\n");
}
}
void* connectionDeamon(void *args){
connection_listener * pcntl = (connection_listener *)args;
string first_data;
printf("Start Listen Connection From Server.\n");
char *buff = nullptr;
Addr t_addr;
ssize_t size = 0;
SocketTCPCServer ntcps;
ntcps.SetDataSFD(pcntl->data_sfd);
ntcps.SetClientAddr(pcntl->client_addr);
// 获得连接的类型是长链还是断链
size = ntcps.RecvRAW_SM(&buff, t_addr);
raw_data *pnrwd = new raw_data();
// 长连接还是短连接
bool if_sm = true;
if(Server::CheckRawMsg(buff, size)){
Server::ProcessSignedRawMsg(buff, size, *pnrwd);
if(!memcmp(&pnrwd->info, "LCNT", sizeof(uint32_t))){
if_sm = false;
printf("Long Connection From Server\n");
}
else if(!memcmp(&pnrwd->info, "SCNT", sizeof(uint32_t))){
if_sm = true;
printf("Short Connection From Server\n");
}
else{
printf("Connection illegal\n");
delete pnrwd;
pthread_exit(NULL);
}
}
else{
printf("Connection illegal\n");
delete pnrwd;
pthread_exit(NULL);
}
delete pnrwd;
while (1) {
if(if_sm) size = ntcps.RecvRAW(&buff, t_addr);
else size = ntcps.RecvRAW_SM(&buff, t_addr);
raw_data *pnrwd = new raw_data();
packet *nppkt = new packet();
encrypt_post *pncryp = new encrypt_post();
if(size > 0){
if(Server::CheckRawMsg(buff, size)){
Server::ProcessSignedRawMsg(buff, size, *pnrwd);
if(!memcmp(&pnrwd->info, "ECYP", sizeof(uint32_t))){
Server::Rawdata2Packet(*nppkt, *pnrwd);
SQEServer::Packet2Post(*nppkt, *pncryp, pcntl->key);
if(!memcmp(&pncryp->type, "JRES", sizeof(uint32_t))){
string jres_str = string(pncryp->buff,pncryp->buff_size);
Document ndoc;
ndoc.Parse(jres_str.data());
if(ndoc["status"].GetString() == string("ok")){
printf("Register Successful.\n");
}
}
}
else if(!memcmp(&pnrwd->info, "BEAT", sizeof(uint32_t))){
printf("Connection Beated.\n");
}
Server::freeRawdataServer(*pnrwd);
Server::freePcaketServer(*nppkt);
}
else if(size < 0){
printf("Lost Connection From Server.\n");
delete pnrwd;
delete pncryp;
delete nppkt;
delete pcntl;
break;
}
free(buff);
}
delete pnrwd;
delete pncryp;
delete nppkt;
}
pthread_exit(NULL);
}

View File

@ -695,7 +695,7 @@ void SQEServer::ProcessRequset(void){
for(auto &preq : req_list){
if(preq == nullptr) continue;
if(prm-- == 0) break;
if(preq->type == "client-square request"){
if(preq->type == "public request"){
if(preq->data == "request for public key"){
respond *pnr = new respond();
pnr->r_id = preq->r_id;
@ -711,11 +711,15 @@ void SQEServer::ProcessRequset(void){
pthread_mutex_unlock(&mutex_sndpkt);
}
}
else if(preq->type == "client-register request"){
else if(preq->type == "private request"){
// 解析JSON结构
preq->req_doc.Parse(preq->data.data());
Document &jdoc = preq->req_doc;
if(1){
auto cltr = rids.find(preq->r_id);
if(cltr != rids.end()){
}
else if(1){
client_register *pclr = new client_register();
pclr->client_id = rand64();
uint8_t *pkey = (uint8_t *) pclr->key.key;
@ -725,11 +729,47 @@ void SQEServer::ProcessRequset(void){
pclr->name = jdoc["name"].GetString();
pclr->tag = jdoc["tag"].GetString();
if(pthread_mutex_lock(&mutex_cltreg) != 0) throw "lock error";
pclr->t_addr = preq->t_addr;
int port = jdoc["listen_port"].GetInt();
pclr->t_addr.SetIP(jdoc["listen_ip"].GetString());
pclr->t_addr.SetPort(port);
pclr->passwd = rand64();
// 联络进程生命周期
pclr->click = 9999;
//if(pthread_mutex_lock(&mutex_cltreg) != 0) throw "lock error";
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());
// 注册客户端联络守护进程
clock_register *pncr = new clock_register();
pncr->if_thread = true;
pncr->if_reset = false;
pncr->click = 64;
pncr->rawclick = 0;
pncr->func = clientWaitDeamon;
pncr->arg = (void *)pclr;
newClock(pncr);
rids.insert({preq->r_id,pclr});
}
// 构建回复包
respond *pnr = new respond();
pnr->r_id = preq->r_id;
string res_data = "{\"status\":\"ok\"}";
pnr->SetBuff((Byte *)res_data.data(), (uint32_t)res_data.size());
pnr->type = "register respond";
pnr->t_addr = preq->t_addr;
pnr->t_addr.SetPort(preq->recv_port);
packet *pnpkt = new packet();
Respond2Packet(*pnpkt, *pnr);
delete pnr;
// 将标准数据包添加到发送列表
if(pthread_mutex_lock(&mutex_sndpkt) != 0) throw "lock error";
packets_out.push_back(pnpkt);
pthread_mutex_unlock(&mutex_sndpkt);
}
delete preq;
@ -811,45 +851,61 @@ const uint8_t *aes_key256::GetKey(void){
void SQEServer::Post2Packet(packet &pkt, encrypt_post &pst, aes_key256 &key){
pkt.type = ENCRYPT_POST_TYPE;
Addr taddr(pst.ip,pst.port);
pkt.address = *taddr.Obj();
pkt.address = *(struct sockaddr_in *)pst.t_addr.Obj();
pkt.AddBuff(&pst.client_id, sizeof(uint64_t));//0
pkt.AddBuff(&pst.p_id, sizeof(uint64_t));//1
pkt.AddBuff((const void *)pst.ip.data(), (uint32_t)pst.ip.size());//2
pkt.AddBuff((void *)&pst.port, sizeof(uint32_t));//3
pkt.AddBuff((struct sockaddr_in *)pst.t_addr.Obj(), sizeof(struct sockaddr_in));//2
// 加密数据
struct AES_ctx naes;
key.MakeIV();
AES_init_ctx_iv(&naes, key.GetKey(),key.GetIV());
// 加密数据填充对齐
if(pst.buff_size % 16){
Byte *t_data = (Byte *) malloc((pst.buff_size/16 + 1) * 16);
memset(t_data, 0, (pst.buff_size/16 + 1) * 16);
memcpy(t_data, pst.buff, pst.buff_size);
pst.buff_size = (pst.buff_size/16 + 1) * 16;
free(pst.buff);
pst.buff = t_data;
}
string MD5_HEX;
MD5EncryptEasy(MD5_HEX, pst.buff, pst.buff_size);
// 加密数据
AES_ctx naes;
AES_init_ctx(&naes, key.GetKey());
AES_CBC_encrypt_buffer(&naes, (uint8_t *)pst.buff, pst.buff_size);
pkt.AddBuff(pst.buff, pst.buff_size);//4
pkt.AddBuff((void *)MD5_HEX.data(), (uint32_t)MD5_HEX.size());//5
pkt.AddBuff(pst.buff, pst.buff_size);//3
pkt.AddBuff((void *)MD5_HEX.data(), 32);//4
pkt.AddBuff((void *)&pst.type, sizeof(uint32_t));//5
}
void SQEServer::GetPostInfo(packet &pkt, encrypt_post &pst){
pst.client_id = *(uint64_t *)pkt.buffs[0].second;
pst.p_id = *(uint64_t *)pkt.buffs[1].second;
pst.ip = (const char *)pkt.buffs[2].second;
pst.port = *(uint32_t *)pkt.buffs[3].second;
pst.t_addr = Addr(*(struct sockaddr_in *)pkt.buffs[2].second);
}
void SQEServer::Packet2Post(packet &pkt, encrypt_post &pst, aes_key256 &key){
pst.client_id = *(uint64_t *)pkt.buffs[0].second;
pst.p_id = *(uint64_t *)pkt.buffs[1].second;
pst.ip = (const char *)pkt.buffs[2].second;
pst.port = *(uint32_t *)pkt.buffs[3].second;
pst.buff_size = pkt.buffs[4].first;
pst.t_addr = Addr(*(struct sockaddr_in *)pkt.buffs[2].second);
pst.type = *(uint32_t *)pkt.buffs[5].second;
pst.buff_size = pkt.buffs[3].first;
string TMD5,MD5;
MD5 = (const char *)pkt.buffs[5].second;
TMD5 = string((const char *)pkt.buffs[4].second,32);
uint8_t *t_data = (uint8_t *)malloc(pst.buff_size);
memcpy(t_data, pkt.buffs[4].second, pst.buff_size);
memcpy(t_data, pkt.buffs[3].second, pst.buff_size);
// 解密数据
AES_ctx naes;
AES_init_ctx(&naes, key.GetKey());
struct AES_ctx naes;
key.MakeIV();
AES_init_ctx_iv(&naes, key.GetKey(),key.GetIV());
AES_CBC_decrypt_buffer(&naes, t_data, pst.buff_size);
MD5EncryptEasy(MD5, (Byte *)t_data, pst.buff_size);
// 校验数据
if(TMD5 != MD5) throw "key error";
pst.buff = (Byte *)t_data;
@ -875,6 +931,12 @@ void net_box::set(void *pbuff, uint16_t pbsize){
memcpy(data, pbuff, pbsize);
}
void encrypt_post::SetBuff(Byte *pbuff, uint32_t size){
buff = (Byte *)malloc(size);
buff_size = size;
memcpy(buff, pbuff, buff_size);
}
void net_box::build(void){
send_data = (UByte *) malloc(data_size+2*sizeof(uint32_t)+3*sizeof(uint16_t)+sizeof(uint64_t));
UByte *tidx = send_data;
@ -941,3 +1003,238 @@ void box_listener::TogtRawData(raw_data &trdt){
}
free(pbyt);
}
encrypt_post::~encrypt_post(){
if(buff != nullptr) free(buff);
}
bool tryConnection(SocketTCPClient **pcnt_sock,client_register *pclr){
try{
*pcnt_sock = new SocketTCPClient (*pclr->t_addr.Obj());
}
catch(const char *error){
if(!strcmp(error, "fail to connect")){
printf("Fail To Connect Client: %s[%s]\n",pclr->name.data(),pclr->tag.data());
return false;
}
}
return true;
}
//发送心跳包
void *clientChecker(void *args){
client_listen *pcltl = (client_listen *)args;
raw_data *pnrwd = new raw_data();
SQEServer::BuildBeatsRawData(*pnrwd);
SocketTCPClient nstcpc(*pcltl->ptcps->GetAddr().Obj());
// 说明连接类型
raw_data nsrwd;
SQEServer::BuildSmallRawData(nsrwd, "LCNT");
nstcpc.SendRAW(nsrwd.msg, nsrwd.msg_size);
Server::freeRawdataServer(nsrwd);
while (1) {
if(pcltl->if_connected == false) break;
if(nstcpc.SendRAW(pnrwd->msg, pnrwd->msg_size) < 0){
printf("Lose Connection %s[%s]\n",pcltl->pcltr->name.data(),pcltl->pcltr->tag.data());
pcltl->if_connected = false;
break;
}
else{
sleep(3);
}
}
pthread_exit(NULL);
}
void *clientListener(void *args){
client_listen *pcltl = (client_listen *)args;
char *buff;
Addr taddr;
while(1){
// 如果连接断开
if(pcltl->if_connected == false) break;
ssize_t size = pcltl->ptcps->RecvRAW(&buff, taddr);
if(size > 0){
if(Server::CheckRawMsg(buff, size)){
raw_data nrwd;
Server::ProcessSignedRawMsg(buff, size, nrwd);
if(!memcmp(&nrwd.info,"ECYP",sizeof(uint32_t))){
packet npkt;
encrypt_post necryp;
Server::Rawdata2Packet(npkt, nrwd);
SQEServer::Packet2Post(npkt, necryp, pcltl->pcltr->key);
Server::freePcaketServer(npkt);
if(!memcmp(&necryp.type,"JIFO",sizeof(uint32_t))){
Document ndoc;
ndoc.Parse(string(necryp.buff,necryp.buff_size).data());
printf("Client %s[%s] Send Encrypt Post(JSON).\n",pcltl->pcltr->name.data(),pcltl->pcltr->tag.data());
uint64_t pwd = ndoc["pwdmd5"].GetInt64();
if(pwd == pcltl->pcltr->passwd){
printf("Password Check Passed.\n");
}
else{
printf("Wrong Password.\n");
}
}
//necryp.FreeBuff();
}
Server::freeRawdataServer(nrwd);
}
free(buff);
}
}
pthread_exit(NULL);
}
void *clientWaitDeamon(void *pvclt){
clock_thread_info *pcti = (clock_thread_info *) pvclt;
client_register *pclr = (client_register *)pcti->args;
SocketTCPClient *pcnt_sock = nullptr;
bool if_success = false;
printf("Connecting client %s[%s].\n",pclr->name.data(),pclr->tag.data());
for(int i = 0; i < 8; i++){
if(tryConnection(&pcnt_sock, pclr)){
if_success = true;
break;
}
else printf("Retry...\n");
sleep(1);
}
if(!if_success){
printf("Fail To Get Register.\n");
delete pclr;
clockThreadFinish(pcti->tid);
pthread_exit(NULL);
}
printf("Get Register: %s[%s]\n",pclr->name.data(),pclr->tag.data());
// 第一报文
string res_type = "{\"status\":\"ok\",\"passwd\":null}";
Document ndoc;
ndoc.Parse(res_type.data());
uint8_t *ppidx = (uint8_t *)&pclr->passwd;
ndoc["passwd"].SetArray();
Document::AllocatorType &allocator = ndoc.GetAllocator();
for(int i = 0; i < 8; i++){
ndoc["passwd"].PushBack(ppidx[i], allocator);
}
StringBuffer sb;
Writer<StringBuffer> writer(sb);
ndoc.Accept(writer);
encrypt_post *ncryp = new encrypt_post();
string send_data = sb.GetString();
// 初始化端对端加密报文
ncryp->SetBuff((Byte *)send_data.data(),(uint32_t)send_data.size());
ncryp->client_id = pclr->client_id;
ncryp->p_id = rand64();
ncryp->t_addr = pclr->t_addr;
memcpy(&ncryp->type, "JRES", sizeof(uint32_t));
packet *nppkt = new packet();
SQEServer::Post2Packet(*nppkt, *ncryp, pclr->key);
raw_data *pnrwd = new raw_data(), nsrwd;
Server::Packet2Rawdata(*nppkt, *pnrwd);
Server::SignedRawdata(pnrwd, "ECYP");
// 说明连接类型
SQEServer::BuildSmallRawData(nsrwd, "SCNT");
pcnt_sock->SendRAW(nsrwd.msg, nsrwd.msg_size);
Server::freeRawdataServer(nsrwd);
pcnt_sock->SendRAW(pnrwd->msg, pnrwd->msg_size);
pcnt_sock->Close();
client_listen *pcltl = new client_listen();
pcltl->pcltr = pclr;
pcltl->if_get = false;
pcltl->pid = 0;
pthread_t bt,lt;
pcltl->pcryp = nullptr;
pcltl->ptcps = pcnt_sock;
pthread_create(&lt, NULL, clientListener, pcltl);
pthread_create(&bt, NULL, clientChecker, pcltl);
while (1 && pclr->click-- > 0) {
sleep(1);
if(pcltl->if_connected == false){
printf("Register lost, start to separate.\n");
break;
}
try{
//pcnt_sock->Reconnect();
//pcnt_sock->Close();
}
catch(const char *error){
if(!strcmp(error, "fail to connect")){
printf("Lose Register: %s[%s]\n",pclr->name.data(),pclr->tag.data());
break;
}
}
}
delete pclr;
delete nppkt;
delete pnrwd;
delete ncryp;
// 等待接收线程返回
pthread_join(lt, NULL);
pthread_join(bt, NULL);
//pcnt_sock->Close();
clockThreadFinish(pcti->tid);
pthread_exit(NULL);
}
void encrypt_post::FreeBuff(void){
if(buff != nullptr){
free(buff);
}
}
void aes_key256::MakeIV(void){
iv[0] = key[2];
iv[1] = key[0];
iv[2] = key[3];
iv[3] = key[1];
}
const uint8_t * aes_key256::GetIV(void){
return (const uint8_t *)iv;
}
void SQEServer::BuildBeatsRawData(raw_data &rwd){
rwd.setData("Beat");
SignedRawdata(&rwd, "BEAT");
}
void SQEServer::Post2SignedRawData(void *buff, uint32_t buff_size, const char *info, aes_key256 &key, raw_data &rwd){
encrypt_post *pecryp = new encrypt_post();
pecryp->SetBuff((Byte *)buff, buff_size);
memcpy(&pecryp->type,info,sizeof(uint32_t));
pecryp->client_id = 0;
pecryp->p_id = rand64();
packet *pnpkt = new packet();
Post2Packet(*pnpkt, *pecryp, key);
Packet2Rawdata(*pnpkt, rwd);
SignedRawdata(&rwd, "ECYP");
delete pnpkt;
delete pecryp;
}
void SQEServer::SignedRawData2Post(raw_data &rwd, encrypt_post &pst, aes_key256 &key){
packet *pnpkt = new packet();
if(!memcmp(&rwd.info, "ECYP", sizeof(uint32_t))){
Rawdata2Packet(*pnpkt, rwd);
Packet2Post(*pnpkt, pst, key);
}
delete pnpkt;
}
void SQEServer::BuildSmallRawData(raw_data &rwd, const char *info){
rwd.setData("");
SignedRawdata(&rwd, info);
}

View File

@ -18,22 +18,20 @@ void SocketClient::SetSendIP(string ip){
}
ssize_t SocketTCPCServer::Recv(string &str){
ssize_t len=recv(ctn_sfd,buff,BUFSIZ,0);
if(len > 0){
buff[len] = '\0';
string str = buff;
return len;
ssize_t bdtas = 0 ,tmp_bdtas;
while ((tmp_bdtas = read(data_sfd, buff, BUFSIZ)) > 0) {
str += string(buff,tmp_bdtas);
bdtas += tmp_bdtas;
}
else return -1;
return bdtas;
}
void SocketTCPCServer::Listen(int connection, void (*func)(class Socket &,int ,Addr)){
listen(server_sfd, 10);
this->func = func;
int SocketTCPCServer::Listen(void){
return listen(server_sfd, 10);
}
void SocketTCPClient::Send(string str){
ssize_t len = send(ctn_sfd,str.data(),str.size(),0);
ssize_t len = send(client_sfd,str.data(),str.size(),0);
if(len != str.size()) throw "size unmatch";
}
@ -117,10 +115,124 @@ void SocketUDPClient::Send(string buff){
sendto(client_sfd, buff.data(), buff.size(), 0, send_addr.RawObj(), send_addr.Size());
}
void SocketUDPClient::SendRAW(char *buff, unsigned long size){
sendto(client_sfd, buff, size, 0, send_addr.RawObj(), send_addr.Size());
ssize_t SocketUDPClient::SendRAW(char *buff, unsigned long size){
return sendto(client_sfd, buff, size, 0, send_addr.RawObj(), send_addr.Size());
}
ssize_t SocketTCPClient::SendRAW(char *buff, unsigned long size){
ssize_t send_size = send(client_sfd, buff, size, 0);
/*if(send_size < 0){
printf("Error[%u]:",errno);
perror("send");
}*/
return send_size;
}
void SocketClient::SetSendSockAddr(struct sockaddr_in tsi){
send_addr.SetSockAddr(tsi);
}
void SocketTCPClient::Close(void){
close(client_sfd);
}
ssize_t SocketTCPCServer::RecvRAW_SM(char **p_rdt, Addr &taddr){
ssize_t tmp_bdtas = recv(data_sfd, buff, BUFSIZ, 0);
if (tmp_bdtas > 0) {
*p_rdt = (char *)malloc(tmp_bdtas);
memcpy(*p_rdt, buff, tmp_bdtas);
}
return tmp_bdtas;
}
ssize_t SocketTCPCServer::RecvRAW(char **p_rdt, Addr &taddr){
ssize_t bdtas = 0 ,tmp_bdtas;
*p_rdt = nullptr;
while ((tmp_bdtas = recv(data_sfd, buff, BUFSIZ, 0)) > 0) {
if(*p_rdt == nullptr){
*p_rdt = (char *)malloc(tmp_bdtas);
memcpy(*p_rdt, buff, tmp_bdtas);
}
else{
*p_rdt = (char *)realloc(*p_rdt, bdtas + tmp_bdtas);
memcpy(*p_rdt + bdtas, buff, tmp_bdtas);
}
bdtas += tmp_bdtas;
}
return bdtas;
}
void SocketTCPCServer::Accept(void ){
data_sfd = accept(server_sfd, client_addr.RawObj(), client_addr.SizeP());
}
void SocketTCPClient::Reconnect(void){
client_sfd = socket(ipptl,SOCK_STREAM,0);
if(!~client_sfd) throw "fail to get client sfd";
if(!~connect(client_sfd,send_addr.RawObj(),send_addr.Size())) throw "fail to connect";
}
void SocketTCPCServer::CloseConnection(void){
close(data_sfd);
}
void SocketTCPClient::GetRespond(string &str){
ssize_t size = recv(client_sfd, buff, BUFSIZ, 0);
if(size > 0){
str = string(buff,size);
}
else str = "";
}
void SocketTCPCServer::SendRespond(string &str){
send(data_sfd, str.data(), str.size(), 0);
}
ssize_t SocketTCPClient::RecvRAW(char **p_rdt, Addr &taddr){
ssize_t bdtas = 0 ,tmp_bdtas;
*p_rdt = nullptr;
while ((tmp_bdtas = recv(client_sfd, buff, BUFSIZ, 0)) > 0) {
if(*p_rdt == nullptr){
*p_rdt = (char *)malloc(tmp_bdtas);
memcpy(*p_rdt, buff, tmp_bdtas);
}
else{
*p_rdt = (char *)realloc(*p_rdt, bdtas + tmp_bdtas);
memcpy(*p_rdt + bdtas, buff, tmp_bdtas);
}
bdtas += tmp_bdtas;
printf("Get Data Size %lu",tmp_bdtas);
}
return bdtas;
}
Addr &SocketTCPClient::GetAddr(void){
return send_addr;
}
void SocketTCPClient::SetAddr(Addr &taddr){
send_addr = taddr;
}
Addr &SocketTCPCServer::GetAddr(void){
return server_addr;
}
Addr &SocketTCPCServer::GetClientAddr(void){
return client_addr;
}
int SocketTCPCServer::GetDataSFD(void){
return data_sfd;
}
void SocketTCPCServer::SetDataSFD(int tdata_sfd){
data_sfd = tdata_sfd;
}
void SocketTCPCServer::SetClientAddr(Addr &caddr){
client_addr = caddr;
}