On Mon, Jan 23, 2017 at 10:37:32PM +0100, Willy Tarreau wrote: > On Mon, Jan 23, 2017 at 01:28:53PM -0800, Wei Wang wrote: > > Hi Willy, > > > > True. If you call connect() multiple times on a socket which already has > > cookie without a write(), the second and onward connect() call will return > > EINPROGRESS. > > It is basically because the following code block in __inet_stream_connect() > > can't distinguish if it is the first time connect() is called or not: > > > > case SS_CONNECTING: > > if (inet_sk(sk)->defer_connect) <----- defer_connect will > > be 0 only after a write() is called > > err = -EINPROGRESS; > > else > > err = -EALREADY; > > /* Fall out of switch with err, set for this state */ > > break; > > Ah OK that totally makes sense, thanks for the explanation! > > > I guess we can add some extra logic here to address this issue. So the > > second connect() and onwards will return EALREADY.
Thinking about it a bit more, I really think it would make more sense to return -EISCONN here if we want to match the semantics of a connect() returning zero on the first call. This way the caller knows it can write whenever it wants and can disable write polling until needed. I'm currently rebuilding a kernel with this change to see if it behaves any better : - err = -EINPROGRESS; + err = -EISCONN; I'll keep you updated. Thanks, Willy