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

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

このコミットは、Go言語のsyscallパッケージにOpenBSDにおけるif_announceメッセージのサポートを追加するものです。これにより、GoプログラムがOpenBSDシステム上でネットワークインターフェースの到着(追加)や離脱(削除)といったイベントを検知し、処理できるようになります。

コミット

commit 6a41b9983c2bce565d6fb5b62c7cfb3db7ec1037
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date:   Sun Feb 24 12:07:20 2013 +0900

    syscall: add if_announce support for openbsd
    
    Update #4866.
    
    R=golang-dev
    CC=golang-dev
    https://golang.org/cl/7382053

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

https://github.com/golang/go/commit/6a41b9983c2bce565d6fb5b62c7cfb3db7ec1037

元コミット内容

syscall: OpenBSD向けにif_announceサポートを追加

変更の背景

この変更は、Go言語のsyscallパッケージがOpenBSD環境でネットワークインターフェースの動的な変更(追加や削除)を適切に処理できるようにするために行われました。OpenBSDでは、if_announceというメカニズムを通じて、カーネルがネットワークインターフェースの状態変化をユーザーランドのプロセスに通知します。Goプログラムがこれらのイベントを監視し、対応するためには、syscallパッケージがif_announceメッセージの構造と関連する定数を認識し、処理できる必要があります。このコミットは、Issue #4866の解決を目的としています。

前提知識の解説

  • OpenBSD: OpenBSDは、セキュリティとコードの品質に重点を置いたUNIX系オペレーティングシステムです。ネットワーク機能が非常に堅牢であり、多くのセキュリティ機能が組み込まれています。
  • if_announce: OpenBSDカーネルが提供するメカニズムの一つで、ネットワークインターフェースの動的な状態変化(例: イーサネットカードの挿入/取り外し、Wi-Fi接続の確立/切断)をユーザーランドのアプリケーションに通知するために使用されます。これにより、アプリケーションはインターフェースの状態変化にリアルタイムで対応できます。
  • ルーティングソケット (Routing Sockets): if_announceメッセージは、ルーティングソケットと呼ばれる特殊なソケットを通じてユーザーランドに配信されます。ルーティングソケットは、カーネルのルーティングテーブルやネットワークインターフェースに関する情報を取得・設定したり、カーネルからのネットワークイベント通知を受け取ったりするためのインターフェースを提供します。
  • Go syscall パッケージ: Go言語の標準ライブラリの一部であり、オペレーティングシステムが提供する低レベルのシステムコールやデータ構造へのインターフェースを提供します。これにより、GoプログラムはOS固有の機能に直接アクセスできます。ネットワーク関連の操作やプロセス管理など、OSと密接に連携する機能の実装に不可欠です。
  • Go golang.org/x/net/route パッケージ: Go言語の拡張パッケージであり、BSD系のシステムにおけるパケットルーティング機能との連携を容易にするための機能を提供します。syscallパッケージと連携して、ルーティングソケットから受信したメッセージをGoのデータ構造にマッピングし、アプリケーションが扱いやすい形式で提供します。

技術的詳細

OpenBSDにおけるif_announceのサポートは、主に以下の要素をGoのsyscallパッケージに追加することで実現されます。

  1. IfAnnounceMsghdr構造体: if_announceメッセージのヘッダー部分を表現するGoの構造体です。この構造体には、メッセージの長さ、バージョン、タイプ、ヘッダー長、インターフェースのインデックス、イベントの種類(到着か離脱か)、インターフェース名などの情報が含まれます。カーネルからルーティングソケット経由で受信したバイナリデータを、Goプログラムが解釈可能な形式にマッピングするために必要です。
  2. SizeofIfAnnounceMsghdr定数: IfAnnounceMsghdr構造体のサイズを示す定数です。これは、メッセージのパースやメモリ割り当てにおいて、正確なサイズを把握するために使用されます。アーキテクチャ(386とamd64)によってサイズが異なるため、それぞれのztypesファイルで定義されます。
  3. イベントタイプ定数:
    • IFAN_ARRIVAL: ネットワークインターフェースがシステムに「到着」した(追加された、利用可能になった)ことを示すイベントタイプです。
    • IFAN_DEPARTURE: ネットワークインターフェースがシステムから「離脱」した(削除された、利用不可になった)ことを示すイベントタイプです。 これらの定数は、受信したif_announceメッセージのWhatフィールドを解釈するために使用されます。

これらの要素がsyscallパッケージに追加されることで、Goプログラムはルーティングソケットを介してRTM_IFANNOUNCEタイプのメッセージを受信し、その内容をIfAnnounceMsghdr構造体としてパースし、インターフェースの到着や離脱イベントを正確に識別できるようになります。これにより、ネットワークインターフェースの動的な変化に対応するGoアプリケーションの開発が可能になります。

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

このコミットでは、以下のファイルが変更されています。

  • src/pkg/syscall/types_openbsd.go: OpenBSD固有のsyscallデータ型定義が含まれるファイルです。
    • SizeofIfAnnounceMsghdr定数の追加。
    • IfAnnounceMsghdr構造体の型定義の追加。
  • src/pkg/syscall/zerrors_openbsd_386.go: OpenBSD/386アーキテクチャ固有のエラーコードや定数が自動生成されるファイルです。
    • IFAN_ARRIVAL定数の追加。
    • IFAN_DEPARTURE定数の追加。
  • src/pkg/syscall/zerrors_openbsd_amd64.go: OpenBSD/amd64アーキテクチャ固有のエラーコードや定数が自動生成されるファイルです。
    • IFAN_ARRIVAL定数の追加。
    • IFAN_DEPARTURE定数の追加。
  • src/pkg/syscall/ztypes_openbsd_386.go: OpenBSD/386アーキテクチャ固有のデータ型サイズや構造体が自動生成されるファイルです。
    • SizeofIfAnnounceMsghdr定数の具体的な値の追加。
    • IfAnnounceMsghdr構造体の具体的なフィールド定義の追加。
  • src/pkg/syscall/ztypes_openbsd_amd64.go: OpenBSD/amd64アーキテクチャ固有のデータ型サイズや構造体が自動生成されるファイルです。
    • SizeofIfAnnounceMsghdr定数の具体的な値の追加。
    • IfAnnounceMsghdr構造体の具体的なフィールド定義の追加。

コアとなるコードの解説

src/pkg/syscall/types_openbsd.go

 const (
-	SizeofIfMsghdr  = C.sizeof_struct_if_msghdr
-	SizeofIfData    = C.sizeof_struct_if_data
-	SizeofIfaMsghdr = C.sizeof_struct_ifa_msghdr
-	SizeofRtMsghdr  = C.sizeof_struct_rt_msghdr
-	SizeofRtMetrics = C.sizeof_struct_rt_metrics
+	SizeofIfMsghdr         = C.sizeof_struct_if_msghdr
+	SizeofIfData           = C.sizeof_struct_if_data
+	SizeofIfaMsghdr        = C.sizeof_struct_ifa_msghdr
+	SizeofIfAnnounceMsghdr = C.sizeof_struct_if_announcemsghdr // 新規追加
+	SizeofRtMsghdr         = C.sizeof_struct_rt_msghdr
+	SizeofRtMetrics        = C.sizeof_struct_rt_metrics
 )

 type IfaMsghdr C.struct_ifa_msghdr

+type IfAnnounceMsghdr C.struct_if_announcemsghdr // 新規追加

この部分では、if_announceメッセージヘッダーのサイズを示すSizeofIfAnnounceMsghdr定数と、そのC言語の構造体に対応するGoの型IfAnnounceMsghdrが追加されています。C.sizeof_struct_if_announcemsghdrは、Cgoを通じてC言語の構造体のサイズを取得します。

src/pkg/syscall/zerrors_openbsd_386.go および src/pkg/syscall/zerrors_openbsd_amd64.go

 	ICANON                            = 0x100
 	ICRNL                             = 0x100
 	IEXTEN                            = 0x400
+	IFAN_ARRIVAL                      = 0x0 // 新規追加
+	IFAN_DEPARTURE                    = 0x1 // 新規追加
 	IFA_ROUTE                         = 0x1
 	IFF_ALLMULTI                      = 0x200
 	IFF_BROADCAST                     = 0x2

これらのファイルでは、if_announceイベントの種類を識別するための定数IFAN_ARRIVAL(インターフェース到着)とIFAN_DEPARTURE(インターフェース離脱)が追加されています。これらの値は、カーネルが通知するイベントの種類に対応します。

src/pkg/syscall/ztypes_openbsd_386.go および src/pkg/syscall/ztypes_openbsd_amd64.go

 const (
-	SizeofIfMsghdr  = 0xe8
-	SizeofIfData    = 0xd0
-	SizeofIfaMsghdr = 0x18
-	SizeofRtMsghdr  = 0x58
-	SizeofRtMetrics = 0x30
+	SizeofIfMsghdr         = 0xe8
+	SizeofIfData           = 0xd0
+	SizeofIfaMsghdr        = 0x18
+	SizeofIfAnnounceMsghdr = 0x1a // 新規追加
+	SizeofRtMsghdr         = 0x58
+	SizeofRtMetrics        = 0x30
 )

 type IfaMsghdr struct {
 	Type    uint8
 	Addrs   int32
 	Flags   int32
 	Metric  int32
 }

+type IfAnnounceMsghdr struct { // 新規追加
+	Msglen  uint16
+	Version uint8
+	Type    uint8
+	Hdrlen  uint16
+	Index   uint16
+	What    uint16
+	Name    [16]int8
+}

これらのファイルでは、SizeofIfAnnounceMsghdrの具体的なバイトサイズ(0x1a)が定義され、IfAnnounceMsghdr構造体のGo言語での具体的なフィールド定義が追加されています。この構造体は、if_announceメッセージのバイナリフォーマットをGoの型システムにマッピングするために不可欠です。各フィールドは、メッセージの長さ、バージョン、タイプ、ヘッダー長、インターフェースインデックス、イベントの種類(What)、およびインターフェース名(Name)に対応します。

これらの変更により、GoのsyscallパッケージはOpenBSDカーネルが発行するif_announceメッセージを正しく解釈し、Goプログラムがネットワークインターフェースの動的な変化に対応できるようになります。

関連リンク

参考にした情報源リンク