1424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// found in the LICENSE file. 4424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 5424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "net/socket/socket_descriptor.h" 6424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 7424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#if defined(OS_POSIX) 8424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include <sys/types.h> 9424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include <sys/socket.h> 10424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#endif 11424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 12424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/basictypes.h" 13424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 14424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#if defined(OS_WIN) 154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <ws2tcpip.h> 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/win/windows_version.h" 17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "net/base/winsock_init.h" 18424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#endif 19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 20424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)namespace net { 21424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 22424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)PlatformSocketFactory* g_socket_factory = NULL; 23424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 24424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)PlatformSocketFactory::PlatformSocketFactory() { 25424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)PlatformSocketFactory::~PlatformSocketFactory() { 28424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 29424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void PlatformSocketFactory::SetInstance(PlatformSocketFactory* factory) { 31424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) g_socket_factory = factory; 32424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 33424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 34424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)SocketDescriptor CreateSocketDefault(int family, int type, int protocol) { 35424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#if defined(OS_WIN) 36424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EnsureWinsockInit(); 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SocketDescriptor result = ::WSASocket(family, type, protocol, NULL, 0, 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WSA_FLAG_OVERLAPPED); 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (result != kInvalidSocket && family == AF_INET6 && 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::win::OSInfo::GetInstance()->version() >= base::win::VERSION_VISTA) { 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DWORD value = 0; 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (setsockopt(result, IPPROTO_IPV6, IPV6_V6ONLY, 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) reinterpret_cast<const char*>(&value), sizeof(value))) { 444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) closesocket(result); 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return kInvalidSocket; 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return result; 49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#else // OS_WIN 50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return ::socket(family, type, protocol); 51424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#endif // OS_WIN 52424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 53424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 54424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)SocketDescriptor CreatePlatformSocket(int family, int type, int protocol) { 55424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (g_socket_factory) 56424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return g_socket_factory->CreateSocket(family, type, protocol); 57424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) else 58424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return CreateSocketDefault(family, type, protocol); 59424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 60424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 61424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} // namespace net 62