1 /** @file
2 
3   Public VConnection declaration and associated declarations
4 
5   @section license License
6 
7   Licensed to the Apache Software Foundation (ASF) under one
8   or more contributor license agreements.  See the NOTICE file
9   distributed with this work for additional information
10   regarding copyright ownership.  The ASF licenses this file
11   to you under the Apache License, Version 2.0 (the
12   "License"); you may not use this file except in compliance
13   with the License.  You may obtain a copy of the License at
14 
15       http://www.apache.org/licenses/LICENSE-2.0
16 
17   Unless required by applicable law or agreed to in writing, software
18   distributed under the License is distributed on an "AS IS" BASIS,
19   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20   See the License for the specific language governing permissions and
21   limitations under the License.
22 
23  */
24 
25 #if !defined(_I_VConnection_h_)
26 #define _I_VConnection_h_
27 
28 #include "ts/ink_platform.h"
29 #include "I_EventSystem.h"
30 #if !defined(I_VIO_h)
31 #error "include I_VIO.h"
32 ---include I_VIO.h
33 #endif
34 
35 //
36 // Data Types
37 //
38 #define VCONNECTION_CACHE_DATA_BASE 0
39 #define VCONNECTION_NET_DATA_BASE 100
40 #define VCONNECTION_API_DATA_BASE 200
41 
42 //
43 // Event signals
44 //
45 
46 #define VC_EVENT_NONE EVENT_NONE
47 
48 /** When a Continuation is first scheduled on a processor. */
49 #define VC_EVENT_IMMEDIATE EVENT_IMMEDIATE
50 
51 #define VC_EVENT_READ_READY VC_EVENT_EVENTS_START
52 
53 /**
54   Any data in the accociated buffer *will be written* when the
55   Continuation returns.
56 
57 */
58 #define VC_EVENT_WRITE_READY (VC_EVENT_EVENTS_START + 1)
59 
60 #define VC_EVENT_READ_COMPLETE (VC_EVENT_EVENTS_START + 2)
61 #define VC_EVENT_WRITE_COMPLETE (VC_EVENT_EVENTS_START + 3)
62 
63 /**
64   No more data (end of stream). It should be interpreted by a
65   protocol engine as either a COMPLETE or ERROR.
66 
67 */
68 #define VC_EVENT_EOS (VC_EVENT_EVENTS_START + 4)
69 
70 #define VC_EVENT_ERROR EVENT_ERROR
71 
72 /**
73   VC_EVENT_INACTIVITY_TIMEOUT indiates that the operation (read or write) has:
74     -# been enabled for more than the inactivity timeout period
75        (for a read, there has been space in the buffer)
76        (for a write, there has been data in the buffer)
77     -# no progress has been made
78        (for a read, no data has been read from the connection)
79        (for a write, no data has been written to the connection)
80 
81 */
82 #define VC_EVENT_INACTIVITY_TIMEOUT (VC_EVENT_EVENTS_START + 5)
83 
84 /**
85   Total time for some operation has been exeeded, regardless of any
86   intermediate progress.
87 
88 */
89 #define VC_EVENT_ACTIVE_TIMEOUT (VC_EVENT_EVENTS_START + 6)
90 
91 #define VC_EVENT_OOB_COMPLETE (VC_EVENT_EVENTS_START + 7)
92 
93 //
94 // Event names
95 //
96 
97 //
98 // VC_EVENT_READ_READ occurs when data *has been written* into
99 // the associated buffer.
100 //
101 // VC_EVENT_ERROR indicates that some error has occured.  The
102 // "data" will be either 0 if the errno is unavailable or errno.
103 //
104 // VC_EVENT_INTERVAL indidates that an interval timer has expired.
105 //
106 
107 //
108 // Event return codes
109 //
110 #define VC_EVENT_DONE CONTINUATION_DONE
111 #define VC_EVENT_CONT CONTINUATION_CONT
112 
113    //////////////////////////////////////////////////////////////////////////////
114    //
115    //      Support Data Structures
116    //
117    //////////////////////////////////////////////////////////////////////////////
118 
119    /** Used in VConnection::shutdown(). */
120    enum ShutdownHowTo_t {
121      IO_SHUTDOWN_READ = 0,
122      IO_SHUTDOWN_WRITE,
123      IO_SHUTDOWN_READWRITE
124    };
125 
126 /** Used in VConnection::get_data(). */
127 enum TSApiDataType {
128   TS_API_DATA_READ_VIO = VCONNECTION_API_DATA_BASE,
129   TS_API_DATA_WRITE_VIO,
130   TS_API_DATA_OUTPUT_VC,
131   TS_API_DATA_CLOSED,
132   TS_API_DATA_LAST ///< Used by other classes to extend the enum values.
133 };
134 
135 extern "C" {
136 typedef struct tsapi_vio *TSVIO;
137 }
138 
139 /**
140   Base class for the connection classes that provide IO capabilities.
141 
142   The VConnection class is an abstract representation of a uni or
143   bi-directional data conduit returned by a Processor. In a sense,
144   they serve a similar purpose to file descriptors. A VConnection
145   is a pure base class that defines methods to perform stream IO.
146   It is also a Continuation that is called back from processors.
147 
148 */
149 class VConnection : public Continuation
150 {
151 public:
152   virtual ~VConnection();
153 
154   /**
155     Read data from the VConnection.
156 
157     Called by a state machine to read data from the VConnection.
158     Processors implementing read functionality take out lock, put
159     new bytes on the buffer and call the continuation back before
160     releasing the lock in order to enable the state machine to
161     handle transfer schemes where the end of a given transaction
162     is marked by a special character (ie: NNTP).
163 
164     <b>Possible Event Codes</b>
165 
166     On the callback to the continuation, the VConnection may use
167     on of the following values for the event code:
168 
169     <table border="1">
170       <tr>
171         <td align="center"><b>Event code</b></td>
172         <td align="center"><b>Meaning</b></td>
173       </tr>
174       <tr>
175         <td>VC_EVENT_READ_READY</td>
176         <td>Data has been added to the buffer or the buffer is full</td>
177       </tr>
178       <tr>
179         <td>VC_EVENT_READ_COMPLETE</td>
180         <td>The amount of data indicated by 'nbytes' has been read into the
181             buffer</td>
182       </tr>
183       <tr>
184         <td>VC_EVENT_EOS</td>
185         <td>The stream being read from has been shutdown</td>
186       </tr>
187       <tr>
188         <td>VC_EVENT_ERROR</td>
189         <td>An error occurred during the read</td>
190       </tr>
191     </table>
192 
193     @param c Continuation to be called back with events.
194     @param nbytes Number of bytes to read. If unknown, nbytes must
195       be set to INT64_MAX.
196     @param buf buffer to read into.
197     @return VIO representing the scheduled IO operation.
198 
199   */
200   virtual VIO *do_io_read(Continuation *c = nullptr, int64_t nbytes = INT64_MAX, MIOBuffer *buf = 0) = 0;
201 
202   /**
203     Write data to the VConnection.
204 
205     This method is called by a state machine to write data to the
206     VConnection.
207 
208     <b>Possible Event Codes</b>
209 
210     On the callback to the continuation, the VConnection may use
211     on of the following event codes:
212 
213     <table border="1">
214       <tr>
215         <td align="center"><b>Event code</b></td>
216         <td align="center"><b>Meaning</b></td>
217       </tr>
218       <tr>
219         <td>VC_EVENT_WRITE_READY</td>
220         <td>Data was written from the reader or there are no bytes available
221         for the reader to write.</td>
222       </tr>
223       <tr>
224         <td>VC_EVENT_WRITE_COMPLETE</td>
225         <td>The amount of data indicated by 'nbytes' has been written to the
226             VConnection</td>
227       </tr>
228       <tr>
229         <td>VC_EVENT_INACTIVITY_TIMEOUT</td>
230         <td>No activity was performed for a certain period.</td>
231       </tr>
232       <tr>
233         <td>VC_EVENT_ACTIVE_TIMEOUT</td>
234         <td>Write operation continued beyond a time limit.</td>
235       </tr>
236       <tr>
237         <td>VC_EVENT_ERROR</td>
238         <td>An error occurred during the write</td>
239       </tr>
240     </table>
241 
242     @param c Continuation to be called back with events.
243     @param nbytes Number of bytes to write. If unknown, nbytes must
244       be set to INT64_MAX.
245     @param buf Reader whose data is to be read from.
246     @param owner
247     @return VIO representing the scheduled IO operation.
248 
249   */
250   virtual VIO *do_io_write(Continuation *c = nullptr, int64_t nbytes = INT64_MAX, IOBufferReader *buf = 0, bool owner = false) = 0;
251 
252   /**
253     Indicate that the VConnection is no longer needed.
254 
255     Once the state machine has finished using this VConnection, it
256     must call this function to indicate that the VConnection can
257     be deallocated.  After a close has been called, the VConnection
258     and underlying processor must not send any more events related
259     to this VConnection to the state machine. Likeswise, the state
260     machine must not access the VConnection or any VIOs obtained
261     from it after calling this method.
262 
263     @param lerrno indicates where a close is a normal close or an
264       abort. The difference between a normal close and an abort
265       depends on the underlying type of the VConnection.
266 
267   */
268   virtual void do_io_close(int lerrno = -1) = 0;
269 
270   /**
271     Terminate one or both directions of the VConnection.
272 
273     Indicates that one or both sides of the VConnection should be
274     terminated. After this call is issued, no further I/O can be
275     done on the specified direction of the connection. The processor
276     must not send any further events (including timeout events) to
277     the state machine, and the state machine must not use any VIOs
278     from a shutdown direction of the connection. Even if both sides
279     of a connection are shutdown, the state machine must still call
280     do_io_close() when it wishes the VConnection to be deallocated.
281 
282     <b>Possible howto values</b>
283 
284     <table border="1">
285       <tr>
286         <td align="center"><b>Value</b></td>
287         <td align="center"><b>Meaning</b></td>
288       </tr>
289       <tr>
290         <td>IO_SHUTDOWN_READ</td>
291         <td>Indicates that this VConnection should not generate any more
292         read events</td>
293       </tr>
294       <tr>
295         <td>IO_SHUTDOWN_WRITE</td>
296         <td>Indicates that this VConnection should not generate any more
297         write events</td>
298       </tr>
299       <tr>
300         <td>IO_SHUTDOWN_READWRITE</td>
301         <td>Indicates that this VConnection should not generate any more
302         read nor write events</td>
303       </tr>
304     </table>
305 
306     @param howto Specifies which direction of the VConnection to
307       shutdown.
308 
309   */
310   virtual void do_io_shutdown(ShutdownHowTo_t howto) = 0;
311 
312   VConnection(ProxyMutex *aMutex);
313   VConnection(Ptr<ProxyMutex> &aMutex);
314 
315   // Private
316   // Set continuation on a given vio. The public interface
317   // is through VIO::set_continuation()
318   virtual void set_continuation(VIO *vio, Continuation *cont);
319 
320   // Reenable a given vio.  The public interface is through VIO::reenable
321   virtual void reenable(VIO *vio);
322   virtual void reenable_re(VIO *vio);
323 
324   /**
325     Convenience function to retrieve information from VConnection.
326 
327     This function is provided as a convenience for state machines
328     to transmit information from/to a VConnection without breaking
329     the VConnection abstraction. Its behavior varies depending on
330     the type of VConnection being used.
331 
332     @param id Identifier associated to interpret the data field
333     @param data Value or pointer with state machine or VConnection data.
334     @return True if the oparation is successful.
335 
336   */
337   virtual bool
338   get_data(int id, void *data)
339   {
340     (void)id;
341     (void)data;
342     return false;
343   }
344 
345   /**
346     Convenience function to set information into the VConnection.
347 
348     This function is provided as a convenience for state machines
349     to transmit information from/to a VConnection without breaking
350     the VConnection abstraction. Its behavior varies depending on
351     the type of VConnection being used.
352 
353     @param id Identifier associated to interpret the data field.
354     @param data Value or pointer with state machine or VConnection data.
355     @return True if the oparation is successful.
356 
357   */
358   virtual bool
359   set_data(int id, void *data)
360   {
361     (void)id;
362     (void)data;
363     return false;
364   }
365 
366 public:
367   /**
368     The error code from the last error.
369 
370     Indicates the last error on the VConnection. They are either
371     system error codes or from the InkErrno.h file.
372 
373   */
374   int lerrno;
375 };
376 
377 struct DummyVConnection : public VConnection {
378   virtual VIO *
379   do_io_write(Continuation * /* c ATS_UNUSED */, int64_t /* nbytes ATS_UNUSED */, IOBufferReader * /* buf ATS_UNUSED */,
380               bool /* owner ATS_UNUSED */)
381   {
382     ink_assert(!"VConnection::do_io_write -- "
383                 "cannot use default implementation");
384     return nullptr;
385   }
386   virtual VIO *
387   do_io_read(Continuation * /* c ATS_UNUSED */, int64_t /* nbytes ATS_UNUSED */, MIOBuffer * /* buf ATS_UNUSED */)
388   {
389     ink_assert(!"VConnection::do_io_read -- "
390                 "cannot use default implementation");
391     return nullptr;
392   }
393   virtual void
394   do_io_close(int /* alerrno ATS_UNUSED */)
395   {
396     ink_assert(!"VConnection::do_io_close -- "
397                 "cannot use default implementation");
398   }
399   virtual void do_io_shutdown(ShutdownHowTo_t /* howto ATS_UNUSED */)
400   {
401     ink_assert(!"VConnection::do_io_shutdown -- "
402                 "cannot use default implementation");
403   }
404   DummyVConnection(ProxyMutex *m) : VConnection(m) {}
405 };
406 
407 #endif /*_I_VConnection_h_*/
408