1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <errno.h> 30 31 #include <cutils/sockets.h> 32 33 #define LISTEN_BACKLOG 4 34 35 extern bool initialize_windows_sockets(); 36 37 SOCKET socket_inaddr_any_server(int port, int type) { 38 if (!initialize_windows_sockets()) { 39 return INVALID_SOCKET; 40 } 41 42 SOCKET sock = socket(AF_INET6, type, 0); 43 if (sock == INVALID_SOCKET) { 44 return INVALID_SOCKET; 45 } 46 47 // Enforce exclusive addresses so nobody can steal the port from us (1), 48 // and enable dual-stack so both IPv4 and IPv6 work (2). 49 // (1) https://msdn.microsoft.com/en-us/library/windows/desktop/ms740621(v=vs.85).aspx. 50 // (2) https://msdn.microsoft.com/en-us/library/windows/desktop/bb513665(v=vs.85).aspx. 51 int exclusive = 1; 52 DWORD v6_only = 0; 53 if (setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char*)&exclusive, 54 sizeof(exclusive)) == SOCKET_ERROR || 55 setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&v6_only, 56 sizeof(v6_only)) == SOCKET_ERROR) { 57 closesocket(sock); 58 return INVALID_SOCKET; 59 } 60 61 // Bind the socket to our local port. 62 struct sockaddr_in6 addr; 63 memset(&addr, 0, sizeof(addr)); 64 addr.sin6_family = AF_INET6; 65 addr.sin6_port = htons(port); 66 addr.sin6_addr = in6addr_any; 67 if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) { 68 closesocket(sock); 69 return INVALID_SOCKET; 70 } 71 72 // Start listening for connections if this is a TCP socket. 73 if (type == SOCK_STREAM && listen(sock, LISTEN_BACKLOG) == SOCKET_ERROR) { 74 closesocket(sock); 75 return INVALID_SOCKET; 76 } 77 78 return sock; 79 } 80