OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 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 | 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/socket/socks5_client_socket.h" | 5 #include "net/socket/socks5_client_socket.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/trace_event.h" | 9 #include "base/trace_event.h" |
10 #include "net/base/io_buffer.h" | 10 #include "net/base/io_buffer.h" |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 return completed_handshake_ && transport_->IsConnected(); | 78 return completed_handshake_ && transport_->IsConnected(); |
79 } | 79 } |
80 | 80 |
81 bool SOCKS5ClientSocket::IsConnectedAndIdle() const { | 81 bool SOCKS5ClientSocket::IsConnectedAndIdle() const { |
82 return completed_handshake_ && transport_->IsConnectedAndIdle(); | 82 return completed_handshake_ && transport_->IsConnectedAndIdle(); |
83 } | 83 } |
84 | 84 |
85 // Read is called by the transport layer above to read. This can only be done | 85 // Read is called by the transport layer above to read. This can only be done |
86 // if the SOCKS handshake is complete. | 86 // if the SOCKS handshake is complete. |
87 int SOCKS5ClientSocket::Read(IOBuffer* buf, int buf_len, | 87 int SOCKS5ClientSocket::Read(IOBuffer* buf, int buf_len, |
88 CompletionCallback* callback) { | 88 CompletionCallback* callback) { |
89 DCHECK(completed_handshake_); | 89 DCHECK(completed_handshake_); |
90 DCHECK_EQ(STATE_NONE, next_state_); | 90 DCHECK_EQ(STATE_NONE, next_state_); |
91 DCHECK(!user_callback_); | 91 DCHECK(!user_callback_); |
92 | 92 |
93 return transport_->Read(buf, buf_len, callback); | 93 return transport_->Read(buf, buf_len, callback); |
94 } | 94 } |
95 | 95 |
96 // Write is called by the transport layer. This can only be done if the | 96 // Write is called by the transport layer. This can only be done if the |
97 // SOCKS handshake is complete. | 97 // SOCKS handshake is complete. |
98 int SOCKS5ClientSocket::Write(IOBuffer* buf, int buf_len, | 98 int SOCKS5ClientSocket::Write(IOBuffer* buf, int buf_len, |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 break; | 175 break; |
176 } | 176 } |
177 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | 177 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
178 return rv; | 178 return rv; |
179 } | 179 } |
180 | 180 |
181 const char kSOCKS5GreetWriteData[] = { 0x05, 0x01, 0x00 }; // no authentication | 181 const char kSOCKS5GreetWriteData[] = { 0x05, 0x01, 0x00 }; // no authentication |
182 const char kSOCKS5GreetReadData[] = { 0x05, 0x00 }; | 182 const char kSOCKS5GreetReadData[] = { 0x05, 0x00 }; |
183 | 183 |
184 int SOCKS5ClientSocket::DoGreetWrite() { | 184 int SOCKS5ClientSocket::DoGreetWrite() { |
| 185 // Since we only have 1 byte to send the hostname length in, if the |
| 186 // URL has a hostname longer than 255 characters we can't send it. |
| 187 if (0xFF < host_request_info_.hostname().size()) |
| 188 return ERR_INVALID_URL; |
| 189 |
185 if (buffer_.empty()) { | 190 if (buffer_.empty()) { |
186 buffer_ = std::string(kSOCKS5GreetWriteData, | 191 buffer_ = std::string(kSOCKS5GreetWriteData, |
187 arraysize(kSOCKS5GreetWriteData)); | 192 arraysize(kSOCKS5GreetWriteData)); |
188 bytes_sent_ = 0; | 193 bytes_sent_ = 0; |
189 } | 194 } |
190 | 195 |
191 next_state_ = STATE_GREET_WRITE_COMPLETE; | 196 next_state_ = STATE_GREET_WRITE_COMPLETE; |
192 size_t handshake_buf_len = buffer_.size() - bytes_sent_; | 197 size_t handshake_buf_len = buffer_.size() - bytes_sent_; |
193 handshake_buf_ = new IOBuffer(handshake_buf_len); | 198 handshake_buf_ = new IOBuffer(handshake_buf_len); |
194 memcpy(handshake_buf_->data(), &buffer_.data()[bytes_sent_], | 199 memcpy(handshake_buf_->data(), &buffer_.data()[bytes_sent_], |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 int SOCKS5ClientSocket::BuildHandshakeWriteBuffer(std::string* handshake) | 249 int SOCKS5ClientSocket::BuildHandshakeWriteBuffer(std::string* handshake) |
245 const { | 250 const { |
246 DCHECK(handshake->empty()); | 251 DCHECK(handshake->empty()); |
247 | 252 |
248 handshake->push_back(kSOCKS5Version); | 253 handshake->push_back(kSOCKS5Version); |
249 handshake->push_back(kTunnelCommand); // Connect command | 254 handshake->push_back(kTunnelCommand); // Connect command |
250 handshake->push_back(kNullByte); // Reserved null | 255 handshake->push_back(kNullByte); // Reserved null |
251 | 256 |
252 handshake->push_back(kEndPointDomain); // The type of the address. | 257 handshake->push_back(kEndPointDomain); // The type of the address. |
253 | 258 |
254 // We only have 1 byte to send the length in, so if the hostname is | 259 DCHECK_GE(static_cast<size_t>(0xFF), host_request_info_.hostname().size()); |
255 // longer than this we can't send it! | |
256 if(256 <= host_request_info_.hostname().size()) | |
257 return ERR_INVALID_URL; | |
258 | 260 |
259 // First add the size of the hostname, followed by the hostname. | 261 // First add the size of the hostname, followed by the hostname. |
260 handshake->push_back(static_cast<unsigned char>( | 262 handshake->push_back(static_cast<unsigned char>( |
261 host_request_info_.hostname().size())); | 263 host_request_info_.hostname().size())); |
262 handshake->append(host_request_info_.hostname()); | 264 handshake->append(host_request_info_.hostname()); |
263 | 265 |
264 uint16 nw_port = htons(host_request_info_.port()); | 266 uint16 nw_port = htons(host_request_info_.port()); |
265 handshake->append(reinterpret_cast<char*>(&nw_port), sizeof(nw_port)); | 267 handshake->append(reinterpret_cast<char*>(&nw_port), sizeof(nw_port)); |
266 return OK; | 268 return OK; |
267 } | 269 } |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 } | 376 } |
375 | 377 |
376 #if defined(OS_LINUX) | 378 #if defined(OS_LINUX) |
377 int SOCKS5ClientSocket::GetPeerName(struct sockaddr* name, | 379 int SOCKS5ClientSocket::GetPeerName(struct sockaddr* name, |
378 socklen_t* namelen) { | 380 socklen_t* namelen) { |
379 return transport_->GetPeerName(name, namelen); | 381 return transport_->GetPeerName(name, namelen); |
380 } | 382 } |
381 #endif | 383 #endif |
382 | 384 |
383 } // namespace net | 385 } // namespace net |
OLD | NEW |