private MPLSPackage RouteByMPLS(MPLSPackage unprocessedPackage, int firstNHLFEPointer = 0) { var processedPackage = unprocessedPackage; // an empty package, push labels if (processedPackage.LabelStack.IsEmpty()) { AddLog("[IP] Decreasing TTL by 1", LogType.Information, Window.ShowDetailedTTLLogs); --processedPackage.TTL; if (processedPackage.TTL == 0) // IP's TTL == 0, discard the package { throw new TimeToLiveExpiredException(); } return(PerformMplsEmptyPacketRouting(processedPackage, firstNHLFEPointer)); } else // not an empty package { AddLog("[MPLS] Decreasing outermost's label TTL by 1", LogType.Information, Window.ShowDetailedTTLLogs); --processedPackage.PeekTopLabel().TTL; if (processedPackage.PeekTopLabel().TTL == 0) // MPLS's TTL == 0, discard the package { throw new TimeToLiveExpiredException(); } return(PerformMplsNotEmptyPacketRouting(processedPackage)); } }
private void ProcessPackage(StateObject state, Socket handler, IAsyncResult ar) { var receivedPackage = MPLSPackage.FromBytes(state.Buffer); string node = SocketToNodeName[handler]; string IP = Config.GetIP(node); string port = Convert.ToString(receivedPackage.Port); AddLog($"Received package from {IP}:{port}", LogType.Received); // Received package from node X, port Y -> check to which port and node send it now try { string nextNode = Config.GetNextNode(node, port); string nextPort = Config.GetNextPort(node, port); string cableStatus = Config.GetCableStatus(node, port, nextNode, nextPort); string nextIP = Config.GetIP(nextNode); if (cableStatus.Equals("OUT-OF-ORDER")) { AddLog($"The cable connecting {IP}:{port} to {nextIP}:{nextPort} is out of order. " + $"Package discarded!", LogType.discarded); } else if (cableStatus.Equals("WORKING")) { receivedPackage.Port = ushort.Parse(nextPort); Socket socket = NodeNameToSocket[nextNode]; SendPackage(socket, receivedPackage.ToBytes()); AddLog($"Sent package to {nextIP}:{nextPort}", LogType.Sent); } } catch (Exception) { var address = Config.GetIP(node); AddLog($"{address}:{port} is not connected. " + $"Package discarded!", LogType.discarded); } }
private MPLSPackage RoutePackage(MPLSPackage package) { var packageNotLabeled = package.LabelStack.IsEmpty(); MPLSPackage routedPackage = null; if (packageNotLabeled) { return(PerformNotLabeledPackageAction(package, routedPackage)); } else { routedPackage = RouteByMPLS(package); } if (routedPackage == null) { return(null); } // the MPLS forwarding process has removed all the labels - we need to determine new FEC if (routedPackage.LabelStack.IsEmpty()) { AddLog($"Label stack is empty, forwarding with IP-FIB table", LogType.Information, Window.ShowDetailedRoutingLogs); return(RouteByIP(routedPackage)); } // but if it hasn't, then return processed MPLS package with new labels return(routedPackage); }
/// <summary> /// Async Task listening by UDPClinet for any sended packages. /// If something came to Host, is converted to Package class /// and then checked if message is meant for Host. /// If is meant for Host, proceed package. /// </summary> public void Listener() { Task.Run(async() => { //using var updClient = udp; while (true) { //Console.WriteLine("[INFO]> waiting for message"); var result = await udp.ReceiveAsync(); //Console.WriteLine("[INFO]> message received"); byte[] resultBytes = result.Buffer; Package package = Package.fromBytes(resultBytes); if (package.isMPLS()) { MPLSPackage mpls = Package.ReceiveMPLSPackage(package); Logs.LogsHostReceivePackage(mpls, HostName); } else if (package.isTerminateOrder()) { Environment.Exit(0); } } }); }
public MPLSPackage RouteMPLSPackage(MPLSPackage package, NetworkNodeRoutingTables networkNodeRoutingTables, MainWindow window) { Window = window; RoutingTables = networkNodeRoutingTables; MPLSPackage routedPackage = null; try { routedPackage = RoutePackage(package); } catch (TimeToLiveExpiredException) { AddLog($"Package {package} has expired (TTL = 0). Package discarded!", LogType.Error); return(null); } catch (Exception e) { AddLog($"Exception: {e.StackTrace}", LogType.Error); return(null); } if (routedPackage == null) { AddLog($"I don't know how to route package: {package}. Package discarded!", LogType.Error); return(null); } return(routedPackage); }
private void SendMessage() { if (ConnectedSocket == null || !ConnectedSocket.Connected) { return; } // construct the MPLS package MPLSPackage package = new MPLSPackage(); package.ID = NextID++; package.SourceAddress = Config.IpAddress; package.Port = Config.OutPort; package.TTL = --package.TTL; Dispatcher.Invoke(() => { package.Payload = messageTextBox.Text; package.DestAddress = ((RemoteHostData)destinationsComboBox.SelectedItem).IPAddress; }); try { ConnectedSocket.Send(package); Dispatcher.Invoke(() => { AddLog($"Package sent: {package}"); }); } catch (Exception e) { Dispatcher.Invoke(() => AddLog(e.Message)); } }
private void PerformLabelAction(MPLSPackage package, NHLFETableRow NHLFE, byte TTL, ref string poppedLabelStack) { if (NHLFE.OutPort != null) { package.Port = (ushort)NHLFE.OutPort; } switch (NHLFE.Action) { case LabelActions.POP: if (poppedLabelStack.Equals("-")) { poppedLabelStack = package.PeekTopLabel().Number.ToString(); } else { poppedLabelStack += "," + package.PeekTopLabel().Number.ToString(); } AddLog($"Popped top label: {package.PeekTopLabel().Number}", LogType.Information, Window.ShowDetailedRoutingLogs); package.PopTopLabel(); if (package.LabelStack.IsEmpty()) { AddLog("[MPLS->IP] Copying TTL from MPLS level 1 label to IP header", LogType.Information, Window.ShowDetailedTTLLogs); package.TTL = TTL; } else { AddLog("[MPLS] Copying TTL from the previous outermost label to the new [lower level] outermost one", LogType.Information, Window.ShowDetailedTTLLogs); package.PeekTopLabel().TTL = TTL; } break; case LabelActions.SWAP: AddLog($"Swapped top label: {package.PeekTopLabel().Number} to {(short)NHLFE.OutLabel}", LogType.Information, Window.ShowDetailedRoutingLogs); package.PopTopLabel(); package.PushLabel(new Label((short)NHLFE.OutLabel)); package.PeekTopLabel().TTL = TTL; break; case LabelActions.PUSH: AddLog($"Pushed new label: {(short)NHLFE.OutLabel}", LogType.Information, Window.ShowDetailedRoutingLogs); package.PushLabel(new Label((short)NHLFE.OutLabel)); if (poppedLabelStack.Equals("Push first label on IP package")) { AddLog("[MPLS] Copying TTL from IP header", LogType.Information, Window.ShowDetailedTTLLogs); poppedLabelStack = "-"; } else { AddLog("[MPLS] Copying TTL from the previous outermost label to the new [higher level] outermost one", LogType.Information, Window.ShowDetailedTTLLogs); } package.PeekTopLabel().TTL = TTL; break; default: break; } }
public void listener() { Task.Run(async() => { using (var updClient = udp) { while (true) { var result = await updClient.ReceiveAsync(); Package package = Package.fromBytes(result.Buffer); if (package.isMPLS()) { MPLSPackage MPLSpackage = Package.ReceiveMPLSPackage(package); Logs.LogsCableCloudReceivePackage(MPLSpackage); var InPort = MPLSpackage.GetPort(); var cable = ConnectedCableList[InPort]; if (ConnectedCableList[InPort].isAvailable == false) { Logs.LogsCableCloudSendingError(ConnectedCableList[InPort].OutNodeName, ConnectedCableList[ConnectedCableList[InPort].OutPort].OutNodeName); } else { MPLSpackage.swapPort(cable.OutPort); var outNodeName = cable.OutNodeName; var outIPEndPoint = IPlist[outNodeName]; IPEndPoint destination = outIPEndPoint; Package package1 = Package.MPLSPackage_(MPLSpackage); Logs.LogsCableCloudSendPackage(MPLSpackage); udp.Send(package1.toBytes(), package1.toBytes().Length, destination); package1 = null; MPLSpackage = null; } } else if (package.isTerminateOrder()) { Environment.Exit(0); } package = null; } } }); }
public void pop(NHLFE.NHFLERow entry, MPLSPackage MPLSpackage) { MPLSpackage.ChangeLabel("pop"); NHLFE.NHFLERow nextentry = ComutationList[entry.next_id]; if (nextentry.method == "swap") { MPLSpackage.swap(nextentry.label_out, nextentry.port_out); return; } while (nextentry.method != "swap") { MPLSpackage.ChangeLabel("pop"); nextentry = ComutationList[nextentry.next_id]; } MPLSpackage.swap(nextentry.label_out, nextentry.port_out); }
public void StartSocket() { Listener(); while (true) { String userData = HostValidationOptions.UserMessage(); String selectedHost = HostValidationOptions.SelectHost(HostsList); int label = HostValidationOptions.labelSelect(); MPLSPackage mpls = new MPLSPackage(EndPoint, HostsList[selectedHost], userData, EndPoint.Port, label); Package mplsSendingPackage = Package.MPLSPackage_(mpls); byte[] mplsSendingPackageByte = mplsSendingPackage.toBytes(); Logs.LogsHostSendPackage(mpls, selectedHost, HostName); udp.Send(mplsSendingPackageByte, mplsSendingPackageByte.Length, CloudEndPoint); } }
private MPLSPackage PerformMplsEmptyPacketRouting(MPLSPackage package, int firstNHLFEPointer) { AddLog($"Looking for NHLFE entry with NHLFE_ID={firstNHLFEPointer}...", LogType.Information, Window.ShowDetailedRoutingLogs); var firstNHLFE = RoutingTables.nhlfeTable.Rows.FirstOrDefault(row => row.ID == firstNHLFEPointer); if (firstNHLFE == null) { // routing information is missing AddLog($"Couldn't find matching entry!", LogType.CantFindMatchingEntry, Window.ShowDetailedRoutingLogs); return(null); } var currentNHLFE = firstNHLFE; var labelTTL = (byte)package.TTL; string message = "Push first label on IP package"; // apply the sequence of NHLFEs while (true) { var thereIsNextAction = currentNHLFE.NextID != null; if (Window.ShowDetailedRoutingLogs) { string nextAction, outputPort, outputLabel; nextAction = currentNHLFE.NextID == null ? "NULL" : currentNHLFE.NextID.ToString(); outputPort = currentNHLFE.OutPort == null ? "NULL" : currentNHLFE.OutPort.ToString(); outputLabel = currentNHLFE.OutLabel == null ? "NULL" : currentNHLFE.OutLabel.ToString(); AddLog($"Action for NHLFE_ID={currentNHLFE.ID} is {currentNHLFE.Action}, output port: {outputPort}, output label: {outputLabel}, next NHLFE_ID: {nextAction}", LogType.Information, Window.ShowDetailedRoutingLogs); } PerformLabelAction(package, currentNHLFE, labelTTL, ref message); if (!thereIsNextAction) { break; } var nextID = currentNHLFE.NextID; currentNHLFE = RoutingTables.nhlfeTable.Rows.FirstOrDefault(row => row.ID == currentNHLFE.NextID); if (currentNHLFE == null) { AddLog($"Couldn't find matching entry for NHLFE_ID={nextID}!", LogType.CantFindMatchingEntry, Window.ShowDetailedRoutingLogs); return(null); } } return(package); }
private void HandlePackage(MPLSPackage package) { MPLSPackage routedPackage = null; routedPackage = packageSwitch.RouteMPLSPackage(package, networkNodeRoutingTables, Window); if (routedPackage == null) { return; } try { ConnectedSocket.Send(routedPackage); AddLog( $"Package {package} routed to port {routedPackage.Port} with label {routedPackage.PeekTopLabel()?.Number.ToString() ?? "None"}", LogType.Sent); } catch (Exception e) { AddLog($"Package {routedPackage} not sent correctly: {e.Message}", LogType.Error); } }
private MPLSPackage RouteByIP(MPLSPackage package) { if (package.TTL == 0) { throw new TimeToLiveExpiredException(); } var matchingRow = RoutingTables.ipFibTable.Rows.FirstOrDefault(row => row.DestAddress.Equals(package.DestAddress)); AddLog($"Looking for output port in IP-FIB table...", LogType.Information, Window.ShowDetailedRoutingLogs); if (matchingRow == null) { AddLog($"Couldn't find matching entry!", LogType.CantFindMatchingEntry, Window.ShowDetailedRoutingLogs); return(null); } package.Port = matchingRow.OutPort; AddLog($"The output port for {package.DestAddress} is {package.Port}", LogType.Information, Window.ShowDetailedRoutingLogs); return(package); }
private MPLSPackage PerformNotLabeledPackageAction(MPLSPackage package, MPLSPackage routedPackage) { // check, if FEC exists for such destination adress var FEC = RoutingTables.mplsFibTable.Rows.FirstOrDefault(row => row.DestAddress.Equals(package.DestAddress))?.FEC; AddLog($"Looking for FEC in MPLS-FIB table...", LogType.Information, Window.ShowDetailedRoutingLogs); if (FEC == null) { // if it doesn't, discard the package AddLog($"Couldn't find matching entry!", LogType.CantFindMatchingEntry, Window.ShowDetailedRoutingLogs); return(null); } AddLog($"FEC for {package.DestAddress} is: {FEC}", LogType.Information, Window.ShowDetailedRoutingLogs); var shouldBeLabeled = FEC != 0; // if FEC is != 0, then route it using MPLS rules if (shouldBeLabeled) { AddLog($"Looking for NHLFE_ID in FTN table...", LogType.Information, Window.ShowDetailedRoutingLogs); var firstNHLFE_ID = RoutingTables.ftnTable.Rows.FirstOrDefault(row => row.FEC == FEC)?.NHLFE_ID; if (firstNHLFE_ID == null) { AddLog($"Couldn't find matching entry!", LogType.CantFindMatchingEntry); return(null); } AddLog($"NHLFE_ID for FEC={FEC} is: {(int)firstNHLFE_ID}", LogType.Information, Window.ShowDetailedRoutingLogs); routedPackage = RouteByMPLS(package, (int)firstNHLFE_ID); AddLog($"Completed last action, forwarding to port {routedPackage.Port}", LogType.Information, Window.ShowDetailedRoutingLogs); return(routedPackage); } else // If FEC == 0, then the package should not be labeled; will be used in such case: H1->R1->H2 { AddLog("[IP] Decreasing TTL by 1", LogType.Information, Window.ShowDetailedTTLLogs); --package.TTL; return(RouteByIP(package)); } }
public void Listen() { while (true) { while (ConnectedSocket == null || !ConnectedSocket.Connected) { Dispatcher.Invoke(() => AddLog("Retrying connection to cable cloud")); ConnectToCloud(); } try { MPLSPackage package = ConnectedSocket.Receive(); if (package != null) { Dispatcher.Invoke(() => AddLog($"Received package: {package}")); } } catch (SocketException e) { if (e.SocketErrorCode != SocketError.TimedOut) { if (e.SocketErrorCode == SocketError.Shutdown || e.SocketErrorCode == SocketError.ConnectionReset) { Dispatcher.Invoke(() => AddLog("Connection to cloud broken!", LogType.BrokenConnection)); continue; } else { Dispatcher.Invoke(() => AddLog($"Couldn't connect to cable cloud!", LogType.BrokenConnection)); } } } } }
public void listener() { Task.Run(async() => { using (var updClient = udp) { while (true) { var result = await updClient.ReceiveAsync(); Package package = Package.fromBytes(result.Buffer); if (package.isRoutingCommunication() && nhfletable_set == false) { ManagementAnswer answer1 = Package.ReceiveRoutingTables(package); ComutationList = NHLFE.setRoutingTables(answer1); nhfletable_set = true; Logs.LogsReceiveRoutingTable(Name); } if (package.isMPLS()) { if (nhfletable_set) { MPLSPackage MPLSpackage = Package.ReceiveMPLSPackage(package); Console.WriteLine($"otrzymany TTL: {MPLSpackage.GetTTL()}"); MPLSpackage.decrementTTL(); if (MPLSpackage.GetTTL() > 0) { Logs.LogsRouterReceivePackage(MPLSpackage, Name); var InPort = MPLSpackage.GetPort(); int label = MPLSpackage.GetLastLabel(); int row_id = get_nhfle_row_id(InPort, label); if (row_id > -1) { switch (ComutationList[row_id].method) { case "swap": MPLSpackage.swap(ComutationList[row_id].label_out, ComutationList[row_id].port_out); break; case "push": push(ComutationList[row_id], MPLSpackage); break; case "pop": pop(ComutationList[row_id], MPLSpackage); break; } Console.WriteLine($"wysyłany TTL: {MPLSpackage.GetTTL()}"); Package package1 = Package.MPLSPackage_(MPLSpackage); Logs.LogsRouterSendPackage(MPLSpackage, Name); udp.Send(package1.toBytes(), package1.toBytes().Length, CableCloudEndPoint); } else { Console.WriteLine("Podana etykieta jest niepoprawna"); } //Thread.Sleep(1000); } } } else if (package.isTerminateOrder()) { Environment.Exit(0); } } } }); }
private MPLSPackage PerformMplsNotEmptyPacketRouting(MPLSPackage package) { var labelTTL = package.PeekTopLabel().TTL; string poppedLabelStack = "-"; while (true) { if (package.LabelStack.IsEmpty()) // in case if we are egress LER { return(package); } AddLog($"Looking for NHLFE_ID in ILM table...", LogType.Information, Window.ShowDetailedRoutingLogs); var ilmRow = RoutingTables.ilmTable.Rows.FirstOrDefault(row => row.IncPort == package.Port && package.PeekTopLabel().Number == (short)row.IncLabel && poppedLabelStack.Equals(row.PoppedLabelStack)); // After completing previous NHFLE action (with nextID==null), check, if there is any rule for such (incPort, incLabel, poppedLabelStack) entry // i.e. let's say that we popped one label in the previous action. We couldn't have NEXT_ID filled, because router can only see what is in the outermost label. // But in order to disgunish, for example, label 17 that was nested from label 17 that was not, we must remember a stack of labels that have been popped. // See Tools/Table Rows/IlmTableRow.cs/incLabel description for more detailed explanation. if (ilmRow == null) { AddLog($"Couldn't find matching entry!", LogType.CantFindMatchingEntry, Window.ShowDetailedRoutingLogs); return(null); } AddLog($"NHLFE_ID for incoming port={package.Port}, incoming label={package.PeekTopLabel().Number}, popped labels={(poppedLabelStack == "-" ? "NULL" : poppedLabelStack)}, is: {ilmRow.NHLFE_ID}", LogType.Information, Window.ShowDetailedRoutingLogs); var currentNHLFE = RoutingTables.nhlfeTable.Rows.FirstOrDefault(row => row.ID == ilmRow.NHLFE_ID); if (currentNHLFE == null) { // routing information is missing AddLog($"Couldn't find NHLFE entry!", LogType.Error, Window.ShowDetailedRoutingLogs); return(null); } while (true) { if (Window.ShowDetailedRoutingLogs) { string nextAction, outputPort, outputLabel; nextAction = currentNHLFE.NextID == null ? "NULL" : currentNHLFE.NextID.ToString(); outputPort = currentNHLFE.OutPort == null ? "NULL" : currentNHLFE.OutPort.ToString(); outputLabel = currentNHLFE.OutLabel == null ? "NULL" : currentNHLFE.OutLabel.ToString(); AddLog($"Action for NHLFE_ID={currentNHLFE.ID} is {currentNHLFE.Action}, output port: {outputPort}, output label: {outputLabel}, next NHLFE_ID: {nextAction}", LogType.Information, Window.ShowDetailedRoutingLogs); } var thereIsNextAction = currentNHLFE.NextID != null; PerformLabelAction(package, currentNHLFE, labelTTL, ref poppedLabelStack); // after doing SWAP, the next action will be delivered via NEXT_ID, not ILM entry. Same thing for PUSH. // if there is no next action id, then it means that we can forward the packet if (!thereIsNextAction && (currentNHLFE.Action.Equals("SWAP") || currentNHLFE.Action.Equals("PUSH"))) { AddLog($"Completed last action, forwarding to port {package.Port}", LogType.Information, Window.ShowDetailedRoutingLogs); return(package); } // this means that we popped a label and the next action - push or swap - will be determined via ILM entry if (!thereIsNextAction) { break; } currentNHLFE = RoutingTables.nhlfeTable.Rows.FirstOrDefault(row => row.ID == currentNHLFE.NextID); } } }