#include #include #include #include #include #include #include #include #include #include "oct_networking.h" struct { int needs_recv; char recv_buffer[BUFFER_SIZE]; //char recv_from[NI_MAXHOST]; int needs_send; char send_buffer[BUFFER_SIZE]; int sfd; } oct_network_node; int oct_network_node_init(char* port, lua_State* L) { oct_network_node.needs_recv = 1; oct_network_node.needs_send = 0; struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; // ipv4 or ipv6 hints.ai_socktype = SOCK_DGRAM; // datagram hints.ai_flags = AI_PASSIVE; // any IP address hints.ai_protocol = 0; // any protocol hints.ai_canonname = NULL; hints.ai_addr = NULL; hints.ai_next = NULL; struct addrinfo* result; int s = getaddrinfo(NULL, port, &hints, &result); if (s != 0) { //fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s)); return 0; } /* getaddrinfo() returns a list of address structures. Try each address until we successfully bind(2). If socket(2) (or bind(2)) fails, we (close the socket and) try the next address. */ struct addrinfo *rp; for (rp = result; rp != NULL; rp = rp->ai_next) { oct_network_node.sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (oct_network_node.sfd == -1) continue; if (bind(oct_network_node.sfd, rp->ai_addr, rp->ai_addrlen) == 0) break; /* Success */ close(oct_network_node.sfd); } freeaddrinfo(result); if (!rp) { return 0; } lua_pushcfunction(L, oct_network_recv_msg_lua); lua_setglobal(L, "oct_recv"); lua_pushcfunction(L, oct_network_send_msg_lua); lua_setglobal(L, "oct_send"); return 1; } // This runs every loop, filling the receive buffer if needed int oct_network_recv_msg() { if (oct_network_node.needs_recv) { struct sockaddr_storage peer_addr; socklen_t peer_addrlen = 0; // init is needed to make valgrind happy // recvfrom returns -1 if nothing was received // Need MSG_DONTWAIT flag for nonblocking if (recvfrom(oct_network_node.sfd, oct_network_node.recv_buffer, BUFFER_SIZE, MSG_DONTWAIT, (struct sockaddr *) &peer_addr, &peer_addrlen) > 0) { oct_network_node.needs_recv = 0; } } return 0; } int oct_network_send_msg() { return 0; } int oct_network_recv_msg_lua(lua_State* L) { if (!oct_network_node.needs_recv) { lua_pushstring(L, oct_network_node.recv_buffer); oct_network_node.needs_recv = 1; } else { lua_pushstring(L, ""); } return 1; } int oct_network_send_msg_lua(lua_State* L) { return 0; }