Merge pull request 'Mitigate target_height denial of service attack in wsMode' (#156) from tobtoht/feather:target_height into master

Reviewed-on: https://git.wownero.com/feather/feather/pulls/156
This commit is contained in:
tobtoht 2020-11-14 21:55:36 +00:00
commit eb801ed9d4
7 changed files with 26 additions and 16 deletions

View file

@ -459,7 +459,8 @@ void AppContext::onWSNodes(const QJsonArray &nodes) {
auto node = new FeatherNode(
obj.value("address").toString(),
(unsigned int)obj.value("height").toInt(),
obj.value("height").toInt(),
obj.value("target_height").toInt(),
obj.value("online").toBool());
QSharedPointer<FeatherNode> r = QSharedPointer<FeatherNode>(node);
l.append(r);

View file

@ -174,7 +174,7 @@ private:
const unsigned int m_donationBoundary = 15;
UtilsNetworking *m_utilsNetworkingNodes;
QTimer *m_storeTimer = new QTimer(this);
QUrl m_wsUrl = QUrl(QStringLiteral("ws://dtg2clrd6iand4mwp2x6nhbqd3nqbxlbiw65f6vkwmmutxy2sijsnjyd.onion/ws"));
QUrl m_wsUrl = QUrl(QStringLiteral("ws://7e6egbawekbkxzkv4244pqeqgoo4axko2imgjbedwnn6s5yb6b7oliqd.onion/ws"));
};
#endif //FEATHER_APPCONTEXT_H

View file

@ -97,7 +97,7 @@ QVariant NodeModel::headerData(int section, Qt::Orientation orientation, int rol
FeatherNode NodeModel::node(int row) {
if (row < 0 || row >= m_nodes.size()) {
qCritical("%s: no reddit post for index %d", __FUNCTION__, row);
return FeatherNode("", 0, false);
return FeatherNode();
}
return m_nodes.at(row);
}

View file

@ -15,7 +15,7 @@ Nodes::Nodes(AppContext *ctx, QNetworkAccessManager *networkAccessManager, QObje
QObject(parent),
m_ctx(ctx),
m_networkAccessManager(networkAccessManager),
m_connection(FeatherNode("", 0, false)),
m_connection(FeatherNode()),
modelWebsocket(new NodeModel(NodeSource::websocket, this)),
modelCustom(new NodeModel(NodeSource::custom, this)) {
this->loadConfig();
@ -47,7 +47,7 @@ void Nodes::loadConfig() {
// load custom nodes
auto nodes = obj.value("custom").toArray();
foreach (const QJsonValue &value, nodes) {
auto customNode = FeatherNode(value.toString(), 0, false);
auto customNode = FeatherNode(value.toString());
customNode.custom = true;
if(m_connection == customNode) {
@ -63,7 +63,7 @@ void Nodes::loadConfig() {
// load cached websocket nodes
auto ws = obj.value("ws").toArray();
foreach (const QJsonValue &value, ws) {
auto wsNode = FeatherNode(value.toString(), 0, false);
auto wsNode = FeatherNode(value.toString());
wsNode.custom = false;
wsNode.online = true; // assume online
@ -214,7 +214,7 @@ void Nodes::onConnectionTimer() {
FeatherNode Nodes::pickEligibleNode() {
// Pick a node at random to connect to
FeatherNode rtn("", 0, false);
auto rtn = FeatherNode();
NodeSource nodeSource = this->source();
auto wsMode = nodeSource == NodeSource::websocket;
auto nodes = wsMode ? m_websocketNodes : m_customNodes;
@ -268,13 +268,20 @@ FeatherNode Nodes::pickEligibleNode() {
continue;
m_connectionAttempts.append(node.full);
if (wsMode && !node.online)
if (wsMode) {
// Ignore offline nodes
if (!node.online)
continue;
// Ignore nodes that are more than 25 blocks behind mode
if (wsMode && node.height < (mode_height - 25))
if (node.height < (mode_height - 25))
continue;
// Ignore nodes that say they aren't synchronized
if (node.target_height > node.height)
continue;
}
return node;
}
}

View file

@ -22,7 +22,8 @@ enum NodeSource {
};
struct FeatherNode {
FeatherNode(QString _address, unsigned int height, bool online) : height(height), online(online){
explicit FeatherNode(QString _address = "", int height = 0, int target_height = 0, bool online = false)
: height(height), target_height(target_height), online(online){
// wonky ipv4/host parsing, should be fine(tm)(c).
if(_address.isEmpty()) return;
if(_address.contains("https://")) {
@ -50,7 +51,8 @@ struct FeatherNode {
QString address;
QString full;
unsigned int height;
int height;
int target_height;
bool online = false;
QString username;
QString password;

View file

@ -176,7 +176,7 @@ void NodeWidget::onCustomAddClicked(){
if(newNodeText.isEmpty())
continue;
auto node = FeatherNode(newNodeText, 0, false);
auto node = FeatherNode(newNodeText);
node.custom = true;
nodesList.append(node);
}

View file

@ -65,7 +65,7 @@ bool NetworkPage::validatePage() {
auto nodeText = ui->lineEdit_customNode->text().trimmed();
if(!nodeText.isEmpty()) {
auto customNodes = m_ctx->nodes->customNodes();
auto node = FeatherNode(nodeText, 0, false);
auto node = FeatherNode(nodeText);
customNodes.append(node);
m_ctx->setCustomNodes(customNodes);
}