Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 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 "remoting/host/gnubby_socket.h" | |
| 6 | |
| 7 #include "base/macros.h" | |
| 8 | |
| 9 namespace remoting { | |
| 10 | |
| 11 namespace { | |
| 12 | |
| 13 const size_t kRequestSizeBytes = 4; | |
| 14 const size_t kMaxRequestLength = 16384; | |
| 15 const unsigned int kRequestTimeoutSeconds = 60; | |
| 16 | |
| 17 // Length-prefixed SSH Failure Code | |
| 18 const char kSshError[] = {0x00, 0x00, 0x00, 0x01, 0x05}; | |
| 19 | |
| 20 } // namespace | |
| 21 | |
| 22 GnubbySocket::GnubbySocket(scoped_ptr<net::StreamListenSocket> socket, | |
| 23 const base::Closure& timeout_callback) | |
| 24 : socket_(socket.Pass()) { | |
| 25 timer_.reset(new base::Timer(false, false)); | |
| 26 timer_->Start(FROM_HERE, | |
| 27 base::TimeDelta::FromSeconds(kRequestTimeoutSeconds), | |
| 28 timeout_callback); | |
| 29 } | |
| 30 | |
| 31 void GnubbySocket::AddRequestData(const char* data, int data_len) { | |
| 32 DCHECK(CalledOnValidThread()); | |
| 33 | |
| 34 request_data_.insert(request_data_.end(), data, data + data_len); | |
| 35 ResetTimer(); | |
| 36 } | |
| 37 | |
| 38 void GnubbySocket::GetAndClearRequestData(std::string* data_out) { | |
| 39 DCHECK(CalledOnValidThread()); | |
| 40 DCHECK(IsRequestComplete() && !IsRequestTooLarge()); | |
| 41 | |
| 42 // The request size is not part of the data; don't send it. | |
| 43 data_out->assign(request_data_.begin() + kRequestSizeBytes, | |
| 44 request_data_.end()); | |
| 45 request_data_.clear(); | |
| 46 } | |
| 47 | |
| 48 bool GnubbySocket::IsRequestComplete() const { | |
| 49 DCHECK(CalledOnValidThread()); | |
| 50 | |
| 51 if (request_data_.size() < kRequestSizeBytes) | |
| 52 return false; | |
| 53 return GetRequestLength() <= request_data_.size(); | |
| 54 } | |
| 55 | |
| 56 bool GnubbySocket::IsRequestTooLarge() const { | |
| 57 DCHECK(CalledOnValidThread()); | |
| 58 | |
| 59 if (request_data_.size() < kRequestSizeBytes) | |
| 60 return false; | |
| 61 return GetRequestLength() > kMaxRequestLength; | |
| 62 } | |
| 63 | |
| 64 void GnubbySocket::SendResponse(const std::string& response_data) { | |
| 65 DCHECK(CalledOnValidThread()); | |
| 66 | |
| 67 socket_->Send(GetResponseLengthAsBytes(response_data)); | |
| 68 socket_->Send(response_data); | |
| 69 ResetTimer(); | |
| 70 } | |
| 71 | |
| 72 void GnubbySocket::SendSshError() { | |
| 73 DCHECK(CalledOnValidThread()); | |
| 74 | |
| 75 socket_->Send(kSshError, arraysize(kSshError)); | |
|
Sergey Ulanov
2014/03/21 22:53:16
Can this invoke SendResponse?
psj
2014/03/21 23:24:17
Done.
| |
| 76 } | |
| 77 | |
| 78 bool GnubbySocket::IsSocket(net::StreamListenSocket* socket) const { | |
| 79 return socket == socket_.get(); | |
| 80 } | |
| 81 | |
| 82 void GnubbySocket::SetTimerForTesting(scoped_ptr<base::Timer> timer) { | |
| 83 timer->Start(FROM_HERE, timer_->GetCurrentDelay(), timer_->user_task()); | |
| 84 timer_ = timer.Pass(); | |
| 85 } | |
| 86 | |
| 87 size_t GnubbySocket::GetRequestLength() const { | |
| 88 DCHECK(request_data_.size() >= kRequestSizeBytes); | |
| 89 | |
| 90 return ((request_data_[0] & 255) << 24) + ((request_data_[1] & 255) << 16) + | |
| 91 ((request_data_[2] & 255) << 8) + (request_data_[3] & 255) + 4; | |
|
Sergey Ulanov
2014/03/21 22:53:16
+kRequestSizeBytes at the end
psj
2014/03/21 23:24:17
Arggggg, I was sure I had gotten all of the 4's...
| |
| 92 } | |
| 93 | |
| 94 std::string GnubbySocket::GetResponseLengthAsBytes( | |
| 95 const std::string& response) const { | |
| 96 std::string response_len; | |
| 97 int len = response.size(); | |
| 98 | |
| 99 response_len.push_back((len >> 24) & 255); | |
| 100 response_len.push_back((len >> 16) & 255); | |
| 101 response_len.push_back((len >> 8) & 255); | |
| 102 response_len.push_back(len & 255); | |
| 103 | |
| 104 return response_len; | |
| 105 } | |
| 106 | |
| 107 void GnubbySocket::ResetTimer() { | |
| 108 timer_->Reset(); | |
| 109 } | |
| 110 | |
| 111 } // namespace remoting | |
| OLD | NEW |