SW 사관학교 정글(Jungle)/컴퓨터 시스템(CSAPP)

[CSAPP] 11.3 글로벌 IP 인터넷

jinsang-2 2024. 9. 16. 16:51

https://jinsang-2.tistory.com/84

 

[CSAPP] 11.2 네트워크

💡호스트에게 네트워크는 단지 또 다른 I/O 디바이스이다 !그림처럼 데이터를 위한 소스와 싱크로 서비스한다. I/O 버스의 확장 슬롯에 꽃혀 있는 어댑터는 네트워크에 물리적인 인터페이스를

jinsang-2.tistory.com

 

글로벌 IP 인터넷은 11.2에서 봤듯이 LAN과 WAN과 라우터를 통해 internet을 성공적으로 구현한 것이다.

인터넷 응용의 하드웨어 및 소프트웨어 구성

각 인터넷 호스트는 `TCP/IP` 프로토콜을 구현한 소프트웨어를 실행한다. 인터넷 클라이언트와 서버는 `소켓 인터페이스`와 `Unix I/O 함수`들의 혼합을 사용해서 통신한다. 소켓 함수들은 일반적으로 `시스템 콜`들로 구현되며 이 시스템 콜은 커널에서 트랩을 발생시키며, TCP/IP에서 다양한 커널 모드 함수들을 호출한다.

💡TCP/IP

TCP와 IP는 실제로는 프로토콜의 집합으로 각각 서로 다른 기능을 제공한다.

  • IP는 기본 명명법과 데이터그램이라 하는 `패킷`을 한 인터넷 호스트에서 다른 호스트로 보낼 수 있는 배달 매커니즘을 제공한다.
    • IP 매커니즘은 만일 데이터그램을 잃어버리거나 네트워크 내에서 중보되는 경우에 복구하려고 노력하지 않는다는 점에서 안정적이지 못하다.
  • TCP는 IP위에 구현한 프로토콜로 프로세스들 간에 안전한 `완전 양방향 연결`을 제공

💡IP 주소

IP 주소는 비부호형 32비트 정수이다. 네트워크 프로그램은 IP 주소를 위 그림 코드와 같이 IP 주소 구조체에 저장한다.

인터넷 호스트들이 서로 다른 호스트 바이트순서를 가질 수 있다.

TCP/IP는 네트워크 패킷 헤더에 포함되는 IP 주소 같은 모든 정수형 데이터 아이템에 대해서 통일된 네트워크 바이트 순서를 빅 엔디안 바이트 순서로 정의한다. IP 주소 구조체의 주소는 호스트 바이트 순서가 리틀 엔디안인 경우에도 항상 네트워크 바이트 순서인 빅 엔디안 방식으로 저장된다.

image

바이트 순서에는 아래 그림과 같이빅 엔디안 바이트 순서와 리틀 엔디안이 있다.

  • 순서 그대로 = Big endian
  • 순서 뒤바꿈 = Little endia
  • ▶ Unix 네트워크와 호스트 바이트 순서 간의 변환을 위한 함수

  • htonl 함수는 비부호형 32비트 정수를 호스트 바이트 순서 ➡️ 네트워크 바이트 순서로 변환
  • ntohl 함수는 비부호형 32비트 정수를 네트워크 바이트 순서 ➡️ 호스트 바이트 순서로 변환
  • htons 와 ntohs 함수는 비부호형 16비트 정수에 대해서 대응하는 변환을 수행한다.
    • 64비트 값들을 다루기 위한 동일한 함수가 없다는 점을 유의

IP 주소는 대게 사람들에게 `dotted-decimal` 표기라고 하는 형식으로 제시되며, 이것은 각 바이트가 십진수 값을 사용하고 다른 바이트들과는 점을 사용해서 구분된다.

  • 128.2.194.242 는 주소 0x8002c2f2의 dotted-decimal 표현

응용 프로그램들은 IP 주소와 dotted-decimal 스트링 사이를 inet_pton과 inet_ntop을 사용해서 상호 변환한다.

  • 함수 이름에서 "n"은 network를 의미하고 "p"는 presentation을 의미한다. "to"는 ~로를 의미
  • 32비트 IPv4 주소 (AF_INET) 이나 128비트 IPv6주소(AF_INET6)을 처리할 수 있다.
  • inet_pton 함수는 dotted-decimal 스트링(src)을 네트워크 바이트 순서를 갖는 이진 IP 주소(dst)로 변환한다
  • src가 유효한 점-십진수 스트링을 가리키지 않는다면, 이 함수는 0을 리턴한다.
  • 다른 모든 에러의 경우에는 -1을 리턴하고 errno를 설정한다.
  • inet_ntop 함수는 네트워크 바이트 순서를 갖는 이진 IP 주소를 이에 대응하는 dotted-decimal 스트링으로 변환하고 널로 끝나는 결과 스트링의 최대 size 바이트를 dst로 복사한다.

연습문제 11.1

주소 변환을 이해하고 있는지에 대한 문제이다. 10진수를 16진수로, 16진수를 10진수로 변환하는 문제로 이해하면 된다.

ex) 107.212.122.205 = 0x6BD47ACD

연습문제 11.2

문제 : 16비트 네트워크 바이트 오더를 16진수로 변환하고 그 결과를 출력하는 dd2hex.c 프로그램을 작성하시오.

ex)

linux> ./dd2hex 1024

0x400

#include "csapp.h"

int main(int argc, char **argv)
{
    struct in_addr inaddr;
    uint16_t addr;
    char buf[MAXBUF];
    
//사용자가 숫자를 입력했는지 확인하는 부분. 만약 숫자를 입력하지 않았으면 오류 메시지를 출력
    if(argc != 2){
        fprintf(stderr, "usage: %s <hex number>\n", argv[0]);
        exit(0);
    }
    
    //사용자가 입력한 값을 16진수로 읽어서 addr 변수에 저장
    sscanf(argv[1], "%x", &addr);
    // 숫자를 네트워크 방식(빅 엔디언)으로 변환
    inaddr.s_addr = htons(addr);
	
    // 숫자를 문자열 변환
    if (!inet_ntop(AF_INET, &inaddr, buf, MAXBUF))
        unix_error("inet_ntop");
       printf("%s\n",buf);
    exit(0);
}
  • `argc` 는 명령어 인수의 개수를 나타내고, `argv`는 명령어 인수들의 배열이다. 
  • `struct in_addr` : ip 주소를 저장하는 구조체, 여기서는 변환된 값을 저장하기 위해 사용된다.
  • `uint16_t addr` : 사용자가 입력한 16비트 값을 저장하기 위한 변수
  • `char buf[MAXBUF] : 변환된 값을 문자열 형태로 저장하기 위한 버퍼

 

💡인터넷 도메인 이름(Internet Domain Name)

인터넷 클라이언트와 서버는 서로 통신할 때 IP 주소를 사용한다. 크기가 큰 정수는 사람들이 기억하기 어려워 인터넷에서는 `도메인 이름들의 집합`을 `IP 주소 집합`으로 `매핑`하는 매커니즘과 함 께 사람들에게 친숙한 별도의 도메인 이름 집합을 정의한다.

 

인터넷 도메인 이름 계층구조의 일부

  • 도메인 이름들의 집합은 계층 구조를 형성하고 있다. 계층구조는 트리로 나타냄
  • 각각의 도메인 일므은 계층 구조에서 자신의 위치를 인코드한다. 
  • 트리의 노드들은 루트로 돌아가는 경로로 형성되는 도메인 이름을 나타냄
  • 서브트리는 서브 도메인이라고도 한다.

도메인 계층별 설명

  • 계층구조의 루트 노드는 `이름이 없는 루트노드`이다.
  • 다음 계층은 ICANN이라 하는 비영리조직이 정의한 1단계 도메인 이름의 집합이다. 
    • com, edu, gov, org, and net 이 포함
  • 다음 계층에는 2단계 도메인 이름인 cmu.edu가 포함되며, 이들은 수많은 ICANN이 인정하는 대행사가 요청한 순서에 의해 그 이름이 할당된다. 일단 한 조직이 2단계 도메인 이름을 받은 후에는 cs.cmu.edu와 같이 서브도메인 내에서는 어떤 새로운 이름도 자유롭게 생성 가능하다.

DNS(Domain Name System)

  • 인터넷은 도메인 이름의 집합과 IP 주소 집합 사이에 매핑을 정의함.
    • 1988년까지 이 매핑은 한 개의 텍스트 파일 HOSTS.TXT로 수동 관리 되었다고 한다.
  • 이후 DNS라 하는 전 세계에 분산된 데이터베이스에 의해 관리되어 왔다.
  • DNS 데이터베이스는 수백만 개의 호스트 엔트리로 구성되어 있으며, 이들 각각은 도메인 이름의 집합과 IP 주소 집합 사이의 매핑을 정의한다.
  • 리눅스 NSLOOKUP프로그램으로 DNS 매핑의 일부 특성들을 조사할 수 있다. 
  • 각 인터넷 호스트는 지역적으로 정의된 도메인 이름 localhost를 가지고 있으며, 이것은 항상 루프백 주소 127.0.0.1에 매핑된다. 

 

💡인터넷 연결

 

클라이언트와 서버는 `연결`을 통해 바이트 스트림을 주고받는 방식으로 통신한다. 

두개의 프로세스를 연결한다는 점에서 `point-to-point` 연결이다. 데이터가 동시에 양방향으로 흐를 수 있기에 `완전양방향`이다.

 

소켓(socket)

  • 연결의 종단점이다. 
  • 각 소켓은 인터넷 주소와 16비트 정수 포트로 이루어진 소켓 주소를 가진다.
    • address : port 로 나타낸다.
  • 클라이언트의 소켓 주소 내의 포트는 클라이언트가 연결 요청을 할 때 커널이 자동으로 할당한다 = 단기 포트
  • http(웹 서버) : 80 포트 , smtp(메일 서버) : 25포트
    • 이름과 포트들 간의 매핑은 /etc/services 파일에 보관
  • 연결은 두 개의 종단점의 소켓 주소에 의해 유일하게 식별된다. 이 두개의 소켓 주소는 소켓 쌍이라고 알려져 있고 tuple로 나타냄
    • (cliaddr : cliport, servaddr : servport)
    • cliaddr은 클라이언트 IP 주소이고 cliport는 클라이언트의 포트, servaddr은 서버의 IP 주소, servport는 서버의 포트다.

  • 128.2.194.242:51213
    • 위에 51213은 커널이 할당한 단기 포트