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 |