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

P_UnixNetVConnection.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 
00027   This file implements an I/O Processor for network I/O on Unix.
00028 
00029 
00030  ****************************************************************************/
00031 
00032 #ifndef __P_UNIXNETVCONNECTION_H__
00033 #define __P_UNIXNETVCONNECTION_H__
00034 
00035 #include "ink_sock.h"
00036 #include "I_NetVConnection.h"
00037 #include "P_UnixNetState.h"
00038 #include "P_Connection.h"
00039 
00040 class UnixNetVConnection;
00041 class NetHandler;
00042 struct PollDescriptor;
00043 
00044 TS_INLINE void
00045 NetVCOptions::reset()
00046 {
00047   ip_proto = USE_TCP;
00048   ip_family = AF_INET;
00049   local_ip.invalidate();
00050   local_port = 0;
00051   addr_binding = ANY_ADDR;
00052   f_blocking = false;
00053   f_blocking_connect = false;
00054   socks_support = NORMAL_SOCKS;
00055   socks_version = SOCKS_DEFAULT_VERSION;
00056   socket_recv_bufsize = 
00057 #if defined(RECV_BUF_SIZE)
00058     RECV_BUF_SIZE;
00059 #else
00060     0;
00061 #endif
00062   socket_send_bufsize = 0;
00063   sockopt_flags = 0;
00064   packet_mark = 0;
00065   packet_tos = 0;
00066 
00067   etype = ET_NET;
00068 
00069   ats_free(sni_servername);
00070   sni_servername = NULL;
00071 }
00072 
00073 TS_INLINE void
00074 NetVCOptions::set_sock_param(int _recv_bufsize, int _send_bufsize, unsigned long _opt_flags,
00075                              unsigned long _packet_mark, unsigned long _packet_tos)
00076 {
00077   socket_recv_bufsize = _recv_bufsize;
00078   socket_send_bufsize = _send_bufsize;
00079   sockopt_flags = _opt_flags;
00080   packet_mark = _packet_mark;
00081   packet_tos = _packet_tos;
00082 }
00083 
00084 struct OOB_callback:public Continuation
00085 {
00086   char *data;
00087   int length;
00088   Event *trigger;
00089   UnixNetVConnection *server_vc;
00090   Continuation *server_cont;
00091   int retry_OOB_send(int, Event *);
00092 
00093     OOB_callback(ProxyMutex *m, NetVConnection *vc, Continuation *cont,
00094                  char *buf, int len):Continuation(m), data(buf), length(len), trigger(0)
00095   {
00096     server_vc = (UnixNetVConnection *) vc;
00097     server_cont = cont;
00098     SET_HANDLER(&OOB_callback::retry_OOB_send);
00099   }
00100 };
00101 
00102 class UnixNetVConnection:public NetVConnection
00103 {
00104 public:
00105 
00106   virtual VIO *do_io_read(Continuation *c, int64_t nbytes, MIOBuffer *buf);
00107   virtual VIO *do_io_write(Continuation *c, int64_t nbytes, IOBufferReader *buf, bool owner = false);
00108 
00109   virtual bool get_data(int id, void *data);
00110 
00111   virtual Action *send_OOB(Continuation *cont, char *buf, int len);
00112   virtual void cancel_OOB();
00113 
00114   virtual void setSSLHandshakeWantsRead(bool /* flag */) { return; }
00115   virtual bool getSSLHandshakeWantsRead() { return false; }
00116   virtual void setSSLHandshakeWantsWrite(bool /* flag */) { return; }
00117 
00118   virtual bool getSSLHandshakeWantsWrite() { return false; }
00119 
00120   virtual void do_io_close(int lerrno = -1);
00121   virtual void do_io_shutdown(ShutdownHowTo_t howto);
00122 
00123   ////////////////////////////////////////////////////////////
00124   // Set the timeouts associated with this connection.      //
00125   // active_timeout is for the total elasped time of        //
00126   // the connection.                                        //
00127   // inactivity_timeout is the elapsed time from the time   //
00128   // a read or a write was scheduled during which the       //
00129   // connection  was unable to sink/provide data.           //
00130   // calling these functions repeatedly resets the timeout. //
00131   // These functions are NOT THREAD-SAFE, and may only be   //
00132   // called when handing an  event from this NetVConnection,//
00133   // or the NetVConnection creation callback.               //
00134   ////////////////////////////////////////////////////////////
00135   virtual void set_active_timeout(ink_hrtime timeout_in);
00136   virtual void set_inactivity_timeout(ink_hrtime timeout_in);
00137   virtual void cancel_active_timeout();
00138   virtual void cancel_inactivity_timeout();
00139 
00140   // The public interface is VIO::reenable()
00141   virtual void reenable(VIO *vio);
00142   virtual void reenable_re(VIO *vio);
00143 
00144   virtual SOCKET get_socket();
00145 
00146   virtual ~ UnixNetVConnection();
00147 
00148   /////////////////////////////////////////////////////////////////
00149   // instances of UnixNetVConnection should be allocated         //
00150   // only from the free list using UnixNetVConnection::alloc().  //
00151   // The constructor is public just to avoid compile errors.      //
00152   /////////////////////////////////////////////////////////////////
00153   UnixNetVConnection();
00154 
00155 private:
00156   UnixNetVConnection(const NetVConnection &);
00157   UnixNetVConnection & operator =(const NetVConnection &);
00158 
00159 public:
00160 
00161   /////////////////////////
00162   // UNIX implementation //
00163   /////////////////////////
00164   void set_enabled(VIO *vio);
00165 
00166   void get_local_sa();
00167 
00168   // these are not part of the pure virtual interface.  They were
00169   // added to reduce the amount of duplicate code in classes inherited
00170   // from NetVConnection (SSL).
00171   virtual int sslStartHandShake(int event, int &err) {
00172     (void) event;
00173     (void) err;
00174     return EVENT_ERROR;
00175   }
00176   virtual bool getSSLHandShakeComplete() {
00177     return (true);
00178   }
00179   virtual bool getSSLClientConnection()
00180   {
00181     return (false);
00182   }
00183   virtual void setSSLClientConnection(bool state)
00184   {
00185     (void) state;
00186   }
00187   virtual void net_read_io(NetHandler *nh, EThread *lthread);
00188   virtual int64_t load_buffer_and_write(int64_t towrite, int64_t &wattempted, int64_t &total_wrote, MIOBufferAccessor & buf, int &needs);
00189   void readDisable(NetHandler *nh);
00190   void readSignalError(NetHandler *nh, int err);
00191   int readSignalDone(int event, NetHandler *nh);
00192   int readSignalAndUpdate(int event);
00193   void readReschedule(NetHandler *nh);
00194   void writeReschedule(NetHandler *nh);
00195   void netActivity(EThread *lthread);
00196 
00197   Action action_;
00198   volatile int closed;
00199   NetState read;
00200   NetState write;
00201 
00202   LINK(UnixNetVConnection, cop_link);
00203   LINKM(UnixNetVConnection, read, ready_link)
00204   SLINKM(UnixNetVConnection, read, enable_link)
00205   LINKM(UnixNetVConnection, write, ready_link)
00206   SLINKM(UnixNetVConnection, write, enable_link)
00207 
00208   ink_hrtime inactivity_timeout_in;
00209   ink_hrtime active_timeout_in;
00210 #ifdef INACTIVITY_TIMEOUT
00211   Event *inactivity_timeout;
00212 #else
00213   ink_hrtime next_inactivity_timeout_at;
00214 #endif
00215   Event *active_timeout;
00216   EventIO ep;
00217   NetHandler *nh;
00218   unsigned int id;
00219   // amc - what is this for? Why not use remote_addr or con.addr?
00220   IpEndpoint server_addr; /// Server address and port.
00221 
00222   union
00223   {
00224     unsigned int flags;
00225 #define NET_VC_SHUTDOWN_READ  1
00226 #define NET_VC_SHUTDOWN_WRITE 2
00227     struct
00228     {
00229       unsigned int got_local_addr:1;
00230       unsigned int shutdown:2;
00231     } f;
00232   };
00233 
00234   Connection con;
00235   int recursion;
00236   ink_hrtime submit_time;
00237   OOB_callback *oob_ptr;
00238   bool from_accept_thread;
00239 
00240   int startEvent(int event, Event *e);
00241   int acceptEvent(int event, Event *e);
00242   int mainEvent(int event, Event *e);
00243   virtual int connectUp(EThread *t, int fd);
00244   virtual void free(EThread *t);
00245 
00246   virtual ink_hrtime get_inactivity_timeout();
00247   virtual ink_hrtime get_active_timeout();
00248 
00249   virtual void set_local_addr();
00250   virtual void set_remote_addr();
00251   virtual int set_tcp_init_cwnd(int init_cwnd);
00252   virtual void apply_options();
00253 };
00254 
00255 extern ClassAllocator<UnixNetVConnection> netVCAllocator;
00256 
00257 typedef int (UnixNetVConnection::*NetVConnHandler) (int, void *);
00258 
00259 
00260 TS_INLINE void
00261 UnixNetVConnection::set_remote_addr()
00262 {
00263   ats_ip_copy(&remote_addr, &con.addr);
00264 }
00265 
00266 TS_INLINE void
00267 UnixNetVConnection::set_local_addr()
00268 {
00269   int local_sa_size = sizeof(local_addr);
00270   safe_getsockname(con.fd, &local_addr.sa, &local_sa_size);
00271 }
00272 
00273 TS_INLINE ink_hrtime
00274 UnixNetVConnection::get_active_timeout()
00275 {
00276   return active_timeout_in;
00277 }
00278 
00279 TS_INLINE ink_hrtime
00280 UnixNetVConnection::get_inactivity_timeout()
00281 {
00282   return inactivity_timeout_in;
00283 }
00284 
00285 TS_INLINE void
00286 UnixNetVConnection::set_inactivity_timeout(ink_hrtime timeout)
00287 {
00288   Debug("socket", "Set inactive timeout=%" PRId64 ", for NetVC=%p", timeout, this);
00289   inactivity_timeout_in = timeout;
00290 #ifndef INACTIVITY_TIMEOUT
00291   next_inactivity_timeout_at = ink_get_hrtime() + timeout;
00292 #else
00293   if (inactivity_timeout)
00294     inactivity_timeout->cancel_action(this);
00295   if (inactivity_timeout_in) {
00296     if (read.enabled) {
00297       ink_assert(read.vio.mutex->thread_holding == this_ethread() && thread);
00298       if (read.vio.mutex->thread_holding == thread)
00299         inactivity_timeout = thread->schedule_in_local(this, inactivity_timeout_in);
00300       else
00301         inactivity_timeout = thread->schedule_in(this, inactivity_timeout_in);
00302     } else if (write.enabled) {
00303       ink_assert(write.vio.mutex->thread_holding == this_ethread() && thread);
00304       if (write.vio.mutex->thread_holding == thread)
00305         inactivity_timeout = thread->schedule_in_local(this, inactivity_timeout_in);
00306       else
00307         inactivity_timeout = thread->schedule_in(this, inactivity_timeout_in);
00308     } else
00309       inactivity_timeout = 0;
00310   } else
00311     inactivity_timeout = 0;
00312 #endif
00313 }
00314 
00315 TS_INLINE void
00316 UnixNetVConnection::set_active_timeout(ink_hrtime timeout)
00317 {
00318   Debug("socket", "Set active timeout=%" PRId64 ", NetVC=%p", timeout, this);
00319   active_timeout_in = timeout;
00320   if (active_timeout)
00321     active_timeout->cancel_action(this);
00322   if (active_timeout_in) {
00323     if (read.enabled) {
00324       ink_assert(read.vio.mutex->thread_holding == this_ethread() && thread);
00325       if (read.vio.mutex->thread_holding == thread)
00326         active_timeout = thread->schedule_in_local(this, active_timeout_in);
00327       else
00328         active_timeout = thread->schedule_in(this, active_timeout_in);
00329     } else if (write.enabled) {
00330       ink_assert(write.vio.mutex->thread_holding == this_ethread() && thread);
00331       if (write.vio.mutex->thread_holding == thread)
00332         active_timeout = thread->schedule_in_local(this, active_timeout_in);
00333       else
00334         active_timeout = thread->schedule_in(this, active_timeout_in);
00335     } else
00336       active_timeout = 0;
00337   } else
00338     active_timeout = 0;
00339 }
00340 
00341 TS_INLINE void
00342 UnixNetVConnection::cancel_inactivity_timeout()
00343 {
00344   inactivity_timeout_in = 0;
00345 #ifdef INACTIVITY_TIMEOUT
00346   if (inactivity_timeout) {
00347     Debug("socket", "Cancel inactive timeout for NetVC=%p", this);
00348     inactivity_timeout->cancel_action(this);
00349     inactivity_timeout = NULL;
00350   }
00351 #else
00352   Debug("socket", "Cancel inactive timeout for NetVC=%p", this);
00353   next_inactivity_timeout_at = 0;
00354 #endif
00355 }
00356 
00357 TS_INLINE void
00358 UnixNetVConnection::cancel_active_timeout()
00359 {
00360   if (active_timeout) {
00361     Debug("socket", "Cancel active timeout for NetVC=%p", this);
00362     active_timeout->cancel_action(this);
00363     active_timeout = NULL;
00364     active_timeout_in = 0;
00365   }
00366 }
00367 
00368 TS_INLINE int
00369 UnixNetVConnection::set_tcp_init_cwnd(int init_cwnd)
00370 {
00371 #ifdef TCP_INIT_CWND
00372   int rv;
00373   uint32_t val = init_cwnd;
00374   rv = setsockopt(con.fd, IPPROTO_TCP, TCP_INIT_CWND, &val, sizeof(val));
00375   Debug("socket", "Setting TCP initial congestion window (%d) -> %d", init_cwnd, rv);
00376   return rv;
00377 #else
00378   Debug("socket", "Setting TCP initial congestion window %d -> unsupported", init_cwnd);
00379   return -1;
00380 #endif
00381 }
00382 
00383 TS_INLINE UnixNetVConnection::~UnixNetVConnection() { }
00384 
00385 TS_INLINE SOCKET
00386 UnixNetVConnection::get_socket() {
00387   return con.fd;
00388 }
00389 
00390 // declarations for local use (within the net module)
00391 
00392 void close_UnixNetVConnection(UnixNetVConnection * vc, EThread * t);
00393 void write_to_net(NetHandler * nh, UnixNetVConnection * vc, EThread * thread);
00394 void write_to_net_io(NetHandler * nh, UnixNetVConnection * vc, EThread * thread);
00395 
00396 #endif

Generated by  doxygen 1.7.1