Date: Thursday, January 11, 2007 @ 19:37:07
  Author: marc
    Path: /cvsroot/carob/carob

Modified: include/Connection.hpp (1.80 -> 1.81) src/Connection.cpp (1.102
          -> 1.103) src/DriverSocket.cpp (1.23 -> 1.24) src/JavaSocket.cpp
          (1.67 -> 1.68)

Fix for CAROB-101. Do not hide CodecException but rethrow it as an
UnexpectedException (should be a ProtocolException). In Connection.cpp
retry/reconnect loop, catch ProtocolException and UnexpectedException
and abort thanks to new method corruptedConnectionClose().

Implemented portable_close(socket) in JavaSocket.cpp and use it
immediately on CodecException


------------------------+
 include/Connection.hpp |    5 +++++
 src/Connection.cpp     |   35 ++++++++++++++++++++++++++++++++++-
 src/DriverSocket.cpp   |   25 +++++++++++++++++++++----
 src/JavaSocket.cpp     |   45 ++++++++++++++++++++++++++++++++++-----------
 4 files changed, 94 insertions(+), 16 deletions(-)


Index: carob/include/Connection.hpp
diff -u carob/include/Connection.hpp:1.80 carob/include/Connection.hpp:1.81
--- carob/include/Connection.hpp:1.80   Thu Jan 11 17:42:36 2007
+++ carob/include/Connection.hpp        Thu Jan 11 19:37:07 2007
@@ -735,6 +735,11 @@
    */
   void                reconnectOrDie() throw (ConnectionException,
                             DriverException, UnexpectedException);
+
+
+
+  void                corruptedConnectionClose(const CarobException& reason);
+
   /**
    * Forbids Connection creation that would lead to unexpected state.
    * A connection is either created, ie. connected to a controller or destroyed
Index: carob/src/Connection.cpp
diff -u carob/src/Connection.cpp:1.102 carob/src/Connection.cpp:1.103
--- carob/src/Connection.cpp:1.102      Thu Jan 11 17:42:35 2007
+++ carob/src/Connection.cpp    Thu Jan 11 19:37:07 2007
@@ -33,6 +33,8 @@
 #include "CarobException.hpp"
 
 #include <string>
+#include <sstream>
+
 
 #ifdef __MINGW32__
   #define sleep _sleep
@@ -63,11 +65,19 @@
 #define FO_CATCH_NTIMES\
     break; /* no exception means success: get out of the retry for loop */\
   }\
-  catch (SocketIOException sioe)\
+  catch (const SocketIOException& sioe)\
   {\
     ::sleep(static_cast<int>(foCnt*0.5)); /* sleep incrementally */\
     reconnectOrDie();\
   }\
+  catch (const ProtocolException& pe)\
+  {\
+    corruptedConnectionClose(pe); throw; /* TODO: type rethrown? */    \
+  }\
+  catch (const UnexpectedException& ue) /* because of CAROB-101 */ \
+  {\
+    corruptedConnectionClose(ue); throw;       \
+  }\
 }
 
 Connection::Connection(ConnectionParameters& prms)
@@ -266,6 +276,29 @@
   }
 }
 
+void Connection::corruptedConnectionClose(const CarobException& reason)
+{
+  const std::wstring fctName(L"Connection::corruptedConnectionClose(const 
CarobException&)");
+
+  std::wostringstream buffer;
+  buffer << reason;
+  logError(fctName, buffer.str());
+
+  // Brutally close network socket FIRST
+  try {
+    driverSocketPtr->closeSocket();
+  } catch (const SocketIOException& sioe) {
+    std::wostringstream buffer;
+    buffer << L"failed to force ->closeSocket(), probably already closed? " << 
sioe.description();
+    logError(fctName, buffer.str());
+  }
+
+  // Then call the regular close(). It will try to send the close
+  // command, and fail. We will survive anyway.
+  close();
+}
+
+
 bool Connection::close()
 {
   const wstring fctName(L"Connection::close");
Index: carob/src/DriverSocket.cpp
diff -u carob/src/DriverSocket.cpp:1.23 carob/src/DriverSocket.cpp:1.24
--- carob/src/DriverSocket.cpp:1.23     Mon Dec 18 17:55:31 2006
+++ carob/src/DriverSocket.cpp  Thu Jan 11 19:37:07 2007
@@ -44,12 +44,14 @@
   }
   catch (CodecException ce)
   {
-    std::wostringstream buffer;
-    buffer<<L"Invalid input string '"<<s<<L"' to send. Exception was:"<<ce;
+    // not so bad fix for CAROB-101
     if (isErrorEnabled())
     {
+      std::wostringstream buffer;
+      buffer<<L"CodecException while UTF8 encoding string to send:'"<< s << 
L"'. " << ce.description();;
       logError(L"DriverSocket::operator<<(wstring)", buffer.str());
     }
+    throw UnexpectedException(ce.description(), ce.getSQLState(), &ce);
   }
   return *this;
 }
@@ -80,8 +82,23 @@
       std::wstring chunk;
       while (static_cast<int>(sizeRead)<strSize)
       {
-       // FIXME: catch CodecException here. See CAROB-101
-        sizeRead += readJavaUTF(chunk);
+        try
+        {
+          sizeRead += readJavaUTF(chunk);
+        }
+        catch (CodecException ce)
+        {
+         // not so bad fix for CAROB-101
+          if (isErrorEnabled())
+          {
+           std::wostringstream buffer;
+           // Here GNU libstdc++ 4.0.2 ostream.tcc will just widen the bytes 
to wchar_t
+           // Not sure this is portable
+           buffer<<L"CodecException while UTF8-decoding byte sequence 
received'"<< chunk << L"'. " << ce.description();
+           logError(L"DriverSocket::operator<<(wstring)", buffer.str());
+         }
+         throw UnexpectedException(ce.description(), ce.getSQLState(), &ce);
+       }
         s += chunk;
       }
     }
Index: carob/src/JavaSocket.cpp
diff -u carob/src/JavaSocket.cpp:1.67 carob/src/JavaSocket.cpp:1.68
--- carob/src/JavaSocket.cpp:1.67       Fri Jan  5 15:58:37 2007
+++ carob/src/JavaSocket.cpp    Thu Jan 11 19:37:07 2007
@@ -16,7 +16,7 @@
  * limitations under the License.
  *
  * Initial developer(s): Gilles Rayrat
- * Contributor(s): Zsolt Simon
+ * Contributor(s): Zsolt Simon, Marc Herbert
  */
 
 #include "JavaSocket.hpp"
@@ -66,7 +66,7 @@
   }
   catch (SocketIOException e)
   {
-    if (isInfoEnabled())
+    if (isWarnEnabled())
       logInfo(fctName, L"Socket closure failed. Exception is: " + 
e.description());
   }
 }
@@ -184,16 +184,23 @@
   return false;
 }
 
+namespace {
+inline int portable_close(int socket_fd)
+{
+#ifdef __MINGW32__
+  return closesocket(socket_fd);
+#else
+  return close(socket_fd);
+#endif
+}
+}
+
 bool JavaSocket::closeSocket() throw (SocketIOException, UnexpectedException)
 {
   const wstring fctName(L"closeSocket");
   if (isValid())
   {
-#ifdef __MINGW32__
-    if (closesocket(socket_fd) != 0)
-#else
-    if (close(socket_fd) != 0)
-#endif
+    if (portable_close(this->socket_fd) != 0)
     {
       wstring msg(L"Could not close socket. Error is ");
 #ifdef __MINGW32__
@@ -220,7 +227,17 @@
 {
   const wstring fctName(L"JavaSocket::writeJavaUTF");
 
-  std::string utf8str(toUTF8(str));
+  std::string utf8str;
+
+  try
+  {
+    utf8str = toUTF8(str);
+  }
+  catch (const CodecException&)
+  { // Don't leave connection in such a rotten state, see CAROB-101
+    portable_close(this->socket_fd);
+    throw;
+  }
 
   int32_t netlen = htonl(utf8str.length());
 
@@ -248,10 +265,16 @@
   receiveFromSocket(fctName, L"UTF string", utfStr, lenRec, 0);
   const std::string received(reinterpret_cast<char*>(utfStr), lenRec);
 
-  try {
+  try
+  {
     s = fromUTF8(received);
-  } catch (CodecException) {
-    delete[] utfStr; throw;
+  }
+  catch (const CodecException&)
+  { 
+    delete[] utfStr;
+    // Don't leave connection in such a rotten state, see CAROB-101
+    portable_close(this->socket_fd);
+    throw;
   }
   sizeRead = (size_t)lenRec;
 

_______________________________________________
Carob-commits mailing list
[email protected]
https://forge.continuent.org/mailman/listinfo/carob-commits

Reply via email to