Added ability to limit network transfer rate

This commit is contained in:
Jonathan Warren 2014-09-10 16:47:51 -04:00
parent c84cdecba4
commit 0865e863ec
10 changed files with 328 additions and 82 deletions

View File

@ -1346,26 +1346,23 @@ class MyForm(QtGui.QMainWindow):
if self.regenerateAddressesDialogInstance.ui.lineEditPassphrase.text() == "": if self.regenerateAddressesDialogInstance.ui.lineEditPassphrase.text() == "":
QMessageBox.about(self, _translate("MainWindow", "bad passphrase"), _translate( QMessageBox.about(self, _translate("MainWindow", "bad passphrase"), _translate(
"MainWindow", "You must type your passphrase. If you don\'t have one then this is not the form for you.")) "MainWindow", "You must type your passphrase. If you don\'t have one then this is not the form for you."))
else: return
streamNumberForAddress = int( streamNumberForAddress = int(
self.regenerateAddressesDialogInstance.ui.lineEditStreamNumber.text()) self.regenerateAddressesDialogInstance.ui.lineEditStreamNumber.text())
try: try:
addressVersionNumber = int( addressVersionNumber = int(
self.regenerateAddressesDialogInstance.ui.lineEditAddressVersionNumber.text()) self.regenerateAddressesDialogInstance.ui.lineEditAddressVersionNumber.text())
except: except:
QMessageBox.about(self, _translate("MainWindow", "Bad address version number"), _translate( QMessageBox.about(self, _translate("MainWindow", "Bad address version number"), _translate(
"MainWindow", "Your address version number must be a number: either 3 or 4.")) "MainWindow", "Your address version number must be a number: either 3 or 4."))
if addressVersionNumber < 3 or addressVersionNumber > 4: return
QMessageBox.about(self, _translate("MainWindow", "Bad address version number"), _translate( if addressVersionNumber < 3 or addressVersionNumber > 4:
"MainWindow", "Your address version number must be either 3 or 4.")) QMessageBox.about(self, _translate("MainWindow", "Bad address version number"), _translate(
# self.addressGenerator = addressGenerator() "MainWindow", "Your address version number must be either 3 or 4."))
# self.addressGenerator.setup(addressVersionNumber,streamNumberForAddress,"unused address",self.regenerateAddressesDialogInstance.ui.spinBoxNumberOfAddressesToMake.value(),self.regenerateAddressesDialogInstance.ui.lineEditPassphrase.text().toUtf8(),self.regenerateAddressesDialogInstance.ui.checkBoxEighteenByteRipe.isChecked()) return
# QtCore.QObject.connect(self.addressGenerator, SIGNAL("writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.writeNewAddressToTable) shared.addressGeneratorQueue.put(('createDeterministicAddresses', addressVersionNumber, streamNumberForAddress, "regenerated deterministic address", self.regenerateAddressesDialogInstance.ui.spinBoxNumberOfAddressesToMake.value(
# QtCore.QObject.connect(self.addressGenerator, QtCore.SIGNAL("updateStatusBar(PyQt_PyObject)"), self.updateStatusBar) ), self.regenerateAddressesDialogInstance.ui.lineEditPassphrase.text().toUtf8(), self.regenerateAddressesDialogInstance.ui.checkBoxEighteenByteRipe.isChecked()))
# self.addressGenerator.start() self.ui.tabWidget.setCurrentIndex(3)
shared.addressGeneratorQueue.put(('createDeterministicAddresses', addressVersionNumber, streamNumberForAddress, "regenerated deterministic address", self.regenerateAddressesDialogInstance.ui.spinBoxNumberOfAddressesToMake.value(
), self.regenerateAddressesDialogInstance.ui.lineEditPassphrase.text().toUtf8(), self.regenerateAddressesDialogInstance.ui.checkBoxEighteenByteRipe.isChecked()))
self.ui.tabWidget.setCurrentIndex(3)
def click_actionJoinChan(self): def click_actionJoinChan(self):
self.newChanDialogInstance = newChanDialog(self) self.newChanDialogInstance = newChanDialog(self)
@ -2322,6 +2319,15 @@ class MyForm(QtGui.QMainWindow):
self.settingsDialogInstance.ui.lineEditSocksPassword.text())) self.settingsDialogInstance.ui.lineEditSocksPassword.text()))
shared.config.set('bitmessagesettings', 'sockslisten', str( shared.config.set('bitmessagesettings', 'sockslisten', str(
self.settingsDialogInstance.ui.checkBoxSocksListen.isChecked())) self.settingsDialogInstance.ui.checkBoxSocksListen.isChecked()))
try:
# Rounding to integers just for aesthetics
shared.config.set('bitmessagesettings', 'maxdownloadrate', str(
int(float(self.settingsDialogInstance.ui.lineEditMaxDownloadRate.text()))))
shared.config.set('bitmessagesettings', 'maxuploadrate', str(
int(float(self.settingsDialogInstance.ui.lineEditMaxUploadRate.text()))))
except:
QMessageBox.about(self, _translate("MainWindow", "Number needed"), _translate(
"MainWindow", "Your maximum download and upload rate must be numbers. Ignoring what you typed."))
shared.config.set('bitmessagesettings', 'namecoinrpctype', shared.config.set('bitmessagesettings', 'namecoinrpctype',
self.settingsDialogInstance.getNamecoinType()) self.settingsDialogInstance.getNamecoinType())
@ -2333,7 +2339,8 @@ class MyForm(QtGui.QMainWindow):
self.settingsDialogInstance.ui.lineEditNamecoinUser.text())) self.settingsDialogInstance.ui.lineEditNamecoinUser.text()))
shared.config.set('bitmessagesettings', 'namecoinrpcpassword', str( shared.config.set('bitmessagesettings', 'namecoinrpcpassword', str(
self.settingsDialogInstance.ui.lineEditNamecoinPassword.text())) self.settingsDialogInstance.ui.lineEditNamecoinPassword.text()))
# Demanded difficulty tab
if float(self.settingsDialogInstance.ui.lineEditTotalDifficulty.text()) >= 1: if float(self.settingsDialogInstance.ui.lineEditTotalDifficulty.text()) >= 1:
shared.config.set('bitmessagesettings', 'defaultnoncetrialsperbyte', str(int(float( shared.config.set('bitmessagesettings', 'defaultnoncetrialsperbyte', str(int(float(
self.settingsDialogInstance.ui.lineEditTotalDifficulty.text()) * shared.networkDefaultProofOfWorkNonceTrialsPerByte))) self.settingsDialogInstance.ui.lineEditTotalDifficulty.text()) * shared.networkDefaultProofOfWorkNonceTrialsPerByte)))
@ -3443,7 +3450,12 @@ class settingsDialog(QtGui.QDialog):
shared.config.get('bitmessagesettings', 'sockspassword'))) shared.config.get('bitmessagesettings', 'sockspassword')))
QtCore.QObject.connect(self.ui.comboBoxProxyType, QtCore.SIGNAL( QtCore.QObject.connect(self.ui.comboBoxProxyType, QtCore.SIGNAL(
"currentIndexChanged(int)"), self.comboBoxProxyTypeChanged) "currentIndexChanged(int)"), self.comboBoxProxyTypeChanged)
self.ui.lineEditMaxDownloadRate.setText(str(
shared.config.get('bitmessagesettings', 'maxdownloadrate')))
self.ui.lineEditMaxUploadRate.setText(str(
shared.config.get('bitmessagesettings', 'maxuploadrate')))
# Demanded difficulty tab
self.ui.lineEditTotalDifficulty.setText(str((float(shared.config.getint( self.ui.lineEditTotalDifficulty.setText(str((float(shared.config.getint(
'bitmessagesettings', 'defaultnoncetrialsperbyte')) / shared.networkDefaultProofOfWorkNonceTrialsPerByte))) 'bitmessagesettings', 'defaultnoncetrialsperbyte')) / shared.networkDefaultProofOfWorkNonceTrialsPerByte)))
self.ui.lineEditSmallMessageDifficulty.setText(str((float(shared.config.getint( self.ui.lineEditSmallMessageDifficulty.setText(str((float(shared.config.getint(

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'settings.ui' # Form implementation generated from reading ui file 'settings.ui'
# #
# Created: Mon May 19 15:54:27 2014 # Created: Tue Sep 09 15:13:28 2014
# by: PyQt4 UI code generator 4.10.3 # by: PyQt4 UI code generator 4.10.3
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -128,6 +128,37 @@ class Ui_settingsDialog(object):
self.lineEditTCPPort.setObjectName(_fromUtf8("lineEditTCPPort")) self.lineEditTCPPort.setObjectName(_fromUtf8("lineEditTCPPort"))
self.gridLayout_3.addWidget(self.lineEditTCPPort, 0, 2, 1, 1) self.gridLayout_3.addWidget(self.lineEditTCPPort, 0, 2, 1, 1)
self.gridLayout_4.addWidget(self.groupBox1, 0, 0, 1, 1) self.gridLayout_4.addWidget(self.groupBox1, 0, 0, 1, 1)
self.groupBox_3 = QtGui.QGroupBox(self.tabNetworkSettings)
self.groupBox_3.setObjectName(_fromUtf8("groupBox_3"))
self.gridLayout_9 = QtGui.QGridLayout(self.groupBox_3)
self.gridLayout_9.setObjectName(_fromUtf8("gridLayout_9"))
spacerItem1 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.gridLayout_9.addItem(spacerItem1, 0, 0, 2, 1)
self.label_24 = QtGui.QLabel(self.groupBox_3)
self.label_24.setObjectName(_fromUtf8("label_24"))
self.gridLayout_9.addWidget(self.label_24, 0, 1, 1, 1)
self.lineEditMaxDownloadRate = QtGui.QLineEdit(self.groupBox_3)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lineEditMaxDownloadRate.sizePolicy().hasHeightForWidth())
self.lineEditMaxDownloadRate.setSizePolicy(sizePolicy)
self.lineEditMaxDownloadRate.setMaximumSize(QtCore.QSize(60, 16777215))
self.lineEditMaxDownloadRate.setObjectName(_fromUtf8("lineEditMaxDownloadRate"))
self.gridLayout_9.addWidget(self.lineEditMaxDownloadRate, 0, 2, 1, 1)
self.label_25 = QtGui.QLabel(self.groupBox_3)
self.label_25.setObjectName(_fromUtf8("label_25"))
self.gridLayout_9.addWidget(self.label_25, 1, 1, 1, 1)
self.lineEditMaxUploadRate = QtGui.QLineEdit(self.groupBox_3)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lineEditMaxUploadRate.sizePolicy().hasHeightForWidth())
self.lineEditMaxUploadRate.setSizePolicy(sizePolicy)
self.lineEditMaxUploadRate.setMaximumSize(QtCore.QSize(60, 16777215))
self.lineEditMaxUploadRate.setObjectName(_fromUtf8("lineEditMaxUploadRate"))
self.gridLayout_9.addWidget(self.lineEditMaxUploadRate, 1, 2, 1, 1)
self.gridLayout_4.addWidget(self.groupBox_3, 2, 0, 1, 1)
self.groupBox_2 = QtGui.QGroupBox(self.tabNetworkSettings) self.groupBox_2 = QtGui.QGroupBox(self.tabNetworkSettings)
self.groupBox_2.setObjectName(_fromUtf8("groupBox_2")) self.groupBox_2.setObjectName(_fromUtf8("groupBox_2"))
self.gridLayout_2 = QtGui.QGridLayout(self.groupBox_2) self.gridLayout_2 = QtGui.QGridLayout(self.groupBox_2)
@ -176,8 +207,8 @@ class Ui_settingsDialog(object):
self.comboBoxProxyType.addItem(_fromUtf8("")) self.comboBoxProxyType.addItem(_fromUtf8(""))
self.gridLayout_2.addWidget(self.comboBoxProxyType, 0, 1, 1, 1) self.gridLayout_2.addWidget(self.comboBoxProxyType, 0, 1, 1, 1)
self.gridLayout_4.addWidget(self.groupBox_2, 1, 0, 1, 1) self.gridLayout_4.addWidget(self.groupBox_2, 1, 0, 1, 1)
spacerItem1 = QtGui.QSpacerItem(20, 70, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) spacerItem2 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.gridLayout_4.addItem(spacerItem1, 2, 0, 1, 1) self.gridLayout_4.addItem(spacerItem2, 3, 0, 1, 1)
self.tabWidgetSettings.addTab(self.tabNetworkSettings, _fromUtf8("")) self.tabWidgetSettings.addTab(self.tabNetworkSettings, _fromUtf8(""))
self.tabDemandedDifficulty = QtGui.QWidget() self.tabDemandedDifficulty = QtGui.QWidget()
self.tabDemandedDifficulty.setObjectName(_fromUtf8("tabDemandedDifficulty")) self.tabDemandedDifficulty.setObjectName(_fromUtf8("tabDemandedDifficulty"))
@ -199,8 +230,8 @@ class Ui_settingsDialog(object):
self.label_8.setWordWrap(True) self.label_8.setWordWrap(True)
self.label_8.setObjectName(_fromUtf8("label_8")) self.label_8.setObjectName(_fromUtf8("label_8"))
self.gridLayout_6.addWidget(self.label_8, 0, 0, 1, 3) self.gridLayout_6.addWidget(self.label_8, 0, 0, 1, 3)
spacerItem2 = QtGui.QSpacerItem(203, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) spacerItem3 = QtGui.QSpacerItem(203, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.gridLayout_6.addItem(spacerItem2, 1, 0, 1, 1) self.gridLayout_6.addItem(spacerItem3, 1, 0, 1, 1)
self.label_12 = QtGui.QLabel(self.tabDemandedDifficulty) self.label_12 = QtGui.QLabel(self.tabDemandedDifficulty)
self.label_12.setWordWrap(True) self.label_12.setWordWrap(True)
self.label_12.setObjectName(_fromUtf8("label_12")) self.label_12.setObjectName(_fromUtf8("label_12"))
@ -223,10 +254,10 @@ class Ui_settingsDialog(object):
self.lineEditTotalDifficulty.setMaximumSize(QtCore.QSize(70, 16777215)) self.lineEditTotalDifficulty.setMaximumSize(QtCore.QSize(70, 16777215))
self.lineEditTotalDifficulty.setObjectName(_fromUtf8("lineEditTotalDifficulty")) self.lineEditTotalDifficulty.setObjectName(_fromUtf8("lineEditTotalDifficulty"))
self.gridLayout_6.addWidget(self.lineEditTotalDifficulty, 1, 2, 1, 1) self.gridLayout_6.addWidget(self.lineEditTotalDifficulty, 1, 2, 1, 1)
spacerItem3 = QtGui.QSpacerItem(203, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) spacerItem4 = QtGui.QSpacerItem(203, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.gridLayout_6.addItem(spacerItem3, 3, 0, 1, 1) self.gridLayout_6.addItem(spacerItem4, 3, 0, 1, 1)
spacerItem4 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) spacerItem5 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.gridLayout_6.addItem(spacerItem4, 5, 0, 1, 1) self.gridLayout_6.addItem(spacerItem5, 5, 0, 1, 1)
self.tabWidgetSettings.addTab(self.tabDemandedDifficulty, _fromUtf8("")) self.tabWidgetSettings.addTab(self.tabDemandedDifficulty, _fromUtf8(""))
self.tabMaxAcceptableDifficulty = QtGui.QWidget() self.tabMaxAcceptableDifficulty = QtGui.QWidget()
self.tabMaxAcceptableDifficulty.setObjectName(_fromUtf8("tabMaxAcceptableDifficulty")) self.tabMaxAcceptableDifficulty.setObjectName(_fromUtf8("tabMaxAcceptableDifficulty"))
@ -236,8 +267,8 @@ class Ui_settingsDialog(object):
self.label_15.setWordWrap(True) self.label_15.setWordWrap(True)
self.label_15.setObjectName(_fromUtf8("label_15")) self.label_15.setObjectName(_fromUtf8("label_15"))
self.gridLayout_7.addWidget(self.label_15, 0, 0, 1, 3) self.gridLayout_7.addWidget(self.label_15, 0, 0, 1, 3)
spacerItem5 = QtGui.QSpacerItem(102, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) spacerItem6 = QtGui.QSpacerItem(102, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.gridLayout_7.addItem(spacerItem5, 1, 0, 1, 1) self.gridLayout_7.addItem(spacerItem6, 1, 0, 1, 1)
self.label_13 = QtGui.QLabel(self.tabMaxAcceptableDifficulty) self.label_13 = QtGui.QLabel(self.tabMaxAcceptableDifficulty)
self.label_13.setLayoutDirection(QtCore.Qt.LeftToRight) self.label_13.setLayoutDirection(QtCore.Qt.LeftToRight)
self.label_13.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) self.label_13.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
@ -252,8 +283,8 @@ class Ui_settingsDialog(object):
self.lineEditMaxAcceptableTotalDifficulty.setMaximumSize(QtCore.QSize(70, 16777215)) self.lineEditMaxAcceptableTotalDifficulty.setMaximumSize(QtCore.QSize(70, 16777215))
self.lineEditMaxAcceptableTotalDifficulty.setObjectName(_fromUtf8("lineEditMaxAcceptableTotalDifficulty")) self.lineEditMaxAcceptableTotalDifficulty.setObjectName(_fromUtf8("lineEditMaxAcceptableTotalDifficulty"))
self.gridLayout_7.addWidget(self.lineEditMaxAcceptableTotalDifficulty, 1, 2, 1, 1) self.gridLayout_7.addWidget(self.lineEditMaxAcceptableTotalDifficulty, 1, 2, 1, 1)
spacerItem6 = QtGui.QSpacerItem(102, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) spacerItem7 = QtGui.QSpacerItem(102, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.gridLayout_7.addItem(spacerItem6, 2, 0, 1, 1) self.gridLayout_7.addItem(spacerItem7, 2, 0, 1, 1)
self.label_14 = QtGui.QLabel(self.tabMaxAcceptableDifficulty) self.label_14 = QtGui.QLabel(self.tabMaxAcceptableDifficulty)
self.label_14.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) self.label_14.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.label_14.setObjectName(_fromUtf8("label_14")) self.label_14.setObjectName(_fromUtf8("label_14"))
@ -267,15 +298,15 @@ class Ui_settingsDialog(object):
self.lineEditMaxAcceptableSmallMessageDifficulty.setMaximumSize(QtCore.QSize(70, 16777215)) self.lineEditMaxAcceptableSmallMessageDifficulty.setMaximumSize(QtCore.QSize(70, 16777215))
self.lineEditMaxAcceptableSmallMessageDifficulty.setObjectName(_fromUtf8("lineEditMaxAcceptableSmallMessageDifficulty")) self.lineEditMaxAcceptableSmallMessageDifficulty.setObjectName(_fromUtf8("lineEditMaxAcceptableSmallMessageDifficulty"))
self.gridLayout_7.addWidget(self.lineEditMaxAcceptableSmallMessageDifficulty, 2, 2, 1, 1) self.gridLayout_7.addWidget(self.lineEditMaxAcceptableSmallMessageDifficulty, 2, 2, 1, 1)
spacerItem7 = QtGui.QSpacerItem(20, 147, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) spacerItem8 = QtGui.QSpacerItem(20, 147, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.gridLayout_7.addItem(spacerItem7, 3, 1, 1, 1) self.gridLayout_7.addItem(spacerItem8, 3, 1, 1, 1)
self.tabWidgetSettings.addTab(self.tabMaxAcceptableDifficulty, _fromUtf8("")) self.tabWidgetSettings.addTab(self.tabMaxAcceptableDifficulty, _fromUtf8(""))
self.tabNamecoin = QtGui.QWidget() self.tabNamecoin = QtGui.QWidget()
self.tabNamecoin.setObjectName(_fromUtf8("tabNamecoin")) self.tabNamecoin.setObjectName(_fromUtf8("tabNamecoin"))
self.gridLayout_8 = QtGui.QGridLayout(self.tabNamecoin) self.gridLayout_8 = QtGui.QGridLayout(self.tabNamecoin)
self.gridLayout_8.setObjectName(_fromUtf8("gridLayout_8")) self.gridLayout_8.setObjectName(_fromUtf8("gridLayout_8"))
spacerItem8 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) spacerItem9 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.gridLayout_8.addItem(spacerItem8, 2, 0, 1, 1) self.gridLayout_8.addItem(spacerItem9, 2, 0, 1, 1)
self.label_16 = QtGui.QLabel(self.tabNamecoin) self.label_16 = QtGui.QLabel(self.tabNamecoin)
self.label_16.setWordWrap(True) self.label_16.setWordWrap(True)
self.label_16.setObjectName(_fromUtf8("label_16")) self.label_16.setObjectName(_fromUtf8("label_16"))
@ -287,10 +318,10 @@ class Ui_settingsDialog(object):
self.lineEditNamecoinHost = QtGui.QLineEdit(self.tabNamecoin) self.lineEditNamecoinHost = QtGui.QLineEdit(self.tabNamecoin)
self.lineEditNamecoinHost.setObjectName(_fromUtf8("lineEditNamecoinHost")) self.lineEditNamecoinHost.setObjectName(_fromUtf8("lineEditNamecoinHost"))
self.gridLayout_8.addWidget(self.lineEditNamecoinHost, 2, 2, 1, 1) self.gridLayout_8.addWidget(self.lineEditNamecoinHost, 2, 2, 1, 1)
spacerItem9 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.gridLayout_8.addItem(spacerItem9, 3, 0, 1, 1)
spacerItem10 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) spacerItem10 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.gridLayout_8.addItem(spacerItem10, 4, 0, 1, 1) self.gridLayout_8.addItem(spacerItem10, 3, 0, 1, 1)
spacerItem11 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.gridLayout_8.addItem(spacerItem11, 4, 0, 1, 1)
self.label_18 = QtGui.QLabel(self.tabNamecoin) self.label_18 = QtGui.QLabel(self.tabNamecoin)
self.label_18.setEnabled(True) self.label_18.setEnabled(True)
self.label_18.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) self.label_18.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
@ -299,8 +330,8 @@ class Ui_settingsDialog(object):
self.lineEditNamecoinPort = QtGui.QLineEdit(self.tabNamecoin) self.lineEditNamecoinPort = QtGui.QLineEdit(self.tabNamecoin)
self.lineEditNamecoinPort.setObjectName(_fromUtf8("lineEditNamecoinPort")) self.lineEditNamecoinPort.setObjectName(_fromUtf8("lineEditNamecoinPort"))
self.gridLayout_8.addWidget(self.lineEditNamecoinPort, 3, 2, 1, 1) self.gridLayout_8.addWidget(self.lineEditNamecoinPort, 3, 2, 1, 1)
spacerItem11 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) spacerItem12 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.gridLayout_8.addItem(spacerItem11, 8, 1, 1, 1) self.gridLayout_8.addItem(spacerItem12, 8, 1, 1, 1)
self.labelNamecoinUser = QtGui.QLabel(self.tabNamecoin) self.labelNamecoinUser = QtGui.QLabel(self.tabNamecoin)
self.labelNamecoinUser.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) self.labelNamecoinUser.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.labelNamecoinUser.setObjectName(_fromUtf8("labelNamecoinUser")) self.labelNamecoinUser.setObjectName(_fromUtf8("labelNamecoinUser"))
@ -308,8 +339,8 @@ class Ui_settingsDialog(object):
self.lineEditNamecoinUser = QtGui.QLineEdit(self.tabNamecoin) self.lineEditNamecoinUser = QtGui.QLineEdit(self.tabNamecoin)
self.lineEditNamecoinUser.setObjectName(_fromUtf8("lineEditNamecoinUser")) self.lineEditNamecoinUser.setObjectName(_fromUtf8("lineEditNamecoinUser"))
self.gridLayout_8.addWidget(self.lineEditNamecoinUser, 4, 2, 1, 1) self.gridLayout_8.addWidget(self.lineEditNamecoinUser, 4, 2, 1, 1)
spacerItem12 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) spacerItem13 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.gridLayout_8.addItem(spacerItem12, 5, 0, 1, 1) self.gridLayout_8.addItem(spacerItem13, 5, 0, 1, 1)
self.labelNamecoinPassword = QtGui.QLabel(self.tabNamecoin) self.labelNamecoinPassword = QtGui.QLabel(self.tabNamecoin)
self.labelNamecoinPassword.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) self.labelNamecoinPassword.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.labelNamecoinPassword.setObjectName(_fromUtf8("labelNamecoinPassword")) self.labelNamecoinPassword.setObjectName(_fromUtf8("labelNamecoinPassword"))
@ -347,8 +378,8 @@ class Ui_settingsDialog(object):
self.label_7.setWordWrap(True) self.label_7.setWordWrap(True)
self.label_7.setObjectName(_fromUtf8("label_7")) self.label_7.setObjectName(_fromUtf8("label_7"))
self.gridLayout_5.addWidget(self.label_7, 0, 0, 1, 3) self.gridLayout_5.addWidget(self.label_7, 0, 0, 1, 3)
spacerItem13 = QtGui.QSpacerItem(212, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) spacerItem14 = QtGui.QSpacerItem(212, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.gridLayout_5.addItem(spacerItem13, 1, 0, 1, 1) self.gridLayout_5.addItem(spacerItem14, 1, 0, 1, 1)
self.widget = QtGui.QWidget(self.tabResendsExpire) self.widget = QtGui.QWidget(self.tabResendsExpire)
self.widget.setMinimumSize(QtCore.QSize(231, 75)) self.widget.setMinimumSize(QtCore.QSize(231, 75))
self.widget.setObjectName(_fromUtf8("widget")) self.widget.setObjectName(_fromUtf8("widget"))
@ -373,8 +404,8 @@ class Ui_settingsDialog(object):
self.label_23.setGeometry(QtCore.QRect(170, 41, 71, 16)) self.label_23.setGeometry(QtCore.QRect(170, 41, 71, 16))
self.label_23.setObjectName(_fromUtf8("label_23")) self.label_23.setObjectName(_fromUtf8("label_23"))
self.gridLayout_5.addWidget(self.widget, 1, 2, 1, 1) self.gridLayout_5.addWidget(self.widget, 1, 2, 1, 1)
spacerItem14 = QtGui.QSpacerItem(20, 129, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) spacerItem15 = QtGui.QSpacerItem(20, 129, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.gridLayout_5.addItem(spacerItem14, 2, 1, 1, 1) self.gridLayout_5.addItem(spacerItem15, 2, 1, 1, 1)
self.tabWidgetSettings.addTab(self.tabResendsExpire, _fromUtf8("")) self.tabWidgetSettings.addTab(self.tabResendsExpire, _fromUtf8(""))
self.gridLayout.addWidget(self.tabWidgetSettings, 0, 0, 1, 1) self.gridLayout.addWidget(self.tabWidgetSettings, 0, 0, 1, 1)
@ -416,6 +447,9 @@ class Ui_settingsDialog(object):
self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tabUserInterface), _translate("settingsDialog", "User Interface", None)) self.tabWidgetSettings.setTabText(self.tabWidgetSettings.indexOf(self.tabUserInterface), _translate("settingsDialog", "User Interface", None))
self.groupBox1.setTitle(_translate("settingsDialog", "Listening port", None)) self.groupBox1.setTitle(_translate("settingsDialog", "Listening port", None))
self.label.setText(_translate("settingsDialog", "Listen for connections on port:", None)) self.label.setText(_translate("settingsDialog", "Listen for connections on port:", None))
self.groupBox_3.setTitle(_translate("settingsDialog", "Bandwidth limit", None))
self.label_24.setText(_translate("settingsDialog", "Maximum download rate (kB/s): [0: unlimited]", None))
self.label_25.setText(_translate("settingsDialog", "Maximum upload rate (kB/s): [0: unlimited]", None))
self.groupBox_2.setTitle(_translate("settingsDialog", "Proxy server / Tor", None)) self.groupBox_2.setTitle(_translate("settingsDialog", "Proxy server / Tor", None))
self.label_2.setText(_translate("settingsDialog", "Type:", None)) self.label_2.setText(_translate("settingsDialog", "Type:", None))
self.label_3.setText(_translate("settingsDialog", "Server hostname:", None)) self.label_3.setText(_translate("settingsDialog", "Server hostname:", None))

View File

@ -247,6 +247,74 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="2" column="0">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Bandwidth limit</string>
</property>
<layout class="QGridLayout" name="gridLayout_9">
<item row="0" column="0" rowspan="2">
<spacer name="horizontalSpacer_11">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_24">
<property name="text">
<string>Maximum download rate (kB/s): [0: unlimited]</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLineEdit" name="lineEditMaxDownloadRate">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_25">
<property name="text">
<string>Maximum upload rate (kB/s): [0: unlimited]</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLineEdit" name="lineEditMaxUploadRate">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QGroupBox" name="groupBox_2"> <widget class="QGroupBox" name="groupBox_2">
<property name="title"> <property name="title">
@ -350,7 +418,7 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="3" column="0">
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
@ -358,7 +426,7 @@
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
<height>70</height> <height>40</height>
</size> </size>
</property> </property>
</spacer> </spacer>

View File

@ -1024,7 +1024,13 @@ class objectProcessor(threading.Thread):
if len(payload) != payloadLength: if len(payload) != payloadLength:
logger.info('ackData payload length doesn\'t match the payload length specified in the header. Not sending ackdata.') logger.info('ackData payload length doesn\'t match the payload length specified in the header. Not sending ackdata.')
return False return False
if payloadLength > 2 ** 18: # 256 KiB if payloadLength > 1600100: # ~1.6 MB which is the maximum possible size of an inv message.
"""
The largest message should be either an inv or a getdata message at 1.6 MB in size.
That doesn't mean that the object may be that big. The
shared.checkAndShareObjectWithPeers function will verify that it is no larger than
2^18 bytes.
"""
return False return False
if checksum != hashlib.sha512(payload).digest()[0:4]: # test the checksum in the message. if checksum != hashlib.sha512(payload).digest()[0:4]: # test the checksum in the message.
logger.info('ackdata checksum wrong. Not sending ackdata.') logger.info('ackdata checksum wrong. Not sending ackdata.')

View File

@ -64,8 +64,6 @@ class outgoingSynSender(threading.Thread):
shared.alreadyAttemptedConnectionsListLock.acquire() shared.alreadyAttemptedConnectionsListLock.acquire()
shared.alreadyAttemptedConnectionsList[peer] = 0 shared.alreadyAttemptedConnectionsList[peer] = 0
shared.alreadyAttemptedConnectionsListLock.release() shared.alreadyAttemptedConnectionsListLock.release()
timeNodeLastSeen = shared.knownNodes[
self.streamNumber][peer]
if peer.host.find(':') == -1: if peer.host.find(':') == -1:
address_family = socket.AF_INET address_family = socket.AF_INET
else: else:
@ -83,7 +81,10 @@ class outgoingSynSender(threading.Thread):
So let us remove the offending address from our knownNodes file. So let us remove the offending address from our knownNodes file.
""" """
shared.knownNodesLock.acquire() shared.knownNodesLock.acquire()
del shared.knownNodes[self.streamNumber][peer] try:
del shared.knownNodes[self.streamNumber][peer]
except:
pass
shared.knownNodesLock.release() shared.knownNodesLock.release()
with shared.printLock: with shared.printLock:
print 'deleting ', peer, 'from shared.knownNodes because it caused a socks.socksocket exception. We must not be 64-bit compatible.' print 'deleting ', peer, 'from shared.knownNodes because it caused a socks.socksocket exception. We must not be 64-bit compatible.'
@ -169,14 +170,24 @@ class outgoingSynSender(threading.Thread):
with shared.printLock: with shared.printLock:
print 'Could NOT connect to', peer, 'during outgoing attempt.', err print 'Could NOT connect to', peer, 'during outgoing attempt.', err
timeLastSeen = shared.knownNodes[ deletedPeer = None
self.streamNumber][peer] with shared.knownNodesLock:
if (int(time.time()) - timeLastSeen) > 172800 and len(shared.knownNodes[self.streamNumber]) > 1000: # for nodes older than 48 hours old if we have more than 1000 hosts in our list, delete from the shared.knownNodes data-structure. """
shared.knownNodesLock.acquire() It is remotely possible that peer is no longer in shared.knownNodes.
del shared.knownNodes[self.streamNumber][peer] This could happen if two outgoingSynSender threads both try to
shared.knownNodesLock.release() connect to the same peer, both fail, and then both try to remove
it from shared.knownNodes. This is unlikely because of the
alreadyAttemptedConnectionsList but because we clear that list once
every half hour, it can happen.
"""
if peer in shared.knownNodes[self.streamNumber]:
timeLastSeen = shared.knownNodes[self.streamNumber][peer]
if (int(time.time()) - timeLastSeen) > 172800 and len(shared.knownNodes[self.streamNumber]) > 1000: # for nodes older than 48 hours old if we have more than 1000 hosts in our list, delete from the shared.knownNodes data-structure.
del shared.knownNodes[self.streamNumber][peer]
deletedPeer = peer
if deletedPeer:
with shared.printLock: with shared.printLock:
print 'deleting ', peer, 'from shared.knownNodes because it is more than 48 hours old and we could not connect to it.' print 'deleting', peer, 'from shared.knownNodes because it is more than 48 hours old and we could not connect to it.'
except socks.Socks5AuthError as err: except socks.Socks5AuthError as err:
shared.UISignalQueue.put(( shared.UISignalQueue.put((
@ -195,14 +206,24 @@ class outgoingSynSender(threading.Thread):
with shared.printLock: with shared.printLock:
print 'Could NOT connect to', peer, 'during outgoing attempt.', err print 'Could NOT connect to', peer, 'during outgoing attempt.', err
timeLastSeen = shared.knownNodes[ deletedPeer = None
self.streamNumber][peer] with shared.knownNodesLock:
if (int(time.time()) - timeLastSeen) > 172800 and len(shared.knownNodes[self.streamNumber]) > 1000: # for nodes older than 48 hours old if we have more than 1000 hosts in our list, delete from the knownNodes data-structure. """
shared.knownNodesLock.acquire() It is remotely possible that peer is no longer in shared.knownNodes.
del shared.knownNodes[self.streamNumber][peer] This could happen if two outgoingSynSender threads both try to
shared.knownNodesLock.release() connect to the same peer, both fail, and then both try to remove
with shared.printLock: it from shared.knownNodes. This is unlikely because of the
print 'deleting ', peer, 'from knownNodes because it is more than 48 hours old and we could not connect to it.' alreadyAttemptedConnectionsList but because we clear that list once
every half hour, it can happen.
"""
if peer in shared.knownNodes[self.streamNumber]:
timeLastSeen = shared.knownNodes[self.streamNumber][peer]
if (int(time.time()) - timeLastSeen) > 172800 and len(shared.knownNodes[self.streamNumber]) > 1000: # for nodes older than 48 hours old if we have more than 1000 hosts in our list, delete from the shared.knownNodes data-structure.
del shared.knownNodes[self.streamNumber][peer]
deletedPeer = peer
if deletedPeer:
with shared.printLock:
print 'deleting', peer, 'from shared.knownNodes because it is more than 48 hours old and we could not connect to it.'
except Exception as err: except Exception as err:
sys.stderr.write( sys.stderr.write(

View File

@ -65,11 +65,25 @@ class receiveDataThread(threading.Thread):
print 'receiveDataThread starting. ID', str(id(self)) + '. The size of the shared.connectedHostsList is now', len(shared.connectedHostsList) print 'receiveDataThread starting. ID', str(id(self)) + '. The size of the shared.connectedHostsList is now', len(shared.connectedHostsList)
while True: while True:
if shared.config.getint('bitmessagesettings', 'maxdownloadrate') == 0:
downloadRateLimitBytes = float("inf")
else:
downloadRateLimitBytes = shared.config.getint('bitmessagesettings', 'maxdownloadrate') * 1000
with shared.receiveDataLock:
while shared.numberOfBytesReceivedLastSecond >= downloadRateLimitBytes:
if int(time.time()) == shared.lastTimeWeResetBytesReceived:
# If it's still the same second that it was last time then sleep.
time.sleep(0.3)
else:
# It's a new second. Let us clear the shared.numberOfBytesReceivedLastSecond.
shared.lastTimeWeResetBytesReceived = int(time.time())
shared.numberOfBytesReceivedLastSecond = 0
dataLen = len(self.data) dataLen = len(self.data)
try: try:
dataRecv = self.sock.recv(4096) dataRecv = self.sock.recv(1024)
self.data += dataRecv self.data += dataRecv
shared.numberOfBytesReceived += len(dataRecv) shared.numberOfBytesReceived += len(dataRecv) # for the 'network status' UI tab. The UI clears this value whenever it updates.
shared.numberOfBytesReceivedLastSecond += len(dataRecv) # for the download rate limit
except socket.timeout: except socket.timeout:
with shared.printLock: with shared.printLock:
print 'Timeout occurred waiting for data from', self.peer, '. Closing receiveData thread. (ID:', str(id(self)) + ')' print 'Timeout occurred waiting for data from', self.peer, '. Closing receiveData thread. (ID:', str(id(self)) + ')'
@ -117,7 +131,7 @@ class receiveDataThread(threading.Thread):
if magic != 0xE9BEB4D9: if magic != 0xE9BEB4D9:
self.data = "" self.data = ""
return return
if payloadLength > 2 ** 18: # 256 KiB if payloadLength > 1600100: # ~1.6 MB which is the maximum possible size of an inv message.
logger.info('The incoming message, which we have not yet download, is too large. Ignoring it. (unfortunately there is no way to tell the other node to stop sending it except to disconnect.) Message size: %s' % payloadLength) logger.info('The incoming message, which we have not yet download, is too large. Ignoring it. (unfortunately there is no way to tell the other node to stop sending it except to disconnect.) Message size: %s' % payloadLength)
self.data = self.data[payloadLength + shared.Header.size:] self.data = self.data[payloadLength + shared.Header.size:]
del magic,command,payloadLength,checksum # we don't need these anymore and better to clean them now before the recursive call rather than after del magic,command,payloadLength,checksum # we don't need these anymore and better to clean them now before the recursive call rather than after
@ -148,7 +162,9 @@ class receiveDataThread(threading.Thread):
try: try:
#TODO: Use a dispatcher here #TODO: Use a dispatcher here
if not self.connectionIsOrWasFullyEstablished: if command == 'error':
self.recerror(payload)
elif not self.connectionIsOrWasFullyEstablished:
if command == 'version': if command == 'version':
self.recversion(payload) self.recversion(payload)
elif command == 'verack': elif command == 'verack':
@ -321,6 +337,37 @@ class receiveDataThread(threading.Thread):
with shared.printLock: with shared.printLock:
print 'Timing attack mitigation: Sleeping for', sleepTime, 'seconds.' print 'Timing attack mitigation: Sleeping for', sleepTime, 'seconds.'
time.sleep(sleepTime) time.sleep(sleepTime)
def recerror(self, data):
"""
The remote node has been polite enough to send you an error message.
"""
fatalStatus, readPosition = decodeVarint(data[:10])
banTime, banTimeLength = decodeVarint(data[readPosition:readPosition+10])
readPosition += banTimeLength
inventoryVectorLength, inventoryVectorLengthLength = decodeVarint(data[readPosition:readPosition+10])
if inventoryVectorLength > 100:
return
readPosition += inventoryVectorLengthLength
inventoryVector = data[readPosition:readPosition+inventoryVectorLength]
readPosition += inventoryVectorLength
errorTextLength, errorTextLengthLength = decodeVarint(data[readPosition:readPosition+10])
if errorTextLength > 1000:
return
readPosition += errorTextLengthLength
errorText = data[readPosition:readPosition+errorTextLength]
if fatalStatus == 0:
fatalHumanFriendly = 'Warning'
elif fatalStatus == 1:
fatalHumanFriendly = 'Error'
elif fatalStatus == 2:
fatalHumanFriendly = 'Fatal'
message = '%s message received from %s: %s.' % (fatalHumanFriendly, self.peer, errorText)
if inventoryVector:
message += " This concerns object %s" % inventoryVector.encode('hex')
if banTime > 0:
message += " Remote node says that the ban time is %s" % banTime
logger.error(message)
def recobject(self, data): def recobject(self, data):
@ -672,7 +719,20 @@ class receiveDataThread(threading.Thread):
with shared.printLock: with shared.printLock:
print 'Closing connection to old protocol version', self.remoteProtocolVersion, 'node: ', self.peer print 'Closing connection to old protocol version', self.remoteProtocolVersion, 'node: ', self.peer
return return
# print 'remoteProtocolVersion', self.remoteProtocolVersion timestamp, = unpack('>Q', data[12:20])
timeOffset = timestamp - int(time.time())
if timeOffset > 3600:
self.sendDataThreadQueue.put((0, 'sendRawData', shared.assembleErrorMessage(fatal=2, errorText="Your time is too far in the future compared to mine. Closing connection.")))
logger.info("%s's time is too far in the future (%s seconds). Closing connection to it." % (self.peer, timeOffset))
time.sleep(2)
self.sendDataThreadQueue.put((0, 'shutdown','no data'))
return
if timeOffset < -3600:
self.sendDataThreadQueue.put((0, 'sendRawData', shared.assembleErrorMessage(fatal=2, errorText="Your time is too far in the past compared to mine. Closing connection.")))
logger.info("%s's time is too far in the past (timeOffset %s seconds). Closing connection to it." % (self.peer, timeOffset))
time.sleep(2)
self.sendDataThreadQueue.put((0, 'shutdown','no data'))
return
self.myExternalIP = socket.inet_ntoa(data[40:44]) self.myExternalIP = socket.inet_ntoa(data[40:44])
# print 'myExternalIP', self.myExternalIP # print 'myExternalIP', self.myExternalIP
self.remoteNodeIncomingPort, = unpack('>H', data[70:72]) self.remoteNodeIncomingPort, = unpack('>H', data[70:72])
@ -688,7 +748,7 @@ class receiveDataThread(threading.Thread):
self.streamNumber, lengthOfRemoteStreamNumber = decodeVarint( self.streamNumber, lengthOfRemoteStreamNumber = decodeVarint(
data[readPosition:]) data[readPosition:])
with shared.printLock: with shared.printLock:
print 'Remote node useragent:', useragent, ' stream number:', self.streamNumber print 'Remote node useragent:', useragent, ' stream number:', self.streamNumber, ' time offset:', timeOffset, 'seconds.'
if self.streamNumber != 1: if self.streamNumber != 1:
self.sendDataThreadQueue.put((0, 'shutdown','no data')) self.sendDataThreadQueue.put((0, 'shutdown','no data'))

View File

@ -62,9 +62,32 @@ class sendDataThread(threading.Thread):
self.versionSent = 1 self.versionSent = 1
def sendBytes(self, data): def sendBytes(self, data):
self.sock.sendall(data) if shared.config.getint('bitmessagesettings', 'maxuploadrate') == 0:
shared.numberOfBytesSent += len(data) uploadRateLimitBytes = 999999999 # float("inf") doesn't work
self.lastTimeISentData = int(time.time()) else:
uploadRateLimitBytes = shared.config.getint('bitmessagesettings', 'maxuploadrate') * 1000
with shared.sendDataLock:
while data:
while shared.numberOfBytesSentLastSecond >= uploadRateLimitBytes:
if int(time.time()) == shared.lastTimeWeResetBytesSent:
time.sleep(0.3)
else:
# It's a new second. Let us clear the shared.numberOfBytesSentLastSecond
shared.lastTimeWeResetBytesSent = int(time.time())
shared.numberOfBytesSentLastSecond = 0
# If the user raises or lowers the uploadRateLimit then we should make use of
# the new setting. If we are hitting the limit then we'll check here about
# once per second.
if shared.config.getint('bitmessagesettings', 'maxuploadrate') == 0:
uploadRateLimitBytes = 999999999 # float("inf") doesn't work
else:
uploadRateLimitBytes = shared.config.getint('bitmessagesettings', 'maxuploadrate') * 1000
numberOfBytesWeMaySend = uploadRateLimitBytes - shared.numberOfBytesSentLastSecond
self.sock.sendall(data[:numberOfBytesWeMaySend])
shared.numberOfBytesSent += len(data[:numberOfBytesWeMaySend]) # used for the 'network status' tab in the UI
shared.numberOfBytesSentLastSecond += len(data[:numberOfBytesWeMaySend])
self.lastTimeISentData = int(time.time())
data = data[numberOfBytesWeMaySend:]
def run(self): def run(self):

View File

@ -341,6 +341,8 @@ class sqlThread(threading.Thread):
shared.config.set(addressInKeysFile,'payloadlengthextrabytes', str(int(previousSmallMessageDifficulty * 1000))) shared.config.set(addressInKeysFile,'payloadlengthextrabytes', str(int(previousSmallMessageDifficulty * 1000)))
except: except:
continue continue
shared.config.set('bitmessagesettings', 'maxdownloadrate', '0')
shared.config.set('bitmessagesettings', 'maxuploadrate', '0')
shared.config.set('bitmessagesettings', 'settingsversion', '10') shared.config.set('bitmessagesettings', 'settingsversion', '10')
with open(shared.appdata + 'keys.dat', 'wb') as configfile: with open(shared.appdata + 'keys.dat', 'wb') as configfile:
shared.config.write(configfile) shared.config.write(configfile)

View File

@ -102,6 +102,8 @@ def loadConfig():
shared.config.set('bitmessagesettings', 'useidenticons', 'True') shared.config.set('bitmessagesettings', 'useidenticons', 'True')
shared.config.set('bitmessagesettings', 'identiconsuffix', ''.join(random.choice("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") for x in range(12))) # a twelve character pseudo-password to salt the identicons shared.config.set('bitmessagesettings', 'identiconsuffix', ''.join(random.choice("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") for x in range(12))) # a twelve character pseudo-password to salt the identicons
shared.config.set('bitmessagesettings', 'replybelow', 'False') shared.config.set('bitmessagesettings', 'replybelow', 'False')
shared.config.set('bitmessagesettings', 'maxdownloadrate', '0')
shared.config.set('bitmessagesettings', 'maxuploadrate', '0')
#start:UI setting to stop trying to send messages after X days/months #start:UI setting to stop trying to send messages after X days/months
shared.config.set( shared.config.set(

View File

@ -70,8 +70,14 @@ numberOfMessagesProcessed = 0
numberOfBroadcastsProcessed = 0 numberOfBroadcastsProcessed = 0
numberOfPubkeysProcessed = 0 numberOfPubkeysProcessed = 0
numberOfInventoryLookupsPerformed = 0 numberOfInventoryLookupsPerformed = 0
numberOfBytesReceived = 0 numberOfBytesReceived = 0 # Used for the 'network status' page
numberOfBytesSent = 0 numberOfBytesSent = 0 # Used for the 'network status' page
numberOfBytesReceivedLastSecond = 0 # used for the bandwidth rate limit
numberOfBytesSentLastSecond = 0 # used for the bandwidth rate limit
lastTimeWeResetBytesReceived = 0 # used for the bandwidth rate limit
lastTimeWeResetBytesSent = 0 # used for the bandwidth rate limit
sendDataLock = threading.Lock() # used for the bandwidth rate limit
receiveDataLock = threading.Lock() # used for the bandwidth rate limit
daemon = False daemon = False
inventorySets = {} # key = streamNumer, value = a set which holds the inventory object hashes that we are aware of. This is used whenever we receive an inv message from a peer to check to see what items are new to us. We don't delete things out of it; instead, the singleCleaner thread clears and refills it every couple hours. inventorySets = {} # key = streamNumer, value = a set which holds the inventory object hashes that we are aware of. This is used whenever we receive an inv message from a peer to check to see what items are new to us. We don't delete things out of it; instead, the singleCleaner thread clears and refills it every couple hours.
needToWriteKnownNodesToDisk = False # If True, the singleCleaner will write it to disk eventually. needToWriteKnownNodesToDisk = False # If True, the singleCleaner will write it to disk eventually.
@ -159,6 +165,15 @@ def assembleVersionMessage(remoteHost, remotePort, myStreamNumber):
return CreatePacket('version', payload) return CreatePacket('version', payload)
def assembleErrorMessage(fatal=0, banTime=0, inventoryVector='', errorText=''):
payload = encodeVarint(fatal)
payload += encodeVarint(banTime)
payload += encodeVarint(len(inventoryVector))
payload += inventoryVector
payload += encodeVarint(len(errorText))
payload += errorText
return CreatePacket('error', payload)
def lookupAppdataFolder(): def lookupAppdataFolder():
APPNAME = "PyBitmessage" APPNAME = "PyBitmessage"
if "BITMESSAGE_HOME" in environ: if "BITMESSAGE_HOME" in environ:
@ -586,11 +601,14 @@ Peer = collections.namedtuple('Peer', ['host', 'port'])
def checkAndShareObjectWithPeers(data): def checkAndShareObjectWithPeers(data):
""" """
Function is called after either receiving an object off of the wire This function is called after either receiving an object off of the wire
or after receiving one as ackdata. or after receiving one as ackdata.
Returns the length of time that we should reserve to process this message Returns the length of time that we should reserve to process this message
if we are receiving it off of the wire. if we are receiving it off of the wire.
""" """
if len(data) > 2 ** 18:
logger.info('The payload length of this object is too large (%s bytes). Ignoring it.' % len(data))
return
# Let us check to make sure that the proof of work is sufficient. # Let us check to make sure that the proof of work is sufficient.
if not isProofOfWorkSufficient(data): if not isProofOfWorkSufficient(data):
logger.info('Proof of work is insufficient.') logger.info('Proof of work is insufficient.')