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

Side by Side Diff: runtime/bin/socket_base_fuchsia.cc

Issue 2797993005: Re-land socket refactor with fixes for Windows. (Closed)
Patch Set: Rebased + reverted original revert Created 3 years, 8 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
« no previous file with comments | « runtime/bin/socket_base_fuchsia.h ('k') | runtime/bin/socket_base_linux.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 #if !defined(DART_IO_DISABLED)
6
7 #include "platform/globals.h"
8 #if defined(HOST_OS_FUCHSIA)
9
10 #include "bin/socket_base.h"
11
12 #include <errno.h> // NOLINT
13 #include <fcntl.h> // NOLINT
14 #include <ifaddrs.h> // NOLINT
15 #include <net/if.h> // NOLINT
16 #include <netinet/tcp.h> // NOLINT
17 #include <stdio.h> // NOLINT
18 #include <stdlib.h> // NOLINT
19 #include <string.h> // NOLINT
20 #include <sys/ioctl.h> // NOLINT
21 #include <sys/stat.h> // NOLINT
22 #include <unistd.h> // NOLINT
23
24 #include "bin/fdutils.h"
25 #include "bin/file.h"
26 #include "bin/socket_base_fuchsia.h"
27 #include "platform/signal_blocker.h"
28
29 // #define SOCKET_LOG_INFO 1
30 // #define SOCKET_LOG_ERROR 1
31
32 // define SOCKET_LOG_ERROR to get log messages only for errors.
33 // define SOCKET_LOG_INFO to get log messages for both information and errors.
34 #if defined(SOCKET_LOG_INFO) || defined(SOCKET_LOG_ERROR)
35 #define LOG_ERR(msg, ...) \
36 { \
37 int err = errno; \
38 Log::PrintErr("Dart Socket ERROR: %s:%d: " msg, __FILE__, __LINE__, \
39 ##__VA_ARGS__); \
40 errno = err; \
41 }
42 #if defined(SOCKET_LOG_INFO)
43 #define LOG_INFO(msg, ...) \
44 Log::Print("Dart Socket INFO: %s:%d: " msg, __FILE__, __LINE__, ##__VA_ARGS__)
45 #else
46 #define LOG_INFO(msg, ...)
47 #endif // defined(SOCKET_LOG_INFO)
48 #else
49 #define LOG_ERR(msg, ...)
50 #define LOG_INFO(msg, ...)
51 #endif // defined(SOCKET_LOG_INFO) || defined(SOCKET_LOG_ERROR)
52
53 namespace dart {
54 namespace bin {
55
56 SocketAddress::SocketAddress(struct sockaddr* sa) {
57 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
58 if (!SocketBase::FormatNumericAddress(*reinterpret_cast<RawAddr*>(sa),
59 as_string_, INET6_ADDRSTRLEN)) {
60 as_string_[0] = 0;
61 }
62 socklen_t salen = GetAddrLength(*reinterpret_cast<RawAddr*>(sa));
63 memmove(reinterpret_cast<void*>(&addr_), sa, salen);
64 }
65
66
67 bool SocketBase::Initialize() {
68 // Nothing to do on Fuchsia.
69 return true;
70 }
71
72
73 bool SocketBase::FormatNumericAddress(const RawAddr& addr,
74 char* address,
75 int len) {
76 socklen_t salen = SocketAddress::GetAddrLength(addr);
77 LOG_INFO("SocketBase::FormatNumericAddress: calling getnameinfo\n");
78 return (NO_RETRY_EXPECTED(getnameinfo(&addr.addr, salen, address, len, NULL,
79 0, NI_NUMERICHOST) == 0));
80 }
81
82
83 bool SocketBase::IsBindError(intptr_t error_number) {
84 return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL ||
85 error_number == EINVAL;
86 }
87
88
89 intptr_t SocketBase::Available(intptr_t fd) {
90 intptr_t available = FDUtils::AvailableBytes(fd);
91 LOG_INFO("SocketBase::Available(%ld) = %ld\n", fd, available);
92 return available;
93 }
94
95
96 intptr_t SocketBase::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
97 ASSERT(fd >= 0);
98 LOG_INFO("SocketBase::Read: calling read(%ld, %p, %ld)\n", fd, buffer,
99 num_bytes);
100 ssize_t read_bytes = NO_RETRY_EXPECTED(read(fd, buffer, num_bytes));
101 ASSERT(EAGAIN == EWOULDBLOCK);
102 if ((read_bytes == -1) && (errno == EWOULDBLOCK)) {
103 // If the read would block we need to retry and therefore return 0
104 // as the number of bytes written.
105 read_bytes = 0;
106 } else if (read_bytes == -1) {
107 LOG_ERR("SocketBase::Read: read(%ld, %p, %ld) failed\n", fd, buffer,
108 num_bytes);
109 } else {
110 LOG_INFO("SocketBase::Read: read(%ld, %p, %ld) succeeded\n", fd, buffer,
111 num_bytes);
112 }
113 return read_bytes;
114 }
115
116
117 intptr_t SocketBase::RecvFrom(intptr_t fd,
118 void* buffer,
119 intptr_t num_bytes,
120 RawAddr* addr) {
121 LOG_ERR("SocketBase::RecvFrom is unimplemented\n");
122 UNIMPLEMENTED();
123 return -1;
124 }
125
126
127 intptr_t SocketBase::Write(intptr_t fd,
128 const void* buffer,
129 intptr_t num_bytes) {
130 ASSERT(fd >= 0);
131 LOG_INFO("SocketBase::Write: calling write(%ld, %p, %ld)\n", fd, buffer,
132 num_bytes);
133 ssize_t written_bytes = NO_RETRY_EXPECTED(write(fd, buffer, num_bytes));
134 ASSERT(EAGAIN == EWOULDBLOCK);
135 if ((written_bytes == -1) && (errno == EWOULDBLOCK)) {
136 // If the would block we need to retry and therefore return 0 as
137 // the number of bytes written.
138 written_bytes = 0;
139 } else if (written_bytes == -1) {
140 LOG_ERR("SocketBase::Write: write(%ld, %p, %ld) failed\n", fd, buffer,
141 num_bytes);
142 } else {
143 LOG_INFO("SocketBase::Write: write(%ld, %p, %ld) succeeded\n", fd, buffer,
144 num_bytes);
145 }
146 return written_bytes;
147 }
148
149
150 intptr_t SocketBase::SendTo(intptr_t fd,
151 const void* buffer,
152 intptr_t num_bytes,
153 const RawAddr& addr) {
154 LOG_ERR("SocketBase::SendTo is unimplemented\n");
155 UNIMPLEMENTED();
156 return -1;
157 }
158
159
160 intptr_t SocketBase::GetPort(intptr_t fd) {
161 ASSERT(fd >= 0);
162 RawAddr raw;
163 socklen_t size = sizeof(raw);
164 LOG_INFO("SocketBase::GetPort: calling getsockname(%ld)\n", fd);
165 if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) {
166 return 0;
167 }
168 return SocketAddress::GetAddrPort(raw);
169 }
170
171
172 SocketAddress* SocketBase::GetRemotePeer(intptr_t fd, intptr_t* port) {
173 ASSERT(fd >= 0);
174 RawAddr raw;
175 socklen_t size = sizeof(raw);
176 if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) {
177 return NULL;
178 }
179 *port = SocketAddress::GetAddrPort(raw);
180 return new SocketAddress(&raw.addr);
181 }
182
183
184 void SocketBase::GetError(intptr_t fd, OSError* os_error) {
185 LOG_ERR("SocketBase::GetError is unimplemented\n");
186 UNIMPLEMENTED();
187 }
188
189
190 int SocketBase::GetType(intptr_t fd) {
191 LOG_ERR("SocketBase::GetType is unimplemented\n");
192 UNIMPLEMENTED();
193 return File::kOther;
194 }
195
196
197 intptr_t SocketBase::GetStdioHandle(intptr_t num) {
198 LOG_ERR("SocketBase::GetStdioHandle is unimplemented\n");
199 UNIMPLEMENTED();
200 return num;
201 }
202
203
204 AddressList<SocketAddress>* SocketBase::LookupAddress(const char* host,
205 int type,
206 OSError** os_error) {
207 // Perform a name lookup for a host name.
208 struct addrinfo hints;
209 memset(&hints, 0, sizeof(hints));
210 hints.ai_family = SocketAddress::FromType(type);
211 hints.ai_socktype = SOCK_STREAM;
212 hints.ai_flags = AI_ADDRCONFIG;
213 hints.ai_protocol = IPPROTO_TCP;
214 struct addrinfo* info = NULL;
215 LOG_INFO("SocketBase::LookupAddress: calling getaddrinfo\n");
216 int status = NO_RETRY_EXPECTED(getaddrinfo(host, 0, &hints, &info));
217 if (status != 0) {
218 // We failed, try without AI_ADDRCONFIG. This can happen when looking up
219 // e.g. '::1', when there are no global IPv6 addresses.
220 hints.ai_flags = 0;
221 LOG_INFO("SocketBase::LookupAddress: calling getaddrinfo again\n");
222 status = NO_RETRY_EXPECTED(getaddrinfo(host, 0, &hints, &info));
223 if (status != 0) {
224 ASSERT(*os_error == NULL);
225 *os_error =
226 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo);
227 return NULL;
228 }
229 }
230 intptr_t count = 0;
231 for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
232 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) {
233 count++;
234 }
235 }
236 intptr_t i = 0;
237 AddressList<SocketAddress>* addresses = new AddressList<SocketAddress>(count);
238 for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
239 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) {
240 addresses->SetAt(i, new SocketAddress(c->ai_addr));
241 i++;
242 }
243 }
244 freeaddrinfo(info);
245 return addresses;
246 }
247
248
249 bool SocketBase::ReverseLookup(const RawAddr& addr,
250 char* host,
251 intptr_t host_len,
252 OSError** os_error) {
253 LOG_ERR("SocketBase::ReverseLookup is unimplemented\n");
254 UNIMPLEMENTED();
255 return false;
256 }
257
258
259 bool SocketBase::ParseAddress(int type, const char* address, RawAddr* addr) {
260 int result;
261 if (type == SocketAddress::TYPE_IPV4) {
262 result = NO_RETRY_EXPECTED(inet_pton(AF_INET, address, &addr->in.sin_addr));
263 } else {
264 ASSERT(type == SocketAddress::TYPE_IPV6);
265 result =
266 NO_RETRY_EXPECTED(inet_pton(AF_INET6, address, &addr->in6.sin6_addr));
267 }
268 return (result == 1);
269 }
270
271
272 bool SocketBase::ListInterfacesSupported() {
273 return false;
274 }
275
276
277 AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces(
278 int type,
279 OSError** os_error) {
280 UNIMPLEMENTED();
281 return NULL;
282 }
283
284
285 void SocketBase::Close(intptr_t fd) {
286 ASSERT(fd >= 0);
287 NO_RETRY_EXPECTED(close(fd));
288 }
289
290
291 bool SocketBase::GetNoDelay(intptr_t fd, bool* enabled) {
292 LOG_ERR("SocketBase::GetNoDelay is unimplemented\n");
293 UNIMPLEMENTED();
294 return false;
295 }
296
297
298 bool SocketBase::SetNoDelay(intptr_t fd, bool enabled) {
299 int on = enabled ? 1 : 0;
300 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
301 reinterpret_cast<char*>(&on),
302 sizeof(on))) == 0;
303 }
304
305
306 bool SocketBase::GetMulticastLoop(intptr_t fd,
307 intptr_t protocol,
308 bool* enabled) {
309 LOG_ERR("SocketBase::GetMulticastLoop is unimplemented\n");
310 UNIMPLEMENTED();
311 return false;
312 }
313
314
315 bool SocketBase::SetMulticastLoop(intptr_t fd,
316 intptr_t protocol,
317 bool enabled) {
318 LOG_ERR("SocketBase::SetMulticastLoop is unimplemented\n");
319 UNIMPLEMENTED();
320 return false;
321 }
322
323
324 bool SocketBase::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) {
325 LOG_ERR("SocketBase::GetMulticastHops is unimplemented\n");
326 UNIMPLEMENTED();
327 return false;
328 }
329
330
331 bool SocketBase::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) {
332 LOG_ERR("SocketBase::SetMulticastHops is unimplemented\n");
333 UNIMPLEMENTED();
334 return false;
335 }
336
337
338 bool SocketBase::GetBroadcast(intptr_t fd, bool* enabled) {
339 LOG_ERR("SocketBase::GetBroadcast is unimplemented\n");
340 UNIMPLEMENTED();
341 return false;
342 }
343
344
345 bool SocketBase::SetBroadcast(intptr_t fd, bool enabled) {
346 LOG_ERR("SocketBase::SetBroadcast is unimplemented\n");
347 UNIMPLEMENTED();
348 return false;
349 }
350
351
352 bool SocketBase::JoinMulticast(intptr_t fd,
353 const RawAddr& addr,
354 const RawAddr&,
355 int interfaceIndex) {
356 LOG_ERR("SocketBase::JoinMulticast is unimplemented\n");
357 UNIMPLEMENTED();
358 return false;
359 }
360
361
362 bool SocketBase::LeaveMulticast(intptr_t fd,
363 const RawAddr& addr,
364 const RawAddr&,
365 int interfaceIndex) {
366 LOG_ERR("SocketBase::LeaveMulticast is unimplemented\n");
367 UNIMPLEMENTED();
368 return false;
369 }
370
371 } // namespace bin
372 } // namespace dart
373
374 #endif // defined(HOST_OS_FUCHSIA)
375
376 #endif // !defined(DART_IO_DISABLED)
OLDNEW
« no previous file with comments | « runtime/bin/socket_base_fuchsia.h ('k') | runtime/bin/socket_base_linux.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698