diff --git a/src/net.c b/src/net.c index d1bd458..e1d03bd 100644 --- a/src/net.c +++ b/src/net.c @@ -2,76 +2,108 @@ #include #include +#include -#include +int net_client_init(net_t *const n, const char *const raddr, const char *const rport) { + struct addrinfo hints, *ri, *cri; -int net_client_init(net_t *const n, const int af_family, const char *const raddr, const int rport) { - if ((n->fd = socket(af_family, SOCK_DGRAM, 0)) == -1 ) + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + + if (getaddrinfo(raddr, rport, &hints, &ri) != 0) return -1; - memset(&n->inaddr, 0, sizeof(n->inaddr)); - n->inaddr_len = sizeof(n->inaddr); + for (cri = ri; cri != NULL; cri = cri->ai_next) { + if ((n->fd = socket(cri->ai_family, cri->ai_socktype, cri->ai_protocol)) == -1) + continue; - memset(&n->raddr, 0, sizeof(n->raddr)); - n->raddr.sin_family = af_family; - n->raddr.sin_addr.s_addr = inet_addr(raddr); - n->raddr.sin_port = htons(rport); - return 0; -} + break; + } -int net_server_init(net_t *const n, const int af_family, const char *const laddr, const int lport) { - if ((n->fd = socket(af_family, SOCK_DGRAM, 0)) == -1 ) + if (cri == NULL) { + freeaddrinfo(ri); return -1; + } memset(&n->inaddr, 0, sizeof(n->inaddr)); n->inaddr_len = sizeof(n->inaddr); memset(&n->laddr, 0, sizeof(n->laddr)); - n->laddr.sin_family = af_family; - n->laddr.sin_addr.s_addr = inet_addr(laddr); - n->laddr.sin_port = htons(lport); memset(&n->raddr, 0, sizeof(n->raddr)); - n->raddr_len = sizeof(n->raddr); + memcpy(&n->raddr, cri->ai_addr, sizeof(n->raddr)); - if (bind(n->fd, (struct sockaddr *)&n->laddr, sizeof(n->laddr)) == -1) + freeaddrinfo(ri); + + return 0; +} + +int net_server_init(net_t *const n, const char *const laddr, const char *const lport) { + struct addrinfo hints, *li, *cli; + int reuseaddr = 1; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_PASSIVE; + + if (getaddrinfo(laddr, lport, &hints, &li) != 0) return -1; + for (cli = li; cli != NULL; cli = cli->ai_next) { + if ((n->fd = socket(cli->ai_family, cli->ai_socktype, cli->ai_protocol)) == -1) + continue; + + if (setsockopt(n->fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr)) == -1) { + close(n->fd); + continue; + } + + if (bind(n->fd, cli->ai_addr, cli->ai_addrlen) == -1) { + close(n->fd); + continue; + } + + break; + } + + memset(&n->inaddr, 0, sizeof(n->inaddr)); + n->inaddr_len = 0; + + memset(&n->raddr, 0, sizeof(n->raddr)); + + memset(&n->laddr, 0, sizeof(n->laddr)); + memcpy(&n->laddr, cli->ai_addr, sizeof(n->raddr)); + + freeaddrinfo(li); + return 0; } void net_destroy(net_t *n) { - if (n->fd > 0) { + if (n->fd != -1) { close(n->fd); n->fd = -1; } memset(&n->raddr, 0, sizeof(n->raddr)); - n->raddr_len = sizeof(n->raddr); + n->raddr_len = 0; memset(&n->laddr, 0, sizeof(n->laddr)); + memset(&n->inaddr, 0, sizeof(n->inaddr)); + n->inaddr_len = 0; } ssize_t net_send(net_t *const n, const char *const buf, int buf_len) { - if (n->fd == -1 || n->raddr.sin_addr.s_addr == 0) + if (n->fd == -1 || n->raddr.sa_family == AF_UNSPEC) return -1; - if (sendto(n->fd, buf, buf_len, 0, (struct sockaddr *)&n->raddr, sizeof(n->raddr)) == -1) - return -1; - - return 0; + return sendto(n->fd, buf, buf_len, 0, &n->raddr, sizeof(n->raddr)); } ssize_t net_recv(net_t *const n, void *const buf, size_t buf_len) { - if (n->fd == -1 || n->raddr.sin_addr.s_addr == 0) + if (n->fd == -1) return -1; - if ((recvfrom(n->fd, buf, buf_len, 0, (struct sockaddr *)&n->inaddr, &n->inaddr_len)) == -1) - return -1; - - if (n->raddr.sin_addr.s_addr != n->inaddr.sin_addr.s_addr) { - /* Incoming packet doesn't originate from the one we are talking to. Drop it. */ - return 0; - } - - return 0; + return recvfrom(n->fd, buf, buf_len, 0, &n->inaddr, &n->inaddr_len); }