You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /***********************************************
  2. File Name: aux.h
  3. Author: Abby Cin
  4. Mail: abbytsing@gmail.com
  5. Created Time: 10/24/20 2:43 PM
  6. ***********************************************/
  7. #ifndef _CONET_AUX_H_
  8. #define _CONET_AUX_H_
  9. #include <sys/socket.h>
  10. #include <sys/epoll.h>
  11. #include <sys/types.h>
  12. #include <signal.h>
  13. #include <errno.h>
  14. #include <netdb.h>
  15. #include <string.h>
  16. #include <unistd.h>
  17. #include <thread>
  18. #include <mutex>
  19. #include <string>
  20. #include <coroutine>
  21. #include <vector>
  22. #include <map>
  23. #include <iostream>
  24. struct debugger
  25. {
  26. debugger(const char* s, int n) { std::cout << s << ':' << n << " => "; }
  27. template<typename... Args>
  28. void print(Args&&... args)
  29. {
  30. ((std::cout << args << ' '), ...);
  31. std::cout << '\n';
  32. }
  33. };
  34. #define debug(...) debugger(__func__, __LINE__).print(__VA_ARGS__)
  35. using handle_t = std::coroutine_handle<>;
  36. class acceptor;
  37. class resolver
  38. {
  39. friend acceptor;
  40. int fd_{0};
  41. explicit resolver(int fd) : fd_{fd} {}
  42. public:
  43. static resolver from_str(std::string s)
  44. {
  45. struct addrinfo hints
  46. {
  47. };
  48. ::memset(&hints, 0, sizeof(hints));
  49. hints.ai_family = AF_UNSPEC;
  50. hints.ai_socktype = SOCK_STREAM;
  51. hints.ai_protocol = 0;
  52. struct addrinfo* addrs;
  53. auto sep = s.find(':');
  54. if(sep == std::string::npos)
  55. {
  56. throw std::runtime_error("invalid address");
  57. }
  58. auto port = s.substr(sep + 1);
  59. auto domain = s.substr(0, sep);
  60. if(port.empty() || domain.empty())
  61. {
  62. throw std::runtime_error("invalid address");
  63. }
  64. int r = ::getaddrinfo(domain.data(), port.data(), &hints, &addrs);
  65. if(r < 0)
  66. {
  67. throw std::runtime_error(::gai_strerror(r));
  68. }
  69. int fd = 0;
  70. for(auto p = addrs; p != nullptr; p = p->ai_next)
  71. {
  72. fd = ::socket(p->ai_family, p->ai_socktype, p->ai_protocol);
  73. if(fd == -1)
  74. {
  75. continue;
  76. }
  77. if(::bind(fd, p->ai_addr, p->ai_addrlen) == 0)
  78. {
  79. break;
  80. }
  81. ::close(fd);
  82. }
  83. ::freeaddrinfo(addrs);
  84. if(fd == 0)
  85. {
  86. throw std::runtime_error("can't bind to any interface");
  87. }
  88. return resolver{fd};
  89. }
  90. };
  91. #endif //_CONET_AUX_H_