Пример #1
0
        private void OnReceive(byte[] buffer, int size, IPEndPoint remoteEP)
        {
            uint senderId   = BitConverter.ToUInt32(buffer, 0);
            uint receiverId = BitConverter.ToUInt32(buffer, 4);

            if (senderId == 0)
            {
                if (receiverId == uint.MaxValue && size >= 8 + 1 + 20) // 8=receiver+sender ids, 1=command, 20=sha1 pass
                {
                    ExecuteCommand((TunnelCommand)buffer[8], buffer, size);
                }

                if (receiverId != 0)
                {
                    return;
                }
            }

            if ((senderId == receiverId && senderId != 0) ||
                remoteEP.Address.Equals(IPAddress.Loopback) ||
                remoteEP.Address.Equals(IPAddress.Any) ||
                remoteEP.Address.Equals(IPAddress.Broadcast) ||
                remoteEP.Port == 0)
            {
                return;
            }

            lock (_lock)
            {
                if (senderId == 0 && receiverId == 0)
                {
                    if (size == 50 && !PingLimitReached(remoteEP.Address))
                    {
                        Client.Client.SendTo(buffer, 0, 12, SocketFlags.None, remoteEP);
                    }

                    return;
                }

                TunnelClient sender;
                if (Mappings.TryGetValue(senderId, out sender))
                {
                    if (!remoteEP.Equals(sender.RemoteEP))
                    {
                        if (sender.TimedOut && !MaintenanceModeEnabled &&
                            NewConnectionAllowed(remoteEP.Address, sender.RemoteEP.Address))
                        {
                            sender.RemoteEP = new IPEndPoint(remoteEP.Address, remoteEP.Port);
                        }
                        else
                        {
                            return;
                        }
                    }

                    sender.SetLastReceiveTick();
                }
                else
                {
                    if (Mappings.Count >= MaxClients || MaintenanceModeEnabled || !NewConnectionAllowed(remoteEP.Address))
                    {
                        return;
                    }

                    sender          = new TunnelClient();
                    sender.RemoteEP = new IPEndPoint(remoteEP.Address, remoteEP.Port);
                    sender.SetLastReceiveTick();

                    Mappings.Add(senderId, sender);
                }

                TunnelClient receiver;
                if (Mappings.TryGetValue(receiverId, out receiver) && !receiver.RemoteEP.Equals(sender.RemoteEP))
                {
                    Client.Client.SendTo(buffer, 0, size, SocketFlags.None, receiver.RemoteEP);
                }
            }
        }
Пример #2
0
        private void ListenerReceive(IAsyncResult result)
        {
            HttpListener        listener = (HttpListener)result.AsyncState;
            HttpListenerContext context  = null;

            try
            {
                context = listener.EndGetContext(result);
            }
            finally
            {
                listener.BeginGetContext(new AsyncCallback(ListenerReceive), listener);
            }

            if (context == null)
            {
                return;
            }

            var response = context.Response;
            var request  = context.Request;

            response.KeepAlive = false;

            if (!NewConnectionAllowed(request.RemoteEndPoint.Address))
            {
                response.StatusCode = 429; // TooManyRequests
                response.Close();
                return;
            }

            if (request.Url.AbsolutePath.StartsWith("/maintenance/"))
            {
                if (MaintenancePassword.Length > 0 && request.Url.AbsolutePath.Split('/')[2] == MaintenancePassword)
                {
                    MaintenanceModeEnabled = true;
                    response.Close();
                    return;
                }

                response.StatusCode = (int)HttpStatusCode.Unauthorized;
                response.Close();
            }
            else if (request.Url.AbsolutePath.Equals("/status"))
            {
                string status = "";

                lock (_lock)
                {
                    status =
                        string.Format(
                            "{0} slots free.\n{1} slots in use.\n", MaxClients - Mappings.Count, Mappings.Count);
                }

                byte[] buf = Encoding.UTF8.GetBytes(status);

                response.ContentLength64 = buf.Length;
                response.OutputStream.Write(buf, 0, buf.Length);
                response.Close();
            }
            else if (request.Url.AbsolutePath.Equals("/request"))
            {
                if (MaintenanceModeEnabled)
                {
                    response.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
                    response.Close();
                    return;
                }

                int clients = 0;

                if (!int.TryParse(request.QueryString["clients"], out clients) || clients < 2 || clients > 8)
                {
                    response.StatusCode = (int)HttpStatusCode.BadRequest;
                    response.Close();
                    return;
                }

                var clientIds = new List <string>(clients);

                lock (_lock)
                {
                    if (Mappings.Count + clients <= MaxClients)
                    {
                        var rand = new Random();

                        while (clients > 0)
                        {
                            short clientId = (short)rand.Next(short.MinValue, short.MaxValue);

                            if (!Mappings.ContainsKey(clientId))
                            {
                                clients--;

                                var client = new TunnelClient();
                                client.SetLastReceiveTick();
                                Mappings.Add(clientId, client);

                                clientIds.Add(clientId.ToString());
                            }
                        }
                    }
                }

                if (clientIds.Count < 2)
                {
                    response.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
                    response.Close();
                    return;
                }


                string msg = string.Format("[{0}]", string.Join(",", clientIds));

                byte[] buffer = Encoding.UTF8.GetBytes(msg);

                response.ContentLength64 = buffer.Length;
                response.OutputStream.Write(buffer, 0, buffer.Length);
                response.Close();
            }
            else
            {
                response.StatusCode = (int)HttpStatusCode.BadRequest;
                response.Close();
            }
        }