QSocket problem with transconnect (proxy)?
Thiago Macieira
thiagom at wanadoo.fr
Thu Jun 20 12:29:03 BST 2002
Michael Goffioul wrote
>Simon Hausmann wrote:
>> I think this is a bug in transconnect, or rather: A missing feature.
>>
>> What QSocket does is to make the socket non-blocking. Then it issues
>> the first connect(), which immediately returns with EINPROGRESS, as
>> the socket is non-blocking. As the socketnotifier indicates
>> writability, QSocket issues a second connect() (on the same fd) ,
>> which (in the normal case) returns 0, indicating a connection
>> success.
>
>I don't think that's what happening. As I explained above, the first
>connect attempt establish the connection immediately, this can
>happen even if the socket is non-blocking (for example on a LAN).
>The socketnotifier being enabled, an event is fired, triggering
>QSocket::sn_write() -> QSocket::tryConnection(). The latter again
>tries to establish the connection, but the problem is that now it
>is using d->addr, which contains 0.0.0.0, it's not the same fd.
>This is the only place in the whole qsocket.cpp file where
>d->addr is used, I couldn't find any place where this might be
>set to something else. No surprise then that it contains 0.0.0.0.
>But trying to connect on 0.0.0.0 fails using transconnect.
>Don't know where's the fault, though.
I think I may have found the bug:
when you call connectToHost(), it creates a QDns to do the lookup and connects
it to QSocket::tryConnecting(). When that slot gets called, it'll fetch the
connection lookup results and try to connect to the first (and only the
first) of the returned values, after placing the socket in non-blocking mode.
What happens is that it expects connect() to return with failure (errno =
EINPROGRESS). What happens is that the local connection is established
immediately and the connection then is successful. The QSocket class never
leaves the QSocket::Connecting state.
By the first time QSocket::sn_write() gets called, it'll see the
QSocket::connecting state and instead call QSocket::tryConnection(). That's
an error, because:
a) the socket is already connected
b) d->addr has never got set
(actually, I couldn't find where it is ever set)
The solution is this:
Index: qsocket.cpp
===================================================================
RCS file: /home/kde/qt-copy/src/network/qsocket.cpp,v
retrieving revision 1.24
diff -u -3 -p -r1.24 qsocket.cpp
--- qsocket.cpp 2002/03/15 19:31:56 1.24
+++ qsocket.cpp 2002/06/20 11:28:09
@@ -358,6 +358,13 @@ void QSocket::tryConnecting()
// The socket write notifier will fire when the connection succeeds
if ( d->wsn )
d->wsn->setEnabled( TRUE );
+
+ // Actually, the connection has already succeeded (returned TRUE
above)
+ // -thiago
+ d->state = Connected;
+ emit connected();
+ if ( d->rsn )
+ d->rsn->setEnabled( TRUE );
}
#endif
}
Note: I haven't tested that
Note 2: I hope you're not developing a KDE application
--
Thiago Macieira - UFOT Registry number: 1001
thiagom at mail.com
ICQ UIN: 1967141 PGP: will create new keys. Erase the old ones!
Registered Linux user #65028
More information about the kde-core-devel
mailing list