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); } } }
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(); } }