hex

hex.git
git clone git://git.lenczewski.org/hex.git
Log | Files | Refs

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);