You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ta...@apache.org on 2010/05/17 21:17:04 UTC
svn commit: r945319 - in
/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src:
main/csharp/Transport/Tcp/TcpTransportFactory.cs
test/csharp/NMSConnectionFactoryTest.cs
Author: tabish
Date: Mon May 17 19:17:04 2010
New Revision: 945319
URL: http://svn.apache.org/viewvc?rev=945319&view=rev
Log:
https://issues.apache.org/activemq/browse/AMQNET-250
Check for a local address and port to bind to on the URI and attempt a bind before connecting if one is found.
Modified:
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/NMSConnectionFactoryTest.cs
Modified: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs?rev=945319&r1=945318&r2=945319&view=diff
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs (original)
+++ activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs Mon May 17 19:17:04 2010
@@ -116,9 +116,28 @@ namespace Apache.NMS.ActiveMQ.Transport.
// Set transport. properties on this (the factory)
URISupport.SetProperties(this, map, "transport.");
- Tracer.Debug("Opening socket to: " + location.Host + " on port: " + location.Port);
- Socket socket = Connect(location.Host, location.Port);
-
+ // See if there is a local address and port specified
+ string localAddress = null;
+ int localPort = -1;
+
+ if(!String.IsNullOrEmpty(location.AbsolutePath) && !location.AbsolutePath.Equals("/"))
+ {
+ int index = location.AbsolutePath.IndexOf(':');
+ try
+ {
+ localPort = Int16.Parse(location.AbsolutePath.Substring(index + 1));
+ localAddress = location.AbsolutePath.Substring(1, index - 1);
+ Tracer.DebugFormat("Binding Socket to {0} on port: {1}", localAddress, localPort);
+ }
+ catch
+ {
+ Tracer.Warn("Invalid Port value on URI for local bind option, ignoring.");
+ }
+ }
+
+ Tracer.Debug("Opening socket to: " + location.Host + " on port: " + location.Port);
+ Socket socket = DoConnect(location.Host, location.Port, localAddress, localPort );
+
#if !NETCF
socket.ReceiveBufferSize = ReceiveBufferSize;
socket.SendBufferSize = SendBufferSize;
@@ -220,7 +239,7 @@ namespace Apache.NMS.ActiveMQ.Transport.
return ipEntry;
}
- private Socket ConnectSocket(IPAddress address, int port)
+ private Socket TryConnectSocket(IPAddress address, int port, string localAddress, int localPort)
{
if(null != address)
{
@@ -230,6 +249,11 @@ namespace Apache.NMS.ActiveMQ.Transport.
if(null != socket)
{
+ if(!String.IsNullOrEmpty(localAddress))
+ {
+ DoBind(socket, localAddress, localPort);
+ }
+
socket.Connect(new IPEndPoint(address, port));
if(socket.Connected)
{
@@ -292,7 +316,7 @@ namespace Apache.NMS.ActiveMQ.Transport.
return null;
}
- protected Socket Connect(string host, int port)
+ protected Socket DoConnect(string host, int port, string localAddress, int localPort)
{
Socket socket = null;
IPAddress ipaddress;
@@ -301,7 +325,7 @@ namespace Apache.NMS.ActiveMQ.Transport.
{
if(TryParseIPAddress(host, out ipaddress))
{
- socket = ConnectSocket(ipaddress, port);
+ socket = TryConnectSocket(ipaddress, port, localAddress, localPort);
}
else
{
@@ -313,12 +337,12 @@ namespace Apache.NMS.ActiveMQ.Transport.
{
// Prefer IPv6 first.
ipaddress = GetIPAddress(hostEntry, AddressFamily.InterNetworkV6);
- socket = ConnectSocket(ipaddress, port);
+ socket = TryConnectSocket(ipaddress, port, localAddress, localPort);
if(null == socket)
{
// Try IPv4 next.
ipaddress = GetIPAddress(hostEntry, AddressFamily.InterNetwork);
- socket = ConnectSocket(ipaddress, port);
+ socket = TryConnectSocket(ipaddress, port, localAddress, localPort);
if(null == socket)
{
// Try whatever else there is.
@@ -331,7 +355,7 @@ namespace Apache.NMS.ActiveMQ.Transport.
continue;
}
- socket = ConnectSocket(address, port);
+ socket = TryConnectSocket(ipaddress, port, localAddress, localPort);
if(null != socket)
{
ipaddress = address;
@@ -356,5 +380,86 @@ namespace Apache.NMS.ActiveMQ.Transport.
Tracer.DebugFormat("Connected to {0}:{1} using {2} protocol.", host, port, ipaddress.AddressFamily.ToString());
return socket;
}
+
+ protected void DoBind(Socket socket, string host, int port)
+ {
+ IPAddress ipaddress;
+
+ try
+ {
+ if(TryParseIPAddress(host, out ipaddress))
+ {
+ TryBindSocket(socket, ipaddress, port);
+ }
+ else
+ {
+ // Looping through the AddressList allows different type of connections to be tried
+ // (IPv6, IPv4 and whatever else may be available).
+ IPHostEntry hostEntry = GetIPHostEntry(host);
+
+ if(null != hostEntry)
+ {
+ // Prefer IPv6 first.
+ ipaddress = GetIPAddress(hostEntry, AddressFamily.InterNetworkV6);
+ if(!TryBindSocket(socket, ipaddress, port))
+ {
+ // Try IPv4 next.
+ ipaddress = GetIPAddress(hostEntry, AddressFamily.InterNetwork);
+ if(!TryBindSocket(socket, ipaddress, port))
+ {
+ // Try whatever else there is.
+ foreach(IPAddress address in hostEntry.AddressList)
+ {
+ if(AddressFamily.InterNetworkV6 == address.AddressFamily
+ || AddressFamily.InterNetwork == address.AddressFamily)
+ {
+ // Already tried these protocols.
+ continue;
+ }
+
+ if(TryBindSocket(socket, ipaddress, port))
+ {
+ ipaddress = address;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if(!socket.IsBound)
+ {
+ throw new SocketException();
+ }
+ }
+ catch(Exception ex)
+ {
+ throw new NMSConnectionException(String.Format("Error binding to {0}:{1}.", host, port), ex);
+ }
+
+ Tracer.DebugFormat("Bound to {0}:{1} using.", host, port);
+ }
+
+ private bool TryBindSocket(Socket socket, IPAddress address, int port)
+ {
+ if(null != socket && null != address)
+ {
+ try
+ {
+ socket.Bind(new IPEndPoint(address, port));
+ if(socket.IsBound)
+ {
+ return true;
+ }
+ }
+ catch
+ {
+ }
+ }
+
+ return false;
+ }
+
}
}
Modified: activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/NMSConnectionFactoryTest.cs
URL: http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/NMSConnectionFactoryTest.cs?rev=945319&r1=945318&r2=945319&view=diff
==============================================================================
--- activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/NMSConnectionFactoryTest.cs (original)
+++ activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/test/csharp/NMSConnectionFactoryTest.cs Mon May 17 19:17:04 2010
@@ -36,6 +36,8 @@ namespace Apache.NMS.ActiveMQ.Test
[RowTest]
[Row("tcp://${activemqhost}:61616")]
[Row("activemq:tcp://${activemqhost}:61616")]
+ [Row("activemq:tcp://${activemqhost}:61616/localhost:0")]
+ [Row("activemq:tcp://${activemqhost}:61616/0.0.0.0:0")]
[Row("activemq:tcp://${activemqhost}:61616?connection.asyncclose=false")]
[Row("activemq:failover:tcp://${activemqhost}:61616")]
[Row("activemq:failover:(tcp://${activemqhost}:61616)")]
@@ -48,6 +50,8 @@ namespace Apache.NMS.ActiveMQ.Test
[Row("activemq:failover:(discovery:(multicast://default))")]
#endif
+ [Row("activemq:tcp://${activemqhost}:61616/InvalidHost:0", ExpectedException = typeof(NMSConnectionException))]
+ [Row("activemq:tcp://${activemqhost}:61616/0.0.0.0:-1", ExpectedException = typeof(NMSConnectionException))]
[Row("tcp://InvalidHost:61616", ExpectedException = typeof(NMSConnectionException))]
[Row("activemq:tcp://InvalidHost:61616", ExpectedException = typeof(NMSConnectionException))]
[Row("activemq:tcp://InvalidHost:61616?connection.asyncclose=false", ExpectedException = typeof(NMSConnectionException))]