[インデックス 14656] ファイルの概要
このコミットは、Go言語のnet
パッケージにおけるListenUnixgram
関数のシグネチャを変更し、戻り値の型を*UDPConn
から*UnixConn
に修正するものです。これにより、Unixドメインソケットのデータグラム通信が正しく機能するようになり、ReadFrom
やWriteTo
といったUnixConn
固有のメソッドが利用可能になります。
コミット
commit 0d197251eedad2185a41f9fe7facb20fd5bb3061
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date: Sun Dec 16 11:51:47 2012 +0900
net: change ListenUnixgram signature to return UnixConn instead of UDPConn
This CL breaks Go 1 API compatibility but it doesn't matter because
previous ListenUnixgram doesn't work in any use cases, oops.
The public API change is:
-pkg net, func ListenUnixgram(string, *UnixAddr) (*UDPConn, error)
+pkg net, func ListenUnixgram(string, *UnixAddr) (*UnixConn, error)
Fixes #3875.
R=rsc, golang-dev, dave
CC=golang-dev
https://golang.org/cl/6937059
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/0d197251eedad2185a41f9fe7facb20fd5bb3061
元コミット内容
net: change ListenUnixgram signature to return UnixConn instead of UDPConn
この変更はGo 1のAPI互換性を破るものですが、以前のListenUnixgram
はどのユースケースでも機能しなかったため問題ないとされています。
公開APIの変更点:
pkg net, func ListenUnixgram(string, *UnixAddr) (*UDPConn, error)
pkg net, func ListenUnixgram(string, *UnixAddr) (*UnixConn, error)
Issue #3875を修正します。
変更の背景
このコミットの背景には、Go言語のnet
パッケージにおけるListenUnixgram
関数の既存の実装が、Unixドメインデータグラムソケットの本来の機能を提供できていなかったという問題があります。具体的には、ListenUnixgram
はUnixドメインデータグラムソケットをリッスンするために設計されていましたが、その戻り値の型が*UDPConn
となっていました。
UDPConn
はIPネットワークにおけるUDP(User Datagram Protocol)通信を扱うための型であり、Unixドメインソケットとは異なる特性を持っています。Unixドメインソケットはファイルシステム上のパスをアドレスとして使用し、プロセス間通信(IPC)に特化しています。UDPConn
のメソッドはIPアドレスやポート番号を前提としているため、Unixドメインソケットの特性(例えば、ReadFromUnix
やWriteToUnix
のようなUnixドメインソケット固有のメソッド)を直接扱うことができませんでした。
結果として、以前のListenUnixgram
は、Unixドメインデータグラムソケットを確立しても、そのソケットを通じてデータグラムを送信したり、送信元アドレスを特定して受信したりするような、期待される動作ができませんでした。コミットメッセージにある「previous ListenUnixgram doesn't work in any use cases, oops.」という記述は、この機能不全を端的に示しています。
この問題を解決し、ListenUnixgram
がUnixドメインデータグラムソケットとして完全に機能するようにするために、戻り値の型を*UnixConn
に変更する必要がありました。UnixConn
はUnixドメインソケットに特化したコネクション型であり、ReadFromUnix
やWriteToUnix
といった、Unixドメインデータグラム通信に必要なメソッドを提供します。この変更により、ListenUnixgram
は意図された通りにUnixドメインデータグラム通信をサポートできるようになります。
前提知識の解説
Unixドメインソケット (Unix Domain Sockets / UDS)
Unixドメインソケットは、同じホストマシン上で動作するプロセス間で通信を行うためのメカニズムです。TCP/IPソケットがネットワークを介した通信(異なるホスト間や同じホスト上の異なるプロセス間)に使用されるのに対し、Unixドメインソケットはファイルシステム上の特殊なファイル(ソケットファイル)を介して通信を行います。
主な特徴:
- 高速性: ネットワークスタックを介さないため、TCP/IPソケットよりも高速なプロセス間通信が可能です。
- セキュリティ: ファイルシステム上のパーミッションによってアクセス制御が可能です。
- アドレス: IPアドレスやポート番号ではなく、ファイルパス(例:
/tmp/my_socket
)をアドレスとして使用します。 - 種類:
- ストリームソケット (SOCK_STREAM): TCPと同様に、信頼性のある接続指向のバイトストリーム通信を提供します。
- データグラムソケット (SOCK_DGRAM): UDPと同様に、非接続指向のデータグラム通信を提供します。メッセージの順序や到達は保証されません。
- シーケンシャルパケットソケット (SOCK_SEQPACKET): ストリームソケットとデータグラムソケットの中間に位置し、信頼性のある接続指向のデータグラム通信を提供します。メッセージの境界が保持され、順序も保証されます。
Go言語のnet
パッケージ
Go言語の標準ライブラリであるnet
パッケージは、ネットワークI/Oプリミティブを提供します。TCP/IP、UDP、Unixドメインソケットなど、様々なネットワークプロトコルを扱うためのインターフェースや型が定義されています。
net.Conn
インターフェース: ネットワーク接続の一般的なインターフェースを定義します。Read
、Write
、Close
、LocalAddr
、RemoteAddr
、SetDeadline
などのメソッドを持ちます。net.PacketConn
インターフェース: パケット指向のネットワーク接続のインターフェースを定義します。ReadFrom
、WriteTo
、Close
、LocalAddr
、SetDeadline
などのメソッドを持ちます。net.UDPConn
: UDPネットワーク接続を表す型です。net.PacketConn
インターフェースを実装し、IPアドレスとポート番号を介したデータグラム通信に使用されます。net.UnixConn
: Unixドメインソケット接続を表す型です。net.Conn
およびnet.PacketConn
インターフェースを実装し、Unixドメインソケットを介したストリーム、データグラム、シーケンシャルパケット通信に使用されます。ReadFromUnix
やWriteToUnix
など、Unixドメインソケット固有のメソッドも提供します。net.UnixAddr
: Unixドメインソケットのアドレスを表す型です。ファイルパスとネットワークタイプ("unix"
、"unixgram"
、"unixpacket"
)を含みます。net.ListenUnixgram
関数: Unixドメインデータグラムソケットをリッスンするための関数です。このコミットの変更対象となっています。
ReadFrom
とWriteTo
メソッド
net.PacketConn
インターフェースに定義されているメソッドで、パケット指向の通信において重要です。
ReadFrom(b []byte) (n int, addr Addr, err error)
: 受信したパケットのデータをb
に読み込み、そのパケットの送信元アドレスをaddr
として返します。WriteTo(b []byte, addr Addr) (n int, err error)
:b
のデータを指定されたaddr
にパケットとして送信します。
これらのメソッドは、特にデータグラム通信において、どの送信元からデータが来たのか、あるいはどの宛先にデータを送るのかをパケットごとに指定・取得するために不可欠です。
技術的詳細
このコミットの核心は、net.ListenUnixgram
関数の戻り値の型を*UDPConn
から*UnixConn
に変更した点にあります。この変更は、単なる型名の変更以上の技術的な意味合いを持ちます。
-
機能の整合性:
ListenUnixgram
は、その名前が示す通り、Unixドメインデータグラムソケットをリッスンするための関数です。Unixドメインソケットは、IPネットワークのUDPとは異なるアドレス体系(ファイルパス)と通信メカニズムを持っています。- 以前の
*UDPConn
を返す実装では、返されたコネクションオブジェクトがnet.UDPConn
のメソッド(例えば、IPアドレスやポート番号を扱うもの)しか提供せず、Unixドメインソケット固有の機能(例えば、ReadFromUnix
やWriteToUnix
でUnixドメインアドレスを直接扱うこと)を利用できませんでした。これは、Unixドメインデータグラムソケットの本来の目的と機能に合致していませんでした。 *UnixConn
を返すように変更することで、返されるコネクションオブジェクトはnet.UnixConn
のすべてのメソッドを利用できるようになります。これにより、Unixドメインデータグラムソケットの特性を完全に活用し、送信元アドレスの取得や特定の宛先への送信が可能になります。
-
APIの正確性:
- Go 1のAPI互換性を破る変更であると明記されていますが、コミットメッセージにあるように「previous ListenUnixgram doesn't work in any use cases」であったため、実質的な影響は限定的であると判断されました。機能しないAPIを修正することは、長期的なAPIの健全性にとって重要です。
- この変更により、
ListenUnixgram
のAPIは、その機能と戻り値の型が一致し、より直感的で正確なものとなりました。
-
内部実装の調整:
- 戻り値の型を変更するだけでなく、内部的なソケットの作成と管理も
UnixConn
のセマンティクスに合わせる必要があります。 src/pkg/net/unixsock_posix.go
内のListenUnixgram
の実装では、最終的にnewUnixConn(fd)
を呼び出して*UnixConn
を返すように変更されています。これは、ソケットディスクリプタ(fd
)がUnixドメインソケットとして適切に初期化され、UnixConn
の構造体でラップされることを意味します。- テストコード(
src/pkg/net/protoconn_test.go
)も、ListenUnixgram
が*UnixConn
を返すことを前提としたテストケース(WriteToUnix
やReadFromUnix
の使用)が追加され、変更の正当性を検証しています。
- 戻り値の型を変更するだけでなく、内部的なソケットの作成と管理も
-
ドキュメントの更新:
doc/go1.1.html
に、ListenUnixgram
がUnixConn
を返すようになったこと、そしてReadFrom
やWriteTo
メソッドがUnixConn
上で利用可能になったことが明記されています。これは、APIの変更をユーザーに明確に伝えるために不可欠です。
この変更は、Go言語のnet
パッケージが提供するUnixドメインソケットの機能が、より堅牢で使いやすいものになるための重要なステップでした。
コアとなるコードの変更箇所
このコミットにおける主要なコード変更は、src/pkg/net/unixsock_posix.go
とsrc/pkg/net/dial.go
、そしてドキュメントファイルdoc/go1.1.html
に集中しています。
-
src/pkg/net/unixsock_posix.go
:ListenUnixgram
関数のシグネチャが変更されました。--- a/src/pkg/net/unixsock_posix.go +++ b/src/pkg/net/unixsock_posix.go @@ -347,5 +348,5 @@ func ListenUnixgram(net string, laddr *UnixAddr) (*UDPConn, error) { if err != nil { return nil, err } - return newUDPConn(fd), nil + return newUnixConn(fd), nil }
ListenUnixgram
のコメントも更新され、戻り値が*UnixConn
であることが明記されました。--- a/src/pkg/net/unixsock_posix.go +++ b/src/pkg/net/unixsock_posix.go @@ -328,16 +329,16 @@ func (l *UnixListener) SetDeadline(t time.Time) (err error) { return setDeadline(l.fd, t) } -// ListenUnixgram listens for incoming Unix datagram packets addressed to the -// local address laddr. The returned connection c's ReadFrom -// and WriteTo methods can be used to receive and send UDP -// packets with per-packet addressing. The network net must be "unixgram". -func ListenUnixgram(net string, laddr *UnixAddr) (*UDPConn, error) { +// ListenUnixgram listens for incoming Unix datagram packets addressed +// to the local address laddr. The returned connection c's ReadFrom +// and WriteTo methods can be used to receive and send packets with +// per-packet addressing. The network net must be "unixgram". +func ListenUnixgram(net string, laddr *UnixAddr) (*UnixConn, error) { switch net { case "unixgram": default: return nil, UnknownNetworkError(net) }
-
src/pkg/net/dial.go
:ListenPacket
関数内で、"unixgram"
ネットワークの場合にDialUnix
の代わりにListenUnixgram
を呼び出すように変更されました。--- a/src/pkg/net/dial.go +++ b/src/pkg/net/dial.go @@ -238,7 +238,7 @@ func ListenPacket(net, laddr string) (PacketConn, error) { if a != nil { la = a.(*UnixAddr) } - return DialUnix(net, la, nil) + return ListenUnixgram(net, la) } return nil, UnknownNetworkError(net) }
-
doc/go1.1.html
:- Go 1.1のドキュメントに、
ListenUnixgram
がUDPConn
ではなくUnixConn
を返すようになったこと、そしてUnixConn
上でReadFrom
およびWriteTo
メソッドが利用可能になったことが追記されました。--- a/doc/go1.1.html +++ b/doc/go1.1.html @@ -84,6 +84,13 @@ The same is true of the other protocol-specific resolvers <code>ResolveIPAddr</c <code>ResolveUnixAddr</code>. </p> +<p> +The previous <code>ListenUnixgram</code> returned <code>UDPConn</code> as +arepresentation of the connection endpoint. The Go 1.1 implementation +returns <code>UnixConn</code> to allow reading and writing +with <code>ReadFrom</code> and <code>WriteTo</code> methods on +the <code>UnixConn</code>. +</p> <h3 id="time">time</h3> <p>
- Go 1.1のドキュメントに、
-
src/pkg/net/protoconn_test.go
:TestUnixConnSpecificMethods
テストケースが拡張され、ListenUnixgram
が返すUnixConn
に対してWriteToUnix
やReadFromUnix
が正しく機能することを確認するテストが追加されました。- 一時ファイルパスとして
p3
が追加され、新しいListenUnixgram
のテストに使用されています。
コアとなるコードの解説
-
src/pkg/net/unixsock_posix.go
におけるListenUnixgram
の変更:- シグネチャの変更: 最も重要な変更は、
ListenUnixgram
関数の戻り値の型が*UDPConn
から*UnixConn
に変更されたことです。- 変更前:
func ListenUnixgram(net string, laddr *UnixAddr) (*UDPConn, error)
- 変更後:
func ListenUnixgram(net string, laddr *UnixAddr) (*UnixConn, error)
- 変更前:
- インスタンス生成の変更: 関数内部で、ソケットディスクリプタ
fd
からコネクションオブジェクトを生成する際に、newUDPConn(fd)
の代わりにnewUnixConn(fd)
が呼び出されるようになりました。newUDPConn
はUDPソケットに特化したUDPConn
型を生成しますが、newUnixConn
はUnixドメインソケットに特化したUnixConn
型を生成します。この変更により、ListenUnixgram
が返すオブジェクトは、Unixドメインソケットの特性(例えば、ファイルパスを介したアドレス指定や、ReadFromUnix
/WriteToUnix
のようなUnixドメインソケット固有のメソッド)を正しく扱うことができるようになります。
- シグネチャの変更: 最も重要な変更は、
-
src/pkg/net/dial.go
におけるListenPacket
の変更:ListenPacket
関数は、指定されたネットワークとローカルアドレスに基づいてパケットコネクションをリッスンするための汎用関数です。- 以前は、
"unixgram"
ネットワークの場合にDialUnix
を呼び出していました。しかし、DialUnix
は通常、クライアント側から特定のUnixドメインソケットに接続するために使用されるものであり、データグラムソケットをリッスンするListenUnixgram
とは目的が異なります。 - この変更により、
"unixgram"
ネットワークの場合は、正しくListenUnixgram
が呼び出されるようになりました。これにより、ListenPacket
を通じてUnixドメインデータグラムソケットをリッスンする際にも、新しいListenUnixgram
の正しい動作が反映されるようになります。
-
doc/go1.1.html
におけるドキュメントの更新:- Go 1.1のリリースノートに、このAPI変更が明記されました。これにより、Go 1.1にアップグレードする開発者は、
ListenUnixgram
の戻り値の型が変更されたこと、そしてUnixConn
上でReadFrom
やWriteTo
といったメソッドが利用可能になったことを認識できます。これは、APIの互換性を破る変更であるため、ユーザーへの明確な情報提供が非常に重要です。
- Go 1.1のリリースノートに、このAPI変更が明記されました。これにより、Go 1.1にアップグレードする開発者は、
これらの変更は、Go言語のnet
パッケージにおけるUnixドメインデータグラムソケットのサポートを修正し、より堅牢で機能的なものにするためのものです。
関連リンク
- GitHubコミットページ: https://github.com/golang/go/commit/0d197251eedad2185a41f9fe7facb20fd5bb3061
- Go Issue #3875: https://github.com/golang/go/issues/3875
- Go CL 6937059: https://golang.org/cl/6937059
参考にした情報源リンク
- Go言語の
net
パッケージ公式ドキュメント: https://pkg.go.dev/net - Unixドメインソケットに関する一般的な情報源 (例: Wikipedia, Linux man pagesなど)
- Go 1.1 Release Notes (該当箇所): https://go.dev/doc/go1.1 (このコミットで更新された
doc/go1.1.html
の内容が反映されています) - Go言語の
net
パッケージのソースコード (特にsrc/pkg/net/unixsock_posix.go
,src/pkg/net/dial.go
,src/pkg/net/protoconn_test.go
)