DC++ 0.868 is out and marked as stable

A year after the previous version, DC++ 0.868 is now available with various library updates (notably OpenSSL 1.1.1 with TLS 1.3 support) and a revised selection of public hub lists.

The list of public hubs came with the client has been pretty much outdated for some time. A few previously listed servers are already defunct while some are changed their web addresses. Therefore a refreshed list of secure and working hublist servers was long overdue. Many of such new public hublists will get auto-added to your collection upon the update to version 0.868 due to a change of policy regarding hublist server defaults. In the past a change of default hublist servers were not reflected in the actual settings – you had to remove  all existing server entries manually to get the updated defaults. This method, being deemed a bit cumbersome, has changed; in this release the addition will happen automatically and it will be the same in case of any future changes as well. A “Reset hub lists” button is also available in the settings should you want to quickly clean up the list of servers and get back to the defaults.

With the OpenSSL library update, DC++ 0.868 introduces support for TLS version 1.3 and is automatically preferring this newest secure communication standard when connecting to other DC clients and hubs. Backwards compatibility to the earlier versions of the protocol is decided to be maintained, similarly to most of the modern popular web browser software, until at least 2020.

Above the aforemntioned feature updates this is a maintanence release, with a few small updates here and there. There’s also a feature removal: support for the long defunct (and often criticised) Coral CDN network ended with this version.

Due to the useful features and security related fixes an immediate upgrade from earlier versions of DC++ is highly recommended.

 

Disabling TLS 1.0 and 1.1 in DC++ by 2020

Following the IETF’s deprecation of TLS 1.0 and TLS 1.1Chrome, Edge, Firefox, and Safari have announced that they’ll disable both TLS 1.0 and 1.1 during the first half of 2020. GitHubStripeCloudFlarePayPal, and KeyCDN have all already done so on the server side. The deprecated TLS 1.0 dates from 1999 and TLS 1.1 from 2006.

Meanwhile, TLS 1.2 has now existed since 2008 and been supported by OpenSSL 1.0.1 since 2012. DC++, along therefore with modified versions, has supported TLS 1.2 since version 0.850 in 2015. ncdc likewise has supported TLS 1.2 for many years. ADCH++, uhub, and Luadch all support TLS 1.2 or 1.3.

Hardening DC++ Cryptography: TLS, HTTPS, and KEYP and BEAST, CRIME, BREACH, and Lucky 13: Assessing TLS in ADCS document vulnerabilities that TLS 1.0 and 1.1 allow or exacerbate, including but not limited to BEAST, Lucky 13, and potential downgrade attacks discovered in the future in TLS 1.0 or TLS 1.1 to which TLS 1.2 is not subject.

As such, DC++ has deprecated TLS 1.0 and 1.1 and will disable both by default in 2020 along with the browsers, while supporting TLS 1.2, 1.3, and newer versions, with an option to re-enable TLS 1.0 and 1.1 should that remain necessary.

DC++ 0.867 is out – Vulnerability disclosure

DC++ 0.867 has been released and also marked as the stable release. It fixes a serious remotely exploitable vulnerability that would crash the client if a malicious attacker sends trivially compilable malformed search result messages.

The victim should not need to initiate searches and the attacker should not need to be logged on to a hub for a successful exploitation altough the obvious place for finding victims and collecting attack surface information are the DC hubs.

Clients configured to a working active connectivity mode are the easiest targets, especially when logged in to any kind of Direct Connect hubs. Theoretically exploits can be created for clients running in passive mode, too, using possible additional weaknesses in various hub software.

The vulnerability seems to be exist as far back as in version 0.671 (released in 2005) and in all newer releases up to DC++ 0.866. Many other DC clients based on dclib, the core library of DC++ and released over the last 12 years should be vulnerable, too.

The vulnerability report and detalis are now publicly available in the DC++ bug tracker. Updating and using the newest, most secure DC clients has never been more important so the best everyone can do is to head over the DC++ download page and upgrade as soon as possible.

DC++ 0.866 goes stable – Vulnerability disclosure

DC++ 0.866 has been marked as stable today. As it was announced before the new version fixes a serious denial of service problem that can be relatively easily triggered by any malicious user of any hub running without defenses applied.

In short, a specially crafted main chat or private message consisting of large number of empty lines can make older versions of DC++ completely stop responding.

Details of the vulnerability are available in the original bug report entry.

The bug causing this problem exists in all versions of DC++ between 0.760 and 0.865.

Above the client update requirement, hubs can relatively easily mitigate this problem by disallowing any hundreds or thousands line long main chat and private messages to be (repeatedly) sent through the hub.

Since there’s no guarantee of proper hubside defense against this bug being implemented on all connected hubs and the vulnerability can also be exploited by sending messages through a direct encrypted private message channel, we strongly recommend all DC++ users to upgrade to the latest release as soon as possible.

DC++ 0.866

DC++ 0.866 is out. This release fixes a serious issue that allows remote denial of service attacks (ability to freeze the client remotely by any user of the connected hubs).  Besides the hardened security, version 0.866 also improves UPnP port mapping which might fix certain issues with the automatic connectivity setup.

The details of the vulnerability will be disclosed as soon as 0.866 or any forthcoming DC++ release is marked as stable.

DC++ 0.865 is out and marked as stable

DC++ 0.865 has been released with zlib and OpenSSL libraries have been updated. The compression issue found in the previous version has been fixed therefore upgrading to version 0.865 is highly recommended.

DC++ 0.864

DC++ 0.864, along with changes in share filtering and an addition of testing notifications, fixes a stability issue regarding processing of search results. The issue is introduced in the previous release so immediate upgrade for users running version 0.863 is highly recommended.

Edit:

Tests with the 0.864 version of DC++ have uncovered a transfer issue (see https://bugs.launchpad.net/dcplusplus/+bug/1656050) so the release has been removed. It never made it to the “stable” status.

Please keep using version 0.863 for now.

DC++ 0.863

DC++ 0.863, along with minor changes, fixes a stability issue in the 32-bit builds. Furthermore it contains additional optimizations for the benefit of users running DC++ on 32-bit operating systems. DC++ needs SSE3 support from this release on which means it requires Intel Core or AMD A64 X2 or newer CPUs to run. Some steppings of older processors will still work though.

Immediate upgrade for users running 32-bit operating systems is highly recommended.

SSE3 in DC++

The next DC++ release will require SSE3. Steam’s hardware survey currently lists SSE3 as having 99.96% penetration. All AMD and Intel x86 CPUs since the Athlon 64 X2 in 2005 and Intel Core in January 2006 have supported SSE3. Even earlier, though, all Pentium 4 steppings since Prescott which support the NX bit required by Windows 8 and 10 also support SSE3, which extends the effective Intel support back to 2004. I can’t find an Intel CPU which supports NX (required for Win8/10) but not SSE3. Finally, this effectively affects only 32-bit builds, since 64-bit builds exclusively use SSE for floating-point arithmetic.

This effects two basic transformations, one minor and one major, depending on how well the existing code compiles. The minor improvement derives from functions such as bool SettingsDialog::handleClosing() using one instruction rather than two, from

bool SettingsDialog::handleClosing() {
	dwt::Point pt = getWindowSize();
	SettingsManager::getInstance()->set(SettingsManager::SETTINGS_WIDTH,
    cvttss2si eax,DWORD PTR [esp+0x18] ;; eax is just a temporary
    mov    DWORD PTR [edx+0x87c],eax   ;; which is promptly stored to mem

to

bool SettingsDialog::handleClosing() {
	dwt::Point pt = getWindowSize();
	SettingsManager::getInstance()->set(SettingsManager::SETTINGS_WIDTH,
    fisttp DWORD PTR [edx+0x87c]      ;; no byway through eax (also, less register pressure)

However, sometimes cvttss2si and related SSE/SSE2 instructions don’t fit as well, so g++ had been relying on fistp. These instances previously produced terrible code generation; without SSE3, only using through SSE2, part of void SearchFrame::runSearch() compiles to:

	auto llsize = static_cast(lsize);
    fnstcw WORD PTR [ebp-0x50e]     ;; save FP control word to mem
    movzx  eax,WORD PTR [ebp-0x50e] ;; zero-extend-move it to eax
    mov    ah,0xc                   ;; build new control word
    mov    WORD PTR [ebp-0x510],ax  ;; place control word in mem for fldcw
    fld    QWORD PTR [ebp-0x520]    ;; load lsize from mem (same as below)
    fldcw  WORD PTR [ebp-0x510]     ;; load new control word
    fistp  QWORD PTR [ebp-0x548]    ;; with correct control word, round lsize
    fldcw  WORD PTR [ebp-0x50e]     ;; restore previous control word

All 6 red-highlighted lines just scaffold around the actual fistp doing the floating point-to-int rounding, which can cost 80 cycles or more for this single innocuous-looking line of code. By contrast, using fisttp from SSE3, that same fragment collapses to:

	auto llsize = static_cast(lsize);
    fld    QWORD PTR [ebp-0x520]    ;; same as above; load lsize
    fisttp QWORD PTR [ebp-0x548]    ;; convert it. simple.

This pattern recurs many times through DC++, including void AdcHub::handle(AdcCommand::GET which has a portion halving in size and dramatically increasing in speed from

		// Ideal size for m is n * k / ln(2), but we allow some slack
		// When h >= 32, m can't go above 2^h anyway since it's stored in a size_t.
		if(m > (5 * Util::roundUp((int64_t)(n * k / log(2.)), (int64_t)64)) || (h < 32 && m > static_cast(1U << h))) {
    mov    DWORD PTR [esp+0x1c],edi
    xor    ecx,ecx
    imul   eax,DWORD PTR [esp+0x18]
    movd   xmm0,eax
    movq   QWORD PTR [esp+0x58],xmm0
    fild   QWORD PTR [esp+0x58]
    fdiv   QWORD PTR ds:0xca8
    fnstcw WORD PTR [esp+0x22]     ;; same control word dance as before
    movzx  eax,WORD PTR [esp+0x22]
    mov    ah,0xc                  ;; same control word
    mov    WORD PTR [esp+0x20],ax  ;; but fldcw loads from mem not reg
    fldcw  WORD PTR [esp+0x20]     ;; load C and C++-compatible rounding mode
    fistp  QWORD PTR [esp+0x58]    ;; the actual conversion
    fldcw  WORD PTR [esp+0x22]     ;; restore previous
    mov    eax,DWORD PTR [esp+0x58]
    mov    edx,DWORD PTR [esp+0x5c]

to, using the fisttp SSE3 instruction,

		// Ideal size for m is n * k / ln(2), but we allow some slack
		// When h >= 32, m can't go above 2^h anyway since it's stored in a size_t.
		if(m > (5 * Util::roundUp((int64_t)(n * k / log(2.)), (int64_t)64)) || (h < 32 && m > static_cast(1U << h))) {
    mov    DWORD PTR [esp+0x20],edi
    xor    ecx,ecx
    imul   eax,DWORD PTR [esp+0x1c]
    movd   xmm0,eax
    movq   QWORD PTR [esp+0x58],xmm0
    fild   QWORD PTR [esp+0x58]
    fdiv   QWORD PTR ds:0xca8
    fisttp QWORD PTR [esp+0x58]    ;; replaces all seven red lines
    mov    eax,DWORD PTR [esp+0x58]
    mov    edx,DWORD PTR [esp+0x5c]

This specific control word save/convert float/control word restore pattern recurs 19 other times across the current codebase in the dcpp, dwt, and win32 directories, including DownloadManager::getRunningAverage(); HashBloom::get_m(size_t n, size_t k); QueueItem::getDownloadedBytes(); Transfer::getParams(); UploadManager::getRunningAverage(); Grid::calcSizes(…); HashProgressDlg::updateStats(); TransferView::on(HttpManagerListener::Updated, …); and TransferView::onTransferTick(…).

Know your FPU: Fixing Floating Fast provides microbenchmarks showing just how slow this fistp-based technique can be due to the fnstcw/fldcw 80+-cycle FPU pipeline flush and therefore how much faster code which replaces it can become:

Fixed tests...
Testing ANSI fixed() ... Time = 2974.57 ms
Testing fistp fixed()... Time = 3100.84 ms
Testing Sree fixed() ... Time =  606.80 ms

SSE3 provides not simply some hidden code generation aesthetic quality improvement, but a speed increase across much of DC++.

Why DCNF uses HTTPS via Let’s Encrypt

All DCNF web services either use HTTPS or are being transitioned to HTTPS.

The US government’s HTTPS-only standard and Google’s “Why HTTPS Matters” describe how HTTPS enables increased website privacy, security, and integrity in general. ISPs, home routers, and antivirus software have all been caught modifying HTTP traffic, for example, which HTTPS hinders. HTTPS also increases Google’s search ranking and, via HTTP/2, decreases website loading time.

Somewhat more forcefully, Chrome 56 will warn users of non-HTTPS login forms, as does Firefox 50 beta and according to schedule, will Firefox 51. This will become important, for example, for the currently-under-maintenance DCBase forums.

Beyond the obvious advantages of not costing money, Let’s Encrypt provides important reduced friction versus alternatives in automatically and therefore scalably managing certificates for multiple subdomains, as well as ameliorating certificate revocation and security-at-rest importance and thereby HTTPS management overhead by such automation allowing more shorter-lived certificates and more rapid renewal. Additionally, as crypto algorithms gain and lose favor, such quick renewals catalyze agility. These HTTPS, in general, and Let’s Encrypt, specifically, advantages have led to adopting HTTPS using Let’s Encrypt.