Skip to content

Commit a07c95f

Browse files
authored
dynamic_modules: add more methods to listener filters ABI (#42789)
## Description This PR adds support for more methods in Dynamic Modules for Listener Filters to get Original Destination, Remote/Local Address, etc. --- **Commit Message:** dynamic_modules: add more methods to listener filters ABI **Additional Description:** Adds support for more methods in Dynamic Modules for Listener Filters to get Original Destination, Remote/Local Address, etc. **Risk Level:** Low **Testing:** Added Tests **Docs Changes:** Added **Release Notes:** N/A --------- Signed-off-by: Rohit Agrawal <rohit.agrawal@databricks.com>
1 parent 98745aa commit a07c95f

File tree

5 files changed

+643
-1
lines changed

5 files changed

+643
-1
lines changed

source/extensions/dynamic_modules/abi.h

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,16 @@ typedef enum envoy_dynamic_module_type_on_listener_filter_status {
678678
envoy_dynamic_module_type_on_listener_filter_status_StopIteration,
679679
} envoy_dynamic_module_type_on_listener_filter_status;
680680

681+
/**
682+
* envoy_dynamic_module_type_address_type represents the socket address type.
683+
*/
684+
typedef enum envoy_dynamic_module_type_address_type {
685+
envoy_dynamic_module_type_address_type_Unknown = 0,
686+
envoy_dynamic_module_type_address_type_Ip = 1,
687+
envoy_dynamic_module_type_address_type_Pipe = 2,
688+
envoy_dynamic_module_type_address_type_EnvoyInternal = 3,
689+
} envoy_dynamic_module_type_address_type;
690+
681691
// -----------------------------------------------------------------------------
682692
// ------------------------------- Event Hooks ---------------------------------
683693
// -----------------------------------------------------------------------------
@@ -2842,6 +2852,20 @@ bool envoy_dynamic_module_callback_listener_filter_get_remote_address(
28422852
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr,
28432853
envoy_dynamic_module_type_envoy_buffer* address_out, uint32_t* port_out);
28442854

2855+
/**
2856+
* envoy_dynamic_module_callback_listener_filter_get_direct_remote_address is called by the module
2857+
* to get the direct remote address which is the peer address before any listener filter
2858+
* modification.
2859+
*
2860+
* @param filter_envoy_ptr is the pointer to the DynamicModuleListenerFilter object.
2861+
* @param address_out is the output buffer where the address owned by Envoy will be stored.
2862+
* @param port_out is the output pointer to the port number.
2863+
* @return true if the address was found and is an IP address, false otherwise.
2864+
*/
2865+
bool envoy_dynamic_module_callback_listener_filter_get_direct_remote_address(
2866+
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr,
2867+
envoy_dynamic_module_type_envoy_buffer* address_out, uint32_t* port_out);
2868+
28452869
/**
28462870
* envoy_dynamic_module_callback_listener_filter_get_local_address is called by the module to get
28472871
* the local address.
@@ -2855,6 +2879,54 @@ bool envoy_dynamic_module_callback_listener_filter_get_local_address(
28552879
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr,
28562880
envoy_dynamic_module_type_envoy_buffer* address_out, uint32_t* port_out);
28572881

2882+
/**
2883+
* envoy_dynamic_module_callback_listener_filter_get_direct_local_address is called by the module to
2884+
* get the direct local address (the listener address before any restoration).
2885+
*
2886+
* @param filter_envoy_ptr is the pointer to the DynamicModuleListenerFilter object.
2887+
* @param address_out is the output buffer where the address owned by Envoy will be stored.
2888+
* @param port_out is the output pointer to the port number.
2889+
* @return true if the address was found and is an IP address, false otherwise.
2890+
*/
2891+
bool envoy_dynamic_module_callback_listener_filter_get_direct_local_address(
2892+
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr,
2893+
envoy_dynamic_module_type_envoy_buffer* address_out, uint32_t* port_out);
2894+
2895+
/**
2896+
* envoy_dynamic_module_callback_listener_filter_get_original_dst is called by the module to get the
2897+
* original destination address obtained from the platform (e.g., iptables redirect).
2898+
*
2899+
* @param filter_envoy_ptr is the pointer to the DynamicModuleListenerFilter object.
2900+
* @param address_out is the output buffer where the address owned by Envoy will be stored.
2901+
* @param port_out is the output pointer to the port number.
2902+
* @return true if the original destination address was found and is an IP address, false otherwise.
2903+
*/
2904+
bool envoy_dynamic_module_callback_listener_filter_get_original_dst(
2905+
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr,
2906+
envoy_dynamic_module_type_envoy_buffer* address_out, uint32_t* port_out);
2907+
2908+
/**
2909+
* envoy_dynamic_module_callback_listener_filter_get_address_type is called by the module to get the
2910+
* socket address type.
2911+
*
2912+
* @param filter_envoy_ptr is the pointer to the DynamicModuleListenerFilter object.
2913+
* @return the address type for the current socket.
2914+
*/
2915+
envoy_dynamic_module_type_address_type
2916+
envoy_dynamic_module_callback_listener_filter_get_address_type(
2917+
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr);
2918+
2919+
/**
2920+
* envoy_dynamic_module_callback_listener_filter_is_local_address_restored is called by the module
2921+
* to check whether the local address has been restored to a value different from the listener
2922+
* address.
2923+
*
2924+
* @param filter_envoy_ptr is the pointer to the DynamicModuleListenerFilter object.
2925+
* @return true if the local address has been restored, false otherwise.
2926+
*/
2927+
bool envoy_dynamic_module_callback_listener_filter_is_local_address_restored(
2928+
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr);
2929+
28582930
/**
28592931
* envoy_dynamic_module_callback_listener_filter_set_remote_address is called by the module to set
28602932
* the remote address (for proxy protocol parsing).
@@ -2898,6 +2970,16 @@ bool envoy_dynamic_module_callback_listener_filter_restore_local_address(
28982970
void envoy_dynamic_module_callback_listener_filter_continue_filter_chain(
28992971
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr, bool success);
29002972

2973+
/**
2974+
* envoy_dynamic_module_callback_listener_filter_use_original_dst is called by the module to control
2975+
* whether the listener should use the original destination for filter chain matching.
2976+
*
2977+
* @param filter_envoy_ptr is the pointer to the DynamicModuleListenerFilter object.
2978+
* @param use_original_dst indicates whether to enable original destination handling.
2979+
*/
2980+
void envoy_dynamic_module_callback_listener_filter_use_original_dst(
2981+
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr, bool use_original_dst);
2982+
29012983
/**
29022984
* envoy_dynamic_module_callback_listener_filter_close_socket is called by the module to close
29032985
* the socket immediately.
@@ -2954,6 +3036,31 @@ bool envoy_dynamic_module_callback_listener_filter_get_filter_state(
29543036
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr,
29553037
envoy_dynamic_module_type_module_buffer key, envoy_dynamic_module_type_envoy_buffer* value_out);
29563038

3039+
// -----------------------------------------------------------------------------
3040+
// Stream Info Operations
3041+
// -----------------------------------------------------------------------------
3042+
3043+
/**
3044+
* envoy_dynamic_module_callback_listener_filter_set_downstream_transport_failure_reason is called
3045+
* by the module to set the downstream transport failure reason for logging and debugging.
3046+
*
3047+
* @param filter_envoy_ptr is the pointer to the DynamicModuleListenerFilter object.
3048+
* @param reason is the reason string owned by the module.
3049+
*/
3050+
void envoy_dynamic_module_callback_listener_filter_set_downstream_transport_failure_reason(
3051+
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr,
3052+
envoy_dynamic_module_type_module_buffer reason);
3053+
3054+
/**
3055+
* envoy_dynamic_module_callback_listener_filter_get_connection_start_time_ms is called by the
3056+
* module to obtain the connection start time in milliseconds since Unix epoch.
3057+
*
3058+
* @param filter_envoy_ptr is the pointer to the DynamicModuleListenerFilter object.
3059+
* @return the start time in milliseconds since Unix epoch.
3060+
*/
3061+
uint64_t envoy_dynamic_module_callback_listener_filter_get_connection_start_time_ms(
3062+
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr);
3063+
29573064
#ifdef __cplusplus
29583065
}
29593066
#endif

source/extensions/dynamic_modules/abi_version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace DynamicModules {
66
#endif
77
// This is the ABI version calculated as a sha256 hash of the ABI header files. When the ABI
88
// changes, this value must change, and the correctness of this value is checked by the test.
9-
const char* kAbiVersion = "b83111f4c9c8c5a9218e2b2f18d0a00be3a6747df2f3c182edf4c2ba4ccb7b0f";
9+
const char* kAbiVersion = "3fe64075e0a96694bcfc55111b047d3c9a62c46482f9e7c91159e12b9211ba96";
1010

1111
#ifdef __cplusplus
1212
} // namespace DynamicModules

source/extensions/filters/listener/dynamic_modules/abi_impl.cc

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
#include <chrono>
2+
13
#include "envoy/network/listen_socket.h"
4+
#include "envoy/stream_info/stream_info.h"
25

36
#include "source/common/network/address_impl.h"
47
#include "source/common/network/utility.h"
@@ -133,6 +136,34 @@ bool envoy_dynamic_module_callback_listener_filter_get_remote_address(
133136
return true;
134137
}
135138

139+
bool envoy_dynamic_module_callback_listener_filter_get_direct_remote_address(
140+
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr,
141+
envoy_dynamic_module_type_envoy_buffer* address_out, uint32_t* port_out) {
142+
auto* filter = static_cast<DynamicModuleListenerFilter*>(filter_envoy_ptr);
143+
auto* callbacks = filter->callbacks();
144+
145+
if (callbacks == nullptr) {
146+
address_out->ptr = nullptr;
147+
address_out->length = 0;
148+
*port_out = 0;
149+
return false;
150+
}
151+
152+
const auto& address = callbacks->socket().connectionInfoProvider().directRemoteAddress();
153+
if (address == nullptr || address->ip() == nullptr) {
154+
address_out->ptr = nullptr;
155+
address_out->length = 0;
156+
*port_out = 0;
157+
return false;
158+
}
159+
160+
const std::string& addr_str = address->ip()->addressAsString();
161+
address_out->ptr = const_cast<char*>(addr_str.c_str());
162+
address_out->length = addr_str.size();
163+
*port_out = address->ip()->port();
164+
return true;
165+
}
166+
136167
bool envoy_dynamic_module_callback_listener_filter_get_local_address(
137168
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr,
138169
envoy_dynamic_module_type_envoy_buffer* address_out, uint32_t* port_out) {
@@ -161,6 +192,114 @@ bool envoy_dynamic_module_callback_listener_filter_get_local_address(
161192
return true;
162193
}
163194

195+
bool envoy_dynamic_module_callback_listener_filter_get_direct_local_address(
196+
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr,
197+
envoy_dynamic_module_type_envoy_buffer* address_out, uint32_t* port_out) {
198+
auto* filter = static_cast<DynamicModuleListenerFilter*>(filter_envoy_ptr);
199+
auto* callbacks = filter->callbacks();
200+
201+
if (callbacks == nullptr) {
202+
address_out->ptr = nullptr;
203+
address_out->length = 0;
204+
*port_out = 0;
205+
return false;
206+
}
207+
208+
const auto& address = callbacks->socket().connectionInfoProvider().directLocalAddress();
209+
if (address == nullptr || address->ip() == nullptr) {
210+
address_out->ptr = nullptr;
211+
address_out->length = 0;
212+
*port_out = 0;
213+
return false;
214+
}
215+
216+
const std::string& addr_str = address->ip()->addressAsString();
217+
address_out->ptr = const_cast<char*>(addr_str.c_str());
218+
address_out->length = addr_str.size();
219+
*port_out = address->ip()->port();
220+
return true;
221+
}
222+
223+
bool envoy_dynamic_module_callback_listener_filter_get_original_dst(
224+
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr,
225+
envoy_dynamic_module_type_envoy_buffer* address_out, uint32_t* port_out) {
226+
auto* filter = static_cast<DynamicModuleListenerFilter*>(filter_envoy_ptr);
227+
auto* callbacks = filter->callbacks();
228+
229+
if (callbacks == nullptr) {
230+
address_out->ptr = nullptr;
231+
address_out->length = 0;
232+
*port_out = 0;
233+
return false;
234+
}
235+
236+
if (callbacks->socket().addressType() != Network::Address::Type::Ip) {
237+
address_out->ptr = nullptr;
238+
address_out->length = 0;
239+
*port_out = 0;
240+
return false;
241+
}
242+
243+
// Avoid calling getOriginalDst on an invalid handle.
244+
if (callbacks->socket().ioHandle().fdDoNotUse() < 0) {
245+
address_out->ptr = nullptr;
246+
address_out->length = 0;
247+
*port_out = 0;
248+
return false;
249+
}
250+
251+
const auto original_dst = Network::Utility::getOriginalDst(callbacks->socket());
252+
if (original_dst == nullptr || original_dst->ip() == nullptr) {
253+
address_out->ptr = nullptr;
254+
address_out->length = 0;
255+
*port_out = 0;
256+
return false;
257+
}
258+
259+
// Cache the address in the filter to ensure lifetime extends beyond this function.
260+
filter->cachedOriginalDst() = original_dst;
261+
262+
const std::string& addr_str = original_dst->ip()->addressAsString();
263+
address_out->ptr = const_cast<char*>(addr_str.c_str());
264+
address_out->length = addr_str.size();
265+
*port_out = original_dst->ip()->port();
266+
return true;
267+
}
268+
269+
envoy_dynamic_module_type_address_type
270+
envoy_dynamic_module_callback_listener_filter_get_address_type(
271+
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr) {
272+
auto* filter = static_cast<DynamicModuleListenerFilter*>(filter_envoy_ptr);
273+
auto* callbacks = filter->callbacks();
274+
275+
if (callbacks == nullptr) {
276+
return envoy_dynamic_module_type_address_type_Unknown;
277+
}
278+
279+
switch (callbacks->socket().addressType()) {
280+
case Network::Address::Type::Ip:
281+
return envoy_dynamic_module_type_address_type_Ip;
282+
case Network::Address::Type::Pipe:
283+
return envoy_dynamic_module_type_address_type_Pipe;
284+
case Network::Address::Type::EnvoyInternal:
285+
return envoy_dynamic_module_type_address_type_EnvoyInternal;
286+
}
287+
288+
return envoy_dynamic_module_type_address_type_Unknown;
289+
}
290+
291+
bool envoy_dynamic_module_callback_listener_filter_is_local_address_restored(
292+
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr) {
293+
auto* filter = static_cast<DynamicModuleListenerFilter*>(filter_envoy_ptr);
294+
auto* callbacks = filter->callbacks();
295+
296+
if (callbacks == nullptr) {
297+
return false;
298+
}
299+
300+
return callbacks->socket().connectionInfoProvider().localAddressRestored();
301+
}
302+
164303
bool envoy_dynamic_module_callback_listener_filter_set_remote_address(
165304
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr,
166305
envoy_dynamic_module_type_module_buffer address, uint32_t port, bool is_ipv6) {
@@ -228,6 +367,15 @@ void envoy_dynamic_module_callback_listener_filter_continue_filter_chain(
228367
}
229368
}
230369

370+
void envoy_dynamic_module_callback_listener_filter_use_original_dst(
371+
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr, bool use_original_dst) {
372+
auto* filter = static_cast<DynamicModuleListenerFilter*>(filter_envoy_ptr);
373+
auto* callbacks = filter->callbacks();
374+
if (callbacks != nullptr) {
375+
callbacks->useOriginalDst(use_original_dst);
376+
}
377+
}
378+
231379
void envoy_dynamic_module_callback_listener_filter_close_socket(
232380
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr) {
233381
auto* filter = static_cast<DynamicModuleListenerFilter*>(filter_envoy_ptr);
@@ -308,6 +456,32 @@ bool envoy_dynamic_module_callback_listener_filter_get_filter_state(
308456
return true;
309457
}
310458

459+
void envoy_dynamic_module_callback_listener_filter_set_downstream_transport_failure_reason(
460+
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr,
461+
envoy_dynamic_module_type_module_buffer reason) {
462+
auto* filter = static_cast<DynamicModuleListenerFilter*>(filter_envoy_ptr);
463+
auto* callbacks = filter->callbacks();
464+
if (callbacks == nullptr || reason.ptr == nullptr || reason.length == 0) {
465+
return;
466+
}
467+
468+
callbacks->streamInfo().setDownstreamTransportFailureReason(
469+
absl::string_view(reason.ptr, reason.length));
470+
}
471+
472+
uint64_t envoy_dynamic_module_callback_listener_filter_get_connection_start_time_ms(
473+
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr) {
474+
auto* filter = static_cast<DynamicModuleListenerFilter*>(filter_envoy_ptr);
475+
auto* callbacks = filter->callbacks();
476+
if (callbacks == nullptr) {
477+
return 0;
478+
}
479+
480+
const auto start_time = callbacks->streamInfo().startTime();
481+
const auto duration = start_time.time_since_epoch();
482+
return std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
483+
}
484+
311485
} // extern "C"
312486

313487
} // namespace ListenerFilters

source/extensions/filters/listener/dynamic_modules/filter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class DynamicModuleListenerFilter : public Network::ListenerFilter,
3535
// Accessors for ABI callbacks.
3636
Network::ListenerFilterCallbacks* callbacks() { return callbacks_; }
3737
Network::ListenerFilterBuffer* currentBuffer() { return current_buffer_; }
38+
Network::Address::InstanceConstSharedPtr& cachedOriginalDst() { return cached_original_dst_; }
3839

3940
// Test-only setters.
4041
void setCallbacksForTest(Network::ListenerFilterCallbacks* callbacks) { callbacks_ = callbacks; }
@@ -71,6 +72,9 @@ class DynamicModuleListenerFilter : public Network::ListenerFilter,
7172
// Current buffer, only valid during onData callback.
7273
Network::ListenerFilterBuffer* current_buffer_ = nullptr;
7374

75+
// Cached original destination address to ensure lifetime extends beyond ABI callback.
76+
Network::Address::InstanceConstSharedPtr cached_original_dst_;
77+
7478
bool destroyed_ = false;
7579
};
7680

0 commit comments

Comments
 (0)