Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
<!-- Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
#Examples
##Topology Module Examples
Two sets of basic configuration files are here included with Topology Module software: the setup for running three TM within the same machine (configuration A) and the setup for running three TM in three dedicated machines (configuration B). In both cases three example network topologies are provided to represent the abstract topology of 2 end-point providers and 1 transit provider.
### Example TM1: 1 Way Test in the same virtual machine, BPG-LS Plugin and UNIFY Export.
The setup has been provided just for testing purpose and configures 3 TADS in the same machine to perform unidirectional information exchange.
![1WayTest](figures/1wayTest.png?raw=true "Test with 3 TM")
The reference files, including Topology Module configuration, BGP-LS Plugin configuration and abstracted topologies are copiend in the folder target/conf1wayTest after the maven installation. Be sure to compile also the Topology Module as indicated in README.md.
To execute TM1 run:
```bash
sudo java -Dlog4j.configurationFile=target/log4j2.xml -jar target/topology-1.3.3-shaded.jar target/conf1wayTest/TM1.xml
```
To execute TM2 run:
```bash
sudo java -Dlog4j.configurationFile=target/log4j2.xml -jar target/topology-1.3.3-shaded.jar target/conf1wayTest/TM2.xml
```
To execute TM3 run:
```bash
sudo java -Dlog4j.configurationFile=target/log4j2.xml -jar target/topology-1.3.3-shaded.jar target/conf1wayTest/TM3.xml
```
To verify the retrieved information:
```bash
curl http://localhost:8087/restconf/data/virtualizer/ | python -m json.tool
```
[for TADS2]
```bash
curl http://localhost:8088/restconf/data/virtualizer/ | python -m json.tool
```
[for TADS3]
```bash
curl http://localhost:8089/restconf/data/virtualizer/ | python -m json.tool
```
### Example TM2: 2 Way Test in the different virtual machines, BPG-LS Plugin and UNIFY Export.
The setup has been provided as reference configuration for the configuration of 3 TM in dedicated machines to perform bidirectional exchange of information
![1WayTest](figures/2wayTest.png?raw=true "Test with 3 TM in 3 different machines")
The reference files, including Topology Module configuration, BGP-LS Plugin configuration and abstracted topologies are in
```bash
target/conf2waysReal
```
Before running the reference scenario be sure to complete the IP configuration in the 3 modules, in fact, according to previous description, minor ad-hoc changes are needed.
In the Topology Module configuration files (TM*.xml):
• set the IP address used for the BGP-LS communication as Identifier
In the BGP-LS Plugin configuration (BGPLS*_2way.xml):
• set the IP address used for the BGP-LS communication as BGPIdentifier
• configure the peers as needed (IP address and port)
[where * = 1,2,3]
To execute TADS1 in machine 1 run:
```bash
sudo java -Dlog4j.configurationFile=target/log4j2.xml -jar target/topology-1.3.3-shaded.jar target/conf1wayTest/TM1.xml
```
To execute TADS1 in machine 2 run:
```bash
sudo java -Dlog4j.configurationFile=target/log4j2.xml -jar target/topology-1.3.3-shaded.jar target/conf1wayTest/TM2.xml
```
To execute TADS1 in machine 3 run:
```bash
sudo java -Dlog4j.configurationFile=target/log4j2.xml -jar target/topology-1.3.3-shaded.jar target/conf1wayTest/TM3.xml
```
To verify the retrieved information:
[for TADS2, in machine 1]
```bash
curl http://localhost:8088/restconf/data/virtualizer/ | python -m json.tool
```
[for TADS2, in machine 2]
```bash
>curl http://localhost:8088/restconf/data/virtualizer/ | python -m json.tool
```
[for TADS3, in machine 3]
```bash
>curl http://localhost:8088/restconf/data/virtualizer/ | python -m json.tool
```
### Topology module with BGP-LS and COP plugins and BGP-LS speaker
In this example there are 2 BGP-LS speakers, one acting as sender of topology, and the other as consumer. A small topology is loaded from an xml file in BGP-LS Speaker #1. This topology is sent to BGP-LS Speaker #2.
```bash
TBD
```
### Topology module with BGP-LS and COP plugins and Topology module with BGP-LS speaker
In this example there are 2 BGP-LS speakers, one acting as sender of topology, and the other as consumer. A small topology is loaded from an xml file in BGP-LS Speaker #1. This topology is sent to BGP-LS Speaker #2.
```bash
TBD
```
## BGP-LS Speaker Examples
### BPP-LS Speaker Example 1
In this example there are 2 BGP-LS speakers, one acting as sender of topology, and the other as consumer. A small topology is loaded from an xml file in BGP-LS Speaker #1. This topology is sent to BGP-LS Speaker #2.
To launch BGP-LS Speaker #1:
```bash
sudo java -Dlog4j.configurationFile=target/log4j2.xml -jar target/bgp-ls-speaker-jar-with-dependencies.jar target/bgpls_example1/BGP4Parameters_1.xml
```
BGP-LS Speaker #2:
```bash
sudo java -Dlog4j.configurationFile=target/log4j2.xml -jar target/bgp-ls-speaker-jar-with-dependencies.jar target/bgpls_example1/BGP4Parameters_2.xml
```
To verify the retrieved information:
```bash
telnet localhost 1112
show topology
```
Then, the topology is printed on screen.
<!-- Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
# Example 1: TM with XML Plugin and TAPI Plugin
- First of all, compile the full-jar if you have not done so
```bash
mvn package -P generate-full-jar
```
Execute the server
```bash
sudo java -Dlog4j.configurationFile=target/examples/log4j2.xml -jar target/topology-1.3.4-SNAPSHOT-shaded.jar target/TM_TAPI_example1/TMConfTAPI.xml
```
Make the query
```bash
curl http://localhost:8089/config/context/topology -X GET -i -H "Content-Type: application/json" -H "Accept: application/json"
```
<!-- Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
# Topology XML File
This section describes the topology file format, used by the TADS to load the abstracted view of the local provider.
The reference file for this description is
```
target/conf1wayTest/network1.xml
```
The main tag of the file is **network** that can include multiple **domains**, each domain represents a provider.
```xml
<network>
<domain>
</domain>
<domain>
</domain>
</network>
```
In this case the network topology includes two providers.
The first part of the each domain contains some general information:
- **domain_id**: the AS number of the domain represented in IPv4 format
- the **reachability_entry**: that summarizes the prefix network for the provider (IPv4 network prefix and mask)
- **it_resources**: here the information related to overall IT resources availability is described considering
- **controller_it**: the entry point for 5GEx orchestration
- **cpu**: overall available CPUs
- **mem**: overall available memory
- **storage**: overall available storage
```xml
<domain_id>0.0.0.1</domain_id>
<reachability_entry>
<ipv4_address>172.16.101.0</ipv4_address>
<prefix>24</prefix>
</reachability_entry>
<it_resources>
<controller_it>https://openstack.5Gex.com/url</controller_it>
<cpu>100</cpu>
<mem>100Gbyte</mem>
<storage>100Tbyte</storage>
</it_resources>
```
Then the file is organized considering a list of nodes and a list unidirectional links.
Each node is represented with a tag **node** and is identified with an IPv4 id called **router_id**
```xml
<node>
<router_id>172.16.101.101</router_id>
</node>
<node>
<router_id>172.16.101.102</router_id>
</node>
<node>
<router_id>172.16.101.103</router_id>
</node>
<node>
<router_id>172.16.101.104</router_id>
</node>
```
In the reference case 4 nodes are considered.
Each link is identified by the tag **edge**.
The link description include:
- **source**: the source node of the link, identified with the pair **router_id** and interface id, **if_id**
- **destination**: the destination node of the link, identified with the pair router_id and interface
- **TE parameters**: several possibilities are available, in the considered example the focus was on
- unidirectional link delay
- minimum experienced delay
- maximum experienced delay
```xml
<edge>
<source>
<router_id>172.16.101.101</router_id>
<if_id>1</if_id>
</source>
<destination>
<router_id>172.16.101.104</router_id>
<if_id>1</if_id>
</destination>
<undir_delay_link>99</undir_delay_link>
<undir_min_max_delay>
<min>23</min>
<max>250</max>
</undir_min_max_delay>
</edge>
```
For setting up default TE parameters for all the network links, the **edgeCommon** tag is used.
```xml
<edgeCommon>
<undir_delay_link>99</undir_delay_link>
<undir_min_max_delay>
<min>23</min>
<max>43</max>
</undir_min_max_delay>
<undir_delay_variation>1</undir_delay_variation>
<undir_link_loss>102</undir_link_loss>
<undir_residual_bandwidth>802</undir_residual_bandwidth>
<undir_available_bandwidth>500</undir_available_bandwidth>
<undir_utilized_bandwidth>436</undir_utilized_bandwidth>
</edgeCommon>
```
<!-- Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="TRACE">
<Appenders>
<Console name="trace" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="BGP4Peer" level="trace" additivity="false">
<AppenderRef ref="Console"/>
</Logger>
<Logger name="BGP4Server" level="trace" additivity="false">
<AppenderRef ref="Console"/>
</Logger>
<Logger name="BGP4Parser" level="trace" additivity="false">
<AppenderRef ref="Console"/>
</Logger>
<Root level="trace">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>es.tid.netphony</groupId>
<artifactId>topology</artifactId>
<version>1.4.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Netphony TED and BGP-LS peer</name>
<description>Traffic Engineering Database, BGP-LS peer, Topology Module</description>
<url>http://telefonicaid.github.io/netphony-topology/</url>
<licenses>
<license>
<name>Apache License 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0</url>
<!-- Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) -->
<!-- Licensed under the Apache License, Version 2.0 (the "License"); -->
<!-- you may not use this file except in compliance with the License. -->
<!-- You may obtain a copy of the License at -->
<!-- http://www.apache.org/licenses/LICENSE-2.0 -->
<!-- Unless required by applicable law or agreed to in writing, software -->
<!-- distributed under the License is distributed on an "AS IS" BASIS, -->
<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -->
<!-- See the License for the specific language governing permissions and -->
<!-- limitations under the License. -->
</license>
</licenses>
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>${jersey-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-version}</version>
</dependency>
<!-- Error slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j-version}</version>
</dependency>
<dependency>
<groupId>es.tid.netphony</groupId>
<artifactId>network-protocols</artifactId>
<version>1.4.1</version>
<!-- Next local repo only on docker container -->
<!-- <scope>system</scope>
<systemPath>/protocols/target/network-protocols-1.1-SNAPSHOT.jar</systemPath> -->
</dependency>
<dependency>
<groupId>org.jgrapht</groupId>
<artifactId>jgrapht-core</artifactId>
<version>${jgrapht-core-version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.metaparadigm</groupId>
<artifactId>json-rpc</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.1.0</version>
</dependency>
<!-- JSON processing: jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-joda</artifactId>
<version>${jackson-datatype-joda-version}</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${jodatime-version}</version>
</dependency>
<!--GRPC DEPENDENCIES-->
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>${grpc-protobuf-version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc-protobuf-version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc-stub-version}</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>${javax-annotation-api-version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
</dependencies>
<developers>
<developer>
<name>Telefonica I+D</name>
<email>oscar.gonzalezdedios@telefonica.com</email>
<organization>Telefonica I+D</organization>
<organizationUrl>https://www.tid.es</organizationUrl>
</developer>
</developers>
<scm>
<connection>scm:git:git@github.com:telefonicaid/netphony-topology.git</connection>
<developerConnection>scm:git:git@github.com:telefonicaid/netphony-topology.git</developerConnection>
<url>git@github.com:telefonicaid/netphony-topology.git</url>
</scm>
<repositories>
<!--Enables to get SNAPSHOTS-->
<repository>
<id>oss.sonatype.org-snapshot</id>
<url>http://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>ossrh</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
<build>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>
<plugins>
<!--GRPC plugins + extensions-->
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.9.0:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.24.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target</outputDirectory>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>${basedir}/src/main/sample-config-files</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>eu.teraflow.tid.bgp4Peer.peer.BGPPeerMain</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>deploy-maven-central</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<additionalparam>-Xdoclint:none</additionalparam>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>bgp-ls-speaker</id>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
<version>4.1.77.Final</version>
<classifier>linux-x86_64</classifier>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>bgp-ls-speaker</finalName>
<archive>
<manifest>
<mainClass>eu.teraflow.tid.bgp4Peer.peer.BGPPeerMain</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>generate-javadoc</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<failOnError>false</failOnError>
</configuration>
<version>2.9.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>integration-test</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.13</version>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
<execution>
<id>verify</id>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- No encuentra surefire-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
<!-- <shutdown>kill</shutdown> Use it if required-->
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>generate-full-jar</id>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<filters>
<filter>
<artifact>*:*</artifact>
<!-- <excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes> -->
</filter>
</filters>
<minimizeJar>false</minimizeJar>
<transformers>
<!-- <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> -->
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>eu.teraflow.tid.bgp.bgp4Peer.peer.BGPPeerMain</mainClass>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformer>
</transformers>
</configuration>
</execution>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<properties>
<jersey-version>1.19.4</jersey-version>
<slf4j-version>2.0.6</slf4j-version>
<junit-version>4.8.1</junit-version>
<servlet-api-version>2.5</servlet-api-version>
<jackson-version>2.4.2</jackson-version>
<jodatime-version>2.3</jodatime-version>
<surefire-version>2.19.1</surefire-version>
<jgrapht-core-version>0.9.1</jgrapht-core-version>
<javax-annotation-api-version>1.3.2</javax-annotation-api-version>
<grpc-stub-version>1.24.0</grpc-stub-version>
<grpc-protobuf-version>1.46.0</grpc-protobuf-version>
<jackson-datatype-joda-version>2.1.5</jackson-datatype-joda-version>
</properties>
</project>
// Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package eu.teraflow.tid.bgp4Peer.bgp4session;
import es.tid.bgp.bgp4.messages.BGP4Message;
import es.tid.bgp.bgp4.messages.BGP4MessageTypes;
import es.tid.bgp.bgp4.messages.BGP4Update;
import eu.teraflow.tid.bgp4Peer.peer.BGP4Exception;
import eu.teraflow.tid.bgp4Peer.updateTEDB.UpdateDispatcher;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.Timer;
/**
* BGP4 session server
*
* @author mcs
*
*/
public class BGP4PeerInitiatedSession extends GenericBGP4Session{
/**
* 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;
/**
* Constructor of the BGP4 Session
* @param s Socket of the BGP4Peer-BGP4Peer Communication
* @param bgp4SessionsInformation bgp4SessionsInformation
* @param updateDispatcher updateDispatcher
* @param holdTime holdTime
* @param BGPIdentifier BGPIdentifier
* @param version version
* @param myAutonomousSystem myAutonomousSystem
* @param noDelay noDelay
* @param keepAliveTimer keepAliveTimer
*/
public BGP4PeerInitiatedSession(Socket s, BGP4SessionsInformation bgp4SessionsInformation, UpdateDispatcher updateDispatcher,int holdTime,Inet4Address BGPIdentifier,int version,int myAutonomousSystem,boolean noDelay,int keepAliveTimer ){
super(bgp4SessionsInformation, holdTime, BGPIdentifier, version, myAutonomousSystem,keepAliveTimer);
this.setFSMstate(BGP4StateSession.BGP4_STATE_IDLE);
log=LoggerFactory.getLogger("BGP4Server");
log.debug("New BGP4Session: "+s);
this.socket = s;
try {
s.setTcpNoDelay(noDelay);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.newSessionId();
this.remotePeerIP =(Inet4Address) ((InetSocketAddress) socket.getRemoteSocketAddress()).getAddress();
timer=new Timer();
this.updateDispatcher = updateDispatcher;
//this.keepAliveLocal=params.getKeepAliveTimer();
//this.deadTimerLocal=params.getDeadTimer();
}
/**
* Initiates a Session the BGP-4 Peers
*/
public void run() {
try {
initializeBGP4Session();
} catch (BGP4Exception e2) {
// TODO Auto-generated catch block
try {
this.socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return;
}
log.info("BGP4 Session established with peer "+this.remotePeerIP);
this.deadTimerT=new DeadTimerThread(this, this.holdTime);
startDeadTimer();
this.keepAliveT=new KeepAliveThread(out, this.keepAliveTimer);
startKeepAlive();
//Listen to new messages
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("Exception Closing BGP4 Session with "+this.remotePeerIP);
}
log.debug("Finishing BGP4 Session with "+this.remotePeerIP);
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("OPEN message received");
//After the session has been started, ignore subsequent OPEN messages
log.warn("OPEN message ignored");
break;
case BGP4MessageTypes.MESSAGE_KEEPALIVE:
log.debug("KEEPALIVE message received from "+this.remotePeerIP);
//The Keepalive message allows to reset the deadtimer
break;
case BGP4MessageTypes.MESSAGE_NOTIFICATION:
log.info("NOTIFICATION message from "+this.remotePeerIP);
break;
case BGP4MessageTypes.MESSAGE_UPDATE:
log.debug("UPDATE message from "+this.remotePeerIP);
BGP4Update bgp4Update = new BGP4Update(msg);
log.debug(bgp4Update.toString());
bgp4Update.setLearntFrom(this.getRemotePeerIP().toString());
updateDispatcher.dispatchRequests(bgp4Update);
break;
default:
log.warn("ERROR: unexpected message from "+this.remotePeerIP);
bgp4Msg = false;
}
if (bgp4Msg) {
//Reseting Dead Timer as BGP4 Session Message has arrived
resetDeadTimer();
}
}
}
}finally{
log.error("BGP4 session with peer "+this.remotePeerIP+" has been closed");
cancelDeadTimer();
cancelKeepAlive();
this.FSMstate=BGP4StateSession.BGP4_STATE_IDLE;
endSession();
}
}
@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()+" from peer "+this.remotePeerIP);
BGP4SessionsInformation.deleteSession(this.getSessionId());
}
}
// Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package eu.teraflow.tid.bgp4Peer.bgp4session;
import es.tid.bgp.bgp4.messages.BGP4Message;
/**
* BGP Session Interface
*
* @author mcs
*
*/
public interface BGP4Session {
/**
* Send close message and finish the BGP Session
*/
public void close(/*int reason*/);
/**
* Finish the BGP Session abruptly,
*/
public void killSession();
/**
* Encodes and sends BGP Message
* If the message is bad encoded, the session is closed
* @param message BGP4 Message
*/
public void sendBGP4Message(BGP4Message message);
}
// Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package eu.teraflow.tid.bgp4Peer.bgp4session;
import es.tid.bgp.bgp4.messages.BGP4Message;
import es.tid.bgp.bgp4.messages.BGP4MessageTypes;
import es.tid.bgp.bgp4.messages.BGP4Update;
import eu.teraflow.tid.bgp4Peer.peer.BGP4Exception;
import eu.teraflow.tid.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());
}
}
// Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package eu.teraflow.tid.bgp4Peer.bgp4session;
public class BGP4SessionExistsException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
}
// Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package eu.teraflow.tid.bgp4Peer.bgp4session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import eu.teraflow.tid.bgp4Peer.peer.BGP4Exception;
import java.io.DataOutputStream;
import java.net.Inet4Address;
import java.util.Enumeration;
import java.util.Hashtable;
/**
* Class where the oppened BGP4 sessions are stored.
*
* @author mcs
*
*/
public class BGP4SessionsInformation {
public Hashtable<Long,GenericBGP4Session> sessionList;
public Hashtable<Inet4Address,GenericBGP4Session> sessionListByPeerIP;
private boolean isTest = false;
Logger log;
//FIXME: ya lo tenemos a trav�s de la lista de sesiones
DataOutputStream out;
public BGP4SessionsInformation(){
sessionList=new Hashtable<Long,GenericBGP4Session>();
sessionListByPeerIP=new Hashtable<Inet4Address,GenericBGP4Session>();
log = LoggerFactory.getLogger("BGP4Parser");
}
public BGP4SessionsInformation(boolean test){
sessionList=new Hashtable<Long,GenericBGP4Session>();
sessionListByPeerIP=new Hashtable<Inet4Address,GenericBGP4Session>();
log = LoggerFactory.getLogger("BGP4Parser");
isTest= test;
}
public synchronized void notifySessionStart(Inet4Address addr) throws BGP4SessionExistsException{
if (sessionListByPeerIP.containsKey(addr)){
throw new BGP4SessionExistsException();
}
}
public synchronized void addSession(long sessionId, GenericBGP4Session session) throws BGP4Exception{
Enumeration <GenericBGP4Session > sessions = sessionList.elements();
log.debug("Looking to add session with id "+sessionId+" --> "+session.toString());
//Check if there is already a session with the remote peer.
//Only one session allowed with each remote peer
GenericBGP4Session existingSession=sessionListByPeerIP.get(session.remotePeerIP);
if(isTest){
//If there is no existing session with the peer
sessionList.put(new Long(sessionId),session);
sessionListByPeerIP.put(session.getPeerIP() , session);
log.debug("Registering new session with Peer "+session.getPeerIP() +" with ID "+sessionId);
}
else{
if (existingSession!=null){
log.debug("Session with id "+existingSession.getSessionId()+" against "+session.remotePeerIP.getHostAddress()+" already exists");
throw new BGP4Exception();//si no existe throw new BGP4Exception();
}
//If there is no existing session with the peer
sessionList.put(new Long(sessionId),session);
sessionListByPeerIP.put(session.getPeerIP() , session);
log.debug("Registering new session with Peer "+session.getPeerIP() +" with ID "+sessionId);
}
}
public synchronized void deleteSession(long sessionId){
GenericBGP4Session ses=sessionList.get(sessionId);
if (ses!=null) {
Inet4Address ip=sessionList.get(sessionId).getPeerIP();
sessionList.remove(new Long(sessionId));
sessionListByPeerIP.remove(ses.getPeerIP());
log.debug("Deleted Session with id "+sessionId +" with peer "+ses.getPeerIP().getHostAddress());
}else {
log.info("SESSION WAS NOT REGISTERED NULL");
}
}
@Override
public String toString() {
StringBuffer sb=new StringBuffer(2000);
int counter = 1;
Enumeration <GenericBGP4Session > sessions = sessionList.elements();
//Comprobar si ya existe la session con ese peer
while (sessions.hasMoreElements()){
sb.append("Session number "+(counter++)+"\n");
sb.append(sessions.nextElement().toString()+"\n");
}
return sb.toString();
}
public String printSession(long sessionId){
GenericBGP4Session ses=sessionList.get(new Long(sessionId));
if (ses!=null){
return ses.toString();
}else {
return "session "+sessionId+" does not exist";
}
}
public DataOutputStream getOut() {
return out;
}
public void setOut(DataOutputStream out) {
this.out = out;
}
public Hashtable<Long, GenericBGP4Session> getSessionList() {
return sessionList;
}
public void setSessionList(Hashtable<Long, GenericBGP4Session> sessionList) {
this.sessionList = sessionList;
}
}
// Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package eu.teraflow.tid.bgp4Peer.bgp4session;
/**
* The state session attribute indicates the current state of the BGP
FSM
* @author mcs
*
*/
public class BGP4StateSession {
public static final int BGP4_STATE_IDLE=0;
public static final int BGP4_STATE_TCP_PENDING=1;
public static final int BGP4_STATE_OPEN_WAIT=2;
public static final int BGP4_STATE_KEEP_WAIT=3;
public static final int BGP4_STATE_SESSION_UP=4;
}
// Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package eu.teraflow.tid.bgp4Peer.bgp4session;
import java.util.TimerTask;
public class ConnectRetryTimer extends TimerTask {
int initialValue;
ConnectRetryTimer(int initialValue){
this.initialValue=initialValue;
}
@Override
public void run() {
// TODO Auto-generated method stub
}
}
// Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package eu.teraflow.tid.bgp4Peer.bgp4session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* BGP4 DeadTimer management Thread
*
*/
public class DeadTimerThread extends Thread {
private BGP4Session bgp4Session = null;
private int deadTimer = 0;
private Logger log;
private boolean running;
public DeadTimerThread(BGP4Session p, int d) {
this.deadTimer = d;
this.bgp4Session = p;
log=LoggerFactory.getLogger("BGP4Server");
}
public void run() {
running=true;
while (running) {
try {
sleep(deadTimer * 1000);
/*
* Time's over, close PCEP Session
*/
log.warn("DeadTimer OVER");
this.bgp4Session.close(/*ObjectParameters.REASON_DEADTIMER*/);
return;
} catch (InterruptedException e) {
//return;
if (running==false){
log.debug("Ending DeadTimerThread");
return;
}
else {
log.debug("Reseting Dead Timer");
}
} catch (Exception e) {
//FIXME: Ver que hacer aqui, por ahora, solo saco un log
log.warn("Unhandled exception: " + e.getMessage());
}
}
}
public void stopRunning(){
running=false;
}
}
// Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package eu.teraflow.tid.bgp4Peer.bgp4session;
import es.tid.bgp.bgp4.messages.BGP4Keepalive;
import es.tid.bgp.bgp4.messages.BGP4Message;
import es.tid.bgp.bgp4.messages.BGP4MessageTypes;
import es.tid.bgp.bgp4.messages.BGP4Open;
import es.tid.bgp.bgp4.open.BGP4CapabilitiesOptionalParameter;
import es.tid.bgp.bgp4.open.BGP4OctetsASByteCapabilityAdvertisement;
import es.tid.bgp.bgp4.open.MultiprotocolExtensionCapabilityAdvertisement;
import es.tid.bgp.bgp4.update.fields.pathAttributes.AFICodes;
import es.tid.bgp.bgp4.update.fields.pathAttributes.SAFICodes;
import eu.teraflow.tid.bgp4Peer.peer.BGP4Exception;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.Socket;
import java.util.Timer;
/**
* Generic BGP4 Session.
* Implements the basics of a BGP4 Session
* Any particular session must inherit this one
*
* @author ogondio
*
*/
public abstract class GenericBGP4Session extends Thread implements BGP4Session {
/**
* PCEP Session Manager
*/
protected BGP4SessionsInformation BGP4SessionsInformation;
/**
* Thread to send periodic Keepalives
*/
protected KeepAliveThread keepAliveT = null;
/**
* Value of the Keepalive timer set by the Local PCE. Used to send keepalives
*/
protected int keepAliveLocal;
/**
* Value of the Keepalive timer of the peer PCC. It is not used in the server!!!
*/
protected int keepAlivePeer;
/**
* Thread to check if the connection is still alive.
* If in this time the PCE has not received anything, it closes the session
* It is set by the PCC (in this case, the remote peer)
*/
protected DeadTimerThread deadTimerT = null;
/**
* Value of the deadtimer that the PCC sends. It is used in the PCC in the thread
*/
protected int deadTimerPeer;
/**
* Socket of the communication between BGP peers
*/
protected Socket socket = null;
/**
* Remote Peer IP Address
* Obtained from the socket for convenience
*/
protected Inet4Address remotePeerIP=null;
/**
* DataOutputStream to send messages to the peer
*/
protected DataOutputStream out=null;
/**
* DataInputStream to receive messages from PCC
*/
protected DataInputStream in=null;//
/**
* Queue to send the Computing Path Requests
*/
//protected RequestQueueSend req;
/**
* Logger to write the Parent PCE server log
*/
protected Logger log;
/**
* Timer to schedule KeepWait and OpenWait Timers
*/
protected Timer timer;
/**
* Finite State Machine of the PCEP protocol
*/
protected int FSMstate;
/**
* Remote Domain ID
* null if not sent
*/
protected Inet4Address remoteDomainId=null;
/**
* Remote List of OF Codes
* If sent by the peer PCE
*/
//private LinkedList<Integer> remoteOfCodes;//FIME: What do we do with them?
/**
* RemoteOK: a boolean that is set to 1 if the system has received an
acceptable Open message.
*/
private boolean remoteOK=false;
/**
*
*/
private boolean localOK=false;
/**
*
*/
private int openRetry=0;
/**
* Byte array to store the last PCEP message read.
*/
protected byte[] msg = null;
/**
* Initial number of the session ID (internal use only)
*/
public static long sessionIdCounter=0;
/**
*
*/
protected Boolean updateFrom;
protected boolean sendTo;
/**
* Session ID (internal use only)
*/
private long sessionId;
/**************** PARAMETROS DE LA SESION ********************/
private int ConnectRetryCounter=0;
private ConnectRetryTimer connectRetryTimer = null;
private int connectRetryTime; //FIXME: esto aun no se que es.
/**************PARAMETROS OPEN MESSAGE************************/
protected int holdTime;
/**
* Time between sending keepalives
*/
protected int keepAliveTimer;
/**
* IP address that is assigned to that BGP speaker
*/
protected Inet4Address BGPIdentifier;
/**
* Autonomous System number of the sender
*/
protected int myAutonomousSystem;
/**
* version indicates the protocol version number of the message
* it must be 4
*/
protected int version;
public GenericBGP4Session(BGP4SessionsInformation bgp4SessionsInformation,int holdTime,Inet4Address BGPIdentifier,int version,int myAutonomousSystem,int mykeepAliveTimer) {
log=LoggerFactory.getLogger("BGP4Parser");
this.BGP4SessionsInformation=bgp4SessionsInformation;
this.holdTime=holdTime;
this.BGPIdentifier=BGPIdentifier;
this.version = version;
this.myAutonomousSystem=myAutonomousSystem;
this.keepAliveTimer = mykeepAliveTimer;
this.newSessionId();
}
/**
* Read PCE message from TCP stream
* @param in InputStream
* @return byte array with a BGP4 Message
* @throws IOException Execption thrown trying to read message
*/
protected byte[] readBGP4Msg(DataInputStream in) throws IOException{
byte[] ret = null;
byte[] hdr = new byte[BGP4Message.getBGPHeaderLength()];
byte[] temp = null;
boolean endHdr = false;
int r = 0;
int length = 0;
boolean endMsg = false;
int offset = 0;
while (!endMsg) {
try {
if (endHdr) {
r = in.read(temp, offset, 1);
}
else {
r = in.read(hdr, offset, 1);
}
} catch (IOException e){
log.warn("Error reading data: "+ e.getMessage());
throw e;
}catch (Exception e) {
log.warn("readMsg Oops: " + e.getMessage());
throw new IOException();
}
if (r > 0) {
if (offset == BGP4Message.getBGPMarkerLength()) {
length = ((int)hdr[offset]&0xFF) << 8;
}
if (offset == BGP4Message.getBGPMarkerLength() + 1) {
length = length | (((int)hdr[offset]&0xFF));
temp = new byte[length];
endHdr = true;
System.arraycopy(hdr, 0, temp, 0, BGP4Message.getBGPHeaderLength());
}
if ((length > 0) && (offset == length - 1)) {
endMsg = true;
}
offset++;
}
else if (r==-1){
log.debug("End of stream has been reached");
throw new IOException();
}
}
if (length > 0) {
ret = new byte[length];
System.arraycopy(temp, 0, ret, 0, length);
}
return ret;
}
/**
* Read PCE message from TCP stream
* @param in InputStream
* @return byte array with a BGP4 Message
* @throws IOException Execption thrown trying to read message
*/
protected byte[] readMsgOptimized(DataInputStream in) throws IOException{
byte[] ret = null;
byte[] hdr = new byte[4];
byte[] temp = null;
boolean endHdr = false;
int r = 0;
int length = 0;
boolean endMsg = false;
int offset = 0;
while (!endMsg) {
try {
if (endHdr) {
//log.info("Vamos a leer datos ");
r = in.read(temp, offset, length-offset);
if (r>0){
if ((offset+r)>=length){
//log.info("Bien ");
endMsg=true;
}else {
offset=offset+r;
}
}
else if (r<0){
log.error("End of stream has been reached reading data");
throw new IOException();
}
}
else {
//log.info("Vamos a leer la cabecera ");
r = in.read(hdr, offset, 4-offset);
if (r < 0) {
log.error("End of stream has been reached reading header");
throw new IOException();
}else if (r >0){
if ((offset+r)>=4){
length = ( (hdr[offset+2]&0xFF) << 8) | ((hdr[offset+3]&0xFF));
offset=4;
temp = new byte[length];
endHdr = true;
System.arraycopy(hdr, 0, temp, 0, 4);
if (length==4){
endMsg=true;
}
}else {
offset=offset+r;
}
}
}
} catch (IOException e){
log.error("Error reading data: "+ e.getMessage());
throw e;
}catch (Exception e) {
log.error("readMsg Oops: " + e.getMessage());
log.error("Failure reason : "+e.getStackTrace());
throw new IOException();
}
}
if (length > 0) {
ret = new byte[length];
System.arraycopy(temp, 0, ret, 0, length);
}
return ret;
}
// /**
// * <p>Close the PCE session</p>
// * <p>List of reasons (RFC 5440):</p>
// * Value Meaning
// 1 No explanation provided
// 2 DeadTimer expired
// 3 Reception of a malformed PCEP message
// 4 Reception of an unacceptable number of unknown
// requests/replies
// 5 Reception of an unacceptable number of unrecognized
// PCEP messages
// * @param reason Reason for closing the PCEP Session
// * @return PCEP Session closed OK
// */
// public void close(int reason){
// log.info("Closing PCEP Session");
// BGP4Close p_close=new BGP4Close();
// p_close.setReason(reason);
// sendPCEPMessage(p_close);
// killSession();
// }
public DataOutputStream getOut() {
return out;
}
public void setOut(DataOutputStream out) {
this.out = out;
}
/**
* Starts the deadTimerThread
*/
protected void startDeadTimer() {
this.deadTimerT.start();
}
/**
* Resets the DeadTimerThread
* To be called every time a message in the session is received
*/
protected void resetDeadTimer() {
if (this.deadTimerT != null) {
this.deadTimerT.interrupt();
}
}
public Socket getSocket() {
return socket;
}
/**
* Ends the DeadTimer Thread
*/
protected void cancelDeadTimer() {
log.debug("Cancelling DeadTimer");
if (this.deadTimerT != null) {
this.deadTimerT.stopRunning();
this.deadTimerT.interrupt();
this.deadTimerT=null;
}
}
/**
* Starts the Keep Alive Thread
*/
public void startKeepAlive() {
this.keepAliveT.start();
}
/**
* Ends the KeepAlive Thread
*/
public void cancelKeepAlive() {
log.debug("Cancelling KeepAliveTimer");
if (this.keepAliveT != null) {
this.keepAliveT.stopRunning();
this.keepAliveT.interrupt();
this.keepAliveT=null;
}
}
/**
* Ends current connections
*/
protected void endConnections(){
try {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
if (this.socket != null) {
log.warn("Closing socket");
this.socket.close();
}
} catch (Exception e) {
log.warn("Error closing connections: " + e.getMessage());
}
}
public int getFSMstate() {
return FSMstate;
}
protected void setFSMstate(int fSMstate) {
FSMstate = fSMstate;
}
public void killSession(){
log.warn("Killing Session");
timer.cancel();
this.endConnections();
this.cancelDeadTimer();
this.cancelKeepAlive();
this.endSession();
this.BGP4SessionsInformation.deleteSession(this.sessionId);
log.warn("Interrupting thread!!!!");
this.interrupt();
}
/**
* DO HERE ANYTHING NEEDED AT CLOSING??
* STATISTICS, ETC
*/
protected abstract void endSession();
protected void initializeBGP4Session() throws BGP4Exception {
this.BGP4SessionsInformation.addSession(this.getSessionId(), this);
/**
* Byte array to store the last PCEP message read.
*/
byte[] msg = null;
//First get the input and output stream
try {
out = new DataOutputStream(socket.getOutputStream());
in = new DataInputStream(socket.getInputStream());
} catch (IOException e) {
log.warn("Problem in the sockets, ending BGP4Session");
killSession();
return;
}
//- Starts the ConnectRetryTimer with initial value
int initialValue=1000;//FIXME: no tengo ni idea de este parametro aun
connectRetryTimer= new ConnectRetryTimer(initialValue) ;
//STARTING PCEP SESSION ESTABLISHMENT PHASE
//It begins in Open Wait State
this.setFSMstate(BGP4StateSession.BGP4_STATE_OPEN_WAIT);
log.debug("Entering BGP4_STATE_OPEN_WAIT, Scheduling Open Wait Timer");
//Create the 60 seconds Open Wait Timer to wait for an OPEN message
OpenWaitTimerTask owtt= new OpenWaitTimerTask(this);
this.timer.schedule(owtt, 60000);
//Define (Not use yet), the keepwait timer
KeepWaitTimerTask kwtt=new KeepWaitTimerTask(this);
BGP4Open open_msg=new BGP4Open();
//Rellenar:
// - My autonomous system
// - holdTime
// - BGPIdentifier
open_msg.setMyAutonomousSystem(myAutonomousSystem);
open_msg.setBGPIdentifier(BGPIdentifier);
open_msg.setHoldTime(holdTime);
//Chek optional parameters
BGP4CapabilitiesOptionalParameter cop = new BGP4CapabilitiesOptionalParameter();
open_msg.getParametersList().add(cop);
MultiprotocolExtensionCapabilityAdvertisement multProtExtCapAdv = new MultiprotocolExtensionCapabilityAdvertisement();
multProtExtCapAdv.setAFI(AFICodes.AFI_BGP_LS);
multProtExtCapAdv.setSAFI(SAFICodes.SAFI_BGP_LS);
cop.getCapabilityList().add(multProtExtCapAdv);
BGP4OctetsASByteCapabilityAdvertisement fouroctects = new BGP4OctetsASByteCapabilityAdvertisement();
fouroctects.setAS(myAutonomousSystem);
cop.getCapabilityList().add(fouroctects);
//Send the OPEN message
this.sendBGP4Message(open_msg);
//Now, read messages until we are in SESSION UP
while (this.FSMstate!=BGP4StateSession.BGP4_STATE_SESSION_UP){
//log.info("State session "+this.FSMstate);
try {
//Read a new message
msg = readBGP4Msg(in);
}catch (IOException e){
log.warn("Error reading message, ending session"+e.getMessage());
killSession();
return;
}
if (msg != null) {//If null, it is not a valid PCEP message
//log.info("Read a message");
switch(BGP4Message.getMessageType(msg)) {
case BGP4MessageTypes.MESSAGE_OPEN:
//log.info("OPEN Message Received");
if (this.FSMstate==BGP4StateSession.BGP4_STATE_OPEN_WAIT){
log.debug("FSMstate = BGP4_STATE_OPEN_WAIT");
BGP4Open open_received;
// try {
open_received=new BGP4Open(msg);
log.debug("**** Open received ****\n"+ open_received.toString());//FIXME!!! Cambiar a finest
owtt.cancel();
//Check parameters
if (openRetry==1){
boolean checkOK=true;
this.version = open_received.getVersion();
if (this.version != 4){
checkOK=false;
}
// this.deadTimerPeer=open_received.getDeadTimer();
// this.keepAlivePeer=open_received.getKeepalive();
//
// if (this.deadTimerPeer>maxDeadTimerAccepted){
// checkOK=false;
// }
// if (this.deadTimerPeer==0){
// if(zeroDeadTimerAccepted==false){
// checkOK=false;
// }
// }
// if (this.keepAlivePeer<minimumKeepAliveTimerAccepted){
// checkOK=false;
// }
if (checkOK==false){
log.debug("Dont accept");
// PCEPError perror=new PCEPError();
// PCEPErrorObject perrorObject=new PCEPErrorObject();
// perrorObject.setErrorType(ObjectParameters.ERROR_ESTABLISHMENT);
// perrorObject.setErrorValue(ObjectParameters.ERROR_ESTABLISHMENT_SECOND_OPEN_MESSAGE_UNACCEPTABLE_SESSION_CHARACTERISTICS);
// ErrorConstruct error_c=new ErrorConstruct();
// error_c.getErrorObjList().add(perrorObject);
// perror.setError(error_c);
// log.info("Sending Error and ending PCEPSession");
// sendPCEPMessage(perror);
}
else {
/**
* If no errors are detected, and the session characteristics are
* acceptable to the local system, the system:
o Sends a Keepalive message to the PCEP peer,
o Starts the Keepalive timer,
o Sets the RemoteOK variable to 1.
If LocalOK=1, the system clears the OpenWait timer and moves to the
UP state.
If LocalOK=0, the system clears the OpenWait timer, starts the
KeepWait timer, and moves to the KeepWait state.
*/
this.BGPIdentifier=open_received.getBGPIdentifier();
this.myAutonomousSystem=open_received.getMyAutonomousSystem();
this.holdTime=open_received.getHoldTime();
// if (open_received.getOptionalParameterLength() != 0){
// log.info("Tiene parametros opcionales");
// }
log.debug("OPEN Accepted");
log.debug("Sending KA to confirm");
BGP4Keepalive ka_snd= new BGP4Keepalive();
log.debug("Sending Keepalive message");
sendBGP4Message(ka_snd); //Creates the Keep Wait Timer to wait for a KA to acknowledge the OPEN sent
//FIXME: START KA TIMER!
this.remoteOK=true;
if(this.localOK==true){
log.debug("Entering STATE_SESSION_UP");
this.setFSMstate(BGP4StateSession.BGP4_STATE_SESSION_UP);
}
else {
log.debug("Entering STATE_KEEP_WAIT");
log.debug("Scheduling KeepwaitTimer");
timer.schedule(kwtt, 60000);
this.setFSMstate(BGP4StateSession.BGP4_STATE_KEEP_WAIT);
}
}
}
else {//Open retry is 0
log.debug("Open retry is equal to 0");
boolean dtOK=true;
// boolean kaOK=true;
this.version=open_received.getVersion();
if (this.version != 4){
dtOK=false;
}
if (dtOK==false){
///Parameters are unacceptable but negotiable
log.debug("PEER Open parameters are unaccpetable, but negotiable");
// PCEPError perror=new PCEPError();
// PCEPErrorObject perrorObject=new PCEPErrorObject();
// perrorObject.setErrorType(ObjectParameters.ERROR_ESTABLISHMENT);
// perrorObject.setErrorValue(ObjectParameters.ERROR_ESTABLISHMENT_UNACCEPTABLE_NEGOTIABLE_SESSION_CHARACTERISTICS);
// if (dtOK==false){
// open_received.setDeadTimer(this.deadTimerLocal);
// }
// if (kaOK==false) {
// open_received.setKeepalive(this.keepAliveLocal);
// }
// LinkedList<PCEPErrorObject> perrobjlist=new LinkedList<PCEPErrorObject>();
// perrobjlist.add(perrorObject);
// perror.setErrorObjList(perrobjlist);
// perror.setOpen(open_received.getOpen());
// log.info("Sending Error with new proposal");
// this.sendPCEPMessage(perror);
// this.openRetry=this.openRetry+1;
/**
* o If LocalOK=1, the system restarts the OpenWait timer and stays in
the OpenWait state.
o If LocalOK=0, the system clears the OpenWait timer, starts the
KeepWait timer, and moves to the KeepWait state.
*/
if (localOK==true){
//log.info("Local ok esta a true, vamos a open wait");
owtt.cancel();
owtt= new OpenWaitTimerTask(this);
this.timer.schedule(owtt, 60000);
this.setFSMstate(BGP4StateSession.BGP4_STATE_OPEN_WAIT);
}
else {
//log.info("Local ok esta a false, vamos a keep wait");
owtt.cancel();
this.setFSMstate(BGP4StateSession.BGP4_STATE_KEEP_WAIT);
this.timer.schedule(kwtt, 60000);
}
}
else {
/*
* If no errors are detected, and the session characteristics are
acceptable to the local system, the system:
o Sends a Keepalive message to the PCEP peer,
o Starts the Keepalive timer,
o Sets the RemoteOK variable to 1.
If LocalOK=1, the system clears the OpenWait timer and moves to the
UP state.
If LocalOK=0, the system clears the OpenWait timer, starts the
KeepWait timer, and moves to the KeepWait state.
*/
this.BGPIdentifier=open_received.getBGPIdentifier();
this.myAutonomousSystem=open_received.getMyAutonomousSystem();
this.holdTime=open_received.getHoldTime();
// if (open_received.getOptionalParameterLength() != 0){
// log.info("Tiene parametros opcionales");
// }
//this.BGP4SessionsInformation.addSession(this.getSessionId(), this);
BGP4Keepalive p_ka= new BGP4Keepalive();
//log.info("Sending Keepalive message");
sendBGP4Message(p_ka); //Creates the Keep Wait Timer to wait for a KA to acknowledge the OPEN sent
//FIXME: START KA TIMER!
this.remoteOK=true;
if(this.localOK==true){
//log.info("Entering STATE_SESSION_UP");
//He conseguido establecer sesion. Hay que matar el otro hilo
this.setFSMstate(BGP4StateSession.BGP4_STATE_SESSION_UP);
//La sesion se ha establecido
}
else {
//log.info("Entering STATE_KEEP_WAIT");
//log.fine("Scheduling KeepwaitTimer");
timer.schedule(kwtt, 60000);
this.setFSMstate(BGP4StateSession.BGP4_STATE_KEEP_WAIT);
}
}
}
}
else{
log.debug("Ignore OPEN message, already one received!!");
}
break;
case BGP4MessageTypes.MESSAGE_KEEPALIVE:
//log.info("KeepAlive Message Received");
this.localOK=true;
if(this.FSMstate==BGP4StateSession.BGP4_STATE_KEEP_WAIT){
// If RemoteOK=1, the system clears the KeepWait timer and moves to
// the UP state.
// If RemoteOK=0, the system clears the KeepWait timer, starts the
// OpenWait timer, and moves to the OpenWait State.
if (remoteOK==true){
kwtt.cancel();
//log.info("Entering STATE_SESSION_UP");
this.setFSMstate(BGP4StateSession.BGP4_STATE_SESSION_UP);
}
else{
kwtt.cancel();
//log.info("Entering OPEN WAIT STATE");
owtt=new OpenWaitTimerTask(this);
this.timer.schedule(owtt, 60000);
this.setFSMstate(BGP4StateSession.BGP4_STATE_OPEN_WAIT);
}
}
//If not... seguimos igual que estabamos
//Mas KA no hacen mal...
break;
default:
log.error("UNEXPECTED Message Received");
if (this.FSMstate!=BGP4StateSession.BGP4_STATE_OPEN_WAIT){
log.debug("Ignore OPEN message, already one received!!");
}
else {
log.error("Unexpected message RECEIVED, closing");
}
break;
}
}
else {
if (this.FSMstate!=BGP4StateSession.BGP4_STATE_OPEN_WAIT){
log.info("Ignore message, already one received!!");
}
else {
log.error("Unexpected message RECEIVED, closing");
}
}//Fin del else
}//Fin del WHILE
}
@Override
public void sendBGP4Message(BGP4Message message) {
message.encode();
try {
out.write(message.getBytes());
out.flush();
} catch (Exception e) {
log.error("Problem writing message, finishing session "+e.getMessage());
killSession();
}
}
public Inet4Address getRemotePeerIP() {
return remotePeerIP;
}
public Inet4Address getBGPIdentifier() {
return BGPIdentifier;
}
public void setBGPIdentifier(Inet4Address bGPIdentifier) {
BGPIdentifier = bGPIdentifier;
}
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 int getMyAutonomousSystem() {
return myAutonomousSystem;
}
public void setMyAutonomousSystem(int myAutonomousSystem) {
this.myAutonomousSystem = myAutonomousSystem;
}
public String shortInfo(){
StringBuffer sb=new StringBuffer(1000);
if (this.socket!=null){
sb.append("remAddr: ");
sb.append(this.socket.getRemoteSocketAddress());
sb.append(" state: ");
if (this.FSMstate==BGP4StateSession.BGP4_STATE_OPEN_WAIT){
sb.append("OPEN_WAIT");
}else if (this.FSMstate==BGP4StateSession.BGP4_STATE_IDLE){
sb.append("IDLE");
}else if (this.FSMstate==BGP4StateSession.BGP4_STATE_KEEP_WAIT){
sb.append("KEEP_WAIT");
}else if (this.FSMstate==BGP4StateSession.BGP4_STATE_SESSION_UP){
sb.append("SESSION_UP");
}else if (this.FSMstate==BGP4StateSession.BGP4_STATE_SESSION_UP){
sb.append("TCP_PENDING");
}else {
sb.append("UNKNOWN");
}
}
return sb.toString();
}
public String toString(){
StringBuffer sb=new StringBuffer(1000);
sb.append("\t> Session ID: "+this.sessionId+"\n");
sb.append("\t> BGP Remote Peer: "+this.remotePeerIP+"\n");
sb.append("\t> BGPIdentifier: "+this.BGPIdentifier+"\n");
if (this.socket!=null){
sb.append("\t> remAddr: ");
sb.append(this.socket.getRemoteSocketAddress()+"\n");
sb.append("\t> state: ");
if (this.FSMstate==BGP4StateSession.BGP4_STATE_OPEN_WAIT){
sb.append("OPEN_WAIT\n");
}else if (this.FSMstate==BGP4StateSession.BGP4_STATE_IDLE){
sb.append("IDLE\n");
}else if (this.FSMstate==BGP4StateSession.BGP4_STATE_KEEP_WAIT){
sb.append("KEEP_WAIT\n");
}else if (this.FSMstate==BGP4StateSession.BGP4_STATE_SESSION_UP){
sb.append("SESSION_UP\n");
}else if (this.FSMstate==BGP4StateSession.BGP4_STATE_SESSION_UP){
sb.append("TCP_PENDING\n");
}else {
sb.append("UNKNOWN");
}
}
return sb.toString();
}
public synchronized void newSessionId(){
this.sessionId=GenericBGP4Session.sessionIdCounter+1;
sessionIdCounter=sessionIdCounter+1;
}
public long getSessionId() {
return sessionId;
}
@Override
public void close() {
// TODO Auto-generated method stub
}
@Override
public boolean equals(Object obj) {
if (remotePeerIP != null){
if (this.remotePeerIP.equals(((GenericBGP4Session)obj).getBGPIdentifier())){
return true;
}
}
else {
log.info("TODO NUL!! en el equals!");
}
return false;
}
public Inet4Address getPeerIP(){
return (Inet4Address)this.socket.getInetAddress();
}
}
// Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package eu.teraflow.tid.bgp4Peer.bgp4session;
import es.tid.bgp.bgp4.messages.BGP4Keepalive;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.DataOutputStream;
import java.io.IOException;
public class KeepAliveThread extends Thread {
private int keepAlive = 0;
private boolean running;
private Logger log;
private DataOutputStream out=null; //Use this to send messages to peer
/*
* @param p
* @param k
*/
public KeepAliveThread(DataOutputStream out, int k) {
this.keepAlive = k;
this.out = out;
log=LoggerFactory.getLogger("BGP4Server");
}
/**
* Starts the Keepalive process
*/
public void run() {
running=true;
while (running) {
try {
if (keepAlive > 0) {
sleep(keepAlive * 1000);
sendKeepAlive();
}
else {
log.debug("Ending KEEPALIVE mechanism");
return;
}
} catch (InterruptedException e) {
if (running==false){
log.debug("Ending KeepAliveThread");
return;
}
else {
//Keepalive Timer is reseted
log.debug("Reseting Keepalive timer");
}
}
}
}
/**
* Sets the running variable to false. After this, an interrupt will cause
* the KeepaliveThread to end.
*/
public void stopRunning(){
running=false;
}
/**
* Sends KeepAlive Message. It does not wait for any response.
*/
private void sendKeepAlive() {
BGP4Keepalive p_ka= new BGP4Keepalive();
//try {
p_ka.encode();
// } catch (PCEPProtocolViolationException e1) {
// // TODO Auto-generated catch block
// e1.printStackTrace();
// }
try {
log.debug("Sending Keepalive message");
out.write(p_ka.getBytes());
out.flush();
} catch (IOException e) {
log.warn("Error sending KEEPALIVE: " + e.getMessage());
}
}
}
// Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package eu.teraflow.tid.bgp4Peer.bgp4session;
import java.util.TimerTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* If no Open message is received before the expiration of the OpenWait
timer, the PCEP peer sends a PCErr message with Error-Type=1 and
Error-value=2, the system releases the PCEP resources for the PCEP
peer, closes the TCP connection, and moves to the Idle state.
* @author Oscar Gonzalez de Dios
*
*/
public class KeepWaitTimerTask extends TimerTask {
// private DataOutputStream out=null; //Use this to send messages to peer
private BGP4Session bgp4Session;
private Logger log;
public KeepWaitTimerTask(BGP4Session bgp4Session){
this.bgp4Session=bgp4Session;
log=LoggerFactory.getLogger("PCEServer");
}
public void run() {
log.warn("KEEP WAIT Timer OVER");
// PCEPError perror=new PCEPError();
// PCEPErrorObject perrorObject=new PCEPErrorObject();
// perrorObject.setErrorType(ObjectParameters.ERROR_ESTABLISHMENT);
// perrorObject.setErrorValue(ObjectParameters.ERROR_ESTABLISHMENT_NO_KA_OR_ERROR_KEEPWAIT_TIMER);
// ErrorConstruct error_c=new ErrorConstruct();
// error_c.getErrorObjList().add(perrorObject);
// perror.setError(error_c);
// bgp4Session.sendBGP4Message(perror);
this.bgp4Session.killSession();
return;
}
}