Beispiel #1
0
        protected virtual bool Send(IPAddress address, Func <SkylakeNATMessage> message, int sent = 1)
        {
            if (address == null || message == null)
            {
                return(false);
            }
            SkylakeNATClient socket = this.GetClient(address, out int sessions);

            if (socket == null)
            {
                return(false);
            }
            SkylakeNATMessage packet = message();

            if (!socket.Send(packet, sent))
            {
                for (int i = 0; i < sessions; i++)
                {
                    socket = this.GetClient(address, out sessions);
                    if (socket == null)
                    {
                        break;
                    }
                    if (socket.Send(packet, sent))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Beispiel #2
0
 protected virtual void ProcessMessage(SkylakeNATClient socket, SkylakeNATMessage message)
 {
     if (message.Commands == Commands.NATCommands_kEthernetOutput)
     {
         IPFrame packet = IPv4Layer.ParseFrame(message.Payload, false);
         if (packet != null)
         {
             if (this._sockets.ContainsKey(packet.Source))
             {
                 this.PrivateInput(socket, packet);
             }
             else
             {
                 this.CloseManyClient(socket.Address);
             }
         }
     }
 }
Beispiel #3
0
 protected internal virtual void OnMessage(SkylakeNATMessage e)
 {
     this.Message?.Invoke(this, e);
 }
Beispiel #4
0
            public virtual bool Send(SkylakeNATMessage message, int sent = 1)
            {
                if (message == null)
                {
                    return(false);
                }
                Socket socket = null;

                lock (this._syncobj)
                {
                    socket = this._socket;
                    if (socket == null)
                    {
                        return(false);
                    }
                }
                BufferSegment payload_segment = message.Payload;

#if !_USE_RC4_SIMPLE_ENCIPHER || __USE_UDP_PAYLOAD_TAP_PACKET
                if (payload_segment.Length > 0)
                {
                    payload_segment = this._encryptor.Encrypt(payload_segment);
                }
#endif
                int    payload_size = payload_segment.Length;
                byte[] packet       = new byte[sizeof(pkg_hdr) + payload_size];
                fixed(byte *pinned = packet)
                {
                    pkg_hdr *pkg = (pkg_hdr *)pinned;

                    pkg->fk  = pkg_hdr.FK;
                    pkg->len = unchecked ((ushort)payload_size);
                    pkg->cmd = unchecked ((byte)message.Commands);
                    if (payload_size > 0)
                    {
                        byte *payload_data = sizeof(pkg_hdr) + pinned;
                        Marshal.Copy(payload_segment.Buffer, payload_segment.Offset, (IntPtr)payload_data, payload_size);
#if _USE_RC4_SIMPLE_ENCIPHER
                        RC4.rc4_crypt(this.Router.Key, payload_data, payload_size, this.Router.Subtract, 1);
#endif
                    }
                }

#if _USE_RC4_SIMPLE_ENCIPHER
                try
                {
                    if (sent <= 0)
                    {
                        sent = 1;
                    }
                    for (int i = 0; i < sent; i++)
                    {
                        socket.BeginSendTo(packet, 0, packet.Length, SocketFlags.None, this.LocalEndPoint, (ar) =>
                        {
                            try
                            {
                                socket.EndSendTo(ar);
                            }
                            catch (Exception) { }
                        }, null);
                    }
                    return(true);
                }
                catch (Exception)
                {
                    return(false);
                }
#else
                SocketError error = SocketError.SocketError;
                try
                {
                    socket.BeginSend(packet, 0, packet.Length, SocketFlags.None, out error, (ar) =>
                    {
                        error = SocketError.SocketError;
                        try
                        {
                            socket.EndSend(ar, out error);
                        }
                        catch (Exception)
                        {
                            error = SocketError.SocketError;
                        }
                        if (error != SocketError.Success)
                        {
                            this.CloseOrAbort();
                        }
                    }, null);
                }
                catch (Exception)
                {
                    error = SocketError.SocketError;
                }
                if (error != SocketError.Success && error != SocketError.IOPending)
                {
                    this.CloseOrAbort();
                    return(false);
                }
                return(true);
#endif
            }
Beispiel #5
0
            private void StartReceive(IAsyncResult ar)
            {
                SkylakeNATMessage message = null;
                SocketError       error   = SocketError.SocketError;

                try
                {
                    do
                    {
                        Socket socket = null;
                        lock (this._syncobj)
                            socket = this._socket;
                        if (socket == null)
                        {
                            return;
                        }
                        if (ar == null)
                        {
                            if (!_fhdr)
                            {
                                socket.BeginReceive(_phdr, 0, _phdr.Length, SocketFlags.None, out error, StartReceive, null);
                            }
                            else
                            {
                                int suplus = _message.Length - _fseek;
                                if (suplus >= Layer3Netif.MSS)
                                {
                                    suplus = Layer3Netif.MSS;
                                }
                                socket.BeginReceive(_message, _fseek, suplus, SocketFlags.None, out error, StartReceive, null);
                            }
                            if (error == SocketError.IOPending)
                            {
                                error = SocketError.Success;
                            }
                        }
                        else
                        {
                            int len = -1;
                            try
                            {
                                len = socket.EndReceive(ar, out error);
                            }
                            catch (Exception)
                            {
                                len = -1;
                            }
                            if (len <= 0)
                            {
                                error = SocketError.SocketError;
                                break;
                            }
                            else
                            {
                                bool completion = false;
                                if (!_fhdr)
                                {
                                    fixed(byte *pinned = _phdr)
                                    {
                                        pkg_hdr *pkg = (pkg_hdr *)pinned;

                                        if (len != sizeof(pkg_hdr) || pkg->fk != pkg_hdr.FK)
                                        {
                                            error = SocketError.SocketError;
                                            break;
                                        }
                                        if (0 == pkg->len)
                                        {
                                            completion = true;
                                        }
                                        else
                                        {
                                            _fseek   = 0;
                                            _fhdr    = true;
                                            _message = new byte[pkg->len];
                                        }
                                        error = SocketError.Success;
                                    }
                                }
                                else
                                {
                                    _fseek += len;
                                    if (_fseek >= _message.Length)
                                    {
                                        completion = true;
                                    }
                                    error = SocketError.Success;
                                }
                                if (completion)
                                {
                                    fixed(byte *pinned = _phdr)
                                    {
                                        pkg_hdr *pkg = (pkg_hdr *)pinned;

                                        if (0 == pkg->len)
                                        {
                                            message = new SkylakeNATMessage(new BufferSegment(BufferSegment.Empty));
                                        }
                                        else
                                        {
                                            message = new SkylakeNATMessage(new BufferSegment(_message));
                                        }
                                        if (0 == this.Id)
                                        {
                                            this.Id = pkg->id;
                                        }
                                        message.Commands = unchecked ((Commands)pkg->cmd);
                                        _fseek           = 0;
                                        _fhdr            = false;
                                        _message         = null;
                                    }
                                    error = SocketError.Success;
                                }
                            }
                        }
                    } while (false);
                }
                catch (Exception)
                {
                    error = SocketError.SocketError;
                }
                if (error != SocketError.Success)
                {
                    this.CloseOrAbort();
                }
                else if (ar != null)
                {
                    if (message != null)
                    {
                        BufferSegment segment = message.Payload;
#if !_USE_RC4_SIMPLE_ENCIPHER
                        if (segment.Length > 0)
                        {
                            segment         = this._encryptor.Decrypt(segment);
                            message.Payload = segment;
                        }
#else
                        fixed(byte *pinned = segment.Buffer)
                        if (pinned != null)
                        {
                            RC4.rc4_crypt(this.Router.Key, pinned, segment.Length, this.Router.Subtract, 0);
                        }
#endif
                        if (message.Commands != Commands.NATCommands_kAuthentication)
                        {
                            this.OnMessage(message);
                        }
                        else
                        {
                            this.OnAuthentication(message);
                        }
                    }
                    this.StartReceive(null);
                }
            }