Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c87faace6b | ||
|
|
1e8b185377 | ||
|
|
031804827f | ||
|
|
6cccd9b6fc | ||
|
|
687fbb0a7e | ||
|
|
8f2db99c86 | ||
|
|
2c0f8dc546 | ||
|
|
a388fb0bb7 | ||
|
|
27465353c1 | ||
|
|
c2ccab4361 | ||
|
|
bb876eac82 | ||
|
|
34c04babbe |
@@ -1,7 +1,6 @@
|
|||||||
# This is the official list of Syncthing authors for copyright purposes.
|
# This is the official list of Syncthing authors for copyright purposes.
|
||||||
|
|
||||||
Aaron Bieber <qbit@deftly.net>
|
Aaron Bieber <qbit@deftly.net>
|
||||||
Adam Piggott <aD@simplypeachy.co.uk> <simplypeachy@users.noreply.github.com>
|
|
||||||
Alexander Graf <register-github@alex-graf.de>
|
Alexander Graf <register-github@alex-graf.de>
|
||||||
Andrew Dunham <andrew@du.nham.ca>
|
Andrew Dunham <andrew@du.nham.ca>
|
||||||
Antony Male <antony.male@gmail.com>
|
Antony Male <antony.male@gmail.com>
|
||||||
@@ -48,7 +47,6 @@ Lord Landon Agahnim <lordlandon@gmail.com>
|
|||||||
Marc Laporte <marc@marclaporte.com> <marc@laporte.name>
|
Marc Laporte <marc@marclaporte.com> <marc@laporte.name>
|
||||||
Marc Pujol <kilburn@la3.org>
|
Marc Pujol <kilburn@la3.org>
|
||||||
Marcin Dziadus <dziadus.marcin@gmail.com>
|
Marcin Dziadus <dziadus.marcin@gmail.com>
|
||||||
Matt Burke <mburke@amplify.com>
|
|
||||||
Michael Jephcote <rewt0r@gmx.com> <Rewt0r@users.noreply.github.com>
|
Michael Jephcote <rewt0r@gmx.com> <Rewt0r@users.noreply.github.com>
|
||||||
Michael Tilli <pyfisch@gmail.com>
|
Michael Tilli <pyfisch@gmail.com>
|
||||||
Pascal Jungblut <github@pascalj.com> <mail@pascal-jungblut.com>
|
Pascal Jungblut <github@pascalj.com> <mail@pascal-jungblut.com>
|
||||||
@@ -58,7 +56,7 @@ Phill Luby <phill.luby@newredo.com>
|
|||||||
Piotr Bejda <piotrb10@gmail.com>
|
Piotr Bejda <piotrb10@gmail.com>
|
||||||
Ryan Sullivan <kayoticsully@gmail.com>
|
Ryan Sullivan <kayoticsully@gmail.com>
|
||||||
Sergey Mishin <ralder@yandex.ru>
|
Sergey Mishin <ralder@yandex.ru>
|
||||||
Stefan Tatschner <stefan@sevenbyte.org> <rumpelsepp@sevenbyte.org>
|
Stefan Tatschner <stefan@sevenbyte.org>
|
||||||
Tim Abell <tim@timwise.co.uk>
|
Tim Abell <tim@timwise.co.uk>
|
||||||
Tobias Nygren <tnn@nygren.pp.se>
|
Tobias Nygren <tnn@nygren.pp.se>
|
||||||
Tomas Cerveny <kozec@kozec.com>
|
Tomas Cerveny <kozec@kozec.com>
|
||||||
|
|||||||
Generated
+11
-12
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ImportPath": "github.com/syncthing/syncthing",
|
"ImportPath": "github.com/syncthing/syncthing",
|
||||||
"GoVersion": "go1.5",
|
"GoVersion": "go1.5rc1",
|
||||||
"Packages": [
|
"Packages": [
|
||||||
"./cmd/..."
|
"./cmd/..."
|
||||||
],
|
],
|
||||||
@@ -39,7 +39,15 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/syncthing/protocol",
|
"ImportPath": "github.com/syncthing/protocol",
|
||||||
"Rev": "388a29bbe21d8772ee4c29f4520aa8040309607d"
|
"Rev": "ebcdea63c07327a342f65415bbadc497462b8f1f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/syncthing/relaysrv/client",
|
||||||
|
"Rev": "7c6a31017968e7c1a69148db1ca3dea71eba8236"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/syncthing/relaysrv/protocol",
|
||||||
|
"Rev": "7c6a31017968e7c1a69148db1ca3dea71eba8236"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb",
|
"ImportPath": "github.com/syndtr/goleveldb/leveldb",
|
||||||
@@ -47,8 +55,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/thejerf/suture",
|
"ImportPath": "github.com/thejerf/suture",
|
||||||
"Comment": "v1.0.1",
|
"Rev": "fc7aaeabdc43fe41c5328efa1479ffea0b820978"
|
||||||
"Rev": "99c1f2d613756768fc4299acd9dc621e11ed3fd7"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/vitrun/qart/coding",
|
"ImportPath": "github.com/vitrun/qart/coding",
|
||||||
@@ -70,14 +77,6 @@
|
|||||||
"ImportPath": "golang.org/x/crypto/blowfish",
|
"ImportPath": "golang.org/x/crypto/blowfish",
|
||||||
"Rev": "c16968172724c0b5e8bdc6ad33f5a79443a44cd7"
|
"Rev": "c16968172724c0b5e8bdc6ad33f5a79443a44cd7"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/net/internal/iana",
|
|
||||||
"Rev": "66f0418ca41253f8d1a024eb9754e9441a8e79b9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/net/ipv6",
|
|
||||||
"Rev": "66f0418ca41253f8d1a024eb9754e9441a8e79b9"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/text/transform",
|
"ImportPath": "golang.org/x/text/transform",
|
||||||
"Rev": "723492b65e225eafcba054e76ba18bb9c5ac1ea2"
|
"Rev": "723492b65e225eafcba054e76ba18bb9c5ac1ea2"
|
||||||
|
|||||||
+2
-2
@@ -31,11 +31,11 @@ func (t *TestModel) Index(deviceID DeviceID, folder string, files []FileInfo, fl
|
|||||||
func (t *TestModel) IndexUpdate(deviceID DeviceID, folder string, files []FileInfo, flags uint32, options []Option) {
|
func (t *TestModel) IndexUpdate(deviceID DeviceID, folder string, files []FileInfo, flags uint32, options []Option) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestModel) Request(deviceID DeviceID, folder, name string, offset int64, hash []byte, flags uint32, options []Option, buf []byte) error {
|
func (t *TestModel) Request(deviceID DeviceID, folder, name string, offset int64, size int, hash []byte, flags uint32, options []Option, buf []byte) error {
|
||||||
t.folder = folder
|
t.folder = folder
|
||||||
t.name = name
|
t.name = name
|
||||||
t.offset = offset
|
t.offset = offset
|
||||||
t.size = len(buf)
|
t.size = size
|
||||||
t.hash = hash
|
t.hash = hash
|
||||||
t.flags = flags
|
t.flags = flags
|
||||||
t.options = options
|
t.options = options
|
||||||
|
|||||||
-70
@@ -1,70 +0,0 @@
|
|||||||
// Copyright (C) 2015 The Protocol Authors.
|
|
||||||
|
|
||||||
// +build gofuzz
|
|
||||||
|
|
||||||
package protocol
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Fuzz(data []byte) int {
|
|
||||||
// Regenerate the length, or we'll most commonly exit quickly due to an
|
|
||||||
// unexpected eof which is unintestering.
|
|
||||||
if len(data) > 8 {
|
|
||||||
binary.BigEndian.PutUint32(data[4:], uint32(len(data))-8)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup a rawConnection we'll use to parse the message.
|
|
||||||
c := rawConnection{
|
|
||||||
cr: &countingReader{Reader: bytes.NewReader(data)},
|
|
||||||
closed: make(chan struct{}),
|
|
||||||
pool: sync.Pool{
|
|
||||||
New: func() interface{} {
|
|
||||||
return make([]byte, BlockSize)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt to parse the message.
|
|
||||||
hdr, msg, err := c.readMessage()
|
|
||||||
if err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// If parsing worked, attempt to encode it again.
|
|
||||||
newBs, err := msg.AppendXDR(nil)
|
|
||||||
if err != nil {
|
|
||||||
panic("not encodable")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create an appriate header for the re-encoding.
|
|
||||||
newMsg := make([]byte, 8)
|
|
||||||
binary.BigEndian.PutUint32(newMsg, encodeHeader(hdr))
|
|
||||||
binary.BigEndian.PutUint32(newMsg[4:], uint32(len(newBs)))
|
|
||||||
newMsg = append(newMsg, newBs...)
|
|
||||||
|
|
||||||
// Use the rawConnection to parse the re-encoding.
|
|
||||||
c.cr = &countingReader{Reader: bytes.NewReader(newMsg)}
|
|
||||||
hdr2, msg2, err := c.readMessage()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Initial:\n" + hex.Dump(data))
|
|
||||||
fmt.Println("New:\n" + hex.Dump(newMsg))
|
|
||||||
panic("not parseable after re-encode: " + err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure the data is the same as it was before.
|
|
||||||
if hdr != hdr2 {
|
|
||||||
panic("headers differ")
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(msg, msg2) {
|
|
||||||
panic("contents differ")
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
-89
@@ -1,89 +0,0 @@
|
|||||||
// Copyright (C) 2015 The Protocol Authors.
|
|
||||||
|
|
||||||
// +build gofuzz
|
|
||||||
|
|
||||||
package protocol
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
"testing/quick"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This can be used to generate a corpus of valid messages as a starting point
|
|
||||||
// for the fuzzer.
|
|
||||||
func TestGenerateCorpus(t *testing.T) {
|
|
||||||
t.Skip("Use to generate initial corpus only")
|
|
||||||
|
|
||||||
n := 0
|
|
||||||
check := func(idx IndexMessage) bool {
|
|
||||||
for i := range idx.Options {
|
|
||||||
if len(idx.Options[i].Key) > 64 {
|
|
||||||
idx.Options[i].Key = idx.Options[i].Key[:64]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hdr := header{
|
|
||||||
version: 0,
|
|
||||||
msgID: 42,
|
|
||||||
msgType: messageTypeIndex,
|
|
||||||
compression: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
msgBs := idx.MustMarshalXDR()
|
|
||||||
|
|
||||||
buf := make([]byte, 8)
|
|
||||||
binary.BigEndian.PutUint32(buf, encodeHeader(hdr))
|
|
||||||
binary.BigEndian.PutUint32(buf[4:], uint32(len(msgBs)))
|
|
||||||
buf = append(buf, msgBs...)
|
|
||||||
|
|
||||||
ioutil.WriteFile(fmt.Sprintf("testdata/corpus/test-%03d.xdr", n), buf, 0644)
|
|
||||||
n++
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := quick.Check(check, &quick.Config{MaxCount: 1000}); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tests any crashers found by the fuzzer, for closer investigation.
|
|
||||||
func TestCrashers(t *testing.T) {
|
|
||||||
testFiles(t, "testdata/crashers")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tests the entire corpus, which should PASS before the fuzzer starts
|
|
||||||
// fuzzing.
|
|
||||||
func TestCorpus(t *testing.T) {
|
|
||||||
testFiles(t, "testdata/corpus")
|
|
||||||
}
|
|
||||||
|
|
||||||
func testFiles(t *testing.T, dir string) {
|
|
||||||
fd, err := os.Open(dir)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
crashers, err := fd.Readdirnames(-1)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
for _, name := range crashers {
|
|
||||||
if strings.HasSuffix(name, ".output") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if strings.HasSuffix(name, ".quoted") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Log(name)
|
|
||||||
crasher, err := ioutil.ReadFile(dir + "/" + name)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
Fuzz(crasher)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+7
-7
@@ -9,7 +9,7 @@ import "fmt"
|
|||||||
|
|
||||||
type IndexMessage struct {
|
type IndexMessage struct {
|
||||||
Folder string
|
Folder string
|
||||||
Files []FileInfo // max:1000000
|
Files []FileInfo
|
||||||
Flags uint32
|
Flags uint32
|
||||||
Options []Option // max:64
|
Options []Option // max:64
|
||||||
}
|
}
|
||||||
@@ -20,7 +20,7 @@ type FileInfo struct {
|
|||||||
Modified int64
|
Modified int64
|
||||||
Version Vector
|
Version Vector
|
||||||
LocalVersion int64
|
LocalVersion int64
|
||||||
Blocks []BlockInfo // max:1000000
|
Blocks []BlockInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f FileInfo) String() string {
|
func (f FileInfo) String() string {
|
||||||
@@ -109,9 +109,9 @@ type ResponseMessage struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ClusterConfigMessage struct {
|
type ClusterConfigMessage struct {
|
||||||
ClientName string // max:64
|
ClientName string // max:64
|
||||||
ClientVersion string // max:64
|
ClientVersion string // max:64
|
||||||
Folders []Folder // max:1000000
|
Folders []Folder
|
||||||
Options []Option // max:64
|
Options []Option // max:64
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,8 +125,8 @@ func (o *ClusterConfigMessage) GetOption(key string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Folder struct {
|
type Folder struct {
|
||||||
ID string // max:64
|
ID string // max:64
|
||||||
Devices []Device // max:1000000
|
Devices []Device
|
||||||
Flags uint32
|
Flags uint32
|
||||||
Options []Option // max:64
|
Options []Option // max:64
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-32
@@ -42,7 +42,7 @@ IndexMessage Structure:
|
|||||||
|
|
||||||
struct IndexMessage {
|
struct IndexMessage {
|
||||||
string Folder<>;
|
string Folder<>;
|
||||||
FileInfo Files<1000000>;
|
FileInfo Files<>;
|
||||||
unsigned int Flags;
|
unsigned int Flags;
|
||||||
Option Options<64>;
|
Option Options<64>;
|
||||||
}
|
}
|
||||||
@@ -75,9 +75,6 @@ func (o IndexMessage) AppendXDR(bs []byte) ([]byte, error) {
|
|||||||
|
|
||||||
func (o IndexMessage) EncodeXDRInto(xw *xdr.Writer) (int, error) {
|
func (o IndexMessage) EncodeXDRInto(xw *xdr.Writer) (int, error) {
|
||||||
xw.WriteString(o.Folder)
|
xw.WriteString(o.Folder)
|
||||||
if l := len(o.Files); l > 1000000 {
|
|
||||||
return xw.Tot(), xdr.ElementSizeExceeded("Files", l, 1000000)
|
|
||||||
}
|
|
||||||
xw.WriteUint32(uint32(len(o.Files)))
|
xw.WriteUint32(uint32(len(o.Files)))
|
||||||
for i := range o.Files {
|
for i := range o.Files {
|
||||||
_, err := o.Files[i].EncodeXDRInto(xw)
|
_, err := o.Files[i].EncodeXDRInto(xw)
|
||||||
@@ -114,10 +111,7 @@ func (o *IndexMessage) DecodeXDRFrom(xr *xdr.Reader) error {
|
|||||||
o.Folder = xr.ReadString()
|
o.Folder = xr.ReadString()
|
||||||
_FilesSize := int(xr.ReadUint32())
|
_FilesSize := int(xr.ReadUint32())
|
||||||
if _FilesSize < 0 {
|
if _FilesSize < 0 {
|
||||||
return xdr.ElementSizeExceeded("Files", _FilesSize, 1000000)
|
return xdr.ElementSizeExceeded("Files", _FilesSize, 0)
|
||||||
}
|
|
||||||
if _FilesSize > 1000000 {
|
|
||||||
return xdr.ElementSizeExceeded("Files", _FilesSize, 1000000)
|
|
||||||
}
|
}
|
||||||
o.Files = make([]FileInfo, _FilesSize)
|
o.Files = make([]FileInfo, _FilesSize)
|
||||||
for i := range o.Files {
|
for i := range o.Files {
|
||||||
@@ -179,7 +173,7 @@ struct FileInfo {
|
|||||||
hyper Modified;
|
hyper Modified;
|
||||||
Vector Version;
|
Vector Version;
|
||||||
hyper LocalVersion;
|
hyper LocalVersion;
|
||||||
BlockInfo Blocks<1000000>;
|
BlockInfo Blocks<>;
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
@@ -220,9 +214,6 @@ func (o FileInfo) EncodeXDRInto(xw *xdr.Writer) (int, error) {
|
|||||||
return xw.Tot(), err
|
return xw.Tot(), err
|
||||||
}
|
}
|
||||||
xw.WriteUint64(uint64(o.LocalVersion))
|
xw.WriteUint64(uint64(o.LocalVersion))
|
||||||
if l := len(o.Blocks); l > 1000000 {
|
|
||||||
return xw.Tot(), xdr.ElementSizeExceeded("Blocks", l, 1000000)
|
|
||||||
}
|
|
||||||
xw.WriteUint32(uint32(len(o.Blocks)))
|
xw.WriteUint32(uint32(len(o.Blocks)))
|
||||||
for i := range o.Blocks {
|
for i := range o.Blocks {
|
||||||
_, err := o.Blocks[i].EncodeXDRInto(xw)
|
_, err := o.Blocks[i].EncodeXDRInto(xw)
|
||||||
@@ -252,10 +243,7 @@ func (o *FileInfo) DecodeXDRFrom(xr *xdr.Reader) error {
|
|||||||
o.LocalVersion = int64(xr.ReadUint64())
|
o.LocalVersion = int64(xr.ReadUint64())
|
||||||
_BlocksSize := int(xr.ReadUint32())
|
_BlocksSize := int(xr.ReadUint32())
|
||||||
if _BlocksSize < 0 {
|
if _BlocksSize < 0 {
|
||||||
return xdr.ElementSizeExceeded("Blocks", _BlocksSize, 1000000)
|
return xdr.ElementSizeExceeded("Blocks", _BlocksSize, 0)
|
||||||
}
|
|
||||||
if _BlocksSize > 1000000 {
|
|
||||||
return xdr.ElementSizeExceeded("Blocks", _BlocksSize, 1000000)
|
|
||||||
}
|
}
|
||||||
o.Blocks = make([]BlockInfo, _BlocksSize)
|
o.Blocks = make([]BlockInfo, _BlocksSize)
|
||||||
for i := range o.Blocks {
|
for i := range o.Blocks {
|
||||||
@@ -583,7 +571,7 @@ ClusterConfigMessage Structure:
|
|||||||
struct ClusterConfigMessage {
|
struct ClusterConfigMessage {
|
||||||
string ClientName<64>;
|
string ClientName<64>;
|
||||||
string ClientVersion<64>;
|
string ClientVersion<64>;
|
||||||
Folder Folders<1000000>;
|
Folder Folders<>;
|
||||||
Option Options<64>;
|
Option Options<64>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -622,9 +610,6 @@ func (o ClusterConfigMessage) EncodeXDRInto(xw *xdr.Writer) (int, error) {
|
|||||||
return xw.Tot(), xdr.ElementSizeExceeded("ClientVersion", l, 64)
|
return xw.Tot(), xdr.ElementSizeExceeded("ClientVersion", l, 64)
|
||||||
}
|
}
|
||||||
xw.WriteString(o.ClientVersion)
|
xw.WriteString(o.ClientVersion)
|
||||||
if l := len(o.Folders); l > 1000000 {
|
|
||||||
return xw.Tot(), xdr.ElementSizeExceeded("Folders", l, 1000000)
|
|
||||||
}
|
|
||||||
xw.WriteUint32(uint32(len(o.Folders)))
|
xw.WriteUint32(uint32(len(o.Folders)))
|
||||||
for i := range o.Folders {
|
for i := range o.Folders {
|
||||||
_, err := o.Folders[i].EncodeXDRInto(xw)
|
_, err := o.Folders[i].EncodeXDRInto(xw)
|
||||||
@@ -661,10 +646,7 @@ func (o *ClusterConfigMessage) DecodeXDRFrom(xr *xdr.Reader) error {
|
|||||||
o.ClientVersion = xr.ReadStringMax(64)
|
o.ClientVersion = xr.ReadStringMax(64)
|
||||||
_FoldersSize := int(xr.ReadUint32())
|
_FoldersSize := int(xr.ReadUint32())
|
||||||
if _FoldersSize < 0 {
|
if _FoldersSize < 0 {
|
||||||
return xdr.ElementSizeExceeded("Folders", _FoldersSize, 1000000)
|
return xdr.ElementSizeExceeded("Folders", _FoldersSize, 0)
|
||||||
}
|
|
||||||
if _FoldersSize > 1000000 {
|
|
||||||
return xdr.ElementSizeExceeded("Folders", _FoldersSize, 1000000)
|
|
||||||
}
|
}
|
||||||
o.Folders = make([]Folder, _FoldersSize)
|
o.Folders = make([]Folder, _FoldersSize)
|
||||||
for i := range o.Folders {
|
for i := range o.Folders {
|
||||||
@@ -715,7 +697,7 @@ Folder Structure:
|
|||||||
|
|
||||||
struct Folder {
|
struct Folder {
|
||||||
string ID<64>;
|
string ID<64>;
|
||||||
Device Devices<1000000>;
|
Device Devices<>;
|
||||||
unsigned int Flags;
|
unsigned int Flags;
|
||||||
Option Options<64>;
|
Option Options<64>;
|
||||||
}
|
}
|
||||||
@@ -751,9 +733,6 @@ func (o Folder) EncodeXDRInto(xw *xdr.Writer) (int, error) {
|
|||||||
return xw.Tot(), xdr.ElementSizeExceeded("ID", l, 64)
|
return xw.Tot(), xdr.ElementSizeExceeded("ID", l, 64)
|
||||||
}
|
}
|
||||||
xw.WriteString(o.ID)
|
xw.WriteString(o.ID)
|
||||||
if l := len(o.Devices); l > 1000000 {
|
|
||||||
return xw.Tot(), xdr.ElementSizeExceeded("Devices", l, 1000000)
|
|
||||||
}
|
|
||||||
xw.WriteUint32(uint32(len(o.Devices)))
|
xw.WriteUint32(uint32(len(o.Devices)))
|
||||||
for i := range o.Devices {
|
for i := range o.Devices {
|
||||||
_, err := o.Devices[i].EncodeXDRInto(xw)
|
_, err := o.Devices[i].EncodeXDRInto(xw)
|
||||||
@@ -790,10 +769,7 @@ func (o *Folder) DecodeXDRFrom(xr *xdr.Reader) error {
|
|||||||
o.ID = xr.ReadStringMax(64)
|
o.ID = xr.ReadStringMax(64)
|
||||||
_DevicesSize := int(xr.ReadUint32())
|
_DevicesSize := int(xr.ReadUint32())
|
||||||
if _DevicesSize < 0 {
|
if _DevicesSize < 0 {
|
||||||
return xdr.ElementSizeExceeded("Devices", _DevicesSize, 1000000)
|
return xdr.ElementSizeExceeded("Devices", _DevicesSize, 0)
|
||||||
}
|
|
||||||
if _DevicesSize > 1000000 {
|
|
||||||
return xdr.ElementSizeExceeded("Devices", _DevicesSize, 1000000)
|
|
||||||
}
|
}
|
||||||
o.Devices = make([]Device, _DevicesSize)
|
o.Devices = make([]Device, _DevicesSize)
|
||||||
for i := range o.Devices {
|
for i := range o.Devices {
|
||||||
|
|||||||
+2
-11
@@ -15,11 +15,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Data block size (128 KiB)
|
BlockSize = 128 * 1024
|
||||||
BlockSize = 128 << 10
|
|
||||||
|
|
||||||
// We reject messages larger than this when encountered on the wire. (64 MiB)
|
|
||||||
MaxMessageLen = 64 << 20
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -387,11 +383,6 @@ func (c *rawConnection) readMessage() (hdr header, msg encodable, err error) {
|
|||||||
l.Debugf("read header %v (msglen=%d)", hdr, msglen)
|
l.Debugf("read header %v (msglen=%d)", hdr, msglen)
|
||||||
}
|
}
|
||||||
|
|
||||||
if msglen > MaxMessageLen {
|
|
||||||
err = fmt.Errorf("message length %d exceeds maximum %d", msglen, MaxMessageLen)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if hdr.version != 0 {
|
if hdr.version != 0 {
|
||||||
err = fmt.Errorf("unknown protocol version 0x%x", hdr.version)
|
err = fmt.Errorf("unknown protocol version 0x%x", hdr.version)
|
||||||
return
|
return
|
||||||
@@ -412,7 +403,7 @@ func (c *rawConnection) readMessage() (hdr header, msg encodable, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
msgBuf := c.rdbuf0
|
msgBuf := c.rdbuf0
|
||||||
if hdr.compression && msglen > 0 {
|
if hdr.compression {
|
||||||
c.rdbuf1 = c.rdbuf1[:cap(c.rdbuf1)]
|
c.rdbuf1 = c.rdbuf1[:cap(c.rdbuf1)]
|
||||||
c.rdbuf1, err = lz4.Decode(c.rdbuf1, c.rdbuf0)
|
c.rdbuf1, err = lz4.Decode(c.rdbuf1, c.rdbuf0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
-5
@@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
package protocol
|
package protocol
|
||||||
|
|
||||||
import "github.com/calmh/xdr"
|
|
||||||
|
|
||||||
// This stuff is hacked up manually because genxdr doesn't support 'type
|
// This stuff is hacked up manually because genxdr doesn't support 'type
|
||||||
// Vector []Counter' declarations and it was tricky when I tried to add it...
|
// Vector []Counter' declarations and it was tricky when I tried to add it...
|
||||||
|
|
||||||
@@ -30,9 +28,6 @@ func (v Vector) EncodeXDRInto(w xdrWriter) (int, error) {
|
|||||||
// DecodeXDRFrom decodes the XDR objects from the given reader into itself.
|
// DecodeXDRFrom decodes the XDR objects from the given reader into itself.
|
||||||
func (v *Vector) DecodeXDRFrom(r xdrReader) error {
|
func (v *Vector) DecodeXDRFrom(r xdrReader) error {
|
||||||
l := int(r.ReadUint32())
|
l := int(r.ReadUint32())
|
||||||
if l > 1e6 {
|
|
||||||
return xdr.ElementSizeExceeded("number of counters", l, 1e6)
|
|
||||||
}
|
|
||||||
n := make(Vector, l)
|
n := make(Vector, l)
|
||||||
for i := range n {
|
for i := range n {
|
||||||
n[i].ID = r.ReadUint64()
|
n[i].ID = r.ReadUint64()
|
||||||
|
|||||||
+280
@@ -0,0 +1,280 @@
|
|||||||
|
// Copyright (C) 2015 Audrius Butkevicius and Contributors (see the CONTRIBUTORS file).
|
||||||
|
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
syncthingprotocol "github.com/syncthing/protocol"
|
||||||
|
"github.com/syncthing/relaysrv/protocol"
|
||||||
|
"github.com/syncthing/syncthing/lib/sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProtocolClient struct {
|
||||||
|
URI *url.URL
|
||||||
|
Invitations chan protocol.SessionInvitation
|
||||||
|
|
||||||
|
closeInvitationsOnFinish bool
|
||||||
|
|
||||||
|
config *tls.Config
|
||||||
|
|
||||||
|
timeout time.Duration
|
||||||
|
|
||||||
|
stop chan struct{}
|
||||||
|
stopped chan struct{}
|
||||||
|
|
||||||
|
conn *tls.Conn
|
||||||
|
|
||||||
|
mut sync.RWMutex
|
||||||
|
connected bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewProtocolClient(uri *url.URL, certs []tls.Certificate, invitations chan protocol.SessionInvitation) *ProtocolClient {
|
||||||
|
closeInvitationsOnFinish := false
|
||||||
|
if invitations == nil {
|
||||||
|
closeInvitationsOnFinish = true
|
||||||
|
invitations = make(chan protocol.SessionInvitation)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ProtocolClient{
|
||||||
|
URI: uri,
|
||||||
|
Invitations: invitations,
|
||||||
|
|
||||||
|
closeInvitationsOnFinish: closeInvitationsOnFinish,
|
||||||
|
|
||||||
|
config: configForCerts(certs),
|
||||||
|
|
||||||
|
timeout: time.Minute * 2,
|
||||||
|
|
||||||
|
stop: make(chan struct{}),
|
||||||
|
stopped: make(chan struct{}),
|
||||||
|
|
||||||
|
mut: sync.NewRWMutex(),
|
||||||
|
connected: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ProtocolClient) Serve() {
|
||||||
|
c.stop = make(chan struct{})
|
||||||
|
c.stopped = make(chan struct{})
|
||||||
|
defer close(c.stopped)
|
||||||
|
|
||||||
|
if err := c.connect(); err != nil {
|
||||||
|
if debug {
|
||||||
|
l.Debugln("Relay connect:", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
l.Debugln(c, "connected", c.conn.RemoteAddr())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.join(); err != nil {
|
||||||
|
c.conn.Close()
|
||||||
|
l.Infoln("Relay join:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.conn.SetDeadline(time.Time{}); err != nil {
|
||||||
|
l.Infoln("Relay set deadline:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
l.Debugln(c, "joined", c.conn.RemoteAddr(), "via", c.conn.LocalAddr())
|
||||||
|
}
|
||||||
|
|
||||||
|
defer c.cleanup()
|
||||||
|
c.mut.Lock()
|
||||||
|
c.connected = true
|
||||||
|
c.mut.Unlock()
|
||||||
|
|
||||||
|
messages := make(chan interface{})
|
||||||
|
errors := make(chan error, 1)
|
||||||
|
|
||||||
|
go messageReader(c.conn, messages, errors)
|
||||||
|
|
||||||
|
timeout := time.NewTimer(c.timeout)
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case message := <-messages:
|
||||||
|
timeout.Reset(c.timeout)
|
||||||
|
if debug {
|
||||||
|
log.Printf("%s received message %T", c, message)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch msg := message.(type) {
|
||||||
|
case protocol.Ping:
|
||||||
|
if err := protocol.WriteMessage(c.conn, protocol.Pong{}); err != nil {
|
||||||
|
l.Infoln("Relay write:", err)
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
if debug {
|
||||||
|
l.Debugln(c, "sent pong")
|
||||||
|
}
|
||||||
|
|
||||||
|
case protocol.SessionInvitation:
|
||||||
|
ip := net.IP(msg.Address)
|
||||||
|
if len(ip) == 0 || ip.IsUnspecified() {
|
||||||
|
msg.Address = c.conn.RemoteAddr().(*net.TCPAddr).IP[:]
|
||||||
|
}
|
||||||
|
c.Invitations <- msg
|
||||||
|
|
||||||
|
default:
|
||||||
|
l.Infoln("Relay: protocol error: unexpected message %v", msg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
case <-c.stop:
|
||||||
|
if debug {
|
||||||
|
l.Debugln(c, "stopping")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
case err := <-errors:
|
||||||
|
l.Infoln("Relay received:", err)
|
||||||
|
return
|
||||||
|
|
||||||
|
case <-timeout.C:
|
||||||
|
if debug {
|
||||||
|
l.Debugln(c, "timed out")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ProtocolClient) Stop() {
|
||||||
|
if c.stop == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
close(c.stop)
|
||||||
|
<-c.stopped
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ProtocolClient) StatusOK() bool {
|
||||||
|
c.mut.RLock()
|
||||||
|
con := c.connected
|
||||||
|
c.mut.RUnlock()
|
||||||
|
return con
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ProtocolClient) String() string {
|
||||||
|
return fmt.Sprintf("ProtocolClient@%p", c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ProtocolClient) connect() error {
|
||||||
|
if c.URI.Scheme != "relay" {
|
||||||
|
return fmt.Errorf("Unsupported relay schema:", c.URI.Scheme)
|
||||||
|
}
|
||||||
|
|
||||||
|
conn, err := tls.Dial("tcp", c.URI.Host, c.config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := conn.SetDeadline(time.Now().Add(10 * time.Second)); err != nil {
|
||||||
|
conn.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := performHandshakeAndValidation(conn, c.URI); err != nil {
|
||||||
|
conn.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c.conn = conn
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ProtocolClient) cleanup() {
|
||||||
|
if c.closeInvitationsOnFinish {
|
||||||
|
close(c.Invitations)
|
||||||
|
c.Invitations = make(chan protocol.SessionInvitation)
|
||||||
|
}
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
l.Debugln(c, "cleaning up")
|
||||||
|
}
|
||||||
|
|
||||||
|
c.mut.Lock()
|
||||||
|
c.connected = false
|
||||||
|
c.mut.Unlock()
|
||||||
|
|
||||||
|
c.conn.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ProtocolClient) join() error {
|
||||||
|
if err := protocol.WriteMessage(c.conn, protocol.JoinRelayRequest{}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
message, err := protocol.ReadMessage(c.conn)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch msg := message.(type) {
|
||||||
|
case protocol.Response:
|
||||||
|
if msg.Code != 0 {
|
||||||
|
return fmt.Errorf("Incorrect response code %d: %s", msg.Code, msg.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("protocol error: expecting response got %v", msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func performHandshakeAndValidation(conn *tls.Conn, uri *url.URL) error {
|
||||||
|
if err := conn.Handshake(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cs := conn.ConnectionState()
|
||||||
|
if !cs.NegotiatedProtocolIsMutual || cs.NegotiatedProtocol != protocol.ProtocolName {
|
||||||
|
return fmt.Errorf("protocol negotiation error")
|
||||||
|
}
|
||||||
|
|
||||||
|
q := uri.Query()
|
||||||
|
relayIDs := q.Get("id")
|
||||||
|
if relayIDs != "" {
|
||||||
|
relayID, err := syncthingprotocol.DeviceIDFromString(relayIDs)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("relay address contains invalid verification id: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
certs := cs.PeerCertificates
|
||||||
|
if cl := len(certs); cl != 1 {
|
||||||
|
return fmt.Errorf("unexpected certificate count: %d", cl)
|
||||||
|
}
|
||||||
|
|
||||||
|
remoteID := syncthingprotocol.NewDeviceID(certs[0].Raw)
|
||||||
|
if remoteID != relayID {
|
||||||
|
return fmt.Errorf("relay id does not match. Expected %v got %v", relayID, remoteID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func messageReader(conn net.Conn, messages chan<- interface{}, errors chan<- error) {
|
||||||
|
for {
|
||||||
|
msg, err := protocol.ReadMessage(conn)
|
||||||
|
if err != nil {
|
||||||
|
errors <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
messages <- msg
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright (C) 2015 Audrius Butkevicius and Contributors (see the CONTRIBUTORS file).
|
||||||
|
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/calmh/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
debug = strings.Contains(os.Getenv("STTRACE"), "relay") || os.Getenv("STTRACE") == "all"
|
||||||
|
l = logger.DefaultLogger
|
||||||
|
)
|
||||||
+117
@@ -0,0 +1,117 @@
|
|||||||
|
// Copyright (C) 2015 Audrius Butkevicius and Contributors (see the CONTRIBUTORS file).
|
||||||
|
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
syncthingprotocol "github.com/syncthing/protocol"
|
||||||
|
"github.com/syncthing/relaysrv/protocol"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetInvitationFromRelay(uri *url.URL, id syncthingprotocol.DeviceID, certs []tls.Certificate) (protocol.SessionInvitation, error) {
|
||||||
|
if uri.Scheme != "relay" {
|
||||||
|
return protocol.SessionInvitation{}, fmt.Errorf("Unsupported relay scheme:", uri.Scheme)
|
||||||
|
}
|
||||||
|
|
||||||
|
conn, err := tls.Dial("tcp", uri.Host, configForCerts(certs))
|
||||||
|
conn.SetDeadline(time.Now().Add(10 * time.Second))
|
||||||
|
if err != nil {
|
||||||
|
return protocol.SessionInvitation{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := performHandshakeAndValidation(conn, uri); err != nil {
|
||||||
|
return protocol.SessionInvitation{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
request := protocol.ConnectRequest{
|
||||||
|
ID: id[:],
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := protocol.WriteMessage(conn, request); err != nil {
|
||||||
|
return protocol.SessionInvitation{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
message, err := protocol.ReadMessage(conn)
|
||||||
|
if err != nil {
|
||||||
|
return protocol.SessionInvitation{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch msg := message.(type) {
|
||||||
|
case protocol.Response:
|
||||||
|
return protocol.SessionInvitation{}, fmt.Errorf("Incorrect response code %d: %s", msg.Code, msg.Message)
|
||||||
|
case protocol.SessionInvitation:
|
||||||
|
if debug {
|
||||||
|
l.Debugln("Received invitation", msg, "via", conn.LocalAddr())
|
||||||
|
}
|
||||||
|
ip := net.IP(msg.Address)
|
||||||
|
if len(ip) == 0 || ip.IsUnspecified() {
|
||||||
|
msg.Address = conn.RemoteAddr().(*net.TCPAddr).IP[:]
|
||||||
|
}
|
||||||
|
return msg, nil
|
||||||
|
default:
|
||||||
|
return protocol.SessionInvitation{}, fmt.Errorf("protocol error: unexpected message %v", msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func JoinSession(invitation protocol.SessionInvitation) (net.Conn, error) {
|
||||||
|
addr := net.JoinHostPort(net.IP(invitation.Address).String(), strconv.Itoa(int(invitation.Port)))
|
||||||
|
|
||||||
|
conn, err := net.Dial("tcp", addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
request := protocol.JoinSessionRequest{
|
||||||
|
Key: invitation.Key,
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.SetDeadline(time.Now().Add(10 * time.Second))
|
||||||
|
err = protocol.WriteMessage(conn, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
message, err := protocol.ReadMessage(conn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.SetDeadline(time.Time{})
|
||||||
|
|
||||||
|
switch msg := message.(type) {
|
||||||
|
case protocol.Response:
|
||||||
|
if msg.Code != 0 {
|
||||||
|
return nil, fmt.Errorf("Incorrect response code %d: %s", msg.Code, msg.Message)
|
||||||
|
}
|
||||||
|
return conn, nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("protocol error: expecting response got %v", msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func configForCerts(certs []tls.Certificate) *tls.Config {
|
||||||
|
return &tls.Config{
|
||||||
|
Certificates: certs,
|
||||||
|
NextProtos: []string{protocol.ProtocolName},
|
||||||
|
ClientAuth: tls.RequestClientCert,
|
||||||
|
SessionTicketsDisabled: true,
|
||||||
|
InsecureSkipVerify: true,
|
||||||
|
MinVersion: tls.VersionTLS12,
|
||||||
|
CipherSuites: []uint16{
|
||||||
|
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||||
|
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||||
|
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
|
||||||
|
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
|
||||||
|
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
|
||||||
|
tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
+65
@@ -0,0 +1,65 @@
|
|||||||
|
// Copyright (C) 2015 Audrius Butkevicius and Contributors (see the CONTRIBUTORS file).
|
||||||
|
|
||||||
|
//go:generate -command genxdr go run ../../syncthing/Godeps/_workspace/src/github.com/calmh/xdr/cmd/genxdr/main.go
|
||||||
|
//go:generate genxdr -o packets_xdr.go packets.go
|
||||||
|
|
||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
syncthingprotocol "github.com/syncthing/protocol"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
messageTypePing int32 = iota
|
||||||
|
messageTypePong
|
||||||
|
messageTypeJoinRelayRequest
|
||||||
|
messageTypeJoinSessionRequest
|
||||||
|
messageTypeResponse
|
||||||
|
messageTypeConnectRequest
|
||||||
|
messageTypeSessionInvitation
|
||||||
|
)
|
||||||
|
|
||||||
|
type header struct {
|
||||||
|
magic uint32
|
||||||
|
messageType int32
|
||||||
|
messageLength int32
|
||||||
|
}
|
||||||
|
|
||||||
|
type Ping struct{}
|
||||||
|
type Pong struct{}
|
||||||
|
type JoinRelayRequest struct{}
|
||||||
|
|
||||||
|
type JoinSessionRequest struct {
|
||||||
|
Key []byte // max:32
|
||||||
|
}
|
||||||
|
|
||||||
|
type Response struct {
|
||||||
|
Code int32
|
||||||
|
Message string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConnectRequest struct {
|
||||||
|
ID []byte // max:32
|
||||||
|
}
|
||||||
|
|
||||||
|
type SessionInvitation struct {
|
||||||
|
From []byte // max:32
|
||||||
|
Key []byte // max:32
|
||||||
|
Address []byte // max:32
|
||||||
|
Port uint16
|
||||||
|
ServerSocket bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i SessionInvitation) String() string {
|
||||||
|
return fmt.Sprintf("%s@%s", syncthingprotocol.DeviceIDFromBytes(i.From), i.AddressString())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i SessionInvitation) GoString() string {
|
||||||
|
return i.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i SessionInvitation) AddressString() string {
|
||||||
|
return fmt.Sprintf("%s:%d", net.IP(i.Address), i.Port)
|
||||||
|
}
|
||||||
+567
@@ -0,0 +1,567 @@
|
|||||||
|
// ************************************************************
|
||||||
|
// This file is automatically generated by genxdr. Do not edit.
|
||||||
|
// ************************************************************
|
||||||
|
|
||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/calmh/xdr"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
header Structure:
|
||||||
|
|
||||||
|
0 1 2 3
|
||||||
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| magic |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| message Type |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| message Length |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
|
||||||
|
struct header {
|
||||||
|
unsigned int magic;
|
||||||
|
int messageType;
|
||||||
|
int messageLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
func (o header) EncodeXDR(w io.Writer) (int, error) {
|
||||||
|
var xw = xdr.NewWriter(w)
|
||||||
|
return o.EncodeXDRInto(xw)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o header) MarshalXDR() ([]byte, error) {
|
||||||
|
return o.AppendXDR(make([]byte, 0, 128))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o header) MustMarshalXDR() []byte {
|
||||||
|
bs, err := o.MarshalXDR()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return bs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o header) AppendXDR(bs []byte) ([]byte, error) {
|
||||||
|
var aw = xdr.AppendWriter(bs)
|
||||||
|
var xw = xdr.NewWriter(&aw)
|
||||||
|
_, err := o.EncodeXDRInto(xw)
|
||||||
|
return []byte(aw), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o header) EncodeXDRInto(xw *xdr.Writer) (int, error) {
|
||||||
|
xw.WriteUint32(o.magic)
|
||||||
|
xw.WriteUint32(uint32(o.messageType))
|
||||||
|
xw.WriteUint32(uint32(o.messageLength))
|
||||||
|
return xw.Tot(), xw.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *header) DecodeXDR(r io.Reader) error {
|
||||||
|
xr := xdr.NewReader(r)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *header) UnmarshalXDR(bs []byte) error {
|
||||||
|
var br = bytes.NewReader(bs)
|
||||||
|
var xr = xdr.NewReader(br)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *header) DecodeXDRFrom(xr *xdr.Reader) error {
|
||||||
|
o.magic = xr.ReadUint32()
|
||||||
|
o.messageType = int32(xr.ReadUint32())
|
||||||
|
o.messageLength = int32(xr.ReadUint32())
|
||||||
|
return xr.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Ping Structure:
|
||||||
|
|
||||||
|
0 1 2 3
|
||||||
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
|
||||||
|
struct Ping {
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
func (o Ping) EncodeXDR(w io.Writer) (int, error) {
|
||||||
|
var xw = xdr.NewWriter(w)
|
||||||
|
return o.EncodeXDRInto(xw)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Ping) MarshalXDR() ([]byte, error) {
|
||||||
|
return o.AppendXDR(make([]byte, 0, 128))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Ping) MustMarshalXDR() []byte {
|
||||||
|
bs, err := o.MarshalXDR()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return bs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Ping) AppendXDR(bs []byte) ([]byte, error) {
|
||||||
|
var aw = xdr.AppendWriter(bs)
|
||||||
|
var xw = xdr.NewWriter(&aw)
|
||||||
|
_, err := o.EncodeXDRInto(xw)
|
||||||
|
return []byte(aw), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Ping) EncodeXDRInto(xw *xdr.Writer) (int, error) {
|
||||||
|
return xw.Tot(), xw.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Ping) DecodeXDR(r io.Reader) error {
|
||||||
|
xr := xdr.NewReader(r)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Ping) UnmarshalXDR(bs []byte) error {
|
||||||
|
var br = bytes.NewReader(bs)
|
||||||
|
var xr = xdr.NewReader(br)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Ping) DecodeXDRFrom(xr *xdr.Reader) error {
|
||||||
|
return xr.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Pong Structure:
|
||||||
|
|
||||||
|
0 1 2 3
|
||||||
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
|
||||||
|
struct Pong {
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
func (o Pong) EncodeXDR(w io.Writer) (int, error) {
|
||||||
|
var xw = xdr.NewWriter(w)
|
||||||
|
return o.EncodeXDRInto(xw)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Pong) MarshalXDR() ([]byte, error) {
|
||||||
|
return o.AppendXDR(make([]byte, 0, 128))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Pong) MustMarshalXDR() []byte {
|
||||||
|
bs, err := o.MarshalXDR()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return bs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Pong) AppendXDR(bs []byte) ([]byte, error) {
|
||||||
|
var aw = xdr.AppendWriter(bs)
|
||||||
|
var xw = xdr.NewWriter(&aw)
|
||||||
|
_, err := o.EncodeXDRInto(xw)
|
||||||
|
return []byte(aw), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Pong) EncodeXDRInto(xw *xdr.Writer) (int, error) {
|
||||||
|
return xw.Tot(), xw.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Pong) DecodeXDR(r io.Reader) error {
|
||||||
|
xr := xdr.NewReader(r)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Pong) UnmarshalXDR(bs []byte) error {
|
||||||
|
var br = bytes.NewReader(bs)
|
||||||
|
var xr = xdr.NewReader(br)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Pong) DecodeXDRFrom(xr *xdr.Reader) error {
|
||||||
|
return xr.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
JoinRelayRequest Structure:
|
||||||
|
|
||||||
|
0 1 2 3
|
||||||
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
|
||||||
|
struct JoinRelayRequest {
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
func (o JoinRelayRequest) EncodeXDR(w io.Writer) (int, error) {
|
||||||
|
var xw = xdr.NewWriter(w)
|
||||||
|
return o.EncodeXDRInto(xw)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o JoinRelayRequest) MarshalXDR() ([]byte, error) {
|
||||||
|
return o.AppendXDR(make([]byte, 0, 128))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o JoinRelayRequest) MustMarshalXDR() []byte {
|
||||||
|
bs, err := o.MarshalXDR()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return bs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o JoinRelayRequest) AppendXDR(bs []byte) ([]byte, error) {
|
||||||
|
var aw = xdr.AppendWriter(bs)
|
||||||
|
var xw = xdr.NewWriter(&aw)
|
||||||
|
_, err := o.EncodeXDRInto(xw)
|
||||||
|
return []byte(aw), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o JoinRelayRequest) EncodeXDRInto(xw *xdr.Writer) (int, error) {
|
||||||
|
return xw.Tot(), xw.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *JoinRelayRequest) DecodeXDR(r io.Reader) error {
|
||||||
|
xr := xdr.NewReader(r)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *JoinRelayRequest) UnmarshalXDR(bs []byte) error {
|
||||||
|
var br = bytes.NewReader(bs)
|
||||||
|
var xr = xdr.NewReader(br)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *JoinRelayRequest) DecodeXDRFrom(xr *xdr.Reader) error {
|
||||||
|
return xr.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
JoinSessionRequest Structure:
|
||||||
|
|
||||||
|
0 1 2 3
|
||||||
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| Length of Key |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
/ /
|
||||||
|
\ Key (variable length) \
|
||||||
|
/ /
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
|
||||||
|
struct JoinSessionRequest {
|
||||||
|
opaque Key<32>;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
func (o JoinSessionRequest) EncodeXDR(w io.Writer) (int, error) {
|
||||||
|
var xw = xdr.NewWriter(w)
|
||||||
|
return o.EncodeXDRInto(xw)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o JoinSessionRequest) MarshalXDR() ([]byte, error) {
|
||||||
|
return o.AppendXDR(make([]byte, 0, 128))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o JoinSessionRequest) MustMarshalXDR() []byte {
|
||||||
|
bs, err := o.MarshalXDR()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return bs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o JoinSessionRequest) AppendXDR(bs []byte) ([]byte, error) {
|
||||||
|
var aw = xdr.AppendWriter(bs)
|
||||||
|
var xw = xdr.NewWriter(&aw)
|
||||||
|
_, err := o.EncodeXDRInto(xw)
|
||||||
|
return []byte(aw), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o JoinSessionRequest) EncodeXDRInto(xw *xdr.Writer) (int, error) {
|
||||||
|
if l := len(o.Key); l > 32 {
|
||||||
|
return xw.Tot(), xdr.ElementSizeExceeded("Key", l, 32)
|
||||||
|
}
|
||||||
|
xw.WriteBytes(o.Key)
|
||||||
|
return xw.Tot(), xw.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *JoinSessionRequest) DecodeXDR(r io.Reader) error {
|
||||||
|
xr := xdr.NewReader(r)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *JoinSessionRequest) UnmarshalXDR(bs []byte) error {
|
||||||
|
var br = bytes.NewReader(bs)
|
||||||
|
var xr = xdr.NewReader(br)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *JoinSessionRequest) DecodeXDRFrom(xr *xdr.Reader) error {
|
||||||
|
o.Key = xr.ReadBytesMax(32)
|
||||||
|
return xr.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Response Structure:
|
||||||
|
|
||||||
|
0 1 2 3
|
||||||
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| Code |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| Length of Message |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
/ /
|
||||||
|
\ Message (variable length) \
|
||||||
|
/ /
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
|
||||||
|
struct Response {
|
||||||
|
int Code;
|
||||||
|
string Message<>;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
func (o Response) EncodeXDR(w io.Writer) (int, error) {
|
||||||
|
var xw = xdr.NewWriter(w)
|
||||||
|
return o.EncodeXDRInto(xw)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Response) MarshalXDR() ([]byte, error) {
|
||||||
|
return o.AppendXDR(make([]byte, 0, 128))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Response) MustMarshalXDR() []byte {
|
||||||
|
bs, err := o.MarshalXDR()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return bs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Response) AppendXDR(bs []byte) ([]byte, error) {
|
||||||
|
var aw = xdr.AppendWriter(bs)
|
||||||
|
var xw = xdr.NewWriter(&aw)
|
||||||
|
_, err := o.EncodeXDRInto(xw)
|
||||||
|
return []byte(aw), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Response) EncodeXDRInto(xw *xdr.Writer) (int, error) {
|
||||||
|
xw.WriteUint32(uint32(o.Code))
|
||||||
|
xw.WriteString(o.Message)
|
||||||
|
return xw.Tot(), xw.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Response) DecodeXDR(r io.Reader) error {
|
||||||
|
xr := xdr.NewReader(r)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Response) UnmarshalXDR(bs []byte) error {
|
||||||
|
var br = bytes.NewReader(bs)
|
||||||
|
var xr = xdr.NewReader(br)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Response) DecodeXDRFrom(xr *xdr.Reader) error {
|
||||||
|
o.Code = int32(xr.ReadUint32())
|
||||||
|
o.Message = xr.ReadString()
|
||||||
|
return xr.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
ConnectRequest Structure:
|
||||||
|
|
||||||
|
0 1 2 3
|
||||||
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| Length of ID |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
/ /
|
||||||
|
\ ID (variable length) \
|
||||||
|
/ /
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
|
||||||
|
struct ConnectRequest {
|
||||||
|
opaque ID<32>;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
func (o ConnectRequest) EncodeXDR(w io.Writer) (int, error) {
|
||||||
|
var xw = xdr.NewWriter(w)
|
||||||
|
return o.EncodeXDRInto(xw)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o ConnectRequest) MarshalXDR() ([]byte, error) {
|
||||||
|
return o.AppendXDR(make([]byte, 0, 128))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o ConnectRequest) MustMarshalXDR() []byte {
|
||||||
|
bs, err := o.MarshalXDR()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return bs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o ConnectRequest) AppendXDR(bs []byte) ([]byte, error) {
|
||||||
|
var aw = xdr.AppendWriter(bs)
|
||||||
|
var xw = xdr.NewWriter(&aw)
|
||||||
|
_, err := o.EncodeXDRInto(xw)
|
||||||
|
return []byte(aw), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o ConnectRequest) EncodeXDRInto(xw *xdr.Writer) (int, error) {
|
||||||
|
if l := len(o.ID); l > 32 {
|
||||||
|
return xw.Tot(), xdr.ElementSizeExceeded("ID", l, 32)
|
||||||
|
}
|
||||||
|
xw.WriteBytes(o.ID)
|
||||||
|
return xw.Tot(), xw.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *ConnectRequest) DecodeXDR(r io.Reader) error {
|
||||||
|
xr := xdr.NewReader(r)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *ConnectRequest) UnmarshalXDR(bs []byte) error {
|
||||||
|
var br = bytes.NewReader(bs)
|
||||||
|
var xr = xdr.NewReader(br)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *ConnectRequest) DecodeXDRFrom(xr *xdr.Reader) error {
|
||||||
|
o.ID = xr.ReadBytesMax(32)
|
||||||
|
return xr.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
SessionInvitation Structure:
|
||||||
|
|
||||||
|
0 1 2 3
|
||||||
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| Length of From |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
/ /
|
||||||
|
\ From (variable length) \
|
||||||
|
/ /
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| Length of Key |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
/ /
|
||||||
|
\ Key (variable length) \
|
||||||
|
/ /
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| Length of Address |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
/ /
|
||||||
|
\ Address (variable length) \
|
||||||
|
/ /
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| 0x0000 | Port |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| Server Socket (V=0 or 1) |V|
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
|
||||||
|
struct SessionInvitation {
|
||||||
|
opaque From<32>;
|
||||||
|
opaque Key<32>;
|
||||||
|
opaque Address<32>;
|
||||||
|
unsigned int Port;
|
||||||
|
bool ServerSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
func (o SessionInvitation) EncodeXDR(w io.Writer) (int, error) {
|
||||||
|
var xw = xdr.NewWriter(w)
|
||||||
|
return o.EncodeXDRInto(xw)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o SessionInvitation) MarshalXDR() ([]byte, error) {
|
||||||
|
return o.AppendXDR(make([]byte, 0, 128))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o SessionInvitation) MustMarshalXDR() []byte {
|
||||||
|
bs, err := o.MarshalXDR()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return bs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o SessionInvitation) AppendXDR(bs []byte) ([]byte, error) {
|
||||||
|
var aw = xdr.AppendWriter(bs)
|
||||||
|
var xw = xdr.NewWriter(&aw)
|
||||||
|
_, err := o.EncodeXDRInto(xw)
|
||||||
|
return []byte(aw), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o SessionInvitation) EncodeXDRInto(xw *xdr.Writer) (int, error) {
|
||||||
|
if l := len(o.From); l > 32 {
|
||||||
|
return xw.Tot(), xdr.ElementSizeExceeded("From", l, 32)
|
||||||
|
}
|
||||||
|
xw.WriteBytes(o.From)
|
||||||
|
if l := len(o.Key); l > 32 {
|
||||||
|
return xw.Tot(), xdr.ElementSizeExceeded("Key", l, 32)
|
||||||
|
}
|
||||||
|
xw.WriteBytes(o.Key)
|
||||||
|
if l := len(o.Address); l > 32 {
|
||||||
|
return xw.Tot(), xdr.ElementSizeExceeded("Address", l, 32)
|
||||||
|
}
|
||||||
|
xw.WriteBytes(o.Address)
|
||||||
|
xw.WriteUint16(o.Port)
|
||||||
|
xw.WriteBool(o.ServerSocket)
|
||||||
|
return xw.Tot(), xw.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *SessionInvitation) DecodeXDR(r io.Reader) error {
|
||||||
|
xr := xdr.NewReader(r)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *SessionInvitation) UnmarshalXDR(bs []byte) error {
|
||||||
|
var br = bytes.NewReader(bs)
|
||||||
|
var xr = xdr.NewReader(br)
|
||||||
|
return o.DecodeXDRFrom(xr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *SessionInvitation) DecodeXDRFrom(xr *xdr.Reader) error {
|
||||||
|
o.From = xr.ReadBytesMax(32)
|
||||||
|
o.Key = xr.ReadBytesMax(32)
|
||||||
|
o.Address = xr.ReadBytesMax(32)
|
||||||
|
o.Port = xr.ReadUint16()
|
||||||
|
o.ServerSocket = xr.ReadBool()
|
||||||
|
return xr.Error()
|
||||||
|
}
|
||||||
+114
@@ -0,0 +1,114 @@
|
|||||||
|
// Copyright (C) 2015 Audrius Butkevicius and Contributors (see the CONTRIBUTORS file).
|
||||||
|
|
||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
magic = 0x9E79BC40
|
||||||
|
ProtocolName = "bep-relay"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ResponseSuccess = Response{0, "success"}
|
||||||
|
ResponseNotFound = Response{1, "not found"}
|
||||||
|
ResponseAlreadyConnected = Response{2, "already connected"}
|
||||||
|
ResponseInternalError = Response{99, "internal error"}
|
||||||
|
ResponseUnexpectedMessage = Response{100, "unexpected message"}
|
||||||
|
)
|
||||||
|
|
||||||
|
func WriteMessage(w io.Writer, message interface{}) error {
|
||||||
|
header := header{
|
||||||
|
magic: magic,
|
||||||
|
}
|
||||||
|
|
||||||
|
var payload []byte
|
||||||
|
var err error
|
||||||
|
|
||||||
|
switch msg := message.(type) {
|
||||||
|
case Ping:
|
||||||
|
payload, err = msg.MarshalXDR()
|
||||||
|
header.messageType = messageTypePing
|
||||||
|
case Pong:
|
||||||
|
payload, err = msg.MarshalXDR()
|
||||||
|
header.messageType = messageTypePong
|
||||||
|
case JoinRelayRequest:
|
||||||
|
payload, err = msg.MarshalXDR()
|
||||||
|
header.messageType = messageTypeJoinRelayRequest
|
||||||
|
case JoinSessionRequest:
|
||||||
|
payload, err = msg.MarshalXDR()
|
||||||
|
header.messageType = messageTypeJoinSessionRequest
|
||||||
|
case Response:
|
||||||
|
payload, err = msg.MarshalXDR()
|
||||||
|
header.messageType = messageTypeResponse
|
||||||
|
case ConnectRequest:
|
||||||
|
payload, err = msg.MarshalXDR()
|
||||||
|
header.messageType = messageTypeConnectRequest
|
||||||
|
case SessionInvitation:
|
||||||
|
payload, err = msg.MarshalXDR()
|
||||||
|
header.messageType = messageTypeSessionInvitation
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("Unknown message type")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
header.messageLength = int32(len(payload))
|
||||||
|
|
||||||
|
headerpayload, err := header.MarshalXDR()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = w.Write(append(headerpayload, payload...))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadMessage(r io.Reader) (interface{}, error) {
|
||||||
|
var header header
|
||||||
|
if err := header.DecodeXDR(r); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if header.magic != magic {
|
||||||
|
return nil, fmt.Errorf("magic mismatch")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch header.messageType {
|
||||||
|
case messageTypePing:
|
||||||
|
var msg Ping
|
||||||
|
err := msg.DecodeXDR(r)
|
||||||
|
return msg, err
|
||||||
|
case messageTypePong:
|
||||||
|
var msg Pong
|
||||||
|
err := msg.DecodeXDR(r)
|
||||||
|
return msg, err
|
||||||
|
case messageTypeJoinRelayRequest:
|
||||||
|
var msg JoinRelayRequest
|
||||||
|
err := msg.DecodeXDR(r)
|
||||||
|
return msg, err
|
||||||
|
case messageTypeJoinSessionRequest:
|
||||||
|
var msg JoinSessionRequest
|
||||||
|
err := msg.DecodeXDR(r)
|
||||||
|
return msg, err
|
||||||
|
case messageTypeResponse:
|
||||||
|
var msg Response
|
||||||
|
err := msg.DecodeXDR(r)
|
||||||
|
return msg, err
|
||||||
|
case messageTypeConnectRequest:
|
||||||
|
var msg ConnectRequest
|
||||||
|
err := msg.DecodeXDR(r)
|
||||||
|
return msg, err
|
||||||
|
case messageTypeSessionInvitation:
|
||||||
|
var msg SessionInvitation
|
||||||
|
err := msg.DecodeXDR(r)
|
||||||
|
return msg, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("Unknown message type")
|
||||||
|
}
|
||||||
-11
@@ -43,14 +43,3 @@ easily fit into the OTP paradigm. It ought to someday be considered a good
|
|||||||
idea to distribute libraries that provide some sort of supervisor tree
|
idea to distribute libraries that provide some sort of supervisor tree
|
||||||
functionality out of the box. It is possible to provide this functionality
|
functionality out of the box. It is possible to provide this functionality
|
||||||
without explicitly depending on the Suture library.
|
without explicitly depending on the Suture library.
|
||||||
|
|
||||||
Changelog
|
|
||||||
---------
|
|
||||||
|
|
||||||
suture uses semantic versioning.
|
|
||||||
|
|
||||||
1. 1.0.0
|
|
||||||
* Initial release.
|
|
||||||
2. 1.0.1
|
|
||||||
* Fixed data race on the .state variable.
|
|
||||||
|
|
||||||
|
|||||||
+4
-23
@@ -59,7 +59,6 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -124,6 +123,7 @@ type Supervisor struct {
|
|||||||
lastFail time.Time
|
lastFail time.Time
|
||||||
failures float64
|
failures float64
|
||||||
restartQueue []serviceID
|
restartQueue []serviceID
|
||||||
|
state uint8
|
||||||
serviceCounter serviceID
|
serviceCounter serviceID
|
||||||
control chan supervisorMessage
|
control chan supervisorMessage
|
||||||
resumeTimer <-chan time.Time
|
resumeTimer <-chan time.Time
|
||||||
@@ -143,9 +143,6 @@ type Supervisor struct {
|
|||||||
// a minimal chunk.
|
// a minimal chunk.
|
||||||
getNow func() time.Time
|
getNow func() time.Time
|
||||||
getResume func(time.Duration) <-chan time.Time
|
getResume func(time.Duration) <-chan time.Time
|
||||||
|
|
||||||
sync.Mutex
|
|
||||||
state uint8
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spec is used to pass arguments to the New function to create a
|
// Spec is used to pass arguments to the New function to create a
|
||||||
@@ -376,7 +373,6 @@ func (s *Supervisor) Add(service Service) ServiceToken {
|
|||||||
supervisor.logBackoff = s.logBackoff
|
supervisor.logBackoff = s.logBackoff
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Lock()
|
|
||||||
if s.state == notRunning {
|
if s.state == notRunning {
|
||||||
id := s.serviceCounter
|
id := s.serviceCounter
|
||||||
s.serviceCounter++
|
s.serviceCounter++
|
||||||
@@ -384,10 +380,8 @@ func (s *Supervisor) Add(service Service) ServiceToken {
|
|||||||
s.services[id] = service
|
s.services[id] = service
|
||||||
s.restartQueue = append(s.restartQueue, id)
|
s.restartQueue = append(s.restartQueue, id)
|
||||||
|
|
||||||
s.Unlock()
|
|
||||||
return ServiceToken{uint64(s.id)<<32 | uint64(id)}
|
return ServiceToken{uint64(s.id)<<32 | uint64(id)}
|
||||||
}
|
}
|
||||||
s.Unlock()
|
|
||||||
|
|
||||||
response := make(chan serviceID)
|
response := make(chan serviceID)
|
||||||
s.control <- addService{service, response}
|
s.control <- addService{service, response}
|
||||||
@@ -414,19 +408,16 @@ func (s *Supervisor) Serve() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
s.Lock()
|
|
||||||
s.state = notRunning
|
s.state = notRunning
|
||||||
s.Unlock()
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
s.Lock()
|
|
||||||
if s.state != notRunning {
|
if s.state != notRunning {
|
||||||
s.Unlock()
|
// FIXME: Don't explain why I don't need a semaphore, just use one
|
||||||
|
// This doesn't use a semaphore because it's just a sanity check.
|
||||||
panic("Running a supervisor while it is already running?")
|
panic("Running a supervisor while it is already running?")
|
||||||
}
|
}
|
||||||
|
|
||||||
s.state = normal
|
s.state = normal
|
||||||
s.Unlock()
|
|
||||||
|
|
||||||
// for all the services I currently know about, start them
|
// for all the services I currently know about, start them
|
||||||
for _, id := range s.restartQueue {
|
for _, id := range s.restartQueue {
|
||||||
@@ -481,9 +472,7 @@ func (s *Supervisor) Serve() {
|
|||||||
// excessive thrashing
|
// excessive thrashing
|
||||||
// FIXME: Ought to permit some spacing of these functions, rather
|
// FIXME: Ought to permit some spacing of these functions, rather
|
||||||
// than simply hammering through them
|
// than simply hammering through them
|
||||||
s.Lock()
|
|
||||||
s.state = normal
|
s.state = normal
|
||||||
s.Unlock()
|
|
||||||
s.failures = 0
|
s.failures = 0
|
||||||
s.logBackoff(s, false)
|
s.logBackoff(s, false)
|
||||||
for _, id := range s.restartQueue {
|
for _, id := range s.restartQueue {
|
||||||
@@ -510,9 +499,7 @@ func (s *Supervisor) handleFailedService(id serviceID, err interface{}, stacktra
|
|||||||
}
|
}
|
||||||
|
|
||||||
if s.failures > s.failureThreshold {
|
if s.failures > s.failureThreshold {
|
||||||
s.Lock()
|
|
||||||
s.state = paused
|
s.state = paused
|
||||||
s.Unlock()
|
|
||||||
s.logBackoff(s, true)
|
s.logBackoff(s, true)
|
||||||
s.resumeTimer = s.getResume(s.failureBackoff)
|
s.resumeTimer = s.getResume(s.failureBackoff)
|
||||||
}
|
}
|
||||||
@@ -524,13 +511,7 @@ func (s *Supervisor) handleFailedService(id serviceID, err interface{}, stacktra
|
|||||||
// It is possible for a service to be no longer monitored
|
// It is possible for a service to be no longer monitored
|
||||||
// by the time we get here. In that case, just ignore it.
|
// by the time we get here. In that case, just ignore it.
|
||||||
if monitored {
|
if monitored {
|
||||||
// this may look dangerous because the state could change, but this
|
if s.state == normal {
|
||||||
// code is only ever run in the one goroutine that is permitted to
|
|
||||||
// change the state, so nothing else will.
|
|
||||||
s.Lock()
|
|
||||||
curState := s.state
|
|
||||||
s.Unlock()
|
|
||||||
if curState == normal {
|
|
||||||
s.runService(failedService, id)
|
s.runService(failedService, id)
|
||||||
s.logFailure(s, failedService, s.failures, s.failureThreshold, true, err, stacktrace)
|
s.logFailure(s, failedService, s.failures, s.failureThreshold, true, err, stacktrace)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@ func (i *Incrementor) Serve() {
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case i.next <- i.current:
|
case i.next <- i.current:
|
||||||
i.current++
|
i.current += 1
|
||||||
case <-i.stop:
|
case <-i.stop:
|
||||||
// We sync here just to guarantee the output of "Stopping the service",
|
// We sync here just to guarantee the output of "Stopping the service",
|
||||||
// so this passes the test reliably.
|
// so this passes the test reliably.
|
||||||
|
|||||||
+4
-20
@@ -478,22 +478,6 @@ func TestNilSupervisorAdd(t *testing.T) {
|
|||||||
s.Add(s)
|
s.Add(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/thejerf/suture/issues/11
|
|
||||||
//
|
|
||||||
// The purpose of this test is to verify that it does not cause data races,
|
|
||||||
// so there are no obvious assertions.
|
|
||||||
func TestIssue11(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
s := NewSimple("main")
|
|
||||||
s.ServeBackground()
|
|
||||||
|
|
||||||
subsuper := NewSimple("sub")
|
|
||||||
s.Add(subsuper)
|
|
||||||
|
|
||||||
subsuper.Add(NewService("may cause data race"))
|
|
||||||
}
|
|
||||||
|
|
||||||
// http://golangtutorials.blogspot.com/2011/10/gotest-unit-testing-and-benchmarking-go.html
|
// http://golangtutorials.blogspot.com/2011/10/gotest-unit-testing-and-benchmarking-go.html
|
||||||
// claims test function are run in the same order as the source file...
|
// claims test function are run in the same order as the source file...
|
||||||
// I'm not sure if this is part of the contract, though. Especially in the
|
// I'm not sure if this is part of the contract, though. Especially in the
|
||||||
@@ -525,7 +509,7 @@ func (s *FailableService) Serve() {
|
|||||||
everMultistarted = true
|
everMultistarted = true
|
||||||
panic("Multi-started the same service! " + s.name)
|
panic("Multi-started the same service! " + s.name)
|
||||||
}
|
}
|
||||||
s.existing++
|
s.existing += 1
|
||||||
|
|
||||||
s.started <- true
|
s.started <- true
|
||||||
|
|
||||||
@@ -538,13 +522,13 @@ func (s *FailableService) Serve() {
|
|||||||
case Happy:
|
case Happy:
|
||||||
// Do nothing on purpose. Life is good!
|
// Do nothing on purpose. Life is good!
|
||||||
case Fail:
|
case Fail:
|
||||||
s.existing--
|
s.existing -= 1
|
||||||
if useStopChan {
|
if useStopChan {
|
||||||
s.stop <- true
|
s.stop <- true
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
case Panic:
|
case Panic:
|
||||||
s.existing--
|
s.existing -= 1
|
||||||
panic("Panic!")
|
panic("Panic!")
|
||||||
case Hang:
|
case Hang:
|
||||||
// or more specifically, "hang until I release you"
|
// or more specifically, "hang until I release you"
|
||||||
@@ -553,7 +537,7 @@ func (s *FailableService) Serve() {
|
|||||||
useStopChan = true
|
useStopChan = true
|
||||||
}
|
}
|
||||||
case <-s.shutdown:
|
case <-s.shutdown:
|
||||||
s.existing--
|
s.existing -= 1
|
||||||
if useStopChan {
|
if useStopChan {
|
||||||
s.stop <- true
|
s.stop <- true
|
||||||
}
|
}
|
||||||
|
|||||||
-181
@@ -1,181 +0,0 @@
|
|||||||
// go generate gen.go
|
|
||||||
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
|
||||||
|
|
||||||
// Package iana provides protocol number resources managed by the Internet Assigned Numbers Authority (IANA).
|
|
||||||
package iana
|
|
||||||
|
|
||||||
// Differentiated Services Field Codepoints (DSCP), Updated: 2013-06-25
|
|
||||||
const (
|
|
||||||
DiffServCS0 = 0x0 // CS0
|
|
||||||
DiffServCS1 = 0x20 // CS1
|
|
||||||
DiffServCS2 = 0x40 // CS2
|
|
||||||
DiffServCS3 = 0x60 // CS3
|
|
||||||
DiffServCS4 = 0x80 // CS4
|
|
||||||
DiffServCS5 = 0xa0 // CS5
|
|
||||||
DiffServCS6 = 0xc0 // CS6
|
|
||||||
DiffServCS7 = 0xe0 // CS7
|
|
||||||
DiffServAF11 = 0x28 // AF11
|
|
||||||
DiffServAF12 = 0x30 // AF12
|
|
||||||
DiffServAF13 = 0x38 // AF13
|
|
||||||
DiffServAF21 = 0x48 // AF21
|
|
||||||
DiffServAF22 = 0x50 // AF22
|
|
||||||
DiffServAF23 = 0x58 // AF23
|
|
||||||
DiffServAF31 = 0x68 // AF31
|
|
||||||
DiffServAF32 = 0x70 // AF32
|
|
||||||
DiffServAF33 = 0x78 // AF33
|
|
||||||
DiffServAF41 = 0x88 // AF41
|
|
||||||
DiffServAF42 = 0x90 // AF42
|
|
||||||
DiffServAF43 = 0x98 // AF43
|
|
||||||
DiffServEFPHB = 0xb8 // EF PHB
|
|
||||||
DiffServVOICEADMIT = 0xb0 // VOICE-ADMIT
|
|
||||||
)
|
|
||||||
|
|
||||||
// IPv4 TOS Byte and IPv6 Traffic Class Octet, Updated: 2001-09-06
|
|
||||||
const (
|
|
||||||
NotECNTransport = 0x0 // Not-ECT (Not ECN-Capable Transport)
|
|
||||||
ECNTransport1 = 0x1 // ECT(1) (ECN-Capable Transport(1))
|
|
||||||
ECNTransport0 = 0x2 // ECT(0) (ECN-Capable Transport(0))
|
|
||||||
CongestionExperienced = 0x3 // CE (Congestion Experienced)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Protocol Numbers, Updated: 2015-06-23
|
|
||||||
const (
|
|
||||||
ProtocolIP = 0 // IPv4 encapsulation, pseudo protocol number
|
|
||||||
ProtocolHOPOPT = 0 // IPv6 Hop-by-Hop Option
|
|
||||||
ProtocolICMP = 1 // Internet Control Message
|
|
||||||
ProtocolIGMP = 2 // Internet Group Management
|
|
||||||
ProtocolGGP = 3 // Gateway-to-Gateway
|
|
||||||
ProtocolIPv4 = 4 // IPv4 encapsulation
|
|
||||||
ProtocolST = 5 // Stream
|
|
||||||
ProtocolTCP = 6 // Transmission Control
|
|
||||||
ProtocolCBT = 7 // CBT
|
|
||||||
ProtocolEGP = 8 // Exterior Gateway Protocol
|
|
||||||
ProtocolIGP = 9 // any private interior gateway (used by Cisco for their IGRP)
|
|
||||||
ProtocolBBNRCCMON = 10 // BBN RCC Monitoring
|
|
||||||
ProtocolNVPII = 11 // Network Voice Protocol
|
|
||||||
ProtocolPUP = 12 // PUP
|
|
||||||
ProtocolARGUS = 13 // ARGUS
|
|
||||||
ProtocolEMCON = 14 // EMCON
|
|
||||||
ProtocolXNET = 15 // Cross Net Debugger
|
|
||||||
ProtocolCHAOS = 16 // Chaos
|
|
||||||
ProtocolUDP = 17 // User Datagram
|
|
||||||
ProtocolMUX = 18 // Multiplexing
|
|
||||||
ProtocolDCNMEAS = 19 // DCN Measurement Subsystems
|
|
||||||
ProtocolHMP = 20 // Host Monitoring
|
|
||||||
ProtocolPRM = 21 // Packet Radio Measurement
|
|
||||||
ProtocolXNSIDP = 22 // XEROX NS IDP
|
|
||||||
ProtocolTRUNK1 = 23 // Trunk-1
|
|
||||||
ProtocolTRUNK2 = 24 // Trunk-2
|
|
||||||
ProtocolLEAF1 = 25 // Leaf-1
|
|
||||||
ProtocolLEAF2 = 26 // Leaf-2
|
|
||||||
ProtocolRDP = 27 // Reliable Data Protocol
|
|
||||||
ProtocolIRTP = 28 // Internet Reliable Transaction
|
|
||||||
ProtocolISOTP4 = 29 // ISO Transport Protocol Class 4
|
|
||||||
ProtocolNETBLT = 30 // Bulk Data Transfer Protocol
|
|
||||||
ProtocolMFENSP = 31 // MFE Network Services Protocol
|
|
||||||
ProtocolMERITINP = 32 // MERIT Internodal Protocol
|
|
||||||
ProtocolDCCP = 33 // Datagram Congestion Control Protocol
|
|
||||||
Protocol3PC = 34 // Third Party Connect Protocol
|
|
||||||
ProtocolIDPR = 35 // Inter-Domain Policy Routing Protocol
|
|
||||||
ProtocolXTP = 36 // XTP
|
|
||||||
ProtocolDDP = 37 // Datagram Delivery Protocol
|
|
||||||
ProtocolIDPRCMTP = 38 // IDPR Control Message Transport Proto
|
|
||||||
ProtocolTPPP = 39 // TP++ Transport Protocol
|
|
||||||
ProtocolIL = 40 // IL Transport Protocol
|
|
||||||
ProtocolIPv6 = 41 // IPv6 encapsulation
|
|
||||||
ProtocolSDRP = 42 // Source Demand Routing Protocol
|
|
||||||
ProtocolIPv6Route = 43 // Routing Header for IPv6
|
|
||||||
ProtocolIPv6Frag = 44 // Fragment Header for IPv6
|
|
||||||
ProtocolIDRP = 45 // Inter-Domain Routing Protocol
|
|
||||||
ProtocolRSVP = 46 // Reservation Protocol
|
|
||||||
ProtocolGRE = 47 // Generic Routing Encapsulation
|
|
||||||
ProtocolDSR = 48 // Dynamic Source Routing Protocol
|
|
||||||
ProtocolBNA = 49 // BNA
|
|
||||||
ProtocolESP = 50 // Encap Security Payload
|
|
||||||
ProtocolAH = 51 // Authentication Header
|
|
||||||
ProtocolINLSP = 52 // Integrated Net Layer Security TUBA
|
|
||||||
ProtocolNARP = 54 // NBMA Address Resolution Protocol
|
|
||||||
ProtocolMOBILE = 55 // IP Mobility
|
|
||||||
ProtocolTLSP = 56 // Transport Layer Security Protocol using Kryptonet key management
|
|
||||||
ProtocolSKIP = 57 // SKIP
|
|
||||||
ProtocolIPv6ICMP = 58 // ICMP for IPv6
|
|
||||||
ProtocolIPv6NoNxt = 59 // No Next Header for IPv6
|
|
||||||
ProtocolIPv6Opts = 60 // Destination Options for IPv6
|
|
||||||
ProtocolCFTP = 62 // CFTP
|
|
||||||
ProtocolSATEXPAK = 64 // SATNET and Backroom EXPAK
|
|
||||||
ProtocolKRYPTOLAN = 65 // Kryptolan
|
|
||||||
ProtocolRVD = 66 // MIT Remote Virtual Disk Protocol
|
|
||||||
ProtocolIPPC = 67 // Internet Pluribus Packet Core
|
|
||||||
ProtocolSATMON = 69 // SATNET Monitoring
|
|
||||||
ProtocolVISA = 70 // VISA Protocol
|
|
||||||
ProtocolIPCV = 71 // Internet Packet Core Utility
|
|
||||||
ProtocolCPNX = 72 // Computer Protocol Network Executive
|
|
||||||
ProtocolCPHB = 73 // Computer Protocol Heart Beat
|
|
||||||
ProtocolWSN = 74 // Wang Span Network
|
|
||||||
ProtocolPVP = 75 // Packet Video Protocol
|
|
||||||
ProtocolBRSATMON = 76 // Backroom SATNET Monitoring
|
|
||||||
ProtocolSUNND = 77 // SUN ND PROTOCOL-Temporary
|
|
||||||
ProtocolWBMON = 78 // WIDEBAND Monitoring
|
|
||||||
ProtocolWBEXPAK = 79 // WIDEBAND EXPAK
|
|
||||||
ProtocolISOIP = 80 // ISO Internet Protocol
|
|
||||||
ProtocolVMTP = 81 // VMTP
|
|
||||||
ProtocolSECUREVMTP = 82 // SECURE-VMTP
|
|
||||||
ProtocolVINES = 83 // VINES
|
|
||||||
ProtocolTTP = 84 // Transaction Transport Protocol
|
|
||||||
ProtocolIPTM = 84 // Internet Protocol Traffic Manager
|
|
||||||
ProtocolNSFNETIGP = 85 // NSFNET-IGP
|
|
||||||
ProtocolDGP = 86 // Dissimilar Gateway Protocol
|
|
||||||
ProtocolTCF = 87 // TCF
|
|
||||||
ProtocolEIGRP = 88 // EIGRP
|
|
||||||
ProtocolOSPFIGP = 89 // OSPFIGP
|
|
||||||
ProtocolSpriteRPC = 90 // Sprite RPC Protocol
|
|
||||||
ProtocolLARP = 91 // Locus Address Resolution Protocol
|
|
||||||
ProtocolMTP = 92 // Multicast Transport Protocol
|
|
||||||
ProtocolAX25 = 93 // AX.25 Frames
|
|
||||||
ProtocolIPIP = 94 // IP-within-IP Encapsulation Protocol
|
|
||||||
ProtocolSCCSP = 96 // Semaphore Communications Sec. Pro.
|
|
||||||
ProtocolETHERIP = 97 // Ethernet-within-IP Encapsulation
|
|
||||||
ProtocolENCAP = 98 // Encapsulation Header
|
|
||||||
ProtocolGMTP = 100 // GMTP
|
|
||||||
ProtocolIFMP = 101 // Ipsilon Flow Management Protocol
|
|
||||||
ProtocolPNNI = 102 // PNNI over IP
|
|
||||||
ProtocolPIM = 103 // Protocol Independent Multicast
|
|
||||||
ProtocolARIS = 104 // ARIS
|
|
||||||
ProtocolSCPS = 105 // SCPS
|
|
||||||
ProtocolQNX = 106 // QNX
|
|
||||||
ProtocolAN = 107 // Active Networks
|
|
||||||
ProtocolIPComp = 108 // IP Payload Compression Protocol
|
|
||||||
ProtocolSNP = 109 // Sitara Networks Protocol
|
|
||||||
ProtocolCompaqPeer = 110 // Compaq Peer Protocol
|
|
||||||
ProtocolIPXinIP = 111 // IPX in IP
|
|
||||||
ProtocolVRRP = 112 // Virtual Router Redundancy Protocol
|
|
||||||
ProtocolPGM = 113 // PGM Reliable Transport Protocol
|
|
||||||
ProtocolL2TP = 115 // Layer Two Tunneling Protocol
|
|
||||||
ProtocolDDX = 116 // D-II Data Exchange (DDX)
|
|
||||||
ProtocolIATP = 117 // Interactive Agent Transfer Protocol
|
|
||||||
ProtocolSTP = 118 // Schedule Transfer Protocol
|
|
||||||
ProtocolSRP = 119 // SpectraLink Radio Protocol
|
|
||||||
ProtocolUTI = 120 // UTI
|
|
||||||
ProtocolSMP = 121 // Simple Message Protocol
|
|
||||||
ProtocolPTP = 123 // Performance Transparency Protocol
|
|
||||||
ProtocolISIS = 124 // ISIS over IPv4
|
|
||||||
ProtocolFIRE = 125 // FIRE
|
|
||||||
ProtocolCRTP = 126 // Combat Radio Transport Protocol
|
|
||||||
ProtocolCRUDP = 127 // Combat Radio User Datagram
|
|
||||||
ProtocolSSCOPMCE = 128 // SSCOPMCE
|
|
||||||
ProtocolIPLT = 129 // IPLT
|
|
||||||
ProtocolSPS = 130 // Secure Packet Shield
|
|
||||||
ProtocolPIPE = 131 // Private IP Encapsulation within IP
|
|
||||||
ProtocolSCTP = 132 // Stream Control Transmission Protocol
|
|
||||||
ProtocolFC = 133 // Fibre Channel
|
|
||||||
ProtocolRSVPE2EIGNORE = 134 // RSVP-E2E-IGNORE
|
|
||||||
ProtocolMobilityHeader = 135 // Mobility Header
|
|
||||||
ProtocolUDPLite = 136 // UDPLite
|
|
||||||
ProtocolMPLSinIP = 137 // MPLS-in-IP
|
|
||||||
ProtocolMANET = 138 // MANET Protocols
|
|
||||||
ProtocolHIP = 139 // Host Identity Protocol
|
|
||||||
ProtocolShim6 = 140 // Shim6 Protocol
|
|
||||||
ProtocolWESP = 141 // Wrapped Encapsulating Security Payload
|
|
||||||
ProtocolROHC = 142 // Robust Header Compression
|
|
||||||
ProtocolReserved = 255 // Reserved
|
|
||||||
)
|
|
||||||
-293
@@ -1,293 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
//go:generate go run gen.go
|
|
||||||
|
|
||||||
// This program generates internet protocol constants and tables by
|
|
||||||
// reading IANA protocol registries.
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/xml"
|
|
||||||
"fmt"
|
|
||||||
"go/format"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var registries = []struct {
|
|
||||||
url string
|
|
||||||
parse func(io.Writer, io.Reader) error
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
"http://www.iana.org/assignments/dscp-registry/dscp-registry.xml",
|
|
||||||
parseDSCPRegistry,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"http://www.iana.org/assignments/ipv4-tos-byte/ipv4-tos-byte.xml",
|
|
||||||
parseTOSTCByte,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml",
|
|
||||||
parseProtocolNumbers,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
var bb bytes.Buffer
|
|
||||||
fmt.Fprintf(&bb, "// go generate gen.go\n")
|
|
||||||
fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n")
|
|
||||||
fmt.Fprintf(&bb, "// Package iana provides protocol number resources managed by the Internet Assigned Numbers Authority (IANA).\n")
|
|
||||||
fmt.Fprintf(&bb, `package iana // import "golang.org/x/net/internal/iana"`+"\n\n")
|
|
||||||
for _, r := range registries {
|
|
||||||
resp, err := http.Get(r.url)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
fmt.Fprintf(os.Stderr, "got HTTP status code %v for %v\n", resp.StatusCode, r.url)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
if err := r.parse(&bb, resp.Body); err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
fmt.Fprintf(&bb, "\n")
|
|
||||||
}
|
|
||||||
b, err := format.Source(bb.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
if err := ioutil.WriteFile("const.go", b, 0644); err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseDSCPRegistry(w io.Writer, r io.Reader) error {
|
|
||||||
dec := xml.NewDecoder(r)
|
|
||||||
var dr dscpRegistry
|
|
||||||
if err := dec.Decode(&dr); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
drs := dr.escape()
|
|
||||||
fmt.Fprintf(w, "// %s, Updated: %s\n", dr.Title, dr.Updated)
|
|
||||||
fmt.Fprintf(w, "const (\n")
|
|
||||||
for _, dr := range drs {
|
|
||||||
fmt.Fprintf(w, "DiffServ%s = %#x", dr.Name, dr.Value)
|
|
||||||
fmt.Fprintf(w, "// %s\n", dr.OrigName)
|
|
||||||
}
|
|
||||||
fmt.Fprintf(w, ")\n")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type dscpRegistry struct {
|
|
||||||
XMLName xml.Name `xml:"registry"`
|
|
||||||
Title string `xml:"title"`
|
|
||||||
Updated string `xml:"updated"`
|
|
||||||
Note string `xml:"note"`
|
|
||||||
RegTitle string `xml:"registry>title"`
|
|
||||||
PoolRecords []struct {
|
|
||||||
Name string `xml:"name"`
|
|
||||||
Space string `xml:"space"`
|
|
||||||
} `xml:"registry>record"`
|
|
||||||
Records []struct {
|
|
||||||
Name string `xml:"name"`
|
|
||||||
Space string `xml:"space"`
|
|
||||||
} `xml:"registry>registry>record"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type canonDSCPRecord struct {
|
|
||||||
OrigName string
|
|
||||||
Name string
|
|
||||||
Value int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (drr *dscpRegistry) escape() []canonDSCPRecord {
|
|
||||||
drs := make([]canonDSCPRecord, len(drr.Records))
|
|
||||||
sr := strings.NewReplacer(
|
|
||||||
"+", "",
|
|
||||||
"-", "",
|
|
||||||
"/", "",
|
|
||||||
".", "",
|
|
||||||
" ", "",
|
|
||||||
)
|
|
||||||
for i, dr := range drr.Records {
|
|
||||||
s := strings.TrimSpace(dr.Name)
|
|
||||||
drs[i].OrigName = s
|
|
||||||
drs[i].Name = sr.Replace(s)
|
|
||||||
n, err := strconv.ParseUint(dr.Space, 2, 8)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
drs[i].Value = int(n) << 2
|
|
||||||
}
|
|
||||||
return drs
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseTOSTCByte(w io.Writer, r io.Reader) error {
|
|
||||||
dec := xml.NewDecoder(r)
|
|
||||||
var ttb tosTCByte
|
|
||||||
if err := dec.Decode(&ttb); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
trs := ttb.escape()
|
|
||||||
fmt.Fprintf(w, "// %s, Updated: %s\n", ttb.Title, ttb.Updated)
|
|
||||||
fmt.Fprintf(w, "const (\n")
|
|
||||||
for _, tr := range trs {
|
|
||||||
fmt.Fprintf(w, "%s = %#x", tr.Keyword, tr.Value)
|
|
||||||
fmt.Fprintf(w, "// %s\n", tr.OrigKeyword)
|
|
||||||
}
|
|
||||||
fmt.Fprintf(w, ")\n")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type tosTCByte struct {
|
|
||||||
XMLName xml.Name `xml:"registry"`
|
|
||||||
Title string `xml:"title"`
|
|
||||||
Updated string `xml:"updated"`
|
|
||||||
Note string `xml:"note"`
|
|
||||||
RegTitle string `xml:"registry>title"`
|
|
||||||
Records []struct {
|
|
||||||
Binary string `xml:"binary"`
|
|
||||||
Keyword string `xml:"keyword"`
|
|
||||||
} `xml:"registry>record"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type canonTOSTCByteRecord struct {
|
|
||||||
OrigKeyword string
|
|
||||||
Keyword string
|
|
||||||
Value int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ttb *tosTCByte) escape() []canonTOSTCByteRecord {
|
|
||||||
trs := make([]canonTOSTCByteRecord, len(ttb.Records))
|
|
||||||
sr := strings.NewReplacer(
|
|
||||||
"Capable", "",
|
|
||||||
"(", "",
|
|
||||||
")", "",
|
|
||||||
"+", "",
|
|
||||||
"-", "",
|
|
||||||
"/", "",
|
|
||||||
".", "",
|
|
||||||
" ", "",
|
|
||||||
)
|
|
||||||
for i, tr := range ttb.Records {
|
|
||||||
s := strings.TrimSpace(tr.Keyword)
|
|
||||||
trs[i].OrigKeyword = s
|
|
||||||
ss := strings.Split(s, " ")
|
|
||||||
if len(ss) > 1 {
|
|
||||||
trs[i].Keyword = strings.Join(ss[1:], " ")
|
|
||||||
} else {
|
|
||||||
trs[i].Keyword = ss[0]
|
|
||||||
}
|
|
||||||
trs[i].Keyword = sr.Replace(trs[i].Keyword)
|
|
||||||
n, err := strconv.ParseUint(tr.Binary, 2, 8)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
trs[i].Value = int(n)
|
|
||||||
}
|
|
||||||
return trs
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseProtocolNumbers(w io.Writer, r io.Reader) error {
|
|
||||||
dec := xml.NewDecoder(r)
|
|
||||||
var pn protocolNumbers
|
|
||||||
if err := dec.Decode(&pn); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
prs := pn.escape()
|
|
||||||
prs = append([]canonProtocolRecord{{
|
|
||||||
Name: "IP",
|
|
||||||
Descr: "IPv4 encapsulation, pseudo protocol number",
|
|
||||||
Value: 0,
|
|
||||||
}}, prs...)
|
|
||||||
fmt.Fprintf(w, "// %s, Updated: %s\n", pn.Title, pn.Updated)
|
|
||||||
fmt.Fprintf(w, "const (\n")
|
|
||||||
for _, pr := range prs {
|
|
||||||
if pr.Name == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fmt.Fprintf(w, "Protocol%s = %d", pr.Name, pr.Value)
|
|
||||||
s := pr.Descr
|
|
||||||
if s == "" {
|
|
||||||
s = pr.OrigName
|
|
||||||
}
|
|
||||||
fmt.Fprintf(w, "// %s\n", s)
|
|
||||||
}
|
|
||||||
fmt.Fprintf(w, ")\n")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type protocolNumbers struct {
|
|
||||||
XMLName xml.Name `xml:"registry"`
|
|
||||||
Title string `xml:"title"`
|
|
||||||
Updated string `xml:"updated"`
|
|
||||||
RegTitle string `xml:"registry>title"`
|
|
||||||
Note string `xml:"registry>note"`
|
|
||||||
Records []struct {
|
|
||||||
Value string `xml:"value"`
|
|
||||||
Name string `xml:"name"`
|
|
||||||
Descr string `xml:"description"`
|
|
||||||
} `xml:"registry>record"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type canonProtocolRecord struct {
|
|
||||||
OrigName string
|
|
||||||
Name string
|
|
||||||
Descr string
|
|
||||||
Value int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pn *protocolNumbers) escape() []canonProtocolRecord {
|
|
||||||
prs := make([]canonProtocolRecord, len(pn.Records))
|
|
||||||
sr := strings.NewReplacer(
|
|
||||||
"-in-", "in",
|
|
||||||
"-within-", "within",
|
|
||||||
"-over-", "over",
|
|
||||||
"+", "P",
|
|
||||||
"-", "",
|
|
||||||
"/", "",
|
|
||||||
".", "",
|
|
||||||
" ", "",
|
|
||||||
)
|
|
||||||
for i, pr := range pn.Records {
|
|
||||||
if strings.Contains(pr.Name, "Deprecated") ||
|
|
||||||
strings.Contains(pr.Name, "deprecated") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
prs[i].OrigName = pr.Name
|
|
||||||
s := strings.TrimSpace(pr.Name)
|
|
||||||
switch pr.Name {
|
|
||||||
case "ISIS over IPv4":
|
|
||||||
prs[i].Name = "ISIS"
|
|
||||||
case "manet":
|
|
||||||
prs[i].Name = "MANET"
|
|
||||||
default:
|
|
||||||
prs[i].Name = sr.Replace(s)
|
|
||||||
}
|
|
||||||
ss := strings.Split(pr.Descr, "\n")
|
|
||||||
for i := range ss {
|
|
||||||
ss[i] = strings.TrimSpace(ss[i])
|
|
||||||
}
|
|
||||||
if len(ss) > 1 {
|
|
||||||
prs[i].Descr = strings.Join(ss, " ")
|
|
||||||
} else {
|
|
||||||
prs[i].Descr = ss[0]
|
|
||||||
}
|
|
||||||
prs[i].Value, _ = strconv.Atoi(pr.Value)
|
|
||||||
}
|
|
||||||
return prs
|
|
||||||
}
|
|
||||||
-92
@@ -1,92 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
errMissingAddress = errors.New("missing address")
|
|
||||||
errInvalidConnType = errors.New("invalid conn type")
|
|
||||||
errNoSuchInterface = errors.New("no such interface")
|
|
||||||
)
|
|
||||||
|
|
||||||
// Note that RFC 3542 obsoletes RFC 2292 but OS X Snow Leopard and the
|
|
||||||
// former still support RFC 2292 only. Please be aware that almost
|
|
||||||
// all protocol implementations prohibit using a combination of RFC
|
|
||||||
// 2292 and RFC 3542 for some practical reasons.
|
|
||||||
|
|
||||||
type rawOpt struct {
|
|
||||||
sync.RWMutex
|
|
||||||
cflags ControlFlags
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *rawOpt) set(f ControlFlags) { c.cflags |= f }
|
|
||||||
func (c *rawOpt) clear(f ControlFlags) { c.cflags &^= f }
|
|
||||||
func (c *rawOpt) isset(f ControlFlags) bool { return c.cflags&f != 0 }
|
|
||||||
|
|
||||||
// A ControlFlags represents per packet basis IP-level socket option
|
|
||||||
// control flags.
|
|
||||||
type ControlFlags uint
|
|
||||||
|
|
||||||
const (
|
|
||||||
FlagTrafficClass ControlFlags = 1 << iota // pass the traffic class on the received packet
|
|
||||||
FlagHopLimit // pass the hop limit on the received packet
|
|
||||||
FlagSrc // pass the source address on the received packet
|
|
||||||
FlagDst // pass the destination address on the received packet
|
|
||||||
FlagInterface // pass the interface index on the received packet
|
|
||||||
FlagPathMTU // pass the path MTU on the received packet path
|
|
||||||
)
|
|
||||||
|
|
||||||
const flagPacketInfo = FlagDst | FlagInterface
|
|
||||||
|
|
||||||
// A ControlMessage represents per packet basis IP-level socket
|
|
||||||
// options.
|
|
||||||
type ControlMessage struct {
|
|
||||||
// Receiving socket options: SetControlMessage allows to
|
|
||||||
// receive the options from the protocol stack using ReadFrom
|
|
||||||
// method of PacketConn.
|
|
||||||
//
|
|
||||||
// Specifying socket options: ControlMessage for WriteTo
|
|
||||||
// method of PacketConn allows to send the options to the
|
|
||||||
// protocol stack.
|
|
||||||
//
|
|
||||||
TrafficClass int // traffic class, must be 1 <= value <= 255 when specifying
|
|
||||||
HopLimit int // hop limit, must be 1 <= value <= 255 when specifying
|
|
||||||
Src net.IP // source address, specifying only
|
|
||||||
Dst net.IP // destination address, receiving only
|
|
||||||
IfIndex int // interface index, must be 1 <= value when specifying
|
|
||||||
NextHop net.IP // next hop address, specifying only
|
|
||||||
MTU int // path MTU, receiving only
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cm *ControlMessage) String() string {
|
|
||||||
if cm == nil {
|
|
||||||
return "<nil>"
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("tclass: %#x, hoplim: %v, src: %v, dst: %v, ifindex: %v, nexthop: %v, mtu: %v", cm.TrafficClass, cm.HopLimit, cm.Src, cm.Dst, cm.IfIndex, cm.NextHop, cm.MTU)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ancillary data socket options
|
|
||||||
const (
|
|
||||||
ctlTrafficClass = iota // header field
|
|
||||||
ctlHopLimit // header field
|
|
||||||
ctlPacketInfo // inbound or outbound packet path
|
|
||||||
ctlNextHop // nexthop
|
|
||||||
ctlPathMTU // path mtu
|
|
||||||
ctlMax
|
|
||||||
)
|
|
||||||
|
|
||||||
// A ctlOpt represents a binding for ancillary data socket option.
|
|
||||||
type ctlOpt struct {
|
|
||||||
name int // option name, must be equal or greater than 1
|
|
||||||
length int // option length
|
|
||||||
marshal func([]byte, *ControlMessage) []byte
|
|
||||||
parse func(*ControlMessage, []byte)
|
|
||||||
}
|
|
||||||
-56
@@ -1,56 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build darwin
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
)
|
|
||||||
|
|
||||||
func marshal2292HopLimit(b []byte, cm *ControlMessage) []byte {
|
|
||||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
|
|
||||||
m.Level = iana.ProtocolIPv6
|
|
||||||
m.Type = sysIPV6_2292HOPLIMIT
|
|
||||||
m.SetLen(syscall.CmsgLen(4))
|
|
||||||
if cm != nil {
|
|
||||||
data := b[syscall.CmsgLen(0):]
|
|
||||||
// TODO(mikio): fix potential misaligned memory access
|
|
||||||
*(*int32)(unsafe.Pointer(&data[:4][0])) = int32(cm.HopLimit)
|
|
||||||
}
|
|
||||||
return b[syscall.CmsgSpace(4):]
|
|
||||||
}
|
|
||||||
|
|
||||||
func marshal2292PacketInfo(b []byte, cm *ControlMessage) []byte {
|
|
||||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
|
|
||||||
m.Level = iana.ProtocolIPv6
|
|
||||||
m.Type = sysIPV6_2292PKTINFO
|
|
||||||
m.SetLen(syscall.CmsgLen(sysSizeofInet6Pktinfo))
|
|
||||||
if cm != nil {
|
|
||||||
pi := (*sysInet6Pktinfo)(unsafe.Pointer(&b[syscall.CmsgLen(0)]))
|
|
||||||
if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
|
|
||||||
copy(pi.Addr[:], ip)
|
|
||||||
}
|
|
||||||
if cm.IfIndex > 0 {
|
|
||||||
pi.setIfindex(cm.IfIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return b[syscall.CmsgSpace(sysSizeofInet6Pktinfo):]
|
|
||||||
}
|
|
||||||
|
|
||||||
func marshal2292NextHop(b []byte, cm *ControlMessage) []byte {
|
|
||||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
|
|
||||||
m.Level = iana.ProtocolIPv6
|
|
||||||
m.Type = sysIPV6_2292NEXTHOP
|
|
||||||
m.SetLen(syscall.CmsgLen(sysSizeofSockaddrInet6))
|
|
||||||
if cm != nil {
|
|
||||||
sa := (*sysSockaddrInet6)(unsafe.Pointer(&b[syscall.CmsgLen(0)]))
|
|
||||||
sa.setSockaddr(cm.NextHop, cm.IfIndex)
|
|
||||||
}
|
|
||||||
return b[syscall.CmsgSpace(sysSizeofSockaddrInet6):]
|
|
||||||
}
|
|
||||||
-103
@@ -1,103 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build darwin dragonfly freebsd linux netbsd openbsd
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
)
|
|
||||||
|
|
||||||
func marshalTrafficClass(b []byte, cm *ControlMessage) []byte {
|
|
||||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
|
|
||||||
m.Level = iana.ProtocolIPv6
|
|
||||||
m.Type = sysIPV6_TCLASS
|
|
||||||
m.SetLen(syscall.CmsgLen(4))
|
|
||||||
if cm != nil {
|
|
||||||
data := b[syscall.CmsgLen(0):]
|
|
||||||
// TODO(mikio): fix potential misaligned memory access
|
|
||||||
*(*int32)(unsafe.Pointer(&data[:4][0])) = int32(cm.TrafficClass)
|
|
||||||
}
|
|
||||||
return b[syscall.CmsgSpace(4):]
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseTrafficClass(cm *ControlMessage, b []byte) {
|
|
||||||
// TODO(mikio): fix potential misaligned memory access
|
|
||||||
cm.TrafficClass = int(*(*int32)(unsafe.Pointer(&b[:4][0])))
|
|
||||||
}
|
|
||||||
|
|
||||||
func marshalHopLimit(b []byte, cm *ControlMessage) []byte {
|
|
||||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
|
|
||||||
m.Level = iana.ProtocolIPv6
|
|
||||||
m.Type = sysIPV6_HOPLIMIT
|
|
||||||
m.SetLen(syscall.CmsgLen(4))
|
|
||||||
if cm != nil {
|
|
||||||
data := b[syscall.CmsgLen(0):]
|
|
||||||
// TODO(mikio): fix potential misaligned memory access
|
|
||||||
*(*int32)(unsafe.Pointer(&data[:4][0])) = int32(cm.HopLimit)
|
|
||||||
}
|
|
||||||
return b[syscall.CmsgSpace(4):]
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseHopLimit(cm *ControlMessage, b []byte) {
|
|
||||||
// TODO(mikio): fix potential misaligned memory access
|
|
||||||
cm.HopLimit = int(*(*int32)(unsafe.Pointer(&b[:4][0])))
|
|
||||||
}
|
|
||||||
|
|
||||||
func marshalPacketInfo(b []byte, cm *ControlMessage) []byte {
|
|
||||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
|
|
||||||
m.Level = iana.ProtocolIPv6
|
|
||||||
m.Type = sysIPV6_PKTINFO
|
|
||||||
m.SetLen(syscall.CmsgLen(sysSizeofInet6Pktinfo))
|
|
||||||
if cm != nil {
|
|
||||||
pi := (*sysInet6Pktinfo)(unsafe.Pointer(&b[syscall.CmsgLen(0)]))
|
|
||||||
if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
|
|
||||||
copy(pi.Addr[:], ip)
|
|
||||||
}
|
|
||||||
if cm.IfIndex > 0 {
|
|
||||||
pi.setIfindex(cm.IfIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return b[syscall.CmsgSpace(sysSizeofInet6Pktinfo):]
|
|
||||||
}
|
|
||||||
|
|
||||||
func parsePacketInfo(cm *ControlMessage, b []byte) {
|
|
||||||
pi := (*sysInet6Pktinfo)(unsafe.Pointer(&b[0]))
|
|
||||||
cm.Dst = pi.Addr[:]
|
|
||||||
cm.IfIndex = int(pi.Ifindex)
|
|
||||||
}
|
|
||||||
|
|
||||||
func marshalNextHop(b []byte, cm *ControlMessage) []byte {
|
|
||||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
|
|
||||||
m.Level = iana.ProtocolIPv6
|
|
||||||
m.Type = sysIPV6_NEXTHOP
|
|
||||||
m.SetLen(syscall.CmsgLen(sysSizeofSockaddrInet6))
|
|
||||||
if cm != nil {
|
|
||||||
sa := (*sysSockaddrInet6)(unsafe.Pointer(&b[syscall.CmsgLen(0)]))
|
|
||||||
sa.setSockaddr(cm.NextHop, cm.IfIndex)
|
|
||||||
}
|
|
||||||
return b[syscall.CmsgSpace(sysSizeofSockaddrInet6):]
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseNextHop(cm *ControlMessage, b []byte) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func marshalPathMTU(b []byte, cm *ControlMessage) []byte {
|
|
||||||
m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
|
|
||||||
m.Level = iana.ProtocolIPv6
|
|
||||||
m.Type = sysIPV6_PATHMTU
|
|
||||||
m.SetLen(syscall.CmsgLen(sysSizeofIPv6Mtuinfo))
|
|
||||||
return b[syscall.CmsgSpace(sysSizeofIPv6Mtuinfo):]
|
|
||||||
}
|
|
||||||
|
|
||||||
func parsePathMTU(cm *ControlMessage, b []byte) {
|
|
||||||
mi := (*sysIPv6Mtuinfo)(unsafe.Pointer(&b[0]))
|
|
||||||
cm.Dst = mi.Addr.Addr[:]
|
|
||||||
cm.IfIndex = int(mi.Addr.Scope_id)
|
|
||||||
cm.MTU = int(mi.Mtu)
|
|
||||||
}
|
|
||||||
-23
@@ -1,23 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build nacl plan9 solaris
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
func newControlMessage(opt *rawOpt) (oob []byte) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseControlMessage(b []byte) (*ControlMessage, error) {
|
|
||||||
return nil, errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
func marshalControlMessage(cm *ControlMessage) (oob []byte) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
-166
@@ -1,166 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build darwin dragonfly freebsd linux netbsd openbsd
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
)
|
|
||||||
|
|
||||||
func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
|
|
||||||
opt.Lock()
|
|
||||||
defer opt.Unlock()
|
|
||||||
if cf&FlagTrafficClass != 0 && sockOpts[ssoReceiveTrafficClass].name > 0 {
|
|
||||||
if err := setInt(fd, &sockOpts[ssoReceiveTrafficClass], boolint(on)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if on {
|
|
||||||
opt.set(FlagTrafficClass)
|
|
||||||
} else {
|
|
||||||
opt.clear(FlagTrafficClass)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if cf&FlagHopLimit != 0 && sockOpts[ssoReceiveHopLimit].name > 0 {
|
|
||||||
if err := setInt(fd, &sockOpts[ssoReceiveHopLimit], boolint(on)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if on {
|
|
||||||
opt.set(FlagHopLimit)
|
|
||||||
} else {
|
|
||||||
opt.clear(FlagHopLimit)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if cf&flagPacketInfo != 0 && sockOpts[ssoReceivePacketInfo].name > 0 {
|
|
||||||
if err := setInt(fd, &sockOpts[ssoReceivePacketInfo], boolint(on)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if on {
|
|
||||||
opt.set(cf & flagPacketInfo)
|
|
||||||
} else {
|
|
||||||
opt.clear(cf & flagPacketInfo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if cf&FlagPathMTU != 0 && sockOpts[ssoReceivePathMTU].name > 0 {
|
|
||||||
if err := setInt(fd, &sockOpts[ssoReceivePathMTU], boolint(on)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if on {
|
|
||||||
opt.set(FlagPathMTU)
|
|
||||||
} else {
|
|
||||||
opt.clear(FlagPathMTU)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func newControlMessage(opt *rawOpt) (oob []byte) {
|
|
||||||
opt.RLock()
|
|
||||||
var l int
|
|
||||||
if opt.isset(FlagTrafficClass) && ctlOpts[ctlTrafficClass].name > 0 {
|
|
||||||
l += syscall.CmsgSpace(ctlOpts[ctlTrafficClass].length)
|
|
||||||
}
|
|
||||||
if opt.isset(FlagHopLimit) && ctlOpts[ctlHopLimit].name > 0 {
|
|
||||||
l += syscall.CmsgSpace(ctlOpts[ctlHopLimit].length)
|
|
||||||
}
|
|
||||||
if opt.isset(flagPacketInfo) && ctlOpts[ctlPacketInfo].name > 0 {
|
|
||||||
l += syscall.CmsgSpace(ctlOpts[ctlPacketInfo].length)
|
|
||||||
}
|
|
||||||
if opt.isset(FlagPathMTU) && ctlOpts[ctlPathMTU].name > 0 {
|
|
||||||
l += syscall.CmsgSpace(ctlOpts[ctlPathMTU].length)
|
|
||||||
}
|
|
||||||
if l > 0 {
|
|
||||||
oob = make([]byte, l)
|
|
||||||
b := oob
|
|
||||||
if opt.isset(FlagTrafficClass) && ctlOpts[ctlTrafficClass].name > 0 {
|
|
||||||
b = ctlOpts[ctlTrafficClass].marshal(b, nil)
|
|
||||||
}
|
|
||||||
if opt.isset(FlagHopLimit) && ctlOpts[ctlHopLimit].name > 0 {
|
|
||||||
b = ctlOpts[ctlHopLimit].marshal(b, nil)
|
|
||||||
}
|
|
||||||
if opt.isset(flagPacketInfo) && ctlOpts[ctlPacketInfo].name > 0 {
|
|
||||||
b = ctlOpts[ctlPacketInfo].marshal(b, nil)
|
|
||||||
}
|
|
||||||
if opt.isset(FlagPathMTU) && ctlOpts[ctlPathMTU].name > 0 {
|
|
||||||
b = ctlOpts[ctlPathMTU].marshal(b, nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
opt.RUnlock()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseControlMessage(b []byte) (*ControlMessage, error) {
|
|
||||||
if len(b) == 0 {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
cmsgs, err := syscall.ParseSocketControlMessage(b)
|
|
||||||
if err != nil {
|
|
||||||
return nil, os.NewSyscallError("parse socket control message", err)
|
|
||||||
}
|
|
||||||
cm := &ControlMessage{}
|
|
||||||
for _, m := range cmsgs {
|
|
||||||
if m.Header.Level != iana.ProtocolIPv6 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
switch int(m.Header.Type) {
|
|
||||||
case ctlOpts[ctlTrafficClass].name:
|
|
||||||
ctlOpts[ctlTrafficClass].parse(cm, m.Data[:])
|
|
||||||
case ctlOpts[ctlHopLimit].name:
|
|
||||||
ctlOpts[ctlHopLimit].parse(cm, m.Data[:])
|
|
||||||
case ctlOpts[ctlPacketInfo].name:
|
|
||||||
ctlOpts[ctlPacketInfo].parse(cm, m.Data[:])
|
|
||||||
case ctlOpts[ctlPathMTU].name:
|
|
||||||
ctlOpts[ctlPathMTU].parse(cm, m.Data[:])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cm, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func marshalControlMessage(cm *ControlMessage) (oob []byte) {
|
|
||||||
if cm == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var l int
|
|
||||||
tclass := false
|
|
||||||
if ctlOpts[ctlTrafficClass].name > 0 && cm.TrafficClass > 0 {
|
|
||||||
tclass = true
|
|
||||||
l += syscall.CmsgSpace(ctlOpts[ctlTrafficClass].length)
|
|
||||||
}
|
|
||||||
hoplimit := false
|
|
||||||
if ctlOpts[ctlHopLimit].name > 0 && cm.HopLimit > 0 {
|
|
||||||
hoplimit = true
|
|
||||||
l += syscall.CmsgSpace(ctlOpts[ctlHopLimit].length)
|
|
||||||
}
|
|
||||||
pktinfo := false
|
|
||||||
if ctlOpts[ctlPacketInfo].name > 0 && (cm.Src.To16() != nil && cm.Src.To4() == nil || cm.IfIndex > 0) {
|
|
||||||
pktinfo = true
|
|
||||||
l += syscall.CmsgSpace(ctlOpts[ctlPacketInfo].length)
|
|
||||||
}
|
|
||||||
nexthop := false
|
|
||||||
if ctlOpts[ctlNextHop].name > 0 && cm.NextHop.To16() != nil && cm.NextHop.To4() == nil {
|
|
||||||
nexthop = true
|
|
||||||
l += syscall.CmsgSpace(ctlOpts[ctlNextHop].length)
|
|
||||||
}
|
|
||||||
if l > 0 {
|
|
||||||
oob = make([]byte, l)
|
|
||||||
b := oob
|
|
||||||
if tclass {
|
|
||||||
b = ctlOpts[ctlTrafficClass].marshal(b, cm)
|
|
||||||
}
|
|
||||||
if hoplimit {
|
|
||||||
b = ctlOpts[ctlHopLimit].marshal(b, cm)
|
|
||||||
}
|
|
||||||
if pktinfo {
|
|
||||||
b = ctlOpts[ctlPacketInfo].marshal(b, cm)
|
|
||||||
}
|
|
||||||
if nexthop {
|
|
||||||
b = ctlOpts[ctlNextHop].marshal(b, cm)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
-27
@@ -1,27 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
func setControlMessage(fd syscall.Handle, opt *rawOpt, cf ControlFlags, on bool) error {
|
|
||||||
// TODO(mikio): implement this
|
|
||||||
return syscall.EWINDOWS
|
|
||||||
}
|
|
||||||
|
|
||||||
func newControlMessage(opt *rawOpt) (oob []byte) {
|
|
||||||
// TODO(mikio): implement this
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseControlMessage(b []byte) (*ControlMessage, error) {
|
|
||||||
// TODO(mikio): implement this
|
|
||||||
return nil, syscall.EWINDOWS
|
|
||||||
}
|
|
||||||
|
|
||||||
func marshalControlMessage(cm *ControlMessage) (oob []byte) {
|
|
||||||
// TODO(mikio): implement this
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
-112
@@ -1,112 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
// +godefs map struct_in6_addr [16]byte /* in6_addr */
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
/*
|
|
||||||
#define __APPLE_USE_RFC_3542
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <netinet/icmp6.h>
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_UNICAST_HOPS = C.IPV6_UNICAST_HOPS
|
|
||||||
sysIPV6_MULTICAST_IF = C.IPV6_MULTICAST_IF
|
|
||||||
sysIPV6_MULTICAST_HOPS = C.IPV6_MULTICAST_HOPS
|
|
||||||
sysIPV6_MULTICAST_LOOP = C.IPV6_MULTICAST_LOOP
|
|
||||||
sysIPV6_JOIN_GROUP = C.IPV6_JOIN_GROUP
|
|
||||||
sysIPV6_LEAVE_GROUP = C.IPV6_LEAVE_GROUP
|
|
||||||
|
|
||||||
sysIPV6_PORTRANGE = C.IPV6_PORTRANGE
|
|
||||||
sysICMP6_FILTER = C.ICMP6_FILTER
|
|
||||||
sysIPV6_2292PKTINFO = C.IPV6_2292PKTINFO
|
|
||||||
sysIPV6_2292HOPLIMIT = C.IPV6_2292HOPLIMIT
|
|
||||||
sysIPV6_2292NEXTHOP = C.IPV6_2292NEXTHOP
|
|
||||||
sysIPV6_2292HOPOPTS = C.IPV6_2292HOPOPTS
|
|
||||||
sysIPV6_2292DSTOPTS = C.IPV6_2292DSTOPTS
|
|
||||||
sysIPV6_2292RTHDR = C.IPV6_2292RTHDR
|
|
||||||
|
|
||||||
sysIPV6_2292PKTOPTIONS = C.IPV6_2292PKTOPTIONS
|
|
||||||
|
|
||||||
sysIPV6_CHECKSUM = C.IPV6_CHECKSUM
|
|
||||||
sysIPV6_V6ONLY = C.IPV6_V6ONLY
|
|
||||||
|
|
||||||
sysIPV6_IPSEC_POLICY = C.IPV6_IPSEC_POLICY
|
|
||||||
|
|
||||||
sysIPV6_RECVTCLASS = C.IPV6_RECVTCLASS
|
|
||||||
sysIPV6_TCLASS = C.IPV6_TCLASS
|
|
||||||
|
|
||||||
sysIPV6_RTHDRDSTOPTS = C.IPV6_RTHDRDSTOPTS
|
|
||||||
|
|
||||||
sysIPV6_RECVPKTINFO = C.IPV6_RECVPKTINFO
|
|
||||||
|
|
||||||
sysIPV6_RECVHOPLIMIT = C.IPV6_RECVHOPLIMIT
|
|
||||||
sysIPV6_RECVRTHDR = C.IPV6_RECVRTHDR
|
|
||||||
sysIPV6_RECVHOPOPTS = C.IPV6_RECVHOPOPTS
|
|
||||||
sysIPV6_RECVDSTOPTS = C.IPV6_RECVDSTOPTS
|
|
||||||
|
|
||||||
sysIPV6_USE_MIN_MTU = C.IPV6_USE_MIN_MTU
|
|
||||||
sysIPV6_RECVPATHMTU = C.IPV6_RECVPATHMTU
|
|
||||||
|
|
||||||
sysIPV6_PATHMTU = C.IPV6_PATHMTU
|
|
||||||
|
|
||||||
sysIPV6_PKTINFO = C.IPV6_PKTINFO
|
|
||||||
sysIPV6_HOPLIMIT = C.IPV6_HOPLIMIT
|
|
||||||
sysIPV6_NEXTHOP = C.IPV6_NEXTHOP
|
|
||||||
sysIPV6_HOPOPTS = C.IPV6_HOPOPTS
|
|
||||||
sysIPV6_DSTOPTS = C.IPV6_DSTOPTS
|
|
||||||
sysIPV6_RTHDR = C.IPV6_RTHDR
|
|
||||||
|
|
||||||
sysIPV6_AUTOFLOWLABEL = C.IPV6_AUTOFLOWLABEL
|
|
||||||
|
|
||||||
sysIPV6_DONTFRAG = C.IPV6_DONTFRAG
|
|
||||||
|
|
||||||
sysIPV6_PREFER_TEMPADDR = C.IPV6_PREFER_TEMPADDR
|
|
||||||
|
|
||||||
sysIPV6_MSFILTER = C.IPV6_MSFILTER
|
|
||||||
sysMCAST_JOIN_GROUP = C.MCAST_JOIN_GROUP
|
|
||||||
sysMCAST_LEAVE_GROUP = C.MCAST_LEAVE_GROUP
|
|
||||||
sysMCAST_JOIN_SOURCE_GROUP = C.MCAST_JOIN_SOURCE_GROUP
|
|
||||||
sysMCAST_LEAVE_SOURCE_GROUP = C.MCAST_LEAVE_SOURCE_GROUP
|
|
||||||
sysMCAST_BLOCK_SOURCE = C.MCAST_BLOCK_SOURCE
|
|
||||||
sysMCAST_UNBLOCK_SOURCE = C.MCAST_UNBLOCK_SOURCE
|
|
||||||
|
|
||||||
sysIPV6_BOUND_IF = C.IPV6_BOUND_IF
|
|
||||||
|
|
||||||
sysIPV6_PORTRANGE_DEFAULT = C.IPV6_PORTRANGE_DEFAULT
|
|
||||||
sysIPV6_PORTRANGE_HIGH = C.IPV6_PORTRANGE_HIGH
|
|
||||||
sysIPV6_PORTRANGE_LOW = C.IPV6_PORTRANGE_LOW
|
|
||||||
|
|
||||||
sysSizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage
|
|
||||||
sysSizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
|
|
||||||
sysSizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo
|
|
||||||
sysSizeofIPv6Mtuinfo = C.sizeof_struct_ip6_mtuinfo
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
|
|
||||||
sysSizeofGroupReq = C.sizeof_struct_group_req
|
|
||||||
sysSizeofGroupSourceReq = C.sizeof_struct_group_source_req
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysSockaddrStorage C.struct_sockaddr_storage
|
|
||||||
|
|
||||||
type sysSockaddrInet6 C.struct_sockaddr_in6
|
|
||||||
|
|
||||||
type sysInet6Pktinfo C.struct_in6_pktinfo
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo C.struct_ip6_mtuinfo
|
|
||||||
|
|
||||||
type sysIPv6Mreq C.struct_ipv6_mreq
|
|
||||||
|
|
||||||
type sysICMPv6Filter C.struct_icmp6_filter
|
|
||||||
|
|
||||||
type sysGroupReq C.struct_group_req
|
|
||||||
|
|
||||||
type sysGroupSourceReq C.struct_group_source_req
|
|
||||||
-84
@@ -1,84 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
// +godefs map struct_in6_addr [16]byte /* in6_addr */
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <netinet/icmp6.h>
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_UNICAST_HOPS = C.IPV6_UNICAST_HOPS
|
|
||||||
sysIPV6_MULTICAST_IF = C.IPV6_MULTICAST_IF
|
|
||||||
sysIPV6_MULTICAST_HOPS = C.IPV6_MULTICAST_HOPS
|
|
||||||
sysIPV6_MULTICAST_LOOP = C.IPV6_MULTICAST_LOOP
|
|
||||||
sysIPV6_JOIN_GROUP = C.IPV6_JOIN_GROUP
|
|
||||||
sysIPV6_LEAVE_GROUP = C.IPV6_LEAVE_GROUP
|
|
||||||
sysIPV6_PORTRANGE = C.IPV6_PORTRANGE
|
|
||||||
sysICMP6_FILTER = C.ICMP6_FILTER
|
|
||||||
|
|
||||||
sysIPV6_CHECKSUM = C.IPV6_CHECKSUM
|
|
||||||
sysIPV6_V6ONLY = C.IPV6_V6ONLY
|
|
||||||
|
|
||||||
sysIPV6_IPSEC_POLICY = C.IPV6_IPSEC_POLICY
|
|
||||||
|
|
||||||
sysIPV6_RTHDRDSTOPTS = C.IPV6_RTHDRDSTOPTS
|
|
||||||
sysIPV6_RECVPKTINFO = C.IPV6_RECVPKTINFO
|
|
||||||
sysIPV6_RECVHOPLIMIT = C.IPV6_RECVHOPLIMIT
|
|
||||||
sysIPV6_RECVRTHDR = C.IPV6_RECVRTHDR
|
|
||||||
sysIPV6_RECVHOPOPTS = C.IPV6_RECVHOPOPTS
|
|
||||||
sysIPV6_RECVDSTOPTS = C.IPV6_RECVDSTOPTS
|
|
||||||
|
|
||||||
sysIPV6_USE_MIN_MTU = C.IPV6_USE_MIN_MTU
|
|
||||||
sysIPV6_RECVPATHMTU = C.IPV6_RECVPATHMTU
|
|
||||||
|
|
||||||
sysIPV6_PATHMTU = C.IPV6_PATHMTU
|
|
||||||
|
|
||||||
sysIPV6_PKTINFO = C.IPV6_PKTINFO
|
|
||||||
sysIPV6_HOPLIMIT = C.IPV6_HOPLIMIT
|
|
||||||
sysIPV6_NEXTHOP = C.IPV6_NEXTHOP
|
|
||||||
sysIPV6_HOPOPTS = C.IPV6_HOPOPTS
|
|
||||||
sysIPV6_DSTOPTS = C.IPV6_DSTOPTS
|
|
||||||
sysIPV6_RTHDR = C.IPV6_RTHDR
|
|
||||||
|
|
||||||
sysIPV6_RECVTCLASS = C.IPV6_RECVTCLASS
|
|
||||||
|
|
||||||
sysIPV6_AUTOFLOWLABEL = C.IPV6_AUTOFLOWLABEL
|
|
||||||
|
|
||||||
sysIPV6_TCLASS = C.IPV6_TCLASS
|
|
||||||
sysIPV6_DONTFRAG = C.IPV6_DONTFRAG
|
|
||||||
|
|
||||||
sysIPV6_PREFER_TEMPADDR = C.IPV6_PREFER_TEMPADDR
|
|
||||||
|
|
||||||
sysIPV6_PORTRANGE_DEFAULT = C.IPV6_PORTRANGE_DEFAULT
|
|
||||||
sysIPV6_PORTRANGE_HIGH = C.IPV6_PORTRANGE_HIGH
|
|
||||||
sysIPV6_PORTRANGE_LOW = C.IPV6_PORTRANGE_LOW
|
|
||||||
|
|
||||||
sysSizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
|
|
||||||
sysSizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo
|
|
||||||
sysSizeofIPv6Mtuinfo = C.sizeof_struct_ip6_mtuinfo
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysSockaddrInet6 C.struct_sockaddr_in6
|
|
||||||
|
|
||||||
type sysInet6Pktinfo C.struct_in6_pktinfo
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo C.struct_ip6_mtuinfo
|
|
||||||
|
|
||||||
type sysIPv6Mreq C.struct_ipv6_mreq
|
|
||||||
|
|
||||||
type sysICMPv6Filter C.struct_icmp6_filter
|
|
||||||
-105
@@ -1,105 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
// +godefs map struct_in6_addr [16]byte /* in6_addr */
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <netinet/icmp6.h>
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_UNICAST_HOPS = C.IPV6_UNICAST_HOPS
|
|
||||||
sysIPV6_MULTICAST_IF = C.IPV6_MULTICAST_IF
|
|
||||||
sysIPV6_MULTICAST_HOPS = C.IPV6_MULTICAST_HOPS
|
|
||||||
sysIPV6_MULTICAST_LOOP = C.IPV6_MULTICAST_LOOP
|
|
||||||
sysIPV6_JOIN_GROUP = C.IPV6_JOIN_GROUP
|
|
||||||
sysIPV6_LEAVE_GROUP = C.IPV6_LEAVE_GROUP
|
|
||||||
sysIPV6_PORTRANGE = C.IPV6_PORTRANGE
|
|
||||||
sysICMP6_FILTER = C.ICMP6_FILTER
|
|
||||||
|
|
||||||
sysIPV6_CHECKSUM = C.IPV6_CHECKSUM
|
|
||||||
sysIPV6_V6ONLY = C.IPV6_V6ONLY
|
|
||||||
|
|
||||||
sysIPV6_IPSEC_POLICY = C.IPV6_IPSEC_POLICY
|
|
||||||
|
|
||||||
sysIPV6_RTHDRDSTOPTS = C.IPV6_RTHDRDSTOPTS
|
|
||||||
|
|
||||||
sysIPV6_RECVPKTINFO = C.IPV6_RECVPKTINFO
|
|
||||||
sysIPV6_RECVHOPLIMIT = C.IPV6_RECVHOPLIMIT
|
|
||||||
sysIPV6_RECVRTHDR = C.IPV6_RECVRTHDR
|
|
||||||
sysIPV6_RECVHOPOPTS = C.IPV6_RECVHOPOPTS
|
|
||||||
sysIPV6_RECVDSTOPTS = C.IPV6_RECVDSTOPTS
|
|
||||||
|
|
||||||
sysIPV6_USE_MIN_MTU = C.IPV6_USE_MIN_MTU
|
|
||||||
sysIPV6_RECVPATHMTU = C.IPV6_RECVPATHMTU
|
|
||||||
|
|
||||||
sysIPV6_PATHMTU = C.IPV6_PATHMTU
|
|
||||||
|
|
||||||
sysIPV6_PKTINFO = C.IPV6_PKTINFO
|
|
||||||
sysIPV6_HOPLIMIT = C.IPV6_HOPLIMIT
|
|
||||||
sysIPV6_NEXTHOP = C.IPV6_NEXTHOP
|
|
||||||
sysIPV6_HOPOPTS = C.IPV6_HOPOPTS
|
|
||||||
sysIPV6_DSTOPTS = C.IPV6_DSTOPTS
|
|
||||||
sysIPV6_RTHDR = C.IPV6_RTHDR
|
|
||||||
|
|
||||||
sysIPV6_RECVTCLASS = C.IPV6_RECVTCLASS
|
|
||||||
|
|
||||||
sysIPV6_AUTOFLOWLABEL = C.IPV6_AUTOFLOWLABEL
|
|
||||||
|
|
||||||
sysIPV6_TCLASS = C.IPV6_TCLASS
|
|
||||||
sysIPV6_DONTFRAG = C.IPV6_DONTFRAG
|
|
||||||
|
|
||||||
sysIPV6_PREFER_TEMPADDR = C.IPV6_PREFER_TEMPADDR
|
|
||||||
|
|
||||||
sysIPV6_BINDANY = C.IPV6_BINDANY
|
|
||||||
|
|
||||||
sysIPV6_MSFILTER = C.IPV6_MSFILTER
|
|
||||||
|
|
||||||
sysMCAST_JOIN_GROUP = C.MCAST_JOIN_GROUP
|
|
||||||
sysMCAST_LEAVE_GROUP = C.MCAST_LEAVE_GROUP
|
|
||||||
sysMCAST_JOIN_SOURCE_GROUP = C.MCAST_JOIN_SOURCE_GROUP
|
|
||||||
sysMCAST_LEAVE_SOURCE_GROUP = C.MCAST_LEAVE_SOURCE_GROUP
|
|
||||||
sysMCAST_BLOCK_SOURCE = C.MCAST_BLOCK_SOURCE
|
|
||||||
sysMCAST_UNBLOCK_SOURCE = C.MCAST_UNBLOCK_SOURCE
|
|
||||||
|
|
||||||
sysIPV6_PORTRANGE_DEFAULT = C.IPV6_PORTRANGE_DEFAULT
|
|
||||||
sysIPV6_PORTRANGE_HIGH = C.IPV6_PORTRANGE_HIGH
|
|
||||||
sysIPV6_PORTRANGE_LOW = C.IPV6_PORTRANGE_LOW
|
|
||||||
|
|
||||||
sysSizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage
|
|
||||||
sysSizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
|
|
||||||
sysSizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo
|
|
||||||
sysSizeofIPv6Mtuinfo = C.sizeof_struct_ip6_mtuinfo
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
|
|
||||||
sysSizeofGroupReq = C.sizeof_struct_group_req
|
|
||||||
sysSizeofGroupSourceReq = C.sizeof_struct_group_source_req
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysSockaddrStorage C.struct_sockaddr_storage
|
|
||||||
|
|
||||||
type sysSockaddrInet6 C.struct_sockaddr_in6
|
|
||||||
|
|
||||||
type sysInet6Pktinfo C.struct_in6_pktinfo
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo C.struct_ip6_mtuinfo
|
|
||||||
|
|
||||||
type sysIPv6Mreq C.struct_ipv6_mreq
|
|
||||||
|
|
||||||
type sysGroupReq C.struct_group_req
|
|
||||||
|
|
||||||
type sysGroupSourceReq C.struct_group_source_req
|
|
||||||
|
|
||||||
type sysICMPv6Filter C.struct_icmp6_filter
|
|
||||||
-136
@@ -1,136 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
// +godefs map struct_in6_addr [16]byte /* in6_addr */
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include <linux/in.h>
|
|
||||||
#include <linux/in6.h>
|
|
||||||
#include <linux/ipv6.h>
|
|
||||||
#include <linux/icmpv6.h>
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_ADDRFORM = C.IPV6_ADDRFORM
|
|
||||||
sysIPV6_2292PKTINFO = C.IPV6_2292PKTINFO
|
|
||||||
sysIPV6_2292HOPOPTS = C.IPV6_2292HOPOPTS
|
|
||||||
sysIPV6_2292DSTOPTS = C.IPV6_2292DSTOPTS
|
|
||||||
sysIPV6_2292RTHDR = C.IPV6_2292RTHDR
|
|
||||||
sysIPV6_2292PKTOPTIONS = C.IPV6_2292PKTOPTIONS
|
|
||||||
sysIPV6_CHECKSUM = C.IPV6_CHECKSUM
|
|
||||||
sysIPV6_2292HOPLIMIT = C.IPV6_2292HOPLIMIT
|
|
||||||
sysIPV6_NEXTHOP = C.IPV6_NEXTHOP
|
|
||||||
sysIPV6_FLOWINFO = C.IPV6_FLOWINFO
|
|
||||||
|
|
||||||
sysIPV6_UNICAST_HOPS = C.IPV6_UNICAST_HOPS
|
|
||||||
sysIPV6_MULTICAST_IF = C.IPV6_MULTICAST_IF
|
|
||||||
sysIPV6_MULTICAST_HOPS = C.IPV6_MULTICAST_HOPS
|
|
||||||
sysIPV6_MULTICAST_LOOP = C.IPV6_MULTICAST_LOOP
|
|
||||||
sysIPV6_ADD_MEMBERSHIP = C.IPV6_ADD_MEMBERSHIP
|
|
||||||
sysIPV6_DROP_MEMBERSHIP = C.IPV6_DROP_MEMBERSHIP
|
|
||||||
sysMCAST_JOIN_GROUP = C.MCAST_JOIN_GROUP
|
|
||||||
sysMCAST_LEAVE_GROUP = C.MCAST_LEAVE_GROUP
|
|
||||||
sysMCAST_JOIN_SOURCE_GROUP = C.MCAST_JOIN_SOURCE_GROUP
|
|
||||||
sysMCAST_LEAVE_SOURCE_GROUP = C.MCAST_LEAVE_SOURCE_GROUP
|
|
||||||
sysMCAST_BLOCK_SOURCE = C.MCAST_BLOCK_SOURCE
|
|
||||||
sysMCAST_UNBLOCK_SOURCE = C.MCAST_UNBLOCK_SOURCE
|
|
||||||
sysMCAST_MSFILTER = C.MCAST_MSFILTER
|
|
||||||
sysIPV6_ROUTER_ALERT = C.IPV6_ROUTER_ALERT
|
|
||||||
sysIPV6_MTU_DISCOVER = C.IPV6_MTU_DISCOVER
|
|
||||||
sysIPV6_MTU = C.IPV6_MTU
|
|
||||||
sysIPV6_RECVERR = C.IPV6_RECVERR
|
|
||||||
sysIPV6_V6ONLY = C.IPV6_V6ONLY
|
|
||||||
sysIPV6_JOIN_ANYCAST = C.IPV6_JOIN_ANYCAST
|
|
||||||
sysIPV6_LEAVE_ANYCAST = C.IPV6_LEAVE_ANYCAST
|
|
||||||
|
|
||||||
//sysIPV6_PMTUDISC_DONT = C.IPV6_PMTUDISC_DONT
|
|
||||||
//sysIPV6_PMTUDISC_WANT = C.IPV6_PMTUDISC_WANT
|
|
||||||
//sysIPV6_PMTUDISC_DO = C.IPV6_PMTUDISC_DO
|
|
||||||
//sysIPV6_PMTUDISC_PROBE = C.IPV6_PMTUDISC_PROBE
|
|
||||||
//sysIPV6_PMTUDISC_INTERFACE = C.IPV6_PMTUDISC_INTERFACE
|
|
||||||
//sysIPV6_PMTUDISC_OMIT = C.IPV6_PMTUDISC_OMIT
|
|
||||||
|
|
||||||
sysIPV6_FLOWLABEL_MGR = C.IPV6_FLOWLABEL_MGR
|
|
||||||
sysIPV6_FLOWINFO_SEND = C.IPV6_FLOWINFO_SEND
|
|
||||||
|
|
||||||
sysIPV6_IPSEC_POLICY = C.IPV6_IPSEC_POLICY
|
|
||||||
sysIPV6_XFRM_POLICY = C.IPV6_XFRM_POLICY
|
|
||||||
|
|
||||||
sysIPV6_RECVPKTINFO = C.IPV6_RECVPKTINFO
|
|
||||||
sysIPV6_PKTINFO = C.IPV6_PKTINFO
|
|
||||||
sysIPV6_RECVHOPLIMIT = C.IPV6_RECVHOPLIMIT
|
|
||||||
sysIPV6_HOPLIMIT = C.IPV6_HOPLIMIT
|
|
||||||
sysIPV6_RECVHOPOPTS = C.IPV6_RECVHOPOPTS
|
|
||||||
sysIPV6_HOPOPTS = C.IPV6_HOPOPTS
|
|
||||||
sysIPV6_RTHDRDSTOPTS = C.IPV6_RTHDRDSTOPTS
|
|
||||||
sysIPV6_RECVRTHDR = C.IPV6_RECVRTHDR
|
|
||||||
sysIPV6_RTHDR = C.IPV6_RTHDR
|
|
||||||
sysIPV6_RECVDSTOPTS = C.IPV6_RECVDSTOPTS
|
|
||||||
sysIPV6_DSTOPTS = C.IPV6_DSTOPTS
|
|
||||||
sysIPV6_RECVPATHMTU = C.IPV6_RECVPATHMTU
|
|
||||||
sysIPV6_PATHMTU = C.IPV6_PATHMTU
|
|
||||||
sysIPV6_DONTFRAG = C.IPV6_DONTFRAG
|
|
||||||
|
|
||||||
sysIPV6_RECVTCLASS = C.IPV6_RECVTCLASS
|
|
||||||
sysIPV6_TCLASS = C.IPV6_TCLASS
|
|
||||||
|
|
||||||
sysIPV6_ADDR_PREFERENCES = C.IPV6_ADDR_PREFERENCES
|
|
||||||
|
|
||||||
sysIPV6_PREFER_SRC_TMP = C.IPV6_PREFER_SRC_TMP
|
|
||||||
sysIPV6_PREFER_SRC_PUBLIC = C.IPV6_PREFER_SRC_PUBLIC
|
|
||||||
sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = C.IPV6_PREFER_SRC_PUBTMP_DEFAULT
|
|
||||||
sysIPV6_PREFER_SRC_COA = C.IPV6_PREFER_SRC_COA
|
|
||||||
sysIPV6_PREFER_SRC_HOME = C.IPV6_PREFER_SRC_HOME
|
|
||||||
sysIPV6_PREFER_SRC_CGA = C.IPV6_PREFER_SRC_CGA
|
|
||||||
sysIPV6_PREFER_SRC_NONCGA = C.IPV6_PREFER_SRC_NONCGA
|
|
||||||
|
|
||||||
sysIPV6_MINHOPCOUNT = C.IPV6_MINHOPCOUNT
|
|
||||||
|
|
||||||
sysIPV6_ORIGDSTADDR = C.IPV6_ORIGDSTADDR
|
|
||||||
sysIPV6_RECVORIGDSTADDR = C.IPV6_RECVORIGDSTADDR
|
|
||||||
sysIPV6_TRANSPARENT = C.IPV6_TRANSPARENT
|
|
||||||
sysIPV6_UNICAST_IF = C.IPV6_UNICAST_IF
|
|
||||||
|
|
||||||
sysICMPV6_FILTER = C.ICMPV6_FILTER
|
|
||||||
|
|
||||||
sysICMPV6_FILTER_BLOCK = C.ICMPV6_FILTER_BLOCK
|
|
||||||
sysICMPV6_FILTER_PASS = C.ICMPV6_FILTER_PASS
|
|
||||||
sysICMPV6_FILTER_BLOCKOTHERS = C.ICMPV6_FILTER_BLOCKOTHERS
|
|
||||||
sysICMPV6_FILTER_PASSONLY = C.ICMPV6_FILTER_PASSONLY
|
|
||||||
|
|
||||||
sysSizeofKernelSockaddrStorage = C.sizeof_struct___kernel_sockaddr_storage
|
|
||||||
sysSizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
|
|
||||||
sysSizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo
|
|
||||||
sysSizeofIPv6Mtuinfo = C.sizeof_struct_ip6_mtuinfo
|
|
||||||
sysSizeofIPv6FlowlabelReq = C.sizeof_struct_in6_flowlabel_req
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
|
|
||||||
sysSizeofGroupReq = C.sizeof_struct_group_req
|
|
||||||
sysSizeofGroupSourceReq = C.sizeof_struct_group_source_req
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysKernelSockaddrStorage C.struct___kernel_sockaddr_storage
|
|
||||||
|
|
||||||
type sysSockaddrInet6 C.struct_sockaddr_in6
|
|
||||||
|
|
||||||
type sysInet6Pktinfo C.struct_in6_pktinfo
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo C.struct_ip6_mtuinfo
|
|
||||||
|
|
||||||
type sysIPv6FlowlabelReq C.struct_in6_flowlabel_req
|
|
||||||
|
|
||||||
type sysIPv6Mreq C.struct_ipv6_mreq
|
|
||||||
|
|
||||||
type sysGroupReq C.struct_group_req
|
|
||||||
|
|
||||||
type sysGroupSourceReq C.struct_group_source_req
|
|
||||||
|
|
||||||
type sysICMPv6Filter C.struct_icmp6_filter
|
|
||||||
-80
@@ -1,80 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
// +godefs map struct_in6_addr [16]byte /* in6_addr */
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <netinet/icmp6.h>
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_UNICAST_HOPS = C.IPV6_UNICAST_HOPS
|
|
||||||
sysIPV6_MULTICAST_IF = C.IPV6_MULTICAST_IF
|
|
||||||
sysIPV6_MULTICAST_HOPS = C.IPV6_MULTICAST_HOPS
|
|
||||||
sysIPV6_MULTICAST_LOOP = C.IPV6_MULTICAST_LOOP
|
|
||||||
sysIPV6_JOIN_GROUP = C.IPV6_JOIN_GROUP
|
|
||||||
sysIPV6_LEAVE_GROUP = C.IPV6_LEAVE_GROUP
|
|
||||||
sysIPV6_PORTRANGE = C.IPV6_PORTRANGE
|
|
||||||
sysICMP6_FILTER = C.ICMP6_FILTER
|
|
||||||
|
|
||||||
sysIPV6_CHECKSUM = C.IPV6_CHECKSUM
|
|
||||||
sysIPV6_V6ONLY = C.IPV6_V6ONLY
|
|
||||||
|
|
||||||
sysIPV6_IPSEC_POLICY = C.IPV6_IPSEC_POLICY
|
|
||||||
|
|
||||||
sysIPV6_RTHDRDSTOPTS = C.IPV6_RTHDRDSTOPTS
|
|
||||||
|
|
||||||
sysIPV6_RECVPKTINFO = C.IPV6_RECVPKTINFO
|
|
||||||
sysIPV6_RECVHOPLIMIT = C.IPV6_RECVHOPLIMIT
|
|
||||||
sysIPV6_RECVRTHDR = C.IPV6_RECVRTHDR
|
|
||||||
sysIPV6_RECVHOPOPTS = C.IPV6_RECVHOPOPTS
|
|
||||||
sysIPV6_RECVDSTOPTS = C.IPV6_RECVDSTOPTS
|
|
||||||
|
|
||||||
sysIPV6_USE_MIN_MTU = C.IPV6_USE_MIN_MTU
|
|
||||||
sysIPV6_RECVPATHMTU = C.IPV6_RECVPATHMTU
|
|
||||||
sysIPV6_PATHMTU = C.IPV6_PATHMTU
|
|
||||||
|
|
||||||
sysIPV6_PKTINFO = C.IPV6_PKTINFO
|
|
||||||
sysIPV6_HOPLIMIT = C.IPV6_HOPLIMIT
|
|
||||||
sysIPV6_NEXTHOP = C.IPV6_NEXTHOP
|
|
||||||
sysIPV6_HOPOPTS = C.IPV6_HOPOPTS
|
|
||||||
sysIPV6_DSTOPTS = C.IPV6_DSTOPTS
|
|
||||||
sysIPV6_RTHDR = C.IPV6_RTHDR
|
|
||||||
|
|
||||||
sysIPV6_RECVTCLASS = C.IPV6_RECVTCLASS
|
|
||||||
|
|
||||||
sysIPV6_TCLASS = C.IPV6_TCLASS
|
|
||||||
sysIPV6_DONTFRAG = C.IPV6_DONTFRAG
|
|
||||||
|
|
||||||
sysIPV6_PORTRANGE_DEFAULT = C.IPV6_PORTRANGE_DEFAULT
|
|
||||||
sysIPV6_PORTRANGE_HIGH = C.IPV6_PORTRANGE_HIGH
|
|
||||||
sysIPV6_PORTRANGE_LOW = C.IPV6_PORTRANGE_LOW
|
|
||||||
|
|
||||||
sysSizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
|
|
||||||
sysSizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo
|
|
||||||
sysSizeofIPv6Mtuinfo = C.sizeof_struct_ip6_mtuinfo
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysSockaddrInet6 C.struct_sockaddr_in6
|
|
||||||
|
|
||||||
type sysInet6Pktinfo C.struct_in6_pktinfo
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo C.struct_ip6_mtuinfo
|
|
||||||
|
|
||||||
type sysIPv6Mreq C.struct_ipv6_mreq
|
|
||||||
|
|
||||||
type sysICMPv6Filter C.struct_icmp6_filter
|
|
||||||
-89
@@ -1,89 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
// +godefs map struct_in6_addr [16]byte /* in6_addr */
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <netinet/icmp6.h>
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_UNICAST_HOPS = C.IPV6_UNICAST_HOPS
|
|
||||||
sysIPV6_MULTICAST_IF = C.IPV6_MULTICAST_IF
|
|
||||||
sysIPV6_MULTICAST_HOPS = C.IPV6_MULTICAST_HOPS
|
|
||||||
sysIPV6_MULTICAST_LOOP = C.IPV6_MULTICAST_LOOP
|
|
||||||
sysIPV6_JOIN_GROUP = C.IPV6_JOIN_GROUP
|
|
||||||
sysIPV6_LEAVE_GROUP = C.IPV6_LEAVE_GROUP
|
|
||||||
sysIPV6_PORTRANGE = C.IPV6_PORTRANGE
|
|
||||||
sysICMP6_FILTER = C.ICMP6_FILTER
|
|
||||||
|
|
||||||
sysIPV6_CHECKSUM = C.IPV6_CHECKSUM
|
|
||||||
sysIPV6_V6ONLY = C.IPV6_V6ONLY
|
|
||||||
|
|
||||||
sysIPV6_RTHDRDSTOPTS = C.IPV6_RTHDRDSTOPTS
|
|
||||||
|
|
||||||
sysIPV6_RECVPKTINFO = C.IPV6_RECVPKTINFO
|
|
||||||
sysIPV6_RECVHOPLIMIT = C.IPV6_RECVHOPLIMIT
|
|
||||||
sysIPV6_RECVRTHDR = C.IPV6_RECVRTHDR
|
|
||||||
sysIPV6_RECVHOPOPTS = C.IPV6_RECVHOPOPTS
|
|
||||||
sysIPV6_RECVDSTOPTS = C.IPV6_RECVDSTOPTS
|
|
||||||
|
|
||||||
sysIPV6_USE_MIN_MTU = C.IPV6_USE_MIN_MTU
|
|
||||||
sysIPV6_RECVPATHMTU = C.IPV6_RECVPATHMTU
|
|
||||||
|
|
||||||
sysIPV6_PATHMTU = C.IPV6_PATHMTU
|
|
||||||
|
|
||||||
sysIPV6_PKTINFO = C.IPV6_PKTINFO
|
|
||||||
sysIPV6_HOPLIMIT = C.IPV6_HOPLIMIT
|
|
||||||
sysIPV6_NEXTHOP = C.IPV6_NEXTHOP
|
|
||||||
sysIPV6_HOPOPTS = C.IPV6_HOPOPTS
|
|
||||||
sysIPV6_DSTOPTS = C.IPV6_DSTOPTS
|
|
||||||
sysIPV6_RTHDR = C.IPV6_RTHDR
|
|
||||||
|
|
||||||
sysIPV6_AUTH_LEVEL = C.IPV6_AUTH_LEVEL
|
|
||||||
sysIPV6_ESP_TRANS_LEVEL = C.IPV6_ESP_TRANS_LEVEL
|
|
||||||
sysIPV6_ESP_NETWORK_LEVEL = C.IPV6_ESP_NETWORK_LEVEL
|
|
||||||
sysIPSEC6_OUTSA = C.IPSEC6_OUTSA
|
|
||||||
sysIPV6_RECVTCLASS = C.IPV6_RECVTCLASS
|
|
||||||
|
|
||||||
sysIPV6_AUTOFLOWLABEL = C.IPV6_AUTOFLOWLABEL
|
|
||||||
sysIPV6_IPCOMP_LEVEL = C.IPV6_IPCOMP_LEVEL
|
|
||||||
|
|
||||||
sysIPV6_TCLASS = C.IPV6_TCLASS
|
|
||||||
sysIPV6_DONTFRAG = C.IPV6_DONTFRAG
|
|
||||||
sysIPV6_PIPEX = C.IPV6_PIPEX
|
|
||||||
|
|
||||||
sysIPV6_RTABLE = C.IPV6_RTABLE
|
|
||||||
|
|
||||||
sysIPV6_PORTRANGE_DEFAULT = C.IPV6_PORTRANGE_DEFAULT
|
|
||||||
sysIPV6_PORTRANGE_HIGH = C.IPV6_PORTRANGE_HIGH
|
|
||||||
sysIPV6_PORTRANGE_LOW = C.IPV6_PORTRANGE_LOW
|
|
||||||
|
|
||||||
sysSizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
|
|
||||||
sysSizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo
|
|
||||||
sysSizeofIPv6Mtuinfo = C.sizeof_struct_ip6_mtuinfo
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysSockaddrInet6 C.struct_sockaddr_in6
|
|
||||||
|
|
||||||
type sysInet6Pktinfo C.struct_in6_pktinfo
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo C.struct_ip6_mtuinfo
|
|
||||||
|
|
||||||
type sysIPv6Mreq C.struct_ipv6_mreq
|
|
||||||
|
|
||||||
type sysICMPv6Filter C.struct_icmp6_filter
|
|
||||||
-96
@@ -1,96 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
// +godefs map struct_in6_addr [16]byte /* in6_addr */
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <netinet/icmp6.h>
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_UNICAST_HOPS = C.IPV6_UNICAST_HOPS
|
|
||||||
sysIPV6_MULTICAST_IF = C.IPV6_MULTICAST_IF
|
|
||||||
sysIPV6_MULTICAST_HOPS = C.IPV6_MULTICAST_HOPS
|
|
||||||
sysIPV6_MULTICAST_LOOP = C.IPV6_MULTICAST_LOOP
|
|
||||||
sysIPV6_JOIN_GROUP = C.IPV6_JOIN_GROUP
|
|
||||||
sysIPV6_LEAVE_GROUP = C.IPV6_LEAVE_GROUP
|
|
||||||
|
|
||||||
sysIPV6_PKTINFO = C.IPV6_PKTINFO
|
|
||||||
|
|
||||||
sysIPV6_HOPLIMIT = C.IPV6_HOPLIMIT
|
|
||||||
sysIPV6_NEXTHOP = C.IPV6_NEXTHOP
|
|
||||||
sysIPV6_HOPOPTS = C.IPV6_HOPOPTS
|
|
||||||
sysIPV6_DSTOPTS = C.IPV6_DSTOPTS
|
|
||||||
|
|
||||||
sysIPV6_RTHDR = C.IPV6_RTHDR
|
|
||||||
sysIPV6_RTHDRDSTOPTS = C.IPV6_RTHDRDSTOPTS
|
|
||||||
|
|
||||||
sysIPV6_RECVPKTINFO = C.IPV6_RECVPKTINFO
|
|
||||||
sysIPV6_RECVHOPLIMIT = C.IPV6_RECVHOPLIMIT
|
|
||||||
sysIPV6_RECVHOPOPTS = C.IPV6_RECVHOPOPTS
|
|
||||||
|
|
||||||
sysIPV6_RECVRTHDR = C.IPV6_RECVRTHDR
|
|
||||||
|
|
||||||
sysIPV6_RECVRTHDRDSTOPTS = C.IPV6_RECVRTHDRDSTOPTS
|
|
||||||
|
|
||||||
sysIPV6_CHECKSUM = C.IPV6_CHECKSUM
|
|
||||||
sysIPV6_RECVTCLASS = C.IPV6_RECVTCLASS
|
|
||||||
sysIPV6_USE_MIN_MTU = C.IPV6_USE_MIN_MTU
|
|
||||||
sysIPV6_DONTFRAG = C.IPV6_DONTFRAG
|
|
||||||
sysIPV6_SEC_OPT = C.IPV6_SEC_OPT
|
|
||||||
sysIPV6_SRC_PREFERENCES = C.IPV6_SRC_PREFERENCES
|
|
||||||
sysIPV6_RECVPATHMTU = C.IPV6_RECVPATHMTU
|
|
||||||
sysIPV6_PATHMTU = C.IPV6_PATHMTU
|
|
||||||
sysIPV6_TCLASS = C.IPV6_TCLASS
|
|
||||||
sysIPV6_V6ONLY = C.IPV6_V6ONLY
|
|
||||||
|
|
||||||
sysIPV6_RECVDSTOPTS = C.IPV6_RECVDSTOPTS
|
|
||||||
|
|
||||||
sysIPV6_PREFER_SRC_HOME = C.IPV6_PREFER_SRC_HOME
|
|
||||||
sysIPV6_PREFER_SRC_COA = C.IPV6_PREFER_SRC_COA
|
|
||||||
sysIPV6_PREFER_SRC_PUBLIC = C.IPV6_PREFER_SRC_PUBLIC
|
|
||||||
sysIPV6_PREFER_SRC_TMP = C.IPV6_PREFER_SRC_TMP
|
|
||||||
sysIPV6_PREFER_SRC_NONCGA = C.IPV6_PREFER_SRC_NONCGA
|
|
||||||
sysIPV6_PREFER_SRC_CGA = C.IPV6_PREFER_SRC_CGA
|
|
||||||
|
|
||||||
sysIPV6_PREFER_SRC_MIPMASK = C.IPV6_PREFER_SRC_MIPMASK
|
|
||||||
sysIPV6_PREFER_SRC_MIPDEFAULT = C.IPV6_PREFER_SRC_MIPDEFAULT
|
|
||||||
sysIPV6_PREFER_SRC_TMPMASK = C.IPV6_PREFER_SRC_TMPMASK
|
|
||||||
sysIPV6_PREFER_SRC_TMPDEFAULT = C.IPV6_PREFER_SRC_TMPDEFAULT
|
|
||||||
sysIPV6_PREFER_SRC_CGAMASK = C.IPV6_PREFER_SRC_CGAMASK
|
|
||||||
sysIPV6_PREFER_SRC_CGADEFAULT = C.IPV6_PREFER_SRC_CGADEFAULT
|
|
||||||
|
|
||||||
sysIPV6_PREFER_SRC_MASK = C.IPV6_PREFER_SRC_MASK
|
|
||||||
|
|
||||||
sysIPV6_PREFER_SRC_DEFAULT = C.IPV6_PREFER_SRC_DEFAULT
|
|
||||||
|
|
||||||
sysIPV6_BOUND_IF = C.IPV6_BOUND_IF
|
|
||||||
sysIPV6_UNSPEC_SRC = C.IPV6_UNSPEC_SRC
|
|
||||||
|
|
||||||
sysICMP6_FILTER = C.ICMP6_FILTER
|
|
||||||
|
|
||||||
sysSizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
|
|
||||||
sysSizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo
|
|
||||||
sysSizeofIPv6Mtuinfo = C.sizeof_struct_ip6_mtuinfo
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysSockaddrInet6 C.struct_sockaddr_in6
|
|
||||||
|
|
||||||
type sysInet6Pktinfo C.struct_in6_pktinfo
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo C.struct_ip6_mtuinfo
|
|
||||||
|
|
||||||
type sysIPv6Mreq C.struct_ipv6_mreq
|
|
||||||
|
|
||||||
type sysICMPv6Filter C.struct_icmp6_filter
|
|
||||||
-288
@@ -1,288 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build darwin dragonfly freebsd linux netbsd openbsd windows
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MulticastHopLimit returns the hop limit field value for outgoing
|
|
||||||
// multicast packets.
|
|
||||||
func (c *dgramOpt) MulticastHopLimit() (int, error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return 0, syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return getInt(fd, &sockOpts[ssoMulticastHopLimit])
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetMulticastHopLimit sets the hop limit field value for future
|
|
||||||
// outgoing multicast packets.
|
|
||||||
func (c *dgramOpt) SetMulticastHopLimit(hoplim int) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return setInt(fd, &sockOpts[ssoMulticastHopLimit], hoplim)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MulticastInterface returns the default interface for multicast
|
|
||||||
// packet transmissions.
|
|
||||||
func (c *dgramOpt) MulticastInterface() (*net.Interface, error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return nil, syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return getInterface(fd, &sockOpts[ssoMulticastInterface])
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetMulticastInterface sets the default interface for future
|
|
||||||
// multicast packet transmissions.
|
|
||||||
func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return setInterface(fd, &sockOpts[ssoMulticastInterface], ifi)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MulticastLoopback reports whether transmitted multicast packets
|
|
||||||
// should be copied and send back to the originator.
|
|
||||||
func (c *dgramOpt) MulticastLoopback() (bool, error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return false, syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
on, err := getInt(fd, &sockOpts[ssoMulticastLoopback])
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return on == 1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetMulticastLoopback sets whether transmitted multicast packets
|
|
||||||
// should be copied and send back to the originator.
|
|
||||||
func (c *dgramOpt) SetMulticastLoopback(on bool) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return setInt(fd, &sockOpts[ssoMulticastLoopback], boolint(on))
|
|
||||||
}
|
|
||||||
|
|
||||||
// JoinGroup joins the group address group on the interface ifi.
|
|
||||||
// By default all sources that can cast data to group are accepted.
|
|
||||||
// It's possible to mute and unmute data transmission from a specific
|
|
||||||
// source by using ExcludeSourceSpecificGroup and
|
|
||||||
// IncludeSourceSpecificGroup.
|
|
||||||
// JoinGroup uses the system assigned multicast interface when ifi is
|
|
||||||
// nil, although this is not recommended because the assignment
|
|
||||||
// depends on platforms and sometimes it might require routing
|
|
||||||
// configuration.
|
|
||||||
func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
grp := netAddrToIP16(group)
|
|
||||||
if grp == nil {
|
|
||||||
return errMissingAddress
|
|
||||||
}
|
|
||||||
return setGroup(fd, &sockOpts[ssoJoinGroup], ifi, grp)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LeaveGroup leaves the group address group on the interface ifi
|
|
||||||
// regardless of whether the group is any-source group or
|
|
||||||
// source-specific group.
|
|
||||||
func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
grp := netAddrToIP16(group)
|
|
||||||
if grp == nil {
|
|
||||||
return errMissingAddress
|
|
||||||
}
|
|
||||||
return setGroup(fd, &sockOpts[ssoLeaveGroup], ifi, grp)
|
|
||||||
}
|
|
||||||
|
|
||||||
// JoinSourceSpecificGroup joins the source-specific group comprising
|
|
||||||
// group and source on the interface ifi.
|
|
||||||
// JoinSourceSpecificGroup uses the system assigned multicast
|
|
||||||
// interface when ifi is nil, although this is not recommended because
|
|
||||||
// the assignment depends on platforms and sometimes it might require
|
|
||||||
// routing configuration.
|
|
||||||
func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
grp := netAddrToIP16(group)
|
|
||||||
if grp == nil {
|
|
||||||
return errMissingAddress
|
|
||||||
}
|
|
||||||
src := netAddrToIP16(source)
|
|
||||||
if src == nil {
|
|
||||||
return errMissingAddress
|
|
||||||
}
|
|
||||||
return setSourceGroup(fd, &sockOpts[ssoJoinSourceGroup], ifi, grp, src)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LeaveSourceSpecificGroup leaves the source-specific group on the
|
|
||||||
// interface ifi.
|
|
||||||
func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
grp := netAddrToIP16(group)
|
|
||||||
if grp == nil {
|
|
||||||
return errMissingAddress
|
|
||||||
}
|
|
||||||
src := netAddrToIP16(source)
|
|
||||||
if src == nil {
|
|
||||||
return errMissingAddress
|
|
||||||
}
|
|
||||||
return setSourceGroup(fd, &sockOpts[ssoLeaveSourceGroup], ifi, grp, src)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExcludeSourceSpecificGroup excludes the source-specific group from
|
|
||||||
// the already joined any-source groups by JoinGroup on the interface
|
|
||||||
// ifi.
|
|
||||||
func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
grp := netAddrToIP16(group)
|
|
||||||
if grp == nil {
|
|
||||||
return errMissingAddress
|
|
||||||
}
|
|
||||||
src := netAddrToIP16(source)
|
|
||||||
if src == nil {
|
|
||||||
return errMissingAddress
|
|
||||||
}
|
|
||||||
return setSourceGroup(fd, &sockOpts[ssoBlockSourceGroup], ifi, grp, src)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IncludeSourceSpecificGroup includes the excluded source-specific
|
|
||||||
// group by ExcludeSourceSpecificGroup again on the interface ifi.
|
|
||||||
func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
grp := netAddrToIP16(group)
|
|
||||||
if grp == nil {
|
|
||||||
return errMissingAddress
|
|
||||||
}
|
|
||||||
src := netAddrToIP16(source)
|
|
||||||
if src == nil {
|
|
||||||
return errMissingAddress
|
|
||||||
}
|
|
||||||
return setSourceGroup(fd, &sockOpts[ssoUnblockSourceGroup], ifi, grp, src)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checksum reports whether the kernel will compute, store or verify a
|
|
||||||
// checksum for both incoming and outgoing packets. If on is true, it
|
|
||||||
// returns an offset in bytes into the data of where the checksum
|
|
||||||
// field is located.
|
|
||||||
func (c *dgramOpt) Checksum() (on bool, offset int, err error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return false, 0, syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return false, 0, err
|
|
||||||
}
|
|
||||||
offset, err = getInt(fd, &sockOpts[ssoChecksum])
|
|
||||||
if err != nil {
|
|
||||||
return false, 0, err
|
|
||||||
}
|
|
||||||
if offset < 0 {
|
|
||||||
return false, 0, nil
|
|
||||||
}
|
|
||||||
return true, offset, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetChecksum enables the kernel checksum processing. If on is ture,
|
|
||||||
// the offset should be an offset in bytes into the data of where the
|
|
||||||
// checksum field is located.
|
|
||||||
func (c *dgramOpt) SetChecksum(on bool, offset int) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !on {
|
|
||||||
offset = -1
|
|
||||||
}
|
|
||||||
return setInt(fd, &sockOpts[ssoChecksum], offset)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ICMPFilter returns an ICMP filter.
|
|
||||||
func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return nil, syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return getICMPFilter(fd, &sockOpts[ssoICMPFilter])
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetICMPFilter deploys the ICMP filter.
|
|
||||||
func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return setICMPFilter(fd, &sockOpts[ssoICMPFilter], f)
|
|
||||||
}
|
|
||||||
-119
@@ -1,119 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build nacl plan9 solaris
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import "net"
|
|
||||||
|
|
||||||
// MulticastHopLimit returns the hop limit field value for outgoing
|
|
||||||
// multicast packets.
|
|
||||||
func (c *dgramOpt) MulticastHopLimit() (int, error) {
|
|
||||||
return 0, errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetMulticastHopLimit sets the hop limit field value for future
|
|
||||||
// outgoing multicast packets.
|
|
||||||
func (c *dgramOpt) SetMulticastHopLimit(hoplim int) error {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// MulticastInterface returns the default interface for multicast
|
|
||||||
// packet transmissions.
|
|
||||||
func (c *dgramOpt) MulticastInterface() (*net.Interface, error) {
|
|
||||||
return nil, errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetMulticastInterface sets the default interface for future
|
|
||||||
// multicast packet transmissions.
|
|
||||||
func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// MulticastLoopback reports whether transmitted multicast packets
|
|
||||||
// should be copied and send back to the originator.
|
|
||||||
func (c *dgramOpt) MulticastLoopback() (bool, error) {
|
|
||||||
return false, errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetMulticastLoopback sets whether transmitted multicast packets
|
|
||||||
// should be copied and send back to the originator.
|
|
||||||
func (c *dgramOpt) SetMulticastLoopback(on bool) error {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// JoinGroup joins the group address group on the interface ifi.
|
|
||||||
// By default all sources that can cast data to group are accepted.
|
|
||||||
// It's possible to mute and unmute data transmission from a specific
|
|
||||||
// source by using ExcludeSourceSpecificGroup and
|
|
||||||
// IncludeSourceSpecificGroup.
|
|
||||||
// JoinGroup uses the system assigned multicast interface when ifi is
|
|
||||||
// nil, although this is not recommended because the assignment
|
|
||||||
// depends on platforms and sometimes it might require routing
|
|
||||||
// configuration.
|
|
||||||
func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// LeaveGroup leaves the group address group on the interface ifi
|
|
||||||
// regardless of whether the group is any-source group or
|
|
||||||
// source-specific group.
|
|
||||||
func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// JoinSourceSpecificGroup joins the source-specific group comprising
|
|
||||||
// group and source on the interface ifi.
|
|
||||||
// JoinSourceSpecificGroup uses the system assigned multicast
|
|
||||||
// interface when ifi is nil, although this is not recommended because
|
|
||||||
// the assignment depends on platforms and sometimes it might require
|
|
||||||
// routing configuration.
|
|
||||||
func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// LeaveSourceSpecificGroup leaves the source-specific group on the
|
|
||||||
// interface ifi.
|
|
||||||
func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExcludeSourceSpecificGroup excludes the source-specific group from
|
|
||||||
// the already joined any-source groups by JoinGroup on the interface
|
|
||||||
// ifi.
|
|
||||||
func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// IncludeSourceSpecificGroup includes the excluded source-specific
|
|
||||||
// group by ExcludeSourceSpecificGroup again on the interface ifi.
|
|
||||||
func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checksum reports whether the kernel will compute, store or verify a
|
|
||||||
// checksum for both incoming and outgoing packets. If on is true, it
|
|
||||||
// returns an offset in bytes into the data of where the checksum
|
|
||||||
// field is located.
|
|
||||||
func (c *dgramOpt) Checksum() (on bool, offset int, err error) {
|
|
||||||
return false, 0, errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetChecksum enables the kernel checksum processing. If on is ture,
|
|
||||||
// the offset should be an offset in bytes into the data of where the
|
|
||||||
// checksum field is located.
|
|
||||||
func (c *dgramOpt) SetChecksum(on bool, offset int) error {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// ICMPFilter returns an ICMP filter.
|
|
||||||
func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) {
|
|
||||||
return nil, errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetICMPFilter deploys the ICMP filter.
|
|
||||||
func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
-240
@@ -1,240 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package ipv6 implements IP-level socket options for the Internet
|
|
||||||
// Protocol version 6.
|
|
||||||
//
|
|
||||||
// The package provides IP-level socket options that allow
|
|
||||||
// manipulation of IPv6 facilities.
|
|
||||||
//
|
|
||||||
// The IPv6 protocol is defined in RFC 2460.
|
|
||||||
// Basic and advanced socket interface extensions are defined in RFC
|
|
||||||
// 3493 and RFC 3542.
|
|
||||||
// Socket interface extensions for multicast source filters are
|
|
||||||
// defined in RFC 3678.
|
|
||||||
// MLDv1 and MLDv2 are defined in RFC 2710 and RFC 3810.
|
|
||||||
// Source-specific multicast is defined in RFC 4607.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Unicasting
|
|
||||||
//
|
|
||||||
// The options for unicasting are available for net.TCPConn,
|
|
||||||
// net.UDPConn and net.IPConn which are created as network connections
|
|
||||||
// that use the IPv6 transport. When a single TCP connection carrying
|
|
||||||
// a data flow of multiple packets needs to indicate the flow is
|
|
||||||
// important, ipv6.Conn is used to set the traffic class field on the
|
|
||||||
// IPv6 header for each packet.
|
|
||||||
//
|
|
||||||
// ln, err := net.Listen("tcp6", "[::]:1024")
|
|
||||||
// if err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// defer ln.Close()
|
|
||||||
// for {
|
|
||||||
// c, err := ln.Accept()
|
|
||||||
// if err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// go func(c net.Conn) {
|
|
||||||
// defer c.Close()
|
|
||||||
//
|
|
||||||
// The outgoing packets will be labeled DiffServ assured forwarding
|
|
||||||
// class 1 low drop precedence, known as AF11 packets.
|
|
||||||
//
|
|
||||||
// if err := ipv6.NewConn(c).SetTrafficClass(DiffServAF11); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// if _, err := c.Write(data); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// }(c)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Multicasting
|
|
||||||
//
|
|
||||||
// The options for multicasting are available for net.UDPConn and
|
|
||||||
// net.IPconn which are created as network connections that use the
|
|
||||||
// IPv6 transport. A few network facilities must be prepared before
|
|
||||||
// you begin multicasting, at a minimum joining network interfaces and
|
|
||||||
// multicast groups.
|
|
||||||
//
|
|
||||||
// en0, err := net.InterfaceByName("en0")
|
|
||||||
// if err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// en1, err := net.InterfaceByIndex(911)
|
|
||||||
// if err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// group := net.ParseIP("ff02::114")
|
|
||||||
//
|
|
||||||
// First, an application listens to an appropriate address with an
|
|
||||||
// appropriate service port.
|
|
||||||
//
|
|
||||||
// c, err := net.ListenPacket("udp6", "[::]:1024")
|
|
||||||
// if err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// defer c.Close()
|
|
||||||
//
|
|
||||||
// Second, the application joins multicast groups, starts listening to
|
|
||||||
// the groups on the specified network interfaces. Note that the
|
|
||||||
// service port for transport layer protocol does not matter with this
|
|
||||||
// operation as joining groups affects only network and link layer
|
|
||||||
// protocols, such as IPv6 and Ethernet.
|
|
||||||
//
|
|
||||||
// p := ipv6.NewPacketConn(c)
|
|
||||||
// if err := p.JoinGroup(en0, &net.UDPAddr{IP: group}); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// if err := p.JoinGroup(en1, &net.UDPAddr{IP: group}); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// The application might set per packet control message transmissions
|
|
||||||
// between the protocol stack within the kernel. When the application
|
|
||||||
// needs a destination address on an incoming packet,
|
|
||||||
// SetControlMessage of ipv6.PacketConn is used to enable control
|
|
||||||
// message transmissons.
|
|
||||||
//
|
|
||||||
// if err := p.SetControlMessage(ipv6.FlagDst, true); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// The application could identify whether the received packets are
|
|
||||||
// of interest by using the control message that contains the
|
|
||||||
// destination address of the received packet.
|
|
||||||
//
|
|
||||||
// b := make([]byte, 1500)
|
|
||||||
// for {
|
|
||||||
// n, rcm, src, err := p.ReadFrom(b)
|
|
||||||
// if err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// if rcm.Dst.IsMulticast() {
|
|
||||||
// if rcm.Dst.Equal(group) {
|
|
||||||
// // joined group, do something
|
|
||||||
// } else {
|
|
||||||
// // unknown group, discard
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// The application can also send both unicast and multicast packets.
|
|
||||||
//
|
|
||||||
// p.SetTrafficClass(DiffServCS0)
|
|
||||||
// p.SetHopLimit(16)
|
|
||||||
// if _, err := p.WriteTo(data[:n], nil, src); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// dst := &net.UDPAddr{IP: group, Port: 1024}
|
|
||||||
// wcm := ipv6.ControlMessage{TrafficClass: DiffServCS7, HopLimit: 1}
|
|
||||||
// for _, ifi := range []*net.Interface{en0, en1} {
|
|
||||||
// wcm.IfIndex = ifi.Index
|
|
||||||
// if _, err := p.WriteTo(data[:n], &wcm, dst); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// More multicasting
|
|
||||||
//
|
|
||||||
// An application that uses PacketConn may join multiple multicast
|
|
||||||
// groups. For example, a UDP listener with port 1024 might join two
|
|
||||||
// different groups across over two different network interfaces by
|
|
||||||
// using:
|
|
||||||
//
|
|
||||||
// c, err := net.ListenPacket("udp6", "[::]:1024")
|
|
||||||
// if err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// defer c.Close()
|
|
||||||
// p := ipv6.NewPacketConn(c)
|
|
||||||
// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::1:114")}); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::2:114")}); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// if err := p.JoinGroup(en1, &net.UDPAddr{IP: net.ParseIP("ff02::2:114")}); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// It is possible for multiple UDP listeners that listen on the same
|
|
||||||
// UDP port to join the same multicast group. The net package will
|
|
||||||
// provide a socket that listens to a wildcard address with reusable
|
|
||||||
// UDP port when an appropriate multicast address prefix is passed to
|
|
||||||
// the net.ListenPacket or net.ListenUDP.
|
|
||||||
//
|
|
||||||
// c1, err := net.ListenPacket("udp6", "[ff02::]:1024")
|
|
||||||
// if err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// defer c1.Close()
|
|
||||||
// c2, err := net.ListenPacket("udp6", "[ff02::]:1024")
|
|
||||||
// if err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// defer c2.Close()
|
|
||||||
// p1 := ipv6.NewPacketConn(c1)
|
|
||||||
// if err := p1.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::114")}); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// p2 := ipv6.NewPacketConn(c2)
|
|
||||||
// if err := p2.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::114")}); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Also it is possible for the application to leave or rejoin a
|
|
||||||
// multicast group on the network interface.
|
|
||||||
//
|
|
||||||
// if err := p.LeaveGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::114")}); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff01::114")}); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Source-specific multicasting
|
|
||||||
//
|
|
||||||
// An application that uses PacketConn on MLDv2 supported platform is
|
|
||||||
// able to join source-specific multicast groups.
|
|
||||||
// The application may use JoinSourceSpecificGroup and
|
|
||||||
// LeaveSourceSpecificGroup for the operation known as "include" mode,
|
|
||||||
//
|
|
||||||
// ssmgroup := net.UDPAddr{IP: net.ParseIP("ff32::8000:9")}
|
|
||||||
// ssmsource := net.UDPAddr{IP: net.ParseIP("fe80::cafe")}
|
|
||||||
// if err := p.JoinSourceSpecificGroup(en0, &ssmgroup, &ssmsource); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// if err := p.LeaveSourceSpecificGroup(en0, &ssmgroup, &ssmsource); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// or JoinGroup, ExcludeSourceSpecificGroup,
|
|
||||||
// IncludeSourceSpecificGroup and LeaveGroup for the operation known
|
|
||||||
// as "exclude" mode.
|
|
||||||
//
|
|
||||||
// exclsource := net.UDPAddr{IP: net.ParseIP("fe80::dead")}
|
|
||||||
// if err := p.JoinGroup(en0, &ssmgroup); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// if err := p.ExcludeSourceSpecificGroup(en0, &ssmgroup, &exclsource); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
// if err := p.LeaveGroup(en0, &ssmgroup); err != nil {
|
|
||||||
// // error handling
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Note that it depends on each platform implementation what happens
|
|
||||||
// when an application which runs on MLDv2 unsupported platform uses
|
|
||||||
// JoinSourceSpecificGroup and LeaveSourceSpecificGroup.
|
|
||||||
// In general the platform tries to fall back to conversations using
|
|
||||||
// MLDv1 and starts to listen to multicast traffic.
|
|
||||||
// In the fallback case, ExcludeSourceSpecificGroup and
|
|
||||||
// IncludeSourceSpecificGroup may return an error.
|
|
||||||
package ipv6
|
|
||||||
-123
@@ -1,123 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Conn represents a network endpoint that uses IPv6 transport.
|
|
||||||
// It allows to set basic IP-level socket options such as traffic
|
|
||||||
// class and hop limit.
|
|
||||||
type Conn struct {
|
|
||||||
genericOpt
|
|
||||||
}
|
|
||||||
|
|
||||||
type genericOpt struct {
|
|
||||||
net.Conn
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *genericOpt) ok() bool { return c != nil && c.Conn != nil }
|
|
||||||
|
|
||||||
// PathMTU returns a path MTU value for the destination associated
|
|
||||||
// with the endpoint.
|
|
||||||
func (c *Conn) PathMTU() (int, error) {
|
|
||||||
if !c.genericOpt.ok() {
|
|
||||||
return 0, syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.genericOpt.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
_, mtu, err := getMTUInfo(fd, &sockOpts[ssoPathMTU])
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return mtu, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewConn returns a new Conn.
|
|
||||||
func NewConn(c net.Conn) *Conn {
|
|
||||||
return &Conn{
|
|
||||||
genericOpt: genericOpt{Conn: c},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// A PacketConn represents a packet network endpoint that uses IPv6
|
|
||||||
// transport. It is used to control several IP-level socket options
|
|
||||||
// including IPv6 header manipulation. It also provides datagram
|
|
||||||
// based network I/O methods specific to the IPv6 and higher layer
|
|
||||||
// protocols such as OSPF, GRE, and UDP.
|
|
||||||
type PacketConn struct {
|
|
||||||
genericOpt
|
|
||||||
dgramOpt
|
|
||||||
payloadHandler
|
|
||||||
}
|
|
||||||
|
|
||||||
type dgramOpt struct {
|
|
||||||
net.PacketConn
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *dgramOpt) ok() bool { return c != nil && c.PacketConn != nil }
|
|
||||||
|
|
||||||
// SetControlMessage allows to receive the per packet basis IP-level
|
|
||||||
// socket options.
|
|
||||||
func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error {
|
|
||||||
if !c.payloadHandler.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.payloadHandler.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return setControlMessage(fd, &c.payloadHandler.rawOpt, cf, on)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetDeadline sets the read and write deadlines associated with the
|
|
||||||
// endpoint.
|
|
||||||
func (c *PacketConn) SetDeadline(t time.Time) error {
|
|
||||||
if !c.payloadHandler.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
return c.payloadHandler.SetDeadline(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetReadDeadline sets the read deadline associated with the
|
|
||||||
// endpoint.
|
|
||||||
func (c *PacketConn) SetReadDeadline(t time.Time) error {
|
|
||||||
if !c.payloadHandler.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
return c.payloadHandler.SetReadDeadline(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetWriteDeadline sets the write deadline associated with the
|
|
||||||
// endpoint.
|
|
||||||
func (c *PacketConn) SetWriteDeadline(t time.Time) error {
|
|
||||||
if !c.payloadHandler.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
return c.payloadHandler.SetWriteDeadline(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close closes the endpoint.
|
|
||||||
func (c *PacketConn) Close() error {
|
|
||||||
if !c.payloadHandler.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
return c.payloadHandler.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPacketConn returns a new PacketConn using c as its underlying
|
|
||||||
// transport.
|
|
||||||
func NewPacketConn(c net.PacketConn) *PacketConn {
|
|
||||||
return &PacketConn{
|
|
||||||
genericOpt: genericOpt{Conn: c.(net.Conn)},
|
|
||||||
dgramOpt: dgramOpt{PacketConn: c},
|
|
||||||
payloadHandler: payloadHandler{PacketConn: c},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-214
@@ -1,214 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/net/icmp"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ExampleConn_markingTCP() {
|
|
||||||
ln, err := net.Listen("tcp6", "[::]:1024")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
defer ln.Close()
|
|
||||||
|
|
||||||
for {
|
|
||||||
c, err := ln.Accept()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
go func(c net.Conn) {
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.NewConn(c)
|
|
||||||
if err := p.SetTrafficClass(0x28); err != nil { // DSCP AF11
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := p.SetHopLimit(128); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
if _, err := c.Write([]byte("HELLO-R-U-THERE-ACK")); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}(c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExamplePacketConn_servingOneShotMulticastDNS() {
|
|
||||||
c, err := net.ListenPacket("udp6", "[::]:5353") // mDNS over UDP
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
|
|
||||||
en0, err := net.InterfaceByName("en0")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
mDNSLinkLocal := net.UDPAddr{IP: net.ParseIP("ff02::fb")}
|
|
||||||
if err := p.JoinGroup(en0, &mDNSLinkLocal); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
defer p.LeaveGroup(en0, &mDNSLinkLocal)
|
|
||||||
if err := p.SetControlMessage(ipv6.FlagDst|ipv6.FlagInterface, true); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var wcm ipv6.ControlMessage
|
|
||||||
b := make([]byte, 1500)
|
|
||||||
for {
|
|
||||||
_, rcm, peer, err := p.ReadFrom(b)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
if !rcm.Dst.IsMulticast() || !rcm.Dst.Equal(mDNSLinkLocal.IP) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
wcm.IfIndex = rcm.IfIndex
|
|
||||||
answers := []byte("FAKE-MDNS-ANSWERS") // fake mDNS answers, you need to implement this
|
|
||||||
if _, err := p.WriteTo(answers, &wcm, peer); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExamplePacketConn_tracingIPPacketRoute() {
|
|
||||||
// Tracing an IP packet route to www.google.com.
|
|
||||||
|
|
||||||
const host = "www.google.com"
|
|
||||||
ips, err := net.LookupIP(host)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
var dst net.IPAddr
|
|
||||||
for _, ip := range ips {
|
|
||||||
if ip.To16() != nil && ip.To4() == nil {
|
|
||||||
dst.IP = ip
|
|
||||||
fmt.Printf("using %v for tracing an IP packet route to %s\n", dst.IP, host)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if dst.IP == nil {
|
|
||||||
log.Fatal("no AAAA record found")
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := net.ListenPacket("ip6:58", "::") // ICMP for IPv6
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
|
|
||||||
if err := p.SetControlMessage(ipv6.FlagHopLimit|ipv6.FlagSrc|ipv6.FlagDst|ipv6.FlagInterface, true); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
wm := icmp.Message{
|
|
||||||
Type: ipv6.ICMPTypeEchoRequest, Code: 0,
|
|
||||||
Body: &icmp.Echo{
|
|
||||||
ID: os.Getpid() & 0xffff,
|
|
||||||
Data: []byte("HELLO-R-U-THERE"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
var f ipv6.ICMPFilter
|
|
||||||
f.SetAll(true)
|
|
||||||
f.Accept(ipv6.ICMPTypeTimeExceeded)
|
|
||||||
f.Accept(ipv6.ICMPTypeEchoReply)
|
|
||||||
if err := p.SetICMPFilter(&f); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var wcm ipv6.ControlMessage
|
|
||||||
rb := make([]byte, 1500)
|
|
||||||
for i := 1; i <= 64; i++ { // up to 64 hops
|
|
||||||
wm.Body.(*icmp.Echo).Seq = i
|
|
||||||
wb, err := wm.Marshal(nil)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// In the real world usually there are several
|
|
||||||
// multiple traffic-engineered paths for each hop.
|
|
||||||
// You may need to probe a few times to each hop.
|
|
||||||
begin := time.Now()
|
|
||||||
wcm.HopLimit = i
|
|
||||||
if _, err := p.WriteTo(wb, &wcm, &dst); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := p.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
n, rcm, peer, err := p.ReadFrom(rb)
|
|
||||||
if err != nil {
|
|
||||||
if err, ok := err.(net.Error); ok && err.Timeout() {
|
|
||||||
fmt.Printf("%v\t*\n", i)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
rm, err := icmp.ParseMessage(58, rb[:n])
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
rtt := time.Since(begin)
|
|
||||||
|
|
||||||
// In the real world you need to determine whether the
|
|
||||||
// received message is yours using ControlMessage.Src,
|
|
||||||
// ControlMesage.Dst, icmp.Echo.ID and icmp.Echo.Seq.
|
|
||||||
switch rm.Type {
|
|
||||||
case ipv6.ICMPTypeTimeExceeded:
|
|
||||||
names, _ := net.LookupAddr(peer.String())
|
|
||||||
fmt.Printf("%d\t%v %+v %v\n\t%+v\n", i, peer, names, rtt, rcm)
|
|
||||||
case ipv6.ICMPTypeEchoReply:
|
|
||||||
names, _ := net.LookupAddr(peer.String())
|
|
||||||
fmt.Printf("%d\t%v %+v %v\n\t%+v\n", i, peer, names, rtt, rcm)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExamplePacketConn_advertisingOSPFHello() {
|
|
||||||
c, err := net.ListenPacket("ip6:89", "::") // OSPF for IPv6
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
|
|
||||||
en0, err := net.InterfaceByName("en0")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
allSPFRouters := net.IPAddr{IP: net.ParseIP("ff02::5")}
|
|
||||||
if err := p.JoinGroup(en0, &allSPFRouters); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
defer p.LeaveGroup(en0, &allSPFRouters)
|
|
||||||
|
|
||||||
hello := make([]byte, 24) // fake hello data, you need to implement this
|
|
||||||
ospf := make([]byte, 16) // fake ospf header, you need to implement this
|
|
||||||
ospf[0] = 3 // version 3
|
|
||||||
ospf[1] = 1 // hello packet
|
|
||||||
ospf = append(ospf, hello...)
|
|
||||||
if err := p.SetChecksum(true, 12); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cm := ipv6.ControlMessage{
|
|
||||||
TrafficClass: 0xc0, // DSCP CS6
|
|
||||||
HopLimit: 1,
|
|
||||||
IfIndex: en0.Index,
|
|
||||||
}
|
|
||||||
if _, err := p.WriteTo(ospf, &cm, &allSPFRouters); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-208
@@ -1,208 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
//go:generate go run gen.go
|
|
||||||
|
|
||||||
// This program generates system adaptation constants and types,
|
|
||||||
// internet protocol constants and tables by reading template files
|
|
||||||
// and IANA protocol registries.
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/xml"
|
|
||||||
"fmt"
|
|
||||||
"go/format"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"runtime"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
if err := genzsys(); err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
if err := geniana(); err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func genzsys() error {
|
|
||||||
defs := "defs_" + runtime.GOOS + ".go"
|
|
||||||
f, err := os.Open(defs)
|
|
||||||
if err != nil {
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
f.Close()
|
|
||||||
cmd := exec.Command("go", "tool", "cgo", "-godefs", defs)
|
|
||||||
b, err := cmd.Output()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// The ipv6 pacakge still supports go1.2, and so we need to
|
|
||||||
// take care of additional platforms in go1.3 and above for
|
|
||||||
// working with go1.2.
|
|
||||||
switch {
|
|
||||||
case runtime.GOOS == "dragonfly" || runtime.GOOS == "solaris":
|
|
||||||
b = bytes.Replace(b, []byte("package ipv6\n"), []byte("// +build "+runtime.GOOS+"\n\npackage ipv6\n"), 1)
|
|
||||||
case runtime.GOOS == "linux" && (runtime.GOARCH == "arm64" || runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le"):
|
|
||||||
b = bytes.Replace(b, []byte("package ipv6\n"), []byte("// +build "+runtime.GOOS+","+runtime.GOARCH+"\n\npackage ipv6\n"), 1)
|
|
||||||
}
|
|
||||||
b, err = format.Source(b)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
zsys := "zsys_" + runtime.GOOS + ".go"
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "freebsd", "linux":
|
|
||||||
zsys = "zsys_" + runtime.GOOS + "_" + runtime.GOARCH + ".go"
|
|
||||||
}
|
|
||||||
if err := ioutil.WriteFile(zsys, b, 0644); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var registries = []struct {
|
|
||||||
url string
|
|
||||||
parse func(io.Writer, io.Reader) error
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
"http://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xml",
|
|
||||||
parseICMPv6Parameters,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func geniana() error {
|
|
||||||
var bb bytes.Buffer
|
|
||||||
fmt.Fprintf(&bb, "// go generate gen.go\n")
|
|
||||||
fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n")
|
|
||||||
fmt.Fprintf(&bb, "package ipv6\n\n")
|
|
||||||
for _, r := range registries {
|
|
||||||
resp, err := http.Get(r.url)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return fmt.Errorf("got HTTP status code %v for %v\n", resp.StatusCode, r.url)
|
|
||||||
}
|
|
||||||
if err := r.parse(&bb, resp.Body); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Fprintf(&bb, "\n")
|
|
||||||
}
|
|
||||||
b, err := format.Source(bb.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := ioutil.WriteFile("iana.go", b, 0644); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseICMPv6Parameters(w io.Writer, r io.Reader) error {
|
|
||||||
dec := xml.NewDecoder(r)
|
|
||||||
var icp icmpv6Parameters
|
|
||||||
if err := dec.Decode(&icp); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
prs := icp.escape()
|
|
||||||
fmt.Fprintf(w, "// %s, Updated: %s\n", icp.Title, icp.Updated)
|
|
||||||
fmt.Fprintf(w, "const (\n")
|
|
||||||
for _, pr := range prs {
|
|
||||||
if pr.Name == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fmt.Fprintf(w, "ICMPType%s ICMPType = %d", pr.Name, pr.Value)
|
|
||||||
fmt.Fprintf(w, "// %s\n", pr.OrigName)
|
|
||||||
}
|
|
||||||
fmt.Fprintf(w, ")\n\n")
|
|
||||||
fmt.Fprintf(w, "// %s, Updated: %s\n", icp.Title, icp.Updated)
|
|
||||||
fmt.Fprintf(w, "var icmpTypes = map[ICMPType]string{\n")
|
|
||||||
for _, pr := range prs {
|
|
||||||
if pr.Name == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fmt.Fprintf(w, "%d: %q,\n", pr.Value, strings.ToLower(pr.OrigName))
|
|
||||||
}
|
|
||||||
fmt.Fprintf(w, "}\n")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type icmpv6Parameters struct {
|
|
||||||
XMLName xml.Name `xml:"registry"`
|
|
||||||
Title string `xml:"title"`
|
|
||||||
Updated string `xml:"updated"`
|
|
||||||
Registries []struct {
|
|
||||||
Title string `xml:"title"`
|
|
||||||
Records []struct {
|
|
||||||
Value string `xml:"value"`
|
|
||||||
Name string `xml:"name"`
|
|
||||||
} `xml:"record"`
|
|
||||||
} `xml:"registry"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type canonICMPv6ParamRecord struct {
|
|
||||||
OrigName string
|
|
||||||
Name string
|
|
||||||
Value int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (icp *icmpv6Parameters) escape() []canonICMPv6ParamRecord {
|
|
||||||
id := -1
|
|
||||||
for i, r := range icp.Registries {
|
|
||||||
if strings.Contains(r.Title, "Type") || strings.Contains(r.Title, "type") {
|
|
||||||
id = i
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if id < 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
prs := make([]canonICMPv6ParamRecord, len(icp.Registries[id].Records))
|
|
||||||
sr := strings.NewReplacer(
|
|
||||||
"Messages", "",
|
|
||||||
"Message", "",
|
|
||||||
"ICMP", "",
|
|
||||||
"+", "P",
|
|
||||||
"-", "",
|
|
||||||
"/", "",
|
|
||||||
".", "",
|
|
||||||
" ", "",
|
|
||||||
)
|
|
||||||
for i, pr := range icp.Registries[id].Records {
|
|
||||||
if strings.Contains(pr.Name, "Reserved") ||
|
|
||||||
strings.Contains(pr.Name, "Unassigned") ||
|
|
||||||
strings.Contains(pr.Name, "Deprecated") ||
|
|
||||||
strings.Contains(pr.Name, "Experiment") ||
|
|
||||||
strings.Contains(pr.Name, "experiment") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
ss := strings.Split(pr.Name, "\n")
|
|
||||||
if len(ss) > 1 {
|
|
||||||
prs[i].Name = strings.Join(ss, " ")
|
|
||||||
} else {
|
|
||||||
prs[i].Name = ss[0]
|
|
||||||
}
|
|
||||||
s := strings.TrimSpace(prs[i].Name)
|
|
||||||
prs[i].OrigName = s
|
|
||||||
prs[i].Name = sr.Replace(s)
|
|
||||||
prs[i].Value, _ = strconv.Atoi(pr.Value)
|
|
||||||
}
|
|
||||||
return prs
|
|
||||||
}
|
|
||||||
-60
@@ -1,60 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build darwin dragonfly freebsd linux netbsd openbsd windows
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
// TrafficClass returns the traffic class field value for outgoing
|
|
||||||
// packets.
|
|
||||||
func (c *genericOpt) TrafficClass() (int, error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return 0, syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return getInt(fd, &sockOpts[ssoTrafficClass])
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTrafficClass sets the traffic class field value for future
|
|
||||||
// outgoing packets.
|
|
||||||
func (c *genericOpt) SetTrafficClass(tclass int) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return setInt(fd, &sockOpts[ssoTrafficClass], tclass)
|
|
||||||
}
|
|
||||||
|
|
||||||
// HopLimit returns the hop limit field value for outgoing packets.
|
|
||||||
func (c *genericOpt) HopLimit() (int, error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return 0, syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return getInt(fd, &sockOpts[ssoHopLimit])
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetHopLimit sets the hop limit field value for future outgoing
|
|
||||||
// packets.
|
|
||||||
func (c *genericOpt) SetHopLimit(hoplim int) error {
|
|
||||||
if !c.ok() {
|
|
||||||
return syscall.EINVAL
|
|
||||||
}
|
|
||||||
fd, err := c.sysfd()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return setInt(fd, &sockOpts[ssoHopLimit], hoplim)
|
|
||||||
}
|
|
||||||
-30
@@ -1,30 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build nacl plan9 solaris
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
// TrafficClass returns the traffic class field value for outgoing
|
|
||||||
// packets.
|
|
||||||
func (c *genericOpt) TrafficClass() (int, error) {
|
|
||||||
return 0, errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTrafficClass sets the traffic class field value for future
|
|
||||||
// outgoing packets.
|
|
||||||
func (c *genericOpt) SetTrafficClass(tclass int) error {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// HopLimit returns the hop limit field value for outgoing packets.
|
|
||||||
func (c *genericOpt) HopLimit() (int, error) {
|
|
||||||
return 0, errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetHopLimit sets the hop limit field value for future outgoing
|
|
||||||
// packets.
|
|
||||||
func (c *genericOpt) SetHopLimit(hoplim int) error {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
-55
@@ -1,55 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
Version = 6 // protocol version
|
|
||||||
HeaderLen = 40 // header length
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Header represents an IPv6 base header.
|
|
||||||
type Header struct {
|
|
||||||
Version int // protocol version
|
|
||||||
TrafficClass int // traffic class
|
|
||||||
FlowLabel int // flow label
|
|
||||||
PayloadLen int // payload length
|
|
||||||
NextHeader int // next header
|
|
||||||
HopLimit int // hop limit
|
|
||||||
Src net.IP // source address
|
|
||||||
Dst net.IP // destination address
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *Header) String() string {
|
|
||||||
if h == nil {
|
|
||||||
return "<nil>"
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("ver: %v, tclass: %#x, flowlbl: %#x, payloadlen: %v, nxthdr: %v, hoplim: %v, src: %v, dst: %v", h.Version, h.TrafficClass, h.FlowLabel, h.PayloadLen, h.NextHeader, h.HopLimit, h.Src, h.Dst)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseHeader parses b as an IPv6 base header.
|
|
||||||
func ParseHeader(b []byte) (*Header, error) {
|
|
||||||
if len(b) < HeaderLen {
|
|
||||||
return nil, errors.New("header too short")
|
|
||||||
}
|
|
||||||
h := &Header{
|
|
||||||
Version: int(b[0]) >> 4,
|
|
||||||
TrafficClass: int(b[0]&0x0f)<<4 | int(b[1])>>4,
|
|
||||||
FlowLabel: int(b[1]&0x0f)<<16 | int(b[2])<<8 | int(b[3]),
|
|
||||||
PayloadLen: int(b[4])<<8 | int(b[5]),
|
|
||||||
NextHeader: int(b[6]),
|
|
||||||
HopLimit: int(b[7]),
|
|
||||||
}
|
|
||||||
h.Src = make(net.IP, net.IPv6len)
|
|
||||||
copy(h.Src, b[8:24])
|
|
||||||
h.Dst = make(net.IP, net.IPv6len)
|
|
||||||
copy(h.Dst, b[24:40])
|
|
||||||
return h, nil
|
|
||||||
}
|
|
||||||
-50
@@ -1,50 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
wireHeaderFromKernel = [ipv6.HeaderLen]byte{
|
|
||||||
0x69, 0x8b, 0xee, 0xf1,
|
|
||||||
0xca, 0xfe, 0x2c, 0x01,
|
|
||||||
0x20, 0x01, 0x0d, 0xb8,
|
|
||||||
0x00, 0x01, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x01,
|
|
||||||
0x20, 0x01, 0x0d, 0xb8,
|
|
||||||
0x00, 0x02, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x01,
|
|
||||||
}
|
|
||||||
|
|
||||||
testHeader = &ipv6.Header{
|
|
||||||
Version: ipv6.Version,
|
|
||||||
TrafficClass: iana.DiffServAF43,
|
|
||||||
FlowLabel: 0xbeef1,
|
|
||||||
PayloadLen: 0xcafe,
|
|
||||||
NextHeader: iana.ProtocolIPv6Frag,
|
|
||||||
HopLimit: 1,
|
|
||||||
Src: net.ParseIP("2001:db8:1::1"),
|
|
||||||
Dst: net.ParseIP("2001:db8:2::1"),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestParseHeader(t *testing.T) {
|
|
||||||
h, err := ipv6.ParseHeader(wireHeaderFromKernel[:])
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(h, testHeader) {
|
|
||||||
t.Fatalf("got %#v; want %#v", h, testHeader)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-33
@@ -1,33 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"net"
|
|
||||||
)
|
|
||||||
|
|
||||||
var errOpNoSupport = errors.New("operation not supported")
|
|
||||||
|
|
||||||
func boolint(b bool) int {
|
|
||||||
if b {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func netAddrToIP16(a net.Addr) net.IP {
|
|
||||||
switch v := a.(type) {
|
|
||||||
case *net.UDPAddr:
|
|
||||||
if ip := v.IP.To16(); ip != nil && ip.To4() == nil {
|
|
||||||
return ip
|
|
||||||
}
|
|
||||||
case *net.IPAddr:
|
|
||||||
if ip := v.IP.To16(); ip != nil && ip.To4() == nil {
|
|
||||||
return ip
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build nacl plan9 solaris
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
func (c *genericOpt) sysfd() (int, error) {
|
|
||||||
return 0, errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *dgramOpt) sysfd() (int, error) {
|
|
||||||
return 0, errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *payloadHandler) sysfd() (int, error) {
|
|
||||||
return 0, errOpNoSupport
|
|
||||||
}
|
|
||||||
-46
@@ -1,46 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build darwin dragonfly freebsd linux netbsd openbsd
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"reflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c *genericOpt) sysfd() (int, error) {
|
|
||||||
switch p := c.Conn.(type) {
|
|
||||||
case *net.TCPConn, *net.UDPConn, *net.IPConn:
|
|
||||||
return sysfd(p)
|
|
||||||
}
|
|
||||||
return 0, errInvalidConnType
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *dgramOpt) sysfd() (int, error) {
|
|
||||||
switch p := c.PacketConn.(type) {
|
|
||||||
case *net.UDPConn, *net.IPConn:
|
|
||||||
return sysfd(p.(net.Conn))
|
|
||||||
}
|
|
||||||
return 0, errInvalidConnType
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *payloadHandler) sysfd() (int, error) {
|
|
||||||
return sysfd(c.PacketConn.(net.Conn))
|
|
||||||
}
|
|
||||||
|
|
||||||
func sysfd(c net.Conn) (int, error) {
|
|
||||||
cv := reflect.ValueOf(c)
|
|
||||||
switch ce := cv.Elem(); ce.Kind() {
|
|
||||||
case reflect.Struct:
|
|
||||||
nfd := ce.FieldByName("conn").FieldByName("fd")
|
|
||||||
switch fe := nfd.Elem(); fe.Kind() {
|
|
||||||
case reflect.Struct:
|
|
||||||
fd := fe.FieldByName("sysfd")
|
|
||||||
return int(fd.Int()), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0, errInvalidConnType
|
|
||||||
}
|
|
||||||
-45
@@ -1,45 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"reflect"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c *genericOpt) sysfd() (syscall.Handle, error) {
|
|
||||||
switch p := c.Conn.(type) {
|
|
||||||
case *net.TCPConn, *net.UDPConn, *net.IPConn:
|
|
||||||
return sysfd(p)
|
|
||||||
}
|
|
||||||
return syscall.InvalidHandle, errInvalidConnType
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *dgramOpt) sysfd() (syscall.Handle, error) {
|
|
||||||
switch p := c.PacketConn.(type) {
|
|
||||||
case *net.UDPConn, *net.IPConn:
|
|
||||||
return sysfd(p.(net.Conn))
|
|
||||||
}
|
|
||||||
return syscall.InvalidHandle, errInvalidConnType
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *payloadHandler) sysfd() (syscall.Handle, error) {
|
|
||||||
return sysfd(c.PacketConn.(net.Conn))
|
|
||||||
}
|
|
||||||
|
|
||||||
func sysfd(c net.Conn) (syscall.Handle, error) {
|
|
||||||
cv := reflect.ValueOf(c)
|
|
||||||
switch ce := cv.Elem(); ce.Kind() {
|
|
||||||
case reflect.Struct:
|
|
||||||
netfd := ce.FieldByName("conn").FieldByName("fd")
|
|
||||||
switch fe := netfd.Elem(); fe.Kind() {
|
|
||||||
case reflect.Struct:
|
|
||||||
fd := fe.FieldByName("sysfd")
|
|
||||||
return syscall.Handle(fd.Uint()), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return syscall.InvalidHandle, errInvalidConnType
|
|
||||||
}
|
|
||||||
-82
@@ -1,82 +0,0 @@
|
|||||||
// go generate gen.go
|
|
||||||
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2015-07-07
|
|
||||||
const (
|
|
||||||
ICMPTypeDestinationUnreachable ICMPType = 1 // Destination Unreachable
|
|
||||||
ICMPTypePacketTooBig ICMPType = 2 // Packet Too Big
|
|
||||||
ICMPTypeTimeExceeded ICMPType = 3 // Time Exceeded
|
|
||||||
ICMPTypeParameterProblem ICMPType = 4 // Parameter Problem
|
|
||||||
ICMPTypeEchoRequest ICMPType = 128 // Echo Request
|
|
||||||
ICMPTypeEchoReply ICMPType = 129 // Echo Reply
|
|
||||||
ICMPTypeMulticastListenerQuery ICMPType = 130 // Multicast Listener Query
|
|
||||||
ICMPTypeMulticastListenerReport ICMPType = 131 // Multicast Listener Report
|
|
||||||
ICMPTypeMulticastListenerDone ICMPType = 132 // Multicast Listener Done
|
|
||||||
ICMPTypeRouterSolicitation ICMPType = 133 // Router Solicitation
|
|
||||||
ICMPTypeRouterAdvertisement ICMPType = 134 // Router Advertisement
|
|
||||||
ICMPTypeNeighborSolicitation ICMPType = 135 // Neighbor Solicitation
|
|
||||||
ICMPTypeNeighborAdvertisement ICMPType = 136 // Neighbor Advertisement
|
|
||||||
ICMPTypeRedirect ICMPType = 137 // Redirect Message
|
|
||||||
ICMPTypeRouterRenumbering ICMPType = 138 // Router Renumbering
|
|
||||||
ICMPTypeNodeInformationQuery ICMPType = 139 // ICMP Node Information Query
|
|
||||||
ICMPTypeNodeInformationResponse ICMPType = 140 // ICMP Node Information Response
|
|
||||||
ICMPTypeInverseNeighborDiscoverySolicitation ICMPType = 141 // Inverse Neighbor Discovery Solicitation Message
|
|
||||||
ICMPTypeInverseNeighborDiscoveryAdvertisement ICMPType = 142 // Inverse Neighbor Discovery Advertisement Message
|
|
||||||
ICMPTypeVersion2MulticastListenerReport ICMPType = 143 // Version 2 Multicast Listener Report
|
|
||||||
ICMPTypeHomeAgentAddressDiscoveryRequest ICMPType = 144 // Home Agent Address Discovery Request Message
|
|
||||||
ICMPTypeHomeAgentAddressDiscoveryReply ICMPType = 145 // Home Agent Address Discovery Reply Message
|
|
||||||
ICMPTypeMobilePrefixSolicitation ICMPType = 146 // Mobile Prefix Solicitation
|
|
||||||
ICMPTypeMobilePrefixAdvertisement ICMPType = 147 // Mobile Prefix Advertisement
|
|
||||||
ICMPTypeCertificationPathSolicitation ICMPType = 148 // Certification Path Solicitation Message
|
|
||||||
ICMPTypeCertificationPathAdvertisement ICMPType = 149 // Certification Path Advertisement Message
|
|
||||||
ICMPTypeMulticastRouterAdvertisement ICMPType = 151 // Multicast Router Advertisement
|
|
||||||
ICMPTypeMulticastRouterSolicitation ICMPType = 152 // Multicast Router Solicitation
|
|
||||||
ICMPTypeMulticastRouterTermination ICMPType = 153 // Multicast Router Termination
|
|
||||||
ICMPTypeFMIPv6 ICMPType = 154 // FMIPv6 Messages
|
|
||||||
ICMPTypeRPLControl ICMPType = 155 // RPL Control Message
|
|
||||||
ICMPTypeILNPv6LocatorUpdate ICMPType = 156 // ILNPv6 Locator Update Message
|
|
||||||
ICMPTypeDuplicateAddressRequest ICMPType = 157 // Duplicate Address Request
|
|
||||||
ICMPTypeDuplicateAddressConfirmation ICMPType = 158 // Duplicate Address Confirmation
|
|
||||||
ICMPTypeMPLControl ICMPType = 159 // MPL Control Message
|
|
||||||
)
|
|
||||||
|
|
||||||
// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2015-07-07
|
|
||||||
var icmpTypes = map[ICMPType]string{
|
|
||||||
1: "destination unreachable",
|
|
||||||
2: "packet too big",
|
|
||||||
3: "time exceeded",
|
|
||||||
4: "parameter problem",
|
|
||||||
128: "echo request",
|
|
||||||
129: "echo reply",
|
|
||||||
130: "multicast listener query",
|
|
||||||
131: "multicast listener report",
|
|
||||||
132: "multicast listener done",
|
|
||||||
133: "router solicitation",
|
|
||||||
134: "router advertisement",
|
|
||||||
135: "neighbor solicitation",
|
|
||||||
136: "neighbor advertisement",
|
|
||||||
137: "redirect message",
|
|
||||||
138: "router renumbering",
|
|
||||||
139: "icmp node information query",
|
|
||||||
140: "icmp node information response",
|
|
||||||
141: "inverse neighbor discovery solicitation message",
|
|
||||||
142: "inverse neighbor discovery advertisement message",
|
|
||||||
143: "version 2 multicast listener report",
|
|
||||||
144: "home agent address discovery request message",
|
|
||||||
145: "home agent address discovery reply message",
|
|
||||||
146: "mobile prefix solicitation",
|
|
||||||
147: "mobile prefix advertisement",
|
|
||||||
148: "certification path solicitation message",
|
|
||||||
149: "certification path advertisement message",
|
|
||||||
151: "multicast router advertisement",
|
|
||||||
152: "multicast router solicitation",
|
|
||||||
153: "multicast router termination",
|
|
||||||
154: "fmipv6 messages",
|
|
||||||
155: "rpl control message",
|
|
||||||
156: "ilnpv6 locator update message",
|
|
||||||
157: "duplicate address request",
|
|
||||||
158: "duplicate address confirmation",
|
|
||||||
159: "mpl control message",
|
|
||||||
}
|
|
||||||
-57
@@ -1,57 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import "golang.org/x/net/internal/iana"
|
|
||||||
|
|
||||||
// An ICMPType represents a type of ICMP message.
|
|
||||||
type ICMPType int
|
|
||||||
|
|
||||||
func (typ ICMPType) String() string {
|
|
||||||
s, ok := icmpTypes[typ]
|
|
||||||
if !ok {
|
|
||||||
return "<nil>"
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// Protocol returns the ICMPv6 protocol number.
|
|
||||||
func (typ ICMPType) Protocol() int {
|
|
||||||
return iana.ProtocolIPv6ICMP
|
|
||||||
}
|
|
||||||
|
|
||||||
// An ICMPFilter represents an ICMP message filter for incoming
|
|
||||||
// packets. The filter belongs to a packet delivery path on a host and
|
|
||||||
// it cannot interact with forwarding packets or tunnel-outer packets.
|
|
||||||
//
|
|
||||||
// Note: RFC 2460 defines a reasonable role model. A node means a
|
|
||||||
// device that implements IP. A router means a node that forwards IP
|
|
||||||
// packets not explicitly addressed to itself, and a host means a node
|
|
||||||
// that is not a router.
|
|
||||||
type ICMPFilter struct {
|
|
||||||
sysICMPv6Filter
|
|
||||||
}
|
|
||||||
|
|
||||||
// Accept accepts incoming ICMP packets including the type field value
|
|
||||||
// typ.
|
|
||||||
func (f *ICMPFilter) Accept(typ ICMPType) {
|
|
||||||
f.accept(typ)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Block blocks incoming ICMP packets including the type field value
|
|
||||||
// typ.
|
|
||||||
func (f *ICMPFilter) Block(typ ICMPType) {
|
|
||||||
f.block(typ)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetAll sets the filter action to the filter.
|
|
||||||
func (f *ICMPFilter) SetAll(block bool) {
|
|
||||||
f.setAll(block)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WillBlock reports whether the ICMP type will be blocked.
|
|
||||||
func (f *ICMPFilter) WillBlock(typ ICMPType) bool {
|
|
||||||
return f.willBlock(typ)
|
|
||||||
}
|
|
||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build darwin dragonfly freebsd netbsd openbsd
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
func (f *sysICMPv6Filter) accept(typ ICMPType) {
|
|
||||||
f.Filt[typ>>5] |= 1 << (uint32(typ) & 31)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPv6Filter) block(typ ICMPType) {
|
|
||||||
f.Filt[typ>>5] &^= 1 << (uint32(typ) & 31)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPv6Filter) setAll(block bool) {
|
|
||||||
for i := range f.Filt {
|
|
||||||
if block {
|
|
||||||
f.Filt[i] = 0
|
|
||||||
} else {
|
|
||||||
f.Filt[i] = 1<<32 - 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPv6Filter) willBlock(typ ICMPType) bool {
|
|
||||||
return f.Filt[typ>>5]&(1<<(uint32(typ)&31)) == 0
|
|
||||||
}
|
|
||||||
-27
@@ -1,27 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
func (f *sysICMPv6Filter) accept(typ ICMPType) {
|
|
||||||
f.Data[typ>>5] &^= 1 << (uint32(typ) & 31)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPv6Filter) block(typ ICMPType) {
|
|
||||||
f.Data[typ>>5] |= 1 << (uint32(typ) & 31)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPv6Filter) setAll(block bool) {
|
|
||||||
for i := range f.Data {
|
|
||||||
if block {
|
|
||||||
f.Data[i] = 1<<32 - 1
|
|
||||||
} else {
|
|
||||||
f.Data[i] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPv6Filter) willBlock(typ ICMPType) bool {
|
|
||||||
return f.Data[typ>>5]&(1<<(uint32(typ)&31)) != 0
|
|
||||||
}
|
|
||||||
-24
@@ -1,24 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build solaris
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
func (f *sysICMPv6Filter) accept(typ ICMPType) {
|
|
||||||
// TODO(mikio): implement this
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPv6Filter) block(typ ICMPType) {
|
|
||||||
// TODO(mikio): implement this
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPv6Filter) setAll(block bool) {
|
|
||||||
// TODO(mikio): implement this
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPv6Filter) willBlock(typ ICMPType) bool {
|
|
||||||
// TODO(mikio): implement this
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
-23
@@ -1,23 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build nacl plan9
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
type sysICMPv6Filter struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPv6Filter) accept(typ ICMPType) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPv6Filter) block(typ ICMPType) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPv6Filter) setAll(block bool) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPv6Filter) willBlock(typ ICMPType) bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
-96
@@ -1,96 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"reflect"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/nettest"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
var icmpStringTests = []struct {
|
|
||||||
in ipv6.ICMPType
|
|
||||||
out string
|
|
||||||
}{
|
|
||||||
{ipv6.ICMPTypeDestinationUnreachable, "destination unreachable"},
|
|
||||||
|
|
||||||
{256, "<nil>"},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestICMPString(t *testing.T) {
|
|
||||||
for _, tt := range icmpStringTests {
|
|
||||||
s := tt.in.String()
|
|
||||||
if s != tt.out {
|
|
||||||
t.Errorf("got %s; want %s", s, tt.out)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestICMPFilter(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "nacl", "plan9", "solaris", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
|
|
||||||
var f ipv6.ICMPFilter
|
|
||||||
for _, toggle := range []bool{false, true} {
|
|
||||||
f.SetAll(toggle)
|
|
||||||
for _, typ := range []ipv6.ICMPType{
|
|
||||||
ipv6.ICMPTypeDestinationUnreachable,
|
|
||||||
ipv6.ICMPTypeEchoReply,
|
|
||||||
ipv6.ICMPTypeNeighborSolicitation,
|
|
||||||
ipv6.ICMPTypeDuplicateAddressConfirmation,
|
|
||||||
} {
|
|
||||||
f.Accept(typ)
|
|
||||||
if f.WillBlock(typ) {
|
|
||||||
t.Errorf("ipv6.ICMPFilter.Set(%v, false) failed", typ)
|
|
||||||
}
|
|
||||||
f.Block(typ)
|
|
||||||
if !f.WillBlock(typ) {
|
|
||||||
t.Errorf("ipv6.ICMPFilter.Set(%v, true) failed", typ)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSetICMPFilter(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "nacl", "plan9", "solaris", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
|
||||||
t.Skip(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := net.ListenPacket("ip6:ipv6-icmp", "::1")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
|
|
||||||
var f ipv6.ICMPFilter
|
|
||||||
f.SetAll(true)
|
|
||||||
f.Accept(ipv6.ICMPTypeEchoRequest)
|
|
||||||
f.Accept(ipv6.ICMPTypeEchoReply)
|
|
||||||
if err := p.SetICMPFilter(&f); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
kf, err := p.ICMPFilter()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(kf, &f) {
|
|
||||||
t.Fatalf("got %#v; want %#v", kf, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-26
@@ -1,26 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
type sysICMPv6Filter struct {
|
|
||||||
// TODO(mikio): implement this
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPv6Filter) accept(typ ICMPType) {
|
|
||||||
// TODO(mikio): implement this
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPv6Filter) block(typ ICMPType) {
|
|
||||||
// TODO(mikio): implement this
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPv6Filter) setAll(block bool) {
|
|
||||||
// TODO(mikio): implement this
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *sysICMPv6Filter) willBlock(typ ICMPType) bool {
|
|
||||||
// TODO(mikio): implement this
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
-32
@@ -1,32 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func connector(t *testing.T, network, addr string, done chan<- bool) {
|
|
||||||
defer func() { done <- true }()
|
|
||||||
|
|
||||||
c, err := net.Dial(network, addr)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func acceptor(t *testing.T, ln net.Listener, done chan<- bool) {
|
|
||||||
defer func() { done <- true }()
|
|
||||||
|
|
||||||
c, err := ln.Accept()
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.Close()
|
|
||||||
}
|
|
||||||
-263
@@ -1,263 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/net/icmp"
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
"golang.org/x/net/internal/nettest"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
var packetConnReadWriteMulticastUDPTests = []struct {
|
|
||||||
addr string
|
|
||||||
grp, src *net.UDPAddr
|
|
||||||
}{
|
|
||||||
{"[ff02::]:0", &net.UDPAddr{IP: net.ParseIP("ff02::114")}, nil}, // see RFC 4727
|
|
||||||
|
|
||||||
{"[ff30::8000:0]:0", &net.UDPAddr{IP: net.ParseIP("ff30::8000:1")}, &net.UDPAddr{IP: net.IPv6loopback}}, // see RFC 5771
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "freebsd": // due to a bug on loopback marking
|
|
||||||
// See http://www.freebsd.org/cgi/query-pr.cgi?pr=180065.
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
case "nacl", "plan9", "solaris", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
|
|
||||||
if ifi == nil {
|
|
||||||
t.Skipf("not available on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range packetConnReadWriteMulticastUDPTests {
|
|
||||||
c, err := net.ListenPacket("udp6", tt.addr)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
grp := *tt.grp
|
|
||||||
grp.Port = c.LocalAddr().(*net.UDPAddr).Port
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
defer p.Close()
|
|
||||||
if tt.src == nil {
|
|
||||||
if err := p.JoinGroup(ifi, &grp); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer p.LeaveGroup(ifi, &grp)
|
|
||||||
} else {
|
|
||||||
if err := p.JoinSourceSpecificGroup(ifi, &grp, tt.src); err != nil {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "freebsd", "linux":
|
|
||||||
default: // platforms that don't support MLDv2 fail here
|
|
||||||
t.Logf("not supported on %s", runtime.GOOS)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer p.LeaveSourceSpecificGroup(ifi, &grp, tt.src)
|
|
||||||
}
|
|
||||||
if err := p.SetMulticastInterface(ifi); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if _, err := p.MulticastInterface(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := p.SetMulticastLoopback(true); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if _, err := p.MulticastLoopback(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cm := ipv6.ControlMessage{
|
|
||||||
TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
|
|
||||||
Src: net.IPv6loopback,
|
|
||||||
IfIndex: ifi.Index,
|
|
||||||
}
|
|
||||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
|
||||||
wb := []byte("HELLO-R-U-THERE")
|
|
||||||
|
|
||||||
for i, toggle := range []bool{true, false, true} {
|
|
||||||
if err := p.SetControlMessage(cf, toggle); err != nil {
|
|
||||||
if nettest.ProtocolNotSupported(err) {
|
|
||||||
t.Logf("not supported on %s", runtime.GOOS)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
cm.HopLimit = i + 1
|
|
||||||
if n, err := p.WriteTo(wb, &cm, &grp); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if n != len(wb) {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
rb := make([]byte, 128)
|
|
||||||
if n, cm, _, err := p.ReadFrom(rb); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if !bytes.Equal(rb[:n], wb) {
|
|
||||||
t.Fatalf("got %v; want %v", rb[:n], wb)
|
|
||||||
} else {
|
|
||||||
t.Logf("rcvd cmsg: %v", cm)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var packetConnReadWriteMulticastICMPTests = []struct {
|
|
||||||
grp, src *net.IPAddr
|
|
||||||
}{
|
|
||||||
{&net.IPAddr{IP: net.ParseIP("ff02::114")}, nil}, // see RFC 4727
|
|
||||||
|
|
||||||
{&net.IPAddr{IP: net.ParseIP("ff30::8000:1")}, &net.IPAddr{IP: net.IPv6loopback}}, // see RFC 5771
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPacketConnReadWriteMulticastICMP(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "freebsd": // due to a bug on loopback marking
|
|
||||||
// See http://www.freebsd.org/cgi/query-pr.cgi?pr=180065.
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
case "nacl", "plan9", "solaris", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
|
||||||
t.Skip(m)
|
|
||||||
}
|
|
||||||
ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
|
|
||||||
if ifi == nil {
|
|
||||||
t.Skipf("not available on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range packetConnReadWriteMulticastICMPTests {
|
|
||||||
c, err := net.ListenPacket("ip6:ipv6-icmp", "::")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
pshicmp := icmp.IPv6PseudoHeader(c.LocalAddr().(*net.IPAddr).IP, tt.grp.IP)
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
defer p.Close()
|
|
||||||
if tt.src == nil {
|
|
||||||
if err := p.JoinGroup(ifi, tt.grp); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer p.LeaveGroup(ifi, tt.grp)
|
|
||||||
} else {
|
|
||||||
if err := p.JoinSourceSpecificGroup(ifi, tt.grp, tt.src); err != nil {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "freebsd", "linux":
|
|
||||||
default: // platforms that don't support MLDv2 fail here
|
|
||||||
t.Logf("not supported on %s", runtime.GOOS)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer p.LeaveSourceSpecificGroup(ifi, tt.grp, tt.src)
|
|
||||||
}
|
|
||||||
if err := p.SetMulticastInterface(ifi); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if _, err := p.MulticastInterface(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := p.SetMulticastLoopback(true); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if _, err := p.MulticastLoopback(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cm := ipv6.ControlMessage{
|
|
||||||
TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
|
|
||||||
Src: net.IPv6loopback,
|
|
||||||
IfIndex: ifi.Index,
|
|
||||||
}
|
|
||||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
|
||||||
|
|
||||||
var f ipv6.ICMPFilter
|
|
||||||
f.SetAll(true)
|
|
||||||
f.Accept(ipv6.ICMPTypeEchoReply)
|
|
||||||
if err := p.SetICMPFilter(&f); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var psh []byte
|
|
||||||
for i, toggle := range []bool{true, false, true} {
|
|
||||||
if toggle {
|
|
||||||
psh = nil
|
|
||||||
if err := p.SetChecksum(true, 2); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
psh = pshicmp
|
|
||||||
// Some platforms never allow to
|
|
||||||
// disable the kernel checksum
|
|
||||||
// processing.
|
|
||||||
p.SetChecksum(false, -1)
|
|
||||||
}
|
|
||||||
wb, err := (&icmp.Message{
|
|
||||||
Type: ipv6.ICMPTypeEchoRequest, Code: 0,
|
|
||||||
Body: &icmp.Echo{
|
|
||||||
ID: os.Getpid() & 0xffff, Seq: i + 1,
|
|
||||||
Data: []byte("HELLO-R-U-THERE"),
|
|
||||||
},
|
|
||||||
}).Marshal(psh)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := p.SetControlMessage(cf, toggle); err != nil {
|
|
||||||
if nettest.ProtocolNotSupported(err) {
|
|
||||||
t.Logf("not supported on %s", runtime.GOOS)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
cm.HopLimit = i + 1
|
|
||||||
if n, err := p.WriteTo(wb, &cm, tt.grp); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if n != len(wb) {
|
|
||||||
t.Fatalf("got %v; want %v", n, len(wb))
|
|
||||||
}
|
|
||||||
rb := make([]byte, 128)
|
|
||||||
if n, cm, _, err := p.ReadFrom(rb); err != nil {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "darwin": // older darwin kernels have some limitation on receiving icmp packet through raw socket
|
|
||||||
t.Logf("not supported on %s", runtime.GOOS)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
t.Fatal(err)
|
|
||||||
} else {
|
|
||||||
t.Logf("rcvd cmsg: %v", cm)
|
|
||||||
if m, err := icmp.ParseMessage(iana.ProtocolIPv6ICMP, rb[:n]); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if m.Type != ipv6.ICMPTypeEchoReply || m.Code != 0 {
|
|
||||||
t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv6.ICMPTypeEchoReply, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-246
@@ -1,246 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/nettest"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
var udpMultipleGroupListenerTests = []net.Addr{
|
|
||||||
&net.UDPAddr{IP: net.ParseIP("ff02::114")}, // see RFC 4727
|
|
||||||
&net.UDPAddr{IP: net.ParseIP("ff02::1:114")},
|
|
||||||
&net.UDPAddr{IP: net.ParseIP("ff02::2:114")},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "nacl", "plan9", "solaris", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, gaddr := range udpMultipleGroupListenerTests {
|
|
||||||
c, err := net.ListenPacket("udp6", "[::]:0") // wildcard address with non-reusable port
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
var mift []*net.Interface
|
|
||||||
|
|
||||||
ift, err := net.Interfaces()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
for i, ifi := range ift {
|
|
||||||
if _, ok := nettest.IsMulticastCapable("ip6", &ifi); !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := p.JoinGroup(&ifi, gaddr); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
mift = append(mift, &ift[i])
|
|
||||||
}
|
|
||||||
for _, ifi := range mift {
|
|
||||||
if err := p.LeaveGroup(ifi, gaddr); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "nacl", "plan9", "solaris", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, gaddr := range udpMultipleGroupListenerTests {
|
|
||||||
c1, err := net.ListenPacket("udp6", "[ff02::]:1024") // wildcard address with reusable port
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c1.Close()
|
|
||||||
|
|
||||||
c2, err := net.ListenPacket("udp6", "[ff02::]:1024") // wildcard address with reusable port
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c2.Close()
|
|
||||||
|
|
||||||
var ps [2]*ipv6.PacketConn
|
|
||||||
ps[0] = ipv6.NewPacketConn(c1)
|
|
||||||
ps[1] = ipv6.NewPacketConn(c2)
|
|
||||||
var mift []*net.Interface
|
|
||||||
|
|
||||||
ift, err := net.Interfaces()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
for i, ifi := range ift {
|
|
||||||
if _, ok := nettest.IsMulticastCapable("ip6", &ifi); !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for _, p := range ps {
|
|
||||||
if err := p.JoinGroup(&ifi, gaddr); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mift = append(mift, &ift[i])
|
|
||||||
}
|
|
||||||
for _, ifi := range mift {
|
|
||||||
for _, p := range ps {
|
|
||||||
if err := p.LeaveGroup(ifi, gaddr); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "nacl", "plan9", "solaris", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
gaddr := net.IPAddr{IP: net.ParseIP("ff02::114")} // see RFC 4727
|
|
||||||
type ml struct {
|
|
||||||
c *ipv6.PacketConn
|
|
||||||
ifi *net.Interface
|
|
||||||
}
|
|
||||||
var mlt []*ml
|
|
||||||
|
|
||||||
ift, err := net.Interfaces()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
for i, ifi := range ift {
|
|
||||||
ip, ok := nettest.IsMulticastCapable("ip6", &ifi)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
c, err := net.ListenPacket("udp6", fmt.Sprintf("[%s%%%s]:1024", ip.String(), ifi.Name)) // unicast address with non-reusable port
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
if err := p.JoinGroup(&ifi, &gaddr); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
mlt = append(mlt, &ml{p, &ift[i]})
|
|
||||||
}
|
|
||||||
for _, m := range mlt {
|
|
||||||
if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIPSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "nacl", "plan9", "solaris", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
|
||||||
t.Skip(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := net.ListenPacket("ip6:ipv6-icmp", "::") // wildcard address
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
gaddr := net.IPAddr{IP: net.ParseIP("ff02::114")} // see RFC 4727
|
|
||||||
var mift []*net.Interface
|
|
||||||
|
|
||||||
ift, err := net.Interfaces()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
for i, ifi := range ift {
|
|
||||||
if _, ok := nettest.IsMulticastCapable("ip6", &ifi); !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := p.JoinGroup(&ifi, &gaddr); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
mift = append(mift, &ift[i])
|
|
||||||
}
|
|
||||||
for _, ifi := range mift {
|
|
||||||
if err := p.LeaveGroup(ifi, &gaddr); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "darwin", "dragonfly", "openbsd": // platforms that return fe80::1%lo0: bind: can't assign requested address
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
case "nacl", "plan9", "solaris", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
|
||||||
t.Skip(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
gaddr := net.IPAddr{IP: net.ParseIP("ff02::114")} // see RFC 4727
|
|
||||||
type ml struct {
|
|
||||||
c *ipv6.PacketConn
|
|
||||||
ifi *net.Interface
|
|
||||||
}
|
|
||||||
var mlt []*ml
|
|
||||||
|
|
||||||
ift, err := net.Interfaces()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
for i, ifi := range ift {
|
|
||||||
ip, ok := nettest.IsMulticastCapable("ip6", &ifi)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
c, err := net.ListenPacket("ip6:ipv6-icmp", fmt.Sprintf("%s%%%s", ip.String(), ifi.Name)) // unicast address
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
if err := p.JoinGroup(&ifi, &gaddr); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
mlt = append(mlt, &ml{p, &ift[i]})
|
|
||||||
}
|
|
||||||
for _, m := range mlt {
|
|
||||||
if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-157
@@ -1,157 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/nettest"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
var packetConnMulticastSocketOptionTests = []struct {
|
|
||||||
net, proto, addr string
|
|
||||||
grp, src net.Addr
|
|
||||||
}{
|
|
||||||
{"udp6", "", "[ff02::]:0", &net.UDPAddr{IP: net.ParseIP("ff02::114")}, nil}, // see RFC 4727
|
|
||||||
{"ip6", ":ipv6-icmp", "::", &net.IPAddr{IP: net.ParseIP("ff02::115")}, nil}, // see RFC 4727
|
|
||||||
|
|
||||||
{"udp6", "", "[ff30::8000:0]:0", &net.UDPAddr{IP: net.ParseIP("ff30::8000:1")}, &net.UDPAddr{IP: net.IPv6loopback}}, // see RFC 5771
|
|
||||||
{"ip6", ":ipv6-icmp", "::", &net.IPAddr{IP: net.ParseIP("ff30::8000:2")}, &net.IPAddr{IP: net.IPv6loopback}}, // see RFC 5771
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPacketConnMulticastSocketOptions(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "nacl", "plan9", "solaris", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
|
|
||||||
if ifi == nil {
|
|
||||||
t.Skipf("not available on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
|
|
||||||
m, ok := nettest.SupportsRawIPSocket()
|
|
||||||
for _, tt := range packetConnMulticastSocketOptionTests {
|
|
||||||
if tt.net == "ip6" && !ok {
|
|
||||||
t.Log(m)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
defer p.Close()
|
|
||||||
|
|
||||||
if tt.src == nil {
|
|
||||||
testMulticastSocketOptions(t, p, ifi, tt.grp)
|
|
||||||
} else {
|
|
||||||
testSourceSpecificMulticastSocketOptions(t, p, ifi, tt.grp, tt.src)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type testIPv6MulticastConn interface {
|
|
||||||
MulticastHopLimit() (int, error)
|
|
||||||
SetMulticastHopLimit(ttl int) error
|
|
||||||
MulticastLoopback() (bool, error)
|
|
||||||
SetMulticastLoopback(bool) error
|
|
||||||
JoinGroup(*net.Interface, net.Addr) error
|
|
||||||
LeaveGroup(*net.Interface, net.Addr) error
|
|
||||||
JoinSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
|
|
||||||
LeaveSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
|
|
||||||
ExcludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
|
|
||||||
IncludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func testMulticastSocketOptions(t *testing.T, c testIPv6MulticastConn, ifi *net.Interface, grp net.Addr) {
|
|
||||||
const hoplim = 255
|
|
||||||
if err := c.SetMulticastHopLimit(hoplim); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if v, err := c.MulticastHopLimit(); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
} else if v != hoplim {
|
|
||||||
t.Errorf("got %v; want %v", v, hoplim)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, toggle := range []bool{true, false} {
|
|
||||||
if err := c.SetMulticastLoopback(toggle); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if v, err := c.MulticastLoopback(); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
} else if v != toggle {
|
|
||||||
t.Errorf("got %v; want %v", v, toggle)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := c.JoinGroup(ifi, grp); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := c.LeaveGroup(ifi, grp); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testSourceSpecificMulticastSocketOptions(t *testing.T, c testIPv6MulticastConn, ifi *net.Interface, grp, src net.Addr) {
|
|
||||||
// MCAST_JOIN_GROUP -> MCAST_BLOCK_SOURCE -> MCAST_UNBLOCK_SOURCE -> MCAST_LEAVE_GROUP
|
|
||||||
if err := c.JoinGroup(ifi, grp); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := c.ExcludeSourceSpecificGroup(ifi, grp, src); err != nil {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "freebsd", "linux":
|
|
||||||
default: // platforms that don't support MLDv2 fail here
|
|
||||||
t.Logf("not supported on %s", runtime.GOOS)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := c.IncludeSourceSpecificGroup(ifi, grp, src); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := c.LeaveGroup(ifi, grp); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_SOURCE_GROUP
|
|
||||||
if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := c.LeaveSourceSpecificGroup(ifi, grp, src); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_GROUP
|
|
||||||
if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := c.LeaveGroup(ifi, grp); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-15
@@ -1,15 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import "net"
|
|
||||||
|
|
||||||
// A payloadHandler represents the IPv6 datagram payload handler.
|
|
||||||
type payloadHandler struct {
|
|
||||||
net.PacketConn
|
|
||||||
rawOpt
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *payloadHandler) ok() bool { return c != nil && c.PacketConn != nil }
|
|
||||||
-70
@@ -1,70 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !nacl,!plan9,!windows
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ReadFrom reads a payload of the received IPv6 datagram, from the
|
|
||||||
// endpoint c, copying the payload into b. It returns the number of
|
|
||||||
// bytes copied into b, the control message cm and the source address
|
|
||||||
// src of the received datagram.
|
|
||||||
func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return 0, nil, nil, syscall.EINVAL
|
|
||||||
}
|
|
||||||
oob := newControlMessage(&c.rawOpt)
|
|
||||||
var oobn int
|
|
||||||
switch c := c.PacketConn.(type) {
|
|
||||||
case *net.UDPConn:
|
|
||||||
if n, oobn, _, src, err = c.ReadMsgUDP(b, oob); err != nil {
|
|
||||||
return 0, nil, nil, err
|
|
||||||
}
|
|
||||||
case *net.IPConn:
|
|
||||||
if n, oobn, _, src, err = c.ReadMsgIP(b, oob); err != nil {
|
|
||||||
return 0, nil, nil, err
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return 0, nil, nil, errInvalidConnType
|
|
||||||
}
|
|
||||||
if cm, err = parseControlMessage(oob[:oobn]); err != nil {
|
|
||||||
return 0, nil, nil, err
|
|
||||||
}
|
|
||||||
if cm != nil {
|
|
||||||
cm.Src = netAddrToIP16(src)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteTo writes a payload of the IPv6 datagram, to the destination
|
|
||||||
// address dst through the endpoint c, copying the payload from b. It
|
|
||||||
// returns the number of bytes written. The control message cm allows
|
|
||||||
// the IPv6 header fields and the datagram path to be specified. The
|
|
||||||
// cm may be nil if control of the outgoing datagram is not required.
|
|
||||||
func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return 0, syscall.EINVAL
|
|
||||||
}
|
|
||||||
oob := marshalControlMessage(cm)
|
|
||||||
if dst == nil {
|
|
||||||
return 0, errMissingAddress
|
|
||||||
}
|
|
||||||
switch c := c.PacketConn.(type) {
|
|
||||||
case *net.UDPConn:
|
|
||||||
n, _, err = c.WriteMsgUDP(b, oob, dst.(*net.UDPAddr))
|
|
||||||
case *net.IPConn:
|
|
||||||
n, _, err = c.WriteMsgIP(b, oob, dst.(*net.IPAddr))
|
|
||||||
default:
|
|
||||||
return 0, errInvalidConnType
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
-41
@@ -1,41 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build nacl plan9 windows
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ReadFrom reads a payload of the received IPv6 datagram, from the
|
|
||||||
// endpoint c, copying the payload into b. It returns the number of
|
|
||||||
// bytes copied into b, the control message cm and the source address
|
|
||||||
// src of the received datagram.
|
|
||||||
func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return 0, nil, nil, syscall.EINVAL
|
|
||||||
}
|
|
||||||
if n, src, err = c.PacketConn.ReadFrom(b); err != nil {
|
|
||||||
return 0, nil, nil, err
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteTo writes a payload of the IPv6 datagram, to the destination
|
|
||||||
// address dst through the endpoint c, copying the payload from b. It
|
|
||||||
// returns the number of bytes written. The control message cm allows
|
|
||||||
// the IPv6 header fields and the datagram path to be specified. The
|
|
||||||
// cm may be nil if control of the outgoing datagram is not required.
|
|
||||||
func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {
|
|
||||||
if !c.ok() {
|
|
||||||
return 0, syscall.EINVAL
|
|
||||||
}
|
|
||||||
if dst == nil {
|
|
||||||
return 0, errMissingAddress
|
|
||||||
}
|
|
||||||
return c.PacketConn.WriteTo(b, dst)
|
|
||||||
}
|
|
||||||
-185
@@ -1,185 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"net"
|
|
||||||
"runtime"
|
|
||||||
"sync"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
"golang.org/x/net/internal/nettest"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
func benchmarkUDPListener() (net.PacketConn, net.Addr, error) {
|
|
||||||
c, err := net.ListenPacket("udp6", "[::1]:0")
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String())
|
|
||||||
if err != nil {
|
|
||||||
c.Close()
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
return c, dst, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkReadWriteNetUDP(b *testing.B) {
|
|
||||||
if !supportsIPv6 {
|
|
||||||
b.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
c, dst, err := benchmarkUDPListener()
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
benchmarkReadWriteNetUDP(b, c, wb, rb, dst)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkReadWriteNetUDP(b *testing.B, c net.PacketConn, wb, rb []byte, dst net.Addr) {
|
|
||||||
if _, err := c.WriteTo(wb, dst); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
if _, _, err := c.ReadFrom(rb); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkReadWriteIPv6UDP(b *testing.B) {
|
|
||||||
if !supportsIPv6 {
|
|
||||||
b.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
c, dst, err := benchmarkUDPListener()
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
|
||||||
if err := p.SetControlMessage(cf, true); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback)
|
|
||||||
|
|
||||||
wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
benchmarkReadWriteIPv6UDP(b, p, wb, rb, dst, ifi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkReadWriteIPv6UDP(b *testing.B, p *ipv6.PacketConn, wb, rb []byte, dst net.Addr, ifi *net.Interface) {
|
|
||||||
cm := ipv6.ControlMessage{
|
|
||||||
TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
|
|
||||||
HopLimit: 1,
|
|
||||||
}
|
|
||||||
if ifi != nil {
|
|
||||||
cm.IfIndex = ifi.Index
|
|
||||||
}
|
|
||||||
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
} else if n != len(wb) {
|
|
||||||
b.Fatalf("got %v; want %v", n, len(wb))
|
|
||||||
}
|
|
||||||
if _, _, _, err := p.ReadFrom(rb); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "nacl", "plan9", "solaris", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := net.ListenPacket("udp6", "[::1]:0")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
defer p.Close()
|
|
||||||
|
|
||||||
dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback)
|
|
||||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
|
||||||
wb := []byte("HELLO-R-U-THERE")
|
|
||||||
|
|
||||||
if err := p.SetControlMessage(cf, true); err != nil { // probe before test
|
|
||||||
if nettest.ProtocolNotSupported(err) {
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
reader := func() {
|
|
||||||
defer wg.Done()
|
|
||||||
rb := make([]byte, 128)
|
|
||||||
if n, cm, _, err := p.ReadFrom(rb); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
} else if !bytes.Equal(rb[:n], wb) {
|
|
||||||
t.Errorf("got %v; want %v", rb[:n], wb)
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
t.Logf("rcvd cmsg: %v", cm)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writer := func(toggle bool) {
|
|
||||||
defer wg.Done()
|
|
||||||
cm := ipv6.ControlMessage{
|
|
||||||
TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
|
|
||||||
Src: net.IPv6loopback,
|
|
||||||
}
|
|
||||||
if ifi != nil {
|
|
||||||
cm.IfIndex = ifi.Index
|
|
||||||
}
|
|
||||||
if err := p.SetControlMessage(cf, toggle); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
} else if n != len(wb) {
|
|
||||||
t.Errorf("got %v; want %v", n, len(wb))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const N = 10
|
|
||||||
wg.Add(N)
|
|
||||||
for i := 0; i < N; i++ {
|
|
||||||
go reader()
|
|
||||||
}
|
|
||||||
wg.Add(2 * N)
|
|
||||||
for i := 0; i < 2*N; i++ {
|
|
||||||
go writer(i%2 != 0)
|
|
||||||
}
|
|
||||||
wg.Add(N)
|
|
||||||
for i := 0; i < N; i++ {
|
|
||||||
go reader()
|
|
||||||
}
|
|
||||||
wg.Wait()
|
|
||||||
}
|
|
||||||
-46
@@ -1,46 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
// Sticky socket options
|
|
||||||
const (
|
|
||||||
ssoTrafficClass = iota // header field for unicast packet, RFC 3542
|
|
||||||
ssoHopLimit // header field for unicast packet, RFC 3493
|
|
||||||
ssoMulticastInterface // outbound interface for multicast packet, RFC 3493
|
|
||||||
ssoMulticastHopLimit // header field for multicast packet, RFC 3493
|
|
||||||
ssoMulticastLoopback // loopback for multicast packet, RFC 3493
|
|
||||||
ssoReceiveTrafficClass // header field on received packet, RFC 3542
|
|
||||||
ssoReceiveHopLimit // header field on received packet, RFC 2292 or 3542
|
|
||||||
ssoReceivePacketInfo // incbound or outbound packet path, RFC 2292 or 3542
|
|
||||||
ssoReceivePathMTU // path mtu, RFC 3542
|
|
||||||
ssoPathMTU // path mtu, RFC 3542
|
|
||||||
ssoChecksum // packet checksum, RFC 2292 or 3542
|
|
||||||
ssoICMPFilter // icmp filter, RFC 2292 or 3542
|
|
||||||
ssoJoinGroup // any-source multicast, RFC 3493
|
|
||||||
ssoLeaveGroup // any-source multicast, RFC 3493
|
|
||||||
ssoJoinSourceGroup // source-specific multicast
|
|
||||||
ssoLeaveSourceGroup // source-specific multicast
|
|
||||||
ssoBlockSourceGroup // any-source or source-specific multicast
|
|
||||||
ssoUnblockSourceGroup // any-source or source-specific multicast
|
|
||||||
ssoMax
|
|
||||||
)
|
|
||||||
|
|
||||||
// Sticky socket option value types
|
|
||||||
const (
|
|
||||||
ssoTypeInt = iota + 1
|
|
||||||
ssoTypeInterface
|
|
||||||
ssoTypeICMPFilter
|
|
||||||
ssoTypeMTUInfo
|
|
||||||
ssoTypeIPMreq
|
|
||||||
ssoTypeGroupReq
|
|
||||||
ssoTypeGroupSourceReq
|
|
||||||
)
|
|
||||||
|
|
||||||
// A sockOpt represents a binding for sticky socket option.
|
|
||||||
type sockOpt struct {
|
|
||||||
level int // option level
|
|
||||||
name int // option name, must be equal or greater than 1
|
|
||||||
typ int // option value type, must be equal or greater than 1
|
|
||||||
}
|
|
||||||
-22
@@ -1,22 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build darwin dragonfly freebsd linux netbsd openbsd
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
func setsockoptIPMreq(fd int, opt *sockOpt, ifi *net.Interface, grp net.IP) error {
|
|
||||||
var mreq sysIPv6Mreq
|
|
||||||
copy(mreq.Multiaddr[:], grp)
|
|
||||||
if ifi != nil {
|
|
||||||
mreq.setIfindex(ifi.Index)
|
|
||||||
}
|
|
||||||
return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, unsafe.Pointer(&mreq), sysSizeofIPv6Mreq))
|
|
||||||
}
|
|
||||||
-21
@@ -1,21 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
func setsockoptIPMreq(fd syscall.Handle, opt *sockOpt, ifi *net.Interface, grp net.IP) error {
|
|
||||||
var mreq sysIPv6Mreq
|
|
||||||
copy(mreq.Multiaddr[:], grp)
|
|
||||||
if ifi != nil {
|
|
||||||
mreq.setIfindex(ifi.Index)
|
|
||||||
}
|
|
||||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, int32(opt.level), int32(opt.name), (*byte)(unsafe.Pointer(&mreq)), sysSizeofIPv6Mreq))
|
|
||||||
}
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !darwin,!freebsd,!linux
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import "net"
|
|
||||||
|
|
||||||
func setsockoptGroupReq(fd int, opt *sockOpt, ifi *net.Interface, grp net.IP) error {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
func setsockoptGroupSourceReq(fd int, opt *sockOpt, ifi *net.Interface, grp, src net.IP) error {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
-59
@@ -1,59 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build darwin freebsd linux
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
var freebsd32o64 bool
|
|
||||||
|
|
||||||
func setsockoptGroupReq(fd int, opt *sockOpt, ifi *net.Interface, grp net.IP) error {
|
|
||||||
var gr sysGroupReq
|
|
||||||
if ifi != nil {
|
|
||||||
gr.Interface = uint32(ifi.Index)
|
|
||||||
}
|
|
||||||
gr.setGroup(grp)
|
|
||||||
var p unsafe.Pointer
|
|
||||||
var l sysSockoptLen
|
|
||||||
if freebsd32o64 {
|
|
||||||
var d [sysSizeofGroupReq + 4]byte
|
|
||||||
s := (*[sysSizeofGroupReq]byte)(unsafe.Pointer(&gr))
|
|
||||||
copy(d[:4], s[:4])
|
|
||||||
copy(d[8:], s[4:])
|
|
||||||
p = unsafe.Pointer(&d[0])
|
|
||||||
l = sysSizeofGroupReq + 4
|
|
||||||
} else {
|
|
||||||
p = unsafe.Pointer(&gr)
|
|
||||||
l = sysSizeofGroupReq
|
|
||||||
}
|
|
||||||
return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, p, l))
|
|
||||||
}
|
|
||||||
|
|
||||||
func setsockoptGroupSourceReq(fd int, opt *sockOpt, ifi *net.Interface, grp, src net.IP) error {
|
|
||||||
var gsr sysGroupSourceReq
|
|
||||||
if ifi != nil {
|
|
||||||
gsr.Interface = uint32(ifi.Index)
|
|
||||||
}
|
|
||||||
gsr.setSourceGroup(grp, src)
|
|
||||||
var p unsafe.Pointer
|
|
||||||
var l sysSockoptLen
|
|
||||||
if freebsd32o64 {
|
|
||||||
var d [sysSizeofGroupSourceReq + 4]byte
|
|
||||||
s := (*[sysSizeofGroupSourceReq]byte)(unsafe.Pointer(&gsr))
|
|
||||||
copy(d[:4], s[:4])
|
|
||||||
copy(d[8:], s[4:])
|
|
||||||
p = unsafe.Pointer(&d[0])
|
|
||||||
l = sysSizeofGroupSourceReq + 4
|
|
||||||
} else {
|
|
||||||
p = unsafe.Pointer(&gsr)
|
|
||||||
l = sysSizeofGroupSourceReq
|
|
||||||
}
|
|
||||||
return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, p, l))
|
|
||||||
}
|
|
||||||
-13
@@ -1,13 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build nacl plan9 solaris
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import "net"
|
|
||||||
|
|
||||||
func getMTUInfo(fd int, opt *sockOpt) (*net.Interface, int, error) {
|
|
||||||
return nil, 0, errOpNoSupport
|
|
||||||
}
|
|
||||||
-133
@@ -1,133 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
"golang.org/x/net/internal/nettest"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
var supportsIPv6 bool = nettest.SupportsIPv6()
|
|
||||||
|
|
||||||
func TestConnInitiatorPathMTU(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "nacl", "plan9", "solaris", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
ln, err := net.Listen("tcp6", "[::1]:0")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer ln.Close()
|
|
||||||
|
|
||||||
done := make(chan bool)
|
|
||||||
go acceptor(t, ln, done)
|
|
||||||
|
|
||||||
c, err := net.Dial("tcp6", ln.Addr().String())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
if pmtu, err := ipv6.NewConn(c).PathMTU(); err != nil {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "darwin": // older darwin kernels don't support IPV6_PATHMTU option
|
|
||||||
t.Logf("not supported on %s", runtime.GOOS)
|
|
||||||
default:
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
t.Logf("path mtu for %v: %v", c.RemoteAddr(), pmtu)
|
|
||||||
}
|
|
||||||
|
|
||||||
<-done
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestConnResponderPathMTU(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "nacl", "plan9", "solaris", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
ln, err := net.Listen("tcp6", "[::1]:0")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer ln.Close()
|
|
||||||
|
|
||||||
done := make(chan bool)
|
|
||||||
go connector(t, "tcp6", ln.Addr().String(), done)
|
|
||||||
|
|
||||||
c, err := ln.Accept()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
if pmtu, err := ipv6.NewConn(c).PathMTU(); err != nil {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "darwin": // older darwin kernels don't support IPV6_PATHMTU option
|
|
||||||
t.Logf("not supported on %s", runtime.GOOS)
|
|
||||||
default:
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
t.Logf("path mtu for %v: %v", c.RemoteAddr(), pmtu)
|
|
||||||
}
|
|
||||||
|
|
||||||
<-done
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPacketConnChecksum(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "nacl", "plan9", "solaris", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
|
||||||
t.Skip(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := net.ListenPacket(fmt.Sprintf("ip6:%d", iana.ProtocolOSPFIGP), "::") // OSPF for IPv6
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
offset := 12 // see RFC 5340
|
|
||||||
|
|
||||||
for _, toggle := range []bool{false, true} {
|
|
||||||
if err := p.SetChecksum(toggle, offset); err != nil {
|
|
||||||
if toggle {
|
|
||||||
t.Fatalf("ipv6.PacketConn.SetChecksum(%v, %v) failed: %v", toggle, offset, err)
|
|
||||||
} else {
|
|
||||||
// Some platforms never allow to disable the kernel
|
|
||||||
// checksum processing.
|
|
||||||
t.Logf("ipv6.PacketConn.SetChecksum(%v, %v) failed: %v", toggle, offset, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if on, offset, err := p.Checksum(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else {
|
|
||||||
t.Logf("kernel checksum processing enabled=%v, offset=%v", on, offset)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-122
@@ -1,122 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build darwin dragonfly freebsd linux netbsd openbsd
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
func getInt(fd int, opt *sockOpt) (int, error) {
|
|
||||||
if opt.name < 1 || opt.typ != ssoTypeInt {
|
|
||||||
return 0, errOpNoSupport
|
|
||||||
}
|
|
||||||
var i int32
|
|
||||||
l := sysSockoptLen(4)
|
|
||||||
if err := getsockopt(fd, opt.level, opt.name, unsafe.Pointer(&i), &l); err != nil {
|
|
||||||
return 0, os.NewSyscallError("getsockopt", err)
|
|
||||||
}
|
|
||||||
return int(i), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setInt(fd int, opt *sockOpt, v int) error {
|
|
||||||
if opt.name < 1 || opt.typ != ssoTypeInt {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
i := int32(v)
|
|
||||||
return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, unsafe.Pointer(&i), sysSockoptLen(4)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func getInterface(fd int, opt *sockOpt) (*net.Interface, error) {
|
|
||||||
if opt.name < 1 || opt.typ != ssoTypeInterface {
|
|
||||||
return nil, errOpNoSupport
|
|
||||||
}
|
|
||||||
var i int32
|
|
||||||
l := sysSockoptLen(4)
|
|
||||||
if err := getsockopt(fd, opt.level, opt.name, unsafe.Pointer(&i), &l); err != nil {
|
|
||||||
return nil, os.NewSyscallError("getsockopt", err)
|
|
||||||
}
|
|
||||||
if i == 0 {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
ifi, err := net.InterfaceByIndex(int(i))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ifi, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setInterface(fd int, opt *sockOpt, ifi *net.Interface) error {
|
|
||||||
if opt.name < 1 || opt.typ != ssoTypeInterface {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
var i int32
|
|
||||||
if ifi != nil {
|
|
||||||
i = int32(ifi.Index)
|
|
||||||
}
|
|
||||||
return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, unsafe.Pointer(&i), sysSockoptLen(4)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func getICMPFilter(fd int, opt *sockOpt) (*ICMPFilter, error) {
|
|
||||||
if opt.name < 1 || opt.typ != ssoTypeICMPFilter {
|
|
||||||
return nil, errOpNoSupport
|
|
||||||
}
|
|
||||||
var f ICMPFilter
|
|
||||||
l := sysSockoptLen(sysSizeofICMPv6Filter)
|
|
||||||
if err := getsockopt(fd, opt.level, opt.name, unsafe.Pointer(&f.sysICMPv6Filter), &l); err != nil {
|
|
||||||
return nil, os.NewSyscallError("getsockopt", err)
|
|
||||||
}
|
|
||||||
return &f, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setICMPFilter(fd int, opt *sockOpt, f *ICMPFilter) error {
|
|
||||||
if opt.name < 1 || opt.typ != ssoTypeICMPFilter {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, unsafe.Pointer(&f.sysICMPv6Filter), sysSizeofICMPv6Filter))
|
|
||||||
}
|
|
||||||
|
|
||||||
func getMTUInfo(fd int, opt *sockOpt) (*net.Interface, int, error) {
|
|
||||||
if opt.name < 1 || opt.typ != ssoTypeMTUInfo {
|
|
||||||
return nil, 0, errOpNoSupport
|
|
||||||
}
|
|
||||||
var mi sysIPv6Mtuinfo
|
|
||||||
l := sysSockoptLen(sysSizeofIPv6Mtuinfo)
|
|
||||||
if err := getsockopt(fd, opt.level, opt.name, unsafe.Pointer(&mi), &l); err != nil {
|
|
||||||
return nil, 0, os.NewSyscallError("getsockopt", err)
|
|
||||||
}
|
|
||||||
if mi.Addr.Scope_id == 0 {
|
|
||||||
return nil, int(mi.Mtu), nil
|
|
||||||
}
|
|
||||||
ifi, err := net.InterfaceByIndex(int(mi.Addr.Scope_id))
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
return ifi, int(mi.Mtu), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setGroup(fd int, opt *sockOpt, ifi *net.Interface, grp net.IP) error {
|
|
||||||
if opt.name < 1 {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
switch opt.typ {
|
|
||||||
case ssoTypeIPMreq:
|
|
||||||
return setsockoptIPMreq(fd, opt, ifi, grp)
|
|
||||||
case ssoTypeGroupReq:
|
|
||||||
return setsockoptGroupReq(fd, opt, ifi, grp)
|
|
||||||
default:
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setSourceGroup(fd int, opt *sockOpt, ifi *net.Interface, grp, src net.IP) error {
|
|
||||||
if opt.name < 1 || opt.typ != ssoTypeGroupSourceReq {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
return setsockoptGroupSourceReq(fd, opt, ifi, grp, src)
|
|
||||||
}
|
|
||||||
-86
@@ -1,86 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
func getInt(fd syscall.Handle, opt *sockOpt) (int, error) {
|
|
||||||
if opt.name < 1 || opt.typ != ssoTypeInt {
|
|
||||||
return 0, errOpNoSupport
|
|
||||||
}
|
|
||||||
var i int32
|
|
||||||
l := int32(4)
|
|
||||||
if err := syscall.Getsockopt(fd, int32(opt.level), int32(opt.name), (*byte)(unsafe.Pointer(&i)), &l); err != nil {
|
|
||||||
return 0, os.NewSyscallError("getsockopt", err)
|
|
||||||
}
|
|
||||||
return int(i), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setInt(fd syscall.Handle, opt *sockOpt, v int) error {
|
|
||||||
if opt.name < 1 || opt.typ != ssoTypeInt {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
i := int32(v)
|
|
||||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, int32(opt.level), int32(opt.name), (*byte)(unsafe.Pointer(&i)), 4))
|
|
||||||
}
|
|
||||||
|
|
||||||
func getInterface(fd syscall.Handle, opt *sockOpt) (*net.Interface, error) {
|
|
||||||
if opt.name < 1 || opt.typ != ssoTypeInterface {
|
|
||||||
return nil, errOpNoSupport
|
|
||||||
}
|
|
||||||
var i int32
|
|
||||||
l := int32(4)
|
|
||||||
if err := syscall.Getsockopt(fd, int32(opt.level), int32(opt.name), (*byte)(unsafe.Pointer(&i)), &l); err != nil {
|
|
||||||
return nil, os.NewSyscallError("getsockopt", err)
|
|
||||||
}
|
|
||||||
if i == 0 {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
ifi, err := net.InterfaceByIndex(int(i))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ifi, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setInterface(fd syscall.Handle, opt *sockOpt, ifi *net.Interface) error {
|
|
||||||
if opt.name < 1 || opt.typ != ssoTypeInterface {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
var i int32
|
|
||||||
if ifi != nil {
|
|
||||||
i = int32(ifi.Index)
|
|
||||||
}
|
|
||||||
return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, int32(opt.level), int32(opt.name), (*byte)(unsafe.Pointer(&i)), 4))
|
|
||||||
}
|
|
||||||
|
|
||||||
func getICMPFilter(fd syscall.Handle, opt *sockOpt) (*ICMPFilter, error) {
|
|
||||||
return nil, errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
func setICMPFilter(fd syscall.Handle, opt *sockOpt, f *ICMPFilter) error {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
func getMTUInfo(fd syscall.Handle, opt *sockOpt) (*net.Interface, int, error) {
|
|
||||||
return nil, 0, errOpNoSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
func setGroup(fd syscall.Handle, opt *sockOpt, ifi *net.Interface, grp net.IP) error {
|
|
||||||
if opt.name < 1 || opt.typ != ssoTypeIPMreq {
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
return setsockoptIPMreq(fd, opt, ifi, grp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setSourceGroup(fd syscall.Handle, opt *sockOpt, ifi *net.Interface, grp, src net.IP) error {
|
|
||||||
// TODO(mikio): implement this
|
|
||||||
return errOpNoSupport
|
|
||||||
}
|
|
||||||
-58
@@ -1,58 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build dragonfly netbsd openbsd
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysSockoptLen int32
|
|
||||||
|
|
||||||
var (
|
|
||||||
ctlOpts = [ctlMax]ctlOpt{
|
|
||||||
ctlTrafficClass: {sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
|
|
||||||
ctlHopLimit: {sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
|
|
||||||
ctlPacketInfo: {sysIPV6_PKTINFO, sysSizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
|
|
||||||
ctlNextHop: {sysIPV6_NEXTHOP, sysSizeofSockaddrInet6, marshalNextHop, parseNextHop},
|
|
||||||
ctlPathMTU: {sysIPV6_PATHMTU, sysSizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
|
|
||||||
}
|
|
||||||
|
|
||||||
sockOpts = [ssoMax]sockOpt{
|
|
||||||
ssoTrafficClass: {iana.ProtocolIPv6, sysIPV6_TCLASS, ssoTypeInt},
|
|
||||||
ssoHopLimit: {iana.ProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt},
|
|
||||||
ssoMulticastInterface: {iana.ProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface},
|
|
||||||
ssoMulticastHopLimit: {iana.ProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt},
|
|
||||||
ssoMulticastLoopback: {iana.ProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt},
|
|
||||||
ssoReceiveTrafficClass: {iana.ProtocolIPv6, sysIPV6_RECVTCLASS, ssoTypeInt},
|
|
||||||
ssoReceiveHopLimit: {iana.ProtocolIPv6, sysIPV6_RECVHOPLIMIT, ssoTypeInt},
|
|
||||||
ssoReceivePacketInfo: {iana.ProtocolIPv6, sysIPV6_RECVPKTINFO, ssoTypeInt},
|
|
||||||
ssoReceivePathMTU: {iana.ProtocolIPv6, sysIPV6_RECVPATHMTU, ssoTypeInt},
|
|
||||||
ssoPathMTU: {iana.ProtocolIPv6, sysIPV6_PATHMTU, ssoTypeMTUInfo},
|
|
||||||
ssoChecksum: {iana.ProtocolIPv6, sysIPV6_CHECKSUM, ssoTypeInt},
|
|
||||||
ssoICMPFilter: {iana.ProtocolIPv6ICMP, sysICMP6_FILTER, ssoTypeICMPFilter},
|
|
||||||
ssoJoinGroup: {iana.ProtocolIPv6, sysIPV6_JOIN_GROUP, ssoTypeIPMreq},
|
|
||||||
ssoLeaveGroup: {iana.ProtocolIPv6, sysIPV6_LEAVE_GROUP, ssoTypeIPMreq},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) {
|
|
||||||
sa.Len = sysSizeofSockaddrInet6
|
|
||||||
sa.Family = syscall.AF_INET6
|
|
||||||
copy(sa.Addr[:], ip)
|
|
||||||
sa.Scope_id = uint32(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pi *sysInet6Pktinfo) setIfindex(i int) {
|
|
||||||
pi.Ifindex = uint32(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mreq *sysIPv6Mreq) setIfindex(i int) {
|
|
||||||
mreq.Interface = uint32(i)
|
|
||||||
}
|
|
||||||
-135
@@ -1,135 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysSockoptLen int32
|
|
||||||
|
|
||||||
var (
|
|
||||||
ctlOpts = [ctlMax]ctlOpt{
|
|
||||||
ctlHopLimit: {sysIPV6_2292HOPLIMIT, 4, marshal2292HopLimit, parseHopLimit},
|
|
||||||
ctlPacketInfo: {sysIPV6_2292PKTINFO, sysSizeofInet6Pktinfo, marshal2292PacketInfo, parsePacketInfo},
|
|
||||||
}
|
|
||||||
|
|
||||||
sockOpts = [ssoMax]sockOpt{
|
|
||||||
ssoHopLimit: {iana.ProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt},
|
|
||||||
ssoMulticastInterface: {iana.ProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface},
|
|
||||||
ssoMulticastHopLimit: {iana.ProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt},
|
|
||||||
ssoMulticastLoopback: {iana.ProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt},
|
|
||||||
ssoReceiveHopLimit: {iana.ProtocolIPv6, sysIPV6_2292HOPLIMIT, ssoTypeInt},
|
|
||||||
ssoReceivePacketInfo: {iana.ProtocolIPv6, sysIPV6_2292PKTINFO, ssoTypeInt},
|
|
||||||
ssoChecksum: {iana.ProtocolIPv6, sysIPV6_CHECKSUM, ssoTypeInt},
|
|
||||||
ssoICMPFilter: {iana.ProtocolIPv6ICMP, sysICMP6_FILTER, ssoTypeICMPFilter},
|
|
||||||
ssoJoinGroup: {iana.ProtocolIPv6, sysIPV6_JOIN_GROUP, ssoTypeIPMreq},
|
|
||||||
ssoLeaveGroup: {iana.ProtocolIPv6, sysIPV6_LEAVE_GROUP, ssoTypeIPMreq},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
// Seems like kern.osreldate is veiled on latest OS X. We use
|
|
||||||
// kern.osrelease instead.
|
|
||||||
osver, err := syscall.Sysctl("kern.osrelease")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var i int
|
|
||||||
for i = range osver {
|
|
||||||
if osver[i] == '.' {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// The IP_PKTINFO and protocol-independent multicast API were
|
|
||||||
// introduced in OS X 10.7 (Darwin 11.0.0). But it looks like
|
|
||||||
// those features require OS X 10.8 (Darwin 12.0.0) and above.
|
|
||||||
// See http://support.apple.com/kb/HT1633.
|
|
||||||
if i > 2 || i == 2 && osver[0] >= '1' && osver[1] >= '2' {
|
|
||||||
ctlOpts[ctlTrafficClass].name = sysIPV6_TCLASS
|
|
||||||
ctlOpts[ctlTrafficClass].length = 4
|
|
||||||
ctlOpts[ctlTrafficClass].marshal = marshalTrafficClass
|
|
||||||
ctlOpts[ctlTrafficClass].parse = parseTrafficClass
|
|
||||||
ctlOpts[ctlHopLimit].name = sysIPV6_HOPLIMIT
|
|
||||||
ctlOpts[ctlHopLimit].marshal = marshalHopLimit
|
|
||||||
ctlOpts[ctlPacketInfo].name = sysIPV6_PKTINFO
|
|
||||||
ctlOpts[ctlPacketInfo].marshal = marshalPacketInfo
|
|
||||||
ctlOpts[ctlNextHop].name = sysIPV6_NEXTHOP
|
|
||||||
ctlOpts[ctlNextHop].length = sysSizeofSockaddrInet6
|
|
||||||
ctlOpts[ctlNextHop].marshal = marshalNextHop
|
|
||||||
ctlOpts[ctlNextHop].parse = parseNextHop
|
|
||||||
ctlOpts[ctlPathMTU].name = sysIPV6_PATHMTU
|
|
||||||
ctlOpts[ctlPathMTU].length = sysSizeofIPv6Mtuinfo
|
|
||||||
ctlOpts[ctlPathMTU].marshal = marshalPathMTU
|
|
||||||
ctlOpts[ctlPathMTU].parse = parsePathMTU
|
|
||||||
sockOpts[ssoTrafficClass].level = iana.ProtocolIPv6
|
|
||||||
sockOpts[ssoTrafficClass].name = sysIPV6_TCLASS
|
|
||||||
sockOpts[ssoTrafficClass].typ = ssoTypeInt
|
|
||||||
sockOpts[ssoReceiveTrafficClass].level = iana.ProtocolIPv6
|
|
||||||
sockOpts[ssoReceiveTrafficClass].name = sysIPV6_RECVTCLASS
|
|
||||||
sockOpts[ssoReceiveTrafficClass].typ = ssoTypeInt
|
|
||||||
sockOpts[ssoReceiveHopLimit].name = sysIPV6_RECVHOPLIMIT
|
|
||||||
sockOpts[ssoReceivePacketInfo].name = sysIPV6_RECVPKTINFO
|
|
||||||
sockOpts[ssoReceivePathMTU].level = iana.ProtocolIPv6
|
|
||||||
sockOpts[ssoReceivePathMTU].name = sysIPV6_RECVPATHMTU
|
|
||||||
sockOpts[ssoReceivePathMTU].typ = ssoTypeInt
|
|
||||||
sockOpts[ssoPathMTU].level = iana.ProtocolIPv6
|
|
||||||
sockOpts[ssoPathMTU].name = sysIPV6_PATHMTU
|
|
||||||
sockOpts[ssoPathMTU].typ = ssoTypeMTUInfo
|
|
||||||
sockOpts[ssoJoinGroup].name = sysMCAST_JOIN_GROUP
|
|
||||||
sockOpts[ssoJoinGroup].typ = ssoTypeGroupReq
|
|
||||||
sockOpts[ssoLeaveGroup].name = sysMCAST_LEAVE_GROUP
|
|
||||||
sockOpts[ssoLeaveGroup].typ = ssoTypeGroupReq
|
|
||||||
sockOpts[ssoJoinSourceGroup].level = iana.ProtocolIPv6
|
|
||||||
sockOpts[ssoJoinSourceGroup].name = sysMCAST_JOIN_SOURCE_GROUP
|
|
||||||
sockOpts[ssoJoinSourceGroup].typ = ssoTypeGroupSourceReq
|
|
||||||
sockOpts[ssoLeaveSourceGroup].level = iana.ProtocolIPv6
|
|
||||||
sockOpts[ssoLeaveSourceGroup].name = sysMCAST_LEAVE_SOURCE_GROUP
|
|
||||||
sockOpts[ssoLeaveSourceGroup].typ = ssoTypeGroupSourceReq
|
|
||||||
sockOpts[ssoBlockSourceGroup].level = iana.ProtocolIPv6
|
|
||||||
sockOpts[ssoBlockSourceGroup].name = sysMCAST_BLOCK_SOURCE
|
|
||||||
sockOpts[ssoBlockSourceGroup].typ = ssoTypeGroupSourceReq
|
|
||||||
sockOpts[ssoUnblockSourceGroup].level = iana.ProtocolIPv6
|
|
||||||
sockOpts[ssoUnblockSourceGroup].name = sysMCAST_UNBLOCK_SOURCE
|
|
||||||
sockOpts[ssoUnblockSourceGroup].typ = ssoTypeGroupSourceReq
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) {
|
|
||||||
sa.Len = sysSizeofSockaddrInet6
|
|
||||||
sa.Family = syscall.AF_INET6
|
|
||||||
copy(sa.Addr[:], ip)
|
|
||||||
sa.Scope_id = uint32(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pi *sysInet6Pktinfo) setIfindex(i int) {
|
|
||||||
pi.Ifindex = uint32(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mreq *sysIPv6Mreq) setIfindex(i int) {
|
|
||||||
mreq.Interface = uint32(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gr *sysGroupReq) setGroup(grp net.IP) {
|
|
||||||
sa := (*sysSockaddrInet6)(unsafe.Pointer(&gr.Pad_cgo_0[0]))
|
|
||||||
sa.Len = sysSizeofSockaddrInet6
|
|
||||||
sa.Family = syscall.AF_INET6
|
|
||||||
copy(sa.Addr[:], grp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gsr *sysGroupSourceReq) setSourceGroup(grp, src net.IP) {
|
|
||||||
sa := (*sysSockaddrInet6)(unsafe.Pointer(&gsr.Pad_cgo_0[0]))
|
|
||||||
sa.Len = sysSizeofSockaddrInet6
|
|
||||||
sa.Family = syscall.AF_INET6
|
|
||||||
copy(sa.Addr[:], grp)
|
|
||||||
sa = (*sysSockaddrInet6)(unsafe.Pointer(&gsr.Pad_cgo_1[0]))
|
|
||||||
sa.Len = sysSizeofSockaddrInet6
|
|
||||||
sa.Family = syscall.AF_INET6
|
|
||||||
copy(sa.Addr[:], src)
|
|
||||||
}
|
|
||||||
-93
@@ -1,93 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysSockoptLen int32
|
|
||||||
|
|
||||||
var (
|
|
||||||
ctlOpts = [ctlMax]ctlOpt{
|
|
||||||
ctlTrafficClass: {sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
|
|
||||||
ctlHopLimit: {sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
|
|
||||||
ctlPacketInfo: {sysIPV6_PKTINFO, sysSizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
|
|
||||||
ctlNextHop: {sysIPV6_NEXTHOP, sysSizeofSockaddrInet6, marshalNextHop, parseNextHop},
|
|
||||||
ctlPathMTU: {sysIPV6_PATHMTU, sysSizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
|
|
||||||
}
|
|
||||||
|
|
||||||
sockOpts = [ssoMax]sockOpt{
|
|
||||||
ssoTrafficClass: {iana.ProtocolIPv6, sysIPV6_TCLASS, ssoTypeInt},
|
|
||||||
ssoHopLimit: {iana.ProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt},
|
|
||||||
ssoMulticastInterface: {iana.ProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface},
|
|
||||||
ssoMulticastHopLimit: {iana.ProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt},
|
|
||||||
ssoMulticastLoopback: {iana.ProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt},
|
|
||||||
ssoReceiveTrafficClass: {iana.ProtocolIPv6, sysIPV6_RECVTCLASS, ssoTypeInt},
|
|
||||||
ssoReceiveHopLimit: {iana.ProtocolIPv6, sysIPV6_RECVHOPLIMIT, ssoTypeInt},
|
|
||||||
ssoReceivePacketInfo: {iana.ProtocolIPv6, sysIPV6_RECVPKTINFO, ssoTypeInt},
|
|
||||||
ssoReceivePathMTU: {iana.ProtocolIPv6, sysIPV6_RECVPATHMTU, ssoTypeInt},
|
|
||||||
ssoPathMTU: {iana.ProtocolIPv6, sysIPV6_PATHMTU, ssoTypeMTUInfo},
|
|
||||||
ssoChecksum: {iana.ProtocolIPv6, sysIPV6_CHECKSUM, ssoTypeInt},
|
|
||||||
ssoICMPFilter: {iana.ProtocolIPv6ICMP, sysICMP6_FILTER, ssoTypeICMPFilter},
|
|
||||||
ssoJoinGroup: {iana.ProtocolIPv6, sysMCAST_JOIN_GROUP, ssoTypeGroupReq},
|
|
||||||
ssoLeaveGroup: {iana.ProtocolIPv6, sysMCAST_LEAVE_GROUP, ssoTypeGroupReq},
|
|
||||||
ssoJoinSourceGroup: {iana.ProtocolIPv6, sysMCAST_JOIN_SOURCE_GROUP, ssoTypeGroupSourceReq},
|
|
||||||
ssoLeaveSourceGroup: {iana.ProtocolIPv6, sysMCAST_LEAVE_SOURCE_GROUP, ssoTypeGroupSourceReq},
|
|
||||||
ssoBlockSourceGroup: {iana.ProtocolIPv6, sysMCAST_BLOCK_SOURCE, ssoTypeGroupSourceReq},
|
|
||||||
ssoUnblockSourceGroup: {iana.ProtocolIPv6, sysMCAST_UNBLOCK_SOURCE, ssoTypeGroupSourceReq},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
if runtime.GOOS == "freebsd" && runtime.GOARCH == "386" {
|
|
||||||
archs, _ := syscall.Sysctl("kern.supported_archs")
|
|
||||||
for _, s := range strings.Fields(archs) {
|
|
||||||
if s == "amd64" {
|
|
||||||
freebsd32o64 = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) {
|
|
||||||
sa.Len = sysSizeofSockaddrInet6
|
|
||||||
sa.Family = syscall.AF_INET6
|
|
||||||
copy(sa.Addr[:], ip)
|
|
||||||
sa.Scope_id = uint32(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pi *sysInet6Pktinfo) setIfindex(i int) {
|
|
||||||
pi.Ifindex = uint32(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mreq *sysIPv6Mreq) setIfindex(i int) {
|
|
||||||
mreq.Interface = uint32(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gr *sysGroupReq) setGroup(grp net.IP) {
|
|
||||||
sa := (*sysSockaddrInet6)(unsafe.Pointer(&gr.Group))
|
|
||||||
sa.Len = sysSizeofSockaddrInet6
|
|
||||||
sa.Family = syscall.AF_INET6
|
|
||||||
copy(sa.Addr[:], grp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gsr *sysGroupSourceReq) setSourceGroup(grp, src net.IP) {
|
|
||||||
sa := (*sysSockaddrInet6)(unsafe.Pointer(&gsr.Group))
|
|
||||||
sa.Len = sysSizeofSockaddrInet6
|
|
||||||
sa.Family = syscall.AF_INET6
|
|
||||||
copy(sa.Addr[:], grp)
|
|
||||||
sa = (*sysSockaddrInet6)(unsafe.Pointer(&gsr.Source))
|
|
||||||
sa.Len = sysSizeofSockaddrInet6
|
|
||||||
sa.Family = syscall.AF_INET6
|
|
||||||
copy(sa.Addr[:], src)
|
|
||||||
}
|
|
||||||
-74
@@ -1,74 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysSockoptLen int32
|
|
||||||
|
|
||||||
var (
|
|
||||||
ctlOpts = [ctlMax]ctlOpt{
|
|
||||||
ctlTrafficClass: {sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
|
|
||||||
ctlHopLimit: {sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
|
|
||||||
ctlPacketInfo: {sysIPV6_PKTINFO, sysSizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
|
|
||||||
ctlPathMTU: {sysIPV6_PATHMTU, sysSizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
|
|
||||||
}
|
|
||||||
|
|
||||||
sockOpts = [ssoMax]sockOpt{
|
|
||||||
ssoTrafficClass: {iana.ProtocolIPv6, sysIPV6_TCLASS, ssoTypeInt},
|
|
||||||
ssoHopLimit: {iana.ProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt},
|
|
||||||
ssoMulticastInterface: {iana.ProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface},
|
|
||||||
ssoMulticastHopLimit: {iana.ProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt},
|
|
||||||
ssoMulticastLoopback: {iana.ProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt},
|
|
||||||
ssoReceiveTrafficClass: {iana.ProtocolIPv6, sysIPV6_RECVTCLASS, ssoTypeInt},
|
|
||||||
ssoReceiveHopLimit: {iana.ProtocolIPv6, sysIPV6_RECVHOPLIMIT, ssoTypeInt},
|
|
||||||
ssoReceivePacketInfo: {iana.ProtocolIPv6, sysIPV6_RECVPKTINFO, ssoTypeInt},
|
|
||||||
ssoReceivePathMTU: {iana.ProtocolIPv6, sysIPV6_RECVPATHMTU, ssoTypeInt},
|
|
||||||
ssoPathMTU: {iana.ProtocolIPv6, sysIPV6_PATHMTU, ssoTypeMTUInfo},
|
|
||||||
ssoChecksum: {iana.ProtocolReserved, sysIPV6_CHECKSUM, ssoTypeInt},
|
|
||||||
ssoICMPFilter: {iana.ProtocolIPv6ICMP, sysICMPV6_FILTER, ssoTypeICMPFilter},
|
|
||||||
ssoJoinGroup: {iana.ProtocolIPv6, sysMCAST_JOIN_GROUP, ssoTypeGroupReq},
|
|
||||||
ssoLeaveGroup: {iana.ProtocolIPv6, sysMCAST_LEAVE_GROUP, ssoTypeGroupReq},
|
|
||||||
ssoJoinSourceGroup: {iana.ProtocolIPv6, sysMCAST_JOIN_SOURCE_GROUP, ssoTypeGroupSourceReq},
|
|
||||||
ssoLeaveSourceGroup: {iana.ProtocolIPv6, sysMCAST_LEAVE_SOURCE_GROUP, ssoTypeGroupSourceReq},
|
|
||||||
ssoBlockSourceGroup: {iana.ProtocolIPv6, sysMCAST_BLOCK_SOURCE, ssoTypeGroupSourceReq},
|
|
||||||
ssoUnblockSourceGroup: {iana.ProtocolIPv6, sysMCAST_UNBLOCK_SOURCE, ssoTypeGroupSourceReq},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) {
|
|
||||||
sa.Family = syscall.AF_INET6
|
|
||||||
copy(sa.Addr[:], ip)
|
|
||||||
sa.Scope_id = uint32(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pi *sysInet6Pktinfo) setIfindex(i int) {
|
|
||||||
pi.Ifindex = int32(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mreq *sysIPv6Mreq) setIfindex(i int) {
|
|
||||||
mreq.Ifindex = int32(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gr *sysGroupReq) setGroup(grp net.IP) {
|
|
||||||
sa := (*sysSockaddrInet6)(unsafe.Pointer(&gr.Group))
|
|
||||||
sa.Family = syscall.AF_INET6
|
|
||||||
copy(sa.Addr[:], grp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gsr *sysGroupSourceReq) setSourceGroup(grp, src net.IP) {
|
|
||||||
sa := (*sysSockaddrInet6)(unsafe.Pointer(&gsr.Group))
|
|
||||||
sa.Family = syscall.AF_INET6
|
|
||||||
copy(sa.Addr[:], grp)
|
|
||||||
sa = (*sysSockaddrInet6)(unsafe.Pointer(&gsr.Source))
|
|
||||||
sa.Family = syscall.AF_INET6
|
|
||||||
copy(sa.Addr[:], src)
|
|
||||||
}
|
|
||||||
-15
@@ -1,15 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build nacl plan9 solaris
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
type sysSockoptLen int32
|
|
||||||
|
|
||||||
var (
|
|
||||||
ctlOpts = [ctlMax]ctlOpt{}
|
|
||||||
|
|
||||||
sockOpts = [ssoMax]sockOpt{}
|
|
||||||
)
|
|
||||||
-63
@@ -1,63 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// See ws2tcpip.h.
|
|
||||||
sysIPV6_UNICAST_HOPS = 0x4
|
|
||||||
sysIPV6_MULTICAST_IF = 0x9
|
|
||||||
sysIPV6_MULTICAST_HOPS = 0xa
|
|
||||||
sysIPV6_MULTICAST_LOOP = 0xb
|
|
||||||
sysIPV6_JOIN_GROUP = 0xc
|
|
||||||
sysIPV6_LEAVE_GROUP = 0xd
|
|
||||||
sysIPV6_PKTINFO = 0x13
|
|
||||||
|
|
||||||
sysSizeofSockaddrInet6 = 0x1c
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = 0x14
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysSockaddrInet6 struct {
|
|
||||||
Family uint16
|
|
||||||
Port uint16
|
|
||||||
Flowinfo uint32
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Scope_id uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mreq struct {
|
|
||||||
Multiaddr [16]byte /* in6_addr */
|
|
||||||
Interface uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
ctlOpts = [ctlMax]ctlOpt{}
|
|
||||||
|
|
||||||
sockOpts = [ssoMax]sockOpt{
|
|
||||||
ssoHopLimit: {iana.ProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt},
|
|
||||||
ssoMulticastInterface: {iana.ProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface},
|
|
||||||
ssoMulticastHopLimit: {iana.ProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt},
|
|
||||||
ssoMulticastLoopback: {iana.ProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt},
|
|
||||||
ssoJoinGroup: {iana.ProtocolIPv6, sysIPV6_JOIN_GROUP, ssoTypeIPMreq},
|
|
||||||
ssoLeaveGroup: {iana.ProtocolIPv6, sysIPV6_LEAVE_GROUP, ssoTypeIPMreq},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) {
|
|
||||||
sa.Family = syscall.AF_INET6
|
|
||||||
copy(sa.Addr[:], ip)
|
|
||||||
sa.Scope_id = uint32(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mreq *sysIPv6Mreq) setIfindex(i int) {
|
|
||||||
mreq.Interface = uint32(i)
|
|
||||||
}
|
|
||||||
-31
@@ -1,31 +0,0 @@
|
|||||||
// Copyright 2009 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysGETSOCKOPT = 0xf
|
|
||||||
sysSETSOCKOPT = 0xe
|
|
||||||
)
|
|
||||||
|
|
||||||
func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno)
|
|
||||||
|
|
||||||
func getsockopt(fd, level, name int, v unsafe.Pointer, l *sysSockoptLen) error {
|
|
||||||
if _, errno := socketcall(sysGETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 {
|
|
||||||
return error(errno)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setsockopt(fd, level, name int, v unsafe.Pointer, l sysSockoptLen) error {
|
|
||||||
if _, errno := socketcall(sysSETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(l), 0); errno != 0 {
|
|
||||||
return error(errno)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
-26
@@ -1,26 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build darwin dragonfly freebsd linux,!386 netbsd openbsd
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
func getsockopt(fd, level, name int, v unsafe.Pointer, l *sysSockoptLen) error {
|
|
||||||
if _, _, errno := syscall.Syscall6(syscall.SYS_GETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 {
|
|
||||||
return error(errno)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setsockopt(fd, level, name int, v unsafe.Pointer, l sysSockoptLen) error {
|
|
||||||
if _, _, errno := syscall.Syscall6(syscall.SYS_SETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(l), 0); errno != 0 {
|
|
||||||
return error(errno)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
-8
@@ -1,8 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build go1.2
|
|
||||||
|
|
||||||
TEXT ·socketcall(SB),4,$0-36
|
|
||||||
JMP syscall·socketcall(SB)
|
|
||||||
-185
@@ -1,185 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/net/icmp"
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
"golang.org/x/net/internal/nettest"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "nacl", "plan9", "solaris", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := net.ListenPacket("udp6", "[::1]:0")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
defer p.Close()
|
|
||||||
|
|
||||||
dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cm := ipv6.ControlMessage{
|
|
||||||
TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
|
|
||||||
Src: net.IPv6loopback,
|
|
||||||
}
|
|
||||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
|
||||||
ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback)
|
|
||||||
if ifi != nil {
|
|
||||||
cm.IfIndex = ifi.Index
|
|
||||||
}
|
|
||||||
wb := []byte("HELLO-R-U-THERE")
|
|
||||||
|
|
||||||
for i, toggle := range []bool{true, false, true} {
|
|
||||||
if err := p.SetControlMessage(cf, toggle); err != nil {
|
|
||||||
if nettest.ProtocolNotSupported(err) {
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
cm.HopLimit = i + 1
|
|
||||||
if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if n != len(wb) {
|
|
||||||
t.Fatalf("got %v; want %v", n, len(wb))
|
|
||||||
}
|
|
||||||
rb := make([]byte, 128)
|
|
||||||
if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if n, cm, _, err := p.ReadFrom(rb); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if !bytes.Equal(rb[:n], wb) {
|
|
||||||
t.Fatalf("got %v; want %v", rb[:n], wb)
|
|
||||||
} else {
|
|
||||||
t.Logf("rcvd cmsg: %v", cm)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "nacl", "plan9", "solaris", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
if m, ok := nettest.SupportsRawIPSocket(); !ok {
|
|
||||||
t.Skip(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := net.ListenPacket("ip6:ipv6-icmp", "::1")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
p := ipv6.NewPacketConn(c)
|
|
||||||
defer p.Close()
|
|
||||||
|
|
||||||
dst, err := net.ResolveIPAddr("ip6", "::1")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
pshicmp := icmp.IPv6PseudoHeader(c.LocalAddr().(*net.IPAddr).IP, dst.IP)
|
|
||||||
cm := ipv6.ControlMessage{
|
|
||||||
TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
|
|
||||||
Src: net.IPv6loopback,
|
|
||||||
}
|
|
||||||
cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
|
|
||||||
ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback)
|
|
||||||
if ifi != nil {
|
|
||||||
cm.IfIndex = ifi.Index
|
|
||||||
}
|
|
||||||
|
|
||||||
var f ipv6.ICMPFilter
|
|
||||||
f.SetAll(true)
|
|
||||||
f.Accept(ipv6.ICMPTypeEchoReply)
|
|
||||||
if err := p.SetICMPFilter(&f); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var psh []byte
|
|
||||||
for i, toggle := range []bool{true, false, true} {
|
|
||||||
if toggle {
|
|
||||||
psh = nil
|
|
||||||
if err := p.SetChecksum(true, 2); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
psh = pshicmp
|
|
||||||
// Some platforms never allow to disable the
|
|
||||||
// kernel checksum processing.
|
|
||||||
p.SetChecksum(false, -1)
|
|
||||||
}
|
|
||||||
wb, err := (&icmp.Message{
|
|
||||||
Type: ipv6.ICMPTypeEchoRequest, Code: 0,
|
|
||||||
Body: &icmp.Echo{
|
|
||||||
ID: os.Getpid() & 0xffff, Seq: i + 1,
|
|
||||||
Data: []byte("HELLO-R-U-THERE"),
|
|
||||||
},
|
|
||||||
}).Marshal(psh)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := p.SetControlMessage(cf, toggle); err != nil {
|
|
||||||
if nettest.ProtocolNotSupported(err) {
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
cm.HopLimit = i + 1
|
|
||||||
if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if n != len(wb) {
|
|
||||||
t.Fatalf("got %v; want %v", n, len(wb))
|
|
||||||
}
|
|
||||||
rb := make([]byte, 128)
|
|
||||||
if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if n, cm, _, err := p.ReadFrom(rb); err != nil {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "darwin": // older darwin kernels have some limitation on receiving icmp packet through raw socket
|
|
||||||
t.Logf("not supported on %s", runtime.GOOS)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
t.Fatal(err)
|
|
||||||
} else {
|
|
||||||
t.Logf("rcvd cmsg: %v", cm)
|
|
||||||
if m, err := icmp.ParseMessage(iana.ProtocolIPv6ICMP, rb[:n]); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if m.Type != ipv6.ICMPTypeEchoReply || m.Code != 0 {
|
|
||||||
t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv6.ICMPTypeEchoReply, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-111
@@ -1,111 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package ipv6_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"golang.org/x/net/internal/iana"
|
|
||||||
"golang.org/x/net/internal/nettest"
|
|
||||||
"golang.org/x/net/ipv6"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestConnUnicastSocketOptions(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "nacl", "plan9", "solaris", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
ln, err := net.Listen("tcp6", "[::1]:0")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer ln.Close()
|
|
||||||
|
|
||||||
done := make(chan bool)
|
|
||||||
go acceptor(t, ln, done)
|
|
||||||
|
|
||||||
c, err := net.Dial("tcp6", ln.Addr().String())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
testUnicastSocketOptions(t, ipv6.NewConn(c))
|
|
||||||
|
|
||||||
<-done
|
|
||||||
}
|
|
||||||
|
|
||||||
var packetConnUnicastSocketOptionTests = []struct {
|
|
||||||
net, proto, addr string
|
|
||||||
}{
|
|
||||||
{"udp6", "", "[::1]:0"},
|
|
||||||
{"ip6", ":ipv6-icmp", "::1"},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPacketConnUnicastSocketOptions(t *testing.T) {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "nacl", "plan9", "solaris", "windows":
|
|
||||||
t.Skipf("not supported on %s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
if !supportsIPv6 {
|
|
||||||
t.Skip("ipv6 is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
m, ok := nettest.SupportsRawIPSocket()
|
|
||||||
for _, tt := range packetConnUnicastSocketOptionTests {
|
|
||||||
if tt.net == "ip6" && !ok {
|
|
||||||
t.Log(m)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
testUnicastSocketOptions(t, ipv6.NewPacketConn(c))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type testIPv6UnicastConn interface {
|
|
||||||
TrafficClass() (int, error)
|
|
||||||
SetTrafficClass(int) error
|
|
||||||
HopLimit() (int, error)
|
|
||||||
SetHopLimit(int) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func testUnicastSocketOptions(t *testing.T, c testIPv6UnicastConn) {
|
|
||||||
tclass := iana.DiffServCS0 | iana.NotECNTransport
|
|
||||||
if err := c.SetTrafficClass(tclass); err != nil {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "darwin": // older darwin kernels don't support IPV6_TCLASS option
|
|
||||||
t.Logf("not supported on %s", runtime.GOOS)
|
|
||||||
goto next
|
|
||||||
}
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if v, err := c.TrafficClass(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if v != tclass {
|
|
||||||
t.Fatalf("got %v; want %v", v, tclass)
|
|
||||||
}
|
|
||||||
|
|
||||||
next:
|
|
||||||
hoplim := 255
|
|
||||||
if err := c.SetHopLimit(hoplim); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if v, err := c.HopLimit(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if v != hoplim {
|
|
||||||
t.Fatalf("got %v; want %v", v, hoplim)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-131
@@ -1,131 +0,0 @@
|
|||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs defs_darwin.go
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_UNICAST_HOPS = 0x4
|
|
||||||
sysIPV6_MULTICAST_IF = 0x9
|
|
||||||
sysIPV6_MULTICAST_HOPS = 0xa
|
|
||||||
sysIPV6_MULTICAST_LOOP = 0xb
|
|
||||||
sysIPV6_JOIN_GROUP = 0xc
|
|
||||||
sysIPV6_LEAVE_GROUP = 0xd
|
|
||||||
|
|
||||||
sysIPV6_PORTRANGE = 0xe
|
|
||||||
sysICMP6_FILTER = 0x12
|
|
||||||
sysIPV6_2292PKTINFO = 0x13
|
|
||||||
sysIPV6_2292HOPLIMIT = 0x14
|
|
||||||
sysIPV6_2292NEXTHOP = 0x15
|
|
||||||
sysIPV6_2292HOPOPTS = 0x16
|
|
||||||
sysIPV6_2292DSTOPTS = 0x17
|
|
||||||
sysIPV6_2292RTHDR = 0x18
|
|
||||||
|
|
||||||
sysIPV6_2292PKTOPTIONS = 0x19
|
|
||||||
|
|
||||||
sysIPV6_CHECKSUM = 0x1a
|
|
||||||
sysIPV6_V6ONLY = 0x1b
|
|
||||||
|
|
||||||
sysIPV6_IPSEC_POLICY = 0x1c
|
|
||||||
|
|
||||||
sysIPV6_RECVTCLASS = 0x23
|
|
||||||
sysIPV6_TCLASS = 0x24
|
|
||||||
|
|
||||||
sysIPV6_RTHDRDSTOPTS = 0x39
|
|
||||||
|
|
||||||
sysIPV6_RECVPKTINFO = 0x3d
|
|
||||||
|
|
||||||
sysIPV6_RECVHOPLIMIT = 0x25
|
|
||||||
sysIPV6_RECVRTHDR = 0x26
|
|
||||||
sysIPV6_RECVHOPOPTS = 0x27
|
|
||||||
sysIPV6_RECVDSTOPTS = 0x28
|
|
||||||
|
|
||||||
sysIPV6_USE_MIN_MTU = 0x2a
|
|
||||||
sysIPV6_RECVPATHMTU = 0x2b
|
|
||||||
|
|
||||||
sysIPV6_PATHMTU = 0x2c
|
|
||||||
|
|
||||||
sysIPV6_PKTINFO = 0x2e
|
|
||||||
sysIPV6_HOPLIMIT = 0x2f
|
|
||||||
sysIPV6_NEXTHOP = 0x30
|
|
||||||
sysIPV6_HOPOPTS = 0x31
|
|
||||||
sysIPV6_DSTOPTS = 0x32
|
|
||||||
sysIPV6_RTHDR = 0x33
|
|
||||||
|
|
||||||
sysIPV6_AUTOFLOWLABEL = 0x3b
|
|
||||||
|
|
||||||
sysIPV6_DONTFRAG = 0x3e
|
|
||||||
|
|
||||||
sysIPV6_PREFER_TEMPADDR = 0x3f
|
|
||||||
|
|
||||||
sysIPV6_MSFILTER = 0x4a
|
|
||||||
sysMCAST_JOIN_GROUP = 0x50
|
|
||||||
sysMCAST_LEAVE_GROUP = 0x51
|
|
||||||
sysMCAST_JOIN_SOURCE_GROUP = 0x52
|
|
||||||
sysMCAST_LEAVE_SOURCE_GROUP = 0x53
|
|
||||||
sysMCAST_BLOCK_SOURCE = 0x54
|
|
||||||
sysMCAST_UNBLOCK_SOURCE = 0x55
|
|
||||||
|
|
||||||
sysIPV6_BOUND_IF = 0x7d
|
|
||||||
|
|
||||||
sysIPV6_PORTRANGE_DEFAULT = 0x0
|
|
||||||
sysIPV6_PORTRANGE_HIGH = 0x1
|
|
||||||
sysIPV6_PORTRANGE_LOW = 0x2
|
|
||||||
|
|
||||||
sysSizeofSockaddrStorage = 0x80
|
|
||||||
sysSizeofSockaddrInet6 = 0x1c
|
|
||||||
sysSizeofInet6Pktinfo = 0x14
|
|
||||||
sysSizeofIPv6Mtuinfo = 0x20
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = 0x14
|
|
||||||
sysSizeofGroupReq = 0x84
|
|
||||||
sysSizeofGroupSourceReq = 0x104
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = 0x20
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysSockaddrStorage struct {
|
|
||||||
Len uint8
|
|
||||||
Family uint8
|
|
||||||
X__ss_pad1 [6]int8
|
|
||||||
X__ss_align int64
|
|
||||||
X__ss_pad2 [112]int8
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysSockaddrInet6 struct {
|
|
||||||
Len uint8
|
|
||||||
Family uint8
|
|
||||||
Port uint16
|
|
||||||
Flowinfo uint32
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Scope_id uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysInet6Pktinfo struct {
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Ifindex uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo struct {
|
|
||||||
Addr sysSockaddrInet6
|
|
||||||
Mtu uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mreq struct {
|
|
||||||
Multiaddr [16]byte /* in6_addr */
|
|
||||||
Interface uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysICMPv6Filter struct {
|
|
||||||
Filt [8]uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Pad_cgo_0 [128]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupSourceReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Pad_cgo_0 [128]byte
|
|
||||||
Pad_cgo_1 [128]byte
|
|
||||||
}
|
|
||||||
-90
@@ -1,90 +0,0 @@
|
|||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs defs_dragonfly.go
|
|
||||||
|
|
||||||
// +build dragonfly
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_UNICAST_HOPS = 0x4
|
|
||||||
sysIPV6_MULTICAST_IF = 0x9
|
|
||||||
sysIPV6_MULTICAST_HOPS = 0xa
|
|
||||||
sysIPV6_MULTICAST_LOOP = 0xb
|
|
||||||
sysIPV6_JOIN_GROUP = 0xc
|
|
||||||
sysIPV6_LEAVE_GROUP = 0xd
|
|
||||||
sysIPV6_PORTRANGE = 0xe
|
|
||||||
sysICMP6_FILTER = 0x12
|
|
||||||
|
|
||||||
sysIPV6_CHECKSUM = 0x1a
|
|
||||||
sysIPV6_V6ONLY = 0x1b
|
|
||||||
|
|
||||||
sysIPV6_IPSEC_POLICY = 0x1c
|
|
||||||
|
|
||||||
sysIPV6_RTHDRDSTOPTS = 0x23
|
|
||||||
sysIPV6_RECVPKTINFO = 0x24
|
|
||||||
sysIPV6_RECVHOPLIMIT = 0x25
|
|
||||||
sysIPV6_RECVRTHDR = 0x26
|
|
||||||
sysIPV6_RECVHOPOPTS = 0x27
|
|
||||||
sysIPV6_RECVDSTOPTS = 0x28
|
|
||||||
|
|
||||||
sysIPV6_USE_MIN_MTU = 0x2a
|
|
||||||
sysIPV6_RECVPATHMTU = 0x2b
|
|
||||||
|
|
||||||
sysIPV6_PATHMTU = 0x2c
|
|
||||||
|
|
||||||
sysIPV6_PKTINFO = 0x2e
|
|
||||||
sysIPV6_HOPLIMIT = 0x2f
|
|
||||||
sysIPV6_NEXTHOP = 0x30
|
|
||||||
sysIPV6_HOPOPTS = 0x31
|
|
||||||
sysIPV6_DSTOPTS = 0x32
|
|
||||||
sysIPV6_RTHDR = 0x33
|
|
||||||
|
|
||||||
sysIPV6_RECVTCLASS = 0x39
|
|
||||||
|
|
||||||
sysIPV6_AUTOFLOWLABEL = 0x3b
|
|
||||||
|
|
||||||
sysIPV6_TCLASS = 0x3d
|
|
||||||
sysIPV6_DONTFRAG = 0x3e
|
|
||||||
|
|
||||||
sysIPV6_PREFER_TEMPADDR = 0x3f
|
|
||||||
|
|
||||||
sysIPV6_PORTRANGE_DEFAULT = 0x0
|
|
||||||
sysIPV6_PORTRANGE_HIGH = 0x1
|
|
||||||
sysIPV6_PORTRANGE_LOW = 0x2
|
|
||||||
|
|
||||||
sysSizeofSockaddrInet6 = 0x1c
|
|
||||||
sysSizeofInet6Pktinfo = 0x14
|
|
||||||
sysSizeofIPv6Mtuinfo = 0x20
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = 0x14
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = 0x20
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysSockaddrInet6 struct {
|
|
||||||
Len uint8
|
|
||||||
Family uint8
|
|
||||||
Port uint16
|
|
||||||
Flowinfo uint32
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Scope_id uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysInet6Pktinfo struct {
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Ifindex uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo struct {
|
|
||||||
Addr sysSockaddrInet6
|
|
||||||
Mtu uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mreq struct {
|
|
||||||
Multiaddr [16]byte /* in6_addr */
|
|
||||||
Interface uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysICMPv6Filter struct {
|
|
||||||
Filt [8]uint32
|
|
||||||
}
|
|
||||||
-122
@@ -1,122 +0,0 @@
|
|||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs defs_freebsd.go
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_UNICAST_HOPS = 0x4
|
|
||||||
sysIPV6_MULTICAST_IF = 0x9
|
|
||||||
sysIPV6_MULTICAST_HOPS = 0xa
|
|
||||||
sysIPV6_MULTICAST_LOOP = 0xb
|
|
||||||
sysIPV6_JOIN_GROUP = 0xc
|
|
||||||
sysIPV6_LEAVE_GROUP = 0xd
|
|
||||||
sysIPV6_PORTRANGE = 0xe
|
|
||||||
sysICMP6_FILTER = 0x12
|
|
||||||
|
|
||||||
sysIPV6_CHECKSUM = 0x1a
|
|
||||||
sysIPV6_V6ONLY = 0x1b
|
|
||||||
|
|
||||||
sysIPV6_IPSEC_POLICY = 0x1c
|
|
||||||
|
|
||||||
sysIPV6_RTHDRDSTOPTS = 0x23
|
|
||||||
|
|
||||||
sysIPV6_RECVPKTINFO = 0x24
|
|
||||||
sysIPV6_RECVHOPLIMIT = 0x25
|
|
||||||
sysIPV6_RECVRTHDR = 0x26
|
|
||||||
sysIPV6_RECVHOPOPTS = 0x27
|
|
||||||
sysIPV6_RECVDSTOPTS = 0x28
|
|
||||||
|
|
||||||
sysIPV6_USE_MIN_MTU = 0x2a
|
|
||||||
sysIPV6_RECVPATHMTU = 0x2b
|
|
||||||
|
|
||||||
sysIPV6_PATHMTU = 0x2c
|
|
||||||
|
|
||||||
sysIPV6_PKTINFO = 0x2e
|
|
||||||
sysIPV6_HOPLIMIT = 0x2f
|
|
||||||
sysIPV6_NEXTHOP = 0x30
|
|
||||||
sysIPV6_HOPOPTS = 0x31
|
|
||||||
sysIPV6_DSTOPTS = 0x32
|
|
||||||
sysIPV6_RTHDR = 0x33
|
|
||||||
|
|
||||||
sysIPV6_RECVTCLASS = 0x39
|
|
||||||
|
|
||||||
sysIPV6_AUTOFLOWLABEL = 0x3b
|
|
||||||
|
|
||||||
sysIPV6_TCLASS = 0x3d
|
|
||||||
sysIPV6_DONTFRAG = 0x3e
|
|
||||||
|
|
||||||
sysIPV6_PREFER_TEMPADDR = 0x3f
|
|
||||||
|
|
||||||
sysIPV6_BINDANY = 0x40
|
|
||||||
|
|
||||||
sysIPV6_MSFILTER = 0x4a
|
|
||||||
|
|
||||||
sysMCAST_JOIN_GROUP = 0x50
|
|
||||||
sysMCAST_LEAVE_GROUP = 0x51
|
|
||||||
sysMCAST_JOIN_SOURCE_GROUP = 0x52
|
|
||||||
sysMCAST_LEAVE_SOURCE_GROUP = 0x53
|
|
||||||
sysMCAST_BLOCK_SOURCE = 0x54
|
|
||||||
sysMCAST_UNBLOCK_SOURCE = 0x55
|
|
||||||
|
|
||||||
sysIPV6_PORTRANGE_DEFAULT = 0x0
|
|
||||||
sysIPV6_PORTRANGE_HIGH = 0x1
|
|
||||||
sysIPV6_PORTRANGE_LOW = 0x2
|
|
||||||
|
|
||||||
sysSizeofSockaddrStorage = 0x80
|
|
||||||
sysSizeofSockaddrInet6 = 0x1c
|
|
||||||
sysSizeofInet6Pktinfo = 0x14
|
|
||||||
sysSizeofIPv6Mtuinfo = 0x20
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = 0x14
|
|
||||||
sysSizeofGroupReq = 0x84
|
|
||||||
sysSizeofGroupSourceReq = 0x104
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = 0x20
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysSockaddrStorage struct {
|
|
||||||
Len uint8
|
|
||||||
Family uint8
|
|
||||||
X__ss_pad1 [6]int8
|
|
||||||
X__ss_align int64
|
|
||||||
X__ss_pad2 [112]int8
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysSockaddrInet6 struct {
|
|
||||||
Len uint8
|
|
||||||
Family uint8
|
|
||||||
Port uint16
|
|
||||||
Flowinfo uint32
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Scope_id uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysInet6Pktinfo struct {
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Ifindex uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo struct {
|
|
||||||
Addr sysSockaddrInet6
|
|
||||||
Mtu uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mreq struct {
|
|
||||||
Multiaddr [16]byte /* in6_addr */
|
|
||||||
Interface uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Group sysSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupSourceReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Group sysSockaddrStorage
|
|
||||||
Source sysSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysICMPv6Filter struct {
|
|
||||||
Filt [8]uint32
|
|
||||||
}
|
|
||||||
-124
@@ -1,124 +0,0 @@
|
|||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs defs_freebsd.go
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_UNICAST_HOPS = 0x4
|
|
||||||
sysIPV6_MULTICAST_IF = 0x9
|
|
||||||
sysIPV6_MULTICAST_HOPS = 0xa
|
|
||||||
sysIPV6_MULTICAST_LOOP = 0xb
|
|
||||||
sysIPV6_JOIN_GROUP = 0xc
|
|
||||||
sysIPV6_LEAVE_GROUP = 0xd
|
|
||||||
sysIPV6_PORTRANGE = 0xe
|
|
||||||
sysICMP6_FILTER = 0x12
|
|
||||||
|
|
||||||
sysIPV6_CHECKSUM = 0x1a
|
|
||||||
sysIPV6_V6ONLY = 0x1b
|
|
||||||
|
|
||||||
sysIPV6_IPSEC_POLICY = 0x1c
|
|
||||||
|
|
||||||
sysIPV6_RTHDRDSTOPTS = 0x23
|
|
||||||
|
|
||||||
sysIPV6_RECVPKTINFO = 0x24
|
|
||||||
sysIPV6_RECVHOPLIMIT = 0x25
|
|
||||||
sysIPV6_RECVRTHDR = 0x26
|
|
||||||
sysIPV6_RECVHOPOPTS = 0x27
|
|
||||||
sysIPV6_RECVDSTOPTS = 0x28
|
|
||||||
|
|
||||||
sysIPV6_USE_MIN_MTU = 0x2a
|
|
||||||
sysIPV6_RECVPATHMTU = 0x2b
|
|
||||||
|
|
||||||
sysIPV6_PATHMTU = 0x2c
|
|
||||||
|
|
||||||
sysIPV6_PKTINFO = 0x2e
|
|
||||||
sysIPV6_HOPLIMIT = 0x2f
|
|
||||||
sysIPV6_NEXTHOP = 0x30
|
|
||||||
sysIPV6_HOPOPTS = 0x31
|
|
||||||
sysIPV6_DSTOPTS = 0x32
|
|
||||||
sysIPV6_RTHDR = 0x33
|
|
||||||
|
|
||||||
sysIPV6_RECVTCLASS = 0x39
|
|
||||||
|
|
||||||
sysIPV6_AUTOFLOWLABEL = 0x3b
|
|
||||||
|
|
||||||
sysIPV6_TCLASS = 0x3d
|
|
||||||
sysIPV6_DONTFRAG = 0x3e
|
|
||||||
|
|
||||||
sysIPV6_PREFER_TEMPADDR = 0x3f
|
|
||||||
|
|
||||||
sysIPV6_BINDANY = 0x40
|
|
||||||
|
|
||||||
sysIPV6_MSFILTER = 0x4a
|
|
||||||
|
|
||||||
sysMCAST_JOIN_GROUP = 0x50
|
|
||||||
sysMCAST_LEAVE_GROUP = 0x51
|
|
||||||
sysMCAST_JOIN_SOURCE_GROUP = 0x52
|
|
||||||
sysMCAST_LEAVE_SOURCE_GROUP = 0x53
|
|
||||||
sysMCAST_BLOCK_SOURCE = 0x54
|
|
||||||
sysMCAST_UNBLOCK_SOURCE = 0x55
|
|
||||||
|
|
||||||
sysIPV6_PORTRANGE_DEFAULT = 0x0
|
|
||||||
sysIPV6_PORTRANGE_HIGH = 0x1
|
|
||||||
sysIPV6_PORTRANGE_LOW = 0x2
|
|
||||||
|
|
||||||
sysSizeofSockaddrStorage = 0x80
|
|
||||||
sysSizeofSockaddrInet6 = 0x1c
|
|
||||||
sysSizeofInet6Pktinfo = 0x14
|
|
||||||
sysSizeofIPv6Mtuinfo = 0x20
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = 0x14
|
|
||||||
sysSizeofGroupReq = 0x88
|
|
||||||
sysSizeofGroupSourceReq = 0x108
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = 0x20
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysSockaddrStorage struct {
|
|
||||||
Len uint8
|
|
||||||
Family uint8
|
|
||||||
X__ss_pad1 [6]int8
|
|
||||||
X__ss_align int64
|
|
||||||
X__ss_pad2 [112]int8
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysSockaddrInet6 struct {
|
|
||||||
Len uint8
|
|
||||||
Family uint8
|
|
||||||
Port uint16
|
|
||||||
Flowinfo uint32
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Scope_id uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysInet6Pktinfo struct {
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Ifindex uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo struct {
|
|
||||||
Addr sysSockaddrInet6
|
|
||||||
Mtu uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mreq struct {
|
|
||||||
Multiaddr [16]byte /* in6_addr */
|
|
||||||
Interface uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Pad_cgo_0 [4]byte
|
|
||||||
Group sysSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupSourceReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Pad_cgo_0 [4]byte
|
|
||||||
Group sysSockaddrStorage
|
|
||||||
Source sysSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysICMPv6Filter struct {
|
|
||||||
Filt [8]uint32
|
|
||||||
}
|
|
||||||
-124
@@ -1,124 +0,0 @@
|
|||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs defs_freebsd.go
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_UNICAST_HOPS = 0x4
|
|
||||||
sysIPV6_MULTICAST_IF = 0x9
|
|
||||||
sysIPV6_MULTICAST_HOPS = 0xa
|
|
||||||
sysIPV6_MULTICAST_LOOP = 0xb
|
|
||||||
sysIPV6_JOIN_GROUP = 0xc
|
|
||||||
sysIPV6_LEAVE_GROUP = 0xd
|
|
||||||
sysIPV6_PORTRANGE = 0xe
|
|
||||||
sysICMP6_FILTER = 0x12
|
|
||||||
|
|
||||||
sysIPV6_CHECKSUM = 0x1a
|
|
||||||
sysIPV6_V6ONLY = 0x1b
|
|
||||||
|
|
||||||
sysIPV6_IPSEC_POLICY = 0x1c
|
|
||||||
|
|
||||||
sysIPV6_RTHDRDSTOPTS = 0x23
|
|
||||||
|
|
||||||
sysIPV6_RECVPKTINFO = 0x24
|
|
||||||
sysIPV6_RECVHOPLIMIT = 0x25
|
|
||||||
sysIPV6_RECVRTHDR = 0x26
|
|
||||||
sysIPV6_RECVHOPOPTS = 0x27
|
|
||||||
sysIPV6_RECVDSTOPTS = 0x28
|
|
||||||
|
|
||||||
sysIPV6_USE_MIN_MTU = 0x2a
|
|
||||||
sysIPV6_RECVPATHMTU = 0x2b
|
|
||||||
|
|
||||||
sysIPV6_PATHMTU = 0x2c
|
|
||||||
|
|
||||||
sysIPV6_PKTINFO = 0x2e
|
|
||||||
sysIPV6_HOPLIMIT = 0x2f
|
|
||||||
sysIPV6_NEXTHOP = 0x30
|
|
||||||
sysIPV6_HOPOPTS = 0x31
|
|
||||||
sysIPV6_DSTOPTS = 0x32
|
|
||||||
sysIPV6_RTHDR = 0x33
|
|
||||||
|
|
||||||
sysIPV6_RECVTCLASS = 0x39
|
|
||||||
|
|
||||||
sysIPV6_AUTOFLOWLABEL = 0x3b
|
|
||||||
|
|
||||||
sysIPV6_TCLASS = 0x3d
|
|
||||||
sysIPV6_DONTFRAG = 0x3e
|
|
||||||
|
|
||||||
sysIPV6_PREFER_TEMPADDR = 0x3f
|
|
||||||
|
|
||||||
sysIPV6_BINDANY = 0x40
|
|
||||||
|
|
||||||
sysIPV6_MSFILTER = 0x4a
|
|
||||||
|
|
||||||
sysMCAST_JOIN_GROUP = 0x50
|
|
||||||
sysMCAST_LEAVE_GROUP = 0x51
|
|
||||||
sysMCAST_JOIN_SOURCE_GROUP = 0x52
|
|
||||||
sysMCAST_LEAVE_SOURCE_GROUP = 0x53
|
|
||||||
sysMCAST_BLOCK_SOURCE = 0x54
|
|
||||||
sysMCAST_UNBLOCK_SOURCE = 0x55
|
|
||||||
|
|
||||||
sysIPV6_PORTRANGE_DEFAULT = 0x0
|
|
||||||
sysIPV6_PORTRANGE_HIGH = 0x1
|
|
||||||
sysIPV6_PORTRANGE_LOW = 0x2
|
|
||||||
|
|
||||||
sysSizeofSockaddrStorage = 0x80
|
|
||||||
sysSizeofSockaddrInet6 = 0x1c
|
|
||||||
sysSizeofInet6Pktinfo = 0x14
|
|
||||||
sysSizeofIPv6Mtuinfo = 0x20
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = 0x14
|
|
||||||
sysSizeofGroupReq = 0x88
|
|
||||||
sysSizeofGroupSourceReq = 0x108
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = 0x20
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysSockaddrStorage struct {
|
|
||||||
Len uint8
|
|
||||||
Family uint8
|
|
||||||
X__ss_pad1 [6]int8
|
|
||||||
X__ss_align int64
|
|
||||||
X__ss_pad2 [112]int8
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysSockaddrInet6 struct {
|
|
||||||
Len uint8
|
|
||||||
Family uint8
|
|
||||||
Port uint16
|
|
||||||
Flowinfo uint32
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Scope_id uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysInet6Pktinfo struct {
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Ifindex uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo struct {
|
|
||||||
Addr sysSockaddrInet6
|
|
||||||
Mtu uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mreq struct {
|
|
||||||
Multiaddr [16]byte /* in6_addr */
|
|
||||||
Interface uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Pad_cgo_0 [4]byte
|
|
||||||
Group sysSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupSourceReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Pad_cgo_0 [4]byte
|
|
||||||
Group sysSockaddrStorage
|
|
||||||
Source sysSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysICMPv6Filter struct {
|
|
||||||
Filt [8]uint32
|
|
||||||
}
|
|
||||||
-152
@@ -1,152 +0,0 @@
|
|||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs defs_linux.go
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_ADDRFORM = 0x1
|
|
||||||
sysIPV6_2292PKTINFO = 0x2
|
|
||||||
sysIPV6_2292HOPOPTS = 0x3
|
|
||||||
sysIPV6_2292DSTOPTS = 0x4
|
|
||||||
sysIPV6_2292RTHDR = 0x5
|
|
||||||
sysIPV6_2292PKTOPTIONS = 0x6
|
|
||||||
sysIPV6_CHECKSUM = 0x7
|
|
||||||
sysIPV6_2292HOPLIMIT = 0x8
|
|
||||||
sysIPV6_NEXTHOP = 0x9
|
|
||||||
sysIPV6_FLOWINFO = 0xb
|
|
||||||
|
|
||||||
sysIPV6_UNICAST_HOPS = 0x10
|
|
||||||
sysIPV6_MULTICAST_IF = 0x11
|
|
||||||
sysIPV6_MULTICAST_HOPS = 0x12
|
|
||||||
sysIPV6_MULTICAST_LOOP = 0x13
|
|
||||||
sysIPV6_ADD_MEMBERSHIP = 0x14
|
|
||||||
sysIPV6_DROP_MEMBERSHIP = 0x15
|
|
||||||
sysMCAST_JOIN_GROUP = 0x2a
|
|
||||||
sysMCAST_LEAVE_GROUP = 0x2d
|
|
||||||
sysMCAST_JOIN_SOURCE_GROUP = 0x2e
|
|
||||||
sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
|
|
||||||
sysMCAST_BLOCK_SOURCE = 0x2b
|
|
||||||
sysMCAST_UNBLOCK_SOURCE = 0x2c
|
|
||||||
sysMCAST_MSFILTER = 0x30
|
|
||||||
sysIPV6_ROUTER_ALERT = 0x16
|
|
||||||
sysIPV6_MTU_DISCOVER = 0x17
|
|
||||||
sysIPV6_MTU = 0x18
|
|
||||||
sysIPV6_RECVERR = 0x19
|
|
||||||
sysIPV6_V6ONLY = 0x1a
|
|
||||||
sysIPV6_JOIN_ANYCAST = 0x1b
|
|
||||||
sysIPV6_LEAVE_ANYCAST = 0x1c
|
|
||||||
|
|
||||||
sysIPV6_FLOWLABEL_MGR = 0x20
|
|
||||||
sysIPV6_FLOWINFO_SEND = 0x21
|
|
||||||
|
|
||||||
sysIPV6_IPSEC_POLICY = 0x22
|
|
||||||
sysIPV6_XFRM_POLICY = 0x23
|
|
||||||
|
|
||||||
sysIPV6_RECVPKTINFO = 0x31
|
|
||||||
sysIPV6_PKTINFO = 0x32
|
|
||||||
sysIPV6_RECVHOPLIMIT = 0x33
|
|
||||||
sysIPV6_HOPLIMIT = 0x34
|
|
||||||
sysIPV6_RECVHOPOPTS = 0x35
|
|
||||||
sysIPV6_HOPOPTS = 0x36
|
|
||||||
sysIPV6_RTHDRDSTOPTS = 0x37
|
|
||||||
sysIPV6_RECVRTHDR = 0x38
|
|
||||||
sysIPV6_RTHDR = 0x39
|
|
||||||
sysIPV6_RECVDSTOPTS = 0x3a
|
|
||||||
sysIPV6_DSTOPTS = 0x3b
|
|
||||||
sysIPV6_RECVPATHMTU = 0x3c
|
|
||||||
sysIPV6_PATHMTU = 0x3d
|
|
||||||
sysIPV6_DONTFRAG = 0x3e
|
|
||||||
|
|
||||||
sysIPV6_RECVTCLASS = 0x42
|
|
||||||
sysIPV6_TCLASS = 0x43
|
|
||||||
|
|
||||||
sysIPV6_ADDR_PREFERENCES = 0x48
|
|
||||||
|
|
||||||
sysIPV6_PREFER_SRC_TMP = 0x1
|
|
||||||
sysIPV6_PREFER_SRC_PUBLIC = 0x2
|
|
||||||
sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
|
|
||||||
sysIPV6_PREFER_SRC_COA = 0x4
|
|
||||||
sysIPV6_PREFER_SRC_HOME = 0x400
|
|
||||||
sysIPV6_PREFER_SRC_CGA = 0x8
|
|
||||||
sysIPV6_PREFER_SRC_NONCGA = 0x800
|
|
||||||
|
|
||||||
sysIPV6_MINHOPCOUNT = 0x49
|
|
||||||
|
|
||||||
sysIPV6_ORIGDSTADDR = 0x4a
|
|
||||||
sysIPV6_RECVORIGDSTADDR = 0x4a
|
|
||||||
sysIPV6_TRANSPARENT = 0x4b
|
|
||||||
sysIPV6_UNICAST_IF = 0x4c
|
|
||||||
|
|
||||||
sysICMPV6_FILTER = 0x1
|
|
||||||
|
|
||||||
sysICMPV6_FILTER_BLOCK = 0x1
|
|
||||||
sysICMPV6_FILTER_PASS = 0x2
|
|
||||||
sysICMPV6_FILTER_BLOCKOTHERS = 0x3
|
|
||||||
sysICMPV6_FILTER_PASSONLY = 0x4
|
|
||||||
|
|
||||||
sysSizeofKernelSockaddrStorage = 0x80
|
|
||||||
sysSizeofSockaddrInet6 = 0x1c
|
|
||||||
sysSizeofInet6Pktinfo = 0x14
|
|
||||||
sysSizeofIPv6Mtuinfo = 0x20
|
|
||||||
sysSizeofIPv6FlowlabelReq = 0x20
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = 0x14
|
|
||||||
sysSizeofGroupReq = 0x84
|
|
||||||
sysSizeofGroupSourceReq = 0x104
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = 0x20
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysKernelSockaddrStorage struct {
|
|
||||||
Family uint16
|
|
||||||
X__data [126]int8
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysSockaddrInet6 struct {
|
|
||||||
Family uint16
|
|
||||||
Port uint16
|
|
||||||
Flowinfo uint32
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Scope_id uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysInet6Pktinfo struct {
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Ifindex int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo struct {
|
|
||||||
Addr sysSockaddrInet6
|
|
||||||
Mtu uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6FlowlabelReq struct {
|
|
||||||
Dst [16]byte /* in6_addr */
|
|
||||||
Label uint32
|
|
||||||
Action uint8
|
|
||||||
Share uint8
|
|
||||||
Flags uint16
|
|
||||||
Expires uint16
|
|
||||||
Linger uint16
|
|
||||||
X__flr_pad uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mreq struct {
|
|
||||||
Multiaddr [16]byte /* in6_addr */
|
|
||||||
Ifindex int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Group sysKernelSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupSourceReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Group sysKernelSockaddrStorage
|
|
||||||
Source sysKernelSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysICMPv6Filter struct {
|
|
||||||
Data [8]uint32
|
|
||||||
}
|
|
||||||
-154
@@ -1,154 +0,0 @@
|
|||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs defs_linux.go
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_ADDRFORM = 0x1
|
|
||||||
sysIPV6_2292PKTINFO = 0x2
|
|
||||||
sysIPV6_2292HOPOPTS = 0x3
|
|
||||||
sysIPV6_2292DSTOPTS = 0x4
|
|
||||||
sysIPV6_2292RTHDR = 0x5
|
|
||||||
sysIPV6_2292PKTOPTIONS = 0x6
|
|
||||||
sysIPV6_CHECKSUM = 0x7
|
|
||||||
sysIPV6_2292HOPLIMIT = 0x8
|
|
||||||
sysIPV6_NEXTHOP = 0x9
|
|
||||||
sysIPV6_FLOWINFO = 0xb
|
|
||||||
|
|
||||||
sysIPV6_UNICAST_HOPS = 0x10
|
|
||||||
sysIPV6_MULTICAST_IF = 0x11
|
|
||||||
sysIPV6_MULTICAST_HOPS = 0x12
|
|
||||||
sysIPV6_MULTICAST_LOOP = 0x13
|
|
||||||
sysIPV6_ADD_MEMBERSHIP = 0x14
|
|
||||||
sysIPV6_DROP_MEMBERSHIP = 0x15
|
|
||||||
sysMCAST_JOIN_GROUP = 0x2a
|
|
||||||
sysMCAST_LEAVE_GROUP = 0x2d
|
|
||||||
sysMCAST_JOIN_SOURCE_GROUP = 0x2e
|
|
||||||
sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
|
|
||||||
sysMCAST_BLOCK_SOURCE = 0x2b
|
|
||||||
sysMCAST_UNBLOCK_SOURCE = 0x2c
|
|
||||||
sysMCAST_MSFILTER = 0x30
|
|
||||||
sysIPV6_ROUTER_ALERT = 0x16
|
|
||||||
sysIPV6_MTU_DISCOVER = 0x17
|
|
||||||
sysIPV6_MTU = 0x18
|
|
||||||
sysIPV6_RECVERR = 0x19
|
|
||||||
sysIPV6_V6ONLY = 0x1a
|
|
||||||
sysIPV6_JOIN_ANYCAST = 0x1b
|
|
||||||
sysIPV6_LEAVE_ANYCAST = 0x1c
|
|
||||||
|
|
||||||
sysIPV6_FLOWLABEL_MGR = 0x20
|
|
||||||
sysIPV6_FLOWINFO_SEND = 0x21
|
|
||||||
|
|
||||||
sysIPV6_IPSEC_POLICY = 0x22
|
|
||||||
sysIPV6_XFRM_POLICY = 0x23
|
|
||||||
|
|
||||||
sysIPV6_RECVPKTINFO = 0x31
|
|
||||||
sysIPV6_PKTINFO = 0x32
|
|
||||||
sysIPV6_RECVHOPLIMIT = 0x33
|
|
||||||
sysIPV6_HOPLIMIT = 0x34
|
|
||||||
sysIPV6_RECVHOPOPTS = 0x35
|
|
||||||
sysIPV6_HOPOPTS = 0x36
|
|
||||||
sysIPV6_RTHDRDSTOPTS = 0x37
|
|
||||||
sysIPV6_RECVRTHDR = 0x38
|
|
||||||
sysIPV6_RTHDR = 0x39
|
|
||||||
sysIPV6_RECVDSTOPTS = 0x3a
|
|
||||||
sysIPV6_DSTOPTS = 0x3b
|
|
||||||
sysIPV6_RECVPATHMTU = 0x3c
|
|
||||||
sysIPV6_PATHMTU = 0x3d
|
|
||||||
sysIPV6_DONTFRAG = 0x3e
|
|
||||||
|
|
||||||
sysIPV6_RECVTCLASS = 0x42
|
|
||||||
sysIPV6_TCLASS = 0x43
|
|
||||||
|
|
||||||
sysIPV6_ADDR_PREFERENCES = 0x48
|
|
||||||
|
|
||||||
sysIPV6_PREFER_SRC_TMP = 0x1
|
|
||||||
sysIPV6_PREFER_SRC_PUBLIC = 0x2
|
|
||||||
sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
|
|
||||||
sysIPV6_PREFER_SRC_COA = 0x4
|
|
||||||
sysIPV6_PREFER_SRC_HOME = 0x400
|
|
||||||
sysIPV6_PREFER_SRC_CGA = 0x8
|
|
||||||
sysIPV6_PREFER_SRC_NONCGA = 0x800
|
|
||||||
|
|
||||||
sysIPV6_MINHOPCOUNT = 0x49
|
|
||||||
|
|
||||||
sysIPV6_ORIGDSTADDR = 0x4a
|
|
||||||
sysIPV6_RECVORIGDSTADDR = 0x4a
|
|
||||||
sysIPV6_TRANSPARENT = 0x4b
|
|
||||||
sysIPV6_UNICAST_IF = 0x4c
|
|
||||||
|
|
||||||
sysICMPV6_FILTER = 0x1
|
|
||||||
|
|
||||||
sysICMPV6_FILTER_BLOCK = 0x1
|
|
||||||
sysICMPV6_FILTER_PASS = 0x2
|
|
||||||
sysICMPV6_FILTER_BLOCKOTHERS = 0x3
|
|
||||||
sysICMPV6_FILTER_PASSONLY = 0x4
|
|
||||||
|
|
||||||
sysSizeofKernelSockaddrStorage = 0x80
|
|
||||||
sysSizeofSockaddrInet6 = 0x1c
|
|
||||||
sysSizeofInet6Pktinfo = 0x14
|
|
||||||
sysSizeofIPv6Mtuinfo = 0x20
|
|
||||||
sysSizeofIPv6FlowlabelReq = 0x20
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = 0x14
|
|
||||||
sysSizeofGroupReq = 0x88
|
|
||||||
sysSizeofGroupSourceReq = 0x108
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = 0x20
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysKernelSockaddrStorage struct {
|
|
||||||
Family uint16
|
|
||||||
X__data [126]int8
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysSockaddrInet6 struct {
|
|
||||||
Family uint16
|
|
||||||
Port uint16
|
|
||||||
Flowinfo uint32
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Scope_id uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysInet6Pktinfo struct {
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Ifindex int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo struct {
|
|
||||||
Addr sysSockaddrInet6
|
|
||||||
Mtu uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6FlowlabelReq struct {
|
|
||||||
Dst [16]byte /* in6_addr */
|
|
||||||
Label uint32
|
|
||||||
Action uint8
|
|
||||||
Share uint8
|
|
||||||
Flags uint16
|
|
||||||
Expires uint16
|
|
||||||
Linger uint16
|
|
||||||
X__flr_pad uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mreq struct {
|
|
||||||
Multiaddr [16]byte /* in6_addr */
|
|
||||||
Ifindex int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Pad_cgo_0 [4]byte
|
|
||||||
Group sysKernelSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupSourceReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Pad_cgo_0 [4]byte
|
|
||||||
Group sysKernelSockaddrStorage
|
|
||||||
Source sysKernelSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysICMPv6Filter struct {
|
|
||||||
Data [8]uint32
|
|
||||||
}
|
|
||||||
-152
@@ -1,152 +0,0 @@
|
|||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs defs_linux.go
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_ADDRFORM = 0x1
|
|
||||||
sysIPV6_2292PKTINFO = 0x2
|
|
||||||
sysIPV6_2292HOPOPTS = 0x3
|
|
||||||
sysIPV6_2292DSTOPTS = 0x4
|
|
||||||
sysIPV6_2292RTHDR = 0x5
|
|
||||||
sysIPV6_2292PKTOPTIONS = 0x6
|
|
||||||
sysIPV6_CHECKSUM = 0x7
|
|
||||||
sysIPV6_2292HOPLIMIT = 0x8
|
|
||||||
sysIPV6_NEXTHOP = 0x9
|
|
||||||
sysIPV6_FLOWINFO = 0xb
|
|
||||||
|
|
||||||
sysIPV6_UNICAST_HOPS = 0x10
|
|
||||||
sysIPV6_MULTICAST_IF = 0x11
|
|
||||||
sysIPV6_MULTICAST_HOPS = 0x12
|
|
||||||
sysIPV6_MULTICAST_LOOP = 0x13
|
|
||||||
sysIPV6_ADD_MEMBERSHIP = 0x14
|
|
||||||
sysIPV6_DROP_MEMBERSHIP = 0x15
|
|
||||||
sysMCAST_JOIN_GROUP = 0x2a
|
|
||||||
sysMCAST_LEAVE_GROUP = 0x2d
|
|
||||||
sysMCAST_JOIN_SOURCE_GROUP = 0x2e
|
|
||||||
sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
|
|
||||||
sysMCAST_BLOCK_SOURCE = 0x2b
|
|
||||||
sysMCAST_UNBLOCK_SOURCE = 0x2c
|
|
||||||
sysMCAST_MSFILTER = 0x30
|
|
||||||
sysIPV6_ROUTER_ALERT = 0x16
|
|
||||||
sysIPV6_MTU_DISCOVER = 0x17
|
|
||||||
sysIPV6_MTU = 0x18
|
|
||||||
sysIPV6_RECVERR = 0x19
|
|
||||||
sysIPV6_V6ONLY = 0x1a
|
|
||||||
sysIPV6_JOIN_ANYCAST = 0x1b
|
|
||||||
sysIPV6_LEAVE_ANYCAST = 0x1c
|
|
||||||
|
|
||||||
sysIPV6_FLOWLABEL_MGR = 0x20
|
|
||||||
sysIPV6_FLOWINFO_SEND = 0x21
|
|
||||||
|
|
||||||
sysIPV6_IPSEC_POLICY = 0x22
|
|
||||||
sysIPV6_XFRM_POLICY = 0x23
|
|
||||||
|
|
||||||
sysIPV6_RECVPKTINFO = 0x31
|
|
||||||
sysIPV6_PKTINFO = 0x32
|
|
||||||
sysIPV6_RECVHOPLIMIT = 0x33
|
|
||||||
sysIPV6_HOPLIMIT = 0x34
|
|
||||||
sysIPV6_RECVHOPOPTS = 0x35
|
|
||||||
sysIPV6_HOPOPTS = 0x36
|
|
||||||
sysIPV6_RTHDRDSTOPTS = 0x37
|
|
||||||
sysIPV6_RECVRTHDR = 0x38
|
|
||||||
sysIPV6_RTHDR = 0x39
|
|
||||||
sysIPV6_RECVDSTOPTS = 0x3a
|
|
||||||
sysIPV6_DSTOPTS = 0x3b
|
|
||||||
sysIPV6_RECVPATHMTU = 0x3c
|
|
||||||
sysIPV6_PATHMTU = 0x3d
|
|
||||||
sysIPV6_DONTFRAG = 0x3e
|
|
||||||
|
|
||||||
sysIPV6_RECVTCLASS = 0x42
|
|
||||||
sysIPV6_TCLASS = 0x43
|
|
||||||
|
|
||||||
sysIPV6_ADDR_PREFERENCES = 0x48
|
|
||||||
|
|
||||||
sysIPV6_PREFER_SRC_TMP = 0x1
|
|
||||||
sysIPV6_PREFER_SRC_PUBLIC = 0x2
|
|
||||||
sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
|
|
||||||
sysIPV6_PREFER_SRC_COA = 0x4
|
|
||||||
sysIPV6_PREFER_SRC_HOME = 0x400
|
|
||||||
sysIPV6_PREFER_SRC_CGA = 0x8
|
|
||||||
sysIPV6_PREFER_SRC_NONCGA = 0x800
|
|
||||||
|
|
||||||
sysIPV6_MINHOPCOUNT = 0x49
|
|
||||||
|
|
||||||
sysIPV6_ORIGDSTADDR = 0x4a
|
|
||||||
sysIPV6_RECVORIGDSTADDR = 0x4a
|
|
||||||
sysIPV6_TRANSPARENT = 0x4b
|
|
||||||
sysIPV6_UNICAST_IF = 0x4c
|
|
||||||
|
|
||||||
sysICMPV6_FILTER = 0x1
|
|
||||||
|
|
||||||
sysICMPV6_FILTER_BLOCK = 0x1
|
|
||||||
sysICMPV6_FILTER_PASS = 0x2
|
|
||||||
sysICMPV6_FILTER_BLOCKOTHERS = 0x3
|
|
||||||
sysICMPV6_FILTER_PASSONLY = 0x4
|
|
||||||
|
|
||||||
sysSizeofKernelSockaddrStorage = 0x80
|
|
||||||
sysSizeofSockaddrInet6 = 0x1c
|
|
||||||
sysSizeofInet6Pktinfo = 0x14
|
|
||||||
sysSizeofIPv6Mtuinfo = 0x20
|
|
||||||
sysSizeofIPv6FlowlabelReq = 0x20
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = 0x14
|
|
||||||
sysSizeofGroupReq = 0x84
|
|
||||||
sysSizeofGroupSourceReq = 0x104
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = 0x20
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysKernelSockaddrStorage struct {
|
|
||||||
Family uint16
|
|
||||||
X__data [126]int8
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysSockaddrInet6 struct {
|
|
||||||
Family uint16
|
|
||||||
Port uint16
|
|
||||||
Flowinfo uint32
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Scope_id uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysInet6Pktinfo struct {
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Ifindex int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo struct {
|
|
||||||
Addr sysSockaddrInet6
|
|
||||||
Mtu uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6FlowlabelReq struct {
|
|
||||||
Dst [16]byte /* in6_addr */
|
|
||||||
Label uint32
|
|
||||||
Action uint8
|
|
||||||
Share uint8
|
|
||||||
Flags uint16
|
|
||||||
Expires uint16
|
|
||||||
Linger uint16
|
|
||||||
X__flr_pad uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mreq struct {
|
|
||||||
Multiaddr [16]byte /* in6_addr */
|
|
||||||
Ifindex int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Group sysKernelSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupSourceReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Group sysKernelSockaddrStorage
|
|
||||||
Source sysKernelSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysICMPv6Filter struct {
|
|
||||||
Data [8]uint32
|
|
||||||
}
|
|
||||||
-156
@@ -1,156 +0,0 @@
|
|||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs defs_linux.go
|
|
||||||
|
|
||||||
// +build linux,arm64
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_ADDRFORM = 0x1
|
|
||||||
sysIPV6_2292PKTINFO = 0x2
|
|
||||||
sysIPV6_2292HOPOPTS = 0x3
|
|
||||||
sysIPV6_2292DSTOPTS = 0x4
|
|
||||||
sysIPV6_2292RTHDR = 0x5
|
|
||||||
sysIPV6_2292PKTOPTIONS = 0x6
|
|
||||||
sysIPV6_CHECKSUM = 0x7
|
|
||||||
sysIPV6_2292HOPLIMIT = 0x8
|
|
||||||
sysIPV6_NEXTHOP = 0x9
|
|
||||||
sysIPV6_FLOWINFO = 0xb
|
|
||||||
|
|
||||||
sysIPV6_UNICAST_HOPS = 0x10
|
|
||||||
sysIPV6_MULTICAST_IF = 0x11
|
|
||||||
sysIPV6_MULTICAST_HOPS = 0x12
|
|
||||||
sysIPV6_MULTICAST_LOOP = 0x13
|
|
||||||
sysIPV6_ADD_MEMBERSHIP = 0x14
|
|
||||||
sysIPV6_DROP_MEMBERSHIP = 0x15
|
|
||||||
sysMCAST_JOIN_GROUP = 0x2a
|
|
||||||
sysMCAST_LEAVE_GROUP = 0x2d
|
|
||||||
sysMCAST_JOIN_SOURCE_GROUP = 0x2e
|
|
||||||
sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
|
|
||||||
sysMCAST_BLOCK_SOURCE = 0x2b
|
|
||||||
sysMCAST_UNBLOCK_SOURCE = 0x2c
|
|
||||||
sysMCAST_MSFILTER = 0x30
|
|
||||||
sysIPV6_ROUTER_ALERT = 0x16
|
|
||||||
sysIPV6_MTU_DISCOVER = 0x17
|
|
||||||
sysIPV6_MTU = 0x18
|
|
||||||
sysIPV6_RECVERR = 0x19
|
|
||||||
sysIPV6_V6ONLY = 0x1a
|
|
||||||
sysIPV6_JOIN_ANYCAST = 0x1b
|
|
||||||
sysIPV6_LEAVE_ANYCAST = 0x1c
|
|
||||||
|
|
||||||
sysIPV6_FLOWLABEL_MGR = 0x20
|
|
||||||
sysIPV6_FLOWINFO_SEND = 0x21
|
|
||||||
|
|
||||||
sysIPV6_IPSEC_POLICY = 0x22
|
|
||||||
sysIPV6_XFRM_POLICY = 0x23
|
|
||||||
|
|
||||||
sysIPV6_RECVPKTINFO = 0x31
|
|
||||||
sysIPV6_PKTINFO = 0x32
|
|
||||||
sysIPV6_RECVHOPLIMIT = 0x33
|
|
||||||
sysIPV6_HOPLIMIT = 0x34
|
|
||||||
sysIPV6_RECVHOPOPTS = 0x35
|
|
||||||
sysIPV6_HOPOPTS = 0x36
|
|
||||||
sysIPV6_RTHDRDSTOPTS = 0x37
|
|
||||||
sysIPV6_RECVRTHDR = 0x38
|
|
||||||
sysIPV6_RTHDR = 0x39
|
|
||||||
sysIPV6_RECVDSTOPTS = 0x3a
|
|
||||||
sysIPV6_DSTOPTS = 0x3b
|
|
||||||
sysIPV6_RECVPATHMTU = 0x3c
|
|
||||||
sysIPV6_PATHMTU = 0x3d
|
|
||||||
sysIPV6_DONTFRAG = 0x3e
|
|
||||||
|
|
||||||
sysIPV6_RECVTCLASS = 0x42
|
|
||||||
sysIPV6_TCLASS = 0x43
|
|
||||||
|
|
||||||
sysIPV6_ADDR_PREFERENCES = 0x48
|
|
||||||
|
|
||||||
sysIPV6_PREFER_SRC_TMP = 0x1
|
|
||||||
sysIPV6_PREFER_SRC_PUBLIC = 0x2
|
|
||||||
sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
|
|
||||||
sysIPV6_PREFER_SRC_COA = 0x4
|
|
||||||
sysIPV6_PREFER_SRC_HOME = 0x400
|
|
||||||
sysIPV6_PREFER_SRC_CGA = 0x8
|
|
||||||
sysIPV6_PREFER_SRC_NONCGA = 0x800
|
|
||||||
|
|
||||||
sysIPV6_MINHOPCOUNT = 0x49
|
|
||||||
|
|
||||||
sysIPV6_ORIGDSTADDR = 0x4a
|
|
||||||
sysIPV6_RECVORIGDSTADDR = 0x4a
|
|
||||||
sysIPV6_TRANSPARENT = 0x4b
|
|
||||||
sysIPV6_UNICAST_IF = 0x4c
|
|
||||||
|
|
||||||
sysICMPV6_FILTER = 0x1
|
|
||||||
|
|
||||||
sysICMPV6_FILTER_BLOCK = 0x1
|
|
||||||
sysICMPV6_FILTER_PASS = 0x2
|
|
||||||
sysICMPV6_FILTER_BLOCKOTHERS = 0x3
|
|
||||||
sysICMPV6_FILTER_PASSONLY = 0x4
|
|
||||||
|
|
||||||
sysSizeofKernelSockaddrStorage = 0x80
|
|
||||||
sysSizeofSockaddrInet6 = 0x1c
|
|
||||||
sysSizeofInet6Pktinfo = 0x14
|
|
||||||
sysSizeofIPv6Mtuinfo = 0x20
|
|
||||||
sysSizeofIPv6FlowlabelReq = 0x20
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = 0x14
|
|
||||||
sysSizeofGroupReq = 0x88
|
|
||||||
sysSizeofGroupSourceReq = 0x108
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = 0x20
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysKernelSockaddrStorage struct {
|
|
||||||
Family uint16
|
|
||||||
X__data [126]int8
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysSockaddrInet6 struct {
|
|
||||||
Family uint16
|
|
||||||
Port uint16
|
|
||||||
Flowinfo uint32
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Scope_id uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysInet6Pktinfo struct {
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Ifindex int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo struct {
|
|
||||||
Addr sysSockaddrInet6
|
|
||||||
Mtu uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6FlowlabelReq struct {
|
|
||||||
Dst [16]byte /* in6_addr */
|
|
||||||
Label uint32
|
|
||||||
Action uint8
|
|
||||||
Share uint8
|
|
||||||
Flags uint16
|
|
||||||
Expires uint16
|
|
||||||
Linger uint16
|
|
||||||
X__flr_pad uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mreq struct {
|
|
||||||
Multiaddr [16]byte /* in6_addr */
|
|
||||||
Ifindex int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Pad_cgo_0 [4]byte
|
|
||||||
Group sysKernelSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupSourceReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Pad_cgo_0 [4]byte
|
|
||||||
Group sysKernelSockaddrStorage
|
|
||||||
Source sysKernelSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysICMPv6Filter struct {
|
|
||||||
Data [8]uint32
|
|
||||||
}
|
|
||||||
-156
@@ -1,156 +0,0 @@
|
|||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs defs_linux.go
|
|
||||||
|
|
||||||
// +build linux,ppc64
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_ADDRFORM = 0x1
|
|
||||||
sysIPV6_2292PKTINFO = 0x2
|
|
||||||
sysIPV6_2292HOPOPTS = 0x3
|
|
||||||
sysIPV6_2292DSTOPTS = 0x4
|
|
||||||
sysIPV6_2292RTHDR = 0x5
|
|
||||||
sysIPV6_2292PKTOPTIONS = 0x6
|
|
||||||
sysIPV6_CHECKSUM = 0x7
|
|
||||||
sysIPV6_2292HOPLIMIT = 0x8
|
|
||||||
sysIPV6_NEXTHOP = 0x9
|
|
||||||
sysIPV6_FLOWINFO = 0xb
|
|
||||||
|
|
||||||
sysIPV6_UNICAST_HOPS = 0x10
|
|
||||||
sysIPV6_MULTICAST_IF = 0x11
|
|
||||||
sysIPV6_MULTICAST_HOPS = 0x12
|
|
||||||
sysIPV6_MULTICAST_LOOP = 0x13
|
|
||||||
sysIPV6_ADD_MEMBERSHIP = 0x14
|
|
||||||
sysIPV6_DROP_MEMBERSHIP = 0x15
|
|
||||||
sysMCAST_JOIN_GROUP = 0x2a
|
|
||||||
sysMCAST_LEAVE_GROUP = 0x2d
|
|
||||||
sysMCAST_JOIN_SOURCE_GROUP = 0x2e
|
|
||||||
sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
|
|
||||||
sysMCAST_BLOCK_SOURCE = 0x2b
|
|
||||||
sysMCAST_UNBLOCK_SOURCE = 0x2c
|
|
||||||
sysMCAST_MSFILTER = 0x30
|
|
||||||
sysIPV6_ROUTER_ALERT = 0x16
|
|
||||||
sysIPV6_MTU_DISCOVER = 0x17
|
|
||||||
sysIPV6_MTU = 0x18
|
|
||||||
sysIPV6_RECVERR = 0x19
|
|
||||||
sysIPV6_V6ONLY = 0x1a
|
|
||||||
sysIPV6_JOIN_ANYCAST = 0x1b
|
|
||||||
sysIPV6_LEAVE_ANYCAST = 0x1c
|
|
||||||
|
|
||||||
sysIPV6_FLOWLABEL_MGR = 0x20
|
|
||||||
sysIPV6_FLOWINFO_SEND = 0x21
|
|
||||||
|
|
||||||
sysIPV6_IPSEC_POLICY = 0x22
|
|
||||||
sysIPV6_XFRM_POLICY = 0x23
|
|
||||||
|
|
||||||
sysIPV6_RECVPKTINFO = 0x31
|
|
||||||
sysIPV6_PKTINFO = 0x32
|
|
||||||
sysIPV6_RECVHOPLIMIT = 0x33
|
|
||||||
sysIPV6_HOPLIMIT = 0x34
|
|
||||||
sysIPV6_RECVHOPOPTS = 0x35
|
|
||||||
sysIPV6_HOPOPTS = 0x36
|
|
||||||
sysIPV6_RTHDRDSTOPTS = 0x37
|
|
||||||
sysIPV6_RECVRTHDR = 0x38
|
|
||||||
sysIPV6_RTHDR = 0x39
|
|
||||||
sysIPV6_RECVDSTOPTS = 0x3a
|
|
||||||
sysIPV6_DSTOPTS = 0x3b
|
|
||||||
sysIPV6_RECVPATHMTU = 0x3c
|
|
||||||
sysIPV6_PATHMTU = 0x3d
|
|
||||||
sysIPV6_DONTFRAG = 0x3e
|
|
||||||
|
|
||||||
sysIPV6_RECVTCLASS = 0x42
|
|
||||||
sysIPV6_TCLASS = 0x43
|
|
||||||
|
|
||||||
sysIPV6_ADDR_PREFERENCES = 0x48
|
|
||||||
|
|
||||||
sysIPV6_PREFER_SRC_TMP = 0x1
|
|
||||||
sysIPV6_PREFER_SRC_PUBLIC = 0x2
|
|
||||||
sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
|
|
||||||
sysIPV6_PREFER_SRC_COA = 0x4
|
|
||||||
sysIPV6_PREFER_SRC_HOME = 0x400
|
|
||||||
sysIPV6_PREFER_SRC_CGA = 0x8
|
|
||||||
sysIPV6_PREFER_SRC_NONCGA = 0x800
|
|
||||||
|
|
||||||
sysIPV6_MINHOPCOUNT = 0x49
|
|
||||||
|
|
||||||
sysIPV6_ORIGDSTADDR = 0x4a
|
|
||||||
sysIPV6_RECVORIGDSTADDR = 0x4a
|
|
||||||
sysIPV6_TRANSPARENT = 0x4b
|
|
||||||
sysIPV6_UNICAST_IF = 0x4c
|
|
||||||
|
|
||||||
sysICMPV6_FILTER = 0x1
|
|
||||||
|
|
||||||
sysICMPV6_FILTER_BLOCK = 0x1
|
|
||||||
sysICMPV6_FILTER_PASS = 0x2
|
|
||||||
sysICMPV6_FILTER_BLOCKOTHERS = 0x3
|
|
||||||
sysICMPV6_FILTER_PASSONLY = 0x4
|
|
||||||
|
|
||||||
sysSizeofKernelSockaddrStorage = 0x80
|
|
||||||
sysSizeofSockaddrInet6 = 0x1c
|
|
||||||
sysSizeofInet6Pktinfo = 0x14
|
|
||||||
sysSizeofIPv6Mtuinfo = 0x20
|
|
||||||
sysSizeofIPv6FlowlabelReq = 0x20
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = 0x14
|
|
||||||
sysSizeofGroupReq = 0x88
|
|
||||||
sysSizeofGroupSourceReq = 0x108
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = 0x20
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysKernelSockaddrStorage struct {
|
|
||||||
Family uint16
|
|
||||||
X__data [126]int8
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysSockaddrInet6 struct {
|
|
||||||
Family uint16
|
|
||||||
Port uint16
|
|
||||||
Flowinfo uint32
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Scope_id uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysInet6Pktinfo struct {
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Ifindex int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo struct {
|
|
||||||
Addr sysSockaddrInet6
|
|
||||||
Mtu uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6FlowlabelReq struct {
|
|
||||||
Dst [16]byte /* in6_addr */
|
|
||||||
Label uint32
|
|
||||||
Action uint8
|
|
||||||
Share uint8
|
|
||||||
Flags uint16
|
|
||||||
Expires uint16
|
|
||||||
Linger uint16
|
|
||||||
X__flr_pad uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mreq struct {
|
|
||||||
Multiaddr [16]byte /* in6_addr */
|
|
||||||
Ifindex int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Pad_cgo_0 [4]byte
|
|
||||||
Group sysKernelSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupSourceReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Pad_cgo_0 [4]byte
|
|
||||||
Group sysKernelSockaddrStorage
|
|
||||||
Source sysKernelSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysICMPv6Filter struct {
|
|
||||||
Data [8]uint32
|
|
||||||
}
|
|
||||||
-156
@@ -1,156 +0,0 @@
|
|||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs defs_linux.go
|
|
||||||
|
|
||||||
// +build linux,ppc64le
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_ADDRFORM = 0x1
|
|
||||||
sysIPV6_2292PKTINFO = 0x2
|
|
||||||
sysIPV6_2292HOPOPTS = 0x3
|
|
||||||
sysIPV6_2292DSTOPTS = 0x4
|
|
||||||
sysIPV6_2292RTHDR = 0x5
|
|
||||||
sysIPV6_2292PKTOPTIONS = 0x6
|
|
||||||
sysIPV6_CHECKSUM = 0x7
|
|
||||||
sysIPV6_2292HOPLIMIT = 0x8
|
|
||||||
sysIPV6_NEXTHOP = 0x9
|
|
||||||
sysIPV6_FLOWINFO = 0xb
|
|
||||||
|
|
||||||
sysIPV6_UNICAST_HOPS = 0x10
|
|
||||||
sysIPV6_MULTICAST_IF = 0x11
|
|
||||||
sysIPV6_MULTICAST_HOPS = 0x12
|
|
||||||
sysIPV6_MULTICAST_LOOP = 0x13
|
|
||||||
sysIPV6_ADD_MEMBERSHIP = 0x14
|
|
||||||
sysIPV6_DROP_MEMBERSHIP = 0x15
|
|
||||||
sysMCAST_JOIN_GROUP = 0x2a
|
|
||||||
sysMCAST_LEAVE_GROUP = 0x2d
|
|
||||||
sysMCAST_JOIN_SOURCE_GROUP = 0x2e
|
|
||||||
sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
|
|
||||||
sysMCAST_BLOCK_SOURCE = 0x2b
|
|
||||||
sysMCAST_UNBLOCK_SOURCE = 0x2c
|
|
||||||
sysMCAST_MSFILTER = 0x30
|
|
||||||
sysIPV6_ROUTER_ALERT = 0x16
|
|
||||||
sysIPV6_MTU_DISCOVER = 0x17
|
|
||||||
sysIPV6_MTU = 0x18
|
|
||||||
sysIPV6_RECVERR = 0x19
|
|
||||||
sysIPV6_V6ONLY = 0x1a
|
|
||||||
sysIPV6_JOIN_ANYCAST = 0x1b
|
|
||||||
sysIPV6_LEAVE_ANYCAST = 0x1c
|
|
||||||
|
|
||||||
sysIPV6_FLOWLABEL_MGR = 0x20
|
|
||||||
sysIPV6_FLOWINFO_SEND = 0x21
|
|
||||||
|
|
||||||
sysIPV6_IPSEC_POLICY = 0x22
|
|
||||||
sysIPV6_XFRM_POLICY = 0x23
|
|
||||||
|
|
||||||
sysIPV6_RECVPKTINFO = 0x31
|
|
||||||
sysIPV6_PKTINFO = 0x32
|
|
||||||
sysIPV6_RECVHOPLIMIT = 0x33
|
|
||||||
sysIPV6_HOPLIMIT = 0x34
|
|
||||||
sysIPV6_RECVHOPOPTS = 0x35
|
|
||||||
sysIPV6_HOPOPTS = 0x36
|
|
||||||
sysIPV6_RTHDRDSTOPTS = 0x37
|
|
||||||
sysIPV6_RECVRTHDR = 0x38
|
|
||||||
sysIPV6_RTHDR = 0x39
|
|
||||||
sysIPV6_RECVDSTOPTS = 0x3a
|
|
||||||
sysIPV6_DSTOPTS = 0x3b
|
|
||||||
sysIPV6_RECVPATHMTU = 0x3c
|
|
||||||
sysIPV6_PATHMTU = 0x3d
|
|
||||||
sysIPV6_DONTFRAG = 0x3e
|
|
||||||
|
|
||||||
sysIPV6_RECVTCLASS = 0x42
|
|
||||||
sysIPV6_TCLASS = 0x43
|
|
||||||
|
|
||||||
sysIPV6_ADDR_PREFERENCES = 0x48
|
|
||||||
|
|
||||||
sysIPV6_PREFER_SRC_TMP = 0x1
|
|
||||||
sysIPV6_PREFER_SRC_PUBLIC = 0x2
|
|
||||||
sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
|
|
||||||
sysIPV6_PREFER_SRC_COA = 0x4
|
|
||||||
sysIPV6_PREFER_SRC_HOME = 0x400
|
|
||||||
sysIPV6_PREFER_SRC_CGA = 0x8
|
|
||||||
sysIPV6_PREFER_SRC_NONCGA = 0x800
|
|
||||||
|
|
||||||
sysIPV6_MINHOPCOUNT = 0x49
|
|
||||||
|
|
||||||
sysIPV6_ORIGDSTADDR = 0x4a
|
|
||||||
sysIPV6_RECVORIGDSTADDR = 0x4a
|
|
||||||
sysIPV6_TRANSPARENT = 0x4b
|
|
||||||
sysIPV6_UNICAST_IF = 0x4c
|
|
||||||
|
|
||||||
sysICMPV6_FILTER = 0x1
|
|
||||||
|
|
||||||
sysICMPV6_FILTER_BLOCK = 0x1
|
|
||||||
sysICMPV6_FILTER_PASS = 0x2
|
|
||||||
sysICMPV6_FILTER_BLOCKOTHERS = 0x3
|
|
||||||
sysICMPV6_FILTER_PASSONLY = 0x4
|
|
||||||
|
|
||||||
sysSizeofKernelSockaddrStorage = 0x80
|
|
||||||
sysSizeofSockaddrInet6 = 0x1c
|
|
||||||
sysSizeofInet6Pktinfo = 0x14
|
|
||||||
sysSizeofIPv6Mtuinfo = 0x20
|
|
||||||
sysSizeofIPv6FlowlabelReq = 0x20
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = 0x14
|
|
||||||
sysSizeofGroupReq = 0x88
|
|
||||||
sysSizeofGroupSourceReq = 0x108
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = 0x20
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysKernelSockaddrStorage struct {
|
|
||||||
Family uint16
|
|
||||||
X__data [126]int8
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysSockaddrInet6 struct {
|
|
||||||
Family uint16
|
|
||||||
Port uint16
|
|
||||||
Flowinfo uint32
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Scope_id uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysInet6Pktinfo struct {
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Ifindex int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo struct {
|
|
||||||
Addr sysSockaddrInet6
|
|
||||||
Mtu uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6FlowlabelReq struct {
|
|
||||||
Dst [16]byte /* in6_addr */
|
|
||||||
Label uint32
|
|
||||||
Action uint8
|
|
||||||
Share uint8
|
|
||||||
Flags uint16
|
|
||||||
Expires uint16
|
|
||||||
Linger uint16
|
|
||||||
X__flr_pad uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mreq struct {
|
|
||||||
Multiaddr [16]byte /* in6_addr */
|
|
||||||
Ifindex int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Pad_cgo_0 [4]byte
|
|
||||||
Group sysKernelSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysGroupSourceReq struct {
|
|
||||||
Interface uint32
|
|
||||||
Pad_cgo_0 [4]byte
|
|
||||||
Group sysKernelSockaddrStorage
|
|
||||||
Source sysKernelSockaddrStorage
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysICMPv6Filter struct {
|
|
||||||
Data [8]uint32
|
|
||||||
}
|
|
||||||
-84
@@ -1,84 +0,0 @@
|
|||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs defs_netbsd.go
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_UNICAST_HOPS = 0x4
|
|
||||||
sysIPV6_MULTICAST_IF = 0x9
|
|
||||||
sysIPV6_MULTICAST_HOPS = 0xa
|
|
||||||
sysIPV6_MULTICAST_LOOP = 0xb
|
|
||||||
sysIPV6_JOIN_GROUP = 0xc
|
|
||||||
sysIPV6_LEAVE_GROUP = 0xd
|
|
||||||
sysIPV6_PORTRANGE = 0xe
|
|
||||||
sysICMP6_FILTER = 0x12
|
|
||||||
|
|
||||||
sysIPV6_CHECKSUM = 0x1a
|
|
||||||
sysIPV6_V6ONLY = 0x1b
|
|
||||||
|
|
||||||
sysIPV6_IPSEC_POLICY = 0x1c
|
|
||||||
|
|
||||||
sysIPV6_RTHDRDSTOPTS = 0x23
|
|
||||||
|
|
||||||
sysIPV6_RECVPKTINFO = 0x24
|
|
||||||
sysIPV6_RECVHOPLIMIT = 0x25
|
|
||||||
sysIPV6_RECVRTHDR = 0x26
|
|
||||||
sysIPV6_RECVHOPOPTS = 0x27
|
|
||||||
sysIPV6_RECVDSTOPTS = 0x28
|
|
||||||
|
|
||||||
sysIPV6_USE_MIN_MTU = 0x2a
|
|
||||||
sysIPV6_RECVPATHMTU = 0x2b
|
|
||||||
sysIPV6_PATHMTU = 0x2c
|
|
||||||
|
|
||||||
sysIPV6_PKTINFO = 0x2e
|
|
||||||
sysIPV6_HOPLIMIT = 0x2f
|
|
||||||
sysIPV6_NEXTHOP = 0x30
|
|
||||||
sysIPV6_HOPOPTS = 0x31
|
|
||||||
sysIPV6_DSTOPTS = 0x32
|
|
||||||
sysIPV6_RTHDR = 0x33
|
|
||||||
|
|
||||||
sysIPV6_RECVTCLASS = 0x39
|
|
||||||
|
|
||||||
sysIPV6_TCLASS = 0x3d
|
|
||||||
sysIPV6_DONTFRAG = 0x3e
|
|
||||||
|
|
||||||
sysIPV6_PORTRANGE_DEFAULT = 0x0
|
|
||||||
sysIPV6_PORTRANGE_HIGH = 0x1
|
|
||||||
sysIPV6_PORTRANGE_LOW = 0x2
|
|
||||||
|
|
||||||
sysSizeofSockaddrInet6 = 0x1c
|
|
||||||
sysSizeofInet6Pktinfo = 0x14
|
|
||||||
sysSizeofIPv6Mtuinfo = 0x20
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = 0x14
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = 0x20
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysSockaddrInet6 struct {
|
|
||||||
Len uint8
|
|
||||||
Family uint8
|
|
||||||
Port uint16
|
|
||||||
Flowinfo uint32
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Scope_id uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysInet6Pktinfo struct {
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Ifindex uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo struct {
|
|
||||||
Addr sysSockaddrInet6
|
|
||||||
Mtu uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mreq struct {
|
|
||||||
Multiaddr [16]byte /* in6_addr */
|
|
||||||
Interface uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysICMPv6Filter struct {
|
|
||||||
Filt [8]uint32
|
|
||||||
}
|
|
||||||
-93
@@ -1,93 +0,0 @@
|
|||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs defs_openbsd.go
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_UNICAST_HOPS = 0x4
|
|
||||||
sysIPV6_MULTICAST_IF = 0x9
|
|
||||||
sysIPV6_MULTICAST_HOPS = 0xa
|
|
||||||
sysIPV6_MULTICAST_LOOP = 0xb
|
|
||||||
sysIPV6_JOIN_GROUP = 0xc
|
|
||||||
sysIPV6_LEAVE_GROUP = 0xd
|
|
||||||
sysIPV6_PORTRANGE = 0xe
|
|
||||||
sysICMP6_FILTER = 0x12
|
|
||||||
|
|
||||||
sysIPV6_CHECKSUM = 0x1a
|
|
||||||
sysIPV6_V6ONLY = 0x1b
|
|
||||||
|
|
||||||
sysIPV6_RTHDRDSTOPTS = 0x23
|
|
||||||
|
|
||||||
sysIPV6_RECVPKTINFO = 0x24
|
|
||||||
sysIPV6_RECVHOPLIMIT = 0x25
|
|
||||||
sysIPV6_RECVRTHDR = 0x26
|
|
||||||
sysIPV6_RECVHOPOPTS = 0x27
|
|
||||||
sysIPV6_RECVDSTOPTS = 0x28
|
|
||||||
|
|
||||||
sysIPV6_USE_MIN_MTU = 0x2a
|
|
||||||
sysIPV6_RECVPATHMTU = 0x2b
|
|
||||||
|
|
||||||
sysIPV6_PATHMTU = 0x2c
|
|
||||||
|
|
||||||
sysIPV6_PKTINFO = 0x2e
|
|
||||||
sysIPV6_HOPLIMIT = 0x2f
|
|
||||||
sysIPV6_NEXTHOP = 0x30
|
|
||||||
sysIPV6_HOPOPTS = 0x31
|
|
||||||
sysIPV6_DSTOPTS = 0x32
|
|
||||||
sysIPV6_RTHDR = 0x33
|
|
||||||
|
|
||||||
sysIPV6_AUTH_LEVEL = 0x35
|
|
||||||
sysIPV6_ESP_TRANS_LEVEL = 0x36
|
|
||||||
sysIPV6_ESP_NETWORK_LEVEL = 0x37
|
|
||||||
sysIPSEC6_OUTSA = 0x38
|
|
||||||
sysIPV6_RECVTCLASS = 0x39
|
|
||||||
|
|
||||||
sysIPV6_AUTOFLOWLABEL = 0x3b
|
|
||||||
sysIPV6_IPCOMP_LEVEL = 0x3c
|
|
||||||
|
|
||||||
sysIPV6_TCLASS = 0x3d
|
|
||||||
sysIPV6_DONTFRAG = 0x3e
|
|
||||||
sysIPV6_PIPEX = 0x3f
|
|
||||||
|
|
||||||
sysIPV6_RTABLE = 0x1021
|
|
||||||
|
|
||||||
sysIPV6_PORTRANGE_DEFAULT = 0x0
|
|
||||||
sysIPV6_PORTRANGE_HIGH = 0x1
|
|
||||||
sysIPV6_PORTRANGE_LOW = 0x2
|
|
||||||
|
|
||||||
sysSizeofSockaddrInet6 = 0x1c
|
|
||||||
sysSizeofInet6Pktinfo = 0x14
|
|
||||||
sysSizeofIPv6Mtuinfo = 0x20
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = 0x14
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = 0x20
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysSockaddrInet6 struct {
|
|
||||||
Len uint8
|
|
||||||
Family uint8
|
|
||||||
Port uint16
|
|
||||||
Flowinfo uint32
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Scope_id uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysInet6Pktinfo struct {
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Ifindex uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo struct {
|
|
||||||
Addr sysSockaddrInet6
|
|
||||||
Mtu uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mreq struct {
|
|
||||||
Multiaddr [16]byte /* in6_addr */
|
|
||||||
Interface uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysICMPv6Filter struct {
|
|
||||||
Filt [8]uint32
|
|
||||||
}
|
|
||||||
-105
@@ -1,105 +0,0 @@
|
|||||||
// Created by cgo -godefs - DO NOT EDIT
|
|
||||||
// cgo -godefs defs_solaris.go
|
|
||||||
|
|
||||||
// +build solaris
|
|
||||||
|
|
||||||
package ipv6
|
|
||||||
|
|
||||||
const (
|
|
||||||
sysIPV6_UNICAST_HOPS = 0x5
|
|
||||||
sysIPV6_MULTICAST_IF = 0x6
|
|
||||||
sysIPV6_MULTICAST_HOPS = 0x7
|
|
||||||
sysIPV6_MULTICAST_LOOP = 0x8
|
|
||||||
sysIPV6_JOIN_GROUP = 0x9
|
|
||||||
sysIPV6_LEAVE_GROUP = 0xa
|
|
||||||
|
|
||||||
sysIPV6_PKTINFO = 0xb
|
|
||||||
|
|
||||||
sysIPV6_HOPLIMIT = 0xc
|
|
||||||
sysIPV6_NEXTHOP = 0xd
|
|
||||||
sysIPV6_HOPOPTS = 0xe
|
|
||||||
sysIPV6_DSTOPTS = 0xf
|
|
||||||
|
|
||||||
sysIPV6_RTHDR = 0x10
|
|
||||||
sysIPV6_RTHDRDSTOPTS = 0x11
|
|
||||||
|
|
||||||
sysIPV6_RECVPKTINFO = 0x12
|
|
||||||
sysIPV6_RECVHOPLIMIT = 0x13
|
|
||||||
sysIPV6_RECVHOPOPTS = 0x14
|
|
||||||
|
|
||||||
sysIPV6_RECVRTHDR = 0x16
|
|
||||||
|
|
||||||
sysIPV6_RECVRTHDRDSTOPTS = 0x17
|
|
||||||
|
|
||||||
sysIPV6_CHECKSUM = 0x18
|
|
||||||
sysIPV6_RECVTCLASS = 0x19
|
|
||||||
sysIPV6_USE_MIN_MTU = 0x20
|
|
||||||
sysIPV6_DONTFRAG = 0x21
|
|
||||||
sysIPV6_SEC_OPT = 0x22
|
|
||||||
sysIPV6_SRC_PREFERENCES = 0x23
|
|
||||||
sysIPV6_RECVPATHMTU = 0x24
|
|
||||||
sysIPV6_PATHMTU = 0x25
|
|
||||||
sysIPV6_TCLASS = 0x26
|
|
||||||
sysIPV6_V6ONLY = 0x27
|
|
||||||
|
|
||||||
sysIPV6_RECVDSTOPTS = 0x28
|
|
||||||
|
|
||||||
sysIPV6_PREFER_SRC_HOME = 0x1
|
|
||||||
sysIPV6_PREFER_SRC_COA = 0x2
|
|
||||||
sysIPV6_PREFER_SRC_PUBLIC = 0x4
|
|
||||||
sysIPV6_PREFER_SRC_TMP = 0x8
|
|
||||||
sysIPV6_PREFER_SRC_NONCGA = 0x10
|
|
||||||
sysIPV6_PREFER_SRC_CGA = 0x20
|
|
||||||
|
|
||||||
sysIPV6_PREFER_SRC_MIPMASK = 0x3
|
|
||||||
sysIPV6_PREFER_SRC_MIPDEFAULT = 0x1
|
|
||||||
sysIPV6_PREFER_SRC_TMPMASK = 0xc
|
|
||||||
sysIPV6_PREFER_SRC_TMPDEFAULT = 0x4
|
|
||||||
sysIPV6_PREFER_SRC_CGAMASK = 0x30
|
|
||||||
sysIPV6_PREFER_SRC_CGADEFAULT = 0x10
|
|
||||||
|
|
||||||
sysIPV6_PREFER_SRC_MASK = 0x3f
|
|
||||||
|
|
||||||
sysIPV6_PREFER_SRC_DEFAULT = 0x15
|
|
||||||
|
|
||||||
sysIPV6_BOUND_IF = 0x41
|
|
||||||
sysIPV6_UNSPEC_SRC = 0x42
|
|
||||||
|
|
||||||
sysICMP6_FILTER = 0x1
|
|
||||||
|
|
||||||
sysSizeofSockaddrInet6 = 0x20
|
|
||||||
sysSizeofInet6Pktinfo = 0x14
|
|
||||||
sysSizeofIPv6Mtuinfo = 0x24
|
|
||||||
|
|
||||||
sysSizeofIPv6Mreq = 0x14
|
|
||||||
|
|
||||||
sysSizeofICMPv6Filter = 0x20
|
|
||||||
)
|
|
||||||
|
|
||||||
type sysSockaddrInet6 struct {
|
|
||||||
Family uint16
|
|
||||||
Port uint16
|
|
||||||
Flowinfo uint32
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Scope_id uint32
|
|
||||||
X__sin6_src_id uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysInet6Pktinfo struct {
|
|
||||||
Addr [16]byte /* in6_addr */
|
|
||||||
Ifindex uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mtuinfo struct {
|
|
||||||
Addr sysSockaddrInet6
|
|
||||||
Mtu uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysIPv6Mreq struct {
|
|
||||||
Multiaddr [16]byte /* in6_addr */
|
|
||||||
Interface uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type sysICMPv6Filter struct {
|
|
||||||
X__icmp6_filt [8]uint32
|
|
||||||
}
|
|
||||||
@@ -18,7 +18,6 @@ brbecker <brbecker@gmail.com>
|
|||||||
brendanlong <self@brendanlong.com>
|
brendanlong <self@brendanlong.com>
|
||||||
brgmnn <dan.arne.bergmann@gmail.com> <brgmnn@users.noreply.github.com>
|
brgmnn <dan.arne.bergmann@gmail.com> <brgmnn@users.noreply.github.com>
|
||||||
bsidhom <bsidhom@gmail.com>
|
bsidhom <bsidhom@gmail.com>
|
||||||
burkemw3 <mburke@amplify.com>
|
|
||||||
calmh <jakob@nym.se>
|
calmh <jakob@nym.se>
|
||||||
canton7 <antony.male@gmail.com>
|
canton7 <antony.male@gmail.com>
|
||||||
cdata <chris@scriptolo.gy>
|
cdata <chris@scriptolo.gy>
|
||||||
@@ -53,11 +52,10 @@ pluby <phill.luby@newredo.com>
|
|||||||
pyfisch <pyfisch@gmail.com>
|
pyfisch <pyfisch@gmail.com>
|
||||||
qbit <qbit@deftly.net>
|
qbit <qbit@deftly.net>
|
||||||
ralder <ralder@yandex.ru>
|
ralder <ralder@yandex.ru>
|
||||||
rumpelsepp <stefan@sevenbyte.org> <rumpelsepp@sevenbyte.org>
|
rumpelsepp <stefan@sevenbyte.org>
|
||||||
sciurius <jvromans@squirrel.nl>
|
sciurius <jvromans@squirrel.nl>
|
||||||
seehuhn <voss@seehuhn.de>
|
seehuhn <voss@seehuhn.de>
|
||||||
snnd <dw@risu.io>
|
snnd <dw@risu.io>
|
||||||
simplypeachy <aD@simplypeachy.co.uk> <simplypeachy@users.noreply.github.com>
|
|
||||||
timabell <tim@timwise.co.uk>
|
timabell <tim@timwise.co.uk>
|
||||||
tnn2 <tnn@nygren.pp.se>
|
tnn2 <tnn@nygren.pp.se>
|
||||||
tojrobinson <tully@tojr.org>
|
tojrobinson <tully@tojr.org>
|
||||||
|
|||||||
@@ -21,11 +21,11 @@ func main() {
|
|||||||
|
|
||||||
var server string
|
var server string
|
||||||
|
|
||||||
flag.StringVar(&server, "server", "udp4://announce.syncthing.net:22026", "Announce server")
|
flag.StringVar(&server, "server", "udp4://announce.syncthing.net:22027", "Announce server")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if len(flag.Args()) != 1 || server == "" {
|
if len(flag.Args()) != 1 || server == "" {
|
||||||
log.Printf("Usage: %s [-server=\"udp4://announce.syncthing.net:22026\"] <device>", os.Args[0])
|
log.Printf("Usage: %s [-server=\"udp4://announce.syncthing.net:22027\"] <device>", os.Args[0])
|
||||||
os.Exit(64)
|
os.Exit(64)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,9 +35,13 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
discoverer := discover.NewDiscoverer(protocol.LocalDeviceID, nil)
|
discoverer := discover.NewDiscoverer(protocol.LocalDeviceID, nil, nil)
|
||||||
discoverer.StartGlobal([]string{server}, 1)
|
discoverer.StartGlobal([]string{server}, 1)
|
||||||
for _, addr := range discoverer.Lookup(id) {
|
addresses, relays := discoverer.Lookup(id)
|
||||||
log.Println(addr)
|
for _, addr := range addresses {
|
||||||
|
log.Println("address:", addr)
|
||||||
|
}
|
||||||
|
for _, addr := range relays {
|
||||||
|
log.Println("relay:", addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user