fix vendor

This commit is contained in:
马嘉聪 2019-05-11 03:14:39 +08:00
parent 10af000e28
commit 3cb1dddb45
189 changed files with 20163 additions and 1135 deletions

5
go.sum
View File

@ -14,6 +14,7 @@ github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk= github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ=
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
@ -51,13 +52,9 @@ github.com/tjfoc/gmsm v0.0.0-20171124023159-98aa888b79d8 h1:6CNSDqI1wiE+JqyOy5Qt
github.com/tjfoc/gmsm v0.0.0-20171124023159-98aa888b79d8/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc= github.com/tjfoc/gmsm v0.0.0-20171124023159-98aa888b79d8/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc=
github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec h1:DGmKwyZwEB8dI7tbLt/I/gQuP559o/0FrAkHKlQM/Ks= github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec h1:DGmKwyZwEB8dI7tbLt/I/gQuP559o/0FrAkHKlQM/Ks=
github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec/go.mod h1:owBmyHYMLkxyrugmfwE/DLJyW8Ro9mkphwuVErQ0iUw= github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec/go.mod h1:owBmyHYMLkxyrugmfwE/DLJyW8Ro9mkphwuVErQ0iUw=
golang.org/x/crypto v0.0.0-20180505025534-4ec37c66abab h1:w4c/LoOA2vE8SYwh8wEEQVRUwpph7TtcjH7AtZvOjy0=
golang.org/x/crypto v0.0.0-20180505025534-4ec37c66abab/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 h1:iMGN4xG0cnqj3t+zOM8wUB0BiPKHEwSxEZCvzcbZuvk= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 h1:iMGN4xG0cnqj3t+zOM8wUB0BiPKHEwSxEZCvzcbZuvk=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20180524181706-dfa909b99c79 h1:1FDlG4HI84rVePw1/0E/crL5tt2N+1blLJpY6UZ6krs=
golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 h1:6M3SDHlHHDCx2PcQw3S4KsR170vGqDhJDOmpVd4Hjak= golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 h1:6M3SDHlHHDCx2PcQw3S4KsR170vGqDhJDOmpVd4Hjak=
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=

0
vendor/github.com/kardianos/service/.gitignore generated vendored Normal file
View File

17
vendor/github.com/kardianos/service/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,17 @@
language: go
go_import_path: github.com/kardianos/service
sudo: required
go:
- 1.10.x
- 1.11.x
- master
before_install:
- go get github.com/mattn/goveralls
- go get golang.org/x/tools/cmd/cover
script:
- chmod +x linux-test-su.sh
- sudo ./linux-test-su.sh $GOPATH `which go`
- $GOPATH/bin/goveralls -service=travis-ci

20
vendor/github.com/kardianos/service/LICENSE generated vendored Normal file
View File

@ -0,0 +1,20 @@
Copyright (c) 2015 Daniel Theophanes
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.

14
vendor/github.com/kardianos/service/README.md generated vendored Normal file
View File

@ -0,0 +1,14 @@
# service [![GoDoc](https://godoc.org/github.com/kardianos/service?status.svg)](https://godoc.org/github.com/kardianos/service)
service will install / un-install, start / stop, and run a program as a service (daemon).
Currently supports Windows XP+, Linux/(systemd | Upstart | SysV), and OSX/Launchd.
Windows controls services by setting up callbacks that is non-trivial. This
is very different then other systems. This package provides the same API
despite the substantial differences.
It also can be used to detect how a program is called, from an interactive
terminal or from a service manager.
## BUGS
* Dependencies field is not implemented for Linux systems and Launchd.
* OS X when running as a UserService Interactive will not be accurate.

21
vendor/github.com/kardianos/service/appveyor.yml generated vendored Normal file
View File

@ -0,0 +1,21 @@
version: "{build}"
platform:
- x86
- x64
clone_folder: c:\gopath\src\github.com\kardianos\service
environment:
GOPATH: c:\gopath
install:
- go version
- go env
- go get -v -t ./...
build_script:
- go install -v ./...
test_script:
- go test -v -tags su ./...

48
vendor/github.com/kardianos/service/console.go generated vendored Normal file
View File

@ -0,0 +1,48 @@
// Copyright 2015 Daniel Theophanes.
// Use of this source code is governed by a zlib-style
// license that can be found in the LICENSE file.
package service
import (
"log"
"os"
)
// ConsoleLogger logs to the std err.
var ConsoleLogger = consoleLogger{}
type consoleLogger struct {
info, warn, err *log.Logger
}
func init() {
ConsoleLogger.info = log.New(os.Stderr, "I: ", log.Ltime)
ConsoleLogger.warn = log.New(os.Stderr, "W: ", log.Ltime)
ConsoleLogger.err = log.New(os.Stderr, "E: ", log.Ltime)
}
func (c consoleLogger) Error(v ...interface{}) error {
c.err.Print(v...)
return nil
}
func (c consoleLogger) Warning(v ...interface{}) error {
c.warn.Print(v...)
return nil
}
func (c consoleLogger) Info(v ...interface{}) error {
c.info.Print(v...)
return nil
}
func (c consoleLogger) Errorf(format string, a ...interface{}) error {
c.err.Printf(format, a...)
return nil
}
func (c consoleLogger) Warningf(format string, a ...interface{}) error {
c.warn.Printf(format, a...)
return nil
}
func (c consoleLogger) Infof(format string, a ...interface{}) error {
c.info.Printf(format, a...)
return nil
}

5
vendor/github.com/kardianos/service/go.mod generated vendored Normal file
View File

@ -0,0 +1,5 @@
module github.com/kardianos/service
go 1.10
require golang.org/x/sys v0.0.0-20190204203706-41f3e6584952

2
vendor/github.com/kardianos/service/go.sum generated vendored Normal file
View File

@ -0,0 +1,2 @@
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952 h1:FDfvYgoVsA7TTZSbgiqjAbfPbK47CNHdWl3h/PJtii0=
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=

15
vendor/github.com/kardianos/service/linux-test-su.sh generated vendored Normal file
View File

@ -0,0 +1,15 @@
#!/usr/bin/env bash
# This script is used to run the tests under linux as root
#
# Usage:
# linux-test-su.sh goPath goBinPath
#
# goPath is the standard GOPATH
# goBinPath is the location of go
#
# Typical usage:
# sudo ./linux-test-su.sh $GOPATH `which go`
export GOPATH=$1
export GOROOT=`dirname $(dirname $2)`
$GOROOT/bin/go test -v -tags su ./...

393
vendor/github.com/kardianos/service/service.go generated vendored Normal file
View File

@ -0,0 +1,393 @@
// Copyright 2015 Daniel Theophanes.
// Use of this source code is governed by a zlib-style
// license that can be found in the LICENSE file.
// Package service provides a simple way to create a system service.
// Currently supports Windows, Linux/(systemd | Upstart | SysV), and OSX/Launchd.
//
// Windows controls services by setting up callbacks that is non-trivial. This
// is very different then other systems. This package provides the same API
// despite the substantial differences.
// It also can be used to detect how a program is called, from an interactive
// terminal or from a service manager.
//
// Examples in the example/ folder.
//
// package main
//
// import (
// "log"
//
// "github.com/kardianos/service"
// )
//
// var logger service.Logger
//
// type program struct{}
//
// func (p *program) Start(s service.Service) error {
// // Start should not block. Do the actual work async.
// go p.run()
// return nil
// }
// func (p *program) run() {
// // Do work here
// }
// func (p *program) Stop(s service.Service) error {
// // Stop should not block. Return with a few seconds.
// return nil
// }
//
// func main() {
// svcConfig := &service.Config{
// Name: "GoServiceTest",
// DisplayName: "Go Service Test",
// Description: "This is a test Go service.",
// }
//
// prg := &program{}
// s, err := service.New(prg, svcConfig)
// if err != nil {
// log.Fatal(err)
// }
// logger, err = s.Logger(nil)
// if err != nil {
// log.Fatal(err)
// }
// err = s.Run()
// if err != nil {
// logger.Error(err)
// }
// }
package service // import "github.com/kardianos/service"
import (
"errors"
"fmt"
)
const (
optionKeepAlive = "KeepAlive"
optionKeepAliveDefault = true
optionRunAtLoad = "RunAtLoad"
optionRunAtLoadDefault = false
optionUserService = "UserService"
optionUserServiceDefault = false
optionSessionCreate = "SessionCreate"
optionSessionCreateDefault = false
optionLogOutput = "LogOutput"
optionLogOutputDefault = false
optionRunWait = "RunWait"
optionReloadSignal = "ReloadSignal"
optionPIDFile = "PIDFile"
optionSystemdScript = "SystemdScript"
optionSysvScript = "SysvScript"
optionUpstartScript = "UpstartScript"
optionLaunchdConfig = "LaunchdConfig"
)
// Status represents service status as an byte value
type Status byte
// Status of service represented as an byte
const (
StatusUnknown Status = iota // Status is unable to be determined due to an error or it was not installed.
StatusRunning
StatusStopped
)
// Config provides the setup for a Service. The Name field is required.
type Config struct {
Name string // Required name of the service. No spaces suggested.
DisplayName string // Display name, spaces allowed.
Description string // Long description of service.
UserName string // Run as username.
Arguments []string // Run with arguments.
// Optional field to specify the executable for service.
// If empty the current executable is used.
Executable string
// Array of service dependencies.
// Not yet implemented on Linux or OS X.
Dependencies []string
// The following fields are not supported on Windows.
WorkingDirectory string // Initial working directory.
ChRoot string
// System specific options.
// * OS X
// - LaunchdConfig string () - Use custom launchd config
// - KeepAlive bool (true)
// - RunAtLoad bool (false)
// - UserService bool (false) - Install as a current user service.
// - SessionCreate bool (false) - Create a full user session.
// * POSIX
// - SystemdScript string () - Use custom systemd script
// - UpstartScript string () - Use custom upstart script
// - SysvScript string () - Use custom sysv script
// - RunWait func() (wait for SIGNAL) - Do not install signal but wait for this function to return.
// - ReloadSignal string () [USR1, ...] - Signal to send on reaload.
// - PIDFile string () [/run/prog.pid] - Location of the PID file.
// - LogOutput bool (false) - Redirect StdErr & StdOut to files.
Option KeyValue
}
var (
system System
systemRegistry []System
)
var (
// ErrNameFieldRequired is returned when Config.Name is empty.
ErrNameFieldRequired = errors.New("Config.Name field is required.")
// ErrNoServiceSystemDetected is returned when no system was detected.
ErrNoServiceSystemDetected = errors.New("No service system detected.")
// ErrNotInstalled is returned when the service is not installed
ErrNotInstalled = errors.New("the service is not installed")
)
// New creates a new service based on a service interface and configuration.
func New(i Interface, c *Config) (Service, error) {
if len(c.Name) == 0 {
return nil, ErrNameFieldRequired
}
if system == nil {
return nil, ErrNoServiceSystemDetected
}
return system.New(i, c)
}
// KeyValue provides a list of platform specific options. See platform docs for
// more details.
type KeyValue map[string]interface{}
// bool returns the value of the given name, assuming the value is a boolean.
// If the value isn't found or is not of the type, the defaultValue is returned.
func (kv KeyValue) bool(name string, defaultValue bool) bool {
if v, found := kv[name]; found {
if castValue, is := v.(bool); is {
return castValue
}
}
return defaultValue
}
// int returns the value of the given name, assuming the value is an int.
// If the value isn't found or is not of the type, the defaultValue is returned.
func (kv KeyValue) int(name string, defaultValue int) int {
if v, found := kv[name]; found {
if castValue, is := v.(int); is {
return castValue
}
}
return defaultValue
}
// string returns the value of the given name, assuming the value is a string.
// If the value isn't found or is not of the type, the defaultValue is returned.
func (kv KeyValue) string(name string, defaultValue string) string {
if v, found := kv[name]; found {
if castValue, is := v.(string); is {
return castValue
}
}
return defaultValue
}
// float64 returns the value of the given name, assuming the value is a float64.
// If the value isn't found or is not of the type, the defaultValue is returned.
func (kv KeyValue) float64(name string, defaultValue float64) float64 {
if v, found := kv[name]; found {
if castValue, is := v.(float64); is {
return castValue
}
}
return defaultValue
}
// funcSingle returns the value of the given name, assuming the value is a float64.
// If the value isn't found or is not of the type, the defaultValue is returned.
func (kv KeyValue) funcSingle(name string, defaultValue func()) func() {
if v, found := kv[name]; found {
if castValue, is := v.(func()); is {
return castValue
}
}
return defaultValue
}
// Platform returns a description of the system service.
func Platform() string {
if system == nil {
return ""
}
return system.String()
}
// Interactive returns false if running under the OS service manager
// and true otherwise.
func Interactive() bool {
if system == nil {
return true
}
return system.Interactive()
}
func newSystem() System {
for _, choice := range systemRegistry {
if choice.Detect() == false {
continue
}
return choice
}
return nil
}
// ChooseSystem chooses a system from the given system services.
// SystemServices are considered in the order they are suggested.
// Calling this may change what Interactive and Platform return.
func ChooseSystem(a ...System) {
systemRegistry = a
system = newSystem()
}
// ChosenSystem returns the system that service will use.
func ChosenSystem() System {
return system
}
// AvailableSystems returns the list of system services considered
// when choosing the system service.
func AvailableSystems() []System {
return systemRegistry
}
// System represents the service manager that is available.
type System interface {
// String returns a description of the system.
String() string
// Detect returns true if the system is available to use.
Detect() bool
// Interactive returns false if running under the system service manager
// and true otherwise.
Interactive() bool
// New creates a new service for this system.
New(i Interface, c *Config) (Service, error)
}
// Interface represents the service interface for a program. Start runs before
// the hosting process is granted control and Stop runs when control is returned.
//
// 1. OS service manager executes user program.
// 2. User program sees it is executed from a service manager (IsInteractive is false).
// 3. User program calls Service.Run() which blocks.
// 4. Interface.Start() is called and quickly returns.
// 5. User program runs.
// 6. OS service manager signals the user program to stop.
// 7. Interface.Stop() is called and quickly returns.
// - For a successful exit, os.Exit should not be called in Interface.Stop().
// 8. Service.Run returns.
// 9. User program should quickly exit.
type Interface interface {
// Start provides a place to initiate the service. The service doesn't not
// signal a completed start until after this function returns, so the
// Start function must not take more then a few seconds at most.
Start(s Service) error
// Stop provides a place to clean up program execution before it is terminated.
// It should not take more then a few seconds to execute.
// Stop should not call os.Exit directly in the function.
Stop(s Service) error
}
// TODO: Add Configure to Service interface.
// Service represents a service that can be run or controlled.
type Service interface {
// Run should be called shortly after the program entry point.
// After Interface.Stop has finished running, Run will stop blocking.
// After Run stops blocking, the program must exit shortly after.
Run() error
// Start signals to the OS service manager the given service should start.
Start() error
// Stop signals to the OS service manager the given service should stop.
Stop() error
// Restart signals to the OS service manager the given service should stop then start.
Restart() error
// Install setups up the given service in the OS service manager. This may require
// greater rights. Will return an error if it is already installed.
Install() error
// Uninstall removes the given service from the OS service manager. This may require
// greater rights. Will return an error if the service is not present.
Uninstall() error
// Opens and returns a system logger. If the user program is running
// interactively rather then as a service, the returned logger will write to
// os.Stderr. If errs is non-nil errors will be sent on errs as well as
// returned from Logger's functions.
Logger(errs chan<- error) (Logger, error)
// SystemLogger opens and returns a system logger. If errs is non-nil errors
// will be sent on errs as well as returned from Logger's functions.
SystemLogger(errs chan<- error) (Logger, error)
// String displays the name of the service. The display name if present,
// otherwise the name.
String() string
// Platform displays the name of the system that manages the service.
// In most cases this will be the same as service.Platform().
Platform() string
// Status returns the current service status.
Status() (Status, error)
}
// ControlAction list valid string texts to use in Control.
var ControlAction = [5]string{"start", "stop", "restart", "install", "uninstall"}
// Control issues control functions to the service from a given action string.
func Control(s Service, action string) error {
var err error
switch action {
case ControlAction[0]:
err = s.Start()
case ControlAction[1]:
err = s.Stop()
case ControlAction[2]:
err = s.Restart()
case ControlAction[3]:
err = s.Install()
case ControlAction[4]:
err = s.Uninstall()
default:
err = fmt.Errorf("Unknown action %s", action)
}
if err != nil {
return fmt.Errorf("Failed to %s %v: %v", action, s, err)
}
return nil
}
// Logger writes to the system log.
type Logger interface {
Error(v ...interface{}) error
Warning(v ...interface{}) error
Info(v ...interface{}) error
Errorf(format string, a ...interface{}) error
Warningf(format string, a ...interface{}) error
Infof(format string, a ...interface{}) error
}

282
vendor/github.com/kardianos/service/service_darwin.go generated vendored Normal file
View File

@ -0,0 +1,282 @@
// Copyright 2015 Daniel Theophanes.
// Use of this source code is governed by a zlib-style
// license that can be found in the LICENSE file.
package service
import (
"errors"
"fmt"
"os"
"os/signal"
"os/user"
"path/filepath"
"regexp"
"strings"
"syscall"
"text/template"
"time"
)
const maxPathSize = 32 * 1024
const version = "darwin-launchd"
type darwinSystem struct{}
func (darwinSystem) String() string {
return version
}
func (darwinSystem) Detect() bool {
return true
}
func (darwinSystem) Interactive() bool {
return interactive
}
func (darwinSystem) New(i Interface, c *Config) (Service, error) {
s := &darwinLaunchdService{
i: i,
Config: c,
userService: c.Option.bool(optionUserService, optionUserServiceDefault),
}
return s, nil
}
func init() {
ChooseSystem(darwinSystem{})
}
var interactive = false
func init() {
var err error
interactive, err = isInteractive()
if err != nil {
panic(err)
}
}
func isInteractive() (bool, error) {
// TODO: The PPID of Launchd is 1. The PPid of a service process should match launchd's PID.
return os.Getppid() != 1, nil
}
type darwinLaunchdService struct {
i Interface
*Config
userService bool
}
func (s *darwinLaunchdService) String() string {
if len(s.DisplayName) > 0 {
return s.DisplayName
}
return s.Name
}
func (s *darwinLaunchdService) Platform() string {
return version
}
func (s *darwinLaunchdService) getHomeDir() (string, error) {
u, err := user.Current()
if err == nil {
return u.HomeDir, nil
}
// alternate methods
homeDir := os.Getenv("HOME") // *nix
if homeDir == "" {
return "", errors.New("User home directory not found.")
}
return homeDir, nil
}
func (s *darwinLaunchdService) getServiceFilePath() (string, error) {
if s.userService {
homeDir, err := s.getHomeDir()
if err != nil {
return "", err
}
return homeDir + "/Library/LaunchAgents/" + s.Name + ".plist", nil
}
return "/Library/LaunchDaemons/" + s.Name + ".plist", nil
}
func (s *darwinLaunchdService) template() *template.Template {
functions := template.FuncMap{
"bool": func(v bool) string {
if v {
return "true"
}
return "false"
},
}
customConfig := s.Option.string(optionLaunchdConfig, "")
if customConfig != "" {
return template.Must(template.New("").Funcs(functions).Parse(customConfig))
} else {
return template.Must(template.New("").Funcs(functions).Parse(launchdConfig))
}
}
func (s *darwinLaunchdService) Install() error {
confPath, err := s.getServiceFilePath()
if err != nil {
return err
}
_, err = os.Stat(confPath)
if err == nil {
return fmt.Errorf("Init already exists: %s", confPath)
}
if s.userService {
// Ensure that ~/Library/LaunchAgents exists.
err = os.MkdirAll(filepath.Dir(confPath), 0700)
if err != nil {
return err
}
}
f, err := os.Create(confPath)
if err != nil {
return err
}
defer f.Close()
path, err := s.execPath()
if err != nil {
return err
}
var to = &struct {
*Config
Path string
KeepAlive, RunAtLoad bool
SessionCreate bool
}{
Config: s.Config,
Path: path,
KeepAlive: s.Option.bool(optionKeepAlive, optionKeepAliveDefault),
RunAtLoad: s.Option.bool(optionRunAtLoad, optionRunAtLoadDefault),
SessionCreate: s.Option.bool(optionSessionCreate, optionSessionCreateDefault),
}
return s.template().Execute(f, to)
}
func (s *darwinLaunchdService) Uninstall() error {
s.Stop()
confPath, err := s.getServiceFilePath()
if err != nil {
return err
}
return os.Remove(confPath)
}
func (s *darwinLaunchdService) Status() (Status, error) {
exitCode, out, err := runWithOutput("launchctl", "list", s.Name)
if exitCode == 0 && err != nil {
if !strings.Contains(err.Error(), "failed with stderr") {
return StatusUnknown, err
}
}
re := regexp.MustCompile(`"PID" = ([0-9]+);`)
matches := re.FindStringSubmatch(out)
if len(matches) == 2 {
return StatusRunning, nil
}
confPath, err := s.getServiceFilePath()
if err != nil {
return StatusUnknown, err
}
if _, err = os.Stat(confPath); err == nil {
return StatusStopped, nil
}
return StatusUnknown, ErrNotInstalled
}
func (s *darwinLaunchdService) Start() error {
confPath, err := s.getServiceFilePath()
if err != nil {
return err
}
return run("launchctl", "load", confPath)
}
func (s *darwinLaunchdService) Stop() error {
confPath, err := s.getServiceFilePath()
if err != nil {
return err
}
return run("launchctl", "unload", confPath)
}
func (s *darwinLaunchdService) Restart() error {
err := s.Stop()
if err != nil {
return err
}
time.Sleep(50 * time.Millisecond)
return s.Start()
}
func (s *darwinLaunchdService) Run() error {
var err error
err = s.i.Start(s)
if err != nil {
return err
}
s.Option.funcSingle(optionRunWait, func() {
var sigChan = make(chan os.Signal, 3)
signal.Notify(sigChan, syscall.SIGTERM, os.Interrupt)
<-sigChan
})()
return s.i.Stop(s)
}
func (s *darwinLaunchdService) Logger(errs chan<- error) (Logger, error) {
if interactive {
return ConsoleLogger, nil
}
return s.SystemLogger(errs)
}
func (s *darwinLaunchdService) SystemLogger(errs chan<- error) (Logger, error) {
return newSysLogger(s.Name, errs)
}
var launchdConfig = `<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd" >
<plist version='1.0'>
<dict>
<key>Label</key><string>{{html .Name}}</string>
<key>ProgramArguments</key>
<array>
<string>{{html .Path}}</string>
{{range .Config.Arguments}}
<string>{{html .}}</string>
{{end}}
</array>
{{if .UserName}}<key>UserName</key><string>{{html .UserName}}</string>{{end}}
{{if .ChRoot}}<key>RootDirectory</key><string>{{html .ChRoot}}</string>{{end}}
{{if .WorkingDirectory}}<key>WorkingDirectory</key><string>{{html .WorkingDirectory}}</string>{{end}}
<key>SessionCreate</key><{{bool .SessionCreate}}/>
<key>KeepAlive</key><{{bool .KeepAlive}}/>
<key>RunAtLoad</key><{{bool .RunAtLoad}}/>
<key>Disabled</key><false/>
</dict>
</plist>
`

15
vendor/github.com/kardianos/service/service_go1.8.go generated vendored Normal file
View File

@ -0,0 +1,15 @@
//+build go1.8
package service
import (
"os"
"path/filepath"
)
func (c *Config) execPath() (string, error) {
if len(c.Executable) != 0 {
return filepath.Abs(c.Executable)
}
return os.Executable()
}

75
vendor/github.com/kardianos/service/service_linux.go generated vendored Normal file
View File

@ -0,0 +1,75 @@
// Copyright 2015 Daniel Theophanes.
// Use of this source code is governed by a zlib-style
// license that can be found in the LICENSE file.
package service
import (
"os"
"strings"
)
type linuxSystemService struct {
name string
detect func() bool
interactive func() bool
new func(i Interface, platform string, c *Config) (Service, error)
}
func (sc linuxSystemService) String() string {
return sc.name
}
func (sc linuxSystemService) Detect() bool {
return sc.detect()
}
func (sc linuxSystemService) Interactive() bool {
return sc.interactive()
}
func (sc linuxSystemService) New(i Interface, c *Config) (Service, error) {
return sc.new(i, sc.String(), c)
}
func init() {
ChooseSystem(linuxSystemService{
name: "linux-systemd",
detect: isSystemd,
interactive: func() bool {
is, _ := isInteractive()
return is
},
new: newSystemdService,
},
linuxSystemService{
name: "linux-upstart",
detect: isUpstart,
interactive: func() bool {
is, _ := isInteractive()
return is
},
new: newUpstartService,
},
linuxSystemService{
name: "unix-systemv",
detect: func() bool { return true },
interactive: func() bool {
is, _ := isInteractive()
return is
},
new: newSystemVService,
},
)
}
func isInteractive() (bool, error) {
// TODO: This is not true for user services.
return os.Getppid() != 1, nil
}
var tf = map[string]interface{}{
"cmd": func(s string) string {
return `"` + strings.Replace(s, `"`, `\"`, -1) + `"`
},
"cmdEscape": func(s string) string {
return strings.Replace(s, " ", `\x20`, -1)
},
}

View File

@ -0,0 +1,251 @@
// Copyright 2015 Daniel Theophanes.
// Use of this source code is governed by a zlib-style
// license that can be found in the LICENSE file.
package service
import (
"errors"
"fmt"
"os"
"os/signal"
"regexp"
"strconv"
"strings"
"syscall"
"text/template"
)
func isSystemd() bool {
if _, err := os.Stat("/run/systemd/system"); err == nil {
return true
}
return false
}
type systemd struct {
i Interface
platform string
*Config
}
func newSystemdService(i Interface, platform string, c *Config) (Service, error) {
s := &systemd{
i: i,
platform: platform,
Config: c,
}
return s, nil
}
func (s *systemd) String() string {
if len(s.DisplayName) > 0 {
return s.DisplayName
}
return s.Name
}
func (s *systemd) Platform() string {
return s.platform
}
// Systemd services should be supported, but are not currently.
var errNoUserServiceSystemd = errors.New("User services are not supported on systemd.")
func (s *systemd) configPath() (cp string, err error) {
if s.Option.bool(optionUserService, optionUserServiceDefault) {
err = errNoUserServiceSystemd
return
}
cp = "/etc/systemd/system/" + s.Config.Name + ".service"
return
}
func (s *systemd) getSystemdVersion() int64 {
_, out, err := runWithOutput("systemctl", "--version")
if err != nil {
return -1
}
re := regexp.MustCompile(`systemd ([0-9]+)`)
matches := re.FindStringSubmatch(out)
if len(matches) != 2 {
return -1
}
v, err := strconv.ParseInt(matches[1], 10, 64)
if err != nil {
return -1
}
return v
}
func (s *systemd) hasOutputFileSupport() bool {
defaultValue := true
version := s.getSystemdVersion()
if version == -1 {
return defaultValue
}
if version < 236 {
return false
}
return defaultValue
}
func (s *systemd) template() *template.Template {
customScript := s.Option.string(optionSystemdScript, "")
if customScript != "" {
return template.Must(template.New("").Funcs(tf).Parse(customScript))
} else {
return template.Must(template.New("").Funcs(tf).Parse(systemdScript))
}
}
func (s *systemd) Install() error {
confPath, err := s.configPath()
if err != nil {
return err
}
_, err = os.Stat(confPath)
if err == nil {
return fmt.Errorf("Init already exists: %s", confPath)
}
f, err := os.Create(confPath)
if err != nil {
return err
}
defer f.Close()
path, err := s.execPath()
if err != nil {
return err
}
var to = &struct {
*Config
Path string
HasOutputFileSupport bool
ReloadSignal string
PIDFile string
LogOutput bool
}{
s.Config,
path,
s.hasOutputFileSupport(),
s.Option.string(optionReloadSignal, ""),
s.Option.string(optionPIDFile, ""),
s.Option.bool(optionLogOutput, optionLogOutputDefault),
}
err = s.template().Execute(f, to)
if err != nil {
return err
}
err = run("systemctl", "enable", s.Name+".service")
if err != nil {
return err
}
return run("systemctl", "daemon-reload")
}
func (s *systemd) Uninstall() error {
err := run("systemctl", "disable", s.Name+".service")
if err != nil {
return err
}
cp, err := s.configPath()
if err != nil {
return err
}
if err := os.Remove(cp); err != nil {
return err
}
return nil
}
func (s *systemd) Logger(errs chan<- error) (Logger, error) {
if system.Interactive() {
return ConsoleLogger, nil
}
return s.SystemLogger(errs)
}
func (s *systemd) SystemLogger(errs chan<- error) (Logger, error) {
return newSysLogger(s.Name, errs)
}
func (s *systemd) Run() (err error) {
err = s.i.Start(s)
if err != nil {
return err
}
s.Option.funcSingle(optionRunWait, func() {
var sigChan = make(chan os.Signal, 3)
signal.Notify(sigChan, syscall.SIGTERM, os.Interrupt)
<-sigChan
})()
return s.i.Stop(s)
}
func (s *systemd) Status() (Status, error) {
exitCode, out, err := runWithOutput("systemctl", "is-active", s.Name)
if exitCode == 0 && err != nil {
return StatusUnknown, err
}
switch {
case strings.HasPrefix(out, "active"):
return StatusRunning, nil
case strings.HasPrefix(out, "inactive"):
return StatusStopped, nil
case strings.HasPrefix(out, "failed"):
return StatusUnknown, errors.New("service in failed state")
default:
return StatusUnknown, ErrNotInstalled
}
}
func (s *systemd) Start() error {
return run("systemctl", "start", s.Name+".service")
}
func (s *systemd) Stop() error {
return run("systemctl", "stop", s.Name+".service")
}
func (s *systemd) Restart() error {
return run("systemctl", "restart", s.Name+".service")
}
const systemdScript = `[Unit]
Description={{.Description}}
ConditionFileIsExecutable={{.Path|cmdEscape}}
[Service]
StartLimitInterval=5
StartLimitBurst=10
ExecStart={{.Path|cmdEscape}}{{range .Arguments}} {{.|cmd}}{{end}}
{{if .ChRoot}}RootDirectory={{.ChRoot|cmd}}{{end}}
{{if .WorkingDirectory}}WorkingDirectory={{.WorkingDirectory|cmdEscape}}{{end}}
{{if .UserName}}User={{.UserName}}{{end}}
{{if .ReloadSignal}}ExecReload=/bin/kill -{{.ReloadSignal}} "$MAINPID"{{end}}
{{if .PIDFile}}PIDFile={{.PIDFile|cmd}}{{end}}
{{if and .LogOutput .HasOutputFileSupport -}}
StandardOutput=file:/var/log/{{.Name}}.out
StandardError=file:/var/log/{{.Name}}.err
{{- end}}
Restart=always
RestartSec=120
EnvironmentFile=-/etc/sysconfig/{{.Name}}
[Install]
WantedBy=multi-user.target
`

View File

@ -0,0 +1,282 @@
// Copyright 2015 Daniel Theophanes.
// Use of this source code is governed by a zlib-style
// license that can be found in the LICENSE file.
package service
import (
"errors"
"fmt"
"os"
"os/signal"
"strings"
"syscall"
"text/template"
"time"
)
type sysv struct {
i Interface
platform string
*Config
}
func newSystemVService(i Interface, platform string, c *Config) (Service, error) {
s := &sysv{
i: i,
platform: platform,
Config: c,
}
return s, nil
}
func (s *sysv) String() string {
if len(s.DisplayName) > 0 {
return s.DisplayName
}
return s.Name
}
func (s *sysv) Platform() string {
return s.platform
}
var errNoUserServiceSystemV = errors.New("User services are not supported on SystemV.")
func (s *sysv) configPath() (cp string, err error) {
if s.Option.bool(optionUserService, optionUserServiceDefault) {
err = errNoUserServiceSystemV
return
}
cp = "/etc/init.d/" + s.Config.Name
return
}
func (s *sysv) template() *template.Template {
customScript := s.Option.string(optionSysvScript, "")
if customScript != "" {
return template.Must(template.New("").Funcs(tf).Parse(customScript))
} else {
return template.Must(template.New("").Funcs(tf).Parse(sysvScript))
}
}
func (s *sysv) Install() error {
confPath, err := s.configPath()
if err != nil {
return err
}
_, err = os.Stat(confPath)
if err == nil {
return fmt.Errorf("Init already exists: %s", confPath)
}
f, err := os.Create(confPath)
if err != nil {
return err
}
defer f.Close()
path, err := s.execPath()
if err != nil {
return err
}
var to = &struct {
*Config
Path string
}{
s.Config,
path,
}
err = s.template().Execute(f, to)
if err != nil {
return err
}
if err = os.Chmod(confPath, 0755); err != nil {
return err
}
for _, i := range [...]string{"2", "3", "4", "5"} {
if err = os.Symlink(confPath, "/etc/rc"+i+".d/S50"+s.Name); err != nil {
continue
}
}
for _, i := range [...]string{"0", "1", "6"} {
if err = os.Symlink(confPath, "/etc/rc"+i+".d/K02"+s.Name); err != nil {
continue
}
}
return nil
}
func (s *sysv) Uninstall() error {
cp, err := s.configPath()
if err != nil {
return err
}
if err := os.Remove(cp); err != nil {
return err
}
return nil
}
func (s *sysv) Logger(errs chan<- error) (Logger, error) {
if system.Interactive() {
return ConsoleLogger, nil
}
return s.SystemLogger(errs)
}
func (s *sysv) SystemLogger(errs chan<- error) (Logger, error) {
return newSysLogger(s.Name, errs)
}
func (s *sysv) Run() (err error) {
err = s.i.Start(s)
if err != nil {
return err
}
s.Option.funcSingle(optionRunWait, func() {
var sigChan = make(chan os.Signal, 3)
signal.Notify(sigChan, syscall.SIGTERM, os.Interrupt)
<-sigChan
})()
return s.i.Stop(s)
}
func (s *sysv) Status() (Status, error) {
_, out, err := runWithOutput("service", s.Name, "status")
if err != nil {
return StatusUnknown, err
}
switch {
case strings.HasPrefix(out, "Running"):
return StatusRunning, nil
case strings.HasPrefix(out, "Stopped"):
return StatusStopped, nil
default:
return StatusUnknown, ErrNotInstalled
}
}
func (s *sysv) Start() error {
return run("service", s.Name, "start")
}
func (s *sysv) Stop() error {
return run("service", s.Name, "stop")
}
func (s *sysv) Restart() error {
err := s.Stop()
if err != nil {
return err
}
time.Sleep(50 * time.Millisecond)
return s.Start()
}
const sysvScript = `#!/bin/sh
# For RedHat and cousins:
# chkconfig: - 99 01
# description: {{.Description}}
# processname: {{.Path}}
### BEGIN INIT INFO
# Provides: {{.Path}}
# Required-Start:
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: {{.DisplayName}}
# Description: {{.Description}}
### END INIT INFO
cmd="{{.Path}}{{range .Arguments}} {{.|cmd}}{{end}}"
name=$(basename $(readlink -f $0))
pid_file="/var/run/$name.pid"
stdout_log="/var/log/$name.log"
stderr_log="/var/log/$name.err"
[ -e /etc/sysconfig/$name ] && . /etc/sysconfig/$name
get_pid() {
cat "$pid_file"
}
is_running() {
[ -f "$pid_file" ] && ps $(get_pid) > /dev/null 2>&1
}
case "$1" in
start)
if is_running; then
echo "Already started"
else
echo "Starting $name"
{{if .WorkingDirectory}}cd '{{.WorkingDirectory}}'{{end}}
$cmd >> "$stdout_log" 2>> "$stderr_log" &
echo $! > "$pid_file"
if ! is_running; then
echo "Unable to start, see $stdout_log and $stderr_log"
exit 1
fi
fi
;;
stop)
if is_running; then
echo -n "Stopping $name.."
kill $(get_pid)
for i in $(seq 1 10)
do
if ! is_running; then
break
fi
echo -n "."
sleep 1
done
echo
if is_running; then
echo "Not stopped; may still be shutting down or shutdown may have failed"
exit 1
else
echo "Stopped"
if [ -f "$pid_file" ]; then
rm "$pid_file"
fi
fi
else
echo "Not running"
fi
;;
restart)
$0 stop
if is_running; then
echo "Unable to stop, will not attempt to start"
exit 1
fi
$0 start
;;
status)
if is_running; then
echo "Running"
else
echo "Stopped"
exit 1
fi
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
exit 0
`

138
vendor/github.com/kardianos/service/service_unix.go generated vendored Normal file
View File

@ -0,0 +1,138 @@
// Copyright 2015 Daniel Theophanes.
// Use of this source code is governed by a zlib-style
// license that can be found in the LICENSE file.
// +build linux darwin
package service
import (
"fmt"
"io"
"io/ioutil"
"log/syslog"
"os/exec"
"syscall"
)
func newSysLogger(name string, errs chan<- error) (Logger, error) {
w, err := syslog.New(syslog.LOG_INFO, name)
if err != nil {
return nil, err
}
return sysLogger{w, errs}, nil
}
type sysLogger struct {
*syslog.Writer
errs chan<- error
}
func (s sysLogger) send(err error) error {
if err != nil && s.errs != nil {
s.errs <- err
}
return err
}
func (s sysLogger) Error(v ...interface{}) error {
return s.send(s.Writer.Err(fmt.Sprint(v...)))
}
func (s sysLogger) Warning(v ...interface{}) error {
return s.send(s.Writer.Warning(fmt.Sprint(v...)))
}
func (s sysLogger) Info(v ...interface{}) error {
return s.send(s.Writer.Info(fmt.Sprint(v...)))
}
func (s sysLogger) Errorf(format string, a ...interface{}) error {
return s.send(s.Writer.Err(fmt.Sprintf(format, a...)))
}
func (s sysLogger) Warningf(format string, a ...interface{}) error {
return s.send(s.Writer.Warning(fmt.Sprintf(format, a...)))
}
func (s sysLogger) Infof(format string, a ...interface{}) error {
return s.send(s.Writer.Info(fmt.Sprintf(format, a...)))
}
func run(command string, arguments ...string) error {
_, _, err := runCommand(command, false, arguments...)
return err
}
func runWithOutput(command string, arguments ...string) (int, string, error) {
return runCommand(command, true, arguments...)
}
func runCommand(command string, readStdout bool, arguments ...string) (int, string, error) {
cmd := exec.Command(command, arguments...)
var output string
var stdout io.ReadCloser
var err error
if readStdout {
// Connect pipe to read Stdout
stdout, err = cmd.StdoutPipe()
if err != nil {
// Failed to connect pipe
return 0, "", fmt.Errorf("%q failed to connect stdout pipe: %v", command, err)
}
}
// Connect pipe to read Stderr
stderr, err := cmd.StderrPipe()
if err != nil {
// Failed to connect pipe
return 0, "", fmt.Errorf("%q failed to connect stderr pipe: %v", command, err)
}
// Do not use cmd.Run()
if err := cmd.Start(); err != nil {
// Problem while copying stdin, stdout, or stderr
return 0, "", fmt.Errorf("%q failed: %v", command, err)
}
// Zero exit status
// Darwin: launchctl can fail with a zero exit status,
// so check for emtpy stderr
if command == "launchctl" {
slurp, _ := ioutil.ReadAll(stderr)
if len(slurp) > 0 {
return 0, "", fmt.Errorf("%q failed with stderr: %s", command, slurp)
}
}
if readStdout {
out, err := ioutil.ReadAll(stdout)
if err != nil {
return 0, "", fmt.Errorf("%q failed while attempting to read stdout: %v", command, err)
} else if len(out) > 0 {
output = string(out)
}
}
if err := cmd.Wait(); err != nil {
exitStatus, ok := isExitError(err)
if ok {
// Command didn't exit with a zero exit status.
return exitStatus, output, err
}
// An error occurred and there is no exit status.
return 0, output, fmt.Errorf("%q failed: %v", command, err)
}
return 0, output, nil
}
func isExitError(err error) (int, bool) {
if exiterr, ok := err.(*exec.ExitError); ok {
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
return status.ExitStatus(), true
}
}
return 0, false
}

View File

@ -0,0 +1,275 @@
// Copyright 2015 Daniel Theophanes.
// Use of this source code is governed by a zlib-style
// license that can be found in the LICENSE file.
package service
import (
"errors"
"fmt"
"os"
"os/signal"
"regexp"
"strings"
"syscall"
"text/template"
"time"
)
func isUpstart() bool {
if _, err := os.Stat("/sbin/upstart-udev-bridge"); err == nil {
return true
}
if _, err := os.Stat("/sbin/initctl"); err == nil {
if _, out, err := runWithOutput("/sbin/initctl", "--version"); err == nil {
if strings.Contains(out, "initctl (upstart") {
return true
}
}
}
return false
}
type upstart struct {
i Interface
platform string
*Config
}
func newUpstartService(i Interface, platform string, c *Config) (Service, error) {
s := &upstart{
i: i,
platform: platform,
Config: c,
}
return s, nil
}
func (s *upstart) String() string {
if len(s.DisplayName) > 0 {
return s.DisplayName
}
return s.Name
}
func (s *upstart) Platform() string {
return s.platform
}
// Upstart has some support for user services in graphical sessions.
// Due to the mix of actual support for user services over versions, just don't bother.
// Upstart will be replaced by systemd in most cases anyway.
var errNoUserServiceUpstart = errors.New("User services are not supported on Upstart.")
func (s *upstart) configPath() (cp string, err error) {
if s.Option.bool(optionUserService, optionUserServiceDefault) {
err = errNoUserServiceUpstart
return
}
cp = "/etc/init/" + s.Config.Name + ".conf"
return
}
func (s *upstart) hasKillStanza() bool {
defaultValue := true
version := s.getUpstartVersion()
if version == nil {
return defaultValue
}
maxVersion := []int{0, 6, 5}
if matches, err := versionAtMost(version, maxVersion); err != nil || matches {
return false
}
return defaultValue
}
func (s *upstart) hasSetUIDStanza() bool {
defaultValue := true
version := s.getUpstartVersion()
if version == nil {
return defaultValue
}
maxVersion := []int{1, 4, 0}
if matches, err := versionAtMost(version, maxVersion); err != nil || matches {
return false
}
return defaultValue
}
func (s *upstart) getUpstartVersion() []int {
_, out, err := runWithOutput("/sbin/initctl", "--version")
if err != nil {
return nil
}
re := regexp.MustCompile(`initctl \(upstart (\d+.\d+.\d+)\)`)
matches := re.FindStringSubmatch(out)
if len(matches) != 2 {
return nil
}
return parseVersion(matches[1])
}
func (s *upstart) template() *template.Template {
customScript := s.Option.string(optionUpstartScript, "")
if customScript != "" {
return template.Must(template.New("").Funcs(tf).Parse(customScript))
} else {
return template.Must(template.New("").Funcs(tf).Parse(upstartScript))
}
}
func (s *upstart) Install() error {
confPath, err := s.configPath()
if err != nil {
return err
}
_, err = os.Stat(confPath)
if err == nil {
return fmt.Errorf("Init already exists: %s", confPath)
}
f, err := os.Create(confPath)
if err != nil {
return err
}
defer f.Close()
path, err := s.execPath()
if err != nil {
return err
}
var to = &struct {
*Config
Path string
HasKillStanza bool
HasSetUIDStanza bool
LogOutput bool
}{
s.Config,
path,
s.hasKillStanza(),
s.hasSetUIDStanza(),
s.Option.bool(optionLogOutput, optionLogOutputDefault),
}
return s.template().Execute(f, to)
}
func (s *upstart) Uninstall() error {
cp, err := s.configPath()
if err != nil {
return err
}
if err := os.Remove(cp); err != nil {
return err
}
return nil
}
func (s *upstart) Logger(errs chan<- error) (Logger, error) {
if system.Interactive() {
return ConsoleLogger, nil
}
return s.SystemLogger(errs)
}
func (s *upstart) SystemLogger(errs chan<- error) (Logger, error) {
return newSysLogger(s.Name, errs)
}
func (s *upstart) Run() (err error) {
err = s.i.Start(s)
if err != nil {
return err
}
s.Option.funcSingle(optionRunWait, func() {
var sigChan = make(chan os.Signal, 3)
signal.Notify(sigChan, syscall.SIGTERM, os.Interrupt)
<-sigChan
})()
return s.i.Stop(s)
}
func (s *upstart) Status() (Status, error) {
exitCode, out, err := runWithOutput("initctl", "status", s.Name)
if exitCode == 0 && err != nil {
return StatusUnknown, err
}
switch {
case strings.HasPrefix(out, fmt.Sprintf("%s start/running", s.Name)):
return StatusRunning, nil
case strings.HasPrefix(out, fmt.Sprintf("%s stop/waiting", s.Name)):
return StatusStopped, nil
default:
return StatusUnknown, ErrNotInstalled
}
}
func (s *upstart) Start() error {
return run("initctl", "start", s.Name)
}
func (s *upstart) Stop() error {
return run("initctl", "stop", s.Name)
}
func (s *upstart) Restart() error {
err := s.Stop()
if err != nil {
return err
}
time.Sleep(50 * time.Millisecond)
return s.Start()
}
// The upstart script should stop with an INT or the Go runtime will terminate
// the program before the Stop handler can run.
const upstartScript = `# {{.Description}}
{{if .DisplayName}}description "{{.DisplayName}}"{{end}}
{{if .HasKillStanza}}kill signal INT{{end}}
{{if .ChRoot}}chroot {{.ChRoot}}{{end}}
{{if .WorkingDirectory}}chdir {{.WorkingDirectory}}{{end}}
start on filesystem or runlevel [2345]
stop on runlevel [!2345]
{{if and .UserName .HasSetUIDStanza}}setuid {{.UserName}}{{end}}
respawn
respawn limit 10 5
umask 022
console none
pre-start script
test -x {{.Path}} || { stop; exit 0; }
end script
# Start
script
{{if .LogOutput}}
stdout_log="/var/log/{{.Name}}.out"
stderr_log="/var/log/{{.Name}}.err"
{{end}}
if [ -f "/etc/sysconfig/{{.Name}}" ]; then
set -a
source /etc/sysconfig/{{.Name}}
set +a
fi
exec {{if and .UserName (not .HasSetUIDStanza)}}sudo -E -u {{.UserName}} {{end}}{{.Path}}{{range .Arguments}} {{.|cmd}}{{end}}{{if .LogOutput}} >> $stdout_log 2>> $stderr_log{{end}}
end script
`

436
vendor/github.com/kardianos/service/service_windows.go generated vendored Normal file
View File

@ -0,0 +1,436 @@
// Copyright 2015 Daniel Theophanes.
// Use of this source code is governed by a zlib-style
// license that can be found in the LICENSE file.
package service
import (
"fmt"
"os"
"os/signal"
"strconv"
"strings"
"sync"
"time"
"golang.org/x/sys/windows/registry"
"golang.org/x/sys/windows/svc"
"golang.org/x/sys/windows/svc/eventlog"
"golang.org/x/sys/windows/svc/mgr"
)
const version = "windows-service"
type windowsService struct {
i Interface
*Config
errSync sync.Mutex
stopStartErr error
}
// WindowsLogger allows using windows specific logging methods.
type WindowsLogger struct {
ev *eventlog.Log
errs chan<- error
}
type windowsSystem struct{}
func (windowsSystem) String() string {
return version
}
func (windowsSystem) Detect() bool {
return true
}
func (windowsSystem) Interactive() bool {
return interactive
}
func (windowsSystem) New(i Interface, c *Config) (Service, error) {
ws := &windowsService{
i: i,
Config: c,
}
return ws, nil
}
func init() {
ChooseSystem(windowsSystem{})
}
func (l WindowsLogger) send(err error) error {
if err == nil {
return nil
}
if l.errs != nil {
l.errs <- err
}
return err
}
// Error logs an error message.
func (l WindowsLogger) Error(v ...interface{}) error {
return l.send(l.ev.Error(3, fmt.Sprint(v...)))
}
// Warning logs an warning message.
func (l WindowsLogger) Warning(v ...interface{}) error {
return l.send(l.ev.Warning(2, fmt.Sprint(v...)))
}
// Info logs an info message.
func (l WindowsLogger) Info(v ...interface{}) error {
return l.send(l.ev.Info(1, fmt.Sprint(v...)))
}
// Errorf logs an error message.
func (l WindowsLogger) Errorf(format string, a ...interface{}) error {
return l.send(l.ev.Error(3, fmt.Sprintf(format, a...)))
}
// Warningf logs an warning message.
func (l WindowsLogger) Warningf(format string, a ...interface{}) error {
return l.send(l.ev.Warning(2, fmt.Sprintf(format, a...)))
}
// Infof logs an info message.
func (l WindowsLogger) Infof(format string, a ...interface{}) error {
return l.send(l.ev.Info(1, fmt.Sprintf(format, a...)))
}
// NError logs an error message and an event ID.
func (l WindowsLogger) NError(eventID uint32, v ...interface{}) error {
return l.send(l.ev.Error(eventID, fmt.Sprint(v...)))
}
// NWarning logs an warning message and an event ID.
func (l WindowsLogger) NWarning(eventID uint32, v ...interface{}) error {
return l.send(l.ev.Warning(eventID, fmt.Sprint(v...)))
}
// NInfo logs an info message and an event ID.
func (l WindowsLogger) NInfo(eventID uint32, v ...interface{}) error {
return l.send(l.ev.Info(eventID, fmt.Sprint(v...)))
}
// NErrorf logs an error message and an event ID.
func (l WindowsLogger) NErrorf(eventID uint32, format string, a ...interface{}) error {
return l.send(l.ev.Error(eventID, fmt.Sprintf(format, a...)))
}
// NWarningf logs an warning message and an event ID.
func (l WindowsLogger) NWarningf(eventID uint32, format string, a ...interface{}) error {
return l.send(l.ev.Warning(eventID, fmt.Sprintf(format, a...)))
}
// NInfof logs an info message and an event ID.
func (l WindowsLogger) NInfof(eventID uint32, format string, a ...interface{}) error {
return l.send(l.ev.Info(eventID, fmt.Sprintf(format, a...)))
}
var interactive = false
func init() {
var err error
interactive, err = svc.IsAnInteractiveSession()
if err != nil {
panic(err)
}
}
func (ws *windowsService) String() string {
if len(ws.DisplayName) > 0 {
return ws.DisplayName
}
return ws.Name
}
func (ws *windowsService) Platform() string {
return version
}
func (ws *windowsService) setError(err error) {
ws.errSync.Lock()
defer ws.errSync.Unlock()
ws.stopStartErr = err
}
func (ws *windowsService) getError() error {
ws.errSync.Lock()
defer ws.errSync.Unlock()
return ws.stopStartErr
}
func (ws *windowsService) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (bool, uint32) {
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown
changes <- svc.Status{State: svc.StartPending}
if err := ws.i.Start(ws); err != nil {
ws.setError(err)
return true, 1
}
changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
loop:
for {
c := <-r
switch c.Cmd {
case svc.Interrogate:
changes <- c.CurrentStatus
case svc.Stop, svc.Shutdown:
changes <- svc.Status{State: svc.StopPending}
if err := ws.i.Stop(ws); err != nil {
ws.setError(err)
return true, 2
}
break loop
default:
continue loop
}
}
return false, 0
}
func (ws *windowsService) Install() error {
exepath, err := ws.execPath()
if err != nil {
return err
}
m, err := mgr.Connect()
if err != nil {
return err
}
defer m.Disconnect()
s, err := m.OpenService(ws.Name)
if err == nil {
s.Close()
return fmt.Errorf("service %s already exists", ws.Name)
}
s, err = m.CreateService(ws.Name, exepath, mgr.Config{
DisplayName: ws.DisplayName,
Description: ws.Description,
StartType: mgr.StartAutomatic,
ServiceStartName: ws.UserName,
Password: ws.Option.string("Password", ""),
Dependencies: ws.Dependencies,
}, ws.Arguments...)
if err != nil {
return err
}
defer s.Close()
err = eventlog.InstallAsEventCreate(ws.Name, eventlog.Error|eventlog.Warning|eventlog.Info)
if err != nil {
if !strings.Contains(err.Error(), "exists") {
s.Delete()
return fmt.Errorf("SetupEventLogSource() failed: %s", err)
}
}
return nil
}
func (ws *windowsService) Uninstall() error {
m, err := mgr.Connect()
if err != nil {
return err
}
defer m.Disconnect()
s, err := m.OpenService(ws.Name)
if err != nil {
return fmt.Errorf("service %s is not installed", ws.Name)
}
defer s.Close()
err = s.Delete()
if err != nil {
return err
}
err = eventlog.Remove(ws.Name)
if err != nil {
return fmt.Errorf("RemoveEventLogSource() failed: %s", err)
}
return nil
}
func (ws *windowsService) Run() error {
ws.setError(nil)
if !interactive {
// Return error messages from start and stop routines
// that get executed in the Execute method.
// Guarded with a mutex as it may run a different thread
// (callback from windows).
runErr := svc.Run(ws.Name, ws)
startStopErr := ws.getError()
if startStopErr != nil {
return startStopErr
}
if runErr != nil {
return runErr
}
return nil
}
err := ws.i.Start(ws)
if err != nil {
return err
}
sigChan := make(chan os.Signal)
signal.Notify(sigChan, os.Interrupt)
<-sigChan
return ws.i.Stop(ws)
}
func (ws *windowsService) Status() (Status, error) {
m, err := mgr.Connect()
if err != nil {
return StatusUnknown, err
}
defer m.Disconnect()
s, err := m.OpenService(ws.Name)
if err != nil {
if err.Error() == "The specified service does not exist as an installed service." {
return StatusUnknown, ErrNotInstalled
}
return StatusUnknown, err
}
status, err := s.Query()
if err != nil {
return StatusUnknown, err
}
switch status.State {
case svc.StartPending:
fallthrough
case svc.Running:
return StatusRunning, nil
case svc.PausePending:
fallthrough
case svc.Paused:
fallthrough
case svc.ContinuePending:
fallthrough
case svc.StopPending:
fallthrough
case svc.Stopped:
return StatusStopped, nil
default:
return StatusUnknown, fmt.Errorf("unknown status %v", status)
}
}
func (ws *windowsService) Start() error {
m, err := mgr.Connect()
if err != nil {
return err
}
defer m.Disconnect()
s, err := m.OpenService(ws.Name)
if err != nil {
return err
}
defer s.Close()
return s.Start()
}
func (ws *windowsService) Stop() error {
m, err := mgr.Connect()
if err != nil {
return err
}
defer m.Disconnect()
s, err := m.OpenService(ws.Name)
if err != nil {
return err
}
defer s.Close()
return ws.stopWait(s)
}
func (ws *windowsService) Restart() error {
m, err := mgr.Connect()
if err != nil {
return err
}
defer m.Disconnect()
s, err := m.OpenService(ws.Name)
if err != nil {
return err
}
defer s.Close()
err = ws.stopWait(s)
if err != nil {
return err
}
return s.Start()
}
func (ws *windowsService) stopWait(s *mgr.Service) error {
// First stop the service. Then wait for the service to
// actually stop before starting it.
status, err := s.Control(svc.Stop)
if err != nil {
return err
}
timeDuration := time.Millisecond * 50
timeout := time.After(getStopTimeout() + (timeDuration * 2))
tick := time.NewTicker(timeDuration)
defer tick.Stop()
for status.State != svc.Stopped {
select {
case <-tick.C:
status, err = s.Query()
if err != nil {
return err
}
case <-timeout:
break
}
}
return nil
}
// getStopTimeout fetches the time before windows will kill the service.
func getStopTimeout() time.Duration {
// For default and paths see https://support.microsoft.com/en-us/kb/146092
defaultTimeout := time.Millisecond * 20000
key, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\Control`, registry.READ)
if err != nil {
return defaultTimeout
}
sv, _, err := key.GetStringValue("WaitToKillServiceTimeout")
if err != nil {
return defaultTimeout
}
v, err := strconv.Atoi(sv)
if err != nil {
return defaultTimeout
}
return time.Millisecond * time.Duration(v)
}
func (ws *windowsService) Logger(errs chan<- error) (Logger, error) {
if interactive {
return ConsoleLogger, nil
}
return ws.SystemLogger(errs)
}
func (ws *windowsService) SystemLogger(errs chan<- error) (Logger, error) {
el, err := eventlog.Open(ws.Name)
if err != nil {
return nil, err
}
return WindowsLogger{el, errs}, nil
}

57
vendor/github.com/kardianos/service/version.go generated vendored Normal file
View File

@ -0,0 +1,57 @@
package service
import (
"errors"
"strconv"
"strings"
)
// versionAtMost will return true if the provided version is less than or equal to max
func versionAtMost(version, max []int) (bool, error) {
if comp, err := versionCompare(version, max); err != nil {
return false, err
} else if comp == 1 {
return false, nil
}
return true, nil
}
// versionCompare take to versions split into integer arrays and attempts to compare them
// An error will be returned if there is an array length mismatch.
// Return values are as follows
// -1 - v1 is less than v2
// 0 - v1 is equal to v2
// 1 - v1 is greater than v2
func versionCompare(v1, v2 []int) (int, error) {
if len(v1) != len(v2) {
return 0, errors.New("version length mismatch")
}
for idx, v2S := range v2 {
v1S := v1[idx]
if v1S > v2S {
return 1, nil
}
if v1S < v2S {
return -1, nil
}
}
return 0, nil
}
// parseVersion will parse any integer type version seperated by periods.
// This does not fully support semver style versions.
func parseVersion(v string) []int {
version := make([]int, 3)
for idx, vStr := range strings.Split(v, ".") {
vS, err := strconv.Atoi(vStr)
if err != nil {
return nil
}
version[idx] = vS
}
return version
}

View File

@ -1,3 +0,0 @@
-----BEGIN SM4 KEY-----
MTIzNDU2Nzg5MGFiY2RlZg==
-----END SM4 KEY-----

View File

@ -3,6 +3,14 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Package blowfish implements Bruce Schneier's Blowfish encryption algorithm. // Package blowfish implements Bruce Schneier's Blowfish encryption algorithm.
//
// Blowfish is a legacy cipher and its short block size makes it vulnerable to
// birthday bound attacks (see https://sweet32.info). It should only be used
// where compatibility with legacy systems, not security, is the goal.
//
// Deprecated: any new system should use AES (from crypto/aes, if necessary in
// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
// golang.org/x/crypto/chacha20poly1305).
package blowfish // import "golang.org/x/crypto/blowfish" package blowfish // import "golang.org/x/crypto/blowfish"
// The code is a port of Bruce Schneier's C implementation. // The code is a port of Bruce Schneier's C implementation.

View File

@ -2,8 +2,15 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Package cast5 implements CAST5, as defined in RFC 2144. CAST5 is a common // Package cast5 implements CAST5, as defined in RFC 2144.
// OpenPGP cipher. //
// CAST5 is a legacy cipher and its short block size makes it vulnerable to
// birthday bound attacks (see https://sweet32.info). It should only be used
// where compatibility with legacy systems, not security, is the goal.
//
// Deprecated: any new system should use AES (from crypto/aes, if necessary in
// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
// golang.org/x/crypto/chacha20poly1305).
package cast5 // import "golang.org/x/crypto/cast5" package cast5 // import "golang.org/x/crypto/cast5"
import "errors" import "errors"

32
vendor/golang.org/x/crypto/internal/subtle/aliasing.go generated vendored Normal file
View File

@ -0,0 +1,32 @@
// Copyright 2018 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 !appengine
// Package subtle implements functions that are often useful in cryptographic
// code but require careful thought to use correctly.
package subtle // import "golang.org/x/crypto/internal/subtle"
import "unsafe"
// AnyOverlap reports whether x and y share memory at any (not necessarily
// corresponding) index. The memory beyond the slice length is ignored.
func AnyOverlap(x, y []byte) bool {
return len(x) > 0 && len(y) > 0 &&
uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) &&
uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1]))
}
// InexactOverlap reports whether x and y share memory at any non-corresponding
// index. The memory beyond the slice length is ignored. Note that x and y can
// have different lengths and still not have any inexact overlap.
//
// InexactOverlap can be used to implement the requirements of the crypto/cipher
// AEAD, Block, BlockMode and Stream interfaces.
func InexactOverlap(x, y []byte) bool {
if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
return false
}
return AnyOverlap(x, y)
}

View File

@ -0,0 +1,35 @@
// Copyright 2018 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 appengine
// Package subtle implements functions that are often useful in cryptographic
// code but require careful thought to use correctly.
package subtle // import "golang.org/x/crypto/internal/subtle"
// This is the Google App Engine standard variant based on reflect
// because the unsafe package and cgo are disallowed.
import "reflect"
// AnyOverlap reports whether x and y share memory at any (not necessarily
// corresponding) index. The memory beyond the slice length is ignored.
func AnyOverlap(x, y []byte) bool {
return len(x) > 0 && len(y) > 0 &&
reflect.ValueOf(&x[0]).Pointer() <= reflect.ValueOf(&y[len(y)-1]).Pointer() &&
reflect.ValueOf(&y[0]).Pointer() <= reflect.ValueOf(&x[len(x)-1]).Pointer()
}
// InexactOverlap reports whether x and y share memory at any non-corresponding
// index. The memory beyond the slice length is ignored. Note that x and y can
// have different lengths and still not have any inexact overlap.
//
// InexactOverlap can be used to implement the requirements of the crypto/cipher
// AEAD, Block, BlockMode and Stream interfaces.
func InexactOverlap(x, y []byte) bool {
if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
return false
}
return AnyOverlap(x, y)
}

View File

@ -6,10 +6,9 @@
package salsa package salsa
// This function is implemented in salsa2020_amd64.s.
//go:noescape //go:noescape
// salsa2020XORKeyStream is implemented in salsa20_amd64.s.
func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte) func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte)
// XORKeyStream crypts bytes from in to out using the given key and counters. // XORKeyStream crypts bytes from in to out using the given key and counters.

View File

@ -99,30 +99,24 @@ TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
MOVL 36 (SP),CX MOVL 36 (SP),CX
MOVL DX,288(SP) MOVL DX,288(SP)
MOVL CX,304(SP) MOVL CX,304(SP)
ADDQ $1,DX
SHLQ $32,CX SHLQ $32,CX
ADDQ CX,DX ADDQ CX,DX
ADDQ $1,DX
MOVQ DX,CX MOVQ DX,CX
SHRQ $32,CX SHRQ $32,CX
MOVL DX, 292 (SP) MOVL DX, 292 (SP)
MOVL CX, 308 (SP) MOVL CX, 308 (SP)
ADDQ $1,DX ADDQ $1,DX
SHLQ $32,CX
ADDQ CX,DX
MOVQ DX,CX MOVQ DX,CX
SHRQ $32,CX SHRQ $32,CX
MOVL DX, 296 (SP) MOVL DX, 296 (SP)
MOVL CX, 312 (SP) MOVL CX, 312 (SP)
ADDQ $1,DX ADDQ $1,DX
SHLQ $32,CX
ADDQ CX,DX
MOVQ DX,CX MOVQ DX,CX
SHRQ $32,CX SHRQ $32,CX
MOVL DX, 300 (SP) MOVL DX, 300 (SP)
MOVL CX, 316 (SP) MOVL CX, 316 (SP)
ADDQ $1,DX ADDQ $1,DX
SHLQ $32,CX
ADDQ CX,DX
MOVQ DX,CX MOVQ DX,CX
SHRQ $32,CX SHRQ $32,CX
MOVL DX,16(SP) MOVL DX,16(SP)

View File

@ -0,0 +1,14 @@
// Copyright 2019 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 !amd64 appengine gccgo
package salsa
// XORKeyStream crypts bytes from in to out using the given key and counters.
// In and out must overlap entirely or not at all. Counter
// contains the raw salsa20 counter bytes (both nonce and block counter).
func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
genericXORKeyStream(out, in, counter, key)
}

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build !amd64 appengine gccgo
package salsa package salsa
const rounds = 20 const rounds = 20
@ -202,10 +200,9 @@ func core(out *[64]byte, in *[16]byte, k *[32]byte, c *[16]byte) {
out[63] = byte(x15 >> 24) out[63] = byte(x15 >> 24)
} }
// XORKeyStream crypts bytes from in to out using the given key and counters. // genericXORKeyStream is the generic implementation of XORKeyStream to be used
// In and out must overlap entirely or not at all. Counter // when no assembly implementation is available.
// contains the raw salsa20 counter bytes (both nonce and block counter). func genericXORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
var block [64]byte var block [64]byte
var counterCopy [16]byte var counterCopy [16]byte
copy(counterCopy[:], counter[:]) copy(counterCopy[:], counter[:])

View File

@ -24,6 +24,7 @@ package salsa20 // import "golang.org/x/crypto/salsa20"
// TODO(agl): implement XORKeyStream12 and XORKeyStream8 - the reduced round variants of Salsa20. // TODO(agl): implement XORKeyStream12 and XORKeyStream8 - the reduced round variants of Salsa20.
import ( import (
"golang.org/x/crypto/internal/subtle"
"golang.org/x/crypto/salsa20/salsa" "golang.org/x/crypto/salsa20/salsa"
) )
@ -32,7 +33,10 @@ import (
// be either 8 or 24 bytes long. // be either 8 or 24 bytes long.
func XORKeyStream(out, in []byte, nonce []byte, key *[32]byte) { func XORKeyStream(out, in []byte, nonce []byte, key *[32]byte) {
if len(out) < len(in) { if len(out) < len(in) {
in = in[:len(out)] panic("salsa20: output smaller than input")
}
if subtle.InexactOverlap(out[:len(in)], in) {
panic("salsa20: invalid buffer overlap")
} }
var subNonce [16]byte var subNonce [16]byte

View File

@ -5,6 +5,14 @@
// Package tea implements the TEA algorithm, as defined in Needham and // Package tea implements the TEA algorithm, as defined in Needham and
// Wheeler's 1994 technical report, “TEA, a Tiny Encryption Algorithm”. See // Wheeler's 1994 technical report, “TEA, a Tiny Encryption Algorithm”. See
// http://www.cix.co.uk/~klockstone/tea.pdf for details. // http://www.cix.co.uk/~klockstone/tea.pdf for details.
//
// TEA is a legacy cipher and its short block size makes it vulnerable to
// birthday bound attacks (see https://sweet32.info). It should only be used
// where compatibility with legacy systems, not security, is the goal.
//
// Deprecated: any new system should use AES (from crypto/aes, if necessary in
// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
// golang.org/x/crypto/chacha20poly1305).
package tea package tea
import ( import (

View File

@ -3,6 +3,12 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Package twofish implements Bruce Schneier's Twofish encryption algorithm. // Package twofish implements Bruce Schneier's Twofish encryption algorithm.
//
// Deprecated: Twofish is a legacy cipher and should not be used for new
// applications. Also, this package does not and will not provide an optimized
// implementation. Instead, use AES (from crypto/aes, if necessary in an AEAD
// mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
// golang.org/x/crypto/chacha20poly1305).
package twofish // import "golang.org/x/crypto/twofish" package twofish // import "golang.org/x/crypto/twofish"
// Twofish is defined in https://www.schneier.com/paper-twofish-paper.pdf [TWOFISH] // Twofish is defined in https://www.schneier.com/paper-twofish-paper.pdf [TWOFISH]

View File

@ -4,6 +4,14 @@
// Package xtea implements XTEA encryption, as defined in Needham and Wheeler's // Package xtea implements XTEA encryption, as defined in Needham and Wheeler's
// 1997 technical report, "Tea extensions." // 1997 technical report, "Tea extensions."
//
// XTEA is a legacy cipher and its short block size makes it vulnerable to
// birthday bound attacks (see https://sweet32.info). It should only be used
// where compatibility with legacy systems, not security, is the goal.
//
// Deprecated: any new system should use AES (from crypto/aes, if necessary in
// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
// golang.org/x/crypto/chacha20poly1305).
package xtea // import "golang.org/x/crypto/xtea" package xtea // import "golang.org/x/crypto/xtea"
// For details, see http://www.cix.co.uk/~klockstone/xtea.pdf // For details, see http://www.cix.co.uk/~klockstone/xtea.pdf

View File

@ -38,6 +38,7 @@ const (
type JumpTest uint16 type JumpTest uint16
// Supported operators for conditional jumps. // Supported operators for conditional jumps.
// K can be RegX for JumpIfX
const ( const (
// K == A // K == A
JumpEqual JumpTest = iota JumpEqual JumpTest = iota
@ -134,12 +135,9 @@ const (
opMaskLoadDest = 0x01 opMaskLoadDest = 0x01
opMaskLoadWidth = 0x18 opMaskLoadWidth = 0x18
opMaskLoadMode = 0xe0 opMaskLoadMode = 0xe0
// opClsALU // opClsALU & opClsJump
opMaskOperandSrc = 0x08 opMaskOperand = 0x08
opMaskOperator = 0xf0 opMaskOperator = 0xf0
// opClsJump
opMaskJumpConst = 0x0f
opMaskJumpCond = 0xf0
) )
const ( const (
@ -192,15 +190,21 @@ const (
opLoadWidth1 opLoadWidth1
) )
// Operator defined by ALUOp* // Operand for ALU and Jump instructions
type opOperand uint16
// Supported operand sources.
const ( const (
opALUSrcConstant uint16 = iota << 3 opOperandConstant opOperand = iota << 3
opALUSrcX opOperandX
) )
// An jumpOp is a conditional jump condition.
type jumpOp uint16
// Supported jump conditions.
const ( const (
opJumpAlways = iota << 4 opJumpAlways jumpOp = iota << 4
opJumpEqual opJumpEqual
opJumpGT opJumpGT
opJumpGE opJumpGE

View File

@ -89,10 +89,14 @@ func (ri RawInstruction) Disassemble() Instruction {
case opClsALU: case opClsALU:
switch op := ALUOp(ri.Op & opMaskOperator); op { switch op := ALUOp(ri.Op & opMaskOperator); op {
case ALUOpAdd, ALUOpSub, ALUOpMul, ALUOpDiv, ALUOpOr, ALUOpAnd, ALUOpShiftLeft, ALUOpShiftRight, ALUOpMod, ALUOpXor: case ALUOpAdd, ALUOpSub, ALUOpMul, ALUOpDiv, ALUOpOr, ALUOpAnd, ALUOpShiftLeft, ALUOpShiftRight, ALUOpMod, ALUOpXor:
if ri.Op&opMaskOperandSrc != 0 { switch operand := opOperand(ri.Op & opMaskOperand); operand {
case opOperandX:
return ALUOpX{Op: op} return ALUOpX{Op: op}
case opOperandConstant:
return ALUOpConstant{Op: op, Val: ri.K}
default:
return ri
} }
return ALUOpConstant{Op: op, Val: ri.K}
case aluOpNeg: case aluOpNeg:
return NegateA{} return NegateA{}
default: default:
@ -100,63 +104,18 @@ func (ri RawInstruction) Disassemble() Instruction {
} }
case opClsJump: case opClsJump:
if ri.Op&opMaskJumpConst != opClsJump { switch op := jumpOp(ri.Op & opMaskOperator); op {
return ri
}
switch ri.Op & opMaskJumpCond {
case opJumpAlways: case opJumpAlways:
return Jump{Skip: ri.K} return Jump{Skip: ri.K}
case opJumpEqual: case opJumpEqual, opJumpGT, opJumpGE, opJumpSet:
if ri.Jt == 0 { cond, skipTrue, skipFalse := jumpOpToTest(op, ri.Jt, ri.Jf)
return JumpIf{ switch operand := opOperand(ri.Op & opMaskOperand); operand {
Cond: JumpNotEqual, case opOperandX:
Val: ri.K, return JumpIfX{Cond: cond, SkipTrue: skipTrue, SkipFalse: skipFalse}
SkipTrue: ri.Jf, case opOperandConstant:
SkipFalse: 0, return JumpIf{Cond: cond, Val: ri.K, SkipTrue: skipTrue, SkipFalse: skipFalse}
} default:
} return ri
return JumpIf{
Cond: JumpEqual,
Val: ri.K,
SkipTrue: ri.Jt,
SkipFalse: ri.Jf,
}
case opJumpGT:
if ri.Jt == 0 {
return JumpIf{
Cond: JumpLessOrEqual,
Val: ri.K,
SkipTrue: ri.Jf,
SkipFalse: 0,
}
}
return JumpIf{
Cond: JumpGreaterThan,
Val: ri.K,
SkipTrue: ri.Jt,
SkipFalse: ri.Jf,
}
case opJumpGE:
if ri.Jt == 0 {
return JumpIf{
Cond: JumpLessThan,
Val: ri.K,
SkipTrue: ri.Jf,
SkipFalse: 0,
}
}
return JumpIf{
Cond: JumpGreaterOrEqual,
Val: ri.K,
SkipTrue: ri.Jt,
SkipFalse: ri.Jf,
}
case opJumpSet:
return JumpIf{
Cond: JumpBitsSet,
Val: ri.K,
SkipTrue: ri.Jt,
SkipFalse: ri.Jf,
} }
default: default:
return ri return ri
@ -187,6 +146,41 @@ func (ri RawInstruction) Disassemble() Instruction {
} }
} }
func jumpOpToTest(op jumpOp, skipTrue uint8, skipFalse uint8) (JumpTest, uint8, uint8) {
var test JumpTest
// Decode "fake" jump conditions that don't appear in machine code
// Ensures the Assemble -> Disassemble stage recreates the same instructions
// See https://github.com/golang/go/issues/18470
if skipTrue == 0 {
switch op {
case opJumpEqual:
test = JumpNotEqual
case opJumpGT:
test = JumpLessOrEqual
case opJumpGE:
test = JumpLessThan
case opJumpSet:
test = JumpBitsNotSet
}
return test, skipFalse, 0
}
switch op {
case opJumpEqual:
test = JumpEqual
case opJumpGT:
test = JumpGreaterThan
case opJumpGE:
test = JumpGreaterOrEqual
case opJumpSet:
test = JumpBitsSet
}
return test, skipTrue, skipFalse
}
// LoadConstant loads Val into register Dst. // LoadConstant loads Val into register Dst.
type LoadConstant struct { type LoadConstant struct {
Dst Register Dst Register
@ -413,7 +407,7 @@ type ALUOpConstant struct {
// Assemble implements the Instruction Assemble method. // Assemble implements the Instruction Assemble method.
func (a ALUOpConstant) Assemble() (RawInstruction, error) { func (a ALUOpConstant) Assemble() (RawInstruction, error) {
return RawInstruction{ return RawInstruction{
Op: opClsALU | opALUSrcConstant | uint16(a.Op), Op: opClsALU | uint16(opOperandConstant) | uint16(a.Op),
K: a.Val, K: a.Val,
}, nil }, nil
} }
@ -454,7 +448,7 @@ type ALUOpX struct {
// Assemble implements the Instruction Assemble method. // Assemble implements the Instruction Assemble method.
func (a ALUOpX) Assemble() (RawInstruction, error) { func (a ALUOpX) Assemble() (RawInstruction, error) {
return RawInstruction{ return RawInstruction{
Op: opClsALU | opALUSrcX | uint16(a.Op), Op: opClsALU | uint16(opOperandX) | uint16(a.Op),
}, nil }, nil
} }
@ -509,7 +503,7 @@ type Jump struct {
// Assemble implements the Instruction Assemble method. // Assemble implements the Instruction Assemble method.
func (a Jump) Assemble() (RawInstruction, error) { func (a Jump) Assemble() (RawInstruction, error) {
return RawInstruction{ return RawInstruction{
Op: opClsJump | opJumpAlways, Op: opClsJump | uint16(opJumpAlways),
K: a.Skip, K: a.Skip,
}, nil }, nil
} }
@ -530,11 +524,39 @@ type JumpIf struct {
// Assemble implements the Instruction Assemble method. // Assemble implements the Instruction Assemble method.
func (a JumpIf) Assemble() (RawInstruction, error) { func (a JumpIf) Assemble() (RawInstruction, error) {
return jumpToRaw(a.Cond, opOperandConstant, a.Val, a.SkipTrue, a.SkipFalse)
}
// String returns the instruction in assembler notation.
func (a JumpIf) String() string {
return jumpToString(a.Cond, fmt.Sprintf("#%d", a.Val), a.SkipTrue, a.SkipFalse)
}
// JumpIfX skips the following Skip instructions in the program if A
// <Cond> X is true.
type JumpIfX struct {
Cond JumpTest
SkipTrue uint8
SkipFalse uint8
}
// Assemble implements the Instruction Assemble method.
func (a JumpIfX) Assemble() (RawInstruction, error) {
return jumpToRaw(a.Cond, opOperandX, 0, a.SkipTrue, a.SkipFalse)
}
// String returns the instruction in assembler notation.
func (a JumpIfX) String() string {
return jumpToString(a.Cond, "x", a.SkipTrue, a.SkipFalse)
}
// jumpToRaw assembles a jump instruction into a RawInstruction
func jumpToRaw(test JumpTest, operand opOperand, k uint32, skipTrue, skipFalse uint8) (RawInstruction, error) {
var ( var (
cond uint16 cond jumpOp
flip bool flip bool
) )
switch a.Cond { switch test {
case JumpEqual: case JumpEqual:
cond = opJumpEqual cond = opJumpEqual
case JumpNotEqual: case JumpNotEqual:
@ -552,63 +574,63 @@ func (a JumpIf) Assemble() (RawInstruction, error) {
case JumpBitsNotSet: case JumpBitsNotSet:
cond, flip = opJumpSet, true cond, flip = opJumpSet, true
default: default:
return RawInstruction{}, fmt.Errorf("unknown JumpTest %v", a.Cond) return RawInstruction{}, fmt.Errorf("unknown JumpTest %v", test)
} }
jt, jf := a.SkipTrue, a.SkipFalse jt, jf := skipTrue, skipFalse
if flip { if flip {
jt, jf = jf, jt jt, jf = jf, jt
} }
return RawInstruction{ return RawInstruction{
Op: opClsJump | cond, Op: opClsJump | uint16(cond) | uint16(operand),
Jt: jt, Jt: jt,
Jf: jf, Jf: jf,
K: a.Val, K: k,
}, nil }, nil
} }
// String returns the instruction in assembler notation. // jumpToString converts a jump instruction to assembler notation
func (a JumpIf) String() string { func jumpToString(cond JumpTest, operand string, skipTrue, skipFalse uint8) string {
switch a.Cond { switch cond {
// K == A // K == A
case JumpEqual: case JumpEqual:
return conditionalJump(a, "jeq", "jneq") return conditionalJump(operand, skipTrue, skipFalse, "jeq", "jneq")
// K != A // K != A
case JumpNotEqual: case JumpNotEqual:
return fmt.Sprintf("jneq #%d,%d", a.Val, a.SkipTrue) return fmt.Sprintf("jneq %s,%d", operand, skipTrue)
// K > A // K > A
case JumpGreaterThan: case JumpGreaterThan:
return conditionalJump(a, "jgt", "jle") return conditionalJump(operand, skipTrue, skipFalse, "jgt", "jle")
// K < A // K < A
case JumpLessThan: case JumpLessThan:
return fmt.Sprintf("jlt #%d,%d", a.Val, a.SkipTrue) return fmt.Sprintf("jlt %s,%d", operand, skipTrue)
// K >= A // K >= A
case JumpGreaterOrEqual: case JumpGreaterOrEqual:
return conditionalJump(a, "jge", "jlt") return conditionalJump(operand, skipTrue, skipFalse, "jge", "jlt")
// K <= A // K <= A
case JumpLessOrEqual: case JumpLessOrEqual:
return fmt.Sprintf("jle #%d,%d", a.Val, a.SkipTrue) return fmt.Sprintf("jle %s,%d", operand, skipTrue)
// K & A != 0 // K & A != 0
case JumpBitsSet: case JumpBitsSet:
if a.SkipFalse > 0 { if skipFalse > 0 {
return fmt.Sprintf("jset #%d,%d,%d", a.Val, a.SkipTrue, a.SkipFalse) return fmt.Sprintf("jset %s,%d,%d", operand, skipTrue, skipFalse)
} }
return fmt.Sprintf("jset #%d,%d", a.Val, a.SkipTrue) return fmt.Sprintf("jset %s,%d", operand, skipTrue)
// K & A == 0, there is no assembler instruction for JumpBitNotSet, use JumpBitSet and invert skips // K & A == 0, there is no assembler instruction for JumpBitNotSet, use JumpBitSet and invert skips
case JumpBitsNotSet: case JumpBitsNotSet:
return JumpIf{Cond: JumpBitsSet, SkipTrue: a.SkipFalse, SkipFalse: a.SkipTrue, Val: a.Val}.String() return jumpToString(JumpBitsSet, operand, skipFalse, skipTrue)
default: default:
return fmt.Sprintf("unknown instruction: %#v", a) return fmt.Sprintf("unknown JumpTest %#v", cond)
} }
} }
func conditionalJump(inst JumpIf, positiveJump, negativeJump string) string { func conditionalJump(operand string, skipTrue, skipFalse uint8, positiveJump, negativeJump string) string {
if inst.SkipTrue > 0 { if skipTrue > 0 {
if inst.SkipFalse > 0 { if skipFalse > 0 {
return fmt.Sprintf("%s #%d,%d,%d", positiveJump, inst.Val, inst.SkipTrue, inst.SkipFalse) return fmt.Sprintf("%s %s,%d,%d", positiveJump, operand, skipTrue, skipFalse)
} }
return fmt.Sprintf("%s #%d,%d", positiveJump, inst.Val, inst.SkipTrue) return fmt.Sprintf("%s %s,%d", positiveJump, operand, skipTrue)
} }
return fmt.Sprintf("%s #%d,%d", negativeJump, inst.Val, inst.SkipFalse) return fmt.Sprintf("%s %s,%d", negativeJump, operand, skipFalse)
} }
// RetA exits the BPF program, returning the value of register A. // RetA exits the BPF program, returning the value of register A.

10
vendor/golang.org/x/net/bpf/vm.go generated vendored
View File

@ -35,6 +35,13 @@ func NewVM(filter []Instruction) (*VM, error) {
if check <= int(ins.SkipFalse) { if check <= int(ins.SkipFalse) {
return nil, fmt.Errorf("cannot jump %d instructions in false case; jumping past program bounds", ins.SkipFalse) return nil, fmt.Errorf("cannot jump %d instructions in false case; jumping past program bounds", ins.SkipFalse)
} }
case JumpIfX:
if check <= int(ins.SkipTrue) {
return nil, fmt.Errorf("cannot jump %d instructions in true case; jumping past program bounds", ins.SkipTrue)
}
if check <= int(ins.SkipFalse) {
return nil, fmt.Errorf("cannot jump %d instructions in false case; jumping past program bounds", ins.SkipFalse)
}
// Check for division or modulus by zero // Check for division or modulus by zero
case ALUOpConstant: case ALUOpConstant:
if ins.Val != 0 { if ins.Val != 0 {
@ -109,6 +116,9 @@ func (v *VM) Run(in []byte) (int, error) {
case JumpIf: case JumpIf:
jump := jumpIf(ins, regA) jump := jumpIf(ins, regA)
i += jump i += jump
case JumpIfX:
jump := jumpIfX(ins, regA, regX)
i += jump
case LoadAbsolute: case LoadAbsolute:
regA, ok = loadAbsolute(ins, in) regA, ok = loadAbsolute(ins, in)
case LoadConstant: case LoadConstant:

View File

@ -55,34 +55,41 @@ func aluOpCommon(op ALUOp, regA uint32, value uint32) uint32 {
} }
} }
func jumpIf(ins JumpIf, value uint32) int { func jumpIf(ins JumpIf, regA uint32) int {
var ok bool return jumpIfCommon(ins.Cond, ins.SkipTrue, ins.SkipFalse, regA, ins.Val)
inV := uint32(ins.Val) }
switch ins.Cond { func jumpIfX(ins JumpIfX, regA uint32, regX uint32) int {
return jumpIfCommon(ins.Cond, ins.SkipTrue, ins.SkipFalse, regA, regX)
}
func jumpIfCommon(cond JumpTest, skipTrue, skipFalse uint8, regA uint32, value uint32) int {
var ok bool
switch cond {
case JumpEqual: case JumpEqual:
ok = value == inV ok = regA == value
case JumpNotEqual: case JumpNotEqual:
ok = value != inV ok = regA != value
case JumpGreaterThan: case JumpGreaterThan:
ok = value > inV ok = regA > value
case JumpLessThan: case JumpLessThan:
ok = value < inV ok = regA < value
case JumpGreaterOrEqual: case JumpGreaterOrEqual:
ok = value >= inV ok = regA >= value
case JumpLessOrEqual: case JumpLessOrEqual:
ok = value <= inV ok = regA <= value
case JumpBitsSet: case JumpBitsSet:
ok = (value & inV) != 0 ok = (regA & value) != 0
case JumpBitsNotSet: case JumpBitsNotSet:
ok = (value & inV) == 0 ok = (regA & value) == 0
} }
if ok { if ok {
return int(ins.SkipTrue) return int(skipTrue)
} }
return int(ins.SkipFalse) return int(skipFalse)
} }
func loadAbsolute(ins LoadAbsolute, in []byte) (uint32, bool) { func loadAbsolute(ins LoadAbsolute, in []byte) (uint32, bool) {

View File

@ -4,38 +4,34 @@
// Package iana provides protocol number resources managed by the Internet Assigned Numbers Authority (IANA). // Package iana provides protocol number resources managed by the Internet Assigned Numbers Authority (IANA).
package iana // import "golang.org/x/net/internal/iana" package iana // import "golang.org/x/net/internal/iana"
// Differentiated Services Field Codepoints (DSCP), Updated: 2017-05-12 // Differentiated Services Field Codepoints (DSCP), Updated: 2018-05-04
const ( const (
DiffServCS0 = 0x0 // CS0 DiffServCS0 = 0x00 // CS0
DiffServCS1 = 0x20 // CS1 DiffServCS1 = 0x20 // CS1
DiffServCS2 = 0x40 // CS2 DiffServCS2 = 0x40 // CS2
DiffServCS3 = 0x60 // CS3 DiffServCS3 = 0x60 // CS3
DiffServCS4 = 0x80 // CS4 DiffServCS4 = 0x80 // CS4
DiffServCS5 = 0xa0 // CS5 DiffServCS5 = 0xa0 // CS5
DiffServCS6 = 0xc0 // CS6 DiffServCS6 = 0xc0 // CS6
DiffServCS7 = 0xe0 // CS7 DiffServCS7 = 0xe0 // CS7
DiffServAF11 = 0x28 // AF11 DiffServAF11 = 0x28 // AF11
DiffServAF12 = 0x30 // AF12 DiffServAF12 = 0x30 // AF12
DiffServAF13 = 0x38 // AF13 DiffServAF13 = 0x38 // AF13
DiffServAF21 = 0x48 // AF21 DiffServAF21 = 0x48 // AF21
DiffServAF22 = 0x50 // AF22 DiffServAF22 = 0x50 // AF22
DiffServAF23 = 0x58 // AF23 DiffServAF23 = 0x58 // AF23
DiffServAF31 = 0x68 // AF31 DiffServAF31 = 0x68 // AF31
DiffServAF32 = 0x70 // AF32 DiffServAF32 = 0x70 // AF32
DiffServAF33 = 0x78 // AF33 DiffServAF33 = 0x78 // AF33
DiffServAF41 = 0x88 // AF41 DiffServAF41 = 0x88 // AF41
DiffServAF42 = 0x90 // AF42 DiffServAF42 = 0x90 // AF42
DiffServAF43 = 0x98 // AF43 DiffServAF43 = 0x98 // AF43
DiffServEF = 0xb8 // EF DiffServEF = 0xb8 // EF
DiffServVOICEADMIT = 0xb0 // VOICE-ADMIT DiffServVOICEADMIT = 0xb0 // VOICE-ADMIT
) NotECNTransport = 0x00 // Not-ECT (Not ECN-Capable Transport)
ECNTransport1 = 0x01 // ECT(1) (ECN-Capable Transport(1))
// IPv4 TOS Byte and IPv6 Traffic Class Octet, Updated: 2001-09-06 ECNTransport0 = 0x02 // ECT(0) (ECN-Capable Transport(0))
const ( CongestionExperienced = 0x03 // CE (Congestion Experienced)
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: 2017-10-13 // Protocol Numbers, Updated: 2017-10-13
@ -179,7 +175,7 @@ const (
ProtocolReserved = 255 // Reserved ProtocolReserved = 255 // Reserved
) )
// Address Family Numbers, Updated: 2016-10-25 // Address Family Numbers, Updated: 2018-04-02
const ( const (
AddrFamilyIPv4 = 1 // IP (IP version 4) AddrFamilyIPv4 = 1 // IP (IP version 4)
AddrFamilyIPv6 = 2 // IP6 (IP version 6) AddrFamilyIPv6 = 2 // IP6 (IP version 6)

View File

@ -31,16 +31,12 @@ var registries = []struct {
"https://www.iana.org/assignments/dscp-registry/dscp-registry.xml", "https://www.iana.org/assignments/dscp-registry/dscp-registry.xml",
parseDSCPRegistry, parseDSCPRegistry,
}, },
{
"https://www.iana.org/assignments/ipv4-tos-byte/ipv4-tos-byte.xml",
parseTOSTCByte,
},
{ {
"https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml", "https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml",
parseProtocolNumbers, parseProtocolNumbers,
}, },
{ {
"http://www.iana.org/assignments/address-family-numbers/address-family-numbers.xml", "https://www.iana.org/assignments/address-family-numbers/address-family-numbers.xml",
parseAddrFamilyNumbers, parseAddrFamilyNumbers,
}, },
} }
@ -85,31 +81,39 @@ func parseDSCPRegistry(w io.Writer, r io.Reader) error {
if err := dec.Decode(&dr); err != nil { if err := dec.Decode(&dr); err != nil {
return err return err
} }
drs := dr.escape()
fmt.Fprintf(w, "// %s, Updated: %s\n", dr.Title, dr.Updated) fmt.Fprintf(w, "// %s, Updated: %s\n", dr.Title, dr.Updated)
fmt.Fprintf(w, "const (\n") fmt.Fprintf(w, "const (\n")
for _, dr := range drs { for _, dr := range dr.escapeDSCP() {
fmt.Fprintf(w, "DiffServ%s = %#x", dr.Name, dr.Value) fmt.Fprintf(w, "DiffServ%s = %#02x", dr.Name, dr.Value)
fmt.Fprintf(w, "// %s\n", dr.OrigName) fmt.Fprintf(w, "// %s\n", dr.OrigName)
} }
for _, er := range dr.escapeECN() {
fmt.Fprintf(w, "%s = %#02x", er.Descr, er.Value)
fmt.Fprintf(w, "// %s\n", er.OrigDescr)
}
fmt.Fprintf(w, ")\n") fmt.Fprintf(w, ")\n")
return nil return nil
} }
type dscpRegistry struct { type dscpRegistry struct {
XMLName xml.Name `xml:"registry"` XMLName xml.Name `xml:"registry"`
Title string `xml:"title"` Title string `xml:"title"`
Updated string `xml:"updated"` Updated string `xml:"updated"`
Note string `xml:"note"` Note string `xml:"note"`
RegTitle string `xml:"registry>title"` Registries []struct {
PoolRecords []struct { Title string `xml:"title"`
Name string `xml:"name"` Registries []struct {
Space string `xml:"space"` Title string `xml:"title"`
} `xml:"registry>record"` Records []struct {
Records []struct { Name string `xml:"name"`
Name string `xml:"name"` Space string `xml:"space"`
Space string `xml:"space"` } `xml:"record"`
} `xml:"registry>registry>record"` } `xml:"registry"`
Records []struct {
Value string `xml:"value"`
Descr string `xml:"description"`
} `xml:"record"`
} `xml:"registry"`
} }
type canonDSCPRecord struct { type canonDSCPRecord struct {
@ -118,92 +122,84 @@ type canonDSCPRecord struct {
Value int Value int
} }
func (drr *dscpRegistry) escape() []canonDSCPRecord { func (drr *dscpRegistry) escapeDSCP() []canonDSCPRecord {
drs := make([]canonDSCPRecord, len(drr.Records)) var drs []canonDSCPRecord
sr := strings.NewReplacer( for _, preg := range drr.Registries {
"+", "", if !strings.Contains(preg.Title, "Differentiated Services Field Codepoints") {
"-", "",
"/", "",
".", "",
" ", "",
)
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 continue
} }
drs[i].Value = int(n) << 2 for _, reg := range preg.Registries {
if !strings.Contains(reg.Title, "Pool 1 Codepoints") {
continue
}
drs = make([]canonDSCPRecord, len(reg.Records))
sr := strings.NewReplacer(
"+", "",
"-", "",
"/", "",
".", "",
" ", "",
)
for i, dr := range reg.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 return drs
} }
func parseTOSTCByte(w io.Writer, r io.Reader) error { type canonECNRecord struct {
dec := xml.NewDecoder(r) OrigDescr string
var ttb tosTCByte Descr string
if err := dec.Decode(&ttb); err != nil { Value int
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 { func (drr *dscpRegistry) escapeECN() []canonECNRecord {
XMLName xml.Name `xml:"registry"` var ers []canonECNRecord
Title string `xml:"title"` for _, reg := range drr.Registries {
Updated string `xml:"updated"` if !strings.Contains(reg.Title, "ECN Field") {
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 continue
} }
trs[i].Value = int(n) ers = make([]canonECNRecord, len(reg.Records))
sr := strings.NewReplacer(
"Capable", "",
"Not-ECT", "",
"ECT(1)", "",
"ECT(0)", "",
"CE", "",
"(", "",
")", "",
"+", "",
"-", "",
"/", "",
".", "",
" ", "",
)
for i, er := range reg.Records {
s := strings.TrimSpace(er.Descr)
ers[i].OrigDescr = s
ss := strings.Split(s, " ")
if len(ss) > 1 {
ers[i].Descr = strings.Join(ss[1:], " ")
} else {
ers[i].Descr = ss[0]
}
ers[i].Descr = sr.Replace(er.Descr)
n, err := strconv.ParseUint(er.Value, 2, 8)
if err != nil {
continue
}
ers[i].Value = int(n)
}
} }
return trs return ers
} }
func parseProtocolNumbers(w io.Writer, r io.Reader) error { func parseProtocolNumbers(w io.Writer, r io.Reader) error {

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package socket package socket

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd netbsd openbsd // +build aix darwin dragonfly freebsd netbsd openbsd
package socket package socket

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris // +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
package socket package socket

47
vendor/golang.org/x/net/internal/socket/defs_aix.go generated vendored Normal file
View File

@ -0,0 +1,47 @@
// Copyright 2019 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_in_addr [4]byte /* in_addr */
// +godefs map struct_in6_addr [16]byte /* in6_addr */
package socket
/*
#include <sys/socket.h>
#include <netinet/in.h>
*/
import "C"
const (
sysAF_UNSPEC = C.AF_UNSPEC
sysAF_INET = C.AF_INET
sysAF_INET6 = C.AF_INET6
sysSOCK_RAW = C.SOCK_RAW
)
type iovec C.struct_iovec
type msghdr C.struct_msghdr
type mmsghdr C.struct_mmsghdr
type cmsghdr C.struct_cmsghdr
type sockaddrInet C.struct_sockaddr_in
type sockaddrInet6 C.struct_sockaddr_in6
const (
sizeofIovec = C.sizeof_struct_iovec
sizeofMsghdr = C.sizeof_struct_msghdr
sizeofMmsghdr = C.sizeof_struct_mmsghdr
sizeofCmsghdr = C.sizeof_struct_cmsghdr
sizeofSockaddrInet = C.sizeof_struct_sockaddr_in
sizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
)

7
vendor/golang.org/x/net/internal/socket/empty.s generated vendored Normal file
View File

@ -0,0 +1,7 @@
// Copyright 2018 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,go1.12
// This exists solely so we can linkname in symbols from syscall.

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package socket package socket

View File

@ -3,7 +3,7 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build arm64 amd64 ppc64 ppc64le mips64 mips64le s390x // +build arm64 amd64 ppc64 ppc64le mips64 mips64le s390x
// +build darwin dragonfly freebsd linux netbsd openbsd // +build aix darwin dragonfly freebsd linux netbsd openbsd
package socket package socket

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris // +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
package socket package socket

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build !linux,!netbsd // +build !aix,!linux,!netbsd
package socket package socket

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build linux netbsd // +build aix linux netbsd
package socket package socket

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd netbsd openbsd // +build aix darwin dragonfly freebsd netbsd openbsd
package socket package socket

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd netbsd // +build aix darwin dragonfly freebsd netbsd
package socket package socket

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris // +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
package socket package socket

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build go1.9
package socket package socket
import ( import (

View File

@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build go1.9
// +build linux // +build linux
package socket package socket

View File

@ -2,8 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build go1.9 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
package socket package socket

View File

@ -2,17 +2,14 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build go1.9
// +build !linux // +build !linux
package socket package socket
import "errors"
func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) { func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) {
return 0, errors.New("not implemented") return 0, errNotImplemented
} }
func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) { func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) {
return 0, errors.New("not implemented") return 0, errNotImplemented
} }

View File

@ -2,17 +2,14 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build go1.9 // +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
package socket package socket
import "errors"
func (c *Conn) recvMsg(m *Message, flags int) error { func (c *Conn) recvMsg(m *Message, flags int) error {
return errors.New("not implemented") return errNotImplemented
} }
func (c *Conn) sendMsg(m *Message, flags int) error { func (c *Conn) sendMsg(m *Message, flags int) error {
return errors.New("not implemented") return errNotImplemented
} }

View File

@ -1,25 +0,0 @@
// Copyright 2017 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.9
package socket
import "errors"
func (c *Conn) recvMsg(m *Message, flags int) error {
return errors.New("not implemented")
}
func (c *Conn) sendMsg(m *Message, flags int) error {
return errors.New("not implemented")
}
func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) {
return 0, errors.New("not implemented")
}
func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) {
return 0, errors.New("not implemented")
}

View File

@ -1,62 +0,0 @@
// Copyright 2017 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.9
package socket
import (
"errors"
"net"
"os"
"reflect"
"runtime"
)
// A Conn represents a raw connection.
type Conn struct {
c net.Conn
}
// NewConn returns a new raw connection.
func NewConn(c net.Conn) (*Conn, error) {
return &Conn{c: c}, nil
}
func (o *Option) get(c *Conn, b []byte) (int, error) {
s, err := socketOf(c.c)
if err != nil {
return 0, err
}
n, err := getsockopt(s, o.Level, o.Name, b)
return n, os.NewSyscallError("getsockopt", err)
}
func (o *Option) set(c *Conn, b []byte) error {
s, err := socketOf(c.c)
if err != nil {
return err
}
return os.NewSyscallError("setsockopt", setsockopt(s, o.Level, o.Name, b))
}
func socketOf(c net.Conn) (uintptr, error) {
switch c.(type) {
case *net.TCPConn, *net.UDPConn, *net.IPConn:
v := reflect.ValueOf(c)
switch e := v.Elem(); e.Kind() {
case reflect.Struct:
fd := e.FieldByName("conn").FieldByName("fd")
switch e := fd.Elem(); e.Kind() {
case reflect.Struct:
sysfd := e.FieldByName("sysfd")
if runtime.GOOS == "windows" {
return uintptr(sysfd.Uint()), nil
}
return uintptr(sysfd.Int()), nil
}
}
}
return 0, errors.New("invalid type")
}

View File

@ -9,9 +9,12 @@ package socket // import "golang.org/x/net/internal/socket"
import ( import (
"errors" "errors"
"net" "net"
"runtime"
"unsafe" "unsafe"
) )
var errNotImplemented = errors.New("not implemented on " + runtime.GOOS + "/" + runtime.GOARCH)
// An Option represents a sticky socket option. // An Option represents a sticky socket option.
type Option struct { type Option struct {
Level int // level Level int // level

View File

@ -29,5 +29,5 @@ func init() {
} }
func roundup(l int) int { func roundup(l int) int {
return (l + kernelAlign - 1) & ^(kernelAlign - 1) return (l + kernelAlign - 1) &^ (kernelAlign - 1)
} }

View File

@ -2,16 +2,14 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd openbsd // +build aix darwin dragonfly freebsd openbsd
package socket package socket
import "errors"
func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
return 0, errors.New("not implemented") return 0, errNotImplemented
} }
func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
return 0, errors.New("not implemented") return 0, errNotImplemented
} }

View File

@ -2,13 +2,22 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build freebsd netbsd openbsd // +build aix freebsd netbsd openbsd
package socket package socket
import "unsafe" import (
"runtime"
"unsafe"
)
func probeProtocolStack() int { func probeProtocolStack() int {
if (runtime.GOOS == "netbsd" || runtime.GOOS == "openbsd") && runtime.GOARCH == "arm" {
return 8
}
if runtime.GOOS == "aix" {
return 1
}
var p uintptr var p uintptr
return int(unsafe.Sizeof(p)) return int(unsafe.Sizeof(p))
} }

View File

@ -0,0 +1,33 @@
// Copyright 2018 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.12
package socket
import (
"syscall"
"unsafe"
)
func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
l := uint32(len(b))
_, _, errno := syscall.Syscall6(syscall.SYS_GETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0)
return int(l), errnoErr(errno)
}
func setsockopt(s uintptr, level, name int, b []byte) error {
_, _, errno := syscall.Syscall6(syscall.SYS_SETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0)
return errnoErr(errno)
}
func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
n, _, errno := syscall.Syscall(syscall.SYS_RECVMSG, s, uintptr(unsafe.Pointer(h)), uintptr(flags))
return int(n), errnoErr(errno)
}
func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
n, _, errno := syscall.Syscall(syscall.SYS_SENDMSG, s, uintptr(unsafe.Pointer(h)), uintptr(flags))
return int(n), errnoErr(errno)
}

View File

@ -0,0 +1,42 @@
// Copyright 2018 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 aix go1.12,darwin
package socket
import (
"syscall"
"unsafe"
)
//go:linkname syscall_getsockopt syscall.getsockopt
func syscall_getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *uint32) error
func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
l := uint32(len(b))
err := syscall_getsockopt(int(s), level, name, unsafe.Pointer(&b[0]), &l)
return int(l), err
}
//go:linkname syscall_setsockopt syscall.setsockopt
func syscall_setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) error
func setsockopt(s uintptr, level, name int, b []byte) error {
return syscall_setsockopt(int(s), level, name, unsafe.Pointer(&b[0]), uintptr(len(b)))
}
//go:linkname syscall_recvmsg syscall.recvmsg
func syscall_recvmsg(s int, msg *syscall.Msghdr, flags int) (n int, err error)
func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
return syscall_recvmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags)
}
//go:linkname syscall_sendmsg syscall.sendmsg
func syscall_sendmsg(s int, msg *syscall.Msghdr, flags int) (n int, err error)
func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
return syscall_sendmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags)
}

View File

@ -2,8 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build go1.9 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
package socket package socket
@ -121,18 +120,21 @@ var zoneCache = ipv6ZoneCache{
toName: make(map[int]string), toName: make(map[int]string),
} }
func (zc *ipv6ZoneCache) update(ift []net.Interface) { // update refreshes the network interface information if the cache was last
// updated more than 1 minute ago, or if force is set. It returns whether the
// cache was updated.
func (zc *ipv6ZoneCache) update(ift []net.Interface, force bool) (updated bool) {
zc.Lock() zc.Lock()
defer zc.Unlock() defer zc.Unlock()
now := time.Now() now := time.Now()
if zc.lastFetched.After(now.Add(-60 * time.Second)) { if !force && zc.lastFetched.After(now.Add(-60*time.Second)) {
return return false
} }
zc.lastFetched = now zc.lastFetched = now
if len(ift) == 0 { if len(ift) == 0 {
var err error var err error
if ift, err = net.Interfaces(); err != nil { if ift, err = net.Interfaces(); err != nil {
return return false
} }
} }
zc.toIndex = make(map[string]int, len(ift)) zc.toIndex = make(map[string]int, len(ift))
@ -143,25 +145,38 @@ func (zc *ipv6ZoneCache) update(ift []net.Interface) {
zc.toName[ifi.Index] = ifi.Name zc.toName[ifi.Index] = ifi.Name
} }
} }
return true
} }
func (zc *ipv6ZoneCache) name(zone int) string { func (zc *ipv6ZoneCache) name(zone int) string {
zoneCache.update(nil) updated := zoneCache.update(nil, false)
zoneCache.RLock() zoneCache.RLock()
defer zoneCache.RUnlock()
name, ok := zoneCache.toName[zone] name, ok := zoneCache.toName[zone]
if !ok { zoneCache.RUnlock()
if !ok && !updated {
zoneCache.update(nil, true)
zoneCache.RLock()
name, ok = zoneCache.toName[zone]
zoneCache.RUnlock()
}
if !ok { // last resort
name = strconv.Itoa(zone) name = strconv.Itoa(zone)
} }
return name return name
} }
func (zc *ipv6ZoneCache) index(zone string) int { func (zc *ipv6ZoneCache) index(zone string) int {
zoneCache.update(nil) updated := zoneCache.update(nil, false)
zoneCache.RLock() zoneCache.RLock()
defer zoneCache.RUnlock()
index, ok := zoneCache.toIndex[zone] index, ok := zoneCache.toIndex[zone]
if !ok { zoneCache.RUnlock()
if !ok && !updated {
zoneCache.update(nil, true)
zoneCache.RLock()
index, ok = zoneCache.toIndex[zone]
zoneCache.RUnlock()
}
if !ok { // last resort
index, _ = strconv.Atoi(zone) index, _ = strconv.Atoi(zone)
} }
return index return index

View File

@ -5,7 +5,6 @@
package socket package socket
import ( import (
"errors"
"runtime" "runtime"
"syscall" "syscall"
"unsafe" "unsafe"
@ -63,9 +62,9 @@ func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
} }
func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
return 0, errors.New("not implemented") return 0, errNotImplemented
} }
func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
return 0, errors.New("not implemented") return 0, errNotImplemented
} }

View File

@ -2,12 +2,11 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows // +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
package socket package socket
import ( import (
"errors"
"net" "net"
"runtime" "runtime"
"unsafe" "unsafe"
@ -36,29 +35,29 @@ func marshalInetAddr(ip net.IP, port int, zone string) []byte {
} }
func parseInetAddr(b []byte, network string) (net.Addr, error) { func parseInetAddr(b []byte, network string) (net.Addr, error) {
return nil, errors.New("not implemented") return nil, errNotImplemented
} }
func getsockopt(s uintptr, level, name int, b []byte) (int, error) { func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
return 0, errors.New("not implemented") return 0, errNotImplemented
} }
func setsockopt(s uintptr, level, name int, b []byte) error { func setsockopt(s uintptr, level, name int, b []byte) error {
return errors.New("not implemented") return errNotImplemented
} }
func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
return 0, errors.New("not implemented") return 0, errNotImplemented
} }
func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
return 0, errors.New("not implemented") return 0, errNotImplemented
} }
func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
return 0, errors.New("not implemented") return 0, errNotImplemented
} }
func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
return 0, errors.New("not implemented") return 0, errNotImplemented
} }

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux,!s390x,!386 netbsd openbsd // +build dragonfly freebsd linux,!s390x,!386 netbsd openbsd
package socket package socket

View File

@ -5,7 +5,6 @@
package socket package socket
import ( import (
"errors"
"syscall" "syscall"
"unsafe" "unsafe"
) )
@ -54,17 +53,17 @@ func setsockopt(s uintptr, level, name int, b []byte) error {
} }
func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { func recvmsg(s uintptr, h *msghdr, flags int) (int, error) {
return 0, errors.New("not implemented") return 0, errNotImplemented
} }
func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { func sendmsg(s uintptr, h *msghdr, flags int) (int, error) {
return 0, errors.New("not implemented") return 0, errNotImplemented
} }
func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
return 0, errors.New("not implemented") return 0, errNotImplemented
} }
func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
return 0, errors.New("not implemented") return 0, errNotImplemented
} }

View File

@ -0,0 +1,69 @@
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs defs_aix.go
// Added for go1.11 compatibility
// +build aix
package socket
const (
sysAF_UNSPEC = 0x0
sysAF_INET = 0x2
sysAF_INET6 = 0x18
sysSOCK_RAW = 0x3
)
type iovec struct {
Base *byte
Len uint64
}
type msghdr struct {
Name *byte
Namelen uint32
Iov *iovec
Iovlen int32
Control *byte
Controllen uint32
Flags int32
}
type mmsghdr struct {
Hdr msghdr
Len uint32
Pad_cgo_0 [4]byte
}
type cmsghdr struct {
Len uint32
Level int32
Type int32
}
type sockaddrInet struct {
Len uint8
Family uint8
Port uint16
Addr [4]byte /* in_addr */
Zero [8]uint8
}
type sockaddrInet6 struct {
Len uint8
Family uint8
Port uint16
Flowinfo uint32
Addr [16]byte /* in6_addr */
Scope_id uint32
}
const (
sizeofIovec = 0x10
sizeofMsghdr = 0x30
sizeofMmsghdr = 0x38
sizeofCmsghdr = 0xc
sizeofSockaddrInet = 0x10
sizeofSockaddrInet6 = 0x1c
)

View File

@ -75,7 +75,7 @@ const (
AuthMethodNotRequired AuthMethod = 0x00 // no authentication required AuthMethodNotRequired AuthMethod = 0x00 // no authentication required
AuthMethodUsernamePassword AuthMethod = 0x02 // use username/password AuthMethodUsernamePassword AuthMethod = 0x02 // use username/password
AuthMethodNoAcceptableMethods AuthMethod = 0xff // no acceptable authetication methods AuthMethodNoAcceptableMethods AuthMethod = 0xff // no acceptable authentication methods
StatusSucceeded Reply = 0x00 StatusSucceeded Reply = 0x00
) )
@ -149,20 +149,13 @@ type Dialer struct {
// See func Dial of the net package of standard library for a // See func Dial of the net package of standard library for a
// description of the network and address parameters. // description of the network and address parameters.
func (d *Dialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) { func (d *Dialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
switch network { if err := d.validateTarget(network, address); err != nil {
case "tcp", "tcp6", "tcp4":
default:
proxy, dst, _ := d.pathAddrs(address) proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("network not implemented")} return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
}
switch d.cmd {
case CmdConnect, cmdBind:
default:
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("command not implemented")}
} }
if ctx == nil { if ctx == nil {
ctx = context.Background() proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("nil context")}
} }
var err error var err error
var c net.Conn var c net.Conn
@ -185,11 +178,70 @@ func (d *Dialer) DialContext(ctx context.Context, network, address string) (net.
return &Conn{Conn: c, boundAddr: a}, nil return &Conn{Conn: c, boundAddr: a}, nil
} }
// DialWithConn initiates a connection from SOCKS server to the target
// network and address using the connection c that is already
// connected to the SOCKS server.
//
// It returns the connection's local address assigned by the SOCKS
// server.
func (d *Dialer) DialWithConn(ctx context.Context, c net.Conn, network, address string) (net.Addr, error) {
if err := d.validateTarget(network, address); err != nil {
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
}
if ctx == nil {
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("nil context")}
}
a, err := d.connect(ctx, c, address)
if err != nil {
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
}
return a, nil
}
// Dial connects to the provided address on the provided network. // Dial connects to the provided address on the provided network.
// //
// Deprecated: Use DialContext instead. // Unlike DialContext, it returns a raw transport connection instead
// of a forward proxy connection.
//
// Deprecated: Use DialContext or DialWithConn instead.
func (d *Dialer) Dial(network, address string) (net.Conn, error) { func (d *Dialer) Dial(network, address string) (net.Conn, error) {
return d.DialContext(context.Background(), network, address) if err := d.validateTarget(network, address); err != nil {
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
}
var err error
var c net.Conn
if d.ProxyDial != nil {
c, err = d.ProxyDial(context.Background(), d.proxyNetwork, d.proxyAddress)
} else {
c, err = net.Dial(d.proxyNetwork, d.proxyAddress)
}
if err != nil {
proxy, dst, _ := d.pathAddrs(address)
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
}
if _, err := d.DialWithConn(context.Background(), c, network, address); err != nil {
c.Close()
return nil, err
}
return c, nil
}
func (d *Dialer) validateTarget(network, address string) error {
switch network {
case "tcp", "tcp6", "tcp4":
default:
return errors.New("network not implemented")
}
switch d.cmd {
case CmdConnect, cmdBind:
default:
return errors.New("command not implemented")
}
return nil
} }
func (d *Dialer) pathAddrs(address string) (proxy, dst net.Addr, err error) { func (d *Dialer) pathAddrs(address string) (proxy, dst net.Addr, err error) {

View File

@ -2,14 +2,11 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build go1.9
package ipv4 package ipv4
import ( import (
"net" "net"
"runtime" "runtime"
"syscall"
"golang.org/x/net/internal/socket" "golang.org/x/net/internal/socket"
) )
@ -76,7 +73,7 @@ type Message = socket.Message
// headers. // headers.
func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) { func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) {
if !c.ok() { if !c.ok() {
return 0, syscall.EINVAL return 0, errInvalidConn
} }
switch runtime.GOOS { switch runtime.GOOS {
case "linux": case "linux":
@ -92,6 +89,9 @@ func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) {
n = 0 n = 0
err = &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} err = &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
} }
if compatFreeBSD32 && ms[0].NN > 0 {
adjustFreeBSD32(&ms[0])
}
return n, err return n, err
} }
} }
@ -107,7 +107,7 @@ func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) {
// On other platforms, this method will write only a single message. // On other platforms, this method will write only a single message.
func (c *payloadHandler) WriteBatch(ms []Message, flags int) (int, error) { func (c *payloadHandler) WriteBatch(ms []Message, flags int) (int, error) {
if !c.ok() { if !c.ok() {
return 0, syscall.EINVAL return 0, errInvalidConn
} }
switch runtime.GOOS { switch runtime.GOOS {
case "linux": case "linux":
@ -139,7 +139,7 @@ func (c *payloadHandler) WriteBatch(ms []Message, flags int) (int, error) {
// On other platforms, this method will read only a single message. // On other platforms, this method will read only a single message.
func (c *packetHandler) ReadBatch(ms []Message, flags int) (int, error) { func (c *packetHandler) ReadBatch(ms []Message, flags int) (int, error) {
if !c.ok() { if !c.ok() {
return 0, syscall.EINVAL return 0, errInvalidConn
} }
switch runtime.GOOS { switch runtime.GOOS {
case "linux": case "linux":
@ -155,6 +155,9 @@ func (c *packetHandler) ReadBatch(ms []Message, flags int) (int, error) {
n = 0 n = 0
err = &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err} err = &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
} }
if compatFreeBSD32 && ms[0].NN > 0 {
adjustFreeBSD32(&ms[0])
}
return n, err return n, err
} }
} }
@ -170,7 +173,7 @@ func (c *packetHandler) ReadBatch(ms []Message, flags int) (int, error) {
// On other platforms, this method will write only a single message. // On other platforms, this method will write only a single message.
func (c *packetHandler) WriteBatch(ms []Message, flags int) (int, error) { func (c *packetHandler) WriteBatch(ms []Message, flags int) (int, error) {
if !c.ok() { if !c.ok() {
return 0, syscall.EINVAL return 0, errInvalidConn
} }
switch runtime.GOOS { switch runtime.GOOS {
case "linux": case "linux":

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd netbsd openbsd // +build aix darwin dragonfly freebsd netbsd openbsd
package ipv4 package ipv4

View File

@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows // +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
package ipv4 package ipv4
import "golang.org/x/net/internal/socket" import "golang.org/x/net/internal/socket"
func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error { func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
return errOpNoSupport return errNotImplemented
} }

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package ipv4 package ipv4

View File

@ -4,13 +4,9 @@
package ipv4 package ipv4
import ( import "golang.org/x/net/internal/socket"
"syscall"
"golang.org/x/net/internal/socket"
)
func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error { func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
// TODO(mikio): implement this // TODO(mikio): implement this
return syscall.EWINDOWS return errNotImplemented
} }

39
vendor/golang.org/x/net/ipv4/defs_aix.go generated vendored Normal file
View File

@ -0,0 +1,39 @@
// Copyright 2019 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_in_addr [4]byte /* in_addr */
package ipv4
/*
#include <netinet/in.h>
*/
import "C"
const (
sysIP_OPTIONS = C.IP_OPTIONS
sysIP_HDRINCL = C.IP_HDRINCL
sysIP_TOS = C.IP_TOS
sysIP_TTL = C.IP_TTL
sysIP_RECVOPTS = C.IP_RECVOPTS
sysIP_RECVRETOPTS = C.IP_RECVRETOPTS
sysIP_RECVDSTADDR = C.IP_RECVDSTADDR
sysIP_RETOPTS = C.IP_RETOPTS
// IP_RECVIF is defined on AIX but doesn't work.
// IP_RECVINTERFACE must be used instead.
sysIP_RECVIF = C.IP_RECVINTERFACE
sysIP_RECVTTL = C.IP_RECVTTL
sysIP_MULTICAST_IF = C.IP_MULTICAST_IF
sysIP_MULTICAST_TTL = C.IP_MULTICAST_TTL
sysIP_MULTICAST_LOOP = C.IP_MULTICAST_LOOP
sysIP_ADD_MEMBERSHIP = C.IP_ADD_MEMBERSHIP
sysIP_DROP_MEMBERSHIP = C.IP_DROP_MEMBERSHIP
sizeofIPMreq = C.sizeof_struct_ip_mreq
)
type ipMreq C.struct_ip_mreq

View File

@ -6,7 +6,6 @@ package ipv4
import ( import (
"net" "net"
"syscall"
"golang.org/x/net/bpf" "golang.org/x/net/bpf"
) )
@ -15,11 +14,11 @@ import (
// multicast packets. // multicast packets.
func (c *dgramOpt) MulticastTTL() (int, error) { func (c *dgramOpt) MulticastTTL() (int, error) {
if !c.ok() { if !c.ok() {
return 0, syscall.EINVAL return 0, errInvalidConn
} }
so, ok := sockOpts[ssoMulticastTTL] so, ok := sockOpts[ssoMulticastTTL]
if !ok { if !ok {
return 0, errOpNoSupport return 0, errNotImplemented
} }
return so.GetInt(c.Conn) return so.GetInt(c.Conn)
} }
@ -28,11 +27,11 @@ func (c *dgramOpt) MulticastTTL() (int, error) {
// outgoing multicast packets. // outgoing multicast packets.
func (c *dgramOpt) SetMulticastTTL(ttl int) error { func (c *dgramOpt) SetMulticastTTL(ttl int) error {
if !c.ok() { if !c.ok() {
return syscall.EINVAL return errInvalidConn
} }
so, ok := sockOpts[ssoMulticastTTL] so, ok := sockOpts[ssoMulticastTTL]
if !ok { if !ok {
return errOpNoSupport return errNotImplemented
} }
return so.SetInt(c.Conn, ttl) return so.SetInt(c.Conn, ttl)
} }
@ -41,11 +40,11 @@ func (c *dgramOpt) SetMulticastTTL(ttl int) error {
// packet transmissions. // packet transmissions.
func (c *dgramOpt) MulticastInterface() (*net.Interface, error) { func (c *dgramOpt) MulticastInterface() (*net.Interface, error) {
if !c.ok() { if !c.ok() {
return nil, syscall.EINVAL return nil, errInvalidConn
} }
so, ok := sockOpts[ssoMulticastInterface] so, ok := sockOpts[ssoMulticastInterface]
if !ok { if !ok {
return nil, errOpNoSupport return nil, errNotImplemented
} }
return so.getMulticastInterface(c.Conn) return so.getMulticastInterface(c.Conn)
} }
@ -54,11 +53,11 @@ func (c *dgramOpt) MulticastInterface() (*net.Interface, error) {
// multicast packet transmissions. // multicast packet transmissions.
func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error { func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error {
if !c.ok() { if !c.ok() {
return syscall.EINVAL return errInvalidConn
} }
so, ok := sockOpts[ssoMulticastInterface] so, ok := sockOpts[ssoMulticastInterface]
if !ok { if !ok {
return errOpNoSupport return errNotImplemented
} }
return so.setMulticastInterface(c.Conn, ifi) return so.setMulticastInterface(c.Conn, ifi)
} }
@ -67,11 +66,11 @@ func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error {
// should be copied and send back to the originator. // should be copied and send back to the originator.
func (c *dgramOpt) MulticastLoopback() (bool, error) { func (c *dgramOpt) MulticastLoopback() (bool, error) {
if !c.ok() { if !c.ok() {
return false, syscall.EINVAL return false, errInvalidConn
} }
so, ok := sockOpts[ssoMulticastLoopback] so, ok := sockOpts[ssoMulticastLoopback]
if !ok { if !ok {
return false, errOpNoSupport return false, errNotImplemented
} }
on, err := so.GetInt(c.Conn) on, err := so.GetInt(c.Conn)
if err != nil { if err != nil {
@ -84,11 +83,11 @@ func (c *dgramOpt) MulticastLoopback() (bool, error) {
// should be copied and send back to the originator. // should be copied and send back to the originator.
func (c *dgramOpt) SetMulticastLoopback(on bool) error { func (c *dgramOpt) SetMulticastLoopback(on bool) error {
if !c.ok() { if !c.ok() {
return syscall.EINVAL return errInvalidConn
} }
so, ok := sockOpts[ssoMulticastLoopback] so, ok := sockOpts[ssoMulticastLoopback]
if !ok { if !ok {
return errOpNoSupport return errNotImplemented
} }
return so.SetInt(c.Conn, boolint(on)) return so.SetInt(c.Conn, boolint(on))
} }
@ -104,11 +103,11 @@ func (c *dgramOpt) SetMulticastLoopback(on bool) error {
// configuration. // configuration.
func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error { func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error {
if !c.ok() { if !c.ok() {
return syscall.EINVAL return errInvalidConn
} }
so, ok := sockOpts[ssoJoinGroup] so, ok := sockOpts[ssoJoinGroup]
if !ok { if !ok {
return errOpNoSupport return errNotImplemented
} }
grp := netAddrToIP4(group) grp := netAddrToIP4(group)
if grp == nil { if grp == nil {
@ -122,11 +121,11 @@ func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error {
// source-specific group. // source-specific group.
func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error { func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {
if !c.ok() { if !c.ok() {
return syscall.EINVAL return errInvalidConn
} }
so, ok := sockOpts[ssoLeaveGroup] so, ok := sockOpts[ssoLeaveGroup]
if !ok { if !ok {
return errOpNoSupport return errNotImplemented
} }
grp := netAddrToIP4(group) grp := netAddrToIP4(group)
if grp == nil { if grp == nil {
@ -143,11 +142,11 @@ func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {
// routing configuration. // routing configuration.
func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
if !c.ok() { if !c.ok() {
return syscall.EINVAL return errInvalidConn
} }
so, ok := sockOpts[ssoJoinSourceGroup] so, ok := sockOpts[ssoJoinSourceGroup]
if !ok { if !ok {
return errOpNoSupport return errNotImplemented
} }
grp := netAddrToIP4(group) grp := netAddrToIP4(group)
if grp == nil { if grp == nil {
@ -164,11 +163,11 @@ func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net
// interface ifi. // interface ifi.
func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
if !c.ok() { if !c.ok() {
return syscall.EINVAL return errInvalidConn
} }
so, ok := sockOpts[ssoLeaveSourceGroup] so, ok := sockOpts[ssoLeaveSourceGroup]
if !ok { if !ok {
return errOpNoSupport return errNotImplemented
} }
grp := netAddrToIP4(group) grp := netAddrToIP4(group)
if grp == nil { if grp == nil {
@ -186,11 +185,11 @@ func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source ne
// ifi. // ifi.
func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
if !c.ok() { if !c.ok() {
return syscall.EINVAL return errInvalidConn
} }
so, ok := sockOpts[ssoBlockSourceGroup] so, ok := sockOpts[ssoBlockSourceGroup]
if !ok { if !ok {
return errOpNoSupport return errNotImplemented
} }
grp := netAddrToIP4(group) grp := netAddrToIP4(group)
if grp == nil { if grp == nil {
@ -207,11 +206,11 @@ func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source
// group by ExcludeSourceSpecificGroup again on the interface ifi. // group by ExcludeSourceSpecificGroup again on the interface ifi.
func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
if !c.ok() { if !c.ok() {
return syscall.EINVAL return errInvalidConn
} }
so, ok := sockOpts[ssoUnblockSourceGroup] so, ok := sockOpts[ssoUnblockSourceGroup]
if !ok { if !ok {
return errOpNoSupport return errNotImplemented
} }
grp := netAddrToIP4(group) grp := netAddrToIP4(group)
if grp == nil { if grp == nil {
@ -228,11 +227,11 @@ func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source
// Currently only Linux supports this. // Currently only Linux supports this.
func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) { func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) {
if !c.ok() { if !c.ok() {
return nil, syscall.EINVAL return nil, errInvalidConn
} }
so, ok := sockOpts[ssoICMPFilter] so, ok := sockOpts[ssoICMPFilter]
if !ok { if !ok {
return nil, errOpNoSupport return nil, errNotImplemented
} }
return so.getICMPFilter(c.Conn) return so.getICMPFilter(c.Conn)
} }
@ -241,11 +240,11 @@ func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) {
// Currently only Linux supports this. // Currently only Linux supports this.
func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error { func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error {
if !c.ok() { if !c.ok() {
return syscall.EINVAL return errInvalidConn
} }
so, ok := sockOpts[ssoICMPFilter] so, ok := sockOpts[ssoICMPFilter]
if !ok { if !ok {
return errOpNoSupport return errNotImplemented
} }
return so.setICMPFilter(c.Conn, f) return so.setICMPFilter(c.Conn, f)
} }
@ -255,11 +254,11 @@ func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error {
// Only supported on Linux. // Only supported on Linux.
func (c *dgramOpt) SetBPF(filter []bpf.RawInstruction) error { func (c *dgramOpt) SetBPF(filter []bpf.RawInstruction) error {
if !c.ok() { if !c.ok() {
return syscall.EINVAL return errInvalidConn
} }
so, ok := sockOpts[ssoAttachFilter] so, ok := sockOpts[ssoAttachFilter]
if !ok { if !ok {
return errOpNoSupport return errNotImplemented
} }
return so.setBPF(c.Conn, filter) return so.setBPF(c.Conn, filter)
} }

View File

@ -55,7 +55,7 @@
// Multicasting // Multicasting
// //
// The options for multicasting are available for net.UDPConn and // The options for multicasting are available for net.UDPConn and
// net.IPconn which are created as network connections that use the // net.IPConn which are created as network connections that use the
// IPv4 transport. A few network facilities must be prepared before // IPv4 transport. A few network facilities must be prepared before
// you begin multicasting, at a minimum joining network interfaces and // you begin multicasting, at a minimum joining network interfaces and
// multicast groups. // multicast groups.
@ -209,7 +209,7 @@
// LeaveSourceSpecificGroup for the operation known as "include" mode, // LeaveSourceSpecificGroup for the operation known as "include" mode,
// //
// ssmgroup := net.UDPAddr{IP: net.IPv4(232, 7, 8, 9)} // ssmgroup := net.UDPAddr{IP: net.IPv4(232, 7, 8, 9)}
// ssmsource := net.UDPAddr{IP: net.IPv4(192, 168, 0, 1)}) // ssmsource := net.UDPAddr{IP: net.IPv4(192, 168, 0, 1)}
// if err := p.JoinSourceSpecificGroup(en0, &ssmgroup, &ssmsource); err != nil { // if err := p.JoinSourceSpecificGroup(en0, &ssmgroup, &ssmsource); err != nil {
// // error handling // // error handling
// } // }
@ -241,4 +241,4 @@
// IncludeSourceSpecificGroup may return an error. // IncludeSourceSpecificGroup may return an error.
package ipv4 // import "golang.org/x/net/ipv4" package ipv4 // import "golang.org/x/net/ipv4"
// BUG(mikio): This package is not implemented on NaCl and Plan 9. // BUG(mikio): This package is not implemented on JS, NaCl and Plan 9.

View File

@ -6,7 +6,6 @@ package ipv4
import ( import (
"net" "net"
"syscall"
"time" "time"
"golang.org/x/net/internal/socket" "golang.org/x/net/internal/socket"
@ -58,7 +57,7 @@ func (c *dgramOpt) ok() bool { return c != nil && c.Conn != nil }
// SetControlMessage sets the per packet IP-level socket options. // SetControlMessage sets the per packet IP-level socket options.
func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error { func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error {
if !c.payloadHandler.ok() { if !c.payloadHandler.ok() {
return syscall.EINVAL return errInvalidConn
} }
return setControlMessage(c.dgramOpt.Conn, &c.payloadHandler.rawOpt, cf, on) return setControlMessage(c.dgramOpt.Conn, &c.payloadHandler.rawOpt, cf, on)
} }
@ -67,7 +66,7 @@ func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error {
// endpoint. // endpoint.
func (c *PacketConn) SetDeadline(t time.Time) error { func (c *PacketConn) SetDeadline(t time.Time) error {
if !c.payloadHandler.ok() { if !c.payloadHandler.ok() {
return syscall.EINVAL return errInvalidConn
} }
return c.payloadHandler.PacketConn.SetDeadline(t) return c.payloadHandler.PacketConn.SetDeadline(t)
} }
@ -76,7 +75,7 @@ func (c *PacketConn) SetDeadline(t time.Time) error {
// endpoint. // endpoint.
func (c *PacketConn) SetReadDeadline(t time.Time) error { func (c *PacketConn) SetReadDeadline(t time.Time) error {
if !c.payloadHandler.ok() { if !c.payloadHandler.ok() {
return syscall.EINVAL return errInvalidConn
} }
return c.payloadHandler.PacketConn.SetReadDeadline(t) return c.payloadHandler.PacketConn.SetReadDeadline(t)
} }
@ -85,7 +84,7 @@ func (c *PacketConn) SetReadDeadline(t time.Time) error {
// endpoint. // endpoint.
func (c *PacketConn) SetWriteDeadline(t time.Time) error { func (c *PacketConn) SetWriteDeadline(t time.Time) error {
if !c.payloadHandler.ok() { if !c.payloadHandler.ok() {
return syscall.EINVAL return errInvalidConn
} }
return c.payloadHandler.PacketConn.SetWriteDeadline(t) return c.payloadHandler.PacketConn.SetWriteDeadline(t)
} }
@ -93,7 +92,7 @@ func (c *PacketConn) SetWriteDeadline(t time.Time) error {
// Close closes the endpoint. // Close closes the endpoint.
func (c *PacketConn) Close() error { func (c *PacketConn) Close() error {
if !c.payloadHandler.ok() { if !c.payloadHandler.ok() {
return syscall.EINVAL return errInvalidConn
} }
return c.payloadHandler.PacketConn.Close() return c.payloadHandler.PacketConn.Close()
} }
@ -124,7 +123,7 @@ type RawConn struct {
// SetControlMessage sets the per packet IP-level socket options. // SetControlMessage sets the per packet IP-level socket options.
func (c *RawConn) SetControlMessage(cf ControlFlags, on bool) error { func (c *RawConn) SetControlMessage(cf ControlFlags, on bool) error {
if !c.packetHandler.ok() { if !c.packetHandler.ok() {
return syscall.EINVAL return errInvalidConn
} }
return setControlMessage(c.dgramOpt.Conn, &c.packetHandler.rawOpt, cf, on) return setControlMessage(c.dgramOpt.Conn, &c.packetHandler.rawOpt, cf, on)
} }
@ -133,7 +132,7 @@ func (c *RawConn) SetControlMessage(cf ControlFlags, on bool) error {
// endpoint. // endpoint.
func (c *RawConn) SetDeadline(t time.Time) error { func (c *RawConn) SetDeadline(t time.Time) error {
if !c.packetHandler.ok() { if !c.packetHandler.ok() {
return syscall.EINVAL return errInvalidConn
} }
return c.packetHandler.IPConn.SetDeadline(t) return c.packetHandler.IPConn.SetDeadline(t)
} }
@ -142,7 +141,7 @@ func (c *RawConn) SetDeadline(t time.Time) error {
// endpoint. // endpoint.
func (c *RawConn) SetReadDeadline(t time.Time) error { func (c *RawConn) SetReadDeadline(t time.Time) error {
if !c.packetHandler.ok() { if !c.packetHandler.ok() {
return syscall.EINVAL return errInvalidConn
} }
return c.packetHandler.IPConn.SetReadDeadline(t) return c.packetHandler.IPConn.SetReadDeadline(t)
} }
@ -151,7 +150,7 @@ func (c *RawConn) SetReadDeadline(t time.Time) error {
// endpoint. // endpoint.
func (c *RawConn) SetWriteDeadline(t time.Time) error { func (c *RawConn) SetWriteDeadline(t time.Time) error {
if !c.packetHandler.ok() { if !c.packetHandler.ok() {
return syscall.EINVAL return errInvalidConn
} }
return c.packetHandler.IPConn.SetWriteDeadline(t) return c.packetHandler.IPConn.SetWriteDeadline(t)
} }
@ -159,7 +158,7 @@ func (c *RawConn) SetWriteDeadline(t time.Time) error {
// Close closes the endpoint. // Close closes the endpoint.
func (c *RawConn) Close() error { func (c *RawConn) Close() error {
if !c.packetHandler.ok() { if !c.packetHandler.ok() {
return syscall.EINVAL return errInvalidConn
} }
return c.packetHandler.IPConn.Close() return c.packetHandler.IPConn.Close()
} }
@ -178,7 +177,7 @@ func NewRawConn(c net.PacketConn) (*RawConn, error) {
} }
so, ok := sockOpts[ssoHeaderPrepend] so, ok := sockOpts[ssoHeaderPrepend]
if !ok { if !ok {
return nil, errOpNoSupport return nil, errNotImplemented
} }
if err := so.SetInt(r.dgramOpt.Conn, boolint(true)); err != nil { if err := so.SetInt(r.dgramOpt.Conn, boolint(true)); err != nil {
return nil, err return nil, err

View File

@ -4,16 +4,14 @@
package ipv4 package ipv4
import "syscall"
// TOS returns the type-of-service field value for outgoing packets. // TOS returns the type-of-service field value for outgoing packets.
func (c *genericOpt) TOS() (int, error) { func (c *genericOpt) TOS() (int, error) {
if !c.ok() { if !c.ok() {
return 0, syscall.EINVAL return 0, errInvalidConn
} }
so, ok := sockOpts[ssoTOS] so, ok := sockOpts[ssoTOS]
if !ok { if !ok {
return 0, errOpNoSupport return 0, errNotImplemented
} }
return so.GetInt(c.Conn) return so.GetInt(c.Conn)
} }
@ -22,11 +20,11 @@ func (c *genericOpt) TOS() (int, error) {
// packets. // packets.
func (c *genericOpt) SetTOS(tos int) error { func (c *genericOpt) SetTOS(tos int) error {
if !c.ok() { if !c.ok() {
return syscall.EINVAL return errInvalidConn
} }
so, ok := sockOpts[ssoTOS] so, ok := sockOpts[ssoTOS]
if !ok { if !ok {
return errOpNoSupport return errNotImplemented
} }
return so.SetInt(c.Conn, tos) return so.SetInt(c.Conn, tos)
} }
@ -34,11 +32,11 @@ func (c *genericOpt) SetTOS(tos int) error {
// TTL returns the time-to-live field value for outgoing packets. // TTL returns the time-to-live field value for outgoing packets.
func (c *genericOpt) TTL() (int, error) { func (c *genericOpt) TTL() (int, error) {
if !c.ok() { if !c.ok() {
return 0, syscall.EINVAL return 0, errInvalidConn
} }
so, ok := sockOpts[ssoTTL] so, ok := sockOpts[ssoTTL]
if !ok { if !ok {
return 0, errOpNoSupport return 0, errNotImplemented
} }
return so.GetInt(c.Conn) return so.GetInt(c.Conn)
} }
@ -47,11 +45,11 @@ func (c *genericOpt) TTL() (int, error) {
// packets. // packets.
func (c *genericOpt) SetTTL(ttl int) error { func (c *genericOpt) SetTTL(ttl int) error {
if !c.ok() { if !c.ok() {
return syscall.EINVAL return errInvalidConn
} }
so, ok := sockOpts[ssoTTL] so, ok := sockOpts[ssoTTL]
if !ok { if !ok {
return errOpNoSupport return errNotImplemented
} }
return so.SetInt(c.Conn, ttl) return so.SetInt(c.Conn, ttl)
} }

View File

@ -9,7 +9,6 @@ import (
"fmt" "fmt"
"net" "net"
"runtime" "runtime"
"syscall"
"golang.org/x/net/internal/socket" "golang.org/x/net/internal/socket"
) )
@ -52,9 +51,13 @@ func (h *Header) String() string {
} }
// Marshal returns the binary encoding of h. // Marshal returns the binary encoding of h.
//
// The returned slice is in the format used by a raw IP socket on the
// local system.
// This may differ from the wire format, depending on the system.
func (h *Header) Marshal() ([]byte, error) { func (h *Header) Marshal() ([]byte, error) {
if h == nil { if h == nil {
return nil, syscall.EINVAL return nil, errNilHeader
} }
if h.Len < HeaderLen { if h.Len < HeaderLen {
return nil, errHeaderTooShort return nil, errHeaderTooShort
@ -99,13 +102,20 @@ func (h *Header) Marshal() ([]byte, error) {
} }
// Parse parses b as an IPv4 header and stores the result in h. // Parse parses b as an IPv4 header and stores the result in h.
//
// The provided b must be in the format used by a raw IP socket on the
// local system.
// This may differ from the wire format, depending on the system.
func (h *Header) Parse(b []byte) error { func (h *Header) Parse(b []byte) error {
if h == nil || len(b) < HeaderLen { if h == nil || b == nil {
return errNilHeader
}
if len(b) < HeaderLen {
return errHeaderTooShort return errHeaderTooShort
} }
hdrlen := int(b[0]&0x0f) << 2 hdrlen := int(b[0]&0x0f) << 2
if hdrlen > len(b) { if len(b) < hdrlen {
return errBufferTooShort return errExtHeaderTooShort
} }
h.Version = int(b[0] >> 4) h.Version = int(b[0] >> 4)
h.Len = hdrlen h.Len = hdrlen
@ -150,6 +160,10 @@ func (h *Header) Parse(b []byte) error {
} }
// ParseHeader parses b as an IPv4 header. // ParseHeader parses b as an IPv4 header.
//
// The provided b must be in the format used by a raw IP socket on the
// local system.
// This may differ from the wire format, depending on the system.
func ParseHeader(b []byte) (*Header, error) { func ParseHeader(b []byte) (*Header, error) {
h := new(Header) h := new(Header)
if err := h.Parse(b); err != nil { if err := h.Parse(b); err != nil {

View File

@ -7,22 +7,39 @@ package ipv4
import ( import (
"errors" "errors"
"net" "net"
"runtime"
"golang.org/x/net/internal/socket"
) )
var ( var (
errInvalidConn = errors.New("invalid connection")
errMissingAddress = errors.New("missing address") errMissingAddress = errors.New("missing address")
errMissingHeader = errors.New("missing header") errMissingHeader = errors.New("missing header")
errNilHeader = errors.New("nil header")
errHeaderTooShort = errors.New("header too short") errHeaderTooShort = errors.New("header too short")
errBufferTooShort = errors.New("buffer too short") errExtHeaderTooShort = errors.New("extension header too short")
errInvalidConnType = errors.New("invalid conn type") errInvalidConnType = errors.New("invalid conn type")
errOpNoSupport = errors.New("operation not supported")
errNoSuchInterface = errors.New("no such interface") errNoSuchInterface = errors.New("no such interface")
errNoSuchMulticastInterface = errors.New("no such multicast interface") errNoSuchMulticastInterface = errors.New("no such multicast interface")
errNotImplemented = errors.New("not implemented on " + runtime.GOOS + "/" + runtime.GOARCH)
// See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html. // See https://www.freebsd.org/doc/en/books/porters-handbook/versions.html.
freebsdVersion uint32 freebsdVersion uint32
compatFreeBSD32 bool // 386 emulation on amd64
) )
// See golang.org/issue/30899.
func adjustFreeBSD32(m *socket.Message) {
// FreeBSD 12.0-RELEASE is affected by https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236737
if 1200086 <= freebsdVersion && freebsdVersion < 1201000 {
l := (m.NN + 4 - 1) &^ (4 - 1)
if m.NN < l && l <= len(m.OOB) {
m.NN = l
}
}
}
func boolint(b bool) int { func boolint(b bool) int {
if b { if b {
return 1 return 1

View File

@ -6,7 +6,6 @@ package ipv4
import ( import (
"net" "net"
"syscall"
"golang.org/x/net/internal/socket" "golang.org/x/net/internal/socket"
) )
@ -28,9 +27,37 @@ func (c *packetHandler) ok() bool { return c != nil && c.IPConn != nil && c.Conn
// header h, the payload p and the control message cm. // header h, the payload p and the control message cm.
func (c *packetHandler) ReadFrom(b []byte) (h *Header, p []byte, cm *ControlMessage, err error) { func (c *packetHandler) ReadFrom(b []byte) (h *Header, p []byte, cm *ControlMessage, err error) {
if !c.ok() { if !c.ok() {
return nil, nil, nil, syscall.EINVAL return nil, nil, nil, errInvalidConn
} }
return c.readFrom(b) c.rawOpt.RLock()
m := socket.Message{
Buffers: [][]byte{b},
OOB: NewControlMessage(c.rawOpt.cflags),
}
c.rawOpt.RUnlock()
if err := c.RecvMsg(&m, 0); err != nil {
return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
}
var hs []byte
if hs, p, err = slicePacket(b[:m.N]); err != nil {
return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
}
if h, err = ParseHeader(hs); err != nil {
return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
}
if m.NN > 0 {
if compatFreeBSD32 {
adjustFreeBSD32(&m)
}
cm = new(ControlMessage)
if err := cm.Parse(m.OOB[:m.NN]); err != nil {
return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
}
}
if src, ok := m.Addr.(*net.IPAddr); ok && cm != nil {
cm.Src = src.IP
}
return
} }
func slicePacket(b []byte) (h, p []byte, err error) { func slicePacket(b []byte) (h, p []byte, err error) {
@ -63,7 +90,28 @@ func slicePacket(b []byte) (h, p []byte, err error) {
// Options = optional // Options = optional
func (c *packetHandler) WriteTo(h *Header, p []byte, cm *ControlMessage) error { func (c *packetHandler) WriteTo(h *Header, p []byte, cm *ControlMessage) error {
if !c.ok() { if !c.ok() {
return syscall.EINVAL return errInvalidConn
} }
return c.writeTo(h, p, cm) m := socket.Message{
OOB: cm.Marshal(),
}
wh, err := h.Marshal()
if err != nil {
return err
}
m.Buffers = [][]byte{wh, p}
dst := new(net.IPAddr)
if cm != nil {
if ip := cm.Dst.To4(); ip != nil {
dst.IP = ip
}
}
if dst.IP == nil {
dst.IP = h.Dst
}
m.Addr = dst
if err := c.SendMsg(&m, 0); err != nil {
return &net.OpError{Op: "write", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Addr: opAddr(dst), Err: err}
}
return nil
} }

View File

@ -1,56 +0,0 @@
// Copyright 2012 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.9
package ipv4
import "net"
func (c *packetHandler) readFrom(b []byte) (h *Header, p []byte, cm *ControlMessage, err error) {
c.rawOpt.RLock()
oob := NewControlMessage(c.rawOpt.cflags)
c.rawOpt.RUnlock()
n, nn, _, src, err := c.ReadMsgIP(b, oob)
if err != nil {
return nil, nil, nil, err
}
var hs []byte
if hs, p, err = slicePacket(b[:n]); err != nil {
return nil, nil, nil, err
}
if h, err = ParseHeader(hs); err != nil {
return nil, nil, nil, err
}
if nn > 0 {
cm = new(ControlMessage)
if err := cm.Parse(oob[:nn]); err != nil {
return nil, nil, nil, err
}
}
if src != nil && cm != nil {
cm.Src = src.IP
}
return
}
func (c *packetHandler) writeTo(h *Header, p []byte, cm *ControlMessage) error {
oob := cm.Marshal()
wh, err := h.Marshal()
if err != nil {
return err
}
dst := new(net.IPAddr)
if cm != nil {
if ip := cm.Dst.To4(); ip != nil {
dst.IP = ip
}
}
if dst.IP == nil {
dst.IP = h.Dst
}
wh = append(wh, p...)
_, _, err = c.WriteMsgIP(wh, oob, dst)
return err
}

View File

@ -1,67 +0,0 @@
// Copyright 2017 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.9
package ipv4
import (
"net"
"golang.org/x/net/internal/socket"
)
func (c *packetHandler) readFrom(b []byte) (h *Header, p []byte, cm *ControlMessage, err error) {
c.rawOpt.RLock()
m := socket.Message{
Buffers: [][]byte{b},
OOB: NewControlMessage(c.rawOpt.cflags),
}
c.rawOpt.RUnlock()
if err := c.RecvMsg(&m, 0); err != nil {
return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
}
var hs []byte
if hs, p, err = slicePacket(b[:m.N]); err != nil {
return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
}
if h, err = ParseHeader(hs); err != nil {
return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
}
if m.NN > 0 {
cm = new(ControlMessage)
if err := cm.Parse(m.OOB[:m.NN]); err != nil {
return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
}
}
if src, ok := m.Addr.(*net.IPAddr); ok && cm != nil {
cm.Src = src.IP
}
return
}
func (c *packetHandler) writeTo(h *Header, p []byte, cm *ControlMessage) error {
m := socket.Message{
OOB: cm.Marshal(),
}
wh, err := h.Marshal()
if err != nil {
return err
}
m.Buffers = [][]byte{wh, p}
dst := new(net.IPAddr)
if cm != nil {
if ip := cm.Dst.To4(); ip != nil {
dst.IP = ip
}
}
if dst.IP == nil {
dst.IP = h.Dst
}
m.Addr = dst
if err := c.SendMsg(&m, 0); err != nil {
return &net.OpError{Op: "write", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Addr: opAddr(dst), Err: err}
}
return nil
}

View File

@ -2,13 +2,14 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build !nacl,!plan9,!windows // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package ipv4 package ipv4
import ( import (
"net" "net"
"syscall"
"golang.org/x/net/internal/socket"
) )
// ReadFrom reads a payload of the received IPv4 datagram, from the // ReadFrom reads a payload of the received IPv4 datagram, from the
@ -17,9 +18,47 @@ import (
// src of the received datagram. // src of the received datagram.
func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) { func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {
if !c.ok() { if !c.ok() {
return 0, nil, nil, syscall.EINVAL return 0, nil, nil, errInvalidConn
} }
return c.readFrom(b) c.rawOpt.RLock()
m := socket.Message{
OOB: NewControlMessage(c.rawOpt.cflags),
}
c.rawOpt.RUnlock()
switch c.PacketConn.(type) {
case *net.UDPConn:
m.Buffers = [][]byte{b}
if err := c.RecvMsg(&m, 0); err != nil {
return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
}
case *net.IPConn:
h := make([]byte, HeaderLen)
m.Buffers = [][]byte{h, b}
if err := c.RecvMsg(&m, 0); err != nil {
return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
}
hdrlen := int(h[0]&0x0f) << 2
if hdrlen > len(h) {
d := hdrlen - len(h)
copy(b, b[d:])
m.N -= d
} else {
m.N -= hdrlen
}
default:
return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: errInvalidConnType}
}
if m.NN > 0 {
if compatFreeBSD32 {
adjustFreeBSD32(&m)
}
cm = new(ControlMessage)
if err := cm.Parse(m.OOB[:m.NN]); err != nil {
return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
}
cm.Src = netAddrToIP4(m.Addr)
}
return m.N, cm, m.Addr, nil
} }
// WriteTo writes a payload of the IPv4 datagram, to the destination // WriteTo writes a payload of the IPv4 datagram, to the destination
@ -30,7 +69,16 @@ func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.
// control of the outgoing datagram is not required. // control of the outgoing datagram is not required.
func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) { func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {
if !c.ok() { if !c.ok() {
return 0, syscall.EINVAL return 0, errInvalidConn
} }
return c.writeTo(b, cm, dst) m := socket.Message{
Buffers: [][]byte{b},
OOB: cm.Marshal(),
Addr: dst,
}
err = c.SendMsg(&m, 0)
if err != nil {
err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Addr: opAddr(dst), Err: err}
}
return m.N, err
} }

View File

@ -1,59 +0,0 @@
// Copyright 2012 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.9
// +build !nacl,!plan9,!windows
package ipv4
import "net"
func (c *payloadHandler) readFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {
c.rawOpt.RLock()
oob := NewControlMessage(c.rawOpt.cflags)
c.rawOpt.RUnlock()
var nn int
switch c := c.PacketConn.(type) {
case *net.UDPConn:
if n, nn, _, src, err = c.ReadMsgUDP(b, oob); err != nil {
return 0, nil, nil, err
}
case *net.IPConn:
nb := make([]byte, maxHeaderLen+len(b))
if n, nn, _, src, err = c.ReadMsgIP(nb, oob); err != nil {
return 0, nil, nil, err
}
hdrlen := int(nb[0]&0x0f) << 2
copy(b, nb[hdrlen:])
n -= hdrlen
default:
return 0, nil, nil, &net.OpError{Op: "read", Net: c.LocalAddr().Network(), Source: c.LocalAddr(), Err: errInvalidConnType}
}
if nn > 0 {
cm = new(ControlMessage)
if err = cm.Parse(oob[:nn]); err != nil {
return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
}
}
if cm != nil {
cm.Src = netAddrToIP4(src)
}
return
}
func (c *payloadHandler) writeTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {
oob := cm.Marshal()
if dst == nil {
return 0, &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: 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, &net.OpError{Op: "write", Net: c.LocalAddr().Network(), Source: c.LocalAddr(), Addr: opAddr(dst), Err: errInvalidConnType}
}
return
}

View File

@ -1,67 +0,0 @@
// Copyright 2017 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.9
// +build !nacl,!plan9,!windows
package ipv4
import (
"net"
"golang.org/x/net/internal/socket"
)
func (c *payloadHandler) readFrom(b []byte) (int, *ControlMessage, net.Addr, error) {
c.rawOpt.RLock()
m := socket.Message{
OOB: NewControlMessage(c.rawOpt.cflags),
}
c.rawOpt.RUnlock()
switch c.PacketConn.(type) {
case *net.UDPConn:
m.Buffers = [][]byte{b}
if err := c.RecvMsg(&m, 0); err != nil {
return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
}
case *net.IPConn:
h := make([]byte, HeaderLen)
m.Buffers = [][]byte{h, b}
if err := c.RecvMsg(&m, 0); err != nil {
return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
}
hdrlen := int(h[0]&0x0f) << 2
if hdrlen > len(h) {
d := hdrlen - len(h)
copy(b, b[d:])
m.N -= d
} else {
m.N -= hdrlen
}
default:
return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: errInvalidConnType}
}
var cm *ControlMessage
if m.NN > 0 {
cm = new(ControlMessage)
if err := cm.Parse(m.OOB[:m.NN]); err != nil {
return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
}
cm.Src = netAddrToIP4(m.Addr)
}
return m.N, cm, m.Addr, nil
}
func (c *payloadHandler) writeTo(b []byte, cm *ControlMessage, dst net.Addr) (int, error) {
m := socket.Message{
Buffers: [][]byte{b},
OOB: cm.Marshal(),
Addr: dst,
}
err := c.SendMsg(&m, 0)
if err != nil {
err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Addr: opAddr(dst), Err: err}
}
return m.N, err
}

View File

@ -2,14 +2,11 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build nacl plan9 windows // +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
package ipv4 package ipv4
import ( import "net"
"net"
"syscall"
)
// ReadFrom reads a payload of the received IPv4 datagram, from the // ReadFrom reads a payload of the received IPv4 datagram, from the
// endpoint c, copying the payload into b. It returns the number of // endpoint c, copying the payload into b. It returns the number of
@ -17,7 +14,7 @@ import (
// src of the received datagram. // src of the received datagram.
func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) { func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {
if !c.ok() { if !c.ok() {
return 0, nil, nil, syscall.EINVAL return 0, nil, nil, errInvalidConn
} }
if n, src, err = c.PacketConn.ReadFrom(b); err != nil { if n, src, err = c.PacketConn.ReadFrom(b); err != nil {
return 0, nil, nil, err return 0, nil, nil, err
@ -33,7 +30,7 @@ func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.
// control of the outgoing datagram is not required. // control of the outgoing datagram is not required.
func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) { func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {
if !c.ok() { if !c.ok() {
return 0, syscall.EINVAL return 0, errInvalidConn
} }
if dst == nil { if dst == nil {
return 0, errMissingAddress return 0, errMissingAddress

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
package ipv4 package ipv4
@ -39,7 +39,7 @@ func (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) {
return nil, err return nil, err
} }
if n != sizeofICMPFilter { if n != sizeofICMPFilter {
return nil, errOpNoSupport return nil, errNotImplemented
} }
return (*ICMPFilter)(unsafe.Pointer(&b[0])), nil return (*ICMPFilter)(unsafe.Pointer(&b[0])), nil
} }
@ -58,7 +58,7 @@ func (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) erro
case ssoTypeGroupReq: case ssoTypeGroupReq:
return so.setGroupReq(c, ifi, grp) return so.setGroupReq(c, ifi, grp)
default: default:
return errOpNoSupport return errNotImplemented
} }
} }

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows // +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
package ipv4 package ipv4
@ -14,29 +14,29 @@ import (
) )
func (so *sockOpt) getMulticastInterface(c *socket.Conn) (*net.Interface, error) { func (so *sockOpt) getMulticastInterface(c *socket.Conn) (*net.Interface, error) {
return nil, errOpNoSupport return nil, errNotImplemented
} }
func (so *sockOpt) setMulticastInterface(c *socket.Conn, ifi *net.Interface) error { func (so *sockOpt) setMulticastInterface(c *socket.Conn, ifi *net.Interface) error {
return errOpNoSupport return errNotImplemented
} }
func (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) { func (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) {
return nil, errOpNoSupport return nil, errNotImplemented
} }
func (so *sockOpt) setICMPFilter(c *socket.Conn, f *ICMPFilter) error { func (so *sockOpt) setICMPFilter(c *socket.Conn, f *ICMPFilter) error {
return errOpNoSupport return errNotImplemented
} }
func (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) error { func (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
return errOpNoSupport return errNotImplemented
} }
func (so *sockOpt) setSourceGroup(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error { func (so *sockOpt) setSourceGroup(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {
return errOpNoSupport return errNotImplemented
} }
func (so *sockOpt) setBPF(c *socket.Conn, f []bpf.RawInstruction) error { func (so *sockOpt) setBPF(c *socket.Conn, f []bpf.RawInstruction) error {
return errOpNoSupport return errNotImplemented
} }

38
vendor/golang.org/x/net/ipv4/sys_aix.go generated vendored Normal file
View File

@ -0,0 +1,38 @@
// Copyright 2019 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.
// Added for go1.11 compatibility
// +build aix
package ipv4
import (
"net"
"syscall"
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/socket"
)
var (
ctlOpts = [ctlMax]ctlOpt{
ctlTTL: {sysIP_RECVTTL, 1, marshalTTL, parseTTL},
ctlDst: {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
}
sockOpts = map[int]*sockOpt{
ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 1}},
ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: 4}},
ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 1}},
ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}},
ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVDSTADDR, Len: 4}},
ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVIF, Len: 4}},
ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
}
)

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd netbsd openbsd solaris windows // +build aix darwin dragonfly freebsd netbsd openbsd solaris windows
package ipv4 package ipv4

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build !darwin,!dragonfly,!freebsd,!netbsd,!openbsd,!solaris,!windows // +build !aix,!darwin,!dragonfly,!freebsd,!netbsd,!openbsd,!solaris,!windows
package ipv4 package ipv4
@ -13,13 +13,13 @@ import (
) )
func (so *sockOpt) setIPMreq(c *socket.Conn, ifi *net.Interface, grp net.IP) error { func (so *sockOpt) setIPMreq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
return errOpNoSupport return errNotImplemented
} }
func (so *sockOpt) getMulticastIf(c *socket.Conn) (*net.Interface, error) { func (so *sockOpt) getMulticastIf(c *socket.Conn) (*net.Interface, error) {
return nil, errOpNoSupport return nil, errNotImplemented
} }
func (so *sockOpt) setMulticastIf(c *socket.Conn, ifi *net.Interface) error { func (so *sockOpt) setMulticastIf(c *socket.Conn, ifi *net.Interface) error {
return errOpNoSupport return errNotImplemented
} }

View File

@ -13,9 +13,9 @@ import (
) )
func (so *sockOpt) getIPMreqn(c *socket.Conn) (*net.Interface, error) { func (so *sockOpt) getIPMreqn(c *socket.Conn) (*net.Interface, error) {
return nil, errOpNoSupport return nil, errNotImplemented
} }
func (so *sockOpt) setIPMreqn(c *socket.Conn, ifi *net.Interface, grp net.IP) error { func (so *sockOpt) setIPMreqn(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
return errOpNoSupport return errNotImplemented
} }

View File

@ -12,5 +12,5 @@ import (
) )
func (so *sockOpt) setAttachFilter(c *socket.Conn, f []bpf.RawInstruction) error { func (so *sockOpt) setAttachFilter(c *socket.Conn, f []bpf.RawInstruction) error {
return errOpNoSupport return errNotImplemented
} }

View File

@ -6,8 +6,6 @@ package ipv4
import ( import (
"net" "net"
"strconv"
"strings"
"syscall" "syscall"
"unsafe" "unsafe"
@ -17,59 +15,33 @@ import (
var ( var (
ctlOpts = [ctlMax]ctlOpt{ ctlOpts = [ctlMax]ctlOpt{
ctlTTL: {sysIP_RECVTTL, 1, marshalTTL, parseTTL}, ctlTTL: {sysIP_RECVTTL, 1, marshalTTL, parseTTL},
ctlDst: {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst}, ctlDst: {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface}, ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
ctlPacketInfo: {sysIP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},
} }
sockOpts = map[int]*sockOpt{ sockOpts = map[int]*sockOpt{
ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}}, ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}}, ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 1}}, ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 1}},
ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: 4}}, ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: sizeofIPMreqn}, typ: ssoTypeIPMreqn},
ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 4}}, ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 4}},
ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}}, ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}},
ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVDSTADDR, Len: 4}}, ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVDSTADDR, Len: 4}},
ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVIF, Len: 4}}, ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVIF, Len: 4}},
ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}}, ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
ssoStripHeader: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_STRIPHDR, Len: 4}}, ssoStripHeader: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_STRIPHDR, Len: 4}},
ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq}, ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq}, ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
ssoPacketInfo: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVPKTINFO, Len: 4}},
} }
) )
func init() {
// Seems like kern.osreldate is veiled on latest OS X. We use
// kern.osrelease instead.
s, err := syscall.Sysctl("kern.osrelease")
if err != nil {
return
}
ss := strings.Split(s, ".")
if len(ss) == 0 {
return
}
// The IP_PKTINFO and protocol-independent multicast API were
// introduced in OS X 10.7 (Darwin 11). But it looks like
// those features require OS X 10.8 (Darwin 12) or above.
// See http://support.apple.com/kb/HT1633.
if mjver, err := strconv.Atoi(ss[0]); err != nil || mjver < 12 {
return
}
ctlOpts[ctlPacketInfo].name = sysIP_PKTINFO
ctlOpts[ctlPacketInfo].length = sizeofInetPktinfo
ctlOpts[ctlPacketInfo].marshal = marshalPacketInfo
ctlOpts[ctlPacketInfo].parse = parsePacketInfo
sockOpts[ssoPacketInfo] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVPKTINFO, Len: 4}}
sockOpts[ssoMulticastInterface] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: sizeofIPMreqn}, typ: ssoTypeIPMreqn}
sockOpts[ssoJoinGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}
sockOpts[ssoLeaveGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}
sockOpts[ssoJoinSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}
sockOpts[ssoLeaveSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}
sockOpts[ssoBlockSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}
sockOpts[ssoUnblockSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}
}
func (pi *inetPktinfo) setIfindex(i int) { func (pi *inetPktinfo) setIfindex(i int) {
pi.Ifindex = uint32(i) pi.Ifindex = uint32(i)
} }

View File

@ -50,7 +50,7 @@ func init() {
archs, _ := syscall.Sysctl("kern.supported_archs") archs, _ := syscall.Sysctl("kern.supported_archs")
for _, s := range strings.Fields(archs) { for _, s := range strings.Fields(archs) {
if s == "amd64" { if s == "amd64" {
freebsd32o64 = true compatFreeBSD32 = true
break break
} }
} }

Some files were not shown because too many files have changed in this diff Show More