updated go-aptproxy (migrate tool, dependencies, cache control)

This commit is contained in:
Paul 2022-09-22 21:02:34 +02:00
parent 68ce22a4f0
commit 57fb26f9b8
286 changed files with 32837 additions and 4908 deletions

View File

@ -20,12 +20,13 @@ func main() {
host = flag.String("host", "0.0.0.0", "`host` to listen on") host = flag.String("host", "0.0.0.0", "`host` to listen on")
port = flag.Int("port", 8000, "`port` to listen on") port = flag.Int("port", 8000, "`port` to listen on")
directory = flag.String("directory", "/var/cache/go-aptproxy", "`directory` used for storing packages") directory = flag.String("directory", "/var/cache/go-aptproxy", "`directory` used for storing packages")
migrate = flag.Bool("migrate", false, "`migrate` applies operations to be done on go-aptproxy update")
) )
flag.Parse() flag.Parse()
// Create the HTTP server and initialize the cache // Create the HTTP server and initialize the cache
addr := fmt.Sprintf("%s:%d", *host, *port) addr := fmt.Sprintf("%s:%d", *host, *port)
httpServer, err := server.NewServer(addr, *directory) httpServer, err := server.NewServer(addr, *directory, *migrate)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
os.Exit(1) os.Exit(1)

15
go.mod
View File

@ -1,16 +1,19 @@
module github.com/paulbsd/go-aptproxy module github.com/paulbsd/go-aptproxy
go 1.17 go 1.19
require ( require (
github.com/fsnotify/fsnotify v1.5.1 github.com/fsnotify/fsnotify v1.5.4
github.com/hashicorp/mdns v1.0.4 github.com/hashicorp/mdns v1.0.5
github.com/hectane/go-asyncserver v0.1.0 github.com/hectane/go-asyncserver v0.1.0
github.com/pquerna/cachecontrol v0.1.0 github.com/pquerna/cachecontrol v0.1.0
) )
require ( require (
github.com/miekg/dns v1.1.43 // indirect github.com/miekg/dns v1.1.50 // indirect
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9 // indirect golang.org/x/mod v0.4.2 // indirect
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 // indirect golang.org/x/net v0.0.0-20220909164309-bea034e7d591 // indirect
golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2 // indirect
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
) )

46
go.sum
View File

@ -1,14 +1,14 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
github.com/hashicorp/mdns v1.0.4 h1:sY0CMhFmjIPDMlTB+HfymFHCaYLhgifZ0QhjaYKD/UQ= github.com/hashicorp/mdns v1.0.5 h1:1M5hW1cunYeoXOqHwEb/GBDDHAFo0Yqb/uz/beC6LbE=
github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/mdns v1.0.5/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
github.com/hectane/go-asyncserver v0.1.0 h1:miQMVjLchB0fklo4nKoUp3votMOCSJhddVlPSmyiieM= github.com/hectane/go-asyncserver v0.1.0 h1:miQMVjLchB0fklo4nKoUp3votMOCSJhddVlPSmyiieM=
github.com/hectane/go-asyncserver v0.1.0/go.mod h1:waBaOSU0nKsRCHYMISp/+MSakn6C5HyDSF3y0NUknu0= github.com/hectane/go-asyncserver v0.1.0/go.mod h1:waBaOSU0nKsRCHYMISp/+MSakn6C5HyDSF3y0NUknu0=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg= github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc= github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc=
@ -16,27 +16,45 @@ github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQ
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= 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.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 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-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220909164309-bea034e7d591 h1:D0B/7al0LLrVC8aWF4+oxpv/m8bc7ViFfVS8/gXGdqI=
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9 h1:0qxwC5n+ttVOINCBeRHO0nq9X7uy8SDsPoi5OaCdIEI= golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c h1:DHcbWVXeY+0Y8HHKR+rbLwnoh2F4tNCY7rTiHJ30RmA= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2 h1:wM1k/lXfpc5HdkJJyW9GELpd8ERGdnh8sMGL6Gzq3Ho=
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 h1:TyHqChC80pFkXWraUUf6RuB5IqFdQieMLwwCJokV2pc= golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/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-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 h1:BonxutuHCTL0rBDnZlKjpGIQFTjyUVTexFOdWkB6Fg0=
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
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-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 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.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

54
src/cache/cache.go vendored
View File

@ -5,13 +5,16 @@ import (
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"log" "log"
"mime" "mime"
"net/http" "net/http"
"net/url"
"os" "os"
"path" "path"
"regexp" "regexp"
"strconv" "strconv"
"strings"
"sync" "sync"
"time" "time"
) )
@ -44,6 +47,16 @@ func NewCache(directory string) (*Cache, error) {
}, nil }, nil
} }
// getFilenames returns the filenames for the JSON and data files from a URL.
func getRelURL(rawurl string) (relurl string) {
parsed, err := url.Parse(rawurl)
if err != nil {
return
}
relurl = parsed.Path
return
}
// getFilenames returns the filenames for the JSON and data files from a URL. // getFilenames returns the filenames for the JSON and data files from a URL.
func (c *Cache) getFilenames(rawurl string) (hash, jsonFilename, dataFilename string) { func (c *Cache) getFilenames(rawurl string) (hash, jsonFilename, dataFilename string) {
b := md5.Sum([]byte(rawurl)) b := md5.Sum([]byte(rawurl))
@ -58,7 +71,8 @@ func (c *Cache) getFilenames(rawurl string) (hash, jsonFilename, dataFilename st
// If the URL exists in the cache, it is read using the standard file API. If // If the URL exists in the cache, it is read using the standard file API. If
// not, a downloader and live reader are created. // not, a downloader and live reader are created.
func (c *Cache) GetReader(rawurl string, maxAge time.Duration) (Reader, error) { func (c *Cache) GetReader(rawurl string, maxAge time.Duration) (Reader, error) {
hash, jsonFilename, dataFilename := c.getFilenames(rawurl) relurl := getRelURL(rawurl)
hash, jsonFilename, dataFilename := c.getFilenames(relurl)
c.mutex.Lock() c.mutex.Lock()
defer c.mutex.Unlock() defer c.mutex.Unlock()
d, ok := c.downloaders[hash] d, ok := c.downloaders[hash]
@ -100,7 +114,8 @@ func (c *Cache) GetReader(rawurl string, maxAge time.Duration) (Reader, error) {
// Insert adds an item into the cache. // Insert adds an item into the cache.
func (c *Cache) Insert(rawurl string, r io.Reader) error { func (c *Cache) Insert(rawurl string, r io.Reader) error {
_, jsonFilename, dataFilename := c.getFilenames(rawurl) relurl := getRelURL(rawurl)
_, jsonFilename, dataFilename := c.getFilenames(relurl)
f, err := os.Open(dataFilename) f, err := os.Open(dataFilename)
if err != nil { if err != nil {
return err return err
@ -112,10 +127,12 @@ func (c *Cache) Insert(rawurl string, r io.Reader) error {
} }
e := &Entry{ e := &Entry{
URL: rawurl, URL: rawurl,
RelURL: relurl,
Complete: true, Complete: true,
ContentLength: strconv.FormatInt(n, 10), ContentLength: strconv.FormatInt(n, 10),
ContentType: mime.TypeByExtension(rawurl), ContentType: mime.TypeByExtension(rawurl),
LastModified: time.Now().Format(http.TimeFormat), LastModified: time.Now().Format(http.TimeFormat),
LastAccessed: time.Now().Format(http.TimeFormat),
} }
return e.Save(jsonFilename) return e.Save(jsonFilename)
} }
@ -127,3 +144,36 @@ func (c *Cache) Insert(rawurl string, r io.Reader) error {
func (c *Cache) Close() { func (c *Cache) Close() {
c.waitGroup.Wait() c.waitGroup.Wait()
} }
func (c *Cache) Migrate(pathname *string) (err error) {
files, err := ioutil.ReadDir(*pathname)
for _, f := range files {
if strings.HasSuffix(f.Name(), ".json") {
basename := strings.Split(f.Name(), ".")[0]
jsonfile := fmt.Sprintf("%s/%s.json", *pathname, basename)
datafile := fmt.Sprintf("%s/%s.data", *pathname, basename)
newDiskReader(jsonfile, datafile)
e := Entry{}
err = e.Load(jsonfile)
if err != nil {
log.Println(err)
continue
}
relurl := getRelURL(e.URL)
_, newjsonfile, newdatafile := c.getFilenames(relurl)
err = os.Rename(jsonfile, newjsonfile)
if err != nil {
log.Println(err)
continue
}
err = os.Rename(datafile, newdatafile)
if err != nil {
log.Println(err)
continue
}
}
}
return
}

View File

@ -1,6 +1,8 @@
package cache package cache
import ( import (
"fmt"
"net/http"
"os" "os"
) )
@ -15,12 +17,22 @@ type diskReader struct {
func newDiskReader(jsonFilename, dataFilename string) (*diskReader, error) { func newDiskReader(jsonFilename, dataFilename string) (*diskReader, error) {
e := &Entry{} e := &Entry{}
if err := e.Load(jsonFilename); err != nil { if err := e.Load(jsonFilename); err != nil {
fmt.Println(err)
return nil, err return nil, err
} }
f, err := os.Open(dataFilename) f, err := os.Open(dataFilename)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if e.LastAccessed == "" {
stat, _ := f.Stat()
e.LastAccessed = stat.ModTime().Format(http.TimeFormat)
e.Save(jsonFilename)
}
if e.RelURL == "" {
e.RelURL = getRelURL(e.URL)
e.Save(jsonFilename)
}
return &diskReader{ return &diskReader{
entry: e, entry: e,
file: f, file: f,

View File

@ -61,17 +61,21 @@ func newDownloader(rawurl, jsonFilename, dataFilename string) *downloader {
return return
} }
defer f.Close() defer f.Close()
relurl := getRelURL(rawurl)
d.entry = &Entry{ d.entry = &Entry{
URL: rawurl, URL: rawurl,
RelURL: relurl,
ContentLength: strconv.FormatInt(resp.ContentLength, 10), ContentLength: strconv.FormatInt(resp.ContentLength, 10),
ContentType: resp.Header.Get("Content-Type"), ContentType: resp.Header.Get("Content-Type"),
LastModified: resp.Header.Get("Last-Modified"), LastModified: resp.Header.Get("Last-Modified"),
LastAccessed: resp.Header.Get("Last-Modified"),
} }
if d.entry.ContentType == "" { if d.entry.ContentType == "" {
d.entry.ContentType = "application/octet-stream" d.entry.ContentType = "application/octet-stream"
} }
if d.entry.LastModified == "" { if d.entry.LastModified == "" || d.entry.LastAccessed == "" {
d.entry.LastModified = time.Now().Format(http.TimeFormat) d.entry.LastModified = time.Now().Format(http.TimeFormat)
d.entry.LastAccessed = time.Now().Format(http.TimeFormat)
} }
if err = d.entry.Save(jsonFilename); err != nil { if err = d.entry.Save(jsonFilename); err != nil {
d.err = err d.err = err

2
src/cache/entry.go vendored
View File

@ -8,10 +8,12 @@ import (
// Entry represents an individual item in the cache. // Entry represents an individual item in the cache.
type Entry struct { type Entry struct {
URL string `json:"url"` URL string `json:"url"`
RelURL string `json:"rel_url"`
Complete bool `json:"complete"` Complete bool `json:"complete"`
ContentLength string `json:"content_length"` ContentLength string `json:"content_length"`
ContentType string `json:"content_type"` ContentType string `json:"content_type"`
LastModified string `json:"last_modified"` LastModified string `json:"last_modified"`
LastAccessed string `json:"last_accessed"`
} }
// Load reads the entry from disk. // Load reads the entry from disk.

View File

@ -89,11 +89,17 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
} }
// NewServer creates a new server. // NewServer creates a new server.
func NewServer(addr, directory string) (*Server, error) { func NewServer(addr, directory string, migrate bool) (*Server, error) {
c, err := cache.NewCache(directory) c, err := cache.NewCache(directory)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Upgrade current database
if migrate {
c.Migrate(&directory)
}
s := &Server{ s := &Server{
server: server.New(addr), server: server.New(addr),
cache: c, cache: c,

View File

@ -7,9 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [1.5.4] - 2022-04-25
* Windows: add missing defer to `Watcher.WatchList` [#447](https://github.com/fsnotify/fsnotify/pull/447)
* go.mod: use latest x/sys [#444](https://github.com/fsnotify/fsnotify/pull/444)
* Fix compilation for OpenBSD [#443](https://github.com/fsnotify/fsnotify/pull/443)
## [1.5.3] - 2022-04-22
* This version is retracted. An incorrect branch is published accidentally [#445](https://github.com/fsnotify/fsnotify/issues/445)
## [1.5.2] - 2022-04-21
* Add a feature to return the directories and files that are being monitored [#374](https://github.com/fsnotify/fsnotify/pull/374)
* Fix potential crash on windows if `raw.FileNameLength` exceeds `syscall.MAX_PATH` [#361](https://github.com/fsnotify/fsnotify/pull/361)
* Allow build on unsupported GOOS [#424](https://github.com/fsnotify/fsnotify/pull/424)
* Don't set `poller.fd` twice in `newFdPoller` [#406](https://github.com/fsnotify/fsnotify/pull/406)
* fix go vet warnings: call to `(*T).Fatalf` from a non-test goroutine [#416](https://github.com/fsnotify/fsnotify/pull/416)
## [1.5.1] - 2021-08-24 ## [1.5.1] - 2021-08-24
* Revert Add AddRaw to not follow symlinks * Revert Add AddRaw to not follow symlinks [#394](https://github.com/fsnotify/fsnotify/pull/394)
## [1.5.0] - 2021-08-20 ## [1.5.0] - 2021-08-20

View File

@ -48,18 +48,6 @@ fsnotify uses build tags to compile different code on Linux, BSD, macOS, and Win
Before doing a pull request, please do your best to test your changes on multiple platforms, and list which platforms you were able/unable to test on. Before doing a pull request, please do your best to test your changes on multiple platforms, and list which platforms you were able/unable to test on.
To aid in cross-platform testing there is a Vagrantfile for Linux and BSD.
* Install [Vagrant](http://www.vagrantup.com/) and [VirtualBox](https://www.virtualbox.org/)
* Setup [Vagrant Gopher](https://github.com/nathany/vagrant-gopher) in your `src` folder.
* Run `vagrant up` from the project folder. You can also setup just one box with `vagrant up linux` or `vagrant up bsd` (note: the BSD box doesn't support Windows hosts at this time, and NFS may prompt for your host OS password)
* Once setup, you can run the test suite on a given OS with a single command `vagrant ssh linux -c 'cd fsnotify/fsnotify; go test'`.
* When you're done, you will want to halt or destroy the Vagrant boxes.
Notice: fsnotify file system events won't trigger in shared folders. The tests get around this limitation by using the /tmp directory.
Right now there is no equivalent solution for Windows and macOS, but there are Windows VMs [freely available from Microsoft](http://www.modern.ie/en-us/virtualization-tools#downloads).
### Maintainers ### Maintainers
Help maintaining fsnotify is welcome. To be a maintainer: Help maintaining fsnotify is welcome. To be a maintainer:
@ -67,11 +55,6 @@ Help maintaining fsnotify is welcome. To be a maintainer:
* Submit a pull request and sign the CLA as above. * Submit a pull request and sign the CLA as above.
* You must be able to run the test suite on Mac, Windows, Linux and BSD. * You must be able to run the test suite on Mac, Windows, Linux and BSD.
To keep master clean, the fsnotify project uses the "apply mail" workflow outlined in Nathaniel Talbott's post ["Merge pull request" Considered Harmful][am]. This requires installing [hub][].
All code changes should be internal pull requests. All code changes should be internal pull requests.
Releases are tagged using [Semantic Versioning](http://semver.org/). Releases are tagged using [Semantic Versioning](http://semver.org/).
[hub]: https://github.com/github/hub
[am]: http://blog.spreedly.com/2014/06/24/merge-pull-request-considered-harmful/#.VGa5yZPF_Zs

View File

@ -1,12 +1,8 @@
# File system notifications for Go # File system notifications for Go
[![GoDoc](https://godoc.org/github.com/fsnotify/fsnotify?status.svg)](https://godoc.org/github.com/fsnotify/fsnotify) [![Go Report Card](https://goreportcard.com/badge/github.com/fsnotify/fsnotify)](https://goreportcard.com/report/github.com/fsnotify/fsnotify) [![Go Reference](https://pkg.go.dev/badge/github.com/fsnotify/fsnotify.svg)](https://pkg.go.dev/github.com/fsnotify/fsnotify) [![Go Report Card](https://goreportcard.com/badge/github.com/fsnotify/fsnotify)](https://goreportcard.com/report/github.com/fsnotify/fsnotify) [![Maintainers Wanted](https://img.shields.io/badge/maintainers-wanted-red.svg)](https://github.com/fsnotify/fsnotify/issues/413)
fsnotify utilizes [golang.org/x/sys](https://godoc.org/golang.org/x/sys) rather than `syscall` from the standard library. Ensure you have the latest version installed by running: fsnotify utilizes [`golang.org/x/sys`](https://pkg.go.dev/golang.org/x/sys) rather than [`syscall`](https://pkg.go.dev/syscall) from the standard library.
```console
go get -u golang.org/x/sys/...
```
Cross platform: Windows, Linux, BSD and macOS. Cross platform: Windows, Linux, BSD and macOS.
@ -16,22 +12,20 @@ Cross platform: Windows, Linux, BSD and macOS.
| kqueue | BSD, macOS, iOS\* | Supported | | kqueue | BSD, macOS, iOS\* | Supported |
| ReadDirectoryChangesW | Windows | Supported | | ReadDirectoryChangesW | Windows | Supported |
| FSEvents | macOS | [Planned](https://github.com/fsnotify/fsnotify/issues/11) | | FSEvents | macOS | [Planned](https://github.com/fsnotify/fsnotify/issues/11) |
| FEN | Solaris 11 | [In Progress](https://github.com/fsnotify/fsnotify/issues/12) | | FEN | Solaris 11 | [In Progress](https://github.com/fsnotify/fsnotify/pull/371) |
| fanotify | Linux 2.6.37+ | [Planned](https://github.com/fsnotify/fsnotify/issues/114) | | fanotify | Linux 2.6.37+ | [Maybe](https://github.com/fsnotify/fsnotify/issues/114) |
| USN Journals | Windows | [Maybe](https://github.com/fsnotify/fsnotify/issues/53) | | USN Journals | Windows | [Maybe](https://github.com/fsnotify/fsnotify/issues/53) |
| Polling | *All* | [Maybe](https://github.com/fsnotify/fsnotify/issues/9) | | Polling | *All* | [Maybe](https://github.com/fsnotify/fsnotify/issues/9) |
\* Android and iOS are untested. \* Android and iOS are untested.
Please see [the documentation](https://godoc.org/github.com/fsnotify/fsnotify) and consult the [FAQ](#faq) for usage information. Please see [the documentation](https://pkg.go.dev/github.com/fsnotify/fsnotify) and consult the [FAQ](#faq) for usage information.
## API stability ## API stability
fsnotify is a fork of [howeyc/fsnotify](https://godoc.org/github.com/howeyc/fsnotify) with a new API as of v1.0. The API is based on [this design document](http://goo.gl/MrYxyA). fsnotify is a fork of [howeyc/fsnotify](https://github.com/howeyc/fsnotify) with a new API as of v1.0. The API is based on [this design document](http://goo.gl/MrYxyA).
All [releases](https://github.com/fsnotify/fsnotify/releases) are tagged based on [Semantic Versioning](http://semver.org/). Further API changes are [planned](https://github.com/fsnotify/fsnotify/milestones), and will be tagged with a new major revision number. All [releases](https://github.com/fsnotify/fsnotify/releases) are tagged based on [Semantic Versioning](http://semver.org/).
Go 1.6 supports dependencies located in the `vendor/` folder. Unless you are creating a library, it is recommended that you copy fsnotify into `vendor/github.com/fsnotify/fsnotify` within your project, and likewise for `golang.org/x/sys`.
## Usage ## Usage
@ -84,10 +78,6 @@ func main() {
Please refer to [CONTRIBUTING][] before opening an issue or pull request. Please refer to [CONTRIBUTING][] before opening an issue or pull request.
## Example
See [example_test.go](https://github.com/fsnotify/fsnotify/blob/master/example_test.go).
## FAQ ## FAQ
**When a file is moved to another directory is it still being watched?** **When a file is moved to another directory is it still being watched?**

View File

@ -0,0 +1,36 @@
// 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 !darwin && !dragonfly && !freebsd && !openbsd && !linux && !netbsd && !solaris && !windows
// +build !darwin,!dragonfly,!freebsd,!openbsd,!linux,!netbsd,!solaris,!windows
package fsnotify
import (
"fmt"
"runtime"
)
// Watcher watches a set of files, delivering events to a channel.
type Watcher struct{}
// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events.
func NewWatcher() (*Watcher, error) {
return nil, fmt.Errorf("fsnotify not supported on %s", runtime.GOOS)
}
// Close removes all watches and closes the events channel.
func (w *Watcher) Close() error {
return nil
}
// Add starts watching the named file or directory (non-recursively).
func (w *Watcher) Add(name string) error {
return nil
}
// Remove stops watching the the named file or directory (non-recursively).
func (w *Watcher) Remove(name string) error {
return nil
}

View File

@ -163,6 +163,19 @@ func (w *Watcher) Remove(name string) error {
return nil return nil
} }
// WatchList returns the directories and files that are being monitered.
func (w *Watcher) WatchList() []string {
w.mu.Lock()
defer w.mu.Unlock()
entries := make([]string, 0, len(w.watches))
for pathname := range w.watches {
entries = append(entries, pathname)
}
return entries
}
type watch struct { type watch struct {
wd uint32 // Watch descriptor (as returned by the inotify_add_watch() syscall) wd uint32 // Watch descriptor (as returned by the inotify_add_watch() syscall)
flags uint32 // inotify flags of this watch (see inotify(7) for the list of valid flags) flags uint32 // inotify flags of this watch (see inotify(7) for the list of valid flags)

View File

@ -38,7 +38,6 @@ func newFdPoller(fd int) (*fdPoller, error) {
poller.close() poller.close()
} }
}() }()
poller.fd = fd
// Create epoll fd // Create epoll fd
poller.epfd, errno = unix.EpollCreate1(unix.EPOLL_CLOEXEC) poller.epfd, errno = unix.EpollCreate1(unix.EPOLL_CLOEXEC)

View File

@ -148,6 +148,19 @@ func (w *Watcher) Remove(name string) error {
return nil return nil
} }
// WatchList returns the directories and files that are being monitered.
func (w *Watcher) WatchList() []string {
w.mu.Lock()
defer w.mu.Unlock()
entries := make([]string, 0, len(w.watches))
for pathname := range w.watches {
entries = append(entries, pathname)
}
return entries
}
// Watch all events (except NOTE_EXTEND, NOTE_LINK, NOTE_REVOKE) // Watch all events (except NOTE_EXTEND, NOTE_LINK, NOTE_REVOKE)
const noteAllEvents = unix.NOTE_DELETE | unix.NOTE_WRITE | unix.NOTE_ATTRIB | unix.NOTE_RENAME const noteAllEvents = unix.NOTE_DELETE | unix.NOTE_WRITE | unix.NOTE_ATTRIB | unix.NOTE_RENAME

View File

@ -12,6 +12,7 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"reflect"
"runtime" "runtime"
"sync" "sync"
"syscall" "syscall"
@ -96,6 +97,21 @@ func (w *Watcher) Remove(name string) error {
return <-in.reply return <-in.reply
} }
// WatchList returns the directories and files that are being monitered.
func (w *Watcher) WatchList() []string {
w.mu.Lock()
defer w.mu.Unlock()
entries := make([]string, 0, len(w.watches))
for _, entry := range w.watches {
for _, watchEntry := range entry {
entries = append(entries, watchEntry.path)
}
}
return entries
}
const ( const (
// Options for AddWatch // Options for AddWatch
sysFSONESHOT = 0x80000000 sysFSONESHOT = 0x80000000
@ -452,8 +468,16 @@ func (w *Watcher) readEvents() {
// Point "raw" to the event in the buffer // Point "raw" to the event in the buffer
raw := (*syscall.FileNotifyInformation)(unsafe.Pointer(&watch.buf[offset])) raw := (*syscall.FileNotifyInformation)(unsafe.Pointer(&watch.buf[offset]))
buf := (*[syscall.MAX_PATH]uint16)(unsafe.Pointer(&raw.FileName)) // TODO: Consider using unsafe.Slice that is available from go1.17
name := syscall.UTF16ToString(buf[:raw.FileNameLength/2]) // https://stackoverflow.com/questions/51187973/how-to-create-an-array-or-a-slice-from-an-array-unsafe-pointer-in-golang
// instead of using a fixed syscall.MAX_PATH buf, we create a buf that is the size of the path name
size := int(raw.FileNameLength / 2)
var buf []uint16
sh := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
sh.Data = uintptr(unsafe.Pointer(&raw.FileName))
sh.Len = size
sh.Cap = size
name := syscall.UTF16ToString(buf)
fullname := filepath.Join(watch.path, name) fullname := filepath.Join(watch.path, name)
var mask uint64 var mask uint64

View File

@ -42,6 +42,8 @@ type QueryParam struct {
Interface *net.Interface // Multicast interface to use Interface *net.Interface // Multicast interface to use
Entries chan<- *ServiceEntry // Entries Channel Entries chan<- *ServiceEntry // Entries Channel
WantUnicastResponse bool // Unicast response desired, as per 5.4 in RFC WantUnicastResponse bool // Unicast response desired, as per 5.4 in RFC
DisableIPv4 bool // Whether to disable usage of IPv4 for MDNS operations. Does not affect discovered addresses.
DisableIPv6 bool // Whether to disable usage of IPv6 for MDNS operations. Does not affect discovered addresses.
} }
// DefaultParams is used to return a default set of QueryParam's // DefaultParams is used to return a default set of QueryParam's
@ -52,6 +54,8 @@ func DefaultParams(service string) *QueryParam {
Timeout: time.Second, Timeout: time.Second,
Entries: make(chan *ServiceEntry), Entries: make(chan *ServiceEntry),
WantUnicastResponse: false, // TODO(reddaly): Change this default. WantUnicastResponse: false, // TODO(reddaly): Change this default.
DisableIPv4: false,
DisableIPv6: false,
} }
} }
@ -61,7 +65,7 @@ func DefaultParams(service string) *QueryParam {
// either read or buffer. // either read or buffer.
func Query(params *QueryParam) error { func Query(params *QueryParam) error {
// Create a new client // Create a new client
client, err := newClient() client, err := newClient(!params.DisableIPv4, !params.DisableIPv6)
if err != nil { if err != nil {
return err return err
} }
@ -96,6 +100,9 @@ func Lookup(service string, entries chan<- *ServiceEntry) error {
// Client provides a query interface that can be used to // Client provides a query interface that can be used to
// search for service providers using mDNS // search for service providers using mDNS
type client struct { type client struct {
use_ipv4 bool
use_ipv6 bool
ipv4UnicastConn *net.UDPConn ipv4UnicastConn *net.UDPConn
ipv6UnicastConn *net.UDPConn ipv6UnicastConn *net.UDPConn
@ -108,29 +115,48 @@ type client struct {
// NewClient creates a new mdns Client that can be used to query // NewClient creates a new mdns Client that can be used to query
// for records // for records
func newClient() (*client, error) { func newClient(v4 bool, v6 bool) (*client, error) {
if !v4 && !v6 {
return nil, fmt.Errorf("Must enable at least one of IPv4 and IPv6 querying")
}
// TODO(reddaly): At least attempt to bind to the port required in the spec. // TODO(reddaly): At least attempt to bind to the port required in the spec.
// Create a IPv4 listener // Create a IPv4 listener
uconn4, err := net.ListenUDP("udp4", &net.UDPAddr{IP: net.IPv4zero, Port: 0}) var uconn4 *net.UDPConn
if err != nil { var uconn6 *net.UDPConn
log.Printf("[ERR] mdns: Failed to bind to udp4 port: %v", err) var mconn4 *net.UDPConn
var mconn6 *net.UDPConn
var err error
if v4 {
uconn4, err = net.ListenUDP("udp4", &net.UDPAddr{IP: net.IPv4zero, Port: 0})
if err != nil {
log.Printf("[ERR] mdns: Failed to bind to udp4 port: %v", err)
}
} }
uconn6, err := net.ListenUDP("udp6", &net.UDPAddr{IP: net.IPv6zero, Port: 0})
if err != nil { if v6 {
log.Printf("[ERR] mdns: Failed to bind to udp6 port: %v", err) uconn6, err = net.ListenUDP("udp6", &net.UDPAddr{IP: net.IPv6zero, Port: 0})
if err != nil {
log.Printf("[ERR] mdns: Failed to bind to udp6 port: %v", err)
}
} }
if uconn4 == nil && uconn6 == nil { if uconn4 == nil && uconn6 == nil {
return nil, fmt.Errorf("failed to bind to any unicast udp port") return nil, fmt.Errorf("failed to bind to any unicast udp port")
} }
mconn4, err := net.ListenMulticastUDP("udp4", nil, ipv4Addr) if v4 {
if err != nil { mconn4, err = net.ListenMulticastUDP("udp4", nil, ipv4Addr)
log.Printf("[ERR] mdns: Failed to bind to udp4 port: %v", err) if err != nil {
log.Printf("[ERR] mdns: Failed to bind to udp4 port: %v", err)
}
} }
mconn6, err := net.ListenMulticastUDP("udp6", nil, ipv6Addr) if v6 {
if err != nil { mconn6, err = net.ListenMulticastUDP("udp6", nil, ipv6Addr)
log.Printf("[ERR] mdns: Failed to bind to udp6 port: %v", err) if err != nil {
log.Printf("[ERR] mdns: Failed to bind to udp6 port: %v", err)
}
} }
if mconn4 == nil && mconn6 == nil { if mconn4 == nil && mconn6 == nil {
@ -138,6 +164,8 @@ func newClient() (*client, error) {
} }
c := &client{ c := &client{
use_ipv4: v4,
use_ipv6: v6,
ipv4MulticastConn: mconn4, ipv4MulticastConn: mconn4,
ipv6MulticastConn: mconn6, ipv6MulticastConn: mconn6,
ipv4UnicastConn: uconn4, ipv4UnicastConn: uconn4,
@ -176,21 +204,25 @@ func (c *client) Close() error {
// setInterface is used to set the query interface, uses system // setInterface is used to set the query interface, uses system
// default if not provided // default if not provided
func (c *client) setInterface(iface *net.Interface) error { func (c *client) setInterface(iface *net.Interface) error {
p := ipv4.NewPacketConn(c.ipv4UnicastConn) if c.use_ipv4 {
if err := p.SetMulticastInterface(iface); err != nil { p := ipv4.NewPacketConn(c.ipv4UnicastConn)
return err if err := p.SetMulticastInterface(iface); err != nil {
return err
}
p = ipv4.NewPacketConn(c.ipv4MulticastConn)
if err := p.SetMulticastInterface(iface); err != nil {
return err
}
} }
p2 := ipv6.NewPacketConn(c.ipv6UnicastConn) if c.use_ipv6 {
if err := p2.SetMulticastInterface(iface); err != nil { p2 := ipv6.NewPacketConn(c.ipv6UnicastConn)
return err if err := p2.SetMulticastInterface(iface); err != nil {
} return err
p = ipv4.NewPacketConn(c.ipv4MulticastConn) }
if err := p.SetMulticastInterface(iface); err != nil { p2 = ipv6.NewPacketConn(c.ipv6MulticastConn)
return err if err := p2.SetMulticastInterface(iface); err != nil {
} return err
p2 = ipv6.NewPacketConn(c.ipv6MulticastConn) }
if err := p2.SetMulticastInterface(iface); err != nil {
return err
} }
return nil return nil
} }
@ -202,10 +234,14 @@ func (c *client) query(params *QueryParam) error {
// Start listening for response packets // Start listening for response packets
msgCh := make(chan *dns.Msg, 32) msgCh := make(chan *dns.Msg, 32)
go c.recv(c.ipv4UnicastConn, msgCh) if c.use_ipv4 {
go c.recv(c.ipv6UnicastConn, msgCh) go c.recv(c.ipv4UnicastConn, msgCh)
go c.recv(c.ipv4MulticastConn, msgCh) go c.recv(c.ipv4MulticastConn, msgCh)
go c.recv(c.ipv6MulticastConn, msgCh) }
if c.use_ipv6 {
go c.recv(c.ipv6UnicastConn, msgCh)
go c.recv(c.ipv6MulticastConn, msgCh)
}
// Send the query // Send the query
m := new(dns.Msg) m := new(dns.Msg)

View File

@ -73,6 +73,10 @@ A not-so-up-to-date-list-that-may-be-actually-current:
* https://github.com/bodgit/tsig * https://github.com/bodgit/tsig
* https://github.com/v2fly/v2ray-core (test only) * https://github.com/v2fly/v2ray-core (test only)
* https://kuma.io/ * https://kuma.io/
* https://www.misaka.io/services/dns
* https://ping.sx/dig
* https://fleetdeck.io/
* https://github.com/markdingo/autoreverse
Send pull request if you want to be listed here. Send pull request if you want to be listed here.

View File

@ -12,7 +12,7 @@ type MsgAcceptFunc func(dh Header) MsgAcceptAction
// //
// * Zero bit isn't zero // * Zero bit isn't zero
// //
// * has more than 1 question in the question section // * does not have exactly 1 question in the question section
// //
// * has more than 1 RR in the Answer section // * has more than 1 RR in the Answer section
// //

127
vendor/github.com/miekg/dns/client.go generated vendored
View File

@ -18,6 +18,18 @@ const (
tcpIdleTimeout time.Duration = 8 * time.Second tcpIdleTimeout time.Duration = 8 * time.Second
) )
func isPacketConn(c net.Conn) bool {
if _, ok := c.(net.PacketConn); !ok {
return false
}
if ua, ok := c.LocalAddr().(*net.UnixAddr); ok {
return ua.Net == "unixgram" || ua.Net == "unixpacket"
}
return true
}
// A Conn represents a connection to a DNS server. // A Conn represents a connection to a DNS server.
type Conn struct { type Conn struct {
net.Conn // a net.Conn holding the connection net.Conn // a net.Conn holding the connection
@ -27,6 +39,14 @@ type Conn struct {
tsigRequestMAC string tsigRequestMAC string
} }
func (co *Conn) tsigProvider() TsigProvider {
if co.TsigProvider != nil {
return co.TsigProvider
}
// tsigSecretProvider will return ErrSecret if co.TsigSecret is nil.
return tsigSecretProvider(co.TsigSecret)
}
// A Client defines parameters for a DNS client. // A Client defines parameters for a DNS client.
type Client struct { type Client struct {
Net string // if "tcp" or "tcp-tls" (DNS over TLS) a TCP query will be initiated, otherwise an UDP one (default is "" for UDP) Net string // if "tcp" or "tcp-tls" (DNS over TLS) a TCP query will be initiated, otherwise an UDP one (default is "" for UDP)
@ -82,6 +102,12 @@ func (c *Client) writeTimeout() time.Duration {
// Dial connects to the address on the named network. // Dial connects to the address on the named network.
func (c *Client) Dial(address string) (conn *Conn, err error) { func (c *Client) Dial(address string) (conn *Conn, err error) {
return c.DialContext(context.Background(), address)
}
// DialContext connects to the address on the named network, with a context.Context.
// For TLS over TCP (DoT) the context isn't used yet. This will be enabled when Go 1.18 is released.
func (c *Client) DialContext(ctx context.Context, address string) (conn *Conn, err error) {
// create a new dialer with the appropriate timeout // create a new dialer with the appropriate timeout
var d net.Dialer var d net.Dialer
if c.Dialer == nil { if c.Dialer == nil {
@ -101,9 +127,17 @@ func (c *Client) Dial(address string) (conn *Conn, err error) {
if useTLS { if useTLS {
network = strings.TrimSuffix(network, "-tls") network = strings.TrimSuffix(network, "-tls")
// TODO(miekg): Enable after Go 1.18 is released, to be able to support two prev. releases.
/*
tlsDialer := tls.Dialer{
NetDialer: &d,
Config: c.TLSConfig,
}
conn.Conn, err = tlsDialer.DialContext(ctx, network, address)
*/
conn.Conn, err = tls.DialWithDialer(&d, network, address, c.TLSConfig) conn.Conn, err = tls.DialWithDialer(&d, network, address, c.TLSConfig)
} else { } else {
conn.Conn, err = d.Dial(network, address) conn.Conn, err = d.DialContext(ctx, network, address)
} }
if err != nil { if err != nil {
return nil, err return nil, err
@ -139,24 +173,34 @@ func (c *Client) Exchange(m *Msg, address string) (r *Msg, rtt time.Duration, er
// ExchangeWithConn has the same behavior as Exchange, just with a predetermined connection // ExchangeWithConn has the same behavior as Exchange, just with a predetermined connection
// that will be used instead of creating a new one. // that will be used instead of creating a new one.
// Usage pattern with a *dns.Client: // Usage pattern with a *dns.Client:
//
// c := new(dns.Client) // c := new(dns.Client)
// // connection management logic goes here // // connection management logic goes here
// //
// conn := c.Dial(address) // conn := c.Dial(address)
// in, rtt, err := c.ExchangeWithConn(message, conn) // in, rtt, err := c.ExchangeWithConn(message, conn)
// //
// This allows users of the library to implement their own connection management, // This allows users of the library to implement their own connection management,
// as opposed to Exchange, which will always use new connections and incur the added overhead // as opposed to Exchange, which will always use new connections and incur the added overhead
// that entails when using "tcp" and especially "tcp-tls" clients. // that entails when using "tcp" and especially "tcp-tls" clients.
//
// When the singleflight is set for this client the context is _not_ forwarded to the (shared) exchange, to
// prevent one cancelation from canceling all outstanding requests.
func (c *Client) ExchangeWithConn(m *Msg, conn *Conn) (r *Msg, rtt time.Duration, err error) { func (c *Client) ExchangeWithConn(m *Msg, conn *Conn) (r *Msg, rtt time.Duration, err error) {
return c.exchangeWithConnContext(context.Background(), m, conn)
}
func (c *Client) exchangeWithConnContext(ctx context.Context, m *Msg, conn *Conn) (r *Msg, rtt time.Duration, err error) {
if !c.SingleInflight { if !c.SingleInflight {
return c.exchange(m, conn) return c.exchangeContext(ctx, m, conn)
} }
q := m.Question[0] q := m.Question[0]
key := fmt.Sprintf("%s:%d:%d", q.Name, q.Qtype, q.Qclass) key := fmt.Sprintf("%s:%d:%d", q.Name, q.Qtype, q.Qclass)
r, rtt, err, shared := c.group.Do(key, func() (*Msg, time.Duration, error) { r, rtt, err, shared := c.group.Do(key, func() (*Msg, time.Duration, error) {
return c.exchange(m, conn) // When we're doing singleflight we don't want one context cancelation, cancel _all_ outstanding queries.
// Hence we ignore the context and use Background().
return c.exchangeContext(context.Background(), m, conn)
}) })
if r != nil && shared { if r != nil && shared {
r = r.Copy() r = r.Copy()
@ -165,8 +209,7 @@ func (c *Client) ExchangeWithConn(m *Msg, conn *Conn) (r *Msg, rtt time.Duration
return r, rtt, err return r, rtt, err
} }
func (c *Client) exchange(m *Msg, co *Conn) (r *Msg, rtt time.Duration, err error) { func (c *Client) exchangeContext(ctx context.Context, m *Msg, co *Conn) (r *Msg, rtt time.Duration, err error) {
opt := m.IsEdns0() opt := m.IsEdns0()
// If EDNS0 is used use that for size. // If EDNS0 is used use that for size.
if opt != nil && opt.UDPSize() >= MinMsgSize { if opt != nil && opt.UDPSize() >= MinMsgSize {
@ -177,16 +220,28 @@ func (c *Client) exchange(m *Msg, co *Conn) (r *Msg, rtt time.Duration, err erro
co.UDPSize = c.UDPSize co.UDPSize = c.UDPSize
} }
co.TsigSecret, co.TsigProvider = c.TsigSecret, c.TsigProvider
t := time.Now()
// write with the appropriate write timeout // write with the appropriate write timeout
co.SetWriteDeadline(t.Add(c.getTimeoutForRequest(c.writeTimeout()))) t := time.Now()
writeDeadline := t.Add(c.getTimeoutForRequest(c.writeTimeout()))
readDeadline := t.Add(c.getTimeoutForRequest(c.readTimeout()))
if deadline, ok := ctx.Deadline(); ok {
if deadline.Before(writeDeadline) {
writeDeadline = deadline
}
if deadline.Before(readDeadline) {
readDeadline = deadline
}
}
co.SetWriteDeadline(writeDeadline)
co.SetReadDeadline(readDeadline)
co.TsigSecret, co.TsigProvider = c.TsigSecret, c.TsigProvider
if err = co.WriteMsg(m); err != nil { if err = co.WriteMsg(m); err != nil {
return nil, 0, err return nil, 0, err
} }
co.SetReadDeadline(time.Now().Add(c.getTimeoutForRequest(c.readTimeout()))) if isPacketConn(co.Conn) {
if _, ok := co.Conn.(net.PacketConn); ok {
for { for {
r, err = co.ReadMsg() r, err = co.ReadMsg()
// Ignore replies with mismatched IDs because they might be // Ignore replies with mismatched IDs because they might be
@ -224,15 +279,8 @@ func (co *Conn) ReadMsg() (*Msg, error) {
return m, err return m, err
} }
if t := m.IsTsig(); t != nil { if t := m.IsTsig(); t != nil {
if co.TsigProvider != nil { // Need to work on the original message p, as that was used to calculate the tsig.
err = tsigVerifyProvider(p, co.TsigProvider, co.tsigRequestMAC, false) err = TsigVerifyWithProvider(p, co.tsigProvider(), co.tsigRequestMAC, false)
} else {
if _, ok := co.TsigSecret[t.Hdr.Name]; !ok {
return m, ErrSecret
}
// Need to work on the original message p, as that was used to calculate the tsig.
err = TsigVerify(p, co.TsigSecret[t.Hdr.Name], co.tsigRequestMAC, false)
}
} }
return m, err return m, err
} }
@ -247,7 +295,7 @@ func (co *Conn) ReadMsgHeader(hdr *Header) ([]byte, error) {
err error err error
) )
if _, ok := co.Conn.(net.PacketConn); ok { if isPacketConn(co.Conn) {
if co.UDPSize > MinMsgSize { if co.UDPSize > MinMsgSize {
p = make([]byte, co.UDPSize) p = make([]byte, co.UDPSize)
} else { } else {
@ -287,7 +335,7 @@ func (co *Conn) Read(p []byte) (n int, err error) {
return 0, ErrConnEmpty return 0, ErrConnEmpty
} }
if _, ok := co.Conn.(net.PacketConn); ok { if isPacketConn(co.Conn) {
// UDP connection // UDP connection
return co.Conn.Read(p) return co.Conn.Read(p)
} }
@ -309,17 +357,8 @@ func (co *Conn) Read(p []byte) (n int, err error) {
func (co *Conn) WriteMsg(m *Msg) (err error) { func (co *Conn) WriteMsg(m *Msg) (err error) {
var out []byte var out []byte
if t := m.IsTsig(); t != nil { if t := m.IsTsig(); t != nil {
mac := "" // Set tsigRequestMAC for the next read, although only used in zone transfers.
if co.TsigProvider != nil { out, co.tsigRequestMAC, err = TsigGenerateWithProvider(m, co.tsigProvider(), co.tsigRequestMAC, false)
out, mac, err = tsigGenerateProvider(m, co.TsigProvider, co.tsigRequestMAC, false)
} else {
if _, ok := co.TsigSecret[t.Hdr.Name]; !ok {
return ErrSecret
}
out, mac, err = TsigGenerate(m, co.TsigSecret[t.Hdr.Name], co.tsigRequestMAC, false)
}
// Set for the next read, although only used in zone transfers
co.tsigRequestMAC = mac
} else { } else {
out, err = m.Pack() out, err = m.Pack()
} }
@ -336,7 +375,7 @@ func (co *Conn) Write(p []byte) (int, error) {
return 0, &Error{err: "message too large"} return 0, &Error{err: "message too large"}
} }
if _, ok := co.Conn.(net.PacketConn); ok { if isPacketConn(co.Conn) {
return co.Conn.Write(p) return co.Conn.Write(p)
} }
@ -435,15 +474,11 @@ func DialTimeoutWithTLS(network, address string, tlsConfig *tls.Config, timeout
// context, if present. If there is both a context deadline and a configured // context, if present. If there is both a context deadline and a configured
// timeout on the client, the earliest of the two takes effect. // timeout on the client, the earliest of the two takes effect.
func (c *Client) ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, rtt time.Duration, err error) { func (c *Client) ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
var timeout time.Duration conn, err := c.DialContext(ctx, a)
if deadline, ok := ctx.Deadline(); !ok { if err != nil {
timeout = 0 return nil, 0, err
} else {
timeout = time.Until(deadline)
} }
// not passing the context to the underlying calls, as the API does not support defer conn.Close()
// context. For timeouts you should set up Client.Dialer and call Client.Exchange.
// TODO(tmthrgd,miekg): this is a race condition. return c.exchangeWithConnContext(ctx, m, conn)
c.Dialer = &net.Dialer{Timeout: timeout}
return c.Exchange(m, a)
} }

View File

@ -218,6 +218,11 @@ func IsDomainName(s string) (labels int, ok bool) {
wasDot = false wasDot = false
case '.': case '.':
if i == 0 && len(s) > 1 {
// leading dots are not legal except for the root zone
return labels, false
}
if wasDot { if wasDot {
// two dots back to back is not legal // two dots back to back is not legal
return labels, false return labels, false

View File

@ -65,6 +65,9 @@ var AlgorithmToString = map[uint8]string{
} }
// AlgorithmToHash is a map of algorithm crypto hash IDs to crypto.Hash's. // AlgorithmToHash is a map of algorithm crypto hash IDs to crypto.Hash's.
// For newer algorithm that do their own hashing (i.e. ED25519) the returned value
// is 0, implying no (external) hashing should occur. The non-exported identityHash is then
// used.
var AlgorithmToHash = map[uint8]crypto.Hash{ var AlgorithmToHash = map[uint8]crypto.Hash{
RSAMD5: crypto.MD5, // Deprecated in RFC 6725 RSAMD5: crypto.MD5, // Deprecated in RFC 6725
DSA: crypto.SHA1, DSA: crypto.SHA1,
@ -74,7 +77,7 @@ var AlgorithmToHash = map[uint8]crypto.Hash{
ECDSAP256SHA256: crypto.SHA256, ECDSAP256SHA256: crypto.SHA256,
ECDSAP384SHA384: crypto.SHA384, ECDSAP384SHA384: crypto.SHA384,
RSASHA512: crypto.SHA512, RSASHA512: crypto.SHA512,
ED25519: crypto.Hash(0), ED25519: 0,
} }
// DNSSEC hashing algorithm codes. // DNSSEC hashing algorithm codes.
@ -137,12 +140,12 @@ func (k *DNSKEY) KeyTag() uint16 {
var keytag int var keytag int
switch k.Algorithm { switch k.Algorithm {
case RSAMD5: case RSAMD5:
// Look at the bottom two bytes of the modules, which the last
// item in the pubkey.
// This algorithm has been deprecated, but keep this key-tag calculation. // This algorithm has been deprecated, but keep this key-tag calculation.
// Look at the bottom two bytes of the modules, which the last item in the pubkey.
// See https://www.rfc-editor.org/errata/eid193 .
modulus, _ := fromBase64([]byte(k.PublicKey)) modulus, _ := fromBase64([]byte(k.PublicKey))
if len(modulus) > 1 { if len(modulus) > 1 {
x := binary.BigEndian.Uint16(modulus[len(modulus)-2:]) x := binary.BigEndian.Uint16(modulus[len(modulus)-3:])
keytag = int(x) keytag = int(x)
} }
default: default:
@ -296,35 +299,20 @@ func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
return err return err
} }
hash, ok := AlgorithmToHash[rr.Algorithm] h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
if !ok { if err != nil {
return ErrAlg return err
} }
switch rr.Algorithm { switch rr.Algorithm {
case ED25519:
// ed25519 signs the raw message and performs hashing internally.
// All other supported signature schemes operate over the pre-hashed
// message, and thus ed25519 must be handled separately here.
//
// The raw message is passed directly into sign and crypto.Hash(0) is
// used to signal to the crypto.Signer that the data has not been hashed.
signature, err := sign(k, append(signdata, wire...), crypto.Hash(0), rr.Algorithm)
if err != nil {
return err
}
rr.Signature = toBase64(signature)
return nil
case RSAMD5, DSA, DSANSEC3SHA1: case RSAMD5, DSA, DSANSEC3SHA1:
// See RFC 6944. // See RFC 6944.
return ErrAlg return ErrAlg
default: default:
h := hash.New()
h.Write(signdata) h.Write(signdata)
h.Write(wire) h.Write(wire)
signature, err := sign(k, h.Sum(nil), hash, rr.Algorithm) signature, err := sign(k, h.Sum(nil), cryptohash, rr.Algorithm)
if err != nil { if err != nil {
return err return err
} }
@ -341,7 +329,7 @@ func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte,
} }
switch alg { switch alg {
case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512: case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512, ED25519:
return signature, nil return signature, nil
case ECDSAP256SHA256, ECDSAP384SHA384: case ECDSAP256SHA256, ECDSAP384SHA384:
ecdsaSignature := &struct { ecdsaSignature := &struct {
@ -362,8 +350,6 @@ func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte,
signature := intToBytes(ecdsaSignature.R, intlen) signature := intToBytes(ecdsaSignature.R, intlen)
signature = append(signature, intToBytes(ecdsaSignature.S, intlen)...) signature = append(signature, intToBytes(ecdsaSignature.S, intlen)...)
return signature, nil return signature, nil
case ED25519:
return signature, nil
default: default:
return nil, ErrAlg return nil, ErrAlg
} }
@ -437,9 +423,9 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
// remove the domain name and assume its ours? // remove the domain name and assume its ours?
} }
hash, ok := AlgorithmToHash[rr.Algorithm] h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
if !ok { if err != nil {
return ErrAlg return err
} }
switch rr.Algorithm { switch rr.Algorithm {
@ -450,10 +436,9 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
return ErrKey return ErrKey
} }
h := hash.New()
h.Write(signeddata) h.Write(signeddata)
h.Write(wire) h.Write(wire)
return rsa.VerifyPKCS1v15(pubkey, hash, h.Sum(nil), sigbuf) return rsa.VerifyPKCS1v15(pubkey, cryptohash, h.Sum(nil), sigbuf)
case ECDSAP256SHA256, ECDSAP384SHA384: case ECDSAP256SHA256, ECDSAP384SHA384:
pubkey := k.publicKeyECDSA() pubkey := k.publicKeyECDSA()
@ -465,7 +450,6 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
r := new(big.Int).SetBytes(sigbuf[:len(sigbuf)/2]) r := new(big.Int).SetBytes(sigbuf[:len(sigbuf)/2])
s := new(big.Int).SetBytes(sigbuf[len(sigbuf)/2:]) s := new(big.Int).SetBytes(sigbuf[len(sigbuf)/2:])
h := hash.New()
h.Write(signeddata) h.Write(signeddata)
h.Write(wire) h.Write(wire)
if ecdsa.Verify(pubkey, h.Sum(nil), r, s) { if ecdsa.Verify(pubkey, h.Sum(nil), r, s) {

2
vendor/github.com/miekg/dns/doc.go generated vendored
View File

@ -251,7 +251,7 @@ information.
EDNS0 EDNS0
EDNS0 is an extension mechanism for the DNS defined in RFC 2671 and updated by EDNS0 is an extension mechanism for the DNS defined in RFC 2671 and updated by
RFC 6891. It defines an new RR type, the OPT RR, which is then completely RFC 6891. It defines a new RR type, the OPT RR, which is then completely
abused. abused.
Basic use pattern for creating an (empty) OPT RR: Basic use pattern for creating an (empty) OPT RR:

98
vendor/github.com/miekg/dns/edns.go generated vendored
View File

@ -14,6 +14,7 @@ const (
EDNS0LLQ = 0x1 // long lived queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01 EDNS0LLQ = 0x1 // long lived queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01
EDNS0UL = 0x2 // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt EDNS0UL = 0x2 // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt
EDNS0NSID = 0x3 // nsid (See RFC 5001) EDNS0NSID = 0x3 // nsid (See RFC 5001)
EDNS0ESU = 0x4 // ENUM Source-URI draft: https://datatracker.ietf.org/doc/html/draft-kaplan-enum-source-uri-00
EDNS0DAU = 0x5 // DNSSEC Algorithm Understood EDNS0DAU = 0x5 // DNSSEC Algorithm Understood
EDNS0DHU = 0x6 // DS Hash Understood EDNS0DHU = 0x6 // DS Hash Understood
EDNS0N3U = 0x7 // NSEC3 Hash Understood EDNS0N3U = 0x7 // NSEC3 Hash Understood
@ -56,6 +57,8 @@ func makeDataOpt(code uint16) EDNS0 {
return new(EDNS0_PADDING) return new(EDNS0_PADDING)
case EDNS0EDE: case EDNS0EDE:
return new(EDNS0_EDE) return new(EDNS0_EDE)
case EDNS0ESU:
return &EDNS0_ESU{Code: EDNS0ESU}
default: default:
e := new(EDNS0_LOCAL) e := new(EDNS0_LOCAL)
e.Code = code e.Code = code
@ -95,6 +98,8 @@ func (rr *OPT) String() string {
s += "\n; SUBNET: " + o.String() s += "\n; SUBNET: " + o.String()
case *EDNS0_COOKIE: case *EDNS0_COOKIE:
s += "\n; COOKIE: " + o.String() s += "\n; COOKIE: " + o.String()
case *EDNS0_TCP_KEEPALIVE:
s += "\n; KEEPALIVE: " + o.String()
case *EDNS0_UL: case *EDNS0_UL:
s += "\n; UPDATE LEASE: " + o.String() s += "\n; UPDATE LEASE: " + o.String()
case *EDNS0_LLQ: case *EDNS0_LLQ:
@ -111,6 +116,8 @@ func (rr *OPT) String() string {
s += "\n; PADDING: " + o.String() s += "\n; PADDING: " + o.String()
case *EDNS0_EDE: case *EDNS0_EDE:
s += "\n; EDE: " + o.String() s += "\n; EDE: " + o.String()
case *EDNS0_ESU:
s += "\n; ESU: " + o.String()
} }
} }
return s return s
@ -577,14 +584,17 @@ func (e *EDNS0_N3U) copy() EDNS0 { return &EDNS0_N3U{e.Code, e.AlgCode} }
type EDNS0_EXPIRE struct { type EDNS0_EXPIRE struct {
Code uint16 // Always EDNS0EXPIRE Code uint16 // Always EDNS0EXPIRE
Expire uint32 Expire uint32
Empty bool // Empty is used to signal an empty Expire option in a backwards compatible way, it's not used on the wire.
} }
// Option implements the EDNS0 interface. // Option implements the EDNS0 interface.
func (e *EDNS0_EXPIRE) Option() uint16 { return EDNS0EXPIRE } func (e *EDNS0_EXPIRE) Option() uint16 { return EDNS0EXPIRE }
func (e *EDNS0_EXPIRE) String() string { return strconv.FormatUint(uint64(e.Expire), 10) } func (e *EDNS0_EXPIRE) copy() EDNS0 { return &EDNS0_EXPIRE{e.Code, e.Expire, e.Empty} }
func (e *EDNS0_EXPIRE) copy() EDNS0 { return &EDNS0_EXPIRE{e.Code, e.Expire} }
func (e *EDNS0_EXPIRE) pack() ([]byte, error) { func (e *EDNS0_EXPIRE) pack() ([]byte, error) {
if e.Empty {
return []byte{}, nil
}
b := make([]byte, 4) b := make([]byte, 4)
binary.BigEndian.PutUint32(b, e.Expire) binary.BigEndian.PutUint32(b, e.Expire)
return b, nil return b, nil
@ -593,15 +603,24 @@ func (e *EDNS0_EXPIRE) pack() ([]byte, error) {
func (e *EDNS0_EXPIRE) unpack(b []byte) error { func (e *EDNS0_EXPIRE) unpack(b []byte) error {
if len(b) == 0 { if len(b) == 0 {
// zero-length EXPIRE query, see RFC 7314 Section 2 // zero-length EXPIRE query, see RFC 7314 Section 2
e.Empty = true
return nil return nil
} }
if len(b) < 4 { if len(b) < 4 {
return ErrBuf return ErrBuf
} }
e.Expire = binary.BigEndian.Uint32(b) e.Expire = binary.BigEndian.Uint32(b)
e.Empty = false
return nil return nil
} }
func (e *EDNS0_EXPIRE) String() (s string) {
if e.Empty {
return ""
}
return strconv.FormatUint(uint64(e.Expire), 10)
}
// The EDNS0_LOCAL option is used for local/experimental purposes. The option // The EDNS0_LOCAL option is used for local/experimental purposes. The option
// code is recommended to be within the range [EDNS0LOCALSTART, EDNS0LOCALEND] // code is recommended to be within the range [EDNS0LOCALSTART, EDNS0LOCALEND]
// (RFC6891), although any unassigned code can actually be used. The content of // (RFC6891), although any unassigned code can actually be used. The content of
@ -652,57 +671,52 @@ func (e *EDNS0_LOCAL) unpack(b []byte) error {
// EDNS0_TCP_KEEPALIVE is an EDNS0 option that instructs the server to keep // EDNS0_TCP_KEEPALIVE is an EDNS0 option that instructs the server to keep
// the TCP connection alive. See RFC 7828. // the TCP connection alive. See RFC 7828.
type EDNS0_TCP_KEEPALIVE struct { type EDNS0_TCP_KEEPALIVE struct {
Code uint16 // Always EDNSTCPKEEPALIVE Code uint16 // Always EDNSTCPKEEPALIVE
Length uint16 // the value 0 if the TIMEOUT is omitted, the value 2 if it is present;
Timeout uint16 // an idle timeout value for the TCP connection, specified in units of 100 milliseconds, encoded in network byte order. // Timeout is an idle timeout value for the TCP connection, specified in
// units of 100 milliseconds, encoded in network byte order. If set to 0,
// pack will return a nil slice.
Timeout uint16
// Length is the option's length.
// Deprecated: this field is deprecated and is always equal to 0.
Length uint16
} }
// Option implements the EDNS0 interface. // Option implements the EDNS0 interface.
func (e *EDNS0_TCP_KEEPALIVE) Option() uint16 { return EDNS0TCPKEEPALIVE } func (e *EDNS0_TCP_KEEPALIVE) Option() uint16 { return EDNS0TCPKEEPALIVE }
func (e *EDNS0_TCP_KEEPALIVE) pack() ([]byte, error) { func (e *EDNS0_TCP_KEEPALIVE) pack() ([]byte, error) {
if e.Timeout != 0 && e.Length != 2 { if e.Timeout > 0 {
return nil, errors.New("dns: timeout specified but length is not 2") b := make([]byte, 2)
binary.BigEndian.PutUint16(b, e.Timeout)
return b, nil
} }
if e.Timeout == 0 && e.Length != 0 { return nil, nil
return nil, errors.New("dns: timeout not specified but length is not 0")
}
b := make([]byte, 4+e.Length)
binary.BigEndian.PutUint16(b[0:], e.Code)
binary.BigEndian.PutUint16(b[2:], e.Length)
if e.Length == 2 {
binary.BigEndian.PutUint16(b[4:], e.Timeout)
}
return b, nil
} }
func (e *EDNS0_TCP_KEEPALIVE) unpack(b []byte) error { func (e *EDNS0_TCP_KEEPALIVE) unpack(b []byte) error {
if len(b) < 4 { switch len(b) {
return ErrBuf case 0:
} case 2:
e.Length = binary.BigEndian.Uint16(b[2:4]) e.Timeout = binary.BigEndian.Uint16(b)
if e.Length != 0 && e.Length != 2 { default:
return errors.New("dns: length mismatch, want 0/2 but got " + strconv.FormatUint(uint64(e.Length), 10)) return fmt.Errorf("dns: length mismatch, want 0/2 but got %d", len(b))
}
if e.Length == 2 {
if len(b) < 6 {
return ErrBuf
}
e.Timeout = binary.BigEndian.Uint16(b[4:6])
} }
return nil return nil
} }
func (e *EDNS0_TCP_KEEPALIVE) String() (s string) { func (e *EDNS0_TCP_KEEPALIVE) String() string {
s = "use tcp keep-alive" s := "use tcp keep-alive"
if e.Length == 0 { if e.Timeout == 0 {
s += ", timeout omitted" s += ", timeout omitted"
} else { } else {
s += fmt.Sprintf(", timeout %dms", e.Timeout*100) s += fmt.Sprintf(", timeout %dms", e.Timeout*100)
} }
return return s
} }
func (e *EDNS0_TCP_KEEPALIVE) copy() EDNS0 { return &EDNS0_TCP_KEEPALIVE{e.Code, e.Length, e.Timeout} }
func (e *EDNS0_TCP_KEEPALIVE) copy() EDNS0 { return &EDNS0_TCP_KEEPALIVE{e.Code, e.Timeout, e.Length} }
// EDNS0_PADDING option is used to add padding to a request/response. The default // EDNS0_PADDING option is used to add padding to a request/response. The default
// value of padding SHOULD be 0x0 but other values MAY be used, for instance if // value of padding SHOULD be 0x0 but other values MAY be used, for instance if
@ -819,3 +833,19 @@ func (e *EDNS0_EDE) unpack(b []byte) error {
e.ExtraText = string(b[2:]) e.ExtraText = string(b[2:])
return nil return nil
} }
// The EDNS0_ESU option for ENUM Source-URI Extension
type EDNS0_ESU struct {
Code uint16
Uri string
}
// Option implements the EDNS0 interface.
func (e *EDNS0_ESU) Option() uint16 { return EDNS0ESU }
func (e *EDNS0_ESU) String() string { return e.Uri }
func (e *EDNS0_ESU) copy() EDNS0 { return &EDNS0_ESU{e.Code, e.Uri} }
func (e *EDNS0_ESU) pack() ([]byte, error) { return []byte(e.Uri), nil }
func (e *EDNS0_ESU) unpack(b []byte) error {
e.Uri = string(b)
return nil
}

31
vendor/github.com/miekg/dns/hash.go generated vendored Normal file
View File

@ -0,0 +1,31 @@
package dns
import (
"bytes"
"crypto"
"hash"
)
// identityHash will not hash, it only buffers the data written into it and returns it as-is.
type identityHash struct {
b *bytes.Buffer
}
// Implement the hash.Hash interface.
func (i identityHash) Write(b []byte) (int, error) { return i.b.Write(b) }
func (i identityHash) Size() int { return i.b.Len() }
func (i identityHash) BlockSize() int { return 1024 }
func (i identityHash) Reset() { i.b.Reset() }
func (i identityHash) Sum(b []byte) []byte { return append(b, i.b.Bytes()...) }
func hashFromAlgorithm(alg uint8) (hash.Hash, crypto.Hash, error) {
hashnumber, ok := AlgorithmToHash[alg]
if !ok {
return nil, 0, ErrAlg
}
if hashnumber == 0 {
return identityHash{b: &bytes.Buffer{}}, hashnumber, nil
}
return hashnumber.New(), hashnumber, nil
}

14
vendor/github.com/miekg/dns/msg.go generated vendored
View File

@ -265,6 +265,11 @@ loop:
wasDot = false wasDot = false
case '.': case '.':
if i == 0 && len(s) > 1 {
// leading dots are not legal except for the root zone
return len(msg), ErrRdata
}
if wasDot { if wasDot {
// two dots back to back is not legal // two dots back to back is not legal
return len(msg), ErrRdata return len(msg), ErrRdata
@ -901,6 +906,11 @@ func (dns *Msg) String() string {
s += "ANSWER: " + strconv.Itoa(len(dns.Answer)) + ", " s += "ANSWER: " + strconv.Itoa(len(dns.Answer)) + ", "
s += "AUTHORITY: " + strconv.Itoa(len(dns.Ns)) + ", " s += "AUTHORITY: " + strconv.Itoa(len(dns.Ns)) + ", "
s += "ADDITIONAL: " + strconv.Itoa(len(dns.Extra)) + "\n" s += "ADDITIONAL: " + strconv.Itoa(len(dns.Extra)) + "\n"
opt := dns.IsEdns0()
if opt != nil {
// OPT PSEUDOSECTION
s += opt.String() + "\n"
}
if len(dns.Question) > 0 { if len(dns.Question) > 0 {
s += "\n;; QUESTION SECTION:\n" s += "\n;; QUESTION SECTION:\n"
for _, r := range dns.Question { for _, r := range dns.Question {
@ -923,10 +933,10 @@ func (dns *Msg) String() string {
} }
} }
} }
if len(dns.Extra) > 0 { if len(dns.Extra) > 0 && (opt == nil || len(dns.Extra) > 1) {
s += "\n;; ADDITIONAL SECTION:\n" s += "\n;; ADDITIONAL SECTION:\n"
for _, r := range dns.Extra { for _, r := range dns.Extra {
if r != nil { if r != nil && r.Header().Rrtype != TypeOPT {
s += r.String() + "\n" s += r.String() + "\n"
} }
} }

View File

@ -476,7 +476,7 @@ func unpackDataNsec(msg []byte, off int) ([]uint16, int, error) {
length, window, lastwindow := 0, 0, -1 length, window, lastwindow := 0, 0, -1
for off < len(msg) { for off < len(msg) {
if off+2 > len(msg) { if off+2 > len(msg) {
return nsec, len(msg), &Error{err: "overflow unpacking nsecx"} return nsec, len(msg), &Error{err: "overflow unpacking NSEC(3)"}
} }
window = int(msg[off]) window = int(msg[off])
length = int(msg[off+1]) length = int(msg[off+1])
@ -484,17 +484,17 @@ func unpackDataNsec(msg []byte, off int) ([]uint16, int, error) {
if window <= lastwindow { if window <= lastwindow {
// RFC 4034: Blocks are present in the NSEC RR RDATA in // RFC 4034: Blocks are present in the NSEC RR RDATA in
// increasing numerical order. // increasing numerical order.
return nsec, len(msg), &Error{err: "out of order NSEC block"} return nsec, len(msg), &Error{err: "out of order NSEC(3) block in type bitmap"}
} }
if length == 0 { if length == 0 {
// RFC 4034: Blocks with no types present MUST NOT be included. // RFC 4034: Blocks with no types present MUST NOT be included.
return nsec, len(msg), &Error{err: "empty NSEC block"} return nsec, len(msg), &Error{err: "empty NSEC(3) block in type bitmap"}
} }
if length > 32 { if length > 32 {
return nsec, len(msg), &Error{err: "NSEC block too long"} return nsec, len(msg), &Error{err: "NSEC(3) block too long in type bitmap"}
} }
if off+length > len(msg) { if off+length > len(msg) {
return nsec, len(msg), &Error{err: "overflowing NSEC block"} return nsec, len(msg), &Error{err: "overflowing NSEC(3) block in type bitmap"}
} }
// Walk the bytes in the window and extract the type bits // Walk the bytes in the window and extract the type bits
@ -558,6 +558,16 @@ func packDataNsec(bitmap []uint16, msg []byte, off int) (int, error) {
if len(bitmap) == 0 { if len(bitmap) == 0 {
return off, nil return off, nil
} }
if off > len(msg) {
return off, &Error{err: "overflow packing nsec"}
}
toZero := msg[off:]
if maxLen := typeBitMapLen(bitmap); maxLen < len(toZero) {
toZero = toZero[:maxLen]
}
for i := range toZero {
toZero[i] = 0
}
var lastwindow, lastlength uint16 var lastwindow, lastlength uint16
for _, t := range bitmap { for _, t := range bitmap {
window := t / 256 window := t / 256
@ -781,6 +791,8 @@ func unpackDataAplPrefix(msg []byte, off int) (APLPrefix, int, error) {
if off+afdlen > len(msg) { if off+afdlen > len(msg) {
return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL address"} return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL address"}
} }
// Address MUST NOT contain trailing zero bytes per RFC3123 Sections 4.1 and 4.2.
off += copy(ip, msg[off:off+afdlen]) off += copy(ip, msg[off:off+afdlen])
if afdlen > 0 { if afdlen > 0 {
last := ip[afdlen-1] last := ip[afdlen-1]
@ -792,10 +804,6 @@ func unpackDataAplPrefix(msg []byte, off int) (APLPrefix, int, error) {
IP: ip, IP: ip,
Mask: net.CIDRMask(int(prefix), 8*len(ip)), Mask: net.CIDRMask(int(prefix), 8*len(ip)),
} }
network := ipnet.IP.Mask(ipnet.Mask)
if !network.Equal(ipnet.IP) {
return APLPrefix{}, len(msg), &Error{err: "invalid APL address length"}
}
return APLPrefix{ return APLPrefix{
Negation: (nlen & 0x80) != 0, Negation: (nlen & 0x80) != 0,

View File

@ -71,12 +71,12 @@ type response struct {
tsigTimersOnly bool tsigTimersOnly bool
tsigStatus error tsigStatus error
tsigRequestMAC string tsigRequestMAC string
tsigSecret map[string]string // the tsig secrets tsigProvider TsigProvider
udp net.PacketConn // i/o connection if UDP was used udp net.PacketConn // i/o connection if UDP was used
tcp net.Conn // i/o connection if TCP was used tcp net.Conn // i/o connection if TCP was used
udpSession *SessionUDP // oob data to get egress interface right udpSession *SessionUDP // oob data to get egress interface right
pcSession net.Addr // address to use when writing to a generic net.PacketConn pcSession net.Addr // address to use when writing to a generic net.PacketConn
writer Writer // writer to output the raw DNS bits writer Writer // writer to output the raw DNS bits
} }
// handleRefused returns a HandlerFunc that returns REFUSED for every request it gets. // handleRefused returns a HandlerFunc that returns REFUSED for every request it gets.
@ -211,6 +211,8 @@ type Server struct {
WriteTimeout time.Duration WriteTimeout time.Duration
// TCP idle timeout for multiple queries, if nil, defaults to 8 * time.Second (RFC 5966). // TCP idle timeout for multiple queries, if nil, defaults to 8 * time.Second (RFC 5966).
IdleTimeout func() time.Duration IdleTimeout func() time.Duration
// An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations.
TsigProvider TsigProvider
// Secret(s) for Tsig map[<zonename>]<base64 secret>. The zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2). // Secret(s) for Tsig map[<zonename>]<base64 secret>. The zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2).
TsigSecret map[string]string TsigSecret map[string]string
// If NotifyStartedFunc is set it is called once the server has started listening. // If NotifyStartedFunc is set it is called once the server has started listening.
@ -238,6 +240,16 @@ type Server struct {
udpPool sync.Pool udpPool sync.Pool
} }
func (srv *Server) tsigProvider() TsigProvider {
if srv.TsigProvider != nil {
return srv.TsigProvider
}
if srv.TsigSecret != nil {
return tsigSecretProvider(srv.TsigSecret)
}
return nil
}
func (srv *Server) isStarted() bool { func (srv *Server) isStarted() bool {
srv.lock.RLock() srv.lock.RLock()
started := srv.started started := srv.started
@ -526,7 +538,7 @@ func (srv *Server) serveUDP(l net.PacketConn) error {
// Serve a new TCP connection. // Serve a new TCP connection.
func (srv *Server) serveTCPConn(wg *sync.WaitGroup, rw net.Conn) { func (srv *Server) serveTCPConn(wg *sync.WaitGroup, rw net.Conn) {
w := &response{tsigSecret: srv.TsigSecret, tcp: rw} w := &response{tsigProvider: srv.tsigProvider(), tcp: rw}
if srv.DecorateWriter != nil { if srv.DecorateWriter != nil {
w.writer = srv.DecorateWriter(w) w.writer = srv.DecorateWriter(w)
} else { } else {
@ -581,7 +593,7 @@ func (srv *Server) serveTCPConn(wg *sync.WaitGroup, rw net.Conn) {
// Serve a new UDP request. // Serve a new UDP request.
func (srv *Server) serveUDPPacket(wg *sync.WaitGroup, m []byte, u net.PacketConn, udpSession *SessionUDP, pcSession net.Addr) { func (srv *Server) serveUDPPacket(wg *sync.WaitGroup, m []byte, u net.PacketConn, udpSession *SessionUDP, pcSession net.Addr) {
w := &response{tsigSecret: srv.TsigSecret, udp: u, udpSession: udpSession, pcSession: pcSession} w := &response{tsigProvider: srv.tsigProvider(), udp: u, udpSession: udpSession, pcSession: pcSession}
if srv.DecorateWriter != nil { if srv.DecorateWriter != nil {
w.writer = srv.DecorateWriter(w) w.writer = srv.DecorateWriter(w)
} else { } else {
@ -632,15 +644,11 @@ func (srv *Server) serveDNS(m []byte, w *response) {
} }
w.tsigStatus = nil w.tsigStatus = nil
if w.tsigSecret != nil { if w.tsigProvider != nil {
if t := req.IsTsig(); t != nil { if t := req.IsTsig(); t != nil {
if secret, ok := w.tsigSecret[t.Hdr.Name]; ok { w.tsigStatus = TsigVerifyWithProvider(m, w.tsigProvider, "", false)
w.tsigStatus = TsigVerify(m, secret, "", false)
} else {
w.tsigStatus = ErrSecret
}
w.tsigTimersOnly = false w.tsigTimersOnly = false
w.tsigRequestMAC = req.Extra[len(req.Extra)-1].(*TSIG).MAC w.tsigRequestMAC = t.MAC
} }
} }
@ -718,9 +726,9 @@ func (w *response) WriteMsg(m *Msg) (err error) {
} }
var data []byte var data []byte
if w.tsigSecret != nil { // if no secrets, dont check for the tsig (which is a longer check) if w.tsigProvider != nil { // if no provider, dont check for the tsig (which is a longer check)
if t := m.IsTsig(); t != nil { if t := m.IsTsig(); t != nil {
data, w.tsigRequestMAC, err = TsigGenerate(m, w.tsigSecret[t.Hdr.Name], w.tsigRequestMAC, w.tsigTimersOnly) data, w.tsigRequestMAC, err = TsigGenerateWithProvider(m, w.tsigProvider, w.tsigRequestMAC, w.tsigTimersOnly)
if err != nil { if err != nil {
return err return err
} }

51
vendor/github.com/miekg/dns/sig0.go generated vendored
View File

@ -3,6 +3,7 @@ package dns
import ( import (
"crypto" "crypto"
"crypto/ecdsa" "crypto/ecdsa"
"crypto/ed25519"
"crypto/rsa" "crypto/rsa"
"encoding/binary" "encoding/binary"
"math/big" "math/big"
@ -38,18 +39,17 @@ func (rr *SIG) Sign(k crypto.Signer, m *Msg) ([]byte, error) {
} }
buf = buf[:off:cap(buf)] buf = buf[:off:cap(buf)]
hash, ok := AlgorithmToHash[rr.Algorithm] h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
if !ok { if err != nil {
return nil, ErrAlg return nil, err
} }
hasher := hash.New()
// Write SIG rdata // Write SIG rdata
hasher.Write(buf[len(mbuf)+1+2+2+4+2:]) h.Write(buf[len(mbuf)+1+2+2+4+2:])
// Write message // Write message
hasher.Write(buf[:len(mbuf)]) h.Write(buf[:len(mbuf)])
signature, err := sign(k, hasher.Sum(nil), hash, rr.Algorithm) signature, err := sign(k, h.Sum(nil), cryptohash, rr.Algorithm)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -82,20 +82,10 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error {
return ErrKey return ErrKey
} }
var hash crypto.Hash h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
switch rr.Algorithm { if err != nil {
case RSASHA1: return err
hash = crypto.SHA1
case RSASHA256, ECDSAP256SHA256:
hash = crypto.SHA256
case ECDSAP384SHA384:
hash = crypto.SHA384
case RSASHA512:
hash = crypto.SHA512
default:
return ErrAlg
} }
hasher := hash.New()
buflen := len(buf) buflen := len(buf)
qdc := binary.BigEndian.Uint16(buf[4:]) qdc := binary.BigEndian.Uint16(buf[4:])
@ -103,7 +93,6 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error {
auc := binary.BigEndian.Uint16(buf[8:]) auc := binary.BigEndian.Uint16(buf[8:])
adc := binary.BigEndian.Uint16(buf[10:]) adc := binary.BigEndian.Uint16(buf[10:])
offset := headerSize offset := headerSize
var err error
for i := uint16(0); i < qdc && offset < buflen; i++ { for i := uint16(0); i < qdc && offset < buflen; i++ {
_, offset, err = UnpackDomainName(buf, offset) _, offset, err = UnpackDomainName(buf, offset)
if err != nil { if err != nil {
@ -166,21 +155,21 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error {
return &Error{err: "signer name doesn't match key name"} return &Error{err: "signer name doesn't match key name"}
} }
sigend := offset sigend := offset
hasher.Write(buf[sigstart:sigend]) h.Write(buf[sigstart:sigend])
hasher.Write(buf[:10]) h.Write(buf[:10])
hasher.Write([]byte{ h.Write([]byte{
byte((adc - 1) << 8), byte((adc - 1) << 8),
byte(adc - 1), byte(adc - 1),
}) })
hasher.Write(buf[12:bodyend]) h.Write(buf[12:bodyend])
hashed := hasher.Sum(nil) hashed := h.Sum(nil)
sig := buf[sigend:] sig := buf[sigend:]
switch k.Algorithm { switch k.Algorithm {
case RSASHA1, RSASHA256, RSASHA512: case RSASHA1, RSASHA256, RSASHA512:
pk := k.publicKeyRSA() pk := k.publicKeyRSA()
if pk != nil { if pk != nil {
return rsa.VerifyPKCS1v15(pk, hash, hashed, sig) return rsa.VerifyPKCS1v15(pk, cryptohash, hashed, sig)
} }
case ECDSAP256SHA256, ECDSAP384SHA384: case ECDSAP256SHA256, ECDSAP384SHA384:
pk := k.publicKeyECDSA() pk := k.publicKeyECDSA()
@ -192,6 +181,14 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error {
} }
return ErrSig return ErrSig
} }
case ED25519:
pk := k.publicKeyED25519()
if pk != nil {
if ed25519.Verify(pk, hashed, sig) {
return nil
}
return ErrSig
}
} }
return ErrKeyAlg return ErrKeyAlg
} }

330
vendor/github.com/miekg/dns/svcb.go generated vendored
View File

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt"
"net" "net"
"sort" "sort"
"strconv" "strconv"
@ -13,16 +14,18 @@ import (
// SVCBKey is the type of the keys used in the SVCB RR. // SVCBKey is the type of the keys used in the SVCB RR.
type SVCBKey uint16 type SVCBKey uint16
// Keys defined in draft-ietf-dnsop-svcb-https-01 Section 12.3.2. // Keys defined in draft-ietf-dnsop-svcb-https-08 Section 14.3.2.
const ( const (
SVCB_MANDATORY SVCBKey = 0 SVCB_MANDATORY SVCBKey = iota
SVCB_ALPN SVCBKey = 1 SVCB_ALPN
SVCB_NO_DEFAULT_ALPN SVCBKey = 2 SVCB_NO_DEFAULT_ALPN
SVCB_PORT SVCBKey = 3 SVCB_PORT
SVCB_IPV4HINT SVCBKey = 4 SVCB_IPV4HINT
SVCB_ECHCONFIG SVCBKey = 5 SVCB_ECHCONFIG
SVCB_IPV6HINT SVCBKey = 6 SVCB_IPV6HINT
svcb_RESERVED SVCBKey = 65535 SVCB_DOHPATH // draft-ietf-add-svcb-dns-02 Section 9
svcb_RESERVED SVCBKey = 65535
) )
var svcbKeyToStringMap = map[SVCBKey]string{ var svcbKeyToStringMap = map[SVCBKey]string{
@ -31,8 +34,9 @@ var svcbKeyToStringMap = map[SVCBKey]string{
SVCB_NO_DEFAULT_ALPN: "no-default-alpn", SVCB_NO_DEFAULT_ALPN: "no-default-alpn",
SVCB_PORT: "port", SVCB_PORT: "port",
SVCB_IPV4HINT: "ipv4hint", SVCB_IPV4HINT: "ipv4hint",
SVCB_ECHCONFIG: "echconfig", SVCB_ECHCONFIG: "ech",
SVCB_IPV6HINT: "ipv6hint", SVCB_IPV6HINT: "ipv6hint",
SVCB_DOHPATH: "dohpath",
} }
var svcbStringToKeyMap = reverseSVCBKeyMap(svcbKeyToStringMap) var svcbStringToKeyMap = reverseSVCBKeyMap(svcbKeyToStringMap)
@ -167,10 +171,14 @@ func (rr *SVCB) parse(c *zlexer, o string) *ParseError {
} }
l, _ = c.Next() l, _ = c.Next()
} }
// "In AliasMode, records SHOULD NOT include any SvcParams, and recipients MUST
// ignore any SvcParams that are present."
// However, we don't check rr.Priority == 0 && len(xs) > 0 here
// It is the responsibility of the user of the library to check this.
// This is to encourage the fixing of the source of this error.
rr.Value = xs rr.Value = xs
if rr.Priority == 0 && len(xs) > 0 {
return &ParseError{l.token, "SVCB aliasform can't have values", l}
}
return nil return nil
} }
@ -191,6 +199,8 @@ func makeSVCBKeyValue(key SVCBKey) SVCBKeyValue {
return new(SVCBECHConfig) return new(SVCBECHConfig)
case SVCB_IPV6HINT: case SVCB_IPV6HINT:
return new(SVCBIPv6Hint) return new(SVCBIPv6Hint)
case SVCB_DOHPATH:
return new(SVCBDoHPath)
case svcb_RESERVED: case svcb_RESERVED:
return nil return nil
default: default:
@ -200,16 +210,24 @@ func makeSVCBKeyValue(key SVCBKey) SVCBKeyValue {
} }
} }
// SVCB RR. See RFC xxxx (https://tools.ietf.org/html/draft-ietf-dnsop-svcb-https-01). // SVCB RR. See RFC xxxx (https://tools.ietf.org/html/draft-ietf-dnsop-svcb-https-08).
//
// NOTE: The HTTPS/SVCB RFCs are in the draft stage.
// The API, including constants and types related to SVCBKeyValues, may
// change in future versions in accordance with the latest drafts.
type SVCB struct { type SVCB struct {
Hdr RR_Header Hdr RR_Header
Priority uint16 Priority uint16 // If zero, Value must be empty or discarded by the user of this library
Target string `dns:"domain-name"` Target string `dns:"domain-name"`
Value []SVCBKeyValue `dns:"pairs"` // Value must be empty if Priority is zero. Value []SVCBKeyValue `dns:"pairs"`
} }
// HTTPS RR. Everything valid for SVCB applies to HTTPS as well. // HTTPS RR. Everything valid for SVCB applies to HTTPS as well.
// Except that the HTTPS record is intended for use with the HTTP and HTTPS protocols. // Except that the HTTPS record is intended for use with the HTTP and HTTPS protocols.
//
// NOTE: The HTTPS/SVCB RFCs are in the draft stage.
// The API, including constants and types related to SVCBKeyValues, may
// change in future versions in accordance with the latest drafts.
type HTTPS struct { type HTTPS struct {
SVCB SVCB
} }
@ -235,15 +253,29 @@ type SVCBKeyValue interface {
} }
// SVCBMandatory pair adds to required keys that must be interpreted for the RR // SVCBMandatory pair adds to required keys that must be interpreted for the RR
// to be functional. // to be functional. If ignored, the whole RRSet must be ignored.
// "port" and "no-default-alpn" are mandatory by default if present,
// so they shouldn't be included here.
//
// It is incumbent upon the user of this library to reject the RRSet if
// or avoid constructing such an RRSet that:
// - "mandatory" is included as one of the keys of mandatory
// - no key is listed multiple times in mandatory
// - all keys listed in mandatory are present
// - escape sequences are not used in mandatory
// - mandatory, when present, lists at least one key
//
// Basic use pattern for creating a mandatory option: // Basic use pattern for creating a mandatory option:
// //
// s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}} // s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
// e := new(dns.SVCBMandatory) // e := new(dns.SVCBMandatory)
// e.Code = []uint16{65403} // e.Code = []uint16{dns.SVCB_ALPN}
// s.Value = append(s.Value, e) // s.Value = append(s.Value, e)
// t := new(dns.SVCBAlpn)
// t.Alpn = []string{"xmpp-client"}
// s.Value = append(s.Value, t)
type SVCBMandatory struct { type SVCBMandatory struct {
Code []SVCBKey // Must not include mandatory Code []SVCBKey
} }
func (*SVCBMandatory) Key() SVCBKey { return SVCB_MANDATORY } func (*SVCBMandatory) Key() SVCBKey { return SVCB_MANDATORY }
@ -302,7 +334,8 @@ func (s *SVCBMandatory) copy() SVCBKeyValue {
} }
// SVCBAlpn pair is used to list supported connection protocols. // SVCBAlpn pair is used to list supported connection protocols.
// Protocol ids can be found at: // The user of this library must ensure that at least one protocol is listed when alpn is present.
// Protocol IDs can be found at:
// https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids // https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
// Basic use pattern for creating an alpn option: // Basic use pattern for creating an alpn option:
// //
@ -310,13 +343,57 @@ func (s *SVCBMandatory) copy() SVCBKeyValue {
// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET} // h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
// e := new(dns.SVCBAlpn) // e := new(dns.SVCBAlpn)
// e.Alpn = []string{"h2", "http/1.1"} // e.Alpn = []string{"h2", "http/1.1"}
// h.Value = append(o.Value, e) // h.Value = append(h.Value, e)
type SVCBAlpn struct { type SVCBAlpn struct {
Alpn []string Alpn []string
} }
func (*SVCBAlpn) Key() SVCBKey { return SVCB_ALPN } func (*SVCBAlpn) Key() SVCBKey { return SVCB_ALPN }
func (s *SVCBAlpn) String() string { return strings.Join(s.Alpn, ",") }
func (s *SVCBAlpn) String() string {
// An ALPN value is a comma-separated list of values, each of which can be
// an arbitrary binary value. In order to allow parsing, the comma and
// backslash characters are themselves excaped.
//
// However, this escaping is done in addition to the normal escaping which
// happens in zone files, meaning that these values must be
// double-escaped. This looks terrible, so if you see a never-ending
// sequence of backslash in a zone file this may be why.
//
// https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-08#appendix-A.1
var str strings.Builder
for i, alpn := range s.Alpn {
// 4*len(alpn) is the worst case where we escape every character in the alpn as \123, plus 1 byte for the ',' separating the alpn from others
str.Grow(4*len(alpn) + 1)
if i > 0 {
str.WriteByte(',')
}
for j := 0; j < len(alpn); j++ {
e := alpn[j]
if ' ' > e || e > '~' {
str.WriteString(escapeByte(e))
continue
}
switch e {
// We escape a few characters which may confuse humans or parsers.
case '"', ';', ' ':
str.WriteByte('\\')
str.WriteByte(e)
// The comma and backslash characters themselves must be
// doubly-escaped. We use `\\` for the first backslash and
// the escaped numeric value for the other value. We especially
// don't want a comma in the output.
case ',':
str.WriteString(`\\\044`)
case '\\':
str.WriteString(`\\\092`)
default:
str.WriteByte(e)
}
}
}
return str.String()
}
func (s *SVCBAlpn) pack() ([]byte, error) { func (s *SVCBAlpn) pack() ([]byte, error) {
// Liberally estimate the size of an alpn as 10 octets // Liberally estimate the size of an alpn as 10 octets
@ -351,7 +428,47 @@ func (s *SVCBAlpn) unpack(b []byte) error {
} }
func (s *SVCBAlpn) parse(b string) error { func (s *SVCBAlpn) parse(b string) error {
s.Alpn = strings.Split(b, ",") if len(b) == 0 {
s.Alpn = []string{}
return nil
}
alpn := []string{}
a := []byte{}
for p := 0; p < len(b); {
c, q := nextByte(b, p)
if q == 0 {
return errors.New("dns: svcbalpn: unterminated escape")
}
p += q
// If we find a comma, we have finished reading an alpn.
if c == ',' {
if len(a) == 0 {
return errors.New("dns: svcbalpn: empty protocol identifier")
}
alpn = append(alpn, string(a))
a = []byte{}
continue
}
// If it's a backslash, we need to handle a comma-separated list.
if c == '\\' {
dc, dq := nextByte(b, p)
if dq == 0 {
return errors.New("dns: svcbalpn: unterminated escape decoding comma-separated list")
}
if dc != '\\' && dc != ',' {
return errors.New("dns: svcbalpn: bad escaped character decoding comma-separated list")
}
p += dq
c = dc
}
a = append(a, c)
}
// Add the final alpn.
if len(a) == 0 {
return errors.New("dns: svcbalpn: last protocol identifier empty")
}
s.Alpn = append(alpn, string(a))
return nil return nil
} }
@ -370,9 +487,13 @@ func (s *SVCBAlpn) copy() SVCBKeyValue {
} }
// SVCBNoDefaultAlpn pair signifies no support for default connection protocols. // SVCBNoDefaultAlpn pair signifies no support for default connection protocols.
// Should be used in conjunction with alpn.
// Basic use pattern for creating a no-default-alpn option: // Basic use pattern for creating a no-default-alpn option:
// //
// s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}} // s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
// t := new(dns.SVCBAlpn)
// t.Alpn = []string{"xmpp-client"}
// s.Value = append(s.Value, t)
// e := new(dns.SVCBNoDefaultAlpn) // e := new(dns.SVCBNoDefaultAlpn)
// s.Value = append(s.Value, e) // s.Value = append(s.Value, e)
type SVCBNoDefaultAlpn struct{} type SVCBNoDefaultAlpn struct{}
@ -385,14 +506,14 @@ func (*SVCBNoDefaultAlpn) len() int { return 0 }
func (*SVCBNoDefaultAlpn) unpack(b []byte) error { func (*SVCBNoDefaultAlpn) unpack(b []byte) error {
if len(b) != 0 { if len(b) != 0 {
return errors.New("dns: svcbnodefaultalpn: no_default_alpn must have no value") return errors.New("dns: svcbnodefaultalpn: no-default-alpn must have no value")
} }
return nil return nil
} }
func (*SVCBNoDefaultAlpn) parse(b string) error { func (*SVCBNoDefaultAlpn) parse(b string) error {
if b != "" { if b != "" {
return errors.New("dns: svcbnodefaultalpn: no_default_alpn must have no value") return errors.New("dns: svcbnodefaultalpn: no-default-alpn must have no value")
} }
return nil return nil
} }
@ -523,7 +644,7 @@ func (s *SVCBIPv4Hint) copy() SVCBKeyValue {
} }
// SVCBECHConfig pair contains the ECHConfig structure defined in draft-ietf-tls-esni [RFC xxxx]. // SVCBECHConfig pair contains the ECHConfig structure defined in draft-ietf-tls-esni [RFC xxxx].
// Basic use pattern for creating an echconfig option: // Basic use pattern for creating an ech option:
// //
// h := new(dns.HTTPS) // h := new(dns.HTTPS)
// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET} // h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
@ -531,7 +652,7 @@ func (s *SVCBIPv4Hint) copy() SVCBKeyValue {
// e.ECH = []byte{0xfe, 0x08, ...} // e.ECH = []byte{0xfe, 0x08, ...}
// h.Value = append(h.Value, e) // h.Value = append(h.Value, e)
type SVCBECHConfig struct { type SVCBECHConfig struct {
ECH []byte ECH []byte // Specifically ECHConfigList including the redundant length prefix
} }
func (*SVCBECHConfig) Key() SVCBKey { return SVCB_ECHCONFIG } func (*SVCBECHConfig) Key() SVCBKey { return SVCB_ECHCONFIG }
@ -555,7 +676,7 @@ func (s *SVCBECHConfig) unpack(b []byte) error {
func (s *SVCBECHConfig) parse(b string) error { func (s *SVCBECHConfig) parse(b string) error {
x, err := fromBase64([]byte(b)) x, err := fromBase64([]byte(b))
if err != nil { if err != nil {
return errors.New("dns: svcbechconfig: bad base64 echconfig") return errors.New("dns: svcbech: bad base64 ech")
} }
s.ECH = x s.ECH = x
return nil return nil
@ -618,9 +739,6 @@ func (s *SVCBIPv6Hint) String() string {
} }
func (s *SVCBIPv6Hint) parse(b string) error { func (s *SVCBIPv6Hint) parse(b string) error {
if strings.Contains(b, ".") {
return errors.New("dns: svcbipv6hint: expected ipv6, got ipv4")
}
str := strings.Split(b, ",") str := strings.Split(b, ",")
dst := make([]net.IP, len(str)) dst := make([]net.IP, len(str))
for i, e := range str { for i, e := range str {
@ -628,6 +746,9 @@ func (s *SVCBIPv6Hint) parse(b string) error {
if ip == nil { if ip == nil {
return errors.New("dns: svcbipv6hint: bad ip") return errors.New("dns: svcbipv6hint: bad ip")
} }
if ip.To4() != nil {
return errors.New("dns: svcbipv6hint: expected ipv6, got ipv4-mapped-ipv6")
}
dst[i] = ip dst[i] = ip
} }
s.Hint = dst s.Hint = dst
@ -645,6 +766,54 @@ func (s *SVCBIPv6Hint) copy() SVCBKeyValue {
} }
} }
// SVCBDoHPath pair is used to indicate the URI template that the
// clients may use to construct a DNS over HTTPS URI.
//
// See RFC xxxx (https://datatracker.ietf.org/doc/html/draft-ietf-add-svcb-dns-02)
// and RFC yyyy (https://datatracker.ietf.org/doc/html/draft-ietf-add-ddr-06).
//
// A basic example of using the dohpath option together with the alpn
// option to indicate support for DNS over HTTPS on a certain path:
//
// s := new(dns.SVCB)
// s.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}
// e := new(dns.SVCBAlpn)
// e.Alpn = []string{"h2", "h3"}
// p := new(dns.SVCBDoHPath)
// p.Template = "/dns-query{?dns}"
// s.Value = append(s.Value, e, p)
//
// The parsing currently doesn't validate that Template is a valid
// RFC 6570 URI template.
type SVCBDoHPath struct {
Template string
}
func (*SVCBDoHPath) Key() SVCBKey { return SVCB_DOHPATH }
func (s *SVCBDoHPath) String() string { return svcbParamToStr([]byte(s.Template)) }
func (s *SVCBDoHPath) len() int { return len(s.Template) }
func (s *SVCBDoHPath) pack() ([]byte, error) { return []byte(s.Template), nil }
func (s *SVCBDoHPath) unpack(b []byte) error {
s.Template = string(b)
return nil
}
func (s *SVCBDoHPath) parse(b string) error {
template, err := svcbParseParam(b)
if err != nil {
return fmt.Errorf("dns: svcbdohpath: %w", err)
}
s.Template = string(template)
return nil
}
func (s *SVCBDoHPath) copy() SVCBKeyValue {
return &SVCBDoHPath{
Template: s.Template,
}
}
// SVCBLocal pair is intended for experimental/private use. The key is recommended // SVCBLocal pair is intended for experimental/private use. The key is recommended
// to be in the range [SVCB_PRIVATE_LOWER, SVCB_PRIVATE_UPPER]. // to be in the range [SVCB_PRIVATE_LOWER, SVCB_PRIVATE_UPPER].
// Basic use pattern for creating a keyNNNNN option: // Basic use pattern for creating a keyNNNNN option:
@ -661,6 +830,7 @@ type SVCBLocal struct {
} }
func (s *SVCBLocal) Key() SVCBKey { return s.KeyCode } func (s *SVCBLocal) Key() SVCBKey { return s.KeyCode }
func (s *SVCBLocal) String() string { return svcbParamToStr(s.Data) }
func (s *SVCBLocal) pack() ([]byte, error) { return append([]byte(nil), s.Data...), nil } func (s *SVCBLocal) pack() ([]byte, error) { return append([]byte(nil), s.Data...), nil }
func (s *SVCBLocal) len() int { return len(s.Data) } func (s *SVCBLocal) len() int { return len(s.Data) }
@ -669,50 +839,10 @@ func (s *SVCBLocal) unpack(b []byte) error {
return nil return nil
} }
func (s *SVCBLocal) String() string {
var str strings.Builder
str.Grow(4 * len(s.Data))
for _, e := range s.Data {
if ' ' <= e && e <= '~' {
switch e {
case '"', ';', ' ', '\\':
str.WriteByte('\\')
str.WriteByte(e)
default:
str.WriteByte(e)
}
} else {
str.WriteString(escapeByte(e))
}
}
return str.String()
}
func (s *SVCBLocal) parse(b string) error { func (s *SVCBLocal) parse(b string) error {
data := make([]byte, 0, len(b)) data, err := svcbParseParam(b)
for i := 0; i < len(b); { if err != nil {
if b[i] != '\\' { return fmt.Errorf("dns: svcblocal: svcb private/experimental key %w", err)
data = append(data, b[i])
i++
continue
}
if i+1 == len(b) {
return errors.New("dns: svcblocal: svcb private/experimental key escape unterminated")
}
if isDigit(b[i+1]) {
if i+3 < len(b) && isDigit(b[i+2]) && isDigit(b[i+3]) {
a, err := strconv.ParseUint(b[i+1:i+4], 10, 8)
if err == nil {
i += 4
data = append(data, byte(a))
continue
}
}
return errors.New("dns: svcblocal: svcb private/experimental key bad escaped octet")
} else {
data = append(data, b[i+1])
i += 2
}
} }
s.Data = data s.Data = data
return nil return nil
@ -753,3 +883,53 @@ func areSVCBPairArraysEqual(a []SVCBKeyValue, b []SVCBKeyValue) bool {
} }
return true return true
} }
// svcbParamStr converts the value of an SVCB parameter into a DNS presentation-format string.
func svcbParamToStr(s []byte) string {
var str strings.Builder
str.Grow(4 * len(s))
for _, e := range s {
if ' ' <= e && e <= '~' {
switch e {
case '"', ';', ' ', '\\':
str.WriteByte('\\')
str.WriteByte(e)
default:
str.WriteByte(e)
}
} else {
str.WriteString(escapeByte(e))
}
}
return str.String()
}
// svcbParseParam parses a DNS presentation-format string into an SVCB parameter value.
func svcbParseParam(b string) ([]byte, error) {
data := make([]byte, 0, len(b))
for i := 0; i < len(b); {
if b[i] != '\\' {
data = append(data, b[i])
i++
continue
}
if i+1 == len(b) {
return nil, errors.New("escape unterminated")
}
if isDigit(b[i+1]) {
if i+3 < len(b) && isDigit(b[i+2]) && isDigit(b[i+3]) {
a, err := strconv.ParseUint(b[i+1:i+4], 10, 8)
if err == nil {
i += 4
data = append(data, byte(a))
continue
}
}
return nil, errors.New("bad escaped octet")
} else {
data = append(data, b[i+1])
i += 2
}
}
return data, nil
}

9
vendor/github.com/miekg/dns/tools.go generated vendored Normal file
View File

@ -0,0 +1,9 @@
// +build tools
// We include our tool dependencies for `go generate` here to ensure they're
// properly tracked by the go tool. See the Go Wiki for the rationale behind this:
// https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module.
package dns
import _ "golang.org/x/tools/go/packages"

65
vendor/github.com/miekg/dns/tsig.go generated vendored
View File

@ -74,6 +74,24 @@ func (key tsigHMACProvider) Verify(msg []byte, t *TSIG) error {
return nil return nil
} }
type tsigSecretProvider map[string]string
func (ts tsigSecretProvider) Generate(msg []byte, t *TSIG) ([]byte, error) {
key, ok := ts[t.Hdr.Name]
if !ok {
return nil, ErrSecret
}
return tsigHMACProvider(key).Generate(msg, t)
}
func (ts tsigSecretProvider) Verify(msg []byte, t *TSIG) error {
key, ok := ts[t.Hdr.Name]
if !ok {
return ErrSecret
}
return tsigHMACProvider(key).Verify(msg, t)
}
// TSIG is the RR the holds the transaction signature of a message. // TSIG is the RR the holds the transaction signature of a message.
// See RFC 2845 and RFC 4635. // See RFC 2845 and RFC 4635.
type TSIG struct { type TSIG struct {
@ -140,18 +158,17 @@ type timerWireFmt struct {
} }
// TsigGenerate fills out the TSIG record attached to the message. // TsigGenerate fills out the TSIG record attached to the message.
// The message should contain // The message should contain a "stub" TSIG RR with the algorithm, key name
// a "stub" TSIG RR with the algorithm, key name (owner name of the RR), // (owner name of the RR), time fudge (defaults to 300 seconds) and the current
// time fudge (defaults to 300 seconds) and the current time // time The TSIG MAC is saved in that Tsig RR. When TsigGenerate is called for
// The TSIG MAC is saved in that Tsig RR. // the first time requestMAC should be set to the empty string and timersOnly to
// When TsigGenerate is called for the first time requestMAC is set to the empty string and // false.
// timersOnly is false.
// If something goes wrong an error is returned, otherwise it is nil.
func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, string, error) { func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, string, error) {
return tsigGenerateProvider(m, tsigHMACProvider(secret), requestMAC, timersOnly) return TsigGenerateWithProvider(m, tsigHMACProvider(secret), requestMAC, timersOnly)
} }
func tsigGenerateProvider(m *Msg, provider TsigProvider, requestMAC string, timersOnly bool) ([]byte, string, error) { // TsigGenerateWithProvider is similar to TsigGenerate, but allows for a custom TsigProvider.
func TsigGenerateWithProvider(m *Msg, provider TsigProvider, requestMAC string, timersOnly bool) ([]byte, string, error) {
if m.IsTsig() == nil { if m.IsTsig() == nil {
panic("dns: TSIG not last RR in additional") panic("dns: TSIG not last RR in additional")
} }
@ -162,20 +179,29 @@ func tsigGenerateProvider(m *Msg, provider TsigProvider, requestMAC string, time
if err != nil { if err != nil {
return nil, "", err return nil, "", err
} }
buf, err := tsigBuffer(mbuf, rr, requestMAC, timersOnly) buf, err := tsigBuffer(mbuf, rr, requestMAC, timersOnly)
if err != nil { if err != nil {
return nil, "", err return nil, "", err
} }
t := new(TSIG) t := new(TSIG)
// Copy all TSIG fields except MAC and its size, which are filled using the computed digest. // Copy all TSIG fields except MAC, its size, and time signed which are filled when signing.
*t = *rr *t = *rr
mac, err := provider.Generate(buf, rr) t.TimeSigned = 0
if err != nil { t.MAC = ""
return nil, "", err t.MACSize = 0
// Sign unless there is a key or MAC validation error (RFC 8945 5.3.2)
if rr.Error != RcodeBadKey && rr.Error != RcodeBadSig {
mac, err := provider.Generate(buf, rr)
if err != nil {
return nil, "", err
}
t.TimeSigned = rr.TimeSigned
t.MAC = hex.EncodeToString(mac)
t.MACSize = uint16(len(t.MAC) / 2) // Size is half!
} }
t.MAC = hex.EncodeToString(mac)
t.MACSize = uint16(len(t.MAC) / 2) // Size is half!
tbuf := make([]byte, Len(t)) tbuf := make([]byte, Len(t))
off, err := PackRR(t, tbuf, 0, nil, false) off, err := PackRR(t, tbuf, 0, nil, false)
@ -189,14 +215,15 @@ func tsigGenerateProvider(m *Msg, provider TsigProvider, requestMAC string, time
return mbuf, t.MAC, nil return mbuf, t.MAC, nil
} }
// TsigVerify verifies the TSIG on a message. // TsigVerify verifies the TSIG on a message. If the signature does not
// If the signature does not validate err contains the // validate the returned error contains the cause. If the signature is OK, the
// error, otherwise it is nil. // error is nil.
func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error { func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error {
return tsigVerify(msg, tsigHMACProvider(secret), requestMAC, timersOnly, uint64(time.Now().Unix())) return tsigVerify(msg, tsigHMACProvider(secret), requestMAC, timersOnly, uint64(time.Now().Unix()))
} }
func tsigVerifyProvider(msg []byte, provider TsigProvider, requestMAC string, timersOnly bool) error { // TsigVerifyWithProvider is similar to TsigVerify, but allows for a custom TsigProvider.
func TsigVerifyWithProvider(msg []byte, provider TsigProvider, requestMAC string, timersOnly bool) error {
return tsigVerify(msg, provider, requestMAC, timersOnly, uint64(time.Now().Unix())) return tsigVerify(msg, provider, requestMAC, timersOnly, uint64(time.Now().Unix()))
} }

View File

@ -32,7 +32,9 @@ func (u *Msg) Used(rr []RR) {
u.Answer = make([]RR, 0, len(rr)) u.Answer = make([]RR, 0, len(rr))
} }
for _, r := range rr { for _, r := range rr {
r.Header().Class = u.Question[0].Qclass hdr := r.Header()
hdr.Class = u.Question[0].Qclass
hdr.Ttl = 0
u.Answer = append(u.Answer, r) u.Answer = append(u.Answer, r)
} }
} }

View File

@ -3,7 +3,7 @@ package dns
import "fmt" import "fmt"
// Version is current version of this library. // Version is current version of this library.
var Version = v{1, 1, 43} var Version = v{1, 1, 50}
// v holds the version of this library. // v holds the version of this library.
type v struct { type v struct {

27
vendor/github.com/miekg/dns/xfr.go generated vendored
View File

@ -17,11 +17,22 @@ type Transfer struct {
DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds
ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds
WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds
TsigProvider TsigProvider // An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations.
TsigSecret map[string]string // Secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2) TsigSecret map[string]string // Secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2)
tsigTimersOnly bool tsigTimersOnly bool
} }
// Think we need to away to stop the transfer func (t *Transfer) tsigProvider() TsigProvider {
if t.TsigProvider != nil {
return t.TsigProvider
}
if t.TsigSecret != nil {
return tsigSecretProvider(t.TsigSecret)
}
return nil
}
// TODO: Think we need to away to stop the transfer
// In performs an incoming transfer with the server in a. // In performs an incoming transfer with the server in a.
// If you would like to set the source IP, or some other attribute // If you would like to set the source IP, or some other attribute
@ -224,12 +235,9 @@ func (t *Transfer) ReadMsg() (*Msg, error) {
if err := m.Unpack(p); err != nil { if err := m.Unpack(p); err != nil {
return nil, err return nil, err
} }
if ts := m.IsTsig(); ts != nil && t.TsigSecret != nil { if ts, tp := m.IsTsig(), t.tsigProvider(); ts != nil && tp != nil {
if _, ok := t.TsigSecret[ts.Hdr.Name]; !ok {
return m, ErrSecret
}
// Need to work on the original message p, as that was used to calculate the tsig. // Need to work on the original message p, as that was used to calculate the tsig.
err = TsigVerify(p, t.TsigSecret[ts.Hdr.Name], t.tsigRequestMAC, t.tsigTimersOnly) err = TsigVerifyWithProvider(p, tp, t.tsigRequestMAC, t.tsigTimersOnly)
t.tsigRequestMAC = ts.MAC t.tsigRequestMAC = ts.MAC
} }
return m, err return m, err
@ -238,11 +246,8 @@ func (t *Transfer) ReadMsg() (*Msg, error) {
// WriteMsg writes a message through the transfer connection t. // WriteMsg writes a message through the transfer connection t.
func (t *Transfer) WriteMsg(m *Msg) (err error) { func (t *Transfer) WriteMsg(m *Msg) (err error) {
var out []byte var out []byte
if ts := m.IsTsig(); ts != nil && t.TsigSecret != nil { if ts, tp := m.IsTsig(), t.tsigProvider(); ts != nil && tp != nil {
if _, ok := t.TsigSecret[ts.Hdr.Name]; !ok { out, t.tsigRequestMAC, err = TsigGenerateWithProvider(m, tp, t.tsigRequestMAC, t.tsigTimersOnly)
return ErrSecret
}
out, t.tsigRequestMAC, err = TsigGenerate(m, t.TsigSecret[ts.Hdr.Name], t.tsigRequestMAC, t.tsigTimersOnly)
} else { } else {
out, err = m.Pack() out, err = m.Pack()
} }

27
vendor/golang.org/x/mod/LICENSE generated vendored Normal file
View File

@ -0,0 +1,27 @@
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

22
vendor/golang.org/x/mod/PATENTS generated vendored Normal file
View File

@ -0,0 +1,22 @@
Additional IP Rights Grant (Patents)
"This implementation" means the copyrightable works distributed by
Google as part of the Go project.
Google 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,
transfer and otherwise run, modify and propagate the contents of this
implementation of Go, where such license applies only to those patent
claims, both currently owned or controlled by Google and acquired in
the future, licensable by Google that are necessarily infringed by this
implementation of Go. This grant does not include claims that would be
infringed only as a consequence of further modification of this
implementation. If you or your agent or exclusive licensee institute or
order or agree to the institution of patent litigation against any
entity (including a cross-claim or counterclaim in a lawsuit) alleging
that this implementation of Go or any code incorporated within this
implementation of Go constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any patent
rights granted to you under this License for this implementation of Go
shall terminate as of the date such litigation is filed.

391
vendor/golang.org/x/mod/semver/semver.go generated vendored Normal file
View File

@ -0,0 +1,391 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package semver implements comparison of semantic version strings.
// In this package, semantic version strings must begin with a leading "v",
// as in "v1.0.0".
//
// The general form of a semantic version string accepted by this package is
//
// vMAJOR[.MINOR[.PATCH[-PRERELEASE][+BUILD]]]
//
// where square brackets indicate optional parts of the syntax;
// MAJOR, MINOR, and PATCH are decimal integers without extra leading zeros;
// PRERELEASE and BUILD are each a series of non-empty dot-separated identifiers
// using only alphanumeric characters and hyphens; and
// all-numeric PRERELEASE identifiers must not have leading zeros.
//
// This package follows Semantic Versioning 2.0.0 (see semver.org)
// with two exceptions. First, it requires the "v" prefix. Second, it recognizes
// vMAJOR and vMAJOR.MINOR (with no prerelease or build suffixes)
// as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0.
package semver
// parsed returns the parsed form of a semantic version string.
type parsed struct {
major string
minor string
patch string
short string
prerelease string
build string
err string
}
// IsValid reports whether v is a valid semantic version string.
func IsValid(v string) bool {
_, ok := parse(v)
return ok
}
// Canonical returns the canonical formatting of the semantic version v.
// It fills in any missing .MINOR or .PATCH and discards build metadata.
// Two semantic versions compare equal only if their canonical formattings
// are identical strings.
// The canonical invalid semantic version is the empty string.
func Canonical(v string) string {
p, ok := parse(v)
if !ok {
return ""
}
if p.build != "" {
return v[:len(v)-len(p.build)]
}
if p.short != "" {
return v + p.short
}
return v
}
// Major returns the major version prefix of the semantic version v.
// For example, Major("v2.1.0") == "v2".
// If v is an invalid semantic version string, Major returns the empty string.
func Major(v string) string {
pv, ok := parse(v)
if !ok {
return ""
}
return v[:1+len(pv.major)]
}
// MajorMinor returns the major.minor version prefix of the semantic version v.
// For example, MajorMinor("v2.1.0") == "v2.1".
// If v is an invalid semantic version string, MajorMinor returns the empty string.
func MajorMinor(v string) string {
pv, ok := parse(v)
if !ok {
return ""
}
i := 1 + len(pv.major)
if j := i + 1 + len(pv.minor); j <= len(v) && v[i] == '.' && v[i+1:j] == pv.minor {
return v[:j]
}
return v[:i] + "." + pv.minor
}
// Prerelease returns the prerelease suffix of the semantic version v.
// For example, Prerelease("v2.1.0-pre+meta") == "-pre".
// If v is an invalid semantic version string, Prerelease returns the empty string.
func Prerelease(v string) string {
pv, ok := parse(v)
if !ok {
return ""
}
return pv.prerelease
}
// Build returns the build suffix of the semantic version v.
// For example, Build("v2.1.0+meta") == "+meta".
// If v is an invalid semantic version string, Build returns the empty string.
func Build(v string) string {
pv, ok := parse(v)
if !ok {
return ""
}
return pv.build
}
// Compare returns an integer comparing two versions according to
// semantic version precedence.
// The result will be 0 if v == w, -1 if v < w, or +1 if v > w.
//
// An invalid semantic version string is considered less than a valid one.
// All invalid semantic version strings compare equal to each other.
func Compare(v, w string) int {
pv, ok1 := parse(v)
pw, ok2 := parse(w)
if !ok1 && !ok2 {
return 0
}
if !ok1 {
return -1
}
if !ok2 {
return +1
}
if c := compareInt(pv.major, pw.major); c != 0 {
return c
}
if c := compareInt(pv.minor, pw.minor); c != 0 {
return c
}
if c := compareInt(pv.patch, pw.patch); c != 0 {
return c
}
return comparePrerelease(pv.prerelease, pw.prerelease)
}
// Max canonicalizes its arguments and then returns the version string
// that compares greater.
//
// Deprecated: use Compare instead. In most cases, returning a canonicalized
// version is not expected or desired.
func Max(v, w string) string {
v = Canonical(v)
w = Canonical(w)
if Compare(v, w) > 0 {
return v
}
return w
}
func parse(v string) (p parsed, ok bool) {
if v == "" || v[0] != 'v' {
p.err = "missing v prefix"
return
}
p.major, v, ok = parseInt(v[1:])
if !ok {
p.err = "bad major version"
return
}
if v == "" {
p.minor = "0"
p.patch = "0"
p.short = ".0.0"
return
}
if v[0] != '.' {
p.err = "bad minor prefix"
ok = false
return
}
p.minor, v, ok = parseInt(v[1:])
if !ok {
p.err = "bad minor version"
return
}
if v == "" {
p.patch = "0"
p.short = ".0"
return
}
if v[0] != '.' {
p.err = "bad patch prefix"
ok = false
return
}
p.patch, v, ok = parseInt(v[1:])
if !ok {
p.err = "bad patch version"
return
}
if len(v) > 0 && v[0] == '-' {
p.prerelease, v, ok = parsePrerelease(v)
if !ok {
p.err = "bad prerelease"
return
}
}
if len(v) > 0 && v[0] == '+' {
p.build, v, ok = parseBuild(v)
if !ok {
p.err = "bad build"
return
}
}
if v != "" {
p.err = "junk on end"
ok = false
return
}
ok = true
return
}
func parseInt(v string) (t, rest string, ok bool) {
if v == "" {
return
}
if v[0] < '0' || '9' < v[0] {
return
}
i := 1
for i < len(v) && '0' <= v[i] && v[i] <= '9' {
i++
}
if v[0] == '0' && i != 1 {
return
}
return v[:i], v[i:], true
}
func parsePrerelease(v string) (t, rest string, ok bool) {
// "A pre-release version MAY be denoted by appending a hyphen and
// a series of dot separated identifiers immediately following the patch version.
// Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-].
// Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes."
if v == "" || v[0] != '-' {
return
}
i := 1
start := 1
for i < len(v) && v[i] != '+' {
if !isIdentChar(v[i]) && v[i] != '.' {
return
}
if v[i] == '.' {
if start == i || isBadNum(v[start:i]) {
return
}
start = i + 1
}
i++
}
if start == i || isBadNum(v[start:i]) {
return
}
return v[:i], v[i:], true
}
func parseBuild(v string) (t, rest string, ok bool) {
if v == "" || v[0] != '+' {
return
}
i := 1
start := 1
for i < len(v) {
if !isIdentChar(v[i]) && v[i] != '.' {
return
}
if v[i] == '.' {
if start == i {
return
}
start = i + 1
}
i++
}
if start == i {
return
}
return v[:i], v[i:], true
}
func isIdentChar(c byte) bool {
return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-'
}
func isBadNum(v string) bool {
i := 0
for i < len(v) && '0' <= v[i] && v[i] <= '9' {
i++
}
return i == len(v) && i > 1 && v[0] == '0'
}
func isNum(v string) bool {
i := 0
for i < len(v) && '0' <= v[i] && v[i] <= '9' {
i++
}
return i == len(v)
}
func compareInt(x, y string) int {
if x == y {
return 0
}
if len(x) < len(y) {
return -1
}
if len(x) > len(y) {
return +1
}
if x < y {
return -1
} else {
return +1
}
}
func comparePrerelease(x, y string) int {
// "When major, minor, and patch are equal, a pre-release version has
// lower precedence than a normal version.
// Example: 1.0.0-alpha < 1.0.0.
// Precedence for two pre-release versions with the same major, minor,
// and patch version MUST be determined by comparing each dot separated
// identifier from left to right until a difference is found as follows:
// identifiers consisting of only digits are compared numerically and
// identifiers with letters or hyphens are compared lexically in ASCII
// sort order. Numeric identifiers always have lower precedence than
// non-numeric identifiers. A larger set of pre-release fields has a
// higher precedence than a smaller set, if all of the preceding
// identifiers are equal.
// Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta <
// 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0."
if x == y {
return 0
}
if x == "" {
return +1
}
if y == "" {
return -1
}
for x != "" && y != "" {
x = x[1:] // skip - or .
y = y[1:] // skip - or .
var dx, dy string
dx, x = nextIdent(x)
dy, y = nextIdent(y)
if dx != dy {
ix := isNum(dx)
iy := isNum(dy)
if ix != iy {
if ix {
return -1
} else {
return +1
}
}
if ix {
if len(dx) < len(dy) {
return -1
}
if len(dx) > len(dy) {
return +1
}
}
if dx < dy {
return -1
} else {
return +1
}
}
}
if x == "" {
return -1
} else {
return +1
}
}
func nextIdent(x string) (dx, rest string) {
i := 0
for i < len(x) && x[i] != '.' {
i++
}
return x[:i], x[i:]
}

6
vendor/golang.org/x/net/bpf/doc.go generated vendored
View File

@ -3,7 +3,6 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
/* /*
Package bpf implements marshaling and unmarshaling of programs for the Package bpf implements marshaling and unmarshaling of programs for the
Berkeley Packet Filter virtual machine, and provides a Go implementation Berkeley Packet Filter virtual machine, and provides a Go implementation
of the virtual machine. of the virtual machine.
@ -21,7 +20,7 @@ access to kernel functions, and while conditional branches are
allowed, they can only jump forwards, to guarantee that there are no allowed, they can only jump forwards, to guarantee that there are no
infinite loops. infinite loops.
The virtual machine # The virtual machine
The BPF VM is an accumulator machine. Its main register, called The BPF VM is an accumulator machine. Its main register, called
register A, is an implicit source and destination in all arithmetic register A, is an implicit source and destination in all arithmetic
@ -50,7 +49,7 @@ to extensions, which are essentially calls to kernel utility
functions. Currently, the only extensions supported by this package functions. Currently, the only extensions supported by this package
are the Linux packet filter extensions. are the Linux packet filter extensions.
Examples # Examples
This packet filter selects all ARP packets. This packet filter selects all ARP packets.
@ -77,6 +76,5 @@ This packet filter captures a random 1% sample of traffic.
// Ignore. // Ignore.
bpf.RetConstant{Val: 0}, bpf.RetConstant{Val: 0},
}) })
*/ */
package bpf // import "golang.org/x/net/bpf" package bpf // import "golang.org/x/net/bpf"

View File

@ -94,7 +94,7 @@ func jumpIfCommon(cond JumpTest, skipTrue, skipFalse uint8, regA uint32, value u
func loadAbsolute(ins LoadAbsolute, in []byte) (uint32, bool) { func loadAbsolute(ins LoadAbsolute, in []byte) (uint32, bool) {
offset := int(ins.Off) offset := int(ins.Off)
size := int(ins.Size) size := ins.Size
return loadCommon(in, offset, size) return loadCommon(in, offset, size)
} }
@ -121,7 +121,7 @@ func loadExtension(ins LoadExtension, in []byte) uint32 {
func loadIndirect(ins LoadIndirect, in []byte, regX uint32) (uint32, bool) { func loadIndirect(ins LoadIndirect, in []byte, regX uint32) (uint32, bool) {
offset := int(ins.Off) + int(regX) offset := int(ins.Off) + int(regX)
size := int(ins.Size) size := ins.Size
return loadCommon(in, offset, size) return loadCommon(in, offset, size)
} }

View File

@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build (arm64 || amd64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && linux //go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && linux
// +build arm64 amd64 ppc64 ppc64le mips64 mips64le riscv64 s390x // +build arm64 amd64 loong64 ppc64 ppc64le mips64 mips64le riscv64 s390x
// +build linux // +build linux
package socket package socket

View File

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

View File

@ -4,22 +4,8 @@
package socket package socket
import "syscall"
func (h *cmsghdr) set(l, lvl, typ int) { func (h *cmsghdr) set(l, lvl, typ int) {
h.Len = int32(l) h.Len = int32(l)
h.Level = int32(lvl) h.Level = int32(lvl)
h.Type = int32(typ) h.Type = int32(typ)
} }
func controlHeaderLen() int {
return syscall.CmsgLen(0)
}
func controlMessageLen(dataLen int) int {
return syscall.CmsgLen(dataLen)
}
func controlMessageSpace(dataLen int) int {
return syscall.CmsgSpace(dataLen)
}

View File

@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build (arm64 || amd64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || zos) //go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || zos)
// +build arm64 amd64 ppc64 ppc64le mips64 mips64le riscv64 s390x // +build arm64 amd64 loong64 ppc64 ppc64le mips64 mips64le riscv64 s390x
// +build aix darwin dragonfly freebsd linux netbsd openbsd zos // +build aix darwin dragonfly freebsd linux netbsd openbsd zos
package socket package socket

View File

@ -9,7 +9,9 @@ package socket
import ( import (
"net" "net"
"os"
"sync" "sync"
"syscall"
) )
type mmsghdrs []mmsghdr type mmsghdrs []mmsghdr
@ -93,22 +95,86 @@ func (p *mmsghdrsPacker) pack(ms []Message, parseFn func([]byte, string) (net.Ad
return hs return hs
} }
var defaultMmsghdrsPool = mmsghdrsPool{ // syscaller is a helper to invoke recvmmsg and sendmmsg via the RawConn.Read/Write interface.
// It is reusable, to amortize the overhead of allocating a closure for the function passed to
// RawConn.Read/Write.
type syscaller struct {
n int
operr error
hs mmsghdrs
flags int
boundRecvmmsgF func(uintptr) bool
boundSendmmsgF func(uintptr) bool
}
func (r *syscaller) init() {
r.boundRecvmmsgF = r.recvmmsgF
r.boundSendmmsgF = r.sendmmsgF
}
func (r *syscaller) recvmmsg(c syscall.RawConn, hs mmsghdrs, flags int) (int, error) {
r.n = 0
r.operr = nil
r.hs = hs
r.flags = flags
if err := c.Read(r.boundRecvmmsgF); err != nil {
return r.n, err
}
if r.operr != nil {
return r.n, os.NewSyscallError("recvmmsg", r.operr)
}
return r.n, nil
}
func (r *syscaller) recvmmsgF(s uintptr) bool {
r.n, r.operr = recvmmsg(s, r.hs, r.flags)
return ioComplete(r.flags, r.operr)
}
func (r *syscaller) sendmmsg(c syscall.RawConn, hs mmsghdrs, flags int) (int, error) {
r.n = 0
r.operr = nil
r.hs = hs
r.flags = flags
if err := c.Write(r.boundSendmmsgF); err != nil {
return r.n, err
}
if r.operr != nil {
return r.n, os.NewSyscallError("sendmmsg", r.operr)
}
return r.n, nil
}
func (r *syscaller) sendmmsgF(s uintptr) bool {
r.n, r.operr = sendmmsg(s, r.hs, r.flags)
return ioComplete(r.flags, r.operr)
}
// mmsgTmps holds reusable temporary helpers for recvmmsg and sendmmsg.
type mmsgTmps struct {
packer mmsghdrsPacker
syscaller syscaller
}
var defaultMmsgTmpsPool = mmsgTmpsPool{
p: sync.Pool{ p: sync.Pool{
New: func() interface{} { New: func() interface{} {
return new(mmsghdrsPacker) tmps := new(mmsgTmps)
tmps.syscaller.init()
return tmps
}, },
}, },
} }
type mmsghdrsPool struct { type mmsgTmpsPool struct {
p sync.Pool p sync.Pool
} }
func (p *mmsghdrsPool) Get() *mmsghdrsPacker { func (p *mmsgTmpsPool) Get() *mmsgTmps {
return p.p.Get().(*mmsghdrsPacker) return p.p.Get().(*mmsgTmps)
} }
func (p *mmsghdrsPool) Put(packer *mmsghdrsPacker) { func (p *mmsgTmpsPool) Put(tmps *mmsgTmps) {
p.p.Put(packer) p.p.Put(tmps)
} }

View File

@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build (arm64 || amd64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && linux //go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && linux
// +build arm64 amd64 ppc64 ppc64le mips64 mips64le riscv64 s390x // +build arm64 amd64 loong64 ppc64 ppc64le mips64 mips64le riscv64 s390x
// +build linux // +build linux
package socket package socket

View File

@ -9,32 +9,23 @@ package socket
import ( import (
"net" "net"
"os"
) )
func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) { func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) {
for i := range ms { for i := range ms {
ms[i].raceWrite() ms[i].raceWrite()
} }
packer := defaultMmsghdrsPool.Get() tmps := defaultMmsgTmpsPool.Get()
defer defaultMmsghdrsPool.Put(packer) defer defaultMmsgTmpsPool.Put(tmps)
var parseFn func([]byte, string) (net.Addr, error) var parseFn func([]byte, string) (net.Addr, error)
if c.network != "tcp" { if c.network != "tcp" {
parseFn = parseInetAddr parseFn = parseInetAddr
} }
hs := packer.pack(ms, parseFn, nil) hs := tmps.packer.pack(ms, parseFn, nil)
var operr error n, err := tmps.syscaller.recvmmsg(c.c, hs, flags)
var n int if err != nil {
fn := func(s uintptr) bool {
n, operr = recvmmsg(s, hs, flags)
return ioComplete(flags, operr)
}
if err := c.c.Read(fn); err != nil {
return n, err return n, err
} }
if operr != nil {
return n, os.NewSyscallError("recvmmsg", operr)
}
if err := hs[:n].unpack(ms[:n], parseFn, c.network); err != nil { if err := hs[:n].unpack(ms[:n], parseFn, c.network); err != nil {
return n, err return n, err
} }
@ -45,25 +36,17 @@ func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) {
for i := range ms { for i := range ms {
ms[i].raceRead() ms[i].raceRead()
} }
packer := defaultMmsghdrsPool.Get() tmps := defaultMmsgTmpsPool.Get()
defer defaultMmsghdrsPool.Put(packer) defer defaultMmsgTmpsPool.Put(tmps)
var marshalFn func(net.Addr, []byte) int var marshalFn func(net.Addr, []byte) int
if c.network != "tcp" { if c.network != "tcp" {
marshalFn = marshalInetAddr marshalFn = marshalInetAddr
} }
hs := packer.pack(ms, nil, marshalFn) hs := tmps.packer.pack(ms, nil, marshalFn)
var operr error n, err := tmps.syscaller.sendmmsg(c.c, hs, flags)
var n int if err != nil {
fn := func(s uintptr) bool {
n, operr = sendmmsg(s, hs, flags)
return ioComplete(flags, operr)
}
if err := c.c.Write(fn); err != nil {
return n, err return n, err
} }
if operr != nil {
return n, os.NewSyscallError("sendmmsg", operr)
}
if err := hs[:n].unpack(ms[:n], nil, ""); err != nil { if err := hs[:n].unpack(ms[:n], nil, ""); err != nil {
return n, err return n, err
} }

View File

@ -8,22 +8,21 @@
package socket package socket
import ( import (
"net"
"os" "os"
) )
func (c *Conn) recvMsg(m *Message, flags int) error { func (c *Conn) recvMsg(m *Message, flags int) error {
m.raceWrite() m.raceWrite()
var h msghdr var (
vs := make([]iovec, len(m.Buffers)) operr error
var sa []byte n int
if c.network != "tcp" { oobn int
sa = make([]byte, sizeofSockaddrInet6) recvflags int
} from net.Addr
h.pack(vs, m.Buffers, m.OOB, sa) )
var operr error
var n int
fn := func(s uintptr) bool { fn := func(s uintptr) bool {
n, operr = recvmsg(s, &h, flags) n, oobn, recvflags, from, operr = recvmsg(s, m.Buffers, m.OOB, flags, c.network)
return ioComplete(flags, operr) return ioComplete(flags, operr)
} }
if err := c.c.Read(fn); err != nil { if err := c.c.Read(fn); err != nil {
@ -32,34 +31,21 @@ func (c *Conn) recvMsg(m *Message, flags int) error {
if operr != nil { if operr != nil {
return os.NewSyscallError("recvmsg", operr) return os.NewSyscallError("recvmsg", operr)
} }
if c.network != "tcp" { m.Addr = from
var err error
m.Addr, err = parseInetAddr(sa[:], c.network)
if err != nil {
return err
}
}
m.N = n m.N = n
m.NN = h.controllen() m.NN = oobn
m.Flags = h.flags() m.Flags = recvflags
return nil return nil
} }
func (c *Conn) sendMsg(m *Message, flags int) error { func (c *Conn) sendMsg(m *Message, flags int) error {
m.raceRead() m.raceRead()
var h msghdr var (
vs := make([]iovec, len(m.Buffers)) operr error
var sa []byte n int
if m.Addr != nil { )
var a [sizeofSockaddrInet6]byte
n := marshalInetAddr(m.Addr, a[:])
sa = a[:n]
}
h.pack(vs, m.Buffers, m.OOB, sa)
var operr error
var n int
fn := func(s uintptr) bool { fn := func(s uintptr) bool {
n, operr = sendmsg(s, &h, flags) n, operr = sendmsg(s, m.Buffers, m.OOB, m.Addr, flags)
return ioComplete(flags, operr) return ioComplete(flags, operr)
} }
if err := c.c.Write(fn); err != nil { if err := c.c.Write(fn); err != nil {

View File

@ -0,0 +1,13 @@
// 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 loong64
// +build loong64
package socket
const (
sysRECVMMSG = 0xf3
sysSENDMMSG = 0x10d
)

View File

@ -36,11 +36,11 @@ func setsockopt(s uintptr, level, name int, b []byte) error {
return errNotImplemented return errNotImplemented
} }
func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) {
return 0, errNotImplemented return 0, 0, 0, nil, errNotImplemented
} }
func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) {
return 0, errNotImplemented return 0, errNotImplemented
} }

View File

@ -8,8 +8,10 @@
package socket package socket
import ( import (
"syscall" "net"
"unsafe" "unsafe"
"golang.org/x/sys/unix"
) )
//go:linkname syscall_getsockopt syscall.getsockopt //go:linkname syscall_getsockopt syscall.getsockopt
@ -18,12 +20,6 @@ func syscall_getsockopt(s, level, name int, val unsafe.Pointer, vallen *uint32)
//go:linkname syscall_setsockopt syscall.setsockopt //go:linkname syscall_setsockopt syscall.setsockopt
func syscall_setsockopt(s, level, name int, val unsafe.Pointer, vallen uintptr) error func syscall_setsockopt(s, level, name int, val unsafe.Pointer, vallen uintptr) error
//go:linkname syscall_recvmsg syscall.recvmsg
func syscall_recvmsg(s int, msg *syscall.Msghdr, flags int) (int, error)
//go:linkname syscall_sendmsg syscall.sendmsg
func syscall_sendmsg(s int, msg *syscall.Msghdr, flags int) (int, error)
func getsockopt(s uintptr, level, name int, b []byte) (int, error) { func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
l := uint32(len(b)) l := uint32(len(b))
err := syscall_getsockopt(int(s), level, name, unsafe.Pointer(&b[0]), &l) err := syscall_getsockopt(int(s), level, name, unsafe.Pointer(&b[0]), &l)
@ -34,10 +30,93 @@ func setsockopt(s uintptr, level, name int, b []byte) error {
return syscall_setsockopt(int(s), level, name, unsafe.Pointer(&b[0]), uintptr(len(b))) return syscall_setsockopt(int(s), level, name, unsafe.Pointer(&b[0]), uintptr(len(b)))
} }
func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) {
return syscall_recvmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags) var unixFrom unix.Sockaddr
n, oobn, recvflags, unixFrom, err = unix.RecvmsgBuffers(int(s), buffers, oob, flags)
if unixFrom != nil {
from = sockaddrToAddr(unixFrom, network)
}
return
} }
func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) {
return syscall_sendmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags) var unixTo unix.Sockaddr
if to != nil {
unixTo = addrToSockaddr(to)
}
return unix.SendmsgBuffers(int(s), buffers, oob, unixTo, flags)
}
// addrToSockaddr converts a net.Addr to a unix.Sockaddr.
func addrToSockaddr(a net.Addr) unix.Sockaddr {
var (
ip net.IP
port int
zone string
)
switch a := a.(type) {
case *net.TCPAddr:
ip = a.IP
port = a.Port
zone = a.Zone
case *net.UDPAddr:
ip = a.IP
port = a.Port
zone = a.Zone
case *net.IPAddr:
ip = a.IP
zone = a.Zone
default:
return nil
}
if ip4 := ip.To4(); ip4 != nil {
sa := unix.SockaddrInet4{Port: port}
copy(sa.Addr[:], ip4)
return &sa
}
if ip6 := ip.To16(); ip6 != nil && ip.To4() == nil {
sa := unix.SockaddrInet6{Port: port}
copy(sa.Addr[:], ip6)
if zone != "" {
sa.ZoneId = uint32(zoneCache.index(zone))
}
return &sa
}
return nil
}
// sockaddrToAddr converts a unix.Sockaddr to a net.Addr.
func sockaddrToAddr(sa unix.Sockaddr, network string) net.Addr {
var (
ip net.IP
port int
zone string
)
switch sa := sa.(type) {
case *unix.SockaddrInet4:
ip = make(net.IP, net.IPv4len)
copy(ip, sa.Addr[:])
port = sa.Port
case *unix.SockaddrInet6:
ip = make(net.IP, net.IPv6len)
copy(ip, sa.Addr[:])
port = sa.Port
if sa.ZoneId > 0 {
zone = zoneCache.name(int(sa.ZoneId))
}
default:
return nil
}
switch network {
case "tcp", "tcp4", "tcp6":
return &net.TCPAddr{IP: ip, Port: port, Zone: zone}
case "udp", "udp4", "udp6":
return &net.UDPAddr{IP: ip, Port: port, Zone: zone}
default:
return &net.IPAddr{IP: ip, Zone: zone}
}
} }

View File

@ -5,6 +5,7 @@
package socket package socket
import ( import (
"net"
"syscall" "syscall"
"unsafe" "unsafe"
@ -37,11 +38,11 @@ func setsockopt(s uintptr, level, name int, b []byte) error {
return syscall.Setsockopt(syscall.Handle(s), int32(level), int32(name), (*byte)(unsafe.Pointer(&b[0])), int32(len(b))) return syscall.Setsockopt(syscall.Handle(s), int32(level), int32(name), (*byte)(unsafe.Pointer(&b[0])), int32(len(b)))
} }
func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) {
return 0, errNotImplemented return 0, 0, 0, nil, errNotImplemented
} }
func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) {
return 0, errNotImplemented return 0, errNotImplemented
} }

View File

@ -5,6 +5,7 @@
package socket package socket
import ( import (
"net"
"syscall" "syscall"
"unsafe" "unsafe"
) )
@ -27,12 +28,39 @@ func setsockopt(s uintptr, level, name int, b []byte) error {
return errnoErr(errno) return errnoErr(errno)
} }
func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) {
n, _, errno := syscall_syscall(syscall.SYS___RECVMSG_A, s, uintptr(unsafe.Pointer(h)), uintptr(flags)) var h msghdr
return int(n), errnoErr(errno) vs := make([]iovec, len(buffers))
var sa []byte
if network != "tcp" {
sa = make([]byte, sizeofSockaddrInet6)
}
h.pack(vs, buffers, oob, sa)
sn, _, errno := syscall_syscall(syscall.SYS___RECVMSG_A, s, uintptr(unsafe.Pointer(&h)), uintptr(flags))
n = int(sn)
oobn = h.controllen()
recvflags = h.flags()
err = errnoErr(errno)
if network != "tcp" {
var err2 error
from, err2 = parseInetAddr(sa, network)
if err2 != nil && err == nil {
err = err2
}
}
return
} }
func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) {
n, _, errno := syscall_syscall(syscall.SYS___SENDMSG_A, s, uintptr(unsafe.Pointer(h)), uintptr(flags)) var h msghdr
vs := make([]iovec, len(buffers))
var sa []byte
if to != nil {
var a [sizeofSockaddrInet6]byte
n := marshalInetAddr(to, a[:])
sa = a[:n]
}
h.pack(vs, buffers, oob, sa)
n, _, errno := syscall_syscall(syscall.SYS___SENDMSG_A, s, uintptr(unsafe.Pointer(&h)), uintptr(flags))
return int(n), errnoErr(errno) return int(n), errnoErr(errno)
} }

View File

@ -1,11 +1,11 @@
// Code generated by cmd/cgo -godefs; DO NOT EDIT. // Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs defs_darwin.go // cgo -godefs defs_freebsd.go
package socket package socket
type iovec struct { type iovec struct {
Base *byte Base *byte
Len uint32 Len uint64
} }
type msghdr struct { type msghdr struct {
@ -25,6 +25,6 @@ type cmsghdr struct {
} }
const ( const (
sizeofIovec = 0x8 sizeofIovec = 0x10
sizeofMsghdr = 0x1c sizeofMsghdr = 0x30
) )

View File

@ -1,30 +1,40 @@
// Code generated by cmd/cgo -godefs; DO NOT EDIT. // Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs defs_darwin.go // cgo -godefs defs_linux.go
//go:build loong64
// +build loong64
package socket package socket
type iovec struct { type iovec struct {
Base *byte Base *byte
Len uint32 Len uint64
} }
type msghdr struct { type msghdr struct {
Name *byte Name *byte
Namelen uint32 Namelen uint32
Iov *iovec Iov *iovec
Iovlen int32 Iovlen uint64
Control *byte Control *byte
Controllen uint32 Controllen uint64
Flags int32 Flags int32
Pad_cgo_0 [4]byte
}
type mmsghdr struct {
Hdr msghdr
Len uint32
Pad_cgo_0 [4]byte
} }
type cmsghdr struct { type cmsghdr struct {
Len uint32 Len uint64
Level int32 Level int32
Type int32 Type int32
} }
const ( const (
sizeofIovec = 0x8 sizeofIovec = 0x10
sizeofMsghdr = 0x1c sizeofMsghdr = 0x38
) )

View File

@ -4,32 +4,32 @@
package socket package socket
type iovec struct { type iovec struct {
Base *byte Base *byte
Len uint32 Len uint32
} }
type msghdr struct { type msghdr struct {
Name *byte Name *byte
Namelen uint32 Namelen uint32
Iov *iovec Iov *iovec
Iovlen uint32 Iovlen uint32
Control *byte Control *byte
Controllen uint32 Controllen uint32
Flags int32 Flags int32
} }
type mmsghdr struct { type mmsghdr struct {
Hdr msghdr Hdr msghdr
Len uint32 Len uint32
} }
type cmsghdr struct { type cmsghdr struct {
Len uint32 Len uint32
Level int32 Level int32
Type int32 Type int32
} }
const ( const (
sizeofIovec = 0x8 sizeofIovec = 0x8
sizeofMsghdr = 0x1c sizeofMsghdr = 0x1c
) )

12
vendor/golang.org/x/net/ipv4/doc.go generated vendored
View File

@ -16,8 +16,7 @@
// 3376. // 3376.
// Source-specific multicast is defined in RFC 4607. // Source-specific multicast is defined in RFC 4607.
// //
// // # Unicasting
// Unicasting
// //
// The options for unicasting are available for net.TCPConn, // The options for unicasting are available for net.TCPConn,
// net.UDPConn and net.IPConn which are created as network connections // net.UDPConn and net.IPConn which are created as network connections
@ -51,8 +50,7 @@
// }(c) // }(c)
// } // }
// //
// // # Multicasting
// Multicasting
// //
// The options for multicasting are available for net.UDPConn and // The options for multicasting are available for net.UDPConn and
// net.IPConn which are created as network connections that use the // net.IPConn which are created as network connections that use the
@ -141,8 +139,7 @@
// } // }
// } // }
// //
// // # More multicasting
// More multicasting
// //
// An application that uses PacketConn or RawConn may join multiple // An application that uses PacketConn or RawConn may join multiple
// multicast groups. For example, a UDP listener with port 1024 might // multicast groups. For example, a UDP listener with port 1024 might
@ -200,8 +197,7 @@
// // error handling // // error handling
// } // }
// //
// // # Source-specific multicasting
// Source-specific multicasting
// //
// An application that uses PacketConn or RawConn on IGMPv3 supported // An application that uses PacketConn or RawConn on IGMPv3 supported
// platform is able to join source-specific multicast groups. // platform is able to join source-specific multicast groups.

52
vendor/golang.org/x/net/ipv4/zsys_freebsd_riscv64.go generated vendored Normal file
View File

@ -0,0 +1,52 @@
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs defs_freebsd.go
package ipv4
const (
sizeofSockaddrStorage = 0x80
sizeofSockaddrInet = 0x10
sizeofIPMreq = 0x8
sizeofIPMreqSource = 0xc
sizeofGroupReq = 0x88
sizeofGroupSourceReq = 0x108
)
type sockaddrStorage struct {
Len uint8
Family uint8
X__ss_pad1 [6]uint8
X__ss_align int64
X__ss_pad2 [112]uint8
}
type sockaddrInet struct {
Len uint8
Family uint8
Port uint16
Addr [4]byte /* in_addr */
Zero [8]uint8
}
type ipMreq struct {
Multiaddr [4]byte /* in_addr */
Interface [4]byte /* in_addr */
}
type ipMreqSource struct {
Multiaddr [4]byte /* in_addr */
Sourceaddr [4]byte /* in_addr */
Interface [4]byte /* in_addr */
}
type groupReq struct {
Interface uint32
Group sockaddrStorage
}
type groupSourceReq struct {
Interface uint32
Group sockaddrStorage
Source sockaddrStorage
}

77
vendor/golang.org/x/net/ipv4/zsys_linux_loong64.go generated vendored Normal file
View File

@ -0,0 +1,77 @@
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs defs_linux.go
//go:build loong64
// +build loong64
package ipv4
const (
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet = 0x10
sizeofInetPktinfo = 0xc
sizeofSockExtendedErr = 0x10
sizeofIPMreq = 0x8
sizeofIPMreqSource = 0xc
sizeofGroupReq = 0x88
sizeofGroupSourceReq = 0x108
sizeofICMPFilter = 0x4
)
type kernelSockaddrStorage struct {
Family uint16
X__data [126]int8
}
type sockaddrInet struct {
Family uint16
Port uint16
Addr [4]byte /* in_addr */
X__pad [8]uint8
}
type inetPktinfo struct {
Ifindex int32
Spec_dst [4]byte /* in_addr */
Addr [4]byte /* in_addr */
}
type sockExtendedErr struct {
Errno uint32
Origin uint8
Type uint8
Code uint8
Pad uint8
Info uint32
Data uint32
}
type ipMreq struct {
Multiaddr [4]byte /* in_addr */
Interface [4]byte /* in_addr */
}
type ipMreqSource struct {
Multiaddr uint32
Interface uint32
Sourceaddr uint32
}
type groupReq struct {
Interface uint32
Pad_cgo_0 [4]byte
Group kernelSockaddrStorage
}
type groupSourceReq struct {
Interface uint32
Pad_cgo_0 [4]byte
Group kernelSockaddrStorage
Source kernelSockaddrStorage
}
type icmpFilter struct {
Data uint32
}

12
vendor/golang.org/x/net/ipv6/doc.go generated vendored
View File

@ -17,8 +17,7 @@
// On Darwin, this package requires OS X Mavericks version 10.9 or // On Darwin, this package requires OS X Mavericks version 10.9 or
// above, or equivalent. // above, or equivalent.
// //
// // # Unicasting
// Unicasting
// //
// The options for unicasting are available for net.TCPConn, // The options for unicasting are available for net.TCPConn,
// net.UDPConn and net.IPConn which are created as network connections // net.UDPConn and net.IPConn which are created as network connections
@ -52,8 +51,7 @@
// }(c) // }(c)
// } // }
// //
// // # Multicasting
// Multicasting
// //
// The options for multicasting are available for net.UDPConn and // The options for multicasting are available for net.UDPConn and
// net.IPConn which are created as network connections that use the // net.IPConn which are created as network connections that use the
@ -140,8 +138,7 @@
// } // }
// } // }
// //
// // # More multicasting
// More multicasting
// //
// An application that uses PacketConn may join multiple multicast // An application that uses PacketConn may join multiple multicast
// groups. For example, a UDP listener with port 1024 might join two // groups. For example, a UDP listener with port 1024 might join two
@ -199,8 +196,7 @@
// // error handling // // error handling
// } // }
// //
// // # Source-specific multicasting
// Source-specific multicasting
// //
// An application that uses PacketConn on MLDv2 supported platform is // An application that uses PacketConn on MLDv2 supported platform is
// able to join source-specific multicast groups. // able to join source-specific multicast groups.

64
vendor/golang.org/x/net/ipv6/zsys_freebsd_riscv64.go generated vendored Normal file
View File

@ -0,0 +1,64 @@
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs defs_freebsd.go
package ipv6
const (
sizeofSockaddrStorage = 0x80
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
sizeofIPv6Mtuinfo = 0x20
sizeofIPv6Mreq = 0x14
sizeofGroupReq = 0x88
sizeofGroupSourceReq = 0x108
sizeofICMPv6Filter = 0x20
)
type sockaddrStorage struct {
Len uint8
Family uint8
X__ss_pad1 [6]uint8
X__ss_align int64
X__ss_pad2 [112]uint8
}
type sockaddrInet6 struct {
Len uint8
Family uint8
Port uint16
Flowinfo uint32
Addr [16]byte /* in6_addr */
Scope_id uint32
}
type inet6Pktinfo struct {
Addr [16]byte /* in6_addr */
Ifindex uint32
}
type ipv6Mtuinfo struct {
Addr sockaddrInet6
Mtu uint32
}
type ipv6Mreq struct {
Multiaddr [16]byte /* in6_addr */
Interface uint32
}
type groupReq struct {
Interface uint32
Group sockaddrStorage
}
type groupSourceReq struct {
Interface uint32
Group sockaddrStorage
Source sockaddrStorage
}
type icmpv6Filter struct {
Filt [8]uint32
}

77
vendor/golang.org/x/net/ipv6/zsys_linux_loong64.go generated vendored Normal file
View File

@ -0,0 +1,77 @@
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs defs_linux.go
//go:build loong64
// +build loong64
package ipv6
const (
sizeofKernelSockaddrStorage = 0x80
sizeofSockaddrInet6 = 0x1c
sizeofInet6Pktinfo = 0x14
sizeofIPv6Mtuinfo = 0x20
sizeofIPv6FlowlabelReq = 0x20
sizeofIPv6Mreq = 0x14
sizeofGroupReq = 0x88
sizeofGroupSourceReq = 0x108
sizeofICMPv6Filter = 0x20
)
type kernelSockaddrStorage struct {
Family uint16
X__data [126]int8
}
type sockaddrInet6 struct {
Family uint16
Port uint16
Flowinfo uint32
Addr [16]byte /* in6_addr */
Scope_id uint32
}
type inet6Pktinfo struct {
Addr [16]byte /* in6_addr */
Ifindex int32
}
type ipv6Mtuinfo struct {
Addr sockaddrInet6
Mtu uint32
}
type ipv6FlowlabelReq struct {
Dst [16]byte /* in6_addr */
Label uint32
Action uint8
Share uint8
Flags uint16
Expires uint16
Linger uint16
X__flr_pad uint32
}
type ipv6Mreq struct {
Multiaddr [16]byte /* in6_addr */
Ifindex int32
}
type groupReq struct {
Interface uint32
Pad_cgo_0 [4]byte
Group kernelSockaddrStorage
}
type groupSourceReq struct {
Interface uint32
Pad_cgo_0 [4]byte
Group kernelSockaddrStorage
Source kernelSockaddrStorage
}
type icmpv6Filter struct {
Data [8]uint32
}

3
vendor/golang.org/x/sys/AUTHORS generated vendored
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.

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.

102
vendor/golang.org/x/sys/execabs/execabs.go generated vendored Normal file
View File

@ -0,0 +1,102 @@
// 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.
// Package execabs is a drop-in replacement for os/exec
// that requires PATH lookups to find absolute paths.
// That is, execabs.Command("cmd") runs the same PATH lookup
// as exec.Command("cmd"), but if the result is a path
// which is relative, the Run and Start methods will report
// an error instead of running the executable.
//
// See https://blog.golang.org/path-security for more information
// about when it may be necessary or appropriate to use this package.
package execabs
import (
"context"
"fmt"
"os/exec"
"path/filepath"
"reflect"
"unsafe"
)
// ErrNotFound is the error resulting if a path search failed to find an executable file.
// It is an alias for exec.ErrNotFound.
var ErrNotFound = exec.ErrNotFound
// Cmd represents an external command being prepared or run.
// It is an alias for exec.Cmd.
type Cmd = exec.Cmd
// Error is returned by LookPath when it fails to classify a file as an executable.
// It is an alias for exec.Error.
type Error = exec.Error
// An ExitError reports an unsuccessful exit by a command.
// It is an alias for exec.ExitError.
type ExitError = exec.ExitError
func relError(file, path string) error {
return fmt.Errorf("%s resolves to executable in current directory (.%c%s)", file, filepath.Separator, path)
}
// LookPath searches for an executable named file in the directories
// named by the PATH environment variable. If file contains a slash,
// it is tried directly and the PATH is not consulted. The result will be
// an absolute path.
//
// LookPath differs from exec.LookPath in its handling of PATH lookups,
// which are used for file names without slashes. If exec.LookPath's
// PATH lookup would have returned an executable from the current directory,
// LookPath instead returns an error.
func LookPath(file string) (string, error) {
path, err := exec.LookPath(file)
if err != nil && !isGo119ErrDot(err) {
return "", err
}
if filepath.Base(file) == file && !filepath.IsAbs(path) {
return "", relError(file, path)
}
return path, nil
}
func fixCmd(name string, cmd *exec.Cmd) {
if filepath.Base(name) == name && !filepath.IsAbs(cmd.Path) {
// exec.Command was called with a bare binary name and
// exec.LookPath returned a path which is not absolute.
// Set cmd.lookPathErr and clear cmd.Path so that it
// cannot be run.
lookPathErr := (*error)(unsafe.Pointer(reflect.ValueOf(cmd).Elem().FieldByName("lookPathErr").Addr().Pointer()))
if *lookPathErr == nil {
*lookPathErr = relError(name, cmd.Path)
}
cmd.Path = ""
}
}
// CommandContext is like Command but includes a context.
//
// The provided context is used to kill the process (by calling os.Process.Kill)
// if the context becomes done before the command completes on its own.
func CommandContext(ctx context.Context, name string, arg ...string) *exec.Cmd {
cmd := exec.CommandContext(ctx, name, arg...)
fixCmd(name, cmd)
return cmd
}
// Command returns the Cmd struct to execute the named program with the given arguments.
// See exec.Command for most details.
//
// Command differs from exec.Command in its handling of PATH lookups,
// which are used when the program name contains no slashes.
// If exec.Command would have returned an exec.Cmd configured to run an
// executable from the current directory, Command instead
// returns an exec.Cmd that will return an error from Start or Run.
func Command(name string, arg ...string) *exec.Cmd {
cmd := exec.Command(name, arg...)
fixCmd(name, cmd)
return cmd
}

12
vendor/golang.org/x/sys/execabs/execabs_go118.go generated vendored Normal file
View File

@ -0,0 +1,12 @@
// 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 !go1.19
// +build !go1.19
package execabs
func isGo119ErrDot(err error) bool {
return false
}

15
vendor/golang.org/x/sys/execabs/execabs_go119.go generated vendored Normal file
View File

@ -0,0 +1,15 @@
// 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 go1.19
// +build go1.19
package execabs
import "strings"
func isGo119ErrDot(err error) bool {
// TODO: return errors.Is(err, exec.ErrDot)
return strings.Contains(err.Error(), "current directory")
}

29
vendor/golang.org/x/sys/unix/asm_bsd_riscv64.s generated vendored Normal file
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)

54
vendor/golang.org/x/sys/unix/asm_linux_loong64.s generated vendored Normal file
View File

@ -0,0 +1,54 @@
// 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 linux && loong64 && gc
// +build linux
// +build loong64
// +build gc
#include "textflag.h"
// 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 ·SyscallNoError(SB),NOSPLIT,$0-48
JAL runtime·entersyscall(SB)
MOVV a1+8(FP), R4
MOVV a2+16(FP), R5
MOVV a3+24(FP), R6
MOVV R0, R7
MOVV R0, R8
MOVV R0, R9
MOVV trap+0(FP), R11 // syscall entry
SYSCALL
MOVV R4, r1+32(FP)
MOVV R0, r2+40(FP) // r2 is not used. Always set to 0
JAL runtime·exitsyscall(SB)
RET
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
JMP syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
JMP syscall·RawSyscall6(SB)
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
MOVV a1+8(FP), R4
MOVV a2+16(FP), R5
MOVV a3+24(FP), R6
MOVV R0, R7
MOVV R0, R8
MOVV R0, R9
MOVV trap+0(FP), R11 // syscall entry
SYSCALL
MOVV R4, r1+32(FP)
MOVV R0, r2+40(FP) // r2 is not used. Always set to 0
RET

View File

@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// //
//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh //go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh
// +build 386 amd64 amd64p32 alpha arm arm64 mipsle mips64le mips64p32le nios2 ppc64le riscv riscv64 sh // +build 386 amd64 amd64p32 alpha arm arm64 loong64 mipsle mips64le mips64p32le nios2 ppc64le riscv riscv64 sh
package unix package unix

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
)

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
)

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
)

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
)

View File

@ -8,7 +8,6 @@
package unix package unix
import ( import (
"bytes"
"unsafe" "unsafe"
) )
@ -45,13 +44,7 @@ func NewIfreq(name string) (*Ifreq, error) {
// Name returns the interface name associated with the Ifreq. // Name returns the interface name associated with the Ifreq.
func (ifr *Ifreq) Name() string { func (ifr *Ifreq) Name() string {
// BytePtrToString requires a NULL terminator or the program may crash. If return ByteSliceToString(ifr.raw.Ifrn[:])
// one is not present, just return the empty string.
if !bytes.Contains(ifr.raw.Ifrn[:], []byte{0x00}) {
return ""
}
return BytePtrToString(&ifr.raw.Ifrn[0])
} }
// According to netdevice(7), only AF_INET addresses are returned for numerous // According to netdevice(7), only AF_INET addresses are returned for numerous

View File

@ -4,9 +4,7 @@
package unix package unix
import ( import "unsafe"
"unsafe"
)
// IoctlRetInt performs an ioctl operation specified by req on a device // IoctlRetInt performs an ioctl operation specified by req on a device
// associated with opened file descriptor fd, and returns a non-negative // associated with opened file descriptor fd, and returns a non-negative
@ -194,3 +192,42 @@ func ioctlIfreqData(fd int, req uint, value *ifreqData) error {
// identical so pass *IfreqData directly. // identical so pass *IfreqData directly.
return ioctlPtr(fd, req, unsafe.Pointer(value)) return ioctlPtr(fd, req, unsafe.Pointer(value))
} }
// IoctlKCMClone attaches a new file descriptor to a multiplexor by cloning an
// existing KCM socket, returning a structure containing the file descriptor of
// the new socket.
func IoctlKCMClone(fd int) (*KCMClone, error) {
var info KCMClone
if err := ioctlPtr(fd, SIOCKCMCLONE, unsafe.Pointer(&info)); err != nil {
return nil, err
}
return &info, nil
}
// IoctlKCMAttach attaches a TCP socket and associated BPF program file
// descriptor to a multiplexor.
func IoctlKCMAttach(fd int, info KCMAttach) error {
return ioctlPtr(fd, SIOCKCMATTACH, unsafe.Pointer(&info))
}
// IoctlKCMUnattach unattaches a TCP socket file descriptor from a multiplexor.
func IoctlKCMUnattach(fd int, info KCMUnattach) error {
return ioctlPtr(fd, SIOCKCMUNATTACH, unsafe.Pointer(&info))
}
// IoctlLoopGetStatus64 gets the status of the loop device associated with the
// file descriptor fd using the LOOP_GET_STATUS64 operation.
func IoctlLoopGetStatus64(fd int) (*LoopInfo64, error) {
var value LoopInfo64
if err := ioctlPtr(fd, LOOP_GET_STATUS64, unsafe.Pointer(&value)); err != nil {
return nil, err
}
return &value, nil
}
// IoctlLoopSetStatus64 sets the status of the loop device associated with the
// file descriptor fd using the LOOP_SET_STATUS64 operation.
func IoctlLoopSetStatus64(fd int, value *LoopInfo64) error {
return ioctlPtr(fd, LOOP_SET_STATUS64, unsafe.Pointer(value))
}

View File

@ -73,12 +73,12 @@ aix_ppc64)
darwin_amd64) darwin_amd64)
mkerrors="$mkerrors -m64" mkerrors="$mkerrors -m64"
mktypes="GOARCH=$GOARCH go tool cgo -godefs" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
mkasm="go run mkasm_darwin.go" mkasm="go run mkasm.go"
;; ;;
darwin_arm64) darwin_arm64)
mkerrors="$mkerrors -m64" mkerrors="$mkerrors -m64"
mktypes="GOARCH=$GOARCH go tool cgo -godefs" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
mkasm="go run mkasm_darwin.go" mkasm="go run mkasm.go"
;; ;;
dragonfly_amd64) dragonfly_amd64)
mkerrors="$mkerrors -m64" mkerrors="$mkerrors -m64"
@ -89,25 +89,30 @@ dragonfly_amd64)
freebsd_386) freebsd_386)
mkerrors="$mkerrors -m32" mkerrors="$mkerrors -m32"
mksyscall="go run mksyscall.go -l32" 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" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;; ;;
freebsd_amd64) freebsd_amd64)
mkerrors="$mkerrors -m64" 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" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;; ;;
freebsd_arm) freebsd_arm)
mkerrors="$mkerrors" mkerrors="$mkerrors"
mksyscall="go run mksyscall.go -l32 -arm" 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 # Let the type of C char be signed for making the bare syscall
# API consistent across platforms. # API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;; ;;
freebsd_arm64) freebsd_arm64)
mkerrors="$mkerrors -m64" 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" mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;; ;;
netbsd_386) netbsd_386)
@ -137,33 +142,33 @@ netbsd_arm64)
mktypes="GOARCH=$GOARCH go tool cgo -godefs" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;; ;;
openbsd_386) openbsd_386)
mkasm="go run mkasm.go"
mkerrors="$mkerrors -m32" mkerrors="$mkerrors -m32"
mksyscall="go run mksyscall.go -l32 -openbsd" mksyscall="go run mksyscall.go -l32 -openbsd -libc"
mksysctl="go run mksysctl_openbsd.go" mksysctl="go run mksysctl_openbsd.go"
mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
mktypes="GOARCH=$GOARCH go tool cgo -godefs" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;; ;;
openbsd_amd64) openbsd_amd64)
mkasm="go run mkasm.go"
mkerrors="$mkerrors -m64" mkerrors="$mkerrors -m64"
mksyscall="go run mksyscall.go -openbsd" mksyscall="go run mksyscall.go -openbsd -libc"
mksysctl="go run mksysctl_openbsd.go" mksysctl="go run mksysctl_openbsd.go"
mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
mktypes="GOARCH=$GOARCH go tool cgo -godefs" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;; ;;
openbsd_arm) openbsd_arm)
mkasm="go run mkasm.go"
mkerrors="$mkerrors" mkerrors="$mkerrors"
mksyscall="go run mksyscall.go -l32 -openbsd -arm" mksyscall="go run mksyscall.go -l32 -openbsd -arm -libc"
mksysctl="go run mksysctl_openbsd.go" mksysctl="go run mksysctl_openbsd.go"
mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
# Let the type of C char be signed for making the bare syscall # Let the type of C char be signed for making the bare syscall
# API consistent across platforms. # API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;; ;;
openbsd_arm64) openbsd_arm64)
mkasm="go run mkasm.go"
mkerrors="$mkerrors -m64" mkerrors="$mkerrors -m64"
mksyscall="go run mksyscall.go -openbsd" mksyscall="go run mksyscall.go -openbsd -libc"
mksysctl="go run mksysctl_openbsd.go" mksysctl="go run mksysctl_openbsd.go"
mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
# Let the type of C char be signed for making the bare syscall # Let the type of C char be signed for making the bare syscall
# API consistent across platforms. # API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
@ -227,5 +232,5 @@ esac
if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
if [ -n "$mktypes" ]; then echo "$mktypes types_$GOOS.go | go run mkpost.go > ztypes_$GOOSARCH.go"; fi if [ -n "$mktypes" ]; then echo "$mktypes types_$GOOS.go | go run mkpost.go > ztypes_$GOOSARCH.go"; fi
if [ -n "$mkasm" ]; then echo "$mkasm $GOARCH"; fi if [ -n "$mkasm" ]; then echo "$mkasm $GOOS $GOARCH"; fi
) | $run ) | $run

View File

@ -128,6 +128,7 @@ includes_FreeBSD='
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/ptrace.h>
#include <net/bpf.h> #include <net/bpf.h>
#include <net/if.h> #include <net/if.h>
#include <net/if_types.h> #include <net/if_types.h>
@ -202,9 +203,11 @@ struct ltchars {
#include <sys/timerfd.h> #include <sys/timerfd.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <sys/xattr.h> #include <sys/xattr.h>
#include <linux/audit.h>
#include <linux/bpf.h> #include <linux/bpf.h>
#include <linux/can.h> #include <linux/can.h>
#include <linux/can/error.h> #include <linux/can/error.h>
#include <linux/can/netlink.h>
#include <linux/can/raw.h> #include <linux/can/raw.h>
#include <linux/capability.h> #include <linux/capability.h>
#include <linux/cryptouser.h> #include <linux/cryptouser.h>
@ -214,6 +217,7 @@ struct ltchars {
#include <linux/ethtool_netlink.h> #include <linux/ethtool_netlink.h>
#include <linux/falloc.h> #include <linux/falloc.h>
#include <linux/fanotify.h> #include <linux/fanotify.h>
#include <linux/fib_rules.h>
#include <linux/filter.h> #include <linux/filter.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/fscrypt.h> #include <linux/fscrypt.h>
@ -231,6 +235,7 @@ struct ltchars {
#include <linux/if_packet.h> #include <linux/if_packet.h>
#include <linux/if_xdp.h> #include <linux/if_xdp.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/kcm.h>
#include <linux/kexec.h> #include <linux/kexec.h>
#include <linux/keyctl.h> #include <linux/keyctl.h>
#include <linux/landlock.h> #include <linux/landlock.h>
@ -261,6 +266,7 @@ struct ltchars {
#include <linux/vm_sockets.h> #include <linux/vm_sockets.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/watchdog.h> #include <linux/watchdog.h>
#include <linux/wireguard.h>
#include <mtd/ubi-user.h> #include <mtd/ubi-user.h>
#include <mtd/mtd-user.h> #include <mtd/mtd-user.h>
@ -291,6 +297,10 @@ struct ltchars {
#define SOL_NETLINK 270 #define SOL_NETLINK 270
#endif #endif
#ifndef SOL_SMC
#define SOL_SMC 286
#endif
#ifdef SOL_BLUETOOTH #ifdef SOL_BLUETOOTH
// SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h // SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h
// but it is already in bluetooth_linux.go // but it is already in bluetooth_linux.go
@ -502,6 +512,7 @@ ccflags="$@"
$2 ~ /^O?XTABS$/ || $2 ~ /^O?XTABS$/ ||
$2 ~ /^TC[IO](ON|OFF)$/ || $2 ~ /^TC[IO](ON|OFF)$/ ||
$2 ~ /^IN_/ || $2 ~ /^IN_/ ||
$2 ~ /^KCM/ ||
$2 ~ /^LANDLOCK_/ || $2 ~ /^LANDLOCK_/ ||
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ || $2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
$2 ~ /^LO_(KEY|NAME)_SIZE$/ || $2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
@ -524,7 +535,7 @@ ccflags="$@"
$2 ~ /^(MS|MNT|MOUNT|UMOUNT)_/ || $2 ~ /^(MS|MNT|MOUNT|UMOUNT)_/ ||
$2 ~ /^NS_GET_/ || $2 ~ /^NS_GET_/ ||
$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ || $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 ~ /^KEXEC_/ ||
$2 ~ /^LINUX_REBOOT_CMD_/ || $2 ~ /^LINUX_REBOOT_CMD_/ ||
$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ || $2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
@ -548,6 +559,7 @@ ccflags="$@"
$2 ~ /^CLONE_[A-Z_]+/ || $2 ~ /^CLONE_[A-Z_]+/ ||
$2 !~ /^(BPF_TIMEVAL|BPF_FIB_LOOKUP_[A-Z]+)$/ && $2 !~ /^(BPF_TIMEVAL|BPF_FIB_LOOKUP_[A-Z]+)$/ &&
$2 ~ /^(BPF|DLT)_/ || $2 ~ /^(BPF|DLT)_/ ||
$2 ~ /^AUDIT_/ ||
$2 ~ /^(CLOCK|TIMER)_/ || $2 ~ /^(CLOCK|TIMER)_/ ||
$2 ~ /^CAN_/ || $2 ~ /^CAN_/ ||
$2 ~ /^CAP_/ || $2 ~ /^CAP_/ ||
@ -570,7 +582,6 @@ ccflags="$@"
$2 ~ /^SEEK_/ || $2 ~ /^SEEK_/ ||
$2 ~ /^SPLICE_/ || $2 ~ /^SPLICE_/ ||
$2 ~ /^SYNC_FILE_RANGE_/ || $2 ~ /^SYNC_FILE_RANGE_/ ||
$2 !~ /^AUDIT_RECORD_MAGIC/ &&
$2 !~ /IOC_MAGIC/ && $2 !~ /IOC_MAGIC/ &&
$2 ~ /^[A-Z][A-Z0-9_]+_MAGIC2?$/ || $2 ~ /^[A-Z][A-Z0-9_]+_MAGIC2?$/ ||
$2 ~ /^(VM|VMADDR)_/ || $2 ~ /^(VM|VMADDR)_/ ||
@ -596,8 +607,10 @@ ccflags="$@"
$2 ~ /^DEVLINK_/ || $2 ~ /^DEVLINK_/ ||
$2 ~ /^ETHTOOL_/ || $2 ~ /^ETHTOOL_/ ||
$2 ~ /^LWTUNNEL_IP/ || $2 ~ /^LWTUNNEL_IP/ ||
$2 ~ /^ITIMER_/ ||
$2 !~ "WMESGLEN" && $2 !~ "WMESGLEN" &&
$2 ~ /^W[A-Z0-9]+$/ || $2 ~ /^W[A-Z0-9]+$/ ||
$2 ~ /^P_/ ||
$2 ~/^PPPIOC/ || $2 ~/^PPPIOC/ ||
$2 ~ /^FAN_|FANOTIFY_/ || $2 ~ /^FAN_|FANOTIFY_/ ||
$2 == "HID_MAX_DESCRIPTOR_SIZE" || $2 == "HID_MAX_DESCRIPTOR_SIZE" ||
@ -606,6 +619,8 @@ ccflags="$@"
$2 ~ /^MTD/ || $2 ~ /^MTD/ ||
$2 ~ /^OTP/ || $2 ~ /^OTP/ ||
$2 ~ /^MEM/ || $2 ~ /^MEM/ ||
$2 ~ /^WG/ ||
$2 ~ /^FIB_RULE_/ ||
$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)} $2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)}
$2 ~ /^__WCOREFLAG$/ {next} $2 ~ /^__WCOREFLAG$/ {next}
$2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)} $2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}

27
vendor/golang.org/x/sys/unix/str.go generated vendored
View File

@ -1,27 +0,0 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package unix
func itoa(val int) string { // do it here rather than with fmt to avoid dependency
if val < 0 {
return "-" + uitoa(uint(-val))
}
return uitoa(uint(val))
}
func uitoa(val uint) string {
var buf [32]byte // big enough for int64
i := len(buf) - 1
for val >= 10 {
buf[i] = byte(val%10 + '0')
i--
val /= 10
}
buf[i] = byte(val + '0')
return string(buf[i:])
}

View File

@ -29,8 +29,6 @@ import (
"bytes" "bytes"
"strings" "strings"
"unsafe" "unsafe"
"golang.org/x/sys/internal/unsafeheader"
) )
// ByteSliceFromString returns a NUL-terminated slice of bytes // ByteSliceFromString returns a NUL-terminated slice of bytes
@ -82,12 +80,7 @@ func BytePtrToString(p *byte) string {
ptr = unsafe.Pointer(uintptr(ptr) + 1) ptr = unsafe.Pointer(uintptr(ptr) + 1)
} }
var s []byte s := unsafe.Slice((*byte)(unsafe.Pointer(p)), n)
h := (*unsafeheader.Slice)(unsafe.Pointer(&s))
h.Data = unsafe.Pointer(p)
h.Len = n
h.Cap = n
return string(s) return string(s)
} }

View File

@ -37,6 +37,7 @@ func Creat(path string, mode uint32) (fd int, err error) {
} }
//sys utimes(path string, times *[2]Timeval) (err error) //sys utimes(path string, times *[2]Timeval) (err error)
func Utimes(path string, tv []Timeval) error { func Utimes(path string, tv []Timeval) error {
if len(tv) != 2 { if len(tv) != 2 {
return EINVAL return EINVAL
@ -45,6 +46,7 @@ func Utimes(path string, tv []Timeval) error {
} }
//sys utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) //sys utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
func UtimesNano(path string, ts []Timespec) error { func UtimesNano(path string, ts []Timespec) error {
if len(ts) != 2 { if len(ts) != 2 {
return EINVAL return EINVAL
@ -215,20 +217,63 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) {
return return
} }
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, 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 var msg Msghdr
sa := new(SockaddrUnix) msg.Name = (*byte)(unsafe.Pointer(rsa))
return -1, -1, -1, sa, ENOSYS msg.Namelen = uint32(SizeofSockaddrAny)
} var dummy byte
if len(oob) > 0 {
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { // receive at least one normal byte
_, err = SendmsgN(fd, p, oob, to, flags) 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))
}
if len(iov) > 0 {
msg.Iov = &iov[0]
msg.SetIovlen(len(iov))
}
if n, err = recvmsg(fd, &msg, flags); n == -1 {
return
}
oobn = int(msg.Controllen)
recvflags = int(msg.Flags)
return return
} }
func SendmsgN(fd int, p, oob []byte, to Sockaddr, 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 var msg Msghdr
return -1, ENOSYS msg.Name = (*byte)(unsafe.Pointer(ptr))
msg.Namelen = uint32(salen)
var dummy byte
var empty bool
if len(oob) > 0 {
// send at least one normal byte
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))
}
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 && empty {
n = 0
}
return n, nil
} }
func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
@ -306,11 +351,13 @@ func direntNamlen(buf []byte) (uint64, bool) {
} }
//sys getdirent(fd int, buf []byte) (n int, err error) //sys getdirent(fd int, buf []byte) (n int, err error)
func Getdents(fd int, buf []byte) (n int, err error) { func Getdents(fd int, buf []byte) (n int, err error) {
return getdirent(fd, buf) return getdirent(fd, buf)
} }
//sys wait4(pid Pid_t, status *_C_int, options int, rusage *Rusage) (wpid Pid_t, err error) //sys wait4(pid Pid_t, status *_C_int, options int, rusage *Rusage) (wpid Pid_t, err error)
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
var status _C_int var status _C_int
var r Pid_t var r Pid_t
@ -378,6 +425,7 @@ func (w WaitStatus) TrapCause() int { return -1 }
//sys fcntl(fd int, cmd int, arg int) (val int, err error) //sys fcntl(fd int, cmd int, arg int) (val int, err error)
//sys fsyncRange(fd int, how int, start int64, length int64) (err error) = fsync_range //sys fsyncRange(fd int, how int, start int64, length int64) (err error) = fsync_range
func Fsync(fd int) error { func Fsync(fd int) error {
return fsyncRange(fd, O_SYNC, 0, 0) return fsyncRange(fd, O_SYNC, 0, 0)
} }
@ -458,8 +506,8 @@ func Fsync(fd int) error {
//sys Listen(s int, n int) (err error) //sys Listen(s int, n int) (err error)
//sys lstat(path string, stat *Stat_t) (err error) //sys lstat(path string, stat *Stat_t) (err error)
//sys Pause() (err error) //sys Pause() (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = pread64 //sys pread(fd int, p []byte, offset int64) (n int, err error) = pread64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = pwrite64 //sys pwrite(fd int, p []byte, offset int64) (n int, err error) = pwrite64
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
//sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) //sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
//sysnb Setregid(rgid int, egid int) (err error) //sysnb Setregid(rgid int, egid int) (err error)
@ -519,8 +567,10 @@ func Pipe(p []int) (err error) {
} }
var pp [2]_C_int var pp [2]_C_int
err = pipe(&pp) err = pipe(&pp)
p[0] = int(pp[0]) if err == nil {
p[1] = int(pp[1]) p[0] = int(pp[0])
p[1] = int(pp[1])
}
return return
} }
@ -540,6 +590,7 @@ func Poll(fds []PollFd, timeout int) (n int, err error) {
//sys Getsystemcfg(label int) (n uint64) //sys Getsystemcfg(label int) (n uint64)
//sys umount(target string) (err error) //sys umount(target string) (err error)
func Unmount(target string, flags int) (err error) { func Unmount(target string, flags int) (err error) {
if flags != 0 { if flags != 0 {
// AIX doesn't have any flags for umount. // AIX doesn't have any flags for umount.

View File

@ -325,80 +325,62 @@ func GetsockoptString(fd, level, opt int) (string, error) {
//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err 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) //sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
var msg Msghdr var msg Msghdr
var rsa RawSockaddrAny msg.Name = (*byte)(unsafe.Pointer(rsa))
msg.Name = (*byte)(unsafe.Pointer(&rsa))
msg.Namelen = uint32(SizeofSockaddrAny) 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 var dummy byte
if len(oob) > 0 { if len(oob) > 0 {
// receive at least one normal byte // receive at least one normal byte
if len(p) == 0 { if emptyIovecs(iov) {
iov.Base = &dummy var iova [1]Iovec
iov.SetLen(1) iova[0].Base = &dummy
iova[0].SetLen(1)
iov = iova[:]
} }
msg.Control = (*byte)(unsafe.Pointer(&oob[0])) msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
msg.SetControllen(len(oob)) msg.SetControllen(len(oob))
} }
msg.Iov = &iov if len(iov) > 0 {
msg.Iovlen = 1 msg.Iov = &iov[0]
msg.SetIovlen(len(iov))
}
if n, err = recvmsg(fd, &msg, flags); err != nil { if n, err = recvmsg(fd, &msg, flags); err != nil {
return return
} }
oobn = int(msg.Controllen) oobn = int(msg.Controllen)
recvflags = int(msg.Flags) recvflags = int(msg.Flags)
// source address is only specified if the socket is unconnected
if rsa.Addr.Family != AF_UNSPEC {
from, err = anyToSockaddr(fd, &rsa)
}
return return
} }
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n 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 ptr unsafe.Pointer
var salen _Socklen
if to != nil {
ptr, salen, err = to.sockaddr()
if err != nil {
return 0, err
}
}
var msg Msghdr var msg Msghdr
msg.Name = (*byte)(unsafe.Pointer(ptr)) msg.Name = (*byte)(unsafe.Pointer(ptr))
msg.Namelen = uint32(salen) 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 dummy byte
var empty bool
if len(oob) > 0 { if len(oob) > 0 {
// send at least one normal byte // send at least one normal byte
if len(p) == 0 { empty = emptyIovecs(iov)
iov.Base = &dummy if empty {
iov.SetLen(1) var iova [1]Iovec
iova[0].Base = &dummy
iova[0].SetLen(1)
iov = iova[:]
} }
msg.Control = (*byte)(unsafe.Pointer(&oob[0])) msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
msg.SetControllen(len(oob)) msg.SetControllen(len(oob))
} }
msg.Iov = &iov if len(iov) > 0 {
msg.Iovlen = 1 msg.Iov = &iov[0]
msg.SetIovlen(len(iov))
}
if n, err = sendmsg(fd, &msg, flags); err != nil { if n, err = sendmsg(fd, &msg, flags); err != nil {
return 0, err return 0, err
} }
if len(oob) > 0 && len(p) == 0 { if len(oob) > 0 && empty {
n = 0 n = 0
} }
return n, nil return n, nil
@ -571,12 +553,7 @@ func UtimesNano(path string, ts []Timespec) error {
if len(ts) != 2 { if len(ts) != 2 {
return EINVAL return EINVAL
} }
// Darwin setattrlist can set nanosecond timestamps err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
err := setattrlistTimes(path, ts, 0)
if err != ENOSYS {
return err
}
err = utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
if err != ENOSYS { if err != ENOSYS {
return err return err
} }
@ -596,10 +573,6 @@ func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
if len(ts) != 2 { if len(ts) != 2 {
return EINVAL return EINVAL
} }
err := setattrlistTimes(path, ts, flags)
if err != ENOSYS {
return err
}
return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags) return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
} }

View File

@ -7,11 +7,7 @@
package unix package unix
import ( import "unsafe"
"unsafe"
"golang.org/x/sys/internal/unsafeheader"
)
//sys closedir(dir uintptr) (err error) //sys closedir(dir uintptr) (err error)
//sys readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) //sys readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno)
@ -86,11 +82,7 @@ func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
} }
// Copy entry into return buffer. // Copy entry into return buffer.
var s []byte s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&s))
hdr.Data = unsafe.Pointer(&entry)
hdr.Cap = reclen
hdr.Len = reclen
copy(buf, s) copy(buf, s)
buf = buf[reclen:] buf = buf[reclen:]

View File

@ -141,16 +141,6 @@ func direntNamlen(buf []byte) (uint64, bool) {
func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) } func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) }
func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) } func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) }
type attrList struct {
bitmapCount uint16
_ uint16
CommonAttr uint32
VolAttr uint32
DirAttr uint32
FileAttr uint32
Forkattr uint32
}
//sysnb pipe(p *[2]int32) (err error) //sysnb pipe(p *[2]int32) (err error)
func Pipe(p []int) (err error) { func Pipe(p []int) (err error) {
@ -159,8 +149,10 @@ func Pipe(p []int) (err error) {
} }
var x [2]int32 var x [2]int32
err = pipe(&x) err = pipe(&x)
p[0] = int(x[0]) if err == nil {
p[1] = int(x[1]) p[0] = int(x[0])
p[1] = int(x[1])
}
return return
} }
@ -280,36 +272,7 @@ func Flistxattr(fd int, dest []byte) (sz int, err error) {
return flistxattr(fd, xattrPointer(dest), len(dest), 0) return flistxattr(fd, xattrPointer(dest), len(dest), 0)
} }
func setattrlistTimes(path string, times []Timespec, flags int) error { //sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)
_p0, err := BytePtrFromString(path)
if err != nil {
return err
}
var attrList attrList
attrList.bitmapCount = ATTR_BIT_MAP_COUNT
attrList.CommonAttr = ATTR_CMN_MODTIME | ATTR_CMN_ACCTIME
// order is mtime, atime: the opposite of Chtimes
attributes := [2]Timespec{times[1], times[0]}
options := 0
if flags&AT_SYMLINK_NOFOLLOW != 0 {
options |= FSOPT_NOFOLLOW
}
return setattrlist(
_p0,
unsafe.Pointer(&attrList),
unsafe.Pointer(&attributes),
unsafe.Sizeof(attributes),
options)
}
//sys setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error)
func utimensat(dirfd int, path string, times *[2]Timespec, flags int) error {
// Darwin doesn't support SYS_UTIMENSAT
return ENOSYS
}
/* /*
* Wrapped * Wrapped
@ -430,6 +393,13 @@ func GetsockoptXucred(fd, level, opt int) (*Xucred, error) {
return x, err 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) { func SysctlKinfoProc(name string, args ...int) (*KinfoProc, error) {
mib, err := sysctlmib(name, args...) mib, err := sysctlmib(name, args...)
if err != nil { if err != nil {
@ -541,11 +511,12 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
//sys Mkdirat(dirfd int, 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 Mkfifo(path string, mode uint32) (err error)
//sys Mknod(path string, mode uint32, dev int) (err error) //sys Mknod(path string, mode uint32, dev int) (err error)
//sys Mount(fsType string, dir string, flags int, data unsafe.Pointer) (err error)
//sys Open(path string, mode int, perm uint32) (fd int, err error) //sys Open(path string, mode int, perm uint32) (fd int, err error)
//sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) //sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error)
//sys Pathconf(path string, name int) (val int, err error) //sys Pathconf(path string, name int) (val int, err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) //sys pread(fd int, p []byte, offset int64) (n int, err error)
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) //sys pwrite(fd int, p []byte, offset int64) (n int, err error)
//sys read(fd int, p []byte) (n int, err error) //sys read(fd int, p []byte) (n int, err error)
//sys Readlink(path string, buf []byte) (n int, err error) //sys Readlink(path string, buf []byte) (n int, err error)
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error) //sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
@ -609,7 +580,6 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
// Nfssvc // Nfssvc
// Getfh // Getfh
// Quotactl // Quotactl
// Mount
// Csops // Csops
// Waitid // Waitid
// Add_profil // Add_profil

View File

@ -101,7 +101,10 @@ func Pipe(p []int) (err error) {
if len(p) != 2 { if len(p) != 2 {
return EINVAL return EINVAL
} }
p[0], p[1], err = pipe() r, w, err := pipe()
if err == nil {
p[0], p[1] = r, w
}
return return
} }
@ -114,17 +117,22 @@ func Pipe2(p []int, flags int) (err error) {
var pp [2]_C_int var pp [2]_C_int
// pipe2 on dragonfly takes an fds array as an argument, but still // pipe2 on dragonfly takes an fds array as an argument, but still
// returns the file descriptors. // returns the file descriptors.
p[0], p[1], err = pipe2(&pp, flags) r, w, err := pipe2(&pp, flags)
if err == nil {
p[0], p[1] = r, w
}
return err return err
} }
//sys extpread(fd int, p []byte, flags int, offset int64) (n int, err error) //sys extpread(fd int, p []byte, flags int, offset int64) (n int, err error)
func Pread(fd int, p []byte, offset int64) (n int, err error) {
func pread(fd int, p []byte, offset int64) (n int, err error) {
return extpread(fd, p, 0, offset) return extpread(fd, p, 0, offset)
} }
//sys extpwrite(fd int, p []byte, flags int, offset int64) (n int, err error) //sys extpwrite(fd int, p []byte, flags int, offset int64) (n int, err error)
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
func pwrite(fd int, p []byte, offset int64) (n int, err error) {
return extpwrite(fd, p, 0, offset) return extpwrite(fd, p, 0, offset)
} }
@ -163,11 +171,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
return return
} }
func setattrlistTimes(path string, times []Timespec, flags int) error {
// used on Darwin for UtimesNano
return ENOSYS
}
//sys ioctl(fd int, req uint, arg uintptr) (err error) //sys ioctl(fd int, req uint, arg uintptr) (err error)
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL //sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL

View File

@ -17,25 +17,12 @@ import (
"unsafe" "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. // See https://www.freebsd.org/doc/en_US.ISO8859-1/books/porters-handbook/versions.html.
var ( var (
osreldateOnce sync.Once osreldateOnce sync.Once
osreldate uint32 osreldate uint32
) )
// INO64_FIRST from /usr/src/lib/libc/sys/compat-ino64.h
const _ino64First = 1200031
func supportsABI(ver uint32) bool { func supportsABI(ver uint32) bool {
osreldateOnce.Do(func() { osreldate, _ = SysctlUint32("kern.osreldate") }) osreldateOnce.Do(func() { osreldate, _ = SysctlUint32("kern.osreldate") })
return osreldate >= ver return osreldate >= ver
@ -110,8 +97,10 @@ func Pipe2(p []int, flags int) error {
} }
var pp [2]_C_int var pp [2]_C_int
err := pipe2(&pp, flags) err := pipe2(&pp, flags)
p[0] = int(pp[0]) if err == nil {
p[1] = int(pp[1]) p[0] = int(pp[0])
p[1] = int(pp[1])
}
return err return err
} }
@ -157,46 +146,21 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) {
func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
var ( var (
_p0 unsafe.Pointer _p0 unsafe.Pointer
bufsize uintptr bufsize uintptr
oldBuf []statfs_freebsd11_t
needsConvert bool
) )
if len(buf) > 0 { if len(buf) > 0 {
if supportsABI(_ino64First) { _p0 = unsafe.Pointer(&buf[0])
_p0 = unsafe.Pointer(&buf[0]) bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
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
}
} }
var sysno uintptr = SYS_GETFSSTAT r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
if supportsABI(_ino64First) {
sysno = SYS_GETFSSTAT_FREEBSD12
}
r0, _, e1 := Syscall(sysno, uintptr(_p0), bufsize, uintptr(flags))
n = int(r0) n = int(r0)
if e1 != 0 { if e1 != 0 {
err = e1 err = e1
} }
if e1 == 0 && needsConvert {
for i := range oldBuf {
buf[i].convertFrom(&oldBuf[i])
}
}
return return
} }
func setattrlistTimes(path string, times []Timespec, flags int) error {
// used on Darwin for UtimesNano
return ENOSYS
}
//sys ioctl(fd int, req uint, arg uintptr) (err error) //sys ioctl(fd int, req uint, arg uintptr) (err error)
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL //sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
@ -248,87 +212,11 @@ func Uname(uname *Utsname) error {
} }
func Stat(path string, st *Stat_t) (err error) { func Stat(path string, st *Stat_t) (err error) {
var oldStat stat_freebsd11_t return Fstatat(AT_FDCWD, path, st, 0)
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
} }
func Lstat(path string, st *Stat_t) (err error) { func Lstat(path string, st *Stat_t) (err error) {
var oldStat stat_freebsd11_t return Fstatat(AT_FDCWD, path, st, AT_SYMLINK_NOFOLLOW)
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
} }
func Getdents(fd int, buf []byte) (n int, err error) { func Getdents(fd int, buf []byte) (n int, err error) {
@ -336,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) { func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
if supportsABI(_ino64First) { if basep == nil || unsafe.Sizeof(*basep) == 8 {
if basep == nil || unsafe.Sizeof(*basep) == 8 { return getdirentries(fd, buf, (*uint64)(unsafe.Pointer(basep)))
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
} }
// The syscall needs a 64-bit base. On 32-bit machines
// The old syscall entries are smaller than the new. Use 1/4 of the original // we can't just use the basep passed in. See #32498.
// buffer size rounded up to DIRBLKSIZ (see /usr/src/lib/libc/sys/getdirentries.c). var base uint64 = uint64(*basep)
oldBufLen := roundup(len(buf)/4, _dirblksiz) n, err = getdirentries(fd, buf, &base)
oldBuf := make([]byte, oldBufLen) *basep = uintptr(base)
n, err = getdirentries(fd, oldBuf, basep) if base>>32 != 0 {
if err == nil && n > 0 { // We can't stuff the base back into a uintptr, so any
n = convertFromDirents11(buf, oldBuf[:n]) // future calls would be suspect. Generate an error.
// EIO is allowed by getdirentries.
err = EIO
} }
return return
} }
func Mknod(path string, mode uint32, dev uint64) (err error) { func Mknod(path string, mode uint32, dev uint64) (err error) {
var oldDev int return Mknodat(AT_FDCWD, path, mode, dev)
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
} }
func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
@ -504,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) //sys ptrace(request int, pid int, addr uintptr, data int) (err error)
func PtraceAttach(pid 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) { 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) { 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) { 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) { 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) { 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) { 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) { func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
@ -548,11 +299,11 @@ func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
} }
func PtraceSetRegs(pid int, regs *Reg) (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) { func PtraceSingleStep(pid int) (err error) {
return ptrace(PTRACE_SINGLESTEP, pid, 1, 0) return ptrace(PT_STEP, pid, 1, 0)
} }
/* /*
@ -594,16 +345,12 @@ func PtraceSingleStep(pid int) (err error) {
//sys Fchownat(dirfd int, path string, uid int, gid int, flags 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 Flock(fd int, how int) (err error)
//sys Fpathconf(fd int, name int) (val 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(fd int, stat *Stat_t) (err error)
//sys fstat_freebsd12(fd int, stat *Stat_t) (err error) //sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
//sys fstatat(fd int, path string, stat *stat_freebsd11_t, flags int) (err error) //sys Fstatfs(fd int, stat *Statfs_t) (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 Fsync(fd int) (err error) //sys Fsync(fd int) (err error)
//sys Ftruncate(fd int, length int64) (err error) //sys Ftruncate(fd int, length int64) (err error)
//sys getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) //sys getdirentries(fd int, buf []byte, basep *uint64) (n int, err error)
//sys getdirentries_freebsd12(fd int, buf []byte, basep *uint64) (n int, err error)
//sys Getdtablesize() (size int) //sys Getdtablesize() (size int)
//sysnb Getegid() (egid int) //sysnb Getegid() (egid int)
//sysnb Geteuid() (uid int) //sysnb Geteuid() (uid int)
@ -625,19 +372,16 @@ func PtraceSingleStep(pid int) (err error) {
//sys Link(path string, link string) (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 Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error)
//sys Listen(s int, backlog 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 Mkdir(path string, mode uint32) (err error)
//sys Mkdirat(dirfd int, 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 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 uint64) (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 Nanosleep(time *Timespec, leftover *Timespec) (err error) //sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
//sys Open(path string, mode int, perm uint32) (fd int, 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) //sys Openat(fdat int, path string, mode int, perm uint32) (fd int, err error)
//sys Pathconf(path string, name int) (val int, err error) //sys Pathconf(path string, name int) (val int, err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) //sys pread(fd int, p []byte, offset int64) (n int, err error)
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) //sys pwrite(fd int, p []byte, offset int64) (n int, err error)
//sys read(fd int, p []byte) (n int, err error) //sys read(fd int, p []byte) (n int, err error)
//sys Readlink(path string, buf []byte) (n int, err error) //sys Readlink(path string, buf []byte) (n int, err error)
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error) //sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
@ -661,9 +405,7 @@ func PtraceSingleStep(pid int) (err error) {
//sysnb Setsid() (pid int, err error) //sysnb Setsid() (pid int, err error)
//sysnb Settimeofday(tp *Timeval) (err error) //sysnb Settimeofday(tp *Timeval) (err error)
//sysnb Setuid(uid int) (err error) //sysnb Setuid(uid int) (err error)
//sys stat(path string, stat *stat_freebsd11_t) (err error) //sys Statfs(path string, stat *Statfs_t) (err error)
//sys statfs(path string, stat *statfs_freebsd11_t) (err error)
//sys statfs_freebsd12(path string, stat *Statfs_t) (err error)
//sys Symlink(path string, link string) (err error) //sys Symlink(path string, link string) (err error)
//sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error) //sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error)
//sys Sync() (err error) //sys Sync() (err error)

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 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) { 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) { 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)} ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(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 return int(ioDesc.Len), err
} }

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 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) { 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) { 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)} ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(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 return int(ioDesc.Len), err
} }

View File

@ -57,7 +57,7 @@ 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 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) { 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)} ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(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 return int(ioDesc.Len), err
} }

View File

@ -57,7 +57,7 @@ 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 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) { 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)} ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(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 return int(ioDesc.Len), err
} }

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: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint64(countin)}
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
return int(ioDesc.Len), err
}

View File

@ -20,10 +20,9 @@ func bytes2iovec(bs [][]byte) []Iovec {
for i, b := range bs { for i, b := range bs {
iovecs[i].SetLen(len(b)) iovecs[i].SetLen(len(b))
if len(b) > 0 { if len(b) > 0 {
// somehow Iovec.Base on illumos is (*int8), not (*byte) iovecs[i].Base = &b[0]
iovecs[i].Base = (*int8)(unsafe.Pointer(&b[0]))
} else { } else {
iovecs[i].Base = (*int8)(unsafe.Pointer(&_zero)) iovecs[i].Base = (*byte)(unsafe.Pointer(&_zero))
} }
} }
return iovecs return iovecs

View File

@ -13,7 +13,9 @@ package unix
import ( import (
"encoding/binary" "encoding/binary"
"strconv"
"syscall" "syscall"
"time"
"unsafe" "unsafe"
) )
@ -131,8 +133,10 @@ func Pipe2(p []int, flags int) error {
} }
var pp [2]_C_int var pp [2]_C_int
err := pipe2(&pp, flags) err := pipe2(&pp, flags)
p[0] = int(pp[0]) if err == nil {
p[1] = int(pp[1]) p[0] = int(pp[0])
p[1] = int(pp[1])
}
return err return err
} }
@ -230,7 +234,7 @@ func Futimesat(dirfd int, path string, tv []Timeval) error {
func Futimes(fd int, tv []Timeval) (err error) { func Futimes(fd int, tv []Timeval) (err error) {
// Believe it or not, this is the best we can do on Linux // Believe it or not, this is the best we can do on Linux
// (and is what glibc does). // (and is what glibc does).
return Utimes("/proc/self/fd/"+itoa(fd), tv) return Utimes("/proc/self/fd/"+strconv.Itoa(fd), tv)
} }
const ImplementsGetwd = true const ImplementsGetwd = true
@ -247,6 +251,13 @@ func Getwd() (wd string, err error) {
if n < 1 || n > len(buf) || buf[n-1] != 0 { if n < 1 || n > len(buf) || buf[n-1] != 0 {
return "", EINVAL return "", EINVAL
} }
// In some cases, Linux can return a path that starts with the
// "(unreachable)" prefix, which can potentially be a valid relative
// path. To work around that, return ENOENT if path is not absolute.
if buf[0] != '/' {
return "", ENOENT
}
return string(buf[0 : n-1]), nil return string(buf[0 : n-1]), nil
} }
@ -356,6 +367,8 @@ func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int,
return return
} }
//sys Waitid(idType int, id int, info *Siginfo, options int, rusage *Rusage) (err error)
func Mkfifo(path string, mode uint32) error { func Mkfifo(path string, mode uint32) error {
return Mknod(path, mode|S_IFIFO, 0) return Mknod(path, mode|S_IFIFO, 0)
} }
@ -500,24 +513,24 @@ func (sa *SockaddrL2) sockaddr() (unsafe.Pointer, _Socklen, error) {
// //
// Server example: // Server example:
// //
// fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM) // fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)
// _ = unix.Bind(fd, &unix.SockaddrRFCOMM{ // _ = unix.Bind(fd, &unix.SockaddrRFCOMM{
// Channel: 1, // Channel: 1,
// Addr: [6]uint8{0, 0, 0, 0, 0, 0}, // BDADDR_ANY or 00:00:00:00:00:00 // Addr: [6]uint8{0, 0, 0, 0, 0, 0}, // BDADDR_ANY or 00:00:00:00:00:00
// }) // })
// _ = Listen(fd, 1) // _ = Listen(fd, 1)
// nfd, sa, _ := Accept(fd) // nfd, sa, _ := Accept(fd)
// fmt.Printf("conn addr=%v fd=%d", sa.(*unix.SockaddrRFCOMM).Addr, nfd) // fmt.Printf("conn addr=%v fd=%d", sa.(*unix.SockaddrRFCOMM).Addr, nfd)
// Read(nfd, buf) // Read(nfd, buf)
// //
// Client example: // Client example:
// //
// fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM) // fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)
// _ = Connect(fd, &SockaddrRFCOMM{ // _ = Connect(fd, &SockaddrRFCOMM{
// Channel: 1, // Channel: 1,
// Addr: [6]byte{0x11, 0x22, 0x33, 0xaa, 0xbb, 0xcc}, // CC:BB:AA:33:22:11 // Addr: [6]byte{0x11, 0x22, 0x33, 0xaa, 0xbb, 0xcc}, // CC:BB:AA:33:22:11
// }) // })
// Write(fd, []byte(`hello`)) // Write(fd, []byte(`hello`))
type SockaddrRFCOMM struct { type SockaddrRFCOMM struct {
// Addr represents a bluetooth address, byte ordering is little-endian. // Addr represents a bluetooth address, byte ordering is little-endian.
Addr [6]uint8 Addr [6]uint8
@ -544,12 +557,12 @@ func (sa *SockaddrRFCOMM) sockaddr() (unsafe.Pointer, _Socklen, error) {
// The SockaddrCAN struct must be bound to the socket file descriptor // The SockaddrCAN struct must be bound to the socket file descriptor
// using Bind before the CAN socket can be used. // using Bind before the CAN socket can be used.
// //
// // Read one raw CAN frame // // Read one raw CAN frame
// fd, _ := Socket(AF_CAN, SOCK_RAW, CAN_RAW) // fd, _ := Socket(AF_CAN, SOCK_RAW, CAN_RAW)
// addr := &SockaddrCAN{Ifindex: index} // addr := &SockaddrCAN{Ifindex: index}
// Bind(fd, addr) // Bind(fd, addr)
// frame := make([]byte, 16) // frame := make([]byte, 16)
// Read(fd, frame) // Read(fd, frame)
// //
// The full SocketCAN documentation can be found in the linux kernel // The full SocketCAN documentation can be found in the linux kernel
// archives at: https://www.kernel.org/doc/Documentation/networking/can.txt // archives at: https://www.kernel.org/doc/Documentation/networking/can.txt
@ -620,13 +633,13 @@ func (sa *SockaddrCANJ1939) sockaddr() (unsafe.Pointer, _Socklen, error) {
// Here is an example of using an AF_ALG socket with SHA1 hashing. // Here is an example of using an AF_ALG socket with SHA1 hashing.
// The initial socket setup process is as follows: // The initial socket setup process is as follows:
// //
// // Open a socket to perform SHA1 hashing. // // Open a socket to perform SHA1 hashing.
// fd, _ := unix.Socket(unix.AF_ALG, unix.SOCK_SEQPACKET, 0) // fd, _ := unix.Socket(unix.AF_ALG, unix.SOCK_SEQPACKET, 0)
// addr := &unix.SockaddrALG{Type: "hash", Name: "sha1"} // addr := &unix.SockaddrALG{Type: "hash", Name: "sha1"}
// unix.Bind(fd, addr) // unix.Bind(fd, addr)
// // Note: unix.Accept does not work at this time; must invoke accept() // // Note: unix.Accept does not work at this time; must invoke accept()
// // manually using unix.Syscall. // // manually using unix.Syscall.
// hashfd, _, _ := unix.Syscall(unix.SYS_ACCEPT, uintptr(fd), 0, 0) // hashfd, _, _ := unix.Syscall(unix.SYS_ACCEPT, uintptr(fd), 0, 0)
// //
// Once a file descriptor has been returned from Accept, it may be used to // Once a file descriptor has been returned from Accept, it may be used to
// perform SHA1 hashing. The descriptor is not safe for concurrent use, but // perform SHA1 hashing. The descriptor is not safe for concurrent use, but
@ -635,39 +648,39 @@ func (sa *SockaddrCANJ1939) sockaddr() (unsafe.Pointer, _Socklen, error) {
// When hashing a small byte slice or string, a single Write and Read may // When hashing a small byte slice or string, a single Write and Read may
// be used: // be used:
// //
// // Assume hashfd is already configured using the setup process. // // Assume hashfd is already configured using the setup process.
// hash := os.NewFile(hashfd, "sha1") // hash := os.NewFile(hashfd, "sha1")
// // Hash an input string and read the results. Each Write discards // // Hash an input string and read the results. Each Write discards
// // previous hash state. Read always reads the current state. // // previous hash state. Read always reads the current state.
// b := make([]byte, 20) // b := make([]byte, 20)
// for i := 0; i < 2; i++ { // for i := 0; i < 2; i++ {
// io.WriteString(hash, "Hello, world.") // io.WriteString(hash, "Hello, world.")
// hash.Read(b) // hash.Read(b)
// fmt.Println(hex.EncodeToString(b)) // fmt.Println(hex.EncodeToString(b))
// } // }
// // Output: // // Output:
// // 2ae01472317d1935a84797ec1983ae243fc6aa28 // // 2ae01472317d1935a84797ec1983ae243fc6aa28
// // 2ae01472317d1935a84797ec1983ae243fc6aa28 // // 2ae01472317d1935a84797ec1983ae243fc6aa28
// //
// For hashing larger byte slices, or byte streams such as those read from // For hashing larger byte slices, or byte streams such as those read from
// a file or socket, use Sendto with MSG_MORE to instruct the kernel to update // a file or socket, use Sendto with MSG_MORE to instruct the kernel to update
// the hash digest instead of creating a new one for a given chunk and finalizing it. // the hash digest instead of creating a new one for a given chunk and finalizing it.
// //
// // Assume hashfd and addr are already configured using the setup process. // // Assume hashfd and addr are already configured using the setup process.
// hash := os.NewFile(hashfd, "sha1") // hash := os.NewFile(hashfd, "sha1")
// // Hash the contents of a file. // // Hash the contents of a file.
// f, _ := os.Open("/tmp/linux-4.10-rc7.tar.xz") // f, _ := os.Open("/tmp/linux-4.10-rc7.tar.xz")
// b := make([]byte, 4096) // b := make([]byte, 4096)
// for { // for {
// n, err := f.Read(b) // n, err := f.Read(b)
// if err == io.EOF { // if err == io.EOF {
// break // break
// } // }
// unix.Sendto(hashfd, b[:n], unix.MSG_MORE, addr) // unix.Sendto(hashfd, b[:n], unix.MSG_MORE, addr)
// } // }
// hash.Read(b) // hash.Read(b)
// fmt.Println(hex.EncodeToString(b)) // fmt.Println(hex.EncodeToString(b))
// // Output: 85cdcad0c06eef66f805ecce353bec9accbeecc5 // // Output: 85cdcad0c06eef66f805ecce353bec9accbeecc5
// //
// For more information, see: http://www.chronox.de/crypto-API/crypto/userspace-if.html. // For more information, see: http://www.chronox.de/crypto-API/crypto/userspace-if.html.
type SockaddrALG struct { type SockaddrALG struct {
@ -1487,19 +1500,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 keyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) = SYS_KEYCTL
//sys keyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL //sys keyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
var msg Msghdr var msg Msghdr
var rsa RawSockaddrAny msg.Name = (*byte)(unsafe.Pointer(rsa))
msg.Name = (*byte)(unsafe.Pointer(&rsa))
msg.Namelen = uint32(SizeofSockaddrAny) msg.Namelen = uint32(SizeofSockaddrAny)
var iov Iovec
if len(p) > 0 {
iov.Base = &p[0]
iov.SetLen(len(p))
}
var dummy byte var dummy byte
if len(oob) > 0 { if len(oob) > 0 {
if len(p) == 0 { if emptyIovecs(iov) {
var sockType int var sockType int
sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
if err != nil { if err != nil {
@ -1507,53 +1514,36 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
} }
// receive at least one normal byte // receive at least one normal byte
if sockType != SOCK_DGRAM { if sockType != SOCK_DGRAM {
iov.Base = &dummy var iova [1]Iovec
iov.SetLen(1) iova[0].Base = &dummy
iova[0].SetLen(1)
iov = iova[:]
} }
} }
msg.Control = &oob[0] msg.Control = &oob[0]
msg.SetControllen(len(oob)) msg.SetControllen(len(oob))
} }
msg.Iov = &iov if len(iov) > 0 {
msg.Iovlen = 1 msg.Iov = &iov[0]
msg.SetIovlen(len(iov))
}
if n, err = recvmsg(fd, &msg, flags); err != nil { if n, err = recvmsg(fd, &msg, flags); err != nil {
return return
} }
oobn = int(msg.Controllen) oobn = int(msg.Controllen)
recvflags = int(msg.Flags) recvflags = int(msg.Flags)
// source address is only specified if the socket is unconnected
if rsa.Addr.Family != AF_UNSPEC {
from, err = anyToSockaddr(fd, &rsa)
}
return return
} }
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n 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 ptr unsafe.Pointer
var salen _Socklen
if to != nil {
var err error
ptr, salen, err = to.sockaddr()
if err != nil {
return 0, err
}
}
var msg Msghdr var msg Msghdr
msg.Name = (*byte)(ptr) msg.Name = (*byte)(ptr)
msg.Namelen = uint32(salen) msg.Namelen = uint32(salen)
var iov Iovec
if len(p) > 0 {
iov.Base = &p[0]
iov.SetLen(len(p))
}
var dummy byte var dummy byte
var empty bool
if len(oob) > 0 { if len(oob) > 0 {
if len(p) == 0 { empty = emptyIovecs(iov)
if empty {
var sockType int var sockType int
sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
if err != nil { if err != nil {
@ -1561,19 +1551,22 @@ func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error)
} }
// send at least one normal byte // send at least one normal byte
if sockType != SOCK_DGRAM { if sockType != SOCK_DGRAM {
iov.Base = &dummy var iova [1]Iovec
iov.SetLen(1) iova[0].Base = &dummy
iova[0].SetLen(1)
} }
} }
msg.Control = &oob[0] msg.Control = &oob[0]
msg.SetControllen(len(oob)) msg.SetControllen(len(oob))
} }
msg.Iov = &iov if len(iov) > 0 {
msg.Iovlen = 1 msg.Iov = &iov[0]
msg.SetIovlen(len(iov))
}
if n, err = sendmsg(fd, &msg, flags); err != nil { if n, err = sendmsg(fd, &msg, flags); err != nil {
return 0, err return 0, err
} }
if len(oob) > 0 && len(p) == 0 { if len(oob) > 0 && empty {
n = 0 n = 0
} }
return n, nil return n, nil
@ -1836,6 +1829,9 @@ func Dup2(oldfd, newfd int) error {
//sys Fremovexattr(fd int, attr string) (err error) //sys Fremovexattr(fd int, attr string) (err error)
//sys Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) //sys Fsetxattr(fd int, attr string, dest []byte, flags int) (err error)
//sys Fsync(fd int) (err error) //sys Fsync(fd int) (err error)
//sys Fsmount(fd int, flags int, mountAttrs int) (fsfd int, err error)
//sys Fsopen(fsName string, flags int) (fd int, err error)
//sys Fspick(dirfd int, pathName string, flags int) (fd int, err error)
//sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64 //sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
//sysnb Getpgid(pid int) (pgid int, err error) //sysnb Getpgid(pid int) (pgid int, err error)
@ -1866,7 +1862,9 @@ func Getpgrp() (pid int) {
//sys MemfdCreate(name string, flags int) (fd int, err error) //sys MemfdCreate(name string, flags int) (fd int, err error)
//sys Mkdirat(dirfd int, path string, mode uint32) (err error) //sys Mkdirat(dirfd int, path string, mode uint32) (err error)
//sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error) //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
//sys MoveMount(fromDirfd int, fromPathName string, toDirfd int, toPathName string, flags int) (err error)
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error) //sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
//sys OpenTree(dfd int, fileName string, flags uint) (r int, err error)
//sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) //sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error)
//sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
//sysnb Prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64 //sysnb Prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64
@ -1894,17 +1892,28 @@ func PrctlRetInt(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uint
return int(ret), nil return int(ret), nil
} }
// issue 1435.
// On linux Setuid and Setgid only affects the current thread, not the process.
// This does not match what most callers expect so we must return an error
// here rather than letting the caller think that the call succeeded.
func Setuid(uid int) (err error) { func Setuid(uid int) (err error) {
return EOPNOTSUPP return syscall.Setuid(uid)
} }
func Setgid(uid int) (err error) { func Setgid(gid int) (err error) {
return EOPNOTSUPP return syscall.Setgid(gid)
}
func Setreuid(ruid, euid int) (err error) {
return syscall.Setreuid(ruid, euid)
}
func Setregid(rgid, egid int) (err error) {
return syscall.Setregid(rgid, egid)
}
func Setresuid(ruid, euid, suid int) (err error) {
return syscall.Setresuid(ruid, euid, suid)
}
func Setresgid(rgid, egid, sgid int) (err error) {
return syscall.Setresgid(rgid, egid, sgid)
} }
// SetfsgidRetGid sets fsgid for current thread and returns previous fsgid set. // SetfsgidRetGid sets fsgid for current thread and returns previous fsgid set.
@ -2191,7 +2200,7 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
gid = Getgid() gid = Getgid()
} }
if uint32(gid) == st.Gid || isGroupMember(gid) { if uint32(gid) == st.Gid || isGroupMember(int(st.Gid)) {
fmode = (st.Mode >> 3) & 7 fmode = (st.Mode >> 3) & 7
} else { } else {
fmode = st.Mode & 7 fmode = st.Mode & 7
@ -2306,17 +2315,63 @@ type RemoteIovec struct {
//sys PidfdOpen(pid int, flags int) (fd int, err error) = SYS_PIDFD_OPEN //sys PidfdOpen(pid int, flags int) (fd int, err error) = SYS_PIDFD_OPEN
//sys PidfdGetfd(pidfd int, targetfd int, flags int) (fd int, err error) = SYS_PIDFD_GETFD //sys PidfdGetfd(pidfd int, targetfd int, flags int) (fd int, err error) = SYS_PIDFD_GETFD
//sys PidfdSendSignal(pidfd int, sig Signal, info *Siginfo, flags int) (err error) = SYS_PIDFD_SEND_SIGNAL
//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error) //sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error)
//sys shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error) //sys shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error)
//sys shmdt(addr uintptr) (err error) //sys shmdt(addr uintptr) (err error)
//sys shmget(key int, size int, flag int) (id int, err error) //sys shmget(key int, size int, flag int) (id int, err error)
//sys getitimer(which int, currValue *Itimerval) (err error)
//sys setitimer(which int, newValue *Itimerval, oldValue *Itimerval) (err error)
// MakeItimerval creates an Itimerval from interval and value durations.
func MakeItimerval(interval, value time.Duration) Itimerval {
return Itimerval{
Interval: NsecToTimeval(interval.Nanoseconds()),
Value: NsecToTimeval(value.Nanoseconds()),
}
}
// A value which may be passed to the which parameter for Getitimer and
// Setitimer.
type ItimerWhich int
// Possible which values for Getitimer and Setitimer.
const (
ItimerReal ItimerWhich = ITIMER_REAL
ItimerVirtual ItimerWhich = ITIMER_VIRTUAL
ItimerProf ItimerWhich = ITIMER_PROF
)
// Getitimer wraps getitimer(2) to return the current value of the timer
// specified by which.
func Getitimer(which ItimerWhich) (Itimerval, error) {
var it Itimerval
if err := getitimer(int(which), &it); err != nil {
return Itimerval{}, err
}
return it, nil
}
// Setitimer wraps setitimer(2) to arm or disarm the timer specified by which.
// It returns the previous value of the timer.
//
// If the Itimerval argument is the zero value, the timer will be disarmed.
func Setitimer(which ItimerWhich, it Itimerval) (Itimerval, error) {
var prev Itimerval
if err := setitimer(int(which), &it, &prev); err != nil {
return Itimerval{}, err
}
return prev, nil
}
/* /*
* Unimplemented * Unimplemented
*/ */
// AfsSyscall // AfsSyscall
// Alarm
// ArchPrctl // ArchPrctl
// Brk // Brk
// ClockNanosleep // ClockNanosleep
@ -2332,7 +2387,6 @@ type RemoteIovec struct {
// GetMempolicy // GetMempolicy
// GetRobustList // GetRobustList
// GetThreadArea // GetThreadArea
// Getitimer
// Getpmsg // Getpmsg
// IoCancel // IoCancel
// IoDestroy // IoDestroy
@ -2410,5 +2464,4 @@ type RemoteIovec struct {
// Vfork // Vfork
// Vhangup // Vhangup
// Vserver // Vserver
// Waitid
// _Sysctl // _Sysctl

View File

@ -35,16 +35,12 @@ func setTimeval(sec, usec int64) Timeval {
//sys Iopl(level int) (err error) //sys Iopl(level int) (err error)
//sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32 //sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64 //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //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 pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64 //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
//sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32 //sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32
//sys setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32 //sys setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32
//sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
//sysnb Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
//sysnb Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
@ -173,14 +169,6 @@ const (
_SENDMMSG = 20 _SENDMMSG = 20
) )
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
fd, e := socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
if e != 0 {
err = e
}
return
}
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) { func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
fd, e := socketcall(_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0) fd, e := socketcall(_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
if e != 0 { if e != 0 {

14
vendor/golang.org/x/sys/unix/syscall_linux_alarm.go generated vendored Normal file
View File

@ -0,0 +1,14 @@
// 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 linux && (386 || amd64 || mips || mipsle || mips64 || mipsle || ppc64 || ppc64le || ppc || s390x || sparc64)
// +build linux
// +build 386 amd64 mips mipsle mips64 mipsle ppc64 ppc64le ppc s390x sparc64
package unix
// SYS_ALARM is not defined on arm or riscv, but is available for other GOARCH
// values.
//sys Alarm(seconds uint) (remaining uint, err error)

View File

@ -28,9 +28,10 @@ func Lstat(path string, stat *Stat_t) (err error) {
return Fstatat(AT_FDCWD, path, stat, AT_SYMLINK_NOFOLLOW) return Fstatat(AT_FDCWD, path, stat, AT_SYMLINK_NOFOLLOW)
} }
//sys MemfdSecret(flags int) (fd int, err error)
//sys Pause() (err error) //sys Pause() (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //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 pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
@ -45,11 +46,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
//sys setfsgid(gid int) (prev int, err error) //sys setfsgid(gid int) (prev int, err error)
//sys setfsuid(uid int) (prev int, err error) //sys setfsuid(uid int) (prev int, err error)
//sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error) //sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Setreuid(ruid int, euid int) (err error)
//sys Shutdown(fd int, how int) (err error) //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) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
@ -62,7 +59,6 @@ func Stat(path string, stat *Stat_t) (err error) {
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error) //sys Truncate(path string, length int64) (err error)
//sys Ustat(dev int, ubuf *Ustat_t) (err error) //sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)

View File

@ -27,7 +27,6 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
return newoffset, nil return newoffset, nil
} }
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
@ -63,10 +62,6 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
//sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32 //sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32
//sys setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32 //sys setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32
//sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
//sysnb Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
//sysnb Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32
//sys Shutdown(fd int, how int) (err error) //sys Shutdown(fd int, how int) (err error)
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
@ -97,8 +92,8 @@ func Utime(path string, buf *Utimbuf) error {
//sys utimes(path string, times *[2]Timeval) (err error) //sys utimes(path string, times *[2]Timeval) (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //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 pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64 //sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
//sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64 //sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64

View File

@ -22,8 +22,9 @@ import "unsafe"
//sysnb getrlimit(resource int, rlim *Rlimit) (err error) //sysnb getrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Getuid() (uid int) //sysnb Getuid() (uid int)
//sys Listen(s int, n int) (err error) //sys Listen(s int, n int) (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys MemfdSecret(flags int) (fd int, err error)
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 //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 Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
@ -38,11 +39,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
//sys setfsgid(gid int) (prev int, err error) //sys setfsgid(gid int) (prev int, err error)
//sys setfsuid(uid int) (prev int, err error) //sys setfsuid(uid int) (prev int, err error)
//sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
//sysnb setrlimit(resource int, rlim *Rlimit) (err error) //sysnb setrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Setreuid(ruid int, euid int) (err error)
//sys Shutdown(fd int, how int) (err error) //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) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
@ -66,7 +63,6 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
return ENOSYS return ENOSYS
} }
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)

222
vendor/golang.org/x/sys/unix/syscall_linux_loong64.go generated vendored Normal file
View File

@ -0,0 +1,222 @@
// 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 loong64 && linux
// +build loong64,linux
package unix
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 Fstatfs(fd int, buf *Statfs_t) (err error)
//sys Ftruncate(fd int, length int64) (err error)
//sysnb Getegid() (egid int)
//sysnb Geteuid() (euid int)
//sysnb Getgid() (gid int)
//sysnb Getuid() (uid int)
//sys Listen(s int, n 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
func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
var ts *Timespec
if timeout != nil {
ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}
}
return Pselect(nfd, r, w, e, ts, nil)
}
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
//sys setfsgid(gid int) (prev int, err error)
//sys setfsuid(uid int) (prev int, err error)
//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)
}
func Lchown(path string, uid int, gid int) (err error) {
return Fchownat(AT_FDCWD, path, uid, gid, AT_SYMLINK_NOFOLLOW)
}
func Lstat(path string, stat *Stat_t) (err error) {
return Fstatat(AT_FDCWD, path, stat, AT_SYMLINK_NOFOLLOW)
}
//sys Statfs(path string, buf *Statfs_t) (err error)
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error)
func Ustat(dev int, ubuf *Ustat_t) (err error) {
return ENOSYS
}
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sysnb getgroups(n int, list *_Gid_t) (nn int, err error)
//sysnb setgroups(n int, list *_Gid_t) (err error)
//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
//sysnb socket(domain int, typ int, proto int) (fd int, err error)
//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
//sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err 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)
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
//sysnb Gettimeofday(tv *Timeval) (err error)
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 Getrlimit(resource int, rlim *Rlimit) (err error) {
err = Prlimit(0, resource, nil, rlim)
return
}
func Setrlimit(resource int, rlim *Rlimit) (err error) {
err = Prlimit(0, resource, rlim, nil)
return
}
func futimesat(dirfd int, path string, tv *[2]Timeval) (err error) {
if tv == nil {
return utimensat(dirfd, path, nil, 0)
}
ts := []Timespec{
NsecToTimespec(TimevalToNsec(tv[0])),
NsecToTimespec(TimevalToNsec(tv[1])),
}
return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
}
func Time(t *Time_t) (Time_t, error) {
var tv Timeval
err := Gettimeofday(&tv)
if err != nil {
return 0, err
}
if t != nil {
*t = Time_t(tv.Sec)
}
return Time_t(tv.Sec), nil
}
func Utime(path string, buf *Utimbuf) error {
tv := []Timeval{
{Sec: buf.Actime},
{Sec: buf.Modtime},
}
return Utimes(path, tv)
}
func utimes(path string, tv *[2]Timeval) (err error) {
if tv == nil {
return utimensat(AT_FDCWD, path, nil, 0)
}
ts := []Timespec{
NsecToTimespec(TimevalToNsec(tv[0])),
NsecToTimespec(TimevalToNsec(tv[1])),
}
return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
}
func (r *PtraceRegs) PC() uint64 { return r.Era }
func (r *PtraceRegs) SetPC(era uint64) { r.Era = era }
func (iov *Iovec) SetLen(length int) {
iov.Len = uint64(length)
}
func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint64(length)
}
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = uint64(length)
}
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length)
}
func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
rsa.Service_name_len = uint64(length)
}
func Pause() error {
_, err := ppoll(nil, 0, nil, nil)
return err
}
func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
return Renameat2(olddirfd, oldpath, newdirfd, newpath, 0)
}
//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {
cmdlineLen := len(cmdline)
if cmdlineLen > 0 {
// Account for the additional NULL byte added by
// BytePtrFromString in kexecFileLoad. The kexec_file_load
// syscall expects a NULL-terminated string.
cmdlineLen++
}
return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)
}

View File

@ -21,8 +21,8 @@ package unix
//sys Lchown(path string, uid int, gid int) (err error) //sys Lchown(path string, uid int, gid int) (err error)
//sys Listen(s int, n int) (err error) //sys Listen(s int, n int) (err error)
//sys Pause() (err error) //sys Pause() (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //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 pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
@ -37,18 +37,13 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
//sys setfsgid(gid int) (prev int, err error) //sys setfsgid(gid int) (prev int, err error)
//sys setfsuid(uid int) (prev int, err error) //sys setfsuid(uid int) (prev int, err error)
//sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error) //sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Setreuid(ruid int, euid int) (err error)
//sys Shutdown(fd int, how int) (err error) //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) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
//sys Statfs(path string, buf *Statfs_t) (err error) //sys Statfs(path string, buf *Statfs_t) (err error)
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error) //sys Truncate(path string, length int64) (err error)
//sys Ustat(dev int, ubuf *Ustat_t) (err error) //sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)

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