Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 15951] ファイルの概要

このコミットは、Go言語のバージョン1.1のリリースノートである doc/go1.1.html ファイルに対するドキュメント更新です。具体的には、net パッケージに加えられた複数の変更点について記述を追加・修正しています。

コミット

commit 237b8b8b66113c081c1407251c0c605d1acdc730
Author: Rob Pike <r@golang.org>
Date:   Tue Mar 26 10:54:55 2013 -0700

    doc/go1.1.html: describe Zone and other net changes
    Mild adaptation of rsc's 8021043, which I was unable to clpatch.
    (rsc is offline)
    
    R=golang-dev, bradfitz
    CC=golang-dev
    https://golang.org/cl/7741049

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/237b8b8b66113c081c1407251c0c605d1acdc730

元コミット内容

このコミットは、doc/go1.1.html ファイルに対して、net パッケージの変更に関する記述を追加・修正しています。主な変更点は以下の通りです。

  • IPAddr, TCPAddr, UDPAddr 構造体に Zone フィールドが追加されたことの説明。これに伴い、タグなし複合リテラルを使用している既存コードが壊れる可能性と、go fix および go vet による対応方法について言及。
  • net.ListenUnixgram 関数の戻り値の型が net.UDPConn から net.UnixConn に変更されたことの修正(Go 1.0でのバグ修正)。
  • net パッケージにおけるリンクローカルIPv6アドレスのゾーン修飾子サポートに関する説明。
  • net パッケージに LookupNS 関数が追加されたことの説明。
  • IPConn および UDPConn に、プロトコル固有のパケット読み書きメソッド(ReadMsgIP, WriteMsgIP, ReadMsgUDP, WriteMsgUDP)が追加されたことの説明。
  • UnixConn に、接続の半分を閉じるメソッド(CloseRead, CloseWrite)が追加されたことの説明。

変更の背景

このコミットの背景は、Go言語の次期メジャーリリースであるGo 1.1に向けて、net パッケージに加えられた重要な変更点を公式ドキュメントに反映させることです。Go言語はGo 1のリリース以降、厳格な互換性保証を掲げていますが、バグ修正や新機能の追加に伴い、一部のAPIに変更が生じることがあります。特に、net パッケージはネットワーク通信の基盤であり、IPv6の進化やより高度なネットワーク機能への対応が求められていました。

このドキュメント更新は、ユーザーがGo 1.1にアップグレードする際に、net パッケージの変更点、特に既存コードに影響を与える可能性のある変更(例: Zone フィールドの追加による複合リテラルの問題)について事前に情報を提供し、スムーズな移行を支援することを目的としています。また、rsc (Russ Cox) による先行する変更の適応であり、rsc がオフラインであったため、Rob Pikeがその変更を自身のコミットとして取り込んだ経緯が示されています。これは、Goプロジェクトにおける開発プロセスの柔軟性と、主要開発者間の連携を示唆しています。

前提知識の解説

Go 1 互換性保証 (Go 1 Compatibility Guarantee)

Go言語は、Go 1のリリース以降、厳格な互換性保証を維持しています。これは、Go 1で書かれたプログラムは、Go 1.xの将来のバージョンでもコンパイルされ、実行されることを意味します。しかし、この保証にはいくつかの例外があります。

  1. バグ修正: バグを修正するためにAPIの動作が変更されることは許容されます。このコミットで言及されている ListenUnixgram の戻り値の型変更は、Go 1.0でのバグ(誤った型を返していた)を修正するためのものであり、互換性保証の範囲内とされています。
  2. 未タグ複合リテラル: 構造体に新しいフィールドが追加された場合、タグなし複合リテラル(例: net.TCPAddr{ip, port})を使用しているコードは、新しいフィールドの初期化順序が不明確になるため、コンパイルエラーになる可能性があります。Goの互換性保証では、このような変更は許容されており、開発者はタグ付き複合リテラル(例: net.TCPAddr{IP: ip, Port: port})を使用することが推奨されます。

複合リテラル (Composite Literals)

Go言語では、構造体、配列、スライス、マップなどの複合型を初期化するために複合リテラルを使用します。

  • タグなし複合リテラル: フィールド名を指定せずに、宣言順に値を並べて初期化する方法です。 例: Point{10, 20} 新しいフィールドが追加されると、既存のコードの意図と異なる初期化が行われたり、コンパイルエラーになったりする可能性があります。
  • タグ付き複合リテラル: フィールド名を明示的に指定して値を初期化する方法です。 例: Point{X: 10, Y: 20} この方法は、フィールドの順序に依存せず、新しいフィールドが追加されても既存のコードが影響を受けにくいため、より堅牢です。

go fix および go vet ツール

Go言語には、コードの品質と互換性を維持するための便利なツールが標準で提供されています。

  • go fix: Goの新しいバージョンへの移行時に、古いAPIの使用法を自動的に新しいAPIに書き換えるツールです。このコミットの文脈では、タグなし複合リテラルをタグ付き複合リテラルに自動変換する機能が提供されます。
  • go vet: Goのソースコードを静的に解析し、潜在的なバグや疑わしい構成を報告するツールです。このコミットの文脈では、タグなし複合リテラルが将来的に問題を引き起こす可能性がある場合に警告を発することができます。
  • IPv6 リンクローカルアドレス: fe80::/10 のプレフィックスを持つIPv6アドレスで、単一のリンク(ネットワークセグメント)内でのみ有効です。ルーターを越えて転送されることはありません。
  • ゾーン修飾子 (Zone Qualifiers): リンクローカルアドレスは、複数のネットワークインターフェースに割り当てられる可能性があるため、どのインターフェースに属するかを明確にするためにゾーン修飾子が使用されます。例えば、fe80::1%lo0 は、lo0 というインターフェースに割り当てられたリンクローカルアドレス fe80::1 を示します。これは、特にマルチホーム環境(複数のネットワークインターフェースを持つシステム)で重要になります。

DNS NSレコード (Name Server Records)

DNS (Domain Name System) におけるリソースレコードの一種で、特定のドメインのネームサーバーを指定します。NSレコードは、そのドメインの権威ネームサーバーがどこにあるかを示し、ドメイン名の解決プロセスにおいて重要な役割を果たします。LookupNS 関数は、指定されたホスト名のNSレコードを問い合わせる機能を提供します。

アウトオブバンドデータ (Out-of-Band Data)

ネットワーク通信において、通常のデータストリームとは別に、特別な制御情報やメタデータを送信するメカニズムです。例えば、TCPの緊急ポインタや、Unixドメインソケットにおけるファイルディスクリプタの転送などがこれに該当します。ReadMsgIPWriteMsgIP といったメソッドは、このようなアウトオブバンドデータへのアクセスを提供し、より低レベルで柔軟なネットワークプログラミングを可能にします。

接続の半分を閉じる (Half-Closing Connections)

TCPなどのストリーム指向のプロトコルでは、接続の一方向だけを閉じることができます。これを「半分閉じる」と呼びます。

  • CloseRead: 読み取り側を閉じ、それ以上データを受信しないようにします。
  • CloseWrite: 書き込み側を閉じ、それ以上データを送信しないようにします。

これにより、例えばクライアントがすべてのデータを送信し終えたが、サーバーからの応答をまだ待っている場合などに、リソースを効率的に管理できます。

技術的詳細

このコミットが記述している net パッケージの変更は、Go 1.1におけるネットワーク機能の強化と改善を目的としています。

  1. IPAddr, TCPAddr, UDPAddr 構造体への Zone フィールド追加: これは、IPv6のリンクローカルアドレスを正確に扱うために導入されました。リンクローカルアドレスは、同じアドレスが異なるネットワークインターフェースに存在しうるため、どのインターフェース(ゾーン)に属するかを識別する必要があります。Zone フィールドは、このインターフェース名を文字列として保持します。 この変更は、Goの互換性保証の範囲内で、タグなし複合リテラルを使用している既存コードに影響を与える可能性があります。例えば、net.TCPAddr{ip, port} のようなコードは、新しい Zone フィールドが追加されたことで、コンパイルエラーになるか、意図しない初期化が行われる可能性があります。Goは、このような場合に go fix ツールで自動的にタグ付きリテラル(net.TCPAddr{IP: ip, Port: port})に変換することを推奨し、go vet で潜在的な問題を検出できるようにしています。

  2. net.ListenUnixgram の戻り値の型変更: Go 1.0では、ListenUnixgram が誤って net.UDPConn を返していましたが、これはUnixドメインソケットのデータグラム接続を扱う関数としては不適切でした。Go 1.1で、正しい型である net.UnixConn を返すように修正されました。これはバグ修正であり、Go 1互換性保証の例外として許容される変更です。

  3. リンクローカルIPv6アドレスのゾーン修飾子サポート: net パッケージの Dial, ResolveIPAddr, ResolveUDPAddr, ResolveTCPAddr などの関数が、fe80::1%lo0 のようなゾーン修飾子を含むIPv6アドレス文字列を受け入れるようになりました。これにより、マルチホーム環境や特定のインターフェースを介した通信において、IPv6リンクローカルアドレスをより正確に指定できるようになります。

  4. net.LookupNS 関数の追加: DNSのネームサーバーレコード(NSレコード)を問い合わせるための LookupNS 関数が追加されました。これにより、Goアプリケーションから特定のドメインの権威ネームサーバー情報をプログラム的に取得できるようになり、DNS関連のツールやサービスを構築する際に有用です。

  5. IPConn および UDPConn へのプロトコル固有のパケット読み書きメソッド追加: IPConn には ReadMsgIPWriteMsgIP が、UDPConn には ReadMsgUDPWriteMsgUDP が追加されました。これらのメソッドは、PacketConn インターフェースの ReadFrom および WriteTo メソッドのより特化したバージョンです。これらは、パケットに関連付けられたアウトオブバンドデータ(例: IPヘッダー情報、エラー情報など)にアクセスするための機能を提供します。これにより、より低レベルのネットワークプロトコル処理や、高度なネットワーク診断ツールをGoで実装する際の柔軟性が向上します。

  6. UnixConn への CloseRead および CloseWrite メソッド追加: UnixConn は、Unixドメインソケット接続を表現する型です。これに CloseReadCloseWrite メソッドが追加され、TCPConn と同様に、接続の読み取り側または書き込み側だけを個別に閉じることができるようになりました。これにより、Unixドメインソケット通信においても、リソース管理の柔軟性が向上し、特定の通信シナリオ(例: クライアントがデータを送信し終えた後にサーバーからの応答を待つ)をより効率的に実装できます。

コアとなるコードの変更箇所

このコミットは、Go 1.1のリリースノートである doc/go1.1.html ファイルのドキュメント内容を更新しています。実際のGo言語のソースコード(net パッケージの実装)を変更しているわけではありません。

変更の差分は以下の通りです。

--- a/doc/go1.1.html
+++ b/doc/go1.1.html
@@ -452,6 +452,26 @@ and
 methods.
 </p>
 
+<p>
+The data structures
+<a href="/pkg/net/#IPAddr"><code>IPAddr</code></a>,
+<a href="/pkg/net/#TCPAddr"><code>TCPAddr</code></a>, and
+<a href="/pkg/net/#UDPAddr"><code>UDPAddr</code></a>
+add a new string field called <code>Zone</code>.
+Code using untagged composite literals (e.g. <code>net.TCPAddr{ip, port}</code>)
+instead of tagged literals (<code>net.TCPAddr{IP: ip, Port: port}</code>)
+will break due to the new field.
+The Go 1 compatibility rules allow this change: client code must use tagged literals to avoid such breakages.
+</p>
+
+<p>
+<em>Updating</em>:
+To correct breakage caused by the new struct field,
+<code>go fix</code> will rewrite code to add tags for these types.
+More generally, <code>go vet</code> will identify composite literals that
+should be revised to use field tags.
+</p>
+
 <h3 id="reflect">reflect</h3>
 
 <p>
@@ -730,19 +750,15 @@ to define the boundary separator used to package the output.
 <li>
 The
 <a href="/pkg/net/"><code>net</code></a> package's
-<a href="/pkg/net/#ListenUnixgram"><code>net/ListenUnixgram</code></a>
+<a href="/pkg/net/#ListenUnixgram"><code>ListenUnixgram</code></a>
 function has changed return types: it now returns a
-<a href="/pkg/net/#UnixConn"><code>net/UnixConn</code></a>
+<a href="/pkg/net/#UnixConn"><code>UnixConn</code></a>
 rather than a
-<a href="/pkg/net/#UDPConn"><code>net/UDPConn</code></a>, which was
+<a href="/pkg/net/#UDPConn"><code>UDPConn</code></a>, which was
 clearly a mistake in Go 1.0.
 Since this API change fixes a bug, it is permitted by the Go 1 compatibility rules.
 </li>
 
-<li> TODO:
-<code>net</code>: LookupNS, IPConn.ReadMsgIP, IPConn.WriteMsgIP, UDPConn.ReadMsgUDP, UDPConn.WriteMsgUDP, UnixConn.CloseRead, UnixConn.CloseWrite
-</li>
-
 <li>
 The <a href="/pkg/net/"><code>net</code></a> package includes a new function,
 <a href="/pkg/net/#DialOpt"><code>DialOpt</code></a>, to supply options to
@@ -756,6 +772,48 @@ The new functions
 <a href="/pkg/net/#LocalAddress"><code>LocalAddress</code></a> return a <code>DialOption</code>.
 </li>
 
+<li>
+The <a href="/pkg/net/"><code>net</code></a> package adds support for
+link-local IPv6 addresses with zone qualifiers, such as <code>fe80::1%lo0</code>.
+The address structures <a href="/pkg/net/#IPAddr"><code>IPAddr</code></a>,
+<a href="/pkg/net/#UDPAddr"><code>UDPAddr</code></a>, and
+<a href="/pkg/net/#TCPAddr"><code>TCPAddr</code></a>
+record the zone in a new field, and functions that expect string forms of these addresses, such as
+<a href="/pkg/net/#Dial"><code>Dial</code></a>,
+<a href="/pkg/net/#ResolveIPAddr"><code>ResolveIPAddr</code></a>,
+<a href="/pkg/net/#ResolveUDPAddr"><code>ResolveUDPAddr</code></a>, and
+<a href="/pkg/net/#ResolveTCPAddr"><code>ResolveTCPAddr</code></a>,
+now accept the zone-qualified form.
+</li>
+
+<li>
+The <a href="/pkg/net/"><code>net</code></a> package adds
+<a href="/pkg/net/#LookupNS"><code>LookupNS</code></a> to its suite of resolving functions.
+<code>LookupNS</code> returns the <a href="/pkg/net/#NS">NS records</a> for a host name.
+</li>
+
+<li>
+The <a href="/pkg/net/"><code>net</code></a> package adds protocol-specific 
+packet reading and writing methods to
+<a href="/pkg/net/#IPConn"><code>IPConn</code></a>
+(<a href="/pkg/net/#IPConn.ReadMsgIP"><code>ReadMsgIP</code></a>
+and <a href="/pkg/net/#IPConn.WriteMsgIP"><code>WriteMsgIP</code></a>) and 
+<a href="/pkg/net/#UDPConn"><code>UDPConn</code></a>
+(<a href="/pkg/net/#UDPConn.ReadMsgUDP"><code>ReadMsgUDP</code></a> and
+<a href="/pkg/net/#UDPConn.WriteMsgUDP"><code>WriteMsgUDP</code></a>).
+These are specialized versions of <a href="/pkg/net/#PacketConn"><code>PacketConn</code></a>'s
+<code>ReadFrom</code> and <code>WriteTo</code> methods that provide access to out-of-band data associated
+with the packets.
+ </li>
+ 
+ <li>
+The <a href="/pkg/net/"><code>net</code></a> package adds methods to
+<a href="/pkg/net/#UnixConn"><code>UnixConn</code></a> to allow closing half of the connection 
+(<a href="/pkg/net/#UnixConn.CloseRead"><code>CloseRead</code></a> and
+<a href="/pkg/net/#UnixConn.CloseWrite"><code>CloseWrite</code></a>),
+matching the existing methods of <a href="/pkg/net/#TCPConn"><code>TCPConn</code></a>.
+</li>
+ 
 <li>
 The <a href="/pkg/net/http/"><code>net/http</code></a> package includes several new additions.
 <a href="/pkg/net/http/#ParseTime"><code>ParseTime</code></a> parses a time string, trying

コアとなるコードの解説

このコミットは、Go 1.1のリリースノート (doc/go1.1.html) に、net パッケージの重要な変更点を追加・修正することで、ユーザーがこれらの変更を理解し、必要に応じてコードを適応できるようにするためのものです。

  • Zone フィールドの追加に関する説明: IPAddr, TCPAddr, UDPAddrZone フィールドが追加されたことは、IPv6のリンクローカルアドレスの正確な処理に不可欠です。このドキュメントは、この変更がタグなし複合リテラルを使用している既存コードに破壊的変更をもたらす可能性があることを明確に警告しています。これは、Goの互換性保証が「バグ修正」や「未タグ複合リテラル」のような特定のケースでは破壊的変更を許容することを示す良い例です。また、go fixgo vet というGoの標準ツールが、このような移行を支援するためにどのように使用できるかを具体的に示しています。

  • ListenUnixgram の戻り値の型修正に関する説明: これはGo 1.0のバグ修正であり、ドキュメントは、このAPI変更がGo 1互換性保証によって許可されていることを明記しています。これにより、ユーザーはなぜこのような変更が行われたのか、そしてそれが互換性保証に反しない理由を理解できます。

  • TODO リストの削除と詳細な説明の追加: 以前のドキュメントには、net パッケージの将来の変更に関する TODO リストが含まれていました。このコミットでは、その TODO リストを削除し、代わりに以下の具体的な機能追加について詳細な説明を加えています。

    • リンクローカルIPv6アドレスのゾーン修飾子サポート: ネットワークプログラミングにおいて、IPv6のリンクローカルアドレスを正確に扱うための重要な機能強化です。ドキュメントは、どの構造体と関数がこの変更の影響を受けるかを具体的に示しています。
    • LookupNS 関数の追加: DNS関連の機能が強化されたことを示します。
    • IPConn および UDPConn へのパケット読み書きメソッド追加: アウトオブバンドデータへのアクセスを可能にすることで、より低レベルで高度なネットワークプログラミングが可能になったことを説明しています。
    • UnixConn への CloseRead および CloseWrite メソッド追加: TCPConn と同様の半閉じ機能がUnixドメインソケットにも提供されたことを示し、APIの一貫性と機能の充実を強調しています。

これらのドキュメントの変更は、Go 1.1の net パッケージが提供する新しい機能と、既存コードへの潜在的な影響について、開発者に明確かつ包括的な情報を提供することを目的としています。

関連リンク

参考にした情報源リンク