Add skeleton for listen and bind TCP sockets
This commit is contained in:
parent
bfc0028755
commit
74024f001f
95
discardd.c
95
discardd.c
@ -12,10 +12,101 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
|
||||||
|
#define nelems(_a) (sizeof((_a)) / sizeof((_a)[0]))
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_listen_address(const struct sockaddr *sa, socklen_t salen, int family)
|
||||||
|
{
|
||||||
|
char host[NI_MAXHOST], serv[NI_MAXSERV];
|
||||||
|
int error;
|
||||||
|
int flags = NI_NUMERICHOST | NI_NUMERICSERV;
|
||||||
|
|
||||||
|
error = getnameinfo(sa, salen, host, NI_MAXHOST, serv, NI_MAXSERV,
|
||||||
|
flags);
|
||||||
|
if (error) {
|
||||||
|
warnx("%s", gai_strerror(error));
|
||||||
|
} else {
|
||||||
|
if (family == AF_INET6)
|
||||||
|
fprintf(stderr, "Listening on [%s]:%s\n", host, serv);
|
||||||
|
else
|
||||||
|
fprintf(stderr, "Listening on %s:%s\n", host, serv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
listen_sock_setup(const char *port, int socktype, int *s, size_t *maxsocks)
|
||||||
|
{
|
||||||
|
struct addrinfo hints, *res, *res0;
|
||||||
|
const char *cause = NULL;
|
||||||
|
int error, save_errno, nsock;
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_socktype = socktype;
|
||||||
|
hints.ai_flags = AI_PASSIVE;
|
||||||
|
|
||||||
|
error = getaddrinfo(NULL, port, &hints, &res0);
|
||||||
|
if (error)
|
||||||
|
errx(1, "%s", gai_strerror(error));
|
||||||
|
|
||||||
|
nsock = 0;
|
||||||
|
for (res = res0; res && nsock < *maxsocks; res = res->ai_next) {
|
||||||
|
s[nsock] = socket(res->ai_family, res->ai_socktype,
|
||||||
|
res->ai_protocol);
|
||||||
|
if (s[nsock] == -1) {
|
||||||
|
cause = "socket";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bind(s[nsock], res->ai_addr, res->ai_addrlen) == -1) {
|
||||||
|
cause = "bind";
|
||||||
|
save_errno = errno;
|
||||||
|
close(s[nsock]);
|
||||||
|
errno = save_errno;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listen(s[nsock], 5) == -1) {
|
||||||
|
cause = "listen";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_listen_address(res->ai_addr, res->ai_addrlen,
|
||||||
|
res->ai_family);
|
||||||
|
nsock++;
|
||||||
|
}
|
||||||
|
if (nsock == 0)
|
||||||
|
err(1, "%s", cause);
|
||||||
|
freeaddrinfo(res0);
|
||||||
|
|
||||||
|
*maxsocks = nsock;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_tcp(const char *port)
|
||||||
|
{
|
||||||
|
int s[8];
|
||||||
|
size_t nsocks = nelems(s);
|
||||||
|
|
||||||
|
listen_sock_setup(port, SOCK_STREAM, s, &nsocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_udp(const char *port)
|
||||||
|
{
|
||||||
|
errx(1, "UDP unimplemented");
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
@ -54,9 +145,9 @@ main(int argc, char *argv[])
|
|||||||
if (do_tcp && do_udp)
|
if (do_tcp && do_udp)
|
||||||
errx(1, "-t and -u are mutually exclusive");
|
errx(1, "-t and -u are mutually exclusive");
|
||||||
if (do_udp)
|
if (do_udp)
|
||||||
errx(1, "UDP unimplemented");
|
handle_udp(port);
|
||||||
if (do_tcp)
|
if (do_tcp)
|
||||||
errx(1, "TCP unimplemented");
|
handle_tcp(port);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user