12c593315Sopenharmony_ci/* 22c593315Sopenharmony_ci * nghttp2 - HTTP/2 C Library 32c593315Sopenharmony_ci * 42c593315Sopenharmony_ci * Copyright (c) 2014 Tatsuhiro Tsujikawa 52c593315Sopenharmony_ci * 62c593315Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining 72c593315Sopenharmony_ci * a copy of this software and associated documentation files (the 82c593315Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 92c593315Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 102c593315Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to 112c593315Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 122c593315Sopenharmony_ci * the following conditions: 132c593315Sopenharmony_ci * 142c593315Sopenharmony_ci * The above copyright notice and this permission notice shall be 152c593315Sopenharmony_ci * included in all copies or substantial portions of the Software. 162c593315Sopenharmony_ci * 172c593315Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 182c593315Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 192c593315Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 202c593315Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 212c593315Sopenharmony_ci * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 222c593315Sopenharmony_ci * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 232c593315Sopenharmony_ci * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 242c593315Sopenharmony_ci */ 252c593315Sopenharmony_ci#include "shrpx_accept_handler.h" 262c593315Sopenharmony_ci 272c593315Sopenharmony_ci#ifdef HAVE_UNISTD_H 282c593315Sopenharmony_ci# include <unistd.h> 292c593315Sopenharmony_ci#endif // HAVE_UNISTD_H 302c593315Sopenharmony_ci 312c593315Sopenharmony_ci#include <cerrno> 322c593315Sopenharmony_ci 332c593315Sopenharmony_ci#include "shrpx_connection_handler.h" 342c593315Sopenharmony_ci#include "shrpx_config.h" 352c593315Sopenharmony_ci#include "shrpx_log.h" 362c593315Sopenharmony_ci#include "util.h" 372c593315Sopenharmony_ci 382c593315Sopenharmony_ciusing namespace nghttp2; 392c593315Sopenharmony_ci 402c593315Sopenharmony_cinamespace shrpx { 412c593315Sopenharmony_ci 422c593315Sopenharmony_cinamespace { 432c593315Sopenharmony_civoid acceptcb(struct ev_loop *loop, ev_io *w, int revent) { 442c593315Sopenharmony_ci auto h = static_cast<AcceptHandler *>(w->data); 452c593315Sopenharmony_ci h->accept_connection(); 462c593315Sopenharmony_ci} 472c593315Sopenharmony_ci} // namespace 482c593315Sopenharmony_ci 492c593315Sopenharmony_ciAcceptHandler::AcceptHandler(const UpstreamAddr *faddr, ConnectionHandler *h) 502c593315Sopenharmony_ci : conn_hnr_(h), faddr_(faddr) { 512c593315Sopenharmony_ci ev_io_init(&wev_, acceptcb, faddr_->fd, EV_READ); 522c593315Sopenharmony_ci wev_.data = this; 532c593315Sopenharmony_ci ev_io_start(conn_hnr_->get_loop(), &wev_); 542c593315Sopenharmony_ci} 552c593315Sopenharmony_ci 562c593315Sopenharmony_ciAcceptHandler::~AcceptHandler() { 572c593315Sopenharmony_ci ev_io_stop(conn_hnr_->get_loop(), &wev_); 582c593315Sopenharmony_ci close(faddr_->fd); 592c593315Sopenharmony_ci} 602c593315Sopenharmony_ci 612c593315Sopenharmony_civoid AcceptHandler::accept_connection() { 622c593315Sopenharmony_ci sockaddr_union sockaddr; 632c593315Sopenharmony_ci socklen_t addrlen = sizeof(sockaddr); 642c593315Sopenharmony_ci 652c593315Sopenharmony_ci#ifdef HAVE_ACCEPT4 662c593315Sopenharmony_ci auto cfd = 672c593315Sopenharmony_ci accept4(faddr_->fd, &sockaddr.sa, &addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC); 682c593315Sopenharmony_ci#else // !HAVE_ACCEPT4 692c593315Sopenharmony_ci auto cfd = accept(faddr_->fd, &sockaddr.sa, &addrlen); 702c593315Sopenharmony_ci#endif // !HAVE_ACCEPT4 712c593315Sopenharmony_ci 722c593315Sopenharmony_ci if (cfd == -1) { 732c593315Sopenharmony_ci switch (errno) { 742c593315Sopenharmony_ci case EINTR: 752c593315Sopenharmony_ci case ENETDOWN: 762c593315Sopenharmony_ci case EPROTO: 772c593315Sopenharmony_ci case ENOPROTOOPT: 782c593315Sopenharmony_ci case EHOSTDOWN: 792c593315Sopenharmony_ci#ifdef ENONET 802c593315Sopenharmony_ci case ENONET: 812c593315Sopenharmony_ci#endif // ENONET 822c593315Sopenharmony_ci case EHOSTUNREACH: 832c593315Sopenharmony_ci case EOPNOTSUPP: 842c593315Sopenharmony_ci case ENETUNREACH: 852c593315Sopenharmony_ci return; 862c593315Sopenharmony_ci case EMFILE: 872c593315Sopenharmony_ci case ENFILE: 882c593315Sopenharmony_ci LOG(WARN) << "acceptor: running out file descriptor; disable acceptor " 892c593315Sopenharmony_ci "temporarily"; 902c593315Sopenharmony_ci conn_hnr_->sleep_acceptor(get_config()->conn.listener.timeout.sleep); 912c593315Sopenharmony_ci return; 922c593315Sopenharmony_ci default: 932c593315Sopenharmony_ci return; 942c593315Sopenharmony_ci } 952c593315Sopenharmony_ci } 962c593315Sopenharmony_ci 972c593315Sopenharmony_ci#ifndef HAVE_ACCEPT4 982c593315Sopenharmony_ci util::make_socket_nonblocking(cfd); 992c593315Sopenharmony_ci util::make_socket_closeonexec(cfd); 1002c593315Sopenharmony_ci#endif // !HAVE_ACCEPT4 1012c593315Sopenharmony_ci 1022c593315Sopenharmony_ci conn_hnr_->handle_connection(cfd, &sockaddr.sa, addrlen, faddr_); 1032c593315Sopenharmony_ci} 1042c593315Sopenharmony_ci 1052c593315Sopenharmony_civoid AcceptHandler::enable() { ev_io_start(conn_hnr_->get_loop(), &wev_); } 1062c593315Sopenharmony_ci 1072c593315Sopenharmony_civoid AcceptHandler::disable() { ev_io_stop(conn_hnr_->get_loop(), &wev_); } 1082c593315Sopenharmony_ci 1092c593315Sopenharmony_ciint AcceptHandler::get_fd() const { return faddr_->fd; } 1102c593315Sopenharmony_ci 1112c593315Sopenharmony_ci} // namespace shrpx 112