| 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 "webrtc/base/byteorder.h" | 15 #include "webrtc/base/byteorder.h" |
| 16 #include "webrtc/base/checks.h" |
| 16 #include "webrtc/base/common.h" | 17 #include "webrtc/base/common.h" |
| 17 #include "webrtc/base/logging.h" | 18 #include "webrtc/base/logging.h" |
| 18 | 19 |
| 19 #if defined(WEBRTC_POSIX) | 20 #if defined(WEBRTC_POSIX) |
| 20 #include <errno.h> | 21 #include <errno.h> |
| 21 #endif // WEBRTC_POSIX | 22 #endif // WEBRTC_POSIX |
| 22 | 23 |
| 23 namespace rtc { | 24 namespace rtc { |
| 24 | 25 |
| 25 static const size_t kMaxPacketSize = 64 * 1024; | 26 static const size_t kMaxPacketSize = 64 * 1024; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 49 } | 50 } |
| 50 | 51 |
| 51 AsyncTCPSocketBase::AsyncTCPSocketBase(AsyncSocket* socket, bool listen, | 52 AsyncTCPSocketBase::AsyncTCPSocketBase(AsyncSocket* socket, bool listen, |
| 52 size_t max_packet_size) | 53 size_t max_packet_size) |
| 53 : socket_(socket), | 54 : socket_(socket), |
| 54 listen_(listen), | 55 listen_(listen), |
| 55 insize_(max_packet_size), | 56 insize_(max_packet_size), |
| 56 inpos_(0), | 57 inpos_(0), |
| 57 outsize_(max_packet_size), | 58 outsize_(max_packet_size), |
| 58 outpos_(0) { | 59 outpos_(0) { |
| 59 inbuf_ = new char[insize_]; | 60 if (!listen_) { |
| 60 outbuf_ = new char[outsize_]; | 61 // Listening sockets don't send/receive data, so they don't need buffers. |
| 62 inbuf_.reset(new char[insize_]); |
| 63 outbuf_.reset(new char[outsize_]); |
| 64 } |
| 61 | 65 |
| 62 ASSERT(socket_.get() != NULL); | 66 RTC_DCHECK(socket_.get() != NULL); |
| 63 socket_->SignalConnectEvent.connect( | 67 socket_->SignalConnectEvent.connect( |
| 64 this, &AsyncTCPSocketBase::OnConnectEvent); | 68 this, &AsyncTCPSocketBase::OnConnectEvent); |
| 65 socket_->SignalReadEvent.connect(this, &AsyncTCPSocketBase::OnReadEvent); | 69 socket_->SignalReadEvent.connect(this, &AsyncTCPSocketBase::OnReadEvent); |
| 66 socket_->SignalWriteEvent.connect(this, &AsyncTCPSocketBase::OnWriteEvent); | 70 socket_->SignalWriteEvent.connect(this, &AsyncTCPSocketBase::OnWriteEvent); |
| 67 socket_->SignalCloseEvent.connect(this, &AsyncTCPSocketBase::OnCloseEvent); | 71 socket_->SignalCloseEvent.connect(this, &AsyncTCPSocketBase::OnCloseEvent); |
| 68 | 72 |
| 69 if (listen_) { | 73 if (listen_) { |
| 70 if (socket_->Listen(kListenBacklog) < 0) { | 74 if (socket_->Listen(kListenBacklog) < 0) { |
| 71 LOG(LS_ERROR) << "Listen() failed with error " << socket_->GetError(); | 75 LOG(LS_ERROR) << "Listen() failed with error " << socket_->GetError(); |
| 72 } | 76 } |
| 73 } | 77 } |
| 74 } | 78 } |
| 75 | 79 |
| 76 AsyncTCPSocketBase::~AsyncTCPSocketBase() { | 80 AsyncTCPSocketBase::~AsyncTCPSocketBase() {} |
| 77 delete [] inbuf_; | |
| 78 delete [] outbuf_; | |
| 79 } | |
| 80 | 81 |
| 81 SocketAddress AsyncTCPSocketBase::GetLocalAddress() const { | 82 SocketAddress AsyncTCPSocketBase::GetLocalAddress() const { |
| 82 return socket_->GetLocalAddress(); | 83 return socket_->GetLocalAddress(); |
| 83 } | 84 } |
| 84 | 85 |
| 85 SocketAddress AsyncTCPSocketBase::GetRemoteAddress() const { | 86 SocketAddress AsyncTCPSocketBase::GetRemoteAddress() const { |
| 86 return socket_->GetRemoteAddress(); | 87 return socket_->GetRemoteAddress(); |
| 87 } | 88 } |
| 88 | 89 |
| 89 int AsyncTCPSocketBase::Close() { | 90 int AsyncTCPSocketBase::Close() { |
| 90 return socket_->Close(); | 91 return socket_->Close(); |
| 91 } | 92 } |
| 92 | 93 |
| 93 AsyncTCPSocket::State AsyncTCPSocketBase::GetState() const { | 94 AsyncTCPSocket::State AsyncTCPSocketBase::GetState() const { |
| 94 switch (socket_->GetState()) { | 95 switch (socket_->GetState()) { |
| 95 case Socket::CS_CLOSED: | 96 case Socket::CS_CLOSED: |
| 96 return STATE_CLOSED; | 97 return STATE_CLOSED; |
| 97 case Socket::CS_CONNECTING: | 98 case Socket::CS_CONNECTING: |
| 98 if (listen_) { | 99 if (listen_) { |
| 99 return STATE_BOUND; | 100 return STATE_BOUND; |
| 100 } else { | 101 } else { |
| 101 return STATE_CONNECTING; | 102 return STATE_CONNECTING; |
| 102 } | 103 } |
| 103 case Socket::CS_CONNECTED: | 104 case Socket::CS_CONNECTED: |
| 104 return STATE_CONNECTED; | 105 return STATE_CONNECTED; |
| 105 default: | 106 default: |
| 106 ASSERT(false); | 107 RTC_NOTREACHED(); |
| 107 return STATE_CLOSED; | 108 return STATE_CLOSED; |
| 108 } | 109 } |
| 109 } | 110 } |
| 110 | 111 |
| 111 int AsyncTCPSocketBase::GetOption(Socket::Option opt, int* value) { | 112 int AsyncTCPSocketBase::GetOption(Socket::Option opt, int* value) { |
| 112 return socket_->GetOption(opt, value); | 113 return socket_->GetOption(opt, value); |
| 113 } | 114 } |
| 114 | 115 |
| 115 int AsyncTCPSocketBase::SetOption(Socket::Option opt, int value) { | 116 int AsyncTCPSocketBase::SetOption(Socket::Option opt, int value) { |
| 116 return socket_->SetOption(opt, value); | 117 return socket_->SetOption(opt, value); |
| 117 } | 118 } |
| 118 | 119 |
| 119 int AsyncTCPSocketBase::GetError() const { | 120 int AsyncTCPSocketBase::GetError() const { |
| 120 return socket_->GetError(); | 121 return socket_->GetError(); |
| 121 } | 122 } |
| 122 | 123 |
| 123 void AsyncTCPSocketBase::SetError(int error) { | 124 void AsyncTCPSocketBase::SetError(int error) { |
| 124 return socket_->SetError(error); | 125 return socket_->SetError(error); |
| 125 } | 126 } |
| 126 | 127 |
| 127 int AsyncTCPSocketBase::SendTo(const void *pv, size_t cb, | 128 int AsyncTCPSocketBase::SendTo(const void *pv, size_t cb, |
| 128 const SocketAddress& addr, | 129 const SocketAddress& addr, |
| 129 const rtc::PacketOptions& options) { | 130 const rtc::PacketOptions& options) { |
| 130 const SocketAddress& remote_address = GetRemoteAddress(); | 131 const SocketAddress& remote_address = GetRemoteAddress(); |
| 131 if (addr == remote_address) | 132 if (addr == remote_address) |
| 132 return Send(pv, cb, options); | 133 return Send(pv, cb, options); |
| 133 // Remote address may be empty if there is a sudden network change. | 134 // Remote address may be empty if there is a sudden network change. |
| 134 ASSERT(remote_address.IsNil()); | 135 RTC_DCHECK(remote_address.IsNil()); |
| 135 socket_->SetError(ENOTCONN); | 136 socket_->SetError(ENOTCONN); |
| 136 return -1; | 137 return -1; |
| 137 } | 138 } |
| 138 | 139 |
| 139 int AsyncTCPSocketBase::SendRaw(const void * pv, size_t cb) { | 140 int AsyncTCPSocketBase::SendRaw(const void * pv, size_t cb) { |
| 140 if (outpos_ + cb > outsize_) { | 141 if (outpos_ + cb > outsize_) { |
| 141 socket_->SetError(EMSGSIZE); | 142 socket_->SetError(EMSGSIZE); |
| 142 return -1; | 143 return -1; |
| 143 } | 144 } |
| 144 | 145 |
| 145 memcpy(outbuf_ + outpos_, pv, cb); | 146 RTC_DCHECK(outbuf_.get()); |
| 147 memcpy(outbuf_.get() + outpos_, pv, cb); |
| 146 outpos_ += cb; | 148 outpos_ += cb; |
| 147 | 149 |
| 148 return FlushOutBuffer(); | 150 return FlushOutBuffer(); |
| 149 } | 151 } |
| 150 | 152 |
| 151 int AsyncTCPSocketBase::FlushOutBuffer() { | 153 int AsyncTCPSocketBase::FlushOutBuffer() { |
| 152 int res = socket_->Send(outbuf_, outpos_); | 154 RTC_DCHECK(outbuf_.get()); |
| 155 int res = socket_->Send(outbuf_.get(), outpos_); |
| 153 if (res <= 0) { | 156 if (res <= 0) { |
| 154 return res; | 157 return res; |
| 155 } | 158 } |
| 156 if (static_cast<size_t>(res) <= outpos_) { | 159 if (static_cast<size_t>(res) <= outpos_) { |
| 157 outpos_ -= res; | 160 outpos_ -= res; |
| 158 } else { | 161 } else { |
| 159 ASSERT(false); | 162 RTC_NOTREACHED(); |
| 160 return -1; | 163 return -1; |
| 161 } | 164 } |
| 162 if (outpos_ > 0) { | 165 if (outpos_ > 0) { |
| 163 memmove(outbuf_, outbuf_ + res, outpos_); | 166 memmove(outbuf_.get(), outbuf_.get() + res, outpos_); |
| 164 } | 167 } |
| 165 return res; | 168 return res; |
| 166 } | 169 } |
| 167 | 170 |
| 168 void AsyncTCPSocketBase::AppendToOutBuffer(const void* pv, size_t cb) { | 171 void AsyncTCPSocketBase::AppendToOutBuffer(const void* pv, size_t cb) { |
| 169 ASSERT(outpos_ + cb < outsize_); | 172 RTC_DCHECK(outpos_ + cb < outsize_); |
| 170 memcpy(outbuf_ + outpos_, pv, cb); | 173 RTC_DCHECK(outbuf_.get()); |
| 174 memcpy(outbuf_.get() + outpos_, pv, cb); |
| 171 outpos_ += cb; | 175 outpos_ += cb; |
| 172 } | 176 } |
| 173 | 177 |
| 174 void AsyncTCPSocketBase::OnConnectEvent(AsyncSocket* socket) { | 178 void AsyncTCPSocketBase::OnConnectEvent(AsyncSocket* socket) { |
| 175 SignalConnect(this); | 179 SignalConnect(this); |
| 176 } | 180 } |
| 177 | 181 |
| 178 void AsyncTCPSocketBase::OnReadEvent(AsyncSocket* socket) { | 182 void AsyncTCPSocketBase::OnReadEvent(AsyncSocket* socket) { |
| 179 ASSERT(socket_.get() == socket); | 183 RTC_DCHECK(socket_.get() == socket); |
| 180 | 184 |
| 181 if (listen_) { | 185 if (listen_) { |
| 182 rtc::SocketAddress address; | 186 rtc::SocketAddress address; |
| 183 rtc::AsyncSocket* new_socket = socket->Accept(&address); | 187 rtc::AsyncSocket* new_socket = socket->Accept(&address); |
| 184 if (!new_socket) { | 188 if (!new_socket) { |
| 185 // TODO: Do something better like forwarding the error | 189 // TODO: Do something better like forwarding the error |
| 186 // to the user. | 190 // to the user. |
| 187 LOG(LS_ERROR) << "TCP accept failed with error " << socket_->GetError(); | 191 LOG(LS_ERROR) << "TCP accept failed with error " << socket_->GetError(); |
| 188 return; | 192 return; |
| 189 } | 193 } |
| 190 | 194 |
| 191 HandleIncomingConnection(new_socket); | 195 HandleIncomingConnection(new_socket); |
| 192 | 196 |
| 193 // Prime a read event in case data is waiting. | 197 // Prime a read event in case data is waiting. |
| 194 new_socket->SignalReadEvent(new_socket); | 198 new_socket->SignalReadEvent(new_socket); |
| 195 } else { | 199 } else { |
| 196 int len = socket_->Recv(inbuf_ + inpos_, insize_ - inpos_); | 200 RTC_DCHECK(inbuf_.get()); |
| 201 int len = socket_->Recv(inbuf_.get() + inpos_, insize_ - inpos_); |
| 197 if (len < 0) { | 202 if (len < 0) { |
| 198 // TODO: Do something better like forwarding the error to the user. | 203 // TODO: Do something better like forwarding the error to the user. |
| 199 if (!socket_->IsBlocking()) { | 204 if (!socket_->IsBlocking()) { |
| 200 LOG(LS_ERROR) << "Recv() returned error: " << socket_->GetError(); | 205 LOG(LS_ERROR) << "Recv() returned error: " << socket_->GetError(); |
| 201 } | 206 } |
| 202 return; | 207 return; |
| 203 } | 208 } |
| 204 | 209 |
| 205 inpos_ += len; | 210 inpos_ += len; |
| 206 | 211 |
| 207 ProcessInput(inbuf_, &inpos_); | 212 ProcessInput(inbuf_.get(), &inpos_); |
| 208 | 213 |
| 209 if (inpos_ >= insize_) { | 214 if (inpos_ >= insize_) { |
| 210 LOG(LS_ERROR) << "input buffer overflow"; | 215 LOG(LS_ERROR) << "input buffer overflow"; |
| 211 ASSERT(false); | 216 RTC_NOTREACHED(); |
| 212 inpos_ = 0; | 217 inpos_ = 0; |
| 213 } | 218 } |
| 214 } | 219 } |
| 215 } | 220 } |
| 216 | 221 |
| 217 void AsyncTCPSocketBase::OnWriteEvent(AsyncSocket* socket) { | 222 void AsyncTCPSocketBase::OnWriteEvent(AsyncSocket* socket) { |
| 218 ASSERT(socket_.get() == socket); | 223 RTC_DCHECK(socket_.get() == socket); |
| 219 | 224 |
| 220 if (outpos_ > 0) { | 225 if (outpos_ > 0) { |
| 221 FlushOutBuffer(); | 226 FlushOutBuffer(); |
| 222 } | 227 } |
| 223 | 228 |
| 224 if (outpos_ == 0) { | 229 if (outpos_ == 0) { |
| 225 SignalReadyToSend(this); | 230 SignalReadyToSend(this); |
| 226 } | 231 } |
| 227 } | 232 } |
| 228 | 233 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 memmove(data, data + kPacketLenSize + pkt_len, *len); | 299 memmove(data, data + kPacketLenSize + pkt_len, *len); |
| 295 } | 300 } |
| 296 } | 301 } |
| 297 } | 302 } |
| 298 | 303 |
| 299 void AsyncTCPSocket::HandleIncomingConnection(AsyncSocket* socket) { | 304 void AsyncTCPSocket::HandleIncomingConnection(AsyncSocket* socket) { |
| 300 SignalNewConnection(this, new AsyncTCPSocket(socket, false)); | 305 SignalNewConnection(this, new AsyncTCPSocket(socket, false)); |
| 301 } | 306 } |
| 302 | 307 |
| 303 } // namespace rtc | 308 } // namespace rtc |
| OLD | NEW |