package es.tid.pce.server; import java.io.IOException; import java.net.Inet4Address; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import java.util.Timer; import java.util.concurrent.LinkedBlockingQueue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import es.tid.pce.computingEngine.RequestDispatcher; import es.tid.pce.pcep.PCEPProtocolViolationException; import es.tid.pce.pcep.messages.PCEPInitiate; import es.tid.pce.pcep.messages.PCEPMessage; import es.tid.pce.pcep.messages.PCEPMessageTypes; import es.tid.pce.pcep.messages.PCEPRequest; import es.tid.pce.pcep.messages.PCEPResponse; import es.tid.pce.pcepsession.DeadTimerThread; import es.tid.pce.pcepsession.GenericPCEPSession; import es.tid.pce.pcepsession.KeepAliveThread; import es.tid.pce.pcepsession.PCEPSessionsInformation; import es.tid.pce.pcepsession.PCEPValues; import es.tid.tedb.TEDB; import es.tid.util.UtilsFunctions; /** * PCEP Session between the Child PCE and the parent PCE. * View from the Child PCE * @author Oscar Gonzalez de Dios * */ public class ChildPCESession extends GenericPCEPSession{ /** * Used to store the incoming requests */ private RequestQueue parentPCERequestQueue; // private //public ClientRequestManager crm; private int sessionID; PCEServerParameters params; private static long sessionIDCounter=0; private RequestDispatcher requestDispatcher; /** * Flag to indicate that the MessageListener is running */ boolean running = true; private TEDB ted; private Inet4Address domainId; private Inet4Address pceId; private Sender sendingThread; private LinkedBlockingQueue<PCEPMessage> parentPCESendingQueue; private ParentPCERequestManager childPCERequestManager; private int state; private RequestDispatcher PCCRequestDispatcherChild; private SingleDomainInitiateDispatcher iniDispatcher; //* Constructor of the PCE Session to implement a new RequestDispatcher for the incoming pceprequest from the ParentPCE. * @param s Socket of the PCC-PCE Communication * @param req RequestQueue to send path requests public ChildPCESession(RequestDispatcher PCCRequestDispatcherChild, PCEServerParameters params, RequestQueue parentPCERequestQueue, TEDB ted, Timer timer,LinkedBlockingQueue<PCEPMessage> parentPCESendingQueue,ParentPCERequestManager childPCERequestManager, Inet4Address domainId, PCEPSessionsInformation pcepSessionInformation, SingleDomainInitiateDispatcher iniDispatcher) { super(pcepSessionInformation); this.PCCRequestDispatcherChild=PCCRequestDispatcherChild; this.state=PCEPValues.PCEP_STATE_IDLE; this.parentPCERequestQueue=parentPCERequestQueue; log=LoggerFactory.getLogger(params.getPCEServerLogFile()); this.requestDispatcher=requestDispatcher; this.ted=ted; this.params = params; this.timer = timer; this.parentPCESendingQueue=parentPCESendingQueue; this.childPCERequestManager=childPCERequestManager; this.keepAliveLocal=30; this.deadTimerLocal=120; this.iniDispatcher=iniDispatcher; //this.sendingThread = new Sender(new LinkedBlockingQueue<PCEPMessage>(), output); try { this.domainId=domainId; this.pceId=(Inet4Address) Inet4Address.getLocalHost(); log.info("pceId"+pceId); log.info("domainId"+domainId); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //* Constructor of the PCE Session * @param s Socket of the PCC-PCE Communication * @param req RequestQueue to send path requests public ChildPCESession(PCEServerParameters params, RequestQueue parentPCERequestQueue, TEDB ted, Timer timer,LinkedBlockingQueue<PCEPMessage> parentPCESendingQueue,ParentPCERequestManager childPCERequestManager, Inet4Address domainId, PCEPSessionsInformation pcepSessionInformation, SingleDomainInitiateDispatcher iniDispatcher) { super(pcepSessionInformation); this.state=PCEPValues.PCEP_STATE_IDLE; this.parentPCERequestQueue=parentPCERequestQueue; log=LoggerFactory.getLogger(params.getPCEServerLogFile()); this.ted=ted; this.params = params; this.timer = timer; this.parentPCESendingQueue=parentPCESendingQueue; this.childPCERequestManager=childPCERequestManager; this.keepAliveLocal=30; this.deadTimerLocal=120; this.iniDispatcher=iniDispatcher; //this.sendingThread = new Sender(new LinkedBlockingQueue<PCEPMessage>(), output); try { this.domainId=domainId; this.pceId=(Inet4Address) Inet4Address.getLocalHost(); log.info("pceId"+pceId); log.info("domainId"+domainId); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * Opens a PCEP session sending an OPEN Message * Then, it launches the Keepalive process, the Deadtimer process and * the listener of PCC messages. */ public void run() { running=true; log.info("Opening new PCEP Session with parent PCE "+ params.getParentPCEAddress() + " on port " + params.getParentPCEPort()); log.info("Local IP address --> "+params.getLocalPceAddress().toString()+" Port --> "+params.getPCEServerPort()); try { Inet4Address addr = (Inet4Address)InetAddress.getByName(params.getLocalPceAddress()); // Metemos el puerto a 0 para que coja por defecto this.socket = new Socket(params.getParentPCEAddress(), params.getParentPCEPort(), addr, 0); log.info("Socket opened"); } catch (IOException e) { log.error("Couldn't get I/O for connection to Parent PCE" + params.getParentPCEAddress() ); killSession(); return; } initializePCEPSession(false, 15, 200,false,true,domainId,pceId,0); log.info("PCE Session succesfully established!!"); this.deadTimerT=new DeadTimerThread(this, this.deadTimerLocal); startDeadTimer(); this.keepAliveT=new KeepAliveThread(out, this.keepAliveLocal); startKeepAlive(); this.sendingThread = new Sender(parentPCESendingQueue, out); this.sendingThread.start(); //Listen to new messages while(running) { try { this.msg = readMsg(in);//Read a new message }catch (IOException e){ cancelDeadTimer(); cancelKeepAlive(); timer.cancel(); try { in.close(); out.close(); } catch (IOException e1) { } log.warn("Finishing PCEP Session abruptly"); return; } if (this.msg != null) {//If null, it is not a valid PCEP message boolean pceMsg = true;//By now, we assume a valid PCEP message has arrived //Depending on the type a different action is performed switch(PCEPMessage.getMessageType(this.msg)) { case PCEPMessageTypes.MESSAGE_OPEN: log.debug("OPEN message received"); //After the session has been started, ignore subsequent OPEN messages log.warn("OPEN message ignored"); break; case PCEPMessageTypes.MESSAGE_KEEPALIVE: log.debug("KEEPALIVE message received"); //The Keepalive message allows to reset the deadtimer break; case PCEPMessageTypes.MESSAGE_CLOSE: log.debug("CLOSE message received"); log.warn("Finishing PCEParentSession due to CLOSE"); killSession(); return; case PCEPMessageTypes.MESSAGE_ERROR: log.debug("ERROR message received"); break; case PCEPMessageTypes.MESSAGE_NOTIFY: log.debug("Received NOTIFY message"); break; case PCEPMessageTypes.MESSAGE_PCREP: log.debug("Received PC RESPONSE message"); PCEPResponse pcres; try { pcres=new PCEPResponse(msg); Long idr= new Long(pcres.getResponse(0).getRequestParameters().getRequestID()); log.info("Llega un response del IdRequest "+idr); synchronized (childPCERequestManager.locks.get(idr)) { childPCERequestManager.notifyResponse(pcres); } } catch (PCEPProtocolViolationException e) { // TODO Auto-generated catch block e.printStackTrace(); break; } break; case PCEPMessageTypes.MESSAGE_PCREQ: log.info("PCREQ message from Parent PCE received"); PCEPRequest p_req; try { p_req=new PCEPRequest(msg); } catch (PCEPProtocolViolationException e) { // TODO Auto-generated catch block e.printStackTrace(); break; } /*RequestProcessor rp=new RequestProcessor(p_req,out, ted,null); this.parentPCERequestQueue.execute(rp);*/ PCCRequestDispatcherChild.dispathRequests(p_req, out); break; case PCEPMessageTypes.MESSAGE_INITIATE: log.info("INITIATE RECEIVED"); PCEPInitiate pcepInitiate = null; try { log.info(" XXXX try"); pcepInitiate = new PCEPInitiate(msg); log.info("pcepInitiate: "+pcepInitiate); log.info("Initiate from "+this.remotePeerIP+": "+pcepInitiate); } catch (PCEPProtocolViolationException e) { log.info(UtilsFunctions.exceptionToString(e)); } if (iniDispatcher!=null){ iniDispatcher.dispathInitiate(pcepInitiate, this.out, this.remotePeerIP); } break; default: log.warn("ERROR: unexpected message, Unknown message received!"); pceMsg = false; } if (pceMsg) { log.info("Reseting Dead Timer as PCEP Message has arrived"); resetDeadTimer(); } } } } public void endSession(){ } }