<commit_before>// Copyright (c) 2011-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <qt/clientmodel.h>

#include <qt/bantablemodel.h>
#include <qt/guiconstants.h>
#include <qt/guiutil.h>
#include <qt/peertablemodel.h>

#include <chain.h>
#include <chainparams.h>
#include <checkpoints.h>
#include <clientversion.h>
#include <net.h>
#include <txmempool.h>
#include <ui_interface.h>
#include <util.h>
#include <validation.h>
#include <warnings.h>

#include <stdint.h>

#include <QDebug>
#include <QTimer>

class CBlockIndex;

static int64_t nLastHeaderTipUpdateNotification = 0;
static int64_t nLastBlockTipUpdateNotification = 0;

ClientModel::ClientModel(OptionsModel* _optionsModel, QObject* parent) : QObject(parent),
                                                                         optionsModel(_optionsModel),
                                                                         peerTableModel(0),
                                                                         banTableModel(0),
                                                                         pollTimer(0)
{
    cachedBestHeaderHeight = -1;
    cachedBestHeaderTime = -1;
    peerTableModel = new PeerTableModel(this);
    banTableModel = new BanTableModel(this);
    pollTimer = new QTimer(this);
    connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer()));
    pollTimer->start(MODEL_UPDATE_DELAY);

    versionOutDated = false;

    subscribeToCoreSignals();

    setDSUntaringRequested(false);
}

ClientModel::~ClientModel()
{
    unsubscribeFromCoreSignals();
}

int ClientModel::getNumConnections(unsigned int flags) const
{
    CConnman::NumConnections connections = CConnman::CONNECTIONS_NONE;

    if (flags == CONNECTIONS_IN)
        connections = CConnman::CONNECTIONS_IN;
    else if (flags == CONNECTIONS_OUT)
        connections = CConnman::CONNECTIONS_OUT;
    else if (flags == CONNECTIONS_ALL)
        connections = CConnman::CONNECTIONS_ALL;

    if (g_connman)
        return g_connman->GetNodeCount(connections);
    return 0;
}

int ClientModel::getNumBlocks() const
{
    LOCK(cs_main);
    return chainActive.Height();
}

int ClientModel::getHeaderTipHeight() const
{
    if (cachedBestHeaderHeight == -1) {
        // make sure we initially populate the cache via a cs_main lock
        // otherwise we need to wait for a tip update
        LOCK(cs_main);
        if (pindexBestHeader) {
            cachedBestHeaderHeight = pindexBestHeader->nHeight;
            cachedBestHeaderTime = pindexBestHeader->GetBlockTime();
        }
    }
    return cachedBestHeaderHeight;
}

int64_t ClientModel::getHeaderTipTime() const
{
    if (cachedBestHeaderTime == -1) {
        LOCK(cs_main);
        if (pindexBestHeader) {
            cachedBestHeaderHeight = pindexBestHeader->nHeight;
            cachedBestHeaderTime = pindexBestHeader->GetBlockTime();
        }
    }
    return cachedBestHeaderTime;
}

quint64 ClientModel::getTotalBytesRecv() const
{
    if (!g_connman)
        return 0;
    return g_connman->GetTotalBytesRecv();
}

quint64 ClientModel::getTotalBytesSent() const
{
    if (!g_connman)
        return 0;
    return g_connman->GetTotalBytesSent();
}

QDateTime ClientModel::getLastBlockDate() const
{
    LOCK(cs_main);

    if (chainActive.Tip())
        return QDateTime::fromTime_t(chainActive.Tip()->GetBlockTime());

    return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network
}

long ClientModel::getMempoolSize() const
{
    return mempool.size();
}

size_t ClientModel::getMempoolDynamicUsage() const
{
    return mempool.DynamicMemoryUsage();
}

double ClientModel::getVerificationProgress(const CBlockIndex* tipIn) const
{
    CBlockIndex* tip = const_cast<CBlockIndex*>(tipIn);
    if (!tip) {
        LOCK(cs_main);
        tip = chainActive.Tip();
    }
    return GuessVerificationProgress(Params().TxData(), tip);
}

void ClientModel::updateTimer()
{
    // no locking required at this point
    // the following calls will acquire the required lock
    Q_EMIT mempoolSizeChanged(getMempoolSize(), getMempoolDynamicUsage());
    Q_EMIT bytesChanged(getTotalBytesRecv(), getTotalBytesSent());
}

void ClientModel::updateNetwork(bool active)
{
    Q_EMIT setNetworkActive(active);
}

void ClientModel::updateNumConnections(int numConnections)
{
    Q_EMIT numConnectionsChanged(numConnections);
}

void ClientModel::updateNetworkActive(bool networkActive)
{
    Q_EMIT networkActiveChanged(networkActive);
}

void ClientModel::updateAlert()
{
    Q_EMIT alertsChanged(getStatusBarWarnings());
}

bool ClientModel::inInitialBlockDownload() const
{
    return IsInitialBlockDownload();
}

void ClientModel::updateBlockchainStatus(int status)
{
    Q_EMIT BlockchainStatusChanged(status);
}

enum BlockSource ClientModel::getBlockSource() const
{
    if (fReindex)
        return BLOCK_SOURCE_REINDEX;
    else if (fImporting)
        return BLOCK_SOURCE_DISK;
    else if (getNumConnections() > 0)
        return BLOCK_SOURCE_NETWORK;

    return BLOCK_SOURCE_NONE;
}

void ClientModel::setNetworkActive(bool active)
{
    if (g_connman) {
        g_connman->SetNetworkActive(active);
    }
}

bool ClientModel::getNetworkActive() const
{
    if (g_connman) {
        return g_connman->GetNetworkActive();
    }
    return false;
}

QString ClientModel::getStatusBarWarnings() const
{
    return QString::fromStdString(GetWarnings("gui"));
}

OptionsModel* ClientModel::getOptionsModel()
{
    return optionsModel;
}

PeerTableModel* ClientModel::getPeerTableModel()
{
    return peerTableModel;
}

BanTableModel* ClientModel::getBanTableModel()
{
    return banTableModel;
}

QString ClientModel::formatFullVersion() const
{
    return QString::fromStdString(FormatFullVersion());
}

QString ClientModel::formatSubVersion() const
{
    return QString::fromStdString(strSubVersion);
}

bool ClientModel::isReleaseVersion() const
{
    return CLIENT_VERSION_IS_RELEASE;
}

QString ClientModel::formatClientStartupTime() const
{
    return QDateTime::fromTime_t(GetStartupTime()).toString();
}

QString ClientModel::dataDir() const
{
    return GUIUtil::boostPathToQString(GetDataDir());
}

void ClientModel::updateBanlist()
{
    banTableModel->refresh();
}

// Handlers for core signals
static void ShowProgress(ClientModel* clientmodel, const std::string& title, int nProgress)
{
    // emits signal "showProgress"
    QMetaObject::invokeMethod(clientmodel, "showProgress", Qt::QueuedConnection,
        Q_ARG(QString, QString::fromStdString(title)),
        Q_ARG(int, nProgress));
}

static void NotifyNumConnectionsChanged(ClientModel* clientmodel, int newNumConnections)
{
    // Too noisy: qDebug() << "NotifyNumConnectionsChanged: " + QString::number(newNumConnections);
    QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
        Q_ARG(int, newNumConnections));
}

static void NotifyNetworkActiveChanged(ClientModel* clientmodel, bool networkActive)
{
    QMetaObject::invokeMethod(clientmodel, "updateNetworkActive", Qt::QueuedConnection,
        Q_ARG(bool, networkActive));
}

static void NotifyAlertChanged(ClientModel* clientmodel)
{
    qDebug() << "NotifyAlertChanged";
    QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection);
}

static void NotifyBlockchainStatusChanged(ClientModel* clientmodel, int newStatus)
{
    qDebug() << "NotifyBlockchainStatusChanged: " + QString::number(newStatus);
    QMetaObject::invokeMethod(clientmodel, "updateBlockchainStatus", Qt::QueuedConnection,
        Q_ARG(int, newStatus));
}

static void BannedListChanged(ClientModel* clientmodel)
{
    qDebug() << QString("%1: Requesting update for peer banlist").arg(__func__);
    QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection);
}

static void BlockTipChanged(ClientModel* clientmodel, bool initialSync, const CBlockIndex* pIndex, bool fHeader)
{
    // lock free async UI updates in case we have a new block tip
    // during initial sync, only update the UI if the last update
    // was > 250ms (MODEL_UPDATE_DELAY) ago
    int64_t now = 0;
    if (initialSync)
        now = GetTimeMillis();

    int64_t& nLastUpdateNotification = fHeader ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification;

    if (fHeader) {
        // cache best headers time and height to reduce future cs_main locks
        clientmodel->cachedBestHeaderHeight = pIndex->nHeight;
        clientmodel->cachedBestHeaderTime = pIndex->GetBlockTime();
    }
    // if we are in-sync, update the UI regardless of last update time
    if (!initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) {
        //pass an async signal to the UI thread
        QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection,
            Q_ARG(int, pIndex->nHeight),
            Q_ARG(QDateTime, QDateTime::fromTime_t(pIndex->GetBlockTime())),
            Q_ARG(double, clientmodel->getVerificationProgress(pIndex)),
            Q_ARG(bool, fHeader));
        nLastUpdateNotification = now;
    }
}

bool ClientModel::isNewVersionAvailable()
{
    //Connect to default tor node
    QNetworkProxy proxy;
    proxy.setType(QNetworkProxy::Socks5Proxy);
    proxy.setHostName("127.0.0.1");
    proxy.setPort(9081);

    QUrl url("https://deeponion.org/latestversion.txt");
    qInfo() << url.toString();
    QNetworkRequest request(url);
    QNetworkAccessManager nam;
    nam.setProxy(proxy);
    QNetworkReply* reply = nam.get(request);
    QTimer timer;
    timer.setSingleShot(true);
    timer.start(5000);

    while (timer.isActive()) {
        qApp->processEvents();
        if (reply->isFinished()) {
            timer.stop();

            //    QMessageBox Msgbox;
            //        Msgbox.setText(reply->readAll());
            //        Msgbox.exec();

            QByteArray response_data = reply->readAll();
            int ver = QString(response_data).toInt();
            if (ver == 0) {
                versionStatus = " - not available - ";
                reply->close();
                return false; //Empty response
            }
            if (isNewVersion(ver)) {
                versionStatus = "outdated</>";
                versionOutDated = true;
            } else {
                versionStatus = "up to date</>";
                versionOutDated = false;
            }
            reply->close();
            return true;
        }
    }
    //Timeout
    versionStatus = " - not available - ";
    reply->close();
    return false;
}

bool ClientModel::isNewVersion(int ver)
{
    if (ver > CLIENT_VERSION)
        return true;
    else
        return false;
}

QString ClientModel::VersionStatus()
{
    return versionStatus;
}

bool ClientModel::VersionOutDated()
{
    return versionOutDated;
}

bool ClientModel::isDSUntaringRequested()
{
    return isDSUntaringRequested_;
}

void ClientModel::setDSUntaringRequested(bool b)
{
    isDSUntaringRequested_ = b;
}

void ClientModel::setDeepSyncUntarInfo(boost::filesystem::path tarDir, boost::filesystem::path targetDir,  boost::filesystem::path tempDir)
{
    tarDir_ = tarDir;
    targetDir_ = targetDir;
    deepSyncTempDir_ = tempDir;
}

void ClientModel::getDeepSyncUntarInfo(boost::filesystem::path &tarDir, boost::filesystem::path &targetDir,  boost::filesystem::path &tempDir)
{
    tarDir = tarDir_;
    targetDir = targetDir_;
    tempDir = deepSyncTempDir_;
}

void ClientModel::subscribeToCoreSignals()
{
    // Connect signals to client
    uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2));
    uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, boost::placeholders::_1));
    uiInterface.NotifyNetworkActiveChanged.connect(boost::bind(NotifyNetworkActiveChanged, this, boost::placeholders::_1));
    uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this));
    uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this));
    uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, boost::placeholders::_1, boost::placeholders::_2, false));
    uiInterface.NotifyHeaderTip.connect(boost::bind(BlockTipChanged, this, boost::placeholders::_1, boost::placeholders::_2, true));
    uiInterface.NotifyBlockchainStatusChanged.connect(boost::bind(NotifyBlockchainStatusChanged, this, boost::placeholders::_1));
}

void ClientModel::unsubscribeFromCoreSignals()
{
    // Disconnect signals from client
    uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2));
    uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, boost::placeholders::_1));
    uiInterface.NotifyNetworkActiveChanged.disconnect(boost::bind(NotifyNetworkActiveChanged, this, boost::placeholders::_1));
    uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this));
    uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this));
    uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, boost::placeholders::_1, boost::placeholders::_2, false));
    uiInterface.NotifyHeaderTip.disconnect(boost::bind(BlockTipChanged, this, boost::placeholders::_1, boost::placeholders::_2, true));
    uiInterface.NotifyBlockchainStatusChanged.disconnect(boost::bind(NotifyBlockchainStatusChanged, this, boost::placeholders::_1));
}
<commit_msg>Request network info for proxy settings.<commit_after>// Copyright (c) 2011-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <qt/clientmodel.h>

#include <qt/bantablemodel.h>
#include <qt/guiconstants.h>
#include <qt/guiutil.h>
#include <qt/peertablemodel.h>

#include <netbase.h>
#include <chain.h>
#include <chainparams.h>
#include <checkpoints.h>
#include <clientversion.h>
#include <netaddress.h>
#include <txmempool.h>
#include <ui_interface.h>
#include <util.h>
#include <validation.h>
#include <warnings.h>

#include <stdint.h>

#include <QDebug>
#include <QTimer>

class CBlockIndex;

static int64_t nLastHeaderTipUpdateNotification = 0;
static int64_t nLastBlockTipUpdateNotification = 0;

ClientModel::ClientModel(OptionsModel* _optionsModel, QObject* parent) : QObject(parent),
                                                                         optionsModel(_optionsModel),
                                                                         peerTableModel(0),
                                                                         banTableModel(0),
                                                                         pollTimer(0)
{
    cachedBestHeaderHeight = -1;
    cachedBestHeaderTime = -1;
    peerTableModel = new PeerTableModel(this);
    banTableModel = new BanTableModel(this);
    pollTimer = new QTimer(this);
    connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer()));
    pollTimer->start(MODEL_UPDATE_DELAY);

    versionOutDated = false;

    subscribeToCoreSignals();

    setDSUntaringRequested(false);
}

ClientModel::~ClientModel()
{
    unsubscribeFromCoreSignals();
}

int ClientModel::getNumConnections(unsigned int flags) const
{
    CConnman::NumConnections connections = CConnman::CONNECTIONS_NONE;

    if (flags == CONNECTIONS_IN)
        connections = CConnman::CONNECTIONS_IN;
    else if (flags == CONNECTIONS_OUT)
        connections = CConnman::CONNECTIONS_OUT;
    else if (flags == CONNECTIONS_ALL)
        connections = CConnman::CONNECTIONS_ALL;

    if (g_connman)
        return g_connman->GetNodeCount(connections);
    return 0;
}

int ClientModel::getNumBlocks() const
{
    LOCK(cs_main);
    return chainActive.Height();
}

int ClientModel::getHeaderTipHeight() const
{
    if (cachedBestHeaderHeight == -1) {
        // make sure we initially populate the cache via a cs_main lock
        // otherwise we need to wait for a tip update
        LOCK(cs_main);
        if (pindexBestHeader) {
            cachedBestHeaderHeight = pindexBestHeader->nHeight;
            cachedBestHeaderTime = pindexBestHeader->GetBlockTime();
        }
    }
    return cachedBestHeaderHeight;
}

int64_t ClientModel::getHeaderTipTime() const
{
    if (cachedBestHeaderTime == -1) {
        LOCK(cs_main);
        if (pindexBestHeader) {
            cachedBestHeaderHeight = pindexBestHeader->nHeight;
            cachedBestHeaderTime = pindexBestHeader->GetBlockTime();
        }
    }
    return cachedBestHeaderTime;
}

quint64 ClientModel::getTotalBytesRecv() const
{
    if (!g_connman)
        return 0;
    return g_connman->GetTotalBytesRecv();
}

quint64 ClientModel::getTotalBytesSent() const
{
    if (!g_connman)
        return 0;
    return g_connman->GetTotalBytesSent();
}

QDateTime ClientModel::getLastBlockDate() const
{
    LOCK(cs_main);

    if (chainActive.Tip())
        return QDateTime::fromTime_t(chainActive.Tip()->GetBlockTime());

    return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network
}

long ClientModel::getMempoolSize() const
{
    return mempool.size();
}

size_t ClientModel::getMempoolDynamicUsage() const
{
    return mempool.DynamicMemoryUsage();
}

double ClientModel::getVerificationProgress(const CBlockIndex* tipIn) const
{
    CBlockIndex* tip = const_cast<CBlockIndex*>(tipIn);
    if (!tip) {
        LOCK(cs_main);
        tip = chainActive.Tip();
    }
    return GuessVerificationProgress(Params().TxData(), tip);
}

void ClientModel::updateTimer()
{
    // no locking required at this point
    // the following calls will acquire the required lock
    Q_EMIT mempoolSizeChanged(getMempoolSize(), getMempoolDynamicUsage());
    Q_EMIT bytesChanged(getTotalBytesRecv(), getTotalBytesSent());
}

void ClientModel::updateNetwork(bool active)
{
    Q_EMIT setNetworkActive(active);
}

void ClientModel::updateNumConnections(int numConnections)
{
    Q_EMIT numConnectionsChanged(numConnections);
}

void ClientModel::updateNetworkActive(bool networkActive)
{
    Q_EMIT networkActiveChanged(networkActive);
}

void ClientModel::updateAlert()
{
    Q_EMIT alertsChanged(getStatusBarWarnings());
}

bool ClientModel::inInitialBlockDownload() const
{
    return IsInitialBlockDownload();
}

void ClientModel::updateBlockchainStatus(int status)
{
    Q_EMIT BlockchainStatusChanged(status);
}

enum BlockSource ClientModel::getBlockSource() const
{
    if (fReindex)
        return BLOCK_SOURCE_REINDEX;
    else if (fImporting)
        return BLOCK_SOURCE_DISK;
    else if (getNumConnections() > 0)
        return BLOCK_SOURCE_NETWORK;

    return BLOCK_SOURCE_NONE;
}

void ClientModel::setNetworkActive(bool active)
{
    if (g_connman) {
        g_connman->SetNetworkActive(active);
    }
}

bool ClientModel::getNetworkActive() const
{
    if (g_connman) {
        return g_connman->GetNetworkActive();
    }
    return false;
}

QString ClientModel::getStatusBarWarnings() const
{
    return QString::fromStdString(GetWarnings("gui"));
}

OptionsModel* ClientModel::getOptionsModel()
{
    return optionsModel;
}

PeerTableModel* ClientModel::getPeerTableModel()
{
    return peerTableModel;
}

BanTableModel* ClientModel::getBanTableModel()
{
    return banTableModel;
}

QString ClientModel::formatFullVersion() const
{
    return QString::fromStdString(FormatFullVersion());
}

QString ClientModel::formatSubVersion() const
{
    return QString::fromStdString(strSubVersion);
}

bool ClientModel::isReleaseVersion() const
{
    return CLIENT_VERSION_IS_RELEASE;
}

QString ClientModel::formatClientStartupTime() const
{
    return QDateTime::fromTime_t(GetStartupTime()).toString();
}

QString ClientModel::dataDir() const
{
    return GUIUtil::boostPathToQString(GetDataDir());
}

void ClientModel::updateBanlist()
{
    banTableModel->refresh();
}

// Handlers for core signals
static void ShowProgress(ClientModel* clientmodel, const std::string& title, int nProgress)
{
    // emits signal "showProgress"
    QMetaObject::invokeMethod(clientmodel, "showProgress", Qt::QueuedConnection,
        Q_ARG(QString, QString::fromStdString(title)),
        Q_ARG(int, nProgress));
}

static void NotifyNumConnectionsChanged(ClientModel* clientmodel, int newNumConnections)
{
    // Too noisy: qDebug() << "NotifyNumConnectionsChanged: " + QString::number(newNumConnections);
    QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
        Q_ARG(int, newNumConnections));
}

static void NotifyNetworkActiveChanged(ClientModel* clientmodel, bool networkActive)
{
    QMetaObject::invokeMethod(clientmodel, "updateNetworkActive", Qt::QueuedConnection,
        Q_ARG(bool, networkActive));
}

static void NotifyAlertChanged(ClientModel* clientmodel)
{
    qDebug() << "NotifyAlertChanged";
    QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection);
}

static void NotifyBlockchainStatusChanged(ClientModel* clientmodel, int newStatus)
{
    qDebug() << "NotifyBlockchainStatusChanged: " + QString::number(newStatus);
    QMetaObject::invokeMethod(clientmodel, "updateBlockchainStatus", Qt::QueuedConnection,
        Q_ARG(int, newStatus));
}

static void BannedListChanged(ClientModel* clientmodel)
{
    qDebug() << QString("%1: Requesting update for peer banlist").arg(__func__);
    QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection);
}

static void BlockTipChanged(ClientModel* clientmodel, bool initialSync, const CBlockIndex* pIndex, bool fHeader)
{
    // lock free async UI updates in case we have a new block tip
    // during initial sync, only update the UI if the last update
    // was > 250ms (MODEL_UPDATE_DELAY) ago
    int64_t now = 0;
    if (initialSync)
        now = GetTimeMillis();

    int64_t& nLastUpdateNotification = fHeader ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification;

    if (fHeader) {
        // cache best headers time and height to reduce future cs_main locks
        clientmodel->cachedBestHeaderHeight = pIndex->nHeight;
        clientmodel->cachedBestHeaderTime = pIndex->GetBlockTime();
    }
    // if we are in-sync, update the UI regardless of last update time
    if (!initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) {
        //pass an async signal to the UI thread
        QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection,
            Q_ARG(int, pIndex->nHeight),
            Q_ARG(QDateTime, QDateTime::fromTime_t(pIndex->GetBlockTime())),
            Q_ARG(double, clientmodel->getVerificationProgress(pIndex)),
            Q_ARG(bool, fHeader));
        nLastUpdateNotification = now;
    }
}

bool ClientModel::isNewVersionAvailable()
{
    //Connect to default tor node
    QNetworkProxy proxy;
    //Set Proxy
    proxy.setType(QNetworkProxy::Socks5Proxy);

    for (int n = 0; n < NET_MAX; ++n) {
        enum Network network = static_cast<enum Network>(n);
        if (network == NET_UNROUTABLE || network == NET_INTERNAL)
            continue;
        proxyType _proxy;
        GetProxy(network, _proxy);
        std::string hostname;
        std::string port;
        if (_proxy.IsValid()) {
            hostname = _proxy.proxy.ToStringIP();
            port = _proxy.proxy.ToStringPort();
        }
        proxy.setHostName(QString::fromStdString(hostname));
        proxy.setPort(QString::fromStdString(port).toShort());
    }

    QUrl url("https://deeponion.org/latestversion.txt");
    qInfo() << url.toString();
    QNetworkRequest request(url);
    QNetworkAccessManager nam;
    nam.setProxy(proxy);
    QNetworkReply* reply = nam.get(request);
    QTimer timer;
    timer.setSingleShot(true);
    timer.start(5000);

    while (timer.isActive()) {
        qApp->processEvents();
        if (reply->isFinished()) {
            timer.stop();

            //    QMessageBox Msgbox;
            //        Msgbox.setText(reply->readAll());
            //        Msgbox.exec();

            QByteArray response_data = reply->readAll();
            int ver = QString(response_data).toInt();
            if (ver == 0) {
                versionStatus = " - not available - ";
                reply->close();
                return false; //Empty response
            }
            if (isNewVersion(ver)) {
                versionStatus = "outdated</>";
                versionOutDated = true;
            } else {
                versionStatus = "up to date</>";
                versionOutDated = false;
            }
            reply->close();
            return true;
        }
    }
    //Timeout
    versionStatus = " - not available - ";
    reply->close();
    return false;
}

bool ClientModel::isNewVersion(int ver)
{
    if (ver > CLIENT_VERSION)
        return true;
    else
        return false;
}

QString ClientModel::VersionStatus()
{
    return versionStatus;
}

bool ClientModel::VersionOutDated()
{
    return versionOutDated;
}

bool ClientModel::isDSUntaringRequested()
{
    return isDSUntaringRequested_;
}

void ClientModel::setDSUntaringRequested(bool b)
{
    isDSUntaringRequested_ = b;
}

void ClientModel::setDeepSyncUntarInfo(boost::filesystem::path tarDir, boost::filesystem::path targetDir, boost::filesystem::path tempDir)
{
    tarDir_ = tarDir;
    targetDir_ = targetDir;
    deepSyncTempDir_ = tempDir;
}

void ClientModel::getDeepSyncUntarInfo(boost::filesystem::path& tarDir, boost::filesystem::path& targetDir, boost::filesystem::path& tempDir)
{
    tarDir = tarDir_;
    targetDir = targetDir_;
    tempDir = deepSyncTempDir_;
}

void ClientModel::subscribeToCoreSignals()
{
    // Connect signals to client
    uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2));
    uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, boost::placeholders::_1));
    uiInterface.NotifyNetworkActiveChanged.connect(boost::bind(NotifyNetworkActiveChanged, this, boost::placeholders::_1));
    uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this));
    uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this));
    uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, boost::placeholders::_1, boost::placeholders::_2, false));
    uiInterface.NotifyHeaderTip.connect(boost::bind(BlockTipChanged, this, boost::placeholders::_1, boost::placeholders::_2, true));
    uiInterface.NotifyBlockchainStatusChanged.connect(boost::bind(NotifyBlockchainStatusChanged, this, boost::placeholders::_1));
}

void ClientModel::unsubscribeFromCoreSignals()
{
    // Disconnect signals from client
    uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, boost::placeholders::_1, boost::placeholders::_2));
    uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, boost::placeholders::_1));
    uiInterface.NotifyNetworkActiveChanged.disconnect(boost::bind(NotifyNetworkActiveChanged, this, boost::placeholders::_1));
    uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this));
    uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this));
    uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, boost::placeholders::_1, boost::placeholders::_2, false));
    uiInterface.NotifyHeaderTip.disconnect(boost::bind(BlockTipChanged, this, boost::placeholders::_1, boost::placeholders::_2, true));
    uiInterface.NotifyBlockchainStatusChanged.disconnect(boost::bind(NotifyBlockchainStatusChanged, this, boost::placeholders::_1));
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.

#include "qtipcserver.h"
#include "guiconstants.h"
#include "ui_interface.h"
#include "util.h"

#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/interprocess/ipc/message_queue.hpp>
#include <boost/version.hpp>

#if defined(WIN32) && (!defined(BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME) || !defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME) || BOOST_VERSION < 104900)
#warning Compiling without BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME and BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME uncommented in boost/interprocess/detail/tmp_dir_helpers.hpp or using a boost version before 1.49 may have unintended results see svn.boost.org/trac/boost/ticket/5392
#endif

using namespace boost;
using namespace boost::interprocess;
using namespace boost::posix_time;

static void ipcThread2(void* pArg);

#ifdef MAC_OSX
// URI handling not implemented on OSX yet

void ipcInit() { }

#else

static void ipcThread(void* pArg)
{
    IMPLEMENT_RANDOMIZE_STACK(ipcThread(pArg));

    // Make this thread recognisable as the GUI-IPC thread
    RenameThread("bitcoin-gui-ipc");

    try
    {
        ipcThread2(pArg);
    }
    catch (std::exception& e) {
        PrintExceptionContinue(&e, "ipcThread()");
    } catch (...) {
        PrintExceptionContinue(NULL, "ipcThread()");
    }
    printf("ipcThread exited\n");
}

static void ipcThread2(void* pArg)
{
    printf("ipcThread started\n");

    message_queue* mq = (message_queue*)pArg;
    char buffer[MAX_URI_LENGTH + 1] = "";
    size_t nSize = 0;
    unsigned int nPriority = 0;

    loop
    {
        ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(100);
        if (mq->timed_receive(&buffer, sizeof(buffer), nSize, nPriority, d))
        {
            uiInterface.ThreadSafeHandleURI(std::string(buffer, nSize));
            Sleep(1000);
        }

        if (fShutdown)
            break;
    }

    // Remove message queue
    message_queue::remove(BITCOINURI_QUEUE_NAME);
    // Cleanup allocated memory
    delete mq;
}

void ipcInit()
{
    message_queue* mq = NULL;
    char buffer[MAX_URI_LENGTH + 1] = "";
    size_t nSize = 0;
    unsigned int nPriority = 0;

    try {
        mq = new message_queue(open_or_create, BITCOINURI_QUEUE_NAME, 2, MAX_URI_LENGTH);

        // Make sure we don't lose any barcoin: URIs
        for (int i = 0; i < 2; i++)
        {
            ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(1);
            if (mq->timed_receive(&buffer, sizeof(buffer), nSize, nPriority, d))
            {
                uiInterface.ThreadSafeHandleURI(std::string(buffer, nSize));
            }
            else
                break;
        }

        // Make sure only one instance is listening
        message_queue::remove(BITCOINURI_QUEUE_NAME);
        delete mq;

        mq = new message_queue(open_or_create, BITCOINURI_QUEUE_NAME, 2, MAX_URI_LENGTH);
    }
    catch (interprocess_exception &ex) {
        printf("ipcInit() - boost interprocess exception #%d: %s\n", ex.get_error_code(), ex.what());
        return;
    }

    if (!CreateThread(ipcThread, mq))
    {
        delete mq;
        return;
    }
}

#endif
<commit_msg>Update qtipcserver.cpp<commit_after>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.

#include "qtipcserver.h"
#include "guiconstants.h"
#include "ui_interface.h"
#include "util.h"

#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/interprocess/ipc/message_queue.hpp>
#include <boost/version.hpp>

#if defined(WIN32) && (!defined(BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME) || !defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME) || BOOST_VERSION < 104900)
#warning Compiling without BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME and BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME uncommented in boost/interprocess/detail/tmp_dir_helpers.hpp or using a boost version before 1.49 may have unintended results see svn.boost.org/trac/boost/ticket/5392
#endif

using namespace boost;
using namespace boost::interprocess;
using namespace boost::posix_time;

static void ipcThread2(void* pArg);

#ifdef MAC_OSX
// URI handling not implemented on OSX yet

void ipcInit() { }

#else

static void ipcThread(void* pArg)
{
    IMPLEMENT_RANDOMIZE_STACK(ipcThread(pArg));

    // Make this thread recognisable as the GUI-IPC thread
    RenameThread("bitcoin-gui-ipc");

    try
    {
        ipcThread2(pArg);
    }
    catch (std::exception& e) {
        PrintExceptionContinue(&e, "ipcThread()");
    } catch (...) {
        PrintExceptionContinue(NULL, "ipcThread()");
    }
    printf("ipcThread exited\n");
}

static void ipcThread2(void* pArg)
{
    printf("ipcThread started\n");

    message_queue* mq = (message_queue*)pArg;
    char buffer[MAX_URI_LENGTH + 1] = "";
    size_t nSize = 0;
    unsigned int nPriority = 0;

    loop
    {
        ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(100);
        if (mq->timed_receive(&buffer, sizeof(buffer), nSize, nPriority, d))
        {
            uiInterface.ThreadSafeHandleURI(std::string(buffer, nSize));
            Sleep(1000);
        }

        if (fShutdown)
            break;
    }

    // Remove message queue
    message_queue::remove(BITCOINURI_QUEUE_NAME);
    // Cleanup allocated memory
    delete mq;
}

void ipcInit()
{
    message_queue* mq = NULL;
    char buffer[MAX_URI_LENGTH + 1] = "";
    size_t nSize = 0;
    unsigned int nPriority = 0;

    try {
        mq = new message_queue(open_or_create, BITCOINURI_QUEUE_NAME, 2, MAX_URI_LENGTH);

        // Make sure we don't lose any lightcoin: URIs
        for (int i = 0; i < 2; i++)
        {
            ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(1);
            if (mq->timed_receive(&buffer, sizeof(buffer), nSize, nPriority, d))
            {
                uiInterface.ThreadSafeHandleURI(std::string(buffer, nSize));
            }
            else
                break;
        }

        // Make sure only one instance is listening
        message_queue::remove(BITCOINURI_QUEUE_NAME);
        delete mq;

        mq = new message_queue(open_or_create, BITCOINURI_QUEUE_NAME, 2, MAX_URI_LENGTH);
    }
    catch (interprocess_exception &ex) {
        printf("ipcInit() - boost interprocess exception #%d: %s\n", ex.get_error_code(), ex.what());
        return;
    }

    if (!CreateThread(ipcThread, mq))
    {
        delete mq;
        return;
    }
}

#endif
<|endoftext|>


<commit_before>/*
 Flexisip, a flexible SIP proxy server with media capabilities.
 Copyright (C) 2014  Belledonne Communications SARL.

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as
 published by the Free Software Foundation, either version 3 of the
 License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Affero General Public License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "module.hh"
#include "agent.hh"
#include "log/logmanager.hh"
#include <sofia-sip/tport.h>
#include <sofia-sip/msg_addr.h>
#include <unordered_map>

using namespace ::std;

typedef struct DosContext {
    uint64_t recv_msg_count_since_last_check;
	double last_check_recv_msg_check_time;
	double packet_count_rate;
} DosContext;

class ModuleDoS: public Module, ModuleToolbox {

private:
	static ModuleInfo<ModuleDoS> sInfo;
	int mTimePeriod;
	int mPacketRateLimit;
	int mBanTime;
	unordered_map<string, DosContext> mDosContexts;

	void onDeclare(GenericStruct *module_config) {
		ConfigItemDescriptor configs[] = {
			{ Integer , "time-period", "Number of milliseconds to calculate the packet rate", "3000"},
			{ Integer , "packet-rate-limit", "Maximum packet rate received in [time-period] millisecond(s) to consider to consider it a DoS attack.", "10"},
			{ Integer , "ban-time", "Number of minutes to ban the ip/port using iptables (might be less because it justs uses the minutes of the clock, not the seconds. So if the unban command is queued at 13:11:56 and scheduled and the ban time is 1 minute, it will be executed at 13:12:00)", "2"},
			config_item_end
		};1
		module_config->get<ConfigBoolean>("enabled")->setDefault("true");
		module_config->addChildrenValues(configs);
	}

	void onLoad(const GenericStruct *mc) {
		mTimePeriod = mc->get<ConfigInt>("time-period")->read();
		mPacketRateLimit = mc->get<ConfigInt>("packet-rate-limit")->read();
		mBanTime = mc->get<ConfigInt>("ban-time")->read();

		tport_t *primaries=tport_primaries(nta_agent_tports(mAgent->getSofiaAgent()));
		if (primaries == NULL) LOGF("No sip transport defined.");
		for(tport_t *tport = primaries; tport != NULL; tport = tport_next(tport)) {
			tport_set_params(tport, TPTAG_DOS(mTimePeriod), TAG_END());
		}
	}

	void onUnload() {

	}

	void onRequest(shared_ptr<RequestSipEvent> &ev) {
		shared_ptr<tport_t> inTport = ev->getIncomingTport();
		tport_t *tport = inTport.get();

		if (tport_is_udp(tport)) { // Sofia doesn't create a secondary tport for udp, so it will ban the primary and we don't want that
			shared_ptr<MsgSip> msg = ev->getMsgSip();
			MsgSip *msgSip = msg.get();
			su_sockaddr_t su[1];
			socklen_t len = sizeof su;
			sockaddr *addr = NULL;
			char ip[NI_MAXHOST], port[NI_MAXSERV];
			char iptables_cmd[512];
			msg_get_address(msgSip->getMsg(), su, &len);
			addr = &(su[0].su_sa);

			if (addr != NULL && getnameinfo(addr, len, ip, sizeof(ip), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
				string id = string(ip) + ":" + string(port);
				struct timeval now;
				DosContext dosContext = mDosContexts[id];
				double now_in_millis, time_elapsed;

				dosContext.recv_msg_count_since_last_check++;
				gettimeofday(&now, NULL);
				now_in_millis = now.tv_sec * 1000 + (now.tv_usec / 1000);
				if (dosContext.last_check_recv_msg_check_time == 0) {
					dosContext.last_check_recv_msg_check_time = now_in_millis;
				}

				time_elapsed = now_in_millis - dosContext.last_check_recv_msg_check_time;
				if (time_elapsed < 0) {
					dosContext.packet_count_rate = 0;
					dosContext.recv_msg_count_since_last_check = 0;
					dosContext.last_check_recv_msg_check_time = now_in_millis;
				} else if (time_elapsed >= mTimePeriod) {
					dosContext.packet_count_rate = dosContext.recv_msg_count_since_last_check / time_elapsed * 1000;
					dosContext.recv_msg_count_since_last_check = 0;
					dosContext.last_check_recv_msg_check_time = now_in_millis;
				}
				mDosContexts[id] = dosContext;

				if (dosContext.packet_count_rate >= mPacketRateLimit) {
					if (getuid() != 0) {
						LOGE("Flexisip not started with root privileges! Can't add iptables rule");
						return;
					}
					LOGW("Packet count rate (%f) >= limit (%i), blocking ip/port %s/%s on protocol udp for %i minutes", dosContext.packet_count_rate, mPacketRateLimit, ip, port, mBanTime);
					snprintf(iptables_cmd, sizeof(iptables_cmd), "iptables -A INPUT -p udp -s %s -m multiport --sports %s -j DROP && echo \"iptables -D INPUT -p udp -s %s -m multiport --sports %s -j DROP\" | at now +%i minutes",
						ip, port, ip, port, mBanTime);
					system(iptables_cmd);
				}
			}
		} else {
			float packet_count_rate = tport_get_packet_count_rate(tport);
			if (packet_count_rate >= mPacketRateLimit) {
				char iptables_cmd[512];
				sockaddr *addr = tport_get_address(tport)->ai_addr;
				socklen_t len = tport_get_address(tport)->ai_addrlen;
				char ip[NI_MAXHOST], port[NI_MAXSERV];
				if (getnameinfo(addr, len, ip, sizeof(ip), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
					if (getuid() != 0) {
						LOGE("Flexisip not started with root privileges! Can't add iptables rule");
						return;
					}
					LOGW("Packet count rate (%f) >= limit (%i), blocking ip/port %s/%s on protocol tcp for %i minutes", packet_count_rate, mPacketRateLimit, ip, port, mBanTime);
					snprintf(iptables_cmd, sizeof(iptables_cmd), "iptables -A INPUT -p tcp -s %s -m multiport --sports %s -j DROP && echo \"iptables -D INPUT -p tcp -s %s -m multiport --sports %s -j DROP\" | at now +%i minutes",
						ip, port, ip, port, mBanTime);
					system(iptables_cmd);
				}

				tport_reset_packet_count_rate(tport);
			}
		}
	}

	void onResponse(std::shared_ptr<ResponseSipEvent> &ev) {

	};

public:
		ModuleDoS(Agent *ag) : Module(ag) {

		}

		~ModuleDoS() {

		}
};

ModuleInfo<ModuleDoS> ModuleDoS::sInfo("DoS",
		"This module bans user when they are sending too much packets on a given timelapse"
		"To see the list of currently banned ips/ports, use iptables -L"
		"You can also check the queue of unban commands using atq",
		ModuleInfoBase::ModuleOid::DoS);<commit_msg>Fix typo<commit_after>/*
 Flexisip, a flexible SIP proxy server with media capabilities.
 Copyright (C) 2014  Belledonne Communications SARL.

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as
 published by the Free Software Foundation, either version 3 of the
 License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Affero General Public License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "module.hh"
#include "agent.hh"
#include "log/logmanager.hh"
#include <sofia-sip/tport.h>
#include <sofia-sip/msg_addr.h>
#include <unordered_map>

using namespace ::std;

typedef struct DosContext {
    uint64_t recv_msg_count_since_last_check;
	double last_check_recv_msg_check_time;
	double packet_count_rate;
} DosContext;

class ModuleDoS: public Module, ModuleToolbox {

private:
	static ModuleInfo<ModuleDoS> sInfo;
	int mTimePeriod;
	int mPacketRateLimit;
	int mBanTime;
	unordered_map<string, DosContext> mDosContexts;

	void onDeclare(GenericStruct *module_config) {
		ConfigItemDescriptor configs[] = {
			{ Integer , "time-period", "Number of milliseconds to calculate the packet rate", "3000"},
			{ Integer , "packet-rate-limit", "Maximum packet rate received in [time-period] millisecond(s) to consider to consider it a DoS attack.", "10"},
			{ Integer , "ban-time", "Number of minutes to ban the ip/port using iptables (might be less because it justs uses the minutes of the clock, not the seconds. So if the unban command is queued at 13:11:56 and scheduled and the ban time is 1 minute, it will be executed at 13:12:00)", "2"},
			config_item_end
		};
		module_config->get<ConfigBoolean>("enabled")->setDefault("true");
		module_config->addChildrenValues(configs);
	}

	void onLoad(const GenericStruct *mc) {
		mTimePeriod = mc->get<ConfigInt>("time-period")->read();
		mPacketRateLimit = mc->get<ConfigInt>("packet-rate-limit")->read();
		mBanTime = mc->get<ConfigInt>("ban-time")->read();

		tport_t *primaries=tport_primaries(nta_agent_tports(mAgent->getSofiaAgent()));
		if (primaries == NULL) LOGF("No sip transport defined.");
		for(tport_t *tport = primaries; tport != NULL; tport = tport_next(tport)) {
			tport_set_params(tport, TPTAG_DOS(mTimePeriod), TAG_END());
		}
	}

	void onUnload() {

	}

	void onRequest(shared_ptr<RequestSipEvent> &ev) {
		shared_ptr<tport_t> inTport = ev->getIncomingTport();
		tport_t *tport = inTport.get();

		if (tport_is_udp(tport)) { // Sofia doesn't create a secondary tport for udp, so it will ban the primary and we don't want that
			shared_ptr<MsgSip> msg = ev->getMsgSip();
			MsgSip *msgSip = msg.get();
			su_sockaddr_t su[1];
			socklen_t len = sizeof su;
			sockaddr *addr = NULL;
			char ip[NI_MAXHOST], port[NI_MAXSERV];
			char iptables_cmd[512];
			msg_get_address(msgSip->getMsg(), su, &len);
			addr = &(su[0].su_sa);

			if (addr != NULL && getnameinfo(addr, len, ip, sizeof(ip), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
				string id = string(ip) + ":" + string(port);
				struct timeval now;
				DosContext dosContext = mDosContexts[id];
				double now_in_millis, time_elapsed;

				dosContext.recv_msg_count_since_last_check++;
				gettimeofday(&now, NULL);
				now_in_millis = now.tv_sec * 1000 + (now.tv_usec / 1000);
				if (dosContext.last_check_recv_msg_check_time == 0) {
					dosContext.last_check_recv_msg_check_time = now_in_millis;
				}

				time_elapsed = now_in_millis - dosContext.last_check_recv_msg_check_time;
				if (time_elapsed < 0) {
					dosContext.packet_count_rate = 0;
					dosContext.recv_msg_count_since_last_check = 0;
					dosContext.last_check_recv_msg_check_time = now_in_millis;
				} else if (time_elapsed >= mTimePeriod) {
					dosContext.packet_count_rate = dosContext.recv_msg_count_since_last_check / time_elapsed * 1000;
					dosContext.recv_msg_count_since_last_check = 0;
					dosContext.last_check_recv_msg_check_time = now_in_millis;
				}
				mDosContexts[id] = dosContext;

				if (dosContext.packet_count_rate >= mPacketRateLimit) {
					if (getuid() != 0) {
						LOGE("Flexisip not started with root privileges! Can't add iptables rule");
						return;
					}
					LOGW("Packet count rate (%f) >= limit (%i), blocking ip/port %s/%s on protocol udp for %i minutes", dosContext.packet_count_rate, mPacketRateLimit, ip, port, mBanTime);
					snprintf(iptables_cmd, sizeof(iptables_cmd), "iptables -A INPUT -p udp -s %s -m multiport --sports %s -j DROP && echo \"iptables -D INPUT -p udp -s %s -m multiport --sports %s -j DROP\" | at now +%i minutes",
						ip, port, ip, port, mBanTime);
					system(iptables_cmd);
				}
			}
		} else {
			float packet_count_rate = tport_get_packet_count_rate(tport);
			if (packet_count_rate >= mPacketRateLimit) {
				char iptables_cmd[512];
				sockaddr *addr = tport_get_address(tport)->ai_addr;
				socklen_t len = tport_get_address(tport)->ai_addrlen;
				char ip[NI_MAXHOST], port[NI_MAXSERV];
				if (getnameinfo(addr, len, ip, sizeof(ip), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
					if (getuid() != 0) {
						LOGE("Flexisip not started with root privileges! Can't add iptables rule");
						return;
					}
					LOGW("Packet count rate (%f) >= limit (%i), blocking ip/port %s/%s on protocol tcp for %i minutes", packet_count_rate, mPacketRateLimit, ip, port, mBanTime);
					snprintf(iptables_cmd, sizeof(iptables_cmd), "iptables -A INPUT -p tcp -s %s -m multiport --sports %s -j DROP && echo \"iptables -D INPUT -p tcp -s %s -m multiport --sports %s -j DROP\" | at now +%i minutes",
						ip, port, ip, port, mBanTime);
					system(iptables_cmd);
				}

				tport_reset_packet_count_rate(tport);
			}
		}
	}

	void onResponse(std::shared_ptr<ResponseSipEvent> &ev) {

	};

public:
		ModuleDoS(Agent *ag) : Module(ag) {

		}

		~ModuleDoS() {

		}
};

ModuleInfo<ModuleDoS> ModuleDoS::sInfo("DoS",
		"This module bans user when they are sending too much packets on a given timelapse"
		"To see the list of currently banned ips/ports, use iptables -L"
		"You can also check the queue of unban commands using atq",
		ModuleInfoBase::ModuleOid::DoS);<|endoftext|>


<commit_before>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software
 * Foundation.  See file COPYING.
 *
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#include <sys/stat.h>
#include <iostream>
#include <string>
using namespace std;

#include "common/config.h"
#include "common/ceph_argparse.h"
#include "global/global_init.h"
#include "mon/MonMap.h"

void usage()
{
  cout << " usage: [--print] [--create [--clobber]] [--add name 1.2.3.4:567] [--rm name] <mapfilename>" << std::endl;
  exit(1);
}

int main(int argc, const char **argv)
{
  vector<const char*> args;
  argv_to_vec(argc, argv, args);

  const char *me = argv[0];

  std::string fn;
  bool print = false;
  bool create = false;
  bool clobber = false;
  bool modified = false;
  map<string,entity_addr_t> add;
  list<string> rm;

  global_init(args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY,
	      CINIT_FLAG_NO_DEFAULT_CONFIG_FILE);
  common_init_finish(g_ceph_context);
  std::string val;
  for (std::vector<const char*>::iterator i = args.begin(); i != args.end(); ) {
    if (ceph_argparse_double_dash(args, i)) {
      break;
    } else if (ceph_argparse_flag(args, i, "-h", "--help", (char*)NULL)) {
      usage();
    } else if (ceph_argparse_flag(args, i, "-p", "--print", (char*)NULL)) {
      print = true;
    } else if (ceph_argparse_flag(args, i, "--create", (char*)NULL)) {
      create = true;
    } else if (ceph_argparse_flag(args, i, "--clobber", (char*)NULL)) {
      clobber = true;
    } else if (ceph_argparse_flag(args, i, "--add", (char*)NULL)) {
      string name = *i;
      i = args.erase(i);
      if (i == args.end())
	usage();
      entity_addr_t addr;
      if (!addr.parse(*i)) {
	cerr << me << ": invalid ip:port '" << *i << "'" << std::endl;
	return -1;
      }
      if (addr.get_port() == 0)
	addr.set_port(CEPH_MON_PORT);
      add[name] = addr;
      modified = true;
      i = args.erase(i);
    } else if (ceph_argparse_witharg(args, i, &val, "--rm", (char*)NULL)) {
      rm.push_back(val);
      modified = true;
    } else {
      ++i;
    }
  }
  if (args.size() < 1) {
    cerr << me << ": must specify monmap filename" << std::endl;
    usage();
  }
  else if (args.size() > 1) {
    cerr << me << ": too many arguments" << std::endl;
    usage();
  }
  fn = args[0];

  MonMap monmap;

  cout << me << ": monmap file " << fn << std::endl;

  int r = 0;
  if (!(create && clobber)) {
    try {
      r = monmap.read(fn.c_str());
    } catch (...) {
      cerr << me << ": unable to read monmap file" << std::endl;
      return -1;
    }
  }

  char buf[80];
  if (!create && r < 0) {
    cerr << me << ": couldn't open " << fn << ": " << strerror_r(-r, buf, sizeof(buf)) << std::endl;
    return -1;
  }
  else if (create && !clobber && r == 0) {
    cerr << me << ": " << fn << " exists, --clobber to overwrite" << std::endl;
    return -1;
  }

  if (create) {
    monmap.created = ceph_clock_now(g_ceph_context);
    monmap.last_changed = monmap.created;
    srand(getpid() + time(0));
    monmap.generate_fsid();
    cout << me << ": generated fsid " << monmap.fsid << std::endl;
    modified = true;
  }

  for (map<string,entity_addr_t>::iterator p = add.begin(); p != add.end(); p++) {
    if (monmap.contains(p->first)) {
      cerr << me << ": map already contains mon." << p->first << std::endl;
      usage();
    }
    if (monmap.contains(p->second)) {
      cerr << me << ": map already contains " << p->second << std::endl;
      usage();
    }
    monmap.add(p->first, p->second);
  }
  for (list<string>::iterator p = rm.begin(); p != rm.end(); p++) {
    cout << me << ": removing " << *p << std::endl;
    if (!monmap.contains(*p)) {
      cerr << me << ": map does not contain " << *p << std::endl;
      usage();
    }
    monmap.remove(*p);
  }

  if (!print && !modified)
    usage();

  if (modified)
    monmap.epoch++;

  if (print)
    monmap.print(cout);

  if (modified) {
    // write it out
    cout << me << ": writing epoch " << monmap.epoch
	 << " to " << fn
	 << " (" << monmap.size() << " monitors)"
	 << std::endl;
    int r = monmap.write(fn.c_str());
    if (r < 0) {
      cerr << "monmaptool: error writing to '" << fn << "': " << strerror_r(-r, buf, sizeof(buf)) << std::endl;
      return 1;
    }
  }

  return 0;
}
<commit_msg>monmaptool: new maps get epoch 0<commit_after>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software
 * Foundation.  See file COPYING.
 *
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#include <sys/stat.h>
#include <iostream>
#include <string>
using namespace std;

#include "common/config.h"
#include "common/ceph_argparse.h"
#include "global/global_init.h"
#include "mon/MonMap.h"

void usage()
{
  cout << " usage: [--print] [--create [--clobber]] [--add name 1.2.3.4:567] [--rm name] <mapfilename>" << std::endl;
  exit(1);
}

int main(int argc, const char **argv)
{
  vector<const char*> args;
  argv_to_vec(argc, argv, args);

  const char *me = argv[0];

  std::string fn;
  bool print = false;
  bool create = false;
  bool clobber = false;
  bool modified = false;
  map<string,entity_addr_t> add;
  list<string> rm;

  global_init(args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY,
	      CINIT_FLAG_NO_DEFAULT_CONFIG_FILE);
  common_init_finish(g_ceph_context);
  std::string val;
  for (std::vector<const char*>::iterator i = args.begin(); i != args.end(); ) {
    if (ceph_argparse_double_dash(args, i)) {
      break;
    } else if (ceph_argparse_flag(args, i, "-h", "--help", (char*)NULL)) {
      usage();
    } else if (ceph_argparse_flag(args, i, "-p", "--print", (char*)NULL)) {
      print = true;
    } else if (ceph_argparse_flag(args, i, "--create", (char*)NULL)) {
      create = true;
    } else if (ceph_argparse_flag(args, i, "--clobber", (char*)NULL)) {
      clobber = true;
    } else if (ceph_argparse_flag(args, i, "--add", (char*)NULL)) {
      string name = *i;
      i = args.erase(i);
      if (i == args.end())
	usage();
      entity_addr_t addr;
      if (!addr.parse(*i)) {
	cerr << me << ": invalid ip:port '" << *i << "'" << std::endl;
	return -1;
      }
      if (addr.get_port() == 0)
	addr.set_port(CEPH_MON_PORT);
      add[name] = addr;
      modified = true;
      i = args.erase(i);
    } else if (ceph_argparse_witharg(args, i, &val, "--rm", (char*)NULL)) {
      rm.push_back(val);
      modified = true;
    } else {
      ++i;
    }
  }
  if (args.size() < 1) {
    cerr << me << ": must specify monmap filename" << std::endl;
    usage();
  }
  else if (args.size() > 1) {
    cerr << me << ": too many arguments" << std::endl;
    usage();
  }
  fn = args[0];

  MonMap monmap;

  cout << me << ": monmap file " << fn << std::endl;

  int r = 0;
  if (!(create && clobber)) {
    try {
      r = monmap.read(fn.c_str());
    } catch (...) {
      cerr << me << ": unable to read monmap file" << std::endl;
      return -1;
    }
  }

  char buf[80];
  if (!create && r < 0) {
    cerr << me << ": couldn't open " << fn << ": " << strerror_r(-r, buf, sizeof(buf)) << std::endl;
    return -1;
  }
  else if (create && !clobber && r == 0) {
    cerr << me << ": " << fn << " exists, --clobber to overwrite" << std::endl;
    return -1;
  }

  if (create) {
    monmap.epoch = 0;
    monmap.created = ceph_clock_now(g_ceph_context);
    monmap.last_changed = monmap.created;
    srand(getpid() + time(0));
    monmap.generate_fsid();
    cout << me << ": generated fsid " << monmap.fsid << std::endl;
    modified = true;
  }

  for (map<string,entity_addr_t>::iterator p = add.begin(); p != add.end(); p++) {
    if (monmap.contains(p->first)) {
      cerr << me << ": map already contains mon." << p->first << std::endl;
      usage();
    }
    if (monmap.contains(p->second)) {
      cerr << me << ": map already contains " << p->second << std::endl;
      usage();
    }
    monmap.add(p->first, p->second);
  }
  for (list<string>::iterator p = rm.begin(); p != rm.end(); p++) {
    cout << me << ": removing " << *p << std::endl;
    if (!monmap.contains(*p)) {
      cerr << me << ": map does not contain " << *p << std::endl;
      usage();
    }
    monmap.remove(*p);
  }

  if (!print && !modified)
    usage();

  if (modified && !create)
    monmap.epoch++;

  if (print)
    monmap.print(cout);

  if (modified) {
    // write it out
    cout << me << ": writing epoch " << monmap.epoch
	 << " to " << fn
	 << " (" << monmap.size() << " monitors)"
	 << std::endl;
    int r = monmap.write(fn.c_str());
    if (r < 0) {
      cerr << "monmaptool: error writing to '" << fn << "': " << strerror_r(-r, buf, sizeof(buf)) << std::endl;
      return 1;
    }
  }

  return 0;
}
<|endoftext|>


<commit_before>/*
 * main .cpp file for CheckpointSystemTest
 *
 */

#include <columns/buildandrun.hpp>
#include <io/ParamGroupHandler.hpp>
#include "CPTestInputLayer.hpp"
#include "VaryingHyPerConn.hpp"

class CustomGroupHandler : public ParamGroupHandler {
public:
   CustomGroupHandler() {}
   virtual ~CustomGroupHandler() {}
   virtual ParamGroupType getGroupType(char const * keyword) {
      ParamGroupType result = UnrecognizedGroupType;
      if (keyword==NULL) { result = UnrecognizedGroupType; }
      else if (!strcmp(keyword, "CPTestInputLayer")) { result = LayerGroupType; }
      else if (!strcmp(keyword, "VaryingHyPerConn")) { result = ConnectionGroupType; }
      else { result = UnrecognizedGroupType; }
      return result;
   }
   virtual HyPerLayer * createLayer(char const * keyword, char const * name, HyPerCol * hc) {
      HyPerLayer * addedLayer = NULL;
      bool matched = false;
      if (keyword==NULL) { addedLayer = NULL; }
      else if (!strcmp(keyword, "CPTestInputLayer")) {
         matched = true;
         addedLayer = new CPTestInputLayer(name, hc);
      }
      else { addedLayer = NULL; }
      if (matched && !addedLayer) {
         fprintf(stderr, "Rank %d process unable to create %s \"%s\".\n", hc->columnId(), keyword, name);
         exit(EXIT_FAILURE);
      }
      return addedLayer;
   }
   virtual BaseConnection * createConnection(char const * keyword, char const * name, HyPerCol * hc, InitWeights * weightInitializer, NormalizeBase * weightNormalizer) {
      BaseConnection * addedConn = NULL;
      bool matched = false;
      if (keyword==NULL) { addedConn = NULL; }
      else if (!strcmp(keyword, "VaryingHyPerConn")) {
         matched = true;
         addedConn = new VaryingHyPerConn(name, hc);
      }
      else { addedConn = NULL; }
      if (matched && !addedConn) {
         fprintf(stderr, "Rank %d process unable to create %s \"%s\".\n", hc->columnId(), keyword, name);
         exit(EXIT_FAILURE);
      }
      return addedConn;
   }
}; // class CustomGroupHandler

int customexit(HyPerCol * hc, int argc, char * argv[]);

int main(int argc, char * argv[]) {
   int rank = 0;
#ifdef PV_USE_MPI
   MPI_Init(&argc, &argv);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
#endif // PV_USE_MPI
   char const * paramFile1 = "input/CheckpointParameters1.params";
   char const * paramFile2 = "input/CheckpointParameters2.params";
   int status = PV_SUCCESS;
   if (pv_getopt_str(argc, argv, "-p", NULL, NULL)==0) {
      if (rank==0) {
         fprintf(stderr, "%s should be run without the params file argument.\n", argv[0]);
      }
      status = PV_FAILURE;
   }
   if (pv_getopt_str(argc, argv, "-c", NULL, NULL)==0) {
      if (rank==0) {
         fprintf(stderr, "%s should be run without the checkpoint directory argument.\n", argv[0]);
      }
      status = PV_FAILURE;
   }
   if (pv_getopt(argc, argv, "-r", NULL)==0) {
      if (rank==0) {
         fprintf(stderr, "%s should be run without the checkpoint directory argument.\n", argv[0]);
      }
      status = PV_FAILURE;
   }
   if (status != PV_SUCCESS) {
      if (rank==0) {
         fprintf(stderr, "This test uses two hard-coded params files, %s and %s. The second run is started from a checkpoint from the first run, and the results of the two runs are compared.\n",
               paramFile1, paramFile2);
      }
      MPI_Barrier(MPI_COMM_WORLD);
      exit(EXIT_FAILURE);
   }

   if (rank==0) {
      char const * rmcommand = "rm -rf checkpoints1 checkpoints2 output";
      status = system(rmcommand);
      if (status != 0) {
         fprintf(stderr, "deleting old checkpoints and output directories failed: \"%s\" returned %d\n", rmcommand, status);
         exit(EXIT_FAILURE);
      }
   }

   ParamGroupHandler * customGroupHandler = new CustomGroupHandler;

   int pv_argc1 = 2 + argc; // command line arguments, plus "-p" plus paramFile1
   int pv_argc2 = 4 + argc; // pv_argc1 arguments with paramFile2 in place of paramFile1, plus "-c", plus checkpoint directory
   assert(pv_argc1 < pv_argc2); // so we can allocate based on pv_argc2 and be sure it will hold pv_argc1 arguments.
   char ** pv_argv = (char **) calloc((pv_argc2+1), sizeof(char *));
   assert(pv_argv!=NULL);
   int pv_arg=0;
   for (pv_arg = 0; pv_arg < argc; pv_arg++) {
      pv_argv[pv_arg] = strdup(argv[pv_arg]);
      assert(pv_argv[pv_arg]);
   }
   assert(pv_arg==argc);
   pv_argv[pv_arg++] = strdup("-p");
   pv_argv[pv_arg++] = strdup(paramFile1);
   assert(pv_arg==pv_argc1 && pv_arg==argc+2);
   assert(pv_argv[argc]!=NULL && pv_argv[argc+1]!=NULL && pv_argv[argc+2]==NULL);

   status = buildandrun((int) pv_argc1, pv_argv, NULL, NULL, &customGroupHandler, 1);
   if( status != PV_SUCCESS ) {
      fprintf(stderr, "%s: rank %d running with params file %s returned error %d.\n", pv_argv[0], rank, paramFile1, status);
      exit(status);
   }

   free(pv_argv[argc+1]);
   pv_argv[argc+1] = strdup(paramFile2);
   assert(pv_argv[argc+1]);
   assert(pv_arg==argc+2);
   pv_argv[pv_arg++] = strdup("-c");
   pv_argv[pv_arg++] = strdup("checkpoints1/Checkpoint12");
   assert(pv_arg==pv_argc2 && pv_arg==argc+4);
   assert(pv_argv[argc+2]!=NULL && pv_argv[argc+3]!=NULL && pv_argv[argc+4]==NULL);

   status = buildandrun(pv_argc2, pv_argv, NULL, &customexit, &customGroupHandler, 1);
   if( status != PV_SUCCESS ) {
      fprintf(stderr, "%s: rank %d running with params file %s returned error %d.\n", pv_argv[0], rank, paramFile2, status);
   }

   for (size_t arg=0; arg<pv_argc2; arg++) {
       free(pv_argv[arg]);
   }
   free(pv_argv);

#ifdef PV_USE_MPI
   MPI_Finalize();
#endif
   return status==PV_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;
}

int customexit(HyPerCol * hc, int argc, char * argv[]) {
   int status = PV_SUCCESS;
   int rank = hc->icCommunicator()->commRank();
   int rootproc = 0;
   if( rank == rootproc ) {
      int index = hc->getFinalStep()-hc->getInitialStep();
      const char * cpdir1 = "checkpoints1";
      const char * cpdir2 = hc->parameters()->stringValue("column", "checkpointWriteDir");
      if(cpdir1 == NULL || cpdir2 == NULL) {
         fprintf(stderr, "%s: unable to allocate memory for names of checkpoint directories", argv[0]);
         exit(EXIT_FAILURE);
      }
      char * shellcommand;
      char c;
      const char * fmtstr = "diff -r -q -x timers.txt -x pv.params %s/Checkpoint%d %s/Checkpoint%d";
      int len = snprintf(&c, 1, fmtstr, cpdir1, index, cpdir2, index);
      shellcommand = (char *) malloc(len+1);
      if( shellcommand == NULL) {
         fprintf(stderr, "%s: unable to allocate memory for shell diff command.\n", argv[0]);
         status = PV_FAILURE;
      }
      assert( snprintf(shellcommand, len+1, fmtstr, cpdir1, index, cpdir2, index) == len );
      status = system(shellcommand);
      if( status != 0 ) {
         fprintf(stderr, "system(\"%s\") returned %d\n", shellcommand, status);
         // Because system() seems to return the result of the shell command multiplied by 256,
         // and Unix only sees the 8 least-significant bits of the value returned by a C/C++ program,
         // simply returning the result of the system call doesn't work.
         // I haven't found the mult-by-256 behavior in the documentation, so I'm not sure what's
         // going on.
         status = PV_FAILURE;
      }
      free(shellcommand); shellcommand = NULL;
   }
#ifdef PV_USE_MPI
   MPI_Bcast(&status, 1, MPI_INT, rootproc, hc->icCommunicator()->communicator());
#endif
   return status;
}
<commit_msg>Bugfix in CheckpointSystemTest<commit_after>/*
 * main .cpp file for CheckpointSystemTest
 *
 */

#include <columns/buildandrun.hpp>
#include <io/ParamGroupHandler.hpp>
#include "CPTestInputLayer.hpp"
#include "VaryingHyPerConn.hpp"

class CustomGroupHandler : public ParamGroupHandler {
public:
   CustomGroupHandler() {}
   virtual ~CustomGroupHandler() {}
   virtual ParamGroupType getGroupType(char const * keyword) {
      ParamGroupType result = UnrecognizedGroupType;
      if (keyword==NULL) { result = UnrecognizedGroupType; }
      else if (!strcmp(keyword, "CPTestInputLayer")) { result = LayerGroupType; }
      else if (!strcmp(keyword, "VaryingHyPerConn")) { result = ConnectionGroupType; }
      else { result = UnrecognizedGroupType; }
      return result;
   }
   virtual HyPerLayer * createLayer(char const * keyword, char const * name, HyPerCol * hc) {
      HyPerLayer * addedLayer = NULL;
      bool matched = false;
      if (keyword==NULL) { addedLayer = NULL; }
      else if (!strcmp(keyword, "CPTestInputLayer")) {
         matched = true;
         addedLayer = new CPTestInputLayer(name, hc);
      }
      else { addedLayer = NULL; }
      if (matched && !addedLayer) {
         fprintf(stderr, "Rank %d process unable to create %s \"%s\".\n", hc->columnId(), keyword, name);
         exit(EXIT_FAILURE);
      }
      return addedLayer;
   }
   virtual BaseConnection * createConnection(char const * keyword, char const * name, HyPerCol * hc, InitWeights * weightInitializer, NormalizeBase * weightNormalizer) {
      BaseConnection * addedConn = NULL;
      bool matched = false;
      if (keyword==NULL) { addedConn = NULL; }
      else if (!strcmp(keyword, "VaryingHyPerConn")) {
         matched = true;
         addedConn = new VaryingHyPerConn(name, hc, weightInitializer, weightNormalizer);
      }
      else { addedConn = NULL; }
      if (matched && !addedConn) {
         fprintf(stderr, "Rank %d process unable to create %s \"%s\".\n", hc->columnId(), keyword, name);
         exit(EXIT_FAILURE);
      }
      return addedConn;
   }
}; // class CustomGroupHandler

int customexit(HyPerCol * hc, int argc, char * argv[]);

int main(int argc, char * argv[]) {
   int rank = 0;
#ifdef PV_USE_MPI
   MPI_Init(&argc, &argv);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
#endif // PV_USE_MPI
   char const * paramFile1 = "input/CheckpointParameters1.params";
   char const * paramFile2 = "input/CheckpointParameters2.params";
   int status = PV_SUCCESS;
   if (pv_getopt_str(argc, argv, "-p", NULL, NULL)==0) {
      if (rank==0) {
         fprintf(stderr, "%s should be run without the params file argument.\n", argv[0]);
      }
      status = PV_FAILURE;
   }
   if (pv_getopt_str(argc, argv, "-c", NULL, NULL)==0) {
      if (rank==0) {
         fprintf(stderr, "%s should be run without the checkpoint directory argument.\n", argv[0]);
      }
      status = PV_FAILURE;
   }
   if (pv_getopt(argc, argv, "-r", NULL)==0) {
      if (rank==0) {
         fprintf(stderr, "%s should be run without the checkpoint directory argument.\n", argv[0]);
      }
      status = PV_FAILURE;
   }
   if (status != PV_SUCCESS) {
      if (rank==0) {
         fprintf(stderr, "This test uses two hard-coded params files, %s and %s. The second run is started from a checkpoint from the first run, and the results of the two runs are compared.\n",
               paramFile1, paramFile2);
      }
      MPI_Barrier(MPI_COMM_WORLD);
      exit(EXIT_FAILURE);
   }

   if (rank==0) {
      char const * rmcommand = "rm -rf checkpoints1 checkpoints2 output";
      status = system(rmcommand);
      if (status != 0) {
         fprintf(stderr, "deleting old checkpoints and output directories failed: \"%s\" returned %d\n", rmcommand, status);
         exit(EXIT_FAILURE);
      }
   }

   ParamGroupHandler * customGroupHandler = new CustomGroupHandler;

   int pv_argc1 = 2 + argc; // command line arguments, plus "-p" plus paramFile1
   int pv_argc2 = 4 + argc; // pv_argc1 arguments with paramFile2 in place of paramFile1, plus "-c", plus checkpoint directory
   assert(pv_argc1 < pv_argc2); // so we can allocate based on pv_argc2 and be sure it will hold pv_argc1 arguments.
   char ** pv_argv = (char **) calloc((pv_argc2+1), sizeof(char *));
   assert(pv_argv!=NULL);
   int pv_arg=0;
   for (pv_arg = 0; pv_arg < argc; pv_arg++) {
      pv_argv[pv_arg] = strdup(argv[pv_arg]);
      assert(pv_argv[pv_arg]);
   }
   assert(pv_arg==argc);
   pv_argv[pv_arg++] = strdup("-p");
   pv_argv[pv_arg++] = strdup(paramFile1);
   assert(pv_arg==pv_argc1 && pv_arg==argc+2);
   assert(pv_argv[argc]!=NULL && pv_argv[argc+1]!=NULL && pv_argv[argc+2]==NULL);

   status = buildandrun((int) pv_argc1, pv_argv, NULL, NULL, &customGroupHandler, 1);
   if( status != PV_SUCCESS ) {
      fprintf(stderr, "%s: rank %d running with params file %s returned error %d.\n", pv_argv[0], rank, paramFile1, status);
      exit(status);
   }

   free(pv_argv[argc+1]);
   pv_argv[argc+1] = strdup(paramFile2);
   assert(pv_argv[argc+1]);
   assert(pv_arg==argc+2);
   pv_argv[pv_arg++] = strdup("-c");
   pv_argv[pv_arg++] = strdup("checkpoints1/Checkpoint12");
   assert(pv_arg==pv_argc2 && pv_arg==argc+4);
   assert(pv_argv[argc+2]!=NULL && pv_argv[argc+3]!=NULL && pv_argv[argc+4]==NULL);

   status = buildandrun(pv_argc2, pv_argv, NULL, &customexit, &customGroupHandler, 1);
   if( status != PV_SUCCESS ) {
      fprintf(stderr, "%s: rank %d running with params file %s returned error %d.\n", pv_argv[0], rank, paramFile2, status);
   }

   delete customGroupHandler;

   for (size_t arg=0; arg<pv_argc2; arg++) {
       free(pv_argv[arg]);
   }
   free(pv_argv);

#ifdef PV_USE_MPI
   MPI_Finalize();
#endif
   return status==PV_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;
}

int customexit(HyPerCol * hc, int argc, char * argv[]) {
   int status = PV_SUCCESS;
   int rank = hc->icCommunicator()->commRank();
   int rootproc = 0;
   if( rank == rootproc ) {
      int index = hc->getFinalStep()-hc->getInitialStep();
      const char * cpdir1 = "checkpoints1";
      const char * cpdir2 = hc->parameters()->stringValue("column", "checkpointWriteDir");
      if(cpdir1 == NULL || cpdir2 == NULL) {
         fprintf(stderr, "%s: unable to allocate memory for names of checkpoint directories", argv[0]);
         exit(EXIT_FAILURE);
      }
      char * shellcommand;
      char c;
      const char * fmtstr = "diff -r -q -x timers.txt -x pv.params %s/Checkpoint%d %s/Checkpoint%d";
      int len = snprintf(&c, 1, fmtstr, cpdir1, index, cpdir2, index);
      shellcommand = (char *) malloc(len+1);
      if( shellcommand == NULL) {
         fprintf(stderr, "%s: unable to allocate memory for shell diff command.\n", argv[0]);
         status = PV_FAILURE;
      }
      assert( snprintf(shellcommand, len+1, fmtstr, cpdir1, index, cpdir2, index) == len );
      status = system(shellcommand);
      if( status != 0 ) {
         fprintf(stderr, "system(\"%s\") returned %d\n", shellcommand, status);
         // Because system() seems to return the result of the shell command multiplied by 256,
         // and Unix only sees the 8 least-significant bits of the value returned by a C/C++ program,
         // simply returning the result of the system call doesn't work.
         // I haven't found the mult-by-256 behavior in the documentation, so I'm not sure what's
         // going on.
         status = PV_FAILURE;
      }
      free(shellcommand); shellcommand = NULL;
   }
#ifdef PV_USE_MPI
   MPI_Bcast(&status, 1, MPI_INT, rootproc, hc->icCommunicator()->communicator());
#endif
   return status;
}
<|endoftext|>


<commit_before>//===-- llc.cpp - Implement the LLVM Native Code Generator ----------------===//
//
// This is the llc code generator.
//
//===----------------------------------------------------------------------===//

#include "llvm/Bytecode/Reader.h"
#include "llvm/Target/TargetMachineImpls.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Pass.h"
#include "Support/CommandLine.h"
#include "Support/Signals.h"
#include <memory>
#include <fstream>

// General options for llc.  Other pass-specific options are specified
// within the corresponding llc passes, and target-specific options
// and back-end code generation options are specified with the target machine.
//
static cl::opt<std::string>
InputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-"));

static cl::opt<std::string>
OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));

static cl::opt<bool> Force("f", cl::desc("Overwrite output files"));

enum ArchName { noarch, x86, Sparc };

static cl::opt<ArchName>
Arch("march", cl::desc("Architecture to generate assembly for:"), cl::Prefix,
     cl::values(clEnumVal(x86, "  IA-32 (Pentium and above)"),
                clEnumValN(Sparc, "sparc", "  SPARC V9"),
		0),
     cl::init(noarch));

// GetFileNameRoot - Helper function to get the basename of a filename...
static inline std::string
GetFileNameRoot(const std::string &InputFilename)
{
  std::string IFN = InputFilename;
  std::string outputFilename;
  int Len = IFN.length();
  if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
    outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
  } else {
    outputFilename = IFN;
  }
  return outputFilename;
}

// main - Entry point for the llc compiler.
//
int main(int argc, char **argv) {
  cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");

  // Load the module to be compiled...
  std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
  if (M.get() == 0) {
    std::cerr << argv[0] << ": bytecode didn't read correctly.\n";
    return 1;
  }
  Module &mod = *M.get();

  // Allocate target machine.  First, check whether the user has
  // explicitly specified an architecture to compile for.
  TargetMachine* (*TargetMachineAllocator)(unsigned) = 0;
  switch (Arch) {
  case x86:
    TargetMachineAllocator = allocateX86TargetMachine;
    break;
  case Sparc:
    TargetMachineAllocator = allocateSparcTargetMachine;
    break;
  default:
    // Decide what the default target machine should be, by looking at
    // the module. This heuristic (ILP32, LE -> IA32; LP64, BE ->
    // SPARCV9) is kind of gross, but it will work until we have more
    // sophisticated target information to work from.
    if (mod.getEndianness()  == Module::LittleEndian &&
        mod.getPointerSize() == Module::Pointer32) {
      TargetMachineAllocator = allocateX86TargetMachine;
    } else if (mod.getEndianness()  == Module::BigEndian &&
               mod.getPointerSize() == Module::Pointer64) {
      TargetMachineAllocator = allocateSparcTargetMachine;
    } else {
      // If the module is target independent, favor a target which matches the
      // current build system.
#if defined(i386) || defined(__i386__) || defined(__x86__)
      TargetMachineAllocator = allocateX86TargetMachine;
#elif defined(sparc) || defined(__sparc__) || defined(__sparcv9)
      TargetMachineAllocator = allocateSparcTargetMachine;
#else
      std::cerr << argv[0] << ": module does not specify a target to use.  "
                << "You must use the -march option.\n";
      return 1;
#endif
    }
    break;
  }
  std::auto_ptr<TargetMachine> target((*TargetMachineAllocator)(0));
  assert(target.get() && "Could not allocate target machine!");
  TargetMachine &Target = *target.get();
  const TargetData &TD = Target.getTargetData();

  // Build up all of the passes that we want to do to the module...
  PassManager Passes;

  Passes.add(new TargetData("llc", TD.isLittleEndian(), TD.getPointerSize(),
                            TD.getPointerAlignment(), TD.getDoubleAlignment()));

  // Figure out where we are going to send the output...
  std::ostream *Out = 0;
  if (OutputFilename != "") {
    if (OutputFilename != "-") {
      // Specified an output filename?
      if (!Force && std::ifstream(OutputFilename.c_str())) {
	// If force is not specified, make sure not to overwrite a file!
	std::cerr << argv[0] << ": error opening '" << OutputFilename
		  << "': file exists!\n"
		  << "Use -f command line argument to force output\n";
	return 1;
      }
      Out = new std::ofstream(OutputFilename.c_str());

      // Make sure that the Out file gets unlink'd from the disk if we get a
      // SIGINT
      RemoveFileOnSignal(OutputFilename);
    } else {
      Out = &std::cout;
    }
  } else {
    if (InputFilename == "-") {
      OutputFilename = "-";
      Out = &std::cout;
    } else {
      OutputFilename = GetFileNameRoot(InputFilename);
      OutputFilename += ".s";

      if (!Force && std::ifstream(OutputFilename.c_str())) {
        // If force is not specified, make sure not to overwrite a file!
        std::cerr << argv[0] << ": error opening '" << OutputFilename
                  << "': file exists!\n"
                  << "Use -f command line argument to force output\n";
        return 1;
      }

      Out = new std::ofstream(OutputFilename.c_str());
      if (!Out->good()) {
        std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
        delete Out;
        return 1;
      }

      // Make sure that the Out file gets unlink'd from the disk if we get a
      // SIGINT
      RemoveFileOnSignal(OutputFilename);
    }
  }

  // Ask the target to add backend passes as necessary
  if (Target.addPassesToEmitAssembly(Passes, *Out)) {
    std::cerr << argv[0] << ": target '" << Target.getName()
              << "' does not support static compilation!\n";
    if (Out != &std::cout) delete Out;
    // And the Out file is empty and useless, so remove it now.
    std::remove(OutputFilename.c_str());
    return 1;
  } else {
    // Run our queue of passes all at once now, efficiently.
    Passes.run(*M.get());
  }

  // Delete the ostream if it's not a stdout stream
  if (Out != &std::cout) delete Out;

  return 0;
}
<commit_msg>Targets now configure themselves with the module, not flags<commit_after>//===-- llc.cpp - Implement the LLVM Native Code Generator ----------------===//
//
// This is the llc code generator.
//
//===----------------------------------------------------------------------===//

#include "llvm/Bytecode/Reader.h"
#include "llvm/Target/TargetMachineImpls.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Pass.h"
#include "Support/CommandLine.h"
#include "Support/Signals.h"
#include <memory>
#include <fstream>

// General options for llc.  Other pass-specific options are specified
// within the corresponding llc passes, and target-specific options
// and back-end code generation options are specified with the target machine.
//
static cl::opt<std::string>
InputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-"));

static cl::opt<std::string>
OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));

static cl::opt<bool> Force("f", cl::desc("Overwrite output files"));

enum ArchName { noarch, x86, Sparc };

static cl::opt<ArchName>
Arch("march", cl::desc("Architecture to generate assembly for:"), cl::Prefix,
     cl::values(clEnumVal(x86, "  IA-32 (Pentium and above)"),
                clEnumValN(Sparc, "sparc", "  SPARC V9"),
		0),
     cl::init(noarch));

// GetFileNameRoot - Helper function to get the basename of a filename...
static inline std::string
GetFileNameRoot(const std::string &InputFilename)
{
  std::string IFN = InputFilename;
  std::string outputFilename;
  int Len = IFN.length();
  if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
    outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
  } else {
    outputFilename = IFN;
  }
  return outputFilename;
}

// main - Entry point for the llc compiler.
//
int main(int argc, char **argv) {
  cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");

  // Load the module to be compiled...
  std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
  if (M.get() == 0) {
    std::cerr << argv[0] << ": bytecode didn't read correctly.\n";
    return 1;
  }
  Module &mod = *M.get();

  // Allocate target machine.  First, check whether the user has
  // explicitly specified an architecture to compile for.
  TargetMachine* (*TargetMachineAllocator)(const Module&) = 0;
  switch (Arch) {
  case x86:
    TargetMachineAllocator = allocateX86TargetMachine;
    break;
  case Sparc:
    TargetMachineAllocator = allocateSparcTargetMachine;
    break;
  default:
    // Decide what the default target machine should be, by looking at
    // the module. This heuristic (ILP32, LE -> IA32; LP64, BE ->
    // SPARCV9) is kind of gross, but it will work until we have more
    // sophisticated target information to work from.
    if (mod.getEndianness()  == Module::LittleEndian &&
        mod.getPointerSize() == Module::Pointer32) {
      TargetMachineAllocator = allocateX86TargetMachine;
    } else if (mod.getEndianness()  == Module::BigEndian &&
               mod.getPointerSize() == Module::Pointer64) {
      TargetMachineAllocator = allocateSparcTargetMachine;
    } else {
      // If the module is target independent, favor a target which matches the
      // current build system.
#if defined(i386) || defined(__i386__) || defined(__x86__)
      TargetMachineAllocator = allocateX86TargetMachine;
#elif defined(sparc) || defined(__sparc__) || defined(__sparcv9)
      TargetMachineAllocator = allocateSparcTargetMachine;
#else
      std::cerr << argv[0] << ": module does not specify a target to use.  "
                << "You must use the -march option.\n";
      return 1;
#endif
    }
    break;
  }
  std::auto_ptr<TargetMachine> target(TargetMachineAllocator(mod));
  assert(target.get() && "Could not allocate target machine!");
  TargetMachine &Target = *target.get();
  const TargetData &TD = Target.getTargetData();

  // Build up all of the passes that we want to do to the module...
  PassManager Passes;

  Passes.add(new TargetData("llc", TD.isLittleEndian(), TD.getPointerSize(),
                            TD.getPointerAlignment(), TD.getDoubleAlignment()));

  // Figure out where we are going to send the output...
  std::ostream *Out = 0;
  if (OutputFilename != "") {
    if (OutputFilename != "-") {
      // Specified an output filename?
      if (!Force && std::ifstream(OutputFilename.c_str())) {
	// If force is not specified, make sure not to overwrite a file!
	std::cerr << argv[0] << ": error opening '" << OutputFilename
		  << "': file exists!\n"
		  << "Use -f command line argument to force output\n";
	return 1;
      }
      Out = new std::ofstream(OutputFilename.c_str());

      // Make sure that the Out file gets unlink'd from the disk if we get a
      // SIGINT
      RemoveFileOnSignal(OutputFilename);
    } else {
      Out = &std::cout;
    }
  } else {
    if (InputFilename == "-") {
      OutputFilename = "-";
      Out = &std::cout;
    } else {
      OutputFilename = GetFileNameRoot(InputFilename);
      OutputFilename += ".s";

      if (!Force && std::ifstream(OutputFilename.c_str())) {
        // If force is not specified, make sure not to overwrite a file!
        std::cerr << argv[0] << ": error opening '" << OutputFilename
                  << "': file exists!\n"
                  << "Use -f command line argument to force output\n";
        return 1;
      }

      Out = new std::ofstream(OutputFilename.c_str());
      if (!Out->good()) {
        std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
        delete Out;
        return 1;
      }

      // Make sure that the Out file gets unlink'd from the disk if we get a
      // SIGINT
      RemoveFileOnSignal(OutputFilename);
    }
  }

  // Ask the target to add backend passes as necessary
  if (Target.addPassesToEmitAssembly(Passes, *Out)) {
    std::cerr << argv[0] << ": target '" << Target.getName()
              << "' does not support static compilation!\n";
    if (Out != &std::cout) delete Out;
    // And the Out file is empty and useless, so remove it now.
    std::remove(OutputFilename.c_str());
    return 1;
  } else {
    // Run our queue of passes all at once now, efficiently.
    Passes.run(*M.get());
  }

  // Delete the ostream if it's not a stdout stream
  if (Out != &std::cout) delete Out;

  return 0;
}
<|endoftext|>