예제 #1
0
        public void HandlePackets()
        {
            IPEndPoint receive_ep  = new IPEndPoint(IPAddress.Any, 0);
            var        mtu_special = Encoding.ASCII.GetBytes("MTU ");

            while (!listener_stop.WaitOne(0))
            {
                try
                {
                    byte[] buf   = Socket.Receive(ref receive_ep);
                    byte[] tuple = EndPointToTuple(receive_ep);

                    if (Sessions.ContainsKey(tuple))
                    {
                        var session = Sessions[tuple];

                        bool mtu_probe = true;

                        for (int i = 0; i < 4; i++)
                        {
                            if (buf[i] != mtu_special[i])
                            {
                                mtu_probe = false;
                                break;
                            }
                        }

                        if (mtu_probe)
                        {
                            session.GoodMTUs.Add(buf.Length);
                            session.LastMTUProbe = DateTime.Now;
                            continue;
                        }

                        if (session.L7FragmentationCapable && !session.NegotiatingMTU)
                        {
                            session.HandleFragment(buf);
                        }
                        else
                        {
                            session.Push(buf);
                        }
                    }
                    else
                    {
                        var session = new UdpSession(Socket, this, receive_ep);

                        Message syn_msg = null;

                        try
                        {
                            syn_msg = Message.Parse(buf);
                        }
                        catch (Exception ex)
                        {
                            Log.Info("Ignored improper connection attempt with message {0}/0x{1:X2}", syn_msg?.Type, syn_msg?.Subtype);
                            continue;
                        }

                        if (syn_msg == null || syn_msg.Type != MessageType.Control || syn_msg.Subtype != UdpSession.SYN)
                        {
                            Log.Info("Ignored improper connection attempt with message {0}/0x{1:X2}", syn_msg?.Type, syn_msg?.Subtype);
                            continue;
                        }

                        Sessions[tuple] = session;

                        Utilities.StartThread(delegate
                        {
                            var syn_ack_msg = new Message(MessageType.Control, UdpSession.SYN_ACK);
                            syn_ack_msg.Store["capabilities"] = new byte[] { (byte)UdpCapabilities.L7Fragmentation };

                            session.Send(syn_ack_msg.Serialize());

                            var ack_msg = session.ReceiveMessage(UdpSession.HANDSHAKE_TIMEOUT);

                            if (ack_msg == null || ack_msg.Type != MessageType.Control || ack_msg.Subtype != UdpSession.ACK)
                            {
                                Log.Info("Ignored improper connection attempt with message {0}/0x{1:X2}", ack_msg?.Type, ack_msg?.Subtype);
                                Sessions.Remove(tuple);
                                return;
                            }

                            if (ack_msg.Store.ContainsKey("capabilities"))
                            {
                                session.L7FragmentationCapable = ack_msg.Store["capabilities"].Contains((byte)UdpCapabilities.L7Fragmentation);
                            }

                            Log.Info("Accepted UDP connection on {0}{1}", receive_ep, QueueConnections ? ", queueing session" : "");

                            if (session.L7FragmentationCapable)
                            {
                                Log.Info("Negotiating MTU...");
                                session.NegotiateMTU();
                            }

                            if (QueueConnections)
                            {
                                Queue.Add(new UdpTunnel(session));
                            }
                        });
                    }
                }
                catch (SocketException ex)
                {
                    Log.Error(ex);
                }
                catch (Exception ex)
                {
                    Log.Error(ex);
                }
            }
        }
예제 #2
0
 internal void Close(UdpSession session)
 {
     Sessions.Remove(EndPointToTuple(session.EndPoint));
 }