1 package org.umu.cops.ospep;
3 import org.slf4j.Logger;
4 import org.slf4j.LoggerFactory;
5 import org.umu.cops.stack.*;
6 import org.umu.cops.stack.COPSHeader.OPCode;
8 import java.io.IOException;
9 import java.net.InetAddress;
10 import java.net.Socket;
11 import java.util.Hashtable;
12 import java.util.List;
15 * This is a outsourcing COPS PEP. Responsible for making
16 * connection to the PDP and maintaining it
18 public class COPSPepOSAgent {
20 public final static Logger logger = LoggerFactory.getLogger(COPSPepOSAgent.class);
25 private String _pepID;
30 private short _clientType;
35 private String _psHost;
43 PEP-PDP connection manager
45 private COPSPepOSConnection _conn;
48 COPS error returned by the PDP
50 private COPSError _error;
53 * Policy data processor class
55 private COPSPepOSDataProcess _process;
60 * @param clientType Client-type
62 public COPSPepOSAgent(final String pepID, final short clientType) {
64 _clientType = clientType;
68 * Creates a PEP agent with a PEP-ID equal to "noname"
69 * @param clientType Client-type
71 public COPSPepOSAgent(final short clientType) {
74 _pepID = InetAddress.getLocalHost().getHostName();
75 } catch (Exception e) {
79 _clientType = clientType;
83 * Gets the identifier of the PEP
86 public String getPepID() {
91 * Sets the policy data processor
92 * @param aDataProcess Data processor class
94 public void setDataProcess(COPSPepOSDataProcess aDataProcess) {
95 this._process = aDataProcess;
99 * Gets the COPS client-type
100 * @return PEP's client-type
102 public int getClientType() {
108 * @return PDP host name
110 public String getPDPName() {
115 * Gets the port of the PDP
118 public int getPDPPort() {
124 * @param psHost PDP host name
125 * @param psPort PDP port
126 * @return <tt>true</tt> if PDP accepts the connection; <tt>false</tt> otherwise
127 * @throws java.net.UnknownHostException
128 * @throws java.io.IOException
129 * @throws COPSException
130 * @throws COPSPepException
132 public boolean connect(String psHost, int psPort) throws IOException, COPSException, COPSPepException {
133 // COPSDebug.out(getClass().getName(), "Thread ( " + _pepID + ") - Connecting to PDP");
137 // Check whether it already exists
139 _conn = processConnection(psHost,psPort);
141 // Check whether it's closed
142 if (_conn.isClosed())
143 _conn = processConnection(psHost,psPort);
146 _conn = processConnection(psHost,psPort);
150 return (_conn != null);
154 * Gets the connection manager
155 * @return PEP-PDP connection manager object
157 public COPSPepOSConnection getConnection() {
162 * Gets the COPS error returned by the PDP
163 * @return <tt>COPSError</tt> returned by PDP
165 public COPSError getConnectionError() {
170 * Disconnects from the PDP
171 * @param error Reason
172 * @throws COPSException
173 * @throws IOException
175 public void disconnect(final COPSError error) throws COPSException, IOException {
176 final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(_clientType, error, null, null);
177 closeMsg.writeData(_conn.getSocket());
183 * Adds a request state to the connection manager.
184 * @param clientSIs The client data from the outsourcing event
185 * @return The newly created connection manager
186 * @throws COPSPepException
187 * @throws COPSException
189 public COPSPepOSReqStateMan addRequestState(final COPSHandle handle, List<COPSClientSI> clientSIs) throws COPSPepException, COPSException {
191 return _conn.addRequestState(handle.getId().str(), _process, clientSIs);
197 * Queries the connection manager to delete a request state
198 * @param man Request state manager
199 * @throws COPSPepException
200 * @throws COPSException
202 public void deleteRequestState (COPSPepOSReqStateMan man) throws COPSPepException, COPSException {
204 _conn.deleteRequestState(man);
208 * Gets all the request state managers
209 * @return A <tt>Hashtable</tt> holding all active request state managers
211 public Hashtable getReqStateMans() {
213 return _conn.getReqStateMans();
218 * Establish connection to PDP's IP address
220 * <Client-Open> ::= <Common Header>
226 * Not support [<ClientSI>], [<LastPDPAddr>], [<Integrity>]
228 * <Client-Accept> ::= <Common Header>
233 * Not send [<Integrity>]
235 * <Client-Close> ::= <Common Header>
240 * Not send [<PDPRedirAddr>], [<Integrity>]
242 * @throws IOException
243 * @throws COPSException
244 * @throws COPSPepException
247 private COPSPepOSConnection processConnection(final String psHost, final int psPort)
248 throws IOException, COPSException, COPSPepException {
250 final COPSClientOpenMsg msg = new COPSClientOpenMsg(_clientType, new COPSPepId(new COPSData(_pepID)),
253 // Create socket and send OPN
254 final InetAddress addr = InetAddress.getByName(psHost);
255 final Socket socket = new Socket(addr,psPort);
256 msg.writeData(socket);
259 final COPSMsg recvmsg = COPSTransceiver.receiveMsg(socket);
261 if (recvmsg.getHeader().getOpCode().equals(OPCode.CAT)) {
262 final COPSClientAcceptMsg cMsg = (COPSClientAcceptMsg) recvmsg;
265 if (cMsg.getIntegrity() != null) {
266 throw new COPSPepException("Unsupported object (Integrity)");
270 final COPSKATimer kt = cMsg.getKATimer();
272 throw new COPSPepException ("Mandatory COPS object missing (KA Timer)");
273 short _kaTimeVal = kt.getTimerVal();
276 final COPSAcctTimer at = cMsg.getAcctTimer();
278 if (at != null) _acctTimer = at.getTimerVal();
281 // Create connection manager
282 final COPSPepOSConnection conn = new COPSPepOSConnection(_clientType, socket);
283 conn.setKaTimer(_kaTimeVal);
284 conn.setAcctTimer(_acctTimer);
285 new Thread(conn).start();
288 } else if (recvmsg.getHeader().getOpCode().equals(OPCode.CC)) {
289 final COPSClientCloseMsg cMsg = (COPSClientCloseMsg) recvmsg;
290 _error = cMsg.getError();
293 } else { // other message types are unexpected
294 throw new COPSPepException("Message not expected. Closing connection for " + socket.toString());
299 * Creates a new request state when the outsourcing event is detected.
300 * @param handle The COPS handle for this request
301 * @param clientSIs The client specific data for this request
303 public void dispatchEvent(COPSHandle handle, final List<COPSClientSI> clientSIs) {
305 addRequestState(handle, clientSIs);
306 } catch (Exception e) {
307 logger.error("Error adding request state", e);