예제 #1
0
            static void ParseShouldSucceed(string text)
            {
                Assert.IsTrue(IPv4EndPoint.TryParse(text, out IPv4EndPoint actual));
                IPEndPoint expected = IPEndPoint.Parse(text);

                Assert.AreEqual(expected, actual);
                Assert.AreEqual(expected.ToString(), actual.ToString());
            }
예제 #2
0
        internal TCPConnection(IPv4Address remoteIP, UInt16 remotePort, IPv4Address localIP, UInt16 localPort,
                               UInt32 initialSeqNumber, State initialState)
        {
            this.remoteEndpoint  = new IPv4EndPoint(remoteIP, remotePort);
            this.localEndpoint   = new IPv4EndPoint(localIP, localPort);
            this.remoteSeqNumber = initialSeqNumber;
            this.localSeqNumber  = 0x3040;

            this.state = initialState;

            // TODO: have socket be a hash key we can use to find connections quickly
            this.socket = remotePort;
        }
예제 #3
0
        internal TCPConnection(IPv4Address remoteIP, UInt16 remotePort, IPv4Address localIP, UInt16 localPort, 
            UInt32 initialSeqNumber, State initialState)
        {
            this.remoteEndpoint = new IPv4EndPoint(remoteIP, remotePort);
            this.localEndpoint = new IPv4EndPoint(localIP, localPort);
            this.remoteSeqNumber = initialSeqNumber;
            this.localSeqNumber = 0x3040;

            this.state = initialState;

            // TODO: have socket be a hash key we can use to find connections quickly
            this.socket = remotePort;
        }
예제 #4
0
        private async void MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
        {
            try
            {
                // accessing the properties of args seems to throw exceptions

                if (args.RemoteAddress.Type != HostNameType.Ipv4)
                {
                    // TODO support other types once the rest of Falcon does
                    Log(LogLevel.Warning, String.Format("Dropped Message - Remote peer: {0} unsupported type: {1}.", args.RemoteAddress.RawName, args.RemoteAddress.Type));
                    return;
                }

                if (args.RemoteAddress.RawName.StartsWith("127.") && args.RemotePort == localPortAsString)
                {
                    Log(LogLevel.Warning, "Dropped Message received from self.");
                    return;
                }

                IPv4EndPoint lastRemoteEndPoint = new IPv4EndPoint(args.RemoteAddress.RawName, args.RemotePort); // careful todo this within the lock so doesn't get re-assigned while we are using it

                DataReader dr = args.GetDataReader();
                int size = (int)dr.UnconsumedBufferLength;

                if (size == 0)
                {
                    // peer has closed 
                    TryRemovePeer(lastRemoteEndPoint);
                    return;
                }
                else if (size < Const.NORMAL_HEADER_SIZE || size > Const.MAX_DATAGRAM_SIZE)
                {
                    Log(LogLevel.Error, String.Format("Message dropped from peer: {0}, bad size: {0}", lastRemoteEndPoint, size));
                    return;
                }

                byte seq = dr.ReadByte();
                byte packetInfo = dr.ReadByte();

                // parse packet info byte
                HeaderPayloadSizeType hpst = (HeaderPayloadSizeType)(packetInfo & Const.PAYLOAD_SIZE_TYPE_MASK);
                SendOptions opts = (SendOptions)(packetInfo & Const.SEND_OPTS_MASK);
                PacketType type = (PacketType)(packetInfo & Const.PACKET_TYPE_MASK);

                // check the header makes sense
                if (!Enum.IsDefined(Const.HEADER_PAYLOAD_SIZE_TYPE_TYPE, hpst)
                    || !Enum.IsDefined(Const.SEND_OPTIONS_TYPE, opts)
                    || !Enum.IsDefined(Const.PACKET_TYPE_TYPE, type))
                {
                    Log(LogLevel.Warning, String.Format("Message dropped from peer: {0}, bad header.", lastRemoteEndPoint));
                    return;
                }

                // parse payload size
                int payloadSize;
                if (hpst == HeaderPayloadSizeType.Byte)
                {
                    payloadSize = dr.ReadByte();
                }
                else
                {
                    if (size < Const.LARGE_HEADER_SIZE)
                    {
                        Log(LogLevel.Error, String.Format("Message with large header dropped from peer: {0}, size: {1}.", lastRemoteEndPoint, size));
                        return;
                    }

                    payloadSizeBytes[0] = dr.ReadByte();
                    payloadSizeBytes[1] = dr.ReadByte();
                    payloadSize = BitConverter.ToUInt16(payloadSizeBytes, 0);
                }

                // validate payload size
                if (payloadSize != dr.UnconsumedBufferLength)
                {
                    Log(LogLevel.Error, String.Format("Message dropped from peer: {0}, payload size: {1}, not as specefied: {2}", lastRemoteEndPoint, dr.UnconsumedBufferLength, payloadSize));
                    return;
                }

                // copy the payload
                byte[] payload = null;
                if (payloadSize > 0)
                {
                    payload = new byte[payloadSize];
                    dr.ReadBytes(payload);
                }

                RemotePeer rp;
                if (!peersByIp.TryGetValue(lastRemoteEndPoint, out rp))
                {
                    // Could be the peer has not been added yet and is requesting to be added. 
                    // Or it could be we are asking to be added and peer is accepting!

                    if (type == PacketType.AddPeer)
                    {
                        string pass = null;
                        if (payloadSize > 0)
                            pass = Settings.TextEncoding.GetString(payload, 0, payloadSize);

                        if (pass != networkPass) // TODO something else?
                        {
                            // TODO send reject and reason
                            Log(LogLevel.Info, String.Format("Join request dropped from peer: {0}, bad pass.", lastRemoteEndPoint));
                        }
                        else if (peersByIp.ContainsKey(lastRemoteEndPoint))
                        {
                            // TODO send reject and reason
                            Log(LogLevel.Warning, String.Format("Join request dropped from peer: {0}, peer is already added!", lastRemoteEndPoint));
                        }
                        else
                        {
                            rp = await TryAddPeerAsync(lastRemoteEndPoint);
                            if(rp != null)
                                rp.BeginSend(SendOptions.Reliable, PacketType.AcceptJoin, null, null);
                        }
                    }
                    else if (type == PacketType.AcceptJoin)
                    {
                        AwaitingAcceptDetail detail;
                        if (!TryGetAndRemoveWaitingAcceptDetail(lastRemoteEndPoint, out detail))
                        {
                            // Possible reasons we do not have detail are: 
                            //  1) Accept is too late,
                            //  2) Accept duplicated and we have already removed it, or
                            //  3) Accept was unsolicited.

                            Log(LogLevel.Warning, String.Format("Accept dropped from peer: {0}, join request not found.", lastRemoteEndPoint));
                        }
                        else
                        {
                            // create the new peer, add the datagram to send ACK, call the callback
                            rp = await TryAddPeerAsync(lastRemoteEndPoint);
                            if (rp != null)
                            {
                                rp.AddReceivedPacket(seq, opts, type, payload);
                                TryResult tr = new TryResult(true, null, null, rp.Id);
                                detail.Callback(tr);
                            }
                        }
                    }
                    else
                    {
                        Log(LogLevel.Warning, String.Format("Message dropped from peer: {0}, peer unknown.", lastRemoteEndPoint));
                    }
                }
                else
                {
                    rp.AddReceivedPacket(seq, opts, type, payload);
                }
            }
            catch (Exception ex)
            {
                Log(LogLevel.Error, String.Format("Exception in MessageReceived handler: {0}.", ex.Message));
            }
        }