10eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell/*
20eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell * Copyright (C) 2015 The Android Open Source Project
30eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell * All rights reserved.
40eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell *
50eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell * Redistribution and use in source and binary forms, with or without
60eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell * modification, are permitted provided that the following conditions
70eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell * are met:
80eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell *  * Redistributions of source code must retain the above copyright
90eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell *    notice, this list of conditions and the following disclaimer.
100eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell *  * Redistributions in binary form must reproduce the above copyright
110eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell *    notice, this list of conditions and the following disclaimer in
120eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell *    the documentation and/or other materials provided with the
130eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell *    distribution.
140eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell *
150eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
160eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
170eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
180eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
190eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
200eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
210eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
220eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
230eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
240eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
250eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
260eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell * SUCH DAMAGE.
270eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell */
280eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell
290eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell#include <cutils/sockets.h>
300eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell
310eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursellextern bool initialize_windows_sockets();
320eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell
330eb8e1b706b577194bab1e23fab5b7d20d5259f1David PursellSOCKET socket_network_client(const char* host, int port, int type) {
340eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell    if (!initialize_windows_sockets()) {
350eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell        return INVALID_SOCKET;
360eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell    }
370eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell
380eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell    // First resolve the host and port parameters into a usable network address.
390eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell    struct addrinfo hints;
400eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell    memset(&hints, 0, sizeof(hints));
410eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell    hints.ai_socktype = type;
420eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell
430eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell    struct addrinfo* address = NULL;
440eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell    char port_str[16];
450eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell    snprintf(port_str, sizeof(port_str), "%d", port);
460eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell    if (getaddrinfo(host, port_str, &hints, &address) != 0 || address == NULL) {
470eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell        if (address != NULL) {
480eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell            freeaddrinfo(address);
490eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell        }
500eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell        return INVALID_SOCKET;
510eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell    }
520eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell
530eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell    // Now create and connect the socket.
540eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell    SOCKET sock = socket(address->ai_family, address->ai_socktype,
550eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell                         address->ai_protocol);
560eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell    if (sock == INVALID_SOCKET) {
570eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell        freeaddrinfo(address);
580eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell        return INVALID_SOCKET;
590eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell    }
600eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell
610eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell    if (connect(sock, address->ai_addr, address->ai_addrlen) == SOCKET_ERROR) {
620eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell        closesocket(sock);
630eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell        freeaddrinfo(address);
640eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell        return INVALID_SOCKET;
650eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell    }
660eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell
670eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell    freeaddrinfo(address);
680eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell    return sock;
690eb8e1b706b577194bab1e23fab5b7d20d5259f1David Pursell}
70