ln.radius/RadiusServer.cs

91 lines
2.6 KiB
C#

// /**
// * File: RadiusServer.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using System.Net.Sockets;
using System.Net;
using System.Collections.Generic;
using System.Threading;
using System.Linq;
using ln.logging;
using ln.types.threads;
namespace ln.radius
{
public delegate byte[] LookupSecretDelegate(IPEndPoint endPoint);
public delegate void RadiusMessageReceived(RadiusServer radiusServer, RadiusMessage radiusMessage);
public class RadiusServer : IDisposable
{
public LookupSecretDelegate LookupSecret { get; set; }
public RadiusMessageReceived MessageReceived { get; set; }
public Pool RequestPool { get; } = new Pool(16);
UdpClient udp;
bool contListeners = true;
public RadiusServer()
{}
public RadiusServer(IPEndPoint endPoint)
{
udp = new UdpClient(endPoint);
RequestPool.Enqueue(() => ListenerThread(udp));
}
public void Close()
{
contListeners = false;
udp.Close();
RequestPool.Close();
}
public void Dispose()
{
Close();
}
public void Send(RadiusMessage message)
{
byte[] packet = message.Authenticate(LookupSecret(message.EndPoint));
lock (udp)
{
int sent = udp.Send(packet, packet.Length, message.EndPoint);
Logging.Log(LogLevel.DEBUG, "Radius sent {0} bytes to {1}", sent, message.EndPoint);
}
}
private void ListenerThread(UdpClient udp)
{
try
{
while (contListeners)
{
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
byte[] rx = udp.Receive(ref remoteEndPoint);
try
{
RadiusMessage radiusMessage = RadiusMessage.FromBytes(rx, remoteEndPoint);
RequestPool.Enqueue(() => MessageReceived(this, radiusMessage));
} catch (Exception e)
{
Logging.Log(e);
}
}
} catch (Exception e)
{
Logging.Log(LogLevel.ERROR, "radius listener thread caught exception: {0}", e);
Logging.Log(e);
}
}
}
}