/** * @copyright 2013 Computer Science Department, Recursive InterNetworking Architecture (RINA) laboratory, Boston University. * All rights reserved. Permission to use, copy, modify, and distribute this software and its documentation * for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all * copies and that both the copyright notice and this permission notice appear in supporting documentation. * The RINA laboratory of the Computer Science Department at Boston University makes no * representations about the suitability of this software for any purpose. * It is provided "as is" without express or implied warranty. */ package rina.ddf.relayApplication; import java.util.LinkedList; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.google.protobuf.InvalidProtocolBufferException; import rina.config.RINAConfig; import rina.ipc.impl.IPCImpl; import rina.irm.util.HandleEntry; import rina.message.CDAP; import rina.object.internal.ApplicationProcessNamingInfo; import rina.object.internal.Flow; import rina.rib.impl.RIBImpl; import application.component.impl.IPCResourceManagerImpl; /** * * @author Yuefeng Wang. Computer Science Department, Boston University * */ public class RelayHandler extends Thread{ private Log log = LogFactory.getLog(this.getClass()); private ApplicationProcessNamingInfo apInfo = null; private IPCResourceManagerImpl ipcManager = null; private RIBImpl rib = null; private int handleID = -1; private HandleEntry he = null; private String relayedApName = null; private String relayedApInstance = null; public RelayHandler(int handleID, IPCResourceManagerImpl ipcManager, HandleEntry he, RIBImpl rib ) { this.handleID = handleID; this.ipcManager = ipcManager; this.he = he; this.rib = rib; this.apInfo = (ApplicationProcessNamingInfo)this.rib.getAttribute("apInfo"); this.relayedApName = (String)this.rib.getAttribute("relayedApName"); this.relayedApInstance = (String)this.rib.getAttribute("relayedApInstance"); this.start(); } public void run() { this.log.info("Relay handler started"); CDAP.CDAPMessage cdapMessage = null; while(true) { byte[] msg = this.ipcManager.receive(this.handleID); try { cdapMessage = CDAP.CDAPMessage.parseFrom(msg); this.handleReceviedCDAPMsg(cdapMessage); } catch (InvalidProtocolBufferException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private void handleReceviedCDAPMsg(CDAP.CDAPMessage cdapMessage) { if(cdapMessage.getOpCode().toString().equals("M_CREATE")) { if(cdapMessage.getObjName().equals("/daf/relay/dif/")) { //check whether the DIF providing relay service is formed or not //here we assume we only form one dif for each relay app //so all client will create IPC to join this dif String DIFName = "relay:DIF:" + this.relayedApName; if( (Boolean)this.rib.getAttribute("difFormedFlag") == false) { //create new DIF by form a new authenticator, and send the DIF info to client this.log.debug("DIF for relaying ap " + this.relayedApName + " is crated with DIF name " + DIFName); //config the IPC process RINAConfig ipcConfig = new RINAConfig(); //ipcConfig.setProperty("rina.ipc.flag", "1"); //non-DIF zero ipc ipcConfig.setProperty("rina.ipc.level", "1"); ipcConfig.setProperty("rina.ipc.name", "relay:ipc:" + this.relayedApName); ipcConfig.setProperty("rina.ipc.instance", "1"); ipcConfig.setProperty("rina.dif.enrolled", "true"); ipcConfig.setProperty("rina.dif.name", DIFName); ipcConfig.setProperty("rina.ipc.userName", "BU"); ipcConfig.setProperty("rina.ipc.passWord", "BU"); ipcConfig.setProperty("rina.enrollment.authenPolicy", "AUTH_PASSWD"); ipcConfig.setProperty("rina.routing.protocol","linkState"); ipcConfig.setProperty("rina.routingEntrySubUpdatePeriod","2"); ipcConfig.setProperty("rina.checkNeighborPeriod","2"); ipcConfig.setProperty("rina.linkCost.policy","hop"); ipcConfig.setUnderlyingDIFs(this.ipcManager.getUnderlyingDIFs()); ipcConfig.setProperty("rina.address","500"); /////////////////////////////////////////////////////////////////////////// //add all underying IPC of this app to the new created IPC, so that they are also its underlying IPC LinkedList<IPCImpl> underlyigIPCList = this.ipcManager.getUnderlyingIPCs(); IPCImpl relayDIFIPC = new IPCImpl(ipcConfig, underlyigIPCList); relayDIFIPC.start(); this.log.debug("relayDIFIPC created."); //add the new ipc to the app as its underlying IPC this.ipcManager.addIPC(relayDIFIPC); this.rib.addAttribute("difFormedFlag", true); } //(1) ask the target app's IRM to form an IPC to join this DIF by an M_CREATE //wait for an M_CREATE_R when done CDAP.objVal_t.Builder objToDst = CDAP.objVal_t.newBuilder(); objToDst.setStrval(DIFName); CDAP.CDAPMessage M_CREATE_Fork_IPC = rina.message.CDAPMessageGenerator.generateM_CREATE ( "fork ipc", "/daf/fork/ipc/", objToDst.buildPartial(), 99 ); //Note:relayedApName is the dst ap //relay CDAP message is handled by ManagementAE //But here, src is just the relay application, not the management AE of the application //Similar to code in the "dynamicDIFFormation" method in the fiel "application.component.impl/IPCResourceManagerImpl.java" where // the dst is just the relay application not the management AE int handleToDstApp = this.ipcManager.allocateFlow(this.apInfo.getApName(),this.apInfo.getApInstance(), "", "", this.relayedApName, this.relayedApInstance, "Management", "1"); try { this.ipcManager.send(handleToDstApp, M_CREATE_Fork_IPC.toByteArray()); this.log.debug("M_CREATE (fork ipc) sent to relayed app " + this.relayedApName + ", now wait for M_CREATE_R (fork ipc)"); } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); this.log.error("Error when sending M_CREATE (fork ipc). return with nothing done"); return; } byte[] reply = this.ipcManager.receive(handleToDstApp); CDAP.CDAPMessage M_CREATE_R_FORK_IPC = null; int result_fork_ipc = -1; try { M_CREATE_R_FORK_IPC = CDAP.CDAPMessage.parseFrom(reply); result_fork_ipc = M_CREATE_R_FORK_IPC.getResult(); this.log.debug("M_CREATE_R (fork ipc) received from " + this.relayedApName + ", with result " + result_fork_ipc ); } catch (InvalidProtocolBufferException e1) { // TODO Auto-generated catch block e1.printStackTrace(); this.log.error("Error when waiting for M_CREATE_R (fork ipc). return with nothing done"); return; } if(result_fork_ipc != 0) { this.log.error("Asking relayed app to fork ipc, but replywith negative result.return with nothing done"); return; } //(2) send DIF info to client ap //always true now int result = 0; CDAP.objVal_t.Builder obj = CDAP.objVal_t.newBuilder(); obj.setStrval(DIFName); CDAP.CDAPMessage M_CREATE_R = rina.message.CDAPMessageGenerator.generateM_CREATE_R( result, "relay dif", "/daf/relay/dif/", obj.buildPartial(), 99 ); try { this.ipcManager.send(this.handleID, M_CREATE_R.toByteArray() ); this.log.debug("M_CREATE_R (relay dif) sent."); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }else { } } }