universe@1: /* universe@1: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. universe@1: * universe@55: * Copyright 2016 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@2: #define new_socket() socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); universe@2: universe@2: int net_create(Server *server, char* port) { universe@2: server->info = NULL; universe@2: universe@2: struct sockaddr_in addr; universe@2: addr.sin_family = AF_INET; universe@2: addr.sin_addr.s_addr = INADDR_ANY; universe@2: addr.sin_port = htons(atoi(port)); universe@2: universe@2: server->fd = new_socket(); universe@1: if (server->fd > -1) { universe@1: int true = 1; universe@1: setsockopt(server->fd, SOL_SOCKET, SO_REUSEADDR, &true, sizeof(int)); universe@2: if (bind(server->fd, (struct sockaddr*)&addr, sizeof(addr))) { 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@48: static 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@56: Client* client = malloc(sizeof(Client)); universe@1: client->fd = -1; universe@56: client->address_len = sizeof(client->address); 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@2: universe@2: Client* client = calloc(1, sizeof(Client)); universe@2: client->fd = -1; universe@2: server->fd = new_socket(); universe@2: server->client = client; universe@2: universe@2: if (server->fd == -1) { universe@1: return 1; universe@1: } universe@1: universe@2: return connect(server->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@59: return 0; universe@1: } universe@2: universe@22: void net_send_code(int socket, uint8_t code) { universe@22: send(socket, &code, sizeof(uint8_t), 0); universe@3: } universe@3: universe@22: void net_send_data(int socket, uint8_t code, void *data, size_t len) { universe@22: uint8_t pkg[len+1]; universe@22: pkg[0] = code; universe@22: memcpy(pkg+1, data, len); universe@22: send(socket, pkg, len+1, 0); universe@2: } universe@2: universe@22: uint8_t net_recieve_code(int socket) { universe@22: uint8_t code; universe@46: if (recv(socket, &code, sizeof(code), 0) == sizeof(code)) { universe@46: return code; universe@46: } else { universe@46: return NETCODE_CONNLOST; universe@46: } universe@2: } universe@2: universe@2: void net_recieve_data(int socket, void *data, size_t len) { universe@45: recv(socket, data, len, MSG_WAITALL); universe@2: }