Ejemplo n.º 1
0
        public BasicTcpPacket getPacket(byte[] bytes)
        {
            BasicTcpPacket packet;

            switch (bytes[BasicTcpPacket.PKT_POS_TYPE])
            {
            case BasicTcpPacket.PKT_TYPE_DISCONNECT:
                packet = new StandardDisconnectPacket();
                break;

            case BasicTcpPacket.PKT_TYPE_DISCONNECT_ACK:
                packet = new StandardDisconnectAckPacket();
                break;

            case BasicTcpPacket.PKT_TYPE_DISCONNECT_RS:
                packet = new StandardDisconnectRsPacket();
                break;

            case BasicTcpPacket.PKT_TYPE_CONNECT_RS_ACK:
                packet = new StandardConnectRsAckPacket();
                break;

            case BasicTcpPacket.PKT_TYPE_CONNECT_NAME_RS:
                packet = new StandardNamedConnectRsPacket();
                break;

            case BasicTcpPacket.PKT_TYPE_CONNECT_NAME_RQ:
                packet = new StandardNamedConnectRqPacket();
                break;

            case BasicTcpPacket.PKT_TYPE_DATA:
                packet = new StandardTcpDataPacket();
                break;

            case BasicTcpPacket.PKT_TYPE_ACK:
                packet = new StandardAckPacket();
                break;

            case BasicTcpPacket.PKT_TYPE_NOP:
                packet = new StandardTcpNopPacket();
                break;

            default:
                throw new UnknownPacketException("Failed to determine packet type");
            }
            packet.ProcessPacket(bytes);
            return(packet);
        }
Ejemplo n.º 2
0
        public ITcpTransportLayer ConnectNamed(byte connectionId, String namedEndPoint, int timeout, byte protocolId)
        {
            long waitTime = timeout;

            Logger.Debug("Connecting to " + namedEndPoint + ", timeout is " + waitTime + "ms");
            StandardNamedConnectRqPacket packet = new StandardNamedConnectRqPacket(connectionId)
            {
                ConnectionName = namedEndPoint,
                ProtocolId     = protocolId,
                Sequence       = (ushort)(_rand.Next(ushort.MaxValue))
            };
            long startTime = DateTime.Now.Ticks;

            _connectEvents.Add(connectionId, new AutoResetEvent(false));
            do
            {
                _transport.SendData(packet);
                packet.ResendCount++;
                var timeSpan = new TimeSpan(DateTime.Now.Ticks - startTime);
                if (timeSpan.TotalMilliseconds > waitTime)
                {
                    Logger.Debug("Connect timeout : " + timeSpan.TotalMilliseconds + "ms");
                    if (_connectEvents.ContainsKey(connectionId))
                    {
                        _connectEvents.Remove(connectionId);
                    }
                    throw new TimeoutException("Timeout occured while connecting to " + namedEndPoint);
                }
                Logger.Debug("Waiting for connect response from " + namedEndPoint);
            } while (_connectEvents.ContainsKey(connectionId) && !_connectEvents[connectionId].WaitOne(5000));

            try
            {
                var response = _connectResults[connectionId];
                if (response.Success)
                {
                    ITcpTransportLayer connection;
                    switch (response.ProtocolId)
                    {
                    case (2):
                    {
                        connection = new TcpTransportLayerSlidingWindow(_transport, connectionId, response.RemoteConnectionId, packet.Sequence, response.Sequence);
                        break;
                    }

                    default:
                    {
                        throw new ConnectionException("Failed to agree on a protocol, I don't support " +
                                                      response.RemoteConnectionId);
                    }
                    }
                    Logger.Debug("We have agreed to protocol " + response.ProtocolId);

                    return(connection);
                }
                throw new ConnectionException("Failed to connect to " + namedEndPoint + ", service is unavailable");
            }
            finally
            {
                _connectResults.Remove(connectionId);
            }
        }
Ejemplo n.º 3
0
        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();
            }
        }