More Related Content Similar to Ipv6 소켓프로그래밍 (20) More from Heo Seungwook (16) Ipv6 소켓프로그래밍1. IPv6 이론과 소켓 프로그래밍 마이에트 엔터테인먼트 건즈팀 서버 프로그래머 최흥배 MS Visual C++ MVP Twitter : @jacking75 22. 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 28. 0:0:0:0:0:0:0:1- 루프백 주소. IPv4의 127.0.0.1에 해당- IPv4에서는 12.0.0.0/8 범위의 주소를 사용할 수 있지만 IPv6에서는 이 주소만 사용할 수 있다- 줄여서 ‘0::1’ 또는 ‘::1’ 34. IPv6/IPv4 클라이언트 -> IPv4만 지원 IPv4 서버 출처: http://www.euchinagrid.org/IPv6/IPv6_presentation/Introduction_to_IPv6_programming.pdf 35. IPv6/IPv4 클라이언트 -> IPv6만 지원 IPv6 서버 출처: http://www.euchinagrid.org/IPv6/IPv6_presentation/Introduction_to_IPv6_programming.pdf 36. IPv6/IPv4 클라이언트 -> Dual StackIPv4 서버 출처: http://www.euchinagrid.org/IPv6/IPv6_presentation/Introduction_to_IPv6_programming.pdf 37. IPv6/IPv4 클라이언트 -> Dual StackIPv6 서버 출처: http://www.euchinagrid.org/IPv6/IPv6_presentation/Introduction_to_IPv6_programming.pdf 38. IPv6/IPv4 클라이언트 -> Separated StackIPv6-only, IPv4-only 서버 출처: http://www.euchinagrid.org/IPv6/IPv6_presentation/Introduction_to_IPv6_programming.pdf 39. IPv6/IPv4 클라이언트 -> IPv4만 지원 IPv4 서버 출처: http://www.euchinagrid.org/IPv6/IPv6_presentation/Introduction_to_IPv6_programming.pdf 43. 변환- IPv6 to IPv4 또는 IPv4 to IPv6으로 패킷을 재조합 하는 방식출처: http://blog.daum.net/ipv6/24 46. 1990년대 초 ST를 개선하여 ST-II를 개발. IPv5의 패킷 구조를 그대로 사용IP 주소 부족 문제 해결은 그대로 안고 감 54. 이 때의 고갈의 의미는 ICANN에서 각 대륙 별 주소 관리 기구에 주소 할당을 다했다는 의미로 지금 IPv4 주소가 더 이상 없다는 뜻이 아니다 55. ICANN은 대륙 별 주소 관리 기구에 인터넷 주소를 줄 때 큰 하나의 덩어리를 주는데 이 덩어리의 크기는 약 1700만개 정도의 인터넷 주소이다. 60. 또 관리자 중 NAT을 내부와 외부 네트워크를 분리하는 보안 기술이라는 생각을 가지고 있음 61. 특히 최근의 CGN, LSN 등의 3중 NAT는 어뷰즈로깅, 위치 추적, NAT Traversal 기능도 못 쓰게 만듬 62. NAT은 웹브라우징 이나 이메일 등의 일반 웹 서비스에는 문제가 없지만 온라인 P2P 게임, 비드오스트리밍, 웹갬, 터널링, VPn, VoIP에서 품질 저하나 서비스가 불가능 하는 경우가 있다 65. IPv6은 IPv4 보다 보안이 더 뛰어나지만 아직 보급된 시장이 작아서 IPv4에 비해 보안 관련 장비가 부족함 67. 이 행사의 목적은 24시간 동안 IPv6 웹 사이트를 올려서 전 세계에서 접속이 가능한지 테스트 및 운영, 또 IPv4 주소가 부족하다는 것을 알리고 IPv6 도입을 촉진 시키기 위해서이다 69. API - IPv6 관련 구조체 #include <netinet/in.h> structsockaddr_in { in_port_tsin_port; // Port 번호 struct in_addrsin_addr; // 인터넷 주소 구조체 } structin_addr { in_addr_ts_addr; // 32bit 크기의 인터넷주소 } IPv4 #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 information struct in6_addr sin6_addr;// IPv6 주소 u_long sin6_scope_id; // 인터페이스 인덱스 아이디 } IPv6 출처 : http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/TCP_IP/IPv6/IPv6Prog 70. API - socket IPv4 IPv6 s = 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 71. 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, (structsockaddr *)&sin6, sizeof(sin6)) == -1) { // 에러처리 } .... 출처 : http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/TCP_IP/IPv6/IPv6Prog 72. API – listen, accept (IPv6) listen 변환 없음 accept struct sockaddr_in6 clisin6; clisockfd = accept(sockfd, (structsockaddr *)&clisin6, (socklen_t *)&clilen); 출처 : http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/TCP_IP/IPv6/IPv6Prog 73. API – inet_addr, inet_ntoa inet_addr inet_pton inet_ntop inet_ntoa WSAAddressToString inet_addr는 32비트, inet_pton는 128비트 그러나 C++에서의 최대 정수의 크기는 64비트 !!!inet_pton, inet_ntop는 Windows Vista부터 지원 74. 코드-IPv6 주소 얻기 (Win32 API) #include ‹winsock2.h› #include ‹ws2tcpip.h› #include ‹stdio.h› int main(intargc, char *argv[]) { char *nodename; WSADATA wsaData; ADDRINFO hints; LPADDRINFO ai, ai0; int e; if (argc != 2) { fprintf(stderr, "syntax: getv6addr HOSTNAME"); 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", 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", nodename, v6addrstr); } freeaddrinfo(ai0); WSACleanup(); } 출처: http://www.ipv6style.jp/jp/apps/20051024/index.shtml 75. 코드-IPv6 주소 얻기 (Win32 API) #include ‹winsock2.h› #include ‹ws2tcpip.h› #include ‹stdio.h› int main(intargc, 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 77. IPv4만 대응하는 경우 보통 IPv4 주소를 기록한 A 레코드만 DNS 서버에 등록. 듀얼스택의 경우 여기에 IPv6 주소를 기록한 AAAA 레코드를 기록. 78. IPv4와 IPv6 둘 다 대응하는 프로그램은- AAAA 레코드에 등록된 IPv6 주소 접근을 시도- AAAA 레코드 접속이 실패하면 A 레코드 주소로 접근 80. 코드-IPv6 서버 (Win32 API) #include ‹winsock2.h› #include ‹ws2tcpip.h› #include ‹stdio.h› #include ‹process.h› void tcp_echo_io(void *arg); int main(intargc, char *argv[]) { WSADATA wsaData; int i; char *servname = "echo"; ADDRINFO hints; LPADDRINFO ai, ai0; int e; SOCKET s[64]; intnsocks; fd_set rfd0; if (WSAStartup(MAKEWORD(2, 2), &wsaData)) { fprintf(stderr, "can not initilize WinSock"); 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", gai_strerror(e)); exit(1); } 81. 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", (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"); exit(1); } 82. FD_ZERO(&rfd0); for (i = 0; i < nsocks; ++i) FD_SET(s[i], &rfd0); while (1) { fd_setrfd; SOCKET iosock; SOCKADDR_STORAGE ss; intsslen; rfd = rfd0; if (select(FD_SETSIZE, &rfd, NULL, NULL, NULL) == SOCKET_ERROR) { fprintf(stderr, "select error"); 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"); exit(1); } if (_beginthread(tcp_echo_io, 0, &iosock) == -1) { fprintf(stderr, "can not create thread"); exit(1); } } } } 83. void tcp_echo_io(void *arg) { SOCKET s; char buf[BUFSIZ]; intbufsiz; printf("start thread"); s = *(SOCKET *)arg; while ((bufsiz = recv(s, buf, sizeof(buf) - 1, 0)) != 0) { if (bufsiz == SOCKET_ERROR ) break; buf[bufsiz] = ''; printf("recv string: %s", buf); if (send(s, buf, bufsiz, 0) == SOCKET_ERROR) break; printf("send string: %s", buf); } printf("end thread"); closesocket(s); _endthread(); } 출처: http://www.ipv6style.jp/jp/apps/20051128/index.shtml 84. 코드-IPv6 클라이언트 (Win32 API) #include ‹winsock2.h› #include ‹ws2tcpip.h› #include ‹stdio.h› int main(intargc, 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); } 85. 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); } 86. 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 87. GunZ2의 네트웍라이브러에IPv6 추가 지원 작업 1. IPv6에 대한 이론 공부 2. 플밍 시작 - IP 문자열 키우기 - IPv4와 IPv6 둘 다 사용할 수 있도록 네트웍라이브러변경 - IPv6 호환 Socket API 변환 - IP 주소 문자열을 정수로 변환하여 사용하는 것 모두 제거 3. 테스트 - 테스트할 PC의 네트웍 환경을 IPv6으로 변경 88. 참고 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 89. 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 – IPv6 http://technet.microsoft.com/ko-kr/library/cc755011%28WS.10%29.aspx