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

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

このドキュメントは、Go言語のnetパッケージにおけるコミット e266d6064c7e485673ea651d673b2ca22e0649f2 についての詳細な技術解説を提供します。このコミットは、Dial関数とunixgramネットワークの使用に関するコメントの修正を目的としています。

コミット

commit e266d6064c7e485673ea651d673b2ca22e0649f2
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date:   Wed Feb 29 07:45:38 2012 +0900

    net: fix comment on Dial with unixgram
    
    We should use DialUnix or ListenPacket for unixgram networks
    because Dial doesn't take a local UnixAddr.
    
    R=golang-dev, rsc
    CC=golang-dev
    https://golang.org/cl/5706043

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

https://github.com/golang/go/commit/e266d6064c7e485673ea651d673b2ca22e0649f2

元コミット内容

net: fix comment on Dial with unixgram

We should use DialUnix or ListenPacket for unixgram networks because Dial doesn't take a local UnixAddr.

変更の背景

このコミットは、Go言語の標準ライブラリであるnetパッケージ内のdial.goファイルにおけるコメントの誤りを修正することを目的としています。具体的には、Dial関数がサポートするネットワークタイプの説明において、unixgramネットワークに関する記述が不正確であったため、その点を修正しています。

Dial関数は、指定されたネットワークアドレスへの接続を確立するための汎用的なインターフェースを提供しますが、unixgramネットワーク(Unixドメインデータグラムソケット)の場合、Dial関数はローカルのUnixAddr(Unixドメインソケットのアドレス)を受け取ることができません。そのため、unixgramネットワークを使用する際には、より特化した関数であるDialUnixまたはListenPacketを使用することが推奨されます。このコミットは、この重要な使用上の注意点をコメントに明記することで、開発者が正しいAPIを選択できるようにガイドすることを意図しています。

前提知識の解説

Go言語のnetパッケージ

Go言語のnetパッケージは、ネットワークI/Oのポータブルなインターフェースを提供します。TCP/IP、UDP、Unixドメインソケットなど、様々なネットワークプロトコルを扱うための機能が含まれています。

net.Dial関数

net.Dialは、Go言語でネットワーク接続を確立するための最も一般的な関数の一つです。以下のようなシグネチャを持ちます。

func Dial(network, address string) (Conn, error)
  • network: 接続するネットワークの種類を指定します(例: "tcp", "udp", "unix")。
  • address: 接続先のアドレスを指定します(例: "localhost:8080", "/tmp/sock")。

この関数は、指定されたネットワークとアドレスに基づいて、適切なnet.Connインターフェースを返します。

Unixドメインソケット

Unixドメインソケットは、同じホスト上のプロセス間通信(IPC)に使用されるソケットの一種です。ネットワークスタックを介さずに直接カーネルを介して通信するため、TCP/IPソケットよりも高速で効率的です。Unixドメインソケットには以下の種類があります。

  • ストリームソケット (unix): TCPと同様に、信頼性のある接続指向のバイトストリームを提供します。
  • データグラムソケット (unixgram): UDPと同様に、非接続指向のデータグラム通信を提供します。メッセージの境界が保持されますが、信頼性や順序は保証されません。
  • シーケンスパケットソケット (unixpacket): ストリームソケットとデータグラムソケットの中間的な性質を持ち、信頼性のある接続指向のデータグラム通信を提供します。

net.UnixAddr

net.UnixAddrは、Unixドメインソケットのアドレスを表す構造体です。通常、ファイルシステム上のパス(例: /tmp/my.sock)として表現されます。

type UnixAddr struct {
    Name string // Unix socket path
    Net  string // "unix", "unixgram", or "unixpacket"
}

net.DialUnix関数

net.DialUnixは、Unixドメインソケットに特化した接続関数です。

func DialUnix(network string, laddr, raddr *UnixAddr) (*UnixConn, error)
  • network: "unix", "unixgram", "unixpacket" のいずれかを指定します。
  • laddr: オプションでローカルのUnixAddrを指定します。nilの場合、システムが自動的に選択します。
  • raddr: 接続先のリモートUnixAddrを指定します。

この関数は、Dialとは異なり、ローカルアドレスを明示的に指定できる点が特徴です。

net.ListenPacket関数

net.ListenPacketは、パケット指向のネットワーク接続をリッスンするための関数です。

func ListenPacket(network, address string) (PacketConn, error)
  • network: "udp", "udp4", "udp6", "unixgram" などを指定します。
  • address: ローカルのネットワークアドレスを指定します。

この関数は、データグラムソケット(例: UDPやUnixデータグラム)からのパケットを受信するために使用されます。

技術的詳細

net.Dial関数は、内部的にresolveNetAddr関数を呼び出してネットワークアドレスを解決します。しかし、unixgramネットワークの場合、Dialの設計上、ローカルのUnixAddrを引数として受け取ることができません。これは、Dialが主にリモートアドレスへの接続を目的としているためです。

unixgramソケットはデータグラム指向であり、送信元アドレスが重要になる場合があります。Dial関数でunixgramを使用しようとすると、ローカルアドレスが適切に設定されないため、意図しない動作やエラーが発生する可能性があります。

このため、unixgramネットワークでクライアントとして接続する場合や、特定のローカルアドレスからパケットを送信したい場合には、net.DialUnixを使用し、laddr引数にローカルのUnixAddrを指定することが適切です。また、unixgramソケットでパケットを受信し、サーバーとして機能する場合には、net.ListenPacketを使用するのが正しいアプローチです。

このコミットは、dial.go内のコメントが、Dial関数がunixgramネットワークもサポートしているかのように誤解を招く可能性があったため、その記述を修正し、より正確な情報を提供することで、開発者が適切なAPIを選択できるように促しています。

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

変更はsrc/pkg/net/dial.goファイル内の1行のみです。

--- a/src/pkg/net/dial.go
+++ b/src/pkg/net/dial.go
@@ -69,7 +69,7 @@ func resolveNetAddr(op, net, addr string) (afnet string, a Addr, err error) {
 //
 // Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
 // "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
-// (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and "unixpacket".
+// (IPv4-only), "ip6" (IPv6-only), "unix" and "unixpacket".
 //
 // For TCP and UDP networks, addresses have the form host:port.
 // If host is a literal IPv6 address, it must be enclosed

具体的には、69行目のコメントから "unixgram"という文字列が削除されています。

コアとなるコードの解説

変更された行は、Dial関数がサポートする「既知のネットワーク」を列挙しているコメントの一部です。

変更前: // (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and "unixpacket".

変更後: // (IPv4-only), "ip6" (IPv6-only), "unix" and "unixpacket".

この修正により、Dial関数がunixgramネットワークに対して直接的に推奨されるAPIではないという事実が、コメントによって明確に示されるようになりました。これは、DialがローカルのUnixAddrを受け取らないという技術的な制約を反映したものです。開発者はこのコメントを見ることで、unixgramネットワークを扱う際にはDialUnixListenPacketといったより適切な関数を使用すべきであると理解できます。

関連リンク

参考にした情報源リンク