1 package org.umu.cops.ospdp;
\r
3 import java.io.IOException;
\r
4 import java.net.ServerSocket;
\r
5 import java.net.Socket;
\r
6 import java.util.Enumeration;
\r
7 import java.util.Hashtable;
\r
9 import org.umu.cops.common.COPSDebug;
\r
10 import org.umu.cops.stack.COPSAcctTimer;
\r
11 import org.umu.cops.stack.COPSClientAcceptMsg;
\r
12 import org.umu.cops.stack.COPSClientCloseMsg;
\r
13 import org.umu.cops.stack.COPSClientOpenMsg;
\r
14 import org.umu.cops.stack.COPSError;
\r
15 import org.umu.cops.stack.COPSException;
\r
16 import org.umu.cops.stack.COPSHeader;
\r
17 import org.umu.cops.stack.COPSKATimer;
\r
18 import org.umu.cops.stack.COPSMsg;
\r
19 import org.umu.cops.stack.COPSPepId;
\r
20 import org.umu.cops.stack.COPSTransceiver;
\r
23 * Core PDP agent for outsourcing.
\r
25 public class COPSPdpOSAgent extends Thread {
\r
26 /** Well-known port for COPS */
\r
27 public static final int WELL_KNOWN_PDP_PORT = 3288;
\r
28 /** Default keep-alive timer value (secs) */
\r
29 public static final short KA_TIMER_VALUE = 30;
\r
30 /** Default accounting timer value (secs) */
\r
31 public static final short ACCT_TIMER_VALUE = 0;
\r
36 private ServerSocket _serverSocket;
\r
41 private int _serverPort;
\r
44 Client-type of connecting PEP
\r
46 private short _clientType;
\r
49 Accounting timer (secs)
\r
51 private short _acctTimer;
\r
54 Keep-alive timer (secs)
\r
56 private short _kaTimer;
\r
59 Maps a PEP-ID to a connection
\r
61 private Hashtable _connectionMap;
\r
62 // map < String(PEPID), COPSPdpOSConnection > ConnectionMap;
\r
65 * Policy data processing object
\r
67 private COPSPdpOSDataProcess _process;
\r
70 * Creates a PDP Agent
\r
72 * @param clientType COPS Client-type
\r
73 * @param process Object to perform policy data processing
\r
75 public COPSPdpOSAgent(short clientType, COPSPdpOSDataProcess process) {
\r
76 _serverPort = WELL_KNOWN_PDP_PORT;
\r
77 _kaTimer = KA_TIMER_VALUE;
\r
78 _acctTimer = ACCT_TIMER_VALUE;
\r
80 _clientType = clientType;
\r
81 _connectionMap = new Hashtable(40);
\r
86 * Creates a PDP Agent
\r
88 * @param port Port to listen to
\r
89 * @param clientType COPS Client-type
\r
90 * @param process Object to perform policy data processing
\r
92 public COPSPdpOSAgent(int port, short clientType, COPSPdpOSDataProcess process) {
\r
95 _kaTimer = KA_TIMER_VALUE;
\r
96 _acctTimer = ACCT_TIMER_VALUE;
\r
98 _clientType = clientType;
\r
99 _connectionMap = new Hashtable(40);
\r
100 _process = process;
\r
104 * Sets the keep-alive timer value
\r
105 * @param kaTimer Keep alive timer value (secs)
\r
107 public void setKaTimer (short kaTimer) {
\r
108 _kaTimer = kaTimer;
\r
112 * Sets the accounting timer value
\r
113 * @param acctTimer Accounting timer value (secs)
\r
115 public void setAcctTimer (short acctTimer) {
\r
116 _acctTimer = acctTimer;
\r
120 * Gets the value of the keep-alive timer
\r
121 * @return Keep-alive timer value (secs)
\r
123 public short getKaTimer () {
\r
128 * Gets the accounting timer value
\r
129 * @return Accounting timer value (secs)
\r
131 public short getAcctTimer () {
\r
136 * Gets the PEPs connected to this PDP
\r
137 * @return An <tt>Enumeration</tt> of all connected PEPs
\r
139 public Enumeration getConnectedPEPIds() {
\r
140 return _connectionMap.keys();
\r
144 * Gets the connection map
\r
145 * @return A <tt>Hashtable</tt> holding the connection map
\r
147 public Hashtable getConnectionMap() {
\r
148 return _connectionMap;
\r
152 * Gets the client-type
\r
153 * @return The client-type
\r
155 public short getClientType() {
\r
156 return _clientType;
\r
160 * Disconnects a PEP
\r
161 * @param pepID PEP-ID of the PEP to be disconnected
\r
162 * @param error COPS Error to be reported as a reason
\r
163 * @throws COPSException
\r
164 * @throws IOException
\r
166 public void disconnect (String pepID, COPSError error) throws COPSException, IOException {
\r
167 COPSPdpOSConnection pdpConn = (COPSPdpOSConnection) _connectionMap.get(pepID);
\r
169 COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, _clientType);
\r
170 COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
\r
171 closeMsg.add(cHdr);
\r
173 closeMsg.add(error);
\r
175 closeMsg.writeData(pdpConn.getSocket());
\r
181 * Requests a COPS sync for a PEP
\r
182 * @param pepID PEP-ID of the PEP to be synced
\r
183 * @throws COPSException
\r
184 * @throws COPSPdpException
\r
186 public void sync(String pepID) throws COPSException, COPSPdpException {
\r
187 COPSPdpOSConnection pdpConn = (COPSPdpOSConnection) _connectionMap.get(pepID);
\r
188 pdpConn.syncAllRequestState();
\r
192 * Removes a PEP from the connection map
\r
193 * @param pepID PEP-ID of the PEP to be removed
\r
195 public void delete (String pepID) {
\r
196 _connectionMap.remove(pepID);
\r
200 * Runs the PDP process
\r
202 public void run() {
\r
204 _serverSocket = new ServerSocket (_serverPort);
\r
206 //Loop through for Incoming messages
\r
208 // server infinite loop
\r
210 // Wait for an incoming connection from a PEP
\r
211 Socket socket = _serverSocket.accept();
\r
213 // COPSDebug.out(getClass().getName(),"New connection accepted " +
\r
214 // socket.getInetAddress() +
\r
215 // ":" + socket.getPort());
\r
217 // We're waiting for an OPN message
\r
219 COPSMsg msg = COPSTransceiver.receiveMsg(socket);
\r
220 if (msg.getHeader().isAClientOpen()) {
\r
221 handleClientOpenMsg(socket, msg);
\r
223 // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);
\r
226 } catch (Exception ex) {};
\r
228 } catch (Exception e) { // COPSException, IOException
\r
229 // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_EXCEPTION,
\r
230 // "(" + socket.getInetAddress() + ":" + socket.getPort() + ")", e);
\r
233 } catch (Exception ex) {};
\r
236 } catch (IOException e) {
\r
237 COPSDebug.err(getClass().getName(), COPSDebug.ERROR_SOCKET, e);
\r
243 * Handles a COPS client-open message
\r
244 * @param conn Socket to the PEP
\r
245 * @param msg <tt>COPSMsg</tt> holding the client-open message
\r
246 * @throws COPSException
\r
247 * @throws IOException
\r
249 private void handleClientOpenMsg(Socket conn, COPSMsg msg) throws COPSException, IOException {
\r
250 COPSClientOpenMsg cMsg = (COPSClientOpenMsg) msg;
\r
251 COPSPepId pepId = cMsg.getPepId();
\r
253 // Validate Client Type
\r
254 if (msg.getHeader().getClientType() != _clientType) {
\r
255 // Unsupported client type
\r
256 COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType());
\r
257 COPSError err = new COPSError(COPSError.COPS_ERR_UNSUPPORTED_CLIENT_TYPE, (short) 0);
\r
258 COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
\r
259 closeMsg.add(cHdr);
\r
262 closeMsg.writeData(conn);
\r
263 } catch (IOException unae) {}
\r
265 throw new COPSException("Unsupported client type");
\r
268 // PEPId is mandatory
\r
269 if (pepId == null) {
\r
270 // Mandatory COPS object missing
\r
271 COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType());
\r
272 COPSError err = new COPSError(COPSError.COPS_ERR_MANDATORY_OBJECT_MISSING, (short) 0);
\r
273 COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
\r
274 closeMsg.add(cHdr);
\r
277 closeMsg.writeData(conn);
\r
278 } catch (IOException unae) {}
\r
280 throw new COPSException("Mandatory COPS object missing (PEPId)");
\r
284 if ( (cMsg.getClientSI() != null) ||
\r
285 (cMsg.getPdpAddress() != null) ||
\r
286 (cMsg.getIntegrity() != null)) {
\r
288 // Unsupported objects
\r
289 COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType());
\r
290 COPSError err = new COPSError(COPSError.COPS_ERR_UNKNOWN_OBJECT, (short) 0);
\r
291 COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
\r
292 closeMsg.add(cHdr);
\r
295 closeMsg.writeData(conn);
\r
296 } catch (IOException unae) {}
\r
298 throw new COPSException("Unsupported objects (ClientSI, PdpAddress, Integrity)");
\r
301 // Connection accepted
\r
302 COPSHeader ahdr = new COPSHeader(COPSHeader.COPS_OP_CAT, msg.getHeader().getClientType());
\r
303 COPSKATimer katimer = new COPSKATimer(_kaTimer);
\r
304 COPSAcctTimer acctTimer = new COPSAcctTimer(_acctTimer);
\r
305 COPSClientAcceptMsg acceptMsg = new COPSClientAcceptMsg();
\r
306 acceptMsg.add(ahdr);
\r
307 acceptMsg.add(katimer) ;
\r
308 if (_acctTimer != 0) acceptMsg.add(acctTimer);
\r
309 acceptMsg.writeData(conn);
\r
311 COPSPdpOSConnection pdpConn = new COPSPdpOSConnection(pepId, conn, _process);
\r
312 pdpConn.setKaTimer(_kaTimer);
\r
313 if (_acctTimer != 0) pdpConn.setAccTimer(_acctTimer);
\r
314 new Thread(pdpConn).start();
\r
315 _connectionMap.put(pepId.getData().str(),pdpConn);
\r