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

Side by Side Diff: chrome/browser/sync/notifier/communicator/ssl_socket_adapter.cc

Issue 270074: Add SSL wrapper for linux and mac (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 1 month 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
Property Changes:
Added: svn:executable
+ *
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/sync/notifier/communicator/ssl_socket_adapter.h"
6
7 #include "base/compiler_specific.h"
8 #include "chrome/browser/net/url_request_context_getter.h"
9 #include "chrome/browser/profile.h"
10 #include "net/base/ssl_config_service.h"
11 #include "net/socket/client_socket_factory.h"
12 #include "net/url_request/url_request_context.h"
13
14 namespace notifier {
15
16 namespace {
17
18 // Convert values from <errno.h> to values from "net/base/net_errors.h"
19 int MapPosixError(int err) {
20 // There are numerous posix error codes, but these are the ones we thus far
21 // find interesting.
22 switch (err) {
23 case EAGAIN:
24 #if EWOULDBLOCK != EAGAIN
25 case EWOULDBLOCK:
26 #endif
27 return net::ERR_IO_PENDING;
28 case ENETDOWN:
29 return net::ERR_INTERNET_DISCONNECTED;
30 case ETIMEDOUT:
31 return net::ERR_TIMED_OUT;
32 case ECONNRESET:
33 case ENETRESET: // Related to keep-alive
34 return net::ERR_CONNECTION_RESET;
35 case ECONNABORTED:
36 return net::ERR_CONNECTION_ABORTED;
37 case ECONNREFUSED:
38 return net::ERR_CONNECTION_REFUSED;
39 case EHOSTUNREACH:
40 case ENETUNREACH:
41 return net::ERR_ADDRESS_UNREACHABLE;
42 case EADDRNOTAVAIL:
43 return net::ERR_ADDRESS_INVALID;
44 case 0:
45 return net::OK;
46 default:
47 LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED";
48 return net::ERR_FAILED;
49 }
50 }
51
52 }
53
54 SSLSocketAdapter* SSLSocketAdapter::Create(AsyncSocket* socket) {
55 return new SSLSocketAdapter(socket);
56 }
57
58 SSLSocketAdapter::SSLSocketAdapter(AsyncSocket* socket)
59 : AsyncSocketAdapter(socket),
60 ignore_bad_cert_(false),
61 ALLOW_THIS_IN_INITIALIZER_LIST(
62 connected_callback_(this, &SSLSocketAdapter::OnConnected)),
63 ALLOW_THIS_IN_INITIALIZER_LIST(
64 io_callback_(this, &SSLSocketAdapter::OnIO)),
65 ssl_connected_(false),
66 state_(STATE_NONE) {
67 socket_.reset(new TransportSocket(socket, this));
68 }
69
70 int SSLSocketAdapter::StartSSL(const char* hostname, bool restartable) {
71 DCHECK(!restartable);
72
73 // SSLConfigService is not thread-safe, and the default values for SSLConfig
74 // are correct for us, so we don't use the config service to initialize this
75 // object.
76 net::SSLConfig ssl_config;
77 socket_->set_addr(talk_base::SocketAddress(hostname));
78 ssl_socket_.reset(
79 net::ClientSocketFactory::GetDefaultFactory()->CreateSSLClientSocket(
80 socket_.release(), hostname, ssl_config));
81
82 int result = ssl_socket_->Connect(&connected_callback_);
83
84 if (result == net::ERR_IO_PENDING || result == net::OK) {
85 return 0;
86 } else {
87 return result;
88 }
89 }
90
91 int SSLSocketAdapter::Send(const void* buf, size_t len) {
92 if (!ssl_connected_) {
93 return AsyncSocketAdapter::Send(buf, len);
94 }
95
96 switch (state_) {
97 case STATE_NONE: {
98 transport_buf_ = new net::IOBuffer(len);
99 memcpy(transport_buf_->data(), buf, len);
100
101 int result = ssl_socket_->Write(transport_buf_, len, &io_callback_);
102 if (result == net::ERR_IO_PENDING) {
103 state_ = STATE_WRITE;
104 SetError(EWOULDBLOCK);
105 } else {
106 transport_buf_ = NULL;
107 }
108 return result;
109 }
110 case STATE_WRITE_COMPLETE:
111 transport_buf_ = NULL;
112 state_ = STATE_NONE;
113 return data_transferred_;
114
115 case STATE_READ:
116 case STATE_READ_COMPLETE:
117 case STATE_WRITE:
118 SetError(EWOULDBLOCK);
119 return -1;
120
121 default:
122 NOTREACHED();
123 break;
124 }
125 return -1;
126 }
127
128 int SSLSocketAdapter::Recv(void* buf, size_t len) {
129 if (!ssl_connected_) {
130 return AsyncSocketAdapter::Recv(buf, len);
131 }
132
133 switch (state_) {
134 case STATE_NONE: {
135 transport_buf_ = new net::IOBuffer(len);
136 int result = ssl_socket_->Read(transport_buf_, len, &io_callback_);
137 if (result >= 0) {
138 memcpy(buf, transport_buf_->data(), len);
139 }
140
141 if (result == net::ERR_IO_PENDING) {
142 state_ = STATE_READ;
143 SetError(EWOULDBLOCK);
144 } else {
145 transport_buf_ = NULL;
146 }
147 return result;
148 }
149 case STATE_READ_COMPLETE:
150 memcpy(buf, transport_buf_->data(), len);
151 transport_buf_ = NULL;
152 state_ = STATE_NONE;
153 return data_transferred_;
154
155 case STATE_READ:
156 case STATE_WRITE:
157 case STATE_WRITE_COMPLETE:
158 SetError(EWOULDBLOCK);
159 return -1;
160
161 default:
162 NOTREACHED();
163 break;
164 }
165 return -1;
166 }
167
168 void SSLSocketAdapter::OnConnected(int result) {
169 if (result == net::OK) {
170 ssl_connected_ = true;
171 OnConnectEvent(this);
172 }
173 }
174
175 void SSLSocketAdapter::OnIO(int result) {
176 switch (state_) {
177 case STATE_READ:
178 state_ = STATE_READ_COMPLETE;
179 data_transferred_ = result;
180 break;
181 case STATE_WRITE:
182 state_ = STATE_WRITE_COMPLETE;
183 data_transferred_ = result;
184 break;
185 case STATE_NONE:
186 case STATE_READ_COMPLETE:
187 case STATE_WRITE_COMPLETE:
188 default:
189 NOTREACHED();
190 break;
191 }
192 }
193
194 TransportSocket::TransportSocket(talk_base::AsyncSocket* socket,
195 SSLSocketAdapter *ssl_adapter)
196 : connect_callback_(NULL),
197 read_callback_(NULL),
198 write_callback_(NULL),
199 read_buffer_len_(0),
200 write_buffer_len_(0),
201 socket_(socket),
202 ssl_adapter_(ssl_adapter) {
203 socket_->SignalConnectEvent.connect(this, &TransportSocket::OnConnectEvent);
204 socket_->SignalReadEvent.connect(this, &TransportSocket::OnReadEvent);
205 socket_->SignalWriteEvent.connect(this, &TransportSocket::OnWriteEvent);
206 socket_->SignalCloseEvent.connect(this, &TransportSocket::OnCloseEvent);
207 }
208
209 int TransportSocket::Connect(net::CompletionCallback* callback) {
210 connect_callback_ = callback;
211 return socket_->Connect(addr_);
212 }
213
214 void TransportSocket::Disconnect() {
215 socket_->Close();
216 }
217
218 bool TransportSocket::IsConnected() const {
219 return (socket_->GetState() == talk_base::Socket::CS_CONNECTED);
220 }
221
222 bool TransportSocket::IsConnectedAndIdle() const {
223 // Not implemented.
224 NOTREACHED();
225 return false;
226 }
227
228 #if defined(OS_LINUX) || defined(OS_MACOSX)
229 int TransportSocket::GetPeerName(struct sockaddr *name, socklen_t *namelen) {
230 talk_base::SocketAddress address = socket_->GetRemoteAddress();
231 address.ToSockAddr(reinterpret_cast<sockaddr_in *>(name));
232 return 0;
233 }
234 #endif
235
236 int TransportSocket::Read(net::IOBuffer* buf, int buf_len,
237 net::CompletionCallback* callback) {
238 DCHECK(buf);
239 DCHECK(!read_callback_);
240 DCHECK(!read_buffer_.get());
241 int result = socket_->Recv(buf->data(), buf_len);
242 if (result < 0) {
243 result = MapPosixError(socket_->GetError());
244 if (result == net::ERR_IO_PENDING) {
245 read_callback_ = callback;
246 read_buffer_ = buf;
247 read_buffer_len_ = buf_len;
248 }
249 }
250 return result;
251 }
252
253 int TransportSocket::Write(net::IOBuffer* buf, int buf_len,
254 net::CompletionCallback* callback) {
255 DCHECK(buf);
256 DCHECK(!write_callback_);
257 DCHECK(!write_buffer_.get());
258 int result = socket_->Send(buf->data(), buf_len);
259 if (result < 0) {
260 result = MapPosixError(socket_->GetError());
261 if (result == net::ERR_IO_PENDING) {
262 write_callback_ = callback;
263 write_buffer_ = buf;
264 write_buffer_len_ = buf_len;
265 }
266 }
267 return result;
268 }
269
270 bool TransportSocket::SetReceiveBufferSize(int32 size) {
271 // Not implemented.
272 return false;
273 }
274
275 bool TransportSocket::SetSendBufferSize(int32 size) {
276 // Not implemented.
277 return false;
278 }
279
280 void TransportSocket::OnConnectEvent(talk_base::AsyncSocket * socket) {
281 if (connect_callback_) {
282 net::CompletionCallback *callback = connect_callback_;
283 connect_callback_ = NULL;
284 callback->RunWithParams(Tuple1<int>(MapPosixError(socket_->GetError())));
285 } else {
286 ssl_adapter_->OnConnectEvent(socket);
287 }
288 }
289
290 void TransportSocket::OnReadEvent(talk_base::AsyncSocket* socket) {
291 if (read_callback_) {
292 DCHECK(read_buffer_.get());
293 net::CompletionCallback* callback = read_callback_;
294 scoped_refptr<net::IOBuffer> buffer = read_buffer_;
295 int buffer_len = read_buffer_len_;
296
297 read_callback_ = NULL;
298 read_buffer_ = NULL;
299 read_buffer_len_ = 0;
300
301 int result = socket_->Recv(buffer->data(), buffer_len);
302 if (result < 0) {
303 result = MapPosixError(socket_->GetError());
304 if (result == net::ERR_IO_PENDING) {
305 read_callback_ = callback;
306 read_buffer_ = buffer;
307 read_buffer_len_ = buffer_len;
308 return;
309 }
310 }
311 callback->RunWithParams(Tuple1<int>(result));
312 } else {
313 ssl_adapter_->OnReadEvent(socket);
314 }
315 }
316
317 void TransportSocket::OnWriteEvent(talk_base::AsyncSocket* socket) {
318 if (write_callback_) {
319 DCHECK(write_buffer_.get());
320 net::CompletionCallback* callback = write_callback_;
321 scoped_refptr<net::IOBuffer> buffer = write_buffer_;
322 int buffer_len = write_buffer_len_;
323
324 write_callback_ = NULL;
325 write_buffer_ = NULL;
326 write_buffer_len_ = 0;
327
328 int result = socket_->Send(buffer->data(), buffer_len);
329 if (result < 0) {
330 result = MapPosixError(socket_->GetError());
331 if (result == net::ERR_IO_PENDING) {
332 write_callback_ = callback;
333 write_buffer_ = buffer;
334 write_buffer_len_ = buffer_len;
335 return;
336 }
337 }
338 callback->RunWithParams(Tuple1<int>(result));
339 } else {
340 ssl_adapter_->OnWriteEvent(socket);
341 }
342 }
343
344 void TransportSocket::OnCloseEvent(talk_base::AsyncSocket* socket, int err) {
345 ssl_adapter_->OnCloseEvent(socket, err);
346 }
347
348 } // namespace notifier
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698