universe@1: /* universe@1: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. universe@1: * universe@1: * Copyright 2014 Mike Becker. All rights reserved. universe@1: * universe@1: * Redistribution and use in source and binary forms, with or without universe@1: * modification, are permitted provided that the following conditions are met: universe@1: * universe@1: * 1. Redistributions of source code must retain the above copyright universe@1: * notice, this list of conditions and the following disclaimer. universe@1: * universe@1: * 2. Redistributions in binary form must reproduce the above copyright universe@1: * notice, this list of conditions and the following disclaimer in the universe@1: * documentation and/or other materials provided with the distribution. universe@1: * universe@1: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" universe@1: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE universe@1: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE universe@1: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE universe@1: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR universe@1: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF universe@1: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS universe@1: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN universe@1: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) universe@1: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE universe@1: * POSSIBILITY OF SUCH DAMAGE. universe@1: * universe@1: */ universe@1: universe@1: #include universe@1: #include universe@1: #include "network.h" universe@1: universe@1: int server_bind(Server *server) { universe@1: server->fd = socket(server->info->ai_family, universe@1: server->info->ai_socktype, server->info->ai_protocol); universe@1: if (server->fd > -1) { universe@1: int true = 1; universe@1: setsockopt(server->fd, SOL_SOCKET, SO_REUSEADDR, &true, sizeof(int)); universe@1: if (bind(server->fd, universe@1: server->info->ai_addr, server->info->ai_addrlen)) { universe@1: server->fd = -1; universe@1: return 1; universe@1: } else { universe@1: return 0; universe@1: } universe@1: } else { universe@1: return 1; universe@1: } universe@1: } universe@1: universe@1: int net_create(Server *server, char* port) { universe@1: return net_find(server, "localhost", port) || server_bind(server); universe@1: } universe@1: universe@1: int getaddrinfo_intrnl(char *host, char *port, struct addrinfo **info) { universe@1: struct addrinfo hints; universe@1: memset(&hints, 0, sizeof(hints)); universe@1: hints.ai_socktype = SOCK_STREAM; universe@1: hints.ai_protocol = IPPROTO_TCP; universe@1: universe@1: return getaddrinfo(host, port, &hints, info); universe@1: } universe@1: universe@1: int net_find(Server *server, char *host, char* port) { universe@1: memset(server, 0, sizeof(Server)); universe@1: server->fd = -1; universe@1: universe@1: return getaddrinfo_intrnl(host, port, &(server->info)); universe@1: } universe@1: universe@1: int net_listen(Server *server) { universe@1: listen(server->fd, 1); universe@1: Client* client = calloc(1, sizeof(Client)); universe@1: client->fd = -1; universe@1: server->client = client; universe@1: universe@1: client->fd = accept(server->fd, universe@1: &(client->address), &(client->address_len)); universe@1: universe@1: return client->fd == -1; universe@1: } universe@1: universe@1: int net_connect(Server *server) { universe@1: struct addrinfo *info; universe@1: if (getaddrinfo_intrnl("localhost", NULL, &info)) { universe@1: return 1; universe@1: } universe@1: universe@1: Client* client = calloc(1, sizeof(Client)); universe@1: client->fd = socket(info->ai_family, info->ai_socktype, info->ai_protocol); universe@1: server->client = client; universe@1: universe@1: freeaddrinfo(info); universe@1: if (client->fd == -1) { universe@1: return 1; universe@1: } universe@1: universe@1: return connect(client->fd, server->info->ai_addr, server->info->ai_addrlen); universe@1: } universe@1: universe@1: int net_destroy(Server *server) { universe@1: if (server->info) { universe@1: freeaddrinfo(server->info); universe@1: } universe@1: if (server->client) { universe@1: shutdown(server->client->fd, SHUT_RDWR); universe@1: free(server->client); universe@1: } universe@1: if (server->fd > -1) { universe@1: return shutdown(server->fd, SHUT_RDWR); universe@1: } universe@1: universe@1: return EXIT_SUCCESS; universe@1: }