| /** @file | |
| A brief file description | |
| @section license License | |
| Licensed to the Apache Software Foundation (ASF) under one | |
| or more contributor license agreements. See the NOTICE file | |
| distributed with this work for additional information | |
| regarding copyright ownership. The ASF licenses this file | |
| to you under the Apache License, Version 2.0 (the | |
| "License"); you may not use this file except in compliance | |
| with the License. You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software | |
| distributed under the License is distributed on an "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| See the License for the specific language governing permissions and | |
| limitations under the License. | |
| */ | |
| #include "proxy/http2/Http2SessionAccept.h" | |
| #include "proxy/http2/Http2ClientSession.h" | |
| #include "iocore/utils/Machine.h" | |
| #include "proxy/IPAllow.h" | |
| namespace | |
| { | |
| DbgCtl dbg_ctl_http2_seq{"http2_seq"}; | |
| } // end anonymous namespace | |
| Http2SessionAccept::Http2SessionAccept(OptionsHandle options, HttpProxyPort *proxy_port) | |
| : HttpSessionAcceptBase(std::move(options), proxy_port) | |
| { | |
| SET_HANDLER(&Http2SessionAccept::mainEvent); | |
| } | |
| Http2SessionAccept::~Http2SessionAccept() = default; | |
| bool | |
| Http2SessionAccept::accept(NetVConnection *netvc, MIOBuffer *iobuf, IOBufferReader *reader) | |
| { | |
| sockaddr const *client_ip = nullptr; | |
| for (int i = 0; i < IpAllow::Subject::MAX_SUBJECTS; ++i) { | |
| if (IpAllow::Subject::PEER == IpAllow::subjects[i]) { | |
| client_ip = netvc->get_effective_remote_addr(); | |
| break; | |
| } else if (IpAllow::Subject::PROXY == IpAllow::subjects[i] && | |
| netvc->get_proxy_protocol_version() != ProxyProtocolVersion::UNDEFINED) { | |
| if (sockaddr const *proxy_ip = netvc->get_proxy_protocol_src_addr(); proxy_ip != nullptr) { | |
| client_ip = proxy_ip; | |
| break; | |
| } | |
| } | |
| } | |
| if (client_ip == nullptr) { | |
| client_ip = netvc->get_remote_addr(); | |
| } | |
| IpAllow::ACL session_acl = IpAllow::match(client_ip, IpAllow::match_key_t::SRC_ADDR); | |
| if (!session_acl.isValid()) { | |
| ip_port_text_buffer ipb; | |
| Warning("HTTP/2 client '%s' prohibited by ip-allow policy", ats_ip_ntop(client_ip, ipb, sizeof(ipb))); | |
| return false; | |
| } | |
| netvc->attributes = this->options().transport_type; | |
| if (dbg_ctl_http2_seq.on()) { | |
| ip_port_text_buffer ipb; | |
| DbgPrint(dbg_ctl_http2_seq, "[HttpSessionAccept2:mainEvent %p] accepted connection from %s transport type = %d", netvc, | |
| ats_ip_nptop(client_ip, ipb, sizeof(ipb)), netvc->attributes); | |
| } | |
| Http2ClientSession *new_session = THREAD_ALLOC_INIT(http2ClientSessionAllocator, this_ethread()); | |
| new_session->acl = std::move(session_acl); | |
| new_session->acceptor = this; | |
| // Pin session to current ET_NET thread | |
| new_session->setThreadAffinity(this_ethread()); | |
| new_session->new_connection(netvc, iobuf, reader); | |
| return true; | |
| } | |
| int | |
| Http2SessionAccept::mainEvent(int event, void *data) | |
| { | |
| ink_release_assert(event == NET_EVENT_ACCEPT || event == EVENT_ERROR); | |
| ink_release_assert((event == NET_EVENT_ACCEPT) ? (data != nullptr) : (1)); | |
| if (event == NET_EVENT_ACCEPT) { | |
| NetVConnection *netvc = static_cast<NetVConnection *>(data); | |
| if (!this->accept(netvc, nullptr, nullptr)) { | |
| netvc->do_io_close(); | |
| } | |
| return EVENT_CONT; | |
| } | |
| // XXX We should hoist the error handling so that all the protocols generate the statistics | |
| // without code duplication. | |
| if (((long)data) == -ECONNABORTED) { | |
| Metrics::Counter::increment(http_rsb.ua_counts_errors_pre_accept_hangups); | |
| // Metrics::Counter::increment(http_rsb.ua_msecs_errors_pre_accept_hangups, 0); // ToDo: This is odd, but we added 0 before as | |
| // well | |
| } | |
| ink_abort("HTTP/2 accept received fatal error: errno = %d", -(static_cast<int>((intptr_t)data))); | |
| return EVENT_CONT; | |
| } |