From: G. P. Z. <pz-...@tr...> - 2007-07-14 07:52:48
|
Bitte entschuldigen sie mir, mein Deutsch ist schlect, also muss ich English benutzen. Versions: gwenhywfar-2.6.0 libofx-0.8.3 aqbanking-2.3.1 Environment: FreeBSD 6.2-STABLE (Jun 3 2007) I was having some problems connecting to my bank's ofx server, which I traced to a race condition in nl_socket.c. After the connect(2) call is issued, the code in GWEN_NetLayerSocket_Work() tests the socket status via getsockopt(SO_ERROR) (via GWEN_Socket_GetSocketError()) in order to decide if the socket is connected. At least on FreeBSD-6.2, this test will succeed if it is performed before the socket is connected. In my case, the SSL code attempted to write its initial text to the socket before the server returned (SYN|ACK), so the write failed and the socket was closed. I think the status of the socket should not be changed to "connected" until it is writable; I made the following change which fixed my problem: --- nl_socket.c.orig Tue Jan 9 10:18:23 2007 +++ nl_socket.c Fri Jul 13 23:52:09 2007 @@ -474,40 +474,48 @@ case GWEN_NetLayerStatus_Connecting: { char addrBuffer[128]; DBG_VERBOUS(GWEN_LOGDOMAIN, "Still connecting"); /* get socket error to check whether the connect succeeded */ err=GWEN_Socket_GetSocketError(nld->socket); if (!GWEN_Error_IsOk(err)) { if (GWEN_Error_GetType(err)!= GWEN_Error_FindType(GWEN_SOCKET_ERROR_TYPE) || (GWEN_Error_GetCode(err)!=GWEN_SOCKET_ERROR_TIMEOUT && GWEN_Error_GetCode(err)!=GWEN_SOCKET_ERROR_INTERRUPTED)) { DBG_INFO_ERR(GWEN_LOGDOMAIN, err); GWEN_NetLayer_SetStatus(nl, GWEN_NetLayerStatus_Disconnected); return GWEN_NetLayerResult_Error; } DBG_VERBOUS(GWEN_LOGDOMAIN, "Still not connected"); GWEN_NetLayer_AddFlags(nl, GWEN_NETLAYER_FLAGS_WANTWRITE); return GWEN_NetLayerResult_WouldBlock; } + + err = GWEN_Socket_WaitForWrite(nld->socket, 0); + if (!GWEN_Error_IsOk(err)) { + DBG_VERBOUS(GWEN_LOGDOMAIN, "Still not connected (write wait)"); + GWEN_NetLayer_AddFlags(nl, GWEN_NETLAYER_FLAGS_WANTWRITE); + return GWEN_NetLayerResult_WouldBlock; + } + /* log address */ GWEN_InetAddr_GetAddress(GWEN_NetLayer_GetPeerAddr(nl), addrBuffer, sizeof(addrBuffer)); -- G. Paul Ziemba FreeBSD unix: 12:51AM up 11 days, 15:14, 9 users, load averages: 1.37, 1.17, 0.73 |