/* * msg_client.h — C++ транспортный клиент для chat GUI * * Подключается к utun msg_transport по localhost TCP. * Протокол: [size:2][type:1][id:8][options:1][data...] (msg_transport.h). */ #ifndef MSG_CLIENT_H #define MSG_CLIENT_H #include #include #include #include class MsgClient : public QObject { Q_OBJECT public: explicit MsgClient(QObject* parent = nullptr); ~MsgClient() override; void connectToHost(const QString& host, quint16 port); void disconnectFromHost(); bool isConnected() const; void bind(quint64 peerId); void unbind(); bool isBound() const { return m_boundPeerId != 0; } quint64 boundPeerId() const { return m_boundPeerId; } void send(const QByteArray& data); void send(const uint8_t* data, size_t len); void sendSigned(const QByteArray& data); void sendTo(quint64 dstPeerId, const QByteArray& data); void requestPublicKey(); void requestPrivateKey(); void requestPeerInfo(quint64 peerId); signals: void connected(); void disconnected(); void bound(quint64 peerId); void unbound(); void received(quint64 peerId, const QByteArray& data); void errorOccurred(uint8_t code, const QString& message); void publicKeyReceived(const QByteArray& key); // 32 байта X25519 void privateKeyReceived(const QByteArray& key); // 32 байта X25519 void peerInfoReceived(quint64 peerId, const QByteArray& x25519Pubkey, const QByteArray& ed25519Pubkey); private: static constexpr size_t kMaxMsgSize = 8192; static constexpr uint8_t kCtlBind = 0x01; static constexpr uint8_t kCtlUnbind = 0x02; static constexpr uint8_t kCtlGetPubkey = 0x03; static constexpr uint8_t kCtlGetPrivkey = 0x04; static constexpr uint8_t kCtlGetPeerInfo = 0x05; static constexpr uint8_t kDataSend = 0x10; static constexpr uint8_t kDataRecv = 0x11; static constexpr uint8_t kRspBindOk = 0xE1; static constexpr uint8_t kRspPubkey = 0xE2; static constexpr uint8_t kRspPrivkey = 0xE3; static constexpr uint8_t kRspPeerInfo = 0xE4; static constexpr uint8_t kRspError = 0xFF; static constexpr uint8_t kOptSigned = 0x01; static constexpr size_t kHdrSize = 12; QTcpSocket* m_socket; QByteArray m_recvBuffer; quint64 m_boundPeerId = 0; void onReadyRead(); void onSocketError(QAbstractSocket::SocketError); void processMessages(); void dispatch(uint8_t type, quint64 id, const QByteArray& payload); QByteArray buildMessage(uint8_t type, quint64 id, uint8_t options, const QByteArray& data); }; #endif // MSG_CLIENT_H