Improve client identification based on BEP 10

Review Request #130077 - Created April 10, 2017 and updated

Information
Fonic Maxxim
libktorrent
master
96d2adf...
Reviewers
ktorrent
aacid

Identify clients more accurately using the 'v' string embedded in extended handshake messages as described by BitTorrent Enhancement Proposal 10 'Extension Protocol' (BEP 10).

My tests showed that:
- most peers/clients send the string
- most peers/clients send useful/compliant string content
- clients are identified even if PeerID::identifyClient() fails to do so (e.g. 'Unknown client' -> 'Tixati')
- client identification becomes more accurate (e.g. 'Azureus 5.7.x.x' -> 'Vuze 5.7.x.x')

Here's a screenshot comparing identification methods. Format of column 'Client': v-string-based identification, peer-id-based identification, peer id.

yes

Fonic Maxxim
Albert Astals Cid
Fonic Maxxim
Fonic Maxxim
Review request changed

Change Summary:

Added screenshot

Description:

   

Identify clients more accurately using the 'v' string embedded in extended handshake messages as described by BitTorrent Enhancement Proposal 10 'Extension Protocol' (BEP 10).

   
   

My tests showed that:

    - most peers/clients send the string
    - most peers/clients send useful/compliant string content
    - clients are identified even if PeerID::identifyClient() fails to do so (e.g. 'Unknown client' -> 'Tixati')
    - client identification becomes more accurate (e.g. 'Azureus 5.7.x.x' -> 'Vuze 5.7.x.x')

  +
  +

Here's a screenshot comparing identification methods. Format of column 'Client': v-string-based identification, peer-id-based identification, peer id.

Alexander Trufanov

   
src/peer/peer.cpp (Diff revision 1)
 
 

How about to check if data() is not empty before overwrite stats.client? I suppose some BT clients may provide end user control over this field and it may be erased.

  1. I think data() will always contain something due to the previous if-clause, but I could check if data().toString() is an empty string before overwriting stats.client. I think that's what you meant, right?

  2. Like this:

            if ((val = dict->getValue(QByteArrayLiteral("v"))))
            {
                QString peerid = val->data().toString();
                if (!peerid.isEmpty())
                {
                    stats.client = val->data().toString();
                }
            }
    
  3. exactly

Loading...