11//! Helpers for interacting with the Datadog Agent.
22
3- use std:: time:: Duration ;
3+ use std:: { net :: IpAddr , time:: Duration } ;
44
55use backon:: Retryable as _;
66use datadog_protos:: agent:: v1:: { RefreshRemoteAgentRequest , RegisterRemoteAgentRequest , RegisterRemoteAgentResponse } ;
@@ -15,7 +15,7 @@ use saluki_error::{generic_error, ErrorContext as _, GenericError};
1515use saluki_io:: net:: client:: http:: HttpsCapableConnectorBuilder ;
1616use tonic:: {
1717 service:: interceptor:: InterceptedService ,
18- transport:: { Channel , Endpoint } ,
18+ transport:: { Channel , Endpoint , Uri } ,
1919 Code , Request , Response ,
2020} ;
2121use tracing:: warn;
@@ -68,15 +68,20 @@ impl RemoteAgentClient {
6868 let auth_interceptor = BearerAuthInterceptor :: from_file ( & config. auth ( ) . auth_token_file_path ( ) ) . await ?;
6969 let ipc_cert_file_path = config. auth ( ) . ipc_cert_file_path ( ) ;
7070 let client_tls_config = build_ipc_client_ipc_tls_config ( ipc_cert_file_path) . await ?;
71- let connector_builder = HttpsCapableConnectorBuilder :: default ( ) . without_dns_resolution ( ) ;
71+ let endpoint = config. endpoint ( ) ?;
72+ let connector_builder = HttpsCapableConnectorBuilder :: default ( ) ;
73+ let connector_builder = if endpoint_requires_dns_resolution ( & endpoint) {
74+ connector_builder
75+ } else {
76+ connector_builder. without_dns_resolution ( )
77+ } ;
7278 #[ cfg( target_os = "linux" ) ]
7379 let connector_builder = if let Some ( addr) = config. vsock_addr ( ) ? {
7480 connector_builder. with_vsock_addr ( addr)
7581 } else {
7682 connector_builder
7783 } ;
7884 let https_connector = connector_builder. build ( client_tls_config) ?;
79- let endpoint = config. endpoint ( ) ?;
8085 let channel = Endpoint :: from ( endpoint. clone ( ) )
8186 . connect_timeout ( Duration :: from_secs ( 2 ) )
8287 . connect_with_connector ( https_connector)
@@ -240,6 +245,19 @@ impl RemoteAgentClient {
240245 }
241246}
242247
248+ fn endpoint_requires_dns_resolution ( endpoint : & Uri ) -> bool {
249+ match endpoint. host ( ) {
250+ Some ( host) => {
251+ let host = host
252+ . strip_prefix ( '[' )
253+ . and_then ( |host| host. strip_suffix ( ']' ) )
254+ . unwrap_or ( host) ;
255+ host. parse :: < IpAddr > ( ) . is_err ( )
256+ }
257+ None => false ,
258+ }
259+ }
260+
243261async fn try_query_agent_api (
244262 client : & mut AgentSecureClient < InterceptedService < Channel , BearerAuthInterceptor > > ,
245263) -> Result < ( ) , GenericError > {
@@ -260,3 +278,25 @@ async fn try_query_agent_api(
260278 } ,
261279 }
262280}
281+
282+ #[ cfg( test) ]
283+ mod tests {
284+ use tonic:: transport:: Uri ;
285+
286+ use super :: endpoint_requires_dns_resolution;
287+
288+ #[ test]
289+ fn hostname_endpoint_requires_dns_resolution ( ) {
290+ let endpoint = "https://datadog-agent:5001" . parse :: < Uri > ( ) . expect ( "valid URI" ) ;
291+ assert ! ( endpoint_requires_dns_resolution( & endpoint) ) ;
292+ }
293+
294+ #[ test]
295+ fn literal_ip_endpoints_do_not_require_dns_resolution ( ) {
296+ let ipv4_endpoint = "https://127.0.0.1:5001" . parse :: < Uri > ( ) . expect ( "valid URI" ) ;
297+ assert ! ( !endpoint_requires_dns_resolution( & ipv4_endpoint) ) ;
298+
299+ let ipv6_endpoint = "https://[::1]:5001" . parse :: < Uri > ( ) . expect ( "valid URI" ) ;
300+ assert ! ( !endpoint_requires_dns_resolution( & ipv6_endpoint) ) ;
301+ }
302+ }
0 commit comments