プログラミングを 特集 1 めよう ! 2 レスと 1 つの IPv4 アドレスが登録されて り、引数にはアドレスファミリーに依 し元に返す働きをする。 いる。したがって、このホスト名を 存した情報がない。アプリケーション 17-26 行で、 getaddrinfo(3) を用いてホ nodename とし、 AF_UNSPEC を hints の としては、与えられたソケットアドレ スト名から IP アドレスを解決する。 18 ai-family に指定して getaddrinfo(3) を呼 ス構造体のアドレスファミリーを気に 行目で、 hints. ai_family に AF UNSPEC び出せば、少なくとも 3 つの要素から せすに、そのホスト名やサービス名に を指定する点が重要である。これによ なるリストが res として返る ( 図 4 ) 。 対応する文字列を得られる。 り、 IPv4 と IPv6 を単一のプログラムで getaddrinfo(3) の逆に相当する関数が アドレスファミリーに依存しない、 同時に扱える。 getnameinfo(3) である。そのプロトタイ 一般性のあるプログラミングのために アドレス解決に成功したら、 getaddr プを図 5 に示す。 これらのライプラリをうまく使う必要 inf 。 ( 3 ) が返したリストを順にたぐって がある。 getnameinfo(3) は、ソケットアドレス ソケットを開き ( 29 行 ) 、 connect(2) を 構造体を入力として受け取り、対応す 試みる ( 33 行 ) 。 で、 connect(2) の るホスト名とサービス名を文字列とし サーバークライアント型モデル 第 3 引数として ai->ai_addrlen を利用し て返す働きをする。 におけるコネクション確立の例 ている点に注意してほしい。 BSD 系の getaddrinfo( 3 ) および getnameinfo ( 3 ) の こでは、サーバークライアント型 システムであれば 、ここで、 ai->ai addr- 最大の特徴は、アドレスファミリ モデルにおけるコネクション確立を想 >sa-len を利用しても同じ結果が得られ 依存しない設計になっていることであ 定して、 IPv6 を用いたネットワークプ るが、ソケットアドレス構造体に る。たとえば、 getaddrinfo(3) が返す ログラムの実例を示す。以下の例では、 sa 」 en メンバを持たないシステムに対す addrinfo 構造体には一般のソケットア そのまま雛形として使えるように、工 る移植性が損なわれてしまう。 ドレス構造体が格納されており、これ ラー処理も見通しを損なわない範囲で connect ( 2 ) に成功すればループを抜け はそのまま connect(2) や sendto(2) といっ 正確を期した。 ( 34 行 ) 、接続したソケットを呼び出し たシステムコールの引数として利用で まず、リスト 2 で示したクライアント 元に返す。一方、経路が不安定な場合 きる。すなわち、各々のアプリケーシ 側プログラム tcp_connect() について説 など、何らかの理由により connect(2) に ョンが sockaddr in6 構造体の各メンバ 明する。この関数は、ホスト名とポー 失敗した場合には、そのソケットを閉 を埋める必要はない。 ト番号を受け取って TCP コネクション じて ( 36 行 ) 、次のアドレスでの接続 getnameinfo(3) についても同様であ を確立し、対応するソケットを呼び出 を試みる。図 5 の例では、まず 3ffe …の IPv6 アドレスに対して接続を試みる。 もしこれが時間切れになれば、次に 2 0 0 1 ... の I P v 6 アドレス、最後に 203.178.14L212 の IPv4 アドレスという 順で接続しようとする。このように 接続先の候補として異なるファミリー のアドレスが混ざっていても、プログ ラム上でそれを意識する必要はない。 getaddrinf 。 ( 3 ) がそれを吸収して一般の ソケットアドレス構造体として渡して くれるからである。 なお、 36 行で、失敗したソケットを 閉じてからループを続けている点は重 要である。これを忘れると不必要なソ ケットが開いたままで放置されてしま 注 3 仕様上は IP 以外のプロトコルも含まれるが、 BSD の実装上は IPv4 と 1Pv6 のみ対応している。また現状のネットワーク環境においては、実際上もそれで十分 であろう。 50 ma azine N07 addrinfo{} AF_INET6 sockaddr in6 3ffe : 501 : 4819 : 2000 : 5054 : ff : fe 面 : 50d2 addrinfo{} AF_INET sockaddr in 203.178.141.212 addrinfo{} AF INET6 sockaddr in6 2001 : 200 : 0 : 4819 : 5054:ff:fedc:50d2 NULL 図 4 www.kame.net に対する getaddrinfo(3) の結果 ( 旧 6 アドレスは折り返して表示 ) int getnameinfo (const struct sockaddr *sa, socklen_t salen, char *host , size_t hostlen, Char *serv, size_t servlen, int flags) ; 図 5 getnameinfo(3) 関数 BSD magazine 087 2001 NO. 7
り、一度バグ入りのプログラムを書い てしまうとデバッグに長時間苦しむ結 果となる。 このようなバグを防ぐためには、 sockaddr-storage 構造体を利用するとよ い。この構造体は、各システム上でサ ポートするすべてのアドレスファミリ ー用のソケットアドレス構造体を収容 できるサイズを持つ。したがって、 sockaddr-storage 構造体を実体としてメ モリ上に確保した後は、サイズを気に せずにそのポインタを任意のアドレス ファミリー依存ソケットアドレス構造 体へのポインタにキャストできる。リ スト 3 に示したバグを、 sockaddr st 。 rage 構造体を用いて修正したプログ ラムがリスト 4 である。 一般に、 sockaddr 構造体を実体とし て利用するのは危険である。実体には 常に sockaddr—storage 構造体を用い、 sockaddr 構造体はポインタとしてのみ 利用するという方針を徹底することで、 よりバグの少ない、安全なプログラム となる。 IPv6 対応アプリケーションの プログラミング時には、この原則を貫 くことをお勧めする。 旧アドレスとホスト名の解決 : getaddrinfo(3) と getnameinfo(3) 経路制御のアプリケーションや診断 用のツールは別として、通常のネット ワークアプリケーションは IP アドレス をユーザーからの入力として直接受け 取ることはない。ユーザーは "www. kame. net" といったホスト名をアプリケ ーションに渡し、アプリケーションが それを IP アドレスに変換する。また、 IP アドレス自体が与えられた場合でも、 最終的には文字列としての表記からソ ケットアドレス構造体に格納するバイ ナリ形式に変換する必要がある。 逆に、たとえばアクセスの記録を取 るなどの目的で、バイナリ形式のアド レスから文字列としてのアドレス表記 へ、さらには対応するホスト名への変 換が必要になる場合もある。 これらの機能を提供するライプラリ 関数はいくっか定義されているが、 こでは、 IPv6 への対応、さらには一般 性のあるプログラミングを考えたとき に最も強力で使いやすい 2 つを紹介す る。ホスト名をアドレスに変換する getaddrinfo(3) と、アドレスをホスト名 に変換する getnameinfo(3) である。 getaddrinfo(3) のプロトタイプを図 2 に示す。 nodename がホスト名、 servname は 'http" のようなサービス名、または " 80 " のようなポート番号文字列である。さ らに、 IPv4 、 IPv6 といったネットワー クプロトコルや、 TCP 、 UDP のような トランスポートプロトコルを指定する ための付加情報として hints という引数 が与えられる。 hints の型である addrmfo 構造体を図 3 に示す。 hints で指定するのは、通常、 ai- family 、 al socktype 、 ai—protocol の 3 つ である。それぞれ、ネットワークプロ トコル、ストリーム型かデータグラム 型かのソケット種別、トランスポート プロトコルを表す。また、用途によっ ては ai-flags にさらに情報を追加する場 合もある。 getaddrinfo(3) は、変換に成功したか どうかを返り値とし、成功した場合に は res に addrinfo 構造体のリストを格納 する。リストの各要素の ai addr メンバ が、与えられた情報に対応するソケッ トアドレス構造体を指す。 getaddrinfo(3) の第 2 引数 hints の ai—family メンバに AF UNSPEC を指定 すれば、 IPv4 と IPv6 の両方のアドレス を同時に要求できる注 3 。たとえば、 www.kame.net" というホスト名に対し て、 DNS 上には実際に 2 つの IPv6 アド int getaddrinfo (const char *nodename , const char *servname , const struct addrinfo *hints , struct addrinfo **res) ; struct addrinfo int int int int size_t char struct struct s 0 ckaddr addr inf 0 図 2 getaddrinfo(3) 関数 al—flags; al—family ; al—socktype ; al—protocol ; ax_addrlen; 図 3 addrinfo 構造体 *ai—next ; *ai_addr ・ *ai_canonname ; 086 BSD magazine 2001 NO. 7
フロジェクト短信 PAO Report FreeBSD 4. x と PAO ますが、あらためて、この場を借りて記載させていただこ として十分ではないことは既にご存じの方も多いとは思い が単独で走り回っているように感じています。これは情報 最近「 PA04 というものは存在しない」という情報だけ うと思います。 のだまさひで / M NODA mac@clave.gr.jp.mac@jp.FreeBSD.0「g PA04 、つまり 4. x 系のプランチに対する PAO パッチとい うものはたしかに存在しません。しかし、だからといって それが、すなわちノート pc で 4. x 系の FreeBSD が使用でき ないということに直結するもの、ではありません。 4. x 系に は PAO の機能がほばすべてマージされており、 PAO パッチ の必要はないのです。 これまでの PAO が持っていた PC カードや APM に対する パッチはすでにそのほとんどが FreeBSD にマージされ、素 の FreeBSD がすでに PAO 相当のものになっているのです。 もし FreeBSD 4. x が利用できないノート PC があったとして も、それは、 PAO がないから利用できないのではなく、 ( PAO がマージされた ) FreeBSD 4. x がそのノート pc への対 応が完了していないためなのです。 デスクトップだけでなくノート pc も次々と新しいもの注 1 が出荷されますが、それらが常に FreeBSD で動作するかど うかはわかりません。もしかしたら動かないかもしれませ ん。が、それカ働かすに終わる注 2 か、動くようになるかは、 あなたの持つ情報に左右されるのです。新しいノート pc で新しいリリースへ挑戦することで、新たな不具合や気に なる点を発見し、どんどん報告していきましよう。そして、 愛する FreeBSD をよりよいものにしていきましよう。 PA03 fo 「 3-STABLE PA03 にはこの 3 か月間特に大きな変更は加えられていま せんが、適当な間隔 ( およそ 1 か月から 2 か月 ) で 3 - STAB LE との同期が取られています。ノート pc で 3 - STABLE を利用するケースなどでは重宝するでしよう。 利用方法ですが、これまでのようにリリースとして出さ れることはないので、 cvsup / cvs などで取得するか、 snapshot を利用することになります。詳しくは PAO project のページ注 3 をご覧ください。 4-STABLE pc カードの認識 / 活性機構については、ほば、 PA03 と 同等のものになりました。あのカード挿入時のメロディー もマージされています。 ドライバの追加や改良も行われています。 ray ドライバが新規に追加されました。 ray ドライバは Raytheon Raylink の IEEE 802.11 無線 LAN カード用のドラ イバです。原稿執筆時では、 GENERIC カーネルなどには 含まれていないため、利用するためにはカーネル再構築を 行うか、カーネルモジュールを利用する必要があるでしよ ed ドライバには Linksys カード問題を解消するためにフ ラグが設けられました。 ed を使うカードには大きく数種類 のものがあり、それぞれ固有の初期化などの処理を行う必 要があります。そのため、カードの probe 時に pccardd から ed ドライバを利用すると通知された上でも、どういった種 類のカードなのかを知るために適当な検査を行う必要があ ります。この検査の中で、 Linksys カードかどうかの検査 ルーチンがあることにより、反応しなくなってしまうカー ドや誤認されてしまうカードなどが出てきてしまいました。 そこで、 ed ドライバに flags オプションにより Linksys カ ードであるかどうかを指定するようにしたのです。 pccard. conf の各カードのエントリ毎に、 Linksys カードの場 合は必ず flags 0X80000 を指定するようにしなければなりま せん。 cs ドライバの改良も行われ、 PCMCIA タイプの IBM EtherJet カードがもうすぐ動くようになりそうです。 4.3-RELEASE が楽しみですね注 4 。 注 1 注 2 注 3 注 4 216 ここ数か月の間では Transmeta 社の crus 。 e を搭載したノート PC などは大きな話題になりました。 Native では動かなくても VMware という手もあります : - ) http://www.jp.FreeBSD.org/PAO/index-j.html 4.3- RELEASE は 3 月 25 日にリリースが予定されているようです。 BSD magazine 2001 NO. 7
フロジェクト短信 FreeBSD プロジェクト リリーススケジュール 今年夏から秋にかけて最初のリリースを出す予定になって リースを目指して開発が進められています。 5.0- cu 皿 nt は 次の 4.3 ー RELEASE はこの号が出たすぐ後の 3 月 25 日のリ います。 i386/1ivetree/ ftp ://current.jp.FreeBSD.org/pub/FreeBSD/snapshots/ 最新の FreeBSD SNAPSHOT を毎日作成している 題が発見されているので、早急に対処するべきでしよう。 ます。 bind 、 inetd 、 ipfw 、 ssh など非常に重要な部分に問 体と p 。 rts あわせて 20 以上ものセキュリティ勧告が出てい 今年に入ってから本稿執筆時点までの間に FreeBSD 本 セキュリティ勧告 ような宣言を出すことを含めて検討されているようです。 例がかなり出てきました。「 3. x のサポートを中止する」の たこともあり、 3. x 系の修正が行われないまま放置される FreeBSD 開発者の興味が 3. x からほとんど離れてしまっ ないということです。 用は ( 少なくともセキュリティの観点からは ) お勧めでき 勧告を出すことになりました。これは事実上、 3. x 系の利 更になり、 3. x での修正ができていなくてもセキュリティ 昨年 11 月に 3. x プランチのセキュリティ対応の方針が変 3 Ⅸ対応の方針変更 と悪影響が非常に大きいためです。 で行っていないのは、修正ができる前に問題点を公開する 問題の報告とパッチ作成をオープンなメーリングリスト を発表する。 ・修正ができたら security Advisory ( セキュリティ勧告 ) パッチを作成する。 ・問題が報告されたら、セキュリティオフィサーが迅速に がとられています。 FreeBSD ではセキュリティ問題について次のような方針 セキュリティについて フ野兀之 / M の 0 坦 Konno motoyuki@FreeBSD.org DEVFS (device filesystem) が GENERIC kernel に標準で DEVFS の標準サポート す。 化の際に使う乱数の種を格納しておくようになっていま 本稿執筆時点では / entr 。 py というファイルにシステム初期 暗号回りを安全にするために重要な乱数生成ですが、 entropy 関係 あります。 の定義を加え、かっ他の CPU 用の定義を全部消す必要が CPU のマシンで -current を使う場合には、 "cpu 1386_CPU" 関係で 386 は別扱いにしたほうが都合がよいためです。 386 1386 ー CPU " という行が消えました。これは SMP サポートの 1 月 14 日に GENERIC kernel の config file から "cpu に 86 CPU さようなら でしよう。 RELEASE に向けて新機能がどんどん実装される時期なの 最近、いろいろと変更が入っています。夏の 5.0- 最近の - cu ent 情報 から該当するファイルを入手して利用するのも便利です。 日本の動き 使うことになります。 vn (vnode disk driver) vn と mfs 入りました。 いすれも廃止となります。代わりに md (memory disk) を と mfs ( memory file sy stem ) 力、 から参照できます。 http ://www.jp.FreeBSD.org/event/matsuri2001/ ました。当日の資料などは ースを出展するとともに有志によるステージ発表も行われ 2 月 10 、 11 日に行われた催しに FreeBSD 友の会からもプ オープンソースまつり 2001 in 秋葉原 212 BSD magazine 2001 NO. 7
フロジェクト短信 FreeBSD ports-jp プロジェクト短信 FreeBSD 3. X のサホート中止 ports Collection での FreeBSD 3-STABLE プランチのサポ ート中止が決まりました。定期的に更新されている Free BSD 3. X 用最新版 packages ftp : //ftp.FreeBSD.org/pub/FreeBSD/ports/i386/ packages—3—stab1e/ は 2 月末で更新が止まります。 http : //www.FreeBSD.org/ports/ にある最新の ports-current をインストールするためのアップ デートキットも FreeBSD3. x 用のものはなくなっています。 最新版 packages は更新が止まるだけで p などからの入 手は今後も可能です。ーっ前の FreeBSD 2.2. x 用 packages も更新が止まった時点のものが p サイトに置かれていま す。 今回のサポート中止は、 FreeBSD 開発の中心が Free BSD 5-CURRENT と 4-STABLE に移ってしまい 3-STABLE の作業をする人がいなくなってしまったためです。同じ理 由でセキュリティ問題の修正も行われなくなるなど問題点 が多いので、 3 ー STABLE を使い続けるのはそろそろ中止し たほうがいいでしよう。 なお、サポート外というのは ports collection 全体での話 です。個々の port によっては FreeBSD 3. X でのインストー ルが可能な場合が今後もあると考えられます。 PO 「 ts システムの変更 この記事を書くために調べていて気付いたのですが、こ の 3 か月の間、 ports/Mk/bsd. port. mk の revision が 1 しか上が っていません。ですが BSDPORTMKVERSION が更新注 1 さ れるような非常に重要な変更が入っています。 PKG 0 望 G ー N の追加 PKG-ORIGIN は package がどの ports から作成されたかを 表します。デフォルトでは フ野元之 / M の , ″ Ko 盟 0 " カテゴリ名 " / " port のディレクトリ名 " motoyuki@FreeBSD.0「g NO ー OPENMOTIF を指定しておくとこの依存をなくしま の ports は Open Motif に依存するようになっていますが、 指定しておきます。現在の ports collection では Motif 関係 商用版の M 。 tif を使っている場合に /etc/make. conf などで NO OPENMO 引 F の追加 という行が入っています。 .com/ent ORIGIN : net/cvsup う package の中身を記録するファイルがありますが、この kage である cvsup-16.1. tgz を展開すると + CONTENTS とい 実際に package の中身を見てみましよう。 cvsup の pac るようになっています。 加され、 package を作成するときに PKG-ORIGIN を記録す となっています。 pkg_create と pkg_info に一 0 オプションが追 す。 新しい committer 日本から ports 関係の committer として、二田 (mita) ん、ふじしま (sf) さんの二人が就任されました。 セキュリティ勧告 さ 今年に入ってから P 。 rts 関係で多くのセキュリティ勧告 が出ています。本稿執筆時点では以下に挙げる 14 個です。 FreeBSD—SA—01 : 16 ・ mysql FreeBSD—SA—01 : 03 . bashl FreeBSD—SA—01 : 17 . exmh2 : 04 ・」 oe FreeBSD-SA-01 FreeBSD-SA—01 FreeBSD—SA—01 FreeBSD—SA—01 : 02 ・ syslog—ng FreeBSD¯SA¯Ol. FreeBSD-SA—01 : 05 . stunnel FreeBSD—SA—01 : 07 . xfree86 : 06 . zope : 14. mICC1 FreeBSD—SA—01 FreeBSD—SA—01 FreeBSD—SA—01 ・ 15 . tinyproxy : 19. ja-xklock : 20 . mars_nwe : 21 ・ ja¯elvis FreeBSD—SA—01 : 22 . dc20ctrI このうち XFree86 は対象となるのが XFree86 3. x と XFree86-aoutIibs の 2 種類であり、ユーザーも多いために影 響は非常に大きいと考えられます。 XFree864.0.1 以降では 注 1 BSDPORTVERSION で指定された日時より古い FreeBSD を使っていると upgrade kit を利用するか make w 。 rld でシステムを更新する必要があります。 BSDPORTVERSION が更新されたのは 9 か月ぶりです。 214 BSD magazine 2001 NO. 7
- 当田第第圏田第国を尊 を新一■ー朝 1 新 Windows で GNU ソフトウェアを使おう ! 256 256 ハンドブック . 冖 動田物紀・ 山 0 ・を豊 . を 0 ヂ、 ( ! 見た ! プレゼントだ ! 望の方は、 BSD magazine ホームページ (http://www.ascii.co.jp/BSDmag/) にあ ートの " ご意見 " 欄にこ希望の商品名 ( ウェアの場合はサイズも ) をご記入のうえ、こ応募くだ 。読アンケートにもこ協力をお願いします。締め切りは、 2001 年 4 月 1 8 日 ( 水 ) ( 当日消印有効 ) 、す。応募者多数の場合は抽選とし、当選者の発表は商品の発送をもってかえさせていただきます。 デーモン君が街で探してきたナイスなグッズ。食事中でも関係なくハガキを書こう ! 1 . Ruby を 256 倍使うための本極道編 1 , 200 円 3 名 9. PC 電源タップ・周辺機器ホルダー「固定くん」 1 , 300 円 アスキー ( 株 ) レメックス・ジャパン (http://www.「emex.co.jp/) 2. Ruby を 256 倍使うための本無道編 1 , 200 円 3 名 10. プラグセイフティーカバー TAP - PSC3 480 円 /TAP-PSC2 680 円 アスキー 3P プラグ用 2P L 型プラグ用をセットで。サンワサプライ 3. Windows で GNLJ ソフトウェアを使おう ! 1 , 980 円 3 名 1 1 . コンセントカバー BP60930 290 円 / PP6099 150 円 アスキー 3P 用、 2P 用をセットで。ヨドバシカメラで購入 4. VMwa 「 e 徹底活用ハンドブック 2 , 000 円 3 名 12. GIobefish (MA-OI 02 ) 1 , 980 円 アスキー 株 ) 多慶屋 (Tel: 03-3835-7777 、 http://www.takeya.co.jp/) で購入 5. 両面キーボード 4 , 980 円 13. 旧 v6 KAME P 「 oject ウミガメぬいぐるみ 1 , 280 円 1 2 名 ックモ 1 1 号店 (Tel: 03-5297-1 1 99 、 http://www.tsukumo.co.jp/) で購入 ぶらっとオンライン (http://online.plathome.co.jp/) での販売価格 6. ミディアムスクロールプラグインマウス 3 , 980 円 14. NetBS ロオリジナル携帯ストラップ 1 0 名 USB 、 PS / 2 対応。ヨドバシカメラ (http://www.yodobashi.co.jp/) で購入 大阪大学の齊藤明紀さん提供。非売品 7. ハンドレスト「のぼほん」 880 円 15. BSD magazine オリジナルデーモン君 T-Shirt 4 名 ( 株 ) サブヒロモリ (Tel: 03-3877-3201 、 http://www.hi 「 omorig 「 p. co.jp/) M 、 L を各 2 名。アスキー。非売品 8. PC カードコネクタセキュリティ 490 円 16. BSD magazine 特製お楽しみ袋大・小各 1 名 6 枚入り。サンワサプライ ( 株 ) (Tel: 03-5763-0011 、 http://www.sanwasupply.co.jp/) 編集部のジャンク ( 中身はひ・み・つ ) 。非売品 ( 返品不可 ) 245 BSD magazine 2001 No. 7
つ。 getaddrinfo(3) は addrinfo 構造体のリ ストを動的に生成するので、必要な処 理を終えた後で freeaddrinfo(3) を用いて リストを解放する必要がある ( 39 行 ) 。 なお、 freeaddrinfo(3) に NULL ポインタ を渡したときの挙動は定義されていな いため、事前に引数が NULL ポインタ でないことを確認するほうが安全であ る ( 38 行 ) 注 4 。 次に、サーバー側の典型的な動作で ある、コネクション受付処理のプログ ラムを示す。その中心となるのがリス ト 5 の tcp-accept() で、これは与えられ たサービス名またはポート番号でクラ イアントからのコネクション要求を待 ち、確立したコネクションのソケット を呼び出し元に返す。また、その際に クライアントのアドレスとポート番号 を標準出力に表示する。 一般性のあるプログラミングのため、 tcp-accept() は少し複雑になる。大まか に言えば、この関数は受け付ける可能 性のあるすべてのプロトコルに対応す るソケットを開き、 select ( 2 ) を使ってす べてのソケットに対するコネクション 要求を同時に待つ。最初の要求に対し てコネクションを確立し、そのソケッ トを呼び出し元に返して終了する。 14-17 行では、複数のソケットに対す るコネクション要求待ちを管理するた めのリスト構造を定義している。必要 なソケットの数は事前にはわからない ので、要素の数を動的に伸長できるリ スト構造がこの場合には適している。 次に tcp-accept() を説明する。内部変 数の中で、ソケットアドレス構造体に 関係する 28-30 行が重要である。すな わち、実体としては sockaddr_storage 構 造体 ss を定義し、そのポインタを一般 4 く、 のソケットアドレス構造体へのポイン タにキャストして変数 sa に格納する。 また、後の accept ( 2 ) の際に、変数 from len に実体の長さである sizeof(ss) を代入 する ( 82 行 ) 。これらは先に述べた原 則にしたがっており、これ以後の部分 でソケットアドレス構造体のサイズに よるバグが回避される。 tcp-accept() は、まず bind ( 2 ) で利用す るソケットアドレス構造体を得るため の getaddrinfo(3) を呼び出す ( 34-41 行 ) 。 3 8 行で ai_fl ag s メンバに AI PASSIVE を指定し、 getaddrinfo(3) のホ スト名 ( 第 1 引数 ) として NULL を渡 している ( 40 行 ) 点が tcp-connect() と 異なる。この場合、 IPv4 については 0.0.0.0 、 IPv6 については : : ( すべてのビ ットが 0 のアドレス ) をアドレスとして 用いる。これによって、各ソケットを 「ワイルドカードアドレス」で bind(2) で きる。 43-66 行では、 getaddrinfo(3) が返した 各ソケットアドレス構造体に対してソ ケットを開いて bind ( 2 ) を呼び出し、 listen(2) によってソケットをコネクショ ン受け付け可能な状態にする。移植性 を高めるために、 bind ( 2 ) の第 3 引数で も ai->ai_addrlen を使っている。ソケッ トの準備ができたら、後の select(2) の ためにリスト構造を作り、開いたソケ ットの番号を記録する ( 57 -65 行 ) 。 tcp-connect() の場合と同様、ソケット を開いた後にエラーが起きた場合には、 そのソケットを閉じてからループを続 けている点に注意が必要である。 すべてのソケットについて準備がで きたら、 select ( 2 ) で接続要求待ちに入 る。まず 70-75 行で select ( 2 ) に必要な読 み出しソケットのマスクを生成する。 こでは、ソケット番号の最大値がど れだけ大きくなっても安全なように、 マスクに必要なサイズをあらかじめ計 算し、マスク用のバッフアを動的に確 保している。 77 行で select ( 2 ) を呼び出す。なお、 今回は、プログラムを簡単にするため に select ( 2 ) が失敗したら即座に関数を 終了している ( 78 行 ) が、実際のサー バーアプリケーションではここでエラ ーからの復帰を試みるべきでる。 select ( 2 ) が成功すると 80 行からのル ープに入る。コネクション要求待ちを していた各ソケットについて実際に要 求があったかどうかを調べ ( 8 1 行 ) 、 あれば accept ( 2 ) で要求を受け入れる。 accept ( 2 ) に成功したらクライアントの アドレスとポート番号を表示して ( 85 ー 86 行 ) 、ループを抜ける。表示に利用 した sa2str ( ) については後述する。 での accept ( 2 ) に失敗することは通常考 えられないが、万一失敗した場合には 一通りループを続け、他に接続要求が あればその処理を試みる。 tcp-accept() は動的に確保した内部資 源を持って動くため、終了前にそれら を解放する必要がある。内部資源とし ては、 getaddrinfo(3) が返す addrinfo 構 造体のリスト、コネクション要求受け 付け用のソケット、およびそれを管理 するリスト、さらに select ( 2 ) 用のマスク がある。 93 ー 101 行で、必要に応じてこ れらを解放している。この解放処理は、 tcp-accept() の途中で回復不能なエラー が起きた場合にも必要になるため、 92 行に " cleanup " というラベルを設けて、 工ラーが起きたらこのラベルに飛ぶよ うにしてある。 sa2str() はソケットアドレス構造体を 受け取って、 " [ アドレス ] : ポート番号 " の形の文字列を返す補助関数である。 注 4 tcp-connect() においては、 getaddrinfo(3) が成功したとき、すなわちリストが空でないときにしか freeaddrinfo(3) が利用されないため、この例においてはこの 確認は冗長である。 088 BSD magazine 2001 NO. 7
2 アイアウォりレを考える N e t w 。 r k 全体にラジオを流し、 当てられた IP アドレスの smtp 送受信 (LAN) を取り上げているが、このモ デルはインターネットでも同じことで Client-1 、 2 、 3 はそのポートで流れて 用ポートの間で通信が行われる。 いる情報をラジオデータとして受け ある。 最後にポート番号に関する話に触れ という状況になっている。ファイアウ とる。 ォールやホストのアクセス制御の設定 ・ http サーバーに割り当てられた IP ア ておくことにする。 TCP や UDP はサー ビス毎にポート番号が割り当てられて ドレスの http ホートと client -1 に割り の際に基本となるのが、この IP アドレ おり、たとえば TCP の 25 番ポートは 当てられた IP アドレスの http 送受信 スとポートを 1 つの識別単位として利 用し、その対応によって通信を行って smtp が利用する場合が多い。何らかの 用ポートの間で通信カ哘われる。 理由によって、サービスを提供するポ いるということである。 ・ smtp サーバーに割り当てられた IP ア ートを明示的に変更しない限り、ポー ドレスの smtp ポートと cIient-3 に割り なお、図 3 の例は、閉じた世界 C1ient—B server は Network に対して「誰でも聞ける」 ように情報を流している。 C1ient-A 、 CI 土 en セー B で聞こえている情報は同じ Network Server C1ient—A 図 2 1 対多通信モデル Rad 土 0 サーバー smtp サーバー http サーバー C1ient—3 CI 土 en セー 1 C1ient—2 図 3 実際にはさらに複雑な状況となっている。 BSD magazine 105 2001 No. 7
GURU 導師への ブートプログラム パーティションテーカレエントリ 1 / ヾーティションテーブルエントリ 2 / ヾーティションテーカレエントリ 3 バーティションテーカレエントリ 4 Ox55AA 起動セクタ データ領域 起動セクタ データ領域 起動セクタ データ領域 拡張バーティションテーブル Ox55AA 起動セクタ データ領域 拡張 / ヾーティションテーブル Ox55AA 起動セクタ データ領域 図 5 ー拡張領域と論理領域の例一 / ヾーティンヨン MBR テーカレ ディスク 本域本域本域張域 基領基領基領拡領 論理領域 EBR 論理領域 EBR root# dd if=/dev/rad0s2 bs = 512 count=l of=ebrl root # hd ebr 1 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 14 83 fe bf 2b 3f 00 00 00 d9 63 83 00 00 00 000001C0 81 2c 05 fe lc 20 00 00 00 000001d0 bf ae 18 64 83 00 c3 000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00000200 て 00t # dd if=/dev/radOs2 bs = 512 co t = 1 skip = 8610840 of=ebr2 て 00t # hd ebr2 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 000001b0 000001C0 81 2c 83 fe ae 3f 00 00 00 84 lc 20 00 00 00 000001d0 81 af 05 fe bf b4 db 80 a3 00 86 78 01 00 00 00 00 00 00 00 00 00 00 00 000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 000001f0 00000200 root# dd if=/dev/radOs2 bs = 512 count=l skip = 10715355 of=ebr3 root# hd ebr3 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 000001b0 00 00 00 00 00 00 00 00 000001 c0 81 af 82 fe bf b4 3f 00 00 00 47 78 01 00 00 00 00 00 00 00 00 00 00 00 000001d0 00 00 00 00 00 00 00 00 000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00000200 . Gx . 図 6 2 番目のスライスの起動セクタのダンプ 191 BSD magazine 2001 No. 7
スライスの範囲を記録するのに CHS (Cylinder/Head/ RELEASE から、プートプログラムが LBA 方式に対応した sector) 方式用と LBA (LogicaI BIock Address) 方式用が ため、この制限はなくなっている。 ある。前者は始点と終点のアドレス、後者は始点とスライ LBA 方式は、全セクタに 1 から順に番号を付ける方式で スの持っセクタ数で範囲が記録される。 ある。 32 ビットの幅があるため、 2TB ( 232X512 ) まで表 CHS 方式では、シリンダ、ヘッド、セクタの 3 つのパラ 現可能だ。また、拡張 INTI 3h ファンクションも 32 ビット メータの組み合わせでディスク上のアドレスを示す。 24 ビ である。ただし、 ATA の規格が 28 ビットなため、 128GB ットの内訳は、シリンダに 10 ビット、ヘッドに 8 ビット、 ( 228X612 ) 以上のアドレスを表現できない。 セクタに 6 ビットである。 ルートパーティションを 1024 シリンダ以下にしなければ ならない、という制限は、テープルのシリンダ数が 10 ビッ トであることからきている。 ATA 規格では CHS 方式でも、 シリンダに 16 ビット、ヘッド 4 ビット、セクタ 8 ビットの合 計 28 ビット、つまり 128GB まで表現可能である。ところ が、パーティションテープル上では 10 ビット分、つまり 1024 までしか表現できない。そして、プートプログラムが CHS 方式でディスク I / O とやり取りをしていた。その結果、 1024 シリンダ以上のスライスの正しい位置を取得できず、 この制限が生まれてしまったのだ。 FreeB SD では 4.1- 表 2 システム ID の例 00 04 05 06 07 OB OC OE OF 82 83 85 9F A5 A6 A9 B7 B8 ディスクの構成を調べるのに、もっとも簡単で、多く用 いられるのはやはり fdisk だろう ( 図 3 ) 。 この出力は印刷して保存しておくべきである。何らかの 理由により、パーティションテープルが壊れてしまったと き、システムを復旧するのに非常に役立つからだ。 新しいプートマネージャを試しているとき、操作ミスや 設定ミス、バグなどで、パーティションテープルを壊して しまうかもしれない。この後で説明するオペレーションで ( 印刷ミスがなくても ) タイプミスしてしまうかもしれない。 dd で if オプションと of オプションを逆に指定してしまった ことを考えてみよう。かなりの確率でシステムをおかしく してしまう。 ハードディスク上のプートプログラムはなくても、 CD- ROM やフロッピーディスクから起動可能だ。コピーも容 易に手に入る。だが、パーティションテープルが壊れたと きには、ディスク内の境界がわからないので、ファイルシ ステムを認識できない。こうなると、ディスクの中から、 ファイルシステムの区切りを見つけ出し、苦労してスライ スを切り直すはめになる。 テープルの内容がおかしくなってしまったけれども、デ ータ領域は壊れていない。このようなときは、もう一度、 以前と同じ範囲を指定するだけで、システムは元どおりに 復旧するのである。 こで、図 3 のような記録があるとな fdisk による確認 番号 ( 16 進 ) 意味 DOS FATI 2 DOS FAT16 ( 32MB 以下 ) DOS 拡張パーティション DOS FATI 6 HPSF ( OS / 2 ) 、 NTFS FAT32 DOS FAT32 (LBA) FATI 6 (LBA) DOS 拡張パーティション (LBA) Linux スワップ Linux ext2 Linux 拡張ノヾーティション BSD/OS FreeBSD 、 BSDI OpenBSD NetBSD BSDI BSDI スワップ LBA 総セクター数 ( 4 バイト ) LBA 開始位置 ( 4 バイト ) CHS 終了位置 ( 3 バイト ) システム ( 1 バイト ) CHS 開始位置 ( 3 バイト ) 起動フラグ ( 1 バイト ) 図 2 。バーティションテープルエントリの構造 188 BSD magazine 2001 NO. 7