14
14
use core:: net:: SocketAddr ;
15
15
use std:: fmt;
16
16
use std:: net:: IpAddr ;
17
+ use std:: net:: Ipv6Addr ;
17
18
#[ cfg( target_os = "linux" ) ]
18
19
use std:: os:: linux:: net:: SocketAddrExt ;
19
20
use std:: str:: FromStr ;
@@ -236,6 +237,26 @@ impl<M: RemoteMessage> Rx<M> for MpscRx<M> {
236
237
}
237
238
}
238
239
240
+ /// The hostname to use for TLS connections.
241
+ #[ derive(
242
+ Clone ,
243
+ Debug ,
244
+ PartialEq ,
245
+ Eq ,
246
+ Hash ,
247
+ Serialize ,
248
+ Deserialize ,
249
+ strum:: EnumIter ,
250
+ strum:: Display ,
251
+ strum:: EnumString
252
+ ) ]
253
+ pub enum TcpMode {
254
+ /// Use localhost/loopback for the connection.
255
+ Localhost ,
256
+ /// Use host domain name for the connection.
257
+ Hostname ,
258
+ }
259
+
239
260
/// The hostname to use for TLS connections.
240
261
#[ derive(
241
262
Clone ,
@@ -315,7 +336,7 @@ impl fmt::Display for MetaTlsAddr {
315
336
#[ derive( Clone , Debug , PartialEq , Eq , Hash , Serialize , Deserialize , Named ) ]
316
337
pub enum ChannelTransport {
317
338
/// Transport over a TCP connection.
318
- Tcp ,
339
+ Tcp ( TcpMode ) ,
319
340
320
341
/// Transport over a TCP connection with TLS support within Meta
321
342
MetaTls ( TlsMode ) ,
@@ -333,7 +354,7 @@ pub enum ChannelTransport {
333
354
impl fmt:: Display for ChannelTransport {
334
355
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
335
356
match self {
336
- Self :: Tcp => write ! ( f, "tcp" ) ,
357
+ Self :: Tcp ( mode ) => write ! ( f, "tcp({:?})" , mode ) ,
337
358
Self :: MetaTls ( mode) => write ! ( f, "metatls({:?})" , mode) ,
338
359
Self :: Local => write ! ( f, "local" ) ,
339
360
Self :: Sim ( transport) => write ! ( f, "sim({})" , transport) ,
@@ -358,7 +379,13 @@ impl FromStr for ChannelTransport {
358
379
}
359
380
360
381
match s {
361
- "tcp" => Ok ( ChannelTransport :: Tcp ) ,
382
+ // Default to TcpMode::Hostname, if the mode isn't set
383
+ "tcp" => Ok ( ChannelTransport :: Tcp ( TcpMode :: Hostname ) ) ,
384
+ s if s. starts_with ( "tcp(" ) => {
385
+ let inner = & s[ "tcp(" . len ( ) ..s. len ( ) - 1 ] ;
386
+ let mode = inner. parse ( ) ?;
387
+ Ok ( ChannelTransport :: Tcp ( mode) )
388
+ }
362
389
"local" => Ok ( ChannelTransport :: Local ) ,
363
390
"unix" => Ok ( ChannelTransport :: Unix ) ,
364
391
s if s. starts_with ( "metatls(" ) && s. ends_with ( ")" ) => {
@@ -373,9 +400,10 @@ impl FromStr for ChannelTransport {
373
400
374
401
impl ChannelTransport {
375
402
/// All known channel transports.
376
- pub fn all ( ) -> [ ChannelTransport ; 3 ] {
403
+ pub fn all ( ) -> [ ChannelTransport ; 4 ] {
377
404
[
378
- ChannelTransport :: Tcp ,
405
+ ChannelTransport :: Tcp ( TcpMode :: Localhost ) ,
406
+ ChannelTransport :: Tcp ( TcpMode :: Hostname ) ,
379
407
ChannelTransport :: Local ,
380
408
ChannelTransport :: Unix ,
381
409
// TODO add MetaTls (T208303369)
@@ -392,7 +420,7 @@ impl ChannelTransport {
392
420
/// Returns true if this transport type represents a remote channel.
393
421
pub fn is_remote ( & self ) -> bool {
394
422
match self {
395
- ChannelTransport :: Tcp => true ,
423
+ ChannelTransport :: Tcp ( _ ) => true ,
396
424
ChannelTransport :: MetaTls ( _) => true ,
397
425
ChannelTransport :: Local => false ,
398
426
ChannelTransport :: Sim ( _) => false ,
@@ -502,18 +530,21 @@ impl ChannelAddr {
502
530
/// servers to "any" address.
503
531
pub fn any ( transport : ChannelTransport ) -> Self {
504
532
match transport {
505
- ChannelTransport :: Tcp => {
506
- let ip = hostname:: get ( )
507
- . ok ( )
508
- . and_then ( |hostname| {
509
- // TODO: Avoid using DNS directly once we figure out a good extensibility story here
510
- hostname. to_str ( ) . and_then ( |hostname_str| {
511
- dns_lookup:: lookup_host ( hostname_str)
512
- . ok ( )
513
- . and_then ( |addresses| addresses. first ( ) . cloned ( ) )
533
+ ChannelTransport :: Tcp ( mode) => {
534
+ let ip = match mode {
535
+ TcpMode :: Localhost => IpAddr :: V6 ( Ipv6Addr :: LOCALHOST ) ,
536
+ TcpMode :: Hostname => hostname:: get ( )
537
+ . ok ( )
538
+ . and_then ( |hostname| {
539
+ // TODO: Avoid using DNS directly once we figure out a good extensibility story here
540
+ hostname. to_str ( ) . and_then ( |hostname_str| {
541
+ dns_lookup:: lookup_host ( hostname_str)
542
+ . ok ( )
543
+ . and_then ( |addresses| addresses. first ( ) . cloned ( ) )
544
+ } )
514
545
} )
515
- } )
516
- . unwrap_or_else ( || IpAddr :: from_str ( "::1" ) . unwrap ( ) ) ;
546
+ . expect ( "Failed to resolve hostname to IP address" ) ,
547
+ } ;
517
548
Self :: Tcp ( SocketAddr :: new ( ip, 0 ) )
518
549
}
519
550
ChannelTransport :: MetaTls ( mode) => {
@@ -542,7 +573,13 @@ impl ChannelAddr {
542
573
/// The transport used by this address.
543
574
pub fn transport ( & self ) -> ChannelTransport {
544
575
match self {
545
- Self :: Tcp ( _) => ChannelTransport :: Tcp ,
576
+ Self :: Tcp ( addr) => {
577
+ if addr. ip ( ) . is_loopback ( ) {
578
+ ChannelTransport :: Tcp ( TcpMode :: Localhost )
579
+ } else {
580
+ ChannelTransport :: Tcp ( TcpMode :: Hostname )
581
+ }
582
+ }
546
583
Self :: MetaTls ( addr) => match addr {
547
584
MetaTlsAddr :: Host { hostname, .. } => match hostname. parse :: < IpAddr > ( ) {
548
585
Ok ( IpAddr :: V6 ( _) ) => ChannelTransport :: MetaTls ( TlsMode :: IpV6 ) ,
0 commit comments