OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "remoting/protocol/chromium_socket_factory.h" | 5 #include "remoting/protocol/chromium_socket_factory.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
10 #include "jingle/glue/utils.h" | 10 #include "jingle/glue/utils.h" |
11 #include "net/base/io_buffer.h" | 11 #include "net/base/io_buffer.h" |
12 #include "net/base/ip_endpoint.h" | 12 #include "net/base/ip_endpoint.h" |
13 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
14 #include "net/udp/udp_server_socket.h" | 14 #include "net/udp/udp_server_socket.h" |
15 #include "remoting/protocol/socket_util.h" | 15 #include "remoting/protocol/socket_util.h" |
16 #include "third_party/libjingle/source/talk/base/asyncpacketsocket.h" | 16 #include "third_party/webrtc/base/asyncpacketsocket.h" |
17 #include "third_party/libjingle/source/talk/base/nethelpers.h" | 17 #include "third_party/webrtc/base/nethelpers.h" |
18 | 18 |
19 namespace remoting { | 19 namespace remoting { |
20 namespace protocol { | 20 namespace protocol { |
21 | 21 |
22 namespace { | 22 namespace { |
23 | 23 |
24 // Size of the buffer to allocate for RecvFrom(). | 24 // Size of the buffer to allocate for RecvFrom(). |
25 const int kReceiveBufferSize = 65536; | 25 const int kReceiveBufferSize = 65536; |
26 | 26 |
27 // Maximum amount of data in the send buffers. This is necessary to | 27 // Maximum amount of data in the send buffers. This is necessary to |
28 // prevent out-of-memory crashes if the caller sends data faster than | 28 // prevent out-of-memory crashes if the caller sends data faster than |
29 // Pepper's UDP API can handle it. This maximum should never be | 29 // Pepper's UDP API can handle it. This maximum should never be |
30 // reached under normal conditions. | 30 // reached under normal conditions. |
31 const int kMaxSendBufferSize = 256 * 1024; | 31 const int kMaxSendBufferSize = 256 * 1024; |
32 | 32 |
33 class UdpPacketSocket : public talk_base::AsyncPacketSocket { | 33 class UdpPacketSocket : public rtc::AsyncPacketSocket { |
34 public: | 34 public: |
35 UdpPacketSocket(); | 35 UdpPacketSocket(); |
36 virtual ~UdpPacketSocket(); | 36 virtual ~UdpPacketSocket(); |
37 | 37 |
38 bool Init(const talk_base::SocketAddress& local_address, | 38 bool Init(const rtc::SocketAddress& local_address, |
39 int min_port, int max_port); | 39 int min_port, int max_port); |
40 | 40 |
41 // talk_base::AsyncPacketSocket interface. | 41 // rtc::AsyncPacketSocket interface. |
42 virtual talk_base::SocketAddress GetLocalAddress() const OVERRIDE; | 42 virtual rtc::SocketAddress GetLocalAddress() const OVERRIDE; |
43 virtual talk_base::SocketAddress GetRemoteAddress() const OVERRIDE; | 43 virtual rtc::SocketAddress GetRemoteAddress() const OVERRIDE; |
44 virtual int Send(const void* data, size_t data_size, | 44 virtual int Send(const void* data, size_t data_size, |
45 const talk_base::PacketOptions& options) OVERRIDE; | 45 const rtc::PacketOptions& options) OVERRIDE; |
46 virtual int SendTo(const void* data, size_t data_size, | 46 virtual int SendTo(const void* data, size_t data_size, |
47 const talk_base::SocketAddress& address, | 47 const rtc::SocketAddress& address, |
48 const talk_base::PacketOptions& options) OVERRIDE; | 48 const rtc::PacketOptions& options) OVERRIDE; |
49 virtual int Close() OVERRIDE; | 49 virtual int Close() OVERRIDE; |
50 virtual State GetState() const OVERRIDE; | 50 virtual State GetState() const OVERRIDE; |
51 virtual int GetOption(talk_base::Socket::Option option, int* value) OVERRIDE; | 51 virtual int GetOption(rtc::Socket::Option option, int* value) OVERRIDE; |
52 virtual int SetOption(talk_base::Socket::Option option, int value) OVERRIDE; | 52 virtual int SetOption(rtc::Socket::Option option, int value) OVERRIDE; |
53 virtual int GetError() const OVERRIDE; | 53 virtual int GetError() const OVERRIDE; |
54 virtual void SetError(int error) OVERRIDE; | 54 virtual void SetError(int error) OVERRIDE; |
55 | 55 |
56 private: | 56 private: |
57 struct PendingPacket { | 57 struct PendingPacket { |
58 PendingPacket(const void* buffer, | 58 PendingPacket(const void* buffer, |
59 int buffer_size, | 59 int buffer_size, |
60 const net::IPEndPoint& address); | 60 const net::IPEndPoint& address); |
61 | 61 |
62 scoped_refptr<net::IOBufferWithSize> data; | 62 scoped_refptr<net::IOBufferWithSize> data; |
63 net::IPEndPoint address; | 63 net::IPEndPoint address; |
64 bool retried; | 64 bool retried; |
65 }; | 65 }; |
66 | 66 |
67 void OnBindCompleted(int error); | 67 void OnBindCompleted(int error); |
68 | 68 |
69 void DoSend(); | 69 void DoSend(); |
70 void OnSendCompleted(int result); | 70 void OnSendCompleted(int result); |
71 | 71 |
72 void DoRead(); | 72 void DoRead(); |
73 void OnReadCompleted(int result); | 73 void OnReadCompleted(int result); |
74 void HandleReadResult(int result); | 74 void HandleReadResult(int result); |
75 | 75 |
76 scoped_ptr<net::UDPServerSocket> socket_; | 76 scoped_ptr<net::UDPServerSocket> socket_; |
77 | 77 |
78 State state_; | 78 State state_; |
79 int error_; | 79 int error_; |
80 | 80 |
81 talk_base::SocketAddress local_address_; | 81 rtc::SocketAddress local_address_; |
82 | 82 |
83 // Receive buffer and address are populated by asynchronous reads. | 83 // Receive buffer and address are populated by asynchronous reads. |
84 scoped_refptr<net::IOBuffer> receive_buffer_; | 84 scoped_refptr<net::IOBuffer> receive_buffer_; |
85 net::IPEndPoint receive_address_; | 85 net::IPEndPoint receive_address_; |
86 | 86 |
87 bool send_pending_; | 87 bool send_pending_; |
88 std::list<PendingPacket> send_queue_; | 88 std::list<PendingPacket> send_queue_; |
89 int send_queue_size_; | 89 int send_queue_size_; |
90 | 90 |
91 DISALLOW_COPY_AND_ASSIGN(UdpPacketSocket); | 91 DISALLOW_COPY_AND_ASSIGN(UdpPacketSocket); |
(...skipping 13 matching lines...) Expand all Loading... |
105 : state_(STATE_CLOSED), | 105 : state_(STATE_CLOSED), |
106 error_(0), | 106 error_(0), |
107 send_pending_(false), | 107 send_pending_(false), |
108 send_queue_size_(0) { | 108 send_queue_size_(0) { |
109 } | 109 } |
110 | 110 |
111 UdpPacketSocket::~UdpPacketSocket() { | 111 UdpPacketSocket::~UdpPacketSocket() { |
112 Close(); | 112 Close(); |
113 } | 113 } |
114 | 114 |
115 bool UdpPacketSocket::Init(const talk_base::SocketAddress& local_address, | 115 bool UdpPacketSocket::Init(const rtc::SocketAddress& local_address, |
116 int min_port, int max_port) { | 116 int min_port, int max_port) { |
117 net::IPEndPoint local_endpoint; | 117 net::IPEndPoint local_endpoint; |
118 if (!jingle_glue::SocketAddressToIPEndPoint( | 118 if (!jingle_glue::SocketAddressToIPEndPoint( |
119 local_address, &local_endpoint)) { | 119 local_address, &local_endpoint)) { |
120 return false; | 120 return false; |
121 } | 121 } |
122 | 122 |
123 for (int port = min_port; port <= max_port; ++port) { | 123 for (int port = min_port; port <= max_port; ++port) { |
124 socket_.reset(new net::UDPServerSocket(NULL, net::NetLog::Source())); | 124 socket_.reset(new net::UDPServerSocket(NULL, net::NetLog::Source())); |
125 int result = socket_->Listen( | 125 int result = socket_->Listen( |
(...skipping 15 matching lines...) Expand all Loading... |
141 &local_address_)) { | 141 &local_address_)) { |
142 return false; | 142 return false; |
143 } | 143 } |
144 | 144 |
145 state_ = STATE_BOUND; | 145 state_ = STATE_BOUND; |
146 DoRead(); | 146 DoRead(); |
147 | 147 |
148 return true; | 148 return true; |
149 } | 149 } |
150 | 150 |
151 talk_base::SocketAddress UdpPacketSocket::GetLocalAddress() const { | 151 rtc::SocketAddress UdpPacketSocket::GetLocalAddress() const { |
152 DCHECK_EQ(state_, STATE_BOUND); | 152 DCHECK_EQ(state_, STATE_BOUND); |
153 return local_address_; | 153 return local_address_; |
154 } | 154 } |
155 | 155 |
156 talk_base::SocketAddress UdpPacketSocket::GetRemoteAddress() const { | 156 rtc::SocketAddress UdpPacketSocket::GetRemoteAddress() const { |
157 // UDP sockets are not connected - this method should never be called. | 157 // UDP sockets are not connected - this method should never be called. |
158 NOTREACHED(); | 158 NOTREACHED(); |
159 return talk_base::SocketAddress(); | 159 return rtc::SocketAddress(); |
160 } | 160 } |
161 | 161 |
162 int UdpPacketSocket::Send(const void* data, size_t data_size, | 162 int UdpPacketSocket::Send(const void* data, size_t data_size, |
163 const talk_base::PacketOptions& options) { | 163 const rtc::PacketOptions& options) { |
164 // UDP sockets are not connected - this method should never be called. | 164 // UDP sockets are not connected - this method should never be called. |
165 NOTREACHED(); | 165 NOTREACHED(); |
166 return EWOULDBLOCK; | 166 return EWOULDBLOCK; |
167 } | 167 } |
168 | 168 |
169 int UdpPacketSocket::SendTo(const void* data, size_t data_size, | 169 int UdpPacketSocket::SendTo(const void* data, size_t data_size, |
170 const talk_base::SocketAddress& address, | 170 const rtc::SocketAddress& address, |
171 const talk_base::PacketOptions& options) { | 171 const rtc::PacketOptions& options) { |
172 if (state_ != STATE_BOUND) { | 172 if (state_ != STATE_BOUND) { |
173 NOTREACHED(); | 173 NOTREACHED(); |
174 return EINVAL; | 174 return EINVAL; |
175 } | 175 } |
176 | 176 |
177 if (error_ != 0) { | 177 if (error_ != 0) { |
178 return error_; | 178 return error_; |
179 } | 179 } |
180 | 180 |
181 net::IPEndPoint endpoint; | 181 net::IPEndPoint endpoint; |
(...skipping 11 matching lines...) Expand all Loading... |
193 DoSend(); | 193 DoSend(); |
194 return data_size; | 194 return data_size; |
195 } | 195 } |
196 | 196 |
197 int UdpPacketSocket::Close() { | 197 int UdpPacketSocket::Close() { |
198 state_ = STATE_CLOSED; | 198 state_ = STATE_CLOSED; |
199 socket_.reset(); | 199 socket_.reset(); |
200 return 0; | 200 return 0; |
201 } | 201 } |
202 | 202 |
203 talk_base::AsyncPacketSocket::State UdpPacketSocket::GetState() const { | 203 rtc::AsyncPacketSocket::State UdpPacketSocket::GetState() const { |
204 return state_; | 204 return state_; |
205 } | 205 } |
206 | 206 |
207 int UdpPacketSocket::GetOption(talk_base::Socket::Option option, int* value) { | 207 int UdpPacketSocket::GetOption(rtc::Socket::Option option, int* value) { |
208 // This method is never called by libjingle. | 208 // This method is never called by libjingle. |
209 NOTIMPLEMENTED(); | 209 NOTIMPLEMENTED(); |
210 return -1; | 210 return -1; |
211 } | 211 } |
212 | 212 |
213 int UdpPacketSocket::SetOption(talk_base::Socket::Option option, int value) { | 213 int UdpPacketSocket::SetOption(rtc::Socket::Option option, int value) { |
214 if (state_ != STATE_BOUND) { | 214 if (state_ != STATE_BOUND) { |
215 NOTREACHED(); | 215 NOTREACHED(); |
216 return EINVAL; | 216 return EINVAL; |
217 } | 217 } |
218 | 218 |
219 switch (option) { | 219 switch (option) { |
220 case talk_base::Socket::OPT_DONTFRAGMENT: | 220 case rtc::Socket::OPT_DONTFRAGMENT: |
221 NOTIMPLEMENTED(); | 221 NOTIMPLEMENTED(); |
222 return -1; | 222 return -1; |
223 | 223 |
224 case talk_base::Socket::OPT_RCVBUF: { | 224 case rtc::Socket::OPT_RCVBUF: { |
225 int net_error = socket_->SetReceiveBufferSize(value); | 225 int net_error = socket_->SetReceiveBufferSize(value); |
226 return (net_error == net::OK) ? 0 : -1; | 226 return (net_error == net::OK) ? 0 : -1; |
227 } | 227 } |
228 | 228 |
229 case talk_base::Socket::OPT_SNDBUF: { | 229 case rtc::Socket::OPT_SNDBUF: { |
230 int net_error = socket_->SetSendBufferSize(value); | 230 int net_error = socket_->SetSendBufferSize(value); |
231 return (net_error == net::OK) ? 0 : -1; | 231 return (net_error == net::OK) ? 0 : -1; |
232 } | 232 } |
233 | 233 |
234 case talk_base::Socket::OPT_NODELAY: | 234 case rtc::Socket::OPT_NODELAY: |
235 // OPT_NODELAY is only for TCP sockets. | 235 // OPT_NODELAY is only for TCP sockets. |
236 NOTREACHED(); | 236 NOTREACHED(); |
237 return -1; | 237 return -1; |
238 | 238 |
239 case talk_base::Socket::OPT_IPV6_V6ONLY: | 239 case rtc::Socket::OPT_IPV6_V6ONLY: |
240 NOTIMPLEMENTED(); | 240 NOTIMPLEMENTED(); |
241 return -1; | 241 return -1; |
242 | 242 |
243 case talk_base::Socket::OPT_DSCP: | 243 case rtc::Socket::OPT_DSCP: |
244 NOTIMPLEMENTED(); | 244 NOTIMPLEMENTED(); |
245 return -1; | 245 return -1; |
246 | 246 |
247 case talk_base::Socket::OPT_RTP_SENDTIME_EXTN_ID: | 247 case rtc::Socket::OPT_RTP_SENDTIME_EXTN_ID: |
248 NOTIMPLEMENTED(); | 248 NOTIMPLEMENTED(); |
249 return -1; | 249 return -1; |
250 } | 250 } |
251 | 251 |
252 NOTREACHED(); | 252 NOTREACHED(); |
253 return -1; | 253 return -1; |
254 } | 254 } |
255 | 255 |
256 int UdpPacketSocket::GetError() const { | 256 int UdpPacketSocket::GetError() const { |
257 return error_; | 257 return error_; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 DoRead(); | 329 DoRead(); |
330 } | 330 } |
331 } | 331 } |
332 | 332 |
333 void UdpPacketSocket::HandleReadResult(int result) { | 333 void UdpPacketSocket::HandleReadResult(int result) { |
334 if (result == net::ERR_IO_PENDING) { | 334 if (result == net::ERR_IO_PENDING) { |
335 return; | 335 return; |
336 } | 336 } |
337 | 337 |
338 if (result > 0) { | 338 if (result > 0) { |
339 talk_base::SocketAddress address; | 339 rtc::SocketAddress address; |
340 if (!jingle_glue::IPEndPointToSocketAddress(receive_address_, &address)) { | 340 if (!jingle_glue::IPEndPointToSocketAddress(receive_address_, &address)) { |
341 NOTREACHED(); | 341 NOTREACHED(); |
342 LOG(ERROR) << "Failed to convert address received from RecvFrom()."; | 342 LOG(ERROR) << "Failed to convert address received from RecvFrom()."; |
343 return; | 343 return; |
344 } | 344 } |
345 SignalReadPacket(this, receive_buffer_->data(), result, address, | 345 SignalReadPacket(this, receive_buffer_->data(), result, address, |
346 talk_base::CreatePacketTime(0)); | 346 rtc::CreatePacketTime(0)); |
347 } else { | 347 } else { |
348 LOG(ERROR) << "Received error when reading from UDP socket: " << result; | 348 LOG(ERROR) << "Received error when reading from UDP socket: " << result; |
349 } | 349 } |
350 } | 350 } |
351 | 351 |
352 } // namespace | 352 } // namespace |
353 | 353 |
354 ChromiumPacketSocketFactory::ChromiumPacketSocketFactory() { | 354 ChromiumPacketSocketFactory::ChromiumPacketSocketFactory() { |
355 } | 355 } |
356 | 356 |
357 ChromiumPacketSocketFactory::~ChromiumPacketSocketFactory() { | 357 ChromiumPacketSocketFactory::~ChromiumPacketSocketFactory() { |
358 } | 358 } |
359 | 359 |
360 talk_base::AsyncPacketSocket* ChromiumPacketSocketFactory::CreateUdpSocket( | 360 rtc::AsyncPacketSocket* ChromiumPacketSocketFactory::CreateUdpSocket( |
361 const talk_base::SocketAddress& local_address, | 361 const rtc::SocketAddress& local_address, |
362 int min_port, int max_port) { | 362 int min_port, int max_port) { |
363 scoped_ptr<UdpPacketSocket> result(new UdpPacketSocket()); | 363 scoped_ptr<UdpPacketSocket> result(new UdpPacketSocket()); |
364 if (!result->Init(local_address, min_port, max_port)) | 364 if (!result->Init(local_address, min_port, max_port)) |
365 return NULL; | 365 return NULL; |
366 return result.release(); | 366 return result.release(); |
367 } | 367 } |
368 | 368 |
369 talk_base::AsyncPacketSocket* | 369 rtc::AsyncPacketSocket* |
370 ChromiumPacketSocketFactory::CreateServerTcpSocket( | 370 ChromiumPacketSocketFactory::CreateServerTcpSocket( |
371 const talk_base::SocketAddress& local_address, | 371 const rtc::SocketAddress& local_address, |
372 int min_port, int max_port, | 372 int min_port, int max_port, |
373 int opts) { | 373 int opts) { |
374 // We don't use TCP sockets for remoting connections. | 374 // We don't use TCP sockets for remoting connections. |
375 NOTIMPLEMENTED(); | 375 NOTIMPLEMENTED(); |
376 return NULL; | 376 return NULL; |
377 } | 377 } |
378 | 378 |
379 talk_base::AsyncPacketSocket* | 379 rtc::AsyncPacketSocket* |
380 ChromiumPacketSocketFactory::CreateClientTcpSocket( | 380 ChromiumPacketSocketFactory::CreateClientTcpSocket( |
381 const talk_base::SocketAddress& local_address, | 381 const rtc::SocketAddress& local_address, |
382 const talk_base::SocketAddress& remote_address, | 382 const rtc::SocketAddress& remote_address, |
383 const talk_base::ProxyInfo& proxy_info, | 383 const rtc::ProxyInfo& proxy_info, |
384 const std::string& user_agent, | 384 const std::string& user_agent, |
385 int opts) { | 385 int opts) { |
386 // We don't use TCP sockets for remoting connections. | 386 // We don't use TCP sockets for remoting connections. |
387 NOTREACHED(); | 387 NOTREACHED(); |
388 return NULL; | 388 return NULL; |
389 } | 389 } |
390 | 390 |
391 talk_base::AsyncResolverInterface* | 391 rtc::AsyncResolverInterface* |
392 ChromiumPacketSocketFactory::CreateAsyncResolver() { | 392 ChromiumPacketSocketFactory::CreateAsyncResolver() { |
393 return new talk_base::AsyncResolver(); | 393 return new rtc::AsyncResolver(); |
394 } | 394 } |
395 | 395 |
396 } // namespace protocol | 396 } // namespace protocol |
397 } // namespace remoting | 397 } // namespace remoting |
OLD | NEW |