1. network 계층의 forwarding

- network 계층에서는 transport 계층에서 전달받은 세그먼트를 패킷에 담아 이를 다른 네트워크 장치로 보내 최종적으로 그 세그먼트의 목적 네트워크 장치로 보내게 된다.

- network 계층에서는 forwarding table이 구현돼 있어(이 구현은 별도의 알고리즘을 통해 이루어진다), 수신한 패킷의 목적지(IP 주소)를 forwarding table에서 참조하여 forwarding table에 쓰인 그 패킷이 보내져야 할 알맞은 link 인터페이스로 그 패킷을 보내게 된다.

- 모든 IP 주소마다 개별적으로 그에 해당하는 link 번호를 저장해 두면 forwarding table이 매우 커지게 되므로 forwarding table은 그렇게 구현되어 있지는 않고, ‘IP 주소가 이 범위에 해당되면 (이러한 prefix를 가지면) x번 link로 보낸다’ 라는 식으로 구현되어 있다.

- 구체적으로, forwarding table의 각 항목은 키값으로 그에 해당하는 IP 주소의 prefix가 저장돼 있어, 현재 라우터가 수신한 패킷의 dest IP 주소가 어떤 항목의 prefix와 일치하는지를 찾아 그에 해당하는 link 번호로 그 패킷을 보내게 된다. 이때, 예를 들어 어떤 항목의 prefix는 0101이고 어떤 항목의 prefix는 010100인데 라우터가 수신한 패킷의 dest IP 주소가 01010001이라면 어떤 prefix의 link 인터페이스를 선택해야 할지 문제가 된다. 일반적으로는 일치하는 길이가 더 긴 prefix를 선택한다(longest prefix matching).

2. 패킷의 헤더

- 패킷의 헤더에는 다음과 같은 필드가 있다.

  • IP version: 현재 사용되는 IP의 버전은 4이다.

  • source IP 주소

  • destination IP 주소

  • time to live: 패킷이 네트워크 망 위에 무한루프를 도는 것을 방지하기 위해, IP를 지나가는 모든 패킷에는 ‘그 패킷이 지나칠 수 있는 라우터 개수’가 할당된다. 예를 들어 time to live가 15로 설정된 패킷은 라우터를 15개 지나가면 사라진다. 이때, 라우터는 그 패킷이 사라졌음을 알리는 패킷을 그 패킷의 센더를 향해 송신한다. (이때 사용되는 프로토콜을 ICMP, internet control message protocol이라 한다.)

  • upper layer: 그 패킷에 담긴 세그먼트가 TCP인지 UDP인지를 나타내며, 이 패킷을 수신한 리시버는 이 필드를 참조하여 패킷을 TCP에 올릴지 UDP에 올릴지를 결정한다.

- 한 패킷에서 헤더가 차지하는 부분은 20B로 정해져 있고, 세그먼트의 헤더가 차지하는 부분은 20B로 정해져 있다. 따라서 패킷 하나가 갖는 오버헤드의 크기는 40B이다. 인터넷 망을 오가는 상당수 패킷이 크기가 40B인데, 이는 그 패킷이 ACK 메시지를 담고 있는 패킷이기 때문이다.

3. IP 주소

1) 개요

IPv4 IP 주소는 총 32비트로, 약 40억 개의 서로 다른 주소를 표현할 수 있다. (보통 8비트씩 끊어 10진수 숫자 네 개로 IP 주소를 표현한다.) 네트워크에 연결된 호스트와 라우터는 하나 이상의 네트워크 인터페이스 장비를 갖고 있으며, 각 네트워크 인터페이스 장비는 각자 고유의 IP 주소를 갖는다. (즉, 라우터 하나는 여러 개의 IP 주소를 가질 수 있다. 이처럼 여러 개의 IP 주소를 갖는 라우터를 두고 ‘여러 서브넷에 걸쳐있다’라고 한다.)

2) 계층화

네트워크 상의 각 호스트가 갖는 IP 주소를 호스트 사이 관계에 전혀 무관하게 무작위적으로 할당할 수 있으나, 그런 식으로 IP 주소를 할당하면 forwarding table을 효율적으로 사용하기 위한 규칙을 만들 수 없어 forwarding table이 매우 커지게 된다. 따라서 보통 IP 주소를 계층화하여, IP 주소의 앞 몇자리는 서브넷의 ID로 할당하고 나머지 자리는 그 서브넷 내 호스트들의 ID로 할당한다.

(1) classfull network

- 초기 인터넷은 서브넷 ID의 자릿수를 고정해서 사용하였으며(classful network) 최초에 서브넷 ID에 할당된 자릿수는 8자리였다. 독립된 서브넷을 최대 254개까지만 지원했으나 한 서브넷이 가질 수 있는 호스트는 최대 약 1600만 개까지 지원되어 하나의 서브넷이 갖는 호스트의 크기가 매우 커질 것을 고려한 할당 방식이었다. 이후 인터넷이 팽창하여 인터넷이 갖는 서브넷 개수가 늘어나게 되면서, 서브넷 ID에 할당되는 자릿수를 점차 늘려나가게 되었다. 각 서브넷마다 호스트 ID에 할당해야 하는 비트수가 다를 수 있으므로 이를 달리하는 클래스 3개(A, B, C)를 따로 두었다.

  • class A: 32비트 중 7비트를 서브넷 ID에 할당하는 방식이다. class A임을 나타내는 비트를 추가로 하나 더 할당하여, IP 주소가 0으로 시작하는 IP 주소를 class A IP 주소로 보았다.

  • class B: 32비트 중 14비트를 서브넷 ID에 할당하고, class B임을 나타내는 비트를 추가로 두 개 더 할당한다. IP 주소가 10으로 시작하는 IP 주소는 class B IP 주소로 본다.

  • class C: 32비트 중 22비트를 서브넷 ID에 할당하고, class C임을 나타내는 비트를 추가로 두 개 더 할당한다. IP 주소가 11로 시작하는 IP 주소는 class C IP 주소로 본다.

(2) CIDR(classless inter-domain routing)

- classful network 방식을 사용하던 중 class C을 사용할 수 없는 서브넷이 너무 많아져서 class B 서브넷이 고갈되게 되었고, 이에 따라 서브넷 ID의 자릿수를 고정하지 않는 방식이 등장하게 되었다(이를 CIDR이라 한다). CIDR 방식은 IP 주소 정보를 전송할 때 그와 함께 어디까지가 서브넷의 ID이고 어디서부터 호스트의 ID인지를 알려주는 정보(서브넷 마스크)를 함께 전송한다. (서브넷 마스크는 보통 서브넷 ID로 할당된 부분을 1로, 호스트 ID로 할당된 부분을 0으로 표현한 IP 주소로 표현된다. 한편, IP 주소 뒤에 /를 쓰고 그 뒤에 서브넷 ID의 자릿수를 적는 경우도 있다. 예를 들어, IP 주소가 192.168.0.1이고 서브넷 마스크가 255.255.255.0이라면 이를 192.168.0.1/24로 표현할 수도 있다.)

3) NAT(network access translation)

- NAT 기술을 사용한 라우터(NAT 게이트웨이)에 연결된 호스트들은 같은 게이트웨이에 연결된 다른 호스트와 동일한 IP 주소를 갖고 인터넷 통신을 할 수 있다. NAT 게이트웨이에 연결된 호스트들은 대외적으로는 NAT 게이트웨이의 IP 주소를 갖는 것으로 간주되며, 대내적으로는 각자 다른 IP 주소를 갖는 것으로 취급된다. 대내적/대외적 IP 주소가 NAT 게이트웨이를 거치며 대외적/대내적 IP 주소로 번역되는 것이다. (각 호스트는 포트 번호로 구분한다.)

- NAT 기술을 사용하면 (1)보안상으로 이점이 있고 (2)IP 주소에만 128비트를 사용하는 IPv6를 사용하지 않고도 인터넷 통신을 할 수 있어 IP 패킷의 오버헤드를 줄이면서 IPv4에 허용되는 호스트 수보다 더 많은 호스트로 인터넷을 사용할 수 있다는 장점이 있다. 그러나 (1)network 계층에 해당하는 패킷의 헤더까지만 통제해야 할 라우터가 패킷에 적힌 IP 주소를 번역하기 위해 세그먼트의 헤더를 변경하는 일이 발생하는 것을 감수해야 한다. (이를 layer violation이라 한다.) 또, (2)프로세스를 구분하기 위해 사용해야 할 포트 번호를 호스트를 구분하는 데 사용하게 되어 어떤 호스트의 어떤 프로세스를 찾아가야 하는지 알 수 없는 경우가 발생할 수도 있다.

- NAT 기술은 application 계층에서 구현되므로, NAT 기능이 있는 라우터는 사실 라우터보다는 하나의 작은 컴퓨터에 더 가깝다.

4. DHCP(dynamic host configuration protocol)

- 게이트웨이에 연결된 적 있는 모든 호스트가 각각 고정된 IP 주소를 갖고 있다면 그 호스트들은 언제든 별도 절차 없이 바로 그 IP 주소를 통해 인터넷 망에 연결될 수 있을 것이나, 그 서브넷이 가질 수 있는 호스트 ID의 개수가 너무 적어 모든 호스트에게 고정된 IP 주소를 할당할 수 없는 경우도 있다. 모든 호스트가 인터넷 망을 당장 사용하고 있지 않은데 고정 IP 주소를 모두 할당해두는 것은 과도한 낭비이므로, 당장 인터넷 통신을 하고자 하는 호스트들에 한해 그때마다 IP 주소를 동적으로 할당하도록 하는 방법(DHCP)이 있다.

- DHCP 방식으로 IP 주소를 할당하는 경우 그 서브넷에 접속한 호스트에게 IP 주소를 할당해 주는 DHCP 서버가 있다. 그런데 이제 막 서브넷에 접속한 호스트는 어떤 IP 주소에 DHCP 서버가 있는지 알 수 없으므로, 서브넷에 속한 모든 호스트의 IP 주소를 향해 IP 주소 할당을 요청하는 패킷을 전송(브로드캐스트)한다. (이 단계를 discover 단계라 한다.) 이때 보통 DHCP 서버만 개방하고 있는 포트 번호가 있기 때문에, 그 포트 번호를 향해 브로드캐스트를 하면 그 포트 번호가 개방돼 있는 경우에만 그 패킷이 그 호스트(DHCP 서버)에 전달되고 그 외 경우에는 패킷이 소멸한다.

(1) discover 단계

  • 브로드캐스트 할 때 자신을 식별할 수 있는 ID(transaction ID)와 브로드캐스트를 수행하는 프로세스의 포트 번호를 함께 패킷에 담아 전송한다. 이때 패킷에 담기는 transaction ID는 이를 수신한 DHCP 서버가 그 호스트를 찾기 위해 사용하는 식별자가 되기도 한다.

  • DHCP를 통한 일련의 IP 할당에서 전송되는 모든 패킷은 UDP 세그먼트에 담기며, 이 단계의 패킷 또한 마찬가지다.

(2) offer 단계

  • 패킷을 받은 DHCP 서버가 그 호스트에 할당할 IP 주소를 지정하여 서브넷에 브로드캐스트 한다. (그 호스트는 서브넷에 연결은 돼있어도 IP 주소는 지정돼 있지 않아 그 호스트만을 향해 패킷을 전송할 방법이 없어, DHCP 서버도 그 호스트를 찾기 위해 브로드캐스트를 할 수밖에 없다.)

(3) request 단계

  • 서브넷에 DHCP 서버는 둘 이상 있을 수 있기 때문에, DHCP 서버가 offer 패킷을 브로드캐스트 할 때 IP 주소 할당이 확정되는 것은 아니며 호스트는 여러 개의 offer 패킷을 보고 거기서 하나를 골라 자신의 IP 주소를 선택할 수 있다. 선택을 했다면 호스트는 그 IP 주소를 할당해준 DHCP 서버를 향해 IP 주소를 선택했음을 뜻하는 패킷을 전송한다.

(4) ACK 단계

  • 호스트로부터 request 패킷을 수신한 DHCP 서버는 IP 주소 할당을 확정하고 ACK 패킷을 그 호스트에게 전송한다.

5. IP fragmentation

- IP 패킷이 link 계층을 통해 전송되기 위해서는 패킷의 크기가 일정 크기보다 작아야 한다. 최대 패킷 크기 단위를 MTU(maximum transfer unit)이라 하며, 전송 매체마다 MTU의 크기가 달라진다. 보내고자 하는 세그먼트 길이가 MTU보다 크다면 network 계층에서는 그 세그먼트를 여러 개의 패킷으로 나누어(fragmentation) 나뉜 패킷을 전송하며, 나뉜 패킷들을 수신한 리시버는 이들을 하나의 세그먼트로 다시 조립하여(reassembly) transport 계층으로 보낸다.

- IP fragmentation을 구현하기 위해 IP 패킷의 헤더에는 다음과 같은 필드가 존재한다.

  • fragflag: 그 패킷이 fragmentation이 이뤄진 패킷이라면 1이 저장된다.

  • offset: 그 패킷이 fragmentation이 이뤄진 패킷일 때, 그 패킷의 첫 번째 자릿수가 원래 세그먼트에서는 몇 번째 자릿수였는지를 나타내는 값이 저장된다. offset값을 아주 정확하게 적을 경우 이를 위한 오버헤드가 지나치게 커질 우려가 있으므로, 보통은 정확한 offset값을 8로 나눈 값을 패킷의 헤더에 담는다.

  • identifier: 같은 세그먼트를 쪼갠 패킷들은 identifier 값이 동일하다. fragflag 값이 1일 때 리시버는 fragflag 값이 1인 패킷들 중 identifier가 동일한 패킷들을 모아 조립하여 transport 계층으로 보낸다.

6. routing algorithm

- 모든 라우터와 호스트들의 연결상태를 알고 있다면, 이를 그래프로 그린 후 다익스트라 알고리즘을 통해 센더에서 리시버로 가는 경로를 구할 수 있다.

- link state 알고리즘은 네트워크의 모든 연결상태를 알아야 사용할 수 있으므로, 네트워크 상의 모든 호스트와 라우터들이 각자 자신과 인접한 라우터/호스트의 연결상태를 브로드캐스트로 네트워크 내 모든 라우터/호스트에게 알려주어야 그때 비로소 link state 알고리즘을 사용할 수 있다. 인터넷의 모든 라우터/호스트가 link state 알고리즘을 위하여 자신의 연결상태를 브로드캐스트하는 것은 지나친 자원 낭비가 될 수 있으므로 그 정도 규모에서는 사용하기 어려운 알고리즘이나, 라우터/호스트가 수백 대 정도 되는 규모에서는 사용하기 용이한 알고리즘이다.

2) distance vector 알고리즘

- 네트워크 상의 모든 호스트/라우터(정점) 사이 최단거리를 vector(배열과 유사한 자료구조)로 표현할 때(이를 distance vector라 하자) 네트워크 상의 모든 호스트/라우터는 각자 자신만의 distance vector를 갖는다. 이 distance vector를 기호로 표현하여, 네트워크 상의 임의의 정점 x에서 또 다른 임의의 정점 z까지 최단거리를 \(d_x (z)\)라 하고 정점 x에서 인접한 정점 y로 이동할 때 비용을 \(c_x (y)\)라 할 때, \(d_x (z)\) = min { \(c_x (y)\) + \(d_y (z)\) } 라는 식을 쓸 수 있다. (이 식을 Bellman-Ford equation이라 한다.)

- 호스트/라우터 사이 아무런 정보 교환이 없었고 각 호스트/라우터는 자신과 인접한 호스트/라우터까지의 전송 시간만을 알고 있다고 할 때, 각 호스트/라우터는 자신이 가지고 있는 distance vector를 인접한 라우터로 전송한 후 이를 전송받은 호스트/라우터는 BF eq를 통해 자신이 갖고 있는 distance vector에서 정보가 없던 숫자를 채워나갈 수 있다. distance vector 알고리즘은 이처럼 네트워크 상의 각 호스트/라우터가 서로 distance vector를 전송하여 BF eq로 distnace vector 상의 채워지지 않은 숫자를 채워나가 목표하는 호스트/라우터까지의 최단거리를 알게 되는 알고리즘이다.

- 만약 어느 한 간선의 비용이 종전보다 증가하거나 감소하거나 간선이 아예 끊기거나 하는 등의 변화가 발생할 경우, 이 정보는 그에 인접한 호스트/라우터가 갖고 있던 distance vector의 값에 반영되어 그 distance vector가 차례대로 네트워크 상의 모든 호스트/라우터에 전달됨으로써 각 호스트/라우터의 distance vector에 반영되게 된다.

  • 그런데 각 호스트/라우터가 갖고 있던 distance vector의 어떤 값들은 주변에서 distance vector를 전달받아 이를 반영하여 계산을 다시 한 뒤에도 변화 이전의 정보를 아직 갖고 있는 경우가 있다. 예를 들어 A-B-C 세 정점이 서로 연결돼 있는 그래프가 있고 이 그래프는 C에서 B로 가는 경로가 직접 이동하는 비용(50)보다 A를 거쳐 가는 비용(1+1)이 더 적은 그래프라고 하자. 그렇다면 A와 B는 ‘C에서 B로 갈 때 최소비용은 2’라는 정보를 가지고 있다. 그런데 여기서 만약 A에서 B로 이동하는 간선이 끊어진다면, A가 갖고 있는 distance vector에서 A에서 B로 이동하는 최소비용은 51이 아니라 3으로 업데이트 되게 된다. A에에서 B로 이동하는 간선이 끊어졌으므로 1이라는 값이 지워지게는 되었지만, 그것만으로 C에서 B로 가는 최소비용이 2라는 정보까지 같이 지워지는 것은 아니기 때문이다. 더 큰 문제는, distance vector를 갱신한 후 다른 정점으로 distance vector를 보내는 작업을 무한히 반복하게 된다는 점이다. (distance vector를 받을 때마다 이 값이 어느 한 점에서 멈추는 게 아니라 계속 증가하기 때문이다.) 이 문제를 count-to-infinity 문제라 한다.

  • A가 B, C로부터 distance vector를 받을 때 거기 있는 정보 중에 자신을 경유하여 만들어진 최소비용이 있다면 그 최소비용을 무한대로 보고 자신을 경유하지 않은 정보들만으로 자신의 distance vector를 갱신하게 함으로써 이 문제를 해결할 수 있다. (이를 poisoned reserve라 한다.)

- distance vector 알고리즘은 link state 알고리즘과 같은 브로드캐스트 문제는 발생하지 않으나, 대신 각 호스트/라우터가 갖고 있는 distance vector의 크기가 네트워크 상의 호스트/라우터의 개수의 제곱에 비례해 커진다는 점에서 link state 알고리즘 못지않게 네트워크 자원 낭비가 있을 수 있다.

3) inter-AS

- 특정 관리자의 관할 안에 있는 네트워크를 AS(autonomous system)라 하며, 전세계에는 이러한 AS가 6만여개 정도 있다. AS들도 각자 규모가 다 다르고, AS끼리는 서로 수직적 관계가 있을 수도 있고 수평적 관계가 있을 수도 있다.

- AS 안에서는 link state 또는 distance vector 알고리즘을 쓸 수 있으나, AS끼리 데이터 통신을 할 때는 이들 알고리즘을 쓰지 않는다. 관리 주체가 서로 다른 경우에는 데이터 통신을 빠르게 하는 것보다 더 고려할 문제가 많기 때문이다. 예를 들어 한 AS에서 다른 AS로 데이터를 전송할 수 있는 경로가 여럿 있더라도, AS의 정책에 따라 최단경로가 아니라 최대 수익을 얻을 수 있는 경로를 선택하여 데이터를 전송하는 경우가 있다. 또는, 정보 보안의 측면에서 신뢰할 수 없는 AS를 최대한 회피하여 데이터 전송 경로를 선택하는 경우를 생각할 수 있다. 이러한 기능을 지원하도록 구현된 프로토콜이 BGP(border gateway protocol)이다.