inet.c 1.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. // SPDX-License-Identifier: GPL-2.0 or GPL-3.0
  2. // Copyright © 2018-2019 Ariadne Devos
  3. /* sHT -- connect to the Internet via Unix APIs */
  4. #include "fd.h"
  5. #include <sHT/compiler.h>
  6. #include <sHT/test.h>
  7. #include <errno.h>
  8. #include <netinet/in.h>
  9. #include <sys/socket.h>
  10. static const int sHT_true = 1;
  11. static int
  12. sHT_enable_sockopt(int fd, int layer, int flag)
  13. {
  14. return setsockopt(fd, layer, flag, &sHT_true, sizeof(sHT_true));
  15. }
  16. int
  17. sHT_passive_ipv6(const struct sHT_passive_in6 *in)
  18. {
  19. int fd = socket(AF_INET6, in->type, 0);
  20. if (sHT_lt0(fd))
  21. return -errno;
  22. int ret = sHT_enable_sockopt(fd, IPPROTO_IP, IP_FREEBIND);
  23. if (sHT_nonzero_p(ret))
  24. goto socket;
  25. ret = sHT_enable_sockopt(fd, SOL_SOCKET, SO_REUSEPORT);
  26. if (sHT_nonzero_p(ret))
  27. goto socket;
  28. /* XXX SO_ATTACH_BPF (seccomp filtering) */
  29. ret = bind(fd, (struct sockaddr *) &in->addr, sizeof(in->addr));
  30. if (sHT_lt0(ret))
  31. goto socket;
  32. ret = listen(fd, in->backlog);
  33. if (sHT_lt0(ret))
  34. goto socket;
  35. return fd;
  36. socket:
  37. ret = -errno;
  38. sHT_close(fd);
  39. return ret;
  40. }