build(deps): bump github.com/labstack/echo/v4 from 4.9.0 to 4.10.0

Bumps [github.com/labstack/echo/v4](https://github.com/labstack/echo) from 4.9.0 to 4.10.0.
- [Release notes](https://github.com/labstack/echo/releases)
- [Changelog](https://github.com/labstack/echo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/labstack/echo/compare/v4.9.0...v4.10.0)

---
updated-dependencies:
- dependency-name: github.com/labstack/echo/v4
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot] 2023-01-16 04:16:32 +00:00 committed by Ondřej Budai
parent ff86f29120
commit c2a290ef76
268 changed files with 21730 additions and 3422 deletions

View file

@ -88,7 +88,7 @@ type Client struct {
//
// The following algorithms are supported:
// RS256, ES256, ES384 and ES512.
// See RFC7518 for more details about the algorithms.
// See RFC 7518 for more details about the algorithms.
Key crypto.Signer
// HTTPClient optionally specifies an HTTP client to use
@ -310,9 +310,9 @@ func (c *Client) UpdateReg(ctx context.Context, acct *Account) (*Account, error)
// On success client's Key is updated which is not concurrency safe.
// On failure an error will be returned.
// The new key is already registered with the ACME provider if the following is true:
// - error is of type acme.Error
// - StatusCode should be 409 (Conflict)
// - Location header will have the KID of the associated account
// - error is of type acme.Error
// - StatusCode should be 409 (Conflict)
// - Location header will have the KID of the associated account
//
// More about account key rollover can be found at
// https://tools.ietf.org/html/rfc8555#section-7.3.5.

View file

@ -463,7 +463,7 @@ func (m *Manager) cert(ctx context.Context, ck certKey) (*tls.Certificate, error
leaf: cert.Leaf,
}
m.state[ck] = s
go m.startRenew(ck, s.key, s.leaf.NotAfter)
m.startRenew(ck, s.key, s.leaf.NotAfter)
return cert, nil
}
@ -609,7 +609,7 @@ func (m *Manager) createCert(ctx context.Context, ck certKey) (*tls.Certificate,
}
state.cert = der
state.leaf = leaf
go m.startRenew(ck, state.key, state.leaf.NotAfter)
m.startRenew(ck, state.key, state.leaf.NotAfter)
return state.tlscert()
}

View file

@ -7,7 +7,6 @@ package autocert
import (
"context"
"errors"
"io/ioutil"
"os"
"path/filepath"
)
@ -48,7 +47,7 @@ func (d DirCache) Get(ctx context.Context, name string) ([]byte, error) {
done = make(chan struct{})
)
go func() {
data, err = ioutil.ReadFile(name)
data, err = os.ReadFile(name)
close(done)
}()
select {
@ -119,7 +118,7 @@ func (d DirCache) Delete(ctx context.Context, name string) error {
// writeTempFile writes b to a temporary file, closes the file and returns its path.
func (d DirCache) writeTempFile(prefix string, b []byte) (name string, reterr error) {
// TempFile uses 0600 permissions
f, err := ioutil.TempFile(string(d), prefix)
f, err := os.CreateTemp(string(d), prefix)
if err != nil {
return "", err
}

View file

@ -12,7 +12,7 @@ import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"io"
"math/big"
"net/http"
"strconv"
@ -156,7 +156,7 @@ func (c *Client) get(ctx context.Context, url string, ok resOkay) (*http.Respons
}
}
// postAsGet is POST-as-GET, a replacement for GET in RFC8555
// postAsGet is POST-as-GET, a replacement for GET in RFC 8555
// as described in https://tools.ietf.org/html/rfc8555#section-6.3.
// It makes a POST request in KID form with zero JWS payload.
// See nopayload doc comments in jws.go.
@ -310,7 +310,7 @@ func isRetriable(code int) bool {
func responseError(resp *http.Response) error {
// don't care if ReadAll returns an error:
// json.Unmarshal will fail in that case anyway
b, _ := ioutil.ReadAll(resp.Body)
b, _ := io.ReadAll(resp.Body)
e := &wireError{Status: resp.StatusCode}
if err := json.Unmarshal(b, e); err != nil {
// this is not a regular error response:

View file

@ -13,7 +13,6 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"time"
)
@ -390,7 +389,7 @@ func (c *Client) fetchCertRFC(ctx context.Context, url string, bundle bool) ([][
// Get all the bytes up to a sane maximum.
// Account very roughly for base64 overhead.
const max = maxCertChainSize + maxCertChainSize/33
b, err := ioutil.ReadAll(io.LimitReader(res.Body, max+1))
b, err := io.ReadAll(io.LimitReader(res.Body, max+1))
if err != nil {
return nil, fmt.Errorf("acme: fetch cert response stream: %v", err)
}
@ -469,7 +468,7 @@ func (c *Client) ListCertAlternates(ctx context.Context, url string) ([]string,
// We don't need the body but we need to discard it so we don't end up
// preventing keep-alive
if _, err := io.Copy(ioutil.Discard, res.Body); err != nil {
if _, err := io.Copy(io.Discard, res.Body); err != nil {
return nil, fmt.Errorf("acme: cert alternates response stream: %v", err)
}
alts := linkHeader(res.Header, "alternate")

View file

@ -297,7 +297,7 @@ type Directory struct {
// CAA consists of lowercase hostname elements, which the ACME server
// recognises as referring to itself for the purposes of CAA record validation
// as defined in RFC6844.
// as defined in RFC 6844.
CAA []string
// ExternalAccountRequired indicates that the CA requires for all account-related
@ -440,7 +440,7 @@ func DomainIDs(names ...string) []AuthzID {
// IPIDs creates a slice of AuthzID with "ip" identifier type.
// Each element of addr is textual form of an address as defined
// in RFC1123 Section 2.1 for IPv4 and in RFC5952 Section 4 for IPv6.
// in RFC 1123 Section 2.1 for IPv4 and in RFC 5952 Section 4 for IPv6.
func IPIDs(addr ...string) []AuthzID {
a := make([]AuthzID, len(addr))
for i, v := range addr {

View file

@ -13,7 +13,10 @@
// golang.org/x/crypto/chacha20poly1305).
package cast5 // import "golang.org/x/crypto/cast5"
import "errors"
import (
"errors"
"math/bits"
)
const BlockSize = 8
const KeySize = 16
@ -241,19 +244,19 @@ func (c *Cipher) keySchedule(in []byte) {
// These are the three 'f' functions. See RFC 2144, section 2.2.
func f1(d, m uint32, r uint8) uint32 {
t := m + d
I := (t << r) | (t >> (32 - r))
I := bits.RotateLeft32(t, int(r))
return ((sBox[0][I>>24] ^ sBox[1][(I>>16)&0xff]) - sBox[2][(I>>8)&0xff]) + sBox[3][I&0xff]
}
func f2(d, m uint32, r uint8) uint32 {
t := m ^ d
I := (t << r) | (t >> (32 - r))
I := bits.RotateLeft32(t, int(r))
return ((sBox[0][I>>24] - sBox[1][(I>>16)&0xff]) + sBox[2][(I>>8)&0xff]) ^ sBox[3][I&0xff]
}
func f3(d, m uint32, r uint8) uint32 {
t := m - d
I := (t << r) | (t >> (32 - r))
I := bits.RotateLeft32(t, int(r))
return ((sBox[0][I>>24] + sBox[1][(I>>16)&0xff]) ^ sBox[2][(I>>8)&0xff]) - sBox[3][I&0xff]
}

View file

@ -5,9 +5,8 @@
//go:build !purego
// +build !purego
// Package subtle implements functions that are often useful in cryptographic
// code but require careful thought to use correctly.
package subtle // import "golang.org/x/crypto/internal/subtle"
// Package alias implements memory aliasing tests.
package alias
import "unsafe"

View file

@ -5,9 +5,8 @@
//go:build purego
// +build purego
// Package subtle implements functions that are often useful in cryptographic
// code but require careful thought to use correctly.
package subtle // import "golang.org/x/crypto/internal/subtle"
// Package alias implements memory aliasing tests.
package alias
// This is the Google App Engine standard variant based on reflect
// because the unsafe package and cgo are disallowed.

View file

@ -35,8 +35,8 @@ This package is interoperable with NaCl: https://nacl.cr.yp.to/secretbox.html.
package secretbox // import "golang.org/x/crypto/nacl/secretbox"
import (
"golang.org/x/crypto/internal/alias"
"golang.org/x/crypto/internal/poly1305"
"golang.org/x/crypto/internal/subtle"
"golang.org/x/crypto/salsa20/salsa"
)
@ -88,7 +88,7 @@ func Seal(out, message []byte, nonce *[24]byte, key *[32]byte) []byte {
copy(poly1305Key[:], firstBlock[:])
ret, out := sliceForAppend(out, len(message)+poly1305.TagSize)
if subtle.AnyOverlap(out, message) {
if alias.AnyOverlap(out, message) {
panic("nacl: invalid buffer overlap")
}
@ -147,7 +147,7 @@ func Open(out, box []byte, nonce *[24]byte, key *[32]byte) ([]byte, bool) {
}
ret, out := sliceForAppend(out, len(box)-Overhead)
if subtle.AnyOverlap(out, box) {
if alias.AnyOverlap(out, box) {
panic("nacl: invalid buffer overlap")
}

View file

@ -7,7 +7,6 @@ package packet
import (
"bytes"
"io"
"io/ioutil"
"golang.org/x/crypto/openpgp/errors"
)
@ -26,7 +25,7 @@ type OpaquePacket struct {
}
func (op *OpaquePacket) parse(r io.Reader) (err error) {
op.Contents, err = ioutil.ReadAll(r)
op.Contents, err = io.ReadAll(r)
return
}

View file

@ -13,7 +13,6 @@ import (
"crypto/rsa"
"crypto/sha1"
"io"
"io/ioutil"
"math/big"
"strconv"
"time"
@ -133,7 +132,7 @@ func (pk *PrivateKey) parse(r io.Reader) (err error) {
}
}
pk.encryptedData, err = ioutil.ReadAll(r)
pk.encryptedData, err = io.ReadAll(r)
if err != nil {
return
}

View file

@ -236,7 +236,7 @@ func (w *seMDCWriter) Close() (err error) {
return w.w.Close()
}
// noOpCloser is like an ioutil.NopCloser, but for an io.Writer.
// noOpCloser is like an io.NopCloser, but for an io.Writer.
type noOpCloser struct {
w io.Writer
}

View file

@ -9,7 +9,6 @@ import (
"image"
"image/jpeg"
"io"
"io/ioutil"
)
const UserAttrImageSubpacket = 1
@ -56,7 +55,7 @@ func NewUserAttribute(contents ...*OpaqueSubpacket) *UserAttribute {
func (uat *UserAttribute) parse(r io.Reader) (err error) {
// RFC 4880, section 5.13
b, err := ioutil.ReadAll(r)
b, err := io.ReadAll(r)
if err != nil {
return
}

View file

@ -6,7 +6,6 @@ package packet
import (
"io"
"io/ioutil"
"strings"
)
@ -66,7 +65,7 @@ func NewUserId(name, comment, email string) *UserId {
func (uid *UserId) parse(r io.Reader) (err error) {
// RFC 4880, section 5.11
b, err := ioutil.ReadAll(r)
b, err := io.ReadAll(r)
if err != nil {
return
}

View file

@ -268,7 +268,7 @@ func HashIdToString(id byte) (name string, ok bool) {
return "", false
}
// HashIdToHash returns an OpenPGP hash id which corresponds the given Hash.
// HashToHashId returns an OpenPGP hash id which corresponds the given Hash.
func HashToHashId(h crypto.Hash) (id byte, ok bool) {
for _, m := range hashToHashIdMapping {
if m.hash == h {

View file

@ -402,7 +402,7 @@ func (s signatureWriter) Close() error {
return s.encryptedData.Close()
}
// noOpCloser is like an ioutil.NopCloser, but for an io.Writer.
// noOpCloser is like an io.NopCloser, but for an io.Writer.
// TODO: we have two of these in OpenPGP packages alone. This probably needs
// to be promoted somewhere more common.
type noOpCloser struct {

View file

@ -117,7 +117,7 @@ func pbDecrypt(info decryptable, password []byte) (decrypted []byte, err error)
}
ps := decrypted[len(decrypted)-psLen:]
decrypted = decrypted[:len(decrypted)-psLen]
if bytes.Compare(ps, bytes.Repeat([]byte{byte(psLen)}, psLen)) != 0 {
if !bytes.Equal(ps, bytes.Repeat([]byte{byte(psLen)}, psLen)) {
return nil, ErrDecryption
}

View file

@ -14,6 +14,7 @@ package rc2
import (
"crypto/cipher"
"encoding/binary"
"math/bits"
)
// The rc2 block size in bytes
@ -80,10 +81,6 @@ func expandKey(key []byte, t1 int) [64]uint16 {
return k
}
func rotl16(x uint16, b uint) uint16 {
return (x >> (16 - b)) | (x << b)
}
func (c *rc2Cipher) Encrypt(dst, src []byte) {
r0 := binary.LittleEndian.Uint16(src[0:])
@ -96,22 +93,22 @@ func (c *rc2Cipher) Encrypt(dst, src []byte) {
for j <= 16 {
// mix r0
r0 = r0 + c.k[j] + (r3 & r2) + ((^r3) & r1)
r0 = rotl16(r0, 1)
r0 = bits.RotateLeft16(r0, 1)
j++
// mix r1
r1 = r1 + c.k[j] + (r0 & r3) + ((^r0) & r2)
r1 = rotl16(r1, 2)
r1 = bits.RotateLeft16(r1, 2)
j++
// mix r2
r2 = r2 + c.k[j] + (r1 & r0) + ((^r1) & r3)
r2 = rotl16(r2, 3)
r2 = bits.RotateLeft16(r2, 3)
j++
// mix r3
r3 = r3 + c.k[j] + (r2 & r1) + ((^r2) & r0)
r3 = rotl16(r3, 5)
r3 = bits.RotateLeft16(r3, 5)
j++
}
@ -124,22 +121,22 @@ func (c *rc2Cipher) Encrypt(dst, src []byte) {
for j <= 40 {
// mix r0
r0 = r0 + c.k[j] + (r3 & r2) + ((^r3) & r1)
r0 = rotl16(r0, 1)
r0 = bits.RotateLeft16(r0, 1)
j++
// mix r1
r1 = r1 + c.k[j] + (r0 & r3) + ((^r0) & r2)
r1 = rotl16(r1, 2)
r1 = bits.RotateLeft16(r1, 2)
j++
// mix r2
r2 = r2 + c.k[j] + (r1 & r0) + ((^r1) & r3)
r2 = rotl16(r2, 3)
r2 = bits.RotateLeft16(r2, 3)
j++
// mix r3
r3 = r3 + c.k[j] + (r2 & r1) + ((^r2) & r0)
r3 = rotl16(r3, 5)
r3 = bits.RotateLeft16(r3, 5)
j++
}
@ -152,22 +149,22 @@ func (c *rc2Cipher) Encrypt(dst, src []byte) {
for j <= 60 {
// mix r0
r0 = r0 + c.k[j] + (r3 & r2) + ((^r3) & r1)
r0 = rotl16(r0, 1)
r0 = bits.RotateLeft16(r0, 1)
j++
// mix r1
r1 = r1 + c.k[j] + (r0 & r3) + ((^r0) & r2)
r1 = rotl16(r1, 2)
r1 = bits.RotateLeft16(r1, 2)
j++
// mix r2
r2 = r2 + c.k[j] + (r1 & r0) + ((^r1) & r3)
r2 = rotl16(r2, 3)
r2 = bits.RotateLeft16(r2, 3)
j++
// mix r3
r3 = r3 + c.k[j] + (r2 & r1) + ((^r2) & r0)
r3 = rotl16(r3, 5)
r3 = bits.RotateLeft16(r3, 5)
j++
}
@ -188,22 +185,22 @@ func (c *rc2Cipher) Decrypt(dst, src []byte) {
for j >= 44 {
// unmix r3
r3 = rotl16(r3, 16-5)
r3 = bits.RotateLeft16(r3, 16-5)
r3 = r3 - c.k[j] - (r2 & r1) - ((^r2) & r0)
j--
// unmix r2
r2 = rotl16(r2, 16-3)
r2 = bits.RotateLeft16(r2, 16-3)
r2 = r2 - c.k[j] - (r1 & r0) - ((^r1) & r3)
j--
// unmix r1
r1 = rotl16(r1, 16-2)
r1 = bits.RotateLeft16(r1, 16-2)
r1 = r1 - c.k[j] - (r0 & r3) - ((^r0) & r2)
j--
// unmix r0
r0 = rotl16(r0, 16-1)
r0 = bits.RotateLeft16(r0, 16-1)
r0 = r0 - c.k[j] - (r3 & r2) - ((^r3) & r1)
j--
}
@ -215,22 +212,22 @@ func (c *rc2Cipher) Decrypt(dst, src []byte) {
for j >= 20 {
// unmix r3
r3 = rotl16(r3, 16-5)
r3 = bits.RotateLeft16(r3, 16-5)
r3 = r3 - c.k[j] - (r2 & r1) - ((^r2) & r0)
j--
// unmix r2
r2 = rotl16(r2, 16-3)
r2 = bits.RotateLeft16(r2, 16-3)
r2 = r2 - c.k[j] - (r1 & r0) - ((^r1) & r3)
j--
// unmix r1
r1 = rotl16(r1, 16-2)
r1 = bits.RotateLeft16(r1, 16-2)
r1 = r1 - c.k[j] - (r0 & r3) - ((^r0) & r2)
j--
// unmix r0
r0 = rotl16(r0, 16-1)
r0 = bits.RotateLeft16(r0, 16-1)
r0 = r0 - c.k[j] - (r3 & r2) - ((^r3) & r1)
j--
@ -243,22 +240,22 @@ func (c *rc2Cipher) Decrypt(dst, src []byte) {
for j >= 0 {
// unmix r3
r3 = rotl16(r3, 16-5)
r3 = bits.RotateLeft16(r3, 16-5)
r3 = r3 - c.k[j] - (r2 & r1) - ((^r2) & r0)
j--
// unmix r2
r2 = rotl16(r2, 16-3)
r2 = bits.RotateLeft16(r2, 16-3)
r2 = r2 - c.k[j] - (r1 & r0) - ((^r1) & r3)
j--
// unmix r1
r1 = rotl16(r1, 16-2)
r1 = bits.RotateLeft16(r1, 16-2)
r1 = r1 - c.k[j] - (r0 & r3) - ((^r0) & r2)
j--
// unmix r0
r0 = rotl16(r0, 16-1)
r0 = bits.RotateLeft16(r0, 16-1)
r0 = r0 - c.k[j] - (r3 & r2) - ((^r3) & r1)
j--

View file

@ -5,6 +5,8 @@
// Package salsa provides low-level access to functions in the Salsa family.
package salsa // import "golang.org/x/crypto/salsa20/salsa"
import "math/bits"
// Sigma is the Salsa20 constant for 256-bit keys.
var Sigma = [16]byte{'e', 'x', 'p', 'a', 'n', 'd', ' ', '3', '2', '-', 'b', 'y', 't', 'e', ' ', 'k'}
@ -31,76 +33,76 @@ func HSalsa20(out *[32]byte, in *[16]byte, k *[32]byte, c *[16]byte) {
for i := 0; i < 20; i += 2 {
u := x0 + x12
x4 ^= u<<7 | u>>(32-7)
x4 ^= bits.RotateLeft32(u, 7)
u = x4 + x0
x8 ^= u<<9 | u>>(32-9)
x8 ^= bits.RotateLeft32(u, 9)
u = x8 + x4
x12 ^= u<<13 | u>>(32-13)
x12 ^= bits.RotateLeft32(u, 13)
u = x12 + x8
x0 ^= u<<18 | u>>(32-18)
x0 ^= bits.RotateLeft32(u, 18)
u = x5 + x1
x9 ^= u<<7 | u>>(32-7)
x9 ^= bits.RotateLeft32(u, 7)
u = x9 + x5
x13 ^= u<<9 | u>>(32-9)
x13 ^= bits.RotateLeft32(u, 9)
u = x13 + x9
x1 ^= u<<13 | u>>(32-13)
x1 ^= bits.RotateLeft32(u, 13)
u = x1 + x13
x5 ^= u<<18 | u>>(32-18)
x5 ^= bits.RotateLeft32(u, 18)
u = x10 + x6
x14 ^= u<<7 | u>>(32-7)
x14 ^= bits.RotateLeft32(u, 7)
u = x14 + x10
x2 ^= u<<9 | u>>(32-9)
x2 ^= bits.RotateLeft32(u, 9)
u = x2 + x14
x6 ^= u<<13 | u>>(32-13)
x6 ^= bits.RotateLeft32(u, 13)
u = x6 + x2
x10 ^= u<<18 | u>>(32-18)
x10 ^= bits.RotateLeft32(u, 18)
u = x15 + x11
x3 ^= u<<7 | u>>(32-7)
x3 ^= bits.RotateLeft32(u, 7)
u = x3 + x15
x7 ^= u<<9 | u>>(32-9)
x7 ^= bits.RotateLeft32(u, 9)
u = x7 + x3
x11 ^= u<<13 | u>>(32-13)
x11 ^= bits.RotateLeft32(u, 13)
u = x11 + x7
x15 ^= u<<18 | u>>(32-18)
x15 ^= bits.RotateLeft32(u, 18)
u = x0 + x3
x1 ^= u<<7 | u>>(32-7)
x1 ^= bits.RotateLeft32(u, 7)
u = x1 + x0
x2 ^= u<<9 | u>>(32-9)
x2 ^= bits.RotateLeft32(u, 9)
u = x2 + x1
x3 ^= u<<13 | u>>(32-13)
x3 ^= bits.RotateLeft32(u, 13)
u = x3 + x2
x0 ^= u<<18 | u>>(32-18)
x0 ^= bits.RotateLeft32(u, 18)
u = x5 + x4
x6 ^= u<<7 | u>>(32-7)
x6 ^= bits.RotateLeft32(u, 7)
u = x6 + x5
x7 ^= u<<9 | u>>(32-9)
x7 ^= bits.RotateLeft32(u, 9)
u = x7 + x6
x4 ^= u<<13 | u>>(32-13)
x4 ^= bits.RotateLeft32(u, 13)
u = x4 + x7
x5 ^= u<<18 | u>>(32-18)
x5 ^= bits.RotateLeft32(u, 18)
u = x10 + x9
x11 ^= u<<7 | u>>(32-7)
x11 ^= bits.RotateLeft32(u, 7)
u = x11 + x10
x8 ^= u<<9 | u>>(32-9)
x8 ^= bits.RotateLeft32(u, 9)
u = x8 + x11
x9 ^= u<<13 | u>>(32-13)
x9 ^= bits.RotateLeft32(u, 13)
u = x9 + x8
x10 ^= u<<18 | u>>(32-18)
x10 ^= bits.RotateLeft32(u, 18)
u = x15 + x14
x12 ^= u<<7 | u>>(32-7)
x12 ^= bits.RotateLeft32(u, 7)
u = x12 + x15
x13 ^= u<<9 | u>>(32-9)
x13 ^= bits.RotateLeft32(u, 9)
u = x13 + x12
x14 ^= u<<13 | u>>(32-13)
x14 ^= bits.RotateLeft32(u, 13)
u = x14 + x13
x15 ^= u<<18 | u>>(32-18)
x15 ^= bits.RotateLeft32(u, 18)
}
out[0] = byte(x0)
out[1] = byte(x0 >> 8)

View file

@ -4,6 +4,8 @@
package salsa
import "math/bits"
// Core208 applies the Salsa20/8 core function to the 64-byte array in and puts
// the result into the 64-byte array out. The input and output may be the same array.
func Core208(out *[64]byte, in *[64]byte) {
@ -29,76 +31,76 @@ func Core208(out *[64]byte, in *[64]byte) {
for i := 0; i < 8; i += 2 {
u := x0 + x12
x4 ^= u<<7 | u>>(32-7)
x4 ^= bits.RotateLeft32(u, 7)
u = x4 + x0
x8 ^= u<<9 | u>>(32-9)
x8 ^= bits.RotateLeft32(u, 9)
u = x8 + x4
x12 ^= u<<13 | u>>(32-13)
x12 ^= bits.RotateLeft32(u, 13)
u = x12 + x8
x0 ^= u<<18 | u>>(32-18)
x0 ^= bits.RotateLeft32(u, 18)
u = x5 + x1
x9 ^= u<<7 | u>>(32-7)
x9 ^= bits.RotateLeft32(u, 7)
u = x9 + x5
x13 ^= u<<9 | u>>(32-9)
x13 ^= bits.RotateLeft32(u, 9)
u = x13 + x9
x1 ^= u<<13 | u>>(32-13)
x1 ^= bits.RotateLeft32(u, 13)
u = x1 + x13
x5 ^= u<<18 | u>>(32-18)
x5 ^= bits.RotateLeft32(u, 18)
u = x10 + x6
x14 ^= u<<7 | u>>(32-7)
x14 ^= bits.RotateLeft32(u, 7)
u = x14 + x10
x2 ^= u<<9 | u>>(32-9)
x2 ^= bits.RotateLeft32(u, 9)
u = x2 + x14
x6 ^= u<<13 | u>>(32-13)
x6 ^= bits.RotateLeft32(u, 13)
u = x6 + x2
x10 ^= u<<18 | u>>(32-18)
x10 ^= bits.RotateLeft32(u, 18)
u = x15 + x11
x3 ^= u<<7 | u>>(32-7)
x3 ^= bits.RotateLeft32(u, 7)
u = x3 + x15
x7 ^= u<<9 | u>>(32-9)
x7 ^= bits.RotateLeft32(u, 9)
u = x7 + x3
x11 ^= u<<13 | u>>(32-13)
x11 ^= bits.RotateLeft32(u, 13)
u = x11 + x7
x15 ^= u<<18 | u>>(32-18)
x15 ^= bits.RotateLeft32(u, 18)
u = x0 + x3
x1 ^= u<<7 | u>>(32-7)
x1 ^= bits.RotateLeft32(u, 7)
u = x1 + x0
x2 ^= u<<9 | u>>(32-9)
x2 ^= bits.RotateLeft32(u, 9)
u = x2 + x1
x3 ^= u<<13 | u>>(32-13)
x3 ^= bits.RotateLeft32(u, 13)
u = x3 + x2
x0 ^= u<<18 | u>>(32-18)
x0 ^= bits.RotateLeft32(u, 18)
u = x5 + x4
x6 ^= u<<7 | u>>(32-7)
x6 ^= bits.RotateLeft32(u, 7)
u = x6 + x5
x7 ^= u<<9 | u>>(32-9)
x7 ^= bits.RotateLeft32(u, 9)
u = x7 + x6
x4 ^= u<<13 | u>>(32-13)
x4 ^= bits.RotateLeft32(u, 13)
u = x4 + x7
x5 ^= u<<18 | u>>(32-18)
x5 ^= bits.RotateLeft32(u, 18)
u = x10 + x9
x11 ^= u<<7 | u>>(32-7)
x11 ^= bits.RotateLeft32(u, 7)
u = x11 + x10
x8 ^= u<<9 | u>>(32-9)
x8 ^= bits.RotateLeft32(u, 9)
u = x8 + x11
x9 ^= u<<13 | u>>(32-13)
x9 ^= bits.RotateLeft32(u, 13)
u = x9 + x8
x10 ^= u<<18 | u>>(32-18)
x10 ^= bits.RotateLeft32(u, 18)
u = x15 + x14
x12 ^= u<<7 | u>>(32-7)
x12 ^= bits.RotateLeft32(u, 7)
u = x12 + x15
x13 ^= u<<9 | u>>(32-9)
x13 ^= bits.RotateLeft32(u, 9)
u = x13 + x12
x14 ^= u<<13 | u>>(32-13)
x14 ^= bits.RotateLeft32(u, 13)
u = x14 + x13
x15 ^= u<<18 | u>>(32-18)
x15 ^= bits.RotateLeft32(u, 18)
}
x0 += j0
x1 += j1

View file

@ -4,6 +4,8 @@
package salsa
import "math/bits"
const rounds = 20
// core applies the Salsa20 core function to 16-byte input in, 32-byte key k,
@ -31,76 +33,76 @@ func core(out *[64]byte, in *[16]byte, k *[32]byte, c *[16]byte) {
for i := 0; i < rounds; i += 2 {
u := x0 + x12
x4 ^= u<<7 | u>>(32-7)
x4 ^= bits.RotateLeft32(u, 7)
u = x4 + x0
x8 ^= u<<9 | u>>(32-9)
x8 ^= bits.RotateLeft32(u, 9)
u = x8 + x4
x12 ^= u<<13 | u>>(32-13)
x12 ^= bits.RotateLeft32(u, 13)
u = x12 + x8
x0 ^= u<<18 | u>>(32-18)
x0 ^= bits.RotateLeft32(u, 18)
u = x5 + x1
x9 ^= u<<7 | u>>(32-7)
x9 ^= bits.RotateLeft32(u, 7)
u = x9 + x5
x13 ^= u<<9 | u>>(32-9)
x13 ^= bits.RotateLeft32(u, 9)
u = x13 + x9
x1 ^= u<<13 | u>>(32-13)
x1 ^= bits.RotateLeft32(u, 13)
u = x1 + x13
x5 ^= u<<18 | u>>(32-18)
x5 ^= bits.RotateLeft32(u, 18)
u = x10 + x6
x14 ^= u<<7 | u>>(32-7)
x14 ^= bits.RotateLeft32(u, 7)
u = x14 + x10
x2 ^= u<<9 | u>>(32-9)
x2 ^= bits.RotateLeft32(u, 9)
u = x2 + x14
x6 ^= u<<13 | u>>(32-13)
x6 ^= bits.RotateLeft32(u, 13)
u = x6 + x2
x10 ^= u<<18 | u>>(32-18)
x10 ^= bits.RotateLeft32(u, 18)
u = x15 + x11
x3 ^= u<<7 | u>>(32-7)
x3 ^= bits.RotateLeft32(u, 7)
u = x3 + x15
x7 ^= u<<9 | u>>(32-9)
x7 ^= bits.RotateLeft32(u, 9)
u = x7 + x3
x11 ^= u<<13 | u>>(32-13)
x11 ^= bits.RotateLeft32(u, 13)
u = x11 + x7
x15 ^= u<<18 | u>>(32-18)
x15 ^= bits.RotateLeft32(u, 18)
u = x0 + x3
x1 ^= u<<7 | u>>(32-7)
x1 ^= bits.RotateLeft32(u, 7)
u = x1 + x0
x2 ^= u<<9 | u>>(32-9)
x2 ^= bits.RotateLeft32(u, 9)
u = x2 + x1
x3 ^= u<<13 | u>>(32-13)
x3 ^= bits.RotateLeft32(u, 13)
u = x3 + x2
x0 ^= u<<18 | u>>(32-18)
x0 ^= bits.RotateLeft32(u, 18)
u = x5 + x4
x6 ^= u<<7 | u>>(32-7)
x6 ^= bits.RotateLeft32(u, 7)
u = x6 + x5
x7 ^= u<<9 | u>>(32-9)
x7 ^= bits.RotateLeft32(u, 9)
u = x7 + x6
x4 ^= u<<13 | u>>(32-13)
x4 ^= bits.RotateLeft32(u, 13)
u = x4 + x7
x5 ^= u<<18 | u>>(32-18)
x5 ^= bits.RotateLeft32(u, 18)
u = x10 + x9
x11 ^= u<<7 | u>>(32-7)
x11 ^= bits.RotateLeft32(u, 7)
u = x11 + x10
x8 ^= u<<9 | u>>(32-9)
x8 ^= bits.RotateLeft32(u, 9)
u = x8 + x11
x9 ^= u<<13 | u>>(32-13)
x9 ^= bits.RotateLeft32(u, 13)
u = x9 + x8
x10 ^= u<<18 | u>>(32-18)
x10 ^= bits.RotateLeft32(u, 18)
u = x15 + x14
x12 ^= u<<7 | u>>(32-7)
x12 ^= bits.RotateLeft32(u, 7)
u = x12 + x15
x13 ^= u<<9 | u>>(32-9)
x13 ^= bits.RotateLeft32(u, 9)
u = x13 + x12
x14 ^= u<<13 | u>>(32-13)
x14 ^= bits.RotateLeft32(u, 13)
u = x14 + x13
x15 ^= u<<18 | u>>(32-18)
x15 ^= bits.RotateLeft32(u, 18)
}
x0 += j0
x1 += j1

View file

@ -7,6 +7,8 @@
package sha3
import "math/bits"
// rc stores the round constants for use in the ι step.
var rc = [24]uint64{
0x0000000000000001,
@ -60,13 +62,13 @@ func keccakF1600(a *[25]uint64) {
bc0 = a[0] ^ d0
t = a[6] ^ d1
bc1 = t<<44 | t>>(64-44)
bc1 = bits.RotateLeft64(t, 44)
t = a[12] ^ d2
bc2 = t<<43 | t>>(64-43)
bc2 = bits.RotateLeft64(t, 43)
t = a[18] ^ d3
bc3 = t<<21 | t>>(64-21)
bc3 = bits.RotateLeft64(t, 21)
t = a[24] ^ d4
bc4 = t<<14 | t>>(64-14)
bc4 = bits.RotateLeft64(t, 14)
a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i]
a[6] = bc1 ^ (bc3 &^ bc2)
a[12] = bc2 ^ (bc4 &^ bc3)
@ -74,15 +76,15 @@ func keccakF1600(a *[25]uint64) {
a[24] = bc4 ^ (bc1 &^ bc0)
t = a[10] ^ d0
bc2 = t<<3 | t>>(64-3)
bc2 = bits.RotateLeft64(t, 3)
t = a[16] ^ d1
bc3 = t<<45 | t>>(64-45)
bc3 = bits.RotateLeft64(t, 45)
t = a[22] ^ d2
bc4 = t<<61 | t>>(64-61)
bc4 = bits.RotateLeft64(t, 61)
t = a[3] ^ d3
bc0 = t<<28 | t>>(64-28)
bc0 = bits.RotateLeft64(t, 28)
t = a[9] ^ d4
bc1 = t<<20 | t>>(64-20)
bc1 = bits.RotateLeft64(t, 20)
a[10] = bc0 ^ (bc2 &^ bc1)
a[16] = bc1 ^ (bc3 &^ bc2)
a[22] = bc2 ^ (bc4 &^ bc3)
@ -90,15 +92,15 @@ func keccakF1600(a *[25]uint64) {
a[9] = bc4 ^ (bc1 &^ bc0)
t = a[20] ^ d0
bc4 = t<<18 | t>>(64-18)
bc4 = bits.RotateLeft64(t, 18)
t = a[1] ^ d1
bc0 = t<<1 | t>>(64-1)
bc0 = bits.RotateLeft64(t, 1)
t = a[7] ^ d2
bc1 = t<<6 | t>>(64-6)
bc1 = bits.RotateLeft64(t, 6)
t = a[13] ^ d3
bc2 = t<<25 | t>>(64-25)
bc2 = bits.RotateLeft64(t, 25)
t = a[19] ^ d4
bc3 = t<<8 | t>>(64-8)
bc3 = bits.RotateLeft64(t, 8)
a[20] = bc0 ^ (bc2 &^ bc1)
a[1] = bc1 ^ (bc3 &^ bc2)
a[7] = bc2 ^ (bc4 &^ bc3)
@ -106,15 +108,15 @@ func keccakF1600(a *[25]uint64) {
a[19] = bc4 ^ (bc1 &^ bc0)
t = a[5] ^ d0
bc1 = t<<36 | t>>(64-36)
bc1 = bits.RotateLeft64(t, 36)
t = a[11] ^ d1
bc2 = t<<10 | t>>(64-10)
bc2 = bits.RotateLeft64(t, 10)
t = a[17] ^ d2
bc3 = t<<15 | t>>(64-15)
bc3 = bits.RotateLeft64(t, 15)
t = a[23] ^ d3
bc4 = t<<56 | t>>(64-56)
bc4 = bits.RotateLeft64(t, 56)
t = a[4] ^ d4
bc0 = t<<27 | t>>(64-27)
bc0 = bits.RotateLeft64(t, 27)
a[5] = bc0 ^ (bc2 &^ bc1)
a[11] = bc1 ^ (bc3 &^ bc2)
a[17] = bc2 ^ (bc4 &^ bc3)
@ -122,15 +124,15 @@ func keccakF1600(a *[25]uint64) {
a[4] = bc4 ^ (bc1 &^ bc0)
t = a[15] ^ d0
bc3 = t<<41 | t>>(64-41)
bc3 = bits.RotateLeft64(t, 41)
t = a[21] ^ d1
bc4 = t<<2 | t>>(64-2)
bc4 = bits.RotateLeft64(t, 2)
t = a[2] ^ d2
bc0 = t<<62 | t>>(64-62)
bc0 = bits.RotateLeft64(t, 62)
t = a[8] ^ d3
bc1 = t<<55 | t>>(64-55)
bc1 = bits.RotateLeft64(t, 55)
t = a[14] ^ d4
bc2 = t<<39 | t>>(64-39)
bc2 = bits.RotateLeft64(t, 39)
a[15] = bc0 ^ (bc2 &^ bc1)
a[21] = bc1 ^ (bc3 &^ bc2)
a[2] = bc2 ^ (bc4 &^ bc3)
@ -151,13 +153,13 @@ func keccakF1600(a *[25]uint64) {
bc0 = a[0] ^ d0
t = a[16] ^ d1
bc1 = t<<44 | t>>(64-44)
bc1 = bits.RotateLeft64(t, 44)
t = a[7] ^ d2
bc2 = t<<43 | t>>(64-43)
bc2 = bits.RotateLeft64(t, 43)
t = a[23] ^ d3
bc3 = t<<21 | t>>(64-21)
bc3 = bits.RotateLeft64(t, 21)
t = a[14] ^ d4
bc4 = t<<14 | t>>(64-14)
bc4 = bits.RotateLeft64(t, 14)
a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+1]
a[16] = bc1 ^ (bc3 &^ bc2)
a[7] = bc2 ^ (bc4 &^ bc3)
@ -165,15 +167,15 @@ func keccakF1600(a *[25]uint64) {
a[14] = bc4 ^ (bc1 &^ bc0)
t = a[20] ^ d0
bc2 = t<<3 | t>>(64-3)
bc2 = bits.RotateLeft64(t, 3)
t = a[11] ^ d1
bc3 = t<<45 | t>>(64-45)
bc3 = bits.RotateLeft64(t, 45)
t = a[2] ^ d2
bc4 = t<<61 | t>>(64-61)
bc4 = bits.RotateLeft64(t, 61)
t = a[18] ^ d3
bc0 = t<<28 | t>>(64-28)
bc0 = bits.RotateLeft64(t, 28)
t = a[9] ^ d4
bc1 = t<<20 | t>>(64-20)
bc1 = bits.RotateLeft64(t, 20)
a[20] = bc0 ^ (bc2 &^ bc1)
a[11] = bc1 ^ (bc3 &^ bc2)
a[2] = bc2 ^ (bc4 &^ bc3)
@ -181,15 +183,15 @@ func keccakF1600(a *[25]uint64) {
a[9] = bc4 ^ (bc1 &^ bc0)
t = a[15] ^ d0
bc4 = t<<18 | t>>(64-18)
bc4 = bits.RotateLeft64(t, 18)
t = a[6] ^ d1
bc0 = t<<1 | t>>(64-1)
bc0 = bits.RotateLeft64(t, 1)
t = a[22] ^ d2
bc1 = t<<6 | t>>(64-6)
bc1 = bits.RotateLeft64(t, 6)
t = a[13] ^ d3
bc2 = t<<25 | t>>(64-25)
bc2 = bits.RotateLeft64(t, 25)
t = a[4] ^ d4
bc3 = t<<8 | t>>(64-8)
bc3 = bits.RotateLeft64(t, 8)
a[15] = bc0 ^ (bc2 &^ bc1)
a[6] = bc1 ^ (bc3 &^ bc2)
a[22] = bc2 ^ (bc4 &^ bc3)
@ -197,15 +199,15 @@ func keccakF1600(a *[25]uint64) {
a[4] = bc4 ^ (bc1 &^ bc0)
t = a[10] ^ d0
bc1 = t<<36 | t>>(64-36)
bc1 = bits.RotateLeft64(t, 36)
t = a[1] ^ d1
bc2 = t<<10 | t>>(64-10)
bc2 = bits.RotateLeft64(t, 10)
t = a[17] ^ d2
bc3 = t<<15 | t>>(64-15)
bc3 = bits.RotateLeft64(t, 15)
t = a[8] ^ d3
bc4 = t<<56 | t>>(64-56)
bc4 = bits.RotateLeft64(t, 56)
t = a[24] ^ d4
bc0 = t<<27 | t>>(64-27)
bc0 = bits.RotateLeft64(t, 27)
a[10] = bc0 ^ (bc2 &^ bc1)
a[1] = bc1 ^ (bc3 &^ bc2)
a[17] = bc2 ^ (bc4 &^ bc3)
@ -213,15 +215,15 @@ func keccakF1600(a *[25]uint64) {
a[24] = bc4 ^ (bc1 &^ bc0)
t = a[5] ^ d0
bc3 = t<<41 | t>>(64-41)
bc3 = bits.RotateLeft64(t, 41)
t = a[21] ^ d1
bc4 = t<<2 | t>>(64-2)
bc4 = bits.RotateLeft64(t, 2)
t = a[12] ^ d2
bc0 = t<<62 | t>>(64-62)
bc0 = bits.RotateLeft64(t, 62)
t = a[3] ^ d3
bc1 = t<<55 | t>>(64-55)
bc1 = bits.RotateLeft64(t, 55)
t = a[19] ^ d4
bc2 = t<<39 | t>>(64-39)
bc2 = bits.RotateLeft64(t, 39)
a[5] = bc0 ^ (bc2 &^ bc1)
a[21] = bc1 ^ (bc3 &^ bc2)
a[12] = bc2 ^ (bc4 &^ bc3)
@ -242,13 +244,13 @@ func keccakF1600(a *[25]uint64) {
bc0 = a[0] ^ d0
t = a[11] ^ d1
bc1 = t<<44 | t>>(64-44)
bc1 = bits.RotateLeft64(t, 44)
t = a[22] ^ d2
bc2 = t<<43 | t>>(64-43)
bc2 = bits.RotateLeft64(t, 43)
t = a[8] ^ d3
bc3 = t<<21 | t>>(64-21)
bc3 = bits.RotateLeft64(t, 21)
t = a[19] ^ d4
bc4 = t<<14 | t>>(64-14)
bc4 = bits.RotateLeft64(t, 14)
a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+2]
a[11] = bc1 ^ (bc3 &^ bc2)
a[22] = bc2 ^ (bc4 &^ bc3)
@ -256,15 +258,15 @@ func keccakF1600(a *[25]uint64) {
a[19] = bc4 ^ (bc1 &^ bc0)
t = a[15] ^ d0
bc2 = t<<3 | t>>(64-3)
bc2 = bits.RotateLeft64(t, 3)
t = a[1] ^ d1
bc3 = t<<45 | t>>(64-45)
bc3 = bits.RotateLeft64(t, 45)
t = a[12] ^ d2
bc4 = t<<61 | t>>(64-61)
bc4 = bits.RotateLeft64(t, 61)
t = a[23] ^ d3
bc0 = t<<28 | t>>(64-28)
bc0 = bits.RotateLeft64(t, 28)
t = a[9] ^ d4
bc1 = t<<20 | t>>(64-20)
bc1 = bits.RotateLeft64(t, 20)
a[15] = bc0 ^ (bc2 &^ bc1)
a[1] = bc1 ^ (bc3 &^ bc2)
a[12] = bc2 ^ (bc4 &^ bc3)
@ -272,15 +274,15 @@ func keccakF1600(a *[25]uint64) {
a[9] = bc4 ^ (bc1 &^ bc0)
t = a[5] ^ d0
bc4 = t<<18 | t>>(64-18)
bc4 = bits.RotateLeft64(t, 18)
t = a[16] ^ d1
bc0 = t<<1 | t>>(64-1)
bc0 = bits.RotateLeft64(t, 1)
t = a[2] ^ d2
bc1 = t<<6 | t>>(64-6)
bc1 = bits.RotateLeft64(t, 6)
t = a[13] ^ d3
bc2 = t<<25 | t>>(64-25)
bc2 = bits.RotateLeft64(t, 25)
t = a[24] ^ d4
bc3 = t<<8 | t>>(64-8)
bc3 = bits.RotateLeft64(t, 8)
a[5] = bc0 ^ (bc2 &^ bc1)
a[16] = bc1 ^ (bc3 &^ bc2)
a[2] = bc2 ^ (bc4 &^ bc3)
@ -288,15 +290,15 @@ func keccakF1600(a *[25]uint64) {
a[24] = bc4 ^ (bc1 &^ bc0)
t = a[20] ^ d0
bc1 = t<<36 | t>>(64-36)
bc1 = bits.RotateLeft64(t, 36)
t = a[6] ^ d1
bc2 = t<<10 | t>>(64-10)
bc2 = bits.RotateLeft64(t, 10)
t = a[17] ^ d2
bc3 = t<<15 | t>>(64-15)
bc3 = bits.RotateLeft64(t, 15)
t = a[3] ^ d3
bc4 = t<<56 | t>>(64-56)
bc4 = bits.RotateLeft64(t, 56)
t = a[14] ^ d4
bc0 = t<<27 | t>>(64-27)
bc0 = bits.RotateLeft64(t, 27)
a[20] = bc0 ^ (bc2 &^ bc1)
a[6] = bc1 ^ (bc3 &^ bc2)
a[17] = bc2 ^ (bc4 &^ bc3)
@ -304,15 +306,15 @@ func keccakF1600(a *[25]uint64) {
a[14] = bc4 ^ (bc1 &^ bc0)
t = a[10] ^ d0
bc3 = t<<41 | t>>(64-41)
bc3 = bits.RotateLeft64(t, 41)
t = a[21] ^ d1
bc4 = t<<2 | t>>(64-2)
bc4 = bits.RotateLeft64(t, 2)
t = a[7] ^ d2
bc0 = t<<62 | t>>(64-62)
bc0 = bits.RotateLeft64(t, 62)
t = a[18] ^ d3
bc1 = t<<55 | t>>(64-55)
bc1 = bits.RotateLeft64(t, 55)
t = a[4] ^ d4
bc2 = t<<39 | t>>(64-39)
bc2 = bits.RotateLeft64(t, 39)
a[10] = bc0 ^ (bc2 &^ bc1)
a[21] = bc1 ^ (bc3 &^ bc2)
a[7] = bc2 ^ (bc4 &^ bc3)
@ -333,13 +335,13 @@ func keccakF1600(a *[25]uint64) {
bc0 = a[0] ^ d0
t = a[1] ^ d1
bc1 = t<<44 | t>>(64-44)
bc1 = bits.RotateLeft64(t, 44)
t = a[2] ^ d2
bc2 = t<<43 | t>>(64-43)
bc2 = bits.RotateLeft64(t, 43)
t = a[3] ^ d3
bc3 = t<<21 | t>>(64-21)
bc3 = bits.RotateLeft64(t, 21)
t = a[4] ^ d4
bc4 = t<<14 | t>>(64-14)
bc4 = bits.RotateLeft64(t, 14)
a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+3]
a[1] = bc1 ^ (bc3 &^ bc2)
a[2] = bc2 ^ (bc4 &^ bc3)
@ -347,15 +349,15 @@ func keccakF1600(a *[25]uint64) {
a[4] = bc4 ^ (bc1 &^ bc0)
t = a[5] ^ d0
bc2 = t<<3 | t>>(64-3)
bc2 = bits.RotateLeft64(t, 3)
t = a[6] ^ d1
bc3 = t<<45 | t>>(64-45)
bc3 = bits.RotateLeft64(t, 45)
t = a[7] ^ d2
bc4 = t<<61 | t>>(64-61)
bc4 = bits.RotateLeft64(t, 61)
t = a[8] ^ d3
bc0 = t<<28 | t>>(64-28)
bc0 = bits.RotateLeft64(t, 28)
t = a[9] ^ d4
bc1 = t<<20 | t>>(64-20)
bc1 = bits.RotateLeft64(t, 20)
a[5] = bc0 ^ (bc2 &^ bc1)
a[6] = bc1 ^ (bc3 &^ bc2)
a[7] = bc2 ^ (bc4 &^ bc3)
@ -363,15 +365,15 @@ func keccakF1600(a *[25]uint64) {
a[9] = bc4 ^ (bc1 &^ bc0)
t = a[10] ^ d0
bc4 = t<<18 | t>>(64-18)
bc4 = bits.RotateLeft64(t, 18)
t = a[11] ^ d1
bc0 = t<<1 | t>>(64-1)
bc0 = bits.RotateLeft64(t, 1)
t = a[12] ^ d2
bc1 = t<<6 | t>>(64-6)
bc1 = bits.RotateLeft64(t, 6)
t = a[13] ^ d3
bc2 = t<<25 | t>>(64-25)
bc2 = bits.RotateLeft64(t, 25)
t = a[14] ^ d4
bc3 = t<<8 | t>>(64-8)
bc3 = bits.RotateLeft64(t, 8)
a[10] = bc0 ^ (bc2 &^ bc1)
a[11] = bc1 ^ (bc3 &^ bc2)
a[12] = bc2 ^ (bc4 &^ bc3)
@ -379,15 +381,15 @@ func keccakF1600(a *[25]uint64) {
a[14] = bc4 ^ (bc1 &^ bc0)
t = a[15] ^ d0
bc1 = t<<36 | t>>(64-36)
bc1 = bits.RotateLeft64(t, 36)
t = a[16] ^ d1
bc2 = t<<10 | t>>(64-10)
bc2 = bits.RotateLeft64(t, 10)
t = a[17] ^ d2
bc3 = t<<15 | t>>(64-15)
bc3 = bits.RotateLeft64(t, 15)
t = a[18] ^ d3
bc4 = t<<56 | t>>(64-56)
bc4 = bits.RotateLeft64(t, 56)
t = a[19] ^ d4
bc0 = t<<27 | t>>(64-27)
bc0 = bits.RotateLeft64(t, 27)
a[15] = bc0 ^ (bc2 &^ bc1)
a[16] = bc1 ^ (bc3 &^ bc2)
a[17] = bc2 ^ (bc4 &^ bc3)
@ -395,15 +397,15 @@ func keccakF1600(a *[25]uint64) {
a[19] = bc4 ^ (bc1 &^ bc0)
t = a[20] ^ d0
bc3 = t<<41 | t>>(64-41)
bc3 = bits.RotateLeft64(t, 41)
t = a[21] ^ d1
bc4 = t<<2 | t>>(64-2)
bc4 = bits.RotateLeft64(t, 2)
t = a[22] ^ d2
bc0 = t<<62 | t>>(64-62)
bc0 = bits.RotateLeft64(t, 62)
t = a[23] ^ d3
bc1 = t<<55 | t>>(64-55)
bc1 = bits.RotateLeft64(t, 55)
t = a[24] ^ d4
bc2 = t<<39 | t>>(64-39)
bc2 = bits.RotateLeft64(t, 39)
a[20] = bc0 ^ (bc2 &^ bc1)
a[21] = bc1 ^ (bc3 &^ bc2)
a[22] = bc2 ^ (bc4 &^ bc3)

View file

@ -15,7 +15,7 @@
// but additional checking functions, most notably Check, verify that
// a particular path, version pair is valid.
//
// Escaped Paths
// # Escaped Paths
//
// Module paths appear as substrings of file system paths
// (in the download cache) and of web server URLs in the proxy protocol.
@ -55,7 +55,7 @@
// Import paths have never allowed exclamation marks, so there is no
// need to define how to escape a literal !.
//
// Unicode Restrictions
// # Unicode Restrictions
//
// Today, paths are disallowed from using Unicode.
//
@ -102,9 +102,9 @@ import (
"strings"
"unicode"
"unicode/utf8"
"errors"
"golang.org/x/mod/semver"
errors "golang.org/x/xerrors"
)
// A Version (for clients, a module.Version) is defined by a module path and version pair.

View file

@ -734,7 +734,7 @@ func inHeadIM(p *parser) bool {
return false
}
// 12.2.6.4.5.
// Section 12.2.6.4.5.
func inHeadNoscriptIM(p *parser) bool {
switch p.tok.Type {
case DoctypeToken:

View file

@ -605,7 +605,10 @@ func (z *Tokenizer) readComment() {
z.data.end = z.data.start
}
}()
for dashCount := 2; ; {
var dashCount int
beginning := true
for {
c := z.readByte()
if z.err != nil {
// Ignore up to two dashes at EOF.
@ -620,7 +623,7 @@ func (z *Tokenizer) readComment() {
dashCount++
continue
case '>':
if dashCount >= 2 {
if dashCount >= 2 || beginning {
z.data.end = z.raw.end - len("-->")
return
}
@ -638,6 +641,7 @@ func (z *Tokenizer) readComment() {
}
}
dashCount = 0
beginning = false
}
}

View file

@ -70,6 +70,15 @@ func NewHandler(h http.Handler, s *http2.Server) http.Handler {
}
}
// extractServer extracts existing http.Server instance from http.Request or create an empty http.Server
func extractServer(r *http.Request) *http.Server {
server, ok := r.Context().Value(http.ServerContextKey).(*http.Server)
if ok {
return server
}
return new(http.Server)
}
// ServeHTTP implement the h2c support that is enabled by h2c.GetH2CHandler.
func (s h2cHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Handle h2c with prior knowledge (RFC 7540 Section 3.4)
@ -87,6 +96,7 @@ func (s h2cHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
defer conn.Close()
s.s.ServeConn(conn, &http2.ServeConnOpts{
Context: r.Context(),
BaseConfig: extractServer(r),
Handler: s.Handler,
SawClientPreface: true,
})
@ -99,11 +109,13 @@ func (s h2cHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if http2VerboseLogs {
log.Printf("h2c: error h2c upgrade: %v", err)
}
w.WriteHeader(http.StatusInternalServerError)
return
}
defer conn.Close()
s.s.ServeConn(conn, &http2.ServeConnOpts{
Context: r.Context(),
BaseConfig: extractServer(r),
Handler: s.Handler,
UpgradeRequest: r,
Settings: settings,
@ -156,7 +168,10 @@ func h2cUpgrade(w http.ResponseWriter, r *http.Request) (_ net.Conn, settings []
return nil, nil, errors.New("h2c: connection does not support Hijack")
}
body, _ := io.ReadAll(r.Body)
body, err := io.ReadAll(r.Body)
if err != nil {
return nil, nil, err
}
r.Body = io.NopCloser(bytes.NewBuffer(body))
conn, rw, err := hijacker.Hijack()

View file

@ -27,7 +27,14 @@ func buildCommonHeaderMaps() {
"accept-language",
"accept-ranges",
"age",
"access-control-allow-credentials",
"access-control-allow-headers",
"access-control-allow-methods",
"access-control-allow-origin",
"access-control-expose-headers",
"access-control-max-age",
"access-control-request-headers",
"access-control-request-method",
"allow",
"authorization",
"cache-control",
@ -53,6 +60,7 @@ func buildCommonHeaderMaps() {
"link",
"location",
"max-forwards",
"origin",
"proxy-authenticate",
"proxy-authorization",
"range",
@ -68,6 +76,8 @@ func buildCommonHeaderMaps() {
"vary",
"via",
"www-authenticate",
"x-forwarded-for",
"x-forwarded-proto",
}
commonLowerHeader = make(map[string]string, len(common))
commonCanonHeader = make(map[string]string, len(common))
@ -85,3 +95,11 @@ func lowerHeader(v string) (lower string, ascii bool) {
}
return asciiToLower(v)
}
func canonicalHeader(v string) string {
buildCommonHeaderMapsOnce()
if s, ok := commonCanonHeader[v]; ok {
return s
}
return http.CanonicalHeaderKey(v)
}

View file

@ -116,6 +116,11 @@ func (e *Encoder) SetMaxDynamicTableSize(v uint32) {
e.dynTab.setMaxSize(v)
}
// MaxDynamicTableSize returns the current dynamic header table size.
func (e *Encoder) MaxDynamicTableSize() (v uint32) {
return e.dynTab.maxSize
}
// SetMaxDynamicTableSizeLimit changes the maximum value that can be
// specified in SetMaxDynamicTableSize to v. By default, it is set to
// 4096, which is the same size of the default dynamic header table

188
vendor/golang.org/x/net/http2/hpack/static_table.go generated vendored Normal file
View file

@ -0,0 +1,188 @@
// go generate gen.go
// Code generated by the command above; DO NOT EDIT.
package hpack
var staticTable = &headerFieldTable{
evictCount: 0,
byName: map[string]uint64{
":authority": 1,
":method": 3,
":path": 5,
":scheme": 7,
":status": 14,
"accept-charset": 15,
"accept-encoding": 16,
"accept-language": 17,
"accept-ranges": 18,
"accept": 19,
"access-control-allow-origin": 20,
"age": 21,
"allow": 22,
"authorization": 23,
"cache-control": 24,
"content-disposition": 25,
"content-encoding": 26,
"content-language": 27,
"content-length": 28,
"content-location": 29,
"content-range": 30,
"content-type": 31,
"cookie": 32,
"date": 33,
"etag": 34,
"expect": 35,
"expires": 36,
"from": 37,
"host": 38,
"if-match": 39,
"if-modified-since": 40,
"if-none-match": 41,
"if-range": 42,
"if-unmodified-since": 43,
"last-modified": 44,
"link": 45,
"location": 46,
"max-forwards": 47,
"proxy-authenticate": 48,
"proxy-authorization": 49,
"range": 50,
"referer": 51,
"refresh": 52,
"retry-after": 53,
"server": 54,
"set-cookie": 55,
"strict-transport-security": 56,
"transfer-encoding": 57,
"user-agent": 58,
"vary": 59,
"via": 60,
"www-authenticate": 61,
},
byNameValue: map[pairNameValue]uint64{
{name: ":authority", value: ""}: 1,
{name: ":method", value: "GET"}: 2,
{name: ":method", value: "POST"}: 3,
{name: ":path", value: "/"}: 4,
{name: ":path", value: "/index.html"}: 5,
{name: ":scheme", value: "http"}: 6,
{name: ":scheme", value: "https"}: 7,
{name: ":status", value: "200"}: 8,
{name: ":status", value: "204"}: 9,
{name: ":status", value: "206"}: 10,
{name: ":status", value: "304"}: 11,
{name: ":status", value: "400"}: 12,
{name: ":status", value: "404"}: 13,
{name: ":status", value: "500"}: 14,
{name: "accept-charset", value: ""}: 15,
{name: "accept-encoding", value: "gzip, deflate"}: 16,
{name: "accept-language", value: ""}: 17,
{name: "accept-ranges", value: ""}: 18,
{name: "accept", value: ""}: 19,
{name: "access-control-allow-origin", value: ""}: 20,
{name: "age", value: ""}: 21,
{name: "allow", value: ""}: 22,
{name: "authorization", value: ""}: 23,
{name: "cache-control", value: ""}: 24,
{name: "content-disposition", value: ""}: 25,
{name: "content-encoding", value: ""}: 26,
{name: "content-language", value: ""}: 27,
{name: "content-length", value: ""}: 28,
{name: "content-location", value: ""}: 29,
{name: "content-range", value: ""}: 30,
{name: "content-type", value: ""}: 31,
{name: "cookie", value: ""}: 32,
{name: "date", value: ""}: 33,
{name: "etag", value: ""}: 34,
{name: "expect", value: ""}: 35,
{name: "expires", value: ""}: 36,
{name: "from", value: ""}: 37,
{name: "host", value: ""}: 38,
{name: "if-match", value: ""}: 39,
{name: "if-modified-since", value: ""}: 40,
{name: "if-none-match", value: ""}: 41,
{name: "if-range", value: ""}: 42,
{name: "if-unmodified-since", value: ""}: 43,
{name: "last-modified", value: ""}: 44,
{name: "link", value: ""}: 45,
{name: "location", value: ""}: 46,
{name: "max-forwards", value: ""}: 47,
{name: "proxy-authenticate", value: ""}: 48,
{name: "proxy-authorization", value: ""}: 49,
{name: "range", value: ""}: 50,
{name: "referer", value: ""}: 51,
{name: "refresh", value: ""}: 52,
{name: "retry-after", value: ""}: 53,
{name: "server", value: ""}: 54,
{name: "set-cookie", value: ""}: 55,
{name: "strict-transport-security", value: ""}: 56,
{name: "transfer-encoding", value: ""}: 57,
{name: "user-agent", value: ""}: 58,
{name: "vary", value: ""}: 59,
{name: "via", value: ""}: 60,
{name: "www-authenticate", value: ""}: 61,
},
ents: []HeaderField{
{Name: ":authority", Value: "", Sensitive: false},
{Name: ":method", Value: "GET", Sensitive: false},
{Name: ":method", Value: "POST", Sensitive: false},
{Name: ":path", Value: "/", Sensitive: false},
{Name: ":path", Value: "/index.html", Sensitive: false},
{Name: ":scheme", Value: "http", Sensitive: false},
{Name: ":scheme", Value: "https", Sensitive: false},
{Name: ":status", Value: "200", Sensitive: false},
{Name: ":status", Value: "204", Sensitive: false},
{Name: ":status", Value: "206", Sensitive: false},
{Name: ":status", Value: "304", Sensitive: false},
{Name: ":status", Value: "400", Sensitive: false},
{Name: ":status", Value: "404", Sensitive: false},
{Name: ":status", Value: "500", Sensitive: false},
{Name: "accept-charset", Value: "", Sensitive: false},
{Name: "accept-encoding", Value: "gzip, deflate", Sensitive: false},
{Name: "accept-language", Value: "", Sensitive: false},
{Name: "accept-ranges", Value: "", Sensitive: false},
{Name: "accept", Value: "", Sensitive: false},
{Name: "access-control-allow-origin", Value: "", Sensitive: false},
{Name: "age", Value: "", Sensitive: false},
{Name: "allow", Value: "", Sensitive: false},
{Name: "authorization", Value: "", Sensitive: false},
{Name: "cache-control", Value: "", Sensitive: false},
{Name: "content-disposition", Value: "", Sensitive: false},
{Name: "content-encoding", Value: "", Sensitive: false},
{Name: "content-language", Value: "", Sensitive: false},
{Name: "content-length", Value: "", Sensitive: false},
{Name: "content-location", Value: "", Sensitive: false},
{Name: "content-range", Value: "", Sensitive: false},
{Name: "content-type", Value: "", Sensitive: false},
{Name: "cookie", Value: "", Sensitive: false},
{Name: "date", Value: "", Sensitive: false},
{Name: "etag", Value: "", Sensitive: false},
{Name: "expect", Value: "", Sensitive: false},
{Name: "expires", Value: "", Sensitive: false},
{Name: "from", Value: "", Sensitive: false},
{Name: "host", Value: "", Sensitive: false},
{Name: "if-match", Value: "", Sensitive: false},
{Name: "if-modified-since", Value: "", Sensitive: false},
{Name: "if-none-match", Value: "", Sensitive: false},
{Name: "if-range", Value: "", Sensitive: false},
{Name: "if-unmodified-since", Value: "", Sensitive: false},
{Name: "last-modified", Value: "", Sensitive: false},
{Name: "link", Value: "", Sensitive: false},
{Name: "location", Value: "", Sensitive: false},
{Name: "max-forwards", Value: "", Sensitive: false},
{Name: "proxy-authenticate", Value: "", Sensitive: false},
{Name: "proxy-authorization", Value: "", Sensitive: false},
{Name: "range", Value: "", Sensitive: false},
{Name: "referer", Value: "", Sensitive: false},
{Name: "refresh", Value: "", Sensitive: false},
{Name: "retry-after", Value: "", Sensitive: false},
{Name: "server", Value: "", Sensitive: false},
{Name: "set-cookie", Value: "", Sensitive: false},
{Name: "strict-transport-security", Value: "", Sensitive: false},
{Name: "transfer-encoding", Value: "", Sensitive: false},
{Name: "user-agent", Value: "", Sensitive: false},
{Name: "vary", Value: "", Sensitive: false},
{Name: "via", Value: "", Sensitive: false},
{Name: "www-authenticate", Value: "", Sensitive: false},
},
}

View file

@ -96,8 +96,7 @@ func (t *headerFieldTable) evictOldest(n int) {
// meaning t.ents is reversed for dynamic tables. Hence, when t is a dynamic
// table, the return value i actually refers to the entry t.ents[t.len()-i].
//
// All tables are assumed to be a dynamic tables except for the global
// staticTable pointer.
// All tables are assumed to be a dynamic tables except for the global staticTable.
//
// See Section 2.3.3.
func (t *headerFieldTable) search(f HeaderField) (i uint64, nameValueMatch bool) {
@ -125,81 +124,6 @@ func (t *headerFieldTable) idToIndex(id uint64) uint64 {
return k + 1
}
// http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-B
var staticTable = newStaticTable()
var staticTableEntries = [...]HeaderField{
{Name: ":authority"},
{Name: ":method", Value: "GET"},
{Name: ":method", Value: "POST"},
{Name: ":path", Value: "/"},
{Name: ":path", Value: "/index.html"},
{Name: ":scheme", Value: "http"},
{Name: ":scheme", Value: "https"},
{Name: ":status", Value: "200"},
{Name: ":status", Value: "204"},
{Name: ":status", Value: "206"},
{Name: ":status", Value: "304"},
{Name: ":status", Value: "400"},
{Name: ":status", Value: "404"},
{Name: ":status", Value: "500"},
{Name: "accept-charset"},
{Name: "accept-encoding", Value: "gzip, deflate"},
{Name: "accept-language"},
{Name: "accept-ranges"},
{Name: "accept"},
{Name: "access-control-allow-origin"},
{Name: "age"},
{Name: "allow"},
{Name: "authorization"},
{Name: "cache-control"},
{Name: "content-disposition"},
{Name: "content-encoding"},
{Name: "content-language"},
{Name: "content-length"},
{Name: "content-location"},
{Name: "content-range"},
{Name: "content-type"},
{Name: "cookie"},
{Name: "date"},
{Name: "etag"},
{Name: "expect"},
{Name: "expires"},
{Name: "from"},
{Name: "host"},
{Name: "if-match"},
{Name: "if-modified-since"},
{Name: "if-none-match"},
{Name: "if-range"},
{Name: "if-unmodified-since"},
{Name: "last-modified"},
{Name: "link"},
{Name: "location"},
{Name: "max-forwards"},
{Name: "proxy-authenticate"},
{Name: "proxy-authorization"},
{Name: "range"},
{Name: "referer"},
{Name: "refresh"},
{Name: "retry-after"},
{Name: "server"},
{Name: "set-cookie"},
{Name: "strict-transport-security"},
{Name: "transfer-encoding"},
{Name: "user-agent"},
{Name: "vary"},
{Name: "via"},
{Name: "www-authenticate"},
}
func newStaticTable() *headerFieldTable {
t := &headerFieldTable{}
t.init()
for _, e := range staticTableEntries[:] {
t.addEntry(e)
}
return t
}
var huffmanCodes = [256]uint32{
0x1ff8,
0x7fffd8,

View file

@ -98,6 +98,19 @@ type Server struct {
// the HTTP/2 spec's recommendations.
MaxConcurrentStreams uint32
// MaxDecoderHeaderTableSize optionally specifies the http2
// SETTINGS_HEADER_TABLE_SIZE to send in the initial settings frame. It
// informs the remote endpoint of the maximum size of the header compression
// table used to decode header blocks, in octets. If zero, the default value
// of 4096 is used.
MaxDecoderHeaderTableSize uint32
// MaxEncoderHeaderTableSize optionally specifies an upper limit for the
// header compression table used for encoding request headers. Received
// SETTINGS_HEADER_TABLE_SIZE settings are capped at this limit. If zero,
// the default value of 4096 is used.
MaxEncoderHeaderTableSize uint32
// MaxReadFrameSize optionally specifies the largest frame
// this server is willing to read. A valid value is between
// 16k and 16M, inclusive. If zero or otherwise invalid, a
@ -143,7 +156,7 @@ type Server struct {
}
func (s *Server) initialConnRecvWindowSize() int32 {
if s.MaxUploadBufferPerConnection > initialWindowSize {
if s.MaxUploadBufferPerConnection >= initialWindowSize {
return s.MaxUploadBufferPerConnection
}
return 1 << 20
@ -170,6 +183,20 @@ func (s *Server) maxConcurrentStreams() uint32 {
return defaultMaxStreams
}
func (s *Server) maxDecoderHeaderTableSize() uint32 {
if v := s.MaxDecoderHeaderTableSize; v > 0 {
return v
}
return initialHeaderTableSize
}
func (s *Server) maxEncoderHeaderTableSize() uint32 {
if v := s.MaxEncoderHeaderTableSize; v > 0 {
return v
}
return initialHeaderTableSize
}
// maxQueuedControlFrames is the maximum number of control frames like
// SETTINGS, PING and RST_STREAM that will be queued for writing before
// the connection is closed to prevent memory exhaustion attacks.
@ -394,7 +421,6 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
advMaxStreams: s.maxConcurrentStreams(),
initialStreamSendWindowSize: initialWindowSize,
maxFrameSize: initialMaxFrameSize,
headerTableSize: initialHeaderTableSize,
serveG: newGoroutineLock(),
pushEnabled: true,
sawClientPreface: opts.SawClientPreface,
@ -424,12 +450,13 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
sc.flow.add(initialWindowSize)
sc.inflow.add(initialWindowSize)
sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf)
sc.hpackEncoder.SetMaxDynamicTableSizeLimit(s.maxEncoderHeaderTableSize())
fr := NewFramer(sc.bw, c)
if s.CountError != nil {
fr.countError = s.CountError
}
fr.ReadMetaHeaders = hpack.NewDecoder(initialHeaderTableSize, nil)
fr.ReadMetaHeaders = hpack.NewDecoder(s.maxDecoderHeaderTableSize(), nil)
fr.MaxHeaderListSize = sc.maxHeaderListSize()
fr.SetMaxReadFrameSize(s.maxReadFrameSize())
sc.framer = fr
@ -559,9 +586,9 @@ type serverConn struct {
streams map[uint32]*stream
initialStreamSendWindowSize int32
maxFrameSize int32
headerTableSize uint32
peerMaxHeaderListSize uint32 // zero means unknown (default)
canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case
canonHeaderKeysSize int // canonHeader keys size in bytes
writingFrame bool // started writing a frame (on serve goroutine or separate)
writingFrameAsync bool // started a frame on its own goroutine but haven't heard back on wroteFrameCh
needsFrameFlush bool // last frame write wasn't a flush
@ -622,7 +649,9 @@ type stream struct {
resetQueued bool // RST_STREAM queued for write; set by sc.resetStream
gotTrailerHeader bool // HEADER frame for trailers was seen
wroteHeaders bool // whether we wrote headers (not status 100)
readDeadline *time.Timer // nil if unused
writeDeadline *time.Timer // nil if unused
closeErr error // set before cw is closed
trailer http.Header // accumulated trailers
reqTrailer http.Header // handler's Request.Trailer
@ -738,6 +767,13 @@ func (sc *serverConn) condlogf(err error, format string, args ...interface{}) {
}
}
// maxCachedCanonicalHeadersKeysSize is an arbitrarily-chosen limit on the size
// of the entries in the canonHeader cache.
// This should be larger than the size of unique, uncommon header keys likely to
// be sent by the peer, while not so high as to permit unreasonable memory usage
// if the peer sends an unbounded number of unique header keys.
const maxCachedCanonicalHeadersKeysSize = 2048
func (sc *serverConn) canonicalHeader(v string) string {
sc.serveG.check()
buildCommonHeaderMapsOnce()
@ -753,14 +789,10 @@ func (sc *serverConn) canonicalHeader(v string) string {
sc.canonHeader = make(map[string]string)
}
cv = http.CanonicalHeaderKey(v)
// maxCachedCanonicalHeaders is an arbitrarily-chosen limit on the number of
// entries in the canonHeader cache. This should be larger than the number
// of unique, uncommon header keys likely to be sent by the peer, while not
// so high as to permit unreasonable memory usage if the peer sends an unbounded
// number of unique header keys.
const maxCachedCanonicalHeaders = 32
if len(sc.canonHeader) < maxCachedCanonicalHeaders {
size := 100 + len(v)*2 // 100 bytes of map overhead + key + value
if sc.canonHeaderKeysSize+size <= maxCachedCanonicalHeadersKeysSize {
sc.canonHeader[v] = cv
sc.canonHeaderKeysSize += size
}
return cv
}
@ -862,6 +894,7 @@ func (sc *serverConn) serve() {
{SettingMaxFrameSize, sc.srv.maxReadFrameSize()},
{SettingMaxConcurrentStreams, sc.advMaxStreams},
{SettingMaxHeaderListSize, sc.maxHeaderListSize()},
{SettingHeaderTableSize, sc.srv.maxDecoderHeaderTableSize()},
{SettingInitialWindowSize, uint32(sc.srv.initialStreamRecvWindowSize())},
},
})
@ -948,6 +981,8 @@ func (sc *serverConn) serve() {
}
case *startPushRequest:
sc.startPush(v)
case func(*serverConn):
v(sc)
default:
panic(fmt.Sprintf("unexpected type %T", v))
}
@ -1461,6 +1496,21 @@ func (sc *serverConn) processFrame(f Frame) error {
sc.sawFirstSettings = true
}
// Discard frames for streams initiated after the identified last
// stream sent in a GOAWAY, or all frames after sending an error.
// We still need to return connection-level flow control for DATA frames.
// RFC 9113 Section 6.8.
if sc.inGoAway && (sc.goAwayCode != ErrCodeNo || f.Header().StreamID > sc.maxClientStreamID) {
if f, ok := f.(*DataFrame); ok {
if sc.inflow.available() < int32(f.Length) {
return sc.countError("data_flow", streamError(f.Header().StreamID, ErrCodeFlowControl))
}
sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
}
return nil
}
switch f := f.(type) {
case *SettingsFrame:
return sc.processSettings(f)
@ -1503,9 +1553,6 @@ func (sc *serverConn) processPing(f *PingFrame) error {
// PROTOCOL_ERROR."
return sc.countError("ping_on_stream", ConnectionError(ErrCodeProtocol))
}
if sc.inGoAway && sc.goAwayCode != ErrCodeNo {
return nil
}
sc.writeFrame(FrameWriteRequest{write: writePingAck{f}})
return nil
}
@ -1567,6 +1614,9 @@ func (sc *serverConn) closeStream(st *stream, err error) {
panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state))
}
st.state = stateClosed
if st.readDeadline != nil {
st.readDeadline.Stop()
}
if st.writeDeadline != nil {
st.writeDeadline.Stop()
}
@ -1592,6 +1642,14 @@ func (sc *serverConn) closeStream(st *stream, err error) {
p.CloseWithError(err)
}
if e, ok := err.(StreamError); ok {
if e.Cause != nil {
err = e.Cause
} else {
err = errStreamClosed
}
}
st.closeErr = err
st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
sc.writeSched.CloseStream(st.id)
}
@ -1634,7 +1692,6 @@ func (sc *serverConn) processSetting(s Setting) error {
}
switch s.ID {
case SettingHeaderTableSize:
sc.headerTableSize = s.Val
sc.hpackEncoder.SetMaxDynamicTableSize(s.Val)
case SettingEnablePush:
sc.pushEnabled = s.Val != 0
@ -1688,16 +1745,6 @@ func (sc *serverConn) processSettingInitialWindowSize(val uint32) error {
func (sc *serverConn) processData(f *DataFrame) error {
sc.serveG.check()
id := f.Header().StreamID
if sc.inGoAway && (sc.goAwayCode != ErrCodeNo || id > sc.maxClientStreamID) {
// Discard all DATA frames if the GOAWAY is due to an
// error, or:
//
// Section 6.8: After sending a GOAWAY frame, the sender
// can discard frames for streams initiated by the
// receiver with identifiers higher than the identified
// last stream.
return nil
}
data := f.Data()
state, st := sc.state(id)
@ -1840,19 +1887,27 @@ func (st *stream) copyTrailersToHandlerRequest() {
}
}
// onReadTimeout is run on its own goroutine (from time.AfterFunc)
// when the stream's ReadTimeout has fired.
func (st *stream) onReadTimeout() {
// Wrap the ErrDeadlineExceeded to avoid callers depending on us
// returning the bare error.
st.body.CloseWithError(fmt.Errorf("%w", os.ErrDeadlineExceeded))
}
// onWriteTimeout is run on its own goroutine (from time.AfterFunc)
// when the stream's WriteTimeout has fired.
func (st *stream) onWriteTimeout() {
st.sc.writeFrameFromHandler(FrameWriteRequest{write: streamError(st.id, ErrCodeInternal)})
st.sc.writeFrameFromHandler(FrameWriteRequest{write: StreamError{
StreamID: st.id,
Code: ErrCodeInternal,
Cause: os.ErrDeadlineExceeded,
}})
}
func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
sc.serveG.check()
id := f.StreamID
if sc.inGoAway {
// Ignore.
return nil
}
// http://tools.ietf.org/html/rfc7540#section-5.1.1
// Streams initiated by a client MUST use odd-numbered stream
// identifiers. [...] An endpoint that receives an unexpected
@ -1955,6 +2010,9 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
// (in Go 1.8), though. That's a more sane option anyway.
if sc.hs.ReadTimeout != 0 {
sc.conn.SetReadDeadline(time.Time{})
if st.body != nil {
st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout)
}
}
go sc.runHandler(rw, req, handler)
@ -2023,9 +2081,6 @@ func (sc *serverConn) checkPriority(streamID uint32, p PriorityParam) error {
}
func (sc *serverConn) processPriority(f *PriorityFrame) error {
if sc.inGoAway {
return nil
}
if err := sc.checkPriority(f.StreamID, f.PriorityParam); err != nil {
return err
}
@ -2099,12 +2154,6 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res
return nil, nil, sc.countError("bad_path_method", streamError(f.StreamID, ErrCodeProtocol))
}
bodyOpen := !f.StreamEnded()
if rp.method == "HEAD" && bodyOpen {
// HEAD requests can't have bodies
return nil, nil, sc.countError("head_body", streamError(f.StreamID, ErrCodeProtocol))
}
rp.header = make(http.Header)
for _, hf := range f.RegularFields() {
rp.header.Add(sc.canonicalHeader(hf.Name), hf.Value)
@ -2117,6 +2166,7 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res
if err != nil {
return nil, nil, err
}
bodyOpen := !f.StreamEnded()
if bodyOpen {
if vv, ok := rp.header["Content-Length"]; ok {
if cl, err := strconv.ParseUint(vv[0], 10, 63); err == nil {
@ -2346,7 +2396,7 @@ func (sc *serverConn) sendWindowUpdate(st *stream, n int) {
// a larger Read than this. Very unlikely, but we handle it here
// rather than elsewhere for now.
const maxUint31 = 1<<31 - 1
for n >= maxUint31 {
for n > maxUint31 {
sc.sendWindowUpdate32(st, maxUint31)
n -= maxUint31
}
@ -2466,7 +2516,15 @@ type responseWriterState struct {
type chunkWriter struct{ rws *responseWriterState }
func (cw chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) }
func (cw chunkWriter) Write(p []byte) (n int, err error) {
n, err = cw.rws.writeChunk(p)
if err == errStreamClosed {
// If writing failed because the stream has been closed,
// return the reason it was closed.
err = cw.rws.stream.closeErr
}
return n, err
}
func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) > 0 }
@ -2505,6 +2563,10 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
rws.writeHeader(200)
}
if rws.handlerDone {
rws.promoteUndeclaredTrailers()
}
isHeadResp := rws.req.Method == "HEAD"
if !rws.sentHeader {
rws.sentHeader = true
@ -2576,10 +2638,6 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
return 0, nil
}
if rws.handlerDone {
rws.promoteUndeclaredTrailers()
}
// only send trailers if they have actually been defined by the
// server handler.
hasNonemptyTrailers := rws.hasNonemptyTrailers()
@ -2660,23 +2718,85 @@ func (rws *responseWriterState) promoteUndeclaredTrailers() {
}
}
func (w *responseWriter) SetReadDeadline(deadline time.Time) error {
st := w.rws.stream
if !deadline.IsZero() && deadline.Before(time.Now()) {
// If we're setting a deadline in the past, reset the stream immediately
// so writes after SetWriteDeadline returns will fail.
st.onReadTimeout()
return nil
}
w.rws.conn.sendServeMsg(func(sc *serverConn) {
if st.readDeadline != nil {
if !st.readDeadline.Stop() {
// Deadline already exceeded, or stream has been closed.
return
}
}
if deadline.IsZero() {
st.readDeadline = nil
} else if st.readDeadline == nil {
st.readDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onReadTimeout)
} else {
st.readDeadline.Reset(deadline.Sub(time.Now()))
}
})
return nil
}
func (w *responseWriter) SetWriteDeadline(deadline time.Time) error {
st := w.rws.stream
if !deadline.IsZero() && deadline.Before(time.Now()) {
// If we're setting a deadline in the past, reset the stream immediately
// so writes after SetWriteDeadline returns will fail.
st.onWriteTimeout()
return nil
}
w.rws.conn.sendServeMsg(func(sc *serverConn) {
if st.writeDeadline != nil {
if !st.writeDeadline.Stop() {
// Deadline already exceeded, or stream has been closed.
return
}
}
if deadline.IsZero() {
st.writeDeadline = nil
} else if st.writeDeadline == nil {
st.writeDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onWriteTimeout)
} else {
st.writeDeadline.Reset(deadline.Sub(time.Now()))
}
})
return nil
}
func (w *responseWriter) Flush() {
w.FlushError()
}
func (w *responseWriter) FlushError() error {
rws := w.rws
if rws == nil {
panic("Header called after Handler finished")
}
var err error
if rws.bw.Buffered() > 0 {
if err := rws.bw.Flush(); err != nil {
// Ignore the error. The frame writer already knows.
return
}
err = rws.bw.Flush()
} else {
// The bufio.Writer won't call chunkWriter.Write
// (writeChunk with zero bytes, so we have to do it
// ourselves to force the HTTP response header and/or
// final DATA frame (with END_STREAM) to be sent.
rws.writeChunk(nil)
_, err = chunkWriter{rws}.Write(nil)
if err == nil {
select {
case <-rws.stream.cw:
err = rws.stream.closeErr
default:
}
}
}
return err
}
func (w *responseWriter) CloseNotify() <-chan bool {

View file

@ -16,6 +16,7 @@ import (
"errors"
"fmt"
"io"
"io/fs"
"log"
"math"
mathrand "math/rand"
@ -117,6 +118,28 @@ type Transport struct {
// to mean no limit.
MaxHeaderListSize uint32
// MaxReadFrameSize is the http2 SETTINGS_MAX_FRAME_SIZE to send in the
// initial settings frame. It is the size in bytes of the largest frame
// payload that the sender is willing to receive. If 0, no setting is
// sent, and the value is provided by the peer, which should be 16384
// according to the spec:
// https://datatracker.ietf.org/doc/html/rfc7540#section-6.5.2.
// Values are bounded in the range 16k to 16M.
MaxReadFrameSize uint32
// MaxDecoderHeaderTableSize optionally specifies the http2
// SETTINGS_HEADER_TABLE_SIZE to send in the initial settings frame. It
// informs the remote endpoint of the maximum size of the header compression
// table used to decode header blocks, in octets. If zero, the default value
// of 4096 is used.
MaxDecoderHeaderTableSize uint32
// MaxEncoderHeaderTableSize optionally specifies an upper limit for the
// header compression table used for encoding request headers. Received
// SETTINGS_HEADER_TABLE_SIZE settings are capped at this limit. If zero,
// the default value of 4096 is used.
MaxEncoderHeaderTableSize uint32
// StrictMaxConcurrentStreams controls whether the server's
// SETTINGS_MAX_CONCURRENT_STREAMS should be respected
// globally. If false, new TCP connections are created to the
@ -170,6 +193,19 @@ func (t *Transport) maxHeaderListSize() uint32 {
return t.MaxHeaderListSize
}
func (t *Transport) maxFrameReadSize() uint32 {
if t.MaxReadFrameSize == 0 {
return 0 // use the default provided by the peer
}
if t.MaxReadFrameSize < minMaxFrameSize {
return minMaxFrameSize
}
if t.MaxReadFrameSize > maxFrameSize {
return maxFrameSize
}
return t.MaxReadFrameSize
}
func (t *Transport) disableCompression() bool {
return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression)
}
@ -258,7 +294,8 @@ func (t *Transport) initConnPool() {
// HTTP/2 server.
type ClientConn struct {
t *Transport
tconn net.Conn // usually *tls.Conn, except specialized impls
tconn net.Conn // usually *tls.Conn, except specialized impls
tconnClosed bool
tlsState *tls.ConnectionState // nil only for specialized impls
reused uint32 // whether conn is being reused; atomic
singleUse bool // whether being used for a single http.Request
@ -291,10 +328,11 @@ type ClientConn struct {
lastActive time.Time
lastIdle time.Time // time last idle
// Settings from peer: (also guarded by wmu)
maxFrameSize uint32
maxConcurrentStreams uint32
peerMaxHeaderListSize uint64
initialWindowSize uint32
maxFrameSize uint32
maxConcurrentStreams uint32
peerMaxHeaderListSize uint64
peerMaxHeaderTableSize uint32
initialWindowSize uint32
// reqHeaderMu is a 1-element semaphore channel controlling access to sending new requests.
// Write to reqHeaderMu to lock it, read from it to unlock.
@ -344,8 +382,8 @@ type clientStream struct {
readErr error // sticky read error; owned by transportResponseBody.Read
reqBody io.ReadCloser
reqBodyContentLength int64 // -1 means unknown
reqBodyClosed bool // body has been closed; guarded by cc.mu
reqBodyContentLength int64 // -1 means unknown
reqBodyClosed chan struct{} // guarded by cc.mu; non-nil on Close, closed when done
// owned by writeRequest:
sentEndStream bool // sent an END_STREAM flag to the peer
@ -385,9 +423,8 @@ func (cs *clientStream) abortStreamLocked(err error) {
cs.abortErr = err
close(cs.abort)
})
if cs.reqBody != nil && !cs.reqBodyClosed {
cs.reqBody.Close()
cs.reqBodyClosed = true
if cs.reqBody != nil {
cs.closeReqBodyLocked()
}
// TODO(dneil): Clean up tests where cs.cc.cond is nil.
if cs.cc.cond != nil {
@ -400,13 +437,24 @@ func (cs *clientStream) abortRequestBodyWrite() {
cc := cs.cc
cc.mu.Lock()
defer cc.mu.Unlock()
if cs.reqBody != nil && !cs.reqBodyClosed {
cs.reqBody.Close()
cs.reqBodyClosed = true
if cs.reqBody != nil && cs.reqBodyClosed == nil {
cs.closeReqBodyLocked()
cc.cond.Broadcast()
}
}
func (cs *clientStream) closeReqBodyLocked() {
if cs.reqBodyClosed != nil {
return
}
cs.reqBodyClosed = make(chan struct{})
reqBodyClosed := cs.reqBodyClosed
go func() {
cs.reqBody.Close()
close(reqBodyClosed)
}()
}
type stickyErrWriter struct {
conn net.Conn
timeout time.Duration
@ -490,6 +538,15 @@ func authorityAddr(scheme string, authority string) (addr string) {
return net.JoinHostPort(host, port)
}
var retryBackoffHook func(time.Duration) *time.Timer
func backoffNewTimer(d time.Duration) *time.Timer {
if retryBackoffHook != nil {
return retryBackoffHook(d)
}
return time.NewTimer(d)
}
// RoundTripOpt is like RoundTrip, but takes options.
func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) {
if !(req.URL.Scheme == "https" || (req.URL.Scheme == "http" && t.AllowHTTP)) {
@ -515,11 +572,14 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res
}
backoff := float64(uint(1) << (uint(retry) - 1))
backoff += backoff * (0.1 * mathrand.Float64())
d := time.Second * time.Duration(backoff)
timer := backoffNewTimer(d)
select {
case <-time.After(time.Second * time.Duration(backoff)):
case <-timer.C:
t.vlogf("RoundTrip retrying after failure: %v", err)
continue
case <-req.Context().Done():
timer.Stop()
err = req.Context().Err()
}
}
@ -657,6 +717,20 @@ func (t *Transport) expectContinueTimeout() time.Duration {
return t.t1.ExpectContinueTimeout
}
func (t *Transport) maxDecoderHeaderTableSize() uint32 {
if v := t.MaxDecoderHeaderTableSize; v > 0 {
return v
}
return initialHeaderTableSize
}
func (t *Transport) maxEncoderHeaderTableSize() uint32 {
if v := t.MaxEncoderHeaderTableSize; v > 0 {
return v
}
return initialHeaderTableSize
}
func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) {
return t.newClientConn(c, t.disableKeepAlives())
}
@ -697,15 +771,19 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
})
cc.br = bufio.NewReader(c)
cc.fr = NewFramer(cc.bw, cc.br)
if t.maxFrameReadSize() != 0 {
cc.fr.SetMaxReadFrameSize(t.maxFrameReadSize())
}
if t.CountError != nil {
cc.fr.countError = t.CountError
}
cc.fr.ReadMetaHeaders = hpack.NewDecoder(initialHeaderTableSize, nil)
maxHeaderTableSize := t.maxDecoderHeaderTableSize()
cc.fr.ReadMetaHeaders = hpack.NewDecoder(maxHeaderTableSize, nil)
cc.fr.MaxHeaderListSize = t.maxHeaderListSize()
// TODO: SetMaxDynamicTableSize, SetMaxDynamicTableSizeLimit on
// henc in response to SETTINGS frames?
cc.henc = hpack.NewEncoder(&cc.hbuf)
cc.henc.SetMaxDynamicTableSizeLimit(t.maxEncoderHeaderTableSize())
cc.peerMaxHeaderTableSize = initialHeaderTableSize
if t.AllowHTTP {
cc.nextStreamID = 3
@ -720,9 +798,15 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
{ID: SettingEnablePush, Val: 0},
{ID: SettingInitialWindowSize, Val: transportDefaultStreamFlow},
}
if max := t.maxFrameReadSize(); max != 0 {
initialSettings = append(initialSettings, Setting{ID: SettingMaxFrameSize, Val: max})
}
if max := t.maxHeaderListSize(); max != 0 {
initialSettings = append(initialSettings, Setting{ID: SettingMaxHeaderListSize, Val: max})
}
if maxHeaderTableSize != initialHeaderTableSize {
initialSettings = append(initialSettings, Setting{ID: SettingHeaderTableSize, Val: maxHeaderTableSize})
}
cc.bw.Write(clientPreface)
cc.fr.WriteSettings(initialSettings...)
@ -921,10 +1005,10 @@ func (cc *ClientConn) onIdleTimeout() {
cc.closeIfIdle()
}
func (cc *ClientConn) closeConn() error {
func (cc *ClientConn) closeConn() {
t := time.AfterFunc(250*time.Millisecond, cc.forceCloseConn)
defer t.Stop()
return cc.tconn.Close()
cc.tconn.Close()
}
// A tls.Conn.Close can hang for a long time if the peer is unresponsive.
@ -990,7 +1074,8 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error {
shutdownEnterWaitStateHook()
select {
case <-done:
return cc.closeConn()
cc.closeConn()
return nil
case <-ctx.Done():
cc.mu.Lock()
// Free the goroutine above
@ -1027,7 +1112,7 @@ func (cc *ClientConn) sendGoAway() error {
// closes the client connection immediately. In-flight requests are interrupted.
// err is sent to streams.
func (cc *ClientConn) closeForError(err error) error {
func (cc *ClientConn) closeForError(err error) {
cc.mu.Lock()
cc.closed = true
for _, cs := range cc.streams {
@ -1035,7 +1120,7 @@ func (cc *ClientConn) closeForError(err error) error {
}
cc.cond.Broadcast()
cc.mu.Unlock()
return cc.closeConn()
cc.closeConn()
}
// Close closes the client connection immediately.
@ -1043,16 +1128,17 @@ func (cc *ClientConn) closeForError(err error) error {
// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead.
func (cc *ClientConn) Close() error {
err := errors.New("http2: client connection force closed via ClientConn.Close")
return cc.closeForError(err)
cc.closeForError(err)
return nil
}
// closes the client connection immediately. In-flight requests are interrupted.
func (cc *ClientConn) closeForLostPing() error {
func (cc *ClientConn) closeForLostPing() {
err := errors.New("http2: client connection lost")
if f := cc.t.CountError; f != nil {
f("conn_close_lost_ping")
}
return cc.closeForError(err)
cc.closeForError(err)
}
// errRequestCanceled is a copy of net/http's errRequestCanceled because it's not
@ -1062,7 +1148,7 @@ var errRequestCanceled = errors.New("net/http: request canceled")
func commaSeparatedTrailers(req *http.Request) (string, error) {
keys := make([]string, 0, len(req.Trailer))
for k := range req.Trailer {
k = http.CanonicalHeaderKey(k)
k = canonicalHeader(k)
switch k {
case "Transfer-Encoding", "Trailer", "Content-Length":
return "", fmt.Errorf("invalid Trailer key %q", k)
@ -1430,11 +1516,19 @@ func (cs *clientStream) cleanupWriteRequest(err error) {
// and in multiple cases: server replies <=299 and >299
// while still writing request body
cc.mu.Lock()
mustCloseBody := false
if cs.reqBody != nil && cs.reqBodyClosed == nil {
mustCloseBody = true
cs.reqBodyClosed = make(chan struct{})
}
bodyClosed := cs.reqBodyClosed
cs.reqBodyClosed = true
cc.mu.Unlock()
if !bodyClosed && cs.reqBody != nil {
if mustCloseBody {
cs.reqBody.Close()
close(bodyClosed)
}
if bodyClosed != nil {
<-bodyClosed
}
if err != nil && cs.sentEndStream {
@ -1591,7 +1685,7 @@ func (cs *clientStream) writeRequestBody(req *http.Request) (err error) {
var sawEOF bool
for !sawEOF {
n, err := body.Read(buf[:len(buf)])
n, err := body.Read(buf)
if hasContentLen {
remainLen -= int64(n)
if remainLen == 0 && err == nil {
@ -1614,7 +1708,7 @@ func (cs *clientStream) writeRequestBody(req *http.Request) (err error) {
}
if err != nil {
cc.mu.Lock()
bodyClosed := cs.reqBodyClosed
bodyClosed := cs.reqBodyClosed != nil
cc.mu.Unlock()
switch {
case bodyClosed:
@ -1709,7 +1803,7 @@ func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error)
if cc.closed {
return 0, errClientConnClosed
}
if cs.reqBodyClosed {
if cs.reqBodyClosed != nil {
return 0, errStopReqBodyWrite
}
select {
@ -1894,7 +1988,7 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail
// Header list size is ok. Write the headers.
enumerateHeaders(func(name, value string) {
name, ascii := asciiToLower(name)
name, ascii := lowerHeader(name)
if !ascii {
// Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
// field names have to be ASCII characters (just as in HTTP/1.x).
@ -1947,7 +2041,7 @@ func (cc *ClientConn) encodeTrailers(trailer http.Header) ([]byte, error) {
}
for k, vv := range trailer {
lowKey, ascii := asciiToLower(k)
lowKey, ascii := lowerHeader(k)
if !ascii {
// Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
// field names have to be ASCII characters (just as in HTTP/1.x).
@ -2005,7 +2099,7 @@ func (cc *ClientConn) forgetStreamID(id uint32) {
// wake up RoundTrip if there is a pending request.
cc.cond.Broadcast()
closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives()
closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil
if closeOnIdle && cc.streamsReserved == 0 && len(cc.streams) == 0 {
if VerboseLogs {
cc.vlogf("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)", cc, cc.singleUse, cc.nextStreamID-2)
@ -2081,6 +2175,7 @@ func (rl *clientConnReadLoop) cleanup() {
err = io.ErrUnexpectedEOF
}
cc.closed = true
for _, cs := range cc.streams {
select {
case <-cs.peerClosed:
@ -2279,7 +2374,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra
Status: status + " " + http.StatusText(statusCode),
}
for _, hf := range regularFields {
key := http.CanonicalHeaderKey(hf.Name)
key := canonicalHeader(hf.Name)
if key == "Trailer" {
t := res.Trailer
if t == nil {
@ -2287,7 +2382,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra
res.Trailer = t
}
foreachHeaderElement(hf.Value, func(v string) {
t[http.CanonicalHeaderKey(v)] = nil
t[canonicalHeader(v)] = nil
})
} else {
vv := header[key]
@ -2392,7 +2487,7 @@ func (rl *clientConnReadLoop) processTrailers(cs *clientStream, f *MetaHeadersFr
trailer := make(http.Header)
for _, hf := range f.RegularFields() {
key := http.CanonicalHeaderKey(hf.Name)
key := canonicalHeader(hf.Name)
trailer[key] = append(trailer[key], hf.Value)
}
cs.trailer = trailer
@ -2674,7 +2769,6 @@ func (rl *clientConnReadLoop) processGoAway(f *GoAwayFrame) error {
if fn := cc.t.CountError; fn != nil {
fn("recv_goaway_" + f.ErrCode.stringToken())
}
}
cc.setGoAway(f)
return nil
@ -2739,8 +2833,10 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error {
cc.cond.Broadcast()
cc.initialWindowSize = s.Val
case SettingHeaderTableSize:
cc.henc.SetMaxDynamicTableSize(s.Val)
cc.peerMaxHeaderTableSize = s.Val
default:
// TODO(bradfitz): handle more settings? SETTINGS_HEADER_TABLE_SIZE probably.
cc.vlogf("Unhandled Setting: %v", s)
}
return nil
@ -2964,7 +3060,11 @@ func (gz *gzipReader) Read(p []byte) (n int, err error) {
}
func (gz *gzipReader) Close() error {
return gz.body.Close()
if err := gz.body.Close(); err != nil {
return err
}
gz.zerr = fs.ErrClosed
return nil
}
type errorReader struct{ err error }
@ -3028,7 +3128,7 @@ func traceGotConn(req *http.Request, cc *ClientConn, reused bool) {
cc.mu.Lock()
ci.WasIdle = len(cc.streams) == 0 && reused
if ci.WasIdle && !cc.lastActive.IsZero() {
ci.IdleTime = time.Now().Sub(cc.lastActive)
ci.IdleTime = time.Since(cc.lastActive)
}
cc.mu.Unlock()

View file

@ -395,7 +395,7 @@ func New(family, title string) Trace {
}
func (tr *trace) Finish() {
elapsed := time.Now().Sub(tr.Start)
elapsed := time.Since(tr.Start)
tr.mu.Lock()
tr.Elapsed = elapsed
tr.mu.Unlock()

3
vendor/golang.org/x/sync/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.

View file

@ -6,7 +6,10 @@ package cpu
import "runtime"
const cacheLineSize = 64
// cacheLineSize is used to prevent false sharing of cache lines.
// We choose 128 because Apple Silicon, a.k.a. M1, has 128-byte cache line size.
// It doesn't cost much and is much more future-proof.
const cacheLineSize = 128
func initOptions() {
options = []option{
@ -41,13 +44,10 @@ func archInit() {
switch runtime.GOOS {
case "freebsd":
readARM64Registers()
case "linux", "netbsd":
case "linux", "netbsd", "openbsd":
doinit()
default:
// Most platforms don't seem to allow reading these registers.
//
// OpenBSD:
// See https://golang.org/issue/31746
// Many platforms don't seem to allow reading these registers.
setMinimalFeatures()
}
}

65
vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go generated vendored Normal file
View file

@ -0,0 +1,65 @@
// 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.
package cpu
import (
"syscall"
"unsafe"
)
// Minimal copy of functionality from x/sys/unix so the cpu package can call
// sysctl without depending on x/sys/unix.
const (
// From OpenBSD's sys/sysctl.h.
_CTL_MACHDEP = 7
// From OpenBSD's machine/cpu.h.
_CPU_ID_AA64ISAR0 = 2
_CPU_ID_AA64ISAR1 = 3
)
// Implemented in the runtime package (runtime/sys_openbsd3.go)
func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
//go:linkname syscall_syscall6 syscall.syscall6
func sysctl(mib []uint32, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
_, _, errno := syscall_syscall6(libc_sysctl_trampoline_addr, uintptr(unsafe.Pointer(&mib[0])), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
if errno != 0 {
return errno
}
return nil
}
var libc_sysctl_trampoline_addr uintptr
//go:cgo_import_dynamic libc_sysctl sysctl "libc.so"
func sysctlUint64(mib []uint32) (uint64, bool) {
var out uint64
nout := unsafe.Sizeof(out)
if err := sysctl(mib, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0); err != nil {
return 0, false
}
return out, true
}
func doinit() {
setMinimalFeatures()
// Get ID_AA64ISAR0 and ID_AA64ISAR1 from sysctl.
isar0, ok := sysctlUint64([]uint32{_CTL_MACHDEP, _CPU_ID_AA64ISAR0})
if !ok {
return
}
isar1, ok := sysctlUint64([]uint32{_CTL_MACHDEP, _CPU_ID_AA64ISAR1})
if !ok {
return
}
parseARM64SystemRegisters(isar0, isar1, 0)
Initialized = true
}

11
vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.s generated vendored Normal file
View file

@ -0,0 +1,11 @@
// 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.
#include "textflag.h"
TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_sysctl(SB)
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)

View file

@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !linux && !netbsd && arm64
// +build !linux,!netbsd,arm64
//go:build !linux && !netbsd && !openbsd && arm64
// +build !linux,!netbsd,!openbsd,arm64
package cpu

15
vendor/golang.org/x/sys/cpu/cpu_other_ppc64x.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 !aix && !linux && (ppc64 || ppc64le)
// +build !aix
// +build !linux
// +build ppc64 ppc64le
package cpu
func archInit() {
PPC64.IsPOWER8 = true
Initialized = true
}

View file

@ -7,9 +7,11 @@
package execabs
import "strings"
import (
"errors"
"os/exec"
)
func isGo119ErrDot(err error) bool {
// TODO: return errors.Is(err, exec.ErrDot)
return strings.Contains(err.Error(), "current directory")
return errors.Is(err, exec.ErrDot)
}

View file

@ -126,7 +126,7 @@ errors=$(
signals=$(
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT' |
sort
)
@ -136,7 +136,7 @@ echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
sort >_error.grep
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT' |
sort >_signal.grep
echo '// mkerrors.sh' "$@"

View file

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

31
vendor/golang.org/x/sys/unix/asm_bsd_ppc64.s generated vendored Normal file
View file

@ -0,0 +1,31 @@
// 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 || freebsd || netbsd || openbsd) && gc
// +build darwin freebsd netbsd openbsd
// +build gc
#include "textflag.h"
//
// System call support for ppc64, 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)

View file

@ -2,8 +2,8 @@
// 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
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package unix

View file

@ -4,9 +4,7 @@
package unix
import (
"unsafe"
)
import "unsafe"
// IoctlRetInt performs an ioctl operation specified by req on a device
// associated with opened file descriptor fd, and returns a non-negative
@ -217,3 +215,19 @@ func IoctlKCMAttach(fd int, info KCMAttach) error {
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)
mkerrors="$mkerrors -m64"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
mkasm="go run mkasm_darwin.go"
mkasm="go run mkasm.go"
;;
darwin_arm64)
mkerrors="$mkerrors -m64"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
mkasm="go run mkasm_darwin.go"
mkasm="go run mkasm.go"
;;
dragonfly_amd64)
mkerrors="$mkerrors -m64"
@ -142,33 +142,33 @@ netbsd_arm64)
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
openbsd_386)
mkasm="go run mkasm.go"
mkerrors="$mkerrors -m32"
mksyscall="go run mksyscall.go -l32 -openbsd"
mksyscall="go run mksyscall.go -l32 -openbsd -libc"
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"
;;
openbsd_amd64)
mkasm="go run mkasm.go"
mkerrors="$mkerrors -m64"
mksyscall="go run mksyscall.go -openbsd"
mksyscall="go run mksyscall.go -openbsd -libc"
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"
;;
openbsd_arm)
mkasm="go run mkasm.go"
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"
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
# API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
openbsd_arm64)
mkasm="go run mkasm.go"
mkerrors="$mkerrors -m64"
mksyscall="go run mksyscall.go -openbsd"
mksyscall="go run mksyscall.go -openbsd -libc"
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
# API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
@ -182,6 +182,24 @@ openbsd_mips64)
# API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
openbsd_ppc64)
mkasm="go run mkasm.go"
mkerrors="$mkerrors -m64"
mksyscall="go run mksyscall.go -openbsd -libc"
mksysctl="go run mksysctl_openbsd.go"
# Let the type of C char be signed for making the bare syscall
# API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
openbsd_riscv64)
mkasm="go run mkasm.go"
mkerrors="$mkerrors -m64"
mksyscall="go run mksyscall.go -openbsd -libc"
mksysctl="go run mksysctl_openbsd.go"
# Let the type of C char be signed for making the bare syscall
# API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
solaris_amd64)
mksyscall="go run mksyscall_solaris.go"
mkerrors="$mkerrors -m64"
@ -214,11 +232,6 @@ esac
if [ "$GOOSARCH" == "aix_ppc64" ]; then
# aix/ppc64 script generates files instead of writing to stdin.
echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in && gofmt -w zsyscall_$GOOSARCH.go && gofmt -w zsyscall_"$GOOSARCH"_gccgo.go && gofmt -w zsyscall_"$GOOSARCH"_gc.go " ;
elif [ "$GOOS" == "darwin" ]; then
# 1.12 and later, syscalls via libSystem
echo "$mksyscall -tags $GOOS,$GOARCH,go1.12 $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go";
# 1.13 and later, syscalls via libSystem (including syscallPtr)
echo "$mksyscall -tags $GOOS,$GOARCH,go1.13 syscall_darwin.1_13.go |gofmt >zsyscall_$GOOSARCH.1_13.go";
elif [ "$GOOS" == "illumos" ]; then
# illumos code generation requires a --illumos switch
echo "$mksyscall -illumos -tags illumos,$GOARCH syscall_illumos.go |gofmt > zsyscall_illumos_$GOARCH.go";
@ -232,5 +245,5 @@ esac
if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; 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 "$mkasm" ]; then echo "$mkasm $GOARCH"; fi
if [ -n "$mkasm" ]; then echo "$mkasm $GOOS $GOARCH"; fi
) | $run

View file

@ -642,7 +642,7 @@ errors=$(
signals=$(
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' |
grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' |
sort
)
@ -652,7 +652,7 @@ echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
sort >_error.grep
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' |
grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' |
sort >_signal.grep
echo '// mkerrors.sh' "$@"

View file

@ -52,6 +52,20 @@ func ParseSocketControlMessage(b []byte) ([]SocketControlMessage, error) {
return msgs, nil
}
// ParseOneSocketControlMessage parses a single socket control message from b, returning the message header,
// message data (a slice of b), and the remainder of b after that single message.
// When there are no remaining messages, len(remainder) == 0.
func ParseOneSocketControlMessage(b []byte) (hdr Cmsghdr, data []byte, remainder []byte, err error) {
h, dbuf, err := socketControlMessageHeaderAndData(b)
if err != nil {
return Cmsghdr{}, nil, nil, err
}
if i := cmsgAlignOf(int(h.Len)); i < len(b) {
remainder = b[i:]
}
return *h, dbuf, remainder, nil
}
func socketControlMessageHeaderAndData(b []byte) (*Cmsghdr, []byte, error) {
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
if h.Len < SizeofCmsghdr || uint64(h.Len) > uint64(len(b)) {

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"
"strings"
"unsafe"
"golang.org/x/sys/internal/unsafeheader"
)
// ByteSliceFromString returns a NUL-terminated slice of bytes
@ -82,13 +80,7 @@ func BytePtrToString(p *byte) string {
ptr = unsafe.Pointer(uintptr(ptr) + 1)
}
var s []byte
h := (*unsafeheader.Slice)(unsafe.Pointer(&s))
h.Data = unsafe.Pointer(p)
h.Len = n
h.Cap = n
return string(s)
return string(unsafe.Slice(p, n))
}
// Single-word zero for use when we need a valid pointer to 0 bytes.

View file

@ -253,7 +253,7 @@ func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Sockle
var empty bool
if len(oob) > 0 {
// send at least one normal byte
empty := emptyIovecs(iov)
empty = emptyIovecs(iov)
if empty {
var iova [1]Iovec
iova[0].Base = &dummy

View file

@ -363,7 +363,7 @@ func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Sockle
var empty bool
if len(oob) > 0 {
// send at least one normal byte
empty := emptyIovecs(iov)
empty = emptyIovecs(iov)
if empty {
var iova [1]Iovec
iova[0].Base = &dummy

View file

@ -1,32 +0,0 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build darwin && go1.12 && !go1.13
// +build darwin,go1.12,!go1.13
package unix
import (
"unsafe"
)
const _SYS_GETDIRENTRIES64 = 344
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
// To implement this using libSystem we'd need syscall_syscallPtr for
// fdopendir. However, syscallPtr was only added in Go 1.13, so we fall
// back to raw syscalls for this func on Go 1.12.
var p unsafe.Pointer
if len(buf) > 0 {
p = unsafe.Pointer(&buf[0])
} else {
p = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall6(_SYS_GETDIRENTRIES64, uintptr(fd), uintptr(p), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
n = int(r0)
if e1 != 0 {
return n, errnoErr(e1)
}
return n, nil
}

View file

@ -1,108 +0,0 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build darwin && go1.13
// +build darwin,go1.13
package unix
import (
"unsafe"
"golang.org/x/sys/internal/unsafeheader"
)
//sys closedir(dir uintptr) (err error)
//sys readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno)
func fdopendir(fd int) (dir uintptr, err error) {
r0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0)
dir = uintptr(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_fdopendir_trampoline_addr uintptr
//go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib"
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
// Simulate Getdirentries using fdopendir/readdir_r/closedir.
// We store the number of entries to skip in the seek
// offset of fd. See issue #31368.
// It's not the full required semantics, but should handle the case
// of calling Getdirentries or ReadDirent repeatedly.
// It won't handle assigning the results of lseek to *basep, or handle
// the directory being edited underfoot.
skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
if err != nil {
return 0, err
}
// We need to duplicate the incoming file descriptor
// because the caller expects to retain control of it, but
// fdopendir expects to take control of its argument.
// Just Dup'ing the file descriptor is not enough, as the
// result shares underlying state. Use Openat to make a really
// new file descriptor referring to the same directory.
fd2, err := Openat(fd, ".", O_RDONLY, 0)
if err != nil {
return 0, err
}
d, err := fdopendir(fd2)
if err != nil {
Close(fd2)
return 0, err
}
defer closedir(d)
var cnt int64
for {
var entry Dirent
var entryp *Dirent
e := readdir_r(d, &entry, &entryp)
if e != 0 {
return n, errnoErr(e)
}
if entryp == nil {
break
}
if skip > 0 {
skip--
cnt++
continue
}
reclen := int(entry.Reclen)
if reclen > len(buf) {
// Not enough room. Return for now.
// The counter will let us know where we should start up again.
// Note: this strategy for suspending in the middle and
// restarting is O(n^2) in the length of the directory. Oh well.
break
}
// Copy entry into return buffer.
var s []byte
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&s))
hdr.Data = unsafe.Pointer(&entry)
hdr.Cap = reclen
hdr.Len = reclen
copy(buf, s)
buf = buf[reclen:]
n += reclen
cnt++
}
// Set the seek offset of the input fd to record
// how many files we've already returned.
_, err = Seek(fd, cnt, 0 /* SEEK_SET */)
if err != nil {
return n, err
}
return n, nil
}

View file

@ -19,6 +19,96 @@ import (
"unsafe"
)
//sys closedir(dir uintptr) (err error)
//sys readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno)
func fdopendir(fd int) (dir uintptr, err error) {
r0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0)
dir = uintptr(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_fdopendir_trampoline_addr uintptr
//go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib"
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
// Simulate Getdirentries using fdopendir/readdir_r/closedir.
// We store the number of entries to skip in the seek
// offset of fd. See issue #31368.
// It's not the full required semantics, but should handle the case
// of calling Getdirentries or ReadDirent repeatedly.
// It won't handle assigning the results of lseek to *basep, or handle
// the directory being edited underfoot.
skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
if err != nil {
return 0, err
}
// We need to duplicate the incoming file descriptor
// because the caller expects to retain control of it, but
// fdopendir expects to take control of its argument.
// Just Dup'ing the file descriptor is not enough, as the
// result shares underlying state. Use Openat to make a really
// new file descriptor referring to the same directory.
fd2, err := Openat(fd, ".", O_RDONLY, 0)
if err != nil {
return 0, err
}
d, err := fdopendir(fd2)
if err != nil {
Close(fd2)
return 0, err
}
defer closedir(d)
var cnt int64
for {
var entry Dirent
var entryp *Dirent
e := readdir_r(d, &entry, &entryp)
if e != 0 {
return n, errnoErr(e)
}
if entryp == nil {
break
}
if skip > 0 {
skip--
cnt++
continue
}
reclen := int(entry.Reclen)
if reclen > len(buf) {
// Not enough room. Return for now.
// The counter will let us know where we should start up again.
// Note: this strategy for suspending in the middle and
// restarting is O(n^2) in the length of the directory. Oh well.
break
}
// Copy entry into return buffer.
s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)
copy(buf, s)
buf = buf[reclen:]
n += reclen
cnt++
}
// Set the seek offset of the input fd to record
// how many files we've already returned.
_, err = Seek(fd, cnt, 0 /* SEEK_SET */)
if err != nil {
return n, err
}
return n, nil
}
// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
type SockaddrDatalink struct {
Len uint8

View file

@ -61,7 +61,7 @@ func PtraceGetFsBase(pid int, fsbase *int64) (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(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
return int(ioDesc.Len), err
}

View file

@ -61,7 +61,7 @@ func PtraceGetFsBase(pid int, fsbase *int64) (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(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
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 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(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
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 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(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
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 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(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
return int(ioDesc.Len), err
}

View file

@ -10,8 +10,6 @@
package unix
import (
"fmt"
"runtime"
"unsafe"
)
@ -79,107 +77,3 @@ func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
}
return
}
//sys putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error)
func Putmsg(fd int, cl []byte, data []byte, flags int) (err error) {
var clp, datap *strbuf
if len(cl) > 0 {
clp = &strbuf{
Len: int32(len(cl)),
Buf: (*int8)(unsafe.Pointer(&cl[0])),
}
}
if len(data) > 0 {
datap = &strbuf{
Len: int32(len(data)),
Buf: (*int8)(unsafe.Pointer(&data[0])),
}
}
return putmsg(fd, clp, datap, flags)
}
//sys getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error)
func Getmsg(fd int, cl []byte, data []byte) (retCl []byte, retData []byte, flags int, err error) {
var clp, datap *strbuf
if len(cl) > 0 {
clp = &strbuf{
Maxlen: int32(len(cl)),
Buf: (*int8)(unsafe.Pointer(&cl[0])),
}
}
if len(data) > 0 {
datap = &strbuf{
Maxlen: int32(len(data)),
Buf: (*int8)(unsafe.Pointer(&data[0])),
}
}
if err = getmsg(fd, clp, datap, &flags); err != nil {
return nil, nil, 0, err
}
if len(cl) > 0 {
retCl = cl[:clp.Len]
}
if len(data) > 0 {
retData = data[:datap.Len]
}
return retCl, retData, flags, nil
}
func IoctlSetIntRetInt(fd int, req uint, arg int) (int, error) {
return ioctlRet(fd, req, uintptr(arg))
}
func IoctlSetString(fd int, req uint, val string) error {
bs := make([]byte, len(val)+1)
copy(bs[:len(bs)-1], val)
err := ioctl(fd, req, uintptr(unsafe.Pointer(&bs[0])))
runtime.KeepAlive(&bs[0])
return err
}
// Lifreq Helpers
func (l *Lifreq) SetName(name string) error {
if len(name) >= len(l.Name) {
return fmt.Errorf("name cannot be more than %d characters", len(l.Name)-1)
}
for i := range name {
l.Name[i] = int8(name[i])
}
return nil
}
func (l *Lifreq) SetLifruInt(d int) {
*(*int)(unsafe.Pointer(&l.Lifru[0])) = d
}
func (l *Lifreq) GetLifruInt() int {
return *(*int)(unsafe.Pointer(&l.Lifru[0]))
}
func (l *Lifreq) SetLifruUint(d uint) {
*(*uint)(unsafe.Pointer(&l.Lifru[0])) = d
}
func (l *Lifreq) GetLifruUint() uint {
return *(*uint)(unsafe.Pointer(&l.Lifru[0]))
}
func IoctlLifreq(fd int, req uint, l *Lifreq) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(l)))
}
// Strioctl Helpers
func (s *Strioctl) SetInt(i int) {
s.Len = int32(unsafe.Sizeof(i))
s.Dp = (*int8)(unsafe.Pointer(&i))
}
func IoctlSetStrioctlRetInt(fd int, req uint, s *Strioctl) (int, error) {
return ioctlRet(fd, req, uintptr(unsafe.Pointer(s)))
}

View file

@ -13,6 +13,7 @@ package unix
import (
"encoding/binary"
"strconv"
"syscall"
"time"
"unsafe"
@ -233,7 +234,7 @@ func Futimesat(dirfd int, path string, tv []Timeval) error {
func Futimes(fd int, tv []Timeval) (err error) {
// Believe it or not, this is the best we can do on Linux
// (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
@ -1541,7 +1542,7 @@ func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Sockle
var dummy byte
var empty bool
if len(oob) > 0 {
empty := emptyIovecs(iov)
empty = emptyIovecs(iov)
if empty {
var sockType int
sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
@ -1553,6 +1554,7 @@ func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Sockle
var iova [1]Iovec
iova[0].Base = &dummy
iova[0].SetLen(1)
iov = iova[:]
}
}
msg.Control = &oob[0]
@ -1891,17 +1893,28 @@ func PrctlRetInt(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uint
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) {
return EOPNOTSUPP
return syscall.Setuid(uid)
}
func Setgid(uid int) (err error) {
return EOPNOTSUPP
func Setgid(gid int) (err error) {
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.
@ -2240,7 +2253,7 @@ func (fh *FileHandle) Bytes() []byte {
if n == 0 {
return nil
}
return (*[1 << 30]byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type)) + 4))[:n:n]
return unsafe.Slice((*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type))+4)), n)
}
// NameToHandleAt wraps the name_to_handle_at system call; it obtains
@ -2356,6 +2369,16 @@ func Setitimer(which ItimerWhich, it Itimerval) (Itimerval, error) {
return prev, nil
}
//sysnb rtSigprocmask(how int, set *Sigset_t, oldset *Sigset_t, sigsetsize uintptr) (err error) = SYS_RT_SIGPROCMASK
func PthreadSigmask(how int, set, oldset *Sigset_t) error {
if oldset != nil {
// Explicitly clear in case Sigset_t is larger than _C__NSIG.
*oldset = Sigset_t{}
}
return rtSigprocmask(how, set, oldset, _C__NSIG/8)
}
/*
* Unimplemented
*/
@ -2414,7 +2437,6 @@ func Setitimer(which ItimerWhich, it Itimerval) (Itimerval, error) {
// RestartSyscall
// RtSigaction
// RtSigpending
// RtSigprocmask
// RtSigqueueinfo
// RtSigreturn
// RtSigsuspend

View file

@ -41,10 +41,6 @@ func setTimeval(sec, usec int64) Timeval {
//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 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 Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)

View file

@ -46,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 setfsgid(gid 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 Setreuid(ruid int, euid 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)

View file

@ -62,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 setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32
//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 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

View file

@ -39,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 setfsgid(gid 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 Setreuid(ruid int, euid 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)

View file

@ -34,10 +34,6 @@ 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 setfsgid(gid 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 Setreuid(ruid int, euid 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)

View file

@ -37,11 +37,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 setfsgid(gid 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 Setreuid(ruid int, euid 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 Statfs(path string, buf *Statfs_t) (err error)

View file

@ -32,10 +32,6 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
//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 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 Setreuid(ruid int, euid 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 SyncFileRange(fd int, off int64, n int64, flags int) (err error)

View file

@ -34,10 +34,6 @@ import (
//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 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 Setreuid(ruid int, euid 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 Stat(path string, stat *Stat_t) (err error) = SYS_STAT64

View file

@ -34,11 +34,7 @@ package unix
//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)
//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 Setreuid(ruid int, euid 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 Stat(path string, stat *Stat_t) (err error)

View file

@ -38,11 +38,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 setfsgid(gid 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 Setreuid(ruid int, euid 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)

View file

@ -34,11 +34,7 @@ import (
//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)
//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 Setreuid(ruid int, euid int) (err error)
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
//sys Stat(path string, stat *Stat_t) (err error)
//sys Statfs(path string, buf *Statfs_t) (err error)

View file

@ -31,11 +31,7 @@ package unix
//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)
//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 Setreuid(ruid int, euid 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 Stat(path string, stat *Stat_t) (err error)

27
vendor/golang.org/x/sys/unix/syscall_openbsd_libc.go generated vendored Normal file
View file

@ -0,0 +1,27 @@
// 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 openbsd && !mips64
// +build openbsd,!mips64
package unix
import _ "unsafe"
// Implemented in the runtime package (runtime/sys_openbsd3.go)
func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
func syscall_syscall10(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 uintptr) (r1, r2 uintptr, err Errno)
func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
func syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
//go:linkname syscall_syscall syscall.syscall
//go:linkname syscall_syscall6 syscall.syscall6
//go:linkname syscall_syscall10 syscall.syscall10
//go:linkname syscall_rawSyscall syscall.rawSyscall
//go:linkname syscall_rawSyscall6 syscall.rawSyscall6
func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno) {
return syscall_syscall10(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, 0)
}

42
vendor/golang.org/x/sys/unix/syscall_openbsd_ppc64.go generated vendored Normal file
View file

@ -0,0 +1,42 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build ppc64 && openbsd
// +build ppc64,openbsd
package unix
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 = uint32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
// of openbsd/ppc64 the syscall is called sysctl instead of __sysctl.
const SYS___SYSCTL = SYS_SYSCTL

View file

@ -0,0 +1,42 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build riscv64 && openbsd
// +build riscv64,openbsd
package unix
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 = uint32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
// of openbsd/riscv64 the syscall is called sysctl instead of __sysctl.
const SYS___SYSCTL = SYS_SYSCTL

View file

@ -750,8 +750,8 @@ type EventPort struct {
// we should handle things gracefully. To do so, we need to keep an extra
// reference to the cookie around until the event is processed
// thus the otherwise seemingly extraneous "cookies" map
// The key of this map is a pointer to the corresponding &fCookie.cookie
cookies map[*interface{}]*fileObjCookie
// The key of this map is a pointer to the corresponding fCookie
cookies map[*fileObjCookie]struct{}
}
// PortEvent is an abstraction of the port_event C struct.
@ -778,7 +778,7 @@ func NewEventPort() (*EventPort, error) {
port: port,
fds: make(map[uintptr]*fileObjCookie),
paths: make(map[string]*fileObjCookie),
cookies: make(map[*interface{}]*fileObjCookie),
cookies: make(map[*fileObjCookie]struct{}),
}
return e, nil
}
@ -799,6 +799,7 @@ func (e *EventPort) Close() error {
}
e.fds = nil
e.paths = nil
e.cookies = nil
return nil
}
@ -826,17 +827,16 @@ func (e *EventPort) AssociatePath(path string, stat os.FileInfo, events int, coo
if _, found := e.paths[path]; found {
return fmt.Errorf("%v is already associated with this Event Port", path)
}
fobj, err := createFileObj(path, stat)
fCookie, err := createFileObjCookie(path, stat, cookie)
if err != nil {
return err
}
fCookie := &fileObjCookie{fobj, cookie}
_, err = port_associate(e.port, PORT_SOURCE_FILE, uintptr(unsafe.Pointer(fobj)), events, (*byte)(unsafe.Pointer(&fCookie.cookie)))
_, err = port_associate(e.port, PORT_SOURCE_FILE, uintptr(unsafe.Pointer(fCookie.fobj)), events, (*byte)(unsafe.Pointer(fCookie)))
if err != nil {
return err
}
e.paths[path] = fCookie
e.cookies[&fCookie.cookie] = fCookie
e.cookies[fCookie] = struct{}{}
return nil
}
@ -858,7 +858,7 @@ func (e *EventPort) DissociatePath(path string) error {
if err == nil {
// dissociate was successful, safe to delete the cookie
fCookie := e.paths[path]
delete(e.cookies, &fCookie.cookie)
delete(e.cookies, fCookie)
}
delete(e.paths, path)
return err
@ -871,13 +871,16 @@ func (e *EventPort) AssociateFd(fd uintptr, events int, cookie interface{}) erro
if _, found := e.fds[fd]; found {
return fmt.Errorf("%v is already associated with this Event Port", fd)
}
fCookie := &fileObjCookie{nil, cookie}
_, err := port_associate(e.port, PORT_SOURCE_FD, fd, events, (*byte)(unsafe.Pointer(&fCookie.cookie)))
fCookie, err := createFileObjCookie("", nil, cookie)
if err != nil {
return err
}
_, err = port_associate(e.port, PORT_SOURCE_FD, fd, events, (*byte)(unsafe.Pointer(fCookie)))
if err != nil {
return err
}
e.fds[fd] = fCookie
e.cookies[&fCookie.cookie] = fCookie
e.cookies[fCookie] = struct{}{}
return nil
}
@ -896,27 +899,31 @@ func (e *EventPort) DissociateFd(fd uintptr) error {
if err == nil {
// dissociate was successful, safe to delete the cookie
fCookie := e.fds[fd]
delete(e.cookies, &fCookie.cookie)
delete(e.cookies, fCookie)
}
delete(e.fds, fd)
return err
}
func createFileObj(name string, stat os.FileInfo) (*fileObj, error) {
fobj := new(fileObj)
bs, err := ByteSliceFromString(name)
if err != nil {
return nil, err
func createFileObjCookie(name string, stat os.FileInfo, cookie interface{}) (*fileObjCookie, error) {
fCookie := new(fileObjCookie)
fCookie.cookie = cookie
if name != "" && stat != nil {
fCookie.fobj = new(fileObj)
bs, err := ByteSliceFromString(name)
if err != nil {
return nil, err
}
fCookie.fobj.Name = (*int8)(unsafe.Pointer(&bs[0]))
s := stat.Sys().(*syscall.Stat_t)
fCookie.fobj.Atim.Sec = s.Atim.Sec
fCookie.fobj.Atim.Nsec = s.Atim.Nsec
fCookie.fobj.Mtim.Sec = s.Mtim.Sec
fCookie.fobj.Mtim.Nsec = s.Mtim.Nsec
fCookie.fobj.Ctim.Sec = s.Ctim.Sec
fCookie.fobj.Ctim.Nsec = s.Ctim.Nsec
}
fobj.Name = (*int8)(unsafe.Pointer(&bs[0]))
s := stat.Sys().(*syscall.Stat_t)
fobj.Atim.Sec = s.Atim.Sec
fobj.Atim.Nsec = s.Atim.Nsec
fobj.Mtim.Sec = s.Mtim.Sec
fobj.Mtim.Nsec = s.Mtim.Nsec
fobj.Ctim.Sec = s.Ctim.Sec
fobj.Ctim.Nsec = s.Ctim.Nsec
return fobj, nil
return fCookie, nil
}
// GetOne wraps port_get(3c) and returns a single PortEvent.
@ -929,44 +936,50 @@ func (e *EventPort) GetOne(t *Timespec) (*PortEvent, error) {
p := new(PortEvent)
e.mu.Lock()
defer e.mu.Unlock()
e.peIntToExt(pe, p)
err = e.peIntToExt(pe, p)
if err != nil {
return nil, err
}
return p, nil
}
// peIntToExt converts a cgo portEvent struct into the friendlier PortEvent
// NOTE: Always call this function while holding the e.mu mutex
func (e *EventPort) peIntToExt(peInt *portEvent, peExt *PortEvent) {
func (e *EventPort) peIntToExt(peInt *portEvent, peExt *PortEvent) error {
if e.cookies == nil {
return fmt.Errorf("this EventPort is already closed")
}
peExt.Events = peInt.Events
peExt.Source = peInt.Source
cookie := (*interface{})(unsafe.Pointer(peInt.User))
peExt.Cookie = *cookie
fCookie := (*fileObjCookie)(unsafe.Pointer(peInt.User))
_, found := e.cookies[fCookie]
if !found {
panic("unexpected event port address; may be due to kernel bug; see https://go.dev/issue/54254")
}
peExt.Cookie = fCookie.cookie
delete(e.cookies, fCookie)
switch peInt.Source {
case PORT_SOURCE_FD:
delete(e.cookies, cookie)
peExt.Fd = uintptr(peInt.Object)
// Only remove the fds entry if it exists and this cookie matches
if fobj, ok := e.fds[peExt.Fd]; ok {
if &fobj.cookie == cookie {
if fobj == fCookie {
delete(e.fds, peExt.Fd)
}
}
case PORT_SOURCE_FILE:
if fCookie, ok := e.cookies[cookie]; ok && uintptr(unsafe.Pointer(fCookie.fobj)) == uintptr(peInt.Object) {
// Use our stashed reference rather than using unsafe on what we got back
// the unsafe version would be (*fileObj)(unsafe.Pointer(uintptr(peInt.Object)))
peExt.fobj = fCookie.fobj
} else {
panic("mismanaged memory")
}
delete(e.cookies, cookie)
peExt.fobj = fCookie.fobj
peExt.Path = BytePtrToString((*byte)(unsafe.Pointer(peExt.fobj.Name)))
// Only remove the paths entry if it exists and this cookie matches
if fobj, ok := e.paths[peExt.Path]; ok {
if &fobj.cookie == cookie {
if fobj == fCookie {
delete(e.paths, peExt.Path)
}
}
}
return nil
}
// Pending wraps port_getn(3c) and returns how many events are pending.
@ -990,7 +1003,7 @@ func (e *EventPort) Get(s []PortEvent, min int, timeout *Timespec) (int, error)
got := uint32(min)
max := uint32(len(s))
var err error
ps := make([]portEvent, max, max)
ps := make([]portEvent, max)
_, err = port_getn(e.port, &ps[0], max, &got, timeout)
// got will be trustworthy with ETIME, but not any other error.
if err != nil && err != ETIME {
@ -998,8 +1011,122 @@ func (e *EventPort) Get(s []PortEvent, min int, timeout *Timespec) (int, error)
}
e.mu.Lock()
defer e.mu.Unlock()
valid := 0
for i := 0; i < int(got); i++ {
e.peIntToExt(&ps[i], &s[i])
err2 := e.peIntToExt(&ps[i], &s[i])
if err2 != nil {
if valid == 0 && err == nil {
// If err2 is the only error and there are no valid events
// to return, return it to the caller.
err = err2
}
break
}
valid = i + 1
}
return int(got), err
return valid, err
}
//sys putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error)
func Putmsg(fd int, cl []byte, data []byte, flags int) (err error) {
var clp, datap *strbuf
if len(cl) > 0 {
clp = &strbuf{
Len: int32(len(cl)),
Buf: (*int8)(unsafe.Pointer(&cl[0])),
}
}
if len(data) > 0 {
datap = &strbuf{
Len: int32(len(data)),
Buf: (*int8)(unsafe.Pointer(&data[0])),
}
}
return putmsg(fd, clp, datap, flags)
}
//sys getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error)
func Getmsg(fd int, cl []byte, data []byte) (retCl []byte, retData []byte, flags int, err error) {
var clp, datap *strbuf
if len(cl) > 0 {
clp = &strbuf{
Maxlen: int32(len(cl)),
Buf: (*int8)(unsafe.Pointer(&cl[0])),
}
}
if len(data) > 0 {
datap = &strbuf{
Maxlen: int32(len(data)),
Buf: (*int8)(unsafe.Pointer(&data[0])),
}
}
if err = getmsg(fd, clp, datap, &flags); err != nil {
return nil, nil, 0, err
}
if len(cl) > 0 {
retCl = cl[:clp.Len]
}
if len(data) > 0 {
retData = data[:datap.Len]
}
return retCl, retData, flags, nil
}
func IoctlSetIntRetInt(fd int, req uint, arg int) (int, error) {
return ioctlRet(fd, req, uintptr(arg))
}
func IoctlSetString(fd int, req uint, val string) error {
bs := make([]byte, len(val)+1)
copy(bs[:len(bs)-1], val)
err := ioctl(fd, req, uintptr(unsafe.Pointer(&bs[0])))
runtime.KeepAlive(&bs[0])
return err
}
// Lifreq Helpers
func (l *Lifreq) SetName(name string) error {
if len(name) >= len(l.Name) {
return fmt.Errorf("name cannot be more than %d characters", len(l.Name)-1)
}
for i := range name {
l.Name[i] = int8(name[i])
}
return nil
}
func (l *Lifreq) SetLifruInt(d int) {
*(*int)(unsafe.Pointer(&l.Lifru[0])) = d
}
func (l *Lifreq) GetLifruInt() int {
return *(*int)(unsafe.Pointer(&l.Lifru[0]))
}
func (l *Lifreq) SetLifruUint(d uint) {
*(*uint)(unsafe.Pointer(&l.Lifru[0])) = d
}
func (l *Lifreq) GetLifruUint() uint {
return *(*uint)(unsafe.Pointer(&l.Lifru[0]))
}
func IoctlLifreq(fd int, req uint, l *Lifreq) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(l)))
}
// Strioctl Helpers
func (s *Strioctl) SetInt(i int) {
s.Len = int32(unsafe.Sizeof(i))
s.Dp = (*int8)(unsafe.Pointer(&i))
}
func IoctlSetStrioctlRetInt(fd int, req uint, s *Strioctl) (int, error) {
return ioctlRet(fd, req, uintptr(unsafe.Pointer(s)))
}

View file

@ -13,8 +13,6 @@ import (
"sync"
"syscall"
"unsafe"
"golang.org/x/sys/internal/unsafeheader"
)
var (
@ -117,11 +115,7 @@ func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (d
}
// Use unsafe to convert addr into a []byte.
var b []byte
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
hdr.Data = unsafe.Pointer(addr)
hdr.Cap = length
hdr.Len = length
b := unsafe.Slice((*byte)(unsafe.Pointer(addr)), length)
// Register mapping in m and return it.
p := &b[cap(b)-1]
@ -429,11 +423,15 @@ func Send(s int, buf []byte, flags int) (err error) {
}
func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
ptr, n, err := to.sockaddr()
if err != nil {
return err
var ptr unsafe.Pointer
var salen _Socklen
if to != nil {
ptr, salen, err = to.sockaddr()
if err != nil {
return err
}
}
return sendto(fd, p, flags, ptr, n)
return sendto(fd, p, flags, ptr, salen)
}
func SetsockoptByte(fd, level, opt int, value byte) (err error) {

View file

@ -2,11 +2,9 @@
// 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 || linux || netbsd || openbsd || solaris) && gc && !ppc64le && !ppc64
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
//go:build (darwin || dragonfly || freebsd || (linux && !ppc64 && !ppc64le) || netbsd || openbsd || solaris) && gc
// +build darwin dragonfly freebsd linux,!ppc64,!ppc64le netbsd openbsd solaris
// +build gc
// +build !ppc64le
// +build !ppc64
package unix

View file

@ -9,8 +9,10 @@ package unix
import (
"bytes"
"fmt"
"runtime"
"sort"
"strings"
"sync"
"syscall"
"unsafe"
@ -55,7 +57,13 @@ func (d *Dirent) NameString() string {
if d == nil {
return ""
}
return string(d.Name[:d.Namlen])
s := string(d.Name[:])
idx := strings.IndexByte(s, 0)
if idx == -1 {
return s
} else {
return s[:idx]
}
}
func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
@ -1230,6 +1238,14 @@ func Readdir(dir uintptr) (*Dirent, error) {
return &ent, err
}
func readdir_r(dirp uintptr, entry *direntLE, result **direntLE) (err error) {
r0, _, e1 := syscall_syscall(SYS___READDIR_R_A, dirp, uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
if int64(r0) == -1 {
err = errnoErr(Errno(e1))
}
return
}
func Closedir(dir uintptr) error {
_, _, e := syscall_syscall(SYS_CLOSEDIR, dir, 0, 0)
if e != 0 {
@ -1821,3 +1837,158 @@ func Unmount(name string, mtm int) (err error) {
}
return err
}
func fdToPath(dirfd int) (path string, err error) {
var buffer [1024]byte
// w_ctrl()
ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_W_IOCTL<<4,
[]uintptr{uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0]))})
if ret == 0 {
zb := bytes.IndexByte(buffer[:], 0)
if zb == -1 {
zb = len(buffer)
}
// __e2a_l()
runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4,
[]uintptr{uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb)})
return string(buffer[:zb]), nil
}
// __errno()
errno := int(*(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4,
[]uintptr{}))))
// __errno2()
errno2 := int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO2<<4,
[]uintptr{}))
// strerror_r()
ret = runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_STRERROR_R<<4,
[]uintptr{uintptr(errno), uintptr(unsafe.Pointer(&buffer[0])), 1024})
if ret == 0 {
zb := bytes.IndexByte(buffer[:], 0)
if zb == -1 {
zb = len(buffer)
}
return "", fmt.Errorf("%s (errno2=0x%x)", buffer[:zb], errno2)
} else {
return "", fmt.Errorf("fdToPath errno %d (errno2=0x%x)", errno, errno2)
}
}
func direntLeToDirentUnix(dirent *direntLE, dir uintptr, path string) (Dirent, error) {
var d Dirent
d.Ino = uint64(dirent.Ino)
offset, err := Telldir(dir)
if err != nil {
return d, err
}
d.Off = int64(offset)
s := string(bytes.Split(dirent.Name[:], []byte{0})[0])
copy(d.Name[:], s)
d.Reclen = uint16(24 + len(d.NameString()))
var st Stat_t
path = path + "/" + s
err = Lstat(path, &st)
if err != nil {
return d, err
}
d.Type = uint8(st.Mode >> 24)
return d, err
}
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
// Simulation of Getdirentries port from the Darwin implementation.
// COMMENTS FROM DARWIN:
// It's not the full required semantics, but should handle the case
// of calling Getdirentries or ReadDirent repeatedly.
// It won't handle assigning the results of lseek to *basep, or handle
// the directory being edited underfoot.
skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
if err != nil {
return 0, err
}
// Get path from fd to avoid unavailable call (fdopendir)
path, err := fdToPath(fd)
if err != nil {
return 0, err
}
d, err := Opendir(path)
if err != nil {
return 0, err
}
defer Closedir(d)
var cnt int64
for {
var entryLE direntLE
var entrypLE *direntLE
e := readdir_r(d, &entryLE, &entrypLE)
if e != nil {
return n, e
}
if entrypLE == nil {
break
}
if skip > 0 {
skip--
cnt++
continue
}
// Dirent on zos has a different structure
entry, e := direntLeToDirentUnix(&entryLE, d, path)
if e != nil {
return n, e
}
reclen := int(entry.Reclen)
if reclen > len(buf) {
// Not enough room. Return for now.
// The counter will let us know where we should start up again.
// Note: this strategy for suspending in the middle and
// restarting is O(n^2) in the length of the directory. Oh well.
break
}
// Copy entry into return buffer.
s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)
copy(buf, s)
buf = buf[reclen:]
n += reclen
cnt++
}
// Set the seek offset of the input fd to record
// how many files we've already returned.
_, err = Seek(fd, cnt, 0 /* SEEK_SET */)
if err != nil {
return n, err
}
return n, nil
}
func ReadDirent(fd int, buf []byte) (n int, err error) {
var base = (*uintptr)(unsafe.Pointer(new(uint64)))
return Getdirentries(fd, buf, base)
}
func direntIno(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
}
func direntReclen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
}
func direntNamlen(buf []byte) (uint64, bool) {
reclen, ok := direntReclen(buf)
if !ok {
return 0, false
}
return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
}

View file

@ -7,11 +7,7 @@
package unix
import (
"unsafe"
"golang.org/x/sys/internal/unsafeheader"
)
import "unsafe"
// SysvShmAttach attaches the Sysv shared memory segment associated with the
// shared memory identifier id.
@ -34,12 +30,7 @@ func SysvShmAttach(id int, addr uintptr, flag int) ([]byte, error) {
}
// Use unsafe to convert addr into a []byte.
// TODO: convert to unsafe.Slice once we can assume Go 1.17
var b []byte
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
hdr.Data = unsafe.Pointer(addr)
hdr.Cap = int(info.Segsz)
hdr.Len = int(info.Segsz)
b := unsafe.Slice((*byte)(unsafe.Pointer(addr)), int(info.Segsz))
return b, nil
}

View file

@ -160,13 +160,12 @@ func Lremovexattr(link string, attr string) (err error) {
}
func Listxattr(file string, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsiz := len(dest)
// FreeBSD won't allow you to list xattrs from multiple namespaces
s := 0
s, pos := 0, 0
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
stmp, e := ExtattrListFile(file, nsid, uintptr(d), destsiz)
stmp, e := ListxattrNS(file, nsid, dest[pos:])
/* Errors accessing system attrs are ignored so that
* we can implement the Linux-like behavior of omitting errors that
@ -175,66 +174,102 @@ func Listxattr(file string, dest []byte) (sz int, err error) {
* Linux will still error if we ask for user attributes on a file that
* we don't have read permissions on, so don't ignore those errors
*/
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
continue
} else if e != nil {
if e != nil {
if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
continue
}
return s, e
}
s += stmp
destsiz -= s
if destsiz < 0 {
destsiz = 0
pos = s
if pos > destsiz {
pos = destsiz
}
d = initxattrdest(dest, s)
}
return s, nil
}
func ListxattrNS(file string, nsid int, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsiz := len(dest)
s, e := ExtattrListFile(file, nsid, uintptr(d), destsiz)
if e != nil {
return 0, err
}
return s, nil
}
func Flistxattr(fd int, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsiz := len(dest)
s := 0
s, pos := 0, 0
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
stmp, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz)
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
continue
} else if e != nil {
stmp, e := FlistxattrNS(fd, nsid, dest[pos:])
if e != nil {
if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
continue
}
return s, e
}
s += stmp
destsiz -= s
if destsiz < 0 {
destsiz = 0
pos = s
if pos > destsiz {
pos = destsiz
}
d = initxattrdest(dest, s)
}
return s, nil
}
func FlistxattrNS(fd int, nsid int, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsiz := len(dest)
s, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz)
if e != nil {
return 0, err
}
return s, nil
}
func Llistxattr(link string, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsiz := len(dest)
s := 0
s, pos := 0, 0
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
stmp, e := ExtattrListLink(link, nsid, uintptr(d), destsiz)
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
continue
} else if e != nil {
stmp, e := LlistxattrNS(link, nsid, dest[pos:])
if e != nil {
if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
continue
}
return s, e
}
s += stmp
destsiz -= s
if destsiz < 0 {
destsiz = 0
pos = s
if pos > destsiz {
pos = destsiz
}
d = initxattrdest(dest, s)
}
return s, nil
}
func LlistxattrNS(link string, nsid int, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsiz := len(dest)
s, e := ExtattrListLink(link, nsid, uintptr(d), destsiz)
if e != nil {
return 0, err
}
return s, nil

View file

@ -1,11 +1,11 @@
// mkerrors.sh -Wall -Werror -static -I/tmp/include -m32
// mkerrors.sh -Wall -Werror -static -I/tmp/386/include -m32
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build 386 && linux
// +build 386,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m32 _const.go
// cgo -godefs -- -Wall -Werror -static -I/tmp/386/include -m32 _const.go
package unix

View file

@ -1,11 +1,11 @@
// mkerrors.sh -Wall -Werror -static -I/tmp/include -m64
// mkerrors.sh -Wall -Werror -static -I/tmp/amd64/include -m64
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build amd64 && linux
// +build amd64,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m64 _const.go
// cgo -godefs -- -Wall -Werror -static -I/tmp/amd64/include -m64 _const.go
package unix

View file

@ -1,11 +1,11 @@
// mkerrors.sh -Wall -Werror -static -I/tmp/include
// mkerrors.sh -Wall -Werror -static -I/tmp/arm/include
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build arm && linux
// +build arm,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
// cgo -godefs -- -Wall -Werror -static -I/tmp/arm/include _const.go
package unix

View file

@ -1,11 +1,11 @@
// mkerrors.sh -Wall -Werror -static -I/tmp/include -fsigned-char
// mkerrors.sh -Wall -Werror -static -I/tmp/arm64/include -fsigned-char
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build arm64 && linux
// +build arm64,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char _const.go
// cgo -godefs -- -Wall -Werror -static -I/tmp/arm64/include -fsigned-char _const.go
package unix

View file

@ -1,11 +1,11 @@
// mkerrors.sh -Wall -Werror -static -I/tmp/include
// mkerrors.sh -Wall -Werror -static -I/tmp/loong64/include
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build loong64 && linux
// +build loong64,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
// cgo -godefs -- -Wall -Werror -static -I/tmp/loong64/include _const.go
package unix

View file

@ -1,11 +1,11 @@
// mkerrors.sh -Wall -Werror -static -I/tmp/include
// mkerrors.sh -Wall -Werror -static -I/tmp/mips/include
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build mips && linux
// +build mips,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
// cgo -godefs -- -Wall -Werror -static -I/tmp/mips/include _const.go
package unix

View file

@ -1,11 +1,11 @@
// mkerrors.sh -Wall -Werror -static -I/tmp/include
// mkerrors.sh -Wall -Werror -static -I/tmp/mips64/include
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build mips64 && linux
// +build mips64,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
// cgo -godefs -- -Wall -Werror -static -I/tmp/mips64/include _const.go
package unix

View file

@ -1,11 +1,11 @@
// mkerrors.sh -Wall -Werror -static -I/tmp/include
// mkerrors.sh -Wall -Werror -static -I/tmp/mips64le/include
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build mips64le && linux
// +build mips64le,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
// cgo -godefs -- -Wall -Werror -static -I/tmp/mips64le/include _const.go
package unix

View file

@ -1,11 +1,11 @@
// mkerrors.sh -Wall -Werror -static -I/tmp/include
// mkerrors.sh -Wall -Werror -static -I/tmp/mipsle/include
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build mipsle && linux
// +build mipsle,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
// cgo -godefs -- -Wall -Werror -static -I/tmp/mipsle/include _const.go
package unix

View file

@ -1,11 +1,11 @@
// mkerrors.sh -Wall -Werror -static -I/tmp/include
// mkerrors.sh -Wall -Werror -static -I/tmp/ppc/include
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build ppc && linux
// +build ppc,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
// cgo -godefs -- -Wall -Werror -static -I/tmp/ppc/include _const.go
package unix

View file

@ -1,11 +1,11 @@
// mkerrors.sh -Wall -Werror -static -I/tmp/include
// mkerrors.sh -Wall -Werror -static -I/tmp/ppc64/include
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build ppc64 && linux
// +build ppc64,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
// cgo -godefs -- -Wall -Werror -static -I/tmp/ppc64/include _const.go
package unix

View file

@ -1,11 +1,11 @@
// mkerrors.sh -Wall -Werror -static -I/tmp/include
// mkerrors.sh -Wall -Werror -static -I/tmp/ppc64le/include
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build ppc64le && linux
// +build ppc64le,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
// cgo -godefs -- -Wall -Werror -static -I/tmp/ppc64le/include _const.go
package unix

View file

@ -1,11 +1,11 @@
// mkerrors.sh -Wall -Werror -static -I/tmp/include
// mkerrors.sh -Wall -Werror -static -I/tmp/riscv64/include
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build riscv64 && linux
// +build riscv64,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
// cgo -godefs -- -Wall -Werror -static -I/tmp/riscv64/include _const.go
package unix

View file

@ -1,11 +1,11 @@
// mkerrors.sh -Wall -Werror -static -I/tmp/include -fsigned-char
// mkerrors.sh -Wall -Werror -static -I/tmp/s390x/include -fsigned-char
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build s390x && linux
// +build s390x,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char _const.go
// cgo -godefs -- -Wall -Werror -static -I/tmp/s390x/include -fsigned-char _const.go
package unix

View file

@ -1,11 +1,11 @@
// mkerrors.sh -Wall -Werror -static -I/tmp/include
// mkerrors.sh -Wall -Werror -static -I/tmp/sparc64/include
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build sparc64 && linux
// +build sparc64,linux
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
// cgo -godefs -- -Wall -Werror -static -I/tmp/sparc64/include _const.go
package unix

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