]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-11362 Attempt to rearrange verto socket shutdown sequence
authorSergey Khripchenko <shripchenko@intermedia.net>
Thu, 6 Sep 2018 15:25:43 +0000 (08:25 -0700)
committerAndrey Volk <andywolk@gmail.com>
Thu, 25 Jul 2019 20:31:11 +0000 (00:31 +0400)
src/mod/endpoints/mod_verto/ws.c

index 1185743298f4e7db51db81979c4af9e84d48e5c4..f33ce57239301077a2f4d063865153c6e3b6d7d2 100644 (file)
@@ -698,23 +698,6 @@ void ws_destroy(wsh_t *wsh)
        }
 
        if (wsh->ssl) {
-               int code, ssl_err, sanity = 100;
-               do {
-                       code = SSL_shutdown(wsh->ssl);
-                       if (code == 1) {
-                               break;
-                       }
-                       if (code < 0) {
-                               ssl_err = SSL_get_error(wsh->ssl, code);
-                       }
-                       if (wsh->block) {
-                               ms_sleep(10);
-                       } else {
-                               ms_sleep(1);
-                       }
-
-               } while ((code == 0 || (code < 0 && SSL_WANT_READ_WRITE(ssl_err))) && --sanity > 0);
-
                SSL_free(wsh->ssl);
                wsh->ssl = NULL;
        }
@@ -749,12 +732,30 @@ ssize_t ws_close(wsh_t *wsh, int16_t reason)
                ws_raw_write(wsh, fr, 4);
        }
 
+       if (wsh->ssl && wsh->sock != ws_sock_invalid) {
+               /* first invocation of SSL_shutdown() would normally return 0 and just try to send SSL protocol close request.
+                  we just slightly polite, since we want to close socket fast and
+                  not bother waiting for SSL protocol close response before closing socket,
+                  since we want cleanup to be done fast for scenarios like:
+                  client change NAT (like jump from one WiFi to another) and now unreachable from old ip:port, however
+                  immidiately reconnect with new ip:port but old session id (and thus should replace the old session/channel)
+               */
+               SSL_shutdown(wsh->ssl);
+       }
+
+       /* restore to blocking here, so any further read/writes will block */
        restore_socket(wsh->sock);
 
        if (wsh->close_sock && wsh->sock != ws_sock_invalid) {
+               /* signal socket to shutdown() before close(): FIN-ACK-FIN-ACK insead of RST-RST
+                  do not really handle errors here since it all going to die anyway.
+                  all buffered writes if any(like SSL_shutdown() ones) will still be sent.
+                */
 #ifndef WIN32
+               shutdown(wsh->sock, SHUT_RDWR);
                close(wsh->sock);
 #else
+               shutdown(wsh->sock, SD_BOTH);
                closesocket(wsh->sock);
 #endif
        }