From 3a8df3e069149159a9ec41da2979c02dc9f8d18b Mon Sep 17 00:00:00 2001 From: Saturneric Date: Tue, 26 Feb 2019 13:43:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=8E=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/server.h | 10 +++++ src/client.cpp | 9 ++-- src/controller.cpp | 4 +- src/model.cpp | 18 ++++++-- src/server.cpp | 103 +++++++++++++++++++++++++++++++-------------- src/socket.cpp | 27 ++++-------- 6 files changed, 114 insertions(+), 57 deletions(-) diff --git a/include/server.h b/include/server.h index 7b1e1ba..bde8796 100644 --- a/include/server.h +++ b/include/server.h @@ -67,9 +67,15 @@ struct encrypt_post{ Byte *buff = nullptr; // 内容长度 uint32_t buff_size = 0; + Document edoc; + + bool Parse(string json); + void GetJSON(string &json); + void SetBuff(Byte *buff, uint32_t size); void FreeBuff(void); ~encrypt_post(void); + void InitNew(uint64_t client_id, Addr t_addr, const char *type); }; //回复数据包 @@ -323,10 +329,12 @@ public: 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 Post2SignedRawData(encrypt_post &ecyp, 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); + static void SendConnectionInfo(SocketTCPClient *pcnt_sock, bool ifshort); }; //通用客户端类 @@ -335,6 +343,8 @@ class Client{ list req_lst; list rwd_lst; list ecryp_lst; +//TCP模式下有效二进制段列表 + list rwd_tcp; // 回复处理列表 list res_lst; // 请求监听端口 diff --git a/src/client.cpp b/src/client.cpp index 8346dcb..f95e68b 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -34,6 +34,7 @@ void *clientRequestDeamon(void *pvclt){ pthread_exit(NULL); } +//客户端回复处理守护线程 void *clientRespondDeamon(void *pvclt){ clock_thread_info *pclt = (clock_thread_info *) pvclt; Client *pclient = (Client *) pclt->args; @@ -78,6 +79,7 @@ void *clientRespondDeamon(void *pvclt){ pthread_exit(NULL); } +//客户端请求监听管理线程 void Client::ProcessRequestListener(void){ // 加锁 if (pthread_mutex_lock(&mutex_clt) != 0) throw "lock error"; @@ -119,6 +121,7 @@ void Client::ProcessRequestListener(void){ req_lst.remove_if([](auto &preq){return preq->active == false;}); } +//设置客户端守护时钟 void setClientClock(Client *pclient,int clicks){ pthread_mutex_init(&mutex_clt, nullptr); // 注册回复数据接收时钟 @@ -143,6 +146,7 @@ void setClientClock(Client *pclient,int clicks){ } +//创建监听结构 void Client::NewRequest(request **ppreq,string send_ip,int send_port,string type, string data, bool if_encrypt){ request *pnreq = new request(); pnreq->type = type; @@ -154,7 +158,7 @@ void Client::NewRequest(request **ppreq,string send_ip,int send_port,string type *ppreq = pnreq; } -//创建新的对服务器的请求 +//创建新的对服务器的请求的监听 void Client::NewRequestListener(request *preq, int timeout, void *args, void (*callback)(respond *,void *)){ request_listener *pnrl = new request_listener(); packet npkt; @@ -167,9 +171,8 @@ void Client::NewRequestListener(request *preq, int timeout, void *args, void (*c SQEServer::Request2Packet(npkt, *preq); Server::Packet2Rawdata(npkt, pnrl->trwd); -// 检查请求是否要求加密 + //检查请求是否要求加密 if(preq->if_encrypt == true){ - Server::EncryptRSARawMsg(pnrl->trwd, sqe_pbc); Server::SignedRawdata(&pnrl->trwd,"RPKT"); } diff --git a/src/controller.cpp b/src/controller.cpp index 45b5801..e9aa145 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -529,11 +529,11 @@ int client(string instruct, vector &configs, vector &lconfigs, v pid_t fpid = fork(); if(fpid == 0){ //守护进程 - printf("Client Register Deamon Has Been Created."); + printf("Client Register Deamon Has Been Created.\n"); nclt.server_cnt = new SocketTCPCServer(9052); nclt.server_cnt->Listen(); -// 获得共享内存地址 + //获得共享内存地址 Byte *buff = (Byte *)shmat(shmid, NULL, 0); if(shmid == -1){ printf("SHMAT Failed.\n"); diff --git a/src/model.cpp b/src/model.cpp index c765220..2eefc84 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -82,11 +82,14 @@ void *connectionDeamon(void *args){ 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; + string dget = "DGET"; if(Server::CheckRawMsg(buff, size)){ Server::ProcessSignedRawMsg(buff, size, *pnrwd); if(!memcmp(&pnrwd->info, "LCNT", sizeof(uint32_t))){ @@ -96,6 +99,7 @@ void *connectionDeamon(void *args){ else if(!memcmp(&pnrwd->info, "SCNT", sizeof(uint32_t))){ if_sm = true; printf("Short Connection From Server.\n"); + ntcps.SendRespond(dget); } else if(!memcmp(&pnrwd->info, "CNTL", sizeof(uint32_t))){ if_sm = true; @@ -105,31 +109,37 @@ void *connectionDeamon(void *args){ pthread_exit(NULL); } else{ - printf("Connection illegal.\n"); + //断开无效连接 + printf("Connection Illegal.\n"); delete pnrwd; pthread_exit(NULL); } } else{ - printf("Connection illegal.\n"); + 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){ + printf("MSG: %s\n", buff); if(Server::CheckRawMsg(buff, size)){ Server::ProcessSignedRawMsg(buff, size, *pnrwd); + //获得端对端加密报文 if(!memcmp(&pnrwd->info, "ECYP", sizeof(uint32_t))){ + printf("Get Encrypt Post.\n"); 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; @@ -140,9 +150,11 @@ void *connectionDeamon(void *args){ } } } + //心跳连接 else if(!memcmp(&pnrwd->info, "BEAT", sizeof(uint32_t))){ //printf("Connection Beated.\n"); } + //管理指令连接 else if(!memcmp(&pnrwd->info, "SCMD", sizeof(uint32_t))){ // 来自管理员的命令 diff --git a/src/server.cpp b/src/server.cpp index d2fa265..4a47491 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1068,11 +1068,11 @@ void *clientChecker(void *args){ pthread_exit(NULL); } +//注册客户端通信维持线程 void *clientListener(void *args){ client_listen *pcltl = (client_listen *)args; char *buff; Addr taddr; - printf("Start listening to client.\n"); while(1){ // 如果连接断开 if(pcltl->if_connected == false) break; @@ -1115,6 +1115,44 @@ void *clientListener(void *args){ } pthread_exit(NULL); } +bool resFromClient(SocketTCPClient *pcnt_sock){ + char *buff; + Addr taddr; + pcnt_sock->RecvRAW(&buff, taddr); + if (!memcmp(buff, "DGET", sizeof(uint32_t))) { + free(buff); + return true; + } + else { + free(buff); + return false; + } +} + +void encrypt_post::InitNew(uint64_t client_id, Addr t_addr, const char * type){ + this->client_id = client_id; + this->t_addr = t_addr; + memcpy(&this->type, type, sizeof(uint32_t)); + this->p_id = rand64(); +} + +void SQEServer::Post2SignedRawData(encrypt_post &ecyp, aes_key256 &key, raw_data &rw) { + packet *pnpkt = new packet(); + Post2Packet(*pnpkt, ecyp, key); + Packet2Rawdata(*pnpkt, rw); + Server::freePcaketServer(*pnpkt); + delete pnpkt; + Server::SignedRawdata(&rw,"ECYP"); +} + +void SQEServer::SendConnectionInfo(SocketTCPClient *pcnt_sock, bool ifshort) { + raw_data nsrwd; + //说明连接类型 + if(ifshort) SQEServer::BuildSmallRawData(nsrwd, "SCNT"); + else SQEServer::BuildSmallRawData(nsrwd, "LCNT"); + pcnt_sock->SendRAW(nsrwd.msg, nsrwd.msg_size); + Server::freeRawdataServer(nsrwd); +} void *clientWaitDeamon(void *pvclt){ clock_thread_info *pcti = (clock_thread_info *) pvclt; @@ -1140,39 +1178,43 @@ void *clientWaitDeamon(void *pvclt){ 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()); + encrypt_post *ncryp = new encrypt_post(); + + ncryp->Parse(res_type); + uint8_t *ppidx = (uint8_t *)&pclr->passwd; - ndoc["passwd"].SetArray(); - Document::AllocatorType &allocator = ndoc.GetAllocator(); + ncryp->edoc["passwd"].SetArray(); + Document::AllocatorType &allocator = ncryp->edoc.GetAllocator(); for(int i = 0; i < 8; i++){ - ndoc["passwd"].PushBack(ppidx[i], allocator); + ncryp->edoc["passwd"].PushBack(ppidx[i], allocator); } - StringBuffer sb; - Writer writer(sb); - ndoc.Accept(writer); - encrypt_post *ncryp = new encrypt_post(); - string send_data = sb.GetString(); -// 初始化端对端加密报文 + //初始化端对端加密报文 + string send_data; + ncryp->GetJSON(send_data); + + + ncryp->InitNew(pclr->client_id, pclr->t_addr, "JRES"); 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(); + raw_data *pnrwd = new raw_data(); + SQEServer::Post2SignedRawData(*ncryp, pclr->key, *pnrwd); + + //发送连接属性信息 + SQEServer::SendConnectionInfo(pcnt_sock); + + if (resFromClient(pcnt_sock)) { + pcnt_sock->SendRAW(pnrwd->msg, pnrwd->msg_size); + pcnt_sock->Close(); + } + else { + //注册连接未被识别 + error::printError("Client connection error."); + delete pclr; + delete pnrwd; + delete ncryp; + clockThreadFinish(pcti->tid); + pthread_exit(NULL); + } + client_listen *pcltl = new client_listen(); pcltl->pcltr = pclr; @@ -1203,7 +1245,6 @@ void *clientWaitDeamon(void *pvclt){ } delete pclr; - delete nppkt; delete pnrwd; delete ncryp; // 等待接收线程返回 diff --git a/src/socket.cpp b/src/socket.cpp index 1243805..9648348 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -71,19 +71,19 @@ ssize_t SocketUDPServer::RecvRAW(char **p_rdt, Addr &taddr){ if(set_fcntl){ tlen = recvfrom(server_sfd, buff, BUFSIZ, 0, (struct sockaddr *)(&tsai), &tsai_size); - // 读取错误 + //读取错误 if(tlen == -1 && errno != EAGAIN){ *p_rdt = nullptr; printf("%d",errno); perror("recv"); return -1; } -// 缓冲区没有信息 + //缓冲区没有信息 else if(tlen == 0 || (tlen == -1 && errno == EAGAIN)){ *p_rdt = nullptr; return 0; } -// 成功读取信息 + //成功读取信息 else{ *p_rdt = (char *)malloc(tlen); taddr.SetSockAddr(tsai); @@ -191,21 +191,12 @@ void SocketTCPCServer::SendRespond(string &str){ } 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; + ssize_t tmp_bdtas = recv(client_sfd, buff, BUFSIZ, 0); + if (tmp_bdtas > 0) { + *p_rdt = (char *)malloc(tmp_bdtas); + memcpy(*p_rdt, buff, tmp_bdtas); + } + return tmp_bdtas; }