modprobe toa
명령을 직접 실행하여 TOA를 로딩할 수 있습니다. 서버가 Linux에서 실행되는 경우 Linux TOA를 대신 사용해야 합니다.insmod toa.ko
dmesg -T | grep TOA
toa.ko
파일을 로딩합니다(ko 파일은 서버가 다시 시작되면 다시 로딩해야 함).rmmod toa
dmesg -T
wget "https://clb-toa-1255852779.file.myqcloud.com/tgw_toa_linux_ver.tar.gz"
wget "https://clb-toa-1255852779.file.myqcloud.com/tgw_toa_tlinux_ver.tar.gz"
yum install gccyum install make//커널 개발 패키지를 설치합니다. 패키지 헤더 파일 및 라이브러리의 버전은 커널 버전과 일치해야 합니다.yum install kernel-devel-`uname -r`
apt-get install gccapt-get install make//커널 개발 패키지를 설치합니다. 패키지 헤더 파일 및 라이브러리의 버전은 커널 버전과 일치해야 합니다.apt-get install linux-headers-`uname -r`
zypper install gcczypper install make//커널 개발 패키지를 설치합니다. 패키지 헤더 파일 및 라이브러리의 버전은 커널 버전과 일치해야 합니다.zypper install kernel-default-devel
warning
및 error
메시지가 표시되지 않으면 컴파일이 성공한 것입니다. Linux OS용 소스 패키지를 예로 들어 보겠습니다.tar zxvf tgw_toa_linux_ver.tar.gzcd tgw_toa_linux_ver//압축 해제된 tgw_toa 디렉터리로 이동make
struct sockaddr v4addr;len = sizeof(struct sockaddr);//get_peer_name 은 표준 Linux 네트워크 프로그래밍 API입니다.if (get_peer_name(client_fd, &v4addr, &len) == 0) {inet_ntop(AF_INET, &(((struct sockaddr_in *)&v4addr)->sin_addr), from, sizeof(from));printf("real client v4 [%s]:%d\\n", from, ntohs(((struct sockaddr_in *)&v4addr)->sin_port));}
toa.ko
커널 모듈을 삽입한 후 원본 코드를 수정해야 하며 TOA는 해당 IP 주소를 리얼 서버에 전달합니다.struct toa_nat64_peer {struct in6_addr saddr;uint16_t sport;};....struct toa_nat64_peer client_addr;....
enum {TOA_BASE_CTL = 4096,TOA_SO_SET_MAX = TOA_BASE_CTL,TOA_SO_GET_LOOKUP = TOA_BASE_CTL,TOA_SO_GET_MAX = TOA_SO_GET_LOOKUP,};getsockopt(client_fd, IPPROTO_IP, TOA_SO_GET_LOOKUP, &client_addr, &len);
real_ipv6_saddr = client_addr.saddr;real_ipv6_sport = client_addr.sport;
//TOA 변수를 정의합니다. 'TOA_BASE_CTL'을 4096으로 설정합니다.enum {TOA_BASE_CTL = 4096,TOA_SO_SET_MAX = TOA_BASE_CTL,TOA_SO_GET_LOOKUP = TOA_BASE_CTL,TOA_SO_GET_MAX = TOA_SO_GET_LOOKUP,};//IP 주소를 저장할 데이터 구조를 정의합니다.struct toa_nat64_peer {struct in6_addr saddr;uint16_t sport;};//주소를 저장할 변수를 선언합니다.struct toa_nat64_peer client_addr;.……//클라이언트의 파일 디스크립터를 가져옵니다. 여기서 listenfd는 서버의 수신 파일 디스크립터입니다.client_fd = accept(listenfd, (struct sockaddr*)&caddr, &length);// NAT64 시나리오에서 사용자의 실제 원본 IP를 가져오기 위해 호출합니다.char from[40];int len = sizeof(struct toa_nat64_peer);if (getsockopt(client_fd, IPPROTO_IP, TOA_SO_GET_LOOKUP, &client_addr, &len) == 0) {inet_ntop(AF_INET6, &client_addr.saddr, from, sizeof(from));//원본 IP와 원본 port 가져오기printf("real client [%s]:%d\\n", from, ntohs(client_addr.sport));}
toa.ko
커널 모듈을 삽입한 후 원본 코드를 수정해야 하며 TOA는 해당 IP 주소를 리얼 서버에 전달합니다.//TOA 변수를 정의합니다. 'TOA_BASE_CTL'을 4096으로 설정합니다.enum {TOA_BASE_CTL = 4096,TOA_SO_SET_MAX = TOA_BASE_CTL,TOA_SO_GET_LOOKUP = TOA_BASE_CTL,TOA_SO_GET_MAX = TOA_SO_GET_LOOKUP,};//IP 주소를 저장할 데이터 구조를 정의합니다.struct toa_nat64_peer {struct in6_addr saddr;uint16_t sport;};//주소를 저장할 변수를 선언합니다.struct toa_nat64_peer client_addr_nat64;.......//클라이언트의 파일 디스크립터를 가져옵니다. 여기서 listenfd는 서버의 수신 파일 디스크립터입니다.//NAT64 시나리오에서 실제 클라이언트 IP를 가져오기 위해 호출합니다.char from[40];int len = sizeof(struct toa_nat64_peer);int ret;ret = getsockopt(client_fd, IPPROTO_IP, TOA_SO_GET_LOOKUP, &client_addr_nat64, &len);if (ret == 0) {inet_ntop(AF_INET6, &(client_addr_nat64.saddr), from, sizeof(from));//원본 IP와 원본 Port를 가져옵니다.printf("real client v6 [%s]:%d\\n", from, ntohs(client_addr_nat64.sport));} else if (ret != 0) {struct sockaddr v4addr;len = sizeof(struct sockaddr);//원본 IP와 원본 Port를 가져옵니다.//하이브리드 클라우드 배포 시나리오에서 원본 IP 주소는 SNAT 뒤의 IP 주소입니다.//비하이브리드 클라우드 배포 시나리오에서 원본 IP 주소는 SNAT 및 NAT64가 없는 클라이언트 IP 주소입니다.//이 함수의 의미는 실제 클라이언트 주소와 포트를 가져오는 것입니다.if (get_peer_name(client_fd, &v4addr, &len) == 0) {inet_ntop(AF_INET, &(((struct sockaddr_in *)&v4addr)->sin_addr), from, sizeof(from));printf("real client v4 [%s]:%d\\n", from, ntohs(((struct sockaddr_in *)&v4addr)->sin_port));}}
cat /proc/net/toa_table
cat /proc/net/toa_stats
메트릭 | 설명 |
syn_recv_sock_toa | TOA 정보와의 연결을 수신합니다. |
syn_recv_sock_no_toa | TOA 정보 없이 연결을 수신합니다. |
getname_toa_ok | 이 수는 getsockopt를 호출하고 원본 IP를 성공적으로 가져오거나 accept를 호출하여 클라이언트 요청을 수신할 때 증가합니다. |
getname_toa_mismatch | 이 수는 getsockopt를 호출하고 필요한 유형과 일치하지 않는 원본 IP를 가져올 때 증가합니다. 예를 들어 클라이언트 연결에는 IPv4 원본 IP 주소가 포함되어 있는 반면 IPv6 주소를 받으면 개수가 증가합니다. |
getname_toa_empty | 이 카운트는 TOA를 포함하지 않는 클라이언트 파일 디스크립터에서 getsockopt 함수가 호출될 때 증가합니다. |
ip6_address_alloc | TOA가 TCP 데이터 패킷에 저장된 원본 IP와 원본 port를 가져오면 정보를 저장할 공간을 할당합니다. |
ip6_address_free | 연결이 릴리스되면 toa는 이전에 원본 IP 및 원본 port를 저장하는 데 사용된 메모리를 릴리스합니다. 모든 연결이 닫히면 각 CPU에 대한 ip6_address_alloc의 총 개수는 이 메트릭의 개수와 같아야 합니다. |
tlinux
가 표시되면 TLinux OS를 사용하고 있는 반면 linux는 Linux OS를 사용하고 있음을 나타냅니다.uname -a
tlinux
또는 tl2
가 반환되면 TLinux OS를 사용하고 있는 것입니다.rpm -qa | grep kernel
lsmod | grep toa
unknown-200
이 표시되면 TCP option 필드에 SNAT 이후의 실제 원본 IP가 삽입되었음을 나타냅니다.unknown-253
이 표시되면 NAT64 시나리오에 실제 원본 IPv6 주소가 삽입되었음을 나타냅니다.
make cleanmake
rmmod toainsmod ./toa.ko
dmesg -Tw
문제 해결에 도움이 되었나요?