// The TCP/IP stack currently does not properly handle dynamic client endpoints.
// It will will reuse a local TCP port before it ought to. So if you are attempting
// to connect to the same remote address:port as a previous connection, you'll wind
// up with the exact same TCP tuple. The remote endpoint will either reset the
// connection, or will simply not respond. So, for now, we just pick a random local
// port, in the dynamic range. The right thing to do is to fix the Singularity
// TCP/IP service; this is just a temporary work-around.
// conn.SendBindLocalEndPoint(0, 0);
Random rand = new Random();
int localPort = rand.Next(30000) + 1024;
conn.SendBindLocalEndPoint(0, (ushort)localPort);
switch receive {
case conn.OK():
// DebugStub.WriteLine("Socket bound");
break;
case conn.InvalidEndPoint():
DebugStub.WriteLine("bind: InvalidEndPoint");
throw new Exception("The TCP/IP driver refused the bind request.");
case conn.ChannelClosed():
throw new Exception("TCP/IP driver closed channel during bind!");
}
conn.SendConnect(ipv4_address, (ushort)port);
IPv4 addr = new IPv4(ipv4_address);
switch receive {
case conn.OK():
return conn;
case unsatisfiable:
delete conn;
throw new Exception(String.Format("Could not connect to TCP destination '{0}'. Unsatisfiable read.", addr.ToString()));
case conn.CouldNotConnect(error):
delete conn;
throw new Exception(String.Format("Could not connect to TCP destination '{0}:{1}': {2}", addr.ToString(), port.ToString(), TcpException.GetMessageForTcpError(error)));