Classified ads
|
Class that represents a network connection. More...
#include <connection.h>
Classes | |
class | ConnectionObserver |
Interface for receiving network traffic. More... | |
Public Types | |
enum | ConnectionState { Initial, Open, Closing, Error } |
Public Slots | |
void | socketReady () |
void | run () |
void | encryptedBytesWritten (qint64 written) |
void | sslErrors (const QList< QSslError > &errors) |
void | socketError (QAbstractSocket::SocketError socketError) |
void | disconnected () |
void | readyRead () |
Signals | |
void | error (QTcpSocket::SocketError socketError) |
void | finished () |
void | blackListNetworkAddr (QHostAddress aAddr) |
void | connectionAttemptFailed (const Hash &aNodeHash) |
Public Member Functions | |
Connection (int aSocketDescriptor, ConnectionObserver &aObserver, Model &aModel, MController &aController) | |
Connection (const QHostAddress &aAddr, const int aPort, ConnectionObserver &aObserver, Model &aModel, MController &aController, const Hash &aFpOfNodeToTry) | |
~Connection () | |
Node * | node () const |
void | setNode (Node *aNode) |
QHostAddress | peerAddress () const |
const Hash & | fingerPrintOfNodeAttempted () |
ConnectionState | connectionState () const |
ProtocolItemType | stageOfBucketFill () const |
void | setStageOfBucketFill (ProtocolItemType aStage) |
bool | isInbound () const |
time_t | getOpenTime () const |
Hash | getPeerHash () const |
unsigned long | bytesIn () const |
unsigned long | bytesOut () const |
bool | forciblyCloseSocket () |
bool | isInPrivateAddrSpace () const |
Static Public Member Functions | |
static bool | Ipv6AddressesEqual (const Q_IPV6ADDR &aAddr1, const Q_IPV6ADDR &aAddr2) |
Public Attributes | |
QList< SendQueueItem > | iSendQueue |
QList< QByteArray * > | iNextProtocolItemToSend |
bool | iNeedsToRun |
time_t | iTimeOfLastActivity |
unsigned | iNumberOfPacketsReceived |
Static Public Attributes | |
static const unsigned | iMinutesBetweenBucketFill = 30 |
Protected Member Functions | |
void | performRead () |
void | readLoop () |
void | runForIncomingConnections () |
void | runForOutgoingConnections () |
void | checkForBucketFill () |
void | flushSocket () |
void | setupSocketSignals () |
void | msleep (int aMilliSeconds) |
Protected Attributes | |
ConnectionState | iConnectionState |
ConnectionObserver & | iObserver |
QSslSocket * | iSocket |
Model & | iModel |
quint32 | iBytesExpectedInPacketBeingRead |
QByteArray * | iBytesRead |
int | iInvocationsSinceLastByteReceived |
Node * | iNodeOfConnectedPeer |
QHostAddress | iAddrToConnect |
const int | iPortToConnect |
const int | iSocketDescriptor |
const bool | iSocketIsIncoming |
MController & | iController |
Hash | iFpOfNodeWeTrying |
ProtocolItemType | iStageOfBucketFill |
quint32 | iTimeOfBucketFill |
Hash | iEndOfBucket |
const time_t | iSocketOpenTime |
unsigned long | iBytesIn |
unsigned long | iBytesOut |
QHostAddress | iPeerAddress |
int | iBytesPendingWrite |
int | iSleepBetweenSendOperations |
Hash | iPeerHash |
Class that represents a network connection.
At runtime we'll have 1-n of these. This is a base-class that allows us to do some operations like "send", "receive" without needing to know if we're having a socket conn or some other kind.
Enumeration of the connection states
Enumerator | |
---|---|
Initial | SYN packet sent |
Open | SSL handshake was success, peerCert is avail |
Closing | Disconnection has been asked |
Error | Connection itself reports an error |
Connection::Connection | ( | int | aSocketDescriptor, |
ConnectionObserver & | aObserver, | ||
Model & | aModel, | ||
MController & | aController | ||
) |
Constructor to use when incoming connection
Connection::Connection | ( | const QHostAddress & | aAddr, |
const int | aPort, | ||
ConnectionObserver & | aObserver, | ||
Model & | aModel, | ||
MController & | aController, | ||
const Hash & | aFpOfNodeToTry | ||
) |
Constructor. Class will initiate connetion to given addr.
aAddr | network address to try |
aPort | port in said addr |
aObserver | class wishing to receive status updates about this connection |
aModel | datamodel reference |
aController | application controller reference |
aFpOfNodeToTry | sometimes we need to connect some particular node ; hash of the attempted host may be given here. It is not used by connection itself but the observers may query it in case of failed connection of the connection was attempted to some particular node. In particular this logic is used by publishing engine that needs to know not only successful connections but also failed ones and for failed ones we don't get node FP via normal mechanism (node greeting) |
Connection::~Connection | ( | ) |
Method for tearing down a connection
|
signal |
|
inline |
returs data transfer amount
|
inline |
returns data transfer amount
|
protected |
method for keeping buckets filled. this checks if we have content that according to its network addr should belong to that peer ; and then adds it to send queue
|
signal |
Emitted when outgoing connectio fails. Used for keeping count on nodes not to try immediately again
|
inline |
getter method for connection state
|
slot |
Connected from QSslSocket. Called on close
|
slot |
Connected from QSslSocket. Called when bytes have been written
|
signal |
const Hash& Connection::fingerPrintOfNodeAttempted | ( | ) |
method for getting the hash this connection was trying to attempt .. if connection was originally asked to be to some particular node, this will return hash of the node ; if connection was to no particular node, a zero hash will be returned
|
signal |
|
protected |
method that tries to flush pending output, if platform supports
bool Connection::forciblyCloseSocket | ( | ) |
Forcibly closes socket.
|
inline |
method for getting open time of connection
Hash Connection::getPeerHash | ( | ) | const |
method for getting peering node fingerprint. if connection is not yet open, returns KNullHash
|
static |
helper method for comparing ipv6 addresses
|
inline |
method for getting information if connection is inbound
bool Connection::isInPrivateAddrSpace | ( | ) | const |
method for checking if connection is in private (non-routable) ipv4-addr space like 192.168.. network
|
protected |
stops execution for some time
|
inline |
getter method for node of this connection. value may be null if connection is still in early stage so non-nulliness must be tested
none |
QHostAddress Connection::peerAddress | ( | ) | const |
method for getting peer addr
|
protected |
|
protected |
called from run()
|
slot |
Connected from QSslSocket. Called when bytes are available
|
slot |
this class is a kind of a thread, we need to have run ; note that right now QThread is not inherited but our worker-method is still named run, called by thread when it is started ( from networklistener or networkconnectorengine)
|
protected |
2 versions of run, called from run(),first for incoming connections
|
protected |
2 versions of run, called from run(),then for outgoing connections
|
inline |
for testing purposes only: this should never be called in production setup. this does get called from test-code
|
inline |
Method for setting bucket fill stage. See also stageOfBucketFill.
|
protected |
method that sets up signals/slots of socket
|
slot |
Connected from QSslSocket::error. Called on error
|
slot |
Called when socket is encrypted and ready to transmit
|
slot |
Connected from QSslSocket. Called on handshake errors
|
inline |
Method for getting the bucket fill stage. See explanation at documentation of the variable Connection::iStageOfBucketFill for idea how this should be used
|
protected |
network address to connect, if connection is outgoing connection
|
protected |
when starting to receive packet from peer, length is stored here
|
protected |
transferred data amount
|
protected |
transferred data amount
|
protected |
indication if write operation has been started but is not yet complete
|
protected |
when reading packet from peer, this contains bytes being read
|
protected |
< closed/open etc.
|
protected |
application controller reference
|
protected |
Where our bucket ends. Our own node fp is the start of the bucket, here is the end
|
protected |
It may be that connection is asked to specific node, in addition to being into some known network address. If the node is known, store the target node fingerprintin here. This is used at least in wishlist-connections where the connection itself will signal its open-for-business state when connection to asked node is ready
|
protected |
this variable here is used as counter during pending read of data packet, zeroed every time bytes are received ; if it reaches high number (a sign of stalled download) do drop connection to that peer
|
static |
how often peers are queried for new content to send/receive ; this is also max permitted lenght for data transmission inactivity ; nodes that have been idle longer than this are considered "dead"
|
protected |
datamodel reference
bool Connection::iNeedsToRun |
if set to false, connection closes itself
QList<QByteArray *> Connection::iNextProtocolItemToSend |
This is the next item to send. This does not include the length. .. as protocol items over socket are sent so that length goes first, as uint32, followed by that many bytes. This QByteArray contains the bytes, not the uint32 that goes first. Reason is that this is wanted this way is that the class doing the sending to be aware of the length, forcing this way it to calculate it itself.
|
protected |
node-data-structure of the connected node
unsigned Connection::iNumberOfPacketsReceived |
nr of received complete protocol packets
|
protected |
received data is sent to ConnectionObserver
|
protected |
storage for peeraddress
|
protected |
hash of peering node
|
protected |
port to connect, if connection is outgoing connection
QList<SendQueueItem> Connection::iSendQueue |
many things going on inside classified ads are about the connected node ; when node is disconnected, we may forget about many things that may have been in progress. therefore it may make sense to store also the queue of things to send in here ; when connection goes away, so goes the queue and no further processing needed.
The order of things in this list is significant, the first item to be append()ed should be sent first.
|
protected |
How many milliseconds to sleep between send operations
|
protected |
socket for data transfer: the actual socket is owned by stack frame of the thread so even tough we have this pointer here, it may not be deleted
|
protected |
descriptor of already-connected socket if connection is incoming-connection
|
protected |
true if incoming socket
|
protected |
time of socket open
|
protected |
method of handling around network churn is implemented in several places. .. churn requires us to copy stuff beloging to NodesAroundHash ( see nodemodel ) to nodes that are in the same bucket with us. Our concept of bucket is a bit stretched but there is kind of bucket and we will send of over new data to nodes that we think belongs to the bucket of connecting node.
sending the data happens in several stages, connection itself stores the stage here. filling the bucket according to stage then happens in NodeModel::getNextItemToSend method
|
protected |
time of last bucket fill
time_t Connection::iTimeOfLastActivity |
last time there was any traffic with peer