| /** @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. |
| */ |
| |
| /**************************************************************************** |
| |
| NetVConnection.cc |
| |
| This file implements an I/O Processor for network I/O. |
| |
| |
| ****************************************************************************/ |
| |
| #include "iocore/net/NetVConnection.h" |
| #include "iocore/eventsystem/IOBuffer.h" |
| #include "tsutil/DbgCtl.h" |
| #include "tsutil/LocalBuffer.h" |
| #include <swoc/TextView.h> |
| #include <algorithm> |
| |
| namespace |
| { |
| |
| // 1024 bytes should be more than enough in the vast majority of |
| // circumstances. proxy.config.proxy_protocol.max_header_size defaults |
| // to 109 bytes. If somehow this is exceeded, LocalBuffer will allocate |
| // space on the heap. |
| static constexpr size_t PROXY_PROTOCOL_LOCAL_BUFFER_SIZE = 1024; |
| |
| DbgCtl dbg_ctl_ssl{"ssl"}; |
| |
| } // end anonymous namespace |
| |
| //// |
| // NetVConnection |
| // |
| |
| /** |
| PROXY Protocol preface check with IOBufferReader. |
| */ |
| bool |
| NetVConnection::has_proxy_protocol_preface(IOBufferReader *reader) const |
| { |
| if (reader == nullptr) { |
| return false; |
| } |
| |
| swoc::TextView tv; |
| |
| char preface[PPv2_CONNECTION_HEADER_LEN]; |
| tv.assign(preface, reader->memcpy(preface, sizeof(preface), 0)); |
| return proxy_protocol_detect(tv); |
| } |
| |
| /** |
| PROXY Protocol preface check with a raw buffer. |
| */ |
| bool |
| NetVConnection::has_proxy_protocol_preface(const char *buffer, int64_t bytes_r) const |
| { |
| if (buffer == nullptr || bytes_r <= 0) { |
| return false; |
| } |
| |
| swoc::TextView tv; |
| tv.assign(buffer, static_cast<size_t>(bytes_r)); |
| return proxy_protocol_detect(tv); |
| } |
| |
| /** |
| PROXY Protocol check with IOBufferReader |
| |
| If the buffer has PROXY Protocol, it will be consumed by this function. |
| */ |
| bool |
| NetVConnection::has_proxy_protocol(IOBufferReader *reader, int max_header_size) |
| { |
| swoc::TextView tv; |
| |
| if (!this->has_proxy_protocol_preface(reader)) { |
| return false; |
| } |
| |
| auto const bufsize = std::min<int64_t>(max_header_size, reader->read_avail()); |
| ts::LocalBuffer<char, PROXY_PROTOCOL_LOCAL_BUFFER_SIZE> buf(static_cast<size_t>(bufsize)); |
| tv.assign(buf.data(), reader->memcpy(buf.data(), bufsize, 0)); |
| |
| size_t len = proxy_protocol_parse(&this->pp_info, tv); |
| |
| if (len > 0) { |
| reader->consume(len); |
| return true; |
| } |
| |
| return false; |
| } |
| |
| /** |
| PROXY Protocol check with buffer |
| |
| If the buffer has PROXY Protocol, it will be consumed by this function. |
| */ |
| bool |
| NetVConnection::has_proxy_protocol(char *buffer, int64_t *bytes_r) |
| { |
| swoc::TextView tv; |
| tv.assign(buffer, *bytes_r); |
| |
| size_t len = proxy_protocol_parse(&this->pp_info, tv); |
| |
| if (len <= 0) { |
| *bytes_r = -EAGAIN; |
| return false; |
| } |
| |
| *bytes_r -= len; |
| if (*bytes_r <= 0) { |
| *bytes_r = -EAGAIN; |
| } else { |
| Dbg(dbg_ctl_ssl, "Moving %" PRId64 " characters remaining in the buffer from %p to %p", *bytes_r, buffer + len, buffer); |
| memmove(buffer, buffer + len, *bytes_r); |
| } |
| |
| return true; |
| } |
| |
| //// |
| // NetVCOptions |
| // |
| std::string_view |
| NetVCOptions::get_proto_string() const |
| { |
| switch (ip_proto) { |
| case USE_TCP: |
| return IP_PROTO_TAG_TCP; |
| case USE_UDP: |
| return IP_PROTO_TAG_UDP; |
| default: |
| break; |
| } |
| return {}; |
| } |
| |
| std::string_view |
| NetVCOptions::get_family_string() const |
| { |
| switch (ip_family) { |
| case AF_INET: |
| return IP_PROTO_TAG_IPV4; |
| case AF_INET6: |
| return IP_PROTO_TAG_IPV6; |
| default: |
| break; |
| } |
| return {}; |
| } |