network.c (2096B)
1 #include "hexes.h" 2 3 bool 4 network_init(struct network *self, char const *host, char const *port) 5 { 6 assert(self); 7 assert(host); 8 assert(port); 9 10 struct addrinfo hints = { 11 .ai_family = AF_UNSPEC, 12 .ai_socktype = SOCK_STREAM, 13 }, *addrinfo, *ptr; 14 15 int res; 16 if ((res = getaddrinfo(host, port, &hints, &addrinfo))) { 17 dbglog(LOG_ERROR, "Failed to get address info: %s\n", gai_strerror(res)); 18 return false; 19 } 20 21 for (ptr = addrinfo; ptr; ptr = ptr->ai_next) { 22 self->sockfd = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); 23 if (self->sockfd == -1) continue; 24 if (connect(self->sockfd, ptr->ai_addr, ptr->ai_addrlen) != -1) break; 25 close(self->sockfd); 26 } 27 28 freeaddrinfo(addrinfo); 29 30 if (!ptr) { 31 dbglog(LOG_ERROR, "Failed to connect to %s:%s\n", host, port); 32 return false; 33 } 34 35 return true; 36 } 37 38 void 39 network_free(struct network *self) 40 { 41 assert(self); 42 43 close(self->sockfd); 44 } 45 46 bool 47 network_send(struct network *self, struct hex_msg const *msg) 48 { 49 assert(self); 50 assert(msg); 51 52 u8 buf[HEX_MSG_SZ]; 53 54 if (!hex_msg_try_serialise(msg, buf)) return false; 55 56 size_t count = 0; 57 do { 58 ssize_t curr = send(self->sockfd, buf + count, ARRLEN(buf) - count, 0); 59 if (curr <= 0) return false; /* error or socket shutdown */ 60 count += curr; 61 } while (count < ARRLEN(buf)); 62 63 return true; 64 } 65 66 bool 67 network_recv(struct network *self, struct hex_msg *out, enum hex_msg_type *expected, size_t len) 68 { 69 assert(self); 70 assert(out); 71 assert(expected); 72 assert(len); 73 74 u8 buf[HEX_MSG_SZ]; 75 76 size_t count = 0; 77 do { 78 ssize_t curr = recv(self->sockfd, buf + count, ARRLEN(buf) - count, 0); 79 if (curr <= 0) return false; /* error or socket shutdown */ 80 count += curr; 81 } while (count < ARRLEN(buf)); 82 83 struct hex_msg msg; 84 if (!hex_msg_try_deserialise(buf, &msg)) return false; 85 86 for (size_t i = 0; i < len; i++) { 87 if (msg.type == expected[i]) { 88 *out = msg; 89 return true; 90 } 91 } 92 93 return false; 94 } 95 96 extern inline bool 97 hex_msg_try_serialise(struct hex_msg const *msg, u8 out[static HEX_MSG_SZ]); 98 99 extern inline bool 100 hex_msg_try_deserialise(u8 buf[static HEX_MSG_SZ], struct hex_msg *out);