Boo(s)t up your DC++

While (especially the past entries of) this blog contains numerous great information about DC++ internals almost in a knowledge base manner, you can’t find any reference to an useful feature  introduced way back in DC++ 0.695. The feature itself is actually in the dcpp lilbrary and I believe it has been made in favour of  *nix ports. It allows the user to specify different folder than the program directory to store config files, temporary data and downloads (by default).  The custom folder can be set in a standalone config file called dcppboot.xml, specifying a path relative to the DC++ executable. If you open up the file you’ll see some usage instructions in the comments.

The configuration parameter can’t be set from DC++ GUI, it can be altered only by manually editing the file. The feature works well under Windows as well, however its rarely used in this platform.  In Windows XP there are no problems accessing (settings) files located besides the executable in the %PROGRAMFILES% folder, even though since the release of Windows 2000, Microsoft recommended using %APPDATA% folders for this purpose.

Problems started growing with the arrival of Windows Vista. According to the years long recommendations (which became expectations over the years), Microsoft introduced User State Virtualization which arose problems described eg. in this support FAQ. dcppboot.xml is (one of the many not too nice) existing solution for Vista users, still, DC++ definiately needed a better way to solve this.

The solution came with DC++ 0.75 as the available parameters of dcppboot.xml are extended in a simple way what suddenly solves all the problems  described earlier. Usage instructions are updated in the comments inside the file as you can see in the repostitory.

The new parameter is called LocalMode and when it is set to zero, all configuration files are stored in the appropriate user folder inside %APPDATA%.
For Windows 2000/XP, settings will be placed into %APPDATA%\DC++, temporary files to %APPDATA%\Local Settings\Application Data\DC++ and you’ll find your downloads in %APPDATA%\DC++\Downloads by default.
In Vista and Windows 7, these will be, respectively (assuming default Windows configs): %APPDATA%\DC++ (expands to C:\Users\[your-nick]\AppData\Roaming\DC++); C:\Users\[your-nick]\AppData\Local\DC++; My documents\Downloads.

The default mode is kept (DC++ runs in LocalMode) when you use the zipped binary archive. However, if you install DC++ with the installer, you’ll have a different dcppboot.xml file installed (existing dcppboot will be overridden) so DC++ will use the user profile folders for storing its settings per user.

The best thing is that these changes will be transparent to the average user even if  they upgrade DC++ using the installer. A nice automatic migrate function added and it takes care of moving settings files to the user profile if LocalMode set to false (zero). This is a one way migration only though; if your settings, etc… are already in the user profile and you want to switch back to local mode, you should edit dcppboot then move your settings files back to program folder manually.

DC++ 0.75

A new version of DC++ has just out and (as you may noticed a bigger leap in the versioning) this seems to be a milestone release. This version is a result of a certain period of development and may start a new era in the ever progressing history of DC++. We can assume that every required adaptations and problems are solved since DC++ switched to an open source compiler, changed  GUI library and introduced a new (segmented) download method.

While the previous version was pretty stable and had all major bugs fixed, this new release focuses to fix bugs that can occour in less common situations. Along with these fixes DC++ 0.75  introcuces a few important improvements as well.

GUI changes

  • By popular demand, a possibility added to unmerge search results for same files. In other words this means that in certain situations when merged results aren’t an advantage, you have the option to organize your search results the same way as before.
  • User interface elements are automatically resized according to the length of the text they hold. It results not just nicely arranged controls; from now, all longer GUI translations will fit so there’s no need to use ugly abbreviations anymore.  (To all translators: its time to review your GUI translations! :) )

Fixed bugs :

  • Fixed compatibility (non-segmented) mode downloads so they always resume correclty if you restart DC++. Also fixed a problem that in some cases DC++ still used chunks in this mode.
  • Fixed a possible crash when two or more shared directories have the same virtual name. This bug could hit those who have very large number of files shared (total share over 1 TiB).
  • Fixed error handling when file lists and zlib transfers are decompressed. This could cause crash in special cases.
  • No more crashes when you remove several hundreds of elements from the finished transfers’ lists.

Improvements :

  • A possibility added to recheck integrity of partially downloaded files. This is useful in case of any disk error,  but the main advantage it brings is the ablility to easily resume large unfinished downloads when your download queue lost or damaged.  Read more in the updated Resume FAQ.
  • From now DC++ optionally uses the user profile folder for default download target and also for storing settings and temporary files (hublists cache, file lists, etc…).  This feture will be most welcomed by Vista and Windows 7 users as it should eliminate UAC warnings in most cases. If you use the installer to install DC++, it will be configured to use profile folders. If installed from the .zip archive manually, settings and downloads will be placed the old way (to the program folder).
  • Translating DC++ Help file to several languages are progressed a lot

For the complete list of changes refer to the changelog.

DCDev goes ADCS

Since today, our public hub has moved from simple ADC to ADCS, aka ADC Secure. If you connected today and noticed that your client just printed out “Connected…” and that’s it, it’s because of that. You need to go to your favorites and change the address from adc:// to adcs:// , this means the DNS is the same, just the protocol handler changed.

So the hub address is now adcs://devpublic.adcportal.com:16591
You are welcome with suggestions, questions or whatever springs to your mind.

DC++ pointing out the corrupted

One of the latest enhancements in DC++ is the hub referral on client-client connections, proposed by Jan Vidar Krey. The current bazaar trunk implements this mechanism and the next DC++ version that will be released soon will also have it. The purpose of this extension is to point out the corrupted hub that is sending the current client to a non DC client, with obvious malevolent purpose. This implies that the hub is either using exploitable software, or that it’s intentionally abusing the clients. Either way, the hubowners are solely responsible.

On connecting to the other party, DC++ will also send the hub URL that it used to connect to the hub sending out the CTM message. By packet inspection, an attacked party can figure out which is the corrupted hub (only a pointer is required, such that they have a point of reference ) . Another good part about this extension is that it works on both ADC and NMDC ( some workaround was found for NMDC: adding the url to the PK string since NMDC is not extensible nor flexible in this matter ) , with the least effort from the clients and it does not bother them in any way. A normal client should ignore the specific message ( I don’t find any particular usage for it ).

We strongly recommend all mods to inherit this extension and other clients out there to implement it so the CTM attacks impact on DC software will stop being so great.

DC++ CTM Proof

In a previous post I was wondering if the whole concept of centralization is obsolete or has major flaws. The problem that is bothering everybody in the last years is that clients can be used ( unwillingly ) as tools in distributed denial of service attacks. Jan Vidar Krey is proposing a hub refferal on c-c connections that can point to a source of CTM attacks via the messages that the client sends on first connection attempt. In this case an attacked entity can see the hub with problems/intentional flooding that is causing the attacks.

As a first step to prevent this kind of abuses in DC++, poy added a static IP protection for the major hublists that were attacked via the client. This kind of measure is just temporary since hublists can change IP anytime and it protects only them, not everybody else that can be attacked ( Also the fun part is that the hublist server is actually running a DC client and wants to download from other users, it can’t ! ) .  A second step was to dynamically resolve the hublist ip’s and block them for c-c connections.

The main idea that I considered is to practically check all the users on a specific hub to see if they actually are real. On CTM receive the client should not connect but send another CTM to see if that IP actually connects to them . This will make sure that the user is the actual owner of that specific IP address. Of course the biggest problem is if the user is passive, in which case it can’t send a CTM back. This could be against the protocol principles but it’s a solution to see if the other peer really exists. I don’t know if a RCM would do something good in this situation but it’s a start.

Another thing that should be done ( if not implemented already ) is that on c-c connections if the first attempt was unsuccessful then no further attempts should be done until the user at least reconnects or changes state ( passive/active ). Also the hubs should be trustworthy. In a previous post I suggested a way to make hubs trustful via a CA authority system, but most people were quite reticent about it. Perhaps this could be the only way to make hubs trustful. Warning messages will not help too much ( Strong DC implements such messages ) since most of the users either don’t read them or don’t care. We shouldn’t let users question this problem, but solve it for them. Continuous problems from the Direct Connect network might be a cause to mark DC software ( and DC++ ) as badware, which will definitely take down the network. It’s time to do something about it.

I’m hoping for more ideas how to make DC++ proof against CTM abuses and I’m waiting for opinions from you as well.

Are centralized networks doomed from the start ?

Recently I heard bad rumors around the DC network. Some malevolent person ( unknown ) has written several scripts for the most known DC hub software, that allow the hub owners to use their users in abusive forms of flooding, using the CTM feature of the protocol. These scripts have started to spread around and now “script kiddies” use it for flame wars and endless childish attacks.

Also, important sites that currently hold on the DC community like the major hublists OpenHublist or DCHublist and the ADC counterpart ADCHublist were attacked and were down for a long time. The major community for ADC , ADCPortal was also attacked ( ADCPortal also provide an alternative wiki to the one on the ADC Project ).

My first concern is that this problem can spread up to the centralized networks principle. In this case, the central node ( hub ) has the power to absolutely control the leaves that are connected, thus it can abusively send them in possible attacks at wish. This might be a serious problem for the centralized networks.

Secure policies have to be enabled in clients and hubs so that this kind of flaws do not affect the community. I don’t know yet if it’s possible in this current situation or the whole concept of centralization is flawed. I hope not, because the Direct Connect community has it’s advantages and there are a lot of people involved and which benefit from it every day.

My advice from the users: make sure you actually know what hubs you are using, and how your client can be abusively used for other purposes than the ones designed, and make sure you are using a proper firewall and perhaps package inspection to see if your computer is not part of a BotNet or similar flooding network.

And one last thing, Happy new year and all the best from the DC++ team.

Help translation

In DC++ 0.7091 you might have noticed a few translated help files. They use po4a and the process to generate them is now mature enough.

So feel free to join the Launchpad translations area for DC++ and chip in!

You’ll encounter HTML tags here and there; make sure you keep them in your translations.

DC++ 0.7091

We are happy to announce that the new version of DC++ is available for download. It’s been about 5 months since the last stable release and numerous improvements and bug fixes come with this new version.

The most interesting GUI changes are as follows:

  • You can set the maximum width of the tabs as you like (no more truncated hub names)
  • Finished Uploads & Downloads windows are refined, from now you can filter to show only 100% finished downloads.
  • Added a popular option to always have a tray icon displayed for quick access
  • Numerous small improvements in the search window
  • DC++ should really remember the positions of all splitters, column orders and column sizes
  • Up-down control in the main status bar to change the number of upload slots quickly

Important bugs fixed :

  • Shell menus are restructured and loaded only if they needed. This also eliminates possible crashes when opening the shell menu under Vista.
  • In some cases it was impossible to add all the found sources to the queue from the search window
  • A possible crash if some ADL Search elements set to auto-download fixed
  • Fixed a possible lockup at start when the download queue has too many directories on Vista
  • Solved a problem which could cause crashes when tabs closed

Other changes and improvements :

  • Automatch queue for all search results is always on from now
  • Partial file list requests are visible in download queue so they can be deleted in case of connection problems
  • The whole Help file became translatable and a few partially translated Help files are added to the release. The localized Help file and tooltips are shown automatically according to the current locale settings

For the complete list of changes refer to the changelog.

Unlike the previous unstable release ( 0.708 ) this new version is tested and found highly stable. As usual it will be marked stable only after the two weeks public test period but the upgrade is recommended even before – especially for Vista users.

The case of a missing tree

Recently when I downloaded some files from an user I came across a situation which seemed a bit confusing at first sight. The user (I knew him before) is from another country and while he has a fast connection with nice upload speeds, the connection to him is usually not fully trouble free: my downloads from him are usually disonnect in every 10-20 minutes with timeout. This is a small problem I know, but this will be a key of this story as you’ll see later…

So I queued up some folders with larger files (there were no other sources available) and left DC++ to download in the background. Sometime later when I came back, I realized that only a couple of smaller files are downloaded so far, despite that the speed of the file transfer was still as nice as usual. When I checked the current transfer in the Connections Tab I found a very suprising fact : the file has been downloaded in one chunk and the chunk size was equal to the file size! Cheking the Finished Downloads window made the problem more mysterious : it said that 150% (!) of the current file has already been transferred…

Since segmented download method introduced DC++ does not create one large chunkfor a download except when segmented downloads are disabled. The size of the chunks are automatically adjusted depending on how fast are the transfers and how many percent left from the current download. Faster transfers result bigger chunk sizes but a chunk never reaches the overall file size unless the file is very small. In this case (as always) I had segmented downloads enabled.

As I thought that this can be a bug, I tried to disconnect the download manually to see if the chunk sizes go normal after reconnect. There came another suprise then : the download wasn’t resumed at all, it started from the beginning and still with that huge chunk size! At this point I understood why this download didn’t finished at all. As I mentioned before there are plenty of disconnects happened during the download from this user so the actual file (which was a pretty large one) wasn’t able to finish. But… why ?!?

The user had a fairly new DC client so incompatibility was ruled out. I checked the download from other users – they worked as they should: normal chunk sizes and successful resume on reconnect. Then I thought I try to get more files from this problematic user and… would you believe or not: some of the files are worked well while others still didn’t! However, this last strangeness started to ring the bell at last…

I asked the user to rebuild his share and… voilà things started to work normally right away. The problem was with his hashdata file, it became partially corrupted. Hash trees of the shared (and queued) files are stored in the hashdata so the other client failed to provide the correct tree information.

Now we found the problem but you may ask: why the hash tree needed to resume an unfinished download? Or: why’s it needed to get smaller parts of a download from more sources at the same time?

Before segmented downloading there were two methods in DC++ for resume a download. Both became more or less obsolete when chunks arrived because since then, the downloaded part of an unfinished file isn’t a contigous data. There’s no certain point to resume the download from as before. Now the unfinished temporary file is fully allocated and it contains non-contigous segments of finished and unfinished data. The size of each segment is equal to or an exact multiply of the TTH leaf size (or block size) and when segments are just finished, their integrity checked at once using the hash(es) of the block(s). The offset and length of the already finished segments are stored in the download queue.

Now its clear that to be able to check the integrity of the finished segments DC++ needs the full Tiger tree of the download (faithful readers of this blog are already familiar with Tiger hashes and hash trees by a very explanatory earlier post). Since compatibility dropped with pre-TTH era DC clients, DC++ checks if the peer supports hashes and gets the full hash tree just before an actual download starts. (The only exception is when a file is smaller than the minimum leaf size – these files are downloaded in one go and checked by their TTH). One could think that if DC++ is unable to get the full tree then it won’t start to download the file. But actually this isn’t the case…

Instead, DC++ will start the download with the hope that it’ll find more sources, so it will be able to grab the full tree later from another source. Until then it uses the full file size as blocksize and TTH for checking the integrity – ofcourse its possible only when the whole download finished. This was a good strategy up until DC++ was able to resume a download without having the hash tree. As the good old rollback function is removed in 0.699 resume without the full tree became impossible.

Possibility of download without the tree is a nice feature for small or medium sized files. They are usually downloaded in short time, they can be checked by the TTH in the end, and thats it. However, it is a problem for huge files, especially if there’s no additional source to get the tree from. Even if they download all day long if it cannot finish in one go then its just a waste of time and bandwith. It will start all over again and again… And even if some other sources with free slots come around later (and the hash tree is successfully grabbed from them) these new sources won’t be used while the full size segment is running…

Denial of service: I’d like one, please

Responses for searches for the most time is usually non-time consuming or difficult to perform. The techniques may vary from application to application, and depend on whoever wrote the code, what libraries were used etc. While simply a linear search of substrings may be fine, techniques such as regular expressions have made its way to ADC. However, there is a huge problem with regular expressions: they’re CPU consuming. A regular expression that is carefully constructed may, by design of course, force the CPU to spike and force the unsuspecting user’s computer to crash. Basically, anyone that is supporting regular expressions may be victims of a denial of service (DOS) attack.

I just know that some people are thinking “hey, let us restrict the length of the regular expression [hub/client side] and it can’t happen”. Well, that’d be pointless and shortsighted. The length of the command (well, any command for that matter) does not have a direct correlation to its possible damage vector. Additionally, the hub doesn’t really care in this matter. Since it’s as well difficult (impossible?) to parse the expression, evaluate if you really want to perform the expression and be completely guarded against an attacker.

(I’m not aware of any attempts of patching NMDC with regular expressions, but you’d probably end up with the same problem.)

Design a site like this with WordPress.com
Get started