[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Re: QSocket problem with transconnect (proxy)?
From:       Thiago Macieira <thiagom () wanadoo ! fr>
Date:       2002-06-20 11:29:03
[Download RAW message or body]

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@mail.com
   ICQ UIN: 1967141  PGP: will create new keys. Erase the old ones!
     Registered Linux user #65028

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic