OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef BIN_SOCKET_H_ | 5 #ifndef BIN_SOCKET_H_ |
6 #define BIN_SOCKET_H_ | 6 #define BIN_SOCKET_H_ |
7 | 7 |
8 #include <map> | 8 #include <map> |
9 | 9 |
10 #include "platform/globals.h" | 10 #include "platform/globals.h" |
(...skipping 15 matching lines...) Expand all Loading... |
26 #include "bin/thread.h" | 26 #include "bin/thread.h" |
27 #include "bin/utils.h" | 27 #include "bin/utils.h" |
28 | 28 |
29 | 29 |
30 namespace dart { | 30 namespace dart { |
31 namespace bin { | 31 namespace bin { |
32 | 32 |
33 union RawAddr { | 33 union RawAddr { |
34 struct sockaddr_in in; | 34 struct sockaddr_in in; |
35 struct sockaddr_in6 in6; | 35 struct sockaddr_in6 in6; |
| 36 struct sockaddr_un un; |
36 struct sockaddr_storage ss; | 37 struct sockaddr_storage ss; |
37 struct sockaddr addr; | 38 struct sockaddr addr; |
38 }; | 39 }; |
39 | 40 |
40 class SocketAddress { | 41 class SocketAddress { |
41 public: | 42 public: |
42 enum { | 43 enum { |
43 TYPE_ANY = -1, | 44 TYPE_ANY = -1, |
44 TYPE_IPV4, | 45 TYPE_IPV4, |
45 TYPE_IPV6, | 46 TYPE_IPV6, |
| 47 TYPE_UNIX, |
46 }; | 48 }; |
47 | 49 |
48 enum { | 50 enum { |
49 ADDRESS_LOOPBACK_IP_V4, | 51 ADDRESS_LOOPBACK_IP_V4, |
50 ADDRESS_LOOPBACK_IP_V6, | 52 ADDRESS_LOOPBACK_IP_V6, |
51 ADDRESS_ANY_IP_V4, | 53 ADDRESS_ANY_IP_V4, |
52 ADDRESS_ANY_IP_V6, | 54 ADDRESS_ANY_IP_V6, |
53 ADDRESS_FIRST = ADDRESS_LOOPBACK_IP_V4, | 55 ADDRESS_FIRST = ADDRESS_LOOPBACK_IP_V4, |
54 ADDRESS_LAST = ADDRESS_ANY_IP_V6, | 56 ADDRESS_LAST = ADDRESS_ANY_IP_V6, |
55 }; | 57 }; |
56 | 58 |
57 explicit SocketAddress(struct sockaddr* sa); | 59 explicit SocketAddress(struct sockaddr* sa); |
58 | 60 |
59 ~SocketAddress() {} | 61 ~SocketAddress() {} |
60 | 62 |
61 int GetType() { | 63 int GetType() { |
62 if (addr_.ss.ss_family == AF_INET6) return TYPE_IPV6; | 64 switch (addr_.ss.ss_family) { |
63 return TYPE_IPV4; | 65 case AF_INET: return TYPE_IPV4; |
| 66 case AF_INET6: return TYPE_IPV6; |
| 67 case AF_UNIX: return TYPE_UNIX; |
| 68 default: |
| 69 UNREACHABLE(); |
| 70 return TYPE_ANY; |
| 71 } |
64 } | 72 } |
65 | 73 |
66 const char* as_string() const { return as_string_; } | 74 const char* as_string() const { |
| 75 if (addr_.ss.ss_family == AF_UNIX) { |
| 76 return addr_.un.sun_path; |
| 77 } else { |
| 78 return as_string_; |
| 79 } |
| 80 } |
| 81 |
67 const RawAddr& addr() const { return addr_; } | 82 const RawAddr& addr() const { return addr_; } |
68 | 83 |
69 static intptr_t GetAddrLength(const RawAddr& addr) { | 84 static intptr_t GetAddrLength(const RawAddr& addr) { |
70 ASSERT(addr.ss.ss_family == AF_INET || addr.ss.ss_family == AF_INET6); | 85 ASSERT(addr.ss.ss_family == AF_INET || |
71 return addr.ss.ss_family == AF_INET6 ? | 86 addr.ss.ss_family == AF_INET6 || |
72 sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); | 87 addr.ss.ss_family == AF_UNIX); |
| 88 switch (addr.ss.ss_family) { |
| 89 case AF_INET: return sizeof(struct sockaddr_in); |
| 90 case AF_INET6: return sizeof(struct sockaddr_in6); |
| 91 case AF_UNIX: return sizeof(struct sockaddr_un); |
| 92 default: |
| 93 UNREACHABLE(); |
| 94 return 0; |
| 95 } |
73 } | 96 } |
74 | 97 |
75 static intptr_t GetInAddrLength(const RawAddr& addr) { | 98 static intptr_t GetInAddrLength(const RawAddr& addr) { |
76 ASSERT(addr.ss.ss_family == AF_INET || addr.ss.ss_family == AF_INET6); | 99 ASSERT(addr.ss.ss_family == AF_INET || addr.ss.ss_family == AF_INET6); |
77 return addr.ss.ss_family == AF_INET6 ? | 100 return addr.ss.ss_family == AF_INET6 ? |
78 sizeof(struct in6_addr) : sizeof(struct in_addr); | 101 sizeof(struct in6_addr) : sizeof(struct in_addr); |
79 } | 102 } |
80 | 103 |
81 static bool AreAddressesEqual(const RawAddr& a, const RawAddr& b) { | 104 static bool AreAddressesEqual(const RawAddr& a, const RawAddr& b) { |
82 if (a.ss.ss_family == AF_INET) { | 105 if (a.ss.ss_family == AF_INET) { |
83 if (b.ss.ss_family != AF_INET) return false; | 106 if (b.ss.ss_family != AF_INET) return false; |
84 return memcmp(&a.in.sin_addr, &b.in.sin_addr, sizeof(a.in.sin_addr)) == 0; | 107 return memcmp(&a.in.sin_addr, &b.in.sin_addr, sizeof(a.in.sin_addr)) == 0; |
85 } else if (a.ss.ss_family == AF_INET6) { | 108 } else if (a.ss.ss_family == AF_INET6) { |
86 if (b.ss.ss_family != AF_INET6) return false; | 109 if (b.ss.ss_family != AF_INET6) return false; |
87 return memcmp(&a.in6.sin6_addr, | 110 return memcmp(&a.in6.sin6_addr, |
88 &b.in6.sin6_addr, | 111 &b.in6.sin6_addr, |
89 sizeof(a.in6.sin6_addr)) == 0; | 112 sizeof(a.in6.sin6_addr)) == 0; |
| 113 } else if (a.ss.ss_family == AF_UNIX) { |
| 114 int len = sizeof(a.un.sun_path); |
| 115 for (int i = 0; i < len; i++) { |
| 116 if (a.un.sun_path[i] != b.un.sun_path[i]) return false; |
| 117 if (a.un.sun_path[i] == '\0') return true; |
| 118 } |
| 119 return true; |
90 } else { | 120 } else { |
91 UNREACHABLE(); | 121 UNREACHABLE(); |
92 return false; | 122 return false; |
93 } | 123 } |
94 } | 124 } |
95 | 125 |
96 static void GetSockAddr(Dart_Handle obj, RawAddr* addr) { | 126 static void GetSockAddr(Dart_Handle obj, RawAddr* addr) { |
97 Dart_TypedData_Type data_type; | 127 Dart_TypedData_Type data_type; |
98 uint8_t* data = NULL; | 128 uint8_t* data = NULL; |
99 intptr_t len; | 129 intptr_t len; |
(...skipping 20 matching lines...) Expand all Loading... |
120 static int16_t FromType(int type) { | 150 static int16_t FromType(int type) { |
121 if (type == TYPE_ANY) return AF_UNSPEC; | 151 if (type == TYPE_ANY) return AF_UNSPEC; |
122 if (type == TYPE_IPV4) return AF_INET; | 152 if (type == TYPE_IPV4) return AF_INET; |
123 ASSERT(type == TYPE_IPV6 && "Invalid type"); | 153 ASSERT(type == TYPE_IPV6 && "Invalid type"); |
124 return AF_INET6; | 154 return AF_INET6; |
125 } | 155 } |
126 | 156 |
127 static void SetAddrPort(RawAddr* addr, intptr_t port) { | 157 static void SetAddrPort(RawAddr* addr, intptr_t port) { |
128 if (addr->ss.ss_family == AF_INET) { | 158 if (addr->ss.ss_family == AF_INET) { |
129 addr->in.sin_port = htons(port); | 159 addr->in.sin_port = htons(port); |
| 160 } else if (addr->ss.ss_family == AF_INET6) { |
| 161 addr->in6.sin6_port = htons(port); |
130 } else { | 162 } else { |
131 addr->in6.sin6_port = htons(port); | 163 UNREACHABLE(); |
132 } | 164 } |
133 } | 165 } |
134 | 166 |
135 static intptr_t GetAddrPort(const RawAddr& addr) { | 167 static intptr_t GetAddrPort(const RawAddr& addr) { |
136 if (addr.ss.ss_family == AF_INET) { | 168 if (addr.ss.ss_family == AF_INET) { |
137 return ntohs(addr.in.sin_port); | 169 return ntohs(addr.in.sin_port); |
| 170 } else if (addr.ss.ss_family == AF_INET6) { |
| 171 return ntohs(addr.in6.sin6_port); |
| 172 } else if (addr.ss.ss_family == AF_UNIX) { |
| 173 return 1; // TODO(sgjesse): Should be -1. |
138 } else { | 174 } else { |
139 return ntohs(addr.in6.sin6_port); | 175 UNREACHABLE(); |
| 176 return -1; |
140 } | 177 } |
141 } | 178 } |
142 | 179 |
143 static Dart_Handle ToTypedData(const RawAddr& addr) { | 180 static Dart_Handle ToTypedData(const RawAddr& addr) { |
144 int len = GetInAddrLength(addr); | 181 int len = GetInAddrLength(addr); |
145 Dart_Handle result = Dart_NewTypedData(Dart_TypedData_kUint8, len); | 182 Dart_Handle result = Dart_NewTypedData(Dart_TypedData_kUint8, len); |
146 if (Dart_IsError(result)) Dart_PropagateError(result); | 183 if (Dart_IsError(result)) Dart_PropagateError(result); |
147 Dart_Handle err; | 184 Dart_Handle err; |
148 RawAddr& raw = const_cast<RawAddr&>(addr); | 185 RawAddr& raw = const_cast<RawAddr&>(addr); |
149 if (addr.addr.sa_family == AF_INET6) { | 186 if (addr.addr.sa_family == AF_INET6) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 intptr_t fd, const void* buffer, intptr_t num_bytes, const RawAddr& addr); | 286 intptr_t fd, const void* buffer, intptr_t num_bytes, const RawAddr& addr); |
250 static intptr_t RecvFrom( | 287 static intptr_t RecvFrom( |
251 intptr_t fd, void* buffer, intptr_t num_bytes, RawAddr* addr); | 288 intptr_t fd, void* buffer, intptr_t num_bytes, RawAddr* addr); |
252 // Creates a socket which is bound and connected. The port to connect to is | 289 // Creates a socket which is bound and connected. The port to connect to is |
253 // specified as the port component of the passed RawAddr structure. | 290 // specified as the port component of the passed RawAddr structure. |
254 static intptr_t CreateConnect(const RawAddr& addr); | 291 static intptr_t CreateConnect(const RawAddr& addr); |
255 // Creates a socket which is bound and connected. The port to connect to is | 292 // Creates a socket which is bound and connected. The port to connect to is |
256 // specified as the port component of the passed RawAddr structure. | 293 // specified as the port component of the passed RawAddr structure. |
257 static intptr_t CreateBindConnect(const RawAddr& addr, | 294 static intptr_t CreateBindConnect(const RawAddr& addr, |
258 const RawAddr& source_addr); | 295 const RawAddr& source_addr); |
| 296 static intptr_t CreateConnectUnix(const RawAddr& addr); |
259 // Creates a datagram socket which is bound. The port to bind | 297 // Creates a datagram socket which is bound. The port to bind |
260 // to is specified as the port component of the RawAddr structure. | 298 // to is specified as the port component of the RawAddr structure. |
261 static intptr_t CreateBindDatagram(const RawAddr& addr, bool reuseAddress); | 299 static intptr_t CreateBindDatagram(const RawAddr& addr, bool reuseAddress); |
262 static intptr_t GetPort(intptr_t fd); | 300 static intptr_t GetPort(intptr_t fd); |
263 static SocketAddress* GetRemotePeer(intptr_t fd, intptr_t* port); | 301 static SocketAddress* GetRemotePeer(intptr_t fd, intptr_t* port); |
264 static void GetError(intptr_t fd, OSError* os_error); | 302 static void GetError(intptr_t fd, OSError* os_error); |
265 static int GetType(intptr_t fd); | 303 static int GetType(intptr_t fd); |
266 static intptr_t GetStdioHandle(intptr_t num); | 304 static intptr_t GetStdioHandle(intptr_t num); |
267 static void Close(intptr_t fd); | 305 static void Close(intptr_t fd); |
268 static bool GetNoDelay(intptr_t fd, bool* enabled); | 306 static bool GetNoDelay(intptr_t fd, bool* enabled); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 // | 364 // |
327 // Returns a positive integer if the call is successful. In case of failure | 365 // Returns a positive integer if the call is successful. In case of failure |
328 // it returns: | 366 // it returns: |
329 // | 367 // |
330 // -1: system error (errno set) | 368 // -1: system error (errno set) |
331 // -5: invalid bindAddress | 369 // -5: invalid bindAddress |
332 static intptr_t CreateBindListen(const RawAddr& addr, | 370 static intptr_t CreateBindListen(const RawAddr& addr, |
333 intptr_t backlog, | 371 intptr_t backlog, |
334 bool v6_only = false); | 372 bool v6_only = false); |
335 | 373 |
| 374 static intptr_t CreateBindListenUnix(const RawAddr& addr, |
| 375 intptr_t backlog); |
| 376 |
336 // Start accepting on a newly created listening socket. If it was unable to | 377 // Start accepting on a newly created listening socket. If it was unable to |
337 // start accepting incoming sockets, the fd is invalidated. | 378 // start accepting incoming sockets, the fd is invalidated. |
338 static bool StartAccept(intptr_t fd); | 379 static bool StartAccept(intptr_t fd); |
339 | 380 |
340 private: | 381 private: |
341 DISALLOW_ALLOCATION(); | 382 DISALLOW_ALLOCATION(); |
342 DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket); | 383 DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket); |
343 }; | 384 }; |
344 | 385 |
345 class ListeningSocketRegistry { | 386 class ListeningSocketRegistry { |
(...skipping 30 matching lines...) Expand all Loading... |
376 delete mutex_; | 417 delete mutex_; |
377 mutex_ = NULL; | 418 mutex_ = NULL; |
378 } | 419 } |
379 | 420 |
380 // This function should be called from a dart runtime call in order to create | 421 // This function should be called from a dart runtime call in order to create |
381 // a new (potentially shared) socket. | 422 // a new (potentially shared) socket. |
382 Dart_Handle CreateBindListen(Dart_Handle socket_object, | 423 Dart_Handle CreateBindListen(Dart_Handle socket_object, |
383 RawAddr addr, | 424 RawAddr addr, |
384 intptr_t backlog, | 425 intptr_t backlog, |
385 bool v6_only, | 426 bool v6_only, |
386 bool shared); | 427 bool shared, |
| 428 bool uds); |
387 | 429 |
388 // This should be called from the event handler for every kCloseEvent it gets | 430 // This should be called from the event handler for every kCloseEvent it gets |
389 // on listening sockets. | 431 // on listening sockets. |
390 // | 432 // |
391 // Returns `true` if the last reference has been dropped and the underlying | 433 // Returns `true` if the last reference has been dropped and the underlying |
392 // socket can be closed. | 434 // socket can be closed. |
393 // | 435 // |
394 // The caller is responsible for obtaining the mutex first, before calling | 436 // The caller is responsible for obtaining the mutex first, before calling |
395 // this function. | 437 // this function. |
396 bool CloseSafe(intptr_t socketfd); | 438 bool CloseSafe(intptr_t socketfd); |
(...skipping 26 matching lines...) Expand all Loading... |
423 | 465 |
424 private: | 466 private: |
425 DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry); | 467 DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry); |
426 }; | 468 }; |
427 | 469 |
428 | 470 |
429 } // namespace bin | 471 } // namespace bin |
430 } // namespace dart | 472 } // namespace dart |
431 | 473 |
432 #endif // BIN_SOCKET_H_ | 474 #endif // BIN_SOCKET_H_ |
OLD | NEW |