/** * JRadius - A RADIUS Server Java Adapter * Copyright (c) 2009 Coova Technologies, LLC <support@coova.com> * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or (at * your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ package net.jradius.client; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; import java.nio.ByteBuffer; import java.nio.channels.DatagramChannel; import net.jradius.exception.RadiusException; import net.jradius.log.RadiusLog; import net.jradius.packet.AccountingRequest; import net.jradius.packet.PacketFactory; import net.jradius.packet.RadiusFormat; import net.jradius.packet.RadiusPacket; import net.jradius.packet.RadiusRequest; import net.jradius.packet.RadiusResponse; public class UDPClientTransport extends RadiusClientTransport { private static final RadiusFormat format = RadiusFormat.getInstance(); public static final int defaultAuthPort = 1812; public static final int defaultAcctPort = 1813; protected DatagramChannel channel; protected DatagramSocket socket; public UDPClientTransport(DatagramSocket socket) { this.socket = socket; this.remoteInetAddress = socket.getInetAddress(); } public UDPClientTransport() throws IOException { this.channel = DatagramChannel.open(); this.socket = channel.socket(); this.remoteInetAddress = socket.getInetAddress(); } public void close() { if (socket != null) { try { socket.close(); } catch (Throwable e) { } } if (channel != null) { try { channel.close(); } catch (Throwable e) { e.printStackTrace(); } } } protected void send(RadiusRequest req, int attempt) throws Exception { int port = req instanceof AccountingRequest ? acctPort : authPort; if (statusListener != null) { statusListener.onBeforeSend(this, req); } if (attempt > 1) { RadiusLog.warn("RadiusClient retrying request (attempt " + attempt + ")..."); } ByteBuffer buffer = ByteBuffer.allocate(4096); format.packPacket(req, sharedSecret, buffer, true); DatagramPacket request = new DatagramPacket(buffer.array(), buffer.position(), getRemoteInetAddress(), port); socket.send(request); if (statusListener != null) { statusListener.onAfterSend(this); } } protected RadiusResponse receive(RadiusRequest req) throws Exception { if (statusListener != null) { statusListener.onBeforeReceive(this); } byte replyBytes[] = new byte[RadiusPacket.MAX_PACKET_LENGTH]; DatagramPacket reply = new DatagramPacket(replyBytes, replyBytes.length); socket.receive(reply); RadiusPacket replyPacket = PacketFactory.parse(reply, req.isRecyclable()); if (!(replyPacket instanceof RadiusResponse)) { throw new RadiusException("Received something other than a RADIUS Response to a Request"); } if (statusListener != null) { statusListener.onAfterReceive(this, replyPacket); } return (RadiusResponse)replyPacket; } @Override public void setSocketTimeout(int timeout) { super.setSocketTimeout(timeout); try { socket.setSoTimeout(this.socketTimeout); } catch (SocketException e) { e.printStackTrace(); } } }