2020-09-15 21:16:35 +03:00
/*
2021-01-31 19:51:00 +03:00
* Copyright ( C ) 2018 - 2021 QuasarApp .
2020-09-15 21:16:35 +03:00
* Distributed under the lgplv3 software license , see the accompanying
* Everyone is permitted to copy and distribute verbatim copies
* of this license document , but changing it is not allowed .
*/
2021-09-02 18:40:14 +03:00
2020-09-15 21:16:35 +03:00
# ifndef ABSTRACTNODE_H
# define ABSTRACTNODE_H
# include "abstractnodeinfo.h"
2021-05-10 18:13:01 +03:00
2021-10-31 22:03:57 +03:00
# ifdef USE_HEART_SSL
2020-09-15 21:16:35 +03:00
# include <openssl/evp.h>
2021-05-10 18:13:01 +03:00
# include <QSslConfiguration>
# endif
2020-09-15 21:16:35 +03:00
# include <QAbstractSocket>
# include <QFutureWatcher>
# include <QMutex>
2021-02-23 19:12:25 +03:00
# include <QSharedPointer>
2020-09-15 21:16:35 +03:00
# include <QTcpServer>
2021-01-15 19:08:30 +03:00
# include <QThreadPool>
2020-09-15 21:16:35 +03:00
# include <QTimer>
2021-01-15 19:08:30 +03:00
# include <softdelete.h>
2020-09-15 21:16:35 +03:00
# include "abstractdata.h"
# include "workstate.h"
2020-09-24 15:24:51 +03:00
# include "package.h"
2020-09-15 21:16:35 +03:00
# include "cryptopairkeys.h"
# include "icrypto.h"
# include "heart_global.h"
# include "packagemanager.h"
2020-10-29 20:23:50 +03:00
# include "abstracterrorcodes.h"
2020-09-15 21:16:35 +03:00
2020-09-15 22:07:49 +03:00
namespace QH {
2020-09-15 21:16:35 +03:00
class DataSender ;
2020-09-24 15:24:51 +03:00
class ReceiveData ;
2021-03-17 19:34:51 +03:00
class SocketFactory ;
2021-03-18 10:16:09 +03:00
class AsyncLauncher ;
2021-10-01 22:54:49 +03:00
class BigDataManager ;
2021-10-11 20:42:13 +03:00
class TaskScheduler ;
class AbstractTask ;
2021-10-31 22:03:57 +03:00
class SslSocket ;
2020-09-15 21:16:35 +03:00
2020-10-29 20:23:50 +03:00
namespace PKG {
class ErrorData ;
}
2020-09-15 21:16:35 +03:00
/**
2021-03-12 12:23:30 +03:00
* @ brief The ParserResult enum .
* Error - parser detect a errorob package .
2020-09-15 21:16:35 +03:00
* NotProcessed - the parser does not know what to do with the package or has not finished processing it .
2021-03-12 12:23:30 +03:00
* Processed - the parser finished processing correctly .
2020-09-15 21:16:35 +03:00
*/
enum class ParserResult {
2021-03-12 12:23:30 +03:00
/// parser detect a errorob package.
2020-09-15 21:16:35 +03:00
Error = 0 ,
/// the parser does not know what to do with the package or has not finished processing it.
NotProcessed = 1 ,
2021-03-12 12:23:30 +03:00
/// the parser finished processing correctly.
2020-09-15 21:16:35 +03:00
Processed = 2
} ;
2020-09-16 23:40:42 +03:00
/**
2021-03-12 12:23:30 +03:00
* @ brief The SslMode enum This enum contatins options for set ssl mode of node ( server ) .
2020-09-16 23:40:42 +03:00
* For more information see AbstractNode : : useSelfSignedSslConfiguration AbstractNode : : useSystemSslConfiguration and AbstractNode : : disableSSL methods .
*/
2020-09-15 21:16:35 +03:00
enum class SslMode {
2021-03-12 12:23:30 +03:00
/// This is not secure connection without ssl encription. It is default value of new any node see AbstractNode(SslMode mode = SslMode::NoSSL, QObject * ptr = nullptr).
2020-09-15 21:16:35 +03:00
NoSSL ,
2021-10-31 22:03:57 +03:00
# ifdef USE_HEART_SSL
2021-05-10 18:13:01 +03:00
2020-09-24 17:03:33 +03:00
/// This option try enable ssl connection from system configuration form fore information see Qt Documentation https://doc.qt.io/qt-5/qsslconfiguration.html
2020-09-15 21:16:35 +03:00
InitFromSystem ,
2021-03-12 12:23:30 +03:00
/// This option force a current node geneerate self signed sertificat and work with it. For more information see a SslSrtData struct.
2020-09-15 21:16:35 +03:00
InitSelfSigned
2021-05-10 18:13:01 +03:00
# endif
2020-09-15 21:16:35 +03:00
} ;
2021-10-31 22:03:57 +03:00
# ifdef USE_HEART_SSL
2020-09-15 21:16:35 +03:00
/**
2020-09-16 23:40:42 +03:00
* @ brief The SslSrtData struct This structure contains base information for generate self signed ssl certefication .
2021-03-12 12:23:30 +03:00
* If you want change selfSigned certificate then use method AbstractNode : : useSelfSignedSslConfiguration .
2020-09-15 21:16:35 +03:00
*/
struct SslSrtData {
QString country = " BY " ;
QString organization = " QuasarApp " ;
2021-11-01 18:35:42 +03:00
QString commonName = " " ;
2020-09-15 21:16:35 +03:00
long long endTime = 31536000L ; //1 year
} ;
2021-05-10 18:13:01 +03:00
# endif
2020-09-15 21:16:35 +03:00
2021-11-01 11:07:24 +03:00
# define CRITICAL_ERROOR -50
# define LOGICK_ERROOR -20
# define REQUEST_ERROR -5
# define NOTSUPPORT_ERROR -1
2020-09-15 21:16:35 +03:00
2021-10-02 22:12:39 +03:00
# define BIG_DATA_HASH_ID 0xFFFF
2020-09-15 21:16:35 +03:00
class Abstract ;
/**
* @ brief The AbstractNode class - Abstract implementation of node .
* this implementation have a methods for send and receive data messages ,
* and work with crypto method for crease a security connections betwin nodes .
2021-03-12 12:23:30 +03:00
* AbstractNode - is thread save class .
2021-09-25 14:26:47 +03:00
*
* @ note For correctly working this class you should be register all you data types using the AbstractNode : : registerPackageType method .
2021-09-03 10:15:56 +03:00
* @ see AbstractData
2021-09-25 14:26:47 +03:00
* @ see AbstractNode : : registerPackageType
* @ see AbstractNode : : parsePackage
2020-09-15 21:16:35 +03:00
*/
2021-01-15 19:08:30 +03:00
class HEARTSHARED_EXPORT AbstractNode : public QTcpServer , public SoftDelete
2020-09-15 21:16:35 +03:00
{
Q_OBJECT
public :
/**
2021-03-12 12:23:30 +03:00
* @ brief AbstractNode - Base constructor of node .
* @ param ptr - Pointrt to parent Qt object , the AbstractNode class is Q_OBJECT .
2021-09-25 14:26:47 +03:00
* @ note For correctly working this class you should be register all you data types using the AbstractNode : : registerPackageType method .
2020-09-15 21:16:35 +03:00
*/
2020-09-16 23:40:42 +03:00
AbstractNode ( QObject * ptr = nullptr ) ;
2020-09-15 21:16:35 +03:00
~ AbstractNode ( ) override ;
/**
2020-09-26 15:16:12 +03:00
* @ brief run This method implement deployment a network node ( server ) on selected address .
* @ param addres This is network address of work node or server .
* If address is empty then server weel be listen all addreses of all interfaces else listen only selected address .
* @ param port This is port of deployment node ( server )
2020-09-16 23:40:42 +03:00
* @ return Result of deployment node ( sever ) . ( True if deploy finished successful else false ) .
2020-09-15 21:16:35 +03:00
*/
virtual bool run ( const QString & addres , unsigned short port ) ;
/**
2021-03-12 12:23:30 +03:00
* @ brief stop - Stopped this node and close all network connections .
2020-09-15 21:16:35 +03:00
*/
virtual void stop ( ) ;
/**
2020-09-16 23:40:42 +03:00
* @ brief getInfoPtr - This method return information class pointer about netwok connection .
* If Connection with id not found then return nullptr .
2021-03-12 12:23:30 +03:00
* @ param id - It is network address of requested node .
* @ return The pointer of information about node . if address not found return nullptr .
2020-09-15 21:16:35 +03:00
*/
virtual AbstractNodeInfo * getInfoPtr ( const HostAddress & id ) ;
/**
2021-03-12 12:23:30 +03:00
* @ brief getInfoPtr - This is some that getInfoPtr ( const HostAddress & id ) bod it is constant implementation .
* @ param id - It is network address of requested node .
* @ return The pointer of information about node . if address not found return nullptr .
2020-09-15 21:16:35 +03:00
*/
virtual const AbstractNodeInfo * getInfoPtr ( const HostAddress & id ) const ;
/**
2021-03-12 12:23:30 +03:00
* @ brief ban - This method set for target connection a trust property to 0 and target connection will been aborted .
* @ param target - It is network address of target connection .
2020-09-15 21:16:35 +03:00
*/
virtual void ban ( const HostAddress & target ) ;
/**
2021-03-12 12:23:30 +03:00
* @ brief unBan - This method set for target connection a trust property to 100.
* @ param target - It is network address of target connection .
2020-09-15 21:16:35 +03:00
*/
virtual void unBan ( const HostAddress & target ) ;
/**
2021-03-22 19:56:33 +03:00
* @ brief addNode - Connect to node ( server ) with address .
2021-03-12 12:23:30 +03:00
* @ param address - This is Network address of node ( server ) .
2021-03-24 15:55:49 +03:00
* @ return true if the node aaded successful
2020-09-15 21:16:35 +03:00
*/
2021-03-22 19:56:33 +03:00
bool addNode ( const HostAddress & address ) ;
2020-09-15 21:16:35 +03:00
/**
2021-03-22 19:56:33 +03:00
* @ brief addNode - Connect to node ( server ) with domain , bud this method find ip address of domain befor connecting .
2021-03-12 12:23:30 +03:00
* @ param domain - This is domain address of node ( server ) .
* @ param port - This is target port of node ( server ) .
2021-03-24 15:55:49 +03:00
* @ return true if the node aaded successful
2020-09-15 21:16:35 +03:00
*/
2021-03-22 19:56:33 +03:00
bool addNode ( const QString & domain , unsigned short port ) ;
2020-09-15 21:16:35 +03:00
/**
2021-03-12 12:23:30 +03:00
* @ brief removeNode - Remove node and disconnected forom node ( server ) .
2020-09-16 23:40:42 +03:00
* @ param nodeAdderess - This is network adddress of removed node ( server ) .
2021-03-24 15:55:49 +03:00
* @ return true if the node removed successful . If the nde with @ a nodeAdderess is not exits return false .
2020-09-15 21:16:35 +03:00
*/
2021-03-24 15:55:49 +03:00
bool removeNode ( const HostAddress & nodeAdderess ) ;
2020-09-15 21:16:35 +03:00
2021-09-30 12:30:16 +03:00
/**
* @ brief removeNode - Remove node and disconnected forom node ( server ) .
* @ param node - This is removed node ( server ) .
* @ return true if the node removed successful . If the nde with @ a nodeAdderess is not exits return false .
*/
bool removeNode ( AbstractNodeInfo * node ) ;
2020-09-15 21:16:35 +03:00
/**
2021-03-12 12:23:30 +03:00
* @ brief address - Thim method return own network address of current node ( server ) .
* @ return The current network adderss .
2020-09-15 21:16:35 +03:00
*/
HostAddress address ( ) const ;
2021-10-31 22:03:57 +03:00
# ifdef USE_HEART_SSL
2021-05-10 18:13:01 +03:00
2020-09-15 21:16:35 +03:00
/**
2020-09-16 23:40:42 +03:00
* @ brief getSslConfig - This method return ssl configuration of current node ( server ) .
2021-03-12 12:23:30 +03:00
* @ return current ssl configuration on this node ( server ) .
2020-09-15 21:16:35 +03:00
*/
QSslConfiguration getSslConfig ( ) const ;
2021-05-10 18:13:01 +03:00
# endif
2020-09-15 21:16:35 +03:00
/**
2020-09-16 23:40:42 +03:00
* @ brief getMode - This method return SSL mode of corrent node ( server ) .
2021-03-12 12:23:30 +03:00
* @ return current mode for more information see SslMode .
2020-09-15 21:16:35 +03:00
*/
SslMode getMode ( ) const ;
/**
2020-09-16 23:40:42 +03:00
* @ brief getWorkState - This method collect general information about this server .
* For more information about returned data see getWorkState
2021-03-12 12:23:30 +03:00
* @ return state value for more information see WorkState class .
2020-09-15 21:16:35 +03:00
*/
virtual WorkState getWorkState ( ) const ;
/**
2020-09-16 23:40:42 +03:00
* @ brief pareseResultToString This method convert ParserResult value to string .
2021-03-12 12:23:30 +03:00
* @ return The String value of pareseresult .
2020-09-15 21:16:35 +03:00
*/
QString pareseResultToString ( const ParserResult & parseResult ) const ;
/**
2021-03-12 12:23:30 +03:00
* @ brief connectionsCount - Return count fo connections ( connections with status connected )
* @ return Count valid connections .
2020-09-15 21:16:35 +03:00
*/
int connectionsCount ( ) const ;
/**
2021-03-12 12:23:30 +03:00
* @ brief connectionsCount - Return count of nodes with status confirmend .
* @ return return confirmend connections of this node ( server ) .
2020-09-15 21:16:35 +03:00
*/
int confirmendCount ( ) const ;
/**
2021-03-12 12:23:30 +03:00
* @ brief ping This method send ping package to address for testing connection .
* @ param address This is address of target node ( server ) .
2020-09-16 23:40:42 +03:00
* @ return true if ping sendet successful .
2020-09-15 21:16:35 +03:00
*/
bool ping ( const HostAddress & address ) ;
2021-03-23 23:02:28 +03:00
/**
* @ brief mainThreadID This method return the pointer to main thread
* @ return pointer to main thread
*/
2021-04-30 22:41:34 +03:00
static QThread * mainThreadID ( ) ;
2021-03-23 23:02:28 +03:00
2021-10-12 00:47:39 +03:00
/**
* @ brief sheduleTask This method shedule execute task on this node .
* @ param task This is task that will be sheduled .
2021-10-14 13:45:03 +03:00
* @ return true if task added successfull else flase
2021-10-12 00:47:39 +03:00
* @ see AbstractNode : : removeTask
* @ see AbstractNode : : sheduledTaskCount
*/
2021-10-14 13:45:03 +03:00
bool sheduleTask ( const QSharedPointer < AbstractTask > & task ) ;
2021-10-12 00:47:39 +03:00
/**
* @ brief removeTask This method remove task from sheduler .
* @ param taskId This is task id that will be removed .
* @ see AbstractNode : : sheduleTask
* @ see AbstractNode : : sheduledTaskCount
*/
void removeTask ( int taskId ) ;
/**
* @ brief sheduledTaskCount This method return count of sheduled tasks .
* @ return count of sheduled tasks .
* @ see AbstractNode : : sheduleTask
* @ see AbstractNode : : removeTask
*/
int sheduledTaskCount ( ) const ;
2021-11-01 22:58:05 +03:00
# ifdef USE_HEART_SSL
/**
* @ brief ignoreSslErrors This method return list of ignored ssl errors
* @ return list of ignored ssl errors .
* @ see handleSslErrorOcurred
*/
const QList < QSslError > & ignoreSslErrors ( ) const ;
# endif
2020-09-15 21:16:35 +03:00
signals :
2020-09-16 23:40:42 +03:00
/**
2020-09-21 16:30:48 +03:00
* @ brief requestError This signal emited when client or node received from remoute server or node the BadRequest package .
2020-10-29 20:23:50 +03:00
* @ param code This is code of error .
2020-09-16 23:40:42 +03:00
* @ param msg - received text of remoute node ( server ) .
*/
2021-02-06 12:45:32 +03:00
void requestError ( unsigned char code , QString msg ) ;
2020-09-15 21:16:35 +03:00
2021-03-23 23:02:28 +03:00
2020-09-15 21:16:35 +03:00
protected :
2021-10-31 22:03:57 +03:00
# ifdef USE_HEART_SSL
2021-05-10 18:13:01 +03:00
2021-11-01 22:58:05 +03:00
/**
* @ brief setIgnoreSslErrors This list sets new ignored errors .
* @ param newIgnoreSslErrors This is new list of ignored errors .
* @ see handleSslErrorOcurred
*/
void setIgnoreSslErrors ( const QList < QSslError > & newIgnoreSslErrors ) ;
2021-05-10 18:13:01 +03:00
2020-09-15 21:16:35 +03:00
/**
2020-09-21 16:30:48 +03:00
* @ brief generateRSAforSSL This method generate ssl rsa pair keys for using in selfsigned cetificate .
* By default generate RSA 2048 , if you want change algorithm or keys size then override this method .
* @ param pkey This is openssl pointer to RSA pair key .
* @ return True if keys generated successful .
2020-09-15 21:16:35 +03:00
*/
virtual bool generateRSAforSSL ( EVP_PKEY * pkey ) const ;
/**
2020-09-21 16:30:48 +03:00
* @ brief generateSslDataPrivate This method generate a ssl certificate and a ssl keys using The SslSrtData structure .
* @ param data The data for generate a selfSigned certificate .
2021-03-12 12:23:30 +03:00
* @ param r_srt This is return value of a certivicate .
* @ param r_key - This is return value of private ssl key .
2020-09-21 16:30:48 +03:00
* @ return True if generate the selfSigned certificate finished succesful .
2020-09-15 21:16:35 +03:00
*/
virtual bool generateSslDataPrivate ( const SslSrtData & data , QSslCertificate & r_srt , QSslKey & r_key ) ;
/**
2020-09-21 16:30:48 +03:00
* @ brief selfSignedSslConfiguration This method create a new ssl configuration with selfsigned certificates .
* @ param data This is data for generate selfsigned certification for more information see SslSrtData structure .
2021-03-12 12:23:30 +03:00
* @ return The new selfsigned ssl configuration .
2020-09-15 21:16:35 +03:00
*/
2020-09-21 16:30:48 +03:00
virtual QSslConfiguration selfSignedSslConfiguration ( const SslSrtData & data = { } ) ;
2021-05-10 18:13:01 +03:00
# endif
2020-09-15 21:16:35 +03:00
/**
2020-09-21 16:30:48 +03:00
* @ brief createNodeInfo This method create a nodeInfo object .
* override this method for create your own nodeInfo objects . for more in
2021-03-12 12:23:30 +03:00
* @ param socket This is socket of network address .
2020-09-21 16:30:48 +03:00
* @ param clientAddress This parameter need to set when the socket du not contains a address or invalid .
* @ return return pointer to info object .
2020-09-15 21:16:35 +03:00
*/
virtual AbstractNodeInfo * createNodeInfo ( QAbstractSocket * socket ,
const HostAddress * clientAddress = nullptr ) const ;
/**
2020-09-21 16:30:48 +03:00
* @ brief registerSocket This method registration new socket object .
2021-03-12 12:23:30 +03:00
* @ param socket This is incomming socket pointer .
2020-09-21 16:30:48 +03:00
* @ param address This is host address of socket . By default is nullptr .
2021-03-12 12:23:30 +03:00
* Set this value for nodes created on this host .
* @ return return true if the scoeket has been registered successful .
2020-09-15 21:16:35 +03:00
*/
virtual bool registerSocket ( QAbstractSocket * socket , const HostAddress * address = nullptr ) ;
/**
2020-09-21 16:30:48 +03:00
* @ brief parsePackage This is main method of all childs classes of an AbstractNode class .
* This method work on own thread .
* If you ovveride this method you need to create this than an example :
2020-10-25 13:39:59 +03:00
* \ code { cpp }
2021-02-22 19:58:07 +03:00
ParserResult DataBaseNode : : parsePackage ( PKG : : AbstractData * pkg ,
const Header & pkgHeader ,
const AbstractNodeInfo * sender ) {
2020-09-21 16:30:48 +03:00
auto parentResult = AbstractNode : : parsePackage ( pkg , sender ) ;
if ( parentResult ! = ParserResult : : NotProcessed ) {
return parentResult ;
}
2021-09-25 14:26:47 +03:00
// you can use parsing without the commandHandler method
2021-10-06 12:29:06 +03:00
if ( MyCommand : : command ( ) = = pkg - > cmd ( ) ) {
2020-09-21 16:30:48 +03:00
BaseId requesterId = getSender ( sender , & obj ) ;
. . .
if ( FailCondition ) {
return ParserResult : : Error ;
}
. . .
return ParserResult : : Processed ;
}
2021-09-25 14:26:47 +03:00
// Or with the commandHandler method
2021-09-25 20:44:58 +03:00
auto result = commandHandler < MyPackage > ( this , & MyClass : : processMyPackage , pkg , sender , pkgHeader ) ;
2021-09-25 14:26:47 +03:00
if ( result ! = QH : : ParserResult : : NotProcessed ) {
return result ;
}
2020-09-21 16:30:48 +03:00
return ParserResult : : NotProcessed ;
}
* \ endcode
* @ param pkg This is package with incomming data .
2021-05-14 14:48:34 +03:00
* @ param sender This is sender this pacakge .
* @ param pkgHeader This is header of the incoming packet is used to create a response .
2020-09-21 16:30:48 +03:00
* @ return item of ParserResult . For more information see The ParserResult enum .
2021-09-25 14:52:42 +03:00
* @ see AbstractNode : : commandHandler
* @ see AbstractNode : : sendData
* @ see AbstractNode : : badRequest
2020-09-15 21:16:35 +03:00
*/
2021-09-25 14:26:47 +03:00
virtual ParserResult parsePackage ( const QSharedPointer < PKG : : AbstractData > & pkg ,
const Header & pkgHeader , const AbstractNodeInfo * sender ) ;
2020-09-15 21:16:35 +03:00
/**
2020-09-21 16:30:48 +03:00
* @ brief sendPackage This method prepare and send to target address a package .
* @ param pkg This is sendet pakcage to target node .
* @ param target This is target node .
2021-03-12 12:23:30 +03:00
* @ return return true if The package is sendet succesfull .
2021-03-17 19:34:51 +03:00
*
* @ note All packages sendets on the sender threaed . But thread of the node is wait for sends result .
* This is done that allthe data that is sent when node are dissconected come without fail .
2020-09-15 21:16:35 +03:00
*/
virtual bool sendPackage ( const Package & pkg , QAbstractSocket * target ) const ;
/**
2021-10-06 12:29:06 +03:00
* @ brief sendData This method send data object another to node
2021-03-12 12:23:30 +03:00
* @ param resp This is pointer to sendet object .
* @ param address This is target addres for sending .
* @ param req This is header of request .
2021-03-05 20:24:50 +03:00
* @ return hash of the sendet package . If function is failed then return 0.
2020-09-15 21:16:35 +03:00
*/
2021-03-05 20:24:50 +03:00
virtual unsigned int sendData ( const PKG : : AbstractData * resp , const HostAddress & address ,
2021-10-06 12:29:06 +03:00
const Header * req = nullptr ) ;
2021-09-30 12:30:16 +03:00
/**
2021-10-06 12:29:06 +03:00
* @ brief sendData This method send data object another to node
2021-09-30 12:30:16 +03:00
* @ param resp This is pointer to sendet object .
* @ param address This is target addres for sending .
* @ param req This is header of request .
* @ return hash of the sendet package . If function is failed then return 0.
*/
virtual unsigned int sendData ( const PKG : : AbstractData * resp , const AbstractNodeInfo * node ,
2021-10-06 12:29:06 +03:00
const Header * req = nullptr ) ;
2021-09-30 12:30:16 +03:00
2020-09-15 21:16:35 +03:00
/**
2021-03-12 12:23:30 +03:00
* @ brief badRequest This method is send data about error of request .
* @ param address This is addrees of receiver .
* @ param req This is header of incomming request .
2020-10-29 20:23:50 +03:00
* @ param err This is message and code of error . For more information see the ErrorData struct .
2021-03-12 12:23:30 +03:00
* @ param diff This is difference of current trust ( currenTrus + = diff ) .
2020-10-26 14:21:33 +03:00
* By default diff equals REQUEST_ERROR
2020-09-15 21:16:35 +03:00
*/
virtual void badRequest ( const HostAddress & address , const Header & req ,
2020-12-08 17:51:30 +03:00
const PKG : : ErrorData & err , qint8 diff = REQUEST_ERROR ) ;
2020-09-15 21:16:35 +03:00
/**
2020-09-21 16:30:48 +03:00
* @ brief getWorkStateString This method generate string about work state of server .
2021-03-12 12:23:30 +03:00
* @ return string of work state .
2020-09-15 21:16:35 +03:00
*/
virtual QString getWorkStateString ( ) const ;
/**
2021-03-12 12:23:30 +03:00
* @ brief connectionState This method return string value about the cocction state .
* @ return string with count users state .
2020-09-15 21:16:35 +03:00
*/
virtual QString connectionState ( ) const ;
/**
2020-09-21 16:30:48 +03:00
* @ brief banedList This method retrun list of banned clients of nodes .
2021-03-12 12:23:30 +03:00
* @ return list of baned nodes .
2020-09-15 21:16:35 +03:00
*/
QList < HostAddress > banedList ( ) const ;
2021-02-06 12:45:32 +03:00
// TO-DO Need to add new method fo collect banned addresses for exmaple use the mask.
// See Task https://github.com/QuasarApp/Heart/issues/13
2020-09-15 21:16:35 +03:00
/**
2020-09-21 16:30:48 +03:00
* @ brief isBanned This method checks if the node is banned .
2021-03-12 12:23:30 +03:00
* @ param socket This is node info object for validation .
* @ return true if node is banned .
2020-09-15 21:16:35 +03:00
*/
bool isBanned ( QAbstractSocket * socket ) const ;
/**
2021-03-12 12:23:30 +03:00
* @ brief incomingConnection This is ovverided method of QTCPServer .
* @ param handle This is socket handle .
2020-09-15 21:16:35 +03:00
*/
2020-09-21 16:30:48 +03:00
void incomingConnection ( qintptr handle ) override final ;
2020-09-15 21:16:35 +03:00
/**
2021-03-12 12:23:30 +03:00
* @ brief changeTrust This method change trust of connected node .
* @ param id This is id of select node .
* @ param diff This is difference of current trust ( currenTrus + = diff ) .
* @ return true if node trust is changed successful .
2020-09-15 21:16:35 +03:00
*/
virtual bool changeTrust ( const HostAddress & id , int diff ) ;
2021-10-31 22:03:57 +03:00
# ifdef USE_HEART_SSL
2020-09-15 21:16:35 +03:00
2020-09-16 23:40:42 +03:00
/**
2020-09-21 16:30:48 +03:00
* @ brief useSelfSignedSslConfiguration This method reconfigure current node to use selfSigned certificate .
2021-03-09 16:10:26 +03:00
* @ note Befor invoke this method stop this node ( server ) see AbstractNode : : stop .
* if mode will be working then this method return false .
2020-09-16 23:40:42 +03:00
* The self signed certificate is temp value , this is will be changed after reboot node ( server )
* @ param crtData - This is data for generation a new self signed certification .
* @ return result of change node ssl configuration .
*/
bool useSelfSignedSslConfiguration ( const SslSrtData & crtData ) ;
2020-09-15 21:16:35 +03:00
/**
2020-09-21 16:30:48 +03:00
* @ brief useSystemSslConfiguration This method reconfigure current node to use sslConfig .
2021-03-09 16:10:26 +03:00
* @ note Befor invoke this method stop this node ( server ) see AbstractNode : : stop .
* if mode will be working then this method return false .
2021-11-01 22:58:05 +03:00
* @ param config This is system ssl configuration . by default used QSslConfiguration : : defaultConfiguration ( ) method .
2020-09-16 23:40:42 +03:00
* @ return result of change node ssl configuration .
2020-09-15 21:16:35 +03:00
*/
2021-11-01 22:58:05 +03:00
bool useSystemSslConfiguration ( QSslConfiguration config = QSslConfiguration : : defaultConfiguration ( ) ) ;
2020-09-16 23:40:42 +03:00
/**
2021-03-12 12:23:30 +03:00
* @ brief disableSSL This method disable ssl mode for this node .
2021-03-09 16:10:26 +03:00
* @ note Befor invoke this method stop this node ( server ) see AbstractNode : : stop .
* if mode will be working then this method return false .
2020-09-16 23:40:42 +03:00
* @ return true if changes is completed .
*/
bool disableSSL ( ) ;
2021-05-10 18:13:01 +03:00
# endif
2020-09-15 21:16:35 +03:00
/**
2021-03-09 16:10:26 +03:00
* @ brief incomingData This method invoked when node get command or ansver .
* This method invoked befor parsing in the parsePackage method .
* @ note use this method for handling received data , but do not change the @ a pkg object .
* If You want change pkg object use the parsePackage method .
2020-09-21 16:30:48 +03:00
* @ param pkg This is received package ( in this implementation it is only the Ping command )
2021-03-12 12:23:30 +03:00
* @ param sender This is information of sender of the package .
2020-09-15 21:16:35 +03:00
* @ note override this method for get a signals .
2021-03-09 16:10:26 +03:00
* @ note This method will be invoked in the own thread .
2020-09-15 21:16:35 +03:00
*/
2021-03-09 16:10:26 +03:00
virtual void incomingData ( const PKG : : AbstractData * pkg ,
2021-02-09 21:17:52 +03:00
const AbstractNodeInfo * sender ) ;
2020-09-15 21:16:35 +03:00
/**
2021-03-12 12:23:30 +03:00
* @ brief connections - Return hash map of all connections of this node .
2020-09-21 16:30:48 +03:00
* @ return return map of connections .
2020-09-15 21:16:35 +03:00
*/
2020-11-11 23:03:18 +03:00
QHash < HostAddress , AbstractNodeInfo * > connections ( ) const ;
2020-09-15 21:16:35 +03:00
/**
* @ brief connectionRegistered Override this method for get registered incoming connections .
2021-03-12 12:23:30 +03:00
* @ param info - Connection information .
2020-09-15 21:16:35 +03:00
*/
virtual void connectionRegistered ( const AbstractNodeInfo * info ) ;
/**
2020-09-21 16:30:48 +03:00
* @ brief nodeConfirmend This method invocked when the node status changed to " confirmend "
2021-03-12 12:23:30 +03:00
* default implementatio do nothing .
* @ param node This is address of changed node .
2020-09-15 21:16:35 +03:00
*/
2021-01-31 19:51:00 +03:00
virtual void nodeConfirmend ( AbstractNodeInfo * node ) ;
2020-09-15 21:16:35 +03:00
/**
2020-09-21 16:30:48 +03:00
* @ brief nodeConnected This method invocked when the node status changed to " connected "
2021-03-12 12:23:30 +03:00
* default implementatio do nothing .
* @ param node This is address of changed node .
2020-09-15 21:16:35 +03:00
*/
2021-01-31 19:51:00 +03:00
virtual void nodeConnected ( AbstractNodeInfo * node ) ;
2020-09-15 21:16:35 +03:00
/**
2020-09-21 16:30:48 +03:00
* @ brief nodeConnected This method invocked when the node status changed to " disconnected "
2021-03-12 12:23:30 +03:00
* default implementatio do nothing .
* @ param node This is address of changed node .
2020-09-15 21:16:35 +03:00
*/
2021-01-31 19:51:00 +03:00
virtual void nodeDisconnected ( AbstractNodeInfo * node ) ;
2021-01-15 19:08:30 +03:00
2021-05-04 14:11:21 +03:00
2021-02-22 19:58:07 +03:00
template < class T >
/**
* @ brief registerPackageType This method register package type T .
* This is need to prepare pacakge for parsing in the parsePackage method .
*/
void registerPackageType ( ) {
2021-10-06 12:29:06 +03:00
_registeredTypes [ T : : command ( ) ] = [ ] ( ) {
2021-02-22 19:58:07 +03:00
return new T ( ) ;
} ;
} ;
2021-01-15 19:08:30 +03:00
void prepareForDelete ( ) override ;
2021-03-05 20:24:50 +03:00
/**
* @ brief prepareData This is private method for preparing package from the byteArray .
* @ param pkg This is a raw package value .
* @ return pointer into prepared data .
2021-03-12 12:23:30 +03:00
* @ warning The return value do not clear automatically .
2021-03-05 20:24:50 +03:00
*/
QSharedPointer < PKG : : AbstractData > prepareData ( const Package & pkg ) const ;
2021-10-01 22:54:49 +03:00
/**
* @ brief genPackage This is factory method that generate data pacakge objects by command .
* All object should be registered before using this method .
* @ param cmd This is command of pacakge see Header : : command .
* @ return shared pointer to new data object .
* @ see AbstractNode : : registerPackageType
* @ see Header : : command
*/
QSharedPointer < PKG : : AbstractData > genPackage ( unsigned short cmd ) const ;
2021-03-10 17:21:26 +03:00
/**
* @ brief checkCommand This method check command are if registered type or not .
* @ brief cmd This is command of a verifiable package .
* @ return True if the package is registered in a node .
*/
bool checkCommand ( unsigned short cmd ) const ;
2021-04-30 22:41:34 +03:00
/**
* @ brief connectionsList This method return list of all node connections
* @ return list of node connections .
* @ warning do not use this method for validation is connected .
*/
QList < HostAddress > connectionsList ( ) const ;
2021-05-04 14:11:21 +03:00
2021-10-08 16:02:50 +03:00
/**
* @ brief activeConnectionsList This method return list of actived nodes connections
* @ return list of actived nodes connections .
* @ warning do not use this method for validation is connected .
*/
QList < HostAddress > activeConnectionsList ( ) const ;
2021-10-11 20:42:13 +03:00
2021-09-25 14:26:47 +03:00
/**
* @ brief commandHandler This method it is simple wrapper for the handle pacakges in the AbstractNode : : parsePackage method .
* Exmaple of use :
* @ code { cpp }
2021-09-25 20:44:58 +03:00
* auto result = commandHandler < MyPackage > ( this , & MyClass : : processMyPackage , pkg , sender , pkgHeader ) ;
2021-09-25 14:26:47 +03:00
if ( result ! = QH : : ParserResult : : NotProcessed ) {
return result ;
}
. . .
* @ endcode
* @ tparam PackageClass This is class name that you want handle . All classes mist be inhert of the QH : : PKG : : AbstractData class .
2021-09-25 20:44:58 +03:00
* @ tparam HandlerType This is type of the handler object that will invoke @ a HandlerMethod method .
2021-09-25 14:26:47 +03:00
* @ tparam HandlerMethod This is name of the handler method .
* The handler method should be support next signature :
* * * bool Method ( const QSharedPointer < QH : : PKG : : PackageClass > & , const QH : : Header & pkgHeader , const QH : : AbstractNodeInfo * sender ) * * .
2021-09-25 20:44:58 +03:00
* @ param handlerObject This is pointer to handler object .
2021-09-25 14:26:47 +03:00
* @ param method This is handler method .
* @ param pkg This is package data from the AbstractNode : : parsePackage argumetns
* @ param pkgHeader This is header of an incomming package .
* @ param sender This is socket object of a sender that send this package .
* @ return item of ParserResult . For more information see The ParserResult enum .
*
* @ see AbstractNode : : parsePackage
* @ see ParserResult
*/
2021-09-25 20:44:58 +03:00
template < class PackageClass , class HandlerType , class HandlerMethod >
2021-09-25 14:26:47 +03:00
2021-09-25 20:44:58 +03:00
inline ParserResult commandHandler ( HandlerType handlerObject , HandlerMethod method ,
2021-09-25 14:26:47 +03:00
const QSharedPointer < QH : : PKG : : AbstractData > & pkg ,
const QH : : AbstractNodeInfo * sender ,
const QH : : Header & pkgHeader ) {
2021-10-06 12:29:06 +03:00
if ( PackageClass : : command ( ) = = pkg - > cmd ( ) ) {
2021-09-25 14:26:47 +03:00
auto data = pkg . staticCast < PackageClass > ( ) ;
if ( ! data - > isValid ( ) ) {
return QH : : ParserResult : : Error ;
}
2021-09-25 20:44:58 +03:00
if ( ! ( handlerObject - > * method ) ( data , sender , pkgHeader ) ) {
2021-09-25 14:26:47 +03:00
return QH : : ParserResult : : Error ;
}
return QH : : ParserResult : : Processed ;
}
2021-09-25 20:44:58 +03:00
return QH : : ParserResult : : NotProcessed ;
2021-09-25 14:26:47 +03:00
}
2021-05-04 14:11:21 +03:00
protected slots :
/**
* @ brief nodeErrorOccured This slot invoked when error ocured in the @ a nodeInfo .
* @ param nodeInfo This is pinter to modeInfoObject .
2021-05-14 14:48:34 +03:00
* @ param errorCode This is error code .
2021-05-04 14:11:21 +03:00
* @ param errorString This is string value of the error .
* @ note default implementation do nothing . Override this method if you want to handle nodes network errors .
*/
virtual void nodeErrorOccured ( AbstractNodeInfo * nodeInfo ,
QAbstractSocket : : SocketError errorCode ,
QString errorString ) ;
2020-09-15 21:16:35 +03:00
private slots :
2021-01-27 21:59:31 +03:00
void avelableBytes ( AbstractNodeInfo * sender ) ;
2021-01-31 19:51:00 +03:00
/**
* @ brief handleNodeStatusChanged This method invoked when status of peer node chganged .
* @ param node This is address of changed node .
* @ param status This is new status of node .
*
*/
void handleNodeStatusChanged ( AbstractNodeInfo * node , NodeCoonectionStatus status ) ;
2020-09-15 21:16:35 +03:00
/**
* @ brief handleWorkerStoped
*/
void handleWorkerStoped ( ) ;
/**
* @ brief handleForceRemoveNode - force remove connection .
* @ param node
*/
void handleForceRemoveNode ( HostAddress node ) ;
2021-10-11 20:42:13 +03:00
/**
* @ brief handleBeginWork This method run task on new thread .
* @ param work This is new work task
*/
void handleBeginWork ( QSharedPointer < QH : : AbstractTask > work ) ;
2021-11-01 22:58:05 +03:00
# ifdef USE_HEART_SSL
2021-10-31 22:03:57 +03:00
/**
2021-11-01 22:58:05 +03:00
* @ brief handleSslErrorOcurred This method invoked when a ssl socket receive an error mesage .
* Default implementation just pront error messages
* @ param errors This is errors list .
2021-10-31 22:03:57 +03:00
*/
2021-11-01 22:58:05 +03:00
void handleSslErrorOcurred ( SslSocket * sender , const QList < QSslError > & errors ) ;
2021-10-31 22:03:57 +03:00
/**
2021-11-01 22:58:05 +03:00
* @ brief handleEncrypted invoke when a ssl socket is encripted !
2021-10-31 22:03:57 +03:00
*/
2021-11-01 22:58:05 +03:00
void handleEncrypted ( AbstractNodeInfo * node ) ;
# endif
2021-10-31 22:03:57 +03:00
2020-09-15 21:16:35 +03:00
private :
/**
@ note just disaable listen method in the node objects .
*/
bool listen ( const HostAddress & address = HostAddress : : Any ) ;
/**
* @ brief newWork - this method it is wraper of the parsePackage method .
* the newWork invoke a parsePackage in the new thread .
* @ param pkg
* @ param sender
*/
2021-01-27 21:59:31 +03:00
void newWork ( const Package & pkg , AbstractNodeInfo * sender , const HostAddress & id ) ;
2020-09-15 21:16:35 +03:00
/**
* @ brief checkConfirmendOfNode - this method remove old not confirmed node .
2021-03-12 12:23:30 +03:00
* @ param node - Node address .
2020-09-15 21:16:35 +03:00
*/
2021-01-31 19:51:00 +03:00
void checkConfirmendOfNode ( AbstractNodeInfo * node ) ;
2020-09-15 21:16:35 +03:00
2021-03-23 23:02:28 +03:00
/**
* @ brief initThreadId This method save curent thread as a main thread .
*/
void initThreadId ( ) const ;
2021-03-25 16:17:26 +03:00
/**
* @ brief initThreadPool This method initialize thread pool of the workers
*/
void initThreadPool ( ) ;
/**
* @ brief deinitThreadPool This method remove all workers threads
*/
void deinitThreadPool ( ) ;
2021-10-31 22:03:57 +03:00
2020-09-21 16:50:31 +03:00
SslMode _mode = SslMode : : NoSSL ;
2021-10-31 22:03:57 +03:00
# ifdef USE_HEART_SSL
bool configureSslSocket ( AbstractNodeInfo * node , bool fServer ) ;
2020-09-15 21:16:35 +03:00
QSslConfiguration _ssl ;
2021-11-01 22:58:05 +03:00
QList < QSslError > _ignoreSslErrors ;
2021-05-10 18:13:01 +03:00
# endif
2020-09-15 21:16:35 +03:00
QHash < HostAddress , AbstractNodeInfo * > _connections ;
2020-09-24 15:24:51 +03:00
QHash < HostAddress , ReceiveData * > _receiveData ;
2020-09-15 21:16:35 +03:00
DataSender * _dataSender = nullptr ;
2021-03-18 10:16:09 +03:00
AsyncLauncher * _socketWorker = nullptr ;
2021-03-17 19:34:51 +03:00
QThread * _senderThread = nullptr ;
2021-10-01 22:54:49 +03:00
BigDataManager * _bigdatamanager = nullptr ;
2021-10-11 20:42:13 +03:00
TaskScheduler * _tasksheduller = nullptr ;
2020-09-15 21:16:35 +03:00
QSet < QFutureWatcher < bool > * > _workers ;
mutable QMutex _connectionsMutex ;
mutable QMutex _confirmNodeMutex ;
2021-03-24 10:39:04 +03:00
mutable QMutex _threadPoolMutex ;
2020-09-15 21:16:35 +03:00
2021-01-15 19:08:30 +03:00
QThreadPool * _threadPool = nullptr ;
2021-02-22 19:58:07 +03:00
QHash < unsigned short , std : : function < PKG : : AbstractData * ( ) > > _registeredTypes ;
2020-09-15 21:16:35 +03:00
2021-01-15 19:08:30 +03:00
friend class WebSocketController ;
2021-03-17 19:34:51 +03:00
friend class SocketFactory ;
2021-10-01 18:31:19 +03:00
friend class BigDataManager ;
2020-09-15 21:16:35 +03:00
} ;
}
# endif // ABSTRACTNODE_H