// // server.hpp // Net // // Created by 胡一兵 on 2019/1/16. // Copyright © 2019年 Bakantu. All rights reserved. // #ifndef server_h #define server_h #include "clock.h" #include "net.h" #include "cpart.h" #include "cthread.h" #include "sqlite3.h" #include "rsa.h" #include "rng.hpp" #include "aes.h" #include "sha1.h" class Server; //外来数据包解析结构 struct compute_result{ string name; vector *args_in; vector *args_out; vector *fargs_in; vector *fargs_out; }; //请求数据包 struct request { // 匹配id uint64_t r_id; // 类型 string type; // 数据 string data; // 接收端口 uint32_t recv_port; // json结构 Document req_doc; StringBuffer doc_str; // 标记是否为加密请求 bool if_encrypt; Addr t_addr; request(); void Json2Data(void); void JsonParse(string data_from); }; //加密端对端报文 struct encrypt_post{ // 注册客户端id uint64_t client_id; // 目标地址信息 Addr t_addr; // 匹配id uint64_t p_id; // 类型 uint32_t type; // 内容 Byte *buff = nullptr; // 内容长度 uint32_t buff_size = 0; Document edoc; StringBuffer sb; bool Parse(string json); void SelfParse(void); 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); }; //回复数据包 struct respond { uint64_t r_id; string type; Byte *buff = nullptr; uint32_t buff_size; Addr t_addr; void SetBuff(Byte *buff, uint32_t size); ~respond(); }; //通用数据包类 class packet{ public: // 数据包类型 unsigned int type; struct sockaddr_in address; // 记录块的大小及内容所在的内存地址 vector> buffs; void AddBuff(const void *pbuff, uint32_t size); bool if_encrypt = false; ~packet(); }; //带标签的二进制串管理结构 class raw_data{ public: // 二进制串 unsigned char *data = NULL; unsigned long size = 0; uint64_t r_id; // 标签 uint32_t head, tail; uint32_t info; // 信息串 char *msg = NULL; unsigned long msg_size = 0; // 来源ip地址 struct sockaddr_in address; // 用简单字符串直接出适合 void setData(string str){ data = (unsigned char *)malloc(str.size()); size = str.size(); memcpy(data, str.data(),str.size()); } raw_data(); }; //请求监听管理结构 struct request_listener{ void (*callback)(respond *,void *args); request *p_req; uint32_t timeout; uint32_t clicks; raw_data trwd; bool active; void *args; ~request_listener(); }; struct server_info{ string tag; string name; string msqes_ip; int msqes_prot; string key; }; 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); }; //UDP分包 struct net_box{ uint16_t idx; uint16_t cnt; uint32_t head; uint32_t tail; uint64_t b_id; void *data = nullptr; uint16_t data_size = 0; UByte *send_data = nullptr; uint16_t sdt_size = 0; void set(void *pbuff, uint16_t pbsize); void build(void); void FreeNetBox(void); net_box(); ~net_box(); }; //UDP分包监听结构 struct box_listener{ uint64_t b_id; // 生命 int32_t clicks; // 应该接收的分包数量 uint16_t cnt; // 接收到的分包数量 uint16_t nbn; //分包来源地址 sockaddr_in address; // 储存接收到的分包的动态数组 net_box **boxs; // 合并分包成RawData void TogtRawData(raw_data &trdt); // 释放动态数组所关联的所有内存 void free_boxs(void); }; //注册客户端管理 struct client_register{ // 客户端id uint64_t client_id; // 通信密钥 aes_key256 key; string name; string tag; // 服务器资源租用时间 uint32_t click; // 认证口令 uint64_t passwd; // 目标地址信息 Addr t_addr; // 守护线程ID pthread_t tid; sqlite3 *psql; }; struct client_listen{ bool if_get; bool if_connected = true; pthread_t pid; SocketTCPClient *ptcps; encrypt_post *pcryp; client_register *pcltr; }; struct connection_info { bool if_listen = false; bool if_beat = false; bool if_send = false; }; struct connection_listener{ int data_sfd; Addr client_addr; aes_key256 key; pthread_t pid = 0; void *father_buff = nullptr; SocketTCPCServer *server_cnt = nullptr; bool if_active = true; bool *pif_atv = nullptr; void *write_buff = nullptr; struct connection_info *p_ci = nullptr; pthread_t *beat_pid = nullptr, *listen_pid = nullptr, *send_pid = nullptr; sqlite3 *psql; }; //通用服务器类 class Server{ protected: // 缓存通用数据包 list packets_in; // 缓存带标签的二进制串管理结构 list rawdata_in; map rids; // 输出的数据包列表 list packets_out; map boxls; struct server_info tsi; sqlite3 *psql; // 服务器公私钥 public_key_class pkc; private_key_class prc; public: // 服务器类的接收套接字对象与发送套接字对象 SocketUDPServer socket; SocketUDPClient send_socket; int packet_max = 1024; Server(int port = 9048, string send_ip = "127.0.0.1",int send_port = 9049); // 重新设置服务器的发送端口 void SetSendPort(int port); // 重新设置服务器的发送IP地址 void SetSendIP(string ip_addr); // 将结构数据包转换成二进制串 static void Packet2Rawdata(packet &tpkt, raw_data &rdt); // 将通用二进制串转换为通用数据包 static void Rawdata2Packet(packet &tpkt, raw_data &trdt); // 释放二进制串占用的空间 static void freeRawdataServer(struct raw_data &trdt); // 释放通用数据包包占用 static void freePcaketServer(struct packet tpkt); // 释放计算结果包占用的空间 static void freeCPURServer(struct compute_result tcpur); // 给二进制串贴上识别标签 static void SignedRawdata(struct raw_data *trdt,string info); // 发送已经贴上标签的二进制串 int SentRawdata(struct raw_data *trdt); // 检查消息串是否为一个贴上标签的二进制串 static bool CheckRawMsg(char *p_rdt, ssize_t size); // 处理一个已贴上标签的原始二进制串,获得其包含的信息 static void ProcessSignedRawMsg(char *p_rdt, ssize_t size, raw_data &rdt); // 解码已加密的原始二进制串 static void DecryptRSARawMsg(raw_data &rdt, private_key_class &pkc); // 编码原始二进制串 static void EncryptRSARawMsg(raw_data &rdt, public_key_class &pkc); // 检查是否为UDP分包 static bool CheckNetBox(char *p_nb, ssize_t size); // 将二进制信息转换成UDP分包 static void ProcessNetBox(net_box &tnb, Byte *p_data); // 服务器守护线程 friend void *serverDeamon(void *psvr); // 分包处理守护线程 friend void *boxProcessorDeamon(void *pvcti); // 处理RawData void ProcessRawData(void); void ProcessSendPackets(void); void CleaningBoxs(void); }; //计算节点服务器类 class CNodeServer:public Server{ vector cpurs_in; public: // 将计算结果包转化为结构数据包 static packet CPURS2Packet(compute_result tcpur); // 将结构数据包转化为计算结果包 static compute_result Packet2CPUR(packet *tpkt); }; class SQEServer:public Server{ protected: // 请求数据包 list req_list; // 注册客户端管理 map client_lst; // 加密端对端报文 listpost_lst; //服务器名 string name; public: SQEServer(int port = 9048); void ProcessPacket(void); void ProcessRequset(void); static void Packet2Request(packet &pkt, request &req); 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 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, string type); }; //通用客户端类 class Client{ // 请求监听列表 list req_lst; list rwd_lst; list ecryp_lst; //TCP模式下有效二进制段列表 list rwd_tcp; // 回复处理列表 list res_lst; // 请求监听端口 uint16_t listen_port; SocketUDPServer socket; SocketUDPClient send_socket; // 与服务器建立的稳定链接 SocketTCPCServer *server_cnt; // 广场服务器通信公钥 public_key_class sqe_pbc; // 报文密钥 aes_key256 post_key; // 客户端名与标签 string name,tag; // 广场服务器服务密钥 string sqe_key; // 数据库 sqlite3 *psql; public: // 构造函数(send_port指的是发送的目标端口) Client(int port = 9050, string send_ip = "127.0.0.1",int send_port = 9049); // 处理请求监听 void ProcessRequestListener(void); // 新的请求 void NewRequest(request **ppreq,string send_ip,int send_port,string type, string data, bool if_encrypt = false); // 新的请求监听 void NewRequestListener(request *preq, int timeout, void *args, void (*callback)(respond *, void *)); // 设置公钥 void SetPublicKey(public_key_class &t_pbc); // 设置AES密钥 void SetAESKey(aes_key256 &key); // 发送RawData void SendRawData(raw_data *trdt); // 友元回复接受守护进程 friend void *clientRespondDeamon(void *); // 友元客户端控制器 friend int client(string instruct, vector &configs, vector &lconfigs, vector &targets); }; //设置服务器守护线程的时钟 void setServerClock(Server *psvr, int clicks); //设置广场服务器守护线程的时钟 void setServerClockForSquare(SQEServer *psvr, int clicks); //服务器接收数据包守护线程 void *serverDeamon(void *psvr); //服务器处理原始数据守护线程 void *dataProcessorDeamon(void *pvcti); //UDP分包监听守护进程 void *boxProcessorDeamon(void *pvcti); //UDP分包监听清理守护进程 void *boxsCleaningProcessorDeamon(void *pvcti); //广场服务器处理数据包守护线程 void *packetProcessorDeamonForSquare(void *pvcti); //广场服务器处理请求守护线程 void *requestProcessorDeamonForSquare(void *pvcti); //服务器发送数据包守护线程 void *sendPacketProcessorDeamonForSquare(void *pvcti); //设置客户端请求监听守护时钟 void setClientClock(Client *pclient,int clicks); //客户端请求监听守护线程 void *clientRequestDeamon(void *pvclt); //客户端回复接收守护线程 void *clientRespondDeamon(void *pvclt); //客户端待机守护线程 void *clientWaitDeamon(void *pvclt); #endif /* server_h */