Procházet zdrojové kódy

Make the hostname in the endpoint configurable

Lucas Trzesniewski před 1 rokem
rodič
revize
d89d67ec59

+ 8 - 0
src/Abc.Zebus.Tests/Transport/ZmqTransportTests.cs

@@ -285,6 +285,14 @@ namespace Abc.Zebus.Tests.Transport
             Wait.Until(() => receivedMessages.Count == 2, 2.Seconds(), "unable to receive message");
         }
 
+        [Test]
+        public void should_use_fqdn_in_endpoint()
+        {
+            var transport = CreateAndStartZmqTransport("tcp://some.test.fqdn:*");
+            transport.InboundEndPoint.ShouldStartWith("tcp://some.test.fqdn:");
+            transport.Stop();
+        }
+
         [Test, Repeat(5)]
         public void should_terminate_zmq_connection_of_a_forgotten_peer_after_some_time()
         {

+ 3 - 18
src/Abc.Zebus/Transport/ZmqEndPoint.cs

@@ -1,28 +1,13 @@
-using System;
-using System.Net;
-
-namespace Abc.Zebus.Transport
+namespace Abc.Zebus.Transport
 {
     internal readonly struct ZmqEndPoint
     {
         private readonly string? _value;
 
         public ZmqEndPoint(string? value)
-        {
-            if (value?.StartsWith("tcp://0.0.0.0:", StringComparison.OrdinalIgnoreCase) == true)
-            {
-                var fqdn = Dns.GetHostEntry(string.Empty).HostName;
-                _value = value.Replace("0.0.0.0", fqdn);
-            }
-            else
-            {
-                _value = value;
-            }
-        }
+            => _value = value;
 
         public override string ToString()
-        {
-            return _value ?? "tcp://*:*";
-        }
+            => _value ?? "tcp://*:*";
     }
 }

+ 26 - 3
src/Abc.Zebus/Transport/ZmqInboundSocket.cs

@@ -1,5 +1,6 @@
 using System;
-using System.Text;
+using System.Net;
+using System.Text.RegularExpressions;
 using Abc.Zebus.Serialization.Protobuf;
 using Abc.Zebus.Transport.Zmq;
 using Microsoft.Extensions.Logging;
@@ -10,6 +11,9 @@ namespace Abc.Zebus.Transport
     {
         private static readonly ILogger _logger = ZebusLogManager.GetLogger(typeof(ZmqInboundSocket));
 
+        private static readonly Regex _endpointRegex = new(@"^tcp://(?<host>\*|[0-9a-zA-Z_.-]+):(?<port>\*|[0-9]+)/?$", RegexOptions.IgnoreCase);
+        private static readonly Regex _ipRegex = new(@"^(?:[0-9]+\.){3}[0-9]+$");
+
         private readonly ZmqContext _context;
         private readonly PeerId _peerId;
         private readonly ZmqEndPoint _configuredEndPoint;
@@ -30,12 +34,31 @@ namespace Abc.Zebus.Transport
         {
             _socket = CreateSocket();
 
-            _socket.Bind(_configuredEndPoint.ToString());
+            var (configuredHost, configuredPort) = ParseEndpoint(_configuredEndPoint.ToString());
+
+            _socket.Bind($"tcp://{(_ipRegex.IsMatch(configuredHost) ? configuredHost : "*")}:{configuredPort}");
+
+            var (boundHost, boundPort) = ParseEndpoint(_socket.GetOptionString(ZmqSocketOption.LAST_ENDPOINT));
+            if (boundHost == "0.0.0.0")
+            {
+                // Use the hostname from the config when one is provided, or the FQDN otherwise
+                boundHost = configuredHost == "*"
+                    ? Dns.GetHostEntry(string.Empty).HostName
+                    : configuredHost;
+            }
 
-            var socketEndPoint = new ZmqEndPoint(_socket.GetOptionString(ZmqSocketOption.LAST_ENDPOINT));
+            var socketEndPoint = new ZmqEndPoint($"tcp://{boundHost}:{boundPort}");
             _logger.LogInformation($"Socket bound, Inbound EndPoint: {socketEndPoint}");
 
             return socketEndPoint;
+
+            static (string host, string port) ParseEndpoint(string endpoint)
+            {
+                var match = _endpointRegex.Match(endpoint);
+                return match.Success
+                    ? (match.Groups["host"].Value, match.Groups["port"].Value)
+                    : throw new InvalidOperationException($"Invalid endpoint: {endpoint}");
+            }
         }
 
         public void Dispose()