From b39edaf5b7fd08989ededb3de79463a34ebaa072 Mon Sep 17 00:00:00 2001 From: "javi%netscape.com" Date: Wed, 13 Jun 2001 18:29:15 +0000 Subject: [PATCH] Fix for Bug 85304 r=wtc, sr=blizzard, a=asa Leaving a socket in blocking mode after a connect caused SSL/SMTP to block a thread causing send message to fail when SSL was enabled. Now we re-set the socket to the non-blocking state it came in with to connect and set it to block for our write method only. git-svn-id: svn://10.0.0.236/trunk@97068 18797224-902f-48f8-a5cc-f745e15eee43 --- .../security/manager/ssl/src/nsNSSIOLayer.cpp | 55 +++++++++---------- .../security/manager/ssl/src/nsNSSIOLayer.h | 4 -- 2 files changed, 25 insertions(+), 34 deletions(-) diff --git a/mozilla/security/manager/ssl/src/nsNSSIOLayer.cpp b/mozilla/security/manager/ssl/src/nsNSSIOLayer.cpp index e1f308b9f45..c1d57edc6e0 100644 --- a/mozilla/security/manager/ssl/src/nsNSSIOLayer.cpp +++ b/mozilla/security/manager/ssl/src/nsNSSIOLayer.cpp @@ -238,20 +238,6 @@ nsNSSSocketInfo::SetNetAddr(const PRNetAddr *aNetAddr) return NS_OK; } -nsresult -nsNSSSocketInfo::GetOldBlockVal(PRBool *aOldBlockVal) -{ - *aOldBlockVal = mOldBlockVal; - return NS_OK; -} - -nsresult -nsNSSSocketInfo::SetOldBlockVal(PRBool aOldBlockVal) -{ - mOldBlockVal = aOldBlockVal; - return NS_OK; -} - NS_IMETHODIMP nsNSSSocketInfo::GetNotificationCallbacks(nsIInterfaceRequestor** aCallbacks) { @@ -398,10 +384,10 @@ nsSSLIOLayerConnect(PRFileDesc* fd, const PRNetAddr* addr, PRSocketOptionData sockopt; sockopt.option = PR_SockOpt_Nonblocking; PR_GetSocketOption(fd, &sockopt); + PRBool oldBlockVal = sockopt.value.non_blocking; nsNSSSocketInfo *infoObject = (nsNSSSocketInfo*)fd->secret; - infoObject->SetOldBlockVal(sockopt.value.non_blocking); infoObject->SetNetAddr(addr); sockopt.option = PR_SockOpt_Nonblocking; @@ -435,11 +421,13 @@ nsSSLIOLayerConnect(PRFileDesc* fd, const PRNetAddr* addr, } loser: - // We keep the socket in blocking mode until the first write is completed. - // This makes it so that we can trap the case where we're trying to talk - // with a TLS intolerant server. I wish we didn't have to do this, but - // outside of hacking necko, this is the only way. After the first write, - // we'll set the non-blocking value back to the value it came in with. + // We put the Nonblocking bit back to the value it was when + // we entered this function. + NS_ASSERTION(sockopt.option == PR_SockOpt_Nonblocking, + "sockopt.option was re-set to an unexpected value"); + sockopt.value.non_blocking = oldBlockVal; + PR_SetSocketOption(fd, &sockopt); + return status; } @@ -552,21 +540,30 @@ nsSSLIOLayerWrite(PRFileDesc* fd, const void* buf, PRInt32 amount) #ifdef DEBUG_SSL_VERBOSE DEBUG_DUMP_BUFFER((unsigned char*)buf, amount); #endif - - PRInt32 bytesWritten = fd->lower->methods->write(fd->lower, buf, amount); - -#ifdef DEBUG_SSL_VERBOSE - PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p] wrote %d bytes\n", (void*)fd, bytesWritten)); -#endif - nsNSSSocketInfo *socketInfo = nsnull; PRBool firstWrite; socketInfo = (nsNSSSocketInfo*)fd->secret; NS_ASSERTION(socketInfo,"nsNSSSocketInfo was null for an fd"); socketInfo->GetFirstWrite(&firstWrite); PRBool oldBlockVal; - socketInfo->GetOldBlockVal(&oldBlockVal); PRBool oldBlockReset = PR_FALSE; + PRSocketOptionData sockopt; + + if (firstWrite) { + // We only want the first write to be blocking so that we + // can trap the case of the TLS intolerant server. + sockopt.option = PR_SockOpt_Nonblocking; + PR_GetSocketOption(fd, &sockopt); + oldBlockVal = sockopt.value.non_blocking; + sockopt.value.non_blocking = PR_FALSE; + PR_SetSocketOption(fd, &sockopt); + } + + PRInt32 bytesWritten = fd->lower->methods->write(fd->lower, buf, amount); + +#ifdef DEBUG_SSL_VERBOSE + PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p] wrote %d bytes\n", (void*)fd, bytesWritten)); +#endif // This is where we work around all of those SSL servers that don't // conform to the SSL spec and shutdown a connection when we request @@ -630,7 +627,6 @@ nsSSLIOLayerWrite(PRFileDesc* fd, const void* buf, PRInt32 amount) socketInfo->GetNetAddr(&addr); PRStatus prv = PR_Connect(fd, &addr, PR_INTERVAL_NO_TIMEOUT); // We no longer need this socket to block, so make it non-blocking. - PRSocketOptionData sockopt; sockopt.option = PR_SockOpt_Nonblocking; sockopt.value.non_blocking = oldBlockVal; PR_SetSocketOption(fd, &sockopt); @@ -649,7 +645,6 @@ nsSSLIOLayerWrite(PRFileDesc* fd, const void* buf, PRInt32 amount) if (firstWrite) { socketInfo->SetFirstWrite(PR_FALSE); if (!oldBlockReset) { - PRSocketOptionData sockopt; sockopt.option = PR_SockOpt_Nonblocking; sockopt.value.non_blocking = oldBlockVal; PR_SetSocketOption(fd, &sockopt); diff --git a/mozilla/security/manager/ssl/src/nsNSSIOLayer.h b/mozilla/security/manager/ssl/src/nsNSSIOLayer.h index 6eb86b38d21..1bb9fe227e1 100644 --- a/mozilla/security/manager/ssl/src/nsNSSIOLayer.h +++ b/mozilla/security/manager/ssl/src/nsNSSIOLayer.h @@ -77,9 +77,6 @@ public: nsresult GetNetAddr(PRNetAddr *aNetAddr); nsresult SetNetAddr(const PRNetAddr *aNetAddr); - nsresult GetOldBlockVal(PRBool *aOldBlockVal); - nsresult SetOldBlockVal(PRBool aOldBlockVal); - /* Set SSL Status values */ nsresult SetSSLStatus(nsISSLStatus *aSSLStatus); @@ -95,7 +92,6 @@ protected: nsXPIDLCString mProxyHostName; PRInt32 mPort, mProxyPort; PRNetAddr mNetAddr; - PRBool mOldBlockVal; /* SSL Status */ nsCOMPtr mSSLStatus;