Search in sources :

Example 1 with PacketReceivedEvent

use of org.forgerock.openam.radius.server.events.PacketReceivedEvent in project OpenAM by OpenRock.

the class RadiusRequestListener method run.

/**
     * Where the work gets done. :-) Blocks until packets are received, validates the source IP against configured
     * clients and drops packets accordingly, then spools valid ones to the thread pool for handling and goes back to
     * listening.
     */
@Override
public void run() {
    // Flag to hold interrupted state for returning after cleanup.
    boolean interrupted = false;
    dumpBannerToLog();
    while (!terminated && !interrupted) {
        try {
            // assure big-endian (network) byte order for our buffer
            final ByteBuffer bfr = ByteBuffer.allocate(RadiusServerConstants.MAX_PACKET_SIZE);
            bfr.order(ByteOrder.BIG_ENDIAN);
            InetSocketAddress iAddr = null;
            // see if we have a datagram packet waiting for us
            try {
                iAddr = (InetSocketAddress) channel.receive(bfr);
                if (iAddr == null) {
                    // no datagram was available, it happens, just go back to listening
                    LOG.message("DatagramChannel receive returned null. No datagram available.");
                    continue;
                } else {
                    eventBus.post(new PacketReceivedEvent());
                }
            } catch (final ClosedByInterruptException c) {
                interrupted = true;
                continue;
            } catch (final IOException e) {
                LOG.warning("Exception Receiving RADIUS packet. Ignoring.", e);
                continue;
            } catch (final SecurityException e) {
                LOG.error("a security manager has been installed and it does not permit datagrams to be " + " accepted from the datagram's sender. Ignoring", e);
                continue;
            }
            // see if it is for a registered client
            final String ipAddr = iAddr.getAddress().toString();
            final ClientConfig clientConfig = config.findClient(ipAddr);
            if (clientConfig == null) {
                LOG.warning("No Defined RADIUS Client matches IP address " + ipAddr + ". Dropping request.");
                continue;
            }
            if (!clientConfig.isClassIsValid()) {
                LOG.warning("Declared Handler Class for Client '" + clientConfig.getName() + "' is not valid. See earlier loading exception. Dropping request.");
                continue;
            }
            // prepare buffer for draining and queue up a handler
            bfr.flip();
            final RadiusRequestContext reqCtx = new RadiusRequestContext(clientConfig, channel, iAddr);
            final PromiseImpl<RadiusResponse, RadiusProcessingException> promise = PromiseImpl.create();
            final RadiusRequestHandler requestHandler = new RadiusRequestHandler(accessRequestHandlerFactory, reqCtx, bfr, promise, promise, eventBus);
            executorService.execute(requestHandler);
            try {
                final RadiusResponse result = promise.getOrThrow();
                eventBus.post(new PacketProcessedEvent());
            } catch (final RadiusProcessingException e) {
                final RadiusProcessingExceptionNature nature = e.getNature();
                switch(nature) {
                    case CATASTROPHIC:
                        LOG.error("Catestrophic error processing a RADIUS request.", e);
                        terminated = true;
                        break;
                    case INVALID_RESPONSE:
                        LOG.error("Failed to handle request. This request will be ignored.", e);
                        break;
                    case TEMPORARY_FAILURE:
                        final String errStr = "Failed to handle request. This request could be retried, but that is" + " currently not implemented.";
                        LOG.error(errStr, e);
                        break;
                    default:
                        break;
                }
            }
        } catch (final Exception t) {
            LOG.error("Error receiving request.", t);
        }
    }
    // re-assert interrupted state if it occurred
    if (interrupted) {
        Thread.currentThread().interrupt();
    }
    try {
        // be sure that channel is closed
        channel.close();
    } catch (final Exception e) {
        LOG.error("Failed to close the Listener's UDP channel", e);
    }
    LOG.message("RADIUS Listener Exited.");
    this.listenerThread = null;
}
Also used : PacketReceivedEvent(org.forgerock.openam.radius.server.events.PacketReceivedEvent) InetSocketAddress(java.net.InetSocketAddress) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) IOException(java.io.IOException) ClosedByInterruptException(java.nio.channels.ClosedByInterruptException) SocketException(java.net.SocketException) ClosedByInterruptException(java.nio.channels.ClosedByInterruptException) PacketProcessedEvent(org.forgerock.openam.radius.server.events.PacketProcessedEvent) ClientConfig(org.forgerock.openam.radius.server.config.ClientConfig)

Aggregations

IOException (java.io.IOException)1 InetSocketAddress (java.net.InetSocketAddress)1 SocketException (java.net.SocketException)1 ByteBuffer (java.nio.ByteBuffer)1 ClosedByInterruptException (java.nio.channels.ClosedByInterruptException)1 ClientConfig (org.forgerock.openam.radius.server.config.ClientConfig)1 PacketProcessedEvent (org.forgerock.openam.radius.server.events.PacketProcessedEvent)1 PacketReceivedEvent (org.forgerock.openam.radius.server.events.PacketReceivedEvent)1