Upstream version 11.39.250.0
[platform/framework/web/crosswalk.git] / src / net / socket / ssl_client_socket_openssl.cc
index f341a9f..994a4d6 100644 (file)
@@ -632,7 +632,7 @@ int SSLClientSocketOpenSSL::Read(IOBuffer* buf,
   user_read_buf_ = buf;
   user_read_buf_len_ = buf_len;
 
-  int rv = DoReadLoop(OK);
+  int rv = DoReadLoop();
 
   if (rv == ERR_IO_PENDING) {
     user_read_callback_ = callback;
@@ -657,7 +657,7 @@ int SSLClientSocketOpenSSL::Write(IOBuffer* buf,
   user_write_buf_ = buf;
   user_write_buf_len_ = buf_len;
 
-  int rv = DoWriteLoop(OK);
+  int rv = DoWriteLoop();
 
   if (rv == ERR_IO_PENDING) {
     user_write_callback_ = callback;
@@ -907,6 +907,11 @@ int SSLClientSocketOpenSSL::DoHandshake() {
                << " is: " << (SSL_session_reused(ssl_) ? "Success" : "Fail");
     }
 
+    if (ssl_config_.version_fallback &&
+        ssl_config_.version_max < ssl_config_.version_fallback_min) {
+      return ERR_SSL_FALLBACK_BEYOND_MINIMUM_VERSION;
+    }
+
     // SSL handshake is completed. If NPN wasn't negotiated, see if ALPN was.
     if (npn_status_ == kNextProtoUnsupported) {
       const uint8_t* alpn_proto = NULL;
@@ -1230,7 +1235,7 @@ void SSLClientSocketOpenSSL::OnRecvComplete(int result) {
   if (!user_read_buf_.get())
     return;
 
-  int rv = DoReadLoop(result);
+  int rv = DoReadLoop();
   if (rv != ERR_IO_PENDING)
     DoReadCallback(rv);
 }
@@ -1282,10 +1287,7 @@ int SSLClientSocketOpenSSL::DoHandshakeLoop(int last_io_result) {
   return rv;
 }
 
-int SSLClientSocketOpenSSL::DoReadLoop(int result) {
-  if (result < 0)
-    return result;
-
+int SSLClientSocketOpenSSL::DoReadLoop() {
   bool network_moved;
   int rv;
   do {
@@ -1296,10 +1298,7 @@ int SSLClientSocketOpenSSL::DoReadLoop(int result) {
   return rv;
 }
 
-int SSLClientSocketOpenSSL::DoWriteLoop(int result) {
-  if (result < 0)
-    return result;
-
+int SSLClientSocketOpenSSL::DoWriteLoop() {
   bool network_moved;
   int rv;
   do {
@@ -1357,6 +1356,15 @@ int SSLClientSocketOpenSSL::DoPayloadRead() {
     } else if (*next_result < 0) {
       int err = SSL_get_error(ssl_, *next_result);
       *next_result = MapOpenSSLError(err, err_tracer);
+
+      // Many servers do not reliably send a close_notify alert when shutting
+      // down a connection, and instead terminate the TCP connection. This is
+      // reported as ERR_CONNECTION_CLOSED. Because of this, map the unclean
+      // shutdown to a graceful EOF, instead of treating it as an error as it
+      // should be.
+      if (*next_result == ERR_CONNECTION_CLOSED)
+        *next_result = 0;
+
       if (rv > 0 && *next_result == ERR_IO_PENDING) {
           // If at least some data was read from SSL_read(), do not treat
           // insufficient data as an error to return in the next call to