Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 155 additions & 0 deletions source/extensions/dynamic_modules/abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,40 @@ typedef enum envoy_dynamic_module_type_metrics_result {
envoy_dynamic_module_type_metrics_result_Frozen,
} envoy_dynamic_module_type_metrics_result;

// -----------------------------------------------------------------------------

/**
* envoy_dynamic_module_type_socket_option_state represents the socket state at which an option
* should be applied.
*/
typedef enum envoy_dynamic_module_type_socket_option_state {
envoy_dynamic_module_type_socket_option_state_Prebind = 0,
envoy_dynamic_module_type_socket_option_state_Bound = 1,
envoy_dynamic_module_type_socket_option_state_Listening = 2,
} envoy_dynamic_module_type_socket_option_state;

/**
* envoy_dynamic_module_type_socket_option_value_type represents the type of value stored in a
* socket option.
*/
typedef enum envoy_dynamic_module_type_socket_option_value_type {
envoy_dynamic_module_type_socket_option_value_type_Int = 0,
envoy_dynamic_module_type_socket_option_value_type_Bytes = 1,
} envoy_dynamic_module_type_socket_option_value_type;

/**
* envoy_dynamic_module_type_socket_option represents a socket option with its level, name, state,
* and value. The value can be either an integer or bytes depending on value_type.
*/
typedef struct envoy_dynamic_module_type_socket_option {
int64_t level;
int64_t name;
envoy_dynamic_module_type_socket_option_state state;
envoy_dynamic_module_type_socket_option_value_type value_type;
int64_t int_value;
envoy_dynamic_module_type_envoy_buffer byte_value;
} envoy_dynamic_module_type_socket_option;

// =============================================================================
// Network Filter Types
// =============================================================================
Expand Down Expand Up @@ -3061,6 +3095,127 @@ void envoy_dynamic_module_callback_listener_filter_set_downstream_transport_fail
uint64_t envoy_dynamic_module_callback_listener_filter_get_connection_start_time_ms(
envoy_dynamic_module_type_listener_filter_envoy_ptr filter_envoy_ptr);

/**
* envoy_dynamic_module_callback_http_set_socket_option sets an arbitrary socket option
* using setsockopt().
*
* WARNING: This provides direct access to setsockopt(). Incorrect usage can break
* the connection or interfere with Envoy's operation.
*
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object.
* @param level is the socket level (e.g., SOL_SOCKET, IPPROTO_TCP).
* @param optname is the option name (e.g., SO_REUSEADDR, TCP_NODELAY).
* @param optval is a pointer to the option value.
* @param optlen is the size of the option value.
* @return true if the socket option was set successfully, false otherwise.
*/
bool envoy_dynamic_module_callback_http_set_socket_option(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, int level, int optname,
const void* optval, size_t optlen);

/**
* envoy_dynamic_module_callback_http_get_socket_option gets a socket option value
* using getsockopt().
*
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object.
* @param level is the socket level (e.g., SOL_SOCKET, IPPROTO_TCP).
* @param optname is the option name (e.g., SO_REUSEADDR, TCP_NODELAY).
* @param optval is a pointer to store the option value.
* @param optlen is a pointer to the size of the optval buffer; updated with actual size.
* @return true if the socket option was retrieved successfully, false otherwise.
*/
bool envoy_dynamic_module_callback_http_get_socket_option(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, int level, int optname,
void* optval, size_t* optlen);

/**
* envoy_dynamic_module_callback_http_set_socket_option_int sets an integer socket option with
* the given level, name, and state.
*
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object.
* @param level is the socket option level (e.g., SOL_SOCKET).
* @param name is the socket option name (e.g., SO_KEEPALIVE).
* @param state is the socket state at which this option should be applied.
* @param value is the integer value for the socket option.
* @return true if the operation is successful, false otherwise.
*/
bool envoy_dynamic_module_callback_http_set_socket_option_int(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, int64_t level, int64_t name,
envoy_dynamic_module_type_socket_option_state state, int64_t value);

/**
* envoy_dynamic_module_callback_http_set_socket_option_bytes sets a bytes socket option with
* the given level, name, and state.
*
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object.
* @param level is the socket option level.
* @param name is the socket option name.
* @param state is the socket state at which this option should be applied.
* @param value is the byte buffer value for the socket option.
* @return true if the operation is successful, false otherwise.
*/
bool envoy_dynamic_module_callback_http_set_socket_option_bytes(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, int64_t level, int64_t name,
envoy_dynamic_module_type_socket_option_state state,
envoy_dynamic_module_type_module_buffer value);

/**
* envoy_dynamic_module_callback_http_get_socket_option_int retrieves an integer socket option
* value.
*
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object.
* @param level is the socket option level.
* @param name is the socket option name.
* @param state is the socket state.
* @param value_out is the pointer to store the retrieved integer value.
* @return true if the option is found, false otherwise.
*/
bool envoy_dynamic_module_callback_http_get_socket_option_int(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, int64_t level, int64_t name,
envoy_dynamic_module_type_socket_option_state state, int64_t* value_out);

/**
* envoy_dynamic_module_callback_http_get_socket_option_bytes retrieves a bytes socket option
* value.
*
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object.
* @param level is the socket option level.
* @param name is the socket option name.
* @param state is the socket state.
* @param value_out is the pointer to store the retrieved buffer. The buffer is owned by Envoy and
* valid until the filter is destroyed.
* @return true if the option is found, false otherwise.
*/
bool envoy_dynamic_module_callback_http_get_socket_option_bytes(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr, int64_t level, int64_t name,
envoy_dynamic_module_type_socket_option_state state,
envoy_dynamic_module_type_envoy_buffer* value_out);

/**
* envoy_dynamic_module_callback_http_get_socket_options_size returns the number of socket
* options stored on the connection.
*
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object.
* @return the number of socket options.
*/
size_t envoy_dynamic_module_callback_http_get_socket_options_size(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr);

/**
* envoy_dynamic_module_callback_http_get_socket_options gets all socket options stored on the
* connection. The caller should first call
* envoy_dynamic_module_callback_http_get_socket_options_size to get the size, allocate an array
* of that size, and pass the pointer to this function.
*
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object.
* @param options_out is the pointer to an array of socket options that will be filled. The array
* must be pre-allocated by the caller with size equal to the value returned by
* envoy_dynamic_module_callback_http_get_socket_options_size.
*/
void envoy_dynamic_module_callback_http_get_socket_options(
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
envoy_dynamic_module_type_socket_option* options_out);

/**
* envoy_dynamic_module_callback_listener_filter_get_dynamic_metadata_string is called by the
* module to retrieve a string-typed dynamic metadata value.
Expand Down
2 changes: 1 addition & 1 deletion source/extensions/dynamic_modules/abi_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace DynamicModules {
#endif
// This is the ABI version calculated as a sha256 hash of the ABI header files. When the ABI
// changes, this value must change, and the correctness of this value is checked by the test.
const char* kAbiVersion = "ecb768e12042cb69b0f1ad5446ffe76085009961157ab4c8c9277beec739572e";
const char* kAbiVersion = "bb0d82735225ace045ce3ec3ecdc9a874553cadec3aa90a0ca111790bb1a0af7";

#ifdef __cplusplus
} // namespace DynamicModules
Expand Down
55 changes: 55 additions & 0 deletions source/extensions/dynamic_modules/sdk/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1086,6 +1086,31 @@ pub trait EnvoyHttpFilter {
/// modifying the request headers, etc that affect the routing decision.
fn clear_route_cache(&mut self);

/// Set an arbitrary socket option using setsockopt().
///
/// WARNING: This provides direct access to setsockopt(). Incorrect usage can break
/// the connection or interfere with Envoy's operation.
///
/// # Arguments
/// * `level` - The socket level (e.g., libc::SOL_SOCKET, libc::IPPROTO_TCP).
/// * `optname` - The option name (e.g., libc::SO_REUSEADDR, libc::TCP_NODELAY).
/// * `optval` - A byte slice containing the option value.
///
/// # Returns
/// `true` if the socket option was set successfully, `false` otherwise.
fn set_socket_option(&mut self, level: i32, optname: i32, optval: &[u8]) -> bool;

/// Get a socket option value using getsockopt().
///
/// # Arguments
/// * `level` - The socket level (e.g., libc::SOL_SOCKET, libc::IPPROTO_TCP).
/// * `optname` - The option name (e.g., libc::SO_REUSEADDR, libc::TCP_NODELAY).
/// * `optval` - A mutable byte slice to store the option value.
///
/// # Returns
/// `Some(len)` with the actual length of the option value if successful, `None` otherwise.
fn get_socket_option(&self, level: i32, optname: i32, optval: &mut [u8]) -> Option<usize>;

/// Get the value of the attribute with the given ID as a string.
///
/// If the attribute is not found, not supported or is the wrong type, this returns `None`.
Expand Down Expand Up @@ -1956,6 +1981,36 @@ impl EnvoyHttpFilter for EnvoyHttpFilterImpl {
unsafe { abi::envoy_dynamic_module_callback_http_clear_route_cache(self.raw_ptr) }
}

fn set_socket_option(&mut self, level: i32, optname: i32, optval: &[u8]) -> bool {
unsafe {
abi::envoy_dynamic_module_callback_http_set_socket_option(
self.raw_ptr,
level,
optname,
optval.as_ptr() as *const std::ffi::c_void,
optval.len(),
)
}
}

fn get_socket_option(&self, level: i32, optname: i32, optval: &mut [u8]) -> Option<usize> {
let mut optlen = optval.len();
let success = unsafe {
abi::envoy_dynamic_module_callback_http_get_socket_option(
self.raw_ptr,
level,
optname,
optval.as_mut_ptr() as *mut std::ffi::c_void,
&mut optlen,
)
};
if success {
Some(optlen)
} else {
None
}
}

fn remove_request_header(&mut self, key: &str) -> bool {
unsafe {
abi::envoy_dynamic_module_callback_http_set_header(
Expand Down
3 changes: 3 additions & 0 deletions source/extensions/filters/http/dynamic_modules/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,11 @@ envoy_cc_library(
deps = [
":filter_lib",
"//source/common/http:utility_lib",
"//source/common/network:socket_option_lib",
"//source/common/network:upstream_socket_options_filter_state_lib",
"//source/common/router:string_accessor_lib",
"//source/extensions/dynamic_modules:dynamic_modules_lib",
"//source/extensions/filters/http/common:pass_through_filter_lib",
"@envoy_api//envoy/config/core/v3:pkg_cc_proto",
],
)
Loading
Loading