라우터는 컴퓨팅 디바이스와 네트워크를 다른 네트워크에 연결하는 네트워킹 디바이스이다. 경로 설정, 데이터 전달, 로드 밸런싱의 역할을 담당한다. 라우터는 인터넷 계층에 위치한다.
라우팅은 패킷이 출발지에서 목적지까지 가는 경로를 결정하는 과정이다. 라우터는 라우팅 테이블을 사용하여 목적지 IP 주소를 분석하고, 다음으로 이동할 경로를 선택한다. 라우터는 패킷의 목적지 주소와 연결된 네트워크 및 서브넷 정보를 확인하여 어느 인터페이스로 전송할지 결정한다.
포워딩은 라우팅에 의해 선택된 경로를 따라 패킷을 실제로 전달하는 과정이다. 라우터 또는 스위치가 패킷을 수신하여 해당 패킷을 목적지로 전달하는 것을 포워딩이라고 한다. 포워딩은 라우팅 결정에 의해 선택된 경로를 따라 패킷을 전송하는 단계이다. 라우팅 테이블에서 얻은 정보를 기반으로 패킷을 올바른 인터페이스로 보낸다.
const routingTable = {
"192.168.1.0/24": "eth0",
"10.0.0.0/8": "eth1",
// ...
};
function routePacket(destinationIP) {
if (routingTable[destinationIP]) {
return routingTable[destinationIP];
} else {
return "defaultGateway";
}
}
class Router {
constructor() {
this.routingTable = {}; // 현재의 라우팅 테이블
this.neighborTables = {}; // 이웃 라우터의 거리 벡터 테이블
}
updateRoutingTable(neighbor, vector) {
// 거리 벡터 정보를 이용하여 라우팅 테이블 업데이트
for (const destination in vector) {
const newDistance = vector[destination] + 1; // 더미값으로 가정
if (!this.routingTable[destination] || newDistance < this.routingTable[destination].distance) {
this.routingTable[destination] = {
nextHop: neighbor,
distance: newDistance
};
}
}
}
sendVector() {
// 거리 벡터 정보를 이웃 라우터에게 전달하는 로직
for (const neighbor in this.neighborTables) {
const vector = this.routingTable; // 현재 라우팅 테이블을 거리 벡터로 전달
this.neighborTables[neighbor].receiveVector(this, vector);
}
}
receiveVector(neighbor, vector) {
// 이웃 라우터로부터 거리 벡터 정보 수신 및 처리
// 업데이트된 정보를 사용하여 라우팅 테이블 업데이트
this.updateRoutingTable(neighbor, vector);
}
}
// 라우터 인스턴스 생성
const routerA = new Router();
const routerB = new Router();
const routerC = new Router();
// 이웃 라우터 설정
routerA.neighborTables['B'] = routerB;
routerA.neighborTables['C'] = routerC;
routerB.neighborTables['A'] = routerA;
routerB.neighborTables['C'] = routerC;
routerC.neighborTables['A'] = routerA;
routerC.neighborTables['B'] = routerB;
// 라우팅 정보 업데이트 및 전달
routerA.updateRoutingTable('A', { 'X': 1 });
routerA.sendVector();
routerB.updateRoutingTable('B', { 'X': 2 });
routerB.sendVector();
routerC.updateRoutingTable('C', { 'X': 3 });
routerC.sendVector();
console.log(routerA.routingTable); // 업데이트된 라우팅 테이블 출력
그렇다면 라우팅에 쓰이는 알고리즘과 그것을 코드로 구현한 예시를 살펴보자.
function bellmanFord(graph, source) {
const distance = Array(graph.length).fill(Infinity);
const predecessor = Array(graph.length).fill(-1);
// 초기화: 출발 노드의 거리는 0
distance[source] = 0;
// 각 엣지에 대해 |V| - 1번 반복
for (let i = 0; i < graph.length - 1; i++) {
for (let u = 0; u < graph.length; u++) {
for (let v = 0; v < graph[u].length; v++) {
if (distance[u] + graph[u][v].weight < distance[graph[u][v].vertex]) {
distance[graph[u][v].vertex] = distance[u] + graph[u][v].weight;
predecessor[graph[u][v].vertex] = u;
}
}
}
}
// 음의 순환을 체크
for (let u = 0; u < graph.length; u++) {
for (let v = 0; v < graph[u].length; v++) {
if (distance[u] + graph[u][v].weight < distance[graph[u][v].vertex]) {
console.log('그래프에 음의 순환 존재');
return;
}
}
}
return { distance, predecessor };
}
// 그래프 예시
const graph = [
[{ vertex: 1, weight: -1 }, { vertex: 2, weight: 4 }],
[{ vertex: 2, weight: 3 }, { vertex: 3, weight: 2 }, { vertex: 4, weight: 2 }],
[{ vertex: 3, weight: 5 }, { vertex: 1, weight: 1 }],
[{ vertex: 4, weight: -3 }],
[]
];
const result = bellmanFord(graph, 0);
console.log(result.distance); // 최단 거리 출력
function dijkstra(graph, source) {
const distance = Array(graph.length).fill(Infinity);
const visited = Array(graph.length).fill(false);
distance[source] = 0;
for (let i = 0; i < graph.length; i++) {
const u = minDistance(distance, visited);
visited[u] = true;
for (let v = 0; v < graph.length; v++) {
if (!visited[v] && graph[u][v] && distance[u] !== Infinity && distance[u] + graph[u][v] < distance[v]) {
distance[v] = distance[u] + graph[u][v];
}
}
}
return distance;
}
function minDistance(distance, visited) {
let min = Infinity;
let minIndex = -1;
for (let v = 0; v < distance.length; v++) {
if (visited[v] === false && distance[v] <= min) {
min = distance[v];
minIndex = v;
}
}
return minIndex;
}
// 그래프 예시 (2차원 배열로 표현된 인접 행렬)
const graph = [
[0, 10, 0, 30, 100],
[10, 0, 50, 0, 0],
[0, 50, 0, 20, 10],
[30, 0, 20, 0, 60],
[100, 0, 10, 60, 0]
];
const result = dijkstra(graph, 0);
console.log(result); // 소스 노드로부터의 최단 거리 출력
포워딩 테이블은 라우터나 스위치에서 데이터 패킷을 전달할 때 사용되는 정보를 담고 있는 테이블이다. 이 테이블은 목적지 IP 주소를 기반으로 패킷을 적절한 출력 포트로 전달하는 역할을 한다. 포워딩 테이블은 네트워크 장비의 전반적인 동작에 중요한 영향을 미치며, 다양한 정보를 포함하고 있다. 포워딩 테이블의 주요 구조 및 정보는 다음과 같다.
목적지 IP 주소 (Destination IP Address)
포워딩 테이블의 핵심 정보로, 패킷의 목적지 IP 주소가 여기에 기록된다.
출력 포트 (Outgoing Port)
목적지 IP 주소에 대응하는 패킷을 어느 출력 포트로 보낼지를 결정한다.
라우터나 스위치는 목적지 IP 주소를 검색하여 해당하는 출력 포트를 찾아 전달한다.
넥스트 홉 (Next Hop)
목적지 IP 주소로 패킷을 전달할 때, 다음으로 이동해야 할 넥스트 홉의 IP 주소가 여기에 기록된다.
주로 다음에 연결되어 있는 라우터의 IP 주소가 넥스트 홉으로 사용된다.
인터페이스 (Interface)
패킷을 목적지로 전달할 때 사용되는 네트워크 인터페이스가 여기에 기록된다. 라우터나 스위치는 해당 인터페이스를 통해 출력 포트로 패킷을 보낸다. 포워딩 테이블은 주로 라우터나 스위치의 하드웨어에 저장되며, 데이터 패킷의 전달 과정에서 빠르게 접근하여 패킷을 적절한 방향으로 전달하는 데 사용된다. 이 테이블은 라우팅 테이블과는 다르게 목적지 IP 주소에 대한 직접적인 포워딩 정보를 가지고 있어서 전송 속도를 향상시키고 네트워크의 성능을 향상시킨다.