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 |