[HN Gopher] Transmission torrent client ported to C++
       ___________________________________________________________________
        
       Transmission torrent client ported to C++
        
       Author : beepog
       Score  : 218 points
       Date   : 2021-09-12 18:28 UTC (4 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | floydian10 wrote:
       | Transmission is one of those pieces of software that just works.
       | I've been using it for around a decade, and can't see that
       | changing anytime soon.
        
       | Aissen wrote:
       | I don't know libtransmission very well... but isn't that getting
       | closer to libtorrent ? It seems to be the defacto C++
       | implementation: https://www.libtorrent.org/
        
         | deelowe wrote:
         | Transmission has always sort of been the (or at least one of
         | the) alternatives to libtorrent. I like transmission because
         | they deliver a more cohesive approach be it cli, web based or
         | GUI.
        
           | stjohnswarts wrote:
           | For me qbittorrent offers more bang for the buck and is just
           | as stable and fast as transmission. The killer feature for me
           | has always been the ability to bind it to a network interface
           | that placed it a big step above transmission. I have used
           | both quite a bit in the past.
        
       | TheChaplain wrote:
       | I'm impressed, it's no insignificant feat.
       | 
       | Although, I'm more amazed this post has been up an hour without
       | any rust comments..
        
         | inshadows wrote:
         | I'm sure the thread is monitored and strike force is being
         | dispatched as we speak.
        
         | chromatin wrote:
         | ...but you did make a Rust comment :-O
        
         | boardwaalk wrote:
         | The PR doesn't do much if you look at the changes. It looks
         | like it's mostly compiling as C++ and using things like 'auto'
         | and C++-style casts.
        
           | pjmlp wrote:
           | Already that little does much, as C++'s type system is more
           | strict.
           | 
           | The rest can be (hopefully) increasingly migrated.
           | 
           | This was both the plus (and now Achilles's heel regarding
           | fixing C++) of migrating C code into C++.
        
           | pianoben wrote:
           | Speaking as a C++ person - you're right that this doesn't
           | _do_ much, but nevertheless this is still a significant
           | effort. This kind of groundwork is _work_, and opens lots of
           | doors for future improvements.
           | 
           | That said, there are definitely downsides here. Even if they
           | manage to keep c++ entirely out of headers, consumers now
           | have the headache of either building libtransmission
           | themselves _or_ making sure they include a compatible runtime
           | in their own projects.
           | 
           | As soon as c++ leaks out into the public interfaces, it's
           | game over for precompiled binaries - everyone will have to
           | build it whether they want to or not. Not the end of the
           | world, but certainly it could be painful for downstream
           | projects.
        
             | Ericson2314 wrote:
             | They should probably be like LLVM and just keep a C wrapper
             | around new C++ interfaces for such purposes.
             | 
             | But agreed this is the right first step.
        
           | maccard wrote:
           | But someone needs to do this before the interesting stuff can
           | happen.
        
         | FpUser wrote:
         | Same impression. I was wondering when those Rustamans will
         | descend ;)
        
         | simias wrote:
         | I confess that it crossed my mind. Torrents are obviously
         | network-oriented and are often used to interact with, uh,
         | untrusted content (the torrent files but also the trackers and
         | peers that exchange data with the client). The surface of
         | attack is rather large, using a memory-safe language doesn't
         | seem like a luxury. I also can't imagine wanting to write C++
         | in this day and age, but that's my prejudice.
         | 
         | That being said I've been using transmission for years without
         | complaints, so I trust them to do the right thing.
        
         | jeltz wrote:
         | Said the guy posting a Rust comment.
        
         | tpush wrote:
         | > Although, I'm more amazed this post has been up an hour
         | without any rust comments..
         | 
         | There are more comments on any given post about hypothetical
         | obnoxious Rust comments than any actual comments of that
         | nature.
        
           | hutzlibu wrote:
           | Ah, this feels like a promising debate. Can't someone do a
           | statistical analysis about it?
        
             | smoldesu wrote:
             | Empirically speaking, OP brought it up first...
        
         | [deleted]
        
         | aaaaaaaaaaab wrote:
         | Rust has jumped the shark.
        
         | pizza234 wrote:
         | > Although, I'm more amazed this post has been up an hour
         | without any rust comments..
         | 
         | I've actually thought "WTF why porting a project to a memory
         | unsafe language", but actually the PR title is somewhat
         | excessive - it's more of a modernization, indeed described by
         | the author as "the first incremental step of getting
         | libtransmission to compile with a C++ compiler".
        
           | phkahler wrote:
           | I think there is a tool to automatically convert C to Rust,
           | but that would probably be a terrible idea given what looks
           | like a lot of custom data structures that would translate to
           | unsafe Rust.
        
             | Ericson2314 wrote:
             | It would be interesting to try to make it recognize C++ STL
             | usage but not much more of C++ next.
        
         | kelnos wrote:
         | It's almost certainly a much more tractable problem to get C
         | code compiling with a C++ compiler, and then gradually
         | transitioning to C++ and the STL over time. I would love to see
         | greater Rust adoption (especially in things that deal with
         | untrusted peers on a network!), but that project is likely
         | orders of magnitude larger than what the author has chosen to
         | take on.
         | 
         | Also it seems like the author is already well-versed in C++;
         | learning Rust might not be a priority for them, and would
         | certainly slow things down a lot.
         | 
         | And while there are certainly plenty of footguns and unsafe
         | things you can do in C++ (even unintentionally), it's probably
         | still safer than C, even if it's not as safe as Rust.
        
           | ryandrake wrote:
           | And just to be that overly pedantic nit-picker, when most
           | people refer to the "STL" today, they are really talking
           | about the C++ Standard Library[1], which is related to and
           | based on the conventions of the old-school Standard Template
           | Library (STL), but a different thing. When you #include
           | <vector> on most modern development platforms, you are not
           | using the actual historic STL implementation.
           | 
           | 1: https://en.wikipedia.org/wiki/C%2B%2B_Standard_Library
        
           | FpUser wrote:
           | >"And while there are certainly plenty of footguns and unsafe
           | things you can do in C++"
           | 
           | If I want to shoot myself in the foot I should have full
           | rights and the ability to do so.
           | 
           | In a normal coding however modern C++ is very reasonable
           | language and I do not recall stepping onto any landmines in a
           | last few years even though my code runs high load / high
           | performance business servers that also do a lot of
           | calculations.
        
           | vlovich123 wrote:
           | I would go with a transpiler approach first (eg
           | https://c2rust.com/) and then gradually transition pieces to
           | use the Rust standard library and to safe code instead of the
           | adhoc custom containers.
           | 
           | Still, that all would be predicated on having good Rust
           | experience or using it as a learning experience and that may
           | not be the motivation of the authors.
        
             | pizza234 wrote:
             | > gradually transition pieces to use the Rust standard
             | library and to safe code
             | 
             | Is this realistically possible on a non-trivial project? I
             | suppose that porting to safe Rust requires a radical
             | rearchitecture of the code.
        
           | dzhiurgis wrote:
           | > especially in things that deal with untrusted peers on a
           | network!
           | 
           | Are there any practical torrent clients that I can run in
           | docker container?
        
             | felipelemos wrote:
             | Transmission itself. I highly recommend the image built by
             | the linuxserver.io:
             | https://hub.docker.com/r/linuxserver/transmission
        
       | jeremy_wiebe wrote:
       | The title is a bit misleading. This PR is just getting the lib to
       | compile with a C++ compiler. Seems like the bulk of the work
       | remains.
       | 
       | > This PR is the first incremental step of getting
       | libtransmission to compile with a C++ compiler.
        
       | userbinator wrote:
       | I wonder how much the size of the compiled code increased ---
       | it's been my experience that "C++-ifying" tends to bloat the
       | binaries quite a bit.
       | 
       | "Zero cost abstractions" are, in practice, quite rare.
        
         | josefx wrote:
         | Most of that is probably in some symbol table used by the
         | linker. C++ symbols include type names for parameters, C
         | compilers only contain a function name, its linker literally
         | can't tell the difference between a char main[10] and int
         | main(int,char*){} because both are compiled to "main" .
        
         | jupp0r wrote:
         | Probably a bit. Monomorphization is expensive in terms of code
         | size. On the other hand - why would you care for a couple of
         | 100kb for a use case like transmission?
        
           | userbinator wrote:
           | uTorrent, a whole torrent client I remember using many years
           | ago, was only ~100k in total.
        
             | aeyes wrote:
             | uTorrent is on the same page as Transmission before this
             | change, it achieves its small size by not using the STL at
             | all.
        
         | mhh__ wrote:
         | This is worth keeping in mind, but the real issue is the
         | pressure on the optimizer and linker rather than size IMO.
        
         | IshKebab wrote:
         | Zero cost abstractions are about performance, not code size.
        
           | userbinator wrote:
           | Code size definitely affects performance, and has done so
           | ever since caches existed.
        
             | pjmlp wrote:
             | I advise a talk from Chandler Carruth where he proves
             | longer code can achieve higher performance due to the way
             | computer architectures work.
             | 
             | Unfortunately I no longer remember in which conference he
             | did it, maybe someone else can link it.
        
               | userbinator wrote:
               | In microbenchmarks, on a long pipeline RISC, or similar
               | microarchitectures like NetBurst (P4), I could see that
               | being true. But we're long past that era now. It's the
               | same misguided assumptions that leads to several-KB-long
               | "optimised" memcpy() implementations whose real-world
               | effects on performance are negligible to negative.
               | 
               | If you don't believe me, read what Linus Torvalds has to
               | say about why the Linux kernel is built with -Os by
               | default.
        
               | pjmlp wrote:
               | He did it on x64.
               | 
               | EDIT: This is the talk, if I remember correctly.
               | 
               | https://isocpp.org/blog/2018/06/cppcon-2017-going-
               | nowhere-fa...
        
         | jdright wrote:
         | It is a common mistake what you're doing by generalizing it out
         | of the original scope, which is _only_ performance wise. Any
         | other aspect you might think is not encompassed into the
         | original zero cost abstraction concept.
        
         | rwmj wrote:
         | Just built both versions for you. Edit: Please note the C++
         | code change doesn't actually use the STL, it really just
         | changes the compiler and code style in a few places. So I don't
         | think this represents any argument for or against C vs C++.
         | -rwxr-xr-x. 1 rjones rjones 4167912 Sep 12 22:09
         | build-c++/gtk/transmission-gtk       -rwxr-xr-x. 1 rjones
         | rjones 3997408 Sep 12 22:12 build-c/gtk/transmission-gtk
         | -rwxr-xr-x. 1 rjones rjones 3130352 Sep 12 22:09
         | build-c++/daemon/transmission-daemon       -rwxr-xr-x. 1 rjones
         | rjones 2959640 Sep 12 22:12 build-c/daemon/transmission-daemon
         | build-c++/utils/:       total 12156       drwxr-xr-x. 6 rjones
         | rjones    4096 Sep 12 22:08 CMakeFiles       -rw-r--r--. 1
         | rjones rjones    5653 Sep 12 22:08 cmake_install.cmake
         | -rw-r--r--. 1 rjones rjones     289 Sep 12 22:08
         | CTestTestfile.cmake       -rw-r--r--. 1 rjones rjones   13793
         | Sep 12 22:08 Makefile       -rwxr-xr-x. 1 rjones rjones 3082448
         | Sep 12 22:09 transmission-create       -rwxr-xr-x. 1 rjones
         | rjones 3066256 Sep 12 22:09 transmission-edit       -rwxr-xr-x.
         | 1 rjones rjones 3182928 Sep 12 22:09 transmission-remote
         | -rwxr-xr-x. 1 rjones rjones 3073952 Sep 12 22:09 transmission-
         | show            build-c/utils/:       total 11496       drwxr-
         | xr-x. 6 rjones rjones    4096 Sep 12 22:12 CMakeFiles
         | -rw-r--r--. 1 rjones rjones    5645 Sep 12 22:12
         | cmake_install.cmake       -rw-r--r--. 1 rjones rjones     287
         | Sep 12 22:12 CTestTestfile.cmake       -rw-r--r--. 1 rjones
         | rjones   13725 Sep 12 22:12 Makefile       -rwxr-xr-x. 1 rjones
         | rjones 2917136 Sep 12 22:12 transmission-create       -rwxr-
         | xr-x. 1 rjones rjones 2895128 Sep 12 22:12 transmission-edit
         | -rwxr-xr-x. 1 rjones rjones 3014872 Sep 12 22:12 transmission-
         | remote       -rwxr-xr-x. 1 rjones rjones 2901832 Sep 12 22:12
         | transmission-show
        
           | userbinator wrote:
           | Thanks for the proof. Over 100k increase on average. Not
           | surprising.
           | 
           | ...and people wonder why software gets slower and bigger over
           | time while doing the same thing. We even get HN articles
           | about that semi-regularly.
        
             | rwmj wrote:
             | A question that I'd like to ask a C++ expert: If you use
             | any STL container, is it always the case that the whole
             | thing is templated, therefore effectively compiled and
             | statically linked into the binary? Or will part/all of it
             | come from functions in the dynamically linked libstdc++.so?
        
               | [deleted]
        
               | 10000truths wrote:
               | That depends on how the standard library is implemented.
               | I wouldn't be surprised if libc++ or libstdc++ used
               | explicit template instantiations for STL containers of
               | primitive types, e.g. std::vector<int>.
        
           | 10000truths wrote:
           | What compiler flags did you use? Perhaps -Os would even
           | things out a little more.
        
       | elktea wrote:
       | Does anyone know where to get up-to-date windows builds?
        
       | posharma wrote:
       | A change of 84 files and not a single code review comment.
       | Approved and merged! Wow!
        
       | ducktective wrote:
       | For CLI fans, aria2c supports BitTorrent protocol.
        
         | paulfurtado wrote:
         | Transmission also does have transmission-cli
        
           | [deleted]
        
           | caslon wrote:
           | I think the point of the good ducktective's comment was to
           | offer an alternative to people who don't _like_ waiting hours
           | for C++ to compile.
        
             | lucb1e wrote:
             | apt install transmission-cli
        
             | stjohnswarts wrote:
             | Sorry it doesn't take hours for transmission or qbittorrent
             | or their cli versions to compile. It takes minutes even on
             | old hardware.
        
           | stjohnswarts wrote:
           | qbittorrent-nox also exists if you like qbittorrent
        
       | vlovich123 wrote:
       | I wonder if Clang-tidy could be used to write a transformation
       | for each pattern rather than converting by hand.
        
         | jupp0r wrote:
         | From my own experience writing transformation tools on top of
         | libtooling: you can make it work but the sweet spot between the
         | time it takes to write the transformation code and just
         | manually doing it makes it uneconomical for most use cases
         | unless you have a gigantic code base and an error prone
         | transformation that you have a better chance of getting correct
         | when a computer can process the whole syntax tree.
         | 
         | For 99% of cases, regex-replace is the better choice (as much
         | fun as writing syntax tree transformations is).
        
       | qalmakka wrote:
       | I think it's a sensible choice. I've seen way too many C
       | codebases rewriting half of the STL or using clunky macro hacks
       | (or worse, half-assed linked lists) when basically every single
       | platform out there has a copy on the STL available which includes
       | containers and algorithms with excellent performances and are
       | well tested.
       | 
       | It's complicated but it's the only reasonable choice. You can
       | then write your code C-style while compiling it as C++ and nobody
       | will bat an eye.
        
         | FpUser wrote:
         | >"You can then write your code C-style while compiling it as
         | C++ and nobody will bat an eye."
         | 
         | Very practical and reasonable choice.
        
           | calvinmorrison wrote:
           | C style code plus you can get some nice things like hashmaps
           | without having to implement or find a implementation and
           | instead use std library
        
         | yakubin wrote:
         | STL has a lot of weird pitfalls. There was _std::vector
         | <bool>_. Here you can see some pitfalls of _std::unordered_map_
         | : <https://youtu.be/ncHmEUmJZf4?t=2220>. The whole talk is
         | interesting to watch. In the beginning you can also see the
         | puzzling design of _std::unordered_map_ (puzzling because of
         | the number of indirections).
         | 
         | I'd reach for abseil first: <https://abseil.io/>.
        
           | fnord77 wrote:
           | after watching that video, I never want to touch C++ again
        
         | jupp0r wrote:
         | You can also statically link libc++. Not much of a binary size
         | increase from static linking because most is template headers.
        
         | ziftface wrote:
         | But if that's the case couldn't there just be a library that
         | provides all the functionality without having to switch
         | languages? Something like boost but for plain C?
        
           | whaaswijk wrote:
           | In theory there could be such a library but in practice I
           | don't think there is. Maybe because maintaining something
           | like the STL is a non-trivial task.
        
             | mastrsushi wrote:
             | That's pretty much what glib is. There are generic
             | structures.
        
               | cassepipe wrote:
               | Does transmission use glib?
        
           | lalaland1125 wrote:
           | The lack of generics for C makes it difficult to write those
           | sorts of libraries in an efficient way.
        
       | Sunspark wrote:
       | As someone who is not a C programmer, but is aware of the fact
       | that the Transmission codebase is 15 years in, can someone state
       | whether it is normal that after 15 years of work on the code,
       | that it is so terrible it has to be changed? I'd like to think
       | that if I worked on something for 15 years that it'd be pretty
       | stable by that point.
        
         | TonyTrapp wrote:
         | For a project that keeps being maintained, you want
         | maintainable code that isn't a burden to work with. That's
         | their rationale according to the PR. It's not that the code is
         | bad, but it's more pedestrian than directly writing C++, so can
         | lower the motivation of the involved people to actually work on
         | the code and implement the things they want to implement.
        
         | throwdbaaway wrote:
         | Not a C/C++ programmer either, but I got an example. InnoDB was
         | first released in 2001, and was ported from C to C++ in 2011:
         | https://github.com/mysql/mysql-server/compare/78f4351..3a455...
        
         | stjohnswarts wrote:
         | The question is too broad. It will depend on your situation and
         | resources. If the code has been stable and secure for 15 years
         | with a bit of maintenance? Why would you replace it? If you are
         | adding new features or the code has become hard to maintain?
         | The sure refactor and rewrite away. There is something to be
         | said for using timetested code, but you should never turn it
         | into a religion and remain practical and open to revising it if
         | good reasons come along.
        
         | usefulcat wrote:
         | Even if it is stable, it may have accreted many features over
         | that time such that the code is now difficult to modify. Being
         | able to leverage standard c++ stuff could be quite valuable,
         | and could even result in less code (for them to maintain). They
         | appear to be doing it very gradually, where the first step is
         | probably little more than simply compiling the existing code as
         | c++ instead of c.
        
         | notriddle wrote:
         | Transmission probably should eventually be changed, so that
         | support for BitTorrent V2 can be added. SHA1 collisions are
         | only ever going to get easier, after all.
        
         | lazypenguin wrote:
         | From the pull request, it was less that the C codebase is bad
         | and more that the C++ STL has gotten better.
        
       ___________________________________________________________________
       (page generated 2021-09-12 23:00 UTC)