123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- /***********************************************
- File Name: aux.h
- Author: Abby Cin
- Mail: abbytsing@gmail.com
- Created Time: 10/24/20 2:43 PM
- ***********************************************/
-
- #ifndef _CONET_AUX_H_
- #define _CONET_AUX_H_
-
- #include <sys/socket.h>
- #include <sys/epoll.h>
- #include <sys/types.h>
- #include <signal.h>
- #include <errno.h>
- #include <netdb.h>
- #include <string.h>
- #include <unistd.h>
- #include <thread>
- #include <mutex>
- #include <string>
- #include <coroutine>
- #include <vector>
- #include <map>
- #include <iostream>
-
- struct debugger
- {
- debugger(const char* s, int n) { std::cout << s << ':' << n << " => "; }
- template<typename... Args>
- void print(Args&&... args)
- {
- ((std::cout << args << ' '), ...);
- std::cout << '\n';
- }
- };
-
- #define debug(...) debugger(__func__, __LINE__).print(__VA_ARGS__)
-
- using handle_t = std::coroutine_handle<>;
-
- class acceptor;
- class resolver
- {
- friend acceptor;
- int fd_{0};
- explicit resolver(int fd) : fd_{fd} {}
-
- public:
- static resolver from_str(std::string s)
- {
- struct addrinfo hints
- {
- };
- ::memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = 0;
- struct addrinfo* addrs;
-
- auto sep = s.find(':');
- if(sep == std::string::npos)
- {
- throw std::runtime_error("invalid address");
- }
- auto port = s.substr(sep + 1);
- auto domain = s.substr(0, sep);
- if(port.empty() || domain.empty())
- {
- throw std::runtime_error("invalid address");
- }
-
- int r = ::getaddrinfo(domain.data(), port.data(), &hints, &addrs);
- if(r < 0)
- {
- throw std::runtime_error(::gai_strerror(r));
- }
- int fd = 0;
- for(auto p = addrs; p != nullptr; p = p->ai_next)
- {
- fd = ::socket(p->ai_family, p->ai_socktype, p->ai_protocol);
- if(fd == -1)
- {
- continue;
- }
-
- if(::bind(fd, p->ai_addr, p->ai_addrlen) == 0)
- {
- break;
- }
- ::close(fd);
- }
- ::freeaddrinfo(addrs);
- if(fd == 0)
- {
- throw std::runtime_error("can't bind to any interface");
- }
- return resolver{fd};
- }
- };
-
- #endif //_CONET_AUX_H_
|