diff --git a/oct_networking.c b/oct_networking.c index a481141..9b2f3a8 100644 --- a/oct_networking.c +++ b/oct_networking.c @@ -24,6 +24,55 @@ struct { int sfd; } oct_network_node; +struct { + unsigned int size; + struct oct_network_ab_entry* first; + struct oct_network_ab_entry* last; +} oct_network_ab; + +// Returns a live sfd, need to close eventually +static int oct_network_init_socket(char* addr, char* port) { + int s; + int sfd; + struct addrinfo hints; + struct addrinfo* result; + struct addrinfo* rp; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ + hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ + hints.ai_flags = 0; + hints.ai_protocol = 0; /* Any protocol */ + s = getaddrinfo(oct_network_node.send_addr, oct_network_node.send_port, &hints, &result); + if (s != 0) { + OCT_LOG_WARNING("getaddrinfo failed on %s:%s\n", addr, port); + return -1; + } + + /* getaddrinfo() returns a list of address structures. + Try each address until we successfully connect(2). + If socket(2) (or connect(2)) fails, we (close the socket + and) try the next address. */ + + for (rp = result; rp != NULL; rp = rp->ai_next) { + + sfd = socket(rp->ai_family, rp->ai_socktype, + rp->ai_protocol); + if (sfd == -1) + continue; + + if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) + break; /* Success */ + + close(sfd); + } + freeaddrinfo(result); /* No longer needed */ + if (rp == NULL) { + OCT_LOG_WARNING("Could not connect to %s:%s", addr, port); + return -1; + } + return s; +} + int oct_network_node_init(char* port, lua_State* L) { oct_network_node.needs_recv = 1; oct_network_node.needs_send = 0; @@ -104,45 +153,7 @@ int oct_network_recv_msg() { int oct_network_send_msg() { if (oct_network_node.needs_send) { - int sfd; - int s; - struct addrinfo hints; - struct addrinfo* result; - struct addrinfo* rp; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ - hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ - hints.ai_flags = 0; - hints.ai_protocol = 0; /* Any protocol */ - s = getaddrinfo(oct_network_node.send_addr, oct_network_node.send_port, &hints, &result); - if (s != 0) { - OCT_LOG_WARNING("getaddrinfo failed when sending message"); - return -1; - } - - /* getaddrinfo() returns a list of address structures. - Try each address until we successfully connect(2). - If socket(2) (or connect(2)) fails, we (close the socket - and) try the next address. */ - - for (rp = result; rp != NULL; rp = rp->ai_next) { - - sfd = socket(rp->ai_family, rp->ai_socktype, - rp->ai_protocol); - if (sfd == -1) - continue; - - if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) - break; /* Success */ - - close(sfd); - } - freeaddrinfo(result); /* No longer needed */ - - if (rp == NULL) { /* No address succeeded */ - fprintf(stderr, "Could not connect\n"); - exit(EXIT_FAILURE); - } + int sfd = oct_network_init_socket(oct_network_node.send_addr, oct_network_node.send_port); ssize_t length = strlen(oct_network_node.send_buffer); if (write(sfd, oct_network_node.send_buffer, length) != length) { OCT_LOG_WARNING("Partial write when sending message"); @@ -175,5 +186,23 @@ int oct_network_send_msg_lua(lua_State* L) { strncpy(oct_network_node.send_port, luaL_checkstring(L, -1), NI_MAXSERV); oct_network_node.needs_send = 1; } + return 0; +} + +void oct_network_ab_init() { + oct_network_ab.size = 0; + oct_network_ab.first = NULL; + oct_network_ab.last = NULL; +} + +int oct_network_ab_insert(char* addr, char* port) { + // First create the entry + struct oct_network_ab_entry* e = (struct oct_network_ab_entry*)malloc(sizeof(struct oct_network_ab_entry)); + + // Then, create the socket + // TODO + + + return 0; } diff --git a/oct_networking.h b/oct_networking.h index 282f395..4f2c836 100644 --- a/oct_networking.h +++ b/oct_networking.h @@ -3,6 +3,7 @@ #include #include +#include #define BUFFER_SIZE 1024 #define NUM_BUFFERS 10; @@ -10,12 +11,27 @@ #define OCT_DEFAULT_PORT "20000" +struct oct_network_ab_entry { + int sfd; + char addr[NI_MAXHOST]; + char port[NI_MAXSERV]; + struct oct_network_ab_entry* next; +}; + int oct_network_node_init(char* port, lua_State* L); int oct_network_node_deinit(); + +// These are heavily based off of man 3 getaddrinfo, e.g. at +// https://www.man7.org/linux/man-pages/man3/getaddrinfo.3.html int oct_network_recv_msg(); int oct_network_send_msg(); - int oct_network_recv_msg_lua(lua_State* L); int oct_network_send_msg_lua(lua_State* L); +void oct_network_ab_init(); +int oct_network_ab_insert(char* addr, char* port); +int oct_network_ab_remove(struct oct_network_ab_entry* e); +int oct_network_ab_deinit(); + + #endif