Credit goes to Stanislav Maslovski. Here's his original argument for it:
Consider a client operating in active mode. In order to get a filelist
NmdcHub::connectToMe() first places the triplet (( peerNick, myNick, hubUrl ))
on the list of expected connections. Internally, nicks are stored in utf-8.
Note that peerNick in this triplet gets stored also in utf-8.
Next, NmdcHub::connectToMe() sends
"$ConnectToMe " + toAcp(peerNick) + ....
So far so good. Now the peer connects. ConnectionManager::accept() creates
new UserConnection, sets flags, etc. but because it does not know anything
about peer's encoding (the new connection can be from an arbitrary user from
arbitrary hub) it leaves it with the default (which is Text::systemCharset).
Now peer sends
$MyNick peerNick_in_acp
UserConnection::on() receives this, blindly translates peerNick_in_acp to
utf-8 from the encoding associated with the connection (which is
Text::systemCharset at the moment). If peer's encoding was different we get
an obvious result: the connection is rejected in ConnectionManager::on(MyNick)
because the translation fails and the peer is not found in the list of
expected connections.
Here goes an example session (text below contains russian chars):
NmdcHub::connect Трельник
NmdcHub::connectToMe Трельник
BufferedSocket::accept() 0x86d2a00
BufferedSocket::run() start 0x86d2a00
ConnectionManager::onMyNick 0x86974e0, ________
Unknown incoming connection from ________
BufferedSocket::run() end 0x86d2a00
In this example, the system locale was ru_RU.UTF-8, but the hub charset was CP1251.
If someone thinks that setting locale to CP1251 will solve the problem, then it
is not so, because there always will be hubs with different encodings and we
want linuxdcpp operate _simultaneously_ on all of them.
The attached patch solves this in the following way. First, the peer nick is
stored on the list of expected connections in ACP, not in uft-8. This is not
a problem, because the stored nick is just a key and is not used for any
other purpose. Next, when UserConnection::on() receives $MyNick it is passed
further untranslated. Peer's nick gets translated to utf-8 later inside
ConnectionManager::on(MyNick) when it becomes possible to determine and set
the correct encoding.
This all can be seen directly from the patch, of course. Perhaps, a better
way of doing things could be to separate incomming connection checking from
ConnectionManager::on(MyNick) and put it in UserConnection::on() or do
something similar.
|