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 "bin/socket.h" | 7 #include "bin/socket.h" |
8 | 8 |
9 #include "bin/dartutils.h" | 9 #include "bin/dartutils.h" |
10 #include "bin/io_buffer.h" | 10 #include "bin/io_buffer.h" |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
94 sockets_by_fd_.Remove(GetHashmapKeyFromIntptr(fd), | 94 sockets_by_fd_.Remove(GetHashmapKeyFromIntptr(fd), |
95 GetHashmapHashFromIntptr(fd)); | 95 GetHashmapHashFromIntptr(fd)); |
96 } | 96 } |
97 | 97 |
98 | 98 |
99 Dart_Handle ListeningSocketRegistry::CreateBindListen(Dart_Handle socket_object, | 99 Dart_Handle ListeningSocketRegistry::CreateBindListen(Dart_Handle socket_object, |
100 RawAddr addr, | 100 RawAddr addr, |
101 intptr_t backlog, | 101 intptr_t backlog, |
102 bool v6_only, | 102 bool v6_only, |
103 bool shared) { | 103 bool shared) { |
104 MutexLocker ml(ListeningSocketRegistry::mutex_); | 104 MutexLocker ml(ListeningSocketRegistry::mutex_); |
Florian Schneider
2016/11/30 00:21:01
nit: no need to use qualified name here
MutexLock
kustermann
2016/11/30 10:51:10
Done.
| |
105 | 105 |
106 OSSocket* first_os_socket = NULL; | |
106 intptr_t port = SocketAddress::GetAddrPort(addr); | 107 intptr_t port = SocketAddress::GetAddrPort(addr); |
107 OSSocket* first_os_socket = LookupByPort(port); | 108 if (port > 0) { |
108 if (first_os_socket != NULL) { | 109 first_os_socket = LookupByPort(port); |
109 // There is already a socket listening on this port. We need to ensure | 110 if (first_os_socket != NULL) { |
110 // that if there is one also listening on the same address, it was created | 111 // There is already a socket listening on this port. We need to ensure |
111 // with `shared = true`, ... | 112 // that if there is one also listening on the same address, it was created |
112 OSSocket* os_socket = first_os_socket; | 113 // with `shared = true`, ... |
113 OSSocket* os_socket_same_addr = findOSSocketWithAddress(os_socket, addr); | 114 OSSocket* os_socket = first_os_socket; |
115 OSSocket* os_socket_same_addr = findOSSocketWithAddress(os_socket, addr); | |
114 | 116 |
115 if (os_socket_same_addr != NULL) { | 117 if (os_socket_same_addr != NULL) { |
116 if (!os_socket_same_addr->shared || !shared) { | 118 if (!os_socket_same_addr->shared || !shared) { |
117 OSError os_error(-1, | 119 OSError os_error(-1, |
118 "The shared flag to bind() needs to be `true` if " | 120 "The shared flag to bind() needs to be `true` if " |
119 "binding multiple times on the same (address, port) " | 121 "binding multiple times on the same (address, port) " |
120 "combination.", | 122 "combination.", |
121 OSError::kUnknown); | 123 OSError::kUnknown); |
122 return DartUtils::NewDartOSError(&os_error); | 124 return DartUtils::NewDartOSError(&os_error); |
125 } | |
126 if (os_socket_same_addr->v6_only != v6_only) { | |
127 OSError os_error(-1, | |
128 "The v6Only flag to bind() needs to be the same if " | |
129 "binding multiple times on the same (address, port) " | |
130 "combination.", | |
131 OSError::kUnknown); | |
132 return DartUtils::NewDartOSError(&os_error); | |
133 } | |
134 | |
135 // This socket creation is the exact same as the one which originally | |
136 // created the socket. We therefore increment the refcount and reuse | |
137 // the file descriptor. | |
138 os_socket->ref_count++; | |
139 | |
140 // We set as a side-effect the file descriptor on the dart | |
141 // socket_object. | |
142 Socket::SetSocketIdNativeField(socket_object, os_socket->socketfd); | |
143 | |
144 return Dart_True(); | |
123 } | 145 } |
124 if (os_socket_same_addr->v6_only != v6_only) { | |
125 OSError os_error(-1, | |
126 "The v6Only flag to bind() needs to be the same if " | |
127 "binding multiple times on the same (address, port) " | |
128 "combination.", | |
129 OSError::kUnknown); | |
130 return DartUtils::NewDartOSError(&os_error); | |
131 } | |
132 | |
133 // This socket creation is the exact same as the one which originally | |
134 // created the socket. We therefore increment the refcount and reuse | |
135 // the file descriptor. | |
136 os_socket->ref_count++; | |
137 | |
138 // We set as a side-effect the file descriptor on the dart socket_object. | |
139 Socket::SetSocketIdNativeField(socket_object, os_socket->socketfd); | |
140 | |
141 return Dart_True(); | |
142 } | 146 } |
143 } | 147 } |
144 | 148 |
145 // There is no socket listening on that (address, port), so we create new one. | 149 // There is no socket listening on that (address, port), so we create new one. |
146 intptr_t socketfd = ServerSocket::CreateBindListen(addr, backlog, v6_only); | 150 intptr_t socketfd = ServerSocket::CreateBindListen(addr, backlog, v6_only); |
147 if (socketfd == -5) { | 151 if (socketfd == -5) { |
148 OSError os_error(-1, "Invalid host", OSError::kUnknown); | 152 OSError os_error(-1, "Invalid host", OSError::kUnknown); |
149 return DartUtils::NewDartOSError(&os_error); | 153 return DartUtils::NewDartOSError(&os_error); |
150 } | 154 } |
151 if (socketfd < 0) { | 155 if (socketfd < 0) { |
152 OSError error; | 156 OSError error; |
153 return DartUtils::NewDartOSError(&error); | 157 return DartUtils::NewDartOSError(&error); |
154 } | 158 } |
155 if (!ServerSocket::StartAccept(socketfd)) { | 159 if (!ServerSocket::StartAccept(socketfd)) { |
156 OSError os_error(-1, "Failed to start accept", OSError::kUnknown); | 160 OSError os_error(-1, "Failed to start accept", OSError::kUnknown); |
157 return DartUtils::NewDartOSError(&os_error); | 161 return DartUtils::NewDartOSError(&os_error); |
158 } | 162 } |
159 intptr_t allocated_port = Socket::GetPort(socketfd); | 163 intptr_t allocated_port = Socket::GetPort(socketfd); |
160 ASSERT(allocated_port > 0); | 164 ASSERT(allocated_port > 0); |
161 | 165 |
166 if (allocated_port != port) { | |
167 ASSERT(port == 0); | |
Florian Schneider
2016/11/30 00:21:01
Maybe add a short comment here about the scenario
kustermann
2016/11/30 10:51:10
Done.
| |
168 first_os_socket = LookupByPort(allocated_port); | |
169 } | |
170 | |
162 OSSocket* os_socket = | 171 OSSocket* os_socket = |
163 new OSSocket(addr, allocated_port, v6_only, shared, socketfd); | 172 new OSSocket(addr, allocated_port, v6_only, shared, socketfd); |
164 os_socket->ref_count = 1; | 173 os_socket->ref_count = 1; |
165 os_socket->next = first_os_socket; | 174 os_socket->next = first_os_socket; |
166 | 175 |
167 InsertByPort(allocated_port, os_socket); | 176 InsertByPort(allocated_port, os_socket); |
168 InsertByFd(socketfd, os_socket); | 177 InsertByFd(socketfd, os_socket); |
169 | 178 |
170 // We set as a side-effect the port on the dart socket_object. | 179 // We set as a side-effect the port on the dart socket_object. |
171 Socket::SetSocketIdNativeField(socket_object, socketfd); | 180 Socket::SetSocketIdNativeField(socket_object, socketfd); |
(...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
919 if (Dart_IsError(err)) { | 928 if (Dart_IsError(err)) { |
920 Dart_PropagateError(err); | 929 Dart_PropagateError(err); |
921 } | 930 } |
922 return socket; | 931 return socket; |
923 } | 932 } |
924 | 933 |
925 } // namespace bin | 934 } // namespace bin |
926 } // namespace dart | 935 } // namespace dart |
927 | 936 |
928 #endif // !defined(DART_IO_DISABLED) | 937 #endif // !defined(DART_IO_DISABLED) |
OLD | NEW |