2 * Copyright (c) 2004 University of Murcia. All rights reserved.
\r
3 * --------------------------------------------------------------
\r
4 * For more information, please see <http://www.umu.euro6ix.org/>.
\r
7 package org.umu.cops.prpdp;
\r
9 import java.io.IOException;
\r
10 import java.net.ServerSocket;
\r
11 import java.net.Socket;
\r
12 import java.util.Enumeration;
\r
13 import java.util.Hashtable;
\r
15 import org.umu.cops.common.COPSDebug;
\r
16 import org.umu.cops.stack.COPSAcctTimer;
\r
17 import org.umu.cops.stack.COPSClientAcceptMsg;
\r
18 import org.umu.cops.stack.COPSClientCloseMsg;
\r
19 import org.umu.cops.stack.COPSClientOpenMsg;
\r
20 import org.umu.cops.stack.COPSError;
\r
21 import org.umu.cops.stack.COPSException;
\r
22 import org.umu.cops.stack.COPSHeader;
\r
23 import org.umu.cops.stack.COPSKATimer;
\r
24 import org.umu.cops.stack.COPSMsg;
\r
25 import org.umu.cops.stack.COPSPepId;
\r
26 import org.umu.cops.stack.COPSTransceiver;
\r
29 * Core PDP agent for provisioning
\r
31 public class COPSPdpAgent extends Thread {
\r
32 /** Well-known port for COPS */
\r
33 public static final int WELL_KNOWN_PDP_PORT = 3288;
\r
34 /** Default keep-alive timer value (secs) */
\r
35 public static final short KA_TIMER_VALUE = 30;
\r
36 /** Default accounting timer value (secs) */
\r
37 public static final short ACCT_TIMER_VALUE = 0;
\r
42 private ServerSocket _serverSocket;
\r
47 private int _serverPort;
\r
50 Client-type of connecting PEP
\r
52 private short _clientType;
\r
55 Accounting timer (secs)
\r
57 private short _acctTimer;
\r
60 Keep-alive timer (secs)
\r
62 private short _kaTimer;
\r
65 Maps a PEP-ID to a connection
\r
67 private Hashtable _connectionMap;
\r
68 // map < String(PEPID), COPSPdpConnection > ConnectionMap;
\r
71 * Policy data processing object
\r
73 private COPSPdpDataProcess _process;
\r
76 * Creates a PDP Agent
\r
78 * @param clientType COPS Client-type
\r
79 * @param process Object to perform policy data processing
\r
81 public COPSPdpAgent(short clientType, COPSPdpDataProcess process) {
\r
82 _serverPort = WELL_KNOWN_PDP_PORT;
\r
83 _kaTimer = KA_TIMER_VALUE;
\r
84 _acctTimer = ACCT_TIMER_VALUE;
\r
86 _clientType = clientType;
\r
87 _connectionMap = new Hashtable(40);
\r
92 * Creates a PDP Agent
\r
94 * @param port Port to listen to
\r
95 * @param clientType COPS Client-type
\r
96 * @param process Object to perform policy data processing
\r
98 public COPSPdpAgent(int port, short clientType, COPSPdpDataProcess process) {
\r
101 _kaTimer = KA_TIMER_VALUE;
\r
102 _acctTimer = ACCT_TIMER_VALUE;
\r
104 _clientType = clientType;
\r
105 _connectionMap = new Hashtable(40);
\r
106 _process = process;
\r
110 * Sets the keep-alive timer value
\r
111 * @param kaTimer Keep alive timer value (secs)
\r
113 public void setKaTimer (short kaTimer) {
\r
114 _kaTimer = kaTimer;
\r
118 * Sets the accounting timer value
\r
119 * @param acctTimer Accounting timer value (secs)
\r
121 public void setAcctTimer (short acctTimer) {
\r
122 _acctTimer = acctTimer;
\r
126 * Gets the value of the keep-alive timer
\r
127 * @return Keep-alive timer value (secs)
\r
129 public short getKaTimer () {
\r
134 * Gets the accounting timer value
\r
135 * @return Accounting timer value (secs)
\r
137 public short getAcctTimer () {
\r
142 * Gets the PEPs connected to this PDP
\r
143 * @return An <tt>Enumeration</tt> of all connected PEPs
\r
145 public Enumeration getConnectedPEPIds() {
\r
146 return _connectionMap.keys();
\r
150 * Gets the connection map
\r
151 * @return A <tt>Hashtable</tt> holding the connection map
\r
153 public Hashtable getConnectionMap() {
\r
154 return _connectionMap;
\r
158 * Gets the client-type
\r
159 * @return The client-type
\r
161 public short getClientType() {
\r
162 return _clientType;
\r
166 * Disconnects a PEP
\r
167 * @param pepID PEP-ID of the PEP to be disconnected
\r
168 * @param error COPS Error to be reported as a reason
\r
169 * @throws COPSException
\r
170 * @throws IOException
\r
172 public void disconnect (String pepID, COPSError error)
\r
173 throws COPSException, IOException {
\r
175 COPSPdpConnection pdpConn = (COPSPdpConnection) _connectionMap.get(pepID);
\r
177 COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, _clientType);
\r
178 COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
\r
179 closeMsg.add(cHdr);
\r
181 closeMsg.add(error);
\r
183 closeMsg.writeData(pdpConn.getSocket());
\r
189 * Requests a COPS sync for a PEP
\r
190 * @param pepID PEP-ID of the PEP to be synced
\r
191 * @throws COPSException
\r
192 * @throws COPSPdpException
\r
194 public void sync (String pepID)
\r
195 throws COPSException, COPSPdpException {
\r
197 COPSPdpConnection pdpConn = (COPSPdpConnection) _connectionMap.get(pepID);
\r
198 pdpConn.syncAllRequestState();
\r
202 * Removes a PEP from the connection map
\r
203 * @param pepID PEP-ID of the PEP to be removed
\r
205 public void delete (String pepID) {
\r
206 _connectionMap.remove(pepID);
\r
211 * Runs the PDP process
\r
213 public void run() {
\r
215 _serverSocket = new ServerSocket (_serverPort);
\r
217 //Loop through for Incoming messages
\r
219 // server infinite loop
\r
222 // Wait for an incoming connection from a PEP
\r
223 Socket socket = _serverSocket.accept();
\r
225 // COPSDebug.out(getClass().getName(),"New connection accepted " +
\r
226 // socket.getInetAddress() +
\r
227 // ":" + socket.getPort());
\r
229 // We're waiting for an OPN message
\r
231 COPSMsg msg = COPSTransceiver.receiveMsg(socket);
\r
232 if (msg.getHeader().isAClientOpen()) {
\r
233 handleClientOpenMsg(socket, msg);
\r
235 // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);
\r
238 } catch (Exception ex) {};
\r
240 } catch (Exception e) { // COPSException, IOException
\r
241 // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_EXCEPTION,
\r
242 // "(" + socket.getInetAddress() + ":" + socket.getPort() + ")", e);
\r
245 } catch (Exception ex) {};
\r
248 } catch (IOException e) {
\r
249 COPSDebug.err(getClass().getName(), COPSDebug.ERROR_SOCKET, e);
\r
255 * Handles a COPS client-open message
\r
256 * @param conn Socket to the PEP
\r
257 * @param msg <tt>COPSMsg</tt> holding the client-open message
\r
258 * @throws COPSException
\r
259 * @throws IOException
\r
261 private void handleClientOpenMsg(Socket conn, COPSMsg msg)
\r
262 throws COPSException, IOException {
\r
263 COPSClientOpenMsg cMsg = (COPSClientOpenMsg) msg;
\r
264 COPSPepId pepId = cMsg.getPepId();
\r
266 // Validate Client Type
\r
267 if (msg.getHeader().getClientType() != _clientType) {
\r
268 // Unsupported client type
\r
269 COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType());
\r
270 COPSError err = new COPSError(COPSError.COPS_ERR_UNSUPPORTED_CLIENT_TYPE, (short) 0);
\r
271 COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
\r
272 closeMsg.add(cHdr);
\r
275 closeMsg.writeData(conn);
\r
276 } catch (IOException unae) {}
\r
278 throw new COPSException("Unsupported client type");
\r
281 // PEPId is mandatory
\r
282 if (pepId == null) {
\r
283 // Mandatory COPS object missing
\r
284 COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType());
\r
285 COPSError err = new COPSError(COPSError.COPS_ERR_MANDATORY_OBJECT_MISSING, (short) 0);
\r
286 COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
\r
287 closeMsg.add(cHdr);
\r
290 closeMsg.writeData(conn);
\r
291 } catch (IOException unae) {}
\r
293 throw new COPSException("Mandatory COPS object missing (PEPId)");
\r
297 if ( (cMsg.getClientSI() != null) ||
\r
298 (cMsg.getPdpAddress() != null) ||
\r
299 (cMsg.getIntegrity() != null)) {
\r
301 // Unsupported objects
\r
302 COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType());
\r
303 COPSError err = new COPSError(COPSError.COPS_ERR_UNKNOWN_OBJECT, (short) 0);
\r
304 COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
\r
305 closeMsg.add(cHdr);
\r
308 closeMsg.writeData(conn);
\r
309 } catch (IOException unae) {}
\r
311 throw new COPSException("Unsupported objects (ClientSI, PdpAddress, Integrity)");
\r
314 // Connection accepted
\r
315 COPSHeader ahdr = new COPSHeader(COPSHeader.COPS_OP_CAT, msg.getHeader().getClientType());
\r
316 COPSKATimer katimer = new COPSKATimer(_kaTimer);
\r
317 COPSAcctTimer acctTimer = new COPSAcctTimer(_acctTimer);
\r
318 COPSClientAcceptMsg acceptMsg = new COPSClientAcceptMsg();
\r
319 acceptMsg.add(ahdr);
\r
320 acceptMsg.add(katimer) ;
\r
321 if (_acctTimer != 0) acceptMsg.add(acctTimer);
\r
322 acceptMsg.writeData(conn);
\r
324 COPSPdpConnection pdpConn = new COPSPdpConnection(pepId,conn,_process);
\r
325 pdpConn.setKaTimer(_kaTimer);
\r
326 if (_acctTimer != 0) pdpConn.setAccTimer(_acctTimer);
\r
327 new Thread(pdpConn).start();
\r
328 _connectionMap.put(pepId.getData().str(),pdpConn);
\r