Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include "webrtc/base/asynctcpsocket.h" | 11 #include "webrtc/base/asynctcpsocket.h" |
| 12 | 12 |
| 13 #include <string.h> | 13 #include <string.h> |
| 14 | 14 |
| 15 #include <algorithm> | |
| 16 | |
| 15 #include "webrtc/base/byteorder.h" | 17 #include "webrtc/base/byteorder.h" |
| 16 #include "webrtc/base/checks.h" | 18 #include "webrtc/base/checks.h" |
| 17 #include "webrtc/base/common.h" | 19 #include "webrtc/base/common.h" |
| 18 #include "webrtc/base/logging.h" | 20 #include "webrtc/base/logging.h" |
| 19 | 21 |
| 20 #if defined(WEBRTC_POSIX) | 22 #if defined(WEBRTC_POSIX) |
| 21 #include <errno.h> | 23 #include <errno.h> |
| 22 #endif // WEBRTC_POSIX | 24 #endif // WEBRTC_POSIX |
| 23 | 25 |
| 24 namespace rtc { | 26 namespace rtc { |
| 25 | 27 |
| 26 static const size_t kMaxPacketSize = 64 * 1024; | 28 static const size_t kMaxPacketSize = 64 * 1024; |
| 27 | 29 |
| 28 typedef uint16_t PacketLength; | 30 typedef uint16_t PacketLength; |
| 29 static const size_t kPacketLenSize = sizeof(PacketLength); | 31 static const size_t kPacketLenSize = sizeof(PacketLength); |
| 30 | 32 |
| 31 static const size_t kBufSize = kMaxPacketSize + kPacketLenSize; | 33 static const size_t kBufSize = kMaxPacketSize + kPacketLenSize; |
| 32 | 34 |
| 35 // The input buffer will be resized up to the maximum size so that at least | |
|
tommi
2016/03/01 09:22:13
do you mean minimum?
joachim
2016/03/01 10:55:23
No, the input buffer will be resized so that at le
tommi
2016/03/01 17:42:41
Thanks.
| |
| 36 // 128 bytes can be received. | |
| 37 static const size_t kMinimumRecvSize = 128; | |
| 38 | |
| 33 static const int kListenBacklog = 5; | 39 static const int kListenBacklog = 5; |
| 34 | 40 |
| 35 // Binds and connects |socket| | 41 // Binds and connects |socket| |
| 36 AsyncSocket* AsyncTCPSocketBase::ConnectSocket( | 42 AsyncSocket* AsyncTCPSocketBase::ConnectSocket( |
| 37 rtc::AsyncSocket* socket, | 43 rtc::AsyncSocket* socket, |
| 38 const rtc::SocketAddress& bind_address, | 44 const rtc::SocketAddress& bind_address, |
| 39 const rtc::SocketAddress& remote_address) { | 45 const rtc::SocketAddress& remote_address) { |
| 40 rtc::scoped_ptr<rtc::AsyncSocket> owned_socket(socket); | 46 rtc::scoped_ptr<rtc::AsyncSocket> owned_socket(socket); |
| 41 if (socket->Bind(bind_address) < 0) { | 47 if (socket->Bind(bind_address) < 0) { |
| 42 LOG(LS_ERROR) << "Bind() failed with error " << socket->GetError(); | 48 LOG(LS_ERROR) << "Bind() failed with error " << socket->GetError(); |
| 43 return NULL; | 49 return NULL; |
| 44 } | 50 } |
| 45 if (socket->Connect(remote_address) < 0) { | 51 if (socket->Connect(remote_address) < 0) { |
| 46 LOG(LS_ERROR) << "Connect() failed with error " << socket->GetError(); | 52 LOG(LS_ERROR) << "Connect() failed with error " << socket->GetError(); |
| 47 return NULL; | 53 return NULL; |
| 48 } | 54 } |
| 49 return owned_socket.release(); | 55 return owned_socket.release(); |
| 50 } | 56 } |
| 51 | 57 |
| 52 AsyncTCPSocketBase::AsyncTCPSocketBase(AsyncSocket* socket, bool listen, | 58 AsyncTCPSocketBase::AsyncTCPSocketBase(AsyncSocket* socket, bool listen, |
| 53 size_t max_packet_size) | 59 size_t max_packet_size) |
| 54 : socket_(socket), | 60 : socket_(socket), |
| 55 listen_(listen), | 61 listen_(listen), |
| 56 insize_(max_packet_size), | 62 max_insize_(max_packet_size), |
| 57 inpos_(0), | |
| 58 max_outsize_(max_packet_size) { | 63 max_outsize_(max_packet_size) { |
| 59 if (!listen_) { | 64 if (!listen_) { |
| 60 // Listening sockets don't send/receive data, so they don't need buffers. | 65 // Listening sockets don't send/receive data, so they don't need buffers. |
| 61 inbuf_.reset(new char[insize_]); | 66 inbuf_.EnsureCapacity(kMinimumRecvSize); |
| 62 } | 67 } |
| 63 | 68 |
| 64 RTC_DCHECK(socket_.get() != NULL); | 69 RTC_DCHECK(socket_.get() != NULL); |
| 65 socket_->SignalConnectEvent.connect( | 70 socket_->SignalConnectEvent.connect( |
| 66 this, &AsyncTCPSocketBase::OnConnectEvent); | 71 this, &AsyncTCPSocketBase::OnConnectEvent); |
| 67 socket_->SignalReadEvent.connect(this, &AsyncTCPSocketBase::OnReadEvent); | 72 socket_->SignalReadEvent.connect(this, &AsyncTCPSocketBase::OnReadEvent); |
| 68 socket_->SignalWriteEvent.connect(this, &AsyncTCPSocketBase::OnWriteEvent); | 73 socket_->SignalWriteEvent.connect(this, &AsyncTCPSocketBase::OnWriteEvent); |
| 69 socket_->SignalCloseEvent.connect(this, &AsyncTCPSocketBase::OnCloseEvent); | 74 socket_->SignalCloseEvent.connect(this, &AsyncTCPSocketBase::OnCloseEvent); |
| 70 | 75 |
| 71 if (listen_) { | 76 if (listen_) { |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 186 // to the user. | 191 // to the user. |
| 187 LOG(LS_ERROR) << "TCP accept failed with error " << socket_->GetError(); | 192 LOG(LS_ERROR) << "TCP accept failed with error " << socket_->GetError(); |
| 188 return; | 193 return; |
| 189 } | 194 } |
| 190 | 195 |
| 191 HandleIncomingConnection(new_socket); | 196 HandleIncomingConnection(new_socket); |
| 192 | 197 |
| 193 // Prime a read event in case data is waiting. | 198 // Prime a read event in case data is waiting. |
| 194 new_socket->SignalReadEvent(new_socket); | 199 new_socket->SignalReadEvent(new_socket); |
| 195 } else { | 200 } else { |
| 196 RTC_DCHECK(inbuf_.get()); | 201 size_t total_recv = 0; |
| 197 int len = socket_->Recv(inbuf_.get() + inpos_, insize_ - inpos_); | 202 while (true) { |
| 198 if (len < 0) { | 203 size_t free_size = inbuf_.capacity() - inbuf_.size(); |
| 199 // TODO: Do something better like forwarding the error to the user. | 204 if (free_size < kMinimumRecvSize && inbuf_.capacity() < max_insize_) { |
| 200 if (!socket_->IsBlocking()) { | 205 inbuf_.EnsureCapacity(std::min(max_insize_, inbuf_.capacity() * 2)); |
| 201 LOG(LS_ERROR) << "Recv() returned error: " << socket_->GetError(); | 206 free_size = inbuf_.capacity() - inbuf_.size(); |
| 202 } | 207 } |
| 208 | |
| 209 int len = socket_->Recv(inbuf_.data() + inbuf_.size(), free_size); | |
| 210 if (len < 0) { | |
| 211 // TODO: Do something better like forwarding the error to the user. | |
|
tommi
2016/03/01 09:22:13
can you assign the TODO to someone?
joachim
2016/03/01 10:55:23
Assigned both TODOs in the file to "henrike" who c
tommi
2016/03/01 17:42:42
henrike doesn't work on webrtc anymore actually.
joachim
2016/03/02 08:32:17
Last changes to that file were from stefan@ and pb
| |
| 212 if (!socket_->IsBlocking()) { | |
| 213 LOG(LS_ERROR) << "Recv() returned error: " << socket_->GetError(); | |
|
tommi
2016/03/01 09:22:13
nit: You can use LOG_IF() to combine the LOG and t
joachim
2016/03/01 10:55:23
Where is LOG_IF defined? I think it's only availab
tommi
2016/03/01 17:42:42
oh, sorry. fine as is.
| |
| 214 } | |
| 215 break; | |
| 216 } | |
| 217 | |
| 218 total_recv += len; | |
| 219 inbuf_.SetSize(inbuf_.size() + len); | |
| 220 if (!len || static_cast<size_t>(len) < free_size) { | |
| 221 break; | |
| 222 } | |
| 223 } | |
| 224 | |
| 225 if (!total_recv) { | |
| 203 return; | 226 return; |
| 204 } | 227 } |
| 205 | 228 |
| 206 inpos_ += len; | 229 size_t size = inbuf_.size(); |
| 230 ProcessInput(inbuf_.data<char>(), &size); | |
| 207 | 231 |
| 208 ProcessInput(inbuf_.get(), &inpos_); | 232 if (size > inbuf_.size()) { |
| 209 | |
| 210 if (inpos_ >= insize_) { | |
| 211 LOG(LS_ERROR) << "input buffer overflow"; | 233 LOG(LS_ERROR) << "input buffer overflow"; |
| 212 RTC_NOTREACHED(); | 234 RTC_NOTREACHED(); |
| 213 inpos_ = 0; | 235 inbuf_.Clear(); |
| 236 } else { | |
| 237 inbuf_.SetSize(size); | |
| 214 } | 238 } |
| 215 } | 239 } |
| 216 } | 240 } |
| 217 | 241 |
| 218 void AsyncTCPSocketBase::OnWriteEvent(AsyncSocket* socket) { | 242 void AsyncTCPSocketBase::OnWriteEvent(AsyncSocket* socket) { |
| 219 RTC_DCHECK(socket_.get() == socket); | 243 RTC_DCHECK(socket_.get() == socket); |
| 220 | 244 |
| 221 if (outbuf_.size() > 0) { | 245 if (outbuf_.size() > 0) { |
| 222 FlushOutBuffer(); | 246 FlushOutBuffer(); |
| 223 } | 247 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 295 memmove(data, data + kPacketLenSize + pkt_len, *len); | 319 memmove(data, data + kPacketLenSize + pkt_len, *len); |
| 296 } | 320 } |
| 297 } | 321 } |
| 298 } | 322 } |
| 299 | 323 |
| 300 void AsyncTCPSocket::HandleIncomingConnection(AsyncSocket* socket) { | 324 void AsyncTCPSocket::HandleIncomingConnection(AsyncSocket* socket) { |
| 301 SignalNewConnection(this, new AsyncTCPSocket(socket, false)); | 325 SignalNewConnection(this, new AsyncTCPSocket(socket, false)); |
| 302 } | 326 } |
| 303 | 327 |
| 304 } // namespace rtc | 328 } // namespace rtc |
| OLD | NEW |