4 Way handshake 종료 과정에서 클라이언트가 FIN 패킷을 전송한 후, 상대방의 ACK를 받은 뒤 일정 시간
동안 유지 되는 상태를 말한다.

 

📌 이유

마지막 ACK 패킷이 손실될 가능성이 있기 때문에 재전송을 대비해 일정 시간 동안 종료하지 않고 머문다.

네트워크에 남아있는 패킷( 지연된 패킷 )으로 인해 문제가 발생할 수 있기 때문에 대기한다.

  • 앞서 말한 문제란, 이전 연결에서 남아 있는 패킷이 새로운 연결에 영향을 미칠 수 있는 것을 말한다.

 

✅ TIME_WAIT 기본 조건

  • 일반적으로 2 * MSL 동안 유지 된다.
  • MSL은 한 패킷이 네트워크에서 생존할 수 있는 최대 시간을 말한다. ( 보통 30초에서 최대 2분 )
  • 즉, TIME_WAIT 상태는 1 ~ 4분 정도 유지 된다.

 

TIME_WAIT 상태가 많아지면, 서버의 포트가 빠르게 소진되어 새로운 연결을 맺기 어려울 수 있다.

이를 해결하기 위한 방법은 아래와 같다.

 

  1. 소켓 옵션 조정
    • SO_REUSEADDR 옵션 사용
      • 동일한 포트를 재사용할 수 있도록 허용하는 옵션이다.
      • 단, 이는 TIME_WAIT 상태를 없애는 것이 아니고, 해당 포트를 다른 프로세스가 빠르게 재사용 할 수 있도록 해준다.
  2. TcpTimeWaitDelay 값 줄이기
    • TcpTimeWaitDelay는 TIME_WAIT 상태를 유지하는 시간을 설정하는 레지스트리 값이다. 기본값은 240초 이지만, 이를 30초 정도로 줄여주면 포트가 빨리 해제된다.
4 Way Handshake는 TCP 연결 종료 과정에서 사용되는 절차를 말한다.
TCP 연결을 종료할 때 양쪽이 각각 연결 종료를 확인해야 하기 때문에 4단계 절차가 필요하다.

 

📌 4 Way Handshake 과정

 (1) FIN -> 연결 종료 요청 ( Client -> Server )

  • 클라이언트가 더 이상 데이터를 보낼 필요가 없으면 FIN 플래그를 설정하여 서버에게 보낸다.
  • 클라는 더 이상 데이터를 보내지 않고, 서버의 응답을 기다리고 있는 상태

(2) ACK -> 종료 요청 확인 ( Server -> Client )

  • 서버는 클라이언트의 FIN을 받았다는 것을 확인한 후 ACK(응답) 패킷을 보낸다.
  • 아직 서버는 데이터를 더 보낼 수 있는 상태

(3) FIN -> 서버도 연결 종료 요청 ( Server -> Client )

  • 서버도 모든 데이터를 보낸 후, 클라이언트에게 FIN 패킷을 보내면서 연결 종료 요청을 한다.
  • 이제 서버도 더 이상 데이터를 보낼 필요가 없으므로 종료 절차를 시작한다.

(4) ACK -> 연결 종료 확인 ( Client -> Server )

  • 클라이언트는 서버의 FIN 패킷을 받으면 ACK(확인 응답)을 보낸다.
  • 이제 연결이 완전히 종료되고, 서버와 클라 모두 더 이상 데이터 전송을 하지 않는다.

 

📌 4 Way Handshake가 필요한 이유

TCP는 양방향 통신을 지원하기 때문에 양쪽이 각각 연결을 종료해야 한다.
  • 3 Way Handshake는 한쪽이 요청을 보내면 상대방이 바로 응답하는 방식
  • 4 Way Handshake는 두 개의 독립적인 FIN + ACK 과정이 필요하다.

'IT' 카테고리의 다른 글

[IT] TIME_WAIT  (0) 2025.04.09
[IT] Sliding Window ( 슬라이딩 윈도우 )  (0) 2025.04.08
[IT] 3 Way Handshake  (0) 2025.04.08
[IT] 운영체제 명령어 삽입 ( OS Command Injection )  (0) 2025.04.01
[IT] 크로스사이트 스크립트  (0) 2025.04.01
슬라이딩 윈도우는 TCP 흐름 제어와 패킷 전송 최적화를 위해 사용되는 기술이다.
데이터를 효율적으로 보내고, 수신 측이 처리할 수 있는 만큼만 보내도록 조절하는 메커니즘을 말한다.

 

📌 Sliding Window 개념

TCP는 데이터를 세그먼트 단위로 전송한다. 하지만 매번 한 개의 패킷을 보내고 ACK(응답)를 기다리면 속도가

너무 느려지기 때문에, 여러 개의 패킷을 연속적으로 보낼 수 있도록 허용하는 기법을 Sliding Window라 한다.

 

✅ Sliding Window 방식

  • 송신자는 미리 여러 개의 패킷을 보내고, ACK을 기다린다.
  • 수신자는 데이터를 받은 후 ACK를 보낸다.
  • 일정 개수의 세그먼트(윈도우 크기)만큼만 한 번에 전송 가능하다.

📌 Sliding Window 동작 방식

Sliding Window는 윈도우 크기에 따라 한 번에 보낼 수 있는 패킷 개수를 결정한다.

즉, ACK 없이 미리 보낼 수 있는 데이터 양을 정하는 것이다.

  • 윈도우 크기 = 4일 경우, 송신자는 4개의 패킷을 연속적으로 보낼 수 있고, 이후 ACK을 받아야 다시 보낼 수 있다.

  송신 윈도우와 수신 윈도우

  • 송신 윈도우 : 송신자가 한 번에 보낼 수 있는 데이터 크기
  • 수신 윈도우 : 수신자가 한 번에 받을 수 있는 데이터 크기
  • 수신 윈도우 크기에 따라 송신 윈도우의 크기가 조정된다.
송신자                                      수신자
---------------------------------------------------
SEQ=1 [패킷1]  ---->   
SEQ=2 [패킷2]  ---->   
SEQ=3 [패킷3]  ---->   
SEQ=4 [패킷4]  ---->  (한 번에 4개 전송 완료!)

(수신자가 패킷을 받은 후)  
<----  ACK=5  (1~4번 패킷 정상 수신!)

SEQ=5 [패킷5]  ---->   
SEQ=6 [패킷6]  ---->   
...

 

위 처럼 송신자는 ACK을 기다리지 않고, 미리 4개 패킷을 보낼 수 있다.

ACK을 받으면 다음 데이터를 연속적으로 보낼 수 있다.

 

📌 윈도우 크기 조절 ( 흐름 제어 & 혼잡 제어 )

TCP에서는 윈도우 크기를 동적으로 조절하여 네트워크 상태에 맞게 최적의 속도로 데이터 전송을 수행한다.

 

🔸 흐름 제어 ( Flow Control )

  • 송신자가 너무 많은 데이터를 보내면 수신자가 처리하지 못하는 경우가 발생한다.
  • 수신자는 자신의 수신 윈도우 크기를 조정하여 한 번에 받을 수 있는 데이터 크기를 제한한다.
  • 수신 윈도우 크기가 0이 되면 일시적으로 전송을 중지한다..

🔸 혼잡 제어 ( Congestion Control )

  • 네트워크에 트래픽이 너무 많으면 패킷 손실이 발생할 수 있다.
  • 송신자는 혼잡 윈도우를 활용하여 네트워크 상태에 맞게 전송량을 조절한다.
    • 혼잡 윈도우는 TCP에서 네트워크 혼잡을 방지하기 위해 송신자가 조절하는 윈도우 크기를 말한다.

'IT' 카테고리의 다른 글

[IT] TIME_WAIT  (0) 2025.04.09
[IT] 4 Way Handshake ( TCP 연결 종료 )  (0) 2025.04.09
[IT] 3 Way Handshake  (0) 2025.04.08
[IT] 운영체제 명령어 삽입 ( OS Command Injection )  (0) 2025.04.01
[IT] 크로스사이트 스크립트  (0) 2025.04.01
TCP 3-Way Handshake는 신뢰성 있는 연결을 설정하기 위해 클라이언트와 서버 간에 세 번의 패킷 교환을 수행하는 과정을 말한다.

 

📌 개요

TCP는 연결형 프로토콜로, 데이터 전송 전에 송신자와 수신자가 서로 연결을 설정해야한다.

이를 위해 TCP는 3 Way Handshake를 사용하여 다음을 보장한다.

  • 양쪽이 데이터 전송 준비가 되었는지 확인
  • 초기 시퀀스 번호( ISN )를 교환하여 데이터 순서를 유지
  • 네트워크 상태를 점검하여 적절한 패킷 크기 및 흐름 제어 설정

📌 과정

 Step 1 : 클라이언트 -> 서버 ( SYN )

클라이언트가 서버에 연결 요청을 보낸다.

  • 클라이언트가 TCP 소켓을 열고, SYN 플래르가 설정된 패킷을 전송한다.
  • 이 패킷에 초기 시퀀스 번호 ( ISN )가 포함된다.
  • 윈도우 크기( Window Size), MSS, 윈도우 스케일( Window Scaling ) 등의 옵션 정보가 포함된다.

 Step 2 : 서버 -> 클라이언트 ( SYN + ACK )

서버가 클라이언트의 요청을 수락하고 응답을 보낸다.

  • 서버는 클라이언트의 SYN 요청을 수락한 후, SYN + ACK 플래그가 설정된 패킷을 전송한다.
  • 이 패킷에 서버의 초기 시퀀스 번호( ISN ) 와 클라이언트의 SYN에 대한 응답 번호(ACK)가 포함된다.

 Step 3 : 클라이언트 -> 서버 ( ACK )

클라이언트가 최종적으로 서버에 연결 완료를 알린다.

  • 클라이언트는 서버가 보낸 SYN + ACK 패킷을 받은 후, ACK 플래그가 설정된 패킷을 다시 서버로 보낸다.
  • 이 패킷에 서버의 SYN에 대한 응답 번호 ( ACK )가 포함된다.

📌 3 Way Handshake에서 설정되는 TCP 옵션

  • MSS : 한 번에 전송할 수 있는 최대 세그먼트 크기
  • 윈도우 크기 : 수신 가능한 버퍼 크기
  • 윈도우 스케일링 : 윈도우 크기 확장 옵션
  • 타임스탬프 : 패킷의 RTT 측정

📌 3 Way Handshake가 실패하는 경우

  • SYN 패킷이 도착하지 않는 경우
  • SYN + ACK 패킷이 도착하지 않는 경우
  • ACK 패킷이 도착하지 않는 경우

📌 3 Way Handshake가 성공하고 나서 데이터 전송

  • 클라이언트가 데이터를 전송한다 ( Sequence Number = 1001 )
  • 서버가 응답한다. ( ACK = 1001 )
  • 이후, Sliding Window를 활용하여 빠르게 데이터를 전송한다.
외부 입력이 시스템 명령어 실행 인수로 적절한 처리 없이 사용되면 위험하다.
일반적으로 명령어 줄 인수나 스트림 입력 등 외부 입력을 사용하여 시스템 명령어를 생성하는 프로그램이 많이 있다.
하지만 이러한 경우 외부 입력 문자열은 신뢰할 수 없기 때문에 적절한 처리를 해주지 않으면, 
공격자가 원하는 명령어 실행이 가능하게 된다.

'IT' 카테고리의 다른 글

[IT] Sliding Window ( 슬라이딩 윈도우 )  (0) 2025.04.08
[IT] 3 Way Handshake  (0) 2025.04.08
[IT] 크로스사이트 스크립트  (0) 2025.04.01
[IT] 자원 삽입 ( Resource Injection )  (0) 2025.04.01
[IT] SQL 삽입 ( SQL Injection )  (0) 2025.04.01
웹 페이지에 악의적인 스크립트를 포함시켜 사용자 측에서 실행되게 유도할 수 있다.

 

아래 그림과 같이 검증되지 않은 외부 입력이 동적 웹페이지 생성에 사용될 경우, 전송된 동적 웹페이지를 열람하는 접속자의 권한으로 부적절한 스크립트가 수행되어 정보유출 등의 공격을 유발할 수 있다.

 

'IT' 카테고리의 다른 글

[IT] 3 Way Handshake  (0) 2025.04.08
[IT] 운영체제 명령어 삽입 ( OS Command Injection )  (0) 2025.04.01
[IT] 자원 삽입 ( Resource Injection )  (0) 2025.04.01
[IT] SQL 삽입 ( SQL Injection )  (0) 2025.04.01
[IT] 레이턴시 ( Latency )  (2) 2024.10.24
외부 입력값을 검증하지 않고 시스템 자원에 대한 식별자로 사용하는 경우, 공격자는 입력값 조작을 통해
시스템이 보호하는 자원에 임의로 접근하거나 수정할 수 있다.

 

📌 안전한 코딩 기법

  • 외부의 입력을 자원( 파일, 소켓의 포트 등 ) 식별자로 사용하는 경우, 적절한 검증을 거치도록 하거나 사전에 정의된 적합한 리스트에서 선택되도록 작성한다. 외부의 입력이 파일명인 경우에는 경로 순회를 수행할 수 있는 문자를 제거한다.
데이터베이스와 연동된 웹 어플리케이션에서 입력된 데이터에 대한 유효성 검증을 하지 않을 경우,
공격자가 입력 폼 및 URL 입력란에 SQL 문을 삽입하여 DB로부터 정보를 열람하거나 조작할 수 있는 보안약점을 말한다.

 

취약한 웹 어플리케이션에서는 사용자로부터 입력된 값을 필터링 과정없이 넘겨받아 동적 쿼리를 생성한다.

이는 개발자가 의도하지 않은 쿼리가 생성되어 정보유출에 악용될 수 있다.

 

📌 안전한 코딩기법

  • 외부 입력이나 외부 변수로부터 받은 값이 직접 SQL 함수의 인자로 전달되거나, 문자열 복사를 통하여 전달되는 것은 위험하다. 그러므로 인자화된 질의문을 사용해야 한다.
  • 외부 입력값을 그대로 사용해야 하는 환경이라면, 입력받은 값을 필터링을 통해 처리한 후 사용해야 한다. 필터링은 SQL문에서 사용하는 단어 사용 금지, 특수문자 사용금지, 길이 제한의 기준을 적용한다.

 

📌 예제

#include <stdlib.h>
#include <sql.h> 
void Sql_process(SQLHSTMT sqlh) 
{ 
    char *query = getenv("query_string"); 
    SQLExecDirect(sqlh, query, SQL_NTS);
}

 

위 코드를 살펴보자.

외부 입력이 SQL 질의어에 어떠한 처리도 없이 삽입되었기 때문에, name' OR 'a'='a 와 같은 문자열을 입력으로 주면

WHERE 절이 항상 참이 된다.

 

#include <sql.h> 
void Sql_process(SQLHSTMT sqlh) 
{ 
    char *query_items = "SELECT * FROM items"; 
    SQLExecDirect(sqlh, query_items, SQL_NTS);
}

 

위 코드는 인자화된 질의를 사용해 질의 구조의 변경을 막을 수 있다.

 

 

레이턴시 ( Latency )

  • 한 지점에서 다른 지점으로 이동하는 데 걸리는 시간

 

라운드 트립 레이턴시 ( Round Trip Latency )

  • 데이터 패킷이 송신지에서 수신지로 이동하고, 다시 수신지에서 송신지로 돌아오는 데 걸리는 전체 시간
  • 라운드 트립 타임( RTT, Round Trip Time )이라고도 불린다.
  • 핑( Ping ) 명령어를 통해 측정된다.

 

레이턴시 마스킹 ( Latency Masking )

  • 네트워크 지연을 사용자가 느끼지 못하도록 숨기는 기술 ( 예측, 보정, 보간 )

 

추측항법 ( Dead Reckoning )

  • 예측 및 보정
  • 이미 지난 약간의 시간 ( = 레이턴시 )만큼 예측해 데이터를 전달

 


 

적용 방법

서버에 유저들이 접속하면 각 유저들의 라운드트립 레이턴시를 측정해 서버에 기록한다.

간단한 방법으로 평균으로 레이턴시를 계산하는 방법과 가장 높은 값을 사용하는 방법이 있다.

 

평균으로 레이턴시 계산

평균으로 레이턴시를 구하면 최소, 최대 값의 차이가 큰 유저간의 차이가 커지게 되는 경우가 있다.

 

가장 높은 값을 사용하는 방법

가장 높은 값을 사용하면 모두에게 느리게 보이기 때문에 안정적인 멀티플레이 동기화 환경을 제공할 수 있다.

 

아래 그림과 같은 경우 상황이 아주 좋을 때를 보여준다.

 

반면 아래 그림과 같이 네트워크 환경이 좋지 않은 유저가 있을 경우 최악의 환경이 될 수 있다.

바이트 저장 순서 ( byte order )

컴퓨터는 데이터를 메모리에 저장할 때, 바이트 ( byte ) 단위로 나눠서 저장한다.

하지만 컴퓨터가 저장하는 데이터는 32 비트 ( 4바이트 ) 또는 64비트 ( 8바이트 )로 구성된다.

따라서 이렇게 연속되는 바이트를 순서대로 저장해야 하는데, 이를 바이트 저장 순서 ( byte order )라고 한다.

 

이때 바이트가 저장되는 순서에 따라 아래와 같이 두 가지 방식으로 나눌 수 있다.

1. 빅 엔디안 ( big endian )

2. 리틀 엔디안 ( little endian )


빅 엔디안 ( big endian )

빅 엔디안 방식은 낮은 주소에 데이터의 높은 바이트 ( MSB, Most Significant Bit )부터 저장하는 방식이다.

이 방식은 평소 우리가 숫자를 사용하는 선형 방식과 같은 방식이다.

따라서 메모리에 저장된 순서 그대로 읽을 수 있고, 이해하기가 쉽다는 장점을 가지고 있다.

SPARC를 포함한 대부분의 RISC CPU 계열에서는 이 방식으로 데이터를 저장한다.

 

예를 들어 아래와 같이 저장할 32비트 크기의 정수가 있다고 가정해보자.

0x12345678

 

이 정수는 각각 아래와 같이 1바이트값 4개로 구성된다.

0x12, 0x34, 0x56, 0x78

 

이 4개의 1바이트 값을 빅 엔디안 방식으로 저장하면 다음 그림과 같이 저장된다.

 

 


 

리틀 엔디안 ( little endian )

리틀 엔디안 방식은 낮은 주소에 데이터의 낮은 바이트 ( LSB, Least Significant Bit )부터 저장하는 방식이다.

이 방식은 평소 사용하는 숫자를 사용하는 선형 방식과는 반대로 수를 거꾸로 읽어야 한다.

대부분의 인텔 CPU 계열에서는 리틀 엔디안 방식으로 데이터를 저장한다.

 

위에서 예를 든 정수 "0x12345678"를 리틀 엔디안 방식으로 저장하면 아래 그림과 같이 저장된다.

 


 

빅 엔디안 vs 리틀 엔디안

빅 엔디안과 리틀 엔디안은 단지 저장해야 할 큰 데이터를 어떻게 나누어 저장하는가에 따른 차이일 뿐, 

어느 방식이 더 우수하다고 단정할 수 없다.

 

물리적으로 데이터를 조작하거나 산술 연산을 수행할 때는 리틀 엔디안 방식이 더 효율적이다.

하지만 데이터의 각 바이트를 배열처럼 취급할 때는 빅 엔디안 방식이 더 적합하다.

 

윈도우에서는 리틀 엔디안 방식을 사용하고 있다.

하지만 네트워크를 통해 데이터를 전송할 때는 빅 엔디안 방식이 사용된다.

따라서 인텔 기반의 시스템에서는 소켓 통신을 할 때는 바이트 순서에 신경을 써서 데이터를 전달해야 한다.

 

+ Recent posts