OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/renderer_host/pepper/pepper_udp_socket.h" | 5 #include "content/browser/renderer_host/pepper/pepper_udp_socket.h" |
6 | 6 |
7 #include <string.h> | |
8 | |
9 #include "base/compiler_specific.h" | |
10 #include "base/logging.h" | 7 #include "base/logging.h" |
11 #include "content/browser/renderer_host/pepper/pepper_message_filter.h" | 8 #include "content/browser/renderer_host/pepper/pepper_message_filter.h" |
12 #include "content/public/browser/browser_thread.h" | 9 #include "ppapi/c/private/ppb_net_address_private.h" |
13 #include "net/base/io_buffer.h" | |
14 #include "net/base/net_errors.h" | |
15 #include "net/udp/udp_server_socket.h" | |
16 #include "ppapi/proxy/ppapi_messages.h" | 10 #include "ppapi/proxy/ppapi_messages.h" |
17 #include "ppapi/shared_impl/private/net_address_private_impl.h" | |
18 | |
19 using ppapi::NetAddressPrivateImpl; | |
20 | 11 |
21 namespace content { | 12 namespace content { |
22 | 13 |
23 PepperUDPSocket::PepperUDPSocket( | 14 PepperUDPSocket::PepperUDPSocket( |
24 PepperMessageFilter* manager, | 15 PepperMessageFilter* manager, |
25 int32 routing_id, | 16 int32 routing_id, |
26 uint32 plugin_dispatcher_id, | 17 uint32 plugin_dispatcher_id, |
27 uint32 socket_id) | 18 uint32 socket_id) |
28 : manager_(manager), | 19 : manager_(manager), |
29 routing_id_(routing_id), | 20 routing_id_(routing_id), |
30 plugin_dispatcher_id_(plugin_dispatcher_id), | 21 plugin_dispatcher_id_(plugin_dispatcher_id), |
31 socket_id_(socket_id), | 22 socket_id_(socket_id) { |
32 allow_address_reuse_(false), | |
33 allow_broadcast_(false) { | |
34 DCHECK(manager); | 23 DCHECK(manager); |
35 } | 24 } |
36 | 25 |
37 PepperUDPSocket::~PepperUDPSocket() { | 26 PepperUDPSocket::~PepperUDPSocket() { |
38 // Make sure there are no further callbacks from socket_. | |
39 if (socket_.get()) | |
40 socket_->Close(); | |
41 } | 27 } |
42 | 28 |
43 void PepperUDPSocket::AllowAddressReuse(bool value) { | 29 void PepperUDPSocket::SendBindReply(bool succeeded, |
44 allow_address_reuse_ = value; | 30 const PP_NetAddress_Private& addr) { |
| 31 manager_->Send(new PpapiMsg_PPBUDPSocket_BindACK( |
| 32 routing_id_, plugin_dispatcher_id_, socket_id_, succeeded, addr)); |
45 } | 33 } |
46 | 34 |
47 void PepperUDPSocket::AllowBroadcast(bool value) { | 35 void PepperUDPSocket::SendSendToReply(bool succeeded, int32_t bytes_written) { |
48 allow_broadcast_ = value; | 36 manager_->Send(new PpapiMsg_PPBUDPSocket_SendToACK( |
| 37 routing_id_, plugin_dispatcher_id_, socket_id_, |
| 38 succeeded, bytes_written)); |
49 } | 39 } |
50 | 40 |
51 void PepperUDPSocket::Bind(const PP_NetAddress_Private& addr) { | 41 void PepperUDPSocket::SendRecvFromReply(bool succeeded, |
52 socket_.reset(new net::UDPServerSocket(NULL, net::NetLog::Source())); | 42 const std::string& data, |
53 | 43 const PP_NetAddress_Private& addr) { |
54 net::IPAddressNumber address; | |
55 int port; | |
56 if (!socket_.get() || | |
57 !NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) { | |
58 SendBindACKError(); | |
59 return; | |
60 } | |
61 | |
62 if (allow_address_reuse_) | |
63 socket_->AllowAddressReuse(); | |
64 if (allow_broadcast_) | |
65 socket_->AllowBroadcast(); | |
66 | |
67 int result = socket_->Listen(net::IPEndPoint(address, port)); | |
68 | |
69 if (result == net::OK && | |
70 socket_->GetLocalAddress(&bound_address_) != net::OK) { | |
71 SendBindACKError(); | |
72 return; | |
73 } | |
74 | |
75 OnBindCompleted(result); | |
76 } | |
77 | |
78 void PepperUDPSocket::RecvFrom(int32_t num_bytes) { | |
79 if (recvfrom_buffer_.get()) { | |
80 SendRecvFromACKError(); | |
81 return; | |
82 } | |
83 | |
84 recvfrom_buffer_ = new net::IOBuffer(num_bytes); | |
85 int result = socket_->RecvFrom( | |
86 recvfrom_buffer_, num_bytes, &recvfrom_address_, | |
87 base::Bind(&PepperUDPSocket::OnRecvFromCompleted, | |
88 base::Unretained(this))); | |
89 | |
90 if (result != net::ERR_IO_PENDING) | |
91 OnRecvFromCompleted(result); | |
92 } | |
93 | |
94 void PepperUDPSocket::SendTo(const std::string& data, | |
95 const PP_NetAddress_Private& addr) { | |
96 if (sendto_buffer_.get() || data.empty()) { | |
97 SendSendToACKError(); | |
98 return; | |
99 } | |
100 | |
101 net::IPAddressNumber address; | |
102 int port; | |
103 if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) { | |
104 SendSendToACKError(); | |
105 return; | |
106 } | |
107 | |
108 int data_size = data.size(); | |
109 | |
110 sendto_buffer_ = new net::IOBuffer(data_size); | |
111 memcpy(sendto_buffer_->data(), data.data(), data_size); | |
112 int result = socket_->SendTo( | |
113 sendto_buffer_, data_size, net::IPEndPoint(address, port), | |
114 base::Bind(&PepperUDPSocket::OnSendToCompleted, base::Unretained(this))); | |
115 | |
116 if (result != net::ERR_IO_PENDING) | |
117 OnSendToCompleted(result); | |
118 } | |
119 | |
120 void PepperUDPSocket::SendRecvFromACKError() { | |
121 PP_NetAddress_Private addr = NetAddressPrivateImpl::kInvalidNetAddress; | |
122 manager_->Send(new PpapiMsg_PPBUDPSocket_RecvFromACK( | 44 manager_->Send(new PpapiMsg_PPBUDPSocket_RecvFromACK( |
123 routing_id_, plugin_dispatcher_id_, socket_id_, false, std::string(), | 45 routing_id_, plugin_dispatcher_id_, socket_id_, succeeded, data, addr)); |
124 addr)); | |
125 } | |
126 | |
127 void PepperUDPSocket::SendSendToACKError() { | |
128 manager_->Send(new PpapiMsg_PPBUDPSocket_SendToACK( | |
129 routing_id_, plugin_dispatcher_id_, socket_id_, false, 0)); | |
130 } | |
131 | |
132 void PepperUDPSocket::SendBindACKError() { | |
133 PP_NetAddress_Private addr = NetAddressPrivateImpl::kInvalidNetAddress; | |
134 manager_->Send(new PpapiMsg_PPBUDPSocket_BindACK( | |
135 routing_id_, plugin_dispatcher_id_, socket_id_, false, addr)); | |
136 } | |
137 | |
138 void PepperUDPSocket::OnBindCompleted(int result) { | |
139 PP_NetAddress_Private addr = NetAddressPrivateImpl::kInvalidNetAddress; | |
140 if (result < 0 || | |
141 !NetAddressPrivateImpl::IPEndPointToNetAddress(bound_address_.address(), | |
142 bound_address_.port(), | |
143 &addr)) { | |
144 SendBindACKError(); | |
145 } else { | |
146 manager_->Send(new PpapiMsg_PPBUDPSocket_BindACK( | |
147 routing_id_, plugin_dispatcher_id_, socket_id_, true, addr)); | |
148 } | |
149 } | |
150 | |
151 void PepperUDPSocket::OnRecvFromCompleted(int result) { | |
152 DCHECK(recvfrom_buffer_.get()); | |
153 | |
154 // Convert IPEndPoint we get back from RecvFrom to a PP_NetAddress_Private, | |
155 // to send back. | |
156 PP_NetAddress_Private addr = NetAddressPrivateImpl::kInvalidNetAddress; | |
157 if (result < 0 || | |
158 !NetAddressPrivateImpl::IPEndPointToNetAddress( | |
159 recvfrom_address_.address(), | |
160 recvfrom_address_.port(), | |
161 &addr)) { | |
162 SendRecvFromACKError(); | |
163 } else { | |
164 manager_->Send(new PpapiMsg_PPBUDPSocket_RecvFromACK( | |
165 routing_id_, plugin_dispatcher_id_, socket_id_, true, | |
166 std::string(recvfrom_buffer_->data(), result), addr)); | |
167 } | |
168 | |
169 recvfrom_buffer_ = NULL; | |
170 } | |
171 | |
172 void PepperUDPSocket::OnSendToCompleted(int result) { | |
173 DCHECK(sendto_buffer_.get()); | |
174 | |
175 if (result < 0) { | |
176 SendSendToACKError(); | |
177 } else { | |
178 manager_->Send(new PpapiMsg_PPBUDPSocket_SendToACK( | |
179 routing_id_, plugin_dispatcher_id_, socket_id_, true, result)); | |
180 } | |
181 | |
182 sendto_buffer_ = NULL; | |
183 } | 46 } |
184 | 47 |
185 } // namespace content | 48 } // namespace content |
OLD | NEW |