-/*\r
- * Copyright (c) 2004 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.prpdp;\r
-\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-import org.umu.cops.stack.*;\r
-\r
-import java.io.IOException;\r
-import java.net.ServerSocket;\r
-import java.net.Socket;\r
-import java.util.Hashtable;\r
-import java.util.Map;\r
-import java.util.concurrent.ConcurrentHashMap;\r
-\r
-/**\r
- * Core PDP agent for provisioning\r
- */\r
-public class COPSPdpAgent extends Thread {\r
-\r
- public final static Logger logger = LoggerFactory.getLogger(COPSPdpAgent.class);\r
-\r
- /** Well-known port for COPS */\r
- public static final int WELL_KNOWN_PDP_PORT = 3288;\r
- /** Default keep-alive timer value (secs) */\r
- public static final short KA_TIMER_VALUE = 30;\r
- /** Default accounting timer value (secs) */\r
- public static final short ACCT_TIMER_VALUE = 0;\r
-\r
- /**\r
- PDP host port\r
- */\r
- private int _serverPort;\r
-\r
- /**\r
- Client-type of connecting PEP\r
- */\r
- private short _clientType;\r
-\r
- /**\r
- Accounting timer (secs)\r
- */\r
- private short _acctTimer;\r
-\r
- /**\r
- Keep-alive timer (secs)\r
- */\r
- private short _kaTimer;\r
-\r
- /**\r
- Maps a PEP-ID to a connection\r
- */\r
- private final Map<String, COPSPdpConnection> _connectionMap;\r
- // map < String(PEPID), COPSPdpConnection > ConnectionMap;\r
-\r
- /**\r
- * Policy data processing object\r
- */\r
- private COPSPdpDataProcess _process;\r
-\r
- /**\r
- * Creates a PDP Agent\r
- *\r
- * @param clientType COPS Client-type\r
- * @param process Object to perform policy data processing\r
- */\r
- public COPSPdpAgent(short clientType, COPSPdpDataProcess process) {\r
- _serverPort = WELL_KNOWN_PDP_PORT;\r
- _kaTimer = KA_TIMER_VALUE;\r
- _acctTimer = ACCT_TIMER_VALUE;\r
-\r
- _clientType = clientType;\r
- _connectionMap = new ConcurrentHashMap<>();\r
- _process = process;\r
- }\r
-\r
- /**\r
- * Creates a PDP Agent\r
- *\r
- * @param port Port to listen to\r
- * @param clientType COPS Client-type\r
- * @param process Object to perform policy data processing\r
- */\r
- public COPSPdpAgent(int port, short clientType, COPSPdpDataProcess process) {\r
- _serverPort = port;\r
-\r
- _kaTimer = KA_TIMER_VALUE;\r
- _acctTimer = ACCT_TIMER_VALUE;\r
-\r
- _clientType = clientType;\r
- _connectionMap = new ConcurrentHashMap<>();\r
- _process = process;\r
- }\r
-\r
- /**\r
- * Sets the keep-alive timer value\r
- * @param kaTimer Keep alive timer value (secs)\r
- */\r
- public void setKaTimer (short kaTimer) {\r
- _kaTimer = kaTimer;\r
- }\r
-\r
- /**\r
- * Sets the accounting timer value\r
- * @param acctTimer Accounting timer value (secs)\r
- */\r
- public void setAcctTimer (short acctTimer) {\r
- _acctTimer = acctTimer;\r
- }\r
-\r
- /**\r
- * Gets the value of the keep-alive timer\r
- * @return Keep-alive timer value (secs)\r
- */\r
- public short getKaTimer () {\r
- return _kaTimer;\r
- }\r
-\r
- /**\r
- * Gets the accounting timer value\r
- * @return Accounting timer value (secs)\r
- */\r
- public short getAcctTimer () {\r
- return _acctTimer;\r
- }\r
-\r
- /**\r
- * Gets the connection map\r
- * @return A <tt>Hashtable</tt> holding the connection map\r
- */\r
- public Hashtable getConnectionMap() {\r
- return new Hashtable(_connectionMap);\r
- }\r
-\r
- /**\r
- * Gets the client-type\r
- * @return The client-type\r
- */\r
- public short getClientType() {\r
- return _clientType;\r
- }\r
-\r
- /**\r
- * Disconnects a PEP\r
- * @param pepID PEP-ID of the PEP to be disconnected\r
- * @param error COPS Error to be reported as a reason\r
- * @throws COPSException\r
- * @throws IOException\r
- */\r
- public void disconnect (String pepID, COPSError error)\r
- throws COPSException, IOException {\r
-\r
- COPSPdpConnection pdpConn = _connectionMap.get(pepID);\r
-\r
- COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, _clientType);\r
- COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
- closeMsg.add(cHdr);\r
- if (error != null)\r
- closeMsg.add(error);\r
-\r
- closeMsg.writeData(pdpConn.getSocket());\r
- pdpConn.close();\r
- }\r
-\r
- /**\r
- * Requests a COPS sync for a PEP\r
- * @param pepID PEP-ID of the PEP to be synced\r
- * @throws COPSException\r
- * @throws COPSPdpException\r
- */\r
- public void sync (String pepID)\r
- throws COPSException, COPSPdpException {\r
-\r
- COPSPdpConnection pdpConn = _connectionMap.get(pepID);\r
- pdpConn.syncAllRequestState();\r
- }\r
-\r
- /**\r
- * Removes a PEP from the connection map\r
- * @param pepID PEP-ID of the PEP to be removed\r
- */\r
- public void delete (String pepID) {\r
- _connectionMap.remove(pepID);\r
- }\r
-\r
-\r
- /**\r
- * Runs the PDP process\r
- */\r
- public void run() {\r
- try {\r
- final ServerSocket serverSocket = new ServerSocket (_serverPort);\r
-\r
- //Loop through for Incoming messages\r
-\r
- // server infinite loop\r
- while (true) {\r
-\r
- // Wait for an incoming connection from a PEP\r
- Socket socket = serverSocket.accept();\r
-\r
- // COPSDebug.out(getClass().getName(),"New connection accepted " +\r
- // socket.getInetAddress() +\r
- // ":" + socket.getPort());\r
-\r
- // We're waiting for an OPN message\r
- try {\r
- COPSMsg msg = COPSTransceiver.receiveMsg(socket);\r
- if (msg.getHeader().isAClientOpen()) {\r
- handleClientOpenMsg(socket, msg);\r
- } else {\r
- // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);\r
- try {\r
- socket.close();\r
- } catch (Exception ex) {\r
- logger.error("Error closing socket", ex);\r
- }\r
- }\r
- } catch (Exception e) { // COPSException, IOException\r
- // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_EXCEPTION,\r
- // "(" + socket.getInetAddress() + ":" + socket.getPort() + ")", e);\r
- try {\r
- socket.close();\r
- } catch (Exception ex) {\r
- logger.error("Error closing socket", ex);\r
- }\r
- }\r
- }\r
- } catch (IOException e) {\r
- logger.error("Error caught while processing socket messages", e);\r
- }\r
- }\r
-\r
- /**\r
- * Handles a COPS client-open message\r
- * @param conn Socket to the PEP\r
- * @param msg <tt>COPSMsg</tt> holding the client-open message\r
- * @throws COPSException\r
- * @throws IOException\r
- */\r
- private void handleClientOpenMsg(Socket conn, COPSMsg msg)\r
- throws COPSException, IOException {\r
- COPSClientOpenMsg cMsg = (COPSClientOpenMsg) msg;\r
- COPSPepId pepId = cMsg.getPepId();\r
-\r
- // Validate Client Type\r
- if (msg.getHeader().getClientType() != _clientType) {\r
- // Unsupported client type\r
- COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType());\r
- COPSError err = new COPSError(COPSError.COPS_ERR_UNSUPPORTED_CLIENT_TYPE, (short) 0);\r
- COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
- closeMsg.add(cHdr);\r
- closeMsg.add(err);\r
- try {\r
- closeMsg.writeData(conn);\r
- } catch (IOException unae) {\r
- logger.error("Error writing COPS data", unae);\r
- }\r
-\r
- throw new COPSException("Unsupported client type");\r
- }\r
-\r
- // PEPId is mandatory\r
- if (pepId == null) {\r
- // Mandatory COPS object missing\r
- COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType());\r
- COPSError err = new COPSError(COPSError.COPS_ERR_MANDATORY_OBJECT_MISSING, (short) 0);\r
- COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
- closeMsg.add(cHdr);\r
- closeMsg.add(err);\r
- try {\r
- closeMsg.writeData(conn);\r
- } catch (IOException unae) {\r
- logger.error("Error writing close message", unae);\r
- }\r
-\r
- throw new COPSException("Mandatory COPS object missing (PEPId)");\r
- }\r
-\r
- // Support\r
- if ( (cMsg.getClientSI() != null) ||\r
- (cMsg.getPdpAddress() != null) ||\r
- (cMsg.getIntegrity() != null)) {\r
-\r
- // Unsupported objects\r
- COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType());\r
- COPSError err = new COPSError(COPSError.COPS_ERR_UNKNOWN_OBJECT, (short) 0);\r
- COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
- closeMsg.add(cHdr);\r
- closeMsg.add(err);\r
- try {\r
- closeMsg.writeData(conn);\r
- } catch (IOException unae) {\r
- logger.error("Error writing close message", unae);\r
- }\r
-\r
- throw new COPSException("Unsupported objects (ClientSI, PdpAddress, Integrity)");\r
- }\r
-\r
- // Connection accepted\r
- COPSHeader ahdr = new COPSHeader(COPSHeader.COPS_OP_CAT, msg.getHeader().getClientType());\r
- COPSKATimer katimer = new COPSKATimer(_kaTimer);\r
- COPSAcctTimer acctTimer = new COPSAcctTimer(_acctTimer);\r
- COPSClientAcceptMsg acceptMsg = new COPSClientAcceptMsg();\r
- acceptMsg.add(ahdr);\r
- acceptMsg.add(katimer) ;\r
- if (_acctTimer != 0) acceptMsg.add(acctTimer);\r
- acceptMsg.writeData(conn);\r
-\r
- COPSPdpConnection pdpConn = new COPSPdpConnection(pepId,conn,_process);\r
- pdpConn.setKaTimer(_kaTimer);\r
- if (_acctTimer != 0) pdpConn.setAccTimer(_acctTimer);\r
- new Thread(pdpConn).start();\r
- _connectionMap.put(pepId.getData().str(),pdpConn);\r
- }\r
-\r
-}\r
-\r
-\r
-\r
+/*
+ * Copyright (c) 2004 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.prpdp;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.umu.cops.stack.*;
+import org.umu.cops.stack.COPSError.ErrorTypes;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Core PDP agent for provisioning
+ */
+public class COPSPdpAgent extends Thread {
+
+ private static final Logger logger = LoggerFactory.getLogger(COPSPdpAgent.class);
+
+ /** Well-known port for COPS */
+ // public static final int WELL_KNOWN_PDP_PORT = 3288;
+ /** Default keep-alive timer value (secs) */
+ public static final short KA_TIMER_VALUE = 30;
+ /** Default accounting timer value (secs) */
+ public static final short ACCT_TIMER_VALUE = 0;
+
+ /**
+ * PDP host port
+ */
+ private int _serverPort;
+
+ /**
+ * Client-type of connecting PEP
+ */
+ private short _clientType;
+
+ /**
+ * Accounting timer (secs)
+ */
+ private short _acctTimer;
+
+ /**
+ * Keep-alive timer (secs)
+ */
+ private short _kaTimer;
+
+ /**
+ * The PEP ID
+ */
+ protected transient COPSPepId _pepId;
+
+ /**
+ * Maps a PEP-ID to a connection
+ * TODO - Refactor COPSPdpConnection to extend PCMMPdpConnection. Until then, the value must remain an Object
+ */
+ protected Map<String, Object> _connectionMap;
+ // map < String(PEPID), COPSPdpConnection > ConnectionMap;
+
+ /**
+ * Policy data processing object
+ */
+ private COPSPdpDataProcess _process;
+
+ /**
+ * Holds all of the threads to manage by PEP ID
+ */
+ protected final Map<String, Thread> threadMap;
+
+ /**
+ * Creates a PDP Agent
+ *
+ * @param port Port to listen to
+ * @param clientType COPS Client-type
+ * @param process Object to perform policy data processing
+ */
+ public COPSPdpAgent(final int port, final short clientType, final COPSPdpDataProcess process) {
+ _serverPort = port;
+
+ _kaTimer = KA_TIMER_VALUE;
+ _acctTimer = ACCT_TIMER_VALUE;
+
+ _clientType = clientType;
+ _connectionMap = new ConcurrentHashMap<>();
+ _process = process;
+ this.threadMap = new ConcurrentHashMap<>();
+ }
+
+ /**
+ * Gets the value of the keep-alive timer
+ * @return Keep-alive timer value (secs)
+ */
+ public short getKaTimer () {
+ return _kaTimer;
+ }
+
+ /**
+ * Gets the accounting timer value
+ * @return Accounting timer value (secs)
+ */
+ public short getAcctTimer () {
+ return _acctTimer;
+ }
+
+ /**
+ * Gets the client-type
+ * @return The client-type
+ */
+ public short getClientType() {
+ return _clientType;
+ }
+
+ /**
+ * Disconnects a PEP
+ * @param pepID PEP-ID of the PEP to be disconnected
+ * @param error COPS Error to be reported as a reason
+ * @throws COPSException
+ * @throws IOException
+ */
+ public void disconnect(final String pepID, final COPSError error) throws COPSException, IOException {
+ final COPSPdpConnection pdpConn = (COPSPdpConnection)_connectionMap.get(pepID);
+ final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(_clientType, error, null, null);
+ closeMsg.writeData(pdpConn.getSocket());
+ pdpConn.close();
+ }
+
+ /**
+ * Requests a COPS sync for a PEP
+ * @param pepID PEP-ID of the PEP to be synced
+ * @throws COPSException
+ * @throws COPSPdpException
+ */
+ public void sync(final String pepID) throws COPSException {
+ COPSPdpConnection pdpConn = (COPSPdpConnection) _connectionMap.get(pepID);
+ pdpConn.syncAllRequestState();
+ }
+
+ /**
+ * Removes a PEP from the connection map
+ * @param pepID PEP-ID of the PEP to be removed
+ */
+ public void delete(final String pepID) {
+ _connectionMap.remove(pepID);
+ }
+
+
+ /**
+ * Runs the PDP process
+ */
+ public void run() {
+ try {
+ final ServerSocket serverSocket = new ServerSocket (_serverPort);
+
+ //Loop through for Incoming messages
+ // server infinite loop
+ while (true) {
+ // Wait for an incoming connection from a PEP
+ final Socket socket = serverSocket.accept();
+
+ // COPSDebug.out(getClass().getName(),"New connection accepted " +
+ // socket.getInetAddress() +
+ // ":" + socket.getPort());
+
+ // We're waiting for an OPN message
+ try {
+ final COPSMsg msg = COPSTransceiver.receiveMsg(socket);
+ logger.info("Message received - " + msg);
+ if (msg.getHeader().getOpCode().equals(OPCode.OPN)) {
+ handleClientOpenMsg(socket, msg);
+ } else {
+ logger.error("Not an open message, closing socket");
+ try {
+ socket.close();
+ } catch (Exception ex) {
+ logger.error("Unexpected exception closing socket", ex);
+ }
+ }
+ } catch (Exception e) { // COPSException, IOException
+ // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_EXCEPTION,
+ // "(" + socket.getInetAddress() + ":" + socket.getPort() + ")", e);
+ try {
+ socket.close();
+ } catch (Exception ex) {
+ logger.error("Unexpected exception closing socket", ex);
+ }
+ }
+ }
+ } catch (IOException e) {
+ logger.error("Error caught while processing socket messages", e);
+ }
+ }
+
+ /**
+ * Handles a COPS client-open message
+ * @param conn Socket to the PEP
+ * @param msg <tt>COPSMsg</tt> holding the client-open message
+ * @throws COPSException
+ * @throws IOException
+ * TODO - Refactor PCMMPdpAgent#handleClientOpenMsg() as it contains much of this same logic
+ */
+ protected void handleClientOpenMsg(final Socket conn, final COPSMsg msg) throws COPSException, IOException {
+ final COPSClientOpenMsg cMsg = (COPSClientOpenMsg) msg;
+ _pepId = cMsg.getPepId();
+
+ // Validate Client Type
+ if (msg.getHeader().getClientType() != _clientType) {
+ // Unsupported client type
+ final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(_clientType,
+ new COPSError(ErrorTypes.UNSUPPORTED_CLIENT_TYPE, ErrorTypes.NA), null, null);
+ try {
+ closeMsg.writeData(conn);
+ } catch (IOException unae) {
+ logger.error("Unexpected exception writing data", unae);
+ }
+
+ throw new COPSException("Unsupported client type");
+ }
+
+ // PEPId is mandatory
+ if (_pepId == null) {
+ // Mandatory COPS object missing
+ final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(_clientType,
+ new COPSError(ErrorTypes.MANDATORY_OBJECT_MISSING, ErrorTypes.NA), null, null);
+ try {
+ closeMsg.writeData(conn);
+ } catch (IOException unae) {
+ logger.error("Unexpected exception writing data", unae);
+ }
+
+ throw new COPSException("Mandatory COPS object missing (PEPId)");
+ }
+
+ // Support
+ if ( (cMsg.getClientSI() != null) || (cMsg.getPdpAddress() != null) || (cMsg.getIntegrity() != null)) {
+ // Unsupported objects
+ final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(_clientType,
+ new COPSError(ErrorTypes.UNKNOWN_OBJECT, ErrorTypes.NA), null, null);
+ try {
+ closeMsg.writeData(conn);
+ } catch (IOException unae) {
+ logger.error("Exception writing data", unae);
+ }
+
+ throw new COPSException("Unsupported objects (ClientSI, PdpAddress, Integrity)");
+ }
+
+ // Connection accepted
+ final COPSClientAcceptMsg acceptMsg;
+ if (_acctTimer != 0)
+ acceptMsg = new COPSClientAcceptMsg(_clientType, new COPSKATimer(_kaTimer),
+ new COPSAcctTimer(_acctTimer), null);
+ else
+ acceptMsg = new COPSClientAcceptMsg(_clientType, new COPSKATimer(_kaTimer),null, null);
+ acceptMsg.writeData(conn);
+
+ final COPSPdpConnection pdpConn = new COPSPdpConnection(_pepId, conn, _process);
+ pdpConn.setKaTimer(_kaTimer);
+ if (_acctTimer != 0) pdpConn.setAcctTimer(_acctTimer);
+ new Thread(pdpConn).start();
+ _connectionMap.put(_pepId.getData().str(), pdpConn);
+ }
+
+}
+
+
+