OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/curvecp/client_packetizer.h" | 5 #include "net/curvecp/client_packetizer.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "net/base/io_buffer.h" | 8 #include "net/base/io_buffer.h" |
9 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" |
10 #include "net/base/sys_addrinfo.h" | 10 #include "net/base/sys_addrinfo.h" |
(...skipping 15 matching lines...) Expand all Loading... |
26 }; | 26 }; |
27 | 27 |
28 } // namespace | 28 } // namespace |
29 | 29 |
30 namespace net { | 30 namespace net { |
31 | 31 |
32 ClientPacketizer::ClientPacketizer() | 32 ClientPacketizer::ClientPacketizer() |
33 : Packetizer(), | 33 : Packetizer(), |
34 next_state_(NONE), | 34 next_state_(NONE), |
35 listener_(NULL), | 35 listener_(NULL), |
36 old_user_callback_(NULL), | |
37 current_address_(NULL), | 36 current_address_(NULL), |
38 hello_attempts_(0), | 37 hello_attempts_(0), |
39 initiate_sent_(false), | 38 initiate_sent_(false), |
40 ALLOW_THIS_IN_INITIALIZER_LIST( | 39 ALLOW_THIS_IN_INITIALIZER_LIST( |
41 io_callback_(this, &ClientPacketizer::OnIOComplete)), | 40 io_callback_(base::Bind(&ClientPacketizer::OnIOComplete, |
| 41 base::Unretained(this)))), |
42 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { | 42 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
43 // TODO(mbelshe): Initialize our keys and such properly. | 43 // TODO(mbelshe): Initialize our keys and such properly. |
44 // for now we use random values to keep them unique. | 44 // for now we use random values to keep them unique. |
45 for (int i = 0; i < 32; ++i) | 45 for (int i = 0; i < 32; ++i) |
46 shortterm_public_key_[i] = rand() % 26 + 'a'; | 46 shortterm_public_key_[i] = rand() % 26 + 'a'; |
47 } | 47 } |
48 | 48 |
49 ClientPacketizer::~ClientPacketizer() { | 49 ClientPacketizer::~ClientPacketizer() { |
50 } | 50 } |
51 | 51 |
52 int ClientPacketizer::Connect(const AddressList& server, | 52 int ClientPacketizer::Connect(const AddressList& server, |
53 Packetizer::Listener* listener, | 53 Packetizer::Listener* listener, |
54 OldCompletionCallback* callback) { | 54 const CompletionCallback& callback) { |
55 DCHECK(!old_user_callback_); | |
56 DCHECK(!socket_.get()); | |
57 DCHECK(!listener_); | |
58 | |
59 listener_ = listener; | |
60 | |
61 addresses_ = server; | |
62 | |
63 old_user_callback_ = callback; | |
64 next_state_ = LOOKUP_COOKIE; | |
65 | |
66 return DoLoop(OK); | |
67 } | |
68 int ClientPacketizer::Connect(const AddressList& server, | |
69 Packetizer::Listener* listener, | |
70 const net::CompletionCallback& callback) { | |
71 DCHECK(user_callback_.is_null()); | 55 DCHECK(user_callback_.is_null()); |
72 DCHECK(!socket_.get()); | 56 DCHECK(!socket_.get()); |
73 DCHECK(!listener_); | 57 DCHECK(!listener_); |
74 | 58 |
75 listener_ = listener; | 59 listener_ = listener; |
76 | 60 |
77 addresses_ = server; | 61 addresses_ = server; |
78 | 62 |
79 user_callback_ = callback; | 63 user_callback_ = callback; |
80 next_state_ = LOOKUP_COOKIE; | 64 next_state_ = LOOKUP_COOKIE; |
81 | 65 |
82 return DoLoop(OK); | 66 return DoLoop(OK); |
83 } | 67 } |
84 | 68 |
85 int ClientPacketizer::SendMessage(ConnectionKey key, | 69 int ClientPacketizer::SendMessage(ConnectionKey key, |
86 const char* data, | 70 const char* data, |
87 size_t length, | 71 size_t length, |
88 OldCompletionCallback* callback) { | 72 const CompletionCallback& callback) { |
89 // We can't send messages smaller than 16 bytes. | 73 // We can't send messages smaller than 16 bytes. |
90 if (length < 16) | 74 if (length < 16) |
91 return ERR_UNEXPECTED; | 75 return ERR_UNEXPECTED; |
92 | 76 |
93 if (!initiate_sent_) { | 77 if (!initiate_sent_) { |
94 const size_t kMaxMessageInInitiatePacket = | 78 const size_t kMaxMessageInInitiatePacket = |
95 kMaxPacketLength - sizeof(InitiatePacket); | 79 kMaxPacketLength - sizeof(InitiatePacket); |
96 | 80 |
97 if (length > kMaxMessageInInitiatePacket) { | 81 if (length > kMaxMessageInInitiatePacket) { |
98 NOTREACHED(); | 82 NOTREACHED(); |
99 return ERR_UNEXPECTED; | 83 return ERR_UNEXPECTED; |
100 } | 84 } |
101 | 85 |
102 initiate_sent_ = true; | 86 initiate_sent_ = true; |
103 | 87 |
104 // Bundle this message into the Initiate Packet. | 88 // Bundle this message into the Initiate Packet. |
105 scoped_refptr<IOBuffer> buffer(new IOBuffer(kMaxPacketLength)); | 89 scoped_refptr<IOBuffer> buffer(new IOBuffer(kMaxPacketLength)); |
106 InitiatePacket* packet = reinterpret_cast<InitiatePacket*>(buffer->data()); | 90 InitiatePacket* packet = reinterpret_cast<InitiatePacket*>(buffer->data()); |
107 memset(packet, 0, sizeof(InitiatePacket)); | 91 memset(packet, 0, sizeof(InitiatePacket)); |
108 memcpy(packet->id, "QvnQ5XlI", 8); | 92 memcpy(packet->id, "QvnQ5XlI", 8); |
109 memcpy(packet->client_shortterm_public_key, shortterm_public_key_, | 93 memcpy(packet->client_shortterm_public_key, shortterm_public_key_, |
110 sizeof(shortterm_public_key_)); | 94 sizeof(shortterm_public_key_)); |
111 // TODO(mbelshe): Fill in rest of Initiate fields here | 95 // TODO(mbelshe): Fill in rest of Initiate fields here |
112 // TODO(mbelshe): Fill in rest of message | 96 // TODO(mbelshe): Fill in rest of message |
113 // | 97 // |
114 // TODO(mbelshe) - this is just broken to make it work with cleartext | 98 // TODO(mbelshe) - this is just broken to make it work with cleartext |
115 memcpy(&buffer->data()[sizeof(InitiatePacket)], data, length); | 99 memcpy(&buffer->data()[sizeof(InitiatePacket)], data, length); |
116 int packet_length = sizeof(InitiatePacket) + length; | 100 int packet_length = sizeof(InitiatePacket) + length; |
117 int rv = socket_->Write(buffer, packet_length, &io_callback_); | 101 int rv = socket_->Write(buffer, packet_length, io_callback_); |
118 if (rv <= 0) | 102 if (rv <= 0) |
119 return rv; | 103 return rv; |
120 CHECK_EQ(packet_length, rv); // We must send all data. | 104 CHECK_EQ(packet_length, rv); // We must send all data. |
121 return length; | 105 return length; |
122 } | 106 } |
123 | 107 |
124 if (length > static_cast<size_t>(kMaxMessageLength)) { | 108 if (length > static_cast<size_t>(kMaxMessageLength)) { |
125 NOTREACHED(); | 109 NOTREACHED(); |
126 return ERR_UNEXPECTED; | 110 return ERR_UNEXPECTED; |
127 } | 111 } |
128 | 112 |
129 // Bundle this message into the Initiate Packet. | 113 // Bundle this message into the Initiate Packet. |
130 scoped_refptr<IOBuffer> buffer(new IOBuffer(kMaxPacketLength)); | 114 scoped_refptr<IOBuffer> buffer(new IOBuffer(kMaxPacketLength)); |
131 ClientMessagePacket* packet = | 115 ClientMessagePacket* packet = |
132 reinterpret_cast<ClientMessagePacket*>(buffer->data()); | 116 reinterpret_cast<ClientMessagePacket*>(buffer->data()); |
133 memset(packet, 0, sizeof(ClientMessagePacket)); | 117 memset(packet, 0, sizeof(ClientMessagePacket)); |
134 memcpy(packet->id, "QvnQ5XlM", 8); | 118 memcpy(packet->id, "QvnQ5XlM", 8); |
135 memcpy(packet->client_shortterm_public_key, shortterm_public_key_, | 119 memcpy(packet->client_shortterm_public_key, shortterm_public_key_, |
136 sizeof(shortterm_public_key_)); | 120 sizeof(shortterm_public_key_)); |
137 // TODO(mbelshe): Fill in rest of Initiate fields here | 121 // TODO(mbelshe): Fill in rest of Initiate fields here |
138 // TODO(mbelshe): Fill in rest of message | 122 // TODO(mbelshe): Fill in rest of message |
139 memcpy(&buffer->data()[sizeof(ClientMessagePacket)], data, length); | 123 memcpy(&buffer->data()[sizeof(ClientMessagePacket)], data, length); |
140 int packet_length = sizeof(ClientMessagePacket) + length; | 124 int packet_length = sizeof(ClientMessagePacket) + length; |
141 int rv = socket_->Write(buffer, packet_length, &io_callback_); | 125 int rv = socket_->Write(buffer, packet_length, io_callback_); |
142 if (rv <= 0) | 126 if (rv <= 0) |
143 return rv; | 127 return rv; |
144 CHECK_EQ(packet_length, rv); // We must send all data. | 128 CHECK_EQ(packet_length, rv); // We must send all data. |
145 return length; | 129 return length; |
146 } | 130 } |
147 | 131 |
148 void ClientPacketizer::Close(ConnectionKey key) { | 132 void ClientPacketizer::Close(ConnectionKey key) { |
149 // TODO(mbelshe): implement me | 133 // TODO(mbelshe): implement me |
150 NOTIMPLEMENTED(); | 134 NOTIMPLEMENTED(); |
151 } | 135 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 // Construct Hello Packet | 208 // Construct Hello Packet |
225 scoped_refptr<IOBuffer> buffer(new IOBuffer(sizeof(struct HelloPacket))); | 209 scoped_refptr<IOBuffer> buffer(new IOBuffer(sizeof(struct HelloPacket))); |
226 struct HelloPacket* data = | 210 struct HelloPacket* data = |
227 reinterpret_cast<struct HelloPacket*>(buffer->data()); | 211 reinterpret_cast<struct HelloPacket*>(buffer->data()); |
228 memset(data, 0, sizeof(struct HelloPacket)); | 212 memset(data, 0, sizeof(struct HelloPacket)); |
229 memcpy(data->id, "QvnQ5XlH", 8); | 213 memcpy(data->id, "QvnQ5XlH", 8); |
230 memcpy(data->client_shortterm_public_key, shortterm_public_key_, | 214 memcpy(data->client_shortterm_public_key, shortterm_public_key_, |
231 sizeof(shortterm_public_key_)); | 215 sizeof(shortterm_public_key_)); |
232 // TODO(mbelshe): populate all other fields of the HelloPacket. | 216 // TODO(mbelshe): populate all other fields of the HelloPacket. |
233 | 217 |
234 return socket_->Write(buffer, sizeof(struct HelloPacket), &io_callback_); | 218 return socket_->Write(buffer, sizeof(struct HelloPacket), io_callback_); |
235 } | 219 } |
236 | 220 |
237 int ClientPacketizer::DoSendingHelloComplete(int rv) { | 221 int ClientPacketizer::DoSendingHelloComplete(int rv) { |
238 next_state_ = NONE; | 222 next_state_ = NONE; |
239 | 223 |
240 if (rv < 0) | 224 if (rv < 0) |
241 return rv; | 225 return rv; |
242 | 226 |
243 // Writing to UDP should not result in a partial datagram. | 227 // Writing to UDP should not result in a partial datagram. |
244 if (rv != sizeof(struct HelloPacket)) | 228 if (rv != sizeof(struct HelloPacket)) |
245 return ERR_FAILED; | 229 return ERR_FAILED; |
246 | 230 |
247 next_state_ = WAITING_COOKIE; | 231 next_state_ = WAITING_COOKIE; |
248 return OK; | 232 return OK; |
249 } | 233 } |
250 | 234 |
251 int ClientPacketizer::DoWaitingCookie() { | 235 int ClientPacketizer::DoWaitingCookie() { |
252 next_state_ = WAITING_COOKIE_COMPLETE; | 236 next_state_ = WAITING_COOKIE_COMPLETE; |
253 | 237 |
254 StartHelloTimer(kHelloTimeoutMs[hello_attempts_++]); | 238 StartHelloTimer(kHelloTimeoutMs[hello_attempts_++]); |
255 | 239 |
256 read_buffer_ = new IOBuffer(kMaxPacketLength); | 240 read_buffer_ = new IOBuffer(kMaxPacketLength); |
257 return socket_->Read(read_buffer_, kMaxPacketLength, &io_callback_); | 241 return socket_->Read(read_buffer_, kMaxPacketLength, io_callback_); |
258 } | 242 } |
259 | 243 |
260 int ClientPacketizer::DoWaitingCookieComplete(int rv) { | 244 int ClientPacketizer::DoWaitingCookieComplete(int rv) { |
261 // TODO(mbelshe): Add Histogram for hello_attempts_. | 245 // TODO(mbelshe): Add Histogram for hello_attempts_. |
262 RevokeHelloTimer(); | 246 RevokeHelloTimer(); |
263 | 247 |
264 // TODO(mbelshe): Validate the cookie here | 248 // TODO(mbelshe): Validate the cookie here |
265 if (rv < 0) | 249 if (rv < 0) |
266 return rv; | 250 return rv; |
267 | 251 |
(...skipping 20 matching lines...) Expand all Loading... |
288 | 272 |
289 int ClientPacketizer::DoConnected(int rv) { | 273 int ClientPacketizer::DoConnected(int rv) { |
290 DCHECK(next_state_ == CONNECTED); | 274 DCHECK(next_state_ == CONNECTED); |
291 if (rv > 0) | 275 if (rv > 0) |
292 ProcessRead(rv); | 276 ProcessRead(rv); |
293 return ReadPackets(); | 277 return ReadPackets(); |
294 } | 278 } |
295 | 279 |
296 void ClientPacketizer::DoCallback(int result) { | 280 void ClientPacketizer::DoCallback(int result) { |
297 DCHECK_NE(result, ERR_IO_PENDING); | 281 DCHECK_NE(result, ERR_IO_PENDING); |
298 DCHECK(old_user_callback_ || !user_callback_.is_null()); | 282 DCHECK(!user_callback_.is_null()); |
299 | 283 |
300 if (old_user_callback_) { | 284 CompletionCallback callback = user_callback_; |
301 OldCompletionCallback* callback = old_user_callback_; | 285 user_callback_.Reset(); |
302 old_user_callback_ = NULL; | 286 callback.Run(result); |
303 callback->Run(result); | |
304 } else { | |
305 CompletionCallback callback = user_callback_; | |
306 user_callback_.Reset(); | |
307 callback.Run(result); | |
308 } | |
309 } | 287 } |
310 | 288 |
311 int ClientPacketizer::ConnectNextAddress() { | 289 int ClientPacketizer::ConnectNextAddress() { |
312 // TODO(mbelshe): plumb Netlog information | 290 // TODO(mbelshe): plumb Netlog information |
313 | 291 |
314 DCHECK(addresses_.head()); | 292 DCHECK(addresses_.head()); |
315 | 293 |
316 socket_.reset(new UDPClientSocket(DatagramSocket::DEFAULT_BIND, | 294 socket_.reset(new UDPClientSocket(DatagramSocket::DEFAULT_BIND, |
317 RandIntCallback(), | 295 RandIntCallback(), |
318 NULL, | 296 NULL, |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 length); | 362 length); |
385 } | 363 } |
386 | 364 |
387 int ClientPacketizer::ReadPackets() { | 365 int ClientPacketizer::ReadPackets() { |
388 DCHECK(socket_.get()); | 366 DCHECK(socket_.get()); |
389 | 367 |
390 int rv; | 368 int rv; |
391 while (true) { | 369 while (true) { |
392 rv = socket_->Read(read_buffer_, | 370 rv = socket_->Read(read_buffer_, |
393 kMaxPacketLength, | 371 kMaxPacketLength, |
394 &io_callback_); | 372 io_callback_); |
395 if (rv <= 0) { | 373 if (rv <= 0) { |
396 if (rv != ERR_IO_PENDING) | 374 if (rv != ERR_IO_PENDING) |
397 LOG(ERROR) << "Error reading socket:" << rv; | 375 LOG(ERROR) << "Error reading socket:" << rv; |
398 return rv; | 376 return rv; |
399 } | 377 } |
400 ProcessRead(rv); | 378 ProcessRead(rv); |
401 } | 379 } |
402 return rv; | 380 return rv; |
403 } | 381 } |
404 | 382 |
405 void ClientPacketizer::OnIOComplete(int result) { | 383 void ClientPacketizer::OnIOComplete(int result) { |
406 int rv = DoLoop(result); | 384 int rv = DoLoop(result); |
407 if (rv != ERR_IO_PENDING) | 385 if (rv != ERR_IO_PENDING) |
408 DoCallback(rv); | 386 DoCallback(rv); |
409 } | 387 } |
410 | 388 |
411 } // namespace net | 389 } // namespace net |
OLD | NEW |