• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

P_UDPPacket.h

Go to the documentation of this file.
00001 /** @file
00002 
00003   A brief file description
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022  */
00023 
00024 /****************************************************************************
00025 
00026   P_UDPPacket.h
00027   Implementation of UDPPacket
00028 
00029  ****************************************************************************/
00030 
00031 
00032 #ifndef __P_UDPPPACKET_H_
00033 #define __P_UDPPPACKET_H_
00034 
00035 #include "I_UDPNet.h"
00036 
00037 class UDPPacketInternal:public UDPPacket
00038 {
00039 
00040 public:
00041   UDPPacketInternal();
00042   virtual ~ UDPPacketInternal();
00043 
00044   void append_block_internal(IOBufferBlock * block);
00045 
00046   virtual void free();
00047 
00048   SLINK(UDPPacketInternal, alink);  // atomic link
00049   // packet scheduling stuff: keep it a doubly linked list
00050   uint64_t pktLength;
00051 
00052   int reqGenerationNum;
00053   ink_hrtime delivery_time;   // when to deliver packet
00054 
00055   Ptr<IOBufferBlock> chain;
00056   Continuation *cont;         // callback on error
00057   UDPConnectionInternal *conn;        // connection where packet should be sent to.
00058 
00059   int in_the_priority_queue;
00060   int in_heap;
00061 };
00062 
00063 inkcoreapi extern ClassAllocator<UDPPacketInternal> udpPacketAllocator;
00064 
00065 TS_INLINE
00066 UDPPacketInternal::UDPPacketInternal()
00067   : pktLength(0), reqGenerationNum(0), delivery_time(0), cont(NULL),
00068     conn(NULL), in_the_priority_queue(0), in_heap(0)
00069 {
00070   memset(&from, '\0', sizeof(from));
00071   memset(&to, '\0', sizeof(to));
00072 }
00073 
00074 TS_INLINE
00075 UDPPacketInternal::~UDPPacketInternal()
00076 {
00077   chain = NULL;
00078 }
00079 
00080 TS_INLINE void
00081 UDPPacketInternal::free()
00082 {
00083   chain = NULL;
00084   if (conn)
00085     conn->Release();
00086   conn = NULL;
00087   udpPacketAllocator.free(this);
00088 }
00089 
00090 TS_INLINE void
00091 UDPPacket::append_block(IOBufferBlock * block)
00092 {
00093   UDPPacketInternal *p = (UDPPacketInternal *) this;
00094 
00095   if (block) {
00096     if (p->chain) {           // append to end
00097       IOBufferBlock *last = p->chain;
00098       while (last->next != NULL) {
00099         last = last->next;
00100       }
00101       last->next = block;
00102     } else {
00103       p->chain = block;
00104     }
00105   }
00106 }
00107 
00108 TS_INLINE int64_t
00109 UDPPacket::getPktLength()
00110 {
00111   UDPPacketInternal *p = (UDPPacketInternal *) this;
00112   IOBufferBlock *b;
00113 
00114   p->pktLength = 0;
00115   b = p->chain;
00116   while (b) {
00117     p->pktLength += b->read_avail();
00118     b = b->next;
00119   }
00120   return p->pktLength;
00121 }
00122 
00123 TS_INLINE void
00124 UDPPacket::free()
00125 {
00126   ((UDPPacketInternal *) this)->free();
00127 }
00128 
00129 TS_INLINE void
00130 UDPPacket::setContinuation(Continuation * c)
00131 {
00132   ((UDPPacketInternal *) this)->cont = c;
00133 }
00134 
00135 TS_INLINE void
00136 UDPPacket::setConnection(UDPConnection * c)
00137 {
00138   /*Code reviewed by Case Larsen.  Previously, we just had
00139      ink_assert(!conn).  This prevents tunneling of packets
00140      correctly---that is, you get packets from a server on a udp
00141      conn. and want to send it to a player on another connection, the
00142      assert will prevent that.  The "if" clause enables correct
00143      handling of the connection ref. counts in such a scenario. */
00144 
00145   UDPConnectionInternal *&conn = ((UDPPacketInternal *) this)->conn;
00146 
00147   if (conn) {
00148     if (conn == c)
00149       return;
00150     conn->Release();
00151     conn = NULL;
00152   }
00153   conn = (UDPConnectionInternal *) c;
00154   conn->AddRef();
00155 }
00156 
00157 TS_INLINE IOBufferBlock *
00158 UDPPacket::getIOBlockChain(void)
00159 {
00160   return ((UDPPacketInternal *) this)->chain;
00161 }
00162 
00163 TS_INLINE UDPConnection *
00164 UDPPacket::getConnection(void)
00165 {
00166   return ((UDPPacketInternal *) this)->conn;
00167 }
00168 
00169 TS_INLINE UDPPacket *
00170 new_UDPPacket(struct sockaddr const* to, ink_hrtime when, char *buf, int len)
00171 {
00172   UDPPacketInternal *p = udpPacketAllocator.alloc();
00173 
00174   p->in_the_priority_queue = 0;
00175   p->in_heap = 0;
00176   p->delivery_time = when;
00177   ats_ip_copy(&p->to, to);
00178 
00179   if (buf) {
00180     IOBufferBlock *body = new_IOBufferBlock();
00181     body->alloc(iobuffer_size_to_index(len));
00182     memcpy(body->end(), buf, len);
00183     body->fill(len);
00184     p->append_block(body);
00185   }
00186 
00187   return p;
00188 }
00189 
00190 TS_INLINE UDPPacket *
00191 new_UDPPacket(struct sockaddr const* to, ink_hrtime when, IOBufferBlock * buf, int len)
00192 {
00193   (void) len;
00194   UDPPacketInternal *p = udpPacketAllocator.alloc();
00195   IOBufferBlock *body;
00196 
00197   p->in_the_priority_queue = 0;
00198   p->in_heap = 0;
00199   p->delivery_time = when;
00200   ats_ip_copy(&p->to, to);
00201 
00202   while (buf) {
00203     body = buf->clone();
00204     p->append_block(body);
00205     buf = buf->next;
00206   }
00207   return p;
00208 }
00209 
00210 TS_INLINE UDPPacket *
00211 new_UDPPacket(struct sockaddr const* to, ink_hrtime when, Ptr<IOBufferBlock> buf)
00212 {
00213   UDPPacketInternal *p = udpPacketAllocator.alloc();
00214 
00215   p->in_the_priority_queue = 0;
00216   p->in_heap = 0;
00217   p->delivery_time = when;
00218   if (to)
00219     ats_ip_copy(&p->to, to);
00220   p->chain = buf;
00221   return p;
00222 }
00223 
00224 TS_INLINE UDPPacket *
00225 new_UDPPacket(ink_hrtime when, Ptr<IOBufferBlock> buf)
00226 {
00227   return new_UDPPacket(NULL, when, buf);
00228 }
00229 
00230 TS_INLINE UDPPacket *
00231 new_incoming_UDPPacket(struct sockaddr * from, char *buf, int len)
00232 {
00233   UDPPacketInternal *p = udpPacketAllocator.alloc();
00234 
00235   p->in_the_priority_queue = 0;
00236   p->in_heap = 0;
00237   p->delivery_time = 0;
00238   ats_ip_copy(&p->from, from);
00239 
00240   IOBufferBlock *body = new_IOBufferBlock();
00241   body->alloc(iobuffer_size_to_index(len));
00242   memcpy(body->end(), buf, len);
00243   body->fill(len);
00244   p->append_block(body);
00245 
00246   return p;
00247 }
00248 
00249 TS_INLINE UDPPacket *
00250 new_UDPPacket()
00251 {
00252   UDPPacketInternal *p = udpPacketAllocator.alloc();
00253   return p;
00254 }
00255 
00256 #endif //__P_UDPPPACKET_H_

Generated by  doxygen 1.7.1