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