Comments
Description
Transcript
課題説明のPDF
情報ネットワ ク演習 情報ネットワーク演習 2009年10月8日(木) 本日の内容 課題5 HTTPクライアント ハイパーテキストへのアクセス 課題4 HTTPサ バのビルド HTTPサーバのビルド 課題3 ソケットを用いた プロセス間通信 課題1 低水準入出力 課題2 名前解決 (ホスト名⇔IPアドレス) 2 第2回課題 • 実施内容と意図 IPアドレスとホスト名の相互変換をするプログラムを拡張 する. この課題を通じて,IPv4における名前解決の方法,および 関連するライブラリル チンや構造体の仕様を学ぶ. 関連するライブラリルーチンや構造体の仕様を学ぶ. 3 ホスト名とは • 例 nachi00 nachi00 sys wakayama-u nachi00.sys.wakayama u.ac.jp ac jp www.wakayama-u.ac.jp www google co jp www.google.co.jp localhost • 書式 英数字等を「.」でつなぐ. 英数字等を .」でつなぐ. 演習室内では これらは同じ計算機 (ホスト ノード) (ホスト,ノ ド) を指す FQDN (Fully Qualified Domain Name)と呼ば れる • 人間にとって見やすい. 4 IPアドレスとは(文字列) • 例 133.42.159.1 66 249 89 104 66.249.89.104 127.0.0.1 32ビット • 書式 0~255の整数を4つ書き,「.」でつなぐ. • ドット付き10進記法(dotted decimal notation)ともい う. • 人間にとって見やすい. 5 IPアドレス(バイナリ) • 例 10000110 00101010 10011111 00000001 • 文字列によるIPアドレスを4オクテット(4バイト)で表 現し,順番に(ネットワークバイトオーダ,またはビッ グエンディアン)メモリに格納する. グエンディアン)メモリに格納する • 計算機が処理するのに適している. 6 IPアドレスとホスト名を知るコマンド • host Vine Linuxでも利用可 host nachi00 host 133.42.159.1 host www www.google.co.jp google co jp • nslookup 古いコマンド.最近のLinuxでは非推奨 7 DNS (Domain Name System) • インターネットにおけるホスト名とIPアドレスとを対応 させるシステム ホスト名 ⇒ IPアドレス を を「正引き」 正引き」, IPアドレス ⇒ ホスト名 を「逆引き」という. • 「DNSサーバ」に「リゾルバ(resolver)」が問い合わせ て情報を得る. DNSサーバ間で情報交換をすることも バ 演習室環境で,通信するDNSサーバを知りたければ cat /etc/resolv.conf • ソフトウェアではBIND (Berkeley Internet Name Domain)が有名 8 ホスト名とIPアドレスは多対多 「多対多」は 二つの 「 対多 に 「一対多」に 分ける 一つのホスト名に 複数のIPアドレス ホスト名とIPアドレスは 一対多 www.l.google.com 66.249.89.99 www.google.com 66.249.89.103 www.google.co.jp 66.249.89.104 66 249 89 147 66.249.89.147 mail.sys.wakayama-u.ac.jp ntp.sys.wakayama-u.ac.jp 133.42.159.1 ns.sys.wakayama-u.ac.jp dns.sys.wakayama-u.ac.jp 一つのIPアドレスに 複数のホスト名 IPアドレスとホスト名は 一対多 9 ホスト名とIPアドレスの変換の使い道 • 実用上は ホスト名からIPアドレスの一つ, IPアドレスからホスト名の一つ(正式なホスト名) を求めれば十分 • 利用例は クライアント: サーバのホスト名 ⇒ IPアドレス サ バ 例えばアクセスをログに記録する際, サーバ: 例えばアクセスを グに記録する際 クライアントのIPアドレス ⇒ ホスト名 10 IPv4とIPv6 • 本演習では,IPv4のみを対象とする. • IPv4 アドレス長: 32ビット (アドレス空間: 232) • IPv6 アドレス長: 128ビット (アドレス空間: 2128) IPアドレスは「.」ではなく「:」で区切って表記する. ア 」 なく 」 区切 表記する 省略記法もある. IPv6に移行しても,ホスト名は変わらない 11 相互変換プログラムをCで書くには • 数個のライブラリルーチンと構造体を理解すること ライブラリルーチン: getaddrinfo, getnameinfo, freeaddrinfo 構造体: struct addrinfo DNSサーバへ直接通信する処理は不要(ライブラリルー DNSサ バへ直接通信する処理は不要(ライブラリル チンに任せる) 12 g getaddrinfoライブラリルーチン • int g getaddrinfo(const ( char *node,, const char *service, const struct addrinfo *hints, struct addrinfo **res); res); ソケットアドレス構造体を生成する. node d は,「ホスト名」または「文字列形式のIPアドレス」. は 「ホスト名」または「文字列形式のIPアドレス」 serviceは,サービス名もしくはポート番号の文字列. 今回は 今回はNULLにする. にする hintsに,ヒント情報を格納して呼び出す(ポインタ渡し). resはソケットアドレスのリストのポインタのポインタ. あらかじめstruct addrinfo *型のポインタ変数を確保した 上で「&変数」と書く(ポインタ渡し). 13 addrinfo構造体 structは不可欠(「struct t tは不可欠(「 t t addrinfo型」を宣言している) dd i f 型」を宣言している) struct addrinfo { i int ai_flags; i int ai_family; int ai_socktype; i t int ai_protocol; i t l size_t ai_addrlen; struct sockaddr *ai_addr; char *ai *ai_canonname; canonname; struct addrinfo *ai_next; }; • 戻り値(線形リスト) . . . ai_addr: _ 133042159002 . . . ai_next: /* / /* /* /* /* /* /* /* フラグ */ / プロトコルファミリ */ TCP, UDPの別 */ プロトコル詳細 */ ai_addrのバイト数 */ IPアドレス(バイナリ) */ ホスト名文字列 */ 次へのリンク */ 実際にはバイナリ形式 適切なホスト名 が格納されて いる保証はない . . . ai_addr: 133042160002 . . . ai_next: NULL 14 g getnameinfoライブラリルーチン • int g getnameinfo(const ( struct sockaddr *sa,, socklen_t salen, char *host, size_t hostlen, char serv, size_t size t servlen, servlen int flags); *serv アドレスから名前へ変換する. saはIPアドレス(バイナリ),salenはその長さ. はIPアドレス(バイナリ) l はその長さ • addrinfo構造体のai_addr, ai_addrlenに対応する. hostに結果が格納される.配列などにより,あらかじめ領 に結果が格納される 配列などにより あらかじめ領 域を確保しておく.hostlenはその長さを指定する. servとservlenは,hostとhostlenと同様.今回は使用しな いので,NULLと0を指定する. flagsが0なら,ホスト名を得る(時間がかかることも). flagsをNI_NUMERICHOSTとすると…自習すること. 15 再入可能性 • IPアドレスから文字列を得るライブラリルーチン inet_ntoaは,再入可能でない. 配列領域を別のところで(静的領域などに)確保しており, 配列領域を別のところで(静的領域などに)確保しており そのアドレスを返す. 連続して呼び出すと 前の結果は上書きされる 連続して呼び出すと,前の結果は上書きされる. • getaddrinfo,getnameinfoは,再入可能である. 連続して呼び出しても,問題ない. 戻り値の領域を,呼び出し側で確保しておき,引数に与え る.ポインタ渡し(参照渡し)になる. getaddrinfoの処理で,mallocなどによりソケットアドレス 構造体が作られる.開放するには,(freeではなく) freeaddrinfoを呼び出す. eeadd oを呼び出す 16 そもそもなぜgetaddrinfo,getnameifoか? g g • IPアドレスとホスト名の相互変換プログラムを書く古 典的な方法は,gethostbyname,gethostbyaddrと いったライブラリ関数を使用することである これは いったライブラリ関数を使用することである.これは, IPv4にしか対応してしておらず,また再入可能でな い(連続して呼び出せない)といった問題があった. い(連続して呼び出せない)といった問題があった • getaddrinfoは,再入の問題がないだけでなく, IPv4/IPv6の両方に対応する.さらに,第3回課題の サ サーバプログラムがすっきり記述できるようになる. グラ す きり記述できるよう なる 17 課題2(1) • ~takehiko/network-enshu2009/2/resolver.c は,ホ スト名またはIPアドレスを引数にとり,そのIPアドレス とホスト名の ア(複数あっても 組だけ)を出力す とホスト名のペア(複数あっても一組だけ)を出力す るプログラムである. (コンパイルしてresolverを作る) ./resolver nachi00.sys.wakayama-u.ac.jp • 133.42.125.50 133 42 125 50 ((nachi00.sys.wakayama-u.ac.jp) hi00 k j ) ./resolver www.google.com • 66.249.89.104 (nrt04s01-in-f104.google.com) host www.google.com ...結果は各自確認のこと 18 課題2(2) • ~takehiko/network ~takehiko/network-enshu2009/2/resolver.c enshu2009/2/resolver c をコピ ーして ~/network-enshu2009/2/resolver.c とし,以 下の仕様を満たすよう 修正をしなさい 下の仕様を満たすよう,修正をしなさい. ホスト名が複数のIPアドレスに結び付けられているとき, IPアドレス(のビット列)に関して昇順で出力する. 見つかったIPアドレスが0個または1個のときは,修正前と 同じ出力とする. ファイル先頭のコメント ファイル先頭の メント (作成者,作成日時) を変更し,末 尾に作業メモを残す. ディレクトリのパーミッションは705 ディレクトリのパ ミッションは705,ファイルは604にして ファイルは604にして おくこと. 19 課題2(3) • プログラムが完成したと思ったら, グラ 完成 思 , ~takehiko/network-enshu2009/2/command?? の 各コマンドを実行し 妥当な出力になることを確かめ 各コマンドを実行し,妥当な出力になることを確かめ ること.さらに,以下のコマンドを実行するとよい. ~takehiko/network-enshu2009/bin/validator1 t k hik / t k h 2009/bi / lid t 1 ~takehiko/network-enshu2009/bin/validator2 20 期限 • 2009年10月8日(金)19:30の回収までに完成させて おくこと. • 期限後のプログラム修正は? 最終的な回収までの修正(コメントの充実,デバッグなど) はOK. はOK 21 線形リストのソート方法(1) • 初期状態 HEAD key: 4 next: key: 2 next: key: 1 next: key: 3 next: NULL 22 線形リストのソート方法(2) • ポインタの配列を確保し,順に代入 代 HEAD key: 4 next: key: 2 next: key: 1 next: key: 3 next: NULL 線形リストを1回走査して要素数(この例では4)を求めて から,配列領域をmallocで確保し,用意しておいた(リスト の要素のポインタのポインタとなる)変数に代入する. ポインタの配列には 線形リストの各要素へのリンクを順 ポインタの配列には,線形リストの各要素へのリンクを順 に代入する(既存の に基づき,同じ箇所を指し示す). 23 線形リストのソート方法(3) • ポインタの配列をソート HEAD key: 4 next: key: 2 next: key: 1 next: key: 3 next: NULL ソートのためのキーは,指し示す先の(構造体の)メンバ keyの値. このソートでは,構造体の値を含め, の値は一切変 わらない わらない. の値(指し示す先)が変わる の値(指し示す先)が変わる. 今回の課題では,要素数が多くならないので,バブルソー トなどを直接書いてもよいが ライブラリ関数のqsortと トなどを直接書いてもよいが,ライブラリ関数のqsortと memcmpを組み合わせると簡潔に書ける. 24 線形リストのソート方法(4) • ポインタの配列の順に,リンクを付け替え HEAD key: 4 next: NULL key: 2 next: key: 1 next: key: 3 next: この付け替えでは,リスト各要素のメンバnextの値(次を 指し示す矢印)が変わる. 以上の処理により,リストの各要素(構造体)のコピーや 交換をすることなく 以下と同じ内容のデータ構造が得ら 交換をすることなく,以下と同じ内容のデ タ構造が得ら れた(線形リストをソートした)ことになる. HEAD key: 1 next: key: 2 next: key: 3 next: key: 4 next: NULL 25