Add libvirt

Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com>
This commit is contained in:
Darko Draskovic
2023-03-14 16:04:49 +01:00
parent b7a1fbb2fa
commit 278331dc81
145 changed files with 32387 additions and 2623 deletions
+60 -20
View File
@@ -12,21 +12,25 @@ import (
"io"
"io/ioutil"
"log"
"net"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/mainflux/mainflux"
"github.com/mainflux/mainflux/logger"
"github.com/ultravioletrs/cocosvm/agent"
"github.com/ultravioletrs/cocosvm/agent/api"
agenthttpapi "github.com/ultravioletrs/cocosvm/agent/api/agent/http"
"github.com/ultravioletrs/cocosvm/manager"
"github.com/ultravioletrs/cocosvm/manager/api"
managerhttpapi "github.com/ultravioletrs/cocosvm/manager/api/manager/http"
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
opentracing "github.com/opentracing/opentracing-go"
stdprometheus "github.com/prometheus/client_golang/prometheus"
jconfig "github.com/uber/jaeger-client-go/config"
"github.com/digitalocean/go-libvirt"
)
const (
@@ -37,11 +41,11 @@ const (
defServerKey = ""
defSecret = "secret"
envLogLevel = "CC_AGENT_LOG_LEVEL"
envHTTPPort = "CC_AGENT_HTTP_PORT"
envServerCert = "CC_AGENT_SERVER_CERT"
envServerKey = "CC_AGENT_SERVER_KEY"
envSecret = "CC_AGENT_SECRET"
envLogLevel = "CC_MANAGER_LOG_LEVEL"
envHTTPPort = "CC_MANAGER_HTTP_PORT"
envServerCert = "CC_MANAGER_SERVER_CERT"
envServerKey = "CC_MANAGER_SERVER_KEY"
envSecret = "CC_MANAGER_SECRET"
envJaegerURL = "CC_JAEGER_URL"
)
@@ -64,13 +68,16 @@ func main() {
log.Fatalf(err.Error())
}
agentTracer, agentCloser := initJaeger("agent", cfg.jaegerURL, logger)
defer agentCloser.Close()
managerTracer, managerCloser := initJaeger("manager", cfg.jaegerURL, logger)
defer managerCloser.Close()
libvirtConn := initLibvirt(logger)
defer libvirtConn.Disconnect()
svc := newService(cfg.secret, libvirtConn, logger)
svc := newService(cfg.secret, logger)
errs := make(chan error, 2)
go startHTTPServer(agenthttpapi.MakeHandler(agentTracer, svc), cfg.httpPort, cfg, logger, errs)
go startHTTPServer(managerhttpapi.MakeHandler(managerTracer, svc), cfg.httpPort, cfg, logger, errs)
go func() {
c := make(chan os.Signal)
@@ -79,7 +86,7 @@ func main() {
}()
err = <-errs
logger.Error(fmt.Sprintf("Agent service terminated: %s", err))
logger.Error(fmt.Sprintf("Manager service terminated: %s", err))
}
func loadConfig() config {
@@ -117,20 +124,20 @@ func initJaeger(svcName, url string, logger logger.Logger) (opentracing.Tracer,
return tracer, closer
}
func newService(secret string, logger logger.Logger) agent.Service {
svc := agent.New(secret)
func newService(secret string, libvirtConn *libvirt.Libvirt, logger logger.Logger) manager.Service {
svc := manager.New(secret, libvirtConn)
svc = api.LoggingMiddleware(svc, logger)
svc = api.MetricsMiddleware(
svc,
kitprometheus.NewCounterFrom(stdprometheus.CounterOpts{
Namespace: "agent",
Namespace: "manager",
Subsystem: "api",
Name: "request_count",
Help: "Number of requests received.",
}, []string{"method"}),
kitprometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
Namespace: "agent",
Namespace: "manager",
Subsystem: "api",
Name: "request_latency_microseconds",
Help: "Total duration of requests in microseconds.",
@@ -143,11 +150,44 @@ func newService(secret string, logger logger.Logger) agent.Service {
func startHTTPServer(handler http.Handler, port string, cfg config, logger logger.Logger, errs chan error) {
p := fmt.Sprintf(":%s", port)
if cfg.serverCert != "" || cfg.serverKey != "" {
logger.Info(fmt.Sprintf("Agent service started using https on port %s with cert %s key %s",
logger.Info(fmt.Sprintf("Manager service started using https on port %s with cert %s key %s",
port, cfg.serverCert, cfg.serverKey))
errs <- http.ListenAndServeTLS(p, cfg.serverCert, cfg.serverKey, handler)
return
}
logger.Info(fmt.Sprintf("Agent service started using http on port %s", cfg.httpPort))
logger.Info(fmt.Sprintf("Manager service started using http on port %s", cfg.httpPort))
errs <- http.ListenAndServe(p, handler)
}
func initLibvirt(logger logger.Logger) *libvirt.Libvirt {
// This dials libvirt on the local machine, but you can substitute the first
// two parameters with "tcp", "<ip address>:<port>" to connect to libvirt on
// a remote machine.
c, err := net.DialTimeout("unix", "/var/run/libvirt/libvirt-sock", 2*time.Second)
if err != nil {
log.Fatalf("failed to dial libvirt: %v", err)
}
l := libvirt.New(c)
if err := l.Connect(); err != nil {
log.Fatalf("failed to connect: %v", err)
}
v, err := l.Version()
if err != nil {
logger.Error(fmt.Sprintf("failed to retrieve libvirt version: %v", err))
}
fmt.Println("Version:", v)
domains, err := l.Domains()
if err != nil {
logger.Error(fmt.Sprintf("failed to retrieve domains: %v", err))
}
fmt.Println("ID\tName\t\tUUID")
fmt.Printf("--------------------------------------------------------\n")
for _, d := range domains {
fmt.Printf("%d\t%s\t%x\n", d.ID, d.Name, d.UUID)
}
return l
}
+6 -6
View File
@@ -1,9 +1,9 @@
# Docker: Environment variables in Compose
## Agent
CC_AGENT_LOG_LEVEL=debug
CC_AGENT_HTTP_PORT=9021
CC_AGENT_SECRET=secret
CC_AGENT_SERVER_CERT=""
CC_AGENT_SERVER_KEY=""
## Manager
CC_MANAGER_LOG_LEVEL=debug
CC_MANAGER_HTTP_PORT=9021
CC_MANAGER_SECRET=secret
CC_MANAGER_SERVER_CERT=""
CC_MANAGER_SERVER_KEY=""
CC_JAEGER_URL="jaeger:6831"
+3 -3
View File
@@ -1,10 +1,10 @@
FROM golang:1.16-alpine AS builder
WORKDIR /go/src/github.com/mainflux/agent
WORKDIR /go/src/github.com/mainflux/manager
COPY . .
RUN CGO_ENABLED=0 GOARCH=amd64 \
go build -mod=vendor -ldflags "-s -w" -o build/mainflux-agent cmd/agent/main.go \
&& mv build/mainflux-agent /exe
go build -mod=vendor -ldflags "-s -w" -o build/mainflux-manager cmd/manager/main.go \
&& mv build/mainflux-manager /exe
FROM scratch
COPY --from=builder /exe /
+9 -9
View File
@@ -13,18 +13,18 @@ networks:
external: true
services:
agent:
image: mainflux/agent:latest
container_name: mainflux-agent
manager:
image: mainflux/manager:latest
container_name: mainflux-manager
restart: on-failure
environment:
CC_AGENT_LOG_LEVEL: ${CC_AGENT_LOG_LEVEL}
CC_AGENT_HTTP_PORT: ${CC_AGENT_HTTP_PORT}
CC_AGENT_SERVER_CERT: ${CC_AGENT_SERVER_CERT}
CC_AGENT_SERVER_KEY: ${CC_AGENT_SERVER_KEY}
CC_MANAGER_LOG_LEVEL: ${CC_MANAGER_LOG_LEVEL}
CC_MANAGER_HTTP_PORT: ${CC_MANAGER_HTTP_PORT}
CC_MANAGER_SERVER_CERT: ${CC_MANAGER_SERVER_CERT}
CC_MANAGER_SERVER_KEY: ${CC_MANAGER_SERVER_KEY}
CC_JAEGER_URL: ${CC_JAEGER_URL}
CC_AGENT_SECRET: ${CC_AGENT_SECRET}
CC_MANAGER_SECRET: ${CC_MANAGER_SECRET}
ports:
- ${CC_AGENT_HTTP_PORT}:${CC_AGENT_HTTP_PORT}
- ${CC_MANAGER_HTTP_PORT}:${CC_MANAGER_HTTP_PORT}
networks:
- docker_mainflux-base-net
+3 -2
View File
@@ -3,6 +3,7 @@ module github.com/ultravioletrs/cocosvm
go 1.19
require (
github.com/digitalocean/go-libvirt v0.0.0-20221205150000-2939327a8519
github.com/go-kit/kit v0.12.0
github.com/go-zoo/bone v1.3.0
github.com/mainflux/mainflux v0.12.0
@@ -25,8 +26,8 @@ require (
github.com/subosito/gotenv v1.2.0 // indirect
github.com/uber/jaeger-lib v2.0.0+incompatible // indirect
go.uber.org/atomic v1.9.0 // indirect
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4 // indirect
google.golang.org/grpc v1.40.0 // indirect
+21 -5
View File
@@ -128,6 +128,8 @@ github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0/go.mod h1:xb
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/digitalocean/go-libvirt v0.0.0-20221205150000-2939327a8519 h1:OpkN/n40cmKenDQS+IOAeW9DLhYy4DADSeZnouCEV/E=
github.com/digitalocean/go-libvirt v0.0.0-20221205150000-2939327a8519/go.mod h1:WyJJyfmJ0gWJvjV+ZH4DOgtOYZc1KOvYyBXWCLKxsUU=
github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
@@ -663,16 +665,21 @@ github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
@@ -708,6 +715,7 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
@@ -756,6 +764,7 @@ golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -792,6 +801,7 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -830,11 +840,13 @@ golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -853,6 +865,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -916,8 +929,9 @@ golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -996,6 +1010,7 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1146,8 +1161,9 @@ gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+17 -17
View File
@@ -1,6 +1,6 @@
# Agent
# Manager
Agent service provides a barebones HTTP API and Service interface implementation for development of a core Mainflux service.
Manager service provides a barebones HTTP API and Service interface implementation for development of a core Mainflux service.
## Configuration
@@ -8,12 +8,12 @@ The service is configured using the environment variables from the following tab
| Variable | Description | Default |
|-----------------------|---------------------------------------------------------|---------|
| CC_AGENT_LOG_LEVEL | Log level for agent service (debug, info, warn, error) | error |
| CC_AGENT_HTTP_PORT | Agent service HTTP port | 9021 |
| CC_AGENT_SERVER_CERT | Path to server certificate in pem format | |
| CC_AGENT_SERVER_KEY | Path to server key in pem format | |
| CC_MANAGER_LOG_LEVEL | Log level for manager service (debug, info, warn, error) | error |
| CC_MANAGER_HTTP_PORT | Manager service HTTP port | 9021 |
| CC_MANAGER_SERVER_CERT | Path to server certificate in pem format | |
| CC_MANAGER_SERVER_KEY | Path to server key in pem format | |
| CC_JAEGER_URL | Jaeger server URL | |
| CC_AGENT_SECRET | Agent service secret | secret |
| CC_MANAGER_SECRET | Manager service secret | secret |
## Deployment
@@ -22,17 +22,17 @@ The service is distributed as a Docker container. The following snippet provides
```yaml
version: "3"
services:
agent:
image: mainflux/agent:[version]
manager:
image: mainflux/manager:[version]
container_name: [instance name]
ports:
- [host machine port]:[configured HTTP port]
environment:
CC_AGENT_LOG_LEVEL: [Kit log level]
CC_AGENT_HTTP_PORT: [Service HTTP port]
CC_AGENT_SERVER_CERT: [String path to server cert in pem format]
CC_AGENT_SERVER_KEY: [String path to server key in pem format]
CC_AGENT_SECRET: [Agent service secret]
CC_MANAGER_LOG_LEVEL: [Kit log level]
CC_MANAGER_HTTP_PORT: [Service HTTP port]
CC_MANAGER_SERVER_CERT: [String path to server cert in pem format]
CC_MANAGER_SERVER_KEY: [String path to server key in pem format]
CC_MANAGER_SECRET: [Manager service secret]
CC_JAEGER_URL: [Jaeger server URL]
```
@@ -44,14 +44,14 @@ go get github.com/mainflux/mainflux
cd $GOPATH/src/github.com/mainflux/mainflux
# compile the agent
make agent
# compile the manager
make manager
# copy binary to bin
make install
# set the environment variables and run the service
CC_AGENT_LOG_LEVEL=[Kit log level] CC_AGENT_HTTP_PORT=[Service HTTP port] CC_AGENT_SERVER_CERT: [String path to server cert in pem format] CC_AGENT_SERVER_KEY: [String path to server key in pem format] CC_JAEGER_URL=[Jaeger server URL] CC_AGENT_SECRET: [Agent service secret] $GOBIN/mainflux-kit
CC_MANAGER_LOG_LEVEL=[Kit log level] CC_MANAGER_HTTP_PORT=[Service HTTP port] CC_MANAGER_SERVER_CERT: [String path to server cert in pem format] CC_MANAGER_SERVER_KEY: [String path to server key in pem format] CC_JAEGER_URL=[Jaeger server URL] CC_MANAGER_SECRET: [Manager service secret] $GOBIN/mainflux-kit
```
## Usage
@@ -11,18 +11,18 @@ import (
"time"
log "github.com/mainflux/mainflux/logger"
"github.com/ultravioletrs/cocosvm/agent"
"github.com/ultravioletrs/cocosvm/manager"
)
var _ agent.Service = (*loggingMiddleware)(nil)
var _ manager.Service = (*loggingMiddleware)(nil)
type loggingMiddleware struct {
logger log.Logger
svc agent.Service
svc manager.Service
}
// LoggingMiddleware adds logging facilities to the core service.
func LoggingMiddleware(svc agent.Service, logger log.Logger) agent.Service {
func LoggingMiddleware(svc manager.Service, logger log.Logger) manager.Service {
return &loggingMiddleware{logger, svc}
}
@@ -7,10 +7,10 @@ import (
"context"
"github.com/go-kit/kit/endpoint"
"github.com/ultravioletrs/cocosvm/agent"
"github.com/ultravioletrs/cocosvm/manager"
)
func pingEndpoint(svc agent.Service) endpoint.Endpoint {
func pingEndpoint(svc manager.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(pingReq)
@@ -3,7 +3,7 @@
package http
import "github.com/ultravioletrs/cocosvm/agent"
import "github.com/ultravioletrs/cocosvm/manager"
type apiReq interface {
validate() error
@@ -15,7 +15,7 @@ type pingReq struct {
func (req pingReq) validate() error {
if req.Secret == "" {
return agent.ErrMalformedEntity
return manager.ErrMalformedEntity
}
return nil
@@ -18,7 +18,7 @@ import (
"github.com/mainflux/mainflux"
opentracing "github.com/opentracing/opentracing-go"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/ultravioletrs/cocosvm/agent"
"github.com/ultravioletrs/cocosvm/manager"
)
const (
@@ -31,7 +31,7 @@ var (
)
// MakeHandler returns a HTTP handler for API endpoints.
func MakeHandler(tracer opentracing.Tracer, svc agent.Service) http.Handler {
func MakeHandler(tracer opentracing.Tracer, svc manager.Service) http.Handler {
opts := []kithttp.ServerOption{
kithttp.ServerErrorEncoder(encodeError),
}
@@ -86,9 +86,9 @@ func encodeError(_ context.Context, err error, w http.ResponseWriter) {
w.Header().Set("Content-Type", contentType)
switch err {
case agent.ErrMalformedEntity:
case manager.ErrMalformedEntity:
w.WriteHeader(http.StatusBadRequest)
case agent.ErrUnauthorizedAccess:
case manager.ErrUnauthorizedAccess:
w.WriteHeader(http.StatusForbidden)
case errUnsupportedContentType:
w.WriteHeader(http.StatusUnsupportedMediaType)
@@ -10,20 +10,20 @@ import (
"time"
"github.com/go-kit/kit/metrics"
"github.com/ultravioletrs/cocosvm/agent"
"github.com/ultravioletrs/cocosvm/manager"
)
var _ agent.Service = (*metricsMiddleware)(nil)
var _ manager.Service = (*metricsMiddleware)(nil)
type metricsMiddleware struct {
counter metrics.Counter
latency metrics.Histogram
svc agent.Service
svc manager.Service
}
// MetricsMiddleware instruments core service by tracking request count and
// latency.
func MetricsMiddleware(svc agent.Service, counter metrics.Counter, latency metrics.Histogram) agent.Service {
func MetricsMiddleware(svc manager.Service, counter metrics.Counter, latency metrics.Histogram) manager.Service {
return &metricsMiddleware{
counter: counter,
latency: latency,
+2 -2
View File
@@ -2,6 +2,6 @@
// SPDX-License-Identifier: Apache-2.0
// Package things contains the domain concept definitions needed to support
// Mainflux agent service functionality.
// Mainflux manager service functionality.
package agent
package manager
+27 -9
View File
@@ -1,10 +1,12 @@
// Copyright (c) Mainflux
// SPDX-License-Identifier: Apache-2.0
package agent
package manager
import (
"errors"
"github.com/digitalocean/go-libvirt"
)
var (
@@ -24,22 +26,38 @@ type Service interface {
Ping(string) (string, error)
}
type agentService struct {
secret string
type managerService struct {
secret string
libvirt *libvirt.Libvirt
}
var _ Service = (*agentService)(nil)
var _ Service = (*managerService)(nil)
// New instantiates the agent service implementation.
func New(secret string) Service {
return &agentService{
secret: secret,
// New instantiates the manager service implementation.
func New(secret string, libvirtConn *libvirt.Libvirt) Service {
return &managerService{
secret: secret,
libvirt: libvirtConn,
}
}
func (ks *agentService) Ping(secret string) (string, error) {
func (ks *managerService) Ping(secret string) (string, error) {
if ks.secret != secret {
return "", ErrUnauthorizedAccess
}
return "Hello World :)", nil
}
func (ks *managerService) CreateDomain(XML string) (libvirt.Domain, error) {
dom, err := ks.libvirt.DomainDefineXMLFlags(XML, 0)
if err != nil {
return libvirt.Domain{}, err
}
err = ks.libvirt.DomainCreate(dom)
if err != nil {
return libvirt.Domain{}, err
}
return dom, nil
}
+1
View File
@@ -0,0 +1 @@
.idea/
+28
View File
@@ -0,0 +1,28 @@
Maintainer
----------
DigitalOcean, Inc
Original Authors
----------------
Ben LeMasurier <blemasurier@digitalocean.com>
Matt Layher <mlayher@digitalocean.com>
Contributors
------------
Justin Kim <justin@digitalocean.com>
Ricky Medina <rm@do.co>
Charlie Drage <charlie@charliedrage.com>
Michael Koppmann <me@mkoppmann.at>
Simarpreet Singh <simar@linux.com>
Alexander Polyakov <apolyakov@beget.com>
Amanda Andrade <amanda.andrade@serpro.gov.br>
Geoff Hickey <ghickey@digitalocean.com>
Yuriy Taraday <yorik.sar@gmail.com>
Sylvain Baubeau <sbaubeau@redhat.com>
David Schneider <dsbrng25b@gmail.com>
Alec Hothan <ahothan@gmail.com>
Akos Varga <vrgakos@gmail.com>
Peter Kurfer <peter.kurfer@gmail.com>
Sam Roberts <sroberts@digitalocean.com>
Moritz Wanzenböck <moritz.wanzenboeck@linbit.com>
Jenni Griesmann <jgriesmann@digitalocean.com>
+30
View File
@@ -0,0 +1,30 @@
Contributing
============
The `go-libvirt` project makes use of the [GitHub Flow](https://guides.github.com/introduction/flow/)
for contributions.
If you'd like to contribute to the project, please
[open an issue](https://github.com/digitalocean/go-libvirt/issues/new) or find an
[existing issue](https://github.com/digitalocean/go-libvirt/issues) that you'd like
to take on. This ensures that efforts are not duplicated, and that a new feature
aligns with the focus of the rest of the repository.
Once your suggestion has been submitted and discussed, please be sure that your
code meets the following criteria:
- code is completely `gofmt`'d
- new features or codepaths have appropriate test coverage
- `go test ./...` passes
- `go vet ./...` passes
- `golint ./...` returns no warnings, including documentation comment warnings
In addition, if this is your first time contributing to the `go-libvirt` project,
add your name and email address to the
[AUTHORS](https://github.com/digitalocean/go-libvirt/blob/master/AUTHORS) file
under the "Contributors" section using the format:
`First Last <email@example.com>`.
Finally, submit a pull request for review!
Feel free to join us in [`#go-libvirt` on libera chat](https://web.libera.chat/)
if you'd like to discuss the project.
+195
View File
@@ -0,0 +1,195 @@
Apache License
==============
_Version 2.0, January 2004_
_&lt;<http://www.apache.org/licenses/>&gt;_
### Terms and Conditions for use, reproduction, and distribution
#### 1. Definitions
“License” shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, “control” means **(i)** the power, direct or
indirect, to cause the direction or management of such entity, whether by
contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the
outstanding shares, or **(iii)** beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising
permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
“Object” form shall mean any form resulting from mechanical transformation or
translation of a Source form, including but not limited to compiled object code,
generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made
available under the License, as indicated by a copyright notice that is included
in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that
is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative Works
shall not include works that remain separable from, or merely link (or bind by
name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative Works
thereof, that is intentionally submitted to Licensor for inclusion in the Work
by the copyright owner or by an individual or Legal Entity authorized to submit
on behalf of the copyright owner. For the purposes of this definition,
“submitted” means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor for
the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently
incorporated within the Work.
#### 2. Grant of Copyright License
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the Work and such
Derivative Works in Source or Object form.
#### 3. Grant of Patent License
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to make, have
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
such license applies only to those patent claims licensable by such Contributor
that are necessarily infringed by their Contribution(s) alone or by combination
of their Contribution(s) with the Work to which such Contribution(s) was
submitted. If You institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
Contribution incorporated within the Work constitutes direct or contributory
patent infringement, then any patent licenses granted to You under this License
for that Work shall terminate as of the date such litigation is filed.
#### 4. Redistribution
You may reproduce and distribute copies of the Work or Derivative Works thereof
in any medium, with or without modifications, and in Source or Object form,
provided that You meet the following conditions:
* **(a)** You must give any other recipients of the Work or Derivative Works a copy of
this License; and
* **(b)** You must cause any modified files to carry prominent notices stating that You
changed the files; and
* **(c)** You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source form
of the Work, excluding those notices that do not pertain to any part of the
Derivative Works; and
* **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any
Derivative Works that You distribute must include a readable copy of the
attribution notices contained within such NOTICE file, excluding those notices
that do not pertain to any part of the Derivative Works, in at least one of the
following places: within a NOTICE text file distributed as part of the
Derivative Works; within the Source form or documentation, if provided along
with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents of
the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works that
You distribute, alongside or as an addendum to the NOTICE text from the Work,
provided that such additional attribution notices cannot be construed as
modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction, or
distribution of Your modifications, or for any such Derivative Works as a whole,
provided Your use, reproduction, and distribution of the Work otherwise complies
with the conditions stated in this License.
#### 5. Submission of Contributions
Unless You explicitly state otherwise, any Contribution intentionally submitted
for inclusion in the Work by You to the Licensor shall be under the terms and
conditions of this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify the terms of
any separate license agreement you may have executed with Licensor regarding
such Contributions.
#### 6. Trademarks
This License does not grant permission to use the trade names, trademarks,
service marks, or product names of the Licensor, except as required for
reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
#### 7. Disclaimer of Warranty
Unless required by applicable law or agreed to in writing, Licensor provides the
Work (and each Contributor provides its Contributions) on an “AS IS” BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
including, without limitation, any warranties or conditions of TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
solely responsible for determining the appropriateness of using or
redistributing the Work and assume any risks associated with Your exercise of
permissions under this License.
#### 8. Limitation of Liability
In no event and under no legal theory, whether in tort (including negligence),
contract, or otherwise, unless required by applicable law (such as deliberate
and grossly negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special, incidental,
or consequential damages of any character arising as a result of this License or
out of the use or inability to use the Work (including but not limited to
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
any and all other commercial damages or losses), even if such Contributor has
been advised of the possibility of such damages.
#### 9. Accepting Warranty or Additional Liability
While redistributing the Work or Derivative Works thereof, You may choose to
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
other liability obligations and/or rights consistent with this License. However,
in accepting such obligations, You may act only on Your own behalf and on Your
sole responsibility, not on behalf of any other Contributor, and only if You
agree to indemnify, defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason of your
accepting any such warranty or additional liability.
_END OF TERMS AND CONDITIONS_
### APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets `[]` replaced with your own
identifying information. (Don't include the brackets!) The text should be
enclosed in the appropriate comment syntax for the file format. We also
recommend that a file or class name and description of purpose be included on
the same “printed page” as the copyright notice for easier identification within
third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+283
View File
@@ -0,0 +1,283 @@
libvirt
[![GoDoc](http://godoc.org/github.com/digitalocean/go-libvirt?status.svg)](http://godoc.org/github.com/digitalocean/go-libvirt)
[![Build Status](https://github.com/digitalocean/go-libvirt/actions/workflows/main.yml/badge.svg)](https://github.com/digitalocean/go-libvirt/actions/)
[![Report Card](https://goreportcard.com/badge/github.com/digitalocean/go-libvirt)](https://goreportcard.com/report/github.com/digitalocean/go-libvirt)
====
Package `go-libvirt` provides a pure Go interface for interacting with libvirt.
Rather than using libvirt's C bindings, this package makes use of
libvirt's RPC interface, as documented [here](https://libvirt.org/kbase/internals/rpc.html).
Connections to the libvirt server may be local, or remote. RPC packets are encoded
using the XDR standard as defined by [RFC 4506](https://tools.ietf.org/html/rfc4506.html).
libvirt's RPC interface is quite extensive, and changes from one version to the
next, so this project uses a pair of code generators to build the go bindings.
The code generators should be run whenever you want to build go-libvirt for a
new version of libvirt. See the next section for directions on re-generating
go-libvirt.
[Pull requests are welcome](https://github.com/digitalocean/go-libvirt/blob/master/CONTRIBUTING.md)!
Feel free to join us in [`#go-libvirt` on libera chat](https://web.libera.chat/)
if you'd like to discuss the project.
Running the Code Generators
---------------------------
The code generator doesn't run automatically when you build go-libvirt. It's
meant to be run manually any time you change the version of libvirt you're
using. When you download go-libvirt it will come with generated files
corresponding to a particular version of libvirt. You can use the library as-is,
but the generated code may be missing libvirt functions, if you're using a newer
version of libvirt, or it may have extra functions that will return
'unimplemented' errors if you try to call them. If this is a problem, you should
re-run the code generator. To do this, follow these steps:
- First, download a copy of the libvirt sources corresponding to the version you
want to use.
- Change directories into where you've unpacked your distribution of libvirt.
- The second step depends on the version of libvirt you'd like to build against.
It's not necessary to actually build libvirt, but it is necessary to run libvirt's
"configure" step because it generates required files.
- For libvirt < v6.7.0:
- `$ mkdir build; cd build`
- `$ ../autogen.sh`
- For libvirt >= v6.7.0:
- `$ meson setup build`
- Finally, set the environment variable `LIBVIRT_SOURCE` to the directory you
put libvirt into, and run `go generate ./...` from the go-libvirt directory.
This runs both of the go-libvirt's code generators.
How to Use This Library
-----------------------
Once you've vendored go-libvirt into your project, you'll probably want to call
some libvirt functions. There's some example code below showing how to connect
to libvirt and make one such call, but once you get past the introduction you'll
next want to call some other libvirt functions. How do you find them?
Start with the [libvirt API reference](https://libvirt.org/html/index.html).
Let's say you want to gracefully shutdown a VM, and after reading through the
libvirt docs you determine that virDomainShutdown() is the function you want to
call to do that. Where's that function in go-libvirt? We transform the names
slightly when building the go bindings. There's no need for a global prefix like
"vir" in Go, since all our functions are inside the package namespace, so we
drop it. That means the Go function for `virDomainShutdown()` is just `DomainShutdown()`,
and sure enough, you can find the Go function `DomainShutdown()` in libvirt.gen.go,
with parameters and return values equivalent to those documented in the API
reference.
Suppose you then decide you need more control over your shutdown, so you switch
over to `virDomainShutdownFlags()`. As its name suggests, this function takes a
flag parameter which has possible values specified in an enum called
`virDomainShutdownFlagValues`. Flag types like this are a little tricky for the
code generator, because the C functions just take an integer type - only the
libvirt documentation actually ties the flags to the enum types. In most cases
though we're able to generate a wrapper function with a distinct flag type,
making it easier for Go tooling to suggest possible flag values while you're
working. Checking the documentation for this function:
`godoc github.com/digitalocean/go-libvirt DomainShutdownFlags`
returns this:
`func (l *Libvirt) DomainShutdownFlags(Dom Domain, Flags DomainShutdownFlagValues) (err error)`
If you want to see the possible flag values, `godoc` can help again:
```
$ godoc github.com/digitalocean/go-libvirt DomainShutdownFlagValues
type DomainShutdownFlagValues int32
DomainShutdownFlagValues as declared in libvirt/libvirt-domain.h:1121
const (
DomainShutdownDefault DomainShutdownFlagValues = iota
DomainShutdownAcpiPowerBtn DomainShutdownFlagValues = 1
DomainShutdownGuestAgent DomainShutdownFlagValues = 2
DomainShutdownInitctl DomainShutdownFlagValues = 4
DomainShutdownSignal DomainShutdownFlagValues = 8
DomainShutdownParavirt DomainShutdownFlagValues = 16
)
DomainShutdownFlagValues enumeration from libvirt/libvirt-domain.h:1121
```
One other suggestion: most of the code in go-libvirt is now generated, but a few
hand-written routines still exist in libvirt.go, and wrap calls to the generated
code with slightly different parameters or return values. We suggest avoiding
these hand-written routines and calling the generated routines in libvirt.gen.go
instead. Over time these handwritten routines will be removed from go-libvirt.
Warning
-------
While these package are reasonably well-tested and have seen some use inside of
DigitalOcean, there may be subtle bugs which could cause the packages to act
in unexpected ways. Use at your own risk!
In addition, the API is not considered stable at this time. If you would like
to include package `libvirt` in a project, we highly recommend vendoring it into
your project.
Example
-------
```go
package main
import (
"fmt"
"log"
"net"
"time"
"github.com/digitalocean/go-libvirt"
)
func main() {
// This dials libvirt on the local machine, but you can substitute the first
// two parameters with "tcp", "<ip address>:<port>" to connect to libvirt on
// a remote machine.
c, err := net.DialTimeout("unix", "/var/run/libvirt/libvirt-sock", 2*time.Second)
if err != nil {
log.Fatalf("failed to dial libvirt: %v", err)
}
l := libvirt.New(c)
if err := l.Connect(); err != nil {
log.Fatalf("failed to connect: %v", err)
}
v, err := l.Version()
if err != nil {
log.Fatalf("failed to retrieve libvirt version: %v", err)
}
fmt.Println("Version:", v)
domains, err := l.Domains()
if err != nil {
log.Fatalf("failed to retrieve domains: %v", err)
}
fmt.Println("ID\tName\t\tUUID")
fmt.Printf("--------------------------------------------------------\n")
for _, d := range domains {
fmt.Printf("%d\t%s\t%x\n", d.ID, d.Name, d.UUID)
}
if err := l.Disconnect(); err != nil {
log.Fatalf("failed to disconnect: %v", err)
}
}
```
```
Version: 1.3.4
ID Name UUID
--------------------------------------------------------
1 Test-1 dc329f87d4de47198cfd2e21c6105b01
2 Test-2 dc229f87d4de47198cfd2e21c6105b01
```
Example (Connect to libvirt via TLS over TCP)
-------
```go
package main
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"log"
"github.com/digitalocean/go-libvirt"
)
func main() {
// This dials libvirt on the local machine
// It connects to libvirt via TLS over TCP
// To connect to a remote machine, you need to have the ca/cert/key of it.
keyFileXML, err := ioutil.ReadFile("/etc/pki/libvirt/private/clientkey.pem")
if err != nil {
log.Fatalf("%v", err)
}
certFileXML, err := ioutil.ReadFile("/etc/pki/libvirt/clientcert.pem")
if err != nil {
log.Fatalf("%v", err)
}
caFileXML, err := ioutil.ReadFile("/etc/pki/CA/cacert.pem")
if err != nil {
log.Fatalf("%v", err)
}
cert, err := tls.X509KeyPair([]byte(certFileXML), []byte(keyFileXML))
if err != nil {
log.Fatalf("%v", err)
}
roots := x509.NewCertPool()
roots.AppendCertsFromPEM([]byte(caFileXML))
config := &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: roots,
}
// Use host name or IP which is valid in certificate
addr := "10.10.10.10"
port := "16514"
c, err := tls.Dial("tcp", addr + ":" + port, config)
if err != nil {
log.Fatalf("failed to dial libvirt: %v", err)
}
// Drop a byte before libvirt.New(c)
// More details at https://github.com/digitalocean/go-libvirt/issues/89
// Remove this line if the issue does not exist any more
c.Read(make([]byte, 1))
l := libvirt.New(c)
if err := l.Connect(); err != nil {
log.Fatalf("failed to connect: %v", err)
}
v, err := l.Version()
if err != nil {
log.Fatalf("failed to retrieve libvirt version: %v", err)
}
fmt.Println("Version:", v)
// Return both running and stopped VMs
flags := libvirt.ConnectListDomainsActive | libvirt.ConnectListDomainsInactive
domains, _, err := l.ConnectListAllDomains(1, flags)
if err != nil {
log.Fatalf("failed to retrieve domains: %v", err)
}
fmt.Println("ID\tName\t\tUUID")
fmt.Println("--------------------------------------------------------")
for _, d := range domains {
fmt.Printf("%d\t%s\t%x\n", d.ID, d.Name, d.UUID)
}
if err := l.Disconnect(); err != nil {
log.Fatalf("failed to disconnect: %v", err)
}
}
```
Running the Integration Tests
-----------------------------
GitHub actions workflows are defined in [.github/workflows](.github/workflows)
and can be triggered manually in the GitHub UI after pushing a branch. There
are not currently convenient scripts for setting up and running integration tests
locally, but installing libvirt and defining only the artifacts described by the
files in testdata should be sufficient to be able to run the integration test file
against.
File diff suppressed because it is too large Load Diff
+70
View File
@@ -0,0 +1,70 @@
// Copyright 2016 The go-libvirt Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package libvirt is a pure Go interface to libvirt.
//
// Rather than using Libvirt's C bindings, this package makes use of Libvirt's
// RPC interface, as documented here: https://libvirt.org/internals/rpc.html.
// Connections to the libvirt server may be local, or remote. RPC packets are
// encoded using the XDR standard as defined by RFC 4506.
//
// Example usage:
//
// package main
//
// import (
// "fmt"
// "log"
// "net"
// "time"
//
// "github.com/digitalocean/go-libvirt"
// )
//
// func main() {
// // This dials libvirt on the local machine, but you can substitute the first
// // two parameters with "tcp", "<ip address>:<port>" to connect to libvirt on
// // a remote machine.
// c, err := net.DialTimeout("unix", "/var/run/libvirt/libvirt-sock", 2*time.Second)
// if err != nil {
// log.Fatalf("failed to dial libvirt: %v", err)
// }
//
// l := libvirt.New(c)
// if err := l.Connect(); err != nil {
// log.Fatalf("failed to connect: %v", err)
// }
//
// v, err := l.Version()
// if err != nil {
// log.Fatalf("failed to retrieve libvirt version: %v", err)
// }
// fmt.Println("Version:", v)
//
// domains, err := l.Domains()
// if err != nil {
// log.Fatalf("failed to retrieve domains: %v", err)
// }
//
// fmt.Println("ID\tName\t\tUUID")
// fmt.Printf("--------------------------------------------------------\n")
// for _, d := range domains {
// fmt.Printf("%d\t%s\t%x\n", d.ID, d.Name, d.UUID)
// }
//
// if err := l.Disconnect(); err != nil {
// log.Fatalf("failed to disconnect: %v", err)
// }
// }
package libvirt
@@ -0,0 +1,47 @@
// Copyright 2018 The go-libvirt Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Code generated by internal/lvgen/generate.go. DO NOT EDIT.
//
// To regenerate, run 'go generate' in internal/lvgen.
//
package constants
// These are libvirt procedure numbers which correspond to each respective
// API call between remote_internal driver and libvirtd. Each procedure is
// identified by a unique number.
const (
// From enums:
// QEMUProcDomainMonitorCommand is libvirt's QEMU_PROC_DOMAIN_MONITOR_COMMAND
QEMUProcDomainMonitorCommand = 1
// QEMUProcDomainAttach is libvirt's QEMU_PROC_DOMAIN_ATTACH
QEMUProcDomainAttach = 2
// QEMUProcDomainAgentCommand is libvirt's QEMU_PROC_DOMAIN_AGENT_COMMAND
QEMUProcDomainAgentCommand = 3
// QEMUProcConnectDomainMonitorEventRegister is libvirt's QEMU_PROC_CONNECT_DOMAIN_MONITOR_EVENT_REGISTER
QEMUProcConnectDomainMonitorEventRegister = 4
// QEMUProcConnectDomainMonitorEventDeregister is libvirt's QEMU_PROC_CONNECT_DOMAIN_MONITOR_EVENT_DEREGISTER
QEMUProcConnectDomainMonitorEventDeregister = 5
// QEMUProcDomainMonitorEvent is libvirt's QEMU_PROC_DOMAIN_MONITOR_EVENT
QEMUProcDomainMonitorEvent = 6
// From consts:
// QEMUProgram is libvirt's QEMU_PROGRAM
QEMUProgram = 0x20008087
// QEMUProtocolVersion is libvirt's QEMU_PROTOCOL_VERSION
QEMUProtocolVersion = 1
)
File diff suppressed because it is too large Load Diff
+20
View File
@@ -0,0 +1,20 @@
// Copyright 2020 The go-libvirt Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package event
// Event represents an internal Event.
type Event interface {
GetCallbackID() int32
}
+157
View File
@@ -0,0 +1,157 @@
// Copyright 2020 The go-libvirt Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package event
import (
"context"
)
// emptyEvent is used as a zero-value. Clients will never receive one of these;
// they are only here to satisfy the compiler. See the comments in process() for
// more information.
type emptyEvent struct{}
func (emptyEvent) GetCallbackID() int32 { return 0 }
// Stream is an unbounded buffered event channel. The implementation
// consists of a pair of unbuffered channels and a goroutine to manage them.
// Client behavior will not cause incoming events to block.
type Stream struct {
// Program specifies the source of the events - libvirt or QEMU.
Program uint32
// CallbackID is returned by the event registration call.
CallbackID int32
// manage unbounded channel behavior.
queue []Event
qlen chan (chan int)
in, out chan Event
// terminates processing
shutdown context.CancelFunc
}
// NewStream configures a new Event Stream. Incoming events are appended to a
// queue, which is then relayed to the listening client. Client behavior will
// not cause incoming events to block. It is the responsibility of the caller
// to terminate the Stream via Shutdown() when no longer in use.
func NewStream(program uint32, cbID int32) *Stream {
s := &Stream{
Program: program,
CallbackID: cbID,
in: make(chan Event),
out: make(chan Event),
qlen: make(chan (chan int)),
}
// Start the processing loop, which will return a routine we can use to
// shut the queue down later.
s.shutdown = s.start()
return s
}
// Len will return the current count of events in the internal queue for a
// stream. It does this by sending a message to the stream's process() loop,
// which will then write the current length to the channel contained in that
// message.
func (s *Stream) Len() int {
// Send a request to the process() loop to get the current length of the
// queue
ch := make(chan int)
s.qlen <- ch
return <-ch
}
// Recv returns the next available event from the Stream's queue.
func (s *Stream) Recv() chan Event {
return s.out
}
// Push appends a new event to the queue.
func (s *Stream) Push(e Event) {
s.in <- e
}
// Shutdown gracefully terminates Stream processing, releasing all internal
// resources. Events which have not yet been received by the client will be
// dropped. Subsequent calls to Shutdown() are idempotent.
func (s *Stream) Shutdown() {
if s.shutdown != nil {
s.shutdown()
}
}
// start starts the event processing loop, which will continue to run until
// terminated by the returned context.CancelFunc.
func (s *Stream) start() context.CancelFunc {
ctx, cancel := context.WithCancel(context.Background())
go s.process(ctx)
return cancel
}
// process manages an Stream's lifecycle until canceled by the provided context.
// Incoming events are appended to a queue which is then relayed to the
// listening client. New events pushed onto the queue will not block if the
// client is not actively polling for them; the stream will buffer them
// internally.
func (s *Stream) process(ctx context.Context) {
// Close the output channel so that clients know this stream is finished.
// We don't close s.in to avoid creating a race with the stream's Push()
// function.
defer close(s.out)
// This function is used to retrieve the next event from the queue, to be
// sent to the client. If there are no more events to send, it returns a nil
// channel and a zero-value event.
nextEvent := func() (chan Event, Event) {
sendCh := chan Event(nil)
next := Event(emptyEvent{})
if len(s.queue) > 0 {
sendCh = s.out
next = s.queue[0]
}
return sendCh, next
}
// The select statement in this loop relies on the fact that a send to a nil
// channel will block forever. If we have no entries in the queue, the
// sendCh variable will be nil, so the clause that attempts to send an event
// to the client will never complete. Clients will never receive an
// emptyEvent.
for {
sendCh, nextEvt := nextEvent()
select {
// new event received, append to queue
case e := <-s.in:
s.queue = append(s.queue, e)
case lenCh := <-s.qlen:
lenCh <- len(s.queue)
// client received an event, pop from queue
case sendCh <- nextEvt:
s.queue = s.queue[1:]
// shutdown requested
case <-ctx.Done():
return
}
}
}
+13
View File
@@ -0,0 +1,13 @@
Copyright (c) 2012-2014 Dave Collins <dave@davec.name>
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -0,0 +1,896 @@
/*
* Copyright (c) 2012-2014 Dave Collins <dave@davec.name>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package xdr
import (
"fmt"
"io"
"math"
"reflect"
"time"
)
var (
errMaxSlice = "data exceeds max slice limit"
errIODecode = "%s while decoding %d bytes"
)
/*
Unmarshal parses XDR-encoded data into the value pointed to by v reading from
reader r and returning the total number of bytes read. An addressable pointer
must be provided since Unmarshal needs to both store the result of the decode as
well as obtain target type information. Unmarhsal traverses v recursively and
automatically indirects pointers through arbitrary depth, allocating them as
necessary, to decode the data into the underlying value pointed to.
Unmarshal uses reflection to determine the type of the concrete value contained
by v and performs a mapping of underlying XDR types to Go types as follows:
Go Type <- XDR Type
--------------------
int8, int16, int32, int <- XDR Integer
uint8, uint16, uint32, uint <- XDR Unsigned Integer
int64 <- XDR Hyper Integer
uint64 <- XDR Unsigned Hyper Integer
bool <- XDR Boolean
float32 <- XDR Floating-Point
float64 <- XDR Double-Precision Floating-Point
string <- XDR String
byte <- XDR Integer
[]byte <- XDR Variable-Length Opaque Data
[#]byte <- XDR Fixed-Length Opaque Data
[]<type> <- XDR Variable-Length Array
[#]<type> <- XDR Fixed-Length Array
struct <- XDR Structure
map <- XDR Variable-Length Array of two-element XDR Structures
time.Time <- XDR String encoded with RFC3339 nanosecond precision
Notes and Limitations:
* Automatic unmarshalling of variable and fixed-length arrays of uint8s
requires a special struct tag `xdropaque:"false"` since byte slices
and byte arrays are assumed to be opaque data and byte is a Go alias
for uint8 thus indistinguishable under reflection
* Cyclic data structures are not supported and will result in infinite
loops
If any issues are encountered during the unmarshalling process, an
UnmarshalError is returned with a human readable description as well as
an ErrorCode value for further inspection from sophisticated callers. Some
potential issues are unsupported Go types, attempting to decode a value which is
too large to fit into a specified Go type, and exceeding max slice limitations.
*/
func Unmarshal(r io.Reader, v interface{}) (int, error) {
d := Decoder{r: r}
return d.Decode(v)
}
// UnmarshalLimited is identical to Unmarshal but it sets maxReadSize in order
// to cap reads.
func UnmarshalLimited(r io.Reader, v interface{}, maxSize uint) (int, error) {
d := Decoder{r: r, maxReadSize: maxSize}
return d.Decode(v)
}
// TypeDecoder lets a caller provide a custom decode routine for a custom type.
type TypeDecoder interface {
Decode(*Decoder, reflect.Value) (int, error)
}
// A Decoder wraps an io.Reader that is expected to provide an XDR-encoded byte
// stream and provides several exposed methods to manually decode various XDR
// primitives without relying on reflection. The NewDecoder function can be
// used to get a new Decoder directly.
//
// Typically, Unmarshal should be used instead of manual decoding. A Decoder
// is exposed so it is possible to perform manual decoding should it be
// necessary in complex scenarios where automatic reflection-based decoding
// won't work.
type Decoder struct {
r io.Reader
// maxReadSize is the default maximum bytes an element can contain. 0
// is unlimited and provides backwards compatability. Setting it to a
// non-zero value caps reads.
maxReadSize uint
// customTypes is a map allowing the caller to provide decoder routines for
// custom types known only to itself.
customTypes map[string]TypeDecoder
}
// DecodeInt treats the next 4 bytes as an XDR encoded integer and returns the
// result as an int32 along with the number of bytes actually read.
//
// An UnmarshalError is returned if there are insufficient bytes remaining.
//
// Reference:
// RFC Section 4.1 - Integer
// 32-bit big-endian signed integer in range [-2147483648, 2147483647]
func (d *Decoder) DecodeInt() (int32, int, error) {
var buf [4]byte
n, err := io.ReadFull(d.r, buf[:])
if err != nil {
msg := fmt.Sprintf(errIODecode, err.Error(), 4)
err := unmarshalError("DecodeInt", ErrIO, msg, buf[:n], err)
return 0, n, err
}
rv := int32(buf[3]) | int32(buf[2])<<8 |
int32(buf[1])<<16 | int32(buf[0])<<24
return rv, n, nil
}
// DecodeUint treats the next 4 bytes as an XDR encoded unsigned integer and
// returns the result as a uint32 along with the number of bytes actually read.
//
// An UnmarshalError is returned if there are insufficient bytes remaining.
//
// Reference:
// RFC Section 4.2 - Unsigned Integer
// 32-bit big-endian unsigned integer in range [0, 4294967295]
func (d *Decoder) DecodeUint() (uint32, int, error) {
var buf [4]byte
n, err := io.ReadFull(d.r, buf[:])
if err != nil {
msg := fmt.Sprintf(errIODecode, err.Error(), 4)
err := unmarshalError("DecodeUint", ErrIO, msg, buf[:n], err)
return 0, n, err
}
rv := uint32(buf[3]) | uint32(buf[2])<<8 |
uint32(buf[1])<<16 | uint32(buf[0])<<24
return rv, n, nil
}
// DecodeEnum treats the next 4 bytes as an XDR encoded enumeration value and
// returns the result as an int32 after verifying that the value is in the
// provided map of valid values. It also returns the number of bytes actually
// read.
//
// An UnmarshalError is returned if there are insufficient bytes remaining or
// the parsed enumeration value is not one of the provided valid values.
//
// Reference:
// RFC Section 4.3 - Enumeration
// Represented as an XDR encoded signed integer
func (d *Decoder) DecodeEnum(validEnums map[int32]bool) (int32, int, error) {
val, n, err := d.DecodeInt()
if err != nil {
return 0, n, err
}
if !validEnums[val] {
err := unmarshalError("DecodeEnum", ErrBadEnumValue,
"invalid enum", val, nil)
return 0, n, err
}
return val, n, nil
}
// DecodeBool treats the next 4 bytes as an XDR encoded boolean value and
// returns the result as a bool along with the number of bytes actually read.
//
// An UnmarshalError is returned if there are insufficient bytes remaining or
// the parsed value is not a 0 or 1.
//
// Reference:
// RFC Section 4.4 - Boolean
// Represented as an XDR encoded enumeration where 0 is false and 1 is true
func (d *Decoder) DecodeBool() (bool, int, error) {
val, n, err := d.DecodeInt()
if err != nil {
return false, n, err
}
switch val {
case 0:
return false, n, nil
case 1:
return true, n, nil
}
err = unmarshalError("DecodeBool", ErrBadEnumValue, "bool not 0 or 1",
val, nil)
return false, n, err
}
// DecodeHyper treats the next 8 bytes as an XDR encoded hyper value and
// returns the result as an int64 along with the number of bytes actually read.
//
// An UnmarshalError is returned if there are insufficient bytes remaining.
//
// Reference:
// RFC Section 4.5 - Hyper Integer
// 64-bit big-endian signed integer in range [-9223372036854775808, 9223372036854775807]
func (d *Decoder) DecodeHyper() (int64, int, error) {
var buf [8]byte
n, err := io.ReadFull(d.r, buf[:])
if err != nil {
msg := fmt.Sprintf(errIODecode, err.Error(), 8)
err := unmarshalError("DecodeHyper", ErrIO, msg, buf[:n], err)
return 0, n, err
}
rv := int64(buf[7]) | int64(buf[6])<<8 |
int64(buf[5])<<16 | int64(buf[4])<<24 |
int64(buf[3])<<32 | int64(buf[2])<<40 |
int64(buf[1])<<48 | int64(buf[0])<<56
return rv, n, err
}
// DecodeUhyper treats the next 8 bytes as an XDR encoded unsigned hyper value
// and returns the result as a uint64 along with the number of bytes actually
// read.
//
// An UnmarshalError is returned if there are insufficient bytes remaining.
//
// Reference:
// RFC Section 4.5 - Unsigned Hyper Integer
// 64-bit big-endian unsigned integer in range [0, 18446744073709551615]
func (d *Decoder) DecodeUhyper() (uint64, int, error) {
var buf [8]byte
n, err := io.ReadFull(d.r, buf[:])
if err != nil {
msg := fmt.Sprintf(errIODecode, err.Error(), 8)
err := unmarshalError("DecodeUhyper", ErrIO, msg, buf[:n], err)
return 0, n, err
}
rv := uint64(buf[7]) | uint64(buf[6])<<8 |
uint64(buf[5])<<16 | uint64(buf[4])<<24 |
uint64(buf[3])<<32 | uint64(buf[2])<<40 |
uint64(buf[1])<<48 | uint64(buf[0])<<56
return rv, n, nil
}
// DecodeFloat treats the next 4 bytes as an XDR encoded floating point and
// returns the result as a float32 along with the number of bytes actually read.
//
// An UnmarshalError is returned if there are insufficient bytes remaining.
//
// Reference:
// RFC Section 4.6 - Floating Point
// 32-bit single-precision IEEE 754 floating point
func (d *Decoder) DecodeFloat() (float32, int, error) {
var buf [4]byte
n, err := io.ReadFull(d.r, buf[:])
if err != nil {
msg := fmt.Sprintf(errIODecode, err.Error(), 4)
err := unmarshalError("DecodeFloat", ErrIO, msg, buf[:n], err)
return 0, n, err
}
val := uint32(buf[3]) | uint32(buf[2])<<8 |
uint32(buf[1])<<16 | uint32(buf[0])<<24
return math.Float32frombits(val), n, nil
}
// DecodeDouble treats the next 8 bytes as an XDR encoded double-precision
// floating point and returns the result as a float64 along with the number of
// bytes actually read.
//
// An UnmarshalError is returned if there are insufficient bytes remaining.
//
// Reference:
// RFC Section 4.7 - Double-Precision Floating Point
// 64-bit double-precision IEEE 754 floating point
func (d *Decoder) DecodeDouble() (float64, int, error) {
var buf [8]byte
n, err := io.ReadFull(d.r, buf[:])
if err != nil {
msg := fmt.Sprintf(errIODecode, err.Error(), 8)
err := unmarshalError("DecodeDouble", ErrIO, msg, buf[:n], err)
return 0, n, err
}
val := uint64(buf[7]) | uint64(buf[6])<<8 |
uint64(buf[5])<<16 | uint64(buf[4])<<24 |
uint64(buf[3])<<32 | uint64(buf[2])<<40 |
uint64(buf[1])<<48 | uint64(buf[0])<<56
return math.Float64frombits(val), n, nil
}
// RFC Section 4.8 - Quadruple-Precision Floating Point
// 128-bit quadruple-precision floating point
// Not Implemented
// DecodeFixedOpaque treats the next 'size' bytes as XDR encoded opaque data and
// returns the result as a byte slice along with the number of bytes actually
// read.
//
// An UnmarshalError is returned if there are insufficient bytes remaining to
// satisfy the passed size, including the necessary padding to make it a
// multiple of 4.
//
// Reference:
// RFC Section 4.9 - Fixed-Length Opaque Data
// Fixed-length uninterpreted data zero-padded to a multiple of four
func (d *Decoder) DecodeFixedOpaque(size int32) ([]byte, int, error) {
// Nothing to do if size is 0.
if size == 0 {
return nil, 0, nil
}
pad := (4 - (size % 4)) % 4
paddedSize := size + pad
if uint(paddedSize) > uint(math.MaxInt32) {
err := unmarshalError("DecodeFixedOpaque", ErrOverflow,
errMaxSlice, paddedSize, nil)
return nil, 0, err
}
buf := make([]byte, paddedSize)
n, err := io.ReadFull(d.r, buf)
if err != nil {
msg := fmt.Sprintf(errIODecode, err.Error(), paddedSize)
err := unmarshalError("DecodeFixedOpaque", ErrIO, msg, buf[:n],
err)
return nil, n, err
}
return buf[0:size], n, nil
}
// DecodeOpaque treats the next bytes as variable length XDR encoded opaque
// data and returns the result as a byte slice along with the number of bytes
// actually read.
//
// An UnmarshalError is returned if there are insufficient bytes remaining or
// the opaque data is larger than the max length of a Go slice.
//
// Reference:
// RFC Section 4.10 - Variable-Length Opaque Data
// Unsigned integer length followed by fixed opaque data of that length
func (d *Decoder) DecodeOpaque() ([]byte, int, error) {
dataLen, n, err := d.DecodeUint()
if err != nil {
return nil, n, err
}
if uint(dataLen) > uint(math.MaxInt32) ||
(d.maxReadSize != 0 && uint(dataLen) > d.maxReadSize) {
err := unmarshalError("DecodeOpaque", ErrOverflow, errMaxSlice,
dataLen, nil)
return nil, n, err
}
rv, n2, err := d.DecodeFixedOpaque(int32(dataLen))
n += n2
if err != nil {
return nil, n, err
}
return rv, n, nil
}
// DecodeString treats the next bytes as a variable length XDR encoded string
// and returns the result as a string along with the number of bytes actually
// read. Character encoding is assumed to be UTF-8 and therefore ASCII
// compatible. If the underlying character encoding is not compatibile with
// this assumption, the data can instead be read as variable-length opaque data
// (DecodeOpaque) and manually converted as needed.
//
// An UnmarshalError is returned if there are insufficient bytes remaining or
// the string data is larger than the max length of a Go slice.
//
// Reference:
// RFC Section 4.11 - String
// Unsigned integer length followed by bytes zero-padded to a multiple of
// four
func (d *Decoder) DecodeString() (string, int, error) {
dataLen, n, err := d.DecodeUint()
if err != nil {
return "", n, err
}
if uint(dataLen) > uint(math.MaxInt32) ||
(d.maxReadSize != 0 && uint(dataLen) > d.maxReadSize) {
err = unmarshalError("DecodeString", ErrOverflow, errMaxSlice,
dataLen, nil)
return "", n, err
}
opaque, n2, err := d.DecodeFixedOpaque(int32(dataLen))
n += n2
if err != nil {
return "", n, err
}
return string(opaque), n, nil
}
// decodeFixedArray treats the next bytes as a series of XDR encoded elements
// of the same type as the array represented by the reflection value and decodes
// each element into the passed array. The ignoreOpaque flag controls whether
// or not uint8 (byte) elements should be decoded individually or as a fixed
// sequence of opaque data. It returns the the number of bytes actually read.
//
// An UnmarshalError is returned if any issues are encountered while decoding
// the array elements.
//
// Reference:
// RFC Section 4.12 - Fixed-Length Array
// Individually XDR encoded array elements
func (d *Decoder) decodeFixedArray(v reflect.Value, ignoreOpaque bool) (int, error) {
// Treat [#]byte (byte is alias for uint8) as opaque data unless
// ignored.
if !ignoreOpaque && v.Type().Elem().Kind() == reflect.Uint8 {
data, n, err := d.DecodeFixedOpaque(int32(v.Len()))
if err != nil {
return n, err
}
reflect.Copy(v, reflect.ValueOf(data))
return n, nil
}
// Decode each array element.
var n int
for i := 0; i < v.Len(); i++ {
n2, err := d.decode(v.Index(i))
n += n2
if err != nil {
return n, err
}
}
return n, nil
}
// decodeArray treats the next bytes as a variable length series of XDR encoded
// elements of the same type as the array represented by the reflection value.
// The number of elements is obtained by first decoding the unsigned integer
// element count. Then each element is decoded into the passed array. The
// ignoreOpaque flag controls whether or not uint8 (byte) elements should be
// decoded individually or as a variable sequence of opaque data. It returns
// the number of bytes actually read.
//
// An UnmarshalError is returned if any issues are encountered while decoding
// the array elements.
//
// Reference:
// RFC Section 4.13 - Variable-Length Array
// Unsigned integer length followed by individually XDR encoded array
// elements
func (d *Decoder) decodeArray(v reflect.Value, ignoreOpaque bool) (int, error) {
dataLen, n, err := d.DecodeUint()
if err != nil {
return n, err
}
if uint(dataLen) > uint(math.MaxInt32) ||
(d.maxReadSize != 0 && uint(dataLen) > d.maxReadSize) {
err := unmarshalError("decodeArray", ErrOverflow, errMaxSlice,
dataLen, nil)
return n, err
}
// Allocate storage for the slice elements (the underlying array) if
// existing slice does not have enough capacity.
sliceLen := int(dataLen)
if v.Cap() < sliceLen {
v.Set(reflect.MakeSlice(v.Type(), sliceLen, sliceLen))
}
if v.Len() < sliceLen {
v.SetLen(sliceLen)
}
// Treat []byte (byte is alias for uint8) as opaque data unless ignored.
if !ignoreOpaque && v.Type().Elem().Kind() == reflect.Uint8 {
data, n2, err := d.DecodeFixedOpaque(int32(sliceLen))
n += n2
if err != nil {
return n, err
}
v.SetBytes(data)
return n, nil
}
// Decode each slice element.
for i := 0; i < sliceLen; i++ {
n2, err := d.decode(v.Index(i))
n += n2
if err != nil {
return n, err
}
}
return n, nil
}
// decodeStruct treats the next bytes as a series of XDR encoded elements
// of the same type as the exported fields of the struct represented by the
// passed reflection value. Pointers are automatically indirected and
// allocated as necessary. It returns the the number of bytes actually read.
//
// An UnmarshalError is returned if any issues are encountered while decoding
// the elements.
//
// Reference:
// RFC Section 4.14 - Structure
// XDR encoded elements in the order of their declaration in the struct
func (d *Decoder) decodeStruct(v reflect.Value) (int, error) {
var n int
vt := v.Type()
for i := 0; i < v.NumField(); i++ {
// Skip unexported fields.
vtf := vt.Field(i)
if vtf.PkgPath != "" {
continue
}
// Indirect through pointers allocating them as needed and
// ensure the field is settable.
vf := v.Field(i)
vf, err := d.indirect(vf)
if err != nil {
return n, err
}
if !vf.CanSet() {
msg := fmt.Sprintf("can't decode to unsettable '%v'",
vf.Type().String())
err := unmarshalError("decodeStruct", ErrNotSettable,
msg, nil, nil)
return n, err
}
// Handle non-opaque data to []uint8 and [#]uint8 based on
// struct tag.
tag := vtf.Tag.Get("xdropaque")
if tag == "false" {
switch vf.Kind() {
case reflect.Slice:
n2, err := d.decodeArray(vf, true)
n += n2
if err != nil {
return n, err
}
continue
case reflect.Array:
n2, err := d.decodeFixedArray(vf, true)
n += n2
if err != nil {
return n, err
}
continue
}
}
// Decode each struct field.
n2, err := d.decode(vf)
n += n2
if err != nil {
return n, err
}
}
return n, nil
}
// RFC Section 4.15 - Discriminated Union
// RFC Section 4.16 - Void
// RFC Section 4.17 - Constant
// RFC Section 4.18 - Typedef
// RFC Section 4.19 - Optional data
// RFC Sections 4.15 though 4.19 only apply to the data specification language
// which is not implemented by this package. In the case of discriminated
// unions, struct tags are used to perform a similar function.
// decodeMap treats the next bytes as an XDR encoded variable array of 2-element
// structures whose fields are of the same type as the map keys and elements
// represented by the passed reflection value. Pointers are automatically
// indirected and allocated as necessary. It returns the the number of bytes
// actually read.
//
// An UnmarshalError is returned if any issues are encountered while decoding
// the elements.
func (d *Decoder) decodeMap(v reflect.Value) (int, error) {
dataLen, n, err := d.DecodeUint()
if err != nil {
return n, err
}
// Allocate storage for the underlying map if needed.
vt := v.Type()
if v.IsNil() {
v.Set(reflect.MakeMap(vt))
}
// Decode each key and value according to their type.
keyType := vt.Key()
elemType := vt.Elem()
for i := uint32(0); i < dataLen; i++ {
key := reflect.New(keyType).Elem()
n2, err := d.decode(key)
n += n2
if err != nil {
return n, err
}
val := reflect.New(elemType).Elem()
n2, err = d.decode(val)
n += n2
if err != nil {
return n, err
}
v.SetMapIndex(key, val)
}
return n, nil
}
// decodeInterface examines the interface represented by the passed reflection
// value to detect whether it is an interface that can be decoded into and
// if it is, extracts the underlying value to pass back into the decode function
// for decoding according to its type. It returns the the number of bytes
// actually read.
//
// An UnmarshalError is returned if any issues are encountered while decoding
// the interface.
func (d *Decoder) decodeInterface(v reflect.Value) (int, error) {
if v.IsNil() || !v.CanInterface() {
msg := fmt.Sprintf("can't decode to nil interface")
err := unmarshalError("decodeInterface", ErrNilInterface, msg,
nil, nil)
return 0, err
}
// Extract underlying value from the interface and indirect through
// pointers allocating them as needed.
ve := reflect.ValueOf(v.Interface())
ve, err := d.indirect(ve)
if err != nil {
return 0, err
}
if !ve.CanSet() {
msg := fmt.Sprintf("can't decode to unsettable '%v'",
ve.Type().String())
err := unmarshalError("decodeInterface", ErrNotSettable, msg,
nil, nil)
return 0, err
}
return d.decode(ve)
}
// decode is the main workhorse for unmarshalling via reflection. It uses
// the passed reflection value to choose the XDR primitives to decode from
// the encapsulated reader. It is a recursive function,
// so cyclic data structures are not supported and will result in an infinite
// loop. It returns the the number of bytes actually read.
func (d *Decoder) decode(v reflect.Value) (int, error) {
if !v.IsValid() {
msg := fmt.Sprintf("type '%s' is not valid", v.Kind().String())
err := unmarshalError("decode", ErrUnsupportedType, msg, nil, nil)
return 0, err
}
// Indirect through pointers allocating them as needed.
ve, err := d.indirect(v)
if err != nil {
return 0, err
}
// Handle time.Time values by decoding them as an RFC3339 formatted
// string with nanosecond precision. Check the type string rather
// than doing a full blown conversion to interface and type assertion
// since checking a string is much quicker.
switch ve.Type().String() {
case "time.Time":
// Read the value as a string and parse it.
timeString, n, err := d.DecodeString()
if err != nil {
return n, err
}
ttv, err := time.Parse(time.RFC3339, timeString)
if err != nil {
err := unmarshalError("decode", ErrParseTime,
err.Error(), timeString, err)
return n, err
}
ve.Set(reflect.ValueOf(ttv))
return n, nil
}
// If this type is in our custom types map, call the decode routine set up
// for it.
if dt, ok := d.customTypes[ve.Type().String()]; ok {
return dt.Decode(d, v)
}
// Handle native Go types.
switch ve.Kind() {
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int:
i, n, err := d.DecodeInt()
if err != nil {
return n, err
}
if ve.OverflowInt(int64(i)) {
msg := fmt.Sprintf("signed integer too large to fit '%s'",
ve.Kind().String())
err = unmarshalError("decode", ErrOverflow, msg, i, nil)
return n, err
}
ve.SetInt(int64(i))
return n, nil
case reflect.Int64:
i, n, err := d.DecodeHyper()
if err != nil {
return n, err
}
ve.SetInt(i)
return n, nil
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint:
ui, n, err := d.DecodeUint()
if err != nil {
return n, err
}
if ve.OverflowUint(uint64(ui)) {
msg := fmt.Sprintf("unsigned integer too large to fit '%s'",
ve.Kind().String())
err = unmarshalError("decode", ErrOverflow, msg, ui, nil)
return n, err
}
ve.SetUint(uint64(ui))
return n, nil
case reflect.Uint64:
ui, n, err := d.DecodeUhyper()
if err != nil {
return n, err
}
ve.SetUint(ui)
return n, nil
case reflect.Bool:
b, n, err := d.DecodeBool()
if err != nil {
return n, err
}
ve.SetBool(b)
return n, nil
case reflect.Float32:
f, n, err := d.DecodeFloat()
if err != nil {
return n, err
}
ve.SetFloat(float64(f))
return n, nil
case reflect.Float64:
f, n, err := d.DecodeDouble()
if err != nil {
return n, err
}
ve.SetFloat(f)
return n, nil
case reflect.String:
s, n, err := d.DecodeString()
if err != nil {
return n, err
}
ve.SetString(s)
return n, nil
case reflect.Array:
n, err := d.decodeFixedArray(ve, false)
if err != nil {
return n, err
}
return n, nil
case reflect.Slice:
n, err := d.decodeArray(ve, false)
if err != nil {
return n, err
}
return n, nil
case reflect.Struct:
n, err := d.decodeStruct(ve)
if err != nil {
return n, err
}
return n, nil
case reflect.Map:
n, err := d.decodeMap(ve)
if err != nil {
return n, err
}
return n, nil
case reflect.Interface:
n, err := d.decodeInterface(ve)
if err != nil {
return n, err
}
return n, nil
}
// The only unhandled types left are unsupported. At the time of this
// writing the only remaining unsupported types that exist are
// reflect.Uintptr and reflect.UnsafePointer.
msg := fmt.Sprintf("unsupported Go type '%s'", ve.Kind().String())
err = unmarshalError("decode", ErrUnsupportedType, msg, nil, nil)
return 0, err
}
// indirect dereferences pointers allocating them as needed until it reaches
// a non-pointer. This allows transparent decoding through arbitrary levels
// of indirection.
func (d *Decoder) indirect(v reflect.Value) (reflect.Value, error) {
rv := v
for rv.Kind() == reflect.Ptr {
// Allocate pointer if needed.
isNil := rv.IsNil()
if isNil && !rv.CanSet() {
msg := fmt.Sprintf("unable to allocate pointer for '%v'",
rv.Type().String())
err := unmarshalError("indirect", ErrNotSettable, msg,
nil, nil)
return rv, err
}
if isNil {
rv.Set(reflect.New(rv.Type().Elem()))
}
rv = rv.Elem()
}
return rv, nil
}
// Decode operates identically to the Unmarshal function with the exception of
// using the reader associated with the Decoder as the source of XDR-encoded
// data instead of a user-supplied reader. See the Unmarhsal documentation for
// specifics.
func (d *Decoder) Decode(v interface{}) (int, error) {
if v == nil {
msg := "can't unmarshal to nil interface"
return 0, unmarshalError("Unmarshal", ErrNilInterface, msg, nil,
nil)
}
vv := reflect.ValueOf(v)
if vv.Kind() != reflect.Ptr {
msg := fmt.Sprintf("can't unmarshal to non-pointer '%v' - use "+
"& operator", vv.Type().String())
err := unmarshalError("Unmarshal", ErrBadArguments, msg, nil, nil)
return 0, err
}
if vv.IsNil() && !vv.CanSet() {
msg := fmt.Sprintf("can't unmarshal to unsettable '%v' - use "+
"& operator", vv.Type().String())
err := unmarshalError("Unmarshal", ErrNotSettable, msg, nil, nil)
return 0, err
}
return d.decode(vv)
}
// NewDecoder returns a Decoder that can be used to manually decode XDR data
// from a provided reader. Typically, Unmarshal should be used instead of
// manually creating a Decoder.
func NewDecoder(r io.Reader) *Decoder {
return &Decoder{r: r}
}
// NewDecoderLimited is identical to NewDecoder but it sets maxReadSize in
// order to cap reads.
func NewDecoderLimited(r io.Reader, maxSize uint) *Decoder {
return &Decoder{r: r, maxReadSize: maxSize}
}
// NewDecoderCustomTypes returns a decoder with support for custom types known
// to the caller. The second parameter is a map of the type name to the decoder
// routine. When the decoder finds a type matching one of the entries in the map
// it will call the custom routine for that type.
func NewDecoderCustomTypes(r io.Reader, maxSize uint, ct map[string]TypeDecoder) *Decoder {
return &Decoder{r: r, maxReadSize: maxSize, customTypes: ct}
}
+171
View File
@@ -0,0 +1,171 @@
/*
* Copyright (c) 2012-2014 Dave Collins <dave@davec.name>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
Package xdr implements the data representation portion of the External Data
Representation (XDR) standard protocol as specified in RFC 4506 (obsoletes
RFC 1832 and RFC 1014).
The XDR RFC defines both a data specification language and a data
representation standard. This package implements methods to encode and decode
XDR data per the data representation standard with the exception of 128-bit
quadruple-precision floating points. It does not currently implement parsing of
the data specification language. In other words, the ability to automatically
generate Go code by parsing an XDR data specification file (typically .x
extension) is not supported. In practice, this limitation of the package is
fairly minor since it is largely unnecessary due to the reflection capabilities
of Go as described below.
This package provides two approaches for encoding and decoding XDR data:
1) Marshal/Unmarshal functions which automatically map between XDR and Go types
2) Individual Encoder/Decoder objects to manually work with XDR primitives
For the Marshal/Unmarshal functions, Go reflection capabilities are used to
choose the type of the underlying XDR data based upon the Go type to encode or
the target Go type to decode into. A description of how each type is mapped is
provided below, however one important type worth reviewing is Go structs. In
the case of structs, each exported field (first letter capitalized) is reflected
and mapped in order. As a result, this means a Go struct with exported fields
of the appropriate types listed in the expected order can be used to
automatically encode / decode the XDR data thereby eliminating the need to write
a lot of boilerplate code to encode/decode and error check each piece of XDR
data as is typically required with C based XDR libraries.
Go Type to XDR Type Mappings
The following chart shows an overview of how Go types are mapped to XDR types
for automatic marshalling and unmarshalling. The documentation for the Marshal
and Unmarshal functions has specific details of how the mapping proceeds.
Go Type <-> XDR Type
--------------------
int8, int16, int32, int <-> XDR Integer
uint8, uint16, uint32, uint <-> XDR Unsigned Integer
int64 <-> XDR Hyper Integer
uint64 <-> XDR Unsigned Hyper Integer
bool <-> XDR Boolean
float32 <-> XDR Floating-Point
float64 <-> XDR Double-Precision Floating-Point
string <-> XDR String
byte <-> XDR Integer
[]byte <-> XDR Variable-Length Opaque Data
[#]byte <-> XDR Fixed-Length Opaque Data
[]<type> <-> XDR Variable-Length Array
[#]<type> <-> XDR Fixed-Length Array
struct <-> XDR Structure
map <-> XDR Variable-Length Array of two-element XDR Structures
time.Time <-> XDR String encoded with RFC3339 nanosecond precision
Notes and Limitations:
* Automatic marshalling and unmarshalling of variable and fixed-length
arrays of uint8s require a special struct tag `xdropaque:"false"`
since byte slices and byte arrays are assumed to be opaque data and
byte is a Go alias for uint8 thus indistinguishable under reflection
* Channel, complex, and function types cannot be encoded
* Interfaces without a concrete value cannot be encoded
* Cyclic data structures are not supported and will result in infinite
loops
* Strings are marshalled and unmarshalled with UTF-8 character encoding
which differs from the XDR specification of ASCII, however UTF-8 is
backwards compatible with ASCII so this should rarely cause issues
Encoding
To encode XDR data, use the Marshal function.
func Marshal(w io.Writer, v interface{}) (int, error)
For example, given the following code snippet:
type ImageHeader struct {
Signature [3]byte
Version uint32
IsGrayscale bool
NumSections uint32
}
h := ImageHeader{[3]byte{0xAB, 0xCD, 0xEF}, 2, true, 10}
var w bytes.Buffer
bytesWritten, err := xdr.Marshal(&w, &h)
// Error check elided
The result, encodedData, will then contain the following XDR encoded byte
sequence:
0xAB, 0xCD, 0xEF, 0x00,
0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x0A
In addition, while the automatic marshalling discussed above will work for the
vast majority of cases, an Encoder object is provided that can be used to
manually encode XDR primitives for complex scenarios where automatic
reflection-based encoding won't work. The included examples provide a sample of
manual usage via an Encoder.
Decoding
To decode XDR data, use the Unmarshal function.
func Unmarshal(r io.Reader, v interface{}) (int, error)
For example, given the following code snippet:
type ImageHeader struct {
Signature [3]byte
Version uint32
IsGrayscale bool
NumSections uint32
}
// Using output from the Encoding section above.
encodedData := []byte{
0xAB, 0xCD, 0xEF, 0x00,
0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x0A,
}
var h ImageHeader
bytesRead, err := xdr.Unmarshal(bytes.NewReader(encodedData), &h)
// Error check elided
The struct instance, h, will then contain the following values:
h.Signature = [3]byte{0xAB, 0xCD, 0xEF}
h.Version = 2
h.IsGrayscale = true
h.NumSections = 10
In addition, while the automatic unmarshalling discussed above will work for the
vast majority of cases, a Decoder object is provided that can be used to
manually decode XDR primitives for complex scenarios where automatic
reflection-based decoding won't work. The included examples provide a sample of
manual usage via a Decoder.
Errors
All errors are either of type UnmarshalError or MarshalError. Both provide
human-readable output as well as an ErrorCode field which can be inspected by
sophisticated callers if necessary.
See the documentation of UnmarshalError, MarshalError, and ErrorCode for further
details.
*/
package xdr
@@ -0,0 +1,669 @@
/*
* Copyright (c) 2012-2014 Dave Collins <dave@davec.name>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package xdr
import (
"fmt"
"io"
"math"
"reflect"
"time"
)
var errIOEncode = "%s while encoding %d bytes"
/*
Marshal writes the XDR encoding of v to writer w and returns the number of bytes
written. It traverses v recursively and automatically indirects pointers
through arbitrary depth to encode the actual value pointed to.
Marshal uses reflection to determine the type of the concrete value contained by
v and performs a mapping of Go types to the underlying XDR types as follows:
Go Type -> XDR Type
--------------------
int8, int16, int32, int -> XDR Integer
uint8, uint16, uint32, uint -> XDR Unsigned Integer
int64 -> XDR Hyper Integer
uint64 -> XDR Unsigned Hyper Integer
bool -> XDR Boolean
float32 -> XDR Floating-Point
float64 -> XDR Double-Precision Floating-Point
string -> XDR String
byte -> XDR Integer
[]byte -> XDR Variable-Length Opaque Data
[#]byte -> XDR Fixed-Length Opaque Data
[]<type> -> XDR Variable-Length Array
[#]<type> -> XDR Fixed-Length Array
struct -> XDR Structure
map -> XDR Variable-Length Array of two-element XDR Structures
time.Time -> XDR String encoded with RFC3339 nanosecond precision
Notes and Limitations:
* Automatic marshalling of variable and fixed-length arrays of uint8s
requires a special struct tag `xdropaque:"false"` since byte slices and
byte arrays are assumed to be opaque data and byte is a Go alias for uint8
thus indistinguishable under reflection
* Channel, complex, and function types cannot be encoded
* Interfaces without a concrete value cannot be encoded
* Cyclic data structures are not supported and will result in infinite loops
* Strings are marshalled with UTF-8 character encoding which differs from
the XDR specification of ASCII, however UTF-8 is backwards compatible with
ASCII so this should rarely cause issues
If any issues are encountered during the marshalling process, a MarshalError is
returned with a human readable description as well as an ErrorCode value for
further inspection from sophisticated callers. Some potential issues are
unsupported Go types, attempting to encode more opaque data than can be
represented by a single opaque XDR entry, and exceeding max slice limitations.
*/
func Marshal(w io.Writer, v interface{}) (int, error) {
enc := Encoder{w: w}
return enc.Encode(v)
}
// An Encoder wraps an io.Writer that will receive the XDR encoded byte stream.
// See NewEncoder.
type Encoder struct {
w io.Writer
}
// EncodeInt writes the XDR encoded representation of the passed 32-bit signed
// integer to the encapsulated writer and returns the number of bytes written.
//
// A MarshalError with an error code of ErrIO is returned if writing the data
// fails.
//
// Reference:
// RFC Section 4.1 - Integer
// 32-bit big-endian signed integer in range [-2147483648, 2147483647]
func (enc *Encoder) EncodeInt(v int32) (int, error) {
var b [4]byte
b[0] = byte(v >> 24)
b[1] = byte(v >> 16)
b[2] = byte(v >> 8)
b[3] = byte(v)
n, err := enc.w.Write(b[:])
if err != nil {
msg := fmt.Sprintf(errIOEncode, err.Error(), 4)
err := marshalError("EncodeInt", ErrIO, msg, b[:n], err)
return n, err
}
return n, nil
}
// EncodeUint writes the XDR encoded representation of the passed 32-bit
// unsigned integer to the encapsulated writer and returns the number of bytes
// written.
//
// A MarshalError with an error code of ErrIO is returned if writing the data
// fails.
//
// Reference:
// RFC Section 4.2 - Unsigned Integer
// 32-bit big-endian unsigned integer in range [0, 4294967295]
func (enc *Encoder) EncodeUint(v uint32) (int, error) {
var b [4]byte
b[0] = byte(v >> 24)
b[1] = byte(v >> 16)
b[2] = byte(v >> 8)
b[3] = byte(v)
n, err := enc.w.Write(b[:])
if err != nil {
msg := fmt.Sprintf(errIOEncode, err.Error(), 4)
err := marshalError("EncodeUint", ErrIO, msg, b[:n], err)
return n, err
}
return n, nil
}
// EncodeEnum treats the passed 32-bit signed integer as an enumeration value
// and, if it is in the list of passed valid enumeration values, writes the XDR
// encoded representation of it to the encapsulated writer. It returns the
// number of bytes written.
//
// A MarshalError is returned if the enumeration value is not one of the
// provided valid values or if writing the data fails.
//
// Reference:
// RFC Section 4.3 - Enumeration
// Represented as an XDR encoded signed integer
func (enc *Encoder) EncodeEnum(v int32, validEnums map[int32]bool) (int, error) {
if !validEnums[v] {
err := marshalError("EncodeEnum", ErrBadEnumValue,
"invalid enum", v, nil)
return 0, err
}
return enc.EncodeInt(v)
}
// EncodeBool writes the XDR encoded representation of the passed boolean to the
// encapsulated writer and returns the number of bytes written.
//
// A MarshalError with an error code of ErrIO is returned if writing the data
// fails.
//
// Reference:
// RFC Section 4.4 - Boolean
// Represented as an XDR encoded enumeration where 0 is false and 1 is true
func (enc *Encoder) EncodeBool(v bool) (int, error) {
i := int32(0)
if v == true {
i = 1
}
return enc.EncodeInt(i)
}
// EncodeHyper writes the XDR encoded representation of the passed 64-bit
// signed integer to the encapsulated writer and returns the number of bytes
// written.
//
// A MarshalError with an error code of ErrIO is returned if writing the data
// fails.
//
// Reference:
// RFC Section 4.5 - Hyper Integer
// 64-bit big-endian signed integer in range [-9223372036854775808, 9223372036854775807]
func (enc *Encoder) EncodeHyper(v int64) (int, error) {
var b [8]byte
b[0] = byte(v >> 56)
b[1] = byte(v >> 48)
b[2] = byte(v >> 40)
b[3] = byte(v >> 32)
b[4] = byte(v >> 24)
b[5] = byte(v >> 16)
b[6] = byte(v >> 8)
b[7] = byte(v)
n, err := enc.w.Write(b[:])
if err != nil {
msg := fmt.Sprintf(errIOEncode, err.Error(), 8)
err := marshalError("EncodeHyper", ErrIO, msg, b[:n], err)
return n, err
}
return n, nil
}
// EncodeUhyper writes the XDR encoded representation of the passed 64-bit
// unsigned integer to the encapsulated writer and returns the number of bytes
// written.
//
// A MarshalError with an error code of ErrIO is returned if writing the data
// fails.
//
// Reference:
// RFC Section 4.5 - Unsigned Hyper Integer
// 64-bit big-endian unsigned integer in range [0, 18446744073709551615]
func (enc *Encoder) EncodeUhyper(v uint64) (int, error) {
var b [8]byte
b[0] = byte(v >> 56)
b[1] = byte(v >> 48)
b[2] = byte(v >> 40)
b[3] = byte(v >> 32)
b[4] = byte(v >> 24)
b[5] = byte(v >> 16)
b[6] = byte(v >> 8)
b[7] = byte(v)
n, err := enc.w.Write(b[:])
if err != nil {
msg := fmt.Sprintf(errIOEncode, err.Error(), 8)
err := marshalError("EncodeUhyper", ErrIO, msg, b[:n], err)
return n, err
}
return n, nil
}
// EncodeFloat writes the XDR encoded representation of the passed 32-bit
// (single-precision) floating point to the encapsulated writer and returns the
// number of bytes written.
//
// A MarshalError with an error code of ErrIO is returned if writing the data
// fails.
//
// Reference:
// RFC Section 4.6 - Floating Point
// 32-bit single-precision IEEE 754 floating point
func (enc *Encoder) EncodeFloat(v float32) (int, error) {
ui := math.Float32bits(v)
return enc.EncodeUint(ui)
}
// EncodeDouble writes the XDR encoded representation of the passed 64-bit
// (double-precision) floating point to the encapsulated writer and returns the
// number of bytes written.
//
// A MarshalError with an error code of ErrIO is returned if writing the data
// fails.
//
// Reference:
// RFC Section 4.7 - Double-Precision Floating Point
// 64-bit double-precision IEEE 754 floating point
func (enc *Encoder) EncodeDouble(v float64) (int, error) {
ui := math.Float64bits(v)
return enc.EncodeUhyper(ui)
}
// RFC Section 4.8 - Quadruple-Precision Floating Point
// 128-bit quadruple-precision floating point
// Not Implemented
// EncodeFixedOpaque treats the passed byte slice as opaque data of a fixed
// size and writes the XDR encoded representation of it to the encapsulated
// writer. It returns the number of bytes written.
//
// A MarshalError with an error code of ErrIO is returned if writing the data
// fails.
//
// Reference:
// RFC Section 4.9 - Fixed-Length Opaque Data
// Fixed-length uninterpreted data zero-padded to a multiple of four
func (enc *Encoder) EncodeFixedOpaque(v []byte) (int, error) {
l := len(v)
pad := (4 - (l % 4)) % 4
// Write the actual bytes.
n, err := enc.w.Write(v)
if err != nil {
msg := fmt.Sprintf(errIOEncode, err.Error(), len(v))
err := marshalError("EncodeFixedOpaque", ErrIO, msg, v[:n], err)
return n, err
}
// Write any padding if needed.
if pad > 0 {
b := make([]byte, pad)
n2, err := enc.w.Write(b)
n += n2
if err != nil {
written := make([]byte, l+n2)
copy(written, v)
copy(written[l:], b[:n2])
msg := fmt.Sprintf(errIOEncode, err.Error(), l+pad)
err := marshalError("EncodeFixedOpaque", ErrIO, msg,
written, err)
return n, err
}
}
return n, nil
}
// EncodeOpaque treats the passed byte slice as opaque data of a variable
// size and writes the XDR encoded representation of it to the encapsulated
// writer. It returns the number of bytes written.
//
// A MarshalError with an error code of ErrIO is returned if writing the data
// fails.
//
// Reference:
// RFC Section 4.10 - Variable-Length Opaque Data
// Unsigned integer length followed by fixed opaque data of that length
func (enc *Encoder) EncodeOpaque(v []byte) (int, error) {
// Length of opaque data.
n, err := enc.EncodeUint(uint32(len(v)))
if err != nil {
return n, err
}
n2, err := enc.EncodeFixedOpaque(v)
n += n2
return n, err
}
// EncodeString writes the XDR encoded representation of the passed string
// to the encapsulated writer and returns the number of bytes written.
// Character encoding is assumed to be UTF-8 and therefore ASCII compatible. If
// the underlying character encoding is not compatible with this assumption, the
// data can instead be written as variable-length opaque data (EncodeOpaque) and
// manually converted as needed.
//
// A MarshalError with an error code of ErrIO is returned if writing the data
// fails.
//
// Reference:
// RFC Section 4.11 - String
// Unsigned integer length followed by bytes zero-padded to a multiple of four
func (enc *Encoder) EncodeString(v string) (int, error) {
// Length of string.
n, err := enc.EncodeUint(uint32(len(v)))
if err != nil {
return n, err
}
n2, err := enc.EncodeFixedOpaque([]byte(v))
n += n2
return n, err
}
// encodeFixedArray writes the XDR encoded representation of each element
// in the passed array represented by the reflection value to the encapsulated
// writer and returns the number of bytes written. The ignoreOpaque flag
// controls whether or not uint8 (byte) elements should be encoded individually
// or as a fixed sequence of opaque data.
//
// A MarshalError is returned if any issues are encountered while encoding
// the array elements.
//
// Reference:
// RFC Section 4.12 - Fixed-Length Array
// Individually XDR encoded array elements
func (enc *Encoder) encodeFixedArray(v reflect.Value, ignoreOpaque bool) (int, error) {
// Treat [#]byte (byte is alias for uint8) as opaque data unless ignored.
if !ignoreOpaque && v.Type().Elem().Kind() == reflect.Uint8 {
// Create a slice of the underlying array for better efficiency
// when possible. Can't create a slice of an unaddressable
// value.
if v.CanAddr() {
return enc.EncodeFixedOpaque(v.Slice(0, v.Len()).Bytes())
}
// When the underlying array isn't addressable fall back to
// copying the array into a new slice. This is rather ugly, but
// the inability to create a constant slice from an
// unaddressable array is a limitation of Go.
slice := make([]byte, v.Len(), v.Len())
reflect.Copy(reflect.ValueOf(slice), v)
return enc.EncodeFixedOpaque(slice)
}
// Encode each array element.
var n int
for i := 0; i < v.Len(); i++ {
n2, err := enc.encode(v.Index(i))
n += n2
if err != nil {
return n, err
}
}
return n, nil
}
// encodeArray writes an XDR encoded integer representing the number of
// elements in the passed slice represented by the reflection value followed by
// the XDR encoded representation of each element in slice to the encapsulated
// writer and returns the number of bytes written. The ignoreOpaque flag
// controls whether or not uint8 (byte) elements should be encoded individually
// or as a variable sequence of opaque data.
//
// A MarshalError is returned if any issues are encountered while encoding
// the array elements.
//
// Reference:
// RFC Section 4.13 - Variable-Length Array
// Unsigned integer length followed by individually XDR encoded array elements
func (enc *Encoder) encodeArray(v reflect.Value, ignoreOpaque bool) (int, error) {
numItems := uint32(v.Len())
n, err := enc.EncodeUint(numItems)
if err != nil {
return n, err
}
n2, err := enc.encodeFixedArray(v, ignoreOpaque)
n += n2
return n, err
}
// encodeStruct writes an XDR encoded representation of each value in the
// exported fields of the struct represented by the passed reflection value to
// the encapsulated writer and returns the number of bytes written. Pointers
// are automatically indirected through arbitrary depth to encode the actual
// value pointed to.
//
// A MarshalError is returned if any issues are encountered while encoding
// the elements.
//
// Reference:
// RFC Section 4.14 - Structure
// XDR encoded elements in the order of their declaration in the struct
func (enc *Encoder) encodeStruct(v reflect.Value) (int, error) {
var n int
vt := v.Type()
for i := 0; i < v.NumField(); i++ {
// Skip unexported fields and indirect through pointers.
vtf := vt.Field(i)
if vtf.PkgPath != "" {
continue
}
vf := v.Field(i)
vf = enc.indirect(vf)
// Handle non-opaque data to []uint8 and [#]uint8 based on struct tag.
tag := vtf.Tag.Get("xdropaque")
if tag == "false" {
switch vf.Kind() {
case reflect.Slice:
n2, err := enc.encodeArray(vf, true)
n += n2
if err != nil {
return n, err
}
continue
case reflect.Array:
n2, err := enc.encodeFixedArray(vf, true)
n += n2
if err != nil {
return n, err
}
continue
}
}
// Encode each struct field.
n2, err := enc.encode(vf)
n += n2
if err != nil {
return n, err
}
}
return n, nil
}
// RFC Section 4.15 - Discriminated Union
// RFC Section 4.16 - Void
// RFC Section 4.17 - Constant
// RFC Section 4.18 - Typedef
// RFC Section 4.19 - Optional data
// RFC Sections 4.15 though 4.19 only apply to the data specification language
// which is not implemented by this package. In the case of discriminated
// unions, struct tags are used to perform a similar function.
// encodeMap treats the map represented by the passed reflection value as a
// variable-length array of 2-element structures whose fields are of the same
// type as the map keys and elements and writes its XDR encoded representation
// to the encapsulated writer. It returns the number of bytes written.
//
// A MarshalError is returned if any issues are encountered while encoding
// the elements.
func (enc *Encoder) encodeMap(v reflect.Value) (int, error) {
// Number of elements.
n, err := enc.EncodeUint(uint32(v.Len()))
if err != nil {
return n, err
}
// Encode each key and value according to their type.
for _, key := range v.MapKeys() {
n2, err := enc.encode(key)
n += n2
if err != nil {
return n, err
}
n2, err = enc.encode(v.MapIndex(key))
n += n2
if err != nil {
return n, err
}
}
return n, nil
}
// encodeInterface examines the interface represented by the passed reflection
// value to detect whether it is an interface that can be encoded if it is,
// extracts the underlying value to pass back into the encode function for
// encoding according to its type.
//
// A MarshalError is returned if any issues are encountered while encoding
// the interface.
func (enc *Encoder) encodeInterface(v reflect.Value) (int, error) {
if v.IsNil() || !v.CanInterface() {
msg := fmt.Sprintf("can't encode nil interface")
err := marshalError("encodeInterface", ErrNilInterface, msg,
nil, nil)
return 0, err
}
// Extract underlying value from the interface and indirect through pointers.
ve := reflect.ValueOf(v.Interface())
ve = enc.indirect(ve)
return enc.encode(ve)
}
// encode is the main workhorse for marshalling via reflection. It uses
// the passed reflection value to choose the XDR primitives to encode into
// the encapsulated writer and returns the number of bytes written. It is a
// recursive function, so cyclic data structures are not supported and will
// result in an infinite loop.
func (enc *Encoder) encode(v reflect.Value) (int, error) {
if !v.IsValid() {
msg := fmt.Sprintf("type '%s' is not valid", v.Kind().String())
err := marshalError("encode", ErrUnsupportedType, msg, nil, nil)
return 0, err
}
// Indirect through pointers to get at the concrete value.
ve := enc.indirect(v)
// Handle time.Time values by encoding them as an RFC3339 formatted
// string with nanosecond precision. Check the type string before
// doing a full blown conversion to interface and type assertion since
// checking a string is much quicker.
if ve.Type().String() == "time.Time" && ve.CanInterface() {
viface := ve.Interface()
if tv, ok := viface.(time.Time); ok {
return enc.EncodeString(tv.Format(time.RFC3339Nano))
}
}
// Handle native Go types.
switch ve.Kind() {
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int:
return enc.EncodeInt(int32(ve.Int()))
case reflect.Int64:
return enc.EncodeHyper(ve.Int())
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint:
return enc.EncodeUint(uint32(ve.Uint()))
case reflect.Uint64:
return enc.EncodeUhyper(ve.Uint())
case reflect.Bool:
return enc.EncodeBool(ve.Bool())
case reflect.Float32:
return enc.EncodeFloat(float32(ve.Float()))
case reflect.Float64:
return enc.EncodeDouble(ve.Float())
case reflect.String:
return enc.EncodeString(ve.String())
case reflect.Array:
return enc.encodeFixedArray(ve, false)
case reflect.Slice:
return enc.encodeArray(ve, false)
case reflect.Struct:
return enc.encodeStruct(ve)
case reflect.Map:
return enc.encodeMap(ve)
case reflect.Interface:
return enc.encodeInterface(ve)
}
// The only unhandled types left are unsupported. At the time of this
// writing the only remaining unsupported types that exist are
// reflect.Uintptr and reflect.UnsafePointer.
msg := fmt.Sprintf("unsupported Go type '%s'", ve.Kind().String())
err := marshalError("encode", ErrUnsupportedType, msg, nil, nil)
return 0, err
}
// indirect dereferences pointers until it reaches a non-pointer. This allows
// transparent encoding through arbitrary levels of indirection.
func (enc *Encoder) indirect(v reflect.Value) reflect.Value {
rv := v
for rv.Kind() == reflect.Ptr {
rv = rv.Elem()
}
return rv
}
// Encode operates identically to the Marshal function with the exception of
// using the writer associated with the Encoder for the destination of the
// XDR-encoded data instead of a user-supplied writer. See the Marshal
// documentation for specifics.
func (enc *Encoder) Encode(v interface{}) (int, error) {
if v == nil {
msg := "can't marshal nil interface"
err := marshalError("Marshal", ErrNilInterface, msg, nil, nil)
return 0, err
}
vv := reflect.ValueOf(v)
vve := vv
for vve.Kind() == reflect.Ptr {
if vve.IsNil() {
msg := fmt.Sprintf("can't marshal nil pointer '%v'",
vv.Type().String())
err := marshalError("Marshal", ErrBadArguments, msg,
nil, nil)
return 0, err
}
vve = vve.Elem()
}
return enc.encode(vve)
}
// NewEncoder returns an object that can be used to manually choose fields to
// XDR encode to the passed writer w. Typically, Marshal should be used instead
// of manually creating an Encoder. An Encoder, along with several of its
// methods to encode XDR primitives, is exposed so it is possible to perform
// manual encoding of data without relying on reflection should it be necessary
// in complex scenarios where automatic reflection-based encoding won't work.
func NewEncoder(w io.Writer) *Encoder {
return &Encoder{w: w}
}
+177
View File
@@ -0,0 +1,177 @@
/*
* Copyright (c) 2012-2014 Dave Collins <dave@davec.name>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package xdr
import "fmt"
// ErrorCode identifies a kind of error.
type ErrorCode int
const (
// ErrBadArguments indicates arguments passed to the function are not
// what was expected.
ErrBadArguments ErrorCode = iota
// ErrUnsupportedType indicates the Go type is not a supported type for
// marshalling and unmarshalling XDR data.
ErrUnsupportedType
// ErrBadEnumValue indicates an enumeration value is not in the list of
// valid values.
ErrBadEnumValue
// ErrNotSettable indicates an interface value cannot be written to.
// This usually means the interface value was not passed with the &
// operator, but it can also happen if automatic pointer allocation
// fails.
ErrNotSettable
// ErrOverflow indicates that the data in question is too large to fit
// into the corresponding Go or XDR data type. For example, an integer
// decoded from XDR that is too large to fit into a target type of int8,
// or opaque data that exceeds the max length of a Go slice.
ErrOverflow
// ErrNilInterface indicates an interface with no concrete type
// information was encountered. Type information is necessary to
// perform mapping between XDR and Go types.
ErrNilInterface
// ErrIO indicates an error was encountered while reading or writing to
// an io.Reader or io.Writer, respectively. The actual underlying error
// will be available via the Err field of the MarshalError or
// UnmarshalError struct.
ErrIO
// ErrParseTime indicates an error was encountered while parsing an
// RFC3339 formatted time value. The actual underlying error will be
// available via the Err field of the UnmarshalError struct.
ErrParseTime
)
// Map of ErrorCode values back to their constant names for pretty printing.
var errorCodeStrings = map[ErrorCode]string{
ErrBadArguments: "ErrBadArguments",
ErrUnsupportedType: "ErrUnsupportedType",
ErrBadEnumValue: "ErrBadEnumValue",
ErrNotSettable: "ErrNotSettable",
ErrOverflow: "ErrOverflow",
ErrNilInterface: "ErrNilInterface",
ErrIO: "ErrIO",
ErrParseTime: "ErrParseTime",
}
// String returns the ErrorCode as a human-readable name.
func (e ErrorCode) String() string {
if s := errorCodeStrings[e]; s != "" {
return s
}
return fmt.Sprintf("Unknown ErrorCode (%d)", e)
}
// UnmarshalError describes a problem encountered while unmarshaling data.
// Some potential issues are unsupported Go types, attempting to decode a value
// which is too large to fit into a specified Go type, and exceeding max slice
// limitations.
type UnmarshalError struct {
ErrorCode ErrorCode // Describes the kind of error
Func string // Function name
Value interface{} // Value actually parsed where appropriate
Description string // Human readable description of the issue
Err error // The underlying error for IO errors
}
// Error satisfies the error interface and prints human-readable errors.
func (e *UnmarshalError) Error() string {
switch e.ErrorCode {
case ErrBadEnumValue, ErrOverflow, ErrIO, ErrParseTime:
return fmt.Sprintf("xdr:%s: %s - read: '%v'", e.Func,
e.Description, e.Value)
}
return fmt.Sprintf("xdr:%s: %s", e.Func, e.Description)
}
// unmarshalError creates an error given a set of arguments and will copy byte
// slices into the Value field since they might otherwise be changed from from
// the original value.
func unmarshalError(f string, c ErrorCode, desc string, v interface{}, err error) *UnmarshalError {
e := &UnmarshalError{ErrorCode: c, Func: f, Description: desc, Err: err}
switch t := v.(type) {
case []byte:
slice := make([]byte, len(t))
copy(slice, t)
e.Value = slice
default:
e.Value = v
}
return e
}
// IsIO returns a boolean indicating whether the error is known to report that
// the underlying reader or writer encountered an ErrIO.
func IsIO(err error) bool {
switch e := err.(type) {
case *UnmarshalError:
return e.ErrorCode == ErrIO
case *MarshalError:
return e.ErrorCode == ErrIO
}
return false
}
// MarshalError describes a problem encountered while marshaling data.
// Some potential issues are unsupported Go types, attempting to encode more
// opaque data than can be represented by a single opaque XDR entry, and
// exceeding max slice limitations.
type MarshalError struct {
ErrorCode ErrorCode // Describes the kind of error
Func string // Function name
Value interface{} // Value actually parsed where appropriate
Description string // Human readable description of the issue
Err error // The underlying error for IO errors
}
// Error satisfies the error interface and prints human-readable errors.
func (e *MarshalError) Error() string {
switch e.ErrorCode {
case ErrIO:
return fmt.Sprintf("xdr:%s: %s - wrote: '%v'", e.Func,
e.Description, e.Value)
case ErrBadEnumValue:
return fmt.Sprintf("xdr:%s: %s - value: '%v'", e.Func,
e.Description, e.Value)
}
return fmt.Sprintf("xdr:%s: %s", e.Func, e.Description)
}
// marshalError creates an error given a set of arguments and will copy byte
// slices into the Value field since they might otherwise be changed from from
// the original value.
func marshalError(f string, c ErrorCode, desc string, v interface{}, err error) *MarshalError {
e := &MarshalError{ErrorCode: c, Func: f, Description: desc, Err: err}
switch t := v.(type) {
case []byte:
slice := make([]byte, len(t))
copy(slice, t)
e.Value = slice
default:
e.Value = v
}
return e
}
+890
View File
@@ -0,0 +1,890 @@
// Copyright 2018 The go-libvirt Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package libvirt
// We'll use c-for-go to extract the consts and typedefs from the libvirt
// sources so we don't have to duplicate them here.
//go:generate scripts/gen-consts.sh
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"net"
"sync"
"syscall"
"time"
"github.com/digitalocean/go-libvirt/internal/constants"
"github.com/digitalocean/go-libvirt/internal/event"
xdr "github.com/digitalocean/go-libvirt/internal/go-xdr/xdr2"
"github.com/digitalocean/go-libvirt/socket"
"github.com/digitalocean/go-libvirt/socket/dialers"
)
// ErrEventsNotSupported is returned by Events() if event streams
// are unsupported by either QEMU or libvirt.
var ErrEventsNotSupported = errors.New("event monitor is not supported")
// ConnectURI defines a type for driver URIs for libvirt
// the defined constants are *not* exhaustive as there are also options
// e.g. to connect remote via SSH
type ConnectURI string
const (
// QEMUSystem connects to a QEMU system mode daemon
QEMUSystem ConnectURI = "qemu:///system"
// QEMUSession connects to a QEMU session mode daemon (unprivileged)
QEMUSession ConnectURI = "qemu:///session"
// XenSystem connects to a Xen system mode daemon
XenSystem ConnectURI = "xen:///system"
//TestDefault connect to default mock driver
TestDefault ConnectURI = "test:///default"
// disconnectedTimeout is how long to wait for disconnect cleanup to
// complete
disconnectTimeout = 5 * time.Second
)
// Libvirt implements libvirt's remote procedure call protocol.
type Libvirt struct {
// socket connection
socket *socket.Socket
// closed after cleanup complete following the underlying connection to
// libvirt being disconnected.
disconnected chan struct{}
// method callbacks
cmux sync.RWMutex
callbacks map[int32]chan response
// event listeners
emux sync.RWMutex
events map[int32]*event.Stream
// next request serial number
s int32
}
// DomainEvent represents a libvirt domain event.
type DomainEvent struct {
CallbackID int32
Domain Domain
Event string
Seconds uint64
Microseconds uint32
Padding uint8
Details []byte
}
// GetCallbackID returns the callback ID of a QEMU domain event.
func (de DomainEvent) GetCallbackID() int32 {
return de.CallbackID
}
// GetCallbackID returns the callback ID of a libvirt lifecycle event.
func (m DomainEventCallbackLifecycleMsg) GetCallbackID() int32 {
return m.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackRebootMsg) GetCallbackID() int32 {
return e.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackRtcChangeMsg) GetCallbackID() int32 {
return e.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackWatchdogMsg) GetCallbackID() int32 {
return e.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackIOErrorMsg) GetCallbackID() int32 {
return e.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackIOErrorReasonMsg) GetCallbackID() int32 {
return e.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackGraphicsMsg) GetCallbackID() int32 {
return e.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackBlockJobMsg) GetCallbackID() int32 {
return e.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackDiskChangeMsg) GetCallbackID() int32 {
return e.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackTrayChangeMsg) GetCallbackID() int32 {
return e.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackPmwakeupMsg) GetCallbackID() int32 {
return e.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackPmsuspendMsg) GetCallbackID() int32 {
return e.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackBalloonChangeMsg) GetCallbackID() int32 {
return e.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackPmsuspendDiskMsg) GetCallbackID() int32 {
return e.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackControlErrorMsg) GetCallbackID() int32 {
return e.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackDeviceRemovedMsg) GetCallbackID() int32 {
return e.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackTunableMsg) GetCallbackID() int32 {
return e.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackDeviceAddedMsg) GetCallbackID() int32 {
return e.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackAgentLifecycleMsg) GetCallbackID() int32 {
return e.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackMigrationIterationMsg) GetCallbackID() int32 {
return e.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackJobCompletedMsg) GetCallbackID() int32 {
return e.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackDeviceRemovalFailedMsg) GetCallbackID() int32 {
return e.CallbackID
}
// GetCallbackID returns the callback ID.
func (e *DomainEventCallbackMetadataChangeMsg) GetCallbackID() int32 {
return e.CallbackID
}
// qemuError represents a QEMU process error.
type qemuError struct {
Error struct {
Class string `json:"class"`
Description string `json:"desc"`
} `json:"error"`
}
// Capabilities returns an XML document describing the host's capabilties.
func (l *Libvirt) Capabilities() ([]byte, error) {
caps, err := l.ConnectGetCapabilities()
return []byte(caps), err
}
// called at connection time, authenticating with all supported auth types
func (l *Libvirt) authenticate() error {
// libvirt requires that we call auth-list prior to connecting,
// even when no authentication is used.
resp, err := l.AuthList()
if err != nil {
return err
}
for _, auth := range resp {
switch auth {
case constants.AuthNone:
case constants.AuthPolkit:
_, err := l.AuthPolkit()
if err != nil {
return err
}
default:
continue
}
break
}
return nil
}
func (l *Libvirt) initLibvirtComms(uri ConnectURI) error {
payload := struct {
Padding [3]byte
Name string
Flags uint32
}{
Padding: [3]byte{0x1, 0x0, 0x0},
Name: string(uri),
Flags: 0,
}
buf, err := encode(&payload)
if err != nil {
return err
}
err = l.authenticate()
if err != nil {
return err
}
_, err = l.request(constants.ProcConnectOpen, constants.Program, buf)
if err != nil {
return err
}
return nil
}
// ConnectToURI establishes communication with the specified libvirt driver
// The underlying libvirt socket connection will be created via the dialer.
// Since the connection can be lost, the Disconnected function can be used
// to monitor for a lost connection.
func (l *Libvirt) ConnectToURI(uri ConnectURI) error {
err := l.socket.Connect()
if err != nil {
return err
}
// Start watching the underlying socket connection immediately.
// If we don't, and Libvirt goes away partway through initLibvirtComms,
// then the callbacks that initLibvirtComms has registered will never
// be closed, and therefore it will be stuck waiting for data from a
// channel that will never arrive.
go l.waitAndDisconnect()
err = l.initLibvirtComms(uri)
if err != nil {
l.socket.Disconnect()
return err
}
l.disconnected = make(chan struct{})
return nil
}
// Connect establishes communication with the libvirt server.
// The underlying libvirt socket connection will be created via the dialer.
// Since the connection can be lost, the Disconnected function can be used
// to monitor for a lost connection.
func (l *Libvirt) Connect() error {
return l.ConnectToURI(QEMUSystem)
}
// Disconnect shuts down communication with the libvirt server and closes the
// underlying net.Conn.
func (l *Libvirt) Disconnect() error {
// Ordering is important here. We want to make sure the connection is closed
// before unsubscribing and deregistering the events and requests, to
// prevent new requests from racing.
_, err := l.request(constants.ProcConnectClose, constants.Program, nil)
// syscall.EINVAL is returned by the socket pkg when things have already
// been disconnected.
if err != nil && err != syscall.EINVAL {
return err
}
err = l.socket.Disconnect()
if err != nil {
return err
}
// wait for the listen goroutine to detect the lost connection and clean up
// to happen once it returns. Safeguard with a timeout.
// Things not fully cleaned up is better than a deadlock.
select {
case <-l.disconnected:
case <-time.After(disconnectTimeout):
}
return err
}
// Disconnected allows callers to detect if the underlying connection
// to libvirt has been closed. If the returned channel is closed, then
// the connection to libvirt has been lost (or disconnected intentionally).
func (l *Libvirt) Disconnected() <-chan struct{} {
return l.disconnected
}
// IsConnected indicates whether or not there is currently a connection to
// libvirtd.
func (l *Libvirt) IsConnected() bool {
select {
case <-l.Disconnected():
return false
default:
return true
}
}
// Domains returns a list of all domains managed by libvirt.
//
// Deprecated: use ConnectListAllDomains instead.
func (l *Libvirt) Domains() ([]Domain, error) {
// these are the flags as passed by `virsh list --all`
flags := ConnectListDomainsActive | ConnectListDomainsInactive
domains, _, err := l.ConnectListAllDomains(1, flags)
return domains, err
}
// DomainState returns state of the domain managed by libvirt.
//
// Deprecated: use DomainGetState instead.
func (l *Libvirt) DomainState(dom string) (DomainState, error) {
d, err := l.lookup(dom)
if err != nil {
return DomainNostate, err
}
state, _, err := l.DomainGetState(d, 0)
return DomainState(state), err
}
// SubscribeQEMUEvents streams domain events until the provided context is
// cancelled. If a problem is encountered setting up the event monitor
// connection an error will be returned. Errors encountered during streaming
// will cause the returned event channel to be closed. QEMU domain events.
func (l *Libvirt) SubscribeQEMUEvents(ctx context.Context, dom string) (<-chan DomainEvent, error) {
d, err := l.lookup(dom)
if err != nil {
return nil, err
}
callbackID, err := l.QEMUConnectDomainMonitorEventRegister([]Domain{d}, nil, 0)
if err != nil {
return nil, err
}
stream := event.NewStream(constants.QEMUProgram, callbackID)
l.addStream(stream)
ch := make(chan DomainEvent)
go func() {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
defer l.unsubscribeQEMUEvents(stream)
defer stream.Shutdown()
defer close(ch)
for {
select {
case ev, ok := <-stream.Recv():
if !ok {
return
}
ch <- *ev.(*DomainEvent)
case <-ctx.Done():
return
}
}
}()
return ch, nil
}
// unsubscribeQEMUEvents stops the flow of events from QEMU through libvirt.
func (l *Libvirt) unsubscribeQEMUEvents(stream *event.Stream) error {
err := l.QEMUConnectDomainMonitorEventDeregister(stream.CallbackID)
l.removeStream(stream.CallbackID)
return err
}
// SubscribeEvents allows the caller to subscribe to any of the event types
// supported by libvirt. The events will continue to be streamed until the
// caller cancels the provided context. After canceling the context, callers
// should wait until the channel is closed to be sure they're collected all the
// events.
func (l *Libvirt) SubscribeEvents(ctx context.Context, eventID DomainEventID,
dom OptDomain) (<-chan interface{}, error) {
callbackID, err := l.ConnectDomainEventCallbackRegisterAny(int32(eventID), nil)
if err != nil {
return nil, err
}
stream := event.NewStream(constants.QEMUProgram, callbackID)
l.addStream(stream)
ch := make(chan interface{})
go func() {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
defer l.unsubscribeEvents(stream)
defer stream.Shutdown()
defer func() { close(ch) }()
for {
select {
case ev, ok := <-stream.Recv():
if !ok {
return
}
ch <- ev
case <-ctx.Done():
return
}
}
}()
return ch, nil
}
// unsubscribeEvents stops the flow of the specified events from libvirt. There
// are two steps to this process: a call to libvirt to deregister our callback,
// and then removing the callback from the list used by the `Route` function. If
// the deregister call fails, we'll return the error, but still remove the
// callback from the list. That's ok; if any events arrive after this point, the
// Route function will drop them when it finds no registered handler.
func (l *Libvirt) unsubscribeEvents(stream *event.Stream) error {
err := l.ConnectDomainEventCallbackDeregisterAny(stream.CallbackID)
l.removeStream(stream.CallbackID)
return err
}
// LifecycleEvents streams lifecycle events until the provided context is
// cancelled. If a problem is encountered setting up the event monitor
// connection, an error will be returned. Errors encountered during streaming
// will cause the returned event channel to be closed.
func (l *Libvirt) LifecycleEvents(ctx context.Context) (<-chan DomainEventLifecycleMsg, error) {
callbackID, err := l.ConnectDomainEventCallbackRegisterAny(int32(DomainEventIDLifecycle), nil)
if err != nil {
return nil, err
}
stream := event.NewStream(constants.Program, callbackID)
l.addStream(stream)
ch := make(chan DomainEventLifecycleMsg)
go func() {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
defer l.unsubscribeEvents(stream)
defer stream.Shutdown()
defer func() { close(ch) }()
for {
select {
case ev, ok := <-stream.Recv():
if !ok {
return
}
ch <- ev.(*DomainEventCallbackLifecycleMsg).Msg
case <-ctx.Done():
return
}
}
}()
return ch, nil
}
// Run executes the given QAPI command against a domain's QEMU instance.
// For a list of available QAPI commands, see:
// http://git.qemu.org/?p=qemu.git;a=blob;f=qapi-schema.json;hb=HEAD
func (l *Libvirt) Run(dom string, cmd []byte) ([]byte, error) {
d, err := l.lookup(dom)
if err != nil {
return nil, err
}
payload := struct {
Domain Domain
Command []byte
Flags uint32
}{
Domain: d,
Command: cmd,
Flags: 0,
}
buf, err := encode(&payload)
if err != nil {
return nil, err
}
res, err := l.request(constants.QEMUProcDomainMonitorCommand, constants.QEMUProgram, buf)
if err != nil {
return nil, err
}
// check for QEMU process errors
if err = getQEMUError(res); err != nil {
return nil, err
}
r := bytes.NewReader(res.Payload)
dec := xdr.NewDecoder(r)
data, _, err := dec.DecodeFixedOpaque(int32(r.Len()))
if err != nil {
return nil, err
}
// drop QMP control characters from start of line, and drop
// any trailing NULL characters from the end
return bytes.TrimRight(data[4:], "\x00"), nil
}
// Secrets returns all secrets managed by the libvirt daemon.
//
// Deprecated: use ConnectListAllSecrets instead.
func (l *Libvirt) Secrets() ([]Secret, error) {
secrets, _, err := l.ConnectListAllSecrets(1, 0)
return secrets, err
}
// StoragePool returns the storage pool associated with the provided name.
// An error is returned if the requested storage pool is not found.
//
// Deprecated: use StoragePoolLookupByName instead.
func (l *Libvirt) StoragePool(name string) (StoragePool, error) {
return l.StoragePoolLookupByName(name)
}
// StoragePools returns a list of defined storage pools. Pools are filtered by
// the provided flags. See StoragePools*.
//
// Deprecated: use ConnectListAllStoragePools instead.
func (l *Libvirt) StoragePools(flags ConnectListAllStoragePoolsFlags) ([]StoragePool, error) {
pools, _, err := l.ConnectListAllStoragePools(1, flags)
return pools, err
}
// Undefine undefines the domain specified by dom, e.g., 'prod-lb-01'.
// The flags argument allows additional options to be specified such as
// cleaning up snapshot metadata. For more information on available
// flags, see DomainUndefine*.
//
// Deprecated: use DomainUndefineFlags instead.
func (l *Libvirt) Undefine(dom string, flags DomainUndefineFlagsValues) error {
d, err := l.lookup(dom)
if err != nil {
return err
}
return l.DomainUndefineFlags(d, flags)
}
// Destroy destroys the domain specified by dom, e.g., 'prod-lb-01'.
// The flags argument allows additional options to be specified such as
// allowing a graceful shutdown with SIGTERM than SIGKILL.
// For more information on available flags, see DomainDestroy*.
//
// Deprecated: use DomainDestroyFlags instead.
func (l *Libvirt) Destroy(dom string, flags DomainDestroyFlagsValues) error {
d, err := l.lookup(dom)
if err != nil {
return err
}
return l.DomainDestroyFlags(d, flags)
}
// XML returns a domain's raw XML definition, akin to `virsh dumpxml <domain>`.
// See DomainXMLFlag* for optional flags.
//
// Deprecated: use DomainGetXMLDesc instead.
func (l *Libvirt) XML(dom string, flags DomainXMLFlags) ([]byte, error) {
d, err := l.lookup(dom)
if err != nil {
return nil, err
}
xml, err := l.DomainGetXMLDesc(d, flags)
return []byte(xml), err
}
// DefineXML defines a domain, but does not start it.
//
// Deprecated: use DomainDefineXMLFlags instead.
func (l *Libvirt) DefineXML(x []byte, flags DomainDefineFlags) error {
_, err := l.DomainDefineXMLFlags(string(x), flags)
return err
}
// Version returns the version of the libvirt daemon.
//
// Deprecated: use ConnectGetLibVersion instead.
func (l *Libvirt) Version() (string, error) {
ver, err := l.ConnectGetLibVersion()
if err != nil {
return "", err
}
// The version is provided as an int following this formula:
// version * 1,000,000 + minor * 1000 + micro
// See src/libvirt-host.c # virConnectGetLibVersion
major := ver / 1000000
ver %= 1000000
minor := ver / 1000
ver %= 1000
micro := ver
versionString := fmt.Sprintf("%d.%d.%d", major, minor, micro)
return versionString, nil
}
// Shutdown shuts down a domain. Note that the guest OS may ignore the request.
// If flags is set to 0 then the hypervisor will choose the method of shutdown it considers best.
//
// Deprecated: use DomainShutdownFlags instead.
func (l *Libvirt) Shutdown(dom string, flags DomainShutdownFlagValues) error {
d, err := l.lookup(dom)
if err != nil {
return err
}
return l.DomainShutdownFlags(d, flags)
}
// Reboot reboots the domain. Note that the guest OS may ignore the request.
// If flags is set to zero, then the hypervisor will choose the method of shutdown it considers best.
//
// Deprecated: use DomainReboot instead.
func (l *Libvirt) Reboot(dom string, flags DomainRebootFlagValues) error {
d, err := l.lookup(dom)
if err != nil {
return err
}
return l.DomainReboot(d, flags)
}
// Reset resets domain immediately without any guest OS shutdown
//
// Deprecated: use DomainReset instead.
func (l *Libvirt) Reset(dom string) error {
d, err := l.lookup(dom)
if err != nil {
return err
}
return l.DomainReset(d, 0)
}
// BlockLimit contains a name and value pair for a Get/SetBlockIOTune limit. The
// Name field is the name of the limit (to see a list of the limits that can be
// applied, execute the 'blkdeviotune' command on a VM in virsh). Callers can
// use the QEMUBlockIO... constants below for the Name value. The Value field is
// the limit to apply.
type BlockLimit struct {
Name string
Value uint64
}
// SetBlockIOTune changes the per-device block I/O tunables within a guest.
// Parameters are the name of the VM, the name of the disk device to which the
// limits should be applied, and 1 or more BlockLimit structs containing the
// actual limits.
//
// The limits which can be applied here are enumerated in the QEMUBlockIO...
// constants above, and you can also see the full list by executing the
// 'blkdeviotune' command on a VM in virsh.
//
// Example usage:
// SetBlockIOTune("vm-name", "vda", BlockLimit{libvirt.QEMUBlockIOWriteBytesSec, 1000000})
//
// Deprecated: use DomainSetBlockIOTune instead.
func (l *Libvirt) SetBlockIOTune(dom string, disk string, limits ...BlockLimit) error {
d, err := l.lookup(dom)
if err != nil {
return err
}
params := make([]TypedParam, len(limits))
for ix, limit := range limits {
tpval := NewTypedParamValueUllong(limit.Value)
params[ix] = TypedParam{Field: limit.Name, Value: *tpval}
}
return l.DomainSetBlockIOTune(d, disk, params, uint32(DomainAffectLive))
}
// GetBlockIOTune returns a slice containing the current block I/O tunables for
// a disk.
//
// Deprecated: use DomainGetBlockIOTune instead.
func (l *Libvirt) GetBlockIOTune(dom string, disk string) ([]BlockLimit, error) {
d, err := l.lookup(dom)
if err != nil {
return nil, err
}
lims, _, err := l.DomainGetBlockIOTune(d, []string{disk}, 32, uint32(TypedParamStringOkay))
if err != nil {
return nil, err
}
var limits []BlockLimit
// now decode each of the returned TypedParams. To do this we read the field
// name and type, then use the type information to decode the value.
for _, lim := range lims {
var l BlockLimit
name := lim.Field
switch lim.Value.I.(type) {
case uint64:
l = BlockLimit{Name: name, Value: lim.Value.I.(uint64)}
}
limits = append(limits, l)
}
return limits, nil
}
// lookup returns a domain as seen by libvirt.
func (l *Libvirt) lookup(name string) (Domain, error) {
return l.DomainLookupByName(name)
}
// getQEMUError checks the provided response for QEMU process errors.
// If an error is found, it is extracted an returned, otherwise nil.
func getQEMUError(r response) error {
pl := bytes.NewReader(r.Payload)
dec := xdr.NewDecoder(pl)
s, _, err := dec.DecodeString()
if err != nil {
return err
}
var e qemuError
if err = json.Unmarshal([]byte(s), &e); err != nil {
return err
}
if e.Error.Description != "" {
return errors.New(e.Error.Description)
}
return nil
}
func (l *Libvirt) waitAndDisconnect() {
// wait for the socket to indicate if/when it's been disconnected
<-l.socket.Disconnected()
// close event streams
l.removeAllStreams()
// Deregister all callbacks to prevent blocking on clients with
// outstanding requests
l.deregisterAll()
select {
case <-l.disconnected:
// l.disconnected is already closed, i.e., Libvirt.ConnectToURI
// was unable to complete all phases of its connection and
// so this hadn't been assigned to an open channel yet (it
// is set to a closed channel in Libvirt.New*)
//
// Just return to avoid closing an already-closed channel.
return
default:
// if we make it here then reading from l.disconnected is blocking,
// which suggests that it is open and must be closed.
}
close(l.disconnected)
}
// NewWithDialer configures a new Libvirt object that can be used to perform
// RPCs via libvirt's socket. The actual connection will not be established
// until Connect is called. The same Libvirt object may be used to re-connect
// multiple times.
func NewWithDialer(dialer socket.Dialer) *Libvirt {
l := &Libvirt{
s: 0,
disconnected: make(chan struct{}),
callbacks: make(map[int32]chan response),
events: make(map[int32]*event.Stream),
}
l.socket = socket.New(dialer, l)
// we start with a closed channel since that indicates no connection
close(l.disconnected)
return l
}
// New configures a new Libvirt RPC connection.
// This function only remains to retain backwards compatability.
// When Libvirt's Connect function is called, the Dial will simply return the
// connection passed in here and start a goroutine listening/reading from it.
// If at any point the Disconnect function is called, any subsequent Connect
// call will simply return an already closed connection.
//
// Deprecated: Please use NewWithDialer.
func New(conn net.Conn) *Libvirt {
return NewWithDialer(dialers.NewAlreadyConnected(conn))
}
// NetworkUpdateCompat is a wrapper over NetworkUpdate which swaps `Command` and `Section` when needed.
// This function must be used instead of NetworkUpdate to be sure that the
// NetworkUpdate call works both with older and newer libvirtd connections.
//
// libvirt on-wire protocol had a bug for a long time where Command and Section
// were reversed. It's been fixed in newer libvirt versions, and backported to
// some older versions. This helper detects what argument order libvirtd expects
// and makes the correct NetworkUpdate call.
func (l *Libvirt) NetworkUpdateCompat(Net Network, Command NetworkUpdateCommand, Section NetworkUpdateSection, ParentIndex int32, XML string, Flags NetworkUpdateFlags) (err error) {
// This is defined in libvirt/src/libvirt_internal.h and thus not available in go-libvirt autogenerated code
const virDrvFeatureNetworkUpdateHasCorrectOrder = 16
hasCorrectOrder, err := l.ConnectSupportsFeature(virDrvFeatureNetworkUpdateHasCorrectOrder)
if err != nil {
return fmt.Errorf("failed to confirm argument order for NetworkUpdate: %w", err)
}
// https://gitlab.com/libvirt/libvirt/-/commit/b0f78d626a18bcecae3a4d165540ab88bfbfc9ee
if hasCorrectOrder == 0 {
return l.NetworkUpdate(Net, uint32(Section), uint32(Command), ParentIndex, XML, Flags)
}
return l.NetworkUpdate(Net, uint32(Command), uint32(Section), ParentIndex, XML, Flags)
}
+64
View File
@@ -0,0 +1,64 @@
# Configuration file for c-for-go, which go-libvirt uses to translate the const
# and type definitions from the C-language sources in the libvirt project into
# Go. This file is used by the c-for-go binary (github.com/xlab/c-for-go), which
# is called when 'go generate' is run. See libvirt.go for the command line used.
---
GENERATOR:
PackageName: libvirt
PackageLicense: |
Copyright 2018 The go-libvirt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Includes: []
PARSER:
# We can't use environment variables here, but we don't want to process the
# libvirt version installed in the system folders (if any). Instead we'll
# rely on our caller to link the libvirt source directory to lv_source/, and
# run on that code. This isn't ideal, but changes to c-for-go are needed to
# fix it.
IncludePaths: [./lv_source/include, ./lv_source/build/include]
SourcesPaths:
- libvirt/libvirt.h
- libvirt/virterror.h
TRANSLATOR:
ConstRules:
defines: eval
Rules:
global:
- {action: accept, from: "^vir"}
post-global:
- {action: replace, from: "^vir"}
- {load: snakecase}
# Follow golint's capitalization conventions.
- {action: replace, from: "Api([A-Z]|$)", to: "API$1"}
- {action: replace, from: "Cpu([A-Z]|$)", to: "CPU$1"}
- {action: replace, from: "Dns([A-Z]|$)", to: "DNS$1"}
- {action: replace, from: "Eof([A-Z]|$)", to: "EOF$1"}
- {action: replace, from: "Id([A-Z]|$)", to: "ID$1"}
- {action: replace, from: "Ip([A-Z]|$)", to: "IP$1"}
- {action: replace, from: "Tls([A-Z]|$)", to: "TLS$1"}
- {action: replace, from: "Uuid([A-Z]|$)", to: "UUID$1"}
- {action: replace, from: "Uri([A-Z]|$)", to: "URI$1"}
- {action: replace, from: "Vcpu([A-Z]|$)", to: "VCPU$1"}
- {action: replace, from: "Xml([A-Z]|$)", to: "XML$1"}
- {action: replace, from: "Rpc([A-Z]|$)", to: "RPC$1"}
- {action: replace, from: "Ssh([A-Z]|$)", to: "SSH$1"}
- {action: replace, from: "Http([A-Z]|$)", to: "HTTP$1"}
- {transform: unexport, from: "^From"}
const:
- {action: accept, from: "^VIR_"}
# Special case to prevent a collision with a type:
- {action: replace, from: "^VIR_DOMAIN_JOB_OPERATION", to: "VIR_DOMAIN_JOB_OPERATION_STR"}
- {transform: lower}
+292
View File
@@ -0,0 +1,292 @@
// Copyright 2018 The go-libvirt Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Code generated by internal/lvgen/generate.go. DO NOT EDIT.
//
// To regenerate, run 'go generate' in internal/lvgen.
//
package libvirt
import (
"bytes"
"io"
"github.com/digitalocean/go-libvirt/internal/constants"
"github.com/digitalocean/go-libvirt/internal/go-xdr/xdr2"
)
// References to prevent "imported and not used" errors.
var (
_ = bytes.Buffer{}
_ = io.Copy
_ = constants.Program
_ = xdr.Unmarshal
)
//
// Typedefs:
//
//
// Enums:
//
// QEMUProcedure is libvirt's qemu_procedure
type QEMUProcedure int32
//
// Structs:
//
// QEMUDomainMonitorCommandArgs is libvirt's qemu_domain_monitor_command_args
type QEMUDomainMonitorCommandArgs struct {
Dom Domain
Cmd string
Flags uint32
}
// QEMUDomainMonitorCommandRet is libvirt's qemu_domain_monitor_command_ret
type QEMUDomainMonitorCommandRet struct {
Result string
}
// QEMUDomainAttachArgs is libvirt's qemu_domain_attach_args
type QEMUDomainAttachArgs struct {
PidValue uint32
Flags uint32
}
// QEMUDomainAttachRet is libvirt's qemu_domain_attach_ret
type QEMUDomainAttachRet struct {
Dom Domain
}
// QEMUDomainAgentCommandArgs is libvirt's qemu_domain_agent_command_args
type QEMUDomainAgentCommandArgs struct {
Dom Domain
Cmd string
Timeout int32
Flags uint32
}
// QEMUDomainAgentCommandRet is libvirt's qemu_domain_agent_command_ret
type QEMUDomainAgentCommandRet struct {
Result OptString
}
// QEMUConnectDomainMonitorEventRegisterArgs is libvirt's qemu_connect_domain_monitor_event_register_args
type QEMUConnectDomainMonitorEventRegisterArgs struct {
Dom OptDomain
Event OptString
Flags uint32
}
// QEMUConnectDomainMonitorEventRegisterRet is libvirt's qemu_connect_domain_monitor_event_register_ret
type QEMUConnectDomainMonitorEventRegisterRet struct {
CallbackID int32
}
// QEMUConnectDomainMonitorEventDeregisterArgs is libvirt's qemu_connect_domain_monitor_event_deregister_args
type QEMUConnectDomainMonitorEventDeregisterArgs struct {
CallbackID int32
}
// QEMUDomainMonitorEventMsg is libvirt's qemu_domain_monitor_event_msg
type QEMUDomainMonitorEventMsg struct {
CallbackID int32
Dom Domain
Event string
Seconds int64
Micros uint32
Details OptString
}
// QEMUDomainMonitorCommand is the go wrapper for QEMU_PROC_DOMAIN_MONITOR_COMMAND.
func (l *Libvirt) QEMUDomainMonitorCommand(Dom Domain, Cmd string, Flags uint32) (rResult string, err error) {
var buf []byte
args := QEMUDomainMonitorCommandArgs {
Dom: Dom,
Cmd: Cmd,
Flags: Flags,
}
buf, err = encode(&args)
if err != nil {
return
}
var r response
r, err = l.requestStream(1, constants.QEMUProgram, buf, nil, nil)
if err != nil {
return
}
// Return value unmarshaling
tpd := typedParamDecoder{}
ct := map[string]xdr.TypeDecoder{"libvirt.TypedParam": tpd}
rdr := bytes.NewReader(r.Payload)
dec := xdr.NewDecoderCustomTypes(rdr, 0, ct)
// Result: string
_, err = dec.Decode(&rResult)
if err != nil {
return
}
return
}
// QEMUDomainAttach is the go wrapper for QEMU_PROC_DOMAIN_ATTACH.
func (l *Libvirt) QEMUDomainAttach(PidValue uint32, Flags uint32) (rDom Domain, err error) {
var buf []byte
args := QEMUDomainAttachArgs {
PidValue: PidValue,
Flags: Flags,
}
buf, err = encode(&args)
if err != nil {
return
}
var r response
r, err = l.requestStream(2, constants.QEMUProgram, buf, nil, nil)
if err != nil {
return
}
// Return value unmarshaling
tpd := typedParamDecoder{}
ct := map[string]xdr.TypeDecoder{"libvirt.TypedParam": tpd}
rdr := bytes.NewReader(r.Payload)
dec := xdr.NewDecoderCustomTypes(rdr, 0, ct)
// Dom: Domain
_, err = dec.Decode(&rDom)
if err != nil {
return
}
return
}
// QEMUDomainAgentCommand is the go wrapper for QEMU_PROC_DOMAIN_AGENT_COMMAND.
func (l *Libvirt) QEMUDomainAgentCommand(Dom Domain, Cmd string, Timeout int32, Flags uint32) (rResult OptString, err error) {
var buf []byte
args := QEMUDomainAgentCommandArgs {
Dom: Dom,
Cmd: Cmd,
Timeout: Timeout,
Flags: Flags,
}
buf, err = encode(&args)
if err != nil {
return
}
var r response
r, err = l.requestStream(3, constants.QEMUProgram, buf, nil, nil)
if err != nil {
return
}
// Return value unmarshaling
tpd := typedParamDecoder{}
ct := map[string]xdr.TypeDecoder{"libvirt.TypedParam": tpd}
rdr := bytes.NewReader(r.Payload)
dec := xdr.NewDecoderCustomTypes(rdr, 0, ct)
// Result: OptString
_, err = dec.Decode(&rResult)
if err != nil {
return
}
return
}
// QEMUConnectDomainMonitorEventRegister is the go wrapper for QEMU_PROC_CONNECT_DOMAIN_MONITOR_EVENT_REGISTER.
func (l *Libvirt) QEMUConnectDomainMonitorEventRegister(Dom OptDomain, Event OptString, Flags uint32) (rCallbackID int32, err error) {
var buf []byte
args := QEMUConnectDomainMonitorEventRegisterArgs {
Dom: Dom,
Event: Event,
Flags: Flags,
}
buf, err = encode(&args)
if err != nil {
return
}
var r response
r, err = l.requestStream(4, constants.QEMUProgram, buf, nil, nil)
if err != nil {
return
}
// Return value unmarshaling
tpd := typedParamDecoder{}
ct := map[string]xdr.TypeDecoder{"libvirt.TypedParam": tpd}
rdr := bytes.NewReader(r.Payload)
dec := xdr.NewDecoderCustomTypes(rdr, 0, ct)
// CallbackID: int32
_, err = dec.Decode(&rCallbackID)
if err != nil {
return
}
return
}
// QEMUConnectDomainMonitorEventDeregister is the go wrapper for QEMU_PROC_CONNECT_DOMAIN_MONITOR_EVENT_DEREGISTER.
func (l *Libvirt) QEMUConnectDomainMonitorEventDeregister(CallbackID int32) (err error) {
var buf []byte
args := QEMUConnectDomainMonitorEventDeregisterArgs {
CallbackID: CallbackID,
}
buf, err = encode(&args)
if err != nil {
return
}
_, err = l.requestStream(5, constants.QEMUProgram, buf, nil, nil)
if err != nil {
return
}
return
}
// QEMUDomainMonitorEvent is the go wrapper for QEMU_PROC_DOMAIN_MONITOR_EVENT.
func (l *Libvirt) QEMUDomainMonitorEvent() (err error) {
var buf []byte
_, err = l.requestStream(6, constants.QEMUProgram, buf, nil, nil)
if err != nil {
return
}
return
}
File diff suppressed because it is too large Load Diff
+481
View File
@@ -0,0 +1,481 @@
// Copyright 2018 The go-libvirt Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package libvirt
import (
"bytes"
"errors"
"fmt"
"io"
"reflect"
"strings"
"sync/atomic"
"github.com/digitalocean/go-libvirt/internal/constants"
"github.com/digitalocean/go-libvirt/internal/event"
xdr "github.com/digitalocean/go-libvirt/internal/go-xdr/xdr2"
"github.com/digitalocean/go-libvirt/socket"
)
// ErrUnsupported is returned if a procedure is not supported by libvirt
var ErrUnsupported = errors.New("unsupported procedure requested")
// ErrInterrupted is returned if the socket is closed while waiting for the
// result of a procedure call.
var ErrInterrupted = errors.New("procedure interrupted while awaiting response")
// internal rpc response
type response struct {
Payload []byte
Status uint32
}
// Error reponse from libvirt
type Error struct {
Code uint32
Message string
}
func (e Error) Error() string {
return e.Message
}
// checkError is used to check whether an error is a libvirtError, and if it is,
// whether its error code matches the one passed in. It will return false if
// these conditions are not met.
func checkError(err error, expectedError ErrorNumber) bool {
for err != nil {
e, ok := err.(Error)
if ok {
return e.Code == uint32(expectedError)
}
err = errors.Unwrap(err)
}
return false
}
// IsNotFound detects libvirt's ERR_NO_DOMAIN.
func IsNotFound(err error) bool {
return checkError(err, ErrNoDomain)
}
// callback sends RPC responses to respective callers.
func (l *Libvirt) callback(id int32, res response) {
l.cmux.Lock()
defer l.cmux.Unlock()
c, ok := l.callbacks[id]
if !ok {
return
}
c <- res
}
// Route sends incoming packets to their listeners.
func (l *Libvirt) Route(h *socket.Header, buf []byte) {
// Route events to their respective listener
var event event.Event
switch h.Program {
case constants.QEMUProgram:
if h.Procedure != constants.QEMUProcDomainMonitorEvent {
break
}
event = &DomainEvent{}
case constants.Program:
event = eventFromProcedureID(h.Procedure)
}
if event != nil {
err := eventDecoder(buf, event)
if err != nil { // event was malformed, drop.
return
}
l.stream(event)
return
}
// send response to caller
l.callback(h.Serial, response{Payload: buf, Status: h.Status})
}
func eventFromProcedureID(procID uint32) event.Event {
switch procID {
case constants.ProcDomainEventCallbackLifecycle:
return &DomainEventCallbackLifecycleMsg{}
case constants.ProcDomainEventCallbackReboot:
return &DomainEventCallbackRebootMsg{}
case constants.ProcDomainEventCallbackRtcChange:
return &DomainEventCallbackRtcChangeMsg{}
case constants.ProcDomainEventCallbackWatchdog:
return &DomainEventCallbackWatchdogMsg{}
case constants.ProcDomainEventCallbackIOError:
return &DomainEventCallbackIOErrorMsg{}
case constants.ProcDomainEventCallbackIOErrorReason:
return &DomainEventCallbackIOErrorReasonMsg{}
case constants.ProcDomainEventCallbackGraphics:
return &DomainEventCallbackGraphicsMsg{}
case constants.ProcDomainEventCallbackBlockJob:
return &DomainEventCallbackBlockJobMsg{}
case constants.ProcDomainEventCallbackDiskChange:
return &DomainEventCallbackDiskChangeMsg{}
case constants.ProcDomainEventCallbackTrayChange:
return &DomainEventCallbackTrayChangeMsg{}
case constants.ProcDomainEventCallbackPmwakeup:
return &DomainEventCallbackPmwakeupMsg{}
case constants.ProcDomainEventCallbackPmsuspend:
return &DomainEventCallbackPmsuspendMsg{}
case constants.ProcDomainEventCallbackBalloonChange:
return &DomainEventCallbackBalloonChangeMsg{}
case constants.ProcDomainEventCallbackPmsuspendDisk:
return &DomainEventCallbackPmsuspendDiskMsg{}
case constants.ProcDomainEventCallbackControlError:
return &DomainEventCallbackControlErrorMsg{}
case constants.ProcDomainEventCallbackDeviceRemoved:
return &DomainEventCallbackDeviceRemovedMsg{}
case constants.ProcDomainEventCallbackTunable:
return &DomainEventCallbackTunableMsg{}
case constants.ProcDomainEventCallbackDeviceAdded:
return &DomainEventCallbackDeviceAddedMsg{}
case constants.ProcDomainEventCallbackAgentLifecycle:
return &DomainEventCallbackAgentLifecycleMsg{}
case constants.ProcDomainEventCallbackMigrationIteration:
return &DomainEventCallbackMigrationIterationMsg{}
case constants.ProcDomainEventCallbackJobCompleted:
return &DomainEventCallbackJobCompletedMsg{}
case constants.ProcDomainEventCallbackDeviceRemovalFailed:
return &DomainEventCallbackDeviceRemovalFailedMsg{}
case constants.ProcDomainEventCallbackMetadataChange:
return &DomainEventCallbackMetadataChangeMsg{}
}
return nil
}
// serial provides atomic access to the next sequential request serial number.
func (l *Libvirt) serial() int32 {
return atomic.AddInt32(&l.s, 1)
}
// stream decodes and relays domain events to their respective listener.
func (l *Libvirt) stream(e event.Event) {
l.emux.RLock()
defer l.emux.RUnlock()
q, ok := l.events[e.GetCallbackID()]
if !ok {
return
}
q.Push(e)
}
// addStream configures the routing for an event stream.
func (l *Libvirt) addStream(s *event.Stream) {
l.emux.Lock()
defer l.emux.Unlock()
l.events[s.CallbackID] = s
}
// removeStream deletes an event stream. The caller should first notify libvirt
// to stop sending events for this stream. Subsequent calls to removeStream are
// idempotent and return nil.
func (l *Libvirt) removeStream(id int32) error {
l.emux.Lock()
defer l.emux.Unlock()
// if the event is already removed, just return nil
q, ok := l.events[id]
if ok {
delete(l.events, id)
q.Shutdown()
}
return nil
}
// removeAllStreams deletes all event streams. This is meant to be used to
// clean up only once the underlying connection to libvirt is disconnected and
// thus does not attempt to notify libvirt to stop sending events.
func (l *Libvirt) removeAllStreams() {
l.emux.Lock()
defer l.emux.Unlock()
for _, ev := range l.events {
ev.Shutdown()
delete(l.events, ev.CallbackID)
}
}
// register configures a method response callback
func (l *Libvirt) register(id int32, c chan response) {
l.cmux.Lock()
defer l.cmux.Unlock()
l.callbacks[id] = c
}
// deregister destroys a method response callback. It is the responsibility of
// the caller to manage locking (l.cmux) during this call.
func (l *Libvirt) deregister(id int32) {
_, ok := l.callbacks[id]
if !ok {
return
}
close(l.callbacks[id])
delete(l.callbacks, id)
}
// deregisterAll closes all waiting callback channels. This is used to clean up
// if the connection to libvirt is lost. Callers waiting for responses will
// return an error when the response channel is closed, rather than just
// hanging.
func (l *Libvirt) deregisterAll() {
l.cmux.Lock()
defer l.cmux.Unlock()
for id := range l.callbacks {
l.deregister(id)
}
}
// request performs a libvirt RPC request.
// returns response returned by server.
// if response is not OK, decodes error from it and returns it.
func (l *Libvirt) request(proc uint32, program uint32, payload []byte) (response, error) {
return l.requestStream(proc, program, payload, nil, nil)
}
// requestStream performs a libvirt RPC request. The `out` and `in` parameters
// are optional, and should be nil when RPC endpoints don't return a stream.
func (l *Libvirt) requestStream(proc uint32, program uint32, payload []byte,
out io.Reader, in io.Writer) (response, error) {
serial := l.serial()
c := make(chan response)
l.register(serial, c)
defer func() {
l.cmux.Lock()
defer l.cmux.Unlock()
l.deregister(serial)
}()
err := l.socket.SendPacket(serial, proc, program, payload, socket.Call,
socket.StatusOK)
if err != nil {
return response{}, err
}
resp, err := l.getResponse(c)
if err != nil {
return resp, err
}
if out != nil {
abort := make(chan bool)
outErr := make(chan error)
go func() {
outErr <- l.socket.SendStream(serial, proc, program, out, abort)
}()
// Even without incoming stream server sends confirmation once all data is received
resp, err = l.processIncomingStream(c, in)
if err != nil {
abort <- true
return resp, err
}
err = <-outErr
if err != nil {
return response{}, err
}
}
switch in {
case nil:
return resp, nil
default:
return l.processIncomingStream(c, in)
}
}
// processIncomingStream is called once we've successfully sent a request to
// libvirt. It writes the responses back to the stream passed by the caller
// until libvirt sends a packet with statusOK or an error.
func (l *Libvirt) processIncomingStream(c chan response, inStream io.Writer) (response, error) {
for {
resp, err := l.getResponse(c)
if err != nil {
return resp, err
}
// StatusOK indicates end of stream
if resp.Status == socket.StatusOK {
return resp, nil
}
// FIXME: this smells.
// StatusError is handled in getResponse, so this must be StatusContinue
// StatusContinue is only valid here for stream packets
// libvirtd breaks protocol and returns StatusContinue with an
// empty response Payload when the stream finishes
if len(resp.Payload) == 0 {
return resp, nil
}
if inStream != nil {
_, err = inStream.Write(resp.Payload)
if err != nil {
return response{}, err
}
}
}
}
func (l *Libvirt) getResponse(c chan response) (response, error) {
resp, ok := <-c
if !ok {
// The channel was closed before a response was received. This means
// that the socket was unexpectedly closed during the RPC call. In
// this case, we must assume the worst, such as libvirt crashed while
// attempting to execute the call.
return resp, ErrInterrupted
}
if resp.Status == socket.StatusError {
return resp, decodeError(resp.Payload)
}
return resp, nil
}
// encode XDR encodes the provided data.
func encode(data interface{}) ([]byte, error) {
var buf bytes.Buffer
_, err := xdr.Marshal(&buf, data)
return buf.Bytes(), err
}
// decodeError extracts an error message from the provider buffer.
func decodeError(buf []byte) error {
dec := xdr.NewDecoder(bytes.NewReader(buf))
e := struct {
Code uint32
DomainID uint32
Padding uint8
Message string
Level uint32
}{}
_, err := dec.Decode(&e)
if err != nil {
return err
}
if strings.Contains(e.Message, "unknown procedure") {
return ErrUnsupported
}
// if libvirt returns ERR_OK, ignore the error
if ErrorNumber(e.Code) == ErrOk {
return nil
}
return Error{Code: uint32(e.Code), Message: e.Message}
}
// eventDecoder decodes an event from a xdr buffer.
func eventDecoder(buf []byte, e interface{}) error {
dec := xdr.NewDecoder(bytes.NewReader(buf))
_, err := dec.Decode(e)
return err
}
type typedParamDecoder struct{}
// Decode decodes a TypedParam. These are part of the libvirt spec, and not xdr
// proper. TypedParams contain a name, which is called Field for some reason,
// and a Value, which itself has a "discriminant" - an integer enum encoding the
// actual type, and a value, the length of which varies based on the actual
// type.
func (tpd typedParamDecoder) Decode(d *xdr.Decoder, v reflect.Value) (int, error) {
// Get the name of the typed param first
name, n, err := d.DecodeString()
if err != nil {
return n, err
}
val, n2, err := tpd.decodeTypedParamValue(d)
n += n2
if err != nil {
return n, err
}
tp := &TypedParam{Field: name, Value: *val}
v.Set(reflect.ValueOf(*tp))
return n, nil
}
// decodeTypedParamValue decodes the Value part of a TypedParam.
func (typedParamDecoder) decodeTypedParamValue(d *xdr.Decoder) (*TypedParamValue, int, error) {
// All TypedParamValues begin with a uint32 discriminant that tells us what
// type they are.
discriminant, n, err := d.DecodeUint()
if err != nil {
return nil, n, err
}
var n2 int
var tpv *TypedParamValue
switch discriminant {
case 1:
var val int32
n2, err = d.Decode(&val)
tpv = &TypedParamValue{D: discriminant, I: val}
case 2:
var val uint32
n2, err = d.Decode(&val)
tpv = &TypedParamValue{D: discriminant, I: val}
case 3:
var val int64
n2, err = d.Decode(&val)
tpv = &TypedParamValue{D: discriminant, I: val}
case 4:
var val uint64
n2, err = d.Decode(&val)
tpv = &TypedParamValue{D: discriminant, I: val}
case 5:
var val float64
n2, err = d.Decode(&val)
tpv = &TypedParamValue{D: discriminant, I: val}
case 6:
var val int32
n2, err = d.Decode(&val)
tpv = &TypedParamValue{D: discriminant, I: val}
case 7:
var val string
n2, err = d.Decode(&val)
tpv = &TypedParamValue{D: discriminant, I: val}
default:
err = fmt.Errorf("invalid parameter type %v", discriminant)
}
n += n2
return tpv, n, err
}
@@ -0,0 +1,26 @@
package dialers
import (
"net"
)
// AlreadyConnected implements a dialer interface for a connection that was
// established prior to initializing the socket object. This exists solely
// for backwards compatability with the previous implementation of Libvirt
// that took an already established connection.
type AlreadyConnected struct {
c net.Conn
}
// NewAlreadyConnected is a noop dialer to simply use a connection previously
// established. This means any re-dial attempts simply won't work.
func NewAlreadyConnected(c net.Conn) AlreadyConnected {
return AlreadyConnected{c}
}
// Dial just returns the connection previously established.
// If at some point it is disconnected by the client, this obviously does *not*
// re-dial and will simply return the already closed connection.
func (a AlreadyConnected) Dial() (net.Conn, error) {
return a.c, nil
}
+57
View File
@@ -0,0 +1,57 @@
package dialers
import (
"net"
"time"
)
const (
// defaultSocket specifies the default path to the libvirt unix socket.
defaultSocket = "/var/run/libvirt/libvirt-sock"
// defaultLocalTimeout specifies the default libvirt dial timeout.
defaultLocalTimeout = 15 * time.Second
)
// Local implements connecting to a local libvirtd over the unix socket.
type Local struct {
timeout time.Duration
socket string
}
// LocalOption is a function for setting local socket options.
type LocalOption func(*Local)
// WithLocalTimeout sets the dial timeout.
func WithLocalTimeout(timeout time.Duration) LocalOption {
return func(l *Local) {
l.timeout = timeout
}
}
// WithSocket sets the path to the local libvirt socket.
func WithSocket(socket string) LocalOption {
return func(l *Local) {
l.socket = socket
}
}
// NewLocal is a default dialer to simply connect to a locally running libvirt's
// socket.
func NewLocal(opts ...LocalOption) *Local {
l := &Local{
timeout: defaultLocalTimeout,
socket: defaultSocket,
}
for _, opt := range opts {
opt(l)
}
return l
}
// Dial connects to a local socket
func (l *Local) Dial() (net.Conn, error) {
return net.DialTimeout("unix", l.socket, l.timeout)
}
+61
View File
@@ -0,0 +1,61 @@
package dialers
import (
"net"
"time"
)
const (
// defaultRemotePort specifies the default libvirtd port.
defaultRemotePort = "16509"
// defaultRemoteTimeout specifies the default libvirt dial timeout.
defaultRemoteTimeout = 20 * time.Second
)
// Remote implements connecting to a remote server's libvirt using tcp
type Remote struct {
timeout time.Duration
host, port string
}
// RemoteOption is a function for setting remote dialer options.
type RemoteOption func(*Remote)
// WithRemoteTimeout sets the dial timeout.
func WithRemoteTimeout(timeout time.Duration) RemoteOption {
return func(r *Remote) {
r.timeout = timeout
}
}
// UsePort sets the port to dial for libirt on the target host server.
func UsePort(port string) RemoteOption {
return func(r *Remote) {
r.port = port
}
}
// NewRemote is a dialer for connecting to libvirt running on another server.
func NewRemote(hostAddr string, opts ...RemoteOption) *Remote {
r := &Remote{
timeout: defaultRemoteTimeout,
host: hostAddr,
port: defaultRemotePort,
}
for _, opt := range opts {
opt(r)
}
return r
}
// Dial connects to libvirt running on another server.
func (r *Remote) Dial() (net.Conn, error) {
return net.DialTimeout(
"tcp",
net.JoinHostPort(r.host, r.port),
r.timeout,
)
}
+376
View File
@@ -0,0 +1,376 @@
package socket
import (
"bufio"
"encoding/binary"
"errors"
"io"
"net"
"sync"
"syscall"
"time"
"unsafe"
"github.com/digitalocean/go-libvirt/internal/constants"
)
const disconnectTimeout = 5 * time.Second
// request and response statuses
const (
// StatusOK is always set for method calls or events.
// For replies it indicates successful completion of the method.
// For streams it indicates confirmation of the end of file on the stream.
StatusOK = iota
// StatusError for replies indicates that the method call failed
// and error information is being returned. For streams this indicates
// that not all data was sent and the stream has aborted.
StatusError
// StatusContinue is only used for streams.
// This indicates that further data packets will be following.
StatusContinue
)
// request and response types
const (
// Call is used when making calls to the remote server.
Call = iota
// Reply indicates a server reply.
Reply
// Message is an asynchronous notification.
Message
// Stream represents a stream data packet.
Stream
// CallWithFDs is used by a client to indicate the request has
// arguments with file descriptors.
CallWithFDs
// ReplyWithFDs is used by a server to indicate the request has
// arguments with file descriptors.
ReplyWithFDs
)
// Dialer is an interface for connecting to libvirt's underlying socket.
type Dialer interface {
Dial() (net.Conn, error)
}
// Router is an interface used to route packets to the appropriate clients.
type Router interface {
Route(*Header, []byte)
}
// Socket represents a libvirt Socket and its connection state
type Socket struct {
dialer Dialer
router Router
conn net.Conn
reader *bufio.Reader
writer *bufio.Writer
// used to serialize any Socket writes and any updates to conn, r, or w
mu *sync.Mutex
// disconnected is closed when the listen goroutine associated with a
// Socket connection has returned.
disconnected chan struct{}
}
// packet represents a RPC request or response.
type packet struct {
// Size of packet, in bytes, including length.
// Len + Header + Payload
Len uint32
Header Header
}
// Global packet instance, for use with unsafe.Sizeof()
var _p packet
// Header is a libvirt rpc packet header
type Header struct {
// Program identifier
Program uint32
// Program version
Version uint32
// Remote procedure identifier
Procedure uint32
// Call type, e.g., Reply
Type uint32
// Call serial number
Serial int32
// Request status, e.g., StatusOK
Status uint32
}
// New initializes a new type for managing the Socket.
func New(dialer Dialer, router Router) *Socket {
s := &Socket{
dialer: dialer,
router: router,
disconnected: make(chan struct{}),
mu: &sync.Mutex{},
}
// we start with a closed channel since that indicates no connection
close(s.disconnected)
return s
}
// Connect uses the dialer provided on creation to establish
// underlying physical connection to the desired libvirt.
func (s *Socket) Connect() error {
s.mu.Lock()
defer s.mu.Unlock()
if !s.isDisconnected() {
return errors.New("already connected to socket")
}
conn, err := s.dialer.Dial()
if err != nil {
return err
}
s.conn = conn
s.reader = bufio.NewReader(conn)
s.writer = bufio.NewWriter(conn)
s.disconnected = make(chan struct{})
go s.listenAndRoute()
return nil
}
// Disconnect closes the Socket connection to libvirt and waits for the reader
// gorouting to shut down.
func (s *Socket) Disconnect() error {
// just return if we're already disconnected
if s.isDisconnected() {
return nil
}
err := s.conn.Close()
if err != nil {
return err
}
// now we wait for the reader to return so as not to avoid it nil
// referencing
// Put this in a select,
// and have it only nil out the conn value if it doesn't fail
select {
case <-s.disconnected:
case <-time.After(disconnectTimeout):
return errors.New("timed out waiting for Disconnect cleanup")
}
return nil
}
// Disconnected returns a channel that will be closed once the current
// connection is closed. This can happen due to an explicit call to Disconnect
// from the client, or due to non-temporary Read or Write errors encountered.
func (s *Socket) Disconnected() <-chan struct{} {
return s.disconnected
}
// isDisconnected is a non-blocking function to query whether a connection
// is disconnected or not.
func (s *Socket) isDisconnected() bool {
select {
case <-s.disconnected:
return true
default:
return false
}
}
// listenAndRoute reads packets from the Socket and calls the provided
// Router function to route them
func (s *Socket) listenAndRoute() {
// only returns once it detects a non-temporary error related to the
// underlying connection
listen(s.reader, s.router)
// signal any clients listening that the connection has been disconnected
close(s.disconnected)
}
// listen processes incoming data and routes
// responses to their respective callback handler.
func listen(s io.Reader, router Router) {
for {
// response packet length
length, err := pktlen(s)
if err != nil {
if isTemporary(err) {
continue
}
// connection is no longer valid, so shutdown
return
}
// response header
h, err := extractHeader(s)
if err != nil {
// invalid packet
continue
}
// payload: packet length minus what was previously read
size := int(length) - int(unsafe.Sizeof(_p))
buf := make([]byte, size)
_, err = io.ReadFull(s, buf)
if err != nil {
// invalid packet
continue
}
// route response to caller
router.Route(h, buf)
}
}
// isTemporary returns true if the error returned from a read is transient.
// If the error type is an OpError, check whether the net connection
// error condition is temporary (which means we can keep using the
// connection).
// Errors not of the net.OpError type tend to be things like io.EOF,
// syscall.EINVAL, or io.ErrClosedPipe (i.e. all things that
// indicate the connection in use is no longer valid.)
func isTemporary(err error) bool {
opErr, ok := err.(*net.OpError)
if ok {
return opErr.Temporary()
}
return false
}
// pktlen returns the length of an incoming RPC packet. Read errors will
// result in a returned response length of 0 and a non-nil error.
func pktlen(r io.Reader) (uint32, error) {
buf := make([]byte, unsafe.Sizeof(_p.Len))
// extract the packet's length from the header
_, err := io.ReadFull(r, buf)
if err != nil {
return 0, err
}
return binary.BigEndian.Uint32(buf), nil
}
// extractHeader returns the decoded header from an incoming response.
func extractHeader(r io.Reader) (*Header, error) {
buf := make([]byte, unsafe.Sizeof(_p.Header))
// extract the packet's header from r
_, err := io.ReadFull(r, buf)
if err != nil {
return nil, err
}
return &Header{
Program: binary.BigEndian.Uint32(buf[0:4]),
Version: binary.BigEndian.Uint32(buf[4:8]),
Procedure: binary.BigEndian.Uint32(buf[8:12]),
Type: binary.BigEndian.Uint32(buf[12:16]),
Serial: int32(binary.BigEndian.Uint32(buf[16:20])),
Status: binary.BigEndian.Uint32(buf[20:24]),
}, nil
}
// SendPacket sends a packet to libvirt on the socket connection.
func (s *Socket) SendPacket(
serial int32,
proc uint32,
program uint32,
payload []byte,
typ uint32,
status uint32,
) error {
p := packet{
Header: Header{
Program: program,
Version: constants.ProtocolVersion,
Procedure: proc,
Type: typ,
Serial: serial,
Status: status,
},
}
size := int(unsafe.Sizeof(p.Len)) + int(unsafe.Sizeof(p.Header))
if payload != nil {
size += len(payload)
}
p.Len = uint32(size)
if s.isDisconnected() {
// this mirrors what a lot of net code return on use of a no
// longer valid connection
return syscall.EINVAL
}
s.mu.Lock()
defer s.mu.Unlock()
err := binary.Write(s.writer, binary.BigEndian, p)
if err != nil {
return err
}
// write payload
if payload != nil {
err = binary.Write(s.writer, binary.BigEndian, payload)
if err != nil {
return err
}
}
return s.writer.Flush()
}
// SendStream sends a stream of packets to libvirt on the socket connection.
func (s *Socket) SendStream(serial int32, proc uint32, program uint32,
stream io.Reader, abort chan bool) error {
// Keep total packet length under 4 MiB to follow possible limitation in libvirt server code
buf := make([]byte, 4*MiB-unsafe.Sizeof(_p))
for {
select {
case <-abort:
return s.SendPacket(serial, proc, program, nil, Stream, StatusError)
default:
}
n, err := stream.Read(buf)
if n > 0 {
err2 := s.SendPacket(serial, proc, program, buf[:n], Stream, StatusContinue)
if err2 != nil {
return err2
}
}
if err != nil {
if err == io.EOF {
return s.SendPacket(serial, proc, program, nil, Stream, StatusOK)
}
// keep original error
err2 := s.SendPacket(serial, proc, program, nil, Stream, StatusError)
if err2 != nil {
return err2
}
return err
}
}
}
+27
View File
@@ -0,0 +1,27 @@
// Copyright 2016 The go-libvirt Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This module provides different units of measurement to make other
// code more readable.
package socket
const (
// B - byte
B = 1
// KiB - kibibyte
KiB = 1024 * B
// MiB - mebibyte
MiB = 1024 * KiB
)
-3
View File
@@ -1,3 +0,0 @@
# This source code refers to The Go Authors for copyright purposes.
# The master list of authors is in the main Go distribution,
# visible at http://tip.golang.org/AUTHORS.
-3
View File
@@ -1,3 +0,0 @@
# This source code was written by the Go contributors.
# The master list of contributors is in the main Go distribution,
# visible at http://tip.golang.org/CONTRIBUTORS.
+29 -25
View File
@@ -173,13 +173,15 @@ func tokenEqual(t1, t2 string) bool {
// isLWS reports whether b is linear white space, according
// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
// LWS = [CRLF] 1*( SP | HT )
//
// LWS = [CRLF] 1*( SP | HT )
func isLWS(b byte) bool { return b == ' ' || b == '\t' }
// isCTL reports whether b is a control byte, according
// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
// CTL = <any US-ASCII control character
// (octets 0 - 31) and DEL (127)>
//
// CTL = <any US-ASCII control character
// (octets 0 - 31) and DEL (127)>
func isCTL(b byte) bool {
const del = 0x7f // a CTL
return b < ' ' || b == del
@@ -189,12 +191,13 @@ func isCTL(b byte) bool {
// HTTP/2 imposes the additional restriction that uppercase ASCII
// letters are not allowed.
//
// RFC 7230 says:
// header-field = field-name ":" OWS field-value OWS
// field-name = token
// token = 1*tchar
// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
// "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
// RFC 7230 says:
//
// header-field = field-name ":" OWS field-value OWS
// field-name = token
// token = 1*tchar
// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
// "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
func ValidHeaderFieldName(v string) bool {
if len(v) == 0 {
return false
@@ -267,27 +270,28 @@ var validHostByte = [256]bool{
// ValidHeaderFieldValue reports whether v is a valid "field-value" according to
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 :
//
// message-header = field-name ":" [ field-value ]
// field-value = *( field-content | LWS )
// field-content = <the OCTETs making up the field-value
// and consisting of either *TEXT or combinations
// of token, separators, and quoted-string>
// message-header = field-name ":" [ field-value ]
// field-value = *( field-content | LWS )
// field-content = <the OCTETs making up the field-value
// and consisting of either *TEXT or combinations
// of token, separators, and quoted-string>
//
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2 :
//
// TEXT = <any OCTET except CTLs,
// but including LWS>
// LWS = [CRLF] 1*( SP | HT )
// CTL = <any US-ASCII control character
// (octets 0 - 31) and DEL (127)>
// TEXT = <any OCTET except CTLs,
// but including LWS>
// LWS = [CRLF] 1*( SP | HT )
// CTL = <any US-ASCII control character
// (octets 0 - 31) and DEL (127)>
//
// RFC 7230 says:
// field-value = *( field-content / obs-fold )
// obj-fold = N/A to http2, and deprecated
// field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
// field-vchar = VCHAR / obs-text
// obs-text = %x80-FF
// VCHAR = "any visible [USASCII] character"
//
// field-value = *( field-content / obs-fold )
// obj-fold = N/A to http2, and deprecated
// field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
// field-vchar = VCHAR / obs-text
// obs-text = %x80-FF
// VCHAR = "any visible [USASCII] character"
//
// http2 further says: "Similarly, HTTP/2 allows header field values
// that are not valid. While most of the values that can be encoded
+2 -1
View File
@@ -139,7 +139,6 @@ func (p *clientConnPool) getStartDialLocked(ctx context.Context, addr string) *d
func (c *dialCall) dial(ctx context.Context, addr string) {
const singleUse = false // shared conn
c.res, c.err = c.p.t.dialClientConn(ctx, addr, singleUse)
close(c.done)
c.p.mu.Lock()
delete(c.p.dialing, addr)
@@ -147,6 +146,8 @@ func (c *dialCall) dial(ctx context.Context, addr string) {
c.p.addConnLocked(addr, c.res)
}
c.p.mu.Unlock()
close(c.done)
}
// addConnIfNeeded makes a NewClientConn out of c if a connection for key doesn't
+1 -1
View File
@@ -136,7 +136,7 @@ func (e headerFieldNameError) Error() string {
type headerFieldValueError string
func (e headerFieldValueError) Error() string {
return fmt.Sprintf("invalid header field value %q", string(e))
return fmt.Sprintf("invalid header field value for %q", string(e))
}
var (
+2 -1
View File
@@ -1532,7 +1532,8 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
fr.debugReadLoggerf("http2: decoded hpack field %+v", hf)
}
if !httpguts.ValidHeaderFieldValue(hf.Value) {
invalid = headerFieldValueError(hf.Value)
// Don't include the value in the error, because it may be sensitive.
invalid = headerFieldValueError(hf.Name)
}
isPseudo := strings.HasPrefix(hf.Name, ":")
if isPseudo {
+40 -47
View File
@@ -169,25 +169,50 @@ func buildRootHuffmanNode() {
// AppendHuffmanString appends s, as encoded in Huffman codes, to dst
// and returns the extended buffer.
func AppendHuffmanString(dst []byte, s string) []byte {
rembits := uint8(8)
// This relies on the maximum huffman code length being 30 (See tables.go huffmanCodeLen array)
// So if a uint64 buffer has less than 32 valid bits can always accommodate another huffmanCode.
var (
x uint64 // buffer
n uint // number valid of bits present in x
)
for i := 0; i < len(s); i++ {
if rembits == 8 {
dst = append(dst, 0)
c := s[i]
n += uint(huffmanCodeLen[c])
x <<= huffmanCodeLen[c] % 64
x |= uint64(huffmanCodes[c])
if n >= 32 {
n %= 32 // Normally would be -= 32 but %= 32 informs compiler 0 <= n <= 31 for upcoming shift
y := uint32(x >> n) // Compiler doesn't combine memory writes if y isn't uint32
dst = append(dst, byte(y>>24), byte(y>>16), byte(y>>8), byte(y))
}
dst, rembits = appendByteToHuffmanCode(dst, rembits, s[i])
}
if rembits < 8 {
// special EOS symbol
code := uint32(0x3fffffff)
nbits := uint8(30)
t := uint8(code >> (nbits - rembits))
dst[len(dst)-1] |= t
// Add padding bits if necessary
if over := n % 8; over > 0 {
const (
eosCode = 0x3fffffff
eosNBits = 30
eosPadByte = eosCode >> (eosNBits - 8)
)
pad := 8 - over
x = (x << pad) | (eosPadByte >> over)
n += pad // 8 now divides into n exactly
}
return dst
// n in (0, 8, 16, 24, 32)
switch n / 8 {
case 0:
return dst
case 1:
return append(dst, byte(x))
case 2:
y := uint16(x)
return append(dst, byte(y>>8), byte(y))
case 3:
y := uint16(x >> 8)
return append(dst, byte(y>>8), byte(y), byte(x))
}
// case 4:
y := uint32(x)
return append(dst, byte(y>>24), byte(y>>16), byte(y>>8), byte(y))
}
// HuffmanEncodeLength returns the number of bytes required to encode
@@ -199,35 +224,3 @@ func HuffmanEncodeLength(s string) uint64 {
}
return (n + 7) / 8
}
// appendByteToHuffmanCode appends Huffman code for c to dst and
// returns the extended buffer and the remaining bits in the last
// element. The appending is not byte aligned and the remaining bits
// in the last element of dst is given in rembits.
func appendByteToHuffmanCode(dst []byte, rembits uint8, c byte) ([]byte, uint8) {
code := huffmanCodes[c]
nbits := huffmanCodeLen[c]
for {
if rembits > nbits {
t := uint8(code << (rembits - nbits))
dst[len(dst)-1] |= t
rembits -= nbits
break
}
t := uint8(code >> (nbits - rembits))
dst[len(dst)-1] |= t
nbits -= rembits
rembits = 8
if nbits == 0 {
break
}
dst = append(dst, 0)
}
return dst, rembits
}
+7 -7
View File
@@ -13,7 +13,6 @@
// See https://http2.github.io/ for more information on HTTP/2.
//
// See https://http2.golang.org/ for a test server running this code.
//
package http2 // import "golang.org/x/net/http2"
import (
@@ -176,10 +175,11 @@ func (s SettingID) String() string {
// name (key). See httpguts.ValidHeaderName for the base rules.
//
// Further, http2 says:
// "Just as in HTTP/1.x, header field names are strings of ASCII
// characters that are compared in a case-insensitive
// fashion. However, header field names MUST be converted to
// lowercase prior to their encoding in HTTP/2. "
//
// "Just as in HTTP/1.x, header field names are strings of ASCII
// characters that are compared in a case-insensitive
// fashion. However, header field names MUST be converted to
// lowercase prior to their encoding in HTTP/2. "
func validWireHeaderFieldName(v string) bool {
if len(v) == 0 {
return false
@@ -365,8 +365,8 @@ func (s *sorter) SortStrings(ss []string) {
// validPseudoPath reports whether v is a valid :path pseudo-header
// value. It must be either:
//
// *) a non-empty string starting with '/'
// *) the string '*', for OPTIONS requests.
// - a non-empty string starting with '/'
// - the string '*', for OPTIONS requests.
//
// For now this is only used a quick check for deciding when to clean
// up Opaque URLs before sending requests from the Transport.
+111 -24
View File
@@ -315,6 +315,20 @@ type ServeConnOpts struct {
// requests. If nil, BaseConfig.Handler is used. If BaseConfig
// or BaseConfig.Handler is nil, http.DefaultServeMux is used.
Handler http.Handler
// UpgradeRequest is an initial request received on a connection
// undergoing an h2c upgrade. The request body must have been
// completely read from the connection before calling ServeConn,
// and the 101 Switching Protocols response written.
UpgradeRequest *http.Request
// Settings is the decoded contents of the HTTP2-Settings header
// in an h2c upgrade request.
Settings []byte
// SawClientPreface is set if the HTTP/2 connection preface
// has already been read from the connection.
SawClientPreface bool
}
func (o *ServeConnOpts) context() context.Context {
@@ -383,6 +397,7 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
headerTableSize: initialHeaderTableSize,
serveG: newGoroutineLock(),
pushEnabled: true,
sawClientPreface: opts.SawClientPreface,
}
s.state.registerConn(sc)
@@ -400,7 +415,7 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
if s.NewWriteScheduler != nil {
sc.writeSched = s.NewWriteScheduler()
} else {
sc.writeSched = NewRandomWriteScheduler()
sc.writeSched = NewPriorityWriteScheduler(nil)
}
// These start at the RFC-specified defaults. If there is a higher
@@ -465,9 +480,27 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
}
}
if opts.Settings != nil {
fr := &SettingsFrame{
FrameHeader: FrameHeader{valid: true},
p: opts.Settings,
}
if err := fr.ForeachSetting(sc.processSetting); err != nil {
sc.rejectConn(ErrCodeProtocol, "invalid settings")
return
}
opts.Settings = nil
}
if hook := testHookGetServerConn; hook != nil {
hook(sc)
}
if opts.UpgradeRequest != nil {
sc.upgradeRequest(opts.UpgradeRequest)
opts.UpgradeRequest = nil
}
sc.serve()
}
@@ -512,6 +545,7 @@ type serverConn struct {
// Everything following is owned by the serve loop; use serveG.check():
serveG goroutineLock // used to verify funcs are on serve()
pushEnabled bool
sawClientPreface bool // preface has already been read, used in h2c upgrade
sawFirstSettings bool // got the initial SETTINGS frame after the preface
needToSendSettingsAck bool
unackedSettings int // how many SETTINGS have we sent without ACKs?
@@ -974,6 +1008,9 @@ var errPrefaceTimeout = errors.New("timeout waiting for client preface")
// returns errPrefaceTimeout on timeout, or an error if the greeting
// is invalid.
func (sc *serverConn) readPreface() error {
if sc.sawClientPreface {
return nil
}
errc := make(chan error, 1)
go func() {
// Read the client preface
@@ -1915,6 +1952,26 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
return nil
}
func (sc *serverConn) upgradeRequest(req *http.Request) {
sc.serveG.check()
id := uint32(1)
sc.maxClientStreamID = id
st := sc.newStream(id, 0, stateHalfClosedRemote)
st.reqTrailer = req.Trailer
if st.reqTrailer != nil {
st.trailer = make(http.Header)
}
rw := sc.newResponseWriter(st, req)
// Disable any read deadline set by the net/http package
// prior to the upgrade.
if sc.hs.ReadTimeout != 0 {
sc.conn.SetReadDeadline(time.Time{})
}
go sc.runHandler(rw, req, sc.handler.ServeHTTP)
}
func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error {
sc := st.sc
sc.serveG.check()
@@ -2145,6 +2202,11 @@ func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*r
}
req = req.WithContext(st.ctx)
rw := sc.newResponseWriter(st, req)
return rw, req, nil
}
func (sc *serverConn) newResponseWriter(st *stream, req *http.Request) *responseWriter {
rws := responseWriterStatePool.Get().(*responseWriterState)
bwSave := rws.bw
*rws = responseWriterState{} // zero all the fields
@@ -2153,10 +2215,7 @@ func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*r
rws.bw.Reset(chunkWriter{rws})
rws.stream = st
rws.req = req
rws.body = body
rw := &responseWriter{rws: rws}
return rw, req, nil
return &responseWriter{rws: rws}
}
// Run on its own goroutine.
@@ -2316,17 +2375,18 @@ type requestBody struct {
_ incomparable
stream *stream
conn *serverConn
closed bool // for use by Close only
sawEOF bool // for use by Read only
pipe *pipe // non-nil if we have a HTTP entity message body
needsContinue bool // need to send a 100-continue
closeOnce sync.Once // for use by Close only
sawEOF bool // for use by Read only
pipe *pipe // non-nil if we have a HTTP entity message body
needsContinue bool // need to send a 100-continue
}
func (b *requestBody) Close() error {
if b.pipe != nil && !b.closed {
b.pipe.BreakWithError(errClosedBody)
}
b.closed = true
b.closeOnce.Do(func() {
if b.pipe != nil {
b.pipe.BreakWithError(errClosedBody)
}
})
return nil
}
@@ -2370,7 +2430,6 @@ type responseWriterState struct {
// immutable within a request:
stream *stream
req *http.Request
body *requestBody // to close at end of request, if DATA frames didn't
conn *serverConn
// TODO: adjust buffer writing sizes based on server config, frame size updates from peer, etc
@@ -2546,8 +2605,9 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
// prior to the headers being written. If the set of trailers is fixed
// or known before the header is written, the normal Go trailers mechanism
// is preferred:
// https://golang.org/pkg/net/http/#ResponseWriter
// https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
//
// https://golang.org/pkg/net/http/#ResponseWriter
// https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
const TrailerPrefix = "Trailer:"
// promoteUndeclaredTrailers permits http.Handlers to set trailers
@@ -2643,8 +2703,7 @@ func checkWriteHeaderCode(code int) {
// Issue 22880: require valid WriteHeader status codes.
// For now we only enforce that it's three digits.
// In the future we might block things over 599 (600 and above aren't defined
// at http://httpwg.org/specs/rfc7231.html#status.codes)
// and we might block under 200 (once we have more mature 1xx support).
// at http://httpwg.org/specs/rfc7231.html#status.codes).
// But for now any three digits.
//
// We used to send "HTTP/1.1 000 0" on the wire in responses but there's
@@ -2665,13 +2724,41 @@ func (w *responseWriter) WriteHeader(code int) {
}
func (rws *responseWriterState) writeHeader(code int) {
if !rws.wroteHeader {
checkWriteHeaderCode(code)
rws.wroteHeader = true
rws.status = code
if len(rws.handlerHeader) > 0 {
rws.snapHeader = cloneHeader(rws.handlerHeader)
if rws.wroteHeader {
return
}
checkWriteHeaderCode(code)
// Handle informational headers
if code >= 100 && code <= 199 {
// Per RFC 8297 we must not clear the current header map
h := rws.handlerHeader
_, cl := h["Content-Length"]
_, te := h["Transfer-Encoding"]
if cl || te {
h = h.Clone()
h.Del("Content-Length")
h.Del("Transfer-Encoding")
}
if rws.conn.writeHeaders(rws.stream, &writeResHeaders{
streamID: rws.stream.id,
httpResCode: code,
h: h,
endStream: rws.handlerDone && !rws.hasTrailers(),
}) != nil {
rws.dirty = true
}
return
}
rws.wroteHeader = true
rws.status = code
if len(rws.handlerHeader) > 0 {
rws.snapHeader = cloneHeader(rws.handlerHeader)
}
}
+14 -4
View File
@@ -16,7 +16,6 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"math"
mathrand "math/rand"
@@ -501,12 +500,14 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res
if req, err = shouldRetryRequest(req, err); err == nil {
// After the first retry, do exponential backoff with 10% jitter.
if retry == 0 {
t.vlogf("RoundTrip retrying after failure: %v", err)
continue
}
backoff := float64(uint(1) << (uint(retry) - 1))
backoff += backoff * (0.1 * mathrand.Float64())
select {
case <-time.After(time.Second * time.Duration(backoff)):
t.vlogf("RoundTrip retrying after failure: %v", err)
continue
case <-req.Context().Done():
err = req.Context().Err()
@@ -732,10 +733,13 @@ func (cc *ClientConn) healthCheck() {
// trigger the healthCheck again if there is no frame received.
ctx, cancel := context.WithTimeout(context.Background(), pingTimeout)
defer cancel()
cc.vlogf("http2: Transport sending health check")
err := cc.Ping(ctx)
if err != nil {
cc.vlogf("http2: Transport health check failure: %v", err)
cc.closeForLostPing()
return
} else {
cc.vlogf("http2: Transport health check success")
}
}
@@ -1765,7 +1769,8 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail
}
for _, v := range vv {
if !httpguts.ValidHeaderFieldValue(v) {
return nil, fmt.Errorf("invalid HTTP header value %q for header %q", v, k)
// Don't include the value in the error, because it may be sensitive.
return nil, fmt.Errorf("invalid HTTP header value for header %q", k)
}
}
}
@@ -2898,7 +2903,12 @@ func (t *Transport) logf(format string, args ...interface{}) {
log.Printf(format, args...)
}
var noBody io.ReadCloser = ioutil.NopCloser(bytes.NewReader(nil))
var noBody io.ReadCloser = noBodyReader{}
type noBodyReader struct{}
func (noBodyReader) Close() error { return nil }
func (noBodyReader) Read([]byte) (int, error) { return 0, io.EOF }
type missingBody struct{}
+4 -5
View File
@@ -383,16 +383,15 @@ func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority Priorit
func (ws *priorityWriteScheduler) Push(wr FrameWriteRequest) {
var n *priorityNode
if id := wr.StreamID(); id == 0 {
if wr.isControl() {
n = &ws.root
} else {
id := wr.StreamID()
n = ws.nodes[id]
if n == nil {
// id is an idle or closed stream. wr should not be a HEADERS or
// DATA frame. However, wr can be a RST_STREAM. In this case, we
// push wr onto the root, rather than creating a new priorityNode,
// since RST_STREAM is tiny and the stream's priority is unknown
// anyway. See issue #17919.
// DATA frame. In other case, we push wr onto the root, rather
// than creating a new priorityNode.
if wr.DataSize() > 0 {
panic("add DATA on non-open stream")
}
+17 -17
View File
@@ -17,23 +17,23 @@ package idna
//
// The per-rune values have the following format:
//
// if mapped {
// if inlinedXOR {
// 15..13 inline XOR marker
// 12..11 unused
// 10..3 inline XOR mask
// } else {
// 15..3 index into xor or mapping table
// }
// } else {
// 15..14 unused
// 13 mayNeedNorm
// 12..11 attributes
// 10..8 joining type
// 7..3 category type
// }
// 2 use xor pattern
// 1..0 mapped category
// if mapped {
// if inlinedXOR {
// 15..13 inline XOR marker
// 12..11 unused
// 10..3 inline XOR mask
// } else {
// 15..3 index into xor or mapping table
// }
// } else {
// 15..14 unused
// 13 mayNeedNorm
// 12..11 attributes
// 10..8 joining type
// 7..3 category type
// }
// 2 use xor pattern
// 1..0 mapped category
//
// See the definitions below for a more detailed description of the various
// bits.
-3
View File
@@ -1,3 +0,0 @@
# This source code refers to The Go Authors for copyright purposes.
# The master list of authors is in the main Go distribution,
# visible at http://tip.golang.org/AUTHORS.
-3
View File
@@ -1,3 +0,0 @@
# This source code was written by the Go contributors.
# The master list of contributors is in the main Go distribution,
# visible at http://tip.golang.org/CONTRIBUTORS.
+29
View File
@@ -0,0 +1,29 @@
// Copyright 2021 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.
//go:build (darwin || freebsd || netbsd || openbsd) && gc
// +build darwin freebsd netbsd openbsd
// +build gc
#include "textflag.h"
// System call support for RISCV64 BSD
// Just jump to package syscall's implementation for all these functions.
// The runtime may know about them.
TEXT ·Syscall(SB),NOSPLIT,$0-56
JMP syscall·Syscall(SB)
TEXT ·Syscall6(SB),NOSPLIT,$0-80
JMP syscall·Syscall6(SB)
TEXT ·Syscall9(SB),NOSPLIT,$0-104
JMP syscall·Syscall9(SB)
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
JMP syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
JMP syscall·RawSyscall6(SB)
+2 -2
View File
@@ -30,7 +30,7 @@ TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
MOVV trap+0(FP), R11 // syscall entry
SYSCALL
MOVV R4, r1+32(FP)
MOVV R5, r2+40(FP)
MOVV R0, r2+40(FP) // r2 is not used. Always set to 0
JAL runtime·exitsyscall(SB)
RET
@@ -50,5 +50,5 @@ TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
MOVV trap+0(FP), R11 // syscall entry
SYSCALL
MOVV R4, r1+32(FP)
MOVV R5, r2+40(FP)
MOVV R0, r2+40(FP) // r2 is not used. Always set to 0
RET
-233
View File
@@ -1,233 +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.
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
// them here for backwards compatibility.
package unix
const (
DLT_HHDLC = 0x79
IFF_SMART = 0x20
IFT_1822 = 0x2
IFT_A12MPPSWITCH = 0x82
IFT_AAL2 = 0xbb
IFT_AAL5 = 0x31
IFT_ADSL = 0x5e
IFT_AFLANE8023 = 0x3b
IFT_AFLANE8025 = 0x3c
IFT_ARAP = 0x58
IFT_ARCNET = 0x23
IFT_ARCNETPLUS = 0x24
IFT_ASYNC = 0x54
IFT_ATM = 0x25
IFT_ATMDXI = 0x69
IFT_ATMFUNI = 0x6a
IFT_ATMIMA = 0x6b
IFT_ATMLOGICAL = 0x50
IFT_ATMRADIO = 0xbd
IFT_ATMSUBINTERFACE = 0x86
IFT_ATMVCIENDPT = 0xc2
IFT_ATMVIRTUAL = 0x95
IFT_BGPPOLICYACCOUNTING = 0xa2
IFT_BSC = 0x53
IFT_CCTEMUL = 0x3d
IFT_CEPT = 0x13
IFT_CES = 0x85
IFT_CHANNEL = 0x46
IFT_CNR = 0x55
IFT_COFFEE = 0x84
IFT_COMPOSITELINK = 0x9b
IFT_DCN = 0x8d
IFT_DIGITALPOWERLINE = 0x8a
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
IFT_DLSW = 0x4a
IFT_DOCSCABLEDOWNSTREAM = 0x80
IFT_DOCSCABLEMACLAYER = 0x7f
IFT_DOCSCABLEUPSTREAM = 0x81
IFT_DS0 = 0x51
IFT_DS0BUNDLE = 0x52
IFT_DS1FDL = 0xaa
IFT_DS3 = 0x1e
IFT_DTM = 0x8c
IFT_DVBASILN = 0xac
IFT_DVBASIOUT = 0xad
IFT_DVBRCCDOWNSTREAM = 0x93
IFT_DVBRCCMACLAYER = 0x92
IFT_DVBRCCUPSTREAM = 0x94
IFT_ENC = 0xf4
IFT_EON = 0x19
IFT_EPLRS = 0x57
IFT_ESCON = 0x49
IFT_ETHER = 0x6
IFT_FAITH = 0xf2
IFT_FAST = 0x7d
IFT_FASTETHER = 0x3e
IFT_FASTETHERFX = 0x45
IFT_FDDI = 0xf
IFT_FIBRECHANNEL = 0x38
IFT_FRAMERELAYINTERCONNECT = 0x3a
IFT_FRAMERELAYMPI = 0x5c
IFT_FRDLCIENDPT = 0xc1
IFT_FRELAY = 0x20
IFT_FRELAYDCE = 0x2c
IFT_FRF16MFRBUNDLE = 0xa3
IFT_FRFORWARD = 0x9e
IFT_G703AT2MB = 0x43
IFT_G703AT64K = 0x42
IFT_GIF = 0xf0
IFT_GIGABITETHERNET = 0x75
IFT_GR303IDT = 0xb2
IFT_GR303RDT = 0xb1
IFT_H323GATEKEEPER = 0xa4
IFT_H323PROXY = 0xa5
IFT_HDH1822 = 0x3
IFT_HDLC = 0x76
IFT_HDSL2 = 0xa8
IFT_HIPERLAN2 = 0xb7
IFT_HIPPI = 0x2f
IFT_HIPPIINTERFACE = 0x39
IFT_HOSTPAD = 0x5a
IFT_HSSI = 0x2e
IFT_HY = 0xe
IFT_IBM370PARCHAN = 0x48
IFT_IDSL = 0x9a
IFT_IEEE80211 = 0x47
IFT_IEEE80212 = 0x37
IFT_IEEE8023ADLAG = 0xa1
IFT_IFGSN = 0x91
IFT_IMT = 0xbe
IFT_INTERLEAVE = 0x7c
IFT_IP = 0x7e
IFT_IPFORWARD = 0x8e
IFT_IPOVERATM = 0x72
IFT_IPOVERCDLC = 0x6d
IFT_IPOVERCLAW = 0x6e
IFT_IPSWITCH = 0x4e
IFT_IPXIP = 0xf9
IFT_ISDN = 0x3f
IFT_ISDNBASIC = 0x14
IFT_ISDNPRIMARY = 0x15
IFT_ISDNS = 0x4b
IFT_ISDNU = 0x4c
IFT_ISO88022LLC = 0x29
IFT_ISO88023 = 0x7
IFT_ISO88024 = 0x8
IFT_ISO88025 = 0x9
IFT_ISO88025CRFPINT = 0x62
IFT_ISO88025DTR = 0x56
IFT_ISO88025FIBER = 0x73
IFT_ISO88026 = 0xa
IFT_ISUP = 0xb3
IFT_L3IPXVLAN = 0x89
IFT_LAPB = 0x10
IFT_LAPD = 0x4d
IFT_LAPF = 0x77
IFT_LOCALTALK = 0x2a
IFT_LOOP = 0x18
IFT_MEDIAMAILOVERIP = 0x8b
IFT_MFSIGLINK = 0xa7
IFT_MIOX25 = 0x26
IFT_MODEM = 0x30
IFT_MPC = 0x71
IFT_MPLS = 0xa6
IFT_MPLSTUNNEL = 0x96
IFT_MSDSL = 0x8f
IFT_MVL = 0xbf
IFT_MYRINET = 0x63
IFT_NFAS = 0xaf
IFT_NSIP = 0x1b
IFT_OPTICALCHANNEL = 0xc3
IFT_OPTICALTRANSPORT = 0xc4
IFT_OTHER = 0x1
IFT_P10 = 0xc
IFT_P80 = 0xd
IFT_PARA = 0x22
IFT_PFLOG = 0xf6
IFT_PFSYNC = 0xf7
IFT_PLC = 0xae
IFT_POS = 0xab
IFT_PPPMULTILINKBUNDLE = 0x6c
IFT_PROPBWAP2MP = 0xb8
IFT_PROPCNLS = 0x59
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
IFT_PROPMUX = 0x36
IFT_PROPWIRELESSP2P = 0x9d
IFT_PTPSERIAL = 0x16
IFT_PVC = 0xf1
IFT_QLLC = 0x44
IFT_RADIOMAC = 0xbc
IFT_RADSL = 0x5f
IFT_REACHDSL = 0xc0
IFT_RFC1483 = 0x9f
IFT_RS232 = 0x21
IFT_RSRB = 0x4f
IFT_SDLC = 0x11
IFT_SDSL = 0x60
IFT_SHDSL = 0xa9
IFT_SIP = 0x1f
IFT_SLIP = 0x1c
IFT_SMDSDXI = 0x2b
IFT_SMDSICIP = 0x34
IFT_SONET = 0x27
IFT_SONETOVERHEADCHANNEL = 0xb9
IFT_SONETPATH = 0x32
IFT_SONETVT = 0x33
IFT_SRP = 0x97
IFT_SS7SIGLINK = 0x9c
IFT_STACKTOSTACK = 0x6f
IFT_STARLAN = 0xb
IFT_STF = 0xd7
IFT_T1 = 0x12
IFT_TDLC = 0x74
IFT_TERMPAD = 0x5b
IFT_TR008 = 0xb0
IFT_TRANSPHDLC = 0x7b
IFT_TUNNEL = 0x83
IFT_ULTRA = 0x1d
IFT_USB = 0xa0
IFT_V11 = 0x40
IFT_V35 = 0x2d
IFT_V36 = 0x41
IFT_V37 = 0x78
IFT_VDSL = 0x61
IFT_VIRTUALIPADDRESS = 0x70
IFT_VOICEEM = 0x64
IFT_VOICEENCAP = 0x67
IFT_VOICEFXO = 0x65
IFT_VOICEFXS = 0x66
IFT_VOICEOVERATM = 0x98
IFT_VOICEOVERFRAMERELAY = 0x99
IFT_VOICEOVERIP = 0x68
IFT_X213 = 0x5d
IFT_X25 = 0x5
IFT_X25DDN = 0x4
IFT_X25HUNTGROUP = 0x7a
IFT_X25MLP = 0x79
IFT_X25PLE = 0x28
IFT_XETHER = 0x1a
IPPROTO_MAXID = 0x34
IPV6_FAITH = 0x1d
IPV6_MIN_MEMBERSHIPS = 0x1f
IP_FAITH = 0x16
IP_MAX_SOURCE_FILTER = 0x400
IP_MIN_MEMBERSHIPS = 0x1f
MAP_NORESERVE = 0x40
MAP_RENAME = 0x20
NET_RT_MAXID = 0x6
RTF_PRCLONING = 0x10000
RTM_OLDADD = 0x9
RTM_OLDDEL = 0xa
RT_CACHING_CONTEXT = 0x1
RT_NORTREF = 0x2
SIOCADDRT = 0x8030720a
SIOCALIFADDR = 0x8118691b
SIOCDELRT = 0x8030720b
SIOCDLIFADDR = 0x8118691d
SIOCGLIFADDR = 0xc118691c
SIOCGLIFPHYADDR = 0xc118694b
SIOCSLIFPHYADDR = 0x8118694a
)
-233
View File
@@ -1,233 +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.
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
// them here for backwards compatibility.
package unix
const (
DLT_HHDLC = 0x79
IFF_SMART = 0x20
IFT_1822 = 0x2
IFT_A12MPPSWITCH = 0x82
IFT_AAL2 = 0xbb
IFT_AAL5 = 0x31
IFT_ADSL = 0x5e
IFT_AFLANE8023 = 0x3b
IFT_AFLANE8025 = 0x3c
IFT_ARAP = 0x58
IFT_ARCNET = 0x23
IFT_ARCNETPLUS = 0x24
IFT_ASYNC = 0x54
IFT_ATM = 0x25
IFT_ATMDXI = 0x69
IFT_ATMFUNI = 0x6a
IFT_ATMIMA = 0x6b
IFT_ATMLOGICAL = 0x50
IFT_ATMRADIO = 0xbd
IFT_ATMSUBINTERFACE = 0x86
IFT_ATMVCIENDPT = 0xc2
IFT_ATMVIRTUAL = 0x95
IFT_BGPPOLICYACCOUNTING = 0xa2
IFT_BSC = 0x53
IFT_CCTEMUL = 0x3d
IFT_CEPT = 0x13
IFT_CES = 0x85
IFT_CHANNEL = 0x46
IFT_CNR = 0x55
IFT_COFFEE = 0x84
IFT_COMPOSITELINK = 0x9b
IFT_DCN = 0x8d
IFT_DIGITALPOWERLINE = 0x8a
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
IFT_DLSW = 0x4a
IFT_DOCSCABLEDOWNSTREAM = 0x80
IFT_DOCSCABLEMACLAYER = 0x7f
IFT_DOCSCABLEUPSTREAM = 0x81
IFT_DS0 = 0x51
IFT_DS0BUNDLE = 0x52
IFT_DS1FDL = 0xaa
IFT_DS3 = 0x1e
IFT_DTM = 0x8c
IFT_DVBASILN = 0xac
IFT_DVBASIOUT = 0xad
IFT_DVBRCCDOWNSTREAM = 0x93
IFT_DVBRCCMACLAYER = 0x92
IFT_DVBRCCUPSTREAM = 0x94
IFT_ENC = 0xf4
IFT_EON = 0x19
IFT_EPLRS = 0x57
IFT_ESCON = 0x49
IFT_ETHER = 0x6
IFT_FAITH = 0xf2
IFT_FAST = 0x7d
IFT_FASTETHER = 0x3e
IFT_FASTETHERFX = 0x45
IFT_FDDI = 0xf
IFT_FIBRECHANNEL = 0x38
IFT_FRAMERELAYINTERCONNECT = 0x3a
IFT_FRAMERELAYMPI = 0x5c
IFT_FRDLCIENDPT = 0xc1
IFT_FRELAY = 0x20
IFT_FRELAYDCE = 0x2c
IFT_FRF16MFRBUNDLE = 0xa3
IFT_FRFORWARD = 0x9e
IFT_G703AT2MB = 0x43
IFT_G703AT64K = 0x42
IFT_GIF = 0xf0
IFT_GIGABITETHERNET = 0x75
IFT_GR303IDT = 0xb2
IFT_GR303RDT = 0xb1
IFT_H323GATEKEEPER = 0xa4
IFT_H323PROXY = 0xa5
IFT_HDH1822 = 0x3
IFT_HDLC = 0x76
IFT_HDSL2 = 0xa8
IFT_HIPERLAN2 = 0xb7
IFT_HIPPI = 0x2f
IFT_HIPPIINTERFACE = 0x39
IFT_HOSTPAD = 0x5a
IFT_HSSI = 0x2e
IFT_HY = 0xe
IFT_IBM370PARCHAN = 0x48
IFT_IDSL = 0x9a
IFT_IEEE80211 = 0x47
IFT_IEEE80212 = 0x37
IFT_IEEE8023ADLAG = 0xa1
IFT_IFGSN = 0x91
IFT_IMT = 0xbe
IFT_INTERLEAVE = 0x7c
IFT_IP = 0x7e
IFT_IPFORWARD = 0x8e
IFT_IPOVERATM = 0x72
IFT_IPOVERCDLC = 0x6d
IFT_IPOVERCLAW = 0x6e
IFT_IPSWITCH = 0x4e
IFT_IPXIP = 0xf9
IFT_ISDN = 0x3f
IFT_ISDNBASIC = 0x14
IFT_ISDNPRIMARY = 0x15
IFT_ISDNS = 0x4b
IFT_ISDNU = 0x4c
IFT_ISO88022LLC = 0x29
IFT_ISO88023 = 0x7
IFT_ISO88024 = 0x8
IFT_ISO88025 = 0x9
IFT_ISO88025CRFPINT = 0x62
IFT_ISO88025DTR = 0x56
IFT_ISO88025FIBER = 0x73
IFT_ISO88026 = 0xa
IFT_ISUP = 0xb3
IFT_L3IPXVLAN = 0x89
IFT_LAPB = 0x10
IFT_LAPD = 0x4d
IFT_LAPF = 0x77
IFT_LOCALTALK = 0x2a
IFT_LOOP = 0x18
IFT_MEDIAMAILOVERIP = 0x8b
IFT_MFSIGLINK = 0xa7
IFT_MIOX25 = 0x26
IFT_MODEM = 0x30
IFT_MPC = 0x71
IFT_MPLS = 0xa6
IFT_MPLSTUNNEL = 0x96
IFT_MSDSL = 0x8f
IFT_MVL = 0xbf
IFT_MYRINET = 0x63
IFT_NFAS = 0xaf
IFT_NSIP = 0x1b
IFT_OPTICALCHANNEL = 0xc3
IFT_OPTICALTRANSPORT = 0xc4
IFT_OTHER = 0x1
IFT_P10 = 0xc
IFT_P80 = 0xd
IFT_PARA = 0x22
IFT_PFLOG = 0xf6
IFT_PFSYNC = 0xf7
IFT_PLC = 0xae
IFT_POS = 0xab
IFT_PPPMULTILINKBUNDLE = 0x6c
IFT_PROPBWAP2MP = 0xb8
IFT_PROPCNLS = 0x59
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
IFT_PROPMUX = 0x36
IFT_PROPWIRELESSP2P = 0x9d
IFT_PTPSERIAL = 0x16
IFT_PVC = 0xf1
IFT_QLLC = 0x44
IFT_RADIOMAC = 0xbc
IFT_RADSL = 0x5f
IFT_REACHDSL = 0xc0
IFT_RFC1483 = 0x9f
IFT_RS232 = 0x21
IFT_RSRB = 0x4f
IFT_SDLC = 0x11
IFT_SDSL = 0x60
IFT_SHDSL = 0xa9
IFT_SIP = 0x1f
IFT_SLIP = 0x1c
IFT_SMDSDXI = 0x2b
IFT_SMDSICIP = 0x34
IFT_SONET = 0x27
IFT_SONETOVERHEADCHANNEL = 0xb9
IFT_SONETPATH = 0x32
IFT_SONETVT = 0x33
IFT_SRP = 0x97
IFT_SS7SIGLINK = 0x9c
IFT_STACKTOSTACK = 0x6f
IFT_STARLAN = 0xb
IFT_STF = 0xd7
IFT_T1 = 0x12
IFT_TDLC = 0x74
IFT_TERMPAD = 0x5b
IFT_TR008 = 0xb0
IFT_TRANSPHDLC = 0x7b
IFT_TUNNEL = 0x83
IFT_ULTRA = 0x1d
IFT_USB = 0xa0
IFT_V11 = 0x40
IFT_V35 = 0x2d
IFT_V36 = 0x41
IFT_V37 = 0x78
IFT_VDSL = 0x61
IFT_VIRTUALIPADDRESS = 0x70
IFT_VOICEEM = 0x64
IFT_VOICEENCAP = 0x67
IFT_VOICEFXO = 0x65
IFT_VOICEFXS = 0x66
IFT_VOICEOVERATM = 0x98
IFT_VOICEOVERFRAMERELAY = 0x99
IFT_VOICEOVERIP = 0x68
IFT_X213 = 0x5d
IFT_X25 = 0x5
IFT_X25DDN = 0x4
IFT_X25HUNTGROUP = 0x7a
IFT_X25MLP = 0x79
IFT_X25PLE = 0x28
IFT_XETHER = 0x1a
IPPROTO_MAXID = 0x34
IPV6_FAITH = 0x1d
IPV6_MIN_MEMBERSHIPS = 0x1f
IP_FAITH = 0x16
IP_MAX_SOURCE_FILTER = 0x400
IP_MIN_MEMBERSHIPS = 0x1f
MAP_NORESERVE = 0x40
MAP_RENAME = 0x20
NET_RT_MAXID = 0x6
RTF_PRCLONING = 0x10000
RTM_OLDADD = 0x9
RTM_OLDDEL = 0xa
RT_CACHING_CONTEXT = 0x1
RT_NORTREF = 0x2
SIOCADDRT = 0x8040720a
SIOCALIFADDR = 0x8118691b
SIOCDELRT = 0x8040720b
SIOCDLIFADDR = 0x8118691d
SIOCGLIFADDR = 0xc118691c
SIOCGLIFPHYADDR = 0xc118694b
SIOCSLIFPHYADDR = 0x8118694a
)
-226
View File
@@ -1,226 +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.
package unix
const (
IFT_1822 = 0x2
IFT_A12MPPSWITCH = 0x82
IFT_AAL2 = 0xbb
IFT_AAL5 = 0x31
IFT_ADSL = 0x5e
IFT_AFLANE8023 = 0x3b
IFT_AFLANE8025 = 0x3c
IFT_ARAP = 0x58
IFT_ARCNET = 0x23
IFT_ARCNETPLUS = 0x24
IFT_ASYNC = 0x54
IFT_ATM = 0x25
IFT_ATMDXI = 0x69
IFT_ATMFUNI = 0x6a
IFT_ATMIMA = 0x6b
IFT_ATMLOGICAL = 0x50
IFT_ATMRADIO = 0xbd
IFT_ATMSUBINTERFACE = 0x86
IFT_ATMVCIENDPT = 0xc2
IFT_ATMVIRTUAL = 0x95
IFT_BGPPOLICYACCOUNTING = 0xa2
IFT_BSC = 0x53
IFT_CCTEMUL = 0x3d
IFT_CEPT = 0x13
IFT_CES = 0x85
IFT_CHANNEL = 0x46
IFT_CNR = 0x55
IFT_COFFEE = 0x84
IFT_COMPOSITELINK = 0x9b
IFT_DCN = 0x8d
IFT_DIGITALPOWERLINE = 0x8a
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
IFT_DLSW = 0x4a
IFT_DOCSCABLEDOWNSTREAM = 0x80
IFT_DOCSCABLEMACLAYER = 0x7f
IFT_DOCSCABLEUPSTREAM = 0x81
IFT_DS0 = 0x51
IFT_DS0BUNDLE = 0x52
IFT_DS1FDL = 0xaa
IFT_DS3 = 0x1e
IFT_DTM = 0x8c
IFT_DVBASILN = 0xac
IFT_DVBASIOUT = 0xad
IFT_DVBRCCDOWNSTREAM = 0x93
IFT_DVBRCCMACLAYER = 0x92
IFT_DVBRCCUPSTREAM = 0x94
IFT_ENC = 0xf4
IFT_EON = 0x19
IFT_EPLRS = 0x57
IFT_ESCON = 0x49
IFT_ETHER = 0x6
IFT_FAST = 0x7d
IFT_FASTETHER = 0x3e
IFT_FASTETHERFX = 0x45
IFT_FDDI = 0xf
IFT_FIBRECHANNEL = 0x38
IFT_FRAMERELAYINTERCONNECT = 0x3a
IFT_FRAMERELAYMPI = 0x5c
IFT_FRDLCIENDPT = 0xc1
IFT_FRELAY = 0x20
IFT_FRELAYDCE = 0x2c
IFT_FRF16MFRBUNDLE = 0xa3
IFT_FRFORWARD = 0x9e
IFT_G703AT2MB = 0x43
IFT_G703AT64K = 0x42
IFT_GIF = 0xf0
IFT_GIGABITETHERNET = 0x75
IFT_GR303IDT = 0xb2
IFT_GR303RDT = 0xb1
IFT_H323GATEKEEPER = 0xa4
IFT_H323PROXY = 0xa5
IFT_HDH1822 = 0x3
IFT_HDLC = 0x76
IFT_HDSL2 = 0xa8
IFT_HIPERLAN2 = 0xb7
IFT_HIPPI = 0x2f
IFT_HIPPIINTERFACE = 0x39
IFT_HOSTPAD = 0x5a
IFT_HSSI = 0x2e
IFT_HY = 0xe
IFT_IBM370PARCHAN = 0x48
IFT_IDSL = 0x9a
IFT_IEEE80211 = 0x47
IFT_IEEE80212 = 0x37
IFT_IEEE8023ADLAG = 0xa1
IFT_IFGSN = 0x91
IFT_IMT = 0xbe
IFT_INTERLEAVE = 0x7c
IFT_IP = 0x7e
IFT_IPFORWARD = 0x8e
IFT_IPOVERATM = 0x72
IFT_IPOVERCDLC = 0x6d
IFT_IPOVERCLAW = 0x6e
IFT_IPSWITCH = 0x4e
IFT_ISDN = 0x3f
IFT_ISDNBASIC = 0x14
IFT_ISDNPRIMARY = 0x15
IFT_ISDNS = 0x4b
IFT_ISDNU = 0x4c
IFT_ISO88022LLC = 0x29
IFT_ISO88023 = 0x7
IFT_ISO88024 = 0x8
IFT_ISO88025 = 0x9
IFT_ISO88025CRFPINT = 0x62
IFT_ISO88025DTR = 0x56
IFT_ISO88025FIBER = 0x73
IFT_ISO88026 = 0xa
IFT_ISUP = 0xb3
IFT_L3IPXVLAN = 0x89
IFT_LAPB = 0x10
IFT_LAPD = 0x4d
IFT_LAPF = 0x77
IFT_LOCALTALK = 0x2a
IFT_LOOP = 0x18
IFT_MEDIAMAILOVERIP = 0x8b
IFT_MFSIGLINK = 0xa7
IFT_MIOX25 = 0x26
IFT_MODEM = 0x30
IFT_MPC = 0x71
IFT_MPLS = 0xa6
IFT_MPLSTUNNEL = 0x96
IFT_MSDSL = 0x8f
IFT_MVL = 0xbf
IFT_MYRINET = 0x63
IFT_NFAS = 0xaf
IFT_NSIP = 0x1b
IFT_OPTICALCHANNEL = 0xc3
IFT_OPTICALTRANSPORT = 0xc4
IFT_OTHER = 0x1
IFT_P10 = 0xc
IFT_P80 = 0xd
IFT_PARA = 0x22
IFT_PFLOG = 0xf6
IFT_PFSYNC = 0xf7
IFT_PLC = 0xae
IFT_POS = 0xab
IFT_PPPMULTILINKBUNDLE = 0x6c
IFT_PROPBWAP2MP = 0xb8
IFT_PROPCNLS = 0x59
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
IFT_PROPMUX = 0x36
IFT_PROPWIRELESSP2P = 0x9d
IFT_PTPSERIAL = 0x16
IFT_PVC = 0xf1
IFT_QLLC = 0x44
IFT_RADIOMAC = 0xbc
IFT_RADSL = 0x5f
IFT_REACHDSL = 0xc0
IFT_RFC1483 = 0x9f
IFT_RS232 = 0x21
IFT_RSRB = 0x4f
IFT_SDLC = 0x11
IFT_SDSL = 0x60
IFT_SHDSL = 0xa9
IFT_SIP = 0x1f
IFT_SLIP = 0x1c
IFT_SMDSDXI = 0x2b
IFT_SMDSICIP = 0x34
IFT_SONET = 0x27
IFT_SONETOVERHEADCHANNEL = 0xb9
IFT_SONETPATH = 0x32
IFT_SONETVT = 0x33
IFT_SRP = 0x97
IFT_SS7SIGLINK = 0x9c
IFT_STACKTOSTACK = 0x6f
IFT_STARLAN = 0xb
IFT_STF = 0xd7
IFT_T1 = 0x12
IFT_TDLC = 0x74
IFT_TERMPAD = 0x5b
IFT_TR008 = 0xb0
IFT_TRANSPHDLC = 0x7b
IFT_TUNNEL = 0x83
IFT_ULTRA = 0x1d
IFT_USB = 0xa0
IFT_V11 = 0x40
IFT_V35 = 0x2d
IFT_V36 = 0x41
IFT_V37 = 0x78
IFT_VDSL = 0x61
IFT_VIRTUALIPADDRESS = 0x70
IFT_VOICEEM = 0x64
IFT_VOICEENCAP = 0x67
IFT_VOICEFXO = 0x65
IFT_VOICEFXS = 0x66
IFT_VOICEOVERATM = 0x98
IFT_VOICEOVERFRAMERELAY = 0x99
IFT_VOICEOVERIP = 0x68
IFT_X213 = 0x5d
IFT_X25 = 0x5
IFT_X25DDN = 0x4
IFT_X25HUNTGROUP = 0x7a
IFT_X25MLP = 0x79
IFT_X25PLE = 0x28
IFT_XETHER = 0x1a
// missing constants on FreeBSD-11.1-RELEASE, copied from old values in ztypes_freebsd_arm.go
IFF_SMART = 0x20
IFT_FAITH = 0xf2
IFT_IPXIP = 0xf9
IPPROTO_MAXID = 0x34
IPV6_FAITH = 0x1d
IP_FAITH = 0x16
MAP_NORESERVE = 0x40
MAP_RENAME = 0x20
NET_RT_MAXID = 0x6
RTF_PRCLONING = 0x10000
RTM_OLDADD = 0x9
RTM_OLDDEL = 0xa
SIOCADDRT = 0x8030720a
SIOCALIFADDR = 0x8118691b
SIOCDELRT = 0x8030720b
SIOCDLIFADDR = 0x8118691d
SIOCGLIFADDR = 0xc118691c
SIOCGLIFPHYADDR = 0xc118694b
SIOCSLIFPHYADDR = 0x8118694a
)
-17
View File
@@ -1,17 +0,0 @@
// Copyright 2020 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.
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
// them here for backwards compatibility.
package unix
const (
DLT_HHDLC = 0x79
IPV6_MIN_MEMBERSHIPS = 0x1f
IP_MAX_SOURCE_FILTER = 0x400
IP_MIN_MEMBERSHIPS = 0x1f
RT_CACHING_CONTEXT = 0x1
RT_NORTREF = 0x2
)
+9 -4
View File
@@ -89,25 +89,30 @@ dragonfly_amd64)
freebsd_386)
mkerrors="$mkerrors -m32"
mksyscall="go run mksyscall.go -l32"
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
freebsd_amd64)
mkerrors="$mkerrors -m64"
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
freebsd_arm)
mkerrors="$mkerrors"
mksyscall="go run mksyscall.go -l32 -arm"
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'"
# Let the type of C char be signed for making the bare syscall
# API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
freebsd_arm64)
mkerrors="$mkerrors -m64"
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'"
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
freebsd_riscv64)
mkerrors="$mkerrors -m64"
mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'"
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
netbsd_386)
+8 -2
View File
@@ -128,6 +128,7 @@ includes_FreeBSD='
#include <sys/mount.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/ptrace.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_types.h>
@@ -202,6 +203,7 @@ struct ltchars {
#include <sys/timerfd.h>
#include <sys/uio.h>
#include <sys/xattr.h>
#include <linux/audit.h>
#include <linux/bpf.h>
#include <linux/can.h>
#include <linux/can/error.h>
@@ -295,6 +297,10 @@ struct ltchars {
#define SOL_NETLINK 270
#endif
#ifndef SOL_SMC
#define SOL_SMC 286
#endif
#ifdef SOL_BLUETOOTH
// SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h
// but it is already in bluetooth_linux.go
@@ -529,7 +535,7 @@ ccflags="$@"
$2 ~ /^(MS|MNT|MOUNT|UMOUNT)_/ ||
$2 ~ /^NS_GET_/ ||
$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
$2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT|TFD)_/ ||
$2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT|PIOD|TFD)_/ ||
$2 ~ /^KEXEC_/ ||
$2 ~ /^LINUX_REBOOT_CMD_/ ||
$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
@@ -553,6 +559,7 @@ ccflags="$@"
$2 ~ /^CLONE_[A-Z_]+/ ||
$2 !~ /^(BPF_TIMEVAL|BPF_FIB_LOOKUP_[A-Z]+)$/ &&
$2 ~ /^(BPF|DLT)_/ ||
$2 ~ /^AUDIT_/ ||
$2 ~ /^(CLOCK|TIMER)_/ ||
$2 ~ /^CAN_/ ||
$2 ~ /^CAP_/ ||
@@ -575,7 +582,6 @@ ccflags="$@"
$2 ~ /^SEEK_/ ||
$2 ~ /^SPLICE_/ ||
$2 ~ /^SYNC_FILE_RANGE_/ ||
$2 !~ /^AUDIT_RECORD_MAGIC/ &&
$2 !~ /IOC_MAGIC/ &&
$2 ~ /^[A-Z][A-Z0-9_]+_MAGIC2?$/ ||
$2 ~ /^(VM|VMADDR)_/ ||
+2 -2
View File
@@ -217,12 +217,12 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) {
return
}
func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
// Recvmsg not implemented on AIX
return -1, -1, -1, ENOSYS
}
func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
// SendmsgN not implemented on AIX
return -1, ENOSYS
}
+23 -23
View File
@@ -325,27 +325,26 @@ func GetsockoptString(fd, level, opt int) (string, error) {
//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
var msg Msghdr
msg.Name = (*byte)(unsafe.Pointer(rsa))
msg.Namelen = uint32(SizeofSockaddrAny)
var iov Iovec
if len(p) > 0 {
iov.Base = (*byte)(unsafe.Pointer(&p[0]))
iov.SetLen(len(p))
}
var dummy byte
if len(oob) > 0 {
// receive at least one normal byte
if len(p) == 0 {
iov.Base = &dummy
iov.SetLen(1)
if emptyIovecs(iov) {
var iova [1]Iovec
iova[0].Base = &dummy
iova[0].SetLen(1)
iov = iova[:]
}
msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
msg.SetControllen(len(oob))
}
msg.Iov = &iov
msg.Iovlen = 1
if len(iov) > 0 {
msg.Iov = &iov[0]
msg.SetIovlen(len(iov))
}
if n, err = recvmsg(fd, &msg, flags); err != nil {
return
}
@@ -356,31 +355,32 @@ func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
var msg Msghdr
msg.Name = (*byte)(unsafe.Pointer(ptr))
msg.Namelen = uint32(salen)
var iov Iovec
if len(p) > 0 {
iov.Base = (*byte)(unsafe.Pointer(&p[0]))
iov.SetLen(len(p))
}
var dummy byte
var empty bool
if len(oob) > 0 {
// send at least one normal byte
if len(p) == 0 {
iov.Base = &dummy
iov.SetLen(1)
empty := emptyIovecs(iov)
if empty {
var iova [1]Iovec
iova[0].Base = &dummy
iova[0].SetLen(1)
iov = iova[:]
}
msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
msg.SetControllen(len(oob))
}
msg.Iov = &iov
msg.Iovlen = 1
if len(iov) > 0 {
msg.Iov = &iov[0]
msg.SetIovlen(len(iov))
}
if n, err = sendmsg(fd, &msg, flags); err != nil {
return 0, err
}
if len(oob) > 0 && len(p) == 0 {
if len(oob) > 0 && empty {
n = 0
}
return n, nil
+7
View File
@@ -393,6 +393,13 @@ func GetsockoptXucred(fd, level, opt int) (*Xucred, error) {
return x, err
}
func GetsockoptTCPConnectionInfo(fd, level, opt int) (*TCPConnectionInfo, error) {
var value TCPConnectionInfo
vallen := _Socklen(SizeofTCPConnectionInfo)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
}
func SysctlKinfoProc(name string, args ...int) (*KinfoProc, error) {
mib, err := sysctlmib(name, args...)
if err != nil {
+35 -290
View File
@@ -17,25 +17,12 @@ import (
"unsafe"
)
const (
SYS_FSTAT_FREEBSD12 = 551 // { int fstat(int fd, _Out_ struct stat *sb); }
SYS_FSTATAT_FREEBSD12 = 552 // { int fstatat(int fd, _In_z_ char *path, \
SYS_GETDIRENTRIES_FREEBSD12 = 554 // { ssize_t getdirentries(int fd, \
SYS_STATFS_FREEBSD12 = 555 // { int statfs(_In_z_ char *path, \
SYS_FSTATFS_FREEBSD12 = 556 // { int fstatfs(int fd, \
SYS_GETFSSTAT_FREEBSD12 = 557 // { int getfsstat( \
SYS_MKNODAT_FREEBSD12 = 559 // { int mknodat(int fd, _In_z_ char *path, \
)
// See https://www.freebsd.org/doc/en_US.ISO8859-1/books/porters-handbook/versions.html.
var (
osreldateOnce sync.Once
osreldate uint32
)
// INO64_FIRST from /usr/src/lib/libc/sys/compat-ino64.h
const _ino64First = 1200031
func supportsABI(ver uint32) bool {
osreldateOnce.Do(func() { osreldate, _ = SysctlUint32("kern.osreldate") })
return osreldate >= ver
@@ -159,38 +146,18 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) {
func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
var (
_p0 unsafe.Pointer
bufsize uintptr
oldBuf []statfs_freebsd11_t
needsConvert bool
_p0 unsafe.Pointer
bufsize uintptr
)
if len(buf) > 0 {
if supportsABI(_ino64First) {
_p0 = unsafe.Pointer(&buf[0])
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
} else {
n := len(buf)
oldBuf = make([]statfs_freebsd11_t, n)
_p0 = unsafe.Pointer(&oldBuf[0])
bufsize = unsafe.Sizeof(statfs_freebsd11_t{}) * uintptr(n)
needsConvert = true
}
_p0 = unsafe.Pointer(&buf[0])
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
}
var sysno uintptr = SYS_GETFSSTAT
if supportsABI(_ino64First) {
sysno = SYS_GETFSSTAT_FREEBSD12
}
r0, _, e1 := Syscall(sysno, uintptr(_p0), bufsize, uintptr(flags))
r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
n = int(r0)
if e1 != 0 {
err = e1
}
if e1 == 0 && needsConvert {
for i := range oldBuf {
buf[i].convertFrom(&oldBuf[i])
}
}
return
}
@@ -245,87 +212,11 @@ func Uname(uname *Utsname) error {
}
func Stat(path string, st *Stat_t) (err error) {
var oldStat stat_freebsd11_t
if supportsABI(_ino64First) {
return fstatat_freebsd12(AT_FDCWD, path, st, 0)
}
err = stat(path, &oldStat)
if err != nil {
return err
}
st.convertFrom(&oldStat)
return nil
return Fstatat(AT_FDCWD, path, st, 0)
}
func Lstat(path string, st *Stat_t) (err error) {
var oldStat stat_freebsd11_t
if supportsABI(_ino64First) {
return fstatat_freebsd12(AT_FDCWD, path, st, AT_SYMLINK_NOFOLLOW)
}
err = lstat(path, &oldStat)
if err != nil {
return err
}
st.convertFrom(&oldStat)
return nil
}
func Fstat(fd int, st *Stat_t) (err error) {
var oldStat stat_freebsd11_t
if supportsABI(_ino64First) {
return fstat_freebsd12(fd, st)
}
err = fstat(fd, &oldStat)
if err != nil {
return err
}
st.convertFrom(&oldStat)
return nil
}
func Fstatat(fd int, path string, st *Stat_t, flags int) (err error) {
var oldStat stat_freebsd11_t
if supportsABI(_ino64First) {
return fstatat_freebsd12(fd, path, st, flags)
}
err = fstatat(fd, path, &oldStat, flags)
if err != nil {
return err
}
st.convertFrom(&oldStat)
return nil
}
func Statfs(path string, st *Statfs_t) (err error) {
var oldStatfs statfs_freebsd11_t
if supportsABI(_ino64First) {
return statfs_freebsd12(path, st)
}
err = statfs(path, &oldStatfs)
if err != nil {
return err
}
st.convertFrom(&oldStatfs)
return nil
}
func Fstatfs(fd int, st *Statfs_t) (err error) {
var oldStatfs statfs_freebsd11_t
if supportsABI(_ino64First) {
return fstatfs_freebsd12(fd, st)
}
err = fstatfs(fd, &oldStatfs)
if err != nil {
return err
}
st.convertFrom(&oldStatfs)
return nil
return Fstatat(AT_FDCWD, path, st, AT_SYMLINK_NOFOLLOW)
}
func Getdents(fd int, buf []byte) (n int, err error) {
@@ -333,162 +224,25 @@ func Getdents(fd int, buf []byte) (n int, err error) {
}
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
if supportsABI(_ino64First) {
if basep == nil || unsafe.Sizeof(*basep) == 8 {
return getdirentries_freebsd12(fd, buf, (*uint64)(unsafe.Pointer(basep)))
}
// The freebsd12 syscall needs a 64-bit base. On 32-bit machines
// we can't just use the basep passed in. See #32498.
var base uint64 = uint64(*basep)
n, err = getdirentries_freebsd12(fd, buf, &base)
*basep = uintptr(base)
if base>>32 != 0 {
// We can't stuff the base back into a uintptr, so any
// future calls would be suspect. Generate an error.
// EIO is allowed by getdirentries.
err = EIO
}
return
if basep == nil || unsafe.Sizeof(*basep) == 8 {
return getdirentries(fd, buf, (*uint64)(unsafe.Pointer(basep)))
}
// The old syscall entries are smaller than the new. Use 1/4 of the original
// buffer size rounded up to DIRBLKSIZ (see /usr/src/lib/libc/sys/getdirentries.c).
oldBufLen := roundup(len(buf)/4, _dirblksiz)
oldBuf := make([]byte, oldBufLen)
n, err = getdirentries(fd, oldBuf, basep)
if err == nil && n > 0 {
n = convertFromDirents11(buf, oldBuf[:n])
// The syscall needs a 64-bit base. On 32-bit machines
// we can't just use the basep passed in. See #32498.
var base uint64 = uint64(*basep)
n, err = getdirentries(fd, buf, &base)
*basep = uintptr(base)
if base>>32 != 0 {
// We can't stuff the base back into a uintptr, so any
// future calls would be suspect. Generate an error.
// EIO is allowed by getdirentries.
err = EIO
}
return
}
func Mknod(path string, mode uint32, dev uint64) (err error) {
var oldDev int
if supportsABI(_ino64First) {
return mknodat_freebsd12(AT_FDCWD, path, mode, dev)
}
oldDev = int(dev)
return mknod(path, mode, oldDev)
}
func Mknodat(fd int, path string, mode uint32, dev uint64) (err error) {
var oldDev int
if supportsABI(_ino64First) {
return mknodat_freebsd12(fd, path, mode, dev)
}
oldDev = int(dev)
return mknodat(fd, path, mode, oldDev)
}
// round x to the nearest multiple of y, larger or equal to x.
//
// from /usr/include/sys/param.h Macros for counting and rounding.
// #define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
func roundup(x, y int) int {
return ((x + y - 1) / y) * y
}
func (s *Stat_t) convertFrom(old *stat_freebsd11_t) {
*s = Stat_t{
Dev: uint64(old.Dev),
Ino: uint64(old.Ino),
Nlink: uint64(old.Nlink),
Mode: old.Mode,
Uid: old.Uid,
Gid: old.Gid,
Rdev: uint64(old.Rdev),
Atim: old.Atim,
Mtim: old.Mtim,
Ctim: old.Ctim,
Btim: old.Btim,
Size: old.Size,
Blocks: old.Blocks,
Blksize: old.Blksize,
Flags: old.Flags,
Gen: uint64(old.Gen),
}
}
func (s *Statfs_t) convertFrom(old *statfs_freebsd11_t) {
*s = Statfs_t{
Version: _statfsVersion,
Type: old.Type,
Flags: old.Flags,
Bsize: old.Bsize,
Iosize: old.Iosize,
Blocks: old.Blocks,
Bfree: old.Bfree,
Bavail: old.Bavail,
Files: old.Files,
Ffree: old.Ffree,
Syncwrites: old.Syncwrites,
Asyncwrites: old.Asyncwrites,
Syncreads: old.Syncreads,
Asyncreads: old.Asyncreads,
// Spare
Namemax: old.Namemax,
Owner: old.Owner,
Fsid: old.Fsid,
// Charspare
// Fstypename
// Mntfromname
// Mntonname
}
sl := old.Fstypename[:]
n := clen(*(*[]byte)(unsafe.Pointer(&sl)))
copy(s.Fstypename[:], old.Fstypename[:n])
sl = old.Mntfromname[:]
n = clen(*(*[]byte)(unsafe.Pointer(&sl)))
copy(s.Mntfromname[:], old.Mntfromname[:n])
sl = old.Mntonname[:]
n = clen(*(*[]byte)(unsafe.Pointer(&sl)))
copy(s.Mntonname[:], old.Mntonname[:n])
}
func convertFromDirents11(buf []byte, old []byte) int {
const (
fixedSize = int(unsafe.Offsetof(Dirent{}.Name))
oldFixedSize = int(unsafe.Offsetof(dirent_freebsd11{}.Name))
)
dstPos := 0
srcPos := 0
for dstPos+fixedSize < len(buf) && srcPos+oldFixedSize < len(old) {
var dstDirent Dirent
var srcDirent dirent_freebsd11
// If multiple direntries are written, sometimes when we reach the final one,
// we may have cap of old less than size of dirent_freebsd11.
copy((*[unsafe.Sizeof(srcDirent)]byte)(unsafe.Pointer(&srcDirent))[:], old[srcPos:])
reclen := roundup(fixedSize+int(srcDirent.Namlen)+1, 8)
if dstPos+reclen > len(buf) {
break
}
dstDirent.Fileno = uint64(srcDirent.Fileno)
dstDirent.Off = 0
dstDirent.Reclen = uint16(reclen)
dstDirent.Type = srcDirent.Type
dstDirent.Pad0 = 0
dstDirent.Namlen = uint16(srcDirent.Namlen)
dstDirent.Pad1 = 0
copy(dstDirent.Name[:], srcDirent.Name[:srcDirent.Namlen])
copy(buf[dstPos:], (*[unsafe.Sizeof(dstDirent)]byte)(unsafe.Pointer(&dstDirent))[:])
padding := buf[dstPos+fixedSize+int(dstDirent.Namlen) : dstPos+reclen]
for i := range padding {
padding[i] = 0
}
dstPos += int(dstDirent.Reclen)
srcPos += int(srcDirent.Reclen)
}
return dstPos
return Mknodat(AT_FDCWD, path, mode, dev)
}
func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
@@ -501,31 +255,31 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
//sys ptrace(request int, pid int, addr uintptr, data int) (err error)
func PtraceAttach(pid int) (err error) {
return ptrace(PTRACE_ATTACH, pid, 0, 0)
return ptrace(PT_ATTACH, pid, 0, 0)
}
func PtraceCont(pid int, signal int) (err error) {
return ptrace(PTRACE_CONT, pid, 1, signal)
return ptrace(PT_CONTINUE, pid, 1, signal)
}
func PtraceDetach(pid int) (err error) {
return ptrace(PTRACE_DETACH, pid, 1, 0)
return ptrace(PT_DETACH, pid, 1, 0)
}
func PtraceGetFpRegs(pid int, fpregsout *FpReg) (err error) {
return ptrace(PTRACE_GETFPREGS, pid, uintptr(unsafe.Pointer(fpregsout)), 0)
return ptrace(PT_GETFPREGS, pid, uintptr(unsafe.Pointer(fpregsout)), 0)
}
func PtraceGetRegs(pid int, regsout *Reg) (err error) {
return ptrace(PTRACE_GETREGS, pid, uintptr(unsafe.Pointer(regsout)), 0)
return ptrace(PT_GETREGS, pid, uintptr(unsafe.Pointer(regsout)), 0)
}
func PtraceLwpEvents(pid int, enable int) (err error) {
return ptrace(PTRACE_LWPEVENTS, pid, 0, enable)
return ptrace(PT_LWP_EVENTS, pid, 0, enable)
}
func PtraceLwpInfo(pid int, info uintptr) (err error) {
return ptrace(PTRACE_LWPINFO, pid, info, int(unsafe.Sizeof(PtraceLwpInfoStruct{})))
return ptrace(PT_LWPINFO, pid, info, int(unsafe.Sizeof(PtraceLwpInfoStruct{})))
}
func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
@@ -545,11 +299,11 @@ func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
}
func PtraceSetRegs(pid int, regs *Reg) (err error) {
return ptrace(PTRACE_SETREGS, pid, uintptr(unsafe.Pointer(regs)), 0)
return ptrace(PT_SETREGS, pid, uintptr(unsafe.Pointer(regs)), 0)
}
func PtraceSingleStep(pid int) (err error) {
return ptrace(PTRACE_SINGLESTEP, pid, 1, 0)
return ptrace(PT_STEP, pid, 1, 0)
}
/*
@@ -591,16 +345,12 @@ func PtraceSingleStep(pid int) (err error) {
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
//sys Flock(fd int, how int) (err error)
//sys Fpathconf(fd int, name int) (val int, err error)
//sys fstat(fd int, stat *stat_freebsd11_t) (err error)
//sys fstat_freebsd12(fd int, stat *Stat_t) (err error)
//sys fstatat(fd int, path string, stat *stat_freebsd11_t, flags int) (err error)
//sys fstatat_freebsd12(fd int, path string, stat *Stat_t, flags int) (err error)
//sys fstatfs(fd int, stat *statfs_freebsd11_t) (err error)
//sys fstatfs_freebsd12(fd int, stat *Statfs_t) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
//sys Fstatfs(fd int, stat *Statfs_t) (err error)
//sys Fsync(fd int) (err error)
//sys Ftruncate(fd int, length int64) (err error)
//sys getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error)
//sys getdirentries_freebsd12(fd int, buf []byte, basep *uint64) (n int, err error)
//sys getdirentries(fd int, buf []byte, basep *uint64) (n int, err error)
//sys Getdtablesize() (size int)
//sysnb Getegid() (egid int)
//sysnb Geteuid() (uid int)
@@ -622,13 +372,10 @@ func PtraceSingleStep(pid int) (err error) {
//sys Link(path string, link string) (err error)
//sys Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error)
//sys Listen(s int, backlog int) (err error)
//sys lstat(path string, stat *stat_freebsd11_t) (err error)
//sys Mkdir(path string, mode uint32) (err error)
//sys Mkdirat(dirfd int, path string, mode uint32) (err error)
//sys Mkfifo(path string, mode uint32) (err error)
//sys mknod(path string, mode uint32, dev int) (err error)
//sys mknodat(fd int, path string, mode uint32, dev int) (err error)
//sys mknodat_freebsd12(fd int, path string, mode uint32, dev uint64) (err error)
//sys Mknodat(fd int, path string, mode uint32, dev uint64) (err error)
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
//sys Open(path string, mode int, perm uint32) (fd int, err error)
//sys Openat(fdat int, path string, mode int, perm uint32) (fd int, err error)
@@ -658,9 +405,7 @@ func PtraceSingleStep(pid int) (err error) {
//sysnb Setsid() (pid int, err error)
//sysnb Settimeofday(tp *Timeval) (err error)
//sysnb Setuid(uid int) (err error)
//sys stat(path string, stat *stat_freebsd11_t) (err error)
//sys statfs(path string, stat *statfs_freebsd11_t) (err error)
//sys statfs_freebsd12(path string, stat *Statfs_t) (err error)
//sys Statfs(path string, stat *Statfs_t) (err error)
//sys Symlink(path string, link string) (err error)
//sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error)
//sys Sync() (err error)
+2 -2
View File
@@ -57,11 +57,11 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
func PtraceGetFsBase(pid int, fsbase *int64) (err error) {
return ptrace(PTRACE_GETFSBASE, pid, uintptr(unsafe.Pointer(fsbase)), 0)
return ptrace(PT_GETFSBASE, pid, uintptr(unsafe.Pointer(fsbase)), 0)
}
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint32(countin)}
err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
return int(ioDesc.Len), err
}
+2 -2
View File
@@ -57,11 +57,11 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
func PtraceGetFsBase(pid int, fsbase *int64) (err error) {
return ptrace(PTRACE_GETFSBASE, pid, uintptr(unsafe.Pointer(fsbase)), 0)
return ptrace(PT_GETFSBASE, pid, uintptr(unsafe.Pointer(fsbase)), 0)
}
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint64(countin)}
err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
return int(ioDesc.Len), err
}
+1 -1
View File
@@ -58,6 +58,6 @@ func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint32(countin)}
err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
return int(ioDesc.Len), err
}
+1 -1
View File
@@ -58,6 +58,6 @@ func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint64(countin)}
err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
return int(ioDesc.Len), err
}
+63
View File
@@ -0,0 +1,63 @@
// Copyright 2022 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.
//go:build riscv64 && freebsd
// +build riscv64,freebsd
package unix
import (
"syscall"
"unsafe"
)
func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec}
}
func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: sec, Usec: usec}
}
func SetKevent(k *Kevent_t, fd, mode, flags int) {
k.Ident = uint64(fd)
k.Filter = int16(mode)
k.Flags = uint16(flags)
}
func (iov *Iovec) SetLen(length int) {
iov.Len = uint64(length)
}
func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length)
}
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = int32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
var writtenOut uint64 = 0
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0)
written = int(writtenOut)
if e1 != 0 {
err = e1
}
return
}
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint64(countin)}
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
return int(ioDesc.Len), err
}
+2 -3
View File
@@ -20,10 +20,9 @@ func bytes2iovec(bs [][]byte) []Iovec {
for i, b := range bs {
iovecs[i].SetLen(len(b))
if len(b) > 0 {
// somehow Iovec.Base on illumos is (*int8), not (*byte)
iovecs[i].Base = (*int8)(unsafe.Pointer(&b[0]))
iovecs[i].Base = &b[0]
} else {
iovecs[i].Base = (*int8)(unsafe.Pointer(&_zero))
iovecs[i].Base = (*byte)(unsafe.Pointer(&_zero))
}
}
return iovecs
+22 -23
View File
@@ -1499,18 +1499,13 @@ func KeyctlRestrictKeyring(ringid int, keyType string, restriction string) error
//sys keyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) = SYS_KEYCTL
//sys keyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL
func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
var msg Msghdr
msg.Name = (*byte)(unsafe.Pointer(rsa))
msg.Namelen = uint32(SizeofSockaddrAny)
var iov Iovec
if len(p) > 0 {
iov.Base = &p[0]
iov.SetLen(len(p))
}
var dummy byte
if len(oob) > 0 {
if len(p) == 0 {
if emptyIovecs(iov) {
var sockType int
sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
if err != nil {
@@ -1518,15 +1513,19 @@ func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn
}
// receive at least one normal byte
if sockType != SOCK_DGRAM {
iov.Base = &dummy
iov.SetLen(1)
var iova [1]Iovec
iova[0].Base = &dummy
iova[0].SetLen(1)
iov = iova[:]
}
}
msg.Control = &oob[0]
msg.SetControllen(len(oob))
}
msg.Iov = &iov
msg.Iovlen = 1
if len(iov) > 0 {
msg.Iov = &iov[0]
msg.SetIovlen(len(iov))
}
if n, err = recvmsg(fd, &msg, flags); err != nil {
return
}
@@ -1535,18 +1534,15 @@ func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn
return
}
func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
var msg Msghdr
msg.Name = (*byte)(ptr)
msg.Namelen = uint32(salen)
var iov Iovec
if len(p) > 0 {
iov.Base = &p[0]
iov.SetLen(len(p))
}
var dummy byte
var empty bool
if len(oob) > 0 {
if len(p) == 0 {
empty := emptyIovecs(iov)
if empty {
var sockType int
sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
if err != nil {
@@ -1554,19 +1550,22 @@ func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags i
}
// send at least one normal byte
if sockType != SOCK_DGRAM {
iov.Base = &dummy
iov.SetLen(1)
var iova [1]Iovec
iova[0].Base = &dummy
iova[0].SetLen(1)
}
}
msg.Control = &oob[0]
msg.SetControllen(len(oob))
}
msg.Iov = &iov
msg.Iovlen = 1
if len(iov) > 0 {
msg.Iov = &iov[0]
msg.SetIovlen(len(iov))
}
if n, err = sendmsg(fd, &msg, flags); err != nil {
return 0, err
}
if len(oob) > 0 && len(p) == 0 {
if len(oob) > 0 && empty {
n = 0
}
return n, nil
+37 -2
View File
@@ -12,8 +12,6 @@ import "unsafe"
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
//sys Fstatfs(fd int, buf *Statfs_t) (err error)
//sys Ftruncate(fd int, length int64) (err error)
//sysnb Getegid() (egid int)
@@ -43,6 +41,43 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
//sys Shutdown(fd int, how int) (err error)
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
func timespecFromStatxTimestamp(x StatxTimestamp) Timespec {
return Timespec{
Sec: x.Sec,
Nsec: int64(x.Nsec),
}
}
func Fstatat(fd int, path string, stat *Stat_t, flags int) error {
var r Statx_t
// Do it the glibc way, add AT_NO_AUTOMOUNT.
if err := Statx(fd, path, AT_NO_AUTOMOUNT|flags, STATX_BASIC_STATS, &r); err != nil {
return err
}
stat.Dev = Mkdev(r.Dev_major, r.Dev_minor)
stat.Ino = r.Ino
stat.Mode = uint32(r.Mode)
stat.Nlink = r.Nlink
stat.Uid = r.Uid
stat.Gid = r.Gid
stat.Rdev = Mkdev(r.Rdev_major, r.Rdev_minor)
// hope we don't get to process files so large to overflow these size
// fields...
stat.Size = int64(r.Size)
stat.Blksize = int32(r.Blksize)
stat.Blocks = int64(r.Blocks)
stat.Atim = timespecFromStatxTimestamp(r.Atime)
stat.Mtim = timespecFromStatxTimestamp(r.Mtime)
stat.Ctim = timespecFromStatxTimestamp(r.Ctime)
return nil
}
func Fstat(fd int, stat *Stat_t) (err error) {
return Fstatat(fd, "", stat, AT_EMPTY_PATH)
}
func Stat(path string, stat *Stat_t) (err error) {
return Fstatat(AT_FDCWD, path, stat, 0)
}
+1
View File
@@ -22,6 +22,7 @@ import "unsafe"
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Getuid() (uid int)
//sys Listen(s int, n int) (err error)
//sys MemfdSecret(flags int) (fd int, err error)
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
+4
View File
@@ -26,6 +26,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length)
}
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = uint32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
+26 -25
View File
@@ -451,26 +451,25 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) {
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.__xnet_recvmsg
func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
var msg Msghdr
msg.Name = (*byte)(unsafe.Pointer(rsa))
msg.Namelen = uint32(SizeofSockaddrAny)
var iov Iovec
if len(p) > 0 {
iov.Base = (*int8)(unsafe.Pointer(&p[0]))
iov.SetLen(len(p))
}
var dummy int8
var dummy byte
if len(oob) > 0 {
// receive at least one normal byte
if len(p) == 0 {
iov.Base = &dummy
iov.SetLen(1)
if emptyIovecs(iov) {
var iova [1]Iovec
iova[0].Base = &dummy
iova[0].SetLen(1)
iov = iova[:]
}
msg.Accrightslen = int32(len(oob))
}
msg.Iov = &iov
msg.Iovlen = 1
if len(iov) > 0 {
msg.Iov = &iov[0]
msg.SetIovlen(len(iov))
}
if n, err = recvmsg(fd, &msg, flags); n == -1 {
return
}
@@ -480,30 +479,31 @@ func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.__xnet_sendmsg
func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
var msg Msghdr
msg.Name = (*byte)(unsafe.Pointer(ptr))
msg.Namelen = uint32(salen)
var iov Iovec
if len(p) > 0 {
iov.Base = (*int8)(unsafe.Pointer(&p[0]))
iov.SetLen(len(p))
}
var dummy int8
var dummy byte
var empty bool
if len(oob) > 0 {
// send at least one normal byte
if len(p) == 0 {
iov.Base = &dummy
iov.SetLen(1)
empty = emptyIovecs(iov)
if empty {
var iova [1]Iovec
iova[0].Base = &dummy
iova[0].SetLen(1)
iov = iova[:]
}
msg.Accrightslen = int32(len(oob))
}
msg.Iov = &iov
msg.Iovlen = 1
if len(iov) > 0 {
msg.Iov = &iov[0]
msg.SetIovlen(len(iov))
}
if n, err = sendmsg(fd, &msg, flags); err != nil {
return 0, err
}
if len(oob) > 0 && len(p) == 0 {
if len(oob) > 0 && empty {
n = 0
}
return n, nil
@@ -618,6 +618,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
//sys Getpriority(which int, who int) (n int, err error)
//sysnb Getrlimit(which int, lim *Rlimit) (err error)
//sysnb Getrusage(who int, rusage *Rusage) (err error)
//sysnb Getsid(pid int) (sid int, err error)
//sysnb Gettimeofday(tv *Timeval) (err error)
//sysnb Getuid() (uid int)
//sys Kill(pid int, signum syscall.Signal) (err error)
+72 -2
View File
@@ -338,8 +338,13 @@ func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
}
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
var iov [1]Iovec
if len(p) > 0 {
iov[0].Base = &p[0]
iov[0].SetLen(len(p))
}
var rsa RawSockaddrAny
n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
n, oobn, recvflags, err = recvmsgRaw(fd, iov[:], oob, flags, &rsa)
// source address is only specified if the socket is unconnected
if rsa.Addr.Family != AF_UNSPEC {
from, err = anyToSockaddr(fd, &rsa)
@@ -347,12 +352,42 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
return
}
// RecvmsgBuffers receives a message from a socket using the recvmsg
// system call. The flags are passed to recvmsg. Any non-control data
// read is scattered into the buffers slices. The results are:
// - n is the number of non-control data read into bufs
// - oobn is the number of control data read into oob; this may be interpreted using [ParseSocketControlMessage]
// - recvflags is flags returned by recvmsg
// - from is the address of the sender
func RecvmsgBuffers(fd int, buffers [][]byte, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
iov := make([]Iovec, len(buffers))
for i := range buffers {
if len(buffers[i]) > 0 {
iov[i].Base = &buffers[i][0]
iov[i].SetLen(len(buffers[i]))
} else {
iov[i].Base = (*byte)(unsafe.Pointer(&_zero))
}
}
var rsa RawSockaddrAny
n, oobn, recvflags, err = recvmsgRaw(fd, iov, oob, flags, &rsa)
if err == nil && rsa.Addr.Family != AF_UNSPEC {
from, err = anyToSockaddr(fd, &rsa)
}
return
}
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
_, err = SendmsgN(fd, p, oob, to, flags)
return
}
func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
var iov [1]Iovec
if len(p) > 0 {
iov[0].Base = &p[0]
iov[0].SetLen(len(p))
}
var ptr unsafe.Pointer
var salen _Socklen
if to != nil {
@@ -361,7 +396,32 @@ func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error)
return 0, err
}
}
return sendmsgN(fd, p, oob, ptr, salen, flags)
return sendmsgN(fd, iov[:], oob, ptr, salen, flags)
}
// SendmsgBuffers sends a message on a socket to an address using the sendmsg
// system call. The flags are passed to sendmsg. Any non-control data written
// is gathered from buffers. The function returns the number of bytes written
// to the socket.
func SendmsgBuffers(fd int, buffers [][]byte, oob []byte, to Sockaddr, flags int) (n int, err error) {
iov := make([]Iovec, len(buffers))
for i := range buffers {
if len(buffers[i]) > 0 {
iov[i].Base = &buffers[i][0]
iov[i].SetLen(len(buffers[i]))
} else {
iov[i].Base = (*byte)(unsafe.Pointer(&_zero))
}
}
var ptr unsafe.Pointer
var salen _Socklen
if to != nil {
ptr, salen, err = to.sockaddr()
if err != nil {
return 0, err
}
}
return sendmsgN(fd, iov, oob, ptr, salen, flags)
}
func Send(s int, buf []byte, flags int) (err error) {
@@ -484,3 +544,13 @@ func Lutimes(path string, tv []Timeval) error {
}
return UtimesNanoAt(AT_FDCWD, path, ts, AT_SYMLINK_NOFOLLOW)
}
// emptyIovec reports whether there are no bytes in the slice of Iovec.
func emptyIovecs(iov []Iovec) bool {
for i := range iov {
if iov[i].Len > 0 {
return false
}
}
return true
}
+102 -7
View File
@@ -151,6 +151,7 @@ const (
BIOCSETF = 0x80084267
BIOCSETFNR = 0x80084282
BIOCSETIF = 0x8020426c
BIOCSETVLANPCP = 0x80044285
BIOCSETWF = 0x8008427b
BIOCSETZBUF = 0x800c4281
BIOCSHDRCMPLT = 0x80044275
@@ -447,7 +448,7 @@ const (
DLT_IEEE802_16_MAC_CPS_RADIO = 0xc1
DLT_INFINIBAND = 0xf7
DLT_IPFILTER = 0x74
DLT_IPMB = 0xc7
DLT_IPMB_KONTRON = 0xc7
DLT_IPMB_LINUX = 0xd1
DLT_IPMI_HPM_2 = 0x104
DLT_IPNET = 0xe2
@@ -487,10 +488,11 @@ const (
DLT_LINUX_LAPD = 0xb1
DLT_LINUX_PPP_WITHDIRECTION = 0xa6
DLT_LINUX_SLL = 0x71
DLT_LINUX_SLL2 = 0x114
DLT_LOOP = 0x6c
DLT_LORATAP = 0x10e
DLT_LTALK = 0x72
DLT_MATCHING_MAX = 0x113
DLT_MATCHING_MAX = 0x114
DLT_MATCHING_MIN = 0x68
DLT_MFR = 0xb6
DLT_MOST = 0xd3
@@ -734,6 +736,7 @@ const (
IPPROTO_CMTP = 0x26
IPPROTO_CPHB = 0x49
IPPROTO_CPNX = 0x48
IPPROTO_DCCP = 0x21
IPPROTO_DDP = 0x25
IPPROTO_DGP = 0x56
IPPROTO_DIVERT = 0x102
@@ -814,7 +817,6 @@ const (
IPPROTO_SCTP = 0x84
IPPROTO_SDRP = 0x2a
IPPROTO_SEND = 0x103
IPPROTO_SEP = 0x21
IPPROTO_SHIM6 = 0x8c
IPPROTO_SKIP = 0x39
IPPROTO_SPACER = 0x7fff
@@ -911,6 +913,7 @@ const (
IPV6_V6ONLY = 0x1b
IPV6_VERSION = 0x60
IPV6_VERSION_MASK = 0xf0
IPV6_VLAN_PCP = 0x4b
IP_ADD_MEMBERSHIP = 0xc
IP_ADD_SOURCE_MEMBERSHIP = 0x46
IP_BINDANY = 0x18
@@ -989,8 +992,12 @@ const (
IP_TOS = 0x3
IP_TTL = 0x4
IP_UNBLOCK_SOURCE = 0x49
IP_VLAN_PCP = 0x4b
ISIG = 0x80
ISTRIP = 0x20
ITIMER_PROF = 0x2
ITIMER_REAL = 0x0
ITIMER_VIRTUAL = 0x1
IXANY = 0x800
IXOFF = 0x400
IXON = 0x200
@@ -1000,7 +1007,6 @@ const (
KERN_VERSION = 0x4
LOCAL_CONNWAIT = 0x4
LOCAL_CREDS = 0x2
LOCAL_CREDS_PERSISTENT = 0x3
LOCAL_PEERCRED = 0x1
LOCAL_VENDOR = 0x80000000
LOCK_EX = 0x2
@@ -1179,6 +1185,8 @@ const (
O_NONBLOCK = 0x4
O_RDONLY = 0x0
O_RDWR = 0x2
O_RESOLVE_BENEATH = 0x800000
O_SEARCH = 0x40000
O_SHLOCK = 0x10
O_SYNC = 0x80
O_TRUNC = 0x400
@@ -1189,6 +1197,10 @@ const (
PARMRK = 0x8
PARODD = 0x2000
PENDIN = 0x20000000
PIOD_READ_D = 0x1
PIOD_READ_I = 0x3
PIOD_WRITE_D = 0x2
PIOD_WRITE_I = 0x4
PRIO_PGRP = 0x1
PRIO_PROCESS = 0x0
PRIO_USER = 0x2
@@ -1196,6 +1208,60 @@ const (
PROT_NONE = 0x0
PROT_READ = 0x1
PROT_WRITE = 0x2
PTRACE_DEFAULT = 0x1
PTRACE_EXEC = 0x1
PTRACE_FORK = 0x8
PTRACE_LWP = 0x10
PTRACE_SCE = 0x2
PTRACE_SCX = 0x4
PTRACE_SYSCALL = 0x6
PTRACE_VFORK = 0x20
PT_ATTACH = 0xa
PT_CLEARSTEP = 0x10
PT_CONTINUE = 0x7
PT_DETACH = 0xb
PT_FIRSTMACH = 0x40
PT_FOLLOW_FORK = 0x17
PT_GETDBREGS = 0x25
PT_GETFPREGS = 0x23
PT_GETFSBASE = 0x47
PT_GETGSBASE = 0x49
PT_GETLWPLIST = 0xf
PT_GETNUMLWPS = 0xe
PT_GETREGS = 0x21
PT_GETXMMREGS = 0x40
PT_GETXSTATE = 0x45
PT_GETXSTATE_INFO = 0x44
PT_GET_EVENT_MASK = 0x19
PT_GET_SC_ARGS = 0x1b
PT_GET_SC_RET = 0x1c
PT_IO = 0xc
PT_KILL = 0x8
PT_LWPINFO = 0xd
PT_LWP_EVENTS = 0x18
PT_READ_D = 0x2
PT_READ_I = 0x1
PT_RESUME = 0x13
PT_SETDBREGS = 0x26
PT_SETFPREGS = 0x24
PT_SETFSBASE = 0x48
PT_SETGSBASE = 0x4a
PT_SETREGS = 0x22
PT_SETSTEP = 0x11
PT_SETXMMREGS = 0x41
PT_SETXSTATE = 0x46
PT_SET_EVENT_MASK = 0x1a
PT_STEP = 0x9
PT_SUSPEND = 0x12
PT_SYSCALL = 0x16
PT_TO_SCE = 0x14
PT_TO_SCX = 0x15
PT_TRACE_ME = 0x0
PT_VM_ENTRY = 0x29
PT_VM_TIMESTAMP = 0x28
PT_WRITE_D = 0x5
PT_WRITE_I = 0x4
P_ZONEID = 0xc
RLIMIT_AS = 0xa
RLIMIT_CORE = 0x4
RLIMIT_CPU = 0x0
@@ -1320,10 +1386,12 @@ const (
SIOCGHWADDR = 0xc020693e
SIOCGI2C = 0xc020693d
SIOCGIFADDR = 0xc0206921
SIOCGIFALIAS = 0xc044692d
SIOCGIFBRDADDR = 0xc0206923
SIOCGIFCAP = 0xc020691f
SIOCGIFCONF = 0xc0086924
SIOCGIFDESCR = 0xc020692a
SIOCGIFDOWNREASON = 0xc058699a
SIOCGIFDSTADDR = 0xc0206922
SIOCGIFFIB = 0xc020695c
SIOCGIFFLAGS = 0xc0206911
@@ -1414,6 +1482,7 @@ const (
SO_RCVBUF = 0x1002
SO_RCVLOWAT = 0x1004
SO_RCVTIMEO = 0x1006
SO_RERROR = 0x20000
SO_REUSEADDR = 0x4
SO_REUSEPORT = 0x200
SO_REUSEPORT_LB = 0x10000
@@ -1472,22 +1541,40 @@ const (
TCOFLUSH = 0x2
TCOOFF = 0x1
TCOON = 0x2
TCPOPT_EOL = 0x0
TCPOPT_FAST_OPEN = 0x22
TCPOPT_MAXSEG = 0x2
TCPOPT_NOP = 0x1
TCPOPT_PAD = 0x0
TCPOPT_SACK = 0x5
TCPOPT_SACK_PERMITTED = 0x4
TCPOPT_SIGNATURE = 0x13
TCPOPT_TIMESTAMP = 0x8
TCPOPT_WINDOW = 0x3
TCP_BBR_ACK_COMP_ALG = 0x448
TCP_BBR_ALGORITHM = 0x43b
TCP_BBR_DRAIN_INC_EXTRA = 0x43c
TCP_BBR_DRAIN_PG = 0x42e
TCP_BBR_EXTRA_GAIN = 0x449
TCP_BBR_EXTRA_STATE = 0x453
TCP_BBR_FLOOR_MIN_TSO = 0x454
TCP_BBR_HDWR_PACE = 0x451
TCP_BBR_HOLD_TARGET = 0x436
TCP_BBR_IWINTSO = 0x42b
TCP_BBR_LOWGAIN_FD = 0x436
TCP_BBR_LOWGAIN_HALF = 0x435
TCP_BBR_LOWGAIN_THRESH = 0x434
TCP_BBR_MAX_RTO = 0x439
TCP_BBR_MIN_RTO = 0x438
TCP_BBR_MIN_TOPACEOUT = 0x455
TCP_BBR_ONE_RETRAN = 0x431
TCP_BBR_PACE_CROSS = 0x442
TCP_BBR_PACE_DEL_TAR = 0x43f
TCP_BBR_PACE_OH = 0x435
TCP_BBR_PACE_PER_SEC = 0x43e
TCP_BBR_PACE_SEG_MAX = 0x440
TCP_BBR_PACE_SEG_MIN = 0x441
TCP_BBR_POLICER_DETECT = 0x457
TCP_BBR_PROBE_RTT_GAIN = 0x44d
TCP_BBR_PROBE_RTT_INT = 0x430
TCP_BBR_PROBE_RTT_LEN = 0x44e
@@ -1496,12 +1583,18 @@ const (
TCP_BBR_REC_OVER_HPTS = 0x43a
TCP_BBR_RETRAN_WTSO = 0x44b
TCP_BBR_RWND_IS_APP = 0x42f
TCP_BBR_SEND_IWND_IN_TSO = 0x44f
TCP_BBR_STARTUP_EXIT_EPOCH = 0x43d
TCP_BBR_STARTUP_LOSS_EXIT = 0x432
TCP_BBR_STARTUP_PG = 0x42d
TCP_BBR_TMR_PACE_OH = 0x448
TCP_BBR_TSLIMITS = 0x434
TCP_BBR_TSTMP_RAISES = 0x456
TCP_BBR_UNLIMITED = 0x43b
TCP_BBR_USEDEL_RATE = 0x437
TCP_BBR_USE_LOWGAIN = 0x433
TCP_BBR_USE_RACK_CHEAT = 0x450
TCP_BBR_UTTER_MAX_TSO = 0x452
TCP_CA_NAME_MAX = 0x10
TCP_CCALGOOPT = 0x41
TCP_CONGESTION = 0x40
@@ -1541,6 +1634,7 @@ const (
TCP_PCAP_OUT = 0x800
TCP_RACK_EARLY_RECOV = 0x423
TCP_RACK_EARLY_SEG = 0x424
TCP_RACK_GP_INCREASE = 0x446
TCP_RACK_IDLE_REDUCE_HIGH = 0x444
TCP_RACK_MIN_PACE = 0x445
TCP_RACK_MIN_PACE_SEG = 0x446
@@ -1554,7 +1648,6 @@ const (
TCP_RACK_PRR_SENDALOT = 0x421
TCP_RACK_REORD_FADE = 0x426
TCP_RACK_REORD_THRESH = 0x425
TCP_RACK_SESS_CWV = 0x42a
TCP_RACK_TLP_INC_VAR = 0x429
TCP_RACK_TLP_REDUCE = 0x41c
TCP_RACK_TLP_THRESH = 0x427
@@ -1694,12 +1787,13 @@ const (
EIDRM = syscall.Errno(0x52)
EILSEQ = syscall.Errno(0x56)
EINPROGRESS = syscall.Errno(0x24)
EINTEGRITY = syscall.Errno(0x61)
EINTR = syscall.Errno(0x4)
EINVAL = syscall.Errno(0x16)
EIO = syscall.Errno(0x5)
EISCONN = syscall.Errno(0x38)
EISDIR = syscall.Errno(0x15)
ELAST = syscall.Errno(0x60)
ELAST = syscall.Errno(0x61)
ELOOP = syscall.Errno(0x3e)
EMFILE = syscall.Errno(0x18)
EMLINK = syscall.Errno(0x1f)
@@ -1842,7 +1936,7 @@ var errorList = [...]struct {
{32, "EPIPE", "broken pipe"},
{33, "EDOM", "numerical argument out of domain"},
{34, "ERANGE", "result too large"},
{35, "EAGAIN", "resource temporarily unavailable"},
{35, "EWOULDBLOCK", "resource temporarily unavailable"},
{36, "EINPROGRESS", "operation now in progress"},
{37, "EALREADY", "operation already in progress"},
{38, "ENOTSOCK", "socket operation on non-socket"},
@@ -1904,6 +1998,7 @@ var errorList = [...]struct {
{94, "ECAPMODE", "not permitted in capability mode"},
{95, "ENOTRECOVERABLE", "state not recoverable"},
{96, "EOWNERDEAD", "previous owner died"},
{97, "EINTEGRITY", "integrity check failed"},
}
// Signal table
+100 -7
View File
@@ -151,6 +151,7 @@ const (
BIOCSETF = 0x80104267
BIOCSETFNR = 0x80104282
BIOCSETIF = 0x8020426c
BIOCSETVLANPCP = 0x80044285
BIOCSETWF = 0x8010427b
BIOCSETZBUF = 0x80184281
BIOCSHDRCMPLT = 0x80044275
@@ -447,7 +448,7 @@ const (
DLT_IEEE802_16_MAC_CPS_RADIO = 0xc1
DLT_INFINIBAND = 0xf7
DLT_IPFILTER = 0x74
DLT_IPMB = 0xc7
DLT_IPMB_KONTRON = 0xc7
DLT_IPMB_LINUX = 0xd1
DLT_IPMI_HPM_2 = 0x104
DLT_IPNET = 0xe2
@@ -487,10 +488,11 @@ const (
DLT_LINUX_LAPD = 0xb1
DLT_LINUX_PPP_WITHDIRECTION = 0xa6
DLT_LINUX_SLL = 0x71
DLT_LINUX_SLL2 = 0x114
DLT_LOOP = 0x6c
DLT_LORATAP = 0x10e
DLT_LTALK = 0x72
DLT_MATCHING_MAX = 0x113
DLT_MATCHING_MAX = 0x114
DLT_MATCHING_MIN = 0x68
DLT_MFR = 0xb6
DLT_MOST = 0xd3
@@ -734,6 +736,7 @@ const (
IPPROTO_CMTP = 0x26
IPPROTO_CPHB = 0x49
IPPROTO_CPNX = 0x48
IPPROTO_DCCP = 0x21
IPPROTO_DDP = 0x25
IPPROTO_DGP = 0x56
IPPROTO_DIVERT = 0x102
@@ -814,7 +817,6 @@ const (
IPPROTO_SCTP = 0x84
IPPROTO_SDRP = 0x2a
IPPROTO_SEND = 0x103
IPPROTO_SEP = 0x21
IPPROTO_SHIM6 = 0x8c
IPPROTO_SKIP = 0x39
IPPROTO_SPACER = 0x7fff
@@ -911,6 +913,7 @@ const (
IPV6_V6ONLY = 0x1b
IPV6_VERSION = 0x60
IPV6_VERSION_MASK = 0xf0
IPV6_VLAN_PCP = 0x4b
IP_ADD_MEMBERSHIP = 0xc
IP_ADD_SOURCE_MEMBERSHIP = 0x46
IP_BINDANY = 0x18
@@ -989,8 +992,12 @@ const (
IP_TOS = 0x3
IP_TTL = 0x4
IP_UNBLOCK_SOURCE = 0x49
IP_VLAN_PCP = 0x4b
ISIG = 0x80
ISTRIP = 0x20
ITIMER_PROF = 0x2
ITIMER_REAL = 0x0
ITIMER_VIRTUAL = 0x1
IXANY = 0x800
IXOFF = 0x400
IXON = 0x200
@@ -1000,7 +1007,6 @@ const (
KERN_VERSION = 0x4
LOCAL_CONNWAIT = 0x4
LOCAL_CREDS = 0x2
LOCAL_CREDS_PERSISTENT = 0x3
LOCAL_PEERCRED = 0x1
LOCAL_VENDOR = 0x80000000
LOCK_EX = 0x2
@@ -1180,6 +1186,8 @@ const (
O_NONBLOCK = 0x4
O_RDONLY = 0x0
O_RDWR = 0x2
O_RESOLVE_BENEATH = 0x800000
O_SEARCH = 0x40000
O_SHLOCK = 0x10
O_SYNC = 0x80
O_TRUNC = 0x400
@@ -1190,6 +1198,10 @@ const (
PARMRK = 0x8
PARODD = 0x2000
PENDIN = 0x20000000
PIOD_READ_D = 0x1
PIOD_READ_I = 0x3
PIOD_WRITE_D = 0x2
PIOD_WRITE_I = 0x4
PRIO_PGRP = 0x1
PRIO_PROCESS = 0x0
PRIO_USER = 0x2
@@ -1197,6 +1209,58 @@ const (
PROT_NONE = 0x0
PROT_READ = 0x1
PROT_WRITE = 0x2
PTRACE_DEFAULT = 0x1
PTRACE_EXEC = 0x1
PTRACE_FORK = 0x8
PTRACE_LWP = 0x10
PTRACE_SCE = 0x2
PTRACE_SCX = 0x4
PTRACE_SYSCALL = 0x6
PTRACE_VFORK = 0x20
PT_ATTACH = 0xa
PT_CLEARSTEP = 0x10
PT_CONTINUE = 0x7
PT_DETACH = 0xb
PT_FIRSTMACH = 0x40
PT_FOLLOW_FORK = 0x17
PT_GETDBREGS = 0x25
PT_GETFPREGS = 0x23
PT_GETFSBASE = 0x47
PT_GETGSBASE = 0x49
PT_GETLWPLIST = 0xf
PT_GETNUMLWPS = 0xe
PT_GETREGS = 0x21
PT_GETXSTATE = 0x45
PT_GETXSTATE_INFO = 0x44
PT_GET_EVENT_MASK = 0x19
PT_GET_SC_ARGS = 0x1b
PT_GET_SC_RET = 0x1c
PT_IO = 0xc
PT_KILL = 0x8
PT_LWPINFO = 0xd
PT_LWP_EVENTS = 0x18
PT_READ_D = 0x2
PT_READ_I = 0x1
PT_RESUME = 0x13
PT_SETDBREGS = 0x26
PT_SETFPREGS = 0x24
PT_SETFSBASE = 0x48
PT_SETGSBASE = 0x4a
PT_SETREGS = 0x22
PT_SETSTEP = 0x11
PT_SETXSTATE = 0x46
PT_SET_EVENT_MASK = 0x1a
PT_STEP = 0x9
PT_SUSPEND = 0x12
PT_SYSCALL = 0x16
PT_TO_SCE = 0x14
PT_TO_SCX = 0x15
PT_TRACE_ME = 0x0
PT_VM_ENTRY = 0x29
PT_VM_TIMESTAMP = 0x28
PT_WRITE_D = 0x5
PT_WRITE_I = 0x4
P_ZONEID = 0xc
RLIMIT_AS = 0xa
RLIMIT_CORE = 0x4
RLIMIT_CPU = 0x0
@@ -1321,10 +1385,12 @@ const (
SIOCGHWADDR = 0xc020693e
SIOCGI2C = 0xc020693d
SIOCGIFADDR = 0xc0206921
SIOCGIFALIAS = 0xc044692d
SIOCGIFBRDADDR = 0xc0206923
SIOCGIFCAP = 0xc020691f
SIOCGIFCONF = 0xc0106924
SIOCGIFDESCR = 0xc020692a
SIOCGIFDOWNREASON = 0xc058699a
SIOCGIFDSTADDR = 0xc0206922
SIOCGIFFIB = 0xc020695c
SIOCGIFFLAGS = 0xc0206911
@@ -1415,6 +1481,7 @@ const (
SO_RCVBUF = 0x1002
SO_RCVLOWAT = 0x1004
SO_RCVTIMEO = 0x1006
SO_RERROR = 0x20000
SO_REUSEADDR = 0x4
SO_REUSEPORT = 0x200
SO_REUSEPORT_LB = 0x10000
@@ -1473,22 +1540,40 @@ const (
TCOFLUSH = 0x2
TCOOFF = 0x1
TCOON = 0x2
TCPOPT_EOL = 0x0
TCPOPT_FAST_OPEN = 0x22
TCPOPT_MAXSEG = 0x2
TCPOPT_NOP = 0x1
TCPOPT_PAD = 0x0
TCPOPT_SACK = 0x5
TCPOPT_SACK_PERMITTED = 0x4
TCPOPT_SIGNATURE = 0x13
TCPOPT_TIMESTAMP = 0x8
TCPOPT_WINDOW = 0x3
TCP_BBR_ACK_COMP_ALG = 0x448
TCP_BBR_ALGORITHM = 0x43b
TCP_BBR_DRAIN_INC_EXTRA = 0x43c
TCP_BBR_DRAIN_PG = 0x42e
TCP_BBR_EXTRA_GAIN = 0x449
TCP_BBR_EXTRA_STATE = 0x453
TCP_BBR_FLOOR_MIN_TSO = 0x454
TCP_BBR_HDWR_PACE = 0x451
TCP_BBR_HOLD_TARGET = 0x436
TCP_BBR_IWINTSO = 0x42b
TCP_BBR_LOWGAIN_FD = 0x436
TCP_BBR_LOWGAIN_HALF = 0x435
TCP_BBR_LOWGAIN_THRESH = 0x434
TCP_BBR_MAX_RTO = 0x439
TCP_BBR_MIN_RTO = 0x438
TCP_BBR_MIN_TOPACEOUT = 0x455
TCP_BBR_ONE_RETRAN = 0x431
TCP_BBR_PACE_CROSS = 0x442
TCP_BBR_PACE_DEL_TAR = 0x43f
TCP_BBR_PACE_OH = 0x435
TCP_BBR_PACE_PER_SEC = 0x43e
TCP_BBR_PACE_SEG_MAX = 0x440
TCP_BBR_PACE_SEG_MIN = 0x441
TCP_BBR_POLICER_DETECT = 0x457
TCP_BBR_PROBE_RTT_GAIN = 0x44d
TCP_BBR_PROBE_RTT_INT = 0x430
TCP_BBR_PROBE_RTT_LEN = 0x44e
@@ -1497,12 +1582,18 @@ const (
TCP_BBR_REC_OVER_HPTS = 0x43a
TCP_BBR_RETRAN_WTSO = 0x44b
TCP_BBR_RWND_IS_APP = 0x42f
TCP_BBR_SEND_IWND_IN_TSO = 0x44f
TCP_BBR_STARTUP_EXIT_EPOCH = 0x43d
TCP_BBR_STARTUP_LOSS_EXIT = 0x432
TCP_BBR_STARTUP_PG = 0x42d
TCP_BBR_TMR_PACE_OH = 0x448
TCP_BBR_TSLIMITS = 0x434
TCP_BBR_TSTMP_RAISES = 0x456
TCP_BBR_UNLIMITED = 0x43b
TCP_BBR_USEDEL_RATE = 0x437
TCP_BBR_USE_LOWGAIN = 0x433
TCP_BBR_USE_RACK_CHEAT = 0x450
TCP_BBR_UTTER_MAX_TSO = 0x452
TCP_CA_NAME_MAX = 0x10
TCP_CCALGOOPT = 0x41
TCP_CONGESTION = 0x40
@@ -1542,6 +1633,7 @@ const (
TCP_PCAP_OUT = 0x800
TCP_RACK_EARLY_RECOV = 0x423
TCP_RACK_EARLY_SEG = 0x424
TCP_RACK_GP_INCREASE = 0x446
TCP_RACK_IDLE_REDUCE_HIGH = 0x444
TCP_RACK_MIN_PACE = 0x445
TCP_RACK_MIN_PACE_SEG = 0x446
@@ -1555,7 +1647,6 @@ const (
TCP_RACK_PRR_SENDALOT = 0x421
TCP_RACK_REORD_FADE = 0x426
TCP_RACK_REORD_THRESH = 0x425
TCP_RACK_SESS_CWV = 0x42a
TCP_RACK_TLP_INC_VAR = 0x429
TCP_RACK_TLP_REDUCE = 0x41c
TCP_RACK_TLP_THRESH = 0x427
@@ -1693,12 +1784,13 @@ const (
EIDRM = syscall.Errno(0x52)
EILSEQ = syscall.Errno(0x56)
EINPROGRESS = syscall.Errno(0x24)
EINTEGRITY = syscall.Errno(0x61)
EINTR = syscall.Errno(0x4)
EINVAL = syscall.Errno(0x16)
EIO = syscall.Errno(0x5)
EISCONN = syscall.Errno(0x38)
EISDIR = syscall.Errno(0x15)
ELAST = syscall.Errno(0x60)
ELAST = syscall.Errno(0x61)
ELOOP = syscall.Errno(0x3e)
EMFILE = syscall.Errno(0x18)
EMLINK = syscall.Errno(0x1f)
@@ -1841,7 +1933,7 @@ var errorList = [...]struct {
{32, "EPIPE", "broken pipe"},
{33, "EDOM", "numerical argument out of domain"},
{34, "ERANGE", "result too large"},
{35, "EAGAIN", "resource temporarily unavailable"},
{35, "EWOULDBLOCK", "resource temporarily unavailable"},
{36, "EINPROGRESS", "operation now in progress"},
{37, "EALREADY", "operation already in progress"},
{38, "ENOTSOCK", "socket operation on non-socket"},
@@ -1903,6 +1995,7 @@ var errorList = [...]struct {
{94, "ECAPMODE", "not permitted in capability mode"},
{95, "ENOTRECOVERABLE", "state not recoverable"},
{96, "EOWNERDEAD", "previous owner died"},
{97, "EINTEGRITY", "integrity check failed"},
}
// Signal table
+204 -16
View File
@@ -151,6 +151,7 @@ const (
BIOCSETF = 0x80084267
BIOCSETFNR = 0x80084282
BIOCSETIF = 0x8020426c
BIOCSETVLANPCP = 0x80044285
BIOCSETWF = 0x8008427b
BIOCSETZBUF = 0x800c4281
BIOCSHDRCMPLT = 0x80044275
@@ -362,7 +363,7 @@ const (
CTL_KERN = 0x1
CTL_MAXNAME = 0x18
CTL_NET = 0x4
DIOCGATTR = 0xc144648e
DIOCGATTR = 0xc148648e
DIOCGDELETE = 0x80106488
DIOCGFLUSH = 0x20006487
DIOCGFRONTSTUFF = 0x40086486
@@ -377,7 +378,7 @@ const (
DIOCGSTRIPESIZE = 0x4008648b
DIOCSKERNELDUMP = 0x804c6490
DIOCSKERNELDUMP_FREEBSD11 = 0x80046485
DIOCZONECMD = 0xc06c648f
DIOCZONECMD = 0xc078648f
DLT_A429 = 0xb8
DLT_A653_ICM = 0xb9
DLT_AIRONET_HEADER = 0x78
@@ -407,7 +408,9 @@ const (
DLT_C_HDLC_WITH_DIR = 0xcd
DLT_DBUS = 0xe7
DLT_DECT = 0xdd
DLT_DISPLAYPORT_AUX = 0x113
DLT_DOCSIS = 0x8f
DLT_DOCSIS31_XRA31 = 0x111
DLT_DVB_CI = 0xeb
DLT_ECONET = 0x73
DLT_EN10MB = 0x1
@@ -417,6 +420,7 @@ const (
DLT_ERF = 0xc5
DLT_ERF_ETH = 0xaf
DLT_ERF_POS = 0xb0
DLT_ETHERNET_MPACKET = 0x112
DLT_FC_2 = 0xe0
DLT_FC_2_WITH_FRAME_DELIMS = 0xe1
DLT_FDDI = 0xa
@@ -444,7 +448,7 @@ const (
DLT_IEEE802_16_MAC_CPS_RADIO = 0xc1
DLT_INFINIBAND = 0xf7
DLT_IPFILTER = 0x74
DLT_IPMB = 0xc7
DLT_IPMB_KONTRON = 0xc7
DLT_IPMB_LINUX = 0xd1
DLT_IPMI_HPM_2 = 0x104
DLT_IPNET = 0xe2
@@ -484,9 +488,11 @@ const (
DLT_LINUX_LAPD = 0xb1
DLT_LINUX_PPP_WITHDIRECTION = 0xa6
DLT_LINUX_SLL = 0x71
DLT_LINUX_SLL2 = 0x114
DLT_LOOP = 0x6c
DLT_LORATAP = 0x10e
DLT_LTALK = 0x72
DLT_MATCHING_MAX = 0x109
DLT_MATCHING_MAX = 0x114
DLT_MATCHING_MIN = 0x68
DLT_MFR = 0xb6
DLT_MOST = 0xd3
@@ -502,7 +508,9 @@ const (
DLT_NFC_LLCP = 0xf5
DLT_NFLOG = 0xef
DLT_NG40 = 0xf4
DLT_NORDIC_BLE = 0x110
DLT_NULL = 0x0
DLT_OPENFLOW = 0x10b
DLT_PCI_EXP = 0x7d
DLT_PFLOG = 0x75
DLT_PFSYNC = 0x79
@@ -526,15 +534,18 @@ const (
DLT_RTAC_SERIAL = 0xfa
DLT_SCCP = 0x8e
DLT_SCTP = 0xf8
DLT_SDLC = 0x10c
DLT_SITA = 0xc4
DLT_SLIP = 0x8
DLT_SLIP_BSDOS = 0xd
DLT_STANAG_5066_D_PDU = 0xed
DLT_SUNATM = 0x7b
DLT_SYMANTEC_FIREWALL = 0x63
DLT_TI_LLN_SNIFFER = 0x10d
DLT_TZSP = 0x80
DLT_USB = 0xba
DLT_USBPCAP = 0xf9
DLT_USB_DARWIN = 0x10a
DLT_USB_FREEBSD = 0xba
DLT_USB_LINUX = 0xbd
DLT_USB_LINUX_MMAPPED = 0xdc
@@ -554,6 +565,7 @@ const (
DLT_USER7 = 0x9a
DLT_USER8 = 0x9b
DLT_USER9 = 0x9c
DLT_VSOCK = 0x10f
DLT_WATTSTOPPER_DLM = 0x107
DLT_WIHART = 0xdf
DLT_WIRESHARK_UPPER_PDU = 0xfc
@@ -578,6 +590,7 @@ const (
ECHONL = 0x10
ECHOPRT = 0x20
EVFILT_AIO = -0x3
EVFILT_EMPTY = -0xd
EVFILT_FS = -0x9
EVFILT_LIO = -0xa
EVFILT_PROC = -0x5
@@ -585,11 +598,12 @@ const (
EVFILT_READ = -0x1
EVFILT_SENDFILE = -0xc
EVFILT_SIGNAL = -0x6
EVFILT_SYSCOUNT = 0xc
EVFILT_SYSCOUNT = 0xd
EVFILT_TIMER = -0x7
EVFILT_USER = -0xb
EVFILT_VNODE = -0x4
EVFILT_WRITE = -0x2
EVNAMEMAP_NAME_SIZE = 0x40
EV_ADD = 0x1
EV_CLEAR = 0x20
EV_DELETE = 0x2
@@ -606,6 +620,7 @@ const (
EV_RECEIPT = 0x40
EV_SYSFLAGS = 0xf000
EXTA = 0x4b00
EXTATTR_MAXNAMELEN = 0xff
EXTATTR_NAMESPACE_EMPTY = 0x0
EXTATTR_NAMESPACE_SYSTEM = 0x2
EXTATTR_NAMESPACE_USER = 0x1
@@ -647,6 +662,7 @@ const (
IEXTEN = 0x400
IFAN_ARRIVAL = 0x0
IFAN_DEPARTURE = 0x1
IFCAP_WOL_MAGIC = 0x2000
IFF_ALLMULTI = 0x200
IFF_ALTPHYS = 0x4000
IFF_BROADCAST = 0x2
@@ -663,6 +679,7 @@ const (
IFF_MONITOR = 0x40000
IFF_MULTICAST = 0x8000
IFF_NOARP = 0x80
IFF_NOGROUP = 0x800000
IFF_OACTIVE = 0x400
IFF_POINTOPOINT = 0x10
IFF_PPROMISC = 0x20000
@@ -719,6 +736,7 @@ const (
IPPROTO_CMTP = 0x26
IPPROTO_CPHB = 0x49
IPPROTO_CPNX = 0x48
IPPROTO_DCCP = 0x21
IPPROTO_DDP = 0x25
IPPROTO_DGP = 0x56
IPPROTO_DIVERT = 0x102
@@ -799,7 +817,6 @@ const (
IPPROTO_SCTP = 0x84
IPPROTO_SDRP = 0x2a
IPPROTO_SEND = 0x103
IPPROTO_SEP = 0x21
IPPROTO_SHIM6 = 0x8c
IPPROTO_SKIP = 0x39
IPPROTO_SPACER = 0x7fff
@@ -837,6 +854,7 @@ const (
IPV6_DSTOPTS = 0x32
IPV6_FLOWID = 0x43
IPV6_FLOWINFO_MASK = 0xffffff0f
IPV6_FLOWLABEL_LEN = 0x14
IPV6_FLOWLABEL_MASK = 0xffff0f00
IPV6_FLOWTYPE = 0x44
IPV6_FRAGTTL = 0x78
@@ -857,13 +875,13 @@ const (
IPV6_MAX_GROUP_SRC_FILTER = 0x200
IPV6_MAX_MEMBERSHIPS = 0xfff
IPV6_MAX_SOCK_SRC_FILTER = 0x80
IPV6_MIN_MEMBERSHIPS = 0x1f
IPV6_MMTU = 0x500
IPV6_MSFILTER = 0x4a
IPV6_MULTICAST_HOPS = 0xa
IPV6_MULTICAST_IF = 0x9
IPV6_MULTICAST_LOOP = 0xb
IPV6_NEXTHOP = 0x30
IPV6_ORIGDSTADDR = 0x48
IPV6_PATHMTU = 0x2c
IPV6_PKTINFO = 0x2e
IPV6_PORTRANGE = 0xe
@@ -875,6 +893,7 @@ const (
IPV6_RECVFLOWID = 0x46
IPV6_RECVHOPLIMIT = 0x25
IPV6_RECVHOPOPTS = 0x27
IPV6_RECVORIGDSTADDR = 0x48
IPV6_RECVPATHMTU = 0x2b
IPV6_RECVPKTINFO = 0x24
IPV6_RECVRSSBUCKETID = 0x47
@@ -894,6 +913,7 @@ const (
IPV6_V6ONLY = 0x1b
IPV6_VERSION = 0x60
IPV6_VERSION_MASK = 0xf0
IPV6_VLAN_PCP = 0x4b
IP_ADD_MEMBERSHIP = 0xc
IP_ADD_SOURCE_MEMBERSHIP = 0x46
IP_BINDANY = 0x18
@@ -935,10 +955,8 @@ const (
IP_MAX_MEMBERSHIPS = 0xfff
IP_MAX_SOCK_MUTE_FILTER = 0x80
IP_MAX_SOCK_SRC_FILTER = 0x80
IP_MAX_SOURCE_FILTER = 0x400
IP_MF = 0x2000
IP_MINTTL = 0x42
IP_MIN_MEMBERSHIPS = 0x1f
IP_MSFILTER = 0x4a
IP_MSS = 0x240
IP_MULTICAST_IF = 0x9
@@ -948,6 +966,7 @@ const (
IP_OFFMASK = 0x1fff
IP_ONESBCAST = 0x17
IP_OPTIONS = 0x1
IP_ORIGDSTADDR = 0x1b
IP_PORTRANGE = 0x13
IP_PORTRANGE_DEFAULT = 0x0
IP_PORTRANGE_HIGH = 0x1
@@ -956,6 +975,7 @@ const (
IP_RECVFLOWID = 0x5d
IP_RECVIF = 0x14
IP_RECVOPTS = 0x5
IP_RECVORIGDSTADDR = 0x1b
IP_RECVRETOPTS = 0x6
IP_RECVRSSBUCKETID = 0x5e
IP_RECVTOS = 0x44
@@ -972,8 +992,12 @@ const (
IP_TOS = 0x3
IP_TTL = 0x4
IP_UNBLOCK_SOURCE = 0x49
IP_VLAN_PCP = 0x4b
ISIG = 0x80
ISTRIP = 0x20
ITIMER_PROF = 0x2
ITIMER_REAL = 0x0
ITIMER_VIRTUAL = 0x1
IXANY = 0x800
IXOFF = 0x400
IXON = 0x200
@@ -983,7 +1007,6 @@ const (
KERN_VERSION = 0x4
LOCAL_CONNWAIT = 0x4
LOCAL_CREDS = 0x2
LOCAL_CREDS_PERSISTENT = 0x3
LOCAL_PEERCRED = 0x1
LOCAL_VENDOR = 0x80000000
LOCK_EX = 0x2
@@ -1071,10 +1094,12 @@ const (
MNT_SUSPEND = 0x4
MNT_SYNCHRONOUS = 0x2
MNT_UNION = 0x20
MNT_UNTRUSTED = 0x800000000
MNT_UPDATE = 0x10000
MNT_UPDATEMASK = 0x2d8d0807e
MNT_UPDATEMASK = 0xad8d0807e
MNT_USER = 0x8000
MNT_VISFLAGMASK = 0x3fef0ffff
MNT_VERIFIED = 0x400000000
MNT_VISFLAGMASK = 0xffef0ffff
MNT_WAIT = 0x1
MSG_CMSG_CLOEXEC = 0x40000
MSG_COMPAT = 0x8000
@@ -1103,6 +1128,7 @@ const (
NFDBITS = 0x20
NOFLSH = 0x80000000
NOKERNINFO = 0x2000000
NOTE_ABSTIME = 0x10
NOTE_ATTRIB = 0x8
NOTE_CHILD = 0x4
NOTE_CLOSE = 0x100
@@ -1159,6 +1185,8 @@ const (
O_NONBLOCK = 0x4
O_RDONLY = 0x0
O_RDWR = 0x2
O_RESOLVE_BENEATH = 0x800000
O_SEARCH = 0x40000
O_SHLOCK = 0x10
O_SYNC = 0x80
O_TRUNC = 0x400
@@ -1169,6 +1197,10 @@ const (
PARMRK = 0x8
PARODD = 0x2000
PENDIN = 0x20000000
PIOD_READ_D = 0x1
PIOD_READ_I = 0x3
PIOD_WRITE_D = 0x2
PIOD_WRITE_I = 0x4
PRIO_PGRP = 0x1
PRIO_PROCESS = 0x0
PRIO_USER = 0x2
@@ -1176,6 +1208,53 @@ const (
PROT_NONE = 0x0
PROT_READ = 0x1
PROT_WRITE = 0x2
PTRACE_DEFAULT = 0x1
PTRACE_EXEC = 0x1
PTRACE_FORK = 0x8
PTRACE_LWP = 0x10
PTRACE_SCE = 0x2
PTRACE_SCX = 0x4
PTRACE_SYSCALL = 0x6
PTRACE_VFORK = 0x20
PT_ATTACH = 0xa
PT_CLEARSTEP = 0x10
PT_CONTINUE = 0x7
PT_DETACH = 0xb
PT_FIRSTMACH = 0x40
PT_FOLLOW_FORK = 0x17
PT_GETDBREGS = 0x25
PT_GETFPREGS = 0x23
PT_GETLWPLIST = 0xf
PT_GETNUMLWPS = 0xe
PT_GETREGS = 0x21
PT_GETVFPREGS = 0x40
PT_GET_EVENT_MASK = 0x19
PT_GET_SC_ARGS = 0x1b
PT_GET_SC_RET = 0x1c
PT_IO = 0xc
PT_KILL = 0x8
PT_LWPINFO = 0xd
PT_LWP_EVENTS = 0x18
PT_READ_D = 0x2
PT_READ_I = 0x1
PT_RESUME = 0x13
PT_SETDBREGS = 0x26
PT_SETFPREGS = 0x24
PT_SETREGS = 0x22
PT_SETSTEP = 0x11
PT_SETVFPREGS = 0x41
PT_SET_EVENT_MASK = 0x1a
PT_STEP = 0x9
PT_SUSPEND = 0x12
PT_SYSCALL = 0x16
PT_TO_SCE = 0x14
PT_TO_SCX = 0x15
PT_TRACE_ME = 0x0
PT_VM_ENTRY = 0x29
PT_VM_TIMESTAMP = 0x28
PT_WRITE_D = 0x5
PT_WRITE_I = 0x4
P_ZONEID = 0xc
RLIMIT_AS = 0xa
RLIMIT_CORE = 0x4
RLIMIT_CPU = 0x0
@@ -1257,7 +1336,6 @@ const (
RTV_WEIGHT = 0x100
RT_ALL_FIBS = -0x1
RT_BLACKHOLE = 0x40
RT_CACHING_CONTEXT = 0x1
RT_DEFAULT_FIB = 0x0
RT_HAS_GW = 0x80
RT_HAS_HEADER = 0x10
@@ -1267,15 +1345,17 @@ const (
RT_LLE_CACHE = 0x100
RT_MAY_LOOP = 0x8
RT_MAY_LOOP_BIT = 0x3
RT_NORTREF = 0x2
RT_REJECT = 0x20
RUSAGE_CHILDREN = -0x1
RUSAGE_SELF = 0x0
RUSAGE_THREAD = 0x1
SCM_BINTIME = 0x4
SCM_CREDS = 0x3
SCM_MONOTONIC = 0x6
SCM_REALTIME = 0x5
SCM_RIGHTS = 0x1
SCM_TIMESTAMP = 0x2
SCM_TIME_INFO = 0x7
SEEK_CUR = 0x1
SEEK_DATA = 0x3
SEEK_END = 0x2
@@ -1299,10 +1379,12 @@ const (
SIOCGHWADDR = 0xc020693e
SIOCGI2C = 0xc020693d
SIOCGIFADDR = 0xc0206921
SIOCGIFALIAS = 0xc044692d
SIOCGIFBRDADDR = 0xc0206923
SIOCGIFCAP = 0xc020691f
SIOCGIFCONF = 0xc0086924
SIOCGIFDESCR = 0xc020692a
SIOCGIFDOWNREASON = 0xc058699a
SIOCGIFDSTADDR = 0xc0206922
SIOCGIFFIB = 0xc020695c
SIOCGIFFLAGS = 0xc0206911
@@ -1318,8 +1400,11 @@ const (
SIOCGIFPDSTADDR = 0xc0206948
SIOCGIFPHYS = 0xc0206935
SIOCGIFPSRCADDR = 0xc0206947
SIOCGIFRSSHASH = 0xc0186997
SIOCGIFRSSKEY = 0xc0946996
SIOCGIFSTATUS = 0xc331693b
SIOCGIFXMEDIA = 0xc028698b
SIOCGLANPCP = 0xc0206998
SIOCGLOWAT = 0x40047303
SIOCGPGRP = 0x40047309
SIOCGPRIVATE_0 = 0xc0206950
@@ -1350,6 +1435,7 @@ const (
SIOCSIFPHYS = 0x80206936
SIOCSIFRVNET = 0xc020695b
SIOCSIFVNET = 0xc020695a
SIOCSLANPCP = 0x80206999
SIOCSLOWAT = 0x80047302
SIOCSPGRP = 0x80047308
SIOCSTUNFIB = 0x8020695f
@@ -1369,6 +1455,7 @@ const (
SO_BINTIME = 0x2000
SO_BROADCAST = 0x20
SO_DEBUG = 0x1
SO_DOMAIN = 0x1019
SO_DONTROUTE = 0x10
SO_ERROR = 0x1007
SO_KEEPALIVE = 0x8
@@ -1377,6 +1464,7 @@ const (
SO_LISTENINCQLEN = 0x1013
SO_LISTENQLEN = 0x1012
SO_LISTENQLIMIT = 0x1011
SO_MAX_PACING_RATE = 0x1018
SO_NOSIGPIPE = 0x800
SO_NO_DDP = 0x8000
SO_NO_OFFLOAD = 0x4000
@@ -1387,13 +1475,22 @@ const (
SO_RCVBUF = 0x1002
SO_RCVLOWAT = 0x1004
SO_RCVTIMEO = 0x1006
SO_RERROR = 0x20000
SO_REUSEADDR = 0x4
SO_REUSEPORT = 0x200
SO_REUSEPORT_LB = 0x10000
SO_SETFIB = 0x1014
SO_SNDBUF = 0x1001
SO_SNDLOWAT = 0x1003
SO_SNDTIMEO = 0x1005
SO_TIMESTAMP = 0x400
SO_TS_BINTIME = 0x1
SO_TS_CLOCK = 0x1017
SO_TS_CLOCK_MAX = 0x3
SO_TS_DEFAULT = 0x0
SO_TS_MONOTONIC = 0x3
SO_TS_REALTIME = 0x2
SO_TS_REALTIME_MICRO = 0x0
SO_TYPE = 0x1008
SO_USELOOPBACK = 0x40
SO_USER_COOKIE = 0x1015
@@ -1437,10 +1534,69 @@ const (
TCOFLUSH = 0x2
TCOOFF = 0x1
TCOON = 0x2
TCPOPT_EOL = 0x0
TCPOPT_FAST_OPEN = 0x22
TCPOPT_MAXSEG = 0x2
TCPOPT_NOP = 0x1
TCPOPT_PAD = 0x0
TCPOPT_SACK = 0x5
TCPOPT_SACK_PERMITTED = 0x4
TCPOPT_SIGNATURE = 0x13
TCPOPT_TIMESTAMP = 0x8
TCPOPT_WINDOW = 0x3
TCP_BBR_ACK_COMP_ALG = 0x448
TCP_BBR_ALGORITHM = 0x43b
TCP_BBR_DRAIN_INC_EXTRA = 0x43c
TCP_BBR_DRAIN_PG = 0x42e
TCP_BBR_EXTRA_GAIN = 0x449
TCP_BBR_EXTRA_STATE = 0x453
TCP_BBR_FLOOR_MIN_TSO = 0x454
TCP_BBR_HDWR_PACE = 0x451
TCP_BBR_HOLD_TARGET = 0x436
TCP_BBR_IWINTSO = 0x42b
TCP_BBR_LOWGAIN_FD = 0x436
TCP_BBR_LOWGAIN_HALF = 0x435
TCP_BBR_LOWGAIN_THRESH = 0x434
TCP_BBR_MAX_RTO = 0x439
TCP_BBR_MIN_RTO = 0x438
TCP_BBR_MIN_TOPACEOUT = 0x455
TCP_BBR_ONE_RETRAN = 0x431
TCP_BBR_PACE_CROSS = 0x442
TCP_BBR_PACE_DEL_TAR = 0x43f
TCP_BBR_PACE_OH = 0x435
TCP_BBR_PACE_PER_SEC = 0x43e
TCP_BBR_PACE_SEG_MAX = 0x440
TCP_BBR_PACE_SEG_MIN = 0x441
TCP_BBR_POLICER_DETECT = 0x457
TCP_BBR_PROBE_RTT_GAIN = 0x44d
TCP_BBR_PROBE_RTT_INT = 0x430
TCP_BBR_PROBE_RTT_LEN = 0x44e
TCP_BBR_RACK_RTT_USE = 0x44a
TCP_BBR_RECFORCE = 0x42c
TCP_BBR_REC_OVER_HPTS = 0x43a
TCP_BBR_RETRAN_WTSO = 0x44b
TCP_BBR_RWND_IS_APP = 0x42f
TCP_BBR_SEND_IWND_IN_TSO = 0x44f
TCP_BBR_STARTUP_EXIT_EPOCH = 0x43d
TCP_BBR_STARTUP_LOSS_EXIT = 0x432
TCP_BBR_STARTUP_PG = 0x42d
TCP_BBR_TMR_PACE_OH = 0x448
TCP_BBR_TSLIMITS = 0x434
TCP_BBR_TSTMP_RAISES = 0x456
TCP_BBR_UNLIMITED = 0x43b
TCP_BBR_USEDEL_RATE = 0x437
TCP_BBR_USE_LOWGAIN = 0x433
TCP_BBR_USE_RACK_CHEAT = 0x450
TCP_BBR_UTTER_MAX_TSO = 0x452
TCP_CA_NAME_MAX = 0x10
TCP_CCALGOOPT = 0x41
TCP_CONGESTION = 0x40
TCP_DATA_AFTER_CLOSE = 0x44c
TCP_DELACK = 0x48
TCP_FASTOPEN = 0x401
TCP_FASTOPEN_MAX_COOKIE_LEN = 0x10
TCP_FASTOPEN_MIN_COOKIE_LEN = 0x4
TCP_FASTOPEN_PSK_LEN = 0x10
TCP_FUNCTION_BLK = 0x2000
TCP_FUNCTION_NAME_LEN_MAX = 0x20
TCP_INFO = 0x20
@@ -1448,6 +1604,12 @@ const (
TCP_KEEPIDLE = 0x100
TCP_KEEPINIT = 0x80
TCP_KEEPINTVL = 0x200
TCP_LOG = 0x22
TCP_LOGBUF = 0x23
TCP_LOGDUMP = 0x25
TCP_LOGDUMPID = 0x26
TCP_LOGID = 0x24
TCP_LOG_ID_LEN = 0x40
TCP_MAXBURST = 0x4
TCP_MAXHLEN = 0x3c
TCP_MAXOLEN = 0x28
@@ -1463,8 +1625,30 @@ const (
TCP_NOPUSH = 0x4
TCP_PCAP_IN = 0x1000
TCP_PCAP_OUT = 0x800
TCP_RACK_EARLY_RECOV = 0x423
TCP_RACK_EARLY_SEG = 0x424
TCP_RACK_GP_INCREASE = 0x446
TCP_RACK_IDLE_REDUCE_HIGH = 0x444
TCP_RACK_MIN_PACE = 0x445
TCP_RACK_MIN_PACE_SEG = 0x446
TCP_RACK_MIN_TO = 0x422
TCP_RACK_PACE_ALWAYS = 0x41f
TCP_RACK_PACE_MAX_SEG = 0x41e
TCP_RACK_PACE_REDUCE = 0x41d
TCP_RACK_PKT_DELAY = 0x428
TCP_RACK_PROP = 0x41b
TCP_RACK_PROP_RATE = 0x420
TCP_RACK_PRR_SENDALOT = 0x421
TCP_RACK_REORD_FADE = 0x426
TCP_RACK_REORD_THRESH = 0x425
TCP_RACK_TLP_INC_VAR = 0x429
TCP_RACK_TLP_REDUCE = 0x41c
TCP_RACK_TLP_THRESH = 0x427
TCP_RACK_TLP_USE = 0x447
TCP_VENDOR = 0x80000000
TCSAFLUSH = 0x2
TIMER_ABSTIME = 0x1
TIMER_RELTIME = 0x0
TIOCCBRK = 0x2000747a
TIOCCDTR = 0x20007478
TIOCCONS = 0x80047462
@@ -1528,6 +1712,8 @@ const (
TIOCTIMESTAMP = 0x40107459
TIOCUCNTL = 0x80047466
TOSTOP = 0x400000
UTIME_NOW = -0x1
UTIME_OMIT = -0x2
VDISCARD = 0xf
VDSUSP = 0xb
VEOF = 0x0
@@ -1592,12 +1778,13 @@ const (
EIDRM = syscall.Errno(0x52)
EILSEQ = syscall.Errno(0x56)
EINPROGRESS = syscall.Errno(0x24)
EINTEGRITY = syscall.Errno(0x61)
EINTR = syscall.Errno(0x4)
EINVAL = syscall.Errno(0x16)
EIO = syscall.Errno(0x5)
EISCONN = syscall.Errno(0x38)
EISDIR = syscall.Errno(0x15)
ELAST = syscall.Errno(0x60)
ELAST = syscall.Errno(0x61)
ELOOP = syscall.Errno(0x3e)
EMFILE = syscall.Errno(0x18)
EMLINK = syscall.Errno(0x1f)
@@ -1740,7 +1927,7 @@ var errorList = [...]struct {
{32, "EPIPE", "broken pipe"},
{33, "EDOM", "numerical argument out of domain"},
{34, "ERANGE", "result too large"},
{35, "EAGAIN", "resource temporarily unavailable"},
{35, "EWOULDBLOCK", "resource temporarily unavailable"},
{36, "EINPROGRESS", "operation now in progress"},
{37, "EALREADY", "operation already in progress"},
{38, "ENOTSOCK", "socket operation on non-socket"},
@@ -1802,6 +1989,7 @@ var errorList = [...]struct {
{94, "ECAPMODE", "not permitted in capability mode"},
{95, "ENOTRECOVERABLE", "state not recoverable"},
{96, "EOWNERDEAD", "previous owner died"},
{97, "EINTEGRITY", "integrity check failed"},
}
// Signal table
+93 -7
View File
@@ -151,6 +151,7 @@ const (
BIOCSETF = 0x80104267
BIOCSETFNR = 0x80104282
BIOCSETIF = 0x8020426c
BIOCSETVLANPCP = 0x80044285
BIOCSETWF = 0x8010427b
BIOCSETZBUF = 0x80184281
BIOCSHDRCMPLT = 0x80044275
@@ -447,7 +448,7 @@ const (
DLT_IEEE802_16_MAC_CPS_RADIO = 0xc1
DLT_INFINIBAND = 0xf7
DLT_IPFILTER = 0x74
DLT_IPMB = 0xc7
DLT_IPMB_KONTRON = 0xc7
DLT_IPMB_LINUX = 0xd1
DLT_IPMI_HPM_2 = 0x104
DLT_IPNET = 0xe2
@@ -487,10 +488,11 @@ const (
DLT_LINUX_LAPD = 0xb1
DLT_LINUX_PPP_WITHDIRECTION = 0xa6
DLT_LINUX_SLL = 0x71
DLT_LINUX_SLL2 = 0x114
DLT_LOOP = 0x6c
DLT_LORATAP = 0x10e
DLT_LTALK = 0x72
DLT_MATCHING_MAX = 0x113
DLT_MATCHING_MAX = 0x114
DLT_MATCHING_MIN = 0x68
DLT_MFR = 0xb6
DLT_MOST = 0xd3
@@ -734,6 +736,7 @@ const (
IPPROTO_CMTP = 0x26
IPPROTO_CPHB = 0x49
IPPROTO_CPNX = 0x48
IPPROTO_DCCP = 0x21
IPPROTO_DDP = 0x25
IPPROTO_DGP = 0x56
IPPROTO_DIVERT = 0x102
@@ -814,7 +817,6 @@ const (
IPPROTO_SCTP = 0x84
IPPROTO_SDRP = 0x2a
IPPROTO_SEND = 0x103
IPPROTO_SEP = 0x21
IPPROTO_SHIM6 = 0x8c
IPPROTO_SKIP = 0x39
IPPROTO_SPACER = 0x7fff
@@ -911,6 +913,7 @@ const (
IPV6_V6ONLY = 0x1b
IPV6_VERSION = 0x60
IPV6_VERSION_MASK = 0xf0
IPV6_VLAN_PCP = 0x4b
IP_ADD_MEMBERSHIP = 0xc
IP_ADD_SOURCE_MEMBERSHIP = 0x46
IP_BINDANY = 0x18
@@ -989,8 +992,12 @@ const (
IP_TOS = 0x3
IP_TTL = 0x4
IP_UNBLOCK_SOURCE = 0x49
IP_VLAN_PCP = 0x4b
ISIG = 0x80
ISTRIP = 0x20
ITIMER_PROF = 0x2
ITIMER_REAL = 0x0
ITIMER_VIRTUAL = 0x1
IXANY = 0x800
IXOFF = 0x400
IXON = 0x200
@@ -1000,7 +1007,6 @@ const (
KERN_VERSION = 0x4
LOCAL_CONNWAIT = 0x4
LOCAL_CREDS = 0x2
LOCAL_CREDS_PERSISTENT = 0x3
LOCAL_PEERCRED = 0x1
LOCAL_VENDOR = 0x80000000
LOCK_EX = 0x2
@@ -1180,6 +1186,8 @@ const (
O_NONBLOCK = 0x4
O_RDONLY = 0x0
O_RDWR = 0x2
O_RESOLVE_BENEATH = 0x800000
O_SEARCH = 0x40000
O_SHLOCK = 0x10
O_SYNC = 0x80
O_TRUNC = 0x400
@@ -1190,6 +1198,10 @@ const (
PARMRK = 0x8
PARODD = 0x2000
PENDIN = 0x20000000
PIOD_READ_D = 0x1
PIOD_READ_I = 0x3
PIOD_WRITE_D = 0x2
PIOD_WRITE_I = 0x4
PRIO_PGRP = 0x1
PRIO_PROCESS = 0x0
PRIO_USER = 0x2
@@ -1197,6 +1209,51 @@ const (
PROT_NONE = 0x0
PROT_READ = 0x1
PROT_WRITE = 0x2
PTRACE_DEFAULT = 0x1
PTRACE_EXEC = 0x1
PTRACE_FORK = 0x8
PTRACE_LWP = 0x10
PTRACE_SCE = 0x2
PTRACE_SCX = 0x4
PTRACE_SYSCALL = 0x6
PTRACE_VFORK = 0x20
PT_ATTACH = 0xa
PT_CLEARSTEP = 0x10
PT_CONTINUE = 0x7
PT_DETACH = 0xb
PT_FIRSTMACH = 0x40
PT_FOLLOW_FORK = 0x17
PT_GETDBREGS = 0x25
PT_GETFPREGS = 0x23
PT_GETLWPLIST = 0xf
PT_GETNUMLWPS = 0xe
PT_GETREGS = 0x21
PT_GET_EVENT_MASK = 0x19
PT_GET_SC_ARGS = 0x1b
PT_GET_SC_RET = 0x1c
PT_IO = 0xc
PT_KILL = 0x8
PT_LWPINFO = 0xd
PT_LWP_EVENTS = 0x18
PT_READ_D = 0x2
PT_READ_I = 0x1
PT_RESUME = 0x13
PT_SETDBREGS = 0x26
PT_SETFPREGS = 0x24
PT_SETREGS = 0x22
PT_SETSTEP = 0x11
PT_SET_EVENT_MASK = 0x1a
PT_STEP = 0x9
PT_SUSPEND = 0x12
PT_SYSCALL = 0x16
PT_TO_SCE = 0x14
PT_TO_SCX = 0x15
PT_TRACE_ME = 0x0
PT_VM_ENTRY = 0x29
PT_VM_TIMESTAMP = 0x28
PT_WRITE_D = 0x5
PT_WRITE_I = 0x4
P_ZONEID = 0xc
RLIMIT_AS = 0xa
RLIMIT_CORE = 0x4
RLIMIT_CPU = 0x0
@@ -1321,10 +1378,12 @@ const (
SIOCGHWADDR = 0xc020693e
SIOCGI2C = 0xc020693d
SIOCGIFADDR = 0xc0206921
SIOCGIFALIAS = 0xc044692d
SIOCGIFBRDADDR = 0xc0206923
SIOCGIFCAP = 0xc020691f
SIOCGIFCONF = 0xc0106924
SIOCGIFDESCR = 0xc020692a
SIOCGIFDOWNREASON = 0xc058699a
SIOCGIFDSTADDR = 0xc0206922
SIOCGIFFIB = 0xc020695c
SIOCGIFFLAGS = 0xc0206911
@@ -1415,6 +1474,7 @@ const (
SO_RCVBUF = 0x1002
SO_RCVLOWAT = 0x1004
SO_RCVTIMEO = 0x1006
SO_RERROR = 0x20000
SO_REUSEADDR = 0x4
SO_REUSEPORT = 0x200
SO_REUSEPORT_LB = 0x10000
@@ -1473,22 +1533,40 @@ const (
TCOFLUSH = 0x2
TCOOFF = 0x1
TCOON = 0x2
TCPOPT_EOL = 0x0
TCPOPT_FAST_OPEN = 0x22
TCPOPT_MAXSEG = 0x2
TCPOPT_NOP = 0x1
TCPOPT_PAD = 0x0
TCPOPT_SACK = 0x5
TCPOPT_SACK_PERMITTED = 0x4
TCPOPT_SIGNATURE = 0x13
TCPOPT_TIMESTAMP = 0x8
TCPOPT_WINDOW = 0x3
TCP_BBR_ACK_COMP_ALG = 0x448
TCP_BBR_ALGORITHM = 0x43b
TCP_BBR_DRAIN_INC_EXTRA = 0x43c
TCP_BBR_DRAIN_PG = 0x42e
TCP_BBR_EXTRA_GAIN = 0x449
TCP_BBR_EXTRA_STATE = 0x453
TCP_BBR_FLOOR_MIN_TSO = 0x454
TCP_BBR_HDWR_PACE = 0x451
TCP_BBR_HOLD_TARGET = 0x436
TCP_BBR_IWINTSO = 0x42b
TCP_BBR_LOWGAIN_FD = 0x436
TCP_BBR_LOWGAIN_HALF = 0x435
TCP_BBR_LOWGAIN_THRESH = 0x434
TCP_BBR_MAX_RTO = 0x439
TCP_BBR_MIN_RTO = 0x438
TCP_BBR_MIN_TOPACEOUT = 0x455
TCP_BBR_ONE_RETRAN = 0x431
TCP_BBR_PACE_CROSS = 0x442
TCP_BBR_PACE_DEL_TAR = 0x43f
TCP_BBR_PACE_OH = 0x435
TCP_BBR_PACE_PER_SEC = 0x43e
TCP_BBR_PACE_SEG_MAX = 0x440
TCP_BBR_PACE_SEG_MIN = 0x441
TCP_BBR_POLICER_DETECT = 0x457
TCP_BBR_PROBE_RTT_GAIN = 0x44d
TCP_BBR_PROBE_RTT_INT = 0x430
TCP_BBR_PROBE_RTT_LEN = 0x44e
@@ -1497,12 +1575,18 @@ const (
TCP_BBR_REC_OVER_HPTS = 0x43a
TCP_BBR_RETRAN_WTSO = 0x44b
TCP_BBR_RWND_IS_APP = 0x42f
TCP_BBR_SEND_IWND_IN_TSO = 0x44f
TCP_BBR_STARTUP_EXIT_EPOCH = 0x43d
TCP_BBR_STARTUP_LOSS_EXIT = 0x432
TCP_BBR_STARTUP_PG = 0x42d
TCP_BBR_TMR_PACE_OH = 0x448
TCP_BBR_TSLIMITS = 0x434
TCP_BBR_TSTMP_RAISES = 0x456
TCP_BBR_UNLIMITED = 0x43b
TCP_BBR_USEDEL_RATE = 0x437
TCP_BBR_USE_LOWGAIN = 0x433
TCP_BBR_USE_RACK_CHEAT = 0x450
TCP_BBR_UTTER_MAX_TSO = 0x452
TCP_CA_NAME_MAX = 0x10
TCP_CCALGOOPT = 0x41
TCP_CONGESTION = 0x40
@@ -1542,6 +1626,7 @@ const (
TCP_PCAP_OUT = 0x800
TCP_RACK_EARLY_RECOV = 0x423
TCP_RACK_EARLY_SEG = 0x424
TCP_RACK_GP_INCREASE = 0x446
TCP_RACK_IDLE_REDUCE_HIGH = 0x444
TCP_RACK_MIN_PACE = 0x445
TCP_RACK_MIN_PACE_SEG = 0x446
@@ -1555,7 +1640,6 @@ const (
TCP_RACK_PRR_SENDALOT = 0x421
TCP_RACK_REORD_FADE = 0x426
TCP_RACK_REORD_THRESH = 0x425
TCP_RACK_SESS_CWV = 0x42a
TCP_RACK_TLP_INC_VAR = 0x429
TCP_RACK_TLP_REDUCE = 0x41c
TCP_RACK_TLP_THRESH = 0x427
@@ -1694,12 +1778,13 @@ const (
EIDRM = syscall.Errno(0x52)
EILSEQ = syscall.Errno(0x56)
EINPROGRESS = syscall.Errno(0x24)
EINTEGRITY = syscall.Errno(0x61)
EINTR = syscall.Errno(0x4)
EINVAL = syscall.Errno(0x16)
EIO = syscall.Errno(0x5)
EISCONN = syscall.Errno(0x38)
EISDIR = syscall.Errno(0x15)
ELAST = syscall.Errno(0x60)
ELAST = syscall.Errno(0x61)
ELOOP = syscall.Errno(0x3e)
EMFILE = syscall.Errno(0x18)
EMLINK = syscall.Errno(0x1f)
@@ -1842,7 +1927,7 @@ var errorList = [...]struct {
{32, "EPIPE", "broken pipe"},
{33, "EDOM", "numerical argument out of domain"},
{34, "ERANGE", "result too large"},
{35, "EAGAIN", "resource temporarily unavailable"},
{35, "EWOULDBLOCK", "resource temporarily unavailable"},
{36, "EINPROGRESS", "operation now in progress"},
{37, "EALREADY", "operation already in progress"},
{38, "ENOTSOCK", "socket operation on non-socket"},
@@ -1904,6 +1989,7 @@ var errorList = [...]struct {
{94, "ECAPMODE", "not permitted in capability mode"},
{95, "ENOTRECOVERABLE", "state not recoverable"},
{96, "EOWNERDEAD", "previous owner died"},
{97, "EINTEGRITY", "integrity check failed"},
}
// Signal table
File diff suppressed because it is too large Load Diff
+381 -8
View File
@@ -140,6 +140,306 @@ const (
ARPHRD_VOID = 0xffff
ARPHRD_VSOCKMON = 0x33a
ARPHRD_X25 = 0x10f
AUDIT_ADD = 0x3eb
AUDIT_ADD_RULE = 0x3f3
AUDIT_ALWAYS = 0x2
AUDIT_ANOM_ABEND = 0x6a5
AUDIT_ANOM_CREAT = 0x6a7
AUDIT_ANOM_LINK = 0x6a6
AUDIT_ANOM_PROMISCUOUS = 0x6a4
AUDIT_ARCH = 0xb
AUDIT_ARCH_AARCH64 = 0xc00000b7
AUDIT_ARCH_ALPHA = 0xc0009026
AUDIT_ARCH_ARCOMPACT = 0x4000005d
AUDIT_ARCH_ARCOMPACTBE = 0x5d
AUDIT_ARCH_ARCV2 = 0x400000c3
AUDIT_ARCH_ARCV2BE = 0xc3
AUDIT_ARCH_ARM = 0x40000028
AUDIT_ARCH_ARMEB = 0x28
AUDIT_ARCH_C6X = 0x4000008c
AUDIT_ARCH_C6XBE = 0x8c
AUDIT_ARCH_CRIS = 0x4000004c
AUDIT_ARCH_CSKY = 0x400000fc
AUDIT_ARCH_FRV = 0x5441
AUDIT_ARCH_H8300 = 0x2e
AUDIT_ARCH_HEXAGON = 0xa4
AUDIT_ARCH_I386 = 0x40000003
AUDIT_ARCH_IA64 = 0xc0000032
AUDIT_ARCH_LOONGARCH32 = 0x40000102
AUDIT_ARCH_LOONGARCH64 = 0xc0000102
AUDIT_ARCH_M32R = 0x58
AUDIT_ARCH_M68K = 0x4
AUDIT_ARCH_MICROBLAZE = 0xbd
AUDIT_ARCH_MIPS = 0x8
AUDIT_ARCH_MIPS64 = 0x80000008
AUDIT_ARCH_MIPS64N32 = 0xa0000008
AUDIT_ARCH_MIPSEL = 0x40000008
AUDIT_ARCH_MIPSEL64 = 0xc0000008
AUDIT_ARCH_MIPSEL64N32 = 0xe0000008
AUDIT_ARCH_NDS32 = 0x400000a7
AUDIT_ARCH_NDS32BE = 0xa7
AUDIT_ARCH_NIOS2 = 0x40000071
AUDIT_ARCH_OPENRISC = 0x5c
AUDIT_ARCH_PARISC = 0xf
AUDIT_ARCH_PARISC64 = 0x8000000f
AUDIT_ARCH_PPC = 0x14
AUDIT_ARCH_PPC64 = 0x80000015
AUDIT_ARCH_PPC64LE = 0xc0000015
AUDIT_ARCH_RISCV32 = 0x400000f3
AUDIT_ARCH_RISCV64 = 0xc00000f3
AUDIT_ARCH_S390 = 0x16
AUDIT_ARCH_S390X = 0x80000016
AUDIT_ARCH_SH = 0x2a
AUDIT_ARCH_SH64 = 0x8000002a
AUDIT_ARCH_SHEL = 0x4000002a
AUDIT_ARCH_SHEL64 = 0xc000002a
AUDIT_ARCH_SPARC = 0x2
AUDIT_ARCH_SPARC64 = 0x8000002b
AUDIT_ARCH_TILEGX = 0xc00000bf
AUDIT_ARCH_TILEGX32 = 0x400000bf
AUDIT_ARCH_TILEPRO = 0x400000bc
AUDIT_ARCH_UNICORE = 0x4000006e
AUDIT_ARCH_X86_64 = 0xc000003e
AUDIT_ARCH_XTENSA = 0x5e
AUDIT_ARG0 = 0xc8
AUDIT_ARG1 = 0xc9
AUDIT_ARG2 = 0xca
AUDIT_ARG3 = 0xcb
AUDIT_AVC = 0x578
AUDIT_AVC_PATH = 0x57a
AUDIT_BITMASK_SIZE = 0x40
AUDIT_BIT_MASK = 0x8000000
AUDIT_BIT_TEST = 0x48000000
AUDIT_BPF = 0x536
AUDIT_BPRM_FCAPS = 0x529
AUDIT_CAPSET = 0x52a
AUDIT_CLASS_CHATTR = 0x2
AUDIT_CLASS_CHATTR_32 = 0x3
AUDIT_CLASS_DIR_WRITE = 0x0
AUDIT_CLASS_DIR_WRITE_32 = 0x1
AUDIT_CLASS_READ = 0x4
AUDIT_CLASS_READ_32 = 0x5
AUDIT_CLASS_SIGNAL = 0x8
AUDIT_CLASS_SIGNAL_32 = 0x9
AUDIT_CLASS_WRITE = 0x6
AUDIT_CLASS_WRITE_32 = 0x7
AUDIT_COMPARE_AUID_TO_EUID = 0x10
AUDIT_COMPARE_AUID_TO_FSUID = 0xe
AUDIT_COMPARE_AUID_TO_OBJ_UID = 0x5
AUDIT_COMPARE_AUID_TO_SUID = 0xf
AUDIT_COMPARE_EGID_TO_FSGID = 0x17
AUDIT_COMPARE_EGID_TO_OBJ_GID = 0x4
AUDIT_COMPARE_EGID_TO_SGID = 0x18
AUDIT_COMPARE_EUID_TO_FSUID = 0x12
AUDIT_COMPARE_EUID_TO_OBJ_UID = 0x3
AUDIT_COMPARE_EUID_TO_SUID = 0x11
AUDIT_COMPARE_FSGID_TO_OBJ_GID = 0x9
AUDIT_COMPARE_FSUID_TO_OBJ_UID = 0x8
AUDIT_COMPARE_GID_TO_EGID = 0x14
AUDIT_COMPARE_GID_TO_FSGID = 0x15
AUDIT_COMPARE_GID_TO_OBJ_GID = 0x2
AUDIT_COMPARE_GID_TO_SGID = 0x16
AUDIT_COMPARE_SGID_TO_FSGID = 0x19
AUDIT_COMPARE_SGID_TO_OBJ_GID = 0x7
AUDIT_COMPARE_SUID_TO_FSUID = 0x13
AUDIT_COMPARE_SUID_TO_OBJ_UID = 0x6
AUDIT_COMPARE_UID_TO_AUID = 0xa
AUDIT_COMPARE_UID_TO_EUID = 0xb
AUDIT_COMPARE_UID_TO_FSUID = 0xc
AUDIT_COMPARE_UID_TO_OBJ_UID = 0x1
AUDIT_COMPARE_UID_TO_SUID = 0xd
AUDIT_CONFIG_CHANGE = 0x519
AUDIT_CWD = 0x51b
AUDIT_DAEMON_ABORT = 0x4b2
AUDIT_DAEMON_CONFIG = 0x4b3
AUDIT_DAEMON_END = 0x4b1
AUDIT_DAEMON_START = 0x4b0
AUDIT_DEL = 0x3ec
AUDIT_DEL_RULE = 0x3f4
AUDIT_DEVMAJOR = 0x64
AUDIT_DEVMINOR = 0x65
AUDIT_DIR = 0x6b
AUDIT_DM_CTRL = 0x53a
AUDIT_DM_EVENT = 0x53b
AUDIT_EGID = 0x6
AUDIT_EOE = 0x528
AUDIT_EQUAL = 0x40000000
AUDIT_EUID = 0x2
AUDIT_EVENT_LISTENER = 0x537
AUDIT_EXE = 0x70
AUDIT_EXECVE = 0x51d
AUDIT_EXIT = 0x67
AUDIT_FAIL_PANIC = 0x2
AUDIT_FAIL_PRINTK = 0x1
AUDIT_FAIL_SILENT = 0x0
AUDIT_FANOTIFY = 0x533
AUDIT_FD_PAIR = 0x525
AUDIT_FEATURE_BITMAP_ALL = 0x7f
AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT = 0x1
AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME = 0x2
AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND = 0x8
AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH = 0x4
AUDIT_FEATURE_BITMAP_FILTER_FS = 0x40
AUDIT_FEATURE_BITMAP_LOST_RESET = 0x20
AUDIT_FEATURE_BITMAP_SESSIONID_FILTER = 0x10
AUDIT_FEATURE_CHANGE = 0x530
AUDIT_FEATURE_LOGINUID_IMMUTABLE = 0x1
AUDIT_FEATURE_ONLY_UNSET_LOGINUID = 0x0
AUDIT_FEATURE_VERSION = 0x1
AUDIT_FIELD_COMPARE = 0x6f
AUDIT_FILETYPE = 0x6c
AUDIT_FILTERKEY = 0xd2
AUDIT_FILTER_ENTRY = 0x2
AUDIT_FILTER_EXCLUDE = 0x5
AUDIT_FILTER_EXIT = 0x4
AUDIT_FILTER_FS = 0x6
AUDIT_FILTER_PREPEND = 0x10
AUDIT_FILTER_TASK = 0x1
AUDIT_FILTER_TYPE = 0x5
AUDIT_FILTER_URING_EXIT = 0x7
AUDIT_FILTER_USER = 0x0
AUDIT_FILTER_WATCH = 0x3
AUDIT_FIRST_KERN_ANOM_MSG = 0x6a4
AUDIT_FIRST_USER_MSG = 0x44c
AUDIT_FIRST_USER_MSG2 = 0x834
AUDIT_FSGID = 0x8
AUDIT_FSTYPE = 0x1a
AUDIT_FSUID = 0x4
AUDIT_GET = 0x3e8
AUDIT_GET_FEATURE = 0x3fb
AUDIT_GID = 0x5
AUDIT_GREATER_THAN = 0x20000000
AUDIT_GREATER_THAN_OR_EQUAL = 0x60000000
AUDIT_INODE = 0x66
AUDIT_INTEGRITY_DATA = 0x708
AUDIT_INTEGRITY_EVM_XATTR = 0x70e
AUDIT_INTEGRITY_HASH = 0x70b
AUDIT_INTEGRITY_METADATA = 0x709
AUDIT_INTEGRITY_PCR = 0x70c
AUDIT_INTEGRITY_POLICY_RULE = 0x70f
AUDIT_INTEGRITY_RULE = 0x70d
AUDIT_INTEGRITY_STATUS = 0x70a
AUDIT_IPC = 0x517
AUDIT_IPC_SET_PERM = 0x51f
AUDIT_KERNEL = 0x7d0
AUDIT_KERNEL_OTHER = 0x524
AUDIT_KERN_MODULE = 0x532
AUDIT_LAST_FEATURE = 0x1
AUDIT_LAST_KERN_ANOM_MSG = 0x707
AUDIT_LAST_USER_MSG = 0x4af
AUDIT_LAST_USER_MSG2 = 0xbb7
AUDIT_LESS_THAN = 0x10000000
AUDIT_LESS_THAN_OR_EQUAL = 0x50000000
AUDIT_LIST = 0x3ea
AUDIT_LIST_RULES = 0x3f5
AUDIT_LOGIN = 0x3ee
AUDIT_LOGINUID = 0x9
AUDIT_LOGINUID_SET = 0x18
AUDIT_MAC_CALIPSO_ADD = 0x58a
AUDIT_MAC_CALIPSO_DEL = 0x58b
AUDIT_MAC_CIPSOV4_ADD = 0x57f
AUDIT_MAC_CIPSOV4_DEL = 0x580
AUDIT_MAC_CONFIG_CHANGE = 0x57d
AUDIT_MAC_IPSEC_ADDSA = 0x583
AUDIT_MAC_IPSEC_ADDSPD = 0x585
AUDIT_MAC_IPSEC_DELSA = 0x584
AUDIT_MAC_IPSEC_DELSPD = 0x586
AUDIT_MAC_IPSEC_EVENT = 0x587
AUDIT_MAC_MAP_ADD = 0x581
AUDIT_MAC_MAP_DEL = 0x582
AUDIT_MAC_POLICY_LOAD = 0x57b
AUDIT_MAC_STATUS = 0x57c
AUDIT_MAC_UNLBL_ALLOW = 0x57e
AUDIT_MAC_UNLBL_STCADD = 0x588
AUDIT_MAC_UNLBL_STCDEL = 0x589
AUDIT_MAKE_EQUIV = 0x3f7
AUDIT_MAX_FIELDS = 0x40
AUDIT_MAX_FIELD_COMPARE = 0x19
AUDIT_MAX_KEY_LEN = 0x100
AUDIT_MESSAGE_TEXT_MAX = 0x2170
AUDIT_MMAP = 0x52b
AUDIT_MQ_GETSETATTR = 0x523
AUDIT_MQ_NOTIFY = 0x522
AUDIT_MQ_OPEN = 0x520
AUDIT_MQ_SENDRECV = 0x521
AUDIT_MSGTYPE = 0xc
AUDIT_NEGATE = 0x80000000
AUDIT_NETFILTER_CFG = 0x52d
AUDIT_NETFILTER_PKT = 0x52c
AUDIT_NEVER = 0x0
AUDIT_NLGRP_MAX = 0x1
AUDIT_NOT_EQUAL = 0x30000000
AUDIT_NR_FILTERS = 0x8
AUDIT_OBJ_GID = 0x6e
AUDIT_OBJ_LEV_HIGH = 0x17
AUDIT_OBJ_LEV_LOW = 0x16
AUDIT_OBJ_PID = 0x526
AUDIT_OBJ_ROLE = 0x14
AUDIT_OBJ_TYPE = 0x15
AUDIT_OBJ_UID = 0x6d
AUDIT_OBJ_USER = 0x13
AUDIT_OPENAT2 = 0x539
AUDIT_OPERATORS = 0x78000000
AUDIT_PATH = 0x516
AUDIT_PERM = 0x6a
AUDIT_PERM_ATTR = 0x8
AUDIT_PERM_EXEC = 0x1
AUDIT_PERM_READ = 0x4
AUDIT_PERM_WRITE = 0x2
AUDIT_PERS = 0xa
AUDIT_PID = 0x0
AUDIT_POSSIBLE = 0x1
AUDIT_PPID = 0x12
AUDIT_PROCTITLE = 0x52f
AUDIT_REPLACE = 0x531
AUDIT_SADDR_FAM = 0x71
AUDIT_SECCOMP = 0x52e
AUDIT_SELINUX_ERR = 0x579
AUDIT_SESSIONID = 0x19
AUDIT_SET = 0x3e9
AUDIT_SET_FEATURE = 0x3fa
AUDIT_SGID = 0x7
AUDIT_SID_UNSET = 0xffffffff
AUDIT_SIGNAL_INFO = 0x3f2
AUDIT_SOCKADDR = 0x51a
AUDIT_SOCKETCALL = 0x518
AUDIT_STATUS_BACKLOG_LIMIT = 0x10
AUDIT_STATUS_BACKLOG_WAIT_TIME = 0x20
AUDIT_STATUS_BACKLOG_WAIT_TIME_ACTUAL = 0x80
AUDIT_STATUS_ENABLED = 0x1
AUDIT_STATUS_FAILURE = 0x2
AUDIT_STATUS_LOST = 0x40
AUDIT_STATUS_PID = 0x4
AUDIT_STATUS_RATE_LIMIT = 0x8
AUDIT_SUBJ_CLR = 0x11
AUDIT_SUBJ_ROLE = 0xe
AUDIT_SUBJ_SEN = 0x10
AUDIT_SUBJ_TYPE = 0xf
AUDIT_SUBJ_USER = 0xd
AUDIT_SUCCESS = 0x68
AUDIT_SUID = 0x3
AUDIT_SYSCALL = 0x514
AUDIT_SYSCALL_CLASSES = 0x10
AUDIT_TIME_ADJNTPVAL = 0x535
AUDIT_TIME_INJOFFSET = 0x534
AUDIT_TRIM = 0x3f6
AUDIT_TTY = 0x527
AUDIT_TTY_GET = 0x3f8
AUDIT_TTY_SET = 0x3f9
AUDIT_UID = 0x1
AUDIT_UID_UNSET = 0xffffffff
AUDIT_UNUSED_BITS = 0x7fffc00
AUDIT_URINGOP = 0x538
AUDIT_USER = 0x3ed
AUDIT_USER_AVC = 0x453
AUDIT_USER_TTY = 0x464
AUDIT_VERSION_BACKLOG_LIMIT = 0x1
AUDIT_VERSION_BACKLOG_WAIT_TIME = 0x2
AUDIT_VERSION_LATEST = 0x7f
AUDIT_WATCH = 0x69
AUDIT_WATCH_INS = 0x3ef
AUDIT_WATCH_LIST = 0x3f1
AUDIT_WATCH_REM = 0x3f0
AUTOFS_SUPER_MAGIC = 0x187
B0 = 0x0
B110 = 0x3
@@ -184,6 +484,7 @@ const (
BPF_F_ALLOW_MULTI = 0x2
BPF_F_ALLOW_OVERRIDE = 0x1
BPF_F_ANY_ALIGNMENT = 0x2
BPF_F_KPROBE_MULTI_RETURN = 0x1
BPF_F_QUERY_EFFECTIVE = 0x1
BPF_F_REPLACE = 0x4
BPF_F_SLEEPABLE = 0x10
@@ -191,6 +492,8 @@ const (
BPF_F_TEST_RND_HI32 = 0x4
BPF_F_TEST_RUN_ON_CPU = 0x1
BPF_F_TEST_STATE_FREQ = 0x8
BPF_F_TEST_XDP_LIVE_FRAMES = 0x2
BPF_F_XDP_HAS_FRAGS = 0x20
BPF_H = 0x8
BPF_IMM = 0x0
BPF_IND = 0x40
@@ -517,9 +820,9 @@ const (
DM_UUID_FLAG = 0x4000
DM_UUID_LEN = 0x81
DM_VERSION = 0xc138fd00
DM_VERSION_EXTRA = "-ioctl (2021-03-22)"
DM_VERSION_EXTRA = "-ioctl (2022-02-22)"
DM_VERSION_MAJOR = 0x4
DM_VERSION_MINOR = 0x2d
DM_VERSION_MINOR = 0x2e
DM_VERSION_PATCHLEVEL = 0x0
DT_BLK = 0x6
DT_CHR = 0x2
@@ -535,6 +838,55 @@ const (
EFD_SEMAPHORE = 0x1
EFIVARFS_MAGIC = 0xde5e81e4
EFS_SUPER_MAGIC = 0x414a53
EM_386 = 0x3
EM_486 = 0x6
EM_68K = 0x4
EM_860 = 0x7
EM_88K = 0x5
EM_AARCH64 = 0xb7
EM_ALPHA = 0x9026
EM_ALTERA_NIOS2 = 0x71
EM_ARCOMPACT = 0x5d
EM_ARCV2 = 0xc3
EM_ARM = 0x28
EM_BLACKFIN = 0x6a
EM_BPF = 0xf7
EM_CRIS = 0x4c
EM_CSKY = 0xfc
EM_CYGNUS_M32R = 0x9041
EM_CYGNUS_MN10300 = 0xbeef
EM_FRV = 0x5441
EM_H8_300 = 0x2e
EM_HEXAGON = 0xa4
EM_IA_64 = 0x32
EM_LOONGARCH = 0x102
EM_M32 = 0x1
EM_M32R = 0x58
EM_MICROBLAZE = 0xbd
EM_MIPS = 0x8
EM_MIPS_RS3_LE = 0xa
EM_MIPS_RS4_BE = 0xa
EM_MN10300 = 0x59
EM_NDS32 = 0xa7
EM_NONE = 0x0
EM_OPENRISC = 0x5c
EM_PARISC = 0xf
EM_PPC = 0x14
EM_PPC64 = 0x15
EM_RISCV = 0xf3
EM_S390 = 0x16
EM_S390_OLD = 0xa390
EM_SH = 0x2a
EM_SPARC = 0x2
EM_SPARC32PLUS = 0x12
EM_SPARCV9 = 0x2b
EM_SPU = 0x17
EM_TILEGX = 0xbf
EM_TILEPRO = 0xbc
EM_TI_C6000 = 0x8c
EM_UNICORE = 0x6e
EM_X86_64 = 0x3e
EM_XTENSA = 0x5e
ENCODING_DEFAULT = 0x0
ENCODING_FM_MARK = 0x3
ENCODING_FM_SPACE = 0x4
@@ -712,6 +1064,7 @@ const (
ETH_P_EDSA = 0xdada
ETH_P_ERSPAN = 0x88be
ETH_P_ERSPAN2 = 0x22eb
ETH_P_ETHERCAT = 0x88a4
ETH_P_FCOE = 0x8906
ETH_P_FIP = 0x8914
ETH_P_HDLC = 0x19
@@ -749,6 +1102,7 @@ const (
ETH_P_PPP_MP = 0x8
ETH_P_PPP_SES = 0x8864
ETH_P_PREAUTH = 0x88c7
ETH_P_PROFINET = 0x8892
ETH_P_PRP = 0x88fb
ETH_P_PUP = 0x200
ETH_P_PUPAT = 0x201
@@ -837,6 +1191,7 @@ const (
FAN_FS_ERROR = 0x8000
FAN_MARK_ADD = 0x1
FAN_MARK_DONT_FOLLOW = 0x4
FAN_MARK_EVICTABLE = 0x200
FAN_MARK_FILESYSTEM = 0x100
FAN_MARK_FLUSH = 0x80
FAN_MARK_IGNORED_MASK = 0x20
@@ -1055,7 +1410,7 @@ const (
IFA_F_STABLE_PRIVACY = 0x800
IFA_F_TEMPORARY = 0x1
IFA_F_TENTATIVE = 0x40
IFA_MAX = 0xa
IFA_MAX = 0xb
IFF_ALLMULTI = 0x200
IFF_ATTACH_QUEUE = 0x200
IFF_AUTOMEDIA = 0x4000
@@ -1403,6 +1758,7 @@ const (
LANDLOCK_ACCESS_FS_MAKE_SYM = 0x1000
LANDLOCK_ACCESS_FS_READ_DIR = 0x8
LANDLOCK_ACCESS_FS_READ_FILE = 0x4
LANDLOCK_ACCESS_FS_REFER = 0x2000
LANDLOCK_ACCESS_FS_REMOVE_DIR = 0x10
LANDLOCK_ACCESS_FS_REMOVE_FILE = 0x20
LANDLOCK_ACCESS_FS_WRITE_FILE = 0x2
@@ -1758,6 +2114,7 @@ const (
NLM_F_ACK_TLVS = 0x200
NLM_F_APPEND = 0x800
NLM_F_ATOMIC = 0x400
NLM_F_BULK = 0x200
NLM_F_CAPPED = 0x100
NLM_F_CREATE = 0x400
NLM_F_DUMP = 0x300
@@ -2075,6 +2432,11 @@ const (
PR_SET_UNALIGN = 0x6
PR_SET_VMA = 0x53564d41
PR_SET_VMA_ANON_NAME = 0x0
PR_SME_GET_VL = 0x40
PR_SME_SET_VL = 0x3f
PR_SME_SET_VL_ONEXEC = 0x40000
PR_SME_VL_INHERIT = 0x20000
PR_SME_VL_LEN_MASK = 0xffff
PR_SPEC_DISABLE = 0x4
PR_SPEC_DISABLE_NOEXEC = 0x10
PR_SPEC_ENABLE = 0x2
@@ -2227,8 +2589,9 @@ const (
RTC_FEATURE_ALARM = 0x0
RTC_FEATURE_ALARM_RES_2S = 0x3
RTC_FEATURE_ALARM_RES_MINUTE = 0x1
RTC_FEATURE_ALARM_WAKEUP_ONLY = 0x7
RTC_FEATURE_BACKUP_SWITCH_MODE = 0x6
RTC_FEATURE_CNT = 0x7
RTC_FEATURE_CNT = 0x8
RTC_FEATURE_CORRECTION = 0x5
RTC_FEATURE_NEED_WEEK_DAY = 0x2
RTC_FEATURE_UPDATE_INTERRUPT = 0x4
@@ -2302,6 +2665,7 @@ const (
RTM_DELRULE = 0x21
RTM_DELTCLASS = 0x29
RTM_DELTFILTER = 0x2d
RTM_DELTUNNEL = 0x79
RTM_DELVLAN = 0x71
RTM_F_CLONED = 0x200
RTM_F_EQUALIZE = 0x400
@@ -2334,8 +2698,9 @@ const (
RTM_GETSTATS = 0x5e
RTM_GETTCLASS = 0x2a
RTM_GETTFILTER = 0x2e
RTM_GETTUNNEL = 0x7a
RTM_GETVLAN = 0x72
RTM_MAX = 0x77
RTM_MAX = 0x7b
RTM_NEWACTION = 0x30
RTM_NEWADDR = 0x14
RTM_NEWADDRLABEL = 0x48
@@ -2359,11 +2724,13 @@ const (
RTM_NEWSTATS = 0x5c
RTM_NEWTCLASS = 0x28
RTM_NEWTFILTER = 0x2c
RTM_NR_FAMILIES = 0x1a
RTM_NR_MSGTYPES = 0x68
RTM_NEWTUNNEL = 0x78
RTM_NR_FAMILIES = 0x1b
RTM_NR_MSGTYPES = 0x6c
RTM_SETDCB = 0x4f
RTM_SETLINK = 0x13
RTM_SETNEIGHTBL = 0x43
RTM_SETSTATS = 0x5f
RTNH_ALIGNTO = 0x4
RTNH_COMPARE_MASK = 0x59
RTNH_F_DEAD = 0x1
@@ -2544,6 +2911,9 @@ const (
SOCK_RDM = 0x4
SOCK_SEQPACKET = 0x5
SOCK_SNDBUF_LOCK = 0x1
SOCK_TXREHASH_DEFAULT = 0xff
SOCK_TXREHASH_DISABLED = 0x0
SOCK_TXREHASH_ENABLED = 0x1
SOL_AAL = 0x109
SOL_ALG = 0x117
SOL_ATM = 0x108
@@ -2559,6 +2929,8 @@ const (
SOL_IUCV = 0x115
SOL_KCM = 0x119
SOL_LLC = 0x10c
SOL_MCTP = 0x11d
SOL_MPTCP = 0x11c
SOL_NETBEUI = 0x10b
SOL_NETLINK = 0x10e
SOL_NFC = 0x118
@@ -2568,6 +2940,7 @@ const (
SOL_RAW = 0xff
SOL_RDS = 0x114
SOL_RXRPC = 0x110
SOL_SMC = 0x11e
SOL_TCP = 0x6
SOL_TIPC = 0x10f
SOL_TLS = 0x11a
@@ -2674,7 +3047,7 @@ const (
TASKSTATS_GENL_NAME = "TASKSTATS"
TASKSTATS_GENL_VERSION = 0x1
TASKSTATS_TYPE_MAX = 0x6
TASKSTATS_VERSION = 0xb
TASKSTATS_VERSION = 0xd
TCIFLUSH = 0x0
TCIOFF = 0x2
TCIOFLUSH = 0x2
+2
View File
@@ -326,6 +326,7 @@ const (
SO_RCVBUF = 0x8
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x12
SO_RCVMARK = 0x4b
SO_RCVTIMEO = 0x14
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x14
@@ -350,6 +351,7 @@ const (
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TXREHASH = 0x4a
SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_WIFI_STATUS = 0x29
+2
View File
@@ -327,6 +327,7 @@ const (
SO_RCVBUF = 0x8
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x12
SO_RCVMARK = 0x4b
SO_RCVTIMEO = 0x14
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x14
@@ -351,6 +352,7 @@ const (
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TXREHASH = 0x4a
SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_WIFI_STATUS = 0x29
+2
View File
@@ -333,6 +333,7 @@ const (
SO_RCVBUF = 0x8
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x12
SO_RCVMARK = 0x4b
SO_RCVTIMEO = 0x14
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x14
@@ -357,6 +358,7 @@ const (
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TXREHASH = 0x4a
SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_WIFI_STATUS = 0x29
+3
View File
@@ -323,6 +323,7 @@ const (
SO_RCVBUF = 0x8
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x12
SO_RCVMARK = 0x4b
SO_RCVTIMEO = 0x14
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x14
@@ -347,6 +348,7 @@ const (
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TXREHASH = 0x4a
SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_WIFI_STATUS = 0x29
@@ -511,6 +513,7 @@ const (
WORDSIZE = 0x40
XCASE = 0x4
XTABS = 0x1800
ZA_MAGIC = 0x54366345
_HIDIOCGRAWNAME = 0x80804804
_HIDIOCGRAWPHYS = 0x80404805
_HIDIOCGRAWUNIQ = 0x80404808
+2 -2
View File
@@ -109,8 +109,6 @@ const (
IUCLC = 0x200
IXOFF = 0x1000
IXON = 0x400
LASX_CTX_MAGIC = 0x41535801
LSX_CTX_MAGIC = 0x53580001
MAP_ANON = 0x20
MAP_ANONYMOUS = 0x20
MAP_DENYWRITE = 0x800
@@ -319,6 +317,7 @@ const (
SO_RCVBUF = 0x8
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x12
SO_RCVMARK = 0x4b
SO_RCVTIMEO = 0x14
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x14
@@ -343,6 +342,7 @@ const (
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TXREHASH = 0x4a
SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_WIFI_STATUS = 0x29
+2
View File
@@ -326,6 +326,7 @@ const (
SO_RCVBUF = 0x1002
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x1004
SO_RCVMARK = 0x4b
SO_RCVTIMEO = 0x1006
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x1006
@@ -351,6 +352,7 @@ const (
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TXREHASH = 0x4a
SO_TXTIME = 0x3d
SO_TYPE = 0x1008
SO_WIFI_STATUS = 0x29
+2
View File
@@ -326,6 +326,7 @@ const (
SO_RCVBUF = 0x1002
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x1004
SO_RCVMARK = 0x4b
SO_RCVTIMEO = 0x1006
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x1006
@@ -351,6 +352,7 @@ const (
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TXREHASH = 0x4a
SO_TXTIME = 0x3d
SO_TYPE = 0x1008
SO_WIFI_STATUS = 0x29
+2
View File
@@ -326,6 +326,7 @@ const (
SO_RCVBUF = 0x1002
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x1004
SO_RCVMARK = 0x4b
SO_RCVTIMEO = 0x1006
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x1006
@@ -351,6 +352,7 @@ const (
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TXREHASH = 0x4a
SO_TXTIME = 0x3d
SO_TYPE = 0x1008
SO_WIFI_STATUS = 0x29
+2
View File
@@ -326,6 +326,7 @@ const (
SO_RCVBUF = 0x1002
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x1004
SO_RCVMARK = 0x4b
SO_RCVTIMEO = 0x1006
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x1006
@@ -351,6 +352,7 @@ const (
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TXREHASH = 0x4a
SO_TXTIME = 0x3d
SO_TYPE = 0x1008
SO_WIFI_STATUS = 0x29
+2
View File
@@ -381,6 +381,7 @@ const (
SO_RCVBUF = 0x8
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x10
SO_RCVMARK = 0x4b
SO_RCVTIMEO = 0x12
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x12
@@ -405,6 +406,7 @@ const (
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TXREHASH = 0x4a
SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_WIFI_STATUS = 0x29
+2
View File
@@ -385,6 +385,7 @@ const (
SO_RCVBUF = 0x8
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x10
SO_RCVMARK = 0x4b
SO_RCVTIMEO = 0x12
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x12
@@ -409,6 +410,7 @@ const (
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TXREHASH = 0x4a
SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_WIFI_STATUS = 0x29
+2
View File
@@ -385,6 +385,7 @@ const (
SO_RCVBUF = 0x8
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x10
SO_RCVMARK = 0x4b
SO_RCVTIMEO = 0x12
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x12
@@ -409,6 +410,7 @@ const (
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TXREHASH = 0x4a
SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_WIFI_STATUS = 0x29
+2
View File
@@ -314,6 +314,7 @@ const (
SO_RCVBUF = 0x8
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x12
SO_RCVMARK = 0x4b
SO_RCVTIMEO = 0x14
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x14
@@ -338,6 +339,7 @@ const (
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TXREHASH = 0x4a
SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_WIFI_STATUS = 0x29

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