1 /***************************************************************************
2 * *
3 * This program is free software; you can redistribute it and/or modify *
4 * it under the terms of the GNU General Public License as published by *
5 * the Free Software Foundation; either version 3 of the License, or *
6 * (at your option) any later version. *
7 * *
8 ***************************************************************************/
9
10 #include "SettingsConnection.h"
11 #include "MainWindow.h"
12 #include "WulforSettings.h"
13 #include "WulforUtil.h"
14
15 #include "dcpp/stdinc.h"
16 #include "dcpp/SettingsManager.h"
17 #include "dcpp/Socket.h"
18
19 #include <QLineEdit>
20 #include <QRadioButton>
21 #include <QList>
22 #include <QMessageBox>
23 //#define DEBUG_CONNECTION
24 #ifdef DEBUG_CONNECTION
25 #include <QtDebug>
26 #endif
27 using namespace dcpp;
28
29 #ifndef IPTOS_TOS_MASK
30 #define IPTOS_TOS_MASK 0x1E
31 #endif
32 #ifndef IPTOS_TOS
33 #define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK)
34 #endif
35 #ifndef IPTOS_LOWDELAY
36 #define IPTOS_LOWDELAY 0x10
37 #endif
38 #ifndef IPTOS_THROUGHPUT
39 #define IPTOS_THROUGHPUT 0x08
40 #endif
41 #ifndef IPTOS_RELIABILITY
42 #define IPTOS_RELIABILITY 0x04
43 #endif
44 #ifndef IPTOS_LOWCOST
45 #define IPTOS_LOWCOST 0x02
46 #endif
47 #ifndef IPTOS_MINCOST
48 #define IPTOS_MINCOST IPTOS_LOWCOST
49 #endif
50
51
SettingsConnection(QWidget * parent)52 SettingsConnection::SettingsConnection( QWidget *parent):
53 QWidget(parent),
54 dirty(false)
55 {
56 setupUi(this);
57
58 init();
59 }
60
eventFilter(QObject * obj,QEvent * e)61 bool SettingsConnection::eventFilter(QObject *obj, QEvent *e){
62 if ((e->type() == QEvent::KeyRelease) || (e->type() == QEvent::MouseButtonRelease))//May be some settings has been changed
63 dirty = true;
64
65 return QWidget::eventFilter(obj, e);
66 }
67
ok()68 void SettingsConnection::ok(){
69
70 bool active = !radioButton_PASSIVE->isChecked();
71 SettingsManager *SM = SettingsManager::getInstance();
72
73 int old_mode = SETTING(INCOMING_CONNECTIONS);
74 SM->set(SettingsManager::AUTO_DETECT_CONNECTION, checkBox_AUTO_DETECT_CONNECTION->isChecked());
75 if (active){
76 if (radioButton_ACTIVE->isChecked())
77 SM->set(SettingsManager::INCOMING_CONNECTIONS, SettingsManager::INCOMING_DIRECT);
78 else if (radioButton_PORT->isChecked())
79 SM->set(SettingsManager::INCOMING_CONNECTIONS, SettingsManager::INCOMING_FIREWALL_NAT);
80 #if (defined USE_MINIUPNP)
81 else
82 SM->set(SettingsManager::INCOMING_CONNECTIONS, SettingsManager::INCOMING_FIREWALL_UPNP);
83 #endif
84 SM->set(SettingsManager::TCP_PORT, spinBox_TCP->value());
85 SM->set(SettingsManager::UDP_PORT, spinBox_UDP->value());
86
87 if (spinBox_TLS->value() != SETTING(TCP_PORT))
88 SM->set(SettingsManager::TLS_PORT, spinBox_TLS->value());
89 else
90 SM->set(SettingsManager::TLS_PORT, spinBox_TLS->value()+1);
91
92 SM->set(SettingsManager::EXTERNAL_IP, lineEdit_WANIP->text().toStdString());
93 QString bind_ip=lineEdit_BIND_ADDRESS->text();
94 if (validateIp(bind_ip))
95 SM->set(SettingsManager::BIND_ADDRESS, lineEdit_BIND_ADDRESS->text().toStdString());
96 SM->set(SettingsManager::NO_IP_OVERRIDE, checkBox_DONTOVERRIDE->checkState() == Qt::Checked);
97 }
98 else {
99 SM->set(SettingsManager::INCOMING_CONNECTIONS, SettingsManager::INCOMING_FIREWALL_PASSIVE);
100 }
101
102 bool use_socks = !radioButton_DC->isChecked();
103 int type = SETTING(OUTGOING_CONNECTIONS);
104
105 SM->set(SettingsManager::BIND_IFACE, radioButton_BIND_IFACE->isChecked());
106 SM->set(SettingsManager::BIND_IFACE_NAME, _tq(comboBox_IFACES->currentText()));
107
108 if (use_socks){
109 QString ip = lineEdit_SIP->text();
110
111 if (!validateIp(ip)){
112 showMsg(tr("No valid SOCKS5 server IP found!"), NULL);
113
114 return;
115 }
116
117 int port = lineEdit_SPORT->text().toInt();
118
119 SM->set(SettingsManager::SOCKS_SERVER, lineEdit_SIP->text().toStdString());
120 SM->set(SettingsManager::SOCKS_USER, lineEdit_SUSR->text().toStdString());
121 SM->set(SettingsManager::SOCKS_PASSWORD, lineEdit_SPSWD->text().toStdString());
122 SM->set(SettingsManager::SOCKS_RESOLVE, checkBox_RESOLVE->checkState() == Qt::Checked);
123 SM->set(SettingsManager::OUTGOING_CONNECTIONS, SettingsManager::OUTGOING_SOCKS5);
124
125 if (port > 0 && port <= 65535)
126 SM->set(SettingsManager::SOCKS_PORT, port);
127 }
128 else{
129 SM->set(SettingsManager::OUTGOING_CONNECTIONS, SettingsManager::OUTGOING_DIRECT);
130 }
131
132 if (SETTING(OUTGOING_CONNECTIONS) != type)
133 Socket::socksUpdated();
134
135 SM->set(SettingsManager::THROTTLE_ENABLE, checkBox_THROTTLE_ENABLE->isChecked());
136 SM->set(SettingsManager::TIME_DEPENDENT_THROTTLE, checkBox_TIME_DEPENDENT_THROTTLE->isChecked());
137 SM->set(SettingsManager::MAX_DOWNLOAD_SPEED_MAIN, spinBox_DOWN_LIMIT_NORMAL->value());
138 SM->set(SettingsManager::MAX_UPLOAD_SPEED_MAIN, spinBox_UP_LIMIT_NORMAL->value());
139 SM->set(SettingsManager::MAX_DOWNLOAD_SPEED_ALTERNATE, spinBox_DOWN_LIMIT_TIME->value());
140 SM->set(SettingsManager::MAX_UPLOAD_SPEED_ALTERNATE, spinBox_UP_LIMIT_TIME->value());
141 SM->set(SettingsManager::BANDWIDTH_LIMIT_START, spinBox_BANDWIDTH_LIMIT_START->value());
142 SM->set(SettingsManager::BANDWIDTH_LIMIT_END, spinBox_BANDWIDTH_LIMIT_END->value());
143 SM->set(SettingsManager::SLOTS_ALTERNATE_LIMITING, spinBox_ALTERNATE_SLOTS->value());
144 SM->set(SettingsManager::RECONNECT_DELAY, spinBox_RECONNECT_DELAY->value());
145 SM->set(SettingsManager::IP_TOS_VALUE, comboBox_TOS->itemData(comboBox_TOS->currentIndex()).toInt());
146 SM->set(SettingsManager::DYNDNS_SERVER, lineEdit_DYNDNS_SERVER->text().toStdString());
147 SM->set(SettingsManager::DYNDNS_ENABLE, checkBox_DYNDNS->isChecked());
148
149 #ifdef WITH_DHT
150 SM->set(SettingsManager::USE_DHT, groupBox_DHT->isChecked());
151 if (spinBox_DHT->value() != SETTING(UDP_PORT))
152 SM->set(SettingsManager::DHT_PORT, spinBox_DHT->value());
153 else
154 SM->set(SettingsManager::DHT_PORT, spinBox_DHT->value()+1);
155
156 if (!(old_dht < 1024) && (SETTING(DHT_PORT) < 1024))
157 showMsg(tr("Program need root privileges to open ports less than 1024"), NULL);
158 #endif
159 SM->set(SettingsManager::ALLOW_UNTRUSTED_CLIENTS, checkBox_UNTRUSTED_CLIENTS->isChecked());
160 SM->set(SettingsManager::ALLOW_UNTRUSTED_HUBS, checkBox_UNTRUSTED_HUBS->isChecked());
161
162 SM->set(SettingsManager::USE_TLS, (comboBox_TLS->currentIndex() == 1) || (comboBox_TLS->currentIndex() == 2));
163 SM->set(SettingsManager::REQUIRE_TLS, (comboBox_TLS->currentIndex() == 2));
164
165 if (old_mode != SETTING(INCOMING_CONNECTIONS) || old_tcp != (SETTING(TCP_PORT))
166 || old_udp != (SETTING(UDP_PORT)) || old_tls != (SETTING(TLS_PORT)))
167 {
168 if (!(old_tcp < 1024 || old_tls < 1024 || old_udp < 1024) &&
169 (SETTING(TCP_PORT) < 1024 || SETTING(UDP_PORT) < 1024 || SETTING(TLS_PORT) < 1024))
170 showMsg(tr("Program need root privileges to open ports less than 1024"), NULL);
171
172 MainWindow::getInstance()->startSocket(true);
173 }
174 }
175
init()176 void SettingsConnection::init(){
177 lineEdit_WANIP->setText(QString::fromStdString(SETTING(EXTERNAL_IP)));
178 lineEdit_BIND_ADDRESS->setText(QString::fromStdString(SETTING(BIND_ADDRESS)));
179
180 spinBox_TCP->setValue(old_tcp = SETTING(TCP_PORT));
181 spinBox_UDP->setValue(old_udp = SETTING(UDP_PORT));
182 spinBox_TLS->setValue(old_tls = SETTING(TLS_PORT));
183 checkBox_AUTO_DETECT_CONNECTION->setChecked(BOOLSETTING(AUTO_DETECT_CONNECTION));
184 checkBox_THROTTLE_ENABLE->setChecked(BOOLSETTING(THROTTLE_ENABLE));
185 checkBox_TIME_DEPENDENT_THROTTLE->setChecked(BOOLSETTING(TIME_DEPENDENT_THROTTLE));
186 spinBox_DOWN_LIMIT_NORMAL->setValue(SETTING(MAX_DOWNLOAD_SPEED_MAIN));
187 spinBox_UP_LIMIT_NORMAL->setValue(SETTING(MAX_UPLOAD_SPEED_MAIN));
188 spinBox_DOWN_LIMIT_TIME->setValue(SETTING(MAX_DOWNLOAD_SPEED_ALTERNATE));
189 spinBox_UP_LIMIT_TIME->setValue(SETTING(MAX_UPLOAD_SPEED_ALTERNATE));
190 spinBox_BANDWIDTH_LIMIT_START->setValue(SETTING(BANDWIDTH_LIMIT_START));
191 spinBox_BANDWIDTH_LIMIT_END->setValue(SETTING(BANDWIDTH_LIMIT_END));
192 spinBox_ALTERNATE_SLOTS->setValue(SETTING(SLOTS_ALTERNATE_LIMITING));
193 spinBox_RECONNECT_DELAY->setValue(SETTING(RECONNECT_DELAY));
194 checkBox_DONTOVERRIDE->setCheckState( SETTING(NO_IP_OVERRIDE)? Qt::Checked : Qt::Unchecked );
195 checkBox_DYNDNS->setCheckState( BOOLSETTING(DYNDNS_ENABLE) ? Qt::Checked : Qt::Unchecked );
196 lineEdit_DYNDNS_SERVER->setText(QString::fromStdString(SETTING(DYNDNS_SERVER)));
197
198 #ifdef WITH_DHT
199 groupBox_DHT->setChecked(BOOLSETTING(USE_DHT));
200 spinBox_DHT->setValue(old_dht = SETTING(DHT_PORT));
201 #else
202 groupBox_DHT->hide();
203 #endif
204
205 checkBox_UNTRUSTED_CLIENTS->setChecked(SETTING(ALLOW_UNTRUSTED_CLIENTS));
206 checkBox_UNTRUSTED_HUBS->setChecked(SETTING(ALLOW_UNTRUSTED_HUBS));
207
208 comboBox_TLS->setCurrentIndex(0);
209 if (SETTING(USE_TLS)) {
210 comboBox_TLS->setCurrentIndex(1);
211 }
212 if (SETTING(REQUIRE_TLS)) {
213 comboBox_TLS->setCurrentIndex(2);
214 }
215
216 QStringList ifaces = WulforUtil::getInstance()->getLocalIfaces();
217
218 if (!ifaces.isEmpty())
219 comboBox_IFACES->addItems(ifaces);
220
221 comboBox_IFACES->addItem("");
222
223 if (SETTING(BIND_IFACE)){
224 radioButton_BIND_IFACE->toggle();
225
226 if (ifaces.contains(_q(SETTING(BIND_IFACE_NAME))))
227 comboBox_IFACES->setCurrentIndex(ifaces.indexOf(_q(SETTING(BIND_IFACE_NAME))));
228 else
229 comboBox_IFACES->setCurrentIndex(comboBox_IFACES->count()-1);
230 }
231 else
232 radioButton_BIND_ADDR->toggle();
233
234 switch (SETTING(INCOMING_CONNECTIONS)){
235 case SettingsManager::INCOMING_DIRECT:
236 {
237 radioButton_ACTIVE->setChecked(true);
238
239 break;
240 }
241 case SettingsManager::INCOMING_FIREWALL_NAT:
242 {
243 radioButton_PORT->setChecked(true);
244
245 break;
246 }
247 case SettingsManager::INCOMING_FIREWALL_PASSIVE:
248 {
249 radioButton_PASSIVE->setChecked(true);
250
251 break;
252 }
253 #if (defined USE_MINIUPNP)
254 case SettingsManager::INCOMING_FIREWALL_UPNP:
255 {
256 radioButton_UPNP->setChecked(true);
257
258 break;
259 }
260 #endif
261 }
262 #if (!defined USE_MINIUPNP)
263 radioButton_UPNP->setEnabled(false);
264 #endif
265
266 lineEdit_SIP->setText(QString::fromStdString(SETTING(SOCKS_SERVER)));
267 lineEdit_SUSR->setText(QString::fromStdString(SETTING(SOCKS_USER)));
268 lineEdit_SPORT->setText(QString().setNum(SETTING(SOCKS_PORT)));
269 lineEdit_SPSWD->setText(QString::fromStdString(SETTING(SOCKS_PASSWORD)));
270
271 checkBox_RESOLVE->setCheckState( SETTING(SOCKS_RESOLVE)? Qt::Checked : Qt::Unchecked );
272
273 switch (SETTING(OUTGOING_CONNECTIONS)){
274 case SettingsManager::OUTGOING_DIRECT:
275 {
276 radioButton_DC->toggle();
277
278 break;
279 }
280 case SettingsManager::OUTGOING_SOCKS5:
281 {
282 radioButton_SOCKS->toggle();
283
284 break;
285 }
286 }
287
288 comboBox_TOS->setItemData(0, -1);
289 comboBox_TOS->setItemData(1, IPTOS_LOWDELAY);
290 comboBox_TOS->setItemData(2, IPTOS_THROUGHPUT);
291 comboBox_TOS->setItemData(3, IPTOS_RELIABILITY);
292 comboBox_TOS->setItemData(4, IPTOS_MINCOST);
293
294 for (int i = 0; i < comboBox_TOS->count(); i++){
295 if (comboBox_TOS->itemData(i).toInt() == SETTING(IP_TOS_VALUE)){
296 comboBox_TOS->setCurrentIndex(i);
297
298 break;
299 }
300 }
301
302 slotToggleIncomming();
303 slotToggleOutgoing();
304
305 connect(radioButton_ACTIVE, SIGNAL(toggled(bool)), this, SLOT(slotToggleIncomming()));
306 connect(radioButton_PORT, SIGNAL(toggled(bool)), this, SLOT(slotToggleIncomming()));
307 connect(radioButton_PASSIVE, SIGNAL(toggled(bool)), this, SLOT(slotToggleIncomming()));
308 #if (defined USE_MINIUPNP)
309 connect(radioButton_UPNP, SIGNAL(toggled(bool)), this, SLOT(slotToggleIncomming()));
310 #endif
311 connect(radioButton_DC, SIGNAL(toggled(bool)), this, SLOT(slotToggleOutgoing()));
312 connect(radioButton_SOCKS, SIGNAL(toggled(bool)), this, SLOT(slotToggleOutgoing()));
313
314 lineEdit_SIP->installEventFilter(this);
315 lineEdit_SPORT->installEventFilter(this);
316 lineEdit_SPSWD->installEventFilter(this);
317 lineEdit_SUSR->installEventFilter(this);
318 lineEdit_WANIP->installEventFilter(this);
319
320 spinBox_TCP->installEventFilter(this);
321 spinBox_UDP->installEventFilter(this);
322 spinBox_TLS->installEventFilter(this);
323
324 radioButton_ACTIVE->installEventFilter(this);
325 radioButton_DC->installEventFilter(this);
326 radioButton_PASSIVE->installEventFilter(this);
327 radioButton_PORT->installEventFilter(this);
328 radioButton_SOCKS->installEventFilter(this);
329 #if (defined USE_MINIUPNP)
330 radioButton_UPNP->installEventFilter(this);
331 #endif
332 checkBox_DONTOVERRIDE->installEventFilter(this);
333 checkBox_RESOLVE->installEventFilter(this);
334 }
335
slotToggleIncomming()336 void SettingsConnection::slotToggleIncomming(){
337 bool b = !radioButton_PASSIVE->isChecked();
338
339 frame->setEnabled(b);
340 }
341
slotToggleOutgoing()342 void SettingsConnection::slotToggleOutgoing(){
343 bool b = !radioButton_DC->isChecked();
344
345 frame_2->setEnabled(b);
346 }
validateIp(QString & ip)347 bool SettingsConnection::validateIp(QString &ip){
348 if (ip.isEmpty() || ip.isNull())
349 return false;
350
351 QStringList l = ip.split(".", QString::SkipEmptyParts);
352
353 if (l.size() != 4)
354 return false;
355
356 QIntValidator v(0, 255, this);
357
358 bool valid = true;
359 int pos = 0;
360
361 for (QString s : l)
362 valid = valid && (v.validate(s, pos) == QValidator::Acceptable);
363
364 return valid;
365 }
366
showMsg(QString msg,QWidget * focusTo)367 void SettingsConnection::showMsg(QString msg, QWidget *focusTo){
368 QMessageBox::warning(this, tr("Warning"), msg);
369
370 if (focusTo)
371 focusTo->setFocus();
372 }
373