Move OpenSSLPtrTypes.h from folly/io/async/ssl to folly/ssl
[folly.git] / folly / io / async / AsyncTransport.h
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #pragma once
18
19 #include <memory>
20
21 #include <folly/io/IOBuf.h>
22 #include <folly/io/async/AsyncSocketBase.h>
23 #include <folly/io/async/DelayedDestruction.h>
24 #include <folly/io/async/EventBase.h>
25 #include <folly/ssl/OpenSSLPtrTypes.h>
26 #include <folly/portability/OpenSSL.h>
27 #include <folly/portability/SysUio.h>
28
29 constexpr bool kOpenSslModeMoveBufferOwnership =
30 #ifdef SSL_MODE_MOVE_BUFFER_OWNERSHIP
31   true
32 #else
33   false
34 #endif
35 ;
36
37 namespace folly {
38
39 class AsyncSocketException;
40 class EventBase;
41 class SocketAddress;
42
43 /*
44  * flags given by the application for write* calls
45  */
46 enum class WriteFlags : uint32_t {
47   NONE = 0x00,
48   /*
49    * Whether to delay the output until a subsequent non-corked write.
50    * (Note: may not be supported in all subclasses or on all platforms.)
51    */
52   CORK = 0x01,
53   /*
54    * for a socket that has ACK latency enabled, it will cause the kernel
55    * to fire a TCP ESTATS event when the last byte of the given write call
56    * will be acknowledged.
57    */
58   EOR = 0x02,
59   /*
60    * this indicates that only the write side of socket should be shutdown
61    */
62   WRITE_SHUTDOWN = 0x04,
63 };
64
65 /*
66  * union operator
67  */
68 inline WriteFlags operator|(WriteFlags a, WriteFlags b) {
69   return static_cast<WriteFlags>(
70     static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
71 }
72
73 /*
74  * compound assignment union operator
75  */
76 inline WriteFlags& operator|=(WriteFlags& a, WriteFlags b) {
77   a = a | b;
78   return a;
79 }
80
81 /*
82  * intersection operator
83  */
84 inline WriteFlags operator&(WriteFlags a, WriteFlags b) {
85   return static_cast<WriteFlags>(
86     static_cast<uint32_t>(a) & static_cast<uint32_t>(b));
87 }
88
89 /*
90  * compound assignment intersection operator
91  */
92 inline WriteFlags& operator&=(WriteFlags& a, WriteFlags b) {
93   a = a & b;
94   return a;
95 }
96
97 /*
98  * exclusion parameter
99  */
100 inline WriteFlags operator~(WriteFlags a) {
101   return static_cast<WriteFlags>(~static_cast<uint32_t>(a));
102 }
103
104 /*
105  * unset operator
106  */
107 inline WriteFlags unSet(WriteFlags a, WriteFlags b) {
108   return a & ~b;
109 }
110
111 /*
112  * inclusion operator
113  */
114 inline bool isSet(WriteFlags a, WriteFlags b) {
115   return (a & b) == b;
116 }
117
118
119 /**
120  * AsyncTransport defines an asynchronous API for streaming I/O.
121  *
122  * This class provides an API to for asynchronously waiting for data
123  * on a streaming transport, and for asynchronously sending data.
124  *
125  * The APIs for reading and writing are intentionally asymmetric.  Waiting for
126  * data to read is a persistent API: a callback is installed, and is notified
127  * whenever new data is available.  It continues to be notified of new events
128  * until it is uninstalled.
129  *
130  * AsyncTransport does not provide read timeout functionality, because it
131  * typically cannot determine when the timeout should be active.  Generally, a
132  * timeout should only be enabled when processing is blocked waiting on data
133  * from the remote endpoint.  For server-side applications, the timeout should
134  * not be active if the server is currently processing one or more outstanding
135  * requests on this transport.  For client-side applications, the timeout
136  * should not be active if there are no requests pending on the transport.
137  * Additionally, if a client has multiple pending requests, it will ususally
138  * want a separate timeout for each request, rather than a single read timeout.
139  *
140  * The write API is fairly intuitive: a user can request to send a block of
141  * data, and a callback will be informed once the entire block has been
142  * transferred to the kernel, or on error.  AsyncTransport does provide a send
143  * timeout, since most callers want to give up if the remote end stops
144  * responding and no further progress can be made sending the data.
145  */
146 class AsyncTransport : public DelayedDestruction, public AsyncSocketBase {
147  public:
148   typedef std::unique_ptr<AsyncTransport, Destructor> UniquePtr;
149
150   /**
151    * Close the transport.
152    *
153    * This gracefully closes the transport, waiting for all pending write
154    * requests to complete before actually closing the underlying transport.
155    *
156    * If a read callback is set, readEOF() will be called immediately.  If there
157    * are outstanding write requests, the close will be delayed until all
158    * remaining writes have completed.  No new writes may be started after
159    * close() has been called.
160    */
161   virtual void close() = 0;
162
163   /**
164    * Close the transport immediately.
165    *
166    * This closes the transport immediately, dropping any outstanding data
167    * waiting to be written.
168    *
169    * If a read callback is set, readEOF() will be called immediately.
170    * If there are outstanding write requests, these requests will be aborted
171    * and writeError() will be invoked immediately on all outstanding write
172    * callbacks.
173    */
174   virtual void closeNow() = 0;
175
176   /**
177    * Reset the transport immediately.
178    *
179    * This closes the transport immediately, sending a reset to the remote peer
180    * if possible to indicate abnormal shutdown.
181    *
182    * Note that not all subclasses implement this reset functionality: some
183    * subclasses may treat reset() the same as closeNow().  Subclasses that use
184    * TCP transports should terminate the connection with a TCP reset.
185    */
186   virtual void closeWithReset() {
187     closeNow();
188   }
189
190   /**
191    * Perform a half-shutdown of the write side of the transport.
192    *
193    * The caller should not make any more calls to write() or writev() after
194    * shutdownWrite() is called.  Any future write attempts will fail
195    * immediately.
196    *
197    * Not all transport types support half-shutdown.  If the underlying
198    * transport does not support half-shutdown, it will fully shutdown both the
199    * read and write sides of the transport.  (Fully shutting down the socket is
200    * better than doing nothing at all, since the caller may rely on the
201    * shutdownWrite() call to notify the other end of the connection that no
202    * more data can be read.)
203    *
204    * If there is pending data still waiting to be written on the transport,
205    * the actual shutdown will be delayed until the pending data has been
206    * written.
207    *
208    * Note: There is no corresponding shutdownRead() equivalent.  Simply
209    * uninstall the read callback if you wish to stop reading.  (On TCP sockets
210    * at least, shutting down the read side of the socket is a no-op anyway.)
211    */
212   virtual void shutdownWrite() = 0;
213
214   /**
215    * Perform a half-shutdown of the write side of the transport.
216    *
217    * shutdownWriteNow() is identical to shutdownWrite(), except that it
218    * immediately performs the shutdown, rather than waiting for pending writes
219    * to complete.  Any pending write requests will be immediately failed when
220    * shutdownWriteNow() is called.
221    */
222   virtual void shutdownWriteNow() = 0;
223
224   /**
225    * Determine if transport is open and ready to read or write.
226    *
227    * Note that this function returns false on EOF; you must also call error()
228    * to distinguish between an EOF and an error.
229    *
230    * @return  true iff the transport is open and ready, false otherwise.
231    */
232   virtual bool good() const = 0;
233
234   /**
235    * Determine if the transport is readable or not.
236    *
237    * @return  true iff the transport is readable, false otherwise.
238    */
239   virtual bool readable() const = 0;
240
241   /**
242    * Determine if the there is pending data on the transport.
243    *
244    * @return  true iff the if the there is pending data, false otherwise.
245    */
246   virtual bool isPending() const {
247     return readable();
248   }
249
250   /**
251    * Determine if transport is connected to the endpoint
252    *
253    * @return  false iff the transport is connected, otherwise true
254    */
255   virtual bool connecting() const = 0;
256
257   /**
258    * Determine if an error has occurred with this transport.
259    *
260    * @return  true iff an error has occurred (not EOF).
261    */
262   virtual bool error() const = 0;
263
264   /**
265    * Attach the transport to a EventBase.
266    *
267    * This may only be called if the transport is not currently attached to a
268    * EventBase (by an earlier call to detachEventBase()).
269    *
270    * This method must be invoked in the EventBase's thread.
271    */
272   virtual void attachEventBase(EventBase* eventBase) = 0;
273
274   /**
275    * Detach the transport from its EventBase.
276    *
277    * This may only be called when the transport is idle and has no reads or
278    * writes pending.  Once detached, the transport may not be used again until
279    * it is re-attached to a EventBase by calling attachEventBase().
280    *
281    * This method must be called from the current EventBase's thread.
282    */
283   virtual void detachEventBase() = 0;
284
285   /**
286    * Determine if the transport can be detached.
287    *
288    * This method must be called from the current EventBase's thread.
289    */
290   virtual bool isDetachable() const = 0;
291
292   /**
293    * Set the send timeout.
294    *
295    * If write requests do not make any progress for more than the specified
296    * number of milliseconds, fail all pending writes and close the transport.
297    *
298    * If write requests are currently pending when setSendTimeout() is called,
299    * the timeout interval is immediately restarted using the new value.
300    *
301    * @param milliseconds  The timeout duration, in milliseconds.  If 0, no
302    *                      timeout will be used.
303    */
304   virtual void setSendTimeout(uint32_t milliseconds) = 0;
305
306   /**
307    * Get the send timeout.
308    *
309    * @return Returns the current send timeout, in milliseconds.  A return value
310    *         of 0 indicates that no timeout is set.
311    */
312   virtual uint32_t getSendTimeout() const = 0;
313
314   /**
315    * Get the address of the local endpoint of this transport.
316    *
317    * This function may throw AsyncSocketException on error.
318    *
319    * @param address  The local address will be stored in the specified
320    *                 SocketAddress.
321    */
322   virtual void getLocalAddress(SocketAddress* address) const = 0;
323
324   /**
325    * Get the address of the remote endpoint to which this transport is
326    * connected.
327    *
328    * This function may throw AsyncSocketException on error.
329    *
330    * @return         Return the local address
331    */
332   SocketAddress getLocalAddress() const {
333     SocketAddress addr;
334     getLocalAddress(&addr);
335     return addr;
336   }
337
338   virtual void getAddress(SocketAddress* address) const {
339     getLocalAddress(address);
340   }
341
342   /**
343    * Get the address of the remote endpoint to which this transport is
344    * connected.
345    *
346    * This function may throw AsyncSocketException on error.
347    *
348    * @param address  The remote endpoint's address will be stored in the
349    *                 specified SocketAddress.
350    */
351   virtual void getPeerAddress(SocketAddress* address) const = 0;
352
353   /**
354    * Get the address of the remote endpoint to which this transport is
355    * connected.
356    *
357    * This function may throw AsyncSocketException on error.
358    *
359    * @return         Return the remote endpoint's address
360    */
361   SocketAddress getPeerAddress() const {
362     SocketAddress addr;
363     getPeerAddress(&addr);
364     return addr;
365   }
366
367   /**
368    * Get the certificate used to authenticate the peer.
369    */
370   virtual ssl::X509UniquePtr getPeerCert() const { return nullptr; }
371
372   /**
373    * The local certificate used for this connection. May be null
374    */
375   virtual const X509* getSelfCert() const {
376     return nullptr;
377   }
378
379   /**
380    * @return True iff end of record tracking is enabled
381    */
382   virtual bool isEorTrackingEnabled() const = 0;
383
384   virtual void setEorTracking(bool track) = 0;
385
386   virtual size_t getAppBytesWritten() const = 0;
387   virtual size_t getRawBytesWritten() const = 0;
388   virtual size_t getAppBytesReceived() const = 0;
389   virtual size_t getRawBytesReceived() const = 0;
390
391   class BufferCallback {
392    public:
393     virtual ~BufferCallback() {}
394     virtual void onEgressBuffered() = 0;
395     virtual void onEgressBufferCleared() = 0;
396   };
397
398   /**
399    * Callback class to signal when a transport that did not have replay
400    * protection gains replay protection. This is needed for 0-RTT security
401    * protocols.
402    */
403   class ReplaySafetyCallback {
404    public:
405     virtual ~ReplaySafetyCallback() = default;
406
407     /**
408      * Called when the transport becomes replay safe.
409      */
410     virtual void onReplaySafe() = 0;
411   };
412
413   /**
414    * False if the transport does not have replay protection, but will in the
415    * future.
416    */
417   virtual bool isReplaySafe() const { return true; }
418
419   /**
420    * Set the ReplaySafeCallback on this transport.
421    *
422    * This should only be called if isReplaySafe() returns false.
423    */
424   virtual void setReplaySafetyCallback(ReplaySafetyCallback* callback) {
425     if (callback) {
426       CHECK(false) << "setReplaySafetyCallback() not supported";
427     }
428   }
429
430  protected:
431   virtual ~AsyncTransport() = default;
432 };
433
434 class AsyncReader {
435  public:
436   class ReadCallback {
437    public:
438     virtual ~ReadCallback() = default;
439
440     /**
441      * When data becomes available, getReadBuffer() will be invoked to get the
442      * buffer into which data should be read.
443      *
444      * This method allows the ReadCallback to delay buffer allocation until
445      * data becomes available.  This allows applications to manage large
446      * numbers of idle connections, without having to maintain a separate read
447      * buffer for each idle connection.
448      *
449      * It is possible that in some cases, getReadBuffer() may be called
450      * multiple times before readDataAvailable() is invoked.  In this case, the
451      * data will be written to the buffer returned from the most recent call to
452      * readDataAvailable().  If the previous calls to readDataAvailable()
453      * returned different buffers, the ReadCallback is responsible for ensuring
454      * that they are not leaked.
455      *
456      * If getReadBuffer() throws an exception, returns a nullptr buffer, or
457      * returns a 0 length, the ReadCallback will be uninstalled and its
458      * readError() method will be invoked.
459      *
460      * getReadBuffer() is not allowed to change the transport state before it
461      * returns.  (For example, it should never uninstall the read callback, or
462      * set a different read callback.)
463      *
464      * @param bufReturn getReadBuffer() should update *bufReturn to contain the
465      *                  address of the read buffer.  This parameter will never
466      *                  be nullptr.
467      * @param lenReturn getReadBuffer() should update *lenReturn to contain the
468      *                  maximum number of bytes that may be written to the read
469      *                  buffer.  This parameter will never be nullptr.
470      */
471     virtual void getReadBuffer(void** bufReturn, size_t* lenReturn) = 0;
472
473     /**
474      * readDataAvailable() will be invoked when data has been successfully read
475      * into the buffer returned by the last call to getReadBuffer().
476      *
477      * The read callback remains installed after readDataAvailable() returns.
478      * It must be explicitly uninstalled to stop receiving read events.
479      * getReadBuffer() will be called at least once before each call to
480      * readDataAvailable().  getReadBuffer() will also be called before any
481      * call to readEOF().
482      *
483      * @param len       The number of bytes placed in the buffer.
484      */
485
486     virtual void readDataAvailable(size_t len) noexcept = 0;
487
488     /**
489      * When data becomes available, isBufferMovable() will be invoked to figure
490      * out which API will be used, readBufferAvailable() or
491      * readDataAvailable(). If isBufferMovable() returns true, that means
492      * ReadCallback supports the IOBuf ownership transfer and
493      * readBufferAvailable() will be used.  Otherwise, not.
494
495      * By default, isBufferMovable() always return false. If
496      * readBufferAvailable() is implemented and to be invoked, You should
497      * overwrite isBufferMovable() and return true in the inherited class.
498      *
499      * This method allows the AsyncSocket/AsyncSSLSocket do buffer allocation by
500      * itself until data becomes available.  Compared with the pre/post buffer
501      * allocation in getReadBuffer()/readDataAvailabe(), readBufferAvailable()
502      * has two advantages.  First, this can avoid memcpy. E.g., in
503      * AsyncSSLSocket, the decrypted data was copied from the openssl internal
504      * buffer to the readbuf buffer.  With the buffer ownership transfer, the
505      * internal buffer can be directly "moved" to ReadCallback. Second, the
506      * memory allocation can be more precise.  The reason is
507      * AsyncSocket/AsyncSSLSocket can allocate the memory of precise size
508      * because they have more context about the available data than
509      * ReadCallback.  Think about the getReadBuffer() pre-allocate 4072 bytes
510      * buffer, but the available data is always 16KB (max OpenSSL record size).
511      */
512
513     virtual bool isBufferMovable() noexcept {
514       return false;
515     }
516
517     /**
518      * Suggested buffer size, allocated for read operations,
519      * if callback is movable and supports folly::IOBuf
520      */
521
522     virtual size_t maxBufferSize() const {
523       return 64 * 1024; // 64K
524     }
525
526     /**
527      * readBufferAvailable() will be invoked when data has been successfully
528      * read.
529      *
530      * Note that only either readBufferAvailable() or readDataAvailable() will
531      * be invoked according to the return value of isBufferMovable(). The timing
532      * and aftereffect of readBufferAvailable() are the same as
533      * readDataAvailable()
534      *
535      * @param readBuf The unique pointer of read buffer.
536      */
537
538     virtual void readBufferAvailable(std::unique_ptr<IOBuf> /*readBuf*/)
539       noexcept {}
540
541     /**
542      * readEOF() will be invoked when the transport is closed.
543      *
544      * The read callback will be automatically uninstalled immediately before
545      * readEOF() is invoked.
546      */
547     virtual void readEOF() noexcept = 0;
548
549     /**
550      * readError() will be invoked if an error occurs reading from the
551      * transport.
552      *
553      * The read callback will be automatically uninstalled immediately before
554      * readError() is invoked.
555      *
556      * @param ex        An exception describing the error that occurred.
557      */
558     virtual void readErr(const AsyncSocketException& ex) noexcept = 0;
559   };
560
561   // Read methods that aren't part of AsyncTransport.
562   virtual void setReadCB(ReadCallback* callback) = 0;
563   virtual ReadCallback* getReadCallback() const = 0;
564
565  protected:
566   virtual ~AsyncReader() = default;
567 };
568
569 class AsyncWriter {
570  public:
571   class WriteCallback {
572    public:
573     virtual ~WriteCallback() = default;
574
575     /**
576      * writeSuccess() will be invoked when all of the data has been
577      * successfully written.
578      *
579      * Note that this mainly signals that the buffer containing the data to
580      * write is no longer needed and may be freed or re-used.  It does not
581      * guarantee that the data has been fully transmitted to the remote
582      * endpoint.  For example, on socket-based transports, writeSuccess() only
583      * indicates that the data has been given to the kernel for eventual
584      * transmission.
585      */
586     virtual void writeSuccess() noexcept = 0;
587
588     /**
589      * writeError() will be invoked if an error occurs writing the data.
590      *
591      * @param bytesWritten      The number of bytes that were successfull
592      * @param ex                An exception describing the error that occurred.
593      */
594     virtual void writeErr(size_t bytesWritten,
595                           const AsyncSocketException& ex) noexcept = 0;
596   };
597
598   // Write methods that aren't part of AsyncTransport
599   virtual void write(WriteCallback* callback, const void* buf, size_t bytes,
600                      WriteFlags flags = WriteFlags::NONE) = 0;
601   virtual void writev(WriteCallback* callback, const iovec* vec, size_t count,
602                       WriteFlags flags = WriteFlags::NONE) = 0;
603   virtual void writeChain(WriteCallback* callback,
604                           std::unique_ptr<IOBuf>&& buf,
605                           WriteFlags flags = WriteFlags::NONE) = 0;
606
607  protected:
608   virtual ~AsyncWriter() = default;
609 };
610
611 // Transitional intermediate interface. This is deprecated.
612 // Wrapper around folly::AsyncTransport, that includes read/write callbacks
613 class AsyncTransportWrapper : virtual public AsyncTransport,
614                               virtual public AsyncReader,
615                               virtual public AsyncWriter {
616  public:
617   using UniquePtr = std::unique_ptr<AsyncTransportWrapper, Destructor>;
618
619   // Alias for inherited members from AsyncReader and AsyncWriter
620   // to keep compatibility.
621   using ReadCallback    = AsyncReader::ReadCallback;
622   using WriteCallback   = AsyncWriter::WriteCallback;
623   virtual void setReadCB(ReadCallback* callback) override = 0;
624   virtual ReadCallback* getReadCallback() const override = 0;
625   virtual void write(WriteCallback* callback, const void* buf, size_t bytes,
626                      WriteFlags flags = WriteFlags::NONE) override = 0;
627   virtual void writev(WriteCallback* callback, const iovec* vec, size_t count,
628                       WriteFlags flags = WriteFlags::NONE) override = 0;
629   virtual void writeChain(WriteCallback* callback,
630                           std::unique_ptr<IOBuf>&& buf,
631                           WriteFlags flags = WriteFlags::NONE) override = 0;
632   /**
633    * The transport wrapper may wrap another transport. This returns the
634    * transport that is wrapped. It returns nullptr if there is no wrapped
635    * transport.
636    */
637   virtual const AsyncTransportWrapper* getWrappedTransport() const {
638     return nullptr;
639   }
640
641   /**
642    * In many cases when we need to set socket properties or otherwise access the
643    * underlying transport from a wrapped transport. This method allows access to
644    * the derived classes of the underlying transport.
645    */
646   template <class T>
647   const T* getUnderlyingTransport() const {
648     const AsyncTransportWrapper* current = this;
649     while (current) {
650       auto sock = dynamic_cast<const T*>(current);
651       if (sock) {
652         return sock;
653       }
654       current = current->getWrappedTransport();
655     }
656     return nullptr;
657   }
658
659   template <class T>
660   T* getUnderlyingTransport() {
661     return const_cast<T*>(static_cast<const AsyncTransportWrapper*>(this)
662         ->getUnderlyingTransport<T>());
663   }
664
665   /**
666    * Return the application protocol being used by the underlying transport
667    * protocol. This is useful for transports which are used to tunnel other
668    * protocols.
669    */
670   virtual std::string getApplicationProtocol() noexcept {
671     return "";
672   }
673
674   /**
675    * Returns the name of the security protocol being used.
676    */
677   virtual std::string getSecurityProtocol() const { return ""; }
678 };
679
680 } // folly