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

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

このコミットは、Go言語の標準ライブラリnetパッケージ内のdial_test.goファイルに対する変更です。具体的には、ネットワーク接続のテストにおけるバックログサイズの設定方法の改善と、関連するコメントの修正が行われています。

コミット

commit 76a1cb5a009d919f4f57e5cdf4ff46d9633fe118
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date:   Sat Feb 11 11:51:12 2012 +0900

    net: fix comment, make use of listenerBacklog
    
    R=golang-dev, rsc
    CC=golang-dev
    https://golang.org/cl/5653056

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

https://github.com/golang/go/commit/76a1cb5a009d919f4f57e5cdf4ff46d9633fe118

元コミット内容

--- a/src/pkg/net/dial_test.go
+++ b/src/pkg/net/dial_test.go
@@ -27,8 +27,7 @@ func TestDialTimeout(t *testing.T) {
 
  	errc := make(chan error)
 
-	const SOMAXCONN = 0x80 // copied from syscall, but not always available
-	const numConns = SOMAXCONN + 10
+	numConns := listenerBacklog + 10
 
  	// TODO(bradfitz): It's hard to test this in a portable
  	// way. This is unforunate, but works for now.
@@ -54,8 +53,8 @@ func TestDialTimeout(t *testing.T) {
  		}()
  	default:
  		// TODO(bradfitz):
-		// OpenBSD may have a reject route to 10/8.
-		// FreeBSD likely works, but is untested.
+		// OpenBSD may have a reject route to 127/8 except 127.0.0.1/32
+		// by default. FreeBSD likely works, but is untested.
  		t.Logf("skipping test on %q; untested.", runtime.GOOS)
  		return
  	}

変更の背景

このコミットの主な背景は、Go言語のnetパッケージにおけるネットワークテストの堅牢性と移植性の向上です。

  1. SOMAXCONNの利用に関する問題: 以前のコードでは、SOMAXCONNという定数を使用して、テストで作成する接続の最大数を決定していました。SOMAXCONNはシステムコール(syscall)パッケージからコピーされた値であり、OSによってその値が異なる可能性や、常に利用可能であるとは限らないという問題がありました。これにより、テストの移植性が損なわれる可能性がありました。
  2. listenerBacklogの導入と活用: Goのnetパッケージでは、リスナーが受け入れることができる保留中の接続の最大数を制御するためにlistenerBacklogという内部的な値が導入されていました。この値は、OSのデフォルト設定やGoランタイムの内部的な調整に基づいて決定されるため、よりポータブルで適切なバックログサイズを提供します。このコミットは、テストコードがこのlistenerBacklogを適切に利用するように変更することで、テストの信頼性と移植性を高めることを目的としています。
  3. コメントの正確性の向上: 特定のOS(OpenBSD)におけるネットワークルーティングに関するコメントが、より正確な情報に更新されています。これは、テストが特定の環境でスキップされる理由を明確にするための改善です。

前提知識の解説

このコミットを理解するためには、以下の概念が役立ちます。

  1. TCP/IPソケットプログラミング:
    • リスナー (Listener): サーバー側で特定のポートを監視し、クライアントからの接続要求を待機するエンティティです。Go言語ではnet.Listen関数などで作成されます。
    • バックログ (Backlog): リスナーが同時に処理できる保留中の接続要求のキューの最大サイズを指します。クライアントが接続を試みた際に、サーバーがすぐにacceptできない場合、その接続要求はこのキューに入れられます。キューが満杯の場合、それ以降の接続要求は拒否されるか、タイムアウトします。listen(2)システムコールにおけるbacklog引数に相当します。
    • SOMAXCONN: 多くのUnix系OSで定義されている、システムが許可するTCPリスニングソケットのバックログキューの最大値を示す定数です。これはOSによって異なり、通常は/proc/sys/net/core/somaxconnなどのカーネルパラメータで設定されます。
  2. Go言語のnetパッケージ:
    • Goの標準ライブラリの一部であり、ネットワークI/Oプリミティブを提供します。TCP/UDPソケット、IPアドレスの解決、HTTPクライアント/サーバーなどが含まれます。
    • dial_test.goは、このnetパッケージの機能、特にDialTimeoutのような接続確立に関するテストを行うためのファイルです。
  3. Goのテストフレームワーク:
    • Goには組み込みのテストフレームワークがあり、go testコマンドで実行されます。テスト関数はTestXxxという命名規則に従います。
    • t.Logfはテスト中にログメッセージを出力するために使用されます。
    • runtime.GOOSは、Goプログラムが実行されているオペレーティングシステムを示す文字列です(例: "linux", "darwin", "windows", "openbsd")。これにより、OS固有の動作をテストで考慮することができます。
  4. Goのコードレビューシステム (Gerrit):
    • https://golang.org/cl/5653056というリンクは、Goプロジェクトが当時使用していたGerritベースのコードレビューシステムへのリンクです。Goの変更はすべてこのシステムを通じてレビューされ、承認されてからメインリポジトリにマージされます。このリンクは、変更の議論や背景に関する追加情報を提供することがあります。

技術的詳細

このコミットの技術的な核心は、TestDialTimeoutというテスト関数内で、テスト対象のネットワーク接続数を決定する方法の変更にあります。

以前のコードでは、numConnsという変数を定義する際に、const SOMAXCONN = 0x80というハードコードされた値を使用していました。この0x80は128に相当し、これは当時の一般的なLinuxシステムにおけるSOMAXCONNのデフォルト値(128)を意識したものと考えられます。しかし、この値はsyscallパッケージからコピーされたものであり、すべてのOSで同じ値が保証されるわけではありませんでした。特に、syscallパッケージの定数はOSやアーキテクチャに依存するため、移植性の問題を引き起こす可能性がありました。

新しいコードでは、numConns := listenerBacklog + 10という形式に変更されています。ここで登場するlistenerBacklogは、Goのnetパッケージ内部で管理されている、システムが許容するリスナーのバックログサイズを示す変数です。このlistenerBacklogは、GoランタイムがOSのSOMAXCONN設定やその他の要因を考慮して動的に決定する値であり、よりポータブルで適切なバックログサイズを提供します。テストでlistenerBacklog + 10という値を使用することで、テストがOSの実際のバックログ制限を考慮し、それをわずかに超える接続を試みることで、タイムアウト動作をより確実に検証できるようになります。これにより、テストが特定のOS環境に依存することなく、より汎用的に機能するようになります。

また、コメントの修正も重要です。OpenBSDに関するコメントは、以前は「10/8への拒否ルート」と漠然と記述されていましたが、新しいコメントでは「127/8(ただし127.0.0.1/32を除く)への拒否ルート」と具体化されています。これは、OpenBSDのデフォルトのネットワーク設定において、ループバックアドレス範囲(127.0.0.0/8)のうち、特定のローカルホストアドレス(127.0.0.1)以外のIPアドレスへの接続がデフォルトで拒否される可能性があるという、より正確な情報を提供しています。これにより、テストがOpenBSDでスキップされる理由が明確になり、将来的なデバッグや理解に役立ちます。

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

src/pkg/net/dial_test.goファイル内の以下の2箇所が変更されています。

  1. numConnsの定義:

    -	const SOMAXCONN = 0x80 // copied from syscall, but not always available
    -	const numConns = SOMAXCONN + 10
    +	numConns := listenerBacklog + 10
    

    SOMAXCONNのハードコードされた定数定義が削除され、代わりにlistenerBacklog変数を利用してnumConnsが初期化されるようになりました。

  2. OpenBSDに関するコメント:

    -		// OpenBSD may have a reject route to 10/8.
    -		// FreeBSD likely works, but is untested.
    +		// OpenBSD may have a reject route to 127/8 except 127.0.0.1/32
    +		// by default. FreeBSD likely works, but is untested.
    

    OpenBSDにおけるルーティングに関するコメントがより詳細かつ正確な記述に修正されました。

コアとなるコードの解説

  • numConns := listenerBacklog + 10:

    • この行は、TestDialTimeout関数内で、同時に試行するネットワーク接続の数を定義しています。
    • listenerBacklogは、Goのnetパッケージ内部で定義されている変数で、OSが許容するTCPリスニングソケットのバックログキューの最大サイズを反映しています。この値は、Goランタイムがシステムコール(例: getsockopt(SO_MAXCONN)sysctl)を通じてOSから取得したり、デフォルト値を設定したりすることで決定されます。
    • + 10は、意図的にlistenerBacklogの値を少し超える数の接続を試みることで、バックログが満杯になった際の挙動(接続拒否やタイムアウト)をテストすることを目的としています。これにより、DialTimeoutが期待通りに機能するかどうかを検証します。
    • この変更により、テストは特定のOSのSOMAXCONN定数に依存することなく、Goランタイムが決定したポータブルなバックログサイズに基づいて動作するようになり、テストの移植性と信頼性が向上します。
  • OpenBSDに関するコメント修正:

    • // OpenBSD may have a reject route to 127/8 except 127.0.0.1/32 by default.
    • このコメントは、TestDialTimeoutが特定のOS(OpenBSD)でスキップされる可能性がある理由を説明しています。
    • OpenBSDでは、デフォルトのネットワーク設定により、ループバックアドレス範囲(127.0.0.0/8)のうち、127.0.0.1(一般的なローカルホスト)以外のIPアドレスへの接続が、ルーティングテーブルに「拒否ルート」として設定されている場合があります。
    • このテストは、127.0.0.1以外のループバックアドレス(例: 127.0.0.2など)への接続を試みることでタイムアウトを検証しようとするため、OpenBSDのデフォルト設定ではこれらの接続が即座に拒否され、テストの意図するタイムアウト動作が確認できない可能性があります。
    • このコメントは、そのようなOS固有の挙動を開発者に知らせ、テストがスキップされる理由を明確にしています。

関連リンク

参考にした情報源リンク

  • Go言語のソースコード (特にsrc/pkg/netディレクトリ)
  • Go言語の公式ドキュメント
  • Unix系OSのネットワークプログラミングに関する一般的な知識
  • TCP/IPプロトコルに関する一般的な知識
  • Gerrit Code Review System (Goプロジェクトが過去に使用)
  • SOMAXCONNに関するWeb上の技術記事