private void ProcessNamedConnectionRequest(StandardNamedConnectRqPacket packet)
{
StandardNamedConnectRsPacket response = new StandardNamedConnectRsPacket
{ConnectionId = packet.ConnectionId};
// By default the conn id going back is the conn id of the request
// this will change if the connection is a success, then it will be our conn id.
lock (_receiveConnectLock)
{
// If this connection exists
if (_tcpConnections.IsRemoteConnection(packet.ConnectionId))
{
Logger.Debug("Request for connection id [" + packet.ConnectionId + "] already established, resending response");
TcpConnectionHolder tcpConnectionHolder = _tcpConnections.GetRemoteConnection(packet.ConnectionId);
response.RemoteConnectionId = tcpConnectionHolder.Connection.ConnectionId;
response.ProtocolId = tcpConnectionHolder.Connection.ProtocolId;
response.Sequence = tcpConnectionHolder.Connection.NextSeqToSend;
// we can respond that we are already established here
response.Success = true;
}
else
{
lock (_listeningNamedTCPEndPoints)
{
if (_listeningNamedTCPEndPoints.ContainsKey(packet.ConnectionName))
{
byte localConnectionId = GetNextConnectionId();
Logger.Debug("Found a listener for " + packet.ConnectionName + " connecting local conn [" + localConnectionId + "] to remote conn [" + packet.ConnectionId + "]");
byte agreedProtocolId = packet.ProtocolId;
if (packet.ProtocolId > MaxSupportedProtocolId)
{
Logger.Debug("They wanted protocol " + packet.ProtocolId + ", but I only support up to " + MaxSupportedProtocolId + ", so I propose it.");
agreedProtocolId = MaxSupportedProtocolId;
}
Logger.Debug("I have agreed to protocol " + agreedProtocolId);
response.ProtocolId = agreedProtocolId;
response.Sequence = (ushort) (_rand.Next(ushort.MaxValue));
ITcpTransportLayer connection = null;
switch (agreedProtocolId)
{
case (2):
{
connection = new TcpTransportLayerSlidingWindow(this, localConnectionId, packet.ConnectionId, response.Sequence, packet.Sequence);
break;
}
default:
{
Logger.Error("Failed to agree on a tcp protocol, I don't support " + agreedProtocolId);
break;
}
}
if (connection != null)
{
// only add the connection if
response.Success =
_listeningNamedTCPEndPoints[packet.ConnectionName].ConnectCallback(connection.Socket);
if (response.Success)
{
// set it up to tie up loose ends when the connection dies
connection.ConnectionClose += ConnectionOnConnectionClose;
_tcpConnections.Add(connection);
response.RemoteConnectionId = localConnectionId;
}
}
else
{
response.Success = false;
}
}
else
{
Logger.Warn("No listener for " + packet.ConnectionName);
response.Success = false;
}
}
}
}
Logger.Debug("Sending connection response : " + response);
SendData(response);
if (response.Success)
{
// This sends a positive response, we would like to get an Ack of this connection response
// which will open this connection, but should that ack not arrive, let set a timer to automatically
// open this connection after 10 seconds
// we know that the sender will retry the connection should it not receive our response.
_tcpConnections.GetLocalOpenConnection(response.RemoteConnectionId).StartTimerToOpen();
}
}