Listen both IPv4 and IPv6 sockets.
This commit is contained in:
parent
6d35f7e470
commit
f11c2a94b4
|
@ -118,6 +118,10 @@ private:
|
||||||
bool mark_del_;
|
bool mark_del_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void on_close(Sessions &sessions, EventHandler *hd);
|
||||||
|
} // namespace
|
||||||
|
|
||||||
class Sessions {
|
class Sessions {
|
||||||
public:
|
public:
|
||||||
Sessions(int max_events, SSL_CTX *ssl_ctx)
|
Sessions(int max_events, SSL_CTX *ssl_ctx)
|
||||||
|
@ -126,6 +130,11 @@ public:
|
||||||
{}
|
{}
|
||||||
~Sessions()
|
~Sessions()
|
||||||
{
|
{
|
||||||
|
for(std::set<EventHandler*>::iterator i = handlers_.begin(),
|
||||||
|
eoi = handlers_.end(); i != eoi; ++i) {
|
||||||
|
on_close(*this, *i);
|
||||||
|
delete *i;
|
||||||
|
}
|
||||||
SSL_CTX_free(ssl_ctx_);
|
SSL_CTX_free(ssl_ctx_);
|
||||||
}
|
}
|
||||||
void add_handler(EventHandler *handler)
|
void add_handler(EventHandler *handler)
|
||||||
|
@ -829,21 +838,37 @@ int reactor()
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, 0);
|
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, 0);
|
||||||
int sfd = make_listen_socket(config.port);
|
|
||||||
if(sfd == -1) {
|
|
||||||
std::cerr << "Could not listen on port " << config.port << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
make_non_block(sfd);
|
|
||||||
|
|
||||||
const size_t MAX_EVENTS = 256;
|
const size_t MAX_EVENTS = 256;
|
||||||
Sessions sessions(MAX_EVENTS, ssl_ctx);
|
Sessions sessions(MAX_EVENTS, ssl_ctx);
|
||||||
|
|
||||||
|
int families[] = { AF_INET, AF_INET6 };
|
||||||
|
bool bind_ok = false;
|
||||||
|
for(int i = 0; i < 2; ++i) {
|
||||||
|
const char* ipv = (families[i] == AF_INET ? "IPv4" : "IPv6");
|
||||||
|
int sfd = make_listen_socket(config.port, families[i]);
|
||||||
|
if(sfd == -1) {
|
||||||
|
std::cerr << ipv << ": Could not listen on port " << config.port
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
make_non_block(sfd);
|
||||||
|
|
||||||
ListenEventHandler *listen_hd = new ListenEventHandler(sfd);
|
ListenEventHandler *listen_hd = new ListenEventHandler(sfd);
|
||||||
if(sessions.add_poll(listen_hd) == -1) {
|
if(sessions.add_poll(listen_hd) == -1) {
|
||||||
std::cerr << "Adding listening socket to poll failed." << std::endl;
|
std::cerr << ipv << ": Adding listening socket to poll failed."
|
||||||
return -1;
|
<< std::endl;
|
||||||
|
delete listen_hd;
|
||||||
}
|
}
|
||||||
sessions.add_handler(listen_hd);
|
sessions.add_handler(listen_hd);
|
||||||
|
if(config.verbose) {
|
||||||
|
std::cout << ipv << ": listen on port " << config.port << std::endl;
|
||||||
|
}
|
||||||
|
bind_ok = true;
|
||||||
|
}
|
||||||
|
if(!bind_ok) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<EventHandler*> del_list;
|
std::vector<EventHandler*> del_list;
|
||||||
while(1) {
|
while(1) {
|
||||||
int n = sessions.poll(-1);
|
int n = sessions.poll(-1);
|
||||||
|
@ -880,7 +905,6 @@ int reactor()
|
||||||
del_list.clear();
|
del_list.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
on_close(sessions, listen_hd);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -159,7 +159,7 @@ int connect_to(const std::string& host, uint16_t port)
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int make_listen_socket(uint16_t port)
|
int make_listen_socket(uint16_t port, int family)
|
||||||
{
|
{
|
||||||
addrinfo hints;
|
addrinfo hints;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
|
@ -167,7 +167,7 @@ int make_listen_socket(uint16_t port)
|
||||||
char service[10];
|
char service[10];
|
||||||
snprintf(service, sizeof(service), "%u", port);
|
snprintf(service, sizeof(service), "%u", port);
|
||||||
memset(&hints, 0, sizeof(addrinfo));
|
memset(&hints, 0, sizeof(addrinfo));
|
||||||
hints.ai_family = AF_UNSPEC;
|
hints.ai_family = family;
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
hints.ai_flags = AI_PASSIVE;
|
hints.ai_flags = AI_PASSIVE;
|
||||||
#ifdef AI_ADDRCONFIG
|
#ifdef AI_ADDRCONFIG
|
||||||
|
@ -190,6 +190,16 @@ int make_listen_socket(uint16_t port)
|
||||||
close(fd);
|
close(fd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
#ifdef IPV6_V6ONLY
|
||||||
|
if(family == AF_INET6) {
|
||||||
|
if(setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val,
|
||||||
|
static_cast<socklen_t>(sizeof(val))) == -1) {
|
||||||
|
close(fd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // IPV6_V6ONLY
|
||||||
|
|
||||||
if(bind(fd, rp->ai_addr, rp->ai_addrlen) == 0) {
|
if(bind(fd, rp->ai_addr, rp->ai_addrlen) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ private:
|
||||||
|
|
||||||
int connect_to(const std::string& host, uint16_t port);
|
int connect_to(const std::string& host, uint16_t port);
|
||||||
|
|
||||||
int make_listen_socket(uint16_t port);
|
int make_listen_socket(uint16_t port, int family);
|
||||||
|
|
||||||
int make_non_block(int fd);
|
int make_non_block(int fd);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue