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