Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(410)

Side by Side Diff: chrome/browser/extensions/api/socket/udp_socket.cc

Issue 183893041: Move sockets APIs out of src/chrome (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: little things Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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 "chrome/browser/extensions/api/socket/udp_socket.h"
6
7 #include <algorithm>
8
9 #include "chrome/browser/extensions/api/api_resource.h"
10 #include "net/base/ip_endpoint.h"
11 #include "net/base/net_errors.h"
12 #include "net/udp/datagram_socket.h"
13 #include "net/udp/udp_client_socket.h"
14
15 namespace extensions {
16
17 static base::LazyInstance<
18 BrowserContextKeyedAPIFactory<ApiResourceManager<ResumableUDPSocket> > >
19 g_factory = LAZY_INSTANCE_INITIALIZER;
20
21 // static
22 template <>
23 BrowserContextKeyedAPIFactory<ApiResourceManager<ResumableUDPSocket> >*
24 ApiResourceManager<ResumableUDPSocket>::GetFactoryInstance() {
25 return g_factory.Pointer();
26 }
27
28 UDPSocket::UDPSocket(const std::string& owner_extension_id)
29 : Socket(owner_extension_id),
30 socket_(net::DatagramSocket::DEFAULT_BIND,
31 net::RandIntCallback(),
32 NULL,
33 net::NetLog::Source()) {
34 }
35
36 UDPSocket::~UDPSocket() {
37 Disconnect();
38 }
39
40 void UDPSocket::Connect(const std::string& address,
41 int port,
42 const CompletionCallback& callback) {
43 int result = net::ERR_CONNECTION_FAILED;
44 do {
45 if (is_connected_)
46 break;
47
48 net::IPEndPoint ip_end_point;
49 if (!StringAndPortToIPEndPoint(address, port, &ip_end_point)) {
50 result = net::ERR_ADDRESS_INVALID;
51 break;
52 }
53
54 result = socket_.Connect(ip_end_point);
55 is_connected_ = (result == net::OK);
56 } while (false);
57
58 callback.Run(result);
59 }
60
61 int UDPSocket::Bind(const std::string& address, int port) {
62 if (IsBound())
63 return net::ERR_CONNECTION_FAILED;
64
65 net::IPEndPoint ip_end_point;
66 if (!StringAndPortToIPEndPoint(address, port, &ip_end_point))
67 return net::ERR_INVALID_ARGUMENT;
68
69 return socket_.Bind(ip_end_point);
70 }
71
72 void UDPSocket::Disconnect() {
73 is_connected_ = false;
74 socket_.Close();
75 read_callback_.Reset();
76 recv_from_callback_.Reset();
77 send_to_callback_.Reset();
78 multicast_groups_.clear();
79 }
80
81 void UDPSocket::Read(int count,
82 const ReadCompletionCallback& callback) {
83 DCHECK(!callback.is_null());
84
85 if (!read_callback_.is_null()) {
86 callback.Run(net::ERR_IO_PENDING, NULL);
87 return;
88 } else {
89 read_callback_ = callback;
90 }
91
92 int result = net::ERR_FAILED;
93 scoped_refptr<net::IOBuffer> io_buffer;
94 do {
95 if (count < 0) {
96 result = net::ERR_INVALID_ARGUMENT;
97 break;
98 }
99
100 if (!socket_.is_connected()) {
101 result = net::ERR_SOCKET_NOT_CONNECTED;
102 break;
103 }
104
105 io_buffer = new net::IOBuffer(count);
106 result = socket_.Read(io_buffer.get(), count,
107 base::Bind(&UDPSocket::OnReadComplete, base::Unretained(this),
108 io_buffer));
109 } while (false);
110
111 if (result != net::ERR_IO_PENDING)
112 OnReadComplete(io_buffer, result);
113 }
114
115 int UDPSocket::WriteImpl(net::IOBuffer* io_buffer,
116 int io_buffer_size,
117 const net::CompletionCallback& callback) {
118 if (!socket_.is_connected())
119 return net::ERR_SOCKET_NOT_CONNECTED;
120 else
121 return socket_.Write(io_buffer, io_buffer_size, callback);
122 }
123
124 void UDPSocket::RecvFrom(int count,
125 const RecvFromCompletionCallback& callback) {
126 DCHECK(!callback.is_null());
127
128 if (!recv_from_callback_.is_null()) {
129 callback.Run(net::ERR_IO_PENDING, NULL, std::string(), 0);
130 return;
131 } else {
132 recv_from_callback_ = callback;
133 }
134
135 int result = net::ERR_FAILED;
136 scoped_refptr<net::IOBuffer> io_buffer;
137 scoped_refptr<IPEndPoint> address;
138 do {
139 if (count < 0) {
140 result = net::ERR_INVALID_ARGUMENT;
141 break;
142 }
143
144 if (!socket_.is_connected()) {
145 result = net::ERR_SOCKET_NOT_CONNECTED;
146 break;
147 }
148
149 io_buffer = new net::IOBuffer(count);
150 address = new IPEndPoint();
151 result = socket_.RecvFrom(
152 io_buffer.get(),
153 count,
154 &address->data,
155 base::Bind(&UDPSocket::OnRecvFromComplete,
156 base::Unretained(this),
157 io_buffer,
158 address));
159 } while (false);
160
161 if (result != net::ERR_IO_PENDING)
162 OnRecvFromComplete(io_buffer, address, result);
163 }
164
165 void UDPSocket::SendTo(scoped_refptr<net::IOBuffer> io_buffer,
166 int byte_count,
167 const std::string& address,
168 int port,
169 const CompletionCallback& callback) {
170 DCHECK(!callback.is_null());
171
172 if (!send_to_callback_.is_null()) {
173 // TODO(penghuang): Put requests in a pending queue to support multiple
174 // sendTo calls.
175 callback.Run(net::ERR_IO_PENDING);
176 return;
177 } else {
178 send_to_callback_ = callback;
179 }
180
181 int result = net::ERR_FAILED;
182 do {
183 net::IPEndPoint ip_end_point;
184 if (!StringAndPortToIPEndPoint(address, port, &ip_end_point)) {
185 result = net::ERR_ADDRESS_INVALID;
186 break;
187 }
188
189 if (!socket_.is_connected()) {
190 result = net::ERR_SOCKET_NOT_CONNECTED;
191 break;
192 }
193
194 result = socket_.SendTo(
195 io_buffer.get(),
196 byte_count,
197 ip_end_point,
198 base::Bind(&UDPSocket::OnSendToComplete, base::Unretained(this)));
199 } while (false);
200
201 if (result != net::ERR_IO_PENDING)
202 OnSendToComplete(result);
203 }
204
205 bool UDPSocket::IsConnected() {
206 return is_connected_;
207 }
208
209 bool UDPSocket::GetPeerAddress(net::IPEndPoint* address) {
210 return !socket_.GetPeerAddress(address);
211 }
212
213 bool UDPSocket::GetLocalAddress(net::IPEndPoint* address) {
214 return !socket_.GetLocalAddress(address);
215 }
216
217 Socket::SocketType UDPSocket::GetSocketType() const {
218 return Socket::TYPE_UDP;
219 }
220
221 void UDPSocket::OnReadComplete(scoped_refptr<net::IOBuffer> io_buffer,
222 int result) {
223 DCHECK(!read_callback_.is_null());
224 read_callback_.Run(result, io_buffer);
225 read_callback_.Reset();
226 }
227
228 void UDPSocket::OnRecvFromComplete(scoped_refptr<net::IOBuffer> io_buffer,
229 scoped_refptr<IPEndPoint> address,
230 int result) {
231 DCHECK(!recv_from_callback_.is_null());
232 std::string ip;
233 int port = 0;
234 if (result > 0 && address.get()) {
235 IPEndPointToStringAndPort(address->data, &ip, &port);
236 }
237 recv_from_callback_.Run(result, io_buffer, ip, port);
238 recv_from_callback_.Reset();
239 }
240
241 void UDPSocket::OnSendToComplete(int result) {
242 DCHECK(!send_to_callback_.is_null());
243 send_to_callback_.Run(result);
244 send_to_callback_.Reset();
245 }
246
247 bool UDPSocket::IsBound() {
248 return socket_.is_connected();
249 }
250
251 int UDPSocket::JoinGroup(const std::string& address) {
252 net::IPAddressNumber ip;
253 if (!net::ParseIPLiteralToNumber(address, &ip))
254 return net::ERR_ADDRESS_INVALID;
255
256 std::string normalized_address = net::IPAddressToString(ip);
257 std::vector<std::string>::iterator find_result =
258 std::find(multicast_groups_.begin(),
259 multicast_groups_.end(),
260 normalized_address);
261 if (find_result != multicast_groups_.end())
262 return net::ERR_ADDRESS_INVALID;
263
264 int rv = socket_.JoinGroup(ip);
265 if (rv == 0)
266 multicast_groups_.push_back(normalized_address);
267 return rv;
268 }
269
270 int UDPSocket::LeaveGroup(const std::string& address) {
271 net::IPAddressNumber ip;
272 if (!net::ParseIPLiteralToNumber(address, &ip))
273 return net::ERR_ADDRESS_INVALID;
274
275 std::string normalized_address = net::IPAddressToString(ip);
276 std::vector<std::string>::iterator find_result =
277 std::find(multicast_groups_.begin(),
278 multicast_groups_.end(),
279 normalized_address);
280 if (find_result == multicast_groups_.end())
281 return net::ERR_ADDRESS_INVALID;
282
283 int rv = socket_.LeaveGroup(ip);
284 if (rv == 0)
285 multicast_groups_.erase(find_result);
286 return rv;
287 }
288
289 int UDPSocket::SetMulticastTimeToLive(int ttl) {
290 return socket_.SetMulticastTimeToLive(ttl);
291 }
292
293 int UDPSocket::SetMulticastLoopbackMode(bool loopback) {
294 return socket_.SetMulticastLoopbackMode(loopback);
295 }
296
297 const std::vector<std::string>& UDPSocket::GetJoinedGroups() const {
298 return multicast_groups_;
299 }
300
301 ResumableUDPSocket::ResumableUDPSocket(const std::string& owner_extension_id)
302 : UDPSocket(owner_extension_id),
303 persistent_(false),
304 buffer_size_(0),
305 paused_(false) {
306 }
307
308 bool ResumableUDPSocket::IsPersistent() const {
309 return persistent();
310 }
311
312 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698