package es.tid.bgp.bgp4Peer.bgp4session; import es.tid.bgp.bgp4.messages.BGP4Message; import es.tid.bgp.bgp4.messages.BGP4MessageTypes; import es.tid.bgp.bgp4.messages.BGP4Update; import es.tid.bgp.bgp4Peer.peer.BGP4Exception; import es.tid.bgp.bgp4Peer.updateTEDB.UpdateDispatcher; import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.Inet4Address; import java.net.Socket; import java.util.Timer; /** * Client session * * @author mcs * */ public class BGP4SessionClient extends GenericBGP4Session{ /** * Peer BGP port to which the session is connected */ private int peerBGP_port; /** * Delay */ private boolean no_delay=true; private String localBGP4Address; private int localBGP4Port; /** * Class to dispatch the BGP4 update messages. * If a BGP5 update message is received, it is stored in a queue of UpdateDispatcher. */ private UpdateDispatcher updateDispatcher; public BGP4SessionClient(BGP4SessionsInformation bgp4SessionsInformation,UpdateDispatcher updateDispatcher, Inet4Address peerBGP_IPaddress, int peerBGP_port, int holdTime,Inet4Address BGPIdentifier,int version,int myAutonomousSystem, String localBGP4Address, int localBGP4Port,int keepAliveTimer){ super(bgp4SessionsInformation, holdTime, BGPIdentifier, version, myAutonomousSystem,keepAliveTimer); timer=new Timer(); log = LoggerFactory.getLogger("BGP4Client"); this.peerBGP_port = peerBGP_port; this.updateDispatcher=updateDispatcher; this.localBGP4Address=localBGP4Address; this.localBGP4Port=localBGP4Port; this.remotePeerIP = peerBGP_IPaddress; } /** * Initiates a Session between the local BGP Peer and the remote BGP Peer */ public void run() { log.info("Opening new BGP4 Session with host "+ this.remotePeerIP.getHostAddress() + " on port " + this.peerBGP_port); log.debug("Do we want to update from peer?" + updateFrom); log.debug("Do we want to send to peer?" + sendTo); try { Inet4Address addr = (Inet4Address) Inet4Address.getByName(localBGP4Address); Inet4Address addrPeer = remotePeerIP; socket = new Socket(addrPeer, peerBGP_port, addr, 0); if (no_delay){ this.socket.setTcpNoDelay(true); log.debug("No delay activated"); } } catch (IOException e) { log.info("Connection refused trying to connect " + remotePeerIP.getHostAddress() + " on port " + peerBGP_port); //As there is not yet a session added (it is added in the beginning of initializeBGP4Session()); //endSession(); return; } try { initializeBGP4Session(); log.info("BGP4 Session established with peer "+this.remotePeerIP); this.keepAliveT= new KeepAliveThread(this.getOut(),this.keepAliveTimer); keepAliveT.start(); } catch (BGP4Exception e2) { // TODO Auto-generated catch block e2.printStackTrace(); log.debug("Session with "+this.remotePeerIP+" already exists: "+e2.getMessage()); try { socket.close(); } catch (IOException e) { // TODO Auto-generated catch block log.error("Problem closing socket "+e.getMessage()); } return; } try{ while(this.FSMstate==BGP4StateSession.BGP4_STATE_SESSION_UP) { try { this.msg = readBGP4Msg(in);//Read a new message }catch (IOException e){ cancelDeadTimer(); cancelKeepAlive(); timer.cancel(); try { in.close(); out.close(); } catch (Exception e1) { log.warn("problem closing sockets"); } log.debug("Finishing BGP4 Session abruptly!"); return; } if (this.msg != null) {//If null, it is not a valid PCEP message boolean bgp4Msg = true;//By now, we assume a valid PCEP message has arrived //Depending on the type a different action is performed switch(BGP4Message.getMessageType(this.msg)) { case BGP4MessageTypes.MESSAGE_OPEN: log.debug("BGP OPEN message received from "+this.remotePeerIP); //After the session has been started, ignore subsequent OPEN messages log.warn("OPEN message ignored"); break; case BGP4MessageTypes.MESSAGE_KEEPALIVE: log.debug("BGP KEEPALIVE message received from "+this.remotePeerIP); //The Keepalive message allows to reset the deadtimer break; case BGP4MessageTypes.MESSAGE_NOTIFICATION: log.debug("BGP NOTIFICATION message received from "+this.remotePeerIP); break; case BGP4MessageTypes.MESSAGE_UPDATE: log.debug("BGP UPDATE message received from "+this.remotePeerIP); if(this.getUpdateFrom()){ BGP4Update bgp4Update = new BGP4Update(msg); log.debug(bgp4Update.toString()); bgp4Update.setLearntFrom(this.remotePeerIP.getHostAddress() ); updateDispatcher.dispatchRequests(bgp4Update); } else log.debug("Update message from " + this.remotePeerIP + " discarded"); break; default: log.warn("ERROR: unexpected message received"); bgp4Msg = false; } if (bgp4Msg) { //Reseting Dead Timer as BGP4 Session Message has arrived resetDeadTimer(); } } } }finally{ //log.error("SESSION "+ internalSessionID+" IS KILLED"); log.info("BGP4 session with peer "+this.remotePeerIP+" has been closed"); cancelDeadTimer(); cancelKeepAlive(); this.FSMstate=BGP4StateSession.BGP4_STATE_IDLE; endSession(); } } public int getPeerBGP_port() { return peerBGP_port; } public void setPeerBGP_port(int peerBGP_port) { this.peerBGP_port = peerBGP_port; } public Boolean getUpdateFrom() { return updateFrom; } public void setUpdateFrom(Boolean updateFrom) { this.updateFrom = updateFrom; } public Boolean getSendTo() { return sendTo; } public void setSendTo(Boolean sendTo) { this.sendTo = sendTo; } public boolean isNo_delay() { return no_delay; } public void setNo_delay(boolean no_delay) { this.no_delay = no_delay; } @Override public void close() { // TODO Auto-generated method stub } @Override protected void endSession() { // TODO Auto-generated method stub log.debug("Ending session with id "+this.getSessionId()); this.BGP4SessionsInformation.deleteSession(this.getSessionId()); } }