@@ -865,21 +865,21 @@ void proxy_server::close() noexcept
865865 acceptor.close (ignore_ec);
866866
867867#if defined(__linux__)
868+
868869 // 关闭 UDP TPROXY 相关资源.
870+ for (auto & [key, flow] : m_udp_tproxy_flows)
869871 {
870- std::lock_guard<std::mutex> lock (m_udp_flows_mutex);
871- for (auto & [key, flow] : m_udp_tproxy_flows)
872+ if (flow)
872873 {
873- if (flow)
874- {
875- flow->backend_sock_ .reset ();
876- flow->relay_sock_ .reset ();
877- }
874+ flow->backend_sock_ .reset ();
875+ flow->relay_sock_ .reset ();
878876 }
879- m_udp_tproxy_flows.clear ();
880877 }
878+ m_udp_tproxy_flows.clear ();
879+
881880 for (auto & s : m_udp_tproxy_listeners)
882881 s.close (ignore_ec);
882+
883883#endif // defined(__linux__)
884884
885885 for (auto & [id, c] : m_clients)
@@ -1182,7 +1182,6 @@ size_t proxy_server::make_udp_flow_key(const udp::endpoint& client, const udp::e
11821182
11831183net::awaitable<void > proxy_server::udp_tproxy_check () noexcept
11841184{
1185- std::lock_guard<std::mutex> lock (m_udp_flows_mutex);
11861185 std::vector<size_t > expired_keys;
11871186
11881187 for (const auto & [key, flow] : m_udp_tproxy_flows)
@@ -1539,16 +1538,14 @@ net::awaitable<void> proxy_server::udp_tproxy_response_loop(udp_tproxy_flow_ptr
15391538 return ;
15401539
15411540 flow->backend_sock_ .reset ();
1541+ flow->relay_sock_ .reset ();
1542+ flow->udp_http_sock_ .reset ();
15421543
1543- auto flow_key = make_udp_flow_key (
1544- flow->client_endp_ , flow->original_endp_ );
1545-
1546- std::lock_guard<std::mutex> lock (m_udp_flows_mutex);
1547- m_udp_tproxy_flows.erase (flow_key);
1544+ m_udp_tproxy_flows.erase (flow->flow_key_ );
15481545 });
15491546
1550- if (!flow-> backend_sock_ )
1551- flow->backend_sock_ .emplace (m_executor);
1547+ // 创建 backend socket 用于接收来自 proxy_pass 的 UDP 数据包.
1548+ flow->backend_sock_ .emplace (m_executor);
15521549
15531550 auto & backend_sock = flow->backend_sock_ ;
15541551 boost::system::error_code ec;
@@ -1702,9 +1699,6 @@ void proxy_server::send_response_to_client(udp_tproxy_flow_ptr flow, const char*
17021699void proxy_server::udp_tproxy_forward_packet (
17031700 udp_tproxy_flow_ptr flow, const char * data, std::size_t len)
17041701{
1705- if (!flow)
1706- return ;
1707-
17081702 if (!flow->backend_sock_ )
17091703 return ;
17101704
@@ -1767,7 +1761,6 @@ void proxy_server::udp_tproxy_forward_packet(
17671761 << " , dest: " << flow->original_endp_
17681762 << " , backend endp: " << m_backend_endp;
17691763
1770- std::lock_guard<std::mutex> lock (m_udp_flows_mutex);
17711764 m_udp_tproxy_flows.erase (flow->flow_key_ );
17721765 }
17731766}
@@ -1780,6 +1773,12 @@ net::awaitable<void> proxy_server::start_udp_tproxy_listen(udp::socket& udp_sock
17801773
17811774 boost::system::error_code ec;
17821775
1776+ auto scheme = boost::to_lower_copy (
1777+ std::string (m_option.proxy_pass_ ->scheme ()));
1778+
1779+ // 如果上游代理是 HTTP 代理, 则通过 connect-udp 协议进行 udp 代理.
1780+ bool using_connect_udp = scheme.starts_with (" http" );
1781+
17831782 while (!m_abort)
17841783 {
17851784 co_await udp_sock.async_wait (net::socket_base::wait_read, net_awaitable[ec]);
@@ -1819,18 +1818,10 @@ net::awaitable<void> proxy_server::start_udp_tproxy_listen(udp::socket& udp_sock
18191818 // 计算 flow 表的 key.
18201819 size_t flow_key = make_udp_flow_key (client_ep, original_dest);
18211820
1822- auto scheme = boost::to_lower_copy (
1823- std::string (m_option.proxy_pass_ ->scheme ()));
1824-
1825- // 如果上游代理是 HTTP 代理, 则通过 connect-udp 协议进行 udp 代理.
1826- bool using_connect_udp = scheme.starts_with (" http" );
1827-
18281821 std::shared_ptr<udp_tproxy_flow> flow;
18291822
18301823 auto make_tproxy_flow = [&]() mutable
18311824 {
1832- std::lock_guard<std::mutex> lock (m_udp_flows_mutex);
1833-
18341825 auto it = m_udp_tproxy_flows.find (flow_key);
18351826 if (it != m_udp_tproxy_flows.end ())
18361827 {
@@ -1891,9 +1882,6 @@ net::awaitable<void> proxy_server::start_udp_tproxy_listen(udp::socket& udp_sock
18911882void proxy_server::udp_tproxy_forward_packet_http (
18921883 udp_tproxy_flow_ptr flow, const char * data, std::size_t len)
18931884{
1894- if (!flow || !flow->udp_http_sock_ )
1895- return ;
1896-
18971885 // 构建 DATAGRAM capsule (RFC 9297):
18981886 // capsule type (varint) = 0x00
18991887 // capsule length (varint) = len + 1 # 这里 + 1 是因为 context ID 为 0 占用一字节
@@ -1913,8 +1901,6 @@ void proxy_server::udp_tproxy_forward_packet_http(
19131901
19141902 // 推入发送队列并通知发送协程.
19151903 {
1916- std::lock_guard<std::mutex> lock (m_udp_flows_mutex);
1917-
19181904 flow->send_queue_ .emplace_back (buf, buf + pos);
19191905
19201906 // 通知发送协程有新数据到达.
@@ -1942,7 +1928,6 @@ net::awaitable<void> proxy_server::udp_tproxy_http_udp_loop(udp_tproxy_flow_ptr
19421928 auto flow_key = make_udp_flow_key (
19431929 flow->client_endp_ , flow->original_endp_ );
19441930
1945- std::lock_guard<std::mutex> lock (m_udp_flows_mutex);
19461931 m_udp_tproxy_flows.erase (flow_key);
19471932 });
19481933
@@ -2088,13 +2073,10 @@ net::awaitable<void> proxy_server::udp_tproxy_http_udp_loop(udp_tproxy_flow_ptr
20882073 {
20892074 std::vector<char > item;
20902075
2076+ if (!flow->send_queue_ .empty ())
20912077 {
2092- std::lock_guard<std::mutex> lock (self->m_udp_flows_mutex );
2093- if (!flow->send_queue_ .empty ())
2094- {
2095- item = std::move (flow->send_queue_ .front ());
2096- flow->send_queue_ .pop_front ();
2097- }
2078+ item = std::move (flow->send_queue_ .front ());
2079+ flow->send_queue_ .pop_front ();
20982080 }
20992081
21002082 if (item.empty ())
@@ -2124,7 +2106,7 @@ net::awaitable<void> proxy_server::udp_tproxy_http_udp_loop(udp_tproxy_flow_ptr
21242106 }
21252107 }, net::detached);
21262108
2127- // 隧道建立成功, 进入响应读取循环: 从 TCP 接收 capsule, 提取 UDP payload,
2109+ // 隧道建立成功, 进入响应读取循环: 从 http 接收 capsule, 提取 UDP payload,
21282110 // 通过 relay_sock_ 发送回客户端.
21292111 while (!m_abort)
21302112 {
@@ -2165,11 +2147,11 @@ net::awaitable<void> proxy_server::udp_tproxy_http_udp_loop(udp_tproxy_flow_ptr
21652147 }
21662148
21672149 // 解析 context ID.
2168- auto val_data = reinterpret_cast <const uint8_t *>(
2169- capsule_value.data ());
2150+ auto val_data = reinterpret_cast <const uint8_t *>(capsule_value.data ());
21702151 size_t val_len = capsule_value.size ();
21712152
2172- if (val_len == 0 ) continue ;
2153+ if (val_len == 0 )
2154+ continue ;
21732155
21742156 auto [ctx_id_len, ctx_id] = varint_int_decode (val_data);
21752157 if (ctx_id != 0 )
@@ -2200,10 +2182,7 @@ net::awaitable<void> proxy_server::udp_tproxy_http_udp_loop(udp_tproxy_flow_ptr
22002182 flow->udp_http_sock_ .reset ();
22012183 flow->backend_sock_ .reset ();
22022184
2203- {
2204- std::lock_guard<std::mutex> lock (m_udp_flows_mutex);
2205- m_udp_tproxy_flows.erase (flow->flow_key_ );
2206- }
2185+ m_udp_tproxy_flows.erase (flow->flow_key_ );
22072186
22082187 XLOG_DBG << " tproxy flow: " << flow->flow_key_
22092188 << " , connect-udp loop ended" ;
0 commit comments