#include "net_tools.h" // some code is inspired by https://github.com/millken/c-example/blob/master/epoll-example.c // (which seems to be copied from https://banu.com/blog/2/how-to-use-epoll-a-complete-example-in-c/epoll-example.c ) int create_tcp_client(char* host, char* service) { int err, sock; struct addrinfo conf; struct addrinfo *result, *cursor; memset(&conf, 0, sizeof(struct addrinfo)); conf.ai_family = AF_UNSPEC; conf.ai_socktype = SOCK_STREAM; conf.ai_flags = 0; conf.ai_protocol = 0; err = getaddrinfo(host, service, &conf, &result); if (err != 0) { fprintf(stderr, "Error with getaddrinfo()\n"); exit(EXIT_FAILURE); } for (cursor = result; cursor != NULL; cursor = cursor->ai_next) { sock = socket(cursor->ai_family, cursor->ai_socktype, cursor->ai_protocol); if (sock == -1) continue; if (connect(sock, cursor->ai_addr, cursor->ai_addrlen) != -1) break; close(sock); } if (cursor == NULL) { fprintf(stderr, "No connect worked\n"); exit(EXIT_FAILURE); } freeaddrinfo(result); return sock; } int create_tcp_server(char* service) { int err, sock; struct addrinfo conf; struct addrinfo *result, *cursor; memset(&conf, 0, sizeof(struct addrinfo)); conf.ai_family = AF_INET; // AF_UNSPEC to listen on IPv6 or IPv4 conf.ai_socktype = SOCK_STREAM; conf.ai_flags = 0; // AI_PASSIVE to listen on 0.0.0.0 conf.ai_protocol = 0; err = getaddrinfo(NULL, service, &conf, &result); if (err != 0) { fprintf(stderr, "Error with getaddrinfo()\n"); exit(EXIT_FAILURE); } for (cursor = result; cursor != NULL; cursor = cursor->ai_next) { sock = socket(cursor->ai_family, cursor->ai_socktype, cursor->ai_protocol); if (sock == -1) continue; if (bind(sock, cursor->ai_addr, cursor->ai_addrlen) != -1) break; close(sock); } if (cursor == NULL) { fprintf(stderr, "We failed to bind\n"); exit(EXIT_FAILURE); } freeaddrinfo (result); return sock; } /* * The idea is to get the file descriptor flags * then we add to the bitmask O_NONBLOCK and set the * new bitmask to the socket */ int make_socket_non_blocking(int fd) { int err, flags; flags = fcntl (fd, F_GETFL); if (flags == -1) { perror("Failed to get socket's flags via fcntl"); return -1; } flags |= O_NONBLOCK; err = fcntl (fd, F_SETFL, flags); if (err != 0) { perror("Failed to set socket's flags via fcntl"); return -1; } return 0; } int read_entity(int fd, void* entity, int size) { int remaining = size; int total_read = 0; while (remaining > 0) { int nread = read(fd, ((char*)entity)+total_read, remaining); if (nread == -1) { return nread; } remaining -= nread; total_read += nread; } return total_read; } void fill_buffer(size_t* written, char* dest, void *src, size_t n) { memcpy(dest+*written, src, n); *written += n; }