1 /** @file
2 
3   This file implements an I/O Processor for network I/O
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 #pragma once
25 
26 #include "ProxyProtocol.h"
27 
28 #include <string_view>
29 #include <optional>
30 
31 #include "tscore/ink_inet.h"
32 #include "I_Action.h"
33 #include "I_VConnection.h"
34 #include "I_Event.h"
35 #include "tscore/List.h"
36 #include "I_IOBuffer.h"
37 #include "I_Socks.h"
38 #include "ts/apidefs.h"
39 #include "YamlSNIConfig.h"
40 #include "tscpp/util/TextView.h"
41 #include "tscore/IpMap.h"
42 
43 #define CONNECT_SUCCESS 1
44 #define CONNECT_FAILURE 0
45 
46 #define SSL_EVENT_SERVER 0
47 #define SSL_EVENT_CLIENT 1
48 
49 // Indicator the context for a NetVConnection
50 typedef enum {
51   NET_VCONNECTION_UNSET = 0,
52   NET_VCONNECTION_IN,  // Client <--> ATS, Client-Side
53   NET_VCONNECTION_OUT, // ATS <--> Server, Server-Side
54 } NetVConnectionContext_t;
55 
56 /** Holds client options for NetVConnection.
57 
58     This class holds various options a user can specify for
59     NetVConnection. Various clients need many slightly different
60     features. This is an attempt to prevent out of control growth of
61     the connection method signatures. Only options of interest need to
62     be explicitly set -- the rest get sensible default values.
63 
64     @note Binding addresses is a bit complex. It is not currently
65     possible to bind indiscriminately across protocols, which means
66     any connection must commit to IPv4 or IPv6. For this reason the
67     connection logic will look at the address family of @a local_addr
68     even if @a addr_binding is @c ANY_ADDR and bind to any address in
69     that protocol. If it's not an IP protocol, IPv4 will be used.
70 */
71 struct NetVCOptions {
72   typedef NetVCOptions self; ///< Self reference type.
73 
74   /// Values for valid IP protocols.
75   enum ip_protocol_t {
76     USE_TCP, ///< TCP protocol.
77     USE_UDP  ///< UDP protocol.
78   };
79 
80   /// IP (TCP or UDP) protocol to use on socket.
81   ip_protocol_t ip_proto;
82 
83   /** IP address family.
84 
85       This is used for inbound connections only if @c local_ip is not
86       set, which is sometimes more convenient for the client. This
87       defaults to @c AF_INET so if the client sets neither this nor @c
88       local_ip then IPv4 is used.
89 
90       For outbound connections this is ignored and the family of the
91       remote address used.
92 
93       @note This is (inconsistently) called "domain" and "protocol" in
94       other places. "family" is used here because that's what the
95       standard IP data structures use.
96 
97   */
98   uint16_t ip_family;
99 
100   /** The set of ways in which the local address should be bound.
101 
102       The protocol is set by the contents of @a local_addr regardless
103       of this value. @c ANY_ADDR will override only the address.
104 
105       @note The difference between @c INTF_ADDR and @c FOREIGN_ADDR is
106       whether transparency is enabled on the socket. It is the
107       client's responsibility to set this correctly based on whether
108       the address in @a local_addr is associated with an interface on
109       the local system ( @c INTF_ADDR ) or is owned by a foreign
110       system ( @c FOREIGN_ADDR ).  A binding style of @c ANY_ADDR
111       causes the value in @a local_addr to be ignored.
112 
113       The IP address and port are separate because most clients treat
114       these independently. For the same reason @c IpAddr is used
115       to be clear that it contains no port data.
116 
117       @see local_addr
118       @see addr_binding
119    */
120   enum addr_bind_style {
121     ANY_ADDR,    ///< Bind to any available local address (don't care, default).
122     INTF_ADDR,   ///< Bind to interface address in @a local_addr.
123     FOREIGN_ADDR ///< Bind to foreign address in @a local_addr.
124   };
125 
126   /** Local address for the connection.
127 
128       For outbound connections this must have the same family as the
129       remote address (which is not stored in this structure). For
130       inbound connections the family of this value overrides @a
131       ip_family if set.
132 
133       @note Ignored if @a addr_binding is @c ANY_ADDR.
134       @see addr_binding
135       @see ip_family
136   */
137   IpAddr local_ip;
138 
139   /** Local port for connection.
140       Set to 0 for "don't care" (default).
141   */
142   uint16_t local_port;
143 
144   /// How to bind the local address.
145   /// @note Default is @c ANY_ADDR.
146   addr_bind_style addr_binding;
147 
148   /// Make the socket blocking on I/O (default: @c false)
149   bool f_blocking;
150   /// Make socket block on connect (default: @c false)
151   bool f_blocking_connect;
152 
153   // Use TCP Fast Open on this socket. The connect(2) call will be omitted.
154   bool f_tcp_fastopen = false;
155 
156   /// Control use of SOCKS.
157   /// Set to @c NO_SOCKS to disable use of SOCKS. Otherwise SOCKS is
158   /// used if available.
159   unsigned char socks_support;
160   /// Version of SOCKS to use.
161   unsigned char socks_version;
162 
163   int socket_recv_bufsize;
164   int socket_send_bufsize;
165 
166   /// Configuration options for sockets.
167   /// @note These are not identical to internal socket options but
168   /// specifically defined for configuration. These are mask values
169   /// and so must be powers of 2.
170   uint32_t sockopt_flags;
171   /// Value for TCP no delay for @c sockopt_flags.
172   static uint32_t const SOCK_OPT_NO_DELAY = 1;
173   /// Value for keep alive for @c sockopt_flags.
174   static uint32_t const SOCK_OPT_KEEP_ALIVE = 2;
175   /// Value for linger on for @c sockopt_flags
176   static uint32_t const SOCK_OPT_LINGER_ON = 4;
177   /// Value for TCP Fast open @c sockopt_flags
178   static uint32_t const SOCK_OPT_TCP_FAST_OPEN = 8;
179   /// Value for SO_MARK @c sockopt_flags
180   static uint32_t const SOCK_OPT_PACKET_MARK = 16;
181   /// Value for IP_TOS @c sockopt_flags
182   static uint32_t const SOCK_OPT_PACKET_TOS = 32;
183 
184   uint32_t packet_mark;
185   uint32_t packet_tos;
186 
187   EventType etype;
188 
189   /** ALPN protocol-lists. The format is OpenSSL protocol-lists format (vector of 8-bit length-prefixed, byte strings)
190       https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_alpn_protos.html
191    */
192   std::string_view alpn_protos;
193   /** Server name to use for SNI data on an outbound connection.
194    */
195   ats_scoped_str sni_servername;
196   /** FQDN used to connect to the origin.  May be different
197    * than sni_servername if pristine host headers are used
198    */
199   ats_scoped_str ssl_servername;
200 
201   /** Server host name from client's request to use for SNI data on an outbound connection.
202    */
203   ats_scoped_str sni_hostname;
204 
205   /**
206    * Client certificate to use in response to OS's certificate request
207    */
208   ats_scoped_str ssl_client_cert_name;
209   /*
210    * File containing private key matching certificate
211    */
212   const char *ssl_client_private_key_name = nullptr;
213   /*
214    * File containing CA certs for verifying origin's cert
215    */
216   const char *ssl_client_ca_cert_name = nullptr;
217   /*
218    * Directory containing CA certs for verifying origin's cert
219    */
220   const char *ssl_client_ca_cert_path = nullptr;
221 
222   bool tls_upstream = false;
223 
224   /// Reset all values to defaults.
225 
226   /**
227    * Set to DISABLED, PERFMISSIVE, or ENFORCED
228    * Controls how the server certificate verification is handled
229    */
230   YamlSNIConfig::Policy verifyServerPolicy = YamlSNIConfig::Policy::DISABLED;
231 
232   /**
233    * Bit mask of which features of the server certificate should be checked
234    * Currently SIGNATURE and NAME
235    */
236   YamlSNIConfig::Property verifyServerProperties = YamlSNIConfig::Property::NONE;
237   void reset();
238 
239   void set_sock_param(int _recv_bufsize, int _send_bufsize, unsigned long _opt_flags, unsigned long _packet_mark = 0,
240                       unsigned long _packet_tos = 0);
241 
NetVCOptionsNetVCOptions242   NetVCOptions() { reset(); }
~NetVCOptionsNetVCOptions243   ~NetVCOptions() {}
244 
245   /** Set the SNI server name.
246       A local copy is made of @a name.
247   */
248   self &
set_sni_servernameNetVCOptions249   set_sni_servername(const char *name, size_t len)
250   {
251     IpEndpoint ip;
252 
253     // Literal IPv4 and IPv6 addresses are not permitted in "HostName".(rfc6066#section-3)
254     if (name && len && ats_ip_pton(std::string_view(name, len), &ip) != 0) {
255       sni_servername = ats_strndup(name, len);
256     } else {
257       sni_servername = nullptr;
258     }
259     return *this;
260   }
261 
262   self &
set_ssl_client_cert_nameNetVCOptions263   set_ssl_client_cert_name(const char *name)
264   {
265     if (name) {
266       ssl_client_cert_name = ats_strdup(name);
267     } else {
268       ssl_client_cert_name = nullptr;
269     }
270     return *this;
271   }
272 
273   self &
set_ssl_servernameNetVCOptions274   set_ssl_servername(const char *name)
275   {
276     if (name) {
277       ssl_servername = ats_strdup(name);
278     } else {
279       ssl_servername = nullptr;
280     }
281     return *this;
282   }
283 
284   self &
set_sni_hostnameNetVCOptions285   set_sni_hostname(const char *name, size_t len)
286   {
287     IpEndpoint ip;
288 
289     // Literal IPv4 and IPv6 addresses are not permitted in "HostName".(rfc6066#section-3)
290     if (name && len && ats_ip_pton(std::string_view(name, len), &ip) != 0) {
291       sni_hostname = ats_strndup(name, len);
292     } else {
293       sni_hostname = nullptr;
294     }
295     return *this;
296   }
297 
298   self &
299   operator=(self const &that)
300   {
301     if (&that != this) {
302       /*
303        * It is odd but necessary to null the scoped string pointer here
304        * and then explicitly call release on them in the string assignments
305        * below.
306        * We a memcpy from that to this.  This will put that's string pointers into
307        * this's memory.  Therefore we must first explicitly null out
308        * this's original version of the string.  The release after the
309        * memcpy removes the extra reference to that's copy of the string
310        * Removing the release will eventually cause a double free crash
311        */
312       sni_servername       = nullptr; // release any current name.
313       ssl_servername       = nullptr;
314       sni_hostname         = nullptr;
315       ssl_client_cert_name = nullptr;
316       memcpy(static_cast<void *>(this), &that, sizeof(self));
317       if (that.sni_servername) {
318         sni_servername.release(); // otherwise we'll free the source string.
319         this->sni_servername = ats_strdup(that.sni_servername);
320       }
321       if (that.ssl_servername) {
322         ssl_servername.release(); // otherwise we'll free the source string.
323         this->ssl_servername = ats_strdup(that.ssl_servername);
324       }
325       if (that.sni_hostname) {
326         sni_hostname.release(); // otherwise we'll free the source string.
327         this->sni_hostname = ats_strdup(that.sni_hostname);
328       }
329       if (that.ssl_client_cert_name) {
330         this->ssl_client_cert_name.release(); // otherwise we'll free the source string.
331         this->ssl_client_cert_name = ats_strdup(that.ssl_client_cert_name);
332       }
333     }
334     return *this;
335   }
336 
337   std::string_view get_family_string() const;
338 
339   std::string_view get_proto_string() const;
340 
341   /// @name Debugging
342   //@{
343   /// Convert @a s to its string equivalent.
344   static const char *toString(addr_bind_style s);
345   //@}
346 
347   // noncopyable
348   NetVCOptions(const NetVCOptions &) = delete;
349 };
350 
351 /**
352   A VConnection for a network socket. Abstraction for a net connection.
353   Similar to a socket descriptor VConnections are IO handles to
354   streams. In one sense, they serve a purpose similar to file
355   descriptors. Unlike file descriptors, VConnections allow for a
356   stream IO to be done based on a single read or write call.
357 
358 */
359 class NetVConnection : public VConnection, public PluginUserArgs<TS_USER_ARGS_VCONN>
360 {
361 public:
362   /**
363      Initiates read. Thread safe, may be called when not handling
364      an event from the NetVConnection, or the NetVConnection creation
365      callback.
366 
367     Callbacks: non-reentrant, c's lock taken during callbacks.
368 
369     <table>
370       <tr><td>c->handleEvent(VC_EVENT_READ_READY, vio)</td><td>data added to buffer</td></tr>
371       <tr><td>c->handleEvent(VC_EVENT_READ_COMPLETE, vio)</td><td>finished reading nbytes of data</td></tr>
372       <tr><td>c->handleEvent(VC_EVENT_EOS, vio)</td><td>the stream has been shutdown</td></tr>
373       <tr><td>c->handleEvent(VC_EVENT_ERROR, vio)</td><td>error</td></tr>
374     </table>
375 
376     The vio returned during callbacks is the same as the one returned
377     by do_io_read(). The vio can be changed only during call backs
378     from the vconnection.
379 
380     @param c continuation to be called back after (partial) read
381     @param nbytes no of bytes to read, if unknown set to INT64_MAX
382     @param buf buffer to put the data into
383     @return vio
384 
385   */
386   VIO *do_io_read(Continuation *c, int64_t nbytes, MIOBuffer *buf) override = 0;
387 
388   virtual Continuation *
read_vio_cont()389   read_vio_cont()
390   {
391     return nullptr;
392   }
393 
394   /**
395     Initiates write. Thread-safe, may be called when not handling
396     an event from the NetVConnection, or the NetVConnection creation
397     callback.
398 
399     Callbacks: non-reentrant, c's lock taken during callbacks.
400 
401     <table>
402       <tr>
403         <td>c->handleEvent(VC_EVENT_WRITE_READY, vio)</td>
404         <td>signifies data has written from the reader or there are no bytes available for the reader to write.</td>
405       </tr>
406       <tr>
407         <td>c->handleEvent(VC_EVENT_WRITE_COMPLETE, vio)</td>
408         <td>signifies the amount of data indicated by nbytes has been read from the buffer</td>
409       </tr>
410       <tr>
411         <td>c->handleEvent(VC_EVENT_ERROR, vio)</td>
412         <td>signified that error occurred during write.</td>
413       </tr>
414     </table>
415 
416     The vio returned during callbacks is the same as the one returned
417     by do_io_write(). The vio can be changed only during call backs
418     from the vconnection. The vconnection deallocates the reader
419     when it is destroyed.
420 
421     @param c continuation to be called back after (partial) write
422     @param nbytes no of bytes to write, if unknown must be set to INT64_MAX
423     @param buf source of data
424     @param owner
425     @return vio pointer
426 
427   */
428   VIO *do_io_write(Continuation *c, int64_t nbytes, IOBufferReader *buf, bool owner = false) override = 0;
429 
430   virtual Continuation *
write_vio_cont()431   write_vio_cont()
432   {
433     return nullptr;
434   }
435   /**
436     Closes the vconnection. A state machine MUST call do_io_close()
437     when it has finished with a VConnection. do_io_close() indicates
438     that the VConnection can be deallocated. After a close has been
439     called, the VConnection and underlying processor must NOT send
440     any more events related to this VConnection to the state machine.
441     Likewise, state machine must not access the VConnection or
442     any returned VIOs after calling close. lerrno indicates whether
443     a close is a normal close or an abort. The difference between
444     a normal close and an abort depends on the underlying type of
445     the VConnection. Passing VIO::CLOSE for lerrno indicates a
446     normal close while passing VIO::ABORT indicates an abort.
447 
448     @param lerrno VIO:CLOSE for regular close or VIO::ABORT for aborts
449 
450   */
451   void do_io_close(int lerrno = -1) override = 0;
452 
453   /**
454     Shuts down read side, write side, or both. do_io_shutdown() can
455     be used to terminate one or both sides of the VConnection. The
456     howto is one of IO_SHUTDOWN_READ, IO_SHUTDOWN_WRITE,
457     IO_SHUTDOWN_READWRITE. Once a side of a VConnection is shutdown,
458     no further I/O can be done on that side of the connections and
459     the underlying processor MUST NOT send any further events
460     (INCLUDING TIMEOUT EVENTS) to the state machine. The state machine
461     MUST NOT use any VIOs from a shutdown side of a connection.
462     Even if both sides of a connection are shutdown, the state
463     machine MUST still call do_io_close() when it wishes the
464     VConnection to be deallocated.
465 
466     @param howto IO_SHUTDOWN_READ, IO_SHUTDOWN_WRITE, IO_SHUTDOWN_READWRITE
467 
468   */
469   void do_io_shutdown(ShutdownHowTo_t howto) override = 0;
470 
471   /**
472     Sends out of band messages over the connection. This function
473     is used to send out of band messages (is this still useful?).
474     cont is called back with VC_EVENT_OOB_COMPLETE - on successful
475     send or VC_EVENT_EOS - if the other side has shutdown the
476     connection. These callbacks could be re-entrant. Only one
477     send_OOB can be in progress at any time for a VC.
478 
479     @param cont to be called back with events.
480     @param buf message buffer.
481     @param len length of the message.
482 
483   */
484   virtual Action *send_OOB(Continuation *cont, char *buf, int len);
485 
486   /**
487     Return the server name that is appropriate for the network VC type
488   */
489   virtual const char *
get_server_name()490   get_server_name() const
491   {
492     return nullptr;
493   }
494 
495   /**
496     Cancels a scheduled send_OOB. Part of the message could have
497     been sent already. Not callbacks to the cont are made after
498     this call. The Action returned by send_OOB should not be accessed
499     after cancel_OOB.
500 
501   */
502   virtual void cancel_OOB();
503 
504   ////////////////////////////////////////////////////////////
505   // Set the timeouts associated with this connection.      //
506   // active_timeout is for the total elapsed time of        //
507   // the connection.                                        //
508   // inactivity_timeout is the elapsed time from the time   //
509   // a read or a write was scheduled during which the       //
510   // connection  was unable to sink/provide data.           //
511   // calling these functions repeatedly resets the timeout. //
512   // These functions are NOT THREAD-SAFE, and may only be   //
513   // called when handing an  event from this NetVConnection,//
514   // or the NetVConnection creation callback.               //
515   ////////////////////////////////////////////////////////////
516 
517   /**
518     Sets time after which SM should be notified.
519 
520     Sets the amount of time (in nanoseconds) after which the state
521     machine using the NetVConnection should receive a
522     VC_EVENT_ACTIVE_TIMEOUT event. The timeout is value is ignored
523     if neither the read side nor the write side of the connection
524     is currently active. The timer is reset if the function is
525     called repeatedly This call can be used by SMs to make sure
526     that it does not keep any connections open for a really long
527     time.
528 
529     Timeout semantics:
530 
531     Should a timeout occur, the state machine for the read side of
532     the NetVConnection is signaled first assuming that a read has
533     been initiated on the NetVConnection and that the read side of
534     the NetVConnection has not been shutdown. Should either of the
535     two conditions not be met, the NetProcessor will attempt to
536     signal the write side. If a timeout is sent to the read side
537     state machine and its handler, return EVENT_DONE, a timeout
538     will not be sent to the write side. Should the return from the
539     handler not be EVENT_DONE and the write side state machine is
540     different (in terms of pointer comparison) from the read side
541     state machine, the NetProcessor will try to signal the write
542     side state machine as well. To signal write side, a write must
543     have been initiated on it and the write must not have been
544     shutdown.
545 
546     Receiving a timeout is only a notification that the timer has
547     expired. The NetVConnection is still usable. Further timeouts
548     of the type signaled will not be generated unless the timeout
549     is reset via the set_active_timeout() or set_inactivity_timeout()
550     interfaces.
551 
552   */
553   virtual void set_active_timeout(ink_hrtime timeout_in) = 0;
554 
555   /**
556     Sets time after which SM should be notified if the requested
557     IO could not be performed. Sets the amount of time (in nanoseconds),
558     if the NetVConnection is idle on both the read or write side,
559     after which the state machine using the NetVConnection should
560     receive a VC_EVENT_INACTIVITY_TIMEOUT event. Either read or
561     write traffic will cause timer to be reset. Calling this function
562     again also resets the timer. The timeout is value is ignored
563     if neither the read side nor the write side of the connection
564     is currently active. See section on timeout semantics above.
565 
566    */
567   virtual void set_inactivity_timeout(ink_hrtime timeout_in)         = 0;
568   virtual void set_default_inactivity_timeout(ink_hrtime timeout_in) = 0;
569   virtual bool is_default_inactivity_timeout()                       = 0;
570 
571   /**
572     Clears the active timeout. No active timeouts will be sent until
573     set_active_timeout() is used to reset the active timeout.
574 
575   */
576   virtual void cancel_active_timeout() = 0;
577 
578   /**
579     Clears the inactivity timeout. No inactivity timeouts will be
580     sent until set_inactivity_timeout() is used to reset the
581     inactivity timeout.
582 
583   */
584   virtual void cancel_inactivity_timeout() = 0;
585 
586   /** Set the action to use a continuation.
587       The action continuation will be called with an event if there is no pending I/O operation
588       to receive the event.
589 
590       Pass @c nullptr to disable.
591 
592       @internal Subclasses should implement this if they support actions. This abstract class does
593       not. If the subclass doesn't have an action this method is silently ignored.
594   */
595   virtual void
set_action(Continuation *)596   set_action(Continuation *)
597   {
598     return;
599   }
600 
601   virtual void add_to_keep_alive_queue() = 0;
602 
603   virtual void remove_from_keep_alive_queue() = 0;
604 
605   virtual bool add_to_active_queue() = 0;
606 
607   /** @return the current active_timeout value in nanosecs */
608   virtual ink_hrtime get_active_timeout() = 0;
609 
610   /** @return current inactivity_timeout value in nanosecs */
611   virtual ink_hrtime get_inactivity_timeout() = 0;
612 
613   /** Force an @a event if a write operation empties the write buffer.
614 
615       This event will be sent to the VIO, the same place as other IO events.
616       Use an @a event value of 0 to cancel the trap.
617 
618       The event is sent only the next time the write buffer is emptied, not
619       every future time. The event is sent only if otherwise no event would
620       be generated.
621    */
622   virtual void trapWriteBufferEmpty(int event = VC_EVENT_WRITE_READY);
623 
624   /** Returns local sockaddr storage. */
625   sockaddr const *get_local_addr();
626   IpEndpoint const &get_local_endpoint();
627 
628   /** Returns local ip.
629       @deprecated get_local_addr() should be used instead for AF_INET6 compatibility.
630   */
631 
632   in_addr_t get_local_ip();
633 
634   /** Returns local port. */
635   uint16_t get_local_port();
636 
637   /** Returns remote sockaddr storage. */
638   sockaddr const *get_remote_addr();
639   IpEndpoint const &get_remote_endpoint();
640 
641   /** Returns remote ip.
642       @deprecated get_remote_addr() should be used instead for AF_INET6 compatibility.
643   */
644   in_addr_t get_remote_ip();
645 
646   /** Returns remote port. */
647   uint16_t get_remote_port();
648 
649   /** Set the context of NetVConnection.
650    * The context is ONLY set once and will not be changed.
651    *
652    * @param context The context to be set.
653    */
654   void
set_context(NetVConnectionContext_t context)655   set_context(NetVConnectionContext_t context)
656   {
657     ink_assert(NET_VCONNECTION_UNSET == netvc_context);
658     netvc_context = context;
659   }
660 
661   /** Get the context.
662    * @return the context of current NetVConnection
663    */
664   NetVConnectionContext_t
get_context()665   get_context() const
666   {
667     return netvc_context;
668   }
669 
670   /**
671    * Returns true if the network protocol
672    * supports a client provided SNI value
673    */
674   virtual bool
support_sni()675   support_sni() const
676   {
677     return false;
678   }
679 
680   virtual const char *
get_sni_servername()681   get_sni_servername() const
682   {
683     return nullptr;
684   }
685 
686   virtual bool
peer_provided_cert()687   peer_provided_cert() const
688   {
689     return false;
690   }
691 
692   virtual int
provided_cert()693   provided_cert() const
694   {
695     return 0;
696   }
697 
698   /** Structure holding user options. */
699   NetVCOptions options;
700 
701   /** Attempt to push any changed options down */
702   virtual void apply_options() = 0;
703 
704   //
705   // Private
706   //
707 
708   // The following variable used to obtain host addr when transparency
709   // is enabled by SocksProxy
710   SocksAddrType socks_addr;
711 
712   unsigned int attributes = 0;
713   EThread *thread         = nullptr;
714 
715   /// PRIVATE: The public interface is VIO::reenable()
716   void reenable(VIO *vio) override = 0;
717 
718   /// PRIVATE: The public interface is VIO::reenable()
719   void reenable_re(VIO *vio) override = 0;
720 
721   /// PRIVATE
~NetVConnection()722   ~NetVConnection() override {}
723   /**
724     PRIVATE: instances of NetVConnection cannot be created directly
725     by the state machines. The objects are created by NetProcessor
726     calls like accept connect_re() etc. The constructor is public
727     just to avoid compile errors.
728 
729   */
730   NetVConnection();
731 
732   virtual SOCKET get_socket() = 0;
733 
734   /** Set the TCP congestion control algorithm */
735   virtual int set_tcp_congestion_control(int side) = 0;
736 
737   /** Set local sock addr struct. */
738   virtual void set_local_addr() = 0;
739 
740   /** Set remote sock addr struct. */
741   virtual void set_remote_addr() = 0;
742 
743   /** Set remote sock addr struct. */
744   virtual void set_remote_addr(const sockaddr *) = 0;
745 
746   /** Set the MPTCP state for this connection */
747   virtual void set_mptcp_state() = 0;
748 
749   // for InkAPI
750   bool
get_is_internal_request()751   get_is_internal_request() const
752   {
753     return is_internal_request;
754   }
755 
756   void
757   set_is_internal_request(bool val = false)
758   {
759     is_internal_request = val;
760   }
761 
762   /// Get the transparency state.
763   bool
get_is_transparent()764   get_is_transparent() const
765   {
766     return is_transparent;
767   }
768 
769   /// Get the MPTCP state of the VC.
770   std::optional<bool>
get_mptcp_state()771   get_mptcp_state() const
772   {
773     return mptcp_state;
774   }
775 
776   /// Set the transparency state.
777   void
778   set_is_transparent(bool state = true)
779   {
780     is_transparent = state;
781   }
782 
783   /// Get the proxy protocol enabled flag
784   bool
get_is_proxy_protocol()785   get_is_proxy_protocol() const
786   {
787     return is_proxy_protocol;
788   }
789   /// Set the proxy protocol enabled flag on the port
790   void
791   set_is_proxy_protocol(bool state = true)
792   {
793     is_proxy_protocol = state;
794   }
795 
796   virtual int
populate_protocol(std::string_view * results,int n)797   populate_protocol(std::string_view *results, int n) const
798   {
799     return 0;
800   }
801 
802   virtual const char *
protocol_contains(std::string_view prefix)803   protocol_contains(std::string_view prefix) const
804   {
805     return nullptr;
806   }
807 
808   // noncopyable
809   NetVConnection(const NetVConnection &) = delete;
810   NetVConnection &operator=(const NetVConnection &) = delete;
811 
812   ProxyProtocolVersion
get_proxy_protocol_version()813   get_proxy_protocol_version() const
814   {
815     return pp_info.version;
816   }
817 
818   sockaddr const *get_proxy_protocol_addr(const ProxyProtocolData) const;
819 
820   sockaddr const *
get_proxy_protocol_src_addr()821   get_proxy_protocol_src_addr() const
822   {
823     return get_proxy_protocol_addr(ProxyProtocolData::SRC);
824   }
825 
826   uint16_t
get_proxy_protocol_src_port()827   get_proxy_protocol_src_port() const
828   {
829     return ats_ip_port_host_order(this->get_proxy_protocol_addr(ProxyProtocolData::SRC));
830   }
831 
832   sockaddr const *
get_proxy_protocol_dst_addr()833   get_proxy_protocol_dst_addr() const
834   {
835     return get_proxy_protocol_addr(ProxyProtocolData::DST);
836   }
837 
838   uint16_t
get_proxy_protocol_dst_port()839   get_proxy_protocol_dst_port() const
840   {
841     return ats_ip_port_host_order(this->get_proxy_protocol_addr(ProxyProtocolData::DST));
842   };
843 
844   void set_proxy_protocol_info(const ProxyProtocol &src);
845   const ProxyProtocol &get_proxy_protocol_info() const;
846 
847   bool has_proxy_protocol(IOBufferReader *);
848   bool has_proxy_protocol(char *, int64_t *);
849 
850 protected:
851   IpEndpoint local_addr;
852   IpEndpoint remote_addr;
853   ProxyProtocol pp_info;
854 
855   bool got_local_addr  = false;
856   bool got_remote_addr = false;
857 
858   bool is_internal_request = false;
859   /// Set if this connection is transparent.
860   bool is_transparent = false;
861   /// Set if proxy protocol is enabled
862   bool is_proxy_protocol = false;
863   /// This is essentially a tri-state, we leave it undefined to mean no MPTCP support
864   std::optional<bool> mptcp_state;
865   /// Set if the next write IO that empties the write buffer should generate an event.
866   int write_buffer_empty_event = 0;
867   /// NetVConnection Context.
868   NetVConnectionContext_t netvc_context = NET_VCONNECTION_UNSET;
869 };
870 
NetVConnection()871 inline NetVConnection::NetVConnection() : VConnection(nullptr)
872 
873 {
874   ink_zero(local_addr);
875   ink_zero(remote_addr);
876 }
877 
878 inline void
trapWriteBufferEmpty(int event)879 NetVConnection::trapWriteBufferEmpty(int event)
880 {
881   write_buffer_empty_event = event;
882 }
883