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

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

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