Beispiel #1
0
        /// <summary>
        /// Handle an incoming ConnectionSetup packet type
        /// </summary>
        /// <param name="packetDataSection">Serialised handshake data</param>
        internal void ConnectionSetupHandler(MemoryStream packetDataSection)
        {
            //We should never be trying to handshake an established connection
            ConnectionInfo remoteConnectionInfo = NetworkComms.InternalFixedSendReceiveOptions.DataSerializer.DeserialiseDataObject <ConnectionInfo>(packetDataSection,
                                                                                                                                                     NetworkComms.InternalFixedSendReceiveOptions.DataProcessors, NetworkComms.InternalFixedSendReceiveOptions.Options);

            if (ConnectionInfo.ConnectionType != remoteConnectionInfo.ConnectionType)
            {
                connectionSetupException    = true;
                connectionSetupExceptionStr = "Remote connectionInfo provided connectionType did not match expected connection type.";
            }
            else
            {
                //We use the following bool to track a possible existing connection which needs closing
                bool       possibleClashWithExistingConnection = false;
                Connection existingConnection = null;

                //We first try to establish everything within this lock in one go
                //If we can't quite complete the establish we have to come out of the lock at try to sort the problem
                bool connectionEstablishedSuccess = ConnectionSetupHandlerFinal(remoteConnectionInfo, ref possibleClashWithExistingConnection, ref existingConnection);

                //If we were not successful at establishing the connection we need to sort it out!
                if (!connectionEstablishedSuccess && !connectionSetupException)
                {
                    if (existingConnection == null)
                    {
                        throw new Exception("Connection establish issues and existingConnection was left as null.");
                    }

                    if (possibleClashWithExistingConnection)
                    {
                        //If we have a clash by endPoint we test the existing connection
                        if (NetworkComms.LoggingEnabled)
                        {
                            NetworkComms.Logger.Debug("Existing connection with " + ConnectionInfo + ". Testing existing connection.");
                        }
                        if (existingConnection.ConnectionAlive(1000))
                        {
                            //If the existing connection comes back as alive we don't allow this one to go any further
                            //This might happen if two peers try to connect to each other at the same time
                            connectionSetupException    = true;
                            connectionSetupExceptionStr = " ... existing live connection at provided end point for this connection (" + ConnectionInfo + "), there should be no need for a second.";
                        }
                    }

                    //We only try again if we did not log an exception
                    if (!connectionSetupException)
                    {
                        //Once we have tried to sort the problem we can try to finish the establish one last time
                        connectionEstablishedSuccess = ConnectionSetupHandlerFinal(remoteConnectionInfo, ref possibleClashWithExistingConnection, ref existingConnection);

                        //If we still failed then that's it for this establish
                        if (!connectionEstablishedSuccess && !connectionSetupException)
                        {
                            connectionSetupException    = true;
                            connectionSetupExceptionStr = "Attempted to establish connection with " + ConnectionInfo + ", but due to an existing connection this was not possible.";
                        }
                    }
                }

                //If we are server side and we receive a successful connection setup we can respond to here
                if (connectionEstablishedSuccess && ConnectionInfo.ServerSide)
                {
                    SendObject(Enum.GetName(typeof(ReservedPacketType), ReservedPacketType.ConnectionSetup), new ConnectionInfo(ConnectionInfo.ConnectionType, NetworkComms.NetworkIdentifier, ConnectionInfo.LocalEndPoint, true), NetworkComms.InternalFixedSendReceiveOptions);
                }
            }

            //Trigger any setup waits
            connectionSetupWait.Set();
        }