| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 #include "bin/tls_socket.h" |
| 6 |
| 7 #include "bin/builtin.h" |
| 8 #include "bin/dartutils.h" |
| 9 #include "bin/thread.h" |
| 10 #include "bin/utils.h" |
| 11 |
| 12 #include "include/dart_api.h" |
| 13 |
| 14 bool TlsFilter::library_initialized_ = false; |
| 15 const char* TlsFilter::bufferNames[kNumBuffers] = { "readPlaintext", |
| 16 "writePlaintext", |
| 17 "readEncrypted", |
| 18 "writeEncrypted" }; |
| 19 |
| 20 /* |
| 21 * The control flow and buffering here are complex. From the outside sources, |
| 22 * here are the incoming signals and outgoing signals: |
| 23 * From the Socket, onData callback when there is data. |
| 24 * available() says how much is available |
| 25 * readList() is safe, non-blocking, and returns amount read. |
| 26 * To the Socket, onWrite when a previously blocked socket becomes available. |
| 27 * writeList() is always safe, and returns amount written. |
| 28 * |
| 29 * To the user, we should provide the same interface: onData and onWrite. |
| 30 * We can have data pushed to us by writeList(). |
| 31 * |
| 32 * The intermediate stages should always be pushed as far as possible - |
| 33 * all reads and writes should be performed until empty buffers happen or |
| 34 * output buffers are full. Then we can rely on onData from the Socket or |
| 35 * writeList from the user to fill empty buffers. |
| 36 * If the buffers are full, we need to make sure that an onData is scheduled |
| 37 * for the user, or an onWrite from the socket, comes to tell us that |
| 38 * we can proceed. |
| 39 * |
| 40 * Because of handshakes, the write pipeline can be blocked on the read |
| 41 * pipeline, or vice versa, but always some anticipated event will |
| 42 * unblock something. So when the read pipeline is processed, we should try |
| 43 * and advance the write pipeline if it is blocked, and vice versa, but |
| 44 * not try to move the other pipeline unless it was blocked in the OpenSSL |
| 45 * filter. |
| 46 */ |
| 47 |
| 48 void FUNCTION_NAME(TlsSocket_Init)(Dart_NativeArguments args) { |
| 49 Dart_EnterScope(); |
| 50 TlsFilter* local_data = new TlsFilter; |
| 51 Dart_Handle dart_this = HandleError(Dart_GetNativeArgument(args, 0)); |
| 52 local_data->Init(dart_this); |
| 53 |
| 54 Dart_SetReturnValue(args, Dart_Null()); |
| 55 Dart_ExitScope(); |
| 56 } |
| 57 |
| 58 void FUNCTION_NAME(TlsSocket_Connect)(Dart_NativeArguments args) { |
| 59 Dart_EnterScope(); |
| 60 TlsFilter* local_data; |
| 61 |
| 62 Dart_Handle dart_this = HandleError(Dart_GetNativeArgument(args, 0)); |
| 63 ASSERT(Dart_IsInstance(dart_this)); |
| 64 int count; |
| 65 HandleError(Dart_GetNativeInstanceFieldCount(dart_this, &count)); |
| 66 ASSERT(count == 1); |
| 67 HandleError(Dart_GetNativeInstanceField(dart_this, 0, |
| 68 reinterpret_cast<intptr_t*>(&local_data))); |
| 69 |
| 70 local_data->Connect(); |
| 71 Dart_SetReturnValue(args, Dart_Null()); |
| 72 Dart_ExitScope(); |
| 73 } |
| 74 |
| 75 void FUNCTION_NAME(TlsSocket_Destroy)(Dart_NativeArguments args) { |
| 76 Dart_EnterScope(); |
| 77 TlsFilter* local_data; |
| 78 |
| 79 Dart_Handle dart_this = HandleError(Dart_GetNativeArgument(args, 0)); |
| 80 ASSERT(Dart_IsInstance(dart_this)); |
| 81 int count; |
| 82 HandleError(Dart_GetNativeInstanceFieldCount(dart_this, &count)); |
| 83 ASSERT(count == 1); |
| 84 HandleError(Dart_GetNativeInstanceField(dart_this, 0, |
| 85 reinterpret_cast<intptr_t*>(&local_data))); |
| 86 |
| 87 local_data->Destroy(); |
| 88 Dart_SetReturnValue(args, Dart_Null()); |
| 89 Dart_ExitScope(); |
| 90 } |
| 91 |
| 92 void FUNCTION_NAME(TlsSocket_RegisterHandshakeCallbacks)( |
| 93 Dart_NativeArguments args) { |
| 94 Dart_EnterScope(); |
| 95 TlsFilter* local_data; |
| 96 |
| 97 Dart_Handle dart_this = HandleError(Dart_GetNativeArgument(args, 0)); |
| 98 Dart_Handle handshake_start = HandleError(Dart_GetNativeArgument(args, 1)); |
| 99 Dart_Handle handshake_finish = HandleError(Dart_GetNativeArgument(args, 2)); |
| 100 if (!Dart_IsInstance(dart_this) || |
| 101 !Dart_IsClosure(handshake_start) || |
| 102 !Dart_IsClosure(handshake_finish)) { |
| 103 Dart_ThrowException(DartUtils::NewDartIllegalArgumentError( |
| 104 "Illegal argument to RegisterHandshakeCallbacks")); |
| 105 } |
| 106 HandleError(Dart_GetNativeInstanceField(dart_this, 0, |
| 107 reinterpret_cast<intptr_t*>(&local_data))); |
| 108 |
| 109 local_data->RegisterHandshakeCallbacks(handshake_start, handshake_finish); |
| 110 Dart_SetReturnValue(args, Dart_Null()); |
| 111 Dart_ExitScope(); |
| 112 } |
| 113 |
| 114 void FUNCTION_NAME(TlsSocket_ProcessBuffer)(Dart_NativeArguments args) { |
| 115 Dart_EnterScope(); |
| 116 TlsFilter* local_data; |
| 117 |
| 118 Dart_Handle dart_this = HandleError(Dart_GetNativeArgument(args, 0)); |
| 119 ASSERT(Dart_IsInstance(dart_this)); |
| 120 HandleError(Dart_GetNativeInstanceField(dart_this, 0, |
| 121 reinterpret_cast<intptr_t*>(&local_data))); |
| 122 Dart_Handle buffer_id_object = HandleError(Dart_GetNativeArgument(args, 1)); |
| 123 int64_t buffer_id = DartUtils::GetIntegerValue(buffer_id_object); |
| 124 if (buffer_id < 0 || buffer_id >= TlsFilter::kNumBuffers) { |
| 125 Dart_ThrowException(DartUtils::NewDartIllegalArgumentError( |
| 126 "Illegal argument to ProcessBuffer")); |
| 127 } |
| 128 |
| 129 intptr_t bytes_read = local_data->ProcessBuffer(static_cast<int>(buffer_id)); |
| 130 Dart_SetReturnValue(args, Dart_NewInteger(bytes_read)); |
| 131 Dart_ExitScope(); |
| 132 } |
| 133 |
| 134 void TlsFilter::Init(Dart_Handle dart_this) { |
| 135 printf("Entering Init\n"); |
| 136 ASSERT(Dart_IsInstance(dart_this)); |
| 137 peer_ = HandleError(Dart_NewPersistentHandle(dart_this)); |
| 138 int count; |
| 139 HandleError(Dart_GetNativeInstanceFieldCount(dart_this, &count)); |
| 140 ASSERT(count == 1); |
| 141 HandleError(Dart_SetNativeInstanceField(dart_this, 0, |
| 142 reinterpret_cast<intptr_t>(this))); |
| 143 stringStart = HandleError( |
| 144 Dart_NewPersistentHandle(Dart_NewString("start"))); |
| 145 stringLength = HandleError( |
| 146 Dart_NewPersistentHandle(Dart_NewString("length"))); |
| 147 |
| 148 InitializeBuffers(); |
| 149 InitializePlatformData(); |
| 150 printf("Exiting Init\n"); |
| 151 } |
| 152 |
| 153 void TlsFilter::InitializeBuffers() { |
| 154 // Create TlsFilter buffers as ExternalUint8Array objects. |
| 155 Dart_Handle dart_buffers_object = HandleError( |
| 156 Dart_GetField(peer_, Dart_NewString("buffers"))); |
| 157 Dart_Handle dart_buffer_object = HandleError( |
| 158 Dart_ListGetAt(dart_buffers_object, kReadPlaintext)); |
| 159 Dart_Handle tlsExternalBuffer_class = HandleError( |
| 160 Dart_InstanceGetClass(dart_buffer_object)); |
| 161 Dart_Handle dart_buffer_size = HandleError( |
| 162 Dart_GetField(tlsExternalBuffer_class, Dart_NewString("kSize"))); |
| 163 buffer_size = DartUtils::GetIntegerValue(dart_buffer_size); |
| 164 if (buffer_size <= 0 || buffer_size > 1024 * 1024) { |
| 165 Dart_ThrowException( |
| 166 Dart_NewString("Invalid buffer size in _TlsExternalBuffer")); |
| 167 } |
| 168 |
| 169 for (int i = 0; i < kNumBuffers; ++i) { |
| 170 dart_buffer_objects[i] = HandleError( |
| 171 Dart_NewPersistentHandle(Dart_ListGetAt(dart_buffers_object, i))); |
| 172 buffers[i] = new uint8_t[buffer_size]; |
| 173 Dart_Handle data = HandleError( |
| 174 Dart_NewExternalByteArray(buffers[i], |
| 175 buffer_size, NULL, NULL)); |
| 176 HandleError( |
| 177 Dart_SetField(dart_buffer_objects[i], Dart_NewString("data"), data)); |
| 178 } |
| 179 } |
| 180 |
| 181 void TlsFilter::RegisterHandshakeCallbacks(Dart_Handle start, |
| 182 Dart_Handle finish) { |
| 183 handshake_start = HandleError(Dart_NewPersistentHandle(start)); |
| 184 handshake_finish = HandleError(Dart_NewPersistentHandle(finish)); |
| 185 } |
| OLD | NEW |