// Resources must be established per-connection. /// <exception cref="NGit.Errors.TransportException"></exception> internal virtual Socket OpenConnection() { int tms = GetTimeout() > 0 ? GetTimeout() * 1000 : 0; int port = uri.GetPort() > 0 ? uri.GetPort() : GIT_PORT; Socket s = Sharpen.Extensions.CreateSocket(); try { IPAddress host = Sharpen.Extensions.GetAddressByName(uri.GetHost()); s.Bind2(null); s.Connect(new IPEndPoint(host, port), tms); } catch (IOException c) { try { s.Close(); } catch (IOException) { } // ignore a failure during close, we're already failing if (c is UnknownHostException) { throw new TransportException(uri, JGitText.Get().unknownHost); } if (c is ConnectException) { throw new TransportException(uri, c.Message); } throw new TransportException(uri, c.Message, c); } return(s); }
public virtual void TestAvoidLoopbackTcpSockets() { Configuration conf = new Configuration(); Socket socket = NetUtils.GetDefaultSocketFactory(conf).CreateSocket(); socket.Bind2(new IPEndPoint("127.0.0.1", 0)); System.Console.Error.WriteLine("local address: " + socket.GetLocalAddress()); System.Console.Error.WriteLine("local port: " + socket.GetLocalPort()); try { NetUtils.Connect(socket, new IPEndPoint(socket.GetLocalAddress(), socket.GetLocalPort ()), 20000); socket.Close(); NUnit.Framework.Assert.Fail("Should not have connected"); } catch (ConnectException ce) { System.Console.Error.WriteLine("Got exception: " + ce); Assert.True(ce.Message.Contains("resulted in a loopback")); } catch (SocketException se) { // Some TCP stacks will actually throw their own Invalid argument exception // here. This is also OK. Assert.True(se.Message.Contains("Invalid argument")); } }
/// <exception cref="System.IO.IOException"/> /// <exception cref="UnknownHostException"/> public override Socket CreateSocket(string host, int port, IPAddress localHostAddr , int localPort) { Socket socket = CreateSocket(); socket.Bind2(new IPEndPoint(localHostAddr, localPort)); socket.Connect(new IPEndPoint(host, port)); return(socket); }
/// <summary> /// Like /// <see cref="Connect(System.Net.Sockets.Socket, System.Net.EndPoint, int)"/> /// but /// also takes a local address and port to bind the socket to. /// </summary> /// <param name="socket"/> /// <param name="endpoint">the remote address</param> /// <param name="localAddr">the local address to bind the socket to</param> /// <param name="timeout">timeout in milliseconds</param> /// <exception cref="System.IO.IOException"/> public static void Connect(Socket socket, EndPoint endpoint, EndPoint localAddr, int timeout) { if (socket == null || endpoint == null || timeout < 0) { throw new ArgumentException("Illegal argument for connect()"); } SocketChannel ch = socket.GetChannel(); if (localAddr != null) { Type localClass = localAddr.GetType(); Type remoteClass = endpoint.GetType(); Preconditions.CheckArgument(localClass.Equals(remoteClass), "Local address %s must be of same family as remote address %s." , localAddr, endpoint); socket.Bind2(localAddr); } try { if (ch == null) { // let the default implementation handle it. socket.Connect(endpoint, timeout); } else { SocketIOWithTimeout.Connect(ch, endpoint, timeout); } } catch (SocketTimeoutException ste) { throw new ConnectTimeoutException(ste.Message); } // There is a very rare case allowed by the TCP specification, such that // if we are trying to connect to an endpoint on the local machine, // and we end up choosing an ephemeral port equal to the destination port, // we will actually end up getting connected to ourself (ie any data we // send just comes right back). This is only possible if the target // daemon is down, so we'll treat it like connection refused. if (socket.GetLocalPort() == socket.GetPort() && socket.GetLocalAddress().Equals( socket.GetInetAddress())) { Log.Info("Detected a loopback TCP socket, disconnecting it"); socket.Close(); throw new ConnectException("Localhost targeted connection resulted in a loopback. " + "No daemon is listening on the target port."); } }