-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
868 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,7 @@ Servers | |
|
||
dummy_close | ||
tcp_stream | ||
tcp_tproxy | ||
tls_stream | ||
http_proxy | ||
socks_proxy | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
.. _configuration_server_tcp_tproxy: | ||
|
||
tcp_tproxy | ||
========== | ||
|
||
.. versionadded:: 1.7.34 | ||
|
||
A simple tcp tproxy server, which will just forward traffic to the targeted remote address. | ||
|
||
The following common keys are supported: | ||
|
||
* :ref:`escaper <conf_server_common_escaper>` | ||
* :ref:`auditor <conf_server_common_auditor>` | ||
* :ref:`shared_logger <conf_server_common_shared_logger>` | ||
* :ref:`listen_in_worker <conf_server_common_listen_in_worker>` | ||
* :ref:`tcp_sock_speed_limit <conf_server_common_tcp_sock_speed_limit>` | ||
* :ref:`ingress_network_filter <conf_server_common_ingress_network_filter>` | ||
* :ref:`tcp_copy_buffer_size <conf_server_common_tcp_copy_buffer_size>` | ||
* :ref:`tcp_copy_yield_size <conf_server_common_tcp_copy_yield_size>` | ||
* :ref:`tcp_misc_opts <conf_server_common_tcp_misc_opts>` | ||
* :ref:`task_idle_check_duration <conf_server_common_task_idle_check_duration>` | ||
* :ref:`task_idle_max_count <conf_server_common_task_idle_max_count>` | ||
* :ref:`extra_metrics_tags <conf_server_common_extra_metrics_tags>` | ||
|
||
listen | ||
------ | ||
|
||
**required**, **type**: :ref:`tcp listen <conf_value_tcp_listen>` | ||
|
||
Set the listen config for this server. | ||
|
||
The instance count setting will be ignored if *listen_in_worker* is correctly enabled. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,239 @@ | ||
/* | ||
* Copyright 2024 ByteDance and/or its affiliates. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
use std::sync::Arc; | ||
use std::time::Duration; | ||
|
||
use anyhow::{anyhow, Context}; | ||
use ascii::AsciiString; | ||
use yaml_rust::{yaml, Yaml}; | ||
|
||
use g3_io_ext::LimitedCopyConfig; | ||
use g3_types::acl::AclNetworkRuleBuilder; | ||
use g3_types::metrics::{MetricsName, StaticMetricsTags}; | ||
use g3_types::net::{TcpListenConfig, TcpMiscSockOpts, TcpSockSpeedLimitConfig}; | ||
use g3_yaml::YamlDocPosition; | ||
|
||
use super::{AnyServerConfig, ServerConfig, ServerConfigDiffAction, IDLE_CHECK_MAXIMUM_DURATION}; | ||
|
||
const SERVER_CONFIG_TYPE: &str = "TcpTProxy"; | ||
|
||
#[derive(Clone, Debug, Eq, PartialEq)] | ||
pub(crate) struct TcpTProxyServerConfig { | ||
name: MetricsName, | ||
position: Option<YamlDocPosition>, | ||
pub(crate) escaper: MetricsName, | ||
pub(crate) auditor: MetricsName, | ||
pub(crate) shared_logger: Option<AsciiString>, | ||
pub(crate) listen: TcpListenConfig, | ||
pub(crate) listen_in_worker: bool, | ||
pub(crate) ingress_net_filter: Option<AclNetworkRuleBuilder>, | ||
pub(crate) tcp_sock_speed_limit: TcpSockSpeedLimitConfig, | ||
pub(crate) task_idle_check_duration: Duration, | ||
pub(crate) task_idle_max_count: i32, | ||
pub(crate) tcp_copy: LimitedCopyConfig, | ||
pub(crate) tcp_misc_opts: TcpMiscSockOpts, | ||
pub(crate) extra_metrics_tags: Option<Arc<StaticMetricsTags>>, | ||
} | ||
|
||
impl TcpTProxyServerConfig { | ||
fn new(position: Option<YamlDocPosition>) -> Self { | ||
TcpTProxyServerConfig { | ||
name: MetricsName::default(), | ||
position, | ||
escaper: MetricsName::default(), | ||
auditor: MetricsName::default(), | ||
shared_logger: None, | ||
listen: TcpListenConfig::default(), | ||
listen_in_worker: false, | ||
ingress_net_filter: None, | ||
tcp_sock_speed_limit: TcpSockSpeedLimitConfig::default(), | ||
task_idle_check_duration: Duration::from_secs(300), | ||
task_idle_max_count: 1, | ||
tcp_copy: Default::default(), | ||
tcp_misc_opts: Default::default(), | ||
extra_metrics_tags: None, | ||
} | ||
} | ||
|
||
pub(crate) fn parse( | ||
map: &yaml::Hash, | ||
position: Option<YamlDocPosition>, | ||
) -> anyhow::Result<Self> { | ||
let mut server = TcpTProxyServerConfig::new(position); | ||
|
||
g3_yaml::foreach_kv(map, |k, v| server.set(k, v))?; | ||
|
||
server.check()?; | ||
Ok(server) | ||
} | ||
|
||
fn set(&mut self, k: &str, v: &Yaml) -> anyhow::Result<()> { | ||
match g3_yaml::key::normalize(k).as_str() { | ||
super::CONFIG_KEY_SERVER_TYPE => Ok(()), | ||
super::CONFIG_KEY_SERVER_NAME => { | ||
self.name = g3_yaml::value::as_metrics_name(v)?; | ||
Ok(()) | ||
} | ||
"escaper" => { | ||
self.escaper = g3_yaml::value::as_metrics_name(v)?; | ||
Ok(()) | ||
} | ||
"auditor" => { | ||
self.auditor = g3_yaml::value::as_metrics_name(v)?; | ||
Ok(()) | ||
} | ||
"shared_logger" => { | ||
let name = g3_yaml::value::as_ascii(v)?; | ||
self.shared_logger = Some(name); | ||
Ok(()) | ||
} | ||
"extra_metrics_tags" => { | ||
let tags = g3_yaml::value::as_static_metrics_tags(v) | ||
.context(format!("invalid static metrics tags value for key {k}"))?; | ||
self.extra_metrics_tags = Some(Arc::new(tags)); | ||
Ok(()) | ||
} | ||
"listen" => { | ||
self.listen = g3_yaml::value::as_tcp_listen_config(v) | ||
.context(format!("invalid tcp listen config value for key {k}"))?; | ||
Ok(()) | ||
} | ||
"listen_in_worker" => { | ||
self.listen_in_worker = g3_yaml::value::as_bool(v)?; | ||
Ok(()) | ||
} | ||
"ingress_network_filter" | "ingress_net_filter" => { | ||
let filter = g3_yaml::value::acl::as_ingress_network_rule_builder(v).context( | ||
format!("invalid ingress network acl rule value for key {k}"), | ||
)?; | ||
self.ingress_net_filter = Some(filter); | ||
Ok(()) | ||
} | ||
"tcp_sock_speed_limit" | "tcp_conn_speed_limit" | "tcp_conn_limit" | "conn_limit" => { | ||
self.tcp_sock_speed_limit = g3_yaml::value::as_tcp_sock_speed_limit(v) | ||
.context(format!("invalid tcp socket speed limit value for key {k}"))?; | ||
Ok(()) | ||
} | ||
"tcp_copy_buffer_size" => { | ||
let buffer_size = g3_yaml::humanize::as_usize(v) | ||
.context(format!("invalid humanize usize value for key {k}"))?; | ||
self.tcp_copy.set_buffer_size(buffer_size); | ||
Ok(()) | ||
} | ||
"tcp_copy_yield_size" => { | ||
let yield_size = g3_yaml::humanize::as_usize(v) | ||
.context(format!("invalid humanize usize value for key {k}"))?; | ||
self.tcp_copy.set_yield_size(yield_size); | ||
Ok(()) | ||
} | ||
"tcp_misc_opts" => { | ||
self.tcp_misc_opts = g3_yaml::value::as_tcp_misc_sock_opts(v) | ||
.context(format!("invalid tcp misc sock opts value for key {k}"))?; | ||
Ok(()) | ||
} | ||
"task_idle_check_duration" => { | ||
self.task_idle_check_duration = g3_yaml::humanize::as_duration(v) | ||
.context(format!("invalid humanize duration value for key {k}"))?; | ||
Ok(()) | ||
} | ||
"task_idle_max_count" => { | ||
self.task_idle_max_count = | ||
g3_yaml::value::as_i32(v).context(format!("invalid i32 value for key {k}"))?; | ||
Ok(()) | ||
} | ||
_ => Err(anyhow!("invalid key {k}")), | ||
} | ||
} | ||
|
||
fn check(&mut self) -> anyhow::Result<()> { | ||
if self.name.is_empty() { | ||
return Err(anyhow!("name is not set")); | ||
} | ||
if self.escaper.is_empty() { | ||
return Err(anyhow!("escaper is not set")); | ||
} | ||
if self.task_idle_check_duration > IDLE_CHECK_MAXIMUM_DURATION { | ||
self.task_idle_check_duration = IDLE_CHECK_MAXIMUM_DURATION; | ||
} | ||
|
||
#[cfg(target_os = "linux")] | ||
self.listen.set_transparent(); | ||
self.listen.check()?; | ||
|
||
Ok(()) | ||
} | ||
} | ||
|
||
impl ServerConfig for TcpTProxyServerConfig { | ||
fn name(&self) -> &MetricsName { | ||
&self.name | ||
} | ||
|
||
fn position(&self) -> Option<YamlDocPosition> { | ||
self.position.clone() | ||
} | ||
|
||
fn server_type(&self) -> &'static str { | ||
SERVER_CONFIG_TYPE | ||
} | ||
|
||
fn escaper(&self) -> &MetricsName { | ||
&self.escaper | ||
} | ||
|
||
fn user_group(&self) -> &MetricsName { | ||
Default::default() | ||
} | ||
|
||
fn auditor(&self) -> &MetricsName { | ||
&self.auditor | ||
} | ||
|
||
fn diff_action(&self, new: &AnyServerConfig) -> ServerConfigDiffAction { | ||
let new = match new { | ||
AnyServerConfig::TcpTProxy(config) => config, | ||
_ => return ServerConfigDiffAction::SpawnNew, | ||
}; | ||
|
||
if self.eq(new) { | ||
return ServerConfigDiffAction::NoAction; | ||
} | ||
|
||
if self.listen != new.listen { | ||
return ServerConfigDiffAction::ReloadAndRespawn; | ||
} | ||
|
||
ServerConfigDiffAction::ReloadOnlyConfig | ||
} | ||
|
||
fn shared_logger(&self) -> Option<&str> { | ||
self.shared_logger.as_ref().map(|s| s.as_str()) | ||
} | ||
|
||
#[inline] | ||
fn limited_copy_config(&self) -> LimitedCopyConfig { | ||
self.tcp_copy | ||
} | ||
#[inline] | ||
fn task_idle_check_duration(&self) -> Duration { | ||
self.task_idle_check_duration | ||
} | ||
#[inline] | ||
fn task_max_idle_count(&self) -> i32 { | ||
self.task_idle_max_count | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.