uws-react-native 0.0.1-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +84 -0
- package/UwsReactNative.podspec +71 -0
- package/android/build.gradle.kts +138 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/id/sufeni/oss/uwsreactnative/UwsReactNativePackage.kt +18 -0
- package/apple/OnLoad.mm +17 -0
- package/cpp/CMakeLists.txt +154 -0
- package/cpp/UwsReactNativeModule.cpp +191 -0
- package/cpp/UwsReactNativeModule.h +30 -0
- package/cpp/app/AppHost.h +37 -0
- package/cpp/app/AppRunner.h +88 -0
- package/cpp/app/CMakeLists.txt +39 -0
- package/cpp/app/HttpRequestObject.h +173 -0
- package/cpp/app/HttpResponseObject.h +623 -0
- package/cpp/app/RecognizedString.h +71 -0
- package/cpp/app/TemplatedAppObject.h +472 -0
- package/cpp/bridging/ArrayBuffer.h +150 -0
- package/cpp/bridging/CMakeLists.txt +34 -0
- package/cpp/jsi/Buffer.h +91 -0
- package/cpp/jsi/CMakeLists.txt +34 -0
- package/cpp/uSockets/bsd.c +767 -0
- package/cpp/uSockets/context.c +524 -0
- package/cpp/uSockets/crypto/openssl.c +858 -0
- package/cpp/uSockets/crypto/sni_tree.cpp +218 -0
- package/cpp/uSockets/eventing/asio.cpp +475 -0
- package/cpp/uSockets/eventing/epoll_kqueue.c +458 -0
- package/cpp/uSockets/eventing/gcd.c +278 -0
- package/cpp/uSockets/eventing/libuv.c +305 -0
- package/cpp/uSockets/internal/eventing/asio.h +45 -0
- package/cpp/uSockets/internal/eventing/epoll_kqueue.h +67 -0
- package/cpp/uSockets/internal/eventing/gcd.h +40 -0
- package/cpp/uSockets/internal/eventing/libuv.h +45 -0
- package/cpp/uSockets/internal/internal.h +224 -0
- package/cpp/uSockets/internal/loop_data.h +38 -0
- package/cpp/uSockets/internal/networking/bsd.h +109 -0
- package/cpp/uSockets/io_uring/internal.h +98 -0
- package/cpp/uSockets/io_uring/io_context.c +302 -0
- package/cpp/uSockets/io_uring/io_loop.c +422 -0
- package/cpp/uSockets/io_uring/io_socket.c +139 -0
- package/cpp/uSockets/libusockets.h +350 -0
- package/cpp/uSockets/loop.c +396 -0
- package/cpp/uSockets/quic.c +1071 -0
- package/cpp/uSockets/quic.h +68 -0
- package/cpp/uSockets/socket.c +231 -0
- package/cpp/uSockets/udp.c +151 -0
- package/cpp/uWebSockets/uWebSockets/App.h +676 -0
- package/cpp/uWebSockets/uWebSockets/AsyncSocket.h +376 -0
- package/cpp/uWebSockets/uWebSockets/AsyncSocketData.h +94 -0
- package/cpp/uWebSockets/uWebSockets/BloomFilter.h +83 -0
- package/cpp/uWebSockets/uWebSockets/CachingApp.h +115 -0
- package/cpp/uWebSockets/uWebSockets/ChunkedEncoding.h +237 -0
- package/cpp/uWebSockets/uWebSockets/ClientApp.h +36 -0
- package/cpp/uWebSockets/uWebSockets/Http3App.h +140 -0
- package/cpp/uWebSockets/uWebSockets/Http3Context.h +157 -0
- package/cpp/uWebSockets/uWebSockets/Http3ContextData.h +21 -0
- package/cpp/uWebSockets/uWebSockets/Http3Request.h +22 -0
- package/cpp/uWebSockets/uWebSockets/Http3Response.h +120 -0
- package/cpp/uWebSockets/uWebSockets/Http3ResponseData.h +25 -0
- package/cpp/uWebSockets/uWebSockets/HttpContext.h +521 -0
- package/cpp/uWebSockets/uWebSockets/HttpContextData.h +60 -0
- package/cpp/uWebSockets/uWebSockets/HttpErrors.h +53 -0
- package/cpp/uWebSockets/uWebSockets/HttpParser.h +747 -0
- package/cpp/uWebSockets/uWebSockets/HttpResponse.h +605 -0
- package/cpp/uWebSockets/uWebSockets/HttpResponseData.h +123 -0
- package/cpp/uWebSockets/uWebSockets/HttpRouter.h +384 -0
- package/cpp/uWebSockets/uWebSockets/LocalCluster.h +64 -0
- package/cpp/uWebSockets/uWebSockets/Loop.h +238 -0
- package/cpp/uWebSockets/uWebSockets/LoopData.h +113 -0
- package/cpp/uWebSockets/uWebSockets/MessageParser.h +64 -0
- package/cpp/uWebSockets/uWebSockets/MoveOnlyFunction.h +389 -0
- package/cpp/uWebSockets/uWebSockets/Multipart.h +231 -0
- package/cpp/uWebSockets/uWebSockets/PerMessageDeflate.h +303 -0
- package/cpp/uWebSockets/uWebSockets/ProxyParser.h +187 -0
- package/cpp/uWebSockets/uWebSockets/QueryParser.h +120 -0
- package/cpp/uWebSockets/uWebSockets/TopicTree.h +364 -0
- package/cpp/uWebSockets/uWebSockets/Utilities.h +66 -0
- package/cpp/uWebSockets/uWebSockets/WebSocket.h +407 -0
- package/cpp/uWebSockets/uWebSockets/WebSocketContext.h +436 -0
- package/cpp/uWebSockets/uWebSockets/WebSocketContextData.h +109 -0
- package/cpp/uWebSockets/uWebSockets/WebSocketData.h +86 -0
- package/cpp/uWebSockets/uWebSockets/WebSocketExtensions.h +256 -0
- package/cpp/uWebSockets/uWebSockets/WebSocketHandshake.h +145 -0
- package/cpp/uWebSockets/uWebSockets/WebSocketProtocol.h +525 -0
- package/lib/commonjs/_internal/native-modules/NativeReactNativeUws.js +12 -0
- package/lib/commonjs/_internal/native-modules/NativeReactNativeUws.js.map +1 -0
- package/lib/commonjs/index.js +28 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/modules/App.js +17 -0
- package/lib/commonjs/modules/App.js.map +1 -0
- package/lib/commonjs/modules/CompressOptions.js +103 -0
- package/lib/commonjs/modules/CompressOptions.js.map +1 -0
- package/lib/commonjs/modules/EnvironmentVariables.js +17 -0
- package/lib/commonjs/modules/EnvironmentVariables.js.map +1 -0
- package/lib/commonjs/modules/ListenOptions.js +12 -0
- package/lib/commonjs/modules/ListenOptions.js.map +1 -0
- package/lib/commonjs/modules/SSLApp.js +15 -0
- package/lib/commonjs/modules/SSLApp.js.map +1 -0
- package/lib/commonjs/modules/getParts.js +28 -0
- package/lib/commonjs/modules/getParts.js.map +1 -0
- package/lib/commonjs/modules/index.js +61 -0
- package/lib/commonjs/modules/index.js.map +1 -0
- package/lib/commonjs/modules/us_listen_socket_close.js +21 -0
- package/lib/commonjs/modules/us_listen_socket_close.js.map +1 -0
- package/lib/commonjs/modules/us_socket_local_port.js +22 -0
- package/lib/commonjs/modules/us_socket_local_port.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/types/AppDescriptor.js +2 -0
- package/lib/commonjs/types/AppDescriptor.js.map +1 -0
- package/lib/commonjs/types/AppOptions.js +2 -0
- package/lib/commonjs/types/AppOptions.js.map +1 -0
- package/lib/commonjs/types/HttpRequest.js +6 -0
- package/lib/commonjs/types/HttpRequest.js.map +1 -0
- package/lib/commonjs/types/HttpResponse.js +6 -0
- package/lib/commonjs/types/HttpResponse.js.map +1 -0
- package/lib/commonjs/types/HttpRouterOptions.js +2 -0
- package/lib/commonjs/types/HttpRouterOptions.js.map +1 -0
- package/lib/commonjs/types/MultipartField.js +2 -0
- package/lib/commonjs/types/MultipartField.js.map +1 -0
- package/lib/commonjs/types/RecognizedString.js +2 -0
- package/lib/commonjs/types/RecognizedString.js.map +1 -0
- package/lib/commonjs/types/TemplatedApp.js +6 -0
- package/lib/commonjs/types/TemplatedApp.js.map +1 -0
- package/lib/commonjs/types/WebSocket.js +6 -0
- package/lib/commonjs/types/WebSocket.js.map +1 -0
- package/lib/commonjs/types/WebSocketBehaviour.js +139 -0
- package/lib/commonjs/types/WebSocketBehaviour.js.map +1 -0
- package/lib/commonjs/types/index.js +2 -0
- package/lib/commonjs/types/index.js.map +1 -0
- package/lib/commonjs/types/us_listen_socket.js +2 -0
- package/lib/commonjs/types/us_listen_socket.js.map +1 -0
- package/lib/commonjs/types/us_socket.js +2 -0
- package/lib/commonjs/types/us_socket.js.map +1 -0
- package/lib/commonjs/types/us_socket_context_t.js +2 -0
- package/lib/commonjs/types/us_socket_context_t.js.map +1 -0
- package/lib/module/_internal/native-modules/NativeReactNativeUws.js +10 -0
- package/lib/module/_internal/native-modules/NativeReactNativeUws.js.map +1 -0
- package/lib/module/index.js +5 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/modules/App.js +12 -0
- package/lib/module/modules/App.js.map +1 -0
- package/lib/module/modules/CompressOptions.js +103 -0
- package/lib/module/modules/CompressOptions.js.map +1 -0
- package/lib/module/modules/EnvironmentVariables.js +13 -0
- package/lib/module/modules/EnvironmentVariables.js.map +1 -0
- package/lib/module/modules/ListenOptions.js +8 -0
- package/lib/module/modules/ListenOptions.js.map +1 -0
- package/lib/module/modules/SSLApp.js +15 -0
- package/lib/module/modules/SSLApp.js.map +1 -0
- package/lib/module/modules/getParts.js +23 -0
- package/lib/module/modules/getParts.js.map +1 -0
- package/lib/module/modules/index.js +11 -0
- package/lib/module/modules/index.js.map +1 -0
- package/lib/module/modules/us_listen_socket_close.js +17 -0
- package/lib/module/modules/us_listen_socket_close.js.map +1 -0
- package/lib/module/modules/us_socket_local_port.js +18 -0
- package/lib/module/modules/us_socket_local_port.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/types/AppDescriptor.js +2 -0
- package/lib/module/types/AppDescriptor.js.map +1 -0
- package/lib/module/types/AppOptions.js +2 -0
- package/lib/module/types/AppOptions.js.map +1 -0
- package/lib/module/types/HttpRequest.js +4 -0
- package/lib/module/types/HttpRequest.js.map +1 -0
- package/lib/module/types/HttpResponse.js +4 -0
- package/lib/module/types/HttpResponse.js.map +1 -0
- package/lib/module/types/HttpRouterOptions.js +2 -0
- package/lib/module/types/HttpRouterOptions.js.map +1 -0
- package/lib/module/types/MultipartField.js +2 -0
- package/lib/module/types/MultipartField.js.map +1 -0
- package/lib/module/types/RecognizedString.js +2 -0
- package/lib/module/types/RecognizedString.js.map +1 -0
- package/lib/module/types/TemplatedApp.js +4 -0
- package/lib/module/types/TemplatedApp.js.map +1 -0
- package/lib/module/types/WebSocket.js +4 -0
- package/lib/module/types/WebSocket.js.map +1 -0
- package/lib/module/types/WebSocketBehaviour.js +139 -0
- package/lib/module/types/WebSocketBehaviour.js.map +1 -0
- package/lib/module/types/index.js +2 -0
- package/lib/module/types/index.js.map +1 -0
- package/lib/module/types/us_listen_socket.js +2 -0
- package/lib/module/types/us_listen_socket.js.map +1 -0
- package/lib/module/types/us_socket.js +2 -0
- package/lib/module/types/us_socket.js.map +1 -0
- package/lib/module/types/us_socket_context_t.js +2 -0
- package/lib/module/types/us_socket_context_t.js.map +1 -0
- package/lib/typescript/commonjs/_internal/native-modules/NativeReactNativeUws.d.ts +22 -0
- package/lib/typescript/commonjs/_internal/native-modules/NativeReactNativeUws.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +3 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/modules/App.d.ts +7 -0
- package/lib/typescript/commonjs/modules/App.d.ts.map +1 -0
- package/lib/typescript/commonjs/modules/CompressOptions.d.ts +1 -0
- package/lib/typescript/commonjs/modules/CompressOptions.d.ts.map +1 -0
- package/lib/typescript/commonjs/modules/EnvironmentVariables.d.ts +16 -0
- package/lib/typescript/commonjs/modules/EnvironmentVariables.d.ts.map +1 -0
- package/lib/typescript/commonjs/modules/ListenOptions.d.ts +5 -0
- package/lib/typescript/commonjs/modules/ListenOptions.d.ts.map +1 -0
- package/lib/typescript/commonjs/modules/SSLApp.d.ts +1 -0
- package/lib/typescript/commonjs/modules/SSLApp.d.ts.map +1 -0
- package/lib/typescript/commonjs/modules/getParts.d.ts +6 -0
- package/lib/typescript/commonjs/modules/getParts.d.ts.map +1 -0
- package/lib/typescript/commonjs/modules/index.d.ts +6 -0
- package/lib/typescript/commonjs/modules/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/modules/us_listen_socket_close.d.ts +5 -0
- package/lib/typescript/commonjs/modules/us_listen_socket_close.d.ts.map +1 -0
- package/lib/typescript/commonjs/modules/us_socket_local_port.d.ts +5 -0
- package/lib/typescript/commonjs/modules/us_socket_local_port.d.ts.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/types/AppDescriptor.d.ts +8 -0
- package/lib/typescript/commonjs/types/AppDescriptor.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/AppOptions.d.ts +17 -0
- package/lib/typescript/commonjs/types/AppOptions.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/HttpRequest.d.ts +54 -0
- package/lib/typescript/commonjs/types/HttpRequest.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/HttpResponse.d.ts +169 -0
- package/lib/typescript/commonjs/types/HttpResponse.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/HttpRouterOptions.d.ts +24 -0
- package/lib/typescript/commonjs/types/HttpRouterOptions.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/MultipartField.d.ts +7 -0
- package/lib/typescript/commonjs/types/MultipartField.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/RecognizedString.d.ts +10 -0
- package/lib/typescript/commonjs/types/RecognizedString.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/TemplatedApp.d.ts +108 -0
- package/lib/typescript/commonjs/types/TemplatedApp.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/WebSocket.d.ts +96 -0
- package/lib/typescript/commonjs/types/WebSocket.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/WebSocketBehaviour.d.ts +1 -0
- package/lib/typescript/commonjs/types/WebSocketBehaviour.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/index.d.ts +6 -0
- package/lib/typescript/commonjs/types/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/us_listen_socket.d.ts +7 -0
- package/lib/typescript/commonjs/types/us_listen_socket.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/us_socket.d.ts +7 -0
- package/lib/typescript/commonjs/types/us_socket.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/us_socket_context_t.d.ts +7 -0
- package/lib/typescript/commonjs/types/us_socket_context_t.d.ts.map +1 -0
- package/lib/typescript/module/_internal/native-modules/NativeReactNativeUws.d.ts +22 -0
- package/lib/typescript/module/_internal/native-modules/NativeReactNativeUws.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +3 -0
- package/lib/typescript/module/index.d.ts.map +1 -0
- package/lib/typescript/module/modules/App.d.ts +7 -0
- package/lib/typescript/module/modules/App.d.ts.map +1 -0
- package/lib/typescript/module/modules/CompressOptions.d.ts +1 -0
- package/lib/typescript/module/modules/CompressOptions.d.ts.map +1 -0
- package/lib/typescript/module/modules/EnvironmentVariables.d.ts +16 -0
- package/lib/typescript/module/modules/EnvironmentVariables.d.ts.map +1 -0
- package/lib/typescript/module/modules/ListenOptions.d.ts +5 -0
- package/lib/typescript/module/modules/ListenOptions.d.ts.map +1 -0
- package/lib/typescript/module/modules/SSLApp.d.ts +1 -0
- package/lib/typescript/module/modules/SSLApp.d.ts.map +1 -0
- package/lib/typescript/module/modules/getParts.d.ts +6 -0
- package/lib/typescript/module/modules/getParts.d.ts.map +1 -0
- package/lib/typescript/module/modules/index.d.ts +6 -0
- package/lib/typescript/module/modules/index.d.ts.map +1 -0
- package/lib/typescript/module/modules/us_listen_socket_close.d.ts +5 -0
- package/lib/typescript/module/modules/us_listen_socket_close.d.ts.map +1 -0
- package/lib/typescript/module/modules/us_socket_local_port.d.ts +5 -0
- package/lib/typescript/module/modules/us_socket_local_port.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/types/AppDescriptor.d.ts +8 -0
- package/lib/typescript/module/types/AppDescriptor.d.ts.map +1 -0
- package/lib/typescript/module/types/AppOptions.d.ts +17 -0
- package/lib/typescript/module/types/AppOptions.d.ts.map +1 -0
- package/lib/typescript/module/types/HttpRequest.d.ts +54 -0
- package/lib/typescript/module/types/HttpRequest.d.ts.map +1 -0
- package/lib/typescript/module/types/HttpResponse.d.ts +169 -0
- package/lib/typescript/module/types/HttpResponse.d.ts.map +1 -0
- package/lib/typescript/module/types/HttpRouterOptions.d.ts +24 -0
- package/lib/typescript/module/types/HttpRouterOptions.d.ts.map +1 -0
- package/lib/typescript/module/types/MultipartField.d.ts +7 -0
- package/lib/typescript/module/types/MultipartField.d.ts.map +1 -0
- package/lib/typescript/module/types/RecognizedString.d.ts +10 -0
- package/lib/typescript/module/types/RecognizedString.d.ts.map +1 -0
- package/lib/typescript/module/types/TemplatedApp.d.ts +108 -0
- package/lib/typescript/module/types/TemplatedApp.d.ts.map +1 -0
- package/lib/typescript/module/types/WebSocket.d.ts +96 -0
- package/lib/typescript/module/types/WebSocket.d.ts.map +1 -0
- package/lib/typescript/module/types/WebSocketBehaviour.d.ts +1 -0
- package/lib/typescript/module/types/WebSocketBehaviour.d.ts.map +1 -0
- package/lib/typescript/module/types/index.d.ts +6 -0
- package/lib/typescript/module/types/index.d.ts.map +1 -0
- package/lib/typescript/module/types/us_listen_socket.d.ts +7 -0
- package/lib/typescript/module/types/us_listen_socket.d.ts.map +1 -0
- package/lib/typescript/module/types/us_socket.d.ts +7 -0
- package/lib/typescript/module/types/us_socket.d.ts.map +1 -0
- package/lib/typescript/module/types/us_socket_context_t.d.ts +7 -0
- package/lib/typescript/module/types/us_socket_context_t.d.ts.map +1 -0
- package/lib/typescript/tsconfig.tsbuildinfo +1 -0
- package/package.json +62 -0
- package/src/_internal/native-modules/NativeUwsReactNative.ts +40 -0
- package/src/index.ts +2 -0
- package/src/modules/App.ts +14 -0
- package/src/modules/CompressOptions.ts +101 -0
- package/src/modules/EnvironmentVariables.ts +16 -0
- package/src/modules/ListenOptions.ts +4 -0
- package/src/modules/SSLApp.ts +13 -0
- package/src/modules/getParts.ts +29 -0
- package/src/modules/index.ts +8 -0
- package/src/modules/us_listen_socket_close.ts +15 -0
- package/src/modules/us_socket_local_port.ts +16 -0
- package/src/types/AppDescriptor.ts +7 -0
- package/src/types/AppOptions.ts +22 -0
- package/src/types/HttpRequest.ts +74 -0
- package/src/types/HttpResponse.ts +309 -0
- package/src/types/HttpRouterOptions.ts +24 -0
- package/src/types/MultipartField.ts +6 -0
- package/src/types/RecognizedString.ts +11 -0
- package/src/types/TemplatedApp.ts +285 -0
- package/src/types/WebSocket.ts +147 -0
- package/src/types/WebSocketBehaviour.ts +137 -0
- package/src/types/index.ts +12 -0
- package/src/types/us_listen_socket.ts +6 -0
- package/src/types/us_socket.ts +6 -0
- package/src/types/us_socket_context_t.ts +6 -0
|
@@ -0,0 +1,858 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Authored by Alex Hultman, 2018-2019.
|
|
3
|
+
* Intellectual property of third-party.
|
|
4
|
+
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#if (defined(LIBUS_USE_OPENSSL) || defined(LIBUS_USE_WOLFSSL))
|
|
19
|
+
|
|
20
|
+
/* These are in sni_tree.cpp */
|
|
21
|
+
void *sni_new();
|
|
22
|
+
void sni_free(void *sni, void(*cb)(void *));
|
|
23
|
+
int sni_add(void *sni, const char *hostname, void *user);
|
|
24
|
+
void *sni_remove(void *sni, const char *hostname);
|
|
25
|
+
void *sni_find(void *sni, const char *hostname);
|
|
26
|
+
|
|
27
|
+
#include "libusockets.h"
|
|
28
|
+
#include "internal/internal.h"
|
|
29
|
+
#include <string.h>
|
|
30
|
+
|
|
31
|
+
/* This module contains the entire OpenSSL implementation
|
|
32
|
+
* of the SSL socket and socket context interfaces. */
|
|
33
|
+
#ifdef LIBUS_USE_OPENSSL
|
|
34
|
+
#include <openssl/ssl.h>
|
|
35
|
+
#include <openssl/bio.h>
|
|
36
|
+
#include <openssl/err.h>
|
|
37
|
+
#include <openssl/dh.h>
|
|
38
|
+
#elif LIBUS_USE_WOLFSSL
|
|
39
|
+
#include <wolfssl/options.h>
|
|
40
|
+
#include <wolfssl/openssl/ssl.h>
|
|
41
|
+
#include <wolfssl/openssl/bio.h>
|
|
42
|
+
#include <wolfssl/openssl/err.h>
|
|
43
|
+
#include <wolfssl/openssl/dh.h>
|
|
44
|
+
#endif
|
|
45
|
+
|
|
46
|
+
struct loop_ssl_data {
|
|
47
|
+
char *ssl_read_input, *ssl_read_output;
|
|
48
|
+
unsigned int ssl_read_input_length;
|
|
49
|
+
unsigned int ssl_read_input_offset;
|
|
50
|
+
struct us_socket_t *ssl_socket;
|
|
51
|
+
|
|
52
|
+
int last_write_was_msg_more;
|
|
53
|
+
int msg_more;
|
|
54
|
+
|
|
55
|
+
BIO *shared_rbio;
|
|
56
|
+
BIO *shared_wbio;
|
|
57
|
+
BIO_METHOD *shared_biom;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
struct us_internal_ssl_socket_context_t {
|
|
61
|
+
struct us_socket_context_t sc;
|
|
62
|
+
|
|
63
|
+
// this thing can be shared with other socket contexts via socket transfer!
|
|
64
|
+
// maybe instead of holding once you hold many, a vector or set
|
|
65
|
+
// when a socket that belongs to another socket context transfers to a new socket context
|
|
66
|
+
SSL_CTX *ssl_context;
|
|
67
|
+
int is_parent;
|
|
68
|
+
|
|
69
|
+
/* These decorate the base implementation */
|
|
70
|
+
struct us_internal_ssl_socket_t *(*on_open)(struct us_internal_ssl_socket_t *, int is_client, char *ip, int ip_length);
|
|
71
|
+
struct us_internal_ssl_socket_t *(*on_data)(struct us_internal_ssl_socket_t *, char *data, int length);
|
|
72
|
+
struct us_internal_ssl_socket_t *(*on_writable)(struct us_internal_ssl_socket_t *);
|
|
73
|
+
struct us_internal_ssl_socket_t *(*on_close)(struct us_internal_ssl_socket_t *, int code, void *reason);
|
|
74
|
+
|
|
75
|
+
/* Called for missing SNI hostnames, if not NULL */
|
|
76
|
+
void (*on_server_name)(struct us_internal_ssl_socket_context_t *, const char *hostname);
|
|
77
|
+
|
|
78
|
+
/* Pointer to sni tree, created when the context is created and freed likewise when freed */
|
|
79
|
+
void *sni;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// same here, should or shouldn't it contain s?
|
|
83
|
+
struct us_internal_ssl_socket_t {
|
|
84
|
+
struct us_socket_t s;
|
|
85
|
+
SSL *ssl;
|
|
86
|
+
int ssl_write_wants_read; // we use this for now
|
|
87
|
+
int ssl_read_wants_write;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
int passphrase_cb(char *buf, int size, int rwflag, void *u) {
|
|
91
|
+
const char *passphrase = (const char *) u;
|
|
92
|
+
size_t passphrase_length = strlen(passphrase);
|
|
93
|
+
memcpy(buf, passphrase, passphrase_length);
|
|
94
|
+
// put null at end? no?
|
|
95
|
+
return (int) passphrase_length;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
int BIO_s_custom_create(BIO *bio) {
|
|
99
|
+
BIO_set_init(bio, 1);
|
|
100
|
+
return 1;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
long BIO_s_custom_ctrl(BIO *bio, int cmd, long num, void *user) {
|
|
104
|
+
switch(cmd) {
|
|
105
|
+
case BIO_CTRL_FLUSH:
|
|
106
|
+
return 1;
|
|
107
|
+
default:
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
int BIO_s_custom_write(BIO *bio, const char *data, int length) {
|
|
113
|
+
struct loop_ssl_data *loop_ssl_data = (struct loop_ssl_data *) BIO_get_data(bio);
|
|
114
|
+
|
|
115
|
+
//printf("BIO_s_custom_write\n");
|
|
116
|
+
|
|
117
|
+
loop_ssl_data->last_write_was_msg_more = loop_ssl_data->msg_more || length == 16413;
|
|
118
|
+
int written = us_socket_write(0, loop_ssl_data->ssl_socket, data, length, loop_ssl_data->last_write_was_msg_more);
|
|
119
|
+
|
|
120
|
+
if (!written) {
|
|
121
|
+
BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY | BIO_FLAGS_WRITE);
|
|
122
|
+
return -1;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
//printf("BIO_s_custom_write returns: %d\n", ret);
|
|
126
|
+
|
|
127
|
+
return written;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
int BIO_s_custom_read(BIO *bio, char *dst, int length) {
|
|
131
|
+
struct loop_ssl_data *loop_ssl_data = (struct loop_ssl_data *) BIO_get_data(bio);
|
|
132
|
+
|
|
133
|
+
//printf("BIO_s_custom_read\n");
|
|
134
|
+
|
|
135
|
+
if (!loop_ssl_data->ssl_read_input_length) {
|
|
136
|
+
BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY | BIO_FLAGS_READ);
|
|
137
|
+
return -1;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if ((unsigned int) length > loop_ssl_data->ssl_read_input_length) {
|
|
141
|
+
length = loop_ssl_data->ssl_read_input_length;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
memcpy(dst, loop_ssl_data->ssl_read_input + loop_ssl_data->ssl_read_input_offset, length);
|
|
145
|
+
|
|
146
|
+
loop_ssl_data->ssl_read_input_offset += length;
|
|
147
|
+
loop_ssl_data->ssl_read_input_length -= length;
|
|
148
|
+
return length;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
struct us_internal_ssl_socket_t *ssl_on_open(struct us_internal_ssl_socket_t *s, int is_client, char *ip, int ip_length) {
|
|
152
|
+
struct us_internal_ssl_socket_context_t *context = (struct us_internal_ssl_socket_context_t *) us_socket_context(0, &s->s);
|
|
153
|
+
|
|
154
|
+
struct us_loop_t *loop = us_socket_context_loop(0, &context->sc);
|
|
155
|
+
struct loop_ssl_data *loop_ssl_data = (struct loop_ssl_data *) loop->data.ssl_data;
|
|
156
|
+
|
|
157
|
+
s->ssl = SSL_new(context->ssl_context);
|
|
158
|
+
s->ssl_write_wants_read = 0;
|
|
159
|
+
s->ssl_read_wants_write = 0;
|
|
160
|
+
SSL_set_bio(s->ssl, loop_ssl_data->shared_rbio, loop_ssl_data->shared_wbio);
|
|
161
|
+
|
|
162
|
+
BIO_up_ref(loop_ssl_data->shared_rbio);
|
|
163
|
+
BIO_up_ref(loop_ssl_data->shared_wbio);
|
|
164
|
+
|
|
165
|
+
if (is_client) {
|
|
166
|
+
SSL_set_connect_state(s->ssl);
|
|
167
|
+
} else {
|
|
168
|
+
SSL_set_accept_state(s->ssl);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return (struct us_internal_ssl_socket_t *) context->on_open(s, is_client, ip, ip_length);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* This one is a helper; it is entirely shared with non-SSL so can be removed */
|
|
175
|
+
struct us_internal_ssl_socket_t *us_internal_ssl_socket_close(struct us_internal_ssl_socket_t *s, int code, void *reason) {
|
|
176
|
+
return (struct us_internal_ssl_socket_t *) us_socket_close(0, (struct us_socket_t *) s, code, reason);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
struct us_internal_ssl_socket_t *ssl_on_close(struct us_internal_ssl_socket_t *s, int code, void *reason) {
|
|
180
|
+
struct us_internal_ssl_socket_context_t *context = (struct us_internal_ssl_socket_context_t *) us_socket_context(0, &s->s);
|
|
181
|
+
|
|
182
|
+
SSL_free(s->ssl);
|
|
183
|
+
|
|
184
|
+
return context->on_close(s, code, reason);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
struct us_internal_ssl_socket_t *ssl_on_end(struct us_internal_ssl_socket_t *s) {
|
|
188
|
+
// struct us_internal_ssl_socket_context_t *context = (struct us_internal_ssl_socket_context_t *) us_socket_context(0, &s->s);
|
|
189
|
+
|
|
190
|
+
// whatever state we are in, a TCP FIN is always an answered shutdown
|
|
191
|
+
|
|
192
|
+
/* Todo: this should report CLEANLY SHUTDOWN as reason */
|
|
193
|
+
return us_internal_ssl_socket_close(s, 0, NULL);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// this whole function needs a complete clean-up
|
|
197
|
+
struct us_internal_ssl_socket_t *ssl_on_data(struct us_internal_ssl_socket_t *s, void *data, int length) {
|
|
198
|
+
// note: this context can change when we adopt the socket!
|
|
199
|
+
struct us_internal_ssl_socket_context_t *context = (struct us_internal_ssl_socket_context_t *) us_socket_context(0, &s->s);
|
|
200
|
+
|
|
201
|
+
struct us_loop_t *loop = us_socket_context_loop(0, &context->sc);
|
|
202
|
+
struct loop_ssl_data *loop_ssl_data = (struct loop_ssl_data *) loop->data.ssl_data;
|
|
203
|
+
|
|
204
|
+
// note: if we put data here we should never really clear it (not in write either, it still should be available for SSL_write to read from!)
|
|
205
|
+
loop_ssl_data->ssl_read_input = data;
|
|
206
|
+
loop_ssl_data->ssl_read_input_length = length;
|
|
207
|
+
loop_ssl_data->ssl_read_input_offset = 0;
|
|
208
|
+
loop_ssl_data->ssl_socket = &s->s;
|
|
209
|
+
loop_ssl_data->msg_more = 0;
|
|
210
|
+
|
|
211
|
+
if (us_internal_ssl_socket_is_shut_down(s)) {
|
|
212
|
+
|
|
213
|
+
int ret;
|
|
214
|
+
if ((ret = SSL_shutdown(s->ssl)) == 1) {
|
|
215
|
+
// two phase shutdown is complete here
|
|
216
|
+
//printf("Two step SSL shutdown complete\n");
|
|
217
|
+
|
|
218
|
+
/* Todo: this should also report some kind of clean shutdown */
|
|
219
|
+
return us_internal_ssl_socket_close(s, 0, NULL);
|
|
220
|
+
} else if (ret < 0) {
|
|
221
|
+
|
|
222
|
+
int err = SSL_get_error(s->ssl, ret);
|
|
223
|
+
|
|
224
|
+
if (err == SSL_ERROR_SSL || err == SSL_ERROR_SYSCALL) {
|
|
225
|
+
// we need to clear the error queue in case these added to the thread local queue
|
|
226
|
+
ERR_clear_error();
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// no further processing of data when in shutdown state
|
|
232
|
+
return s;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// bug checking: this loop needs a lot of attention and clean-ups and check-ups
|
|
236
|
+
int read = 0;
|
|
237
|
+
restart:
|
|
238
|
+
while (1) {
|
|
239
|
+
int just_read = SSL_read(s->ssl, loop_ssl_data->ssl_read_output + LIBUS_RECV_BUFFER_PADDING + read, LIBUS_RECV_BUFFER_LENGTH - read);
|
|
240
|
+
|
|
241
|
+
if (just_read <= 0) {
|
|
242
|
+
int err = SSL_get_error(s->ssl, just_read);
|
|
243
|
+
|
|
244
|
+
// as far as I know these are the only errors we want to handle
|
|
245
|
+
if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) {
|
|
246
|
+
|
|
247
|
+
// clear per thread error queue if it may contain something
|
|
248
|
+
if (err == SSL_ERROR_SSL || err == SSL_ERROR_SYSCALL) {
|
|
249
|
+
ERR_clear_error();
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// terminate connection here
|
|
253
|
+
return us_internal_ssl_socket_close(s, 0, NULL);
|
|
254
|
+
} else {
|
|
255
|
+
// emit the data we have and exit
|
|
256
|
+
|
|
257
|
+
if (err == SSL_ERROR_WANT_WRITE) {
|
|
258
|
+
// here we need to trigger writable event next ssl_read!
|
|
259
|
+
s->ssl_read_wants_write = 1;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// assume we emptied the input buffer fully or error here as well!
|
|
263
|
+
if (loop_ssl_data->ssl_read_input_length) {
|
|
264
|
+
return us_internal_ssl_socket_close(s, 0, NULL);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// cannot emit zero length to app
|
|
268
|
+
if (!read) {
|
|
269
|
+
break;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
context = (struct us_internal_ssl_socket_context_t *) us_socket_context(0, &s->s);
|
|
273
|
+
|
|
274
|
+
s = context->on_data(s, loop_ssl_data->ssl_read_output + LIBUS_RECV_BUFFER_PADDING, read);
|
|
275
|
+
if (us_socket_is_closed(0, &s->s)) {
|
|
276
|
+
return s;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
read += just_read;
|
|
285
|
+
|
|
286
|
+
// at this point we might be full and need to emit the data to application and start over
|
|
287
|
+
if (read == LIBUS_RECV_BUFFER_LENGTH) {
|
|
288
|
+
|
|
289
|
+
context = (struct us_internal_ssl_socket_context_t *) us_socket_context(0, &s->s);
|
|
290
|
+
|
|
291
|
+
// emit data and restart
|
|
292
|
+
s = context->on_data(s, loop_ssl_data->ssl_read_output + LIBUS_RECV_BUFFER_PADDING, read);
|
|
293
|
+
if (us_socket_is_closed(0, &s->s)) {
|
|
294
|
+
return s;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
read = 0;
|
|
298
|
+
goto restart;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// trigger writable if we failed last write with want read
|
|
303
|
+
if (s->ssl_write_wants_read) {
|
|
304
|
+
s->ssl_write_wants_read = 0;
|
|
305
|
+
|
|
306
|
+
// make sure to update context before we call (context can change if the user adopts the socket!)
|
|
307
|
+
context = (struct us_internal_ssl_socket_context_t *) us_socket_context(0, &s->s);
|
|
308
|
+
|
|
309
|
+
s = (struct us_internal_ssl_socket_t *) context->sc.on_writable(&s->s); // cast here!
|
|
310
|
+
// if we are closed here, then exit
|
|
311
|
+
if (us_socket_is_closed(0, &s->s)) {
|
|
312
|
+
return s;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// check this then?
|
|
317
|
+
if (SSL_get_shutdown(s->ssl) & SSL_RECEIVED_SHUTDOWN) {
|
|
318
|
+
//printf("SSL_RECEIVED_SHUTDOWN\n");
|
|
319
|
+
|
|
320
|
+
//exit(-2);
|
|
321
|
+
|
|
322
|
+
// not correct anyways!
|
|
323
|
+
s = us_internal_ssl_socket_close(s, 0, NULL);
|
|
324
|
+
|
|
325
|
+
//us_
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
return s;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
struct us_internal_ssl_socket_t *ssl_on_writable(struct us_internal_ssl_socket_t *s) {
|
|
332
|
+
|
|
333
|
+
struct us_internal_ssl_socket_context_t *context = (struct us_internal_ssl_socket_context_t *) us_socket_context(0, &s->s);
|
|
334
|
+
|
|
335
|
+
// todo: cork here so that we efficiently output both from reading and from writing?
|
|
336
|
+
|
|
337
|
+
if (s->ssl_read_wants_write) {
|
|
338
|
+
s->ssl_read_wants_write = 0;
|
|
339
|
+
|
|
340
|
+
// make sure to update context before we call (context can change if the user adopts the socket!)
|
|
341
|
+
context = (struct us_internal_ssl_socket_context_t *) us_socket_context(0, &s->s);
|
|
342
|
+
|
|
343
|
+
// if this one fails to write data, it sets ssl_read_wants_write again
|
|
344
|
+
s = (struct us_internal_ssl_socket_t *) context->sc.on_data(&s->s, 0, 0); // cast here!
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// should this one come before we have read? should it come always? spurious on_writable is okay
|
|
348
|
+
s = context->on_writable(s);
|
|
349
|
+
|
|
350
|
+
return s;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/* Lazily inits loop ssl data first time */
|
|
354
|
+
void us_internal_init_loop_ssl_data(struct us_loop_t *loop) {
|
|
355
|
+
if (!loop->data.ssl_data) {
|
|
356
|
+
struct loop_ssl_data *loop_ssl_data = malloc(sizeof(struct loop_ssl_data));
|
|
357
|
+
|
|
358
|
+
loop_ssl_data->ssl_read_output = malloc(LIBUS_RECV_BUFFER_LENGTH + LIBUS_RECV_BUFFER_PADDING * 2);
|
|
359
|
+
|
|
360
|
+
OPENSSL_init_ssl(0, NULL);
|
|
361
|
+
|
|
362
|
+
loop_ssl_data->shared_biom = BIO_meth_new(BIO_TYPE_MEM, "µS BIO");
|
|
363
|
+
BIO_meth_set_create(loop_ssl_data->shared_biom, BIO_s_custom_create);
|
|
364
|
+
BIO_meth_set_write(loop_ssl_data->shared_biom, BIO_s_custom_write);
|
|
365
|
+
BIO_meth_set_read(loop_ssl_data->shared_biom, BIO_s_custom_read);
|
|
366
|
+
BIO_meth_set_ctrl(loop_ssl_data->shared_biom, BIO_s_custom_ctrl);
|
|
367
|
+
|
|
368
|
+
loop_ssl_data->shared_rbio = BIO_new(loop_ssl_data->shared_biom);
|
|
369
|
+
loop_ssl_data->shared_wbio = BIO_new(loop_ssl_data->shared_biom);
|
|
370
|
+
BIO_set_data(loop_ssl_data->shared_rbio, loop_ssl_data);
|
|
371
|
+
BIO_set_data(loop_ssl_data->shared_wbio, loop_ssl_data);
|
|
372
|
+
|
|
373
|
+
loop->data.ssl_data = loop_ssl_data;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/* Called by loop free, clears any loop ssl data */
|
|
378
|
+
void us_internal_free_loop_ssl_data(struct us_loop_t *loop) {
|
|
379
|
+
struct loop_ssl_data *loop_ssl_data = (struct loop_ssl_data *) loop->data.ssl_data;
|
|
380
|
+
|
|
381
|
+
if (loop_ssl_data) {
|
|
382
|
+
free(loop_ssl_data->ssl_read_output);
|
|
383
|
+
|
|
384
|
+
BIO_free(loop_ssl_data->shared_rbio);
|
|
385
|
+
BIO_free(loop_ssl_data->shared_wbio);
|
|
386
|
+
|
|
387
|
+
BIO_meth_free(loop_ssl_data->shared_biom);
|
|
388
|
+
|
|
389
|
+
free(loop_ssl_data);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// we throttle reading data for ssl sockets that are in init state. here we actually use
|
|
394
|
+
// the kernel buffering to our advantage
|
|
395
|
+
int ssl_is_low_prio(struct us_internal_ssl_socket_t *s) {
|
|
396
|
+
/* We use SSL_in_before() instead of SSL_in_init(), because only the first step is CPU intensive, and we want to
|
|
397
|
+
* speed up the rest of connection establishing if the CPU intensive work is already done, so fully established
|
|
398
|
+
* connections increase lineary over time under high load */
|
|
399
|
+
return SSL_in_init(s->ssl);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/* Per-context functions */
|
|
403
|
+
void *us_internal_ssl_socket_context_get_native_handle(struct us_internal_ssl_socket_context_t *context) {
|
|
404
|
+
return context->ssl_context;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
struct us_internal_ssl_socket_context_t *us_internal_create_child_ssl_socket_context(struct us_internal_ssl_socket_context_t *context, int context_ext_size) {
|
|
408
|
+
/* Create a new non-SSL context */
|
|
409
|
+
struct us_socket_context_options_t options = {0};
|
|
410
|
+
struct us_internal_ssl_socket_context_t *child_context = (struct us_internal_ssl_socket_context_t *) us_create_socket_context(0, context->sc.loop, sizeof(struct us_internal_ssl_socket_context_t) + context_ext_size, options);
|
|
411
|
+
|
|
412
|
+
/* The only thing we share is SSL_CTX */
|
|
413
|
+
child_context->ssl_context = context->ssl_context;
|
|
414
|
+
child_context->is_parent = 0;
|
|
415
|
+
|
|
416
|
+
return child_context;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/* Common function for creating a context from options.
|
|
420
|
+
* We must NOT free a SSL_CTX with only SSL_CTX_free! Also free any password */
|
|
421
|
+
void free_ssl_context(SSL_CTX *ssl_context) {
|
|
422
|
+
if (!ssl_context) {
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/* If we have set a password string, free it here */
|
|
427
|
+
void *password = SSL_CTX_get_default_passwd_cb_userdata(ssl_context);
|
|
428
|
+
/* OpenSSL returns NULL if we have no set password */
|
|
429
|
+
free(password);
|
|
430
|
+
|
|
431
|
+
SSL_CTX_free(ssl_context);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/* This function should take any options and return SSL_CTX - which has to be free'd with
|
|
435
|
+
* our destructor function - free_ssl_context() */
|
|
436
|
+
SSL_CTX *create_ssl_context_from_options(struct us_socket_context_options_t options) {
|
|
437
|
+
/* Create the context */
|
|
438
|
+
SSL_CTX *ssl_context = SSL_CTX_new(TLS_method());
|
|
439
|
+
|
|
440
|
+
/* Default options we rely on - changing these will break our logic */
|
|
441
|
+
SSL_CTX_set_read_ahead(ssl_context, 1);
|
|
442
|
+
SSL_CTX_set_mode(ssl_context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
|
|
443
|
+
|
|
444
|
+
/* Anything below TLS 1.2 is disabled */
|
|
445
|
+
SSL_CTX_set_min_proto_version(ssl_context, TLS1_2_VERSION);
|
|
446
|
+
|
|
447
|
+
/* The following are helpers. You may easily implement whatever you want by using the native handle directly */
|
|
448
|
+
|
|
449
|
+
/* Important option for lowering memory usage, but lowers performance slightly */
|
|
450
|
+
if (options.ssl_prefer_low_memory_usage) {
|
|
451
|
+
SSL_CTX_set_mode(ssl_context, SSL_MODE_RELEASE_BUFFERS);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
if (options.passphrase) {
|
|
455
|
+
/* When freeing the CTX we need to check SSL_CTX_get_default_passwd_cb_userdata and
|
|
456
|
+
* free it if set */
|
|
457
|
+
SSL_CTX_set_default_passwd_cb_userdata(ssl_context, (void *) strdup(options.passphrase));
|
|
458
|
+
SSL_CTX_set_default_passwd_cb(ssl_context, passphrase_cb);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/* This one most probably do not need the cert_file_name string to be kept alive */
|
|
462
|
+
if (options.cert_file_name) {
|
|
463
|
+
if (SSL_CTX_use_certificate_chain_file(ssl_context, options.cert_file_name) != 1) {
|
|
464
|
+
free_ssl_context(ssl_context);
|
|
465
|
+
return NULL;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/* Same as above - we can discard this string afterwards I suppose */
|
|
470
|
+
if (options.key_file_name) {
|
|
471
|
+
if (SSL_CTX_use_PrivateKey_file(ssl_context, options.key_file_name, SSL_FILETYPE_PEM) != 1) {
|
|
472
|
+
free_ssl_context(ssl_context);
|
|
473
|
+
return NULL;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
if (options.ca_file_name) {
|
|
478
|
+
STACK_OF(X509_NAME) *ca_list;
|
|
479
|
+
ca_list = SSL_load_client_CA_file(options.ca_file_name);
|
|
480
|
+
if(ca_list == NULL) {
|
|
481
|
+
free_ssl_context(ssl_context);
|
|
482
|
+
return NULL;
|
|
483
|
+
}
|
|
484
|
+
SSL_CTX_set_client_CA_list(ssl_context, ca_list);
|
|
485
|
+
if (SSL_CTX_load_verify_locations(ssl_context, options.ca_file_name, NULL) != 1) {
|
|
486
|
+
free_ssl_context(ssl_context);
|
|
487
|
+
return NULL;
|
|
488
|
+
}
|
|
489
|
+
SSL_CTX_set_verify(ssl_context, SSL_VERIFY_PEER, NULL);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
if (options.dh_params_file_name) {
|
|
493
|
+
/* Set up ephemeral DH parameters. */
|
|
494
|
+
DH *dh_2048 = NULL;
|
|
495
|
+
FILE *paramfile;
|
|
496
|
+
paramfile = fopen(options.dh_params_file_name, "r");
|
|
497
|
+
|
|
498
|
+
if (paramfile) {
|
|
499
|
+
dh_2048 = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
|
|
500
|
+
fclose(paramfile);
|
|
501
|
+
} else {
|
|
502
|
+
free_ssl_context(ssl_context);
|
|
503
|
+
return NULL;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
if (dh_2048 == NULL) {
|
|
507
|
+
free_ssl_context(ssl_context);
|
|
508
|
+
return NULL;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
const long set_tmp_dh = SSL_CTX_set_tmp_dh(ssl_context, dh_2048);
|
|
512
|
+
DH_free(dh_2048);
|
|
513
|
+
|
|
514
|
+
if (set_tmp_dh != 1) {
|
|
515
|
+
free_ssl_context(ssl_context);
|
|
516
|
+
return NULL;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/* OWASP Cipher String 'A+' (https://www.owasp.org/index.php/TLS_Cipher_String_Cheat_Sheet) */
|
|
520
|
+
if (SSL_CTX_set_cipher_list(ssl_context, "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256") != 1) {
|
|
521
|
+
free_ssl_context(ssl_context);
|
|
522
|
+
return NULL;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
if (options.ssl_ciphers) {
|
|
527
|
+
if (SSL_CTX_set_cipher_list(ssl_context, options.ssl_ciphers) != 1) {
|
|
528
|
+
free_ssl_context(ssl_context);
|
|
529
|
+
return NULL;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/* This must be free'd with free_ssl_context, not SSL_CTX_free */
|
|
534
|
+
return ssl_context;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
/* Returns a servername's userdata if any */
|
|
538
|
+
void *us_internal_ssl_socket_context_find_server_name_userdata(struct us_internal_ssl_socket_context_t *context, const char *hostname_pattern) {
|
|
539
|
+
printf("finding %s\n", hostname_pattern);
|
|
540
|
+
|
|
541
|
+
/* We can use sni_find because looking up a "wildcard pattern" will match the exact literal "wildcard pattern" first,
|
|
542
|
+
* before it matches by the very wildcard itself, so it works fine (exact match is the only thing we care for here) */
|
|
543
|
+
SSL_CTX *ssl_context = sni_find(context->sni, hostname_pattern);
|
|
544
|
+
|
|
545
|
+
if (ssl_context) {
|
|
546
|
+
return SSL_CTX_get_ex_data(ssl_context, 0);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
return 0;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/* Returns either nullptr or the previously set user data attached to this SSL's selected SNI context */
|
|
553
|
+
void *us_internal_ssl_socket_get_sni_userdata(struct us_internal_ssl_socket_t *s) {
|
|
554
|
+
return SSL_CTX_get_ex_data(SSL_get_SSL_CTX(s->ssl), 0);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/* Todo: return error on failure? */
|
|
558
|
+
void us_internal_ssl_socket_context_add_server_name(struct us_internal_ssl_socket_context_t *context, const char *hostname_pattern, struct us_socket_context_options_t options, void *user) {
|
|
559
|
+
|
|
560
|
+
/* Try and construct an SSL_CTX from options */
|
|
561
|
+
SSL_CTX *ssl_context = create_ssl_context_from_options(options);
|
|
562
|
+
|
|
563
|
+
/* Attach the user data to this context */
|
|
564
|
+
if (ssl_context) {
|
|
565
|
+
if (1 != SSL_CTX_set_ex_data(ssl_context, 0, user)) {
|
|
566
|
+
printf("CANNOT SET EX DATA!\n");
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/* We do not want to hold any nullptr's in our SNI tree */
|
|
570
|
+
|
|
571
|
+
if (sni_add(context->sni, hostname_pattern, ssl_context)) {
|
|
572
|
+
/* If we already had that name, ignore */
|
|
573
|
+
free_ssl_context(ssl_context);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
void us_internal_ssl_socket_context_on_server_name(struct us_internal_ssl_socket_context_t *context, void (*cb)(struct us_internal_ssl_socket_context_t *, const char *hostname)) {
|
|
579
|
+
context->on_server_name = cb;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
void us_internal_ssl_socket_context_remove_server_name(struct us_internal_ssl_socket_context_t *context, const char *hostname_pattern) {
|
|
583
|
+
|
|
584
|
+
/* The same thing must happen for sni_free, that's why we have a callback */
|
|
585
|
+
SSL_CTX *sni_node_ssl_context = (SSL_CTX *) sni_remove(context->sni, hostname_pattern);
|
|
586
|
+
free_ssl_context(sni_node_ssl_context);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/* Returns NULL or SSL_CTX. May call missing server name callback */
|
|
590
|
+
SSL_CTX *resolve_context(struct us_internal_ssl_socket_context_t *context, const char *hostname) {
|
|
591
|
+
|
|
592
|
+
/* Try once first */
|
|
593
|
+
void *user = sni_find(context->sni, hostname);
|
|
594
|
+
if (!user) {
|
|
595
|
+
/* Emit missing hostname then try again */
|
|
596
|
+
if (!context->on_server_name) {
|
|
597
|
+
/* We have no callback registered, so fail */
|
|
598
|
+
return NULL;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
context->on_server_name(context, hostname);
|
|
602
|
+
|
|
603
|
+
/* Last try */
|
|
604
|
+
user = sni_find(context->sni, hostname);
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
return user;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
// arg is context
|
|
611
|
+
int sni_cb(SSL *ssl, int *al, void *arg) {
|
|
612
|
+
|
|
613
|
+
if (ssl) {
|
|
614
|
+
const char *hostname = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
|
|
615
|
+
if (hostname && hostname[0]) {
|
|
616
|
+
/* Try and resolve (match) required hostname with what we have registered */
|
|
617
|
+
SSL_CTX *resolved_ssl_context = resolve_context((struct us_internal_ssl_socket_context_t *) arg, hostname);
|
|
618
|
+
if (resolved_ssl_context) {
|
|
619
|
+
//printf("Did find matching SNI context for hostname: <%s>!\n", hostname);
|
|
620
|
+
SSL_set_SSL_CTX(ssl, resolved_ssl_context);
|
|
621
|
+
} else {
|
|
622
|
+
/* Call a blocking callback notifying of missing context */
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
return SSL_TLSEXT_ERR_OK;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/* Can we even come here ever? */
|
|
631
|
+
return SSL_TLSEXT_ERR_NOACK;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
struct us_internal_ssl_socket_context_t *us_internal_create_ssl_socket_context(struct us_loop_t *loop, int context_ext_size, struct us_socket_context_options_t options) {
|
|
635
|
+
/* If we haven't initialized the loop data yet, do so .
|
|
636
|
+
* This is needed because loop data holds shared OpenSSL data and
|
|
637
|
+
* the function is also responsible for initializing OpenSSL */
|
|
638
|
+
us_internal_init_loop_ssl_data(loop);
|
|
639
|
+
|
|
640
|
+
/* First of all we try and create the SSL context from options */
|
|
641
|
+
SSL_CTX *ssl_context = create_ssl_context_from_options(options);
|
|
642
|
+
if (!ssl_context) {
|
|
643
|
+
/* We simply fail early if we cannot even create the OpenSSL context */
|
|
644
|
+
return NULL;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/* Otherwise ee continue by creating a non-SSL context, but with larger ext to hold our SSL stuff */
|
|
648
|
+
struct us_internal_ssl_socket_context_t *context = (struct us_internal_ssl_socket_context_t *) us_create_socket_context(0, loop, sizeof(struct us_internal_ssl_socket_context_t) + context_ext_size, options);
|
|
649
|
+
|
|
650
|
+
/* I guess this is the only optional callback */
|
|
651
|
+
context->on_server_name = NULL;
|
|
652
|
+
|
|
653
|
+
/* Then we extend its SSL parts */
|
|
654
|
+
context->ssl_context = ssl_context;//create_ssl_context_from_options(options);
|
|
655
|
+
context->is_parent = 1;
|
|
656
|
+
|
|
657
|
+
/* We, as parent context, may ignore data */
|
|
658
|
+
context->sc.is_low_prio = (int (*)(struct us_socket_t *)) ssl_is_low_prio;
|
|
659
|
+
|
|
660
|
+
/* Parent contexts may use SNI */
|
|
661
|
+
SSL_CTX_set_tlsext_servername_callback(context->ssl_context, sni_cb);
|
|
662
|
+
SSL_CTX_set_tlsext_servername_arg(context->ssl_context, context);
|
|
663
|
+
|
|
664
|
+
/* Also create the SNI tree */
|
|
665
|
+
context->sni = sni_new();
|
|
666
|
+
|
|
667
|
+
return context;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
/* Our destructor for hostnames, used below */
|
|
671
|
+
void sni_hostname_destructor(void *user) {
|
|
672
|
+
/* Some nodes hold null, so this one must ignore this case */
|
|
673
|
+
free_ssl_context((SSL_CTX *) user);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
void us_internal_ssl_socket_context_free(struct us_internal_ssl_socket_context_t *context) {
|
|
677
|
+
/* If we are parent then we need to free our OpenSSL context */
|
|
678
|
+
if (context->is_parent) {
|
|
679
|
+
free_ssl_context(context->ssl_context);
|
|
680
|
+
|
|
681
|
+
/* Here we need to register a temporary callback for all still-existing hostnames
|
|
682
|
+
* and their contexts. Only parents have an SNI tree */
|
|
683
|
+
sni_free(context->sni, sni_hostname_destructor);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
us_socket_context_free(0, &context->sc);
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
struct us_listen_socket_t *us_internal_ssl_socket_context_listen(struct us_internal_ssl_socket_context_t *context, const char *host, int port, int options, int socket_ext_size) {
|
|
690
|
+
return us_socket_context_listen(0, &context->sc, host, port, options, sizeof(struct us_internal_ssl_socket_t) - sizeof(struct us_socket_t) + socket_ext_size);
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
struct us_listen_socket_t *us_internal_ssl_socket_context_listen_unix(struct us_internal_ssl_socket_context_t *context, const char *path, int options, int socket_ext_size) {
|
|
694
|
+
return us_socket_context_listen_unix(0, &context->sc, path, options, sizeof(struct us_internal_ssl_socket_t) - sizeof(struct us_socket_t) + socket_ext_size);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
struct us_internal_ssl_socket_t *us_internal_ssl_adopt_accepted_socket(struct us_internal_ssl_socket_context_t *context, LIBUS_SOCKET_DESCRIPTOR accepted_fd,
|
|
698
|
+
unsigned int socket_ext_size, char *addr_ip, int addr_ip_length) {
|
|
699
|
+
return (struct us_internal_ssl_socket_t *) us_adopt_accepted_socket(0, &context->sc, accepted_fd, sizeof(struct us_internal_ssl_socket_t) - sizeof(struct us_socket_t) + socket_ext_size, addr_ip, addr_ip_length);
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
struct us_internal_ssl_socket_t *us_internal_ssl_socket_context_connect(struct us_internal_ssl_socket_context_t *context, const char *host, int port, const char *source_host, int options, int socket_ext_size) {
|
|
703
|
+
return (struct us_internal_ssl_socket_t *) us_socket_context_connect(0, &context->sc, host, port, source_host, options, sizeof(struct us_internal_ssl_socket_t) - sizeof(struct us_socket_t) + socket_ext_size);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
struct us_internal_ssl_socket_t *us_internal_ssl_socket_context_connect_unix(struct us_internal_ssl_socket_context_t *context, const char *server_path, int options, int socket_ext_size) {
|
|
707
|
+
return (struct us_internal_ssl_socket_t *) us_socket_context_connect_unix(0, &context->sc, server_path, options, sizeof(struct us_internal_ssl_socket_t) - sizeof(struct us_socket_t) + socket_ext_size);
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
void us_internal_ssl_socket_context_on_open(struct us_internal_ssl_socket_context_t *context, struct us_internal_ssl_socket_t *(*on_open)(struct us_internal_ssl_socket_t *s, int is_client, char *ip, int ip_length)) {
|
|
711
|
+
us_socket_context_on_open(0, &context->sc, (struct us_socket_t *(*)(struct us_socket_t *, int, char *, int)) ssl_on_open);
|
|
712
|
+
context->on_open = on_open;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
void us_internal_ssl_socket_context_on_close(struct us_internal_ssl_socket_context_t *context, struct us_internal_ssl_socket_t *(*on_close)(struct us_internal_ssl_socket_t *s, int code, void *reason)) {
|
|
716
|
+
us_socket_context_on_close(0, (struct us_socket_context_t *) context, (struct us_socket_t *(*)(struct us_socket_t *, int, void *)) ssl_on_close);
|
|
717
|
+
context->on_close = on_close;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
void us_internal_ssl_socket_context_on_data(struct us_internal_ssl_socket_context_t *context, struct us_internal_ssl_socket_t *(*on_data)(struct us_internal_ssl_socket_t *s, char *data, int length)) {
|
|
721
|
+
us_socket_context_on_data(0, (struct us_socket_context_t *) context, (struct us_socket_t *(*)(struct us_socket_t *, char *, int)) ssl_on_data);
|
|
722
|
+
context->on_data = on_data;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
void us_internal_ssl_socket_context_on_writable(struct us_internal_ssl_socket_context_t *context, struct us_internal_ssl_socket_t *(*on_writable)(struct us_internal_ssl_socket_t *s)) {
|
|
726
|
+
us_socket_context_on_writable(0, (struct us_socket_context_t *) context, (struct us_socket_t *(*)(struct us_socket_t *)) ssl_on_writable);
|
|
727
|
+
context->on_writable = on_writable;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
void us_internal_ssl_socket_context_on_timeout(struct us_internal_ssl_socket_context_t *context, struct us_internal_ssl_socket_t *(*on_timeout)(struct us_internal_ssl_socket_t *s)) {
|
|
731
|
+
us_socket_context_on_timeout(0, (struct us_socket_context_t *) context, (struct us_socket_t *(*)(struct us_socket_t *)) on_timeout);
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
void us_internal_ssl_socket_context_on_long_timeout(struct us_internal_ssl_socket_context_t *context, struct us_internal_ssl_socket_t *(*on_long_timeout)(struct us_internal_ssl_socket_t *s)) {
|
|
735
|
+
us_socket_context_on_long_timeout(0, (struct us_socket_context_t *) context, (struct us_socket_t *(*)(struct us_socket_t *)) on_long_timeout);
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
/* We do not really listen to passed FIN-handler, we entirely override it with our handler since SSL doesn't really have support for half-closed sockets */
|
|
739
|
+
void us_internal_ssl_socket_context_on_end(struct us_internal_ssl_socket_context_t *context, struct us_internal_ssl_socket_t *(*on_end)(struct us_internal_ssl_socket_t *)) {
|
|
740
|
+
us_socket_context_on_end(0, (struct us_socket_context_t *) context, (struct us_socket_t *(*)(struct us_socket_t *)) ssl_on_end);
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
void us_internal_ssl_socket_context_on_connect_error(struct us_internal_ssl_socket_context_t *context, struct us_internal_ssl_socket_t *(*on_connect_error)(struct us_internal_ssl_socket_t *, int code)) {
|
|
744
|
+
us_socket_context_on_connect_error(0, (struct us_socket_context_t *) context, (struct us_socket_t *(*)(struct us_socket_t *, int)) on_connect_error);
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
void *us_internal_ssl_socket_context_ext(struct us_internal_ssl_socket_context_t *context) {
|
|
748
|
+
return context + 1;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
/* Per socket functions */
|
|
752
|
+
void *us_internal_ssl_socket_get_native_handle(struct us_internal_ssl_socket_t *s) {
|
|
753
|
+
return s->ssl;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
int us_internal_ssl_socket_write(struct us_internal_ssl_socket_t *s, const char *data, int length, int msg_more) {
|
|
757
|
+
if (us_socket_is_closed(0, &s->s) || us_internal_ssl_socket_is_shut_down(s)) {
|
|
758
|
+
return 0;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
struct us_internal_ssl_socket_context_t *context = (struct us_internal_ssl_socket_context_t *) us_socket_context(0, &s->s);
|
|
762
|
+
|
|
763
|
+
struct us_loop_t *loop = us_socket_context_loop(0, &context->sc);
|
|
764
|
+
struct loop_ssl_data *loop_ssl_data = (struct loop_ssl_data *) loop->data.ssl_data;
|
|
765
|
+
|
|
766
|
+
// it makes literally no sense to touch this here! it should start at 0 and ONLY be set and reset by the on_data function!
|
|
767
|
+
// the way is is now, triggering a write from a read will essentially delete all input data!
|
|
768
|
+
// what we need to do is to check if this ever is non-zero and print a warning
|
|
769
|
+
|
|
770
|
+
|
|
771
|
+
|
|
772
|
+
loop_ssl_data->ssl_read_input_length = 0;
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
loop_ssl_data->ssl_socket = &s->s;
|
|
776
|
+
loop_ssl_data->msg_more = msg_more;
|
|
777
|
+
loop_ssl_data->last_write_was_msg_more = 0;
|
|
778
|
+
//printf("Calling SSL_write\n");
|
|
779
|
+
int written = SSL_write(s->ssl, data, length);
|
|
780
|
+
//printf("Returning from SSL_write\n");
|
|
781
|
+
loop_ssl_data->msg_more = 0;
|
|
782
|
+
|
|
783
|
+
if (loop_ssl_data->last_write_was_msg_more && !msg_more) {
|
|
784
|
+
us_socket_flush(0, &s->s);
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
if (written > 0) {
|
|
788
|
+
return written;
|
|
789
|
+
} else {
|
|
790
|
+
int err = SSL_get_error(s->ssl, written);
|
|
791
|
+
if (err == SSL_ERROR_WANT_READ) {
|
|
792
|
+
// here we need to trigger writable event next ssl_read!
|
|
793
|
+
s->ssl_write_wants_read = 1;
|
|
794
|
+
} else if (err == SSL_ERROR_SSL || err == SSL_ERROR_SYSCALL) {
|
|
795
|
+
// these two errors may add to the error queue, which is per thread and must be cleared
|
|
796
|
+
ERR_clear_error();
|
|
797
|
+
|
|
798
|
+
// all errors here except for want write are critical and should not happen
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
return 0;
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
void *us_internal_ssl_socket_ext(struct us_internal_ssl_socket_t *s) {
|
|
806
|
+
return s + 1;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
int us_internal_ssl_socket_is_shut_down(struct us_internal_ssl_socket_t *s) {
|
|
810
|
+
return us_socket_is_shut_down(0, &s->s) || SSL_get_shutdown(s->ssl) & SSL_SENT_SHUTDOWN;
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
void us_internal_ssl_socket_shutdown(struct us_internal_ssl_socket_t *s) {
|
|
814
|
+
if (!us_socket_is_closed(0, &s->s) && !us_internal_ssl_socket_is_shut_down(s)) {
|
|
815
|
+
struct us_internal_ssl_socket_context_t *context = (struct us_internal_ssl_socket_context_t *) us_socket_context(0, &s->s);
|
|
816
|
+
struct us_loop_t *loop = us_socket_context_loop(0, &context->sc);
|
|
817
|
+
struct loop_ssl_data *loop_ssl_data = (struct loop_ssl_data *) loop->data.ssl_data;
|
|
818
|
+
|
|
819
|
+
// also makes no sense to touch this here!
|
|
820
|
+
// however the idea is that if THIS socket is not the same as ssl_socket then this data is not for me
|
|
821
|
+
// but this is not correct as it is currently anyways, any data available should be properly reset
|
|
822
|
+
loop_ssl_data->ssl_read_input_length = 0;
|
|
823
|
+
|
|
824
|
+
|
|
825
|
+
// essentially we need two of these: one for CURRENT CALL and one for CURRENT SOCKET WITH DATA
|
|
826
|
+
// if those match in the BIO function then you may read, if not then you may not read
|
|
827
|
+
// we need ssl_read_socket to be set in on_data and checked in the BIO
|
|
828
|
+
loop_ssl_data->ssl_socket = &s->s;
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
loop_ssl_data->msg_more = 0;
|
|
832
|
+
|
|
833
|
+
// sets SSL_SENT_SHUTDOWN no matter what (not actually true if error!)
|
|
834
|
+
int ret = SSL_shutdown(s->ssl);
|
|
835
|
+
if (ret == 0) {
|
|
836
|
+
ret = SSL_shutdown(s->ssl);
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
if (ret < 0) {
|
|
840
|
+
|
|
841
|
+
int err = SSL_get_error(s->ssl, ret);
|
|
842
|
+
if (err == SSL_ERROR_SSL || err == SSL_ERROR_SYSCALL) {
|
|
843
|
+
// clear
|
|
844
|
+
ERR_clear_error();
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
// we get here if we are shutting down while still in init
|
|
848
|
+
us_socket_shutdown(0, &s->s);
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
struct us_internal_ssl_socket_t *us_internal_ssl_socket_context_adopt_socket(struct us_internal_ssl_socket_context_t *context, struct us_internal_ssl_socket_t *s, int ext_size) {
|
|
854
|
+
// todo: this is completely untested
|
|
855
|
+
return (struct us_internal_ssl_socket_t *) us_socket_context_adopt_socket(0, &context->sc, &s->s, sizeof(struct us_internal_ssl_socket_t) - sizeof(struct us_socket_t) + ext_size);
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
#endif
|