Heart 1.4.918.d927d9c
Heart is base back end library for your c++ Qt projects.
Loading...
Searching...
No Matches
abstractnode.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2018-2025 QuasarApp.
3 * Distributed under the lgplv3 software license, see the accompanying
4 * Everyone is permitted to copy and distribute verbatim copies
5 * of this license document, but changing it is not allowed.
6*/
7
8
9#ifndef ABSTRACTNODE_H
10#define ABSTRACTNODE_H
11
12#include "abstractnodeinfo.h"
13#include "ping.h"
14
15#ifdef USE_HEART_SSL
16#include <QSslConfiguration>
17#include <easyssl/icertificate.h>
18#endif
19
20#include <QAbstractSocket>
21#include <QFutureWatcher>
22#include <QMutex>
23#include <QSharedPointer>
24#include <QTcpServer>
25#include <QThreadPool>
26#include <QTimer>
27#include <softdelete.h>
28#include "abstractdata.h"
29#include "workstate.h"
30#include "package.h"
31#include "heart_global.h"
32#include <iparser.h>
33
34namespace QH {
35
36class DataSender;
37class ReceiveData;
38class SocketFactory;
39class AsyncLauncher;
40class TaskScheduler;
41class AbstractTask;
42class SslSocket;
44
45namespace PKG {
46class ErrorData;
47}
48
53enum class SslMode {
56#ifdef USE_HEART_SSL
57
59 InitFromSystem,
61 InitSelfSigned
62#endif
63};
64
79
80#define CRITICAL_ERROOR -50
81#define LOGICK_ERROOR -20
82#define REQUEST_ERROR -5
83#define NOTSUPPORT_ERROR -1
84
85#define BIG_DATA_HASH_ID 0xFFFF
86
87class Abstract;
88
100class HEARTSHARED_EXPORT AbstractNode : public QTcpServer, public SoftDelete
101{
102 Q_OBJECT
103
104public:
105
109 enum NodeType: int {
112
114 Node = 1,
115
118 };
119
125 AbstractNode(QObject * ptr = nullptr);
126 ~AbstractNode() override;
127
132 virtual NodeType nodeType() const = 0;
133
141 virtual bool run(const QString& addres, unsigned short port);
142
149 QSharedPointer<QH::iParser> selectParser(unsigned short cmd,
150 AbstractNodeInfo *sender) const;
151
158 QSharedPointer<QH::iParser> selectParser(const QString& type,
159 int version) const;
160
167 QSharedPointer<QH::iParser> selectParser(const QString& type,
168 AbstractNodeInfo *sender) const;
169
173 virtual void stop();
174
181 virtual AbstractNodeInfo* getInfoPtr(const HostAddress &id);
182
188 virtual const AbstractNodeInfo* getInfoPtr(const HostAddress &id) const;
189
194 virtual void ban(const HostAddress& target);
195
200 virtual void unBan(const HostAddress& target);
201
209 virtual unsigned int sendData(const PKG::AbstractData *resp, const HostAddress& address,
210 const Header *req = nullptr);
211
219 virtual unsigned int sendData(const PKG::AbstractData *resp, const AbstractNodeInfo *node,
220 const Header *req = nullptr);
221
229 bool addNode(const HostAddress &address);
230
244 bool addNode(const HostAddress &address,
245 const std::function<void(QH::AbstractNodeInfo *)>& action,
247
270 bool addNode(const QString &domain, unsigned short port,
271 const std::function<void(QH::AbstractNodeInfo *)>& action = nullptr,
273
279 bool removeNode(const HostAddress& nodeAdderess);
280
286 bool removeNode(AbstractNodeInfo* node);
287
292 HostAddress address() const;
293
294#ifdef USE_HEART_SSL
295
300 QSslConfiguration getSslConfig() const;
301#endif
306 SslMode getMode() const;
307
313 virtual WorkState getWorkState() const;
314
319 int connectionsCount() const;
320
325 int confirmendCount() const;
326
332 bool ping( const HostAddress& address);
333
338 static QThread *mainThreadID();
339
348 bool sheduleTask(const QSharedPointer<AbstractTask>& task);
349
356 void removeTask(int taskId);
357
364 int sheduledTaskCount() const;
365
374 virtual void badRequest(const HostAddress &address, const Header &req,
375 const PKG::ErrorData& err, qint8 diff = REQUEST_ERROR);
376
377#ifdef USE_HEART_SSL
378
384 const QList<QSslError> &ignoreSslErrors() const;
385#endif
386
392 bool addApiParser(const QSharedPointer<iParser>& parser);
393
398 bool fSendBadRequestErrors() const;
399
404 void setSendBadRequestErrors(bool value);
405
411
416 void setCloseConnectionAfterBadRequest(bool value);
417
418signals:
424 void requestError(unsigned char code, QString msg);
425
432 void sigNoLongerSupport(const QString& ApiKey, unsigned short version);
433
434
435protected:
436
437#ifdef USE_HEART_SSL
438
444 void setIgnoreSslErrors(const QList<QSslError> &newIgnoreSslErrors);
445
451 virtual QSslConfiguration selfSignedSslConfiguration( const EasySSL::SslSrtData& data = {});
452#endif
453
461 virtual AbstractNodeInfo* createNodeInfo(QAbstractSocket *socket,
462 const HostAddress *clientAddress = nullptr) const;
463
471 virtual bool registerSocket(QAbstractSocket *socket, const HostAddress* address = nullptr);
472
482 virtual bool sendPackage(const Package &pkg, QAbstractSocket *target) const;
483
488 virtual QString getWorkStateString() const;
489
494 virtual QString connectionState() const;
495
500 QList<HostAddress> banedList() const;
501
502 // TO-DO Need to add new method fo collect banned addresses for exmaple use the mask.
503 // See Task https://github.com/QuasarApp/Heart/issues/13
509 virtual bool isBanned(const AbstractNodeInfo *socket) const;
510
515 void incomingConnection(qintptr handle) override final;
516
523 virtual bool changeTrust(const HostAddress& id, int diff);
524
525
526#ifdef USE_HEART_SSL
527
536 bool useSelfSignedSslConfiguration(const EasySSL::SslSrtData& crtData);
537
545 bool useSystemSslConfiguration(QSslConfiguration config = QSslConfiguration::defaultConfiguration());
546
553 bool disableSSL();
554#endif
555
560 QHash<HostAddress, AbstractNodeInfo *> connections() const;
561
567 virtual void nodeConfirmend(AbstractNodeInfo *node);
568
574 virtual void nodeConnected(AbstractNodeInfo *node);
575
581 virtual void nodeDisconnected(AbstractNodeInfo *node);
582
583 void prepareForDelete() override;
584
592 QSharedPointer<PKG::AbstractData> prepareData(const Package& pkg, AbstractNodeInfo *sender) const;
593
599 QList<HostAddress> connectionsList() const;
600
606 QList<HostAddress> activeConnectionsList() const;
607
615 virtual void addNodeFailed(AddNodeError error);
616
624 virtual void nodeAddedSucessful(AbstractNodeInfo* node);
625
632 template<class ApiType, class ... Args >
633 QSharedPointer<ApiType> addApiParserNative(Args&&... arg) {
634 return addApiParserImpl(QSharedPointer<ApiType>::create(this, std::forward<Args>(arg)...)).template staticCast<ApiType>();
635 }
636
643 template<class ApiType, class ... Args >
644 const QSharedPointer<iParser> & addApiParser(Args&&... arg) {
645 return addApiParserImpl(QSharedPointer<ApiType>::create(this, std::forward<Args>(arg)...));
646 }
647
648protected slots:
653 virtual void receivePing(const QSharedPointer<QH::PKG::Ping>& ping);;
654
662 virtual void nodeErrorOccured(QH::AbstractNodeInfo *nodeInfo,
663 QAbstractSocket::SocketError errorCode,
664 QString errorString);
665
666#ifdef USE_HEART_SSL
667
674 virtual void handleSslErrorOcurred(QH::SslSocket *scket, const QSslError& error);
675#endif
676
677private slots:
678
679 void avelableBytes(QH::AbstractNodeInfo* sender);
680
687 void handleNodeStatusChanged(QH::AbstractNodeInfo* node, QH::NodeCoonectionStatus status);
688
692 void handleWorkerStoped();
693
698 void handleForceRemoveNode(QH::HostAddress node);
699
704 void handleBeginWork(QSharedPointer<QH::AbstractTask> work);
705
706#ifdef USE_HEART_SSL
707
713 void handleSslErrorOcurredPrivate(QH::SslSocket *sender, const QList<QSslError> & errors);
714
718 void handleEncrypted(QH::AbstractNodeInfo *node);
719
720#endif
721
722private:
723
729 const QSharedPointer<iParser> & addApiParserImpl(const QSharedPointer<QH::iParser>& parserObject);
730
731 // iParser interface
732 ParserResult parsePackage(const QSharedPointer<PKG::AbstractData> &pkg,
733 const Header &pkgHeader,
734 AbstractNodeInfo *sender);
735
742 QSharedPointer<PKG::AbstractData>
743 genPackage(unsigned short cmd,
744 AbstractNodeInfo *sender) const;
745
749 bool listen(const HostAddress& address = HostAddress::Any);
750
757 void newWork(const Package &pkg, AbstractNodeInfo *sender, const HostAddress &id);
758
763 void checkConfirmendOfNode(AbstractNodeInfo *node);
764
768 void initThreadId() const;
769
773 void initThreadPool();
774
778 void deinitThreadPool();
779
780
781 SslMode _mode = SslMode::NoSSL;
782#ifdef USE_HEART_SSL
783 bool configureSslSocket(AbstractNodeInfo *node, bool fServer);
784 QSslConfiguration _ssl;
785 QList<QSslError> _ignoreSslErrors;
786#endif
787 QHash<HostAddress, AbstractNodeInfo*> _connections;
788 QHash<HostAddress, ReceiveData*> _receiveData;
789
790 DataSender * _dataSender = nullptr;
791 AsyncLauncher * _socketWorker = nullptr;
792 TaskScheduler *_tasksheduller = nullptr;
793 APIVersionParser *_apiVersionParser = nullptr;
794
796 QHash<HostAddress,
797 std::function<void (QH::AbstractNodeInfo *)>>> _connectActions;
798
799 QSet<QFutureWatcher <bool>*> _workers;
800 bool _sendBadRequestErrors = true;
801 bool _closeConnectionAfterBadRequest = false;
802
803 mutable QMutex _connectionsMutex;
804 mutable QMutex _confirmNodeMutex;
805 mutable QMutex _threadPoolMutex;
806 mutable QMutex _workersMutex;
807
808 QThreadPool *_threadPool = nullptr;
809
811 friend class SocketFactory;
812 friend class BigDataParser;
813 friend class BigDataParserOld;
814 friend class AbstractNodeParser;
816
817
818};
819
820}
821#endif // ABSTRACTNODE_H
#define REQUEST_ERROR
The APIVersionParser class This is main parser forthe main command. This parsers work only with the A...
The AbstractNodeInfo class contains information about client or server connection and tcp socket of n...
The AbstractNode class - Abstract implementation of node. this implementation have a methods for send...
friend class AbstractNodeParser
int sheduledTaskCount() const
sheduledTaskCount This method return count of sheduled tasks.
QSharedPointer< ApiType > addApiParserNative(Args &&... arg)
addApiParserNative This is template metod that add sipport of new apiparser ApiType
friend class BigDataParserOld
bool fSendBadRequestErrors() const
fSendBadRequestErrors This property enable or disable sending feedback to connected node when them se...
QSharedPointer< QH::iParser > selectParser(unsigned short cmd, AbstractNodeInfo *sender) const
selectParser This method select parser by command and sender.
bool removeNode(const HostAddress &nodeAdderess)
removeNode - Remove node and disconnected forom node (server).
virtual void stop()
stop - Stopped this node and close all network connections.
friend class AbstractNodeParserOld
bool sheduleTask(const QSharedPointer< AbstractTask > &task)
sheduleTask This method shedule execute task on this node.
static QThread * mainThreadID()
mainThreadID This method return the pointer to main thread
bool addApiParser(const QSharedPointer< iParser > &parser)
addApiParser This method add new Api parser for this node.
bool addNode(const HostAddress &address)
addNode - Connect to node (server) with address.
void removeTask(int taskId)
removeTask This method remove task from sheduler.
virtual void ban(const HostAddress &target)
ban - This method set for target connection a trust property to 0 and target connection will been abo...
HostAddress address() const
address - Thim method return own network address of current node (server).
friend class BigDataParser
NodeType
The NodeType enum contains types of the node. By default node contains only 3 types.
@ Client
Node with this type is general clints nodes.
@ Node
Node with this ytpe is midle nodes that can works as a client and as servers.
@ Server
This is node can works only as a public server.
const QSharedPointer< iParser > & addApiParser(Args &&... arg)
addApiParser This is template metod that add sipport of new apiparser ApiType
virtual void badRequest(const HostAddress &address, const Header &req, const PKG::ErrorData &err, qint8 diff=REQUEST_ERROR)
badRequest This method is send data about error of request.
SslMode getMode() const
getMode - This method return SSL mode of corrent node (server).
AbstractNode(QObject *ptr=nullptr)
AbstractNode - Base constructor of node.
virtual WorkState getWorkState() const
getWorkState - This method collect general information about this server. For more information about ...
virtual AbstractNodeInfo * getInfoPtr(const HostAddress &id)
getInfoPtr - This method return information class pointer about netwok connection....
void sigNoLongerSupport(const QString &ApiKey, unsigned short version)
sigNoLongerSupport is some as a APIVersionParser::sigNoLongerSupport. This signal just retronslate th...
friend class WebSocketController
void setSendBadRequestErrors(bool value)
setSendBadRequestErrors This method enable or disable the fSendBadRequestErrors property.
virtual bool run(const QString &addres, unsigned short port)
run This method implement deployment a network node (server) on selected address.
virtual void unBan(const HostAddress &target)
unBan - This method set for target connection a trust property to 100.
bool ping(const HostAddress &address)
ping This method send ping package to address for testing connection.
void setCloseConnectionAfterBadRequest(bool value)
setSendBadRequestErrors This method enable or disable the fcloseConnectionAfterBadRequest property.
int confirmendCount() const
connectionsCount - Return count of nodes with status confirmend.
bool fCloseConnectionAfterBadRequest() const
fCloseConnectionAfterBadRequest This propery enable or disable droping connection after badRequests....
int connectionsCount() const
connectionsCount - Return count fo connections (connections with status connected)
friend class SocketFactory
virtual unsigned int sendData(const PKG::AbstractData *resp, const HostAddress &address, const Header *req=nullptr)
sendData This method send data object another to node
void requestError(unsigned char code, QString msg)
requestError This signal emited when client or node received from remoute server or node the BadReque...
virtual NodeType nodeType() const =0
nodeType This method should be return type of the serve.
The AbstractTask class. All tasks executed on separate thread.
The AsyncLauncher class is wraper of the Async class for support moving invokes to thread of the curr...
The DataSender class this class create a queue for sendet data to network.
Definition datasender.h:23
The Host Address class this is wrapper of QHostAddress. Contains the NetworkAddress and network port.
Definition hostaddress.h:22
The AbstractData class is provide base functions for transport data by network For create you own pac...
The Package struct. This is base structure for transporting data by network between QH nodes....
Definition package.h:23
The TaskScheduler class This class contains queue of all shedule tasks.
The WorkState class is simple class with data of work state of node.
Definition workstate.h:20
The PKG namesapce - this namespace contains all default packages of the Heart library....
Definition heart.h:211
The QH namespace - QuasarApp Heart namespace. This namespace contains all classes of the Heart librar...
Definition heart.cpp:13
ParserResult
The ParserResult enum. Error - parser detect a errorob package. NotProcessed - the parser does not kn...
Definition iparser.h:35
NodeCoonectionStatus
The AbstractNodeState enum - This is status of the known nodes or clients.
@ Connected
The node with this status has socket status is connected.
AddNodeError
The AddNodeError enum contains error code that can be occured after invoke the AbstractNode::addNode ...
@ RegisterSocketFailed
This error ocurred when you try add baned node or server is overrload.
@ HostNotFound
This error ocurred when DNS server not responce to node or node can't find the server ip address by h...
SslMode
The SslMode enum This enum contatins options for set ssl mode of node (server). For more information ...
@ NoSSL
This is not secure connection without ssl encription. It is default value of new any node see Abstrac...
The Header struct 32 bytes.
Definition header.h:19
The ErrorData struct is simple structure for contains data of the error.
Definition badrequest.h:20
The ReceiveData struct This is private structure for contains informaton for parse packages.
Definition receivedata.h:20