63
IPv6 이이이 이이 이이이이이 이이이이 이이이이이이 이이이 이이 이이이이이 이이이 MS Visual C++ MVP Twitter : @jacking75

Ipv6 소켓프로그래밍

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Ipv6 소켓프로그래밍

IPv6 이론과 소켓 프로그래밍

마이에트 엔터테인먼트 건즈팀서버 프로그래머

최흥배MS Visual C++ MVPTwitter : @jacking75

Page 2: Ipv6 소켓프로그래밍

목차• IPv6 이론 정리

• IPv6 소켓 프로그래밍

Page 3: Ipv6 소켓프로그래밍

IPv6 이론 정리

Page 4: Ipv6 소켓프로그래밍

IPv6 이란 ?

IPv6 이란 ‘ Internet Protocol Version 6’ 의 줄임 말 .

현재 사용하고 있는 것은 IPv4 이다 .

이미 많은 통신 관련 제품들은 IPv6 지원을 하고 있음 .

일본의 경우는 일반 유저를 대상으로 IPv6 서비스 ( 유료 ) 를 제공하고 있음 .

Page 6: Ipv6 소켓프로그래밍

왜 IPv6 을 사용해야 하나 ?

부족

- IPv4 로 할당할 수 있는 IP 가 부족함 . - IPv4 로는 42 억 개의 IP 를 사용할 수 있음 - 부족을 해결하기 위해 NAT 를 이용하기도 함- 2011 년 2 월 3 일로 남은 것이 모두 고갈 .

Page 7: Ipv6 소켓프로그래밍

왜 IPv6 을 사용해야 하나 ?

풍족 - 지구상의 모든 모래까지도 IP 를 부여할 수 있음- 128bit 주소 지정 -

340282366920938463463374607431768211456 개 만큼 사용할 수 있음

Page 8: Ipv6 소켓프로그래밍

왜 IPv6 을 사용해야 하나 ?

보안 IPv4 는 보안을 신경 쓰지 않고 만들어서 쉽게 패킷을 캡쳐 하여 분석할 수 있음 .

성능 - IPv6 의 헤더 크기는 40byte 로 IPv4 의 두 배의 크기지만 단순해져서 처리가 빨라짐

IP 주소 자동 설정 . DHCP 불필요

프로토콜 차원에서 QoS 지원

Page 9: Ipv6 소켓프로그래밍

출처 : Joinc http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/TCP_IP/IPv6/IPv6Intro

IPv4 과 IPv6 의 헤더 포맷

Page 10: Ipv6 소켓프로그래밍

IPv6 을 사용하기 위해 필요한 것

OS

- Windows XP, Windows Server 2003 이후 가능 - 완전한 대응은 Windows Vista, Windows Server 2008 이후

- Mac OS 는 10.2(Jaguar) 부터 대응

- Linux 나 FreeBSD 는 USAGI 나 THAI 프로젝트에서 IPv6 대응 프로토콜 스택을 개발하였으므로 이것을 사용하면 된다 .

Page 11: Ipv6 소켓프로그래밍

IPv6 을 사용하기 위해 필요한 것

하드웨어

- 스위치 허브와 같은 레이어 2 에서 사용하는 기기는 IPv6 과 상관 없음 .- 라우터 , 레이어 3 스위치는 네트워크 계층이므로 IPv6 을 지원해야 한다 .

I-O Data WN-GDN/RS Wi-Fi g/n Router Cisco Catalyst 3750-E Series Switch

Page 12: Ipv6 소켓프로그래밍

IPv6 을 사용하기 위해 필요한 것

기존 시스템과 호환

- 앞으로 당분간 IPv4 와 같이 사용해야 하므로 IPv4 와 IPv6 둘 다 사용할 수 있는 Dual Stack 으로 구성해야 한다 .- Windows Vista 에서는 IPv6 통신을 먼저 시도하고 실패하면 IPv4 를 사용한다 .

출처 : http://www.dbguide.net/knowledge.db?cmd=view&boardUid=126274&boardConfigUid=19&boardStep=0

Page 13: Ipv6 소켓프로그래밍

Dual Stack 이란 ?

IPv4 와 IPv6 양쪽 모두를 지원하는 것을 말한다 .- 현재와 같이 IPv4 에서 IPv6 이행기에 꼭 필요- 대부분의 OS 에서 지원하고 있음

Page 14: Ipv6 소켓프로그래밍

출처 : http://www.euchinagrid.org/IPv6/IPv6_presentation/Introduction_to_IPv6_programming.pdf

Page 15: Ipv6 소켓프로그래밍

출처 : http://www.euchinagrid.org/IPv6/IPv6_presentation/Introduction_to_IPv6_programming.pdf

Page 16: Ipv6 소켓프로그래밍

IPv6 은 이미 사용 중

IPv6 관련 기술을 개발하기 위해 실험적인 목적으로 1996 년에 실험 네트워크 6Bone 신설 .

1998 년 10 월에는 6REN(IPv6 Research and Education Networks Ini-tiative) 발족 .

미군 ( 美軍 ) 에서는 GIG(Global Information Grid) 라고 하는 세계 규모의 정보 통신망을 구축 운용하고 있는데 2003 년 6 월에 IPv6 으로 이행을 발표 . 2008 년에는 전면적으로 IPv6 베이스로 이행 .

2003 년 이후 미군이 조달하는 네트워크 기기는 모두 IPv6 대응이 필수이다 .

일본의 경우 이미 일반 유저들을 대상으로 IPv6 서비스를 제공하고 있음 .

Page 17: Ipv6 소켓프로그래밍

IPv6 Address( 주소 )

IPv4 의 주소 길이는 32 비트 , IPv6 의 주소 길이는 128 비트

IPv4 의 주소는 10 진수로 0~255 사이의 숫자를 사용IPv6 의 주소는 16 진수를 사용하고 블록 수는 8 개 . 블록 구분은 ‘ :’ 사용fe80:1234:5678:9abc:def0:1234하나의 블록에서 표현할 수 있는 수의 범위는 0000 ~ ffff

Page 18: Ipv6 소켓프로그래밍

IPv6 주소 단축 표기 법 – 방법 1

- 0 생략- 블록의 첫 숫자가 0 으로 시작하는 경우만 생략할 수 있다 .

f0f0:0100:0020:0003:1000:0100:0020:0003

f0f0:100:20:3:1000:100:20:3

Page 19: Ipv6 소켓프로그래밍

IPv6 주소 단축 표기 법 – 방법 2

- 0 압축 . 모두 0 으로 되는 블록은 생략한다 .

- 생략되는 부분에 대해서는 : 을 연속으로 붙임 ::

- 생략은 하나의 주소에서 한번만 가능 1234:0000:0000:5678:9abc:0000:0000:def0 -> 1234::5678:9abc::def0 -> 1234::5678:9abc:0:0:def0

1234:5678:0000:9abc:def0:1234:5678:9abc

1234:5678::9abc:def0:1234:5678:9abc

1234:0000:0000:0000:5678:9abc:def0:1234

1234::5678:9abc:def0:1234

Page 20: Ipv6 소켓프로그래밍

‘0’ 압축 복원- 단순히 ‘ ::’ 부분을 ‘ 0000’ 으로 하는 것으로는 원래 주소로 복원할 수 없다 .

- 공식 - (8 - 압축 후의 IPv6 주소 블록 수 )×16 - ‘ff02::2’ -> (8-2)×16 = 96. (16X6=96) 이므로 6 블록의 ‘ 0000’ 이 필요

IPv6 주소 단축 표기 법 – 방법 2

ff02::2

ff02:0000:0000:0000:0000:0000:0000:0002

Page 21: Ipv6 소켓프로그래밍

출처 : http://blog.daum.net/ipv6/30

Page 22: Ipv6 소켓프로그래밍

LINKLOCAL 주소

IPv4 에서는 APIPA 의 사양으로 DHCP 서버에서 IP 주소를 받을 수 없을 때 대용으로 LINKLOCAL 주소를 이용한다 .- 169.254.*.*/16 범위에서 IP 주소를 자동으로 할당 받음

IPV6 에서도 같은 사양으로 지원하고 있다 .- fe80::/64 범위를 사용한다 .

Page 23: Ipv6 소켓프로그래밍

익명 ( 혹은 임시 ) 주소

LINKLOCAL 주소 방식에는 개인 보안에 문제가 있음MAC 주소는 LAN 어댑터를 바꾸지 않는 한 바뀌지 않으므로 IPv6 주소의 인터페이스 ID 를 개인정보와 연결 지을 수 있으므로 개인 추적을 할 수도 있다

출처 : http://journal.mycom.co.jp/photo/series/ipv6/006/images/001l.jpg

Page 24: Ipv6 소켓프로그래밍

IPv6 의 특별한 주소

0:0:0:0:0:0:0:0- 미 지정 주소 . 줄여서 ‘ 0::0’ 이나 ‘ ::’ 로도 표기- 노드에 주소가 할당되어 있지 않고 , 할당 할 수도 없음을 나타냄

0:0:0:0:0:0:0:1- 루프백 주소 . IPv4 의 127.0.0.1 에 해당- IPv4 에서는 12.0.0.0/8 범위의 주소를 사용할 수 있지만 IPv6 에서는 이 주소만 사용할 수 있다- 줄여서 ‘ 0::1’ 또는 ‘ ::1’

2001:db8::/32- 문서 작성용 주소 공간

2001: 로 시작하는 것 (sTLA 주소 )- 상용 서비스에 할당되고 있는 주소

2002:: 로 시작하는 것 (6to4 주소 )- IPv6 over IPv4 터널링의 6to4 에서 사용하는 주소 . 2002: 에 연속해서 32 비트 부분에 IPv4 글로벌 주소를 넣는다 . IPv6 을 지원하지 않는 ISP 의 유저 등에 사용된다

Page 25: Ipv6 소켓프로그래밍

3ffe: 로 시작하는 것 (pTLA 주소 )- 비 상용 실험 프로젝트에서 배포 되고 있는 주소

ff00::/8 시작하는 주소- 멀티캐스트

fe80::/10- 로컬 유니캐스트 ( 링크 )- 단일 링크상에 라우터가 없는 경우에 사용

IPv6 의 특별한 주소

Page 26: Ipv6 소켓프로그래밍

IPv6 과 IPv4 간의 접속 (Dual Stack 지원하지 않는 경우 )

IPv6( 클라이언트 )

IPv4( 클라이언트 )

IPv6( 서버 )

IPv4( 서버 )

IPv4 가 Ipv6 에 접속할 수 있는 이유는 IPv4 는 32 비트인데 비해 IPv6 은 128비트로 크 rh 16 진수 표기로 16 비트 단위로 ‘ :’ 로 나누고 생략할 수도 있다 . 그리고 특별한 표기 방법도 있어서 하위 32 비트에 IPv4 의 주소를 넣을 수 있다 . 이 때문에 IPv4 와 호환성이 생겨서 IPv4 와도 통신할 수 있다 .예 ) ffff::10.1.2.3

Page 27: Ipv6 소켓프로그래밍

출처 : http://www.euchinagrid.org/IPv6/IPv6_presentation/Introduction_to_IPv6_programming.pdf

IPv6/IPv4 클라이언트 -> IPv4 만 지원 IPv4 서버

Page 28: Ipv6 소켓프로그래밍

IPv6/IPv4 클라이언트 -> IPv6 만 지원 IPv6 서버

출처 : http://www.euchinagrid.org/IPv6/IPv6_presentation/Introduction_to_IPv6_programming.pdf

Page 29: Ipv6 소켓프로그래밍

IPv6/IPv4 클라이언트 -> Dual Stack IPv4 서버

출처 : http://www.euchinagrid.org/IPv6/IPv6_presentation/Introduction_to_IPv6_programming.pdf

Page 30: Ipv6 소켓프로그래밍

IPv6/IPv4 클라이언트 -> Dual Stack IPv6 서버

출처 : http://www.euchinagrid.org/IPv6/IPv6_presentation/Introduction_to_IPv6_programming.pdf

Page 31: Ipv6 소켓프로그래밍

IPv6/IPv4 클라이언트 -> Separated Stack IPv6-only, IPv4-only 서버

출처 : http://www.euchinagrid.org/IPv6/IPv6_presentation/Introduction_to_IPv6_programming.pdf

Page 32: Ipv6 소켓프로그래밍

출처 : http://www.euchinagrid.org/IPv6/IPv6_presentation/Introduction_to_IPv6_programming.pdf

IPv6/IPv4 클라이언트 -> IPv4 만 지원 IPv4 서버

Page 33: Ipv6 소켓프로그래밍

출처 : http://www.euchinagrid.org/IPv6/IPv6_presentation/Introduction_to_IPv6_programming.pdf

Page 34: Ipv6 소켓프로그래밍

IPv6 과 IPv4 전환 기술

듀얼 스택- 운영체제 , 응용 프로그램에서 IPv4 와 IPv6 을 모두 사용할 수 있게 지원- IPv6 전환 시 가장 일반적인 방식

터널링- 양 끝단에 단말이 있고 중간 경로상에 IPv4 망이 있는 경우

변환- IPv6 to IPv4 또는 IPv4 to IPv6 으로 패킷을 재조합 하는 방식

출처 : http://blog.daum.net/ipv6/24

Page 35: Ipv6 소켓프로그래밍

IPv5 는 어디에 ?

1970 년대 말 비디오 / 오디오 스트리밍 전송을 위해 Streaming Protocol(ST)

ST 의 IP 패킷의 버전 번호로 ‘ 5’ 를 사용하여 IPv5 라고 부르기도 하였다

1990 년대 초 ST 를 개선하여 ST-II 를 개발 . IPv5 의 패킷 구조를 그대로 사용IP 주소 부족 문제 해결은 그대로 안고 감

이후 ST-II 이외에 다양한 비디오 / 오디오 스트리밍 관련 기술이 개발되면서 ST-II는 사장 . 동시에 IPv5 도 사장 됨

Page 36: Ipv6 소켓프로그래밍

IPv6 과 Windows OS

MSR(Microsoft Research) 는 1996 년부터 2002 년까지 IETF 의 IPv6 표준화 작업에 기여

MSR 은 Windows NT/2000 용으로 1998 년에 프로토타입인 MSRIPv6 1.0을 개발하여 공개

2001 년 10 월 Windows XP 에 IPv6 을 기본으로 탑재 . 기본적인 것만 구현

Windows Server 2003 에 상용 수준의 IPv6 스택이 탑재

Windows Visata 에서 IPv4/IPv6 이 통합된 진정한 듀얼스택을 개발하여 탑재 . 드디어 IPv6 을 완벽하게 구현

IE 에서는 버전 4 에서 부터 IPv6 을 지원했음

Page 37: Ipv6 소켓프로그래밍

IP 주소 할당 체계

ICANN( 국제 인터넷 주소 관리 기구 )

대륙 별 주소 관리 기구

APNIC( 아태 지역 )

ARIN( 북미 지역 )

LACNIC( 남미 지역 )

RIPE-NCC( 유럽 지역 )

AfrNIC( 아프리카 지역 )

Page 38: Ipv6 소켓프로그래밍

2 월 3 일 기자 회견에서의 IPv4 주소 고갈의 의미

ICANN 은 2 월 3 일 기자 회견을 통해 IPv4 주소가 고갈 되었다고 보도

이 때의 고갈의 의미는 ICANN 에서 각 대륙 별 주소 관리 기구에 주소 할당을 다했다는 의미로 지금 IPv4 주소가 더 이상 없다는 뜻이 아니다

ICANN 은 대륙 별 주소 관리 기구에 인터넷 주소를 줄 때 큰 하나의 덩어리를 주는데 이 덩어리의 크기는 약 1700 만개 정도의 인터넷 주소이다 .

2 월 3 일의 고갈은 마지막 남은 덩어리를 하나씩 각 대륙 별 주소 관리 기구에 다 주었다는 뜻이다 .

그러나 APNIC 의 경우 이번에 받은 덩어리를 약 4~6 개월 사이에 다 소진고 , 인터넷 인프라가 거의 없는 AfrNIC 가 가장 오래 동안 사용할 수 있을 것으로 예측하고 있다 .

Page 39: Ipv6 소켓프로그래밍

IPv6 과 NAT

IPv4 에서 주소 부족 문제를 해결하기 위해서 NAT(Network Address Transla-tion) 기술을 사용

NAT 은 주소 부족 문제를 해결해 주지만 P2P 통신에 문제가 있음

UPnP 나 NAT Traversal 등으로 이 문제를 회피하지만 완벽하지 않음

또 관리자 중 NAT 을 내부와 외부 네트워크를 분리하는 보안 기술이라는 생각을 가지고 있음

특히 최근의 CGN, LSN 등의 3 중 NAT 는 어뷰즈 로깅 , 위치 추적 , NAT Tra-versal 기능도 못 쓰게 만듬

NAT 은 웹브라우징 이나 이메일 등의 일반 웹 서비스에는 문제가 없지만 온라인 P2P 게임 , 비드오 스트리밍 , 웹갬 , 터널링 , VPn, VoIP 에서 품질 저하나 서비스가 불가능 하는 경우가 있다

IPv6 이 도입되면서 자연스럽게 NAT 에서 IPv6 으로 전환하는 것이 좋음

Page 40: Ipv6 소켓프로그래밍

IPv6 과 보안

IPv4 는 연구실에서 사용할 목적으로 만든 프로토콜로 설계 시에 보안은 거의 고려하지 않았음

IPv6 은 처음 설계 시부터 보안을 고려해서 만든

IPv6 은 IPv4 보다 보안이 더 뛰어나지만 아직 보급된 시장이 작아서 IPv4 에 비해 보안 관련 장비가 부족함

IPv6 전환기 동안에는 네트웍 관리자는 IPv4 와 IPv6 을 같이 관리해야 하므로 관리 비용이 2 배로 늘었다고도 할 수 있음

Page 41: Ipv6 소켓프로그래밍

World IPv6 Day

2011 년 6 월 8 일에 Internet Sociey(ISOC) 주최로 ‘ World IPv6 Day’ 행사 개최

이 행사의 목적은 24 시간 동안 IPv6 웹 사이트를 올려서 전 세계에서 접속이 가능한지 테스트 및 운영 , 또 IPv4 주소가 부족하다는 것을 알리고 IPv6 도입을 촉진 시키기 위해서이다

구글을 시작으로 야후 , 페이스북 , Bing 및 미국 최대 케이블 회사인 comcast 와 Time Warner cable 나 시스코와 같은 기업들이 참가하기로 함

Page 42: Ipv6 소켓프로그래밍

IPv6 사용 가능 여부 테스트 방법

http://test-ipv6.com/ 에 접속하면 알 수 있다

Page 43: Ipv6 소켓프로그래밍

Big Game 의 IPv6 지원

MMORPG 인 WOW 의 PTR 패치에서 환경 설정에서 IPv6 을 지원(2011.03.17)http://www.fix6.net/archives/2011/03/17/latest-world-of-warcraft-ptr-patch-brings-ipv6-support/

Page 44: Ipv6 소켓프로그래밍

프로그래밍

Page 45: Ipv6 소켓프로그래밍

API - IPv6 관련 구조체

#include <netinet/in.h> struct sockaddr_in { in_port_t sin_port; // Port 번호 struct in_addr sin_addr; // 인터넷 주소 구조체 }

struct in_addr { in_addr_t s_addr; // 32bit 크기의 인터넷주소 }

#include <netinet/in.h> struct sockaddr_in6 { u_int16m_t sin6_family; // AF_INET6 u_int16m_t sin6_port; // Port 번호 u_int32m_t sin6_flowinfo; // IPv6 flow infor-mation struct in6_addr sin6_addr;// IPv6 주소 u_long sin6_scope_id; // 인터페이스 인덱스 아이디 }

IPv4

IPv6

출처 : http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/TCP_IP/IPv6/IPv6Prog

Page 46: Ipv6 소켓프로그래밍

API - socket

IPv4 IPv6s = socket(PF_INET, SOCK_STREAM, 0); s = socket(PF_INET, SOCK_DGRAM, 0);

s = socket(PF_INET6, SOCK_STREAM, 0); s = socket(PF_INET6, SOCK_DGRAM, 0);

출처 : http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/TCP_IP/IPv6/IPv6Prog

Page 47: Ipv6 소켓프로그래밍

출처 : http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/TCP_IP/IPv6/IPv6Prog

API – bind (IPv6)

struct sockaddr_in6 sin6; .... sin6.sin6_family = AF_INET6; sin6.sin6_flowinfo = 0; sin6_sin6_port = htons(23); sin6.sin6_addr = in6addr_any; sin6.sin6_addr = in6addr_any; sin6.sin6_scope_id = if_nametoindex("eth0"); .... if (bind(s, (struct sockaddr *)&sin6, sizeof(sin6)) == -1) { // 에러처리 } ....

Page 48: Ipv6 소켓프로그래밍

API – listen, accept (IPv6)

listen 변환 없음

accept

struct sockaddr_in6 clisin6;clisockfd = accept(sockfd, (struct sockaddr *)&-clisin6, (socklen_t *)&clilen);

출처 : http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/TCP_IP/IPv6/IPv6Prog

Page 49: Ipv6 소켓프로그래밍

API – inet_addr, inet_ntoa

inet_addr inet_pton

inet_ntoa inet_ntop

inet_addr 는 32 비트 , inet_pton 는 128 비트 그러나 C++ 에서의 최대 정수의 크기는 64 비트 !!!

inet_pton, inet_ntop 는 Windows Vista 부터 지원

WSAAddressToString

Page 50: Ipv6 소켓프로그래밍

코드 - IPv6 주소 얻기 (Win32 API)

#include ‹winsock2.h› #include ‹ws2tcpip.h› #include ‹stdio.h›

int main(int argc, char *argv[]) { char *nodename; WSADATA wsaData; ADDRINFO hints; LPADDRINFO ai, ai0; int e;

if (argc != 2) { fprintf(stderr, "syntax: getv6addr HOSTNAME\n"); exit(1); } nodename = argv[1];

WSAStartup(MAKEWORD(2, 2), &wsaData);

/* resolving "www.ipv6style.jp" */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; if (e = getaddrinfo(nodename, NULL, &hints, &ai0)) { fprintf(stderr, "%s: %s\n", nodename, gai_strerror(e)); WSACleanup(); exit(1); }

for (ai = ai0; ai; ai = ai->ai_next) { char v6addrstr[NI_MAXHOST]; getnameinfo(ai->ai_addr, ai->ai_addrlen, v6addrstr, sizeof(v6addrstr), NULL, 0, NI_NUMERICHOST); printf("%s IPv6 address: %s\n", nodename, v6addrstr); }

freeaddrinfo(ai0); WSACleanup(); } 출처 : http://www.ipv6style.jp/jp/apps/20051024/index.shtml

Page 51: Ipv6 소켓프로그래밍

코드 - IPv6 주소 얻기 (Win32 API)

#include ‹winsock2.h› #include ‹ws2tcpip.h› #include ‹stdio.h›

int main(int argc, char *argv[]) { PHOSTENT pHostInfo = NULL; char szHostName[255] = {0, }; if (gethostname(szHostName, 255) == 0) { /// Windows XP1 이상 DWORD dwSize; LPADDRINFO lpAddrInfo; ADDRINFO addrHints; ZeroMemory(&addrHints, sizeof(addrinfo));

if( bUseIPv6Address ) {addrHints.ai_family = AF_INET6;

} else {addrHints.ai_family = AF_INET;

}

if (getaddrinfo(szHostName, NULL, &addrHints, &lpAddrInfo) != 0) {return false;

}

dwSize = MAX_IP_STRING_LENGTH; if( 0 != WSAAddressToString(lpAddrInfo->ai_addr, (DWORD)lpAddrInfo->ai_addrlen, NULL, szIP, &dwSize) ) {

return false; } }}

출처 : http://www.ipv6style.jp/jp/apps/20051024/index.shtml

Page 52: Ipv6 소켓프로그래밍

접속할 곳이 IPv6 지원을 하는지 어떻게 알 수 있을까 ?

보통 어느 노드에 접근할 때는 FQDN(Fully Qualified Domain Name.인터넷 상에서 단말을 식별하기 위한 이름 ) 을 기초로 하여 DNS 서버에 질문한다 . 듀얼 스택은 바로 이것을 활용한다 .

IPv4 만 대응하는 경우 보통 IPv4 주소를 기록한 A 레코드만 DNS 서버에 등록 . 듀얼 스택의 경우 여기에 IPv6 주소를 기록한 AAAA 레코드를 기록 .

IPv4 와 IPv6 둘 다 대응하는 프로그램은- AAAA 레코드에 등록된 IPv6 주소 접근을 시도- AAAA 레코드 접속이 실패하면 A 레코드 주소로 접근

IPv4, IPv6, 이 후의 프로토콜에 비 의존적인 네트웍 프로그래밍을 위해서는 gethostbyname 대신 getaddrinfo, getnameinfo 를 사용해야 한다 .

Page 53: Ipv6 소켓프로그래밍

#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <netdb.h> int sock,err;struct addrinfo hints, *res0, *res;

memset(&hints, 0, sizeof(hints));hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM;

/* getaddrinfo 로 AAAA 및 A 레코드 획득 */err = getaddrinfo("www.linux-ipv6.org", "http", &hints, &res0);

if (err) { fprintf(stderr, "error : %s", gai_strerror(err)); freeaddrinfo(res0); exit(1);}

/* getaddrinfo 의 결과를 이용하여 접속이 성공할 때까지 시도한다 */for (res = res0; res; res = res->ai_next) { sock = socket (res->ai_family, res->ai_socktype, res->ai_protocol); if (sock < 0) continue;

if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) { close (sock); continue; } break;}freeaddrinfo(res0);・・・

출처 : http://www.ipv6style.jp/jp/apps/20030617/index.shtml

Page 54: Ipv6 소켓프로그래밍

코드 - IPv6 서버 (Win32 API)#include ‹winsock2.h› #include ‹ws2tcpip.h› #include ‹stdio.h› #include ‹process.h›

void tcp_echo_io(void *arg);

int main(int argc, char *argv[]) { WSADATA wsaData; int i; char *servname = "echo"; ADDRINFO hints; LPADDRINFO ai, ai0; int e; SOCKET s[64]; int nsocks; fd_set rfd0;

if (WSAStartup(MAKEWORD(2, 2), &wsaData)) { fprintf(stderr, "can not initilize WinSock\n"); exit(1); }

memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; if (e = getaddrinfo(NULL, servname, &hints, &ai0)) { fprintf(stderr, "%s\n", gai_strerror(e)); exit(1); }

Page 55: Ipv6 소켓프로그래밍

for (nsocks = 0, ai = ai0; ai; ai = ai->ai_next) { s[nsocks] = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (s[nsocks] == INVALID_SOCKET) continue;

if (bind(s[nsocks], ai->ai_addr, ai->ai_addrlen) == SOCKET_ERROR) { closesocket(s[nsocks]); s[nsocks] = INVALID_SOCKET; continue; }

if (listen(s[nsocks], 5) == SOCKET_ERROR) { closesocket(s[nsocks]); s[nsocks] = INVALID_SOCKET; continue; }

nsocks++;

printf("create %s listen socket\n", (ai->ai_family == AF_INET) ? "IPv4" : (ai->ai_family == AF_INET6) ? "IPv6" : "Unknown"); }

if (nsocks == 0) { fprintf(stderr, "can not create listen socket with any protocol\n"); exit(1);}

Page 56: Ipv6 소켓프로그래밍

FD_ZERO(&rfd0); for (i = 0; i < nsocks; ++i) FD_SET(s[i], &rfd0);

while (1) { fd_set rfd; SOCKET iosock; SOCKADDR_STORAGE ss; int sslen;

rfd = rfd0; if (select(FD_SETSIZE, &rfd, NULL, NULL, NULL) == SOCKET_ERROR) { fprintf(stderr, "select error\n"); exit(1); }

for (i = 0; i < nsocks; ++i) { if (FD_ISSET(s[i], &rfd)) { sslen = sizeof(ss); iosock = accept(s[i], (LPSOCKADDR)&ss, &sslen); if(iosock == INVALID_SOCKET) { fprintf(stderr, "accept error\n"); exit(1); }

if (_beginthread(tcp_echo_io, 0, &iosock) == -1) { fprintf(stderr, "can not create thread\n"); exit(1); } } } }

Page 57: Ipv6 소켓프로그래밍

void tcp_echo_io(void *arg) { SOCKET s; char buf[BUFSIZ]; int bufsiz;

printf("start thread\n");

s = *(SOCKET *)arg;

while ((bufsiz = recv(s, buf, sizeof(buf) - 1, 0)) != 0) { if (bufsiz == SOCKET_ERROR ) break;

buf[bufsiz] = '\0'; printf("recv string: %s\n", buf);

if (send(s, buf, bufsiz, 0) == SOCKET_ERROR) break;

printf("send string: %s\n", buf); }

printf("end thread\n");

closesocket(s); _endthread(); }

출처 : http://www.ipv6style.jp/jp/apps/20051128/index.shtml

Page 58: Ipv6 소켓프로그래밍

코드 - IPv6 클라이언트 (Win32 API)

#include ‹winsock2.h› #include ‹ws2tcpip.h› #include ‹stdio.h›

int main(int argc, char *argv[]) { WSADATA wsaData; char *nodename; char *servname = "echo"; ADDRINFO hints; LPADDRINFO ai, ai0; int e; SOCKET s; char linebuf[BUFSIZ];

if (argc != 2) { fprintf(stderr, "syntax: tcp-echo-client servername ¥ n"); exit(1); } nodename = argv[1];

if (WSAStartup(MAKEWORD(2, 2), &wsaData)) { fprintf(stderr, "can not initilize WinSock ¥ n"); exit(1); }

Page 59: Ipv6 소켓프로그래밍

memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if (e = getaddrinfo(nodename, servname, &hints, &ai0)) { fprintf(stderr, "%s ¥ n", gai_strerror(e)); exit(1); }

for (ai = ai0; ai; ai = ai->ai_next) { s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (s == INVALID_SOCKET) continue;

if (connect(s, ai->ai_addr, ai->ai_addrlen) == SOCKET_ERROR) { closesocket(s); s = INVALID_SOCKET; continue; }

printf("connected ¥ n"); break; }

if (s == INVALID_SOCKET) { freeaddrinfo(ai0); WSACleanup(); fprintf(stderr, "can not connect server(%s) ¥ n", nodename); exit(1); }

Page 60: Ipv6 소켓프로그래밍

while (fgets(linebuf, sizeof(linebuf), stdin) != NULL) { if (send(s, linebuf, strlen(linebuf), 0) == SOCKET_ERROR) { fprintf(stderr, "send error ¥ n"); exit(1); }

if (recv(s, linebuf, sizeof(linebuf), 0) == SOCKET_ERROR) { fprintf(stderr, "recv error ¥ n"); exit(1); } printf(linebuf); }

freeaddrinfo(ai0); WSACleanup(); }

출처 : http://www.ipv6style.jp/jp/apps/20051114/index.shtml

Page 61: Ipv6 소켓프로그래밍

1. IPv6 에 대한 이론 공부

2. 플밍 시작 - IP 문자열 키우기 - IPv4 와 IPv6 둘 다 사용할 수 있도록 네트웍 라이브러 변경 - IPv6 호환 Socket API 변환 - IP 주소 문자열을 정수로 변환하여 사용하는 것 모두 제거

3. 테스트 - 테스트할 PC 의 네트웍 환경을 IPv6 으로 변경

GunZ2 의 네트웍 라이브러에 IPv6 추가 지원 작업

Page 62: Ipv6 소켓프로그래밍

참고

IPv6 개요 ( 한국어 )http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/TCP_IP/IPv6/IPv6Intro

IPv6 프로그래밍 ( 한글 )http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/TCP_IP/IPv6/IPv6Prog

5 분으로 이해하는 IPv6 프로그래밍 ( 일본어 )http://www.ipv6style.jp/jp/apps/20030617/index.shtml

IPv6 소켓 프로그래밍 ( 일본어 )http://www.nslabs.jp/socket.rhtml

Windows 에서의 IPv6 소켓 프로그래밍 강좌 ( 일본어 )http://www.admintech.jp/wiki.cgi?page=Windows%A4%C7%A4%CEIPv6%A5%D7%A5%ED%A5%B0%A5%E9%A5%DF%A5%F3%A5%B0%B9%D6%BA%C2

문제로 풀어보는 IPv4 와 IPv6 ( 일본어 )http://www.ie.u-ryukyu.ac.jp/~e055723/info2/ipv6/main.html

Page 63: Ipv6 소켓프로그래밍

Introduction to IPv6 Programming ( 영어 )http://www.euchinagrid.org/IPv6/IPv6_presentation/Introduction_to_IPv6_programming.pdf

IPv6 으로 시작하는 네트워크 ( 일본어 )http://journal.mycom.co.jp/series/ipv6/001/index.html

IPv6 위키피디아 ( 일본어 )http://ja.wikipedia.org/wiki/IPv6#cite_note-5

Windows 7 에서 IPv6 환경 설정 ( 일본어 )https://ybb.softbank.jp/support/connect/step2/ipv6/win7_net_set.html

IPv6_Vasily ( 한글 . 블로그 )http://blog.daum.net/ipv6

MS TechNet – IPv6http://technet.microsoft.com/ko-kr/library/cc755011%28WS.10%29.aspx