| /** @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/http/HttpSessionAccept.h" | |
| #include "proxy/IPAllow.h" | |
| #include "proxy/http/Http1ClientSession.h" | |
| #include "iocore/utils/Machine.h" | |
| namespace | |
| { | |
| DbgCtl dbg_ctl_http_seq{"http_seq"}; | |
| } // end anonymous namespace | |
| bool | |
| HttpSessionAccept::accept(NetVConnection *netvc, MIOBuffer *iobuf, IOBufferReader *reader) | |
| { | |
| sockaddr const *client_ip = nullptr; | |
| IpAllow::ACL acl; | |
| ip_port_text_buffer ipb; | |
| for (int i = 0; i < IpAllow::Subject::MAX_SUBJECTS; ++i) { | |
| if (IpAllow::Subject::PEER == IpAllow::subjects[i]) { | |
| client_ip = netvc->get_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) { | |
| // Use addresses from peer if none of the configured sources are avaialable | |
| client_ip = netvc->get_remote_addr(); | |
| } | |
| if (ats_is_ip(client_ip)) { | |
| acl = IpAllow::match(client_ip, IpAllow::match_key_t::SRC_ADDR); | |
| if (!acl.isValid()) { // if there's no ACL, it's a hard deny. | |
| Warning("client '%s' prohibited by ip-allow policy", ats_ip_ntop(client_ip, ipb, sizeof(ipb))); | |
| return false; | |
| } | |
| } else { | |
| // If IP address is not available (e.g. UDS), IP-based ACLs are not relevant | |
| acl = IpAllow::makeAllowAllACL(); | |
| } | |
| // Set the transport type if not already set | |
| if (HttpProxyPort::TRANSPORT_NONE == netvc->attributes) { | |
| netvc->attributes = options().transport_type; | |
| } | |
| if (dbg_ctl_http_seq.on()) { | |
| Dbg(dbg_ctl_http_seq, "[HttpSessionAccept:mainEvent %p] accepted connection from %s transport type = %d", netvc, | |
| ats_ip_nptop(client_ip, ipb, sizeof(ipb)), netvc->attributes); | |
| } | |
| Http1ClientSession *new_session = THREAD_ALLOC_INIT(http1ClientSessionAllocator, this_ethread()); | |
| new_session->acceptor = this; | |
| new_session->acl = std::move(acl); | |
| // Pin session to current ET_NET thread | |
| new_session->setThreadAffinity(this_ethread()); | |
| new_session->new_connection(netvc, iobuf, reader); | |
| return true; | |
| } | |
| int | |
| HttpSessionAccept::mainEvent(int event, void *data) | |
| { | |
| NetVConnection *netvc; | |
| 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) { | |
| netvc = static_cast<NetVConnection *>(data); | |
| if (!this->accept(netvc, nullptr, nullptr)) { | |
| netvc->do_io_close(); | |
| } | |
| return EVENT_CONT; | |
| } | |
| ///////////////// | |
| // EVENT_ERROR // | |
| ///////////////// | |
| if (((long)data) == -ECONNABORTED) { | |
| // FIX: add time to user_agent_hangup | |
| Metrics::Counter::increment(http_rsb.ua_counts_errors_pre_accept_hangups); | |
| // Metrics::Counter::increment(http_rsb.ua_msecs_errors_pre_accept_hangups, 0); // ToDo: Weird, but we added 0 here before | |
| } | |
| ink_abort("HTTP accept received fatal error: errno = %d", -(static_cast<int>((intptr_t)data))); | |
| return EVENT_CONT; | |
| } |