Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(216)

Side by Side Diff: runtime/bin/tls_socket.cc

Issue 10704159: Start adding TLS (SSL) sockets to dart:io. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add proper event handling during handshake phase of connection. Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698