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 #if !defined(DART_IO_DISABLED) | 5 #if !defined(DART_IO_DISABLED) |
6 | 6 |
7 #include "platform/globals.h" | 7 #include "platform/globals.h" |
8 #if defined(HOST_OS_LINUX) | 8 #if defined(HOST_OS_LINUX) |
9 | 9 |
10 #include "bin/socket.h" | 10 #include "bin/socket.h" |
11 | 11 |
12 #include <errno.h> // NOLINT | 12 #include <errno.h> // NOLINT |
13 | 13 |
14 #include "bin/fdutils.h" | 14 #include "bin/fdutils.h" |
15 #include "platform/signal_blocker.h" | 15 #include "platform/signal_blocker.h" |
16 | 16 |
17 namespace dart { | 17 namespace dart { |
18 namespace bin { | 18 namespace bin { |
19 | 19 |
20 Socket::Socket(intptr_t fd) | 20 Socket::Socket(intptr_t fd) |
21 : ReferenceCounted(), fd_(fd), port_(ILLEGAL_PORT) {} | 21 : ReferenceCounted(), fd_(fd), port_(ILLEGAL_PORT) {} |
22 | 22 |
23 | |
24 void Socket::SetClosedFd() { | 23 void Socket::SetClosedFd() { |
25 fd_ = kClosedFd; | 24 fd_ = kClosedFd; |
26 } | 25 } |
27 | 26 |
28 | |
29 static intptr_t Create(const RawAddr& addr) { | 27 static intptr_t Create(const RawAddr& addr) { |
30 intptr_t fd; | 28 intptr_t fd; |
31 intptr_t type = SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC; | 29 intptr_t type = SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC; |
32 fd = NO_RETRY_EXPECTED(socket(addr.ss.ss_family, type, 0)); | 30 fd = NO_RETRY_EXPECTED(socket(addr.ss.ss_family, type, 0)); |
33 if (fd < 0) { | 31 if (fd < 0) { |
34 return -1; | 32 return -1; |
35 } | 33 } |
36 return fd; | 34 return fd; |
37 } | 35 } |
38 | 36 |
39 | |
40 static intptr_t Connect(intptr_t fd, const RawAddr& addr) { | 37 static intptr_t Connect(intptr_t fd, const RawAddr& addr) { |
41 intptr_t result = TEMP_FAILURE_RETRY( | 38 intptr_t result = TEMP_FAILURE_RETRY( |
42 connect(fd, &addr.addr, SocketAddress::GetAddrLength(addr))); | 39 connect(fd, &addr.addr, SocketAddress::GetAddrLength(addr))); |
43 if ((result == 0) || (errno == EINPROGRESS)) { | 40 if ((result == 0) || (errno == EINPROGRESS)) { |
44 return fd; | 41 return fd; |
45 } | 42 } |
46 FDUtils::FDUtils::SaveErrorAndClose(fd); | 43 FDUtils::FDUtils::SaveErrorAndClose(fd); |
47 return -1; | 44 return -1; |
48 } | 45 } |
49 | 46 |
50 | |
51 intptr_t Socket::CreateConnect(const RawAddr& addr) { | 47 intptr_t Socket::CreateConnect(const RawAddr& addr) { |
52 intptr_t fd = Create(addr); | 48 intptr_t fd = Create(addr); |
53 if (fd < 0) { | 49 if (fd < 0) { |
54 return fd; | 50 return fd; |
55 } | 51 } |
56 return Connect(fd, addr); | 52 return Connect(fd, addr); |
57 } | 53 } |
58 | 54 |
59 | |
60 intptr_t Socket::CreateBindConnect(const RawAddr& addr, | 55 intptr_t Socket::CreateBindConnect(const RawAddr& addr, |
61 const RawAddr& source_addr) { | 56 const RawAddr& source_addr) { |
62 intptr_t fd = Create(addr); | 57 intptr_t fd = Create(addr); |
63 if (fd < 0) { | 58 if (fd < 0) { |
64 return fd; | 59 return fd; |
65 } | 60 } |
66 | 61 |
67 intptr_t result = TEMP_FAILURE_RETRY( | 62 intptr_t result = TEMP_FAILURE_RETRY( |
68 bind(fd, &source_addr.addr, SocketAddress::GetAddrLength(source_addr))); | 63 bind(fd, &source_addr.addr, SocketAddress::GetAddrLength(source_addr))); |
69 if ((result != 0) && (errno != EINPROGRESS)) { | 64 if ((result != 0) && (errno != EINPROGRESS)) { |
70 FDUtils::SaveErrorAndClose(fd); | 65 FDUtils::SaveErrorAndClose(fd); |
71 return -1; | 66 return -1; |
72 } | 67 } |
73 | 68 |
74 return Connect(fd, addr); | 69 return Connect(fd, addr); |
75 } | 70 } |
76 | 71 |
77 | |
78 intptr_t Socket::CreateBindDatagram(const RawAddr& addr, bool reuseAddress) { | 72 intptr_t Socket::CreateBindDatagram(const RawAddr& addr, bool reuseAddress) { |
79 intptr_t fd; | 73 intptr_t fd; |
80 | 74 |
81 fd = NO_RETRY_EXPECTED(socket(addr.addr.sa_family, | 75 fd = NO_RETRY_EXPECTED(socket(addr.addr.sa_family, |
82 SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, | 76 SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, |
83 IPPROTO_UDP)); | 77 IPPROTO_UDP)); |
84 if (fd < 0) { | 78 if (fd < 0) { |
85 return -1; | 79 return -1; |
86 } | 80 } |
87 | 81 |
88 if (reuseAddress) { | 82 if (reuseAddress) { |
89 int optval = 1; | 83 int optval = 1; |
90 VOID_NO_RETRY_EXPECTED( | 84 VOID_NO_RETRY_EXPECTED( |
91 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); | 85 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); |
92 } | 86 } |
93 | 87 |
94 if (NO_RETRY_EXPECTED( | 88 if (NO_RETRY_EXPECTED( |
95 bind(fd, &addr.addr, SocketAddress::GetAddrLength(addr))) < 0) { | 89 bind(fd, &addr.addr, SocketAddress::GetAddrLength(addr))) < 0) { |
96 FDUtils::SaveErrorAndClose(fd); | 90 FDUtils::SaveErrorAndClose(fd); |
97 return -1; | 91 return -1; |
98 } | 92 } |
99 return fd; | 93 return fd; |
100 } | 94 } |
101 | 95 |
102 | |
103 intptr_t ServerSocket::CreateBindListen(const RawAddr& addr, | 96 intptr_t ServerSocket::CreateBindListen(const RawAddr& addr, |
104 intptr_t backlog, | 97 intptr_t backlog, |
105 bool v6_only) { | 98 bool v6_only) { |
106 intptr_t fd; | 99 intptr_t fd; |
107 | 100 |
108 fd = NO_RETRY_EXPECTED( | 101 fd = NO_RETRY_EXPECTED( |
109 socket(addr.ss.ss_family, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)); | 102 socket(addr.ss.ss_family, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)); |
110 if (fd < 0) { | 103 if (fd < 0) { |
111 return -1; | 104 return -1; |
112 } | 105 } |
(...skipping 25 matching lines...) Expand all Loading... |
138 } | 131 } |
139 | 132 |
140 if (NO_RETRY_EXPECTED(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) { | 133 if (NO_RETRY_EXPECTED(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) { |
141 FDUtils::SaveErrorAndClose(fd); | 134 FDUtils::SaveErrorAndClose(fd); |
142 return -1; | 135 return -1; |
143 } | 136 } |
144 | 137 |
145 return fd; | 138 return fd; |
146 } | 139 } |
147 | 140 |
148 | |
149 bool ServerSocket::StartAccept(intptr_t fd) { | 141 bool ServerSocket::StartAccept(intptr_t fd) { |
150 USE(fd); | 142 USE(fd); |
151 return true; | 143 return true; |
152 } | 144 } |
153 | 145 |
154 | |
155 static bool IsTemporaryAcceptError(int error) { | 146 static bool IsTemporaryAcceptError(int error) { |
156 // On Linux a number of protocol errors should be treated as EAGAIN. | 147 // On Linux a number of protocol errors should be treated as EAGAIN. |
157 // These are the ones for TCP/IP. | 148 // These are the ones for TCP/IP. |
158 return (error == EAGAIN) || (error == ENETDOWN) || (error == EPROTO) || | 149 return (error == EAGAIN) || (error == ENETDOWN) || (error == EPROTO) || |
159 (error == ENOPROTOOPT) || (error == EHOSTDOWN) || (error == ENONET) || | 150 (error == ENOPROTOOPT) || (error == EHOSTDOWN) || (error == ENONET) || |
160 (error == EHOSTUNREACH) || (error == EOPNOTSUPP) || | 151 (error == EHOSTUNREACH) || (error == EOPNOTSUPP) || |
161 (error == ENETUNREACH); | 152 (error == ENETUNREACH); |
162 } | 153 } |
163 | 154 |
164 | |
165 intptr_t ServerSocket::Accept(intptr_t fd) { | 155 intptr_t ServerSocket::Accept(intptr_t fd) { |
166 intptr_t socket; | 156 intptr_t socket; |
167 struct sockaddr clientaddr; | 157 struct sockaddr clientaddr; |
168 socklen_t addrlen = sizeof(clientaddr); | 158 socklen_t addrlen = sizeof(clientaddr); |
169 socket = TEMP_FAILURE_RETRY(accept(fd, &clientaddr, &addrlen)); | 159 socket = TEMP_FAILURE_RETRY(accept(fd, &clientaddr, &addrlen)); |
170 if (socket == -1) { | 160 if (socket == -1) { |
171 if (IsTemporaryAcceptError(errno)) { | 161 if (IsTemporaryAcceptError(errno)) { |
172 // We need to signal to the caller that this is actually not an | 162 // We need to signal to the caller that this is actually not an |
173 // error. We got woken up from the poll on the listening socket, | 163 // error. We got woken up from the poll on the listening socket, |
174 // but there is no connection ready to be accepted. | 164 // but there is no connection ready to be accepted. |
(...skipping 12 matching lines...) Expand all Loading... |
187 } | 177 } |
188 return socket; | 178 return socket; |
189 } | 179 } |
190 | 180 |
191 } // namespace bin | 181 } // namespace bin |
192 } // namespace dart | 182 } // namespace dart |
193 | 183 |
194 #endif // defined(HOST_OS_LINUX) | 184 #endif // defined(HOST_OS_LINUX) |
195 | 185 |
196 #endif // !defined(DART_IO_DISABLED) | 186 #endif // !defined(DART_IO_DISABLED) |
OLD | NEW |