xref: /aosp_15_r20/external/grpc-grpc/src/core/lib/event_engine/extensions/supports_fd.h (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 // Copyright 2024 The gRPC Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef GRPC_SRC_CORE_LIB_EVENT_ENGINE_EXTENSIONS_SUPPORTS_FD_H
16 #define GRPC_SRC_CORE_LIB_EVENT_ENGINE_EXTENSIONS_SUPPORTS_FD_H
17 
18 #include <grpc/support/port_platform.h>
19 
20 #include "absl/functional/any_invocable.h"
21 #include "absl/status/statusor.h"
22 #include "absl/strings/string_view.h"
23 
24 #include <grpc/event_engine/event_engine.h>
25 
26 namespace grpc_event_engine {
27 namespace experimental {
28 
29 class EndpointSupportsFdExtension {
30  public:
31   virtual ~EndpointSupportsFdExtension() = default;
EndpointExtensionName()32   static absl::string_view EndpointExtensionName() {
33     return "io.grpc.event_engine.extension.endpoint_supports_fd";
34   }
35   /// Returns the file descriptor associated with the posix endpoint.
36   virtual int GetWrappedFd() = 0;
37 
38   /// Shutdown the endpoint. This function call should trigger execution of
39   /// any pending endpoint Read/Write callbacks with appropriate error
40   /// absl::Status. After this function call any subsequent endpoint
41   /// Read/Write operations until endpoint deletion should fail with an
42   /// appropriate absl::Status.
43   ///
44   /// \a on_release_fd - If specified, the callback is invoked when the
45   /// endpoint is destroyed/deleted. The underlying file descriptor is
46   /// released instead of being closed. The callback will get the released
47   /// file descriptor as its argument if the release operation is successful.
48   /// Otherwise it would get an appropriate error status as its argument.
49   virtual void Shutdown(absl::AnyInvocable<void(absl::StatusOr<int> release_fd)>
50                             on_release_fd) = 0;
51 };
52 
53 class ListenerSupportsFdExtension {
54  public:
55   virtual ~ListenerSupportsFdExtension() = default;
EndpointExtensionName()56   static absl::string_view EndpointExtensionName() {
57     return "io.grpc.event_engine.extension.listener_supports_fd";
58   }
59   /// Called when a posix listener bind operation completes. A single bind
60   /// operation may trigger creation of multiple listener fds. This callback
61   /// should be invoked once on each newly created and bound fd. If the
62   /// corresponding bind operation fails for a particular fd, this callback
63   /// must be invoked with a absl::FailedPreConditionError status.
64   ///
65   /// \a listener_fd - The listening socket fd that was bound to the specified
66   /// address.
67   using OnPosixBindNewFdCallback =
68       absl::AnyInvocable<void(absl::StatusOr<int> listener_fd)>;
69   /// Bind an address/port to this Listener.
70   ///
71   /// It is expected that multiple addresses/ports can be bound to this
72   /// Listener before Listener::Start has been called. Returns either the
73   /// bound port or an appropriate error status.
74   /// \a addr - The address to listen for incoming connections.
75   /// \a on_bind_new_fd The callback is invoked once for each newly bound
76   /// listener fd that may be created by this Bind operation.
77   virtual absl::StatusOr<int> BindWithFd(
78       const EventEngine::ResolvedAddress& addr,
79       OnPosixBindNewFdCallback on_bind_new_fd) = 0;
80 
81   /// Handle an externally accepted client connection. It must return an
82   /// appropriate error status in case of failure.
83   ///
84   /// This may be invoked to process a new client connection accepted by an
85   /// external listening fd.
86   /// \a listener_fd - The external listening socket fd that accepted the new
87   /// client connection.
88   /// \a fd - The socket file descriptor representing the new client
89   /// connection.
90   /// \a pending_data - If specified, it holds any pending data that may have
91   /// already been read over the externally accepted client connection.
92   /// Otherwise, it is assumed that no data has been read over the new client
93   /// connection.
94   virtual absl::Status HandleExternalConnection(int listener_fd, int fd,
95                                                 SliceBuffer* pending_data) = 0;
96 
97   /// Shutdown/stop listening on all bind Fds.
98   virtual void ShutdownListeningFds() = 0;
99 };
100 
101 class EventEngineSupportsFdExtension {
102  public:
103   virtual ~EventEngineSupportsFdExtension() = default;
EndpointExtensionName()104   static absl::string_view EndpointExtensionName() {
105     return "io.grpc.event_engine.extension.event_engine_supports_fd";
106   }
107   /// Creates a posix specific EventEngine::Endpoint from an fd which is already
108   /// assumed to be connected to a remote peer. \a fd - The connected socket
109   /// file descriptor. \a config - Additional configuration to applied to the
110   /// endpoint. \a memory_allocator - The endpoint may use the provided memory
111   /// allocator to track memory allocations.
112   virtual std::unique_ptr<EventEngine::Endpoint> CreatePosixEndpointFromFd(
113       int fd, const EndpointConfig& config,
114       MemoryAllocator memory_allocator) = 0;
115 
116   /// Called when the posix listener has accepted a new client connection.
117   /// \a listener_fd - The listening socket fd that accepted the new client
118   /// connection.
119   /// \a endpoint - The EventEngine endpoint to handle data exchange over the
120   /// new client connection.
121   /// \a is_external - A boolean indicating whether the new client connection
122   /// is accepted by an external listener_fd or by a listener_fd that is
123   /// managed by the EventEngine listener.
124   /// \a memory_allocator - The callback may use the provided memory
125   /// allocator to handle memory allocation operations.
126   /// \a pending_data - If specified, it holds any pending data that may have
127   /// already been read over the new client connection. Otherwise, it is
128   /// assumed that no data has been read over the new client connection.
129   using PosixAcceptCallback = absl::AnyInvocable<void(
130       int listener_fd, std::unique_ptr<EventEngine::Endpoint> endpoint,
131       bool is_external, MemoryAllocator memory_allocator,
132       SliceBuffer* pending_data)>;
133 
134   /// Factory method to create a posix specific network listener / server with
135   /// fd support.
136   ///
137   /// Once a \a Listener is created and started, the \a on_accept callback will
138   /// be called once asynchronously for each established connection. This method
139   /// may return a non-OK status immediately if an error was encountered in any
140   /// synchronous steps required to create the Listener. In this case,
141   /// \a on_shutdown will never be called.
142   ///
143   /// If this method returns a Listener, then \a on_shutdown will be invoked
144   /// exactly once, when the Listener is shut down. The status passed to it will
145   /// indicate if there was a problem during shutdown.
146   ///
147   /// The provided \a MemoryAllocatorFactory is used to create \a
148   /// MemoryAllocators for Endpoint construction.
149   virtual absl::StatusOr<std::unique_ptr<EventEngine::Listener>>
150   CreatePosixListener(
151       PosixAcceptCallback on_accept,
152       absl::AnyInvocable<void(absl::Status)> on_shutdown,
153       const EndpointConfig& config,
154       std::unique_ptr<MemoryAllocatorFactory> memory_allocator_factory) = 0;
155 };
156 
157 }  // namespace experimental
158 }  // namespace grpc_event_engine
159 
160 #endif  // GRPC_SRC_CORE_LIB_EVENT_ENGINE_EXTENSIONS_SUPPORTS_FD_H
161