| 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 |