00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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 ) { return; }
00115 virtual bool getSSLHandshakeWantsRead() { return false; }
00116 virtual void setSSLHandshakeWantsWrite(bool ) { 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
00125
00126
00127
00128
00129
00130
00131
00132
00133
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
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
00150
00151
00152
00153 UnixNetVConnection();
00154
00155 private:
00156 UnixNetVConnection(const NetVConnection &);
00157 UnixNetVConnection & operator =(const NetVConnection &);
00158
00159 public:
00160
00161
00162
00163
00164 void set_enabled(VIO *vio);
00165
00166 void get_local_sa();
00167
00168
00169
00170
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
00220 IpEndpoint server_addr;
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
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