diff options
| author | Anton <anton@picapica> | 2019-05-20 22:02:24 +0400 |
|---|---|---|
| committer | Anton <anton@picapica> | 2019-05-20 22:02:24 +0400 |
| commit | 7db26f9d7c28d2b0320a213b6e6d20d296f8b282 (patch) | |
| tree | 2604444b6637040ce1424fdcfd64c30f88945921 | |
| parent | 8d5582bc573f83dbb45f527fc47039664b5f939e (diff) | |
| download | pica-pica-7db26f9d7c28d2b0320a213b6e6d20d296f8b282.tar.gz pica-pica-7db26f9d7c28d2b0320a213b6e6d20d296f8b282.zip | |
pica-client: improved reconnect behavior
| -rw-r--r-- | pica-client/skynet.cpp | 112 | ||||
| -rw-r--r-- | pica-client/skynet.h | 7 |
2 files changed, 70 insertions, 49 deletions
diff --git a/pica-client/skynet.cpp b/pica-client/skynet.cpp index bf02e11..89386d0 100644 --- a/pica-client/skynet.cpp +++ b/pica-client/skynet.cpp @@ -29,6 +29,7 @@ #include "askpassword.h" #include "settings.h" #include "../PICA_netconf.h" +#include <time.h> SkyNet::SkyNet() : nodes(config_dbname), QObject(0), active_filetransfers(0) @@ -70,6 +71,7 @@ SkyNet::SkyNet() connect(this, SIGNAL(MultiloginMessageReceived(quint64,QString,quint16)), this, SLOT(multilogin_event(quint64,QString,quint16)), Qt::QueuedConnection); event_loop_timer_id = startTimer(100); + c2c_reconnect_timer_id = startTimer(1000); file_transfer_timer_id = 0; } @@ -132,9 +134,6 @@ void SkyNet::nodelink_activated(PICA_c2n *c2n) nodes.MakeClean(); emit BecameSelfAware(); - // - //restore old peer connections, if any - QList<QByteArray> c2c_peer_ids; //load undelivered messages from history if (msgqueues.isEmpty()) @@ -146,26 +145,8 @@ void SkyNet::nodelink_activated(PICA_c2n *c2n) //load file transfers to be completed // sndfilequeues = ... - - QMap<QByteArray, QList<QString> > queues = msgqueues; - - queues.unite(sndfilequeues); - - c2c_peer_ids = queues.uniqueKeys(); - - for (int i = 0; i < c2c_peer_ids.size(); i++) - { - int ret; - struct PICA_c2c *chan = NULL; - - ret = PICA_new_c2c(active_nodelink, (const unsigned char*)c2c_peer_ids[i].constData(), NULL, &chan); - - qDebug() << "restoring c2c to " << c2c_peer_ids[i] << " ret =" << ret << "\n"; - } - - //start timer - retry_timer_id = startTimer(10000); - // + c2c_reconnect_timeouts.clear(); + reconnect_c2c(); } } @@ -176,6 +157,7 @@ void SkyNet::nodelink_closed(PICA_c2n *c2n, int error) active_nodelink = NULL; self_aware = false; emit LostSelfAwareness(); + nodelink_reconnect_timer_id = startTimer(10000); } else { @@ -224,6 +206,7 @@ void SkyNet::nodelink_failed(PICA_c2n *c2n, int error) { self_aware = false; emit LostSelfAwareness(); + nodelink_reconnect_timer_id = startTimer(10000); } } @@ -304,6 +287,57 @@ void SkyNet::verify_peer_cert(QByteArray peer_id, QString cert_pem, bool *verifi } } +void SkyNet::update_c2c_reconnect_timeout(QByteArray peer_id) +{ + if (c2c_reconnect_timeouts.contains(QByteArray((const char*)peer_id, PICA_ID_SIZE))) + c2c_reconnect_timeouts[QByteArray((const char*)peer_id, PICA_ID_SIZE)] *= 2; + else + c2c_reconnect_timeouts[QByteArray((const char*)peer_id, PICA_ID_SIZE)] = 1; + + if (c2c_reconnect_timeouts[QByteArray((const char*)peer_id, PICA_ID_SIZE)] >= 64) + c2c_reconnect_timeouts[QByteArray((const char*)peer_id, PICA_ID_SIZE)] = 64; +} + +void SkyNet::reset_c2c_reconnect_timeout(QByteArray peer_id) +{ + c2c_reconnect_timeouts.remove(peer_id); +} + +void SkyNet::reconnect_c2c() +{ + if (msgqueues.empty() && sndfilequeues.empty()) + return; + + if (self_aware) + { + QMap<QByteArray, QList<QString> > queues = msgqueues; + queues.unite(sndfilequeues); + time_t t = time(NULL); + + QList<QByteArray> c2c_peer_ids = queues.uniqueKeys(); + + c2c_peer_ids = filter_existing_chans(c2c_peer_ids); + + for (int i = 0; i < c2c_peer_ids.size(); i++) + { + int ret; + + struct PICA_c2c *chan = NULL; + + if (c2c_reconnect_timeouts.contains(c2c_peer_ids[i])) + { + if (t % c2c_reconnect_timeouts[c2c_peer_ids[i]] != 0) + continue; + } + + ret = PICA_new_c2c(active_nodelink, (const unsigned char*)c2c_peer_ids[i].constData(), NULL, &chan); + + qDebug() << "restoring c2c to " << c2c_peer_ids[i].toBase64() << " ret =" << ret << " in timer event\n"; + + } + } +} + void SkyNet::timerEvent(QTimerEvent *e) { if (e->timerId() == file_transfer_timer_id || e->timerId() == event_loop_timer_id) @@ -337,32 +371,12 @@ void SkyNet::timerEvent(QTimerEvent *e) return; } + if (self_aware && e->timerId() == c2c_reconnect_timer_id) + reconnect_c2c(); - if (self_aware) - { - QMap<QByteArray, QList<QString> > queues = msgqueues; - queues.unite(sndfilequeues); - - QList<QByteArray> c2c_peer_ids = queues.uniqueKeys(); - - c2c_peer_ids = filter_existing_chans(c2c_peer_ids); - - for (int i = 0; i < c2c_peer_ids.size(); i++) - { - int ret; - - struct PICA_c2c *chan = NULL; - - ret = PICA_new_c2c(active_nodelink, (const unsigned char*)c2c_peer_ids[i].constData(), NULL, &chan); - - qDebug() << "restoring c2c to " << c2c_peer_ids[i].toBase64() << " ret =" << ret << " in timer event\n"; - - } - - } - else + if (!self_aware && e->timerId() == nodelink_reconnect_timer_id) { - killTimer(e->timerId()); + killTimer(nodelink_reconnect_timer_id); Accounts::AccountRecord acc = this->CurrentAccount(); Join(acc); } @@ -508,7 +522,6 @@ void SkyNet::Exit() self_aware = false; active_filetransfers_reset(); - killTimer(retry_timer_id); msgqueues.clear(); @@ -915,12 +928,14 @@ void SkyNet::msgok_cb(const unsigned char *peer_id) void SkyNet::c2c_established_cb(const unsigned char *peer_id, const char *ciphersuitename) { + skynet->reset_c2c_reconnect_timeout(QByteArray((const char*)peer_id, PICA_ID_SIZE)); skynet->emit_ConnectionStatusUpdated(QByteArray((const char*)peer_id, PICA_ID_SIZE), QString("🔐: %1 c2c").arg(ciphersuitename)); skynet->flush_queues(QByteArray((const char*)peer_id, PICA_ID_SIZE)); } void SkyNet::c2c_failed(const unsigned char *peer_id) { + skynet->update_c2c_reconnect_timeout(QByteArray((const char*)peer_id, PICA_ID_SIZE)); qDebug() << "c2c failed (" << QByteArray((const char*)peer_id, PICA_ID_SIZE).toBase64() << ")\n"; skynet->emit_ConnectionStatusUpdated(QByteArray((const char*)peer_id, PICA_ID_SIZE), QString(tr("Failed to connect"))); } @@ -932,6 +947,7 @@ int SkyNet::accept_cb(const unsigned char *caller_id) void SkyNet::notfound_cb(const unsigned char *callee_id) { + skynet->update_c2c_reconnect_timeout(QByteArray((const char*)callee_id, PICA_ID_SIZE)); qDebug() << "not found (" << QByteArray((const char*)callee_id, PICA_ID_SIZE).toBase64() << ")\n"; /* diff --git a/pica-client/skynet.h b/pica-client/skynet.h index 875277e..79a368e 100644 --- a/pica-client/skynet.h +++ b/pica-client/skynet.h @@ -92,12 +92,17 @@ private: QMap<QByteArray, QList<QString> > msgqueues; QMap<QByteArray, QList<QString> > sndfilequeues; - int retry_timer_id; + QMap<QByteArray, quint32> c2c_reconnect_timeouts; + int nodelink_reconnect_timer_id; int event_loop_timer_id; int file_transfer_timer_id; + int c2c_reconnect_timer_id; void timerEvent(QTimerEvent * e); + void reconnect_c2c(); + void update_c2c_reconnect_timeout(QByteArray peer_id); + void reset_c2c_reconnect_timeout(QByteArray peer_id); void flush_queues(QByteArray to); struct PICA_c2c *find_active_chan(QByteArray peer_id); QList<QByteArray> filter_existing_chans(QList<QByteArray> peer_ids); |
