diff --git a/include/instruct.h b/include/instruct.h index 613559d..28a92b2 100644 --- a/include/instruct.h +++ b/include/instruct.h @@ -50,5 +50,6 @@ int set(string instruct, vector &configs, vector &lconfigs, vect bool config_search(vector &configs,string tfg); void getSQEPublicKey(respond *pres,void *args); void registerSQECallback(respond *pres,void *args); +void* connectionDeamon(void *args); #endif /* instruct_h */ diff --git a/include/net.h b/include/net.h index 7fb0bb3..ef1eace 100644 --- a/include/net.h +++ b/include/net.h @@ -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 */ diff --git a/include/server.h b/include/server.h index 8f94a46..92cf14a 100644 --- a/include/server.h +++ b/include/server.h @@ -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 packets_in; // 缓存带标签的二进制串管理结构 list rawdata_in; + map rids; // 输出的数据包列表 list packets_out; map 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 req_lst; + list rwd_lst; + // 回复处理列表 list res_lst; // 请求监听端口 uint32_t listen_port; SocketUDPServer socket; SocketUDPClient send_socket; +// 与服务器建立的稳定链接 + SocketTCPCServer *server_cnt; // 广场服务器通信公钥 public_key_class sqe_pbc; // 报文密钥 diff --git a/src/addr.cpp b/src/addr.cpp index 2fccc0e..c2d4d10 100644 --- a/src/addr.cpp +++ b/src/addr.cpp @@ -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); } diff --git a/src/client.cpp b/src/client.cpp index 02bc53a..94a3d6b 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -44,7 +44,6 @@ void *clientRespondDeamon(void *pvclt){ do{ tlen = pclient->socket.RecvRAW(&str,taddr); if(tlen > 0){ - // 记录有效数据包 if(Server::CheckRawMsg(str, tlen)){ diff --git a/src/clock.cpp b/src/clock.cpp index 38cb395..1bfe7c0 100644 --- a/src/clock.cpp +++ b/src/clock.cpp @@ -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; diff --git a/src/controller.cpp b/src/controller.cpp index 014812a..c7ba3e2 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -217,7 +217,7 @@ int server(string instruct, vector &configs, vector &lconfigs, v setServerClockForSquare(&nsvr, 3); } } - while(1) usleep(10000); + while(1) sleep(1); return 0; } @@ -319,7 +319,7 @@ int client(string instruct, vector &configs, vector &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 &configs, vector &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 &configs, vector &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 writer(strbuff); @@ -372,13 +376,34 @@ int client(string instruct, vector &configs, vector &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; } + + + + diff --git a/src/model.cpp b/src/model.cpp index 7b410f5..c9ad2fa 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -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); +} diff --git a/src/server.cpp b/src/server.cpp index 72016fd..eb26020 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -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 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(<, 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); +} diff --git a/src/socket.cpp b/src/socket.cpp index 4348ad9..1243805 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -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; +}