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

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

Issue 14083007: Add new InternetAddress class with a static lookup function (including IPv6 results). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix new test. Created 7 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 | Annotate | Revision Log
« no previous file with comments | « runtime/bin/socket_patch.dart ('k') | runtime/bin/vmstats_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "platform/globals.h" 5 #include "platform/globals.h"
6 #if defined(TARGET_OS_WINDOWS) 6 #if defined(TARGET_OS_WINDOWS)
7 7
8 #include "bin/builtin.h" 8 #include "bin/builtin.h"
9 #include "bin/eventhandler.h" 9 #include "bin/eventhandler.h"
10 #include "bin/file.h" 10 #include "bin/file.h"
11 #include "bin/log.h" 11 #include "bin/log.h"
12 #include "bin/socket.h" 12 #include "bin/socket.h"
13 13
14 #define SOCKADDR_STORAGE_SET_PORT(addr, port) \
15 if (addr.ss_family == AF_INET) { \
16 reinterpret_cast<struct sockaddr_in*>(&addr)->sin_port = htons(port); \
17 } else { \
18 reinterpret_cast<struct sockaddr_in6*>(&addr)->sin6_port = htons(port); \
19 }
20
21 #define SOCKADDR_STORAGE_GET_PORT(addr) \
22 addr.ss_family == AF_INET ? \
23 ntohs(reinterpret_cast<struct sockaddr_in*>(&addr)->sin_port) : \
24 ntohs(reinterpret_cast<struct sockaddr_in6*>(&addr)->sin6_port)
25
26 SocketAddress::SocketAddress(struct addrinfo* addrinfo) {
27 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
28 sockaddr_storage *sockaddr =
29 reinterpret_cast<sockaddr_storage *>(addrinfo->ai_addr);
30
31 // Clear the port before calling WSAAddressToString as WSAAddressToString
32 // includes the port in the formatted string.
33 DWORD len = INET6_ADDRSTRLEN;
34 int err = WSAAddressToStringA(reinterpret_cast<LPSOCKADDR>(sockaddr),
35 sizeof(sockaddr_storage),
36 NULL,
37 as_string_,
38 &len);
39
40 if (err != 0) {
41 as_string_[0] = 0;
42 }
43 memmove(reinterpret_cast<void *>(&addr_),
44 addrinfo->ai_addr,
45 addrinfo->ai_addrlen);
46 }
47
14 bool Socket::Initialize() { 48 bool Socket::Initialize() {
15 static bool socket_initialized = false; 49 static bool socket_initialized = false;
16 if (socket_initialized) return true; 50 if (socket_initialized) return true;
17 int err; 51 int err;
18 WSADATA winsock_data; 52 WSADATA winsock_data;
19 WORD version_requested = MAKEWORD(2, 2); 53 WORD version_requested = MAKEWORD(2, 2);
20 err = WSAStartup(version_requested, &winsock_data); 54 err = WSAStartup(version_requested, &winsock_data);
21 if (err == 0) { 55 if (err == 0) {
22 socket_initialized = true; 56 socket_initialized = true;
23 } else { 57 } else {
(...skipping 16 matching lines...) Expand all
40 74
41 intptr_t Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) { 75 intptr_t Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) {
42 Handle* handle = reinterpret_cast<Handle*>(fd); 76 Handle* handle = reinterpret_cast<Handle*>(fd);
43 return handle->Write(buffer, num_bytes); 77 return handle->Write(buffer, num_bytes);
44 } 78 }
45 79
46 80
47 intptr_t Socket::GetPort(intptr_t fd) { 81 intptr_t Socket::GetPort(intptr_t fd) {
48 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket()); 82 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket());
49 SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd); 83 SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd);
50 struct sockaddr_in socket_address; 84 struct sockaddr_storage socket_address;
51 socklen_t size = sizeof(socket_address); 85 socklen_t size = sizeof(socket_address);
52 if (getsockname(socket_handle->socket(), 86 if (getsockname(socket_handle->socket(),
53 reinterpret_cast<struct sockaddr *>(&socket_address), 87 reinterpret_cast<struct sockaddr *>(&socket_address),
54 &size)) { 88 &size) == SOCKET_ERROR) {
55 Log::PrintErr("Error getsockname: %s\n", strerror(errno)); 89 Log::PrintErr("Error getsockname: %d\n", WSAGetLastError());
56 return 0; 90 return 0;
57 } 91 }
58 return ntohs(socket_address.sin_port); 92 return SOCKADDR_STORAGE_GET_PORT(socket_address);
59 } 93 }
60 94
61 95
62 bool Socket::GetRemotePeer(intptr_t fd, char *host, intptr_t *port) { 96 bool Socket::GetRemotePeer(intptr_t fd, char *host, intptr_t *port) {
63 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket()); 97 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket());
64 SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd); 98 SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd);
65 struct sockaddr_in socket_address; 99 struct sockaddr_storage socket_address;
66 socklen_t size = sizeof(socket_address); 100 socklen_t size = sizeof(sockaddr_storage);
67 if (getpeername(socket_handle->socket(), 101 if (getpeername(socket_handle->socket(),
68 reinterpret_cast<struct sockaddr *>(&socket_address), 102 reinterpret_cast<struct sockaddr *>(&socket_address),
69 &size)) { 103 &size)) {
70 Log::PrintErr("Error getpeername: %s\n", strerror(errno)); 104 Log::PrintErr("Error getpeername: %d\n", WSAGetLastError());
71 return false; 105 return false;
72 } 106 }
73 *port = ntohs(socket_address.sin_port); 107 *port = SOCKADDR_STORAGE_GET_PORT(socket_address);
74 // Clear the port before calling WSAAddressToString as WSAAddressToString 108 // Clear the port before calling WSAAddressToString as WSAAddressToString
75 // includes the port in the formatted string. 109 // includes the port in the formatted string.
76 socket_address.sin_port = 0; 110 SOCKADDR_STORAGE_SET_PORT(socket_address, 0);
77 DWORD len = INET_ADDRSTRLEN; 111 DWORD len = INET6_ADDRSTRLEN;
78 int err = WSAAddressToStringA(reinterpret_cast<LPSOCKADDR>(&socket_address), 112 int err = WSAAddressToStringA(reinterpret_cast<LPSOCKADDR>(&socket_address),
79 sizeof(socket_address), 113 sizeof(socket_address),
80 NULL, 114 NULL,
81 host, 115 host,
82 &len); 116 &len);
83 if (err != 0) { 117 if (err != 0) {
84 Log::PrintErr("Error WSAAddressToString: %d\n", WSAGetLastError()); 118 Log::PrintErr("Error WSAAddressToString: %d\n", WSAGetLastError());
85 return false; 119 return false;
86 } 120 }
87 return true; 121 return true;
88 } 122 }
89 123
90 intptr_t Socket::CreateConnect(const char* host, const intptr_t port) { 124 intptr_t Socket::CreateConnect(sockaddr_storage addr, const intptr_t port) {
91 SOCKET s = socket(AF_INET, SOCK_STREAM, 0); 125 SOCKET s = socket(addr.ss_family, SOCK_STREAM, 0);
92 if (s == INVALID_SOCKET) { 126 if (s == INVALID_SOCKET) {
93 return -1; 127 return -1;
94 } 128 }
95 129
96 linger l; 130 linger l;
97 l.l_onoff = 1; 131 l.l_onoff = 1;
98 l.l_linger = 10; 132 l.l_linger = 10;
99 int status = setsockopt(s, 133 int status = setsockopt(s,
100 SOL_SOCKET, 134 SOL_SOCKET,
101 SO_LINGER, 135 SO_LINGER,
102 reinterpret_cast<char*>(&l), 136 reinterpret_cast<char*>(&l),
103 sizeof(l)); 137 sizeof(l));
104 if (status != NO_ERROR) { 138 if (status != NO_ERROR) {
105 FATAL("Failed setting SO_LINGER on socket"); 139 FATAL("Failed setting SO_LINGER on socket");
106 } 140 }
107 141
108 // Perform a name lookup for an IPv4 address. 142 SOCKADDR_STORAGE_SET_PORT(addr, port);
109 struct addrinfo hints;
110 memset(&hints, 0, sizeof(hints));
111 hints.ai_family = AF_INET;
112 hints.ai_socktype = SOCK_STREAM;
113 hints.ai_protocol = IPPROTO_TCP;
114 struct addrinfo* result = NULL;
115 status = getaddrinfo(host, 0, &hints, &result);
116 if (status != NO_ERROR) {
117 return -1;
118 }
119
120 // Copy IPv4 address and set the port.
121 struct sockaddr_in server_address;
122 memcpy(&server_address,
123 reinterpret_cast<sockaddr_in *>(result->ai_addr),
124 sizeof(server_address));
125 server_address.sin_port = htons(port);
126 freeaddrinfo(result); // Free data allocated by getaddrinfo.
127 status = connect( 143 status = connect(
128 s, 144 s,
129 reinterpret_cast<struct sockaddr*>(&server_address), 145 reinterpret_cast<struct sockaddr*>(&addr),
130 sizeof(server_address)); 146 SocketAddress::GetAddrLength(addr));
131 if (status == SOCKET_ERROR) { 147 if (status == SOCKET_ERROR) {
132 DWORD rc = WSAGetLastError(); 148 DWORD rc = WSAGetLastError();
133 closesocket(s); 149 closesocket(s);
134 SetLastError(rc); 150 SetLastError(rc);
135 return -1; 151 return -1;
136 } 152 }
137 153
138 ClientSocket* client_socket = new ClientSocket(s); 154 ClientSocket* client_socket = new ClientSocket(s);
139 return reinterpret_cast<intptr_t>(client_socket); 155 return reinterpret_cast<intptr_t>(client_socket);
140 } 156 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 ListenSocket* listen_socket = reinterpret_cast<ListenSocket*>(fd); 201 ListenSocket* listen_socket = reinterpret_cast<ListenSocket*>(fd);
186 ClientSocket* client_socket = listen_socket->Accept(); 202 ClientSocket* client_socket = listen_socket->Accept();
187 if (client_socket != NULL) { 203 if (client_socket != NULL) {
188 return reinterpret_cast<intptr_t>(client_socket); 204 return reinterpret_cast<intptr_t>(client_socket);
189 } else { 205 } else {
190 return -1; 206 return -1;
191 } 207 }
192 } 208 }
193 209
194 210
195 const char* Socket::LookupIPv4Address(char* host, OSError** os_error) { 211 SocketAddresses* Socket::LookupAddress(const char* host,
196 // Perform a name lookup for an IPv4 address. 212 int type,
213 OSError** os_error) {
197 Initialize(); 214 Initialize();
215
216 // Perform a name lookup for a host name.
198 struct addrinfo hints; 217 struct addrinfo hints;
199 memset(&hints, 0, sizeof(hints)); 218 memset(&hints, 0, sizeof(hints));
200 hints.ai_family = AF_INET; 219 hints.ai_family = SocketAddress::FromType(type);
201 hints.ai_socktype = SOCK_STREAM; 220 hints.ai_socktype = SOCK_STREAM;
221 hints.ai_flags = 0;
202 hints.ai_protocol = IPPROTO_TCP; 222 hints.ai_protocol = IPPROTO_TCP;
203 struct addrinfo* info = NULL; 223 struct addrinfo* info = NULL;
204 int status = getaddrinfo(host, 0, &hints, &info); 224 int status = getaddrinfo(host, 0, &hints, &info);
205 if (status != 0) { 225 if (status != 0) {
206 ASSERT(*os_error == NULL); 226 ASSERT(*os_error == NULL);
207 DWORD error_code = WSAGetLastError(); 227 DWORD error_code = WSAGetLastError();
208 SetLastError(error_code); 228 SetLastError(error_code);
209 *os_error = new OSError(); 229 *os_error = new OSError();
210 return NULL; 230 return NULL;
211 } 231 }
212 // Convert the address into IPv4 dotted decimal notation. 232 intptr_t count = 0;
213 char* buffer = reinterpret_cast<char*>(malloc(INET_ADDRSTRLEN)); 233 for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
214 sockaddr_in *sockaddr = reinterpret_cast<sockaddr_in *>(info->ai_addr); 234 if (c->ai_family == AF_INET || c->ai_family == AF_INET6) count++;
215
216 // Clear the port before calling WSAAddressToString as WSAAddressToString
217 // includes the port in the formatted string.
218 DWORD len = INET_ADDRSTRLEN;
219 int err = WSAAddressToStringA(reinterpret_cast<LPSOCKADDR>(sockaddr),
220 sizeof(sockaddr_in),
221 NULL,
222 buffer,
223 &len);
224 if (err != 0) {
225 free(buffer);
226 return NULL;
227 } 235 }
228 return buffer; 236 SocketAddresses* addresses = new SocketAddresses(count);
237 intptr_t i = 0;
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));
241 i++;
242 }
243 }
244 freeaddrinfo(info);
245 return addresses;
229 } 246 }
230 247
231 248
232 intptr_t ServerSocket::CreateBindListen(const char* host, 249 intptr_t ServerSocket::CreateBindListen(sockaddr_storage addr,
233 intptr_t port, 250 intptr_t port,
234 intptr_t backlog) { 251 intptr_t backlog) {
235 unsigned long socket_addr = inet_addr(host); // NOLINT 252 SOCKET s = socket(addr.ss_family, SOCK_STREAM, IPPROTO_TCP);
236 if (socket_addr == INADDR_NONE) {
237 return -5;
238 }
239
240 SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
241 if (s == INVALID_SOCKET) { 253 if (s == INVALID_SOCKET) {
242 return -1; 254 return -1;
243 } 255 }
244 256
245 BOOL optval = true; 257 BOOL optval = true;
246 int status = setsockopt(s, 258 int status = setsockopt(s,
247 SOL_SOCKET, 259 SOL_SOCKET,
248 SO_REUSEADDR, 260 SO_REUSEADDR,
249 reinterpret_cast<const char*>(&optval), 261 reinterpret_cast<const char*>(&optval),
250 sizeof(optval)); 262 sizeof(optval));
251 if (status == SOCKET_ERROR) { 263 if (status == SOCKET_ERROR) {
252 DWORD rc = WSAGetLastError(); 264 DWORD rc = WSAGetLastError();
253 closesocket(s); 265 closesocket(s);
254 SetLastError(rc); 266 SetLastError(rc);
255 return -1; 267 return -1;
256 } 268 }
257 269
258 sockaddr_in addr; 270 if (addr.ss_family == AF_INET6) {
259 memset(&addr, 0, sizeof(addr)); 271 optval = false;
260 addr.sin_family = AF_INET; 272 setsockopt(s,
261 addr.sin_addr.s_addr = socket_addr; 273 IPPROTO_IPV6,
262 addr.sin_port = htons(port); 274 IPV6_V6ONLY,
275 reinterpret_cast<const char*>(&optval),
276 sizeof(optval));
277 }
278
279 SOCKADDR_STORAGE_SET_PORT(addr, port);
263 status = bind(s, 280 status = bind(s,
264 reinterpret_cast<struct sockaddr *>(&addr), 281 reinterpret_cast<struct sockaddr *>(&addr),
265 sizeof(addr)); 282 SocketAddress::GetAddrLength(addr));
266 if (status == SOCKET_ERROR) { 283 if (status == SOCKET_ERROR) {
267 DWORD rc = WSAGetLastError(); 284 DWORD rc = WSAGetLastError();
268 closesocket(s); 285 closesocket(s);
269 SetLastError(rc); 286 SetLastError(rc);
270 return -1; 287 return -1;
271 } 288 }
272 289
273 status = listen(s, backlog > 0 ? backlog : SOMAXCONN); 290 status = listen(s, backlog > 0 ? backlog : SOMAXCONN);
274 if (status == SOCKET_ERROR) { 291 if (status == SOCKET_ERROR) {
275 DWORD rc = WSAGetLastError(); 292 DWORD rc = WSAGetLastError();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); 332 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
316 int on = enabled ? 1 : 0; 333 int on = enabled ? 1 : 0;
317 return setsockopt(fd, 334 return setsockopt(fd,
318 IPPROTO_TCP, 335 IPPROTO_TCP,
319 TCP_NODELAY, 336 TCP_NODELAY,
320 reinterpret_cast<char *>(&on), 337 reinterpret_cast<char *>(&on),
321 sizeof(on)) == 0; 338 sizeof(on)) == 0;
322 } 339 }
323 340
324 #endif // defined(TARGET_OS_WINDOWS) 341 #endif // defined(TARGET_OS_WINDOWS)
OLDNEW
« no previous file with comments | « runtime/bin/socket_patch.dart ('k') | runtime/bin/vmstats_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698