Sqix

Linux에서 libtins 라이브러리 사용하기 - 5. TCP Stream 본문

libtins

Linux에서 libtins 라이브러리 사용하기 - 5. TCP Stream

Sqix_ow 2017. 9. 22. 05:32

<작성자가 libtins를 사용하는 환경은 Ubuntu 16.04.2 LTS, Kernel version 4.10 환경입니다>



1. Introduction


해당하는 기능을 이용하시기 위해서는 C++11과 GCC 4.6버전 이상이 필요합니다. tins 3.4 버전부터 새로운 클래스가 도입되어 콜백 기반 인터페이스를 이용해 스트림을 따라 데이터를 처리하고 옵션들을 구성할 수 있습니다. 


2. StreamFollower


StreamFollower 클래스는 TCP 패킷을 처리하여 IP 패킷에 사용된 IP 주소와 포트를 찾아냅니다. 기본적으로 4-tuple(Source, destination IP Address, Source , destination Port)을 이용해서 구별을 하고, 새로운 4-tuple을 가진 패킷이 보일 때 마다 TCP Stream에 대한 Context를 생성하고, 사용자가 작성한 Callback Function을 이용합니다. 그 다음, 해당 Stream에 속한 모든 패킷이 그에 맞는 개체로 전달되어 데이터를 처리합니다. 또한, StreamFollower는 Stream 상에서 발생하는 문제에 대한 감지를 할 수 있도록 합니다. 예를 들어, 패킷 손실이 많거나, 재조합이 되지 않는 스트림에 대해 버퍼를 유지하거나, FIN/RST 패킷이 포착되지 않은 상태에서 닫힌 스트림에 대한 Status나 Data를 저장하지 않는 경우가 있습니다. 이러한 경우, 클래스는 해당 이벤트가 감지되면 Status를 삭제합니다. StreamFollower를 생성하고 Callback을 작성하는 예제는 다음과 같습니다.


#include <tins/tins.h>


using namespace Tins;


void on_new_stream(Stream &stream){

// New Stream

}


void on_stream_terminated(Stream& stream, StreamFollower::TerminationReason reason){

// 중단된 Stream. 두 번째 파라미터는 중단된 이유를 알려줍니다.

}


StreamFollower follower;


follower.new_stream_callback(&on_new_stream);

// 새로운 스트림을 위한 콜백 함수입니다. 이는 std::function에 속하기 때문에, std::bind를 이용해도 무관합니다.


follower.stream_termination_callback(&on_stream_terminated);

// 종료 콜백을 설정합니다. 스트림이 종료될 때 호출됩니다. 


Sniffer sniffer = ...;

sniffer.sniff_loop([&](PDU& pdu){

follower.process_packed(pdu);

return true;

})

//이제 스니퍼를 생성하고 스니핑을 시작합니다. 


3. 스트림의 사용


StreamFollower에서 새로운 스트림에 대한 콜백을 구성하고 나면, Stream 클래스를 이용하여 스트림에서 발생하는 이벤트에 대한 콜백 함수들을 작성할 수 있습니다. 새로운 데이터가 처리가 될 때 마다 데이터 이벤트가 생성되는데, 클라이언트 또는 서버에서 각 스트림의 새로운 데이터가 있을 때 마다 콜백에 대한 알림을 받을 수 있습니다. 예제는 다음과 같습니다.


void on_client_data(Stream &stream){// 새로운 데이터가 들어오면 호출됩니다.

const Stream::payload_type& payload = stream.client_payload();

//클라이언트의 payload를 vector<uint8_t> 타입으로 가져옵니다.

...(do sth)

}


void on_server_data(Stream &stream){

// 서버 데이터를 처리하는 곳입니다.

}


void on_new_stream(Stream& stream){// 새로운 데이터가 발견되는 곳입니다.

stream.client_data_callback(&on_client_data);

stream.server_data_callback(&on_server_data);

//콜백 함수 설정을 합니다.

}



--추후 작성


Comments