X-Git-Url: https://git.sesse.net/?p=cubemap;a=blobdiff_plain;f=acceptor.cpp;h=b3cd3c1bd92824d27840ef52a04b95bed22e5c62;hp=32a89fa7670d7221b54e7c98ffa0f8ce7e255abd;hb=d5f3f941faaf113936113fc2105bf59913e9125e;hpb=981cdb79fdbf75ff755c80297d6d0e893d076555 diff --git a/acceptor.cpp b/acceptor.cpp index 32a89fa..b3cd3c1 100644 --- a/acceptor.cpp +++ b/acceptor.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include "acceptor.h" @@ -20,14 +19,15 @@ using namespace std; extern ServerPool *servers; -int create_server_socket(int port, SocketType socket_type) +int create_server_socket(const sockaddr_in6 &addr, SocketType socket_type) { + // NOTE: We set as non-blocking, so the acceptor thread can notice that we want to shut it down. int server_sock; if (socket_type == TCP_SOCKET) { - server_sock = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP); + server_sock = socket(PF_INET6, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP); } else { assert(socket_type == UDP_SOCKET); - server_sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); + server_sock = socket(PF_INET6, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP); } if (server_sock == -1) { log_perror("socket"); @@ -47,18 +47,7 @@ int create_server_socket(int port, SocketType socket_type) exit(1); } - // Set as non-blocking, so the acceptor thread can notice that we want to shut it down. - if (ioctl(server_sock, FIONBIO, &one) == -1) { - log_perror("ioctl(FIONBIO)"); - exit(1); - } - - sockaddr_in6 addr; - memset(&addr, 0, sizeof(addr)); - addr.sin6_family = AF_INET6; - addr.sin6_port = htons(port); - - if (bind(server_sock, reinterpret_cast(&addr), sizeof(addr)) == -1) { + if (bind(server_sock, reinterpret_cast(&addr), sizeof(addr)) == -1) { log_perror("bind"); exit(1); } @@ -72,24 +61,59 @@ int create_server_socket(int port, SocketType socket_type) return server_sock; } + +sockaddr_in6 create_any_address(int port) +{ + sockaddr_in6 sin6; + memset(&sin6, 0, sizeof(sin6)); + sin6.sin6_family = AF_INET6; + sin6.sin6_port = htons(port); + return sin6; +} + +sockaddr_in6 extract_address_from_acceptor_proto(const AcceptorProto &proto) +{ + sockaddr_in6 sin6; + memset(&sin6, 0, sizeof(sin6)); + sin6.sin6_family = AF_INET6; + + if (!proto.addr().empty()) { + int ret = inet_pton(AF_INET6, proto.addr().c_str(), &sin6.sin6_addr); + assert(ret == 1); + } + + sin6.sin6_port = htons(proto.port()); + return sin6; +} -Acceptor::Acceptor(int server_sock, int port) +Acceptor::Acceptor(int server_sock, const sockaddr_in6 &addr, + const string &certificate_chain, const string &private_key) : server_sock(server_sock), - port(port) + addr(addr), + certificate_chain(certificate_chain), + private_key(private_key) { } Acceptor::Acceptor(const AcceptorProto &serialized) : server_sock(serialized.server_sock()), - port(serialized.port()) + addr(extract_address_from_acceptor_proto(serialized)), + certificate_chain(serialized.certificate_chain()), + private_key(serialized.private_key()) { } AcceptorProto Acceptor::serialize() const { + char buf[INET6_ADDRSTRLEN]; + inet_ntop(addr.sin6_family, &addr.sin6_addr, buf, sizeof(buf)); + AcceptorProto serialized; serialized.set_server_sock(server_sock); - serialized.set_port(port); + serialized.set_addr(buf); + serialized.set_port(ntohs(addr.sin6_port)); + serialized.set_certificate_chain(certificate_chain); + serialized.set_private_key(private_key); return serialized; } @@ -101,15 +125,15 @@ void Acceptor::close_socket() void Acceptor::do_work() { while (!should_stop()) { - if (!wait_for_activity(server_sock, POLLIN, NULL)) { + if (!wait_for_activity(server_sock, POLLIN, nullptr)) { continue; } sockaddr_in6 addr; socklen_t addrlen = sizeof(addr); - // Get a new socket. - int sock = accept(server_sock, reinterpret_cast(&addr), &addrlen); + // Get a new socket, and set it as nonblocking. + int sock = accept4(server_sock, reinterpret_cast(&addr), &addrlen, SOCK_NONBLOCK); if (sock == -1 && errno == EINTR) { continue; } @@ -119,22 +143,16 @@ void Acceptor::do_work() continue; } - // Set the socket as nonblocking. - int one = 1; - if (ioctl(sock, FIONBIO, &one) == -1) { - log_perror("ioctl(FIONBIO)"); - exit(1); - } - // Enable TCP_CORK for maximum throughput. In the rare case that the // stream stops entirely, this will cause a small delay (~200 ms) // before the last part is sent out, but that should be fine. + int one = 1; if (setsockopt(sock, SOL_TCP, TCP_CORK, &one, sizeof(one)) == -1) { log_perror("setsockopt(TCP_CORK)"); // Can still continue. } // Pick a server, round-robin, and hand over the socket to it. - servers->add_client(sock); + servers->add_client(sock, this); } }