| /** @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. |
| */ |
| |
| /**************************************************************************** |
| |
| I_UDPPacket.h |
| UDPPacket interface |
| |
| |
| ****************************************************************************/ |
| |
| #pragma once |
| |
| #include "iocore/eventsystem/IOBuffer.h" |
| #include "iocore/net/UDPConnection.h" |
| |
| struct UDPPacketInternal { |
| // packet scheduling stuff: keep it a doubly linked list |
| uint64_t pktLength = 0; |
| uint16_t segment_size = 0; |
| |
| int reqGenerationNum = 0; |
| ink_hrtime delivery_time = 0; // when to deliver packet |
| #ifdef HAVE_SO_TXTIME |
| struct timespec send_at; |
| #endif |
| |
| Ptr<IOBufferBlock> chain; |
| Continuation *cont = nullptr; // callback on error |
| UDPConnection *conn = nullptr; // connection where packet should be sent to. |
| |
| int in_the_priority_queue = 0; |
| int in_heap = 0; |
| }; |
| |
| /** @name UDPPacket |
| UDP packet functions used by UDPConnection |
| */ |
| //@{ |
| /** |
| UDP data with destination |
| */ |
| class UDPPacket |
| { |
| friend class UDPQueue; |
| friend class PacketQueue; |
| friend class UDPConnection; |
| friend class UnixUDPConnection; |
| |
| public: |
| UDPPacket(); |
| ~UDPPacket(); |
| void free(); // fast deallocate |
| |
| void setContinuation(Continuation *c); |
| void setConnection(UDPConnection *c); |
| UDPConnection *getConnection(); |
| IOBufferBlock *getIOBlockChain(); |
| int64_t getPktLength(); |
| uint8_t *get_entire_chain_buffer(size_t *buf_len); |
| |
| /** |
| Add IOBufferBlock (chain) to end of packet. |
| @param block block chain to add. |
| */ |
| void append_block(IOBufferBlock *block); |
| |
| IpEndpoint from; // what address came from |
| IpEndpoint to; // what address to send to |
| |
| LINK(UDPPacket, link); |
| // Factory (static) methods |
| |
| /** |
| Create a new packet to be sent over UDPConnection. Packet has no |
| destination or data. |
| */ |
| static UDPPacket *new_UDPPacket(); |
| |
| /** |
| Create a new packet to be sent over UDPConnection. This actually |
| copies data from a buffer. |
| |
| @param to address of where to send packet |
| @param when ink_hrtime relative to ink_get_hrtime() |
| @param buf IOBufferBlock chain of data to use |
| @param segment_size Segment size |
| */ |
| static UDPPacket *new_UDPPacket(struct sockaddr const *to, ink_hrtime when, Ptr<IOBufferBlock> &buf, uint16_t segment_size = 0, |
| struct timespec *send_at_hint = nullptr); |
| |
| /** |
| Create a new packet to be delivered to application. |
| Internal function only |
| */ |
| static UDPPacket *new_incoming_UDPPacket(struct sockaddr *from, struct sockaddr *to, Ptr<IOBufferBlock> block); |
| |
| private: |
| SLINK(UDPPacket, alink); // atomic link |
| UDPPacketInternal p; |
| ats_unique_buf _payload{nullptr}; |
| }; |
| |
| // Inline definitions |
| |
| inline void |
| UDPPacket::setContinuation(Continuation *c) |
| { |
| p.cont = c; |
| } |
| |
| inline void |
| UDPPacket::setConnection(UDPConnection *c) |
| { |
| /*Code reviewed by Case Larsen. Previously, we just had |
| ink_assert(!conn). This prevents tunneling of packets |
| correctly---that is, you get packets from a server on a udp |
| conn. and want to send it to a player on another connection, the |
| assert will prevent that. The "if" clause enables correct |
| handling of the connection ref. counts in such a scenario. */ |
| |
| if (p.conn) { |
| if (p.conn == c) { |
| return; |
| } |
| p.conn->Release(); |
| p.conn = nullptr; |
| } |
| p.conn = c; |
| p.conn->AddRef(); |
| } |
| |
| inline UDPConnection * |
| UDPPacket::getConnection() |
| { |
| return p.conn; |
| } |
| |
| inline IOBufferBlock * |
| UDPPacket::getIOBlockChain() |
| { |
| return p.chain.get(); |
| } |