Compare commits

..

2 commits

Author SHA1 Message Date
dependabot[bot] bb8dfd3368
[chore]: Bump go.opentelemetry.io/otel/sdk from 1.29.0 to 1.32.0
Bumps [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) from 1.29.0 to 1.32.0.
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.29.0...v1.32.0)

---
updated-dependencies:
- dependency-name: go.opentelemetry.io/otel/sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-11 15:16:41 +00:00
dependabot[bot] 98eef328ea
[chore]: Bump golang.org/x/net from 0.30.0 to 0.31.0 (#3536)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.30.0 to 0.31.0.
- [Commits](https://github.com/golang/net/compare/v0.30.0...v0.31.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-11 15:15:24 +00:00
24 changed files with 693 additions and 282 deletions

8
go.mod
View file

@ -78,11 +78,11 @@ require (
go.opentelemetry.io/otel/sdk/metric v1.29.0 go.opentelemetry.io/otel/sdk/metric v1.29.0
go.opentelemetry.io/otel/trace v1.32.0 go.opentelemetry.io/otel/trace v1.32.0
go.uber.org/automaxprocs v1.6.0 go.uber.org/automaxprocs v1.6.0
golang.org/x/crypto v0.28.0 golang.org/x/crypto v0.29.0
golang.org/x/image v0.21.0 golang.org/x/image v0.21.0
golang.org/x/net v0.30.0 golang.org/x/net v0.31.0
golang.org/x/oauth2 v0.23.0 golang.org/x/oauth2 v0.23.0
golang.org/x/text v0.19.0 golang.org/x/text v0.20.0
gopkg.in/mcuadros/go-syslog.v2 v2.3.0 gopkg.in/mcuadros/go-syslog.v2 v2.3.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
modernc.org/sqlite v0.0.0-00010101000000-000000000000 modernc.org/sqlite v0.0.0-00010101000000-000000000000
@ -218,7 +218,7 @@ require (
golang.org/x/arch v0.8.0 // indirect golang.org/x/arch v0.8.0 // indirect
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
golang.org/x/mod v0.18.0 // indirect golang.org/x/mod v0.18.0 // indirect
golang.org/x/sync v0.8.0 // indirect golang.org/x/sync v0.9.0 // indirect
golang.org/x/sys v0.27.0 // indirect golang.org/x/sys v0.27.0 // indirect
golang.org/x/tools v0.22.0 // indirect golang.org/x/tools v0.22.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect

20
go.sum generated
View file

@ -668,8 +668,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -739,8 +739,8 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -758,8 +758,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -805,8 +805,8 @@ golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU=
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -814,8 +814,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build (!arm64 && !s390x && !ppc64le) || !gc || purego //go:build (!arm64 && !s390x && !ppc64 && !ppc64le) || !gc || purego
package chacha20 package chacha20

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gc && !purego //go:build gc && !purego && (ppc64 || ppc64le)
package chacha20 package chacha20

View file

@ -19,7 +19,7 @@
// The differences in this and the original implementation are // The differences in this and the original implementation are
// due to the calling conventions and initialization of constants. // due to the calling conventions and initialization of constants.
//go:build gc && !purego //go:build gc && !purego && (ppc64 || ppc64le)
#include "textflag.h" #include "textflag.h"
@ -36,32 +36,68 @@
// for VPERMXOR // for VPERMXOR
#define MASK R18 #define MASK R18
DATA consts<>+0x00(SB)/8, $0x3320646e61707865 DATA consts<>+0x00(SB)/4, $0x61707865
DATA consts<>+0x08(SB)/8, $0x6b20657479622d32 DATA consts<>+0x04(SB)/4, $0x3320646e
DATA consts<>+0x10(SB)/8, $0x0000000000000001 DATA consts<>+0x08(SB)/4, $0x79622d32
DATA consts<>+0x18(SB)/8, $0x0000000000000000 DATA consts<>+0x0c(SB)/4, $0x6b206574
DATA consts<>+0x20(SB)/8, $0x0000000000000004 DATA consts<>+0x10(SB)/4, $0x00000001
DATA consts<>+0x28(SB)/8, $0x0000000000000000 DATA consts<>+0x14(SB)/4, $0x00000000
DATA consts<>+0x30(SB)/8, $0x0a0b08090e0f0c0d DATA consts<>+0x18(SB)/4, $0x00000000
DATA consts<>+0x38(SB)/8, $0x0203000106070405 DATA consts<>+0x1c(SB)/4, $0x00000000
DATA consts<>+0x40(SB)/8, $0x090a0b080d0e0f0c DATA consts<>+0x20(SB)/4, $0x00000004
DATA consts<>+0x48(SB)/8, $0x0102030005060704 DATA consts<>+0x24(SB)/4, $0x00000000
DATA consts<>+0x50(SB)/8, $0x6170786561707865 DATA consts<>+0x28(SB)/4, $0x00000000
DATA consts<>+0x58(SB)/8, $0x6170786561707865 DATA consts<>+0x2c(SB)/4, $0x00000000
DATA consts<>+0x60(SB)/8, $0x3320646e3320646e DATA consts<>+0x30(SB)/4, $0x0e0f0c0d
DATA consts<>+0x68(SB)/8, $0x3320646e3320646e DATA consts<>+0x34(SB)/4, $0x0a0b0809
DATA consts<>+0x70(SB)/8, $0x79622d3279622d32 DATA consts<>+0x38(SB)/4, $0x06070405
DATA consts<>+0x78(SB)/8, $0x79622d3279622d32 DATA consts<>+0x3c(SB)/4, $0x02030001
DATA consts<>+0x80(SB)/8, $0x6b2065746b206574 DATA consts<>+0x40(SB)/4, $0x0d0e0f0c
DATA consts<>+0x88(SB)/8, $0x6b2065746b206574 DATA consts<>+0x44(SB)/4, $0x090a0b08
DATA consts<>+0x90(SB)/8, $0x0000000100000000 DATA consts<>+0x48(SB)/4, $0x05060704
DATA consts<>+0x98(SB)/8, $0x0000000300000002 DATA consts<>+0x4c(SB)/4, $0x01020300
DATA consts<>+0xa0(SB)/8, $0x5566774411223300 DATA consts<>+0x50(SB)/4, $0x61707865
DATA consts<>+0xa8(SB)/8, $0xddeeffcc99aabb88 DATA consts<>+0x54(SB)/4, $0x61707865
DATA consts<>+0xb0(SB)/8, $0x6677445522330011 DATA consts<>+0x58(SB)/4, $0x61707865
DATA consts<>+0xb8(SB)/8, $0xeeffccddaabb8899 DATA consts<>+0x5c(SB)/4, $0x61707865
DATA consts<>+0x60(SB)/4, $0x3320646e
DATA consts<>+0x64(SB)/4, $0x3320646e
DATA consts<>+0x68(SB)/4, $0x3320646e
DATA consts<>+0x6c(SB)/4, $0x3320646e
DATA consts<>+0x70(SB)/4, $0x79622d32
DATA consts<>+0x74(SB)/4, $0x79622d32
DATA consts<>+0x78(SB)/4, $0x79622d32
DATA consts<>+0x7c(SB)/4, $0x79622d32
DATA consts<>+0x80(SB)/4, $0x6b206574
DATA consts<>+0x84(SB)/4, $0x6b206574
DATA consts<>+0x88(SB)/4, $0x6b206574
DATA consts<>+0x8c(SB)/4, $0x6b206574
DATA consts<>+0x90(SB)/4, $0x00000000
DATA consts<>+0x94(SB)/4, $0x00000001
DATA consts<>+0x98(SB)/4, $0x00000002
DATA consts<>+0x9c(SB)/4, $0x00000003
DATA consts<>+0xa0(SB)/4, $0x11223300
DATA consts<>+0xa4(SB)/4, $0x55667744
DATA consts<>+0xa8(SB)/4, $0x99aabb88
DATA consts<>+0xac(SB)/4, $0xddeeffcc
DATA consts<>+0xb0(SB)/4, $0x22330011
DATA consts<>+0xb4(SB)/4, $0x66774455
DATA consts<>+0xb8(SB)/4, $0xaabb8899
DATA consts<>+0xbc(SB)/4, $0xeeffccdd
GLOBL consts<>(SB), RODATA, $0xc0 GLOBL consts<>(SB), RODATA, $0xc0
#ifdef GOARCH_ppc64
#define BE_XXBRW_INIT() \
LVSL (R0)(R0), V24 \
VSPLTISB $3, V25 \
VXOR V24, V25, V24 \
#define BE_XXBRW(vr) VPERM vr, vr, V24, vr
#else
#define BE_XXBRW_INIT()
#define BE_XXBRW(vr)
#endif
//func chaCha20_ctr32_vsx(out, inp *byte, len int, key *[8]uint32, counter *uint32) //func chaCha20_ctr32_vsx(out, inp *byte, len int, key *[8]uint32, counter *uint32)
TEXT ·chaCha20_ctr32_vsx(SB),NOSPLIT,$64-40 TEXT ·chaCha20_ctr32_vsx(SB),NOSPLIT,$64-40
MOVD out+0(FP), OUT MOVD out+0(FP), OUT
@ -94,6 +130,8 @@ TEXT ·chaCha20_ctr32_vsx(SB),NOSPLIT,$64-40
// Clear V27 // Clear V27
VXOR V27, V27, V27 VXOR V27, V27, V27
BE_XXBRW_INIT()
// V28 // V28
LXVW4X (CONSTBASE)(R11), VS60 LXVW4X (CONSTBASE)(R11), VS60
@ -299,6 +337,11 @@ loop_vsx:
VADDUWM V8, V18, V8 VADDUWM V8, V18, V8
VADDUWM V12, V19, V12 VADDUWM V12, V19, V12
BE_XXBRW(V0)
BE_XXBRW(V4)
BE_XXBRW(V8)
BE_XXBRW(V12)
CMPU LEN, $64 CMPU LEN, $64
BLT tail_vsx BLT tail_vsx
@ -327,6 +370,11 @@ loop_vsx:
VADDUWM V9, V18, V8 VADDUWM V9, V18, V8
VADDUWM V13, V19, V12 VADDUWM V13, V19, V12
BE_XXBRW(V0)
BE_XXBRW(V4)
BE_XXBRW(V8)
BE_XXBRW(V12)
CMPU LEN, $64 CMPU LEN, $64
BLT tail_vsx BLT tail_vsx
@ -334,8 +382,8 @@ loop_vsx:
LXVW4X (INP)(R8), VS60 LXVW4X (INP)(R8), VS60
LXVW4X (INP)(R9), VS61 LXVW4X (INP)(R9), VS61
LXVW4X (INP)(R10), VS62 LXVW4X (INP)(R10), VS62
VXOR V27, V0, V27
VXOR V27, V0, V27
VXOR V28, V4, V28 VXOR V28, V4, V28
VXOR V29, V8, V29 VXOR V29, V8, V29
VXOR V30, V12, V30 VXOR V30, V12, V30
@ -354,6 +402,11 @@ loop_vsx:
VADDUWM V10, V18, V8 VADDUWM V10, V18, V8
VADDUWM V14, V19, V12 VADDUWM V14, V19, V12
BE_XXBRW(V0)
BE_XXBRW(V4)
BE_XXBRW(V8)
BE_XXBRW(V12)
CMPU LEN, $64 CMPU LEN, $64
BLT tail_vsx BLT tail_vsx
@ -381,6 +434,11 @@ loop_vsx:
VADDUWM V11, V18, V8 VADDUWM V11, V18, V8
VADDUWM V15, V19, V12 VADDUWM V15, V19, V12
BE_XXBRW(V0)
BE_XXBRW(V4)
BE_XXBRW(V8)
BE_XXBRW(V12)
CMPU LEN, $64 CMPU LEN, $64
BLT tail_vsx BLT tail_vsx
@ -408,9 +466,9 @@ loop_vsx:
done_vsx: done_vsx:
// Increment counter by number of 64 byte blocks // Increment counter by number of 64 byte blocks
MOVD (CNT), R14 MOVWZ (CNT), R14
ADD BLOCKS, R14 ADD BLOCKS, R14
MOVD R14, (CNT) MOVWZ R14, (CNT)
RET RET
tail_vsx: tail_vsx:

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build (!amd64 && !ppc64le && !s390x) || !gc || purego //go:build (!amd64 && !ppc64le && !ppc64 && !s390x) || !gc || purego
package poly1305 package poly1305

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gc && !purego //go:build gc && !purego && (ppc64 || ppc64le)
package poly1305 package poly1305

View file

@ -2,15 +2,25 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gc && !purego //go:build gc && !purego && (ppc64 || ppc64le)
#include "textflag.h" #include "textflag.h"
// This was ported from the amd64 implementation. // This was ported from the amd64 implementation.
#ifdef GOARCH_ppc64le
#define LE_MOVD MOVD
#define LE_MOVWZ MOVWZ
#define LE_MOVHZ MOVHZ
#else
#define LE_MOVD MOVDBR
#define LE_MOVWZ MOVWBR
#define LE_MOVHZ MOVHBR
#endif
#define POLY1305_ADD(msg, h0, h1, h2, t0, t1, t2) \ #define POLY1305_ADD(msg, h0, h1, h2, t0, t1, t2) \
MOVD (msg), t0; \ LE_MOVD (msg)( R0), t0; \
MOVD 8(msg), t1; \ LE_MOVD (msg)(R24), t1; \
MOVD $1, t2; \ MOVD $1, t2; \
ADDC t0, h0, h0; \ ADDC t0, h0, h0; \
ADDE t1, h1, h1; \ ADDE t1, h1, h1; \
@ -50,10 +60,6 @@
ADDE t3, h1, h1; \ ADDE t3, h1, h1; \
ADDZE h2 ADDZE h2
DATA ·poly1305Mask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF
DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
GLOBL ·poly1305Mask<>(SB), RODATA, $16
// func update(state *[7]uint64, msg []byte) // func update(state *[7]uint64, msg []byte)
TEXT ·update(SB), $0-32 TEXT ·update(SB), $0-32
MOVD state+0(FP), R3 MOVD state+0(FP), R3
@ -66,6 +72,8 @@ TEXT ·update(SB), $0-32
MOVD 24(R3), R11 // r0 MOVD 24(R3), R11 // r0
MOVD 32(R3), R12 // r1 MOVD 32(R3), R12 // r1
MOVD $8, R24
CMP R5, $16 CMP R5, $16
BLT bytes_between_0_and_15 BLT bytes_between_0_and_15
@ -94,7 +102,7 @@ flush_buffer:
// Greater than 8 -- load the rightmost remaining bytes in msg // Greater than 8 -- load the rightmost remaining bytes in msg
// and put into R17 (h1) // and put into R17 (h1)
MOVD (R4)(R21), R17 LE_MOVD (R4)(R21), R17
MOVD $16, R22 MOVD $16, R22
// Find the offset to those bytes // Find the offset to those bytes
@ -118,7 +126,7 @@ just1:
BLT less8 BLT less8
// Exactly 8 // Exactly 8
MOVD (R4), R16 LE_MOVD (R4), R16
CMP R17, $0 CMP R17, $0
@ -133,7 +141,7 @@ less8:
MOVD $0, R22 // shift count MOVD $0, R22 // shift count
CMP R5, $4 CMP R5, $4
BLT less4 BLT less4
MOVWZ (R4), R16 LE_MOVWZ (R4), R16
ADD $4, R4 ADD $4, R4
ADD $-4, R5 ADD $-4, R5
MOVD $32, R22 MOVD $32, R22
@ -141,7 +149,7 @@ less8:
less4: less4:
CMP R5, $2 CMP R5, $2
BLT less2 BLT less2
MOVHZ (R4), R21 LE_MOVHZ (R4), R21
SLD R22, R21, R21 SLD R22, R21, R21
OR R16, R21, R16 OR R16, R21, R16
ADD $16, R22 ADD $16, R22

View file

@ -5,6 +5,10 @@
// Package sha3 implements the SHA-3 fixed-output-length hash functions and // Package sha3 implements the SHA-3 fixed-output-length hash functions and
// the SHAKE variable-output-length hash functions defined by FIPS-202. // the SHAKE variable-output-length hash functions defined by FIPS-202.
// //
// All types in this package also implement [encoding.BinaryMarshaler],
// [encoding.BinaryAppender] and [encoding.BinaryUnmarshaler] to marshal and
// unmarshal the internal state of the hash.
//
// Both types of hash function use the "sponge" construction and the Keccak // Both types of hash function use the "sponge" construction and the Keccak
// permutation. For a detailed specification see http://keccak.noekeon.org/ // permutation. For a detailed specification see http://keccak.noekeon.org/
// //

View file

@ -48,33 +48,52 @@ func init() {
crypto.RegisterHash(crypto.SHA3_512, New512) crypto.RegisterHash(crypto.SHA3_512, New512)
} }
const (
dsbyteSHA3 = 0b00000110
dsbyteKeccak = 0b00000001
dsbyteShake = 0b00011111
dsbyteCShake = 0b00000100
// rateK[c] is the rate in bytes for Keccak[c] where c is the capacity in
// bits. Given the sponge size is 1600 bits, the rate is 1600 - c bits.
rateK256 = (1600 - 256) / 8
rateK448 = (1600 - 448) / 8
rateK512 = (1600 - 512) / 8
rateK768 = (1600 - 768) / 8
rateK1024 = (1600 - 1024) / 8
)
func new224Generic() *state { func new224Generic() *state {
return &state{rate: 144, outputLen: 28, dsbyte: 0x06} return &state{rate: rateK448, outputLen: 28, dsbyte: dsbyteSHA3}
} }
func new256Generic() *state { func new256Generic() *state {
return &state{rate: 136, outputLen: 32, dsbyte: 0x06} return &state{rate: rateK512, outputLen: 32, dsbyte: dsbyteSHA3}
} }
func new384Generic() *state { func new384Generic() *state {
return &state{rate: 104, outputLen: 48, dsbyte: 0x06} return &state{rate: rateK768, outputLen: 48, dsbyte: dsbyteSHA3}
} }
func new512Generic() *state { func new512Generic() *state {
return &state{rate: 72, outputLen: 64, dsbyte: 0x06} return &state{rate: rateK1024, outputLen: 64, dsbyte: dsbyteSHA3}
} }
// NewLegacyKeccak256 creates a new Keccak-256 hash. // NewLegacyKeccak256 creates a new Keccak-256 hash.
// //
// Only use this function if you require compatibility with an existing cryptosystem // Only use this function if you require compatibility with an existing cryptosystem
// that uses non-standard padding. All other users should use New256 instead. // that uses non-standard padding. All other users should use New256 instead.
func NewLegacyKeccak256() hash.Hash { return &state{rate: 136, outputLen: 32, dsbyte: 0x01} } func NewLegacyKeccak256() hash.Hash {
return &state{rate: rateK512, outputLen: 32, dsbyte: dsbyteKeccak}
}
// NewLegacyKeccak512 creates a new Keccak-512 hash. // NewLegacyKeccak512 creates a new Keccak-512 hash.
// //
// Only use this function if you require compatibility with an existing cryptosystem // Only use this function if you require compatibility with an existing cryptosystem
// that uses non-standard padding. All other users should use New512 instead. // that uses non-standard padding. All other users should use New512 instead.
func NewLegacyKeccak512() hash.Hash { return &state{rate: 72, outputLen: 64, dsbyte: 0x01} } func NewLegacyKeccak512() hash.Hash {
return &state{rate: rateK1024, outputLen: 64, dsbyte: dsbyteKeccak}
}
// Sum224 returns the SHA3-224 digest of the data. // Sum224 returns the SHA3-224 digest of the data.
func Sum224(data []byte) (digest [28]byte) { func Sum224(data []byte) (digest [28]byte) {

View file

@ -4,6 +4,15 @@
package sha3 package sha3
import (
"crypto/subtle"
"encoding/binary"
"errors"
"unsafe"
"golang.org/x/sys/cpu"
)
// spongeDirection indicates the direction bytes are flowing through the sponge. // spongeDirection indicates the direction bytes are flowing through the sponge.
type spongeDirection int type spongeDirection int
@ -14,16 +23,13 @@
spongeSqueezing spongeSqueezing
) )
const (
// maxRate is the maximum size of the internal buffer. SHAKE-256
// currently needs the largest buffer.
maxRate = 168
)
type state struct { type state struct {
// Generic sponge components. a [1600 / 8]byte // main state of the hash
a [25]uint64 // main state of the hash
rate int // the number of bytes of state to use // a[n:rate] is the buffer. If absorbing, it's the remaining space to XOR
// into before running the permutation. If squeezing, it's the remaining
// output to produce before running the permutation.
n, rate int
// dsbyte contains the "domain separation" bits and the first bit of // dsbyte contains the "domain separation" bits and the first bit of
// the padding. Sections 6.1 and 6.2 of [1] separate the outputs of the // the padding. Sections 6.1 and 6.2 of [1] separate the outputs of the
@ -39,10 +45,6 @@ type state struct {
// Extendable-Output Functions (May 2014)" // Extendable-Output Functions (May 2014)"
dsbyte byte dsbyte byte
i, n int // storage[i:n] is the buffer, i is only used while squeezing
storage [maxRate]byte
// Specific to SHA-3 and SHAKE.
outputLen int // the default output size in bytes outputLen int // the default output size in bytes
state spongeDirection // whether the sponge is absorbing or squeezing state spongeDirection // whether the sponge is absorbing or squeezing
} }
@ -61,7 +63,7 @@ func (d *state) Reset() {
d.a[i] = 0 d.a[i] = 0
} }
d.state = spongeAbsorbing d.state = spongeAbsorbing
d.i, d.n = 0, 0 d.n = 0
} }
func (d *state) clone() *state { func (d *state) clone() *state {
@ -69,22 +71,25 @@ func (d *state) clone() *state {
return &ret return &ret
} }
// permute applies the KeccakF-1600 permutation. It handles // permute applies the KeccakF-1600 permutation.
// any input-output buffering.
func (d *state) permute() { func (d *state) permute() {
switch d.state { var a *[25]uint64
case spongeAbsorbing: if cpu.IsBigEndian {
// If we're absorbing, we need to xor the input into the state a = new([25]uint64)
// before applying the permutation. for i := range a {
xorIn(d, d.storage[:d.rate]) a[i] = binary.LittleEndian.Uint64(d.a[i*8:])
}
} else {
a = (*[25]uint64)(unsafe.Pointer(&d.a))
}
keccakF1600(a)
d.n = 0 d.n = 0
keccakF1600(&d.a)
case spongeSqueezing: if cpu.IsBigEndian {
// If we're squeezing, we need to apply the permutation before for i := range a {
// copying more output. binary.LittleEndian.PutUint64(d.a[i*8:], a[i])
keccakF1600(&d.a) }
d.i = 0
copyOut(d, d.storage[:d.rate])
} }
} }
@ -92,55 +97,38 @@ func (d *state) permute() {
// the multi-bitrate 10..1 padding rule, and permutes the state. // the multi-bitrate 10..1 padding rule, and permutes the state.
func (d *state) padAndPermute() { func (d *state) padAndPermute() {
// Pad with this instance's domain-separator bits. We know that there's // Pad with this instance's domain-separator bits. We know that there's
// at least one byte of space in d.buf because, if it were full, // at least one byte of space in the sponge because, if it were full,
// permute would have been called to empty it. dsbyte also contains the // permute would have been called to empty it. dsbyte also contains the
// first one bit for the padding. See the comment in the state struct. // first one bit for the padding. See the comment in the state struct.
d.storage[d.n] = d.dsbyte d.a[d.n] ^= d.dsbyte
d.n++
for d.n < d.rate {
d.storage[d.n] = 0
d.n++
}
// This adds the final one bit for the padding. Because of the way that // This adds the final one bit for the padding. Because of the way that
// bits are numbered from the LSB upwards, the final bit is the MSB of // bits are numbered from the LSB upwards, the final bit is the MSB of
// the last byte. // the last byte.
d.storage[d.rate-1] ^= 0x80 d.a[d.rate-1] ^= 0x80
// Apply the permutation // Apply the permutation
d.permute() d.permute()
d.state = spongeSqueezing d.state = spongeSqueezing
d.n = d.rate
copyOut(d, d.storage[:d.rate])
} }
// Write absorbs more data into the hash's state. It panics if any // Write absorbs more data into the hash's state. It panics if any
// output has already been read. // output has already been read.
func (d *state) Write(p []byte) (written int, err error) { func (d *state) Write(p []byte) (n int, err error) {
if d.state != spongeAbsorbing { if d.state != spongeAbsorbing {
panic("sha3: Write after Read") panic("sha3: Write after Read")
} }
written = len(p)
n = len(p)
for len(p) > 0 { for len(p) > 0 {
if d.n == 0 && len(p) >= d.rate { x := subtle.XORBytes(d.a[d.n:d.rate], d.a[d.n:d.rate], p)
// The fast path; absorb a full "rate" bytes of input and apply the permutation. d.n += x
xorIn(d, p[:d.rate]) p = p[x:]
p = p[d.rate:]
keccakF1600(&d.a)
} else {
// The slow path; buffer the input until we can fill the sponge, and then xor it in.
todo := d.rate - d.n
if todo > len(p) {
todo = len(p)
}
d.n += copy(d.storage[d.n:], p[:todo])
p = p[todo:]
// If the sponge is full, apply the permutation. // If the sponge is full, apply the permutation.
if d.n == d.rate { if d.n == d.rate {
d.permute() d.permute()
} }
} }
}
return return
} }
@ -156,14 +144,14 @@ func (d *state) Read(out []byte) (n int, err error) {
// Now, do the squeezing. // Now, do the squeezing.
for len(out) > 0 { for len(out) > 0 {
n := copy(out, d.storage[d.i:d.n])
d.i += n
out = out[n:]
// Apply the permutation if we've squeezed the sponge dry. // Apply the permutation if we've squeezed the sponge dry.
if d.i == d.rate { if d.n == d.rate {
d.permute() d.permute()
} }
x := copy(out, d.a[d.n:d.rate])
d.n += x
out = out[x:]
} }
return return
@ -183,3 +171,74 @@ func (d *state) Sum(in []byte) []byte {
dup.Read(hash) dup.Read(hash)
return append(in, hash...) return append(in, hash...)
} }
const (
magicSHA3 = "sha\x08"
magicShake = "sha\x09"
magicCShake = "sha\x0a"
magicKeccak = "sha\x0b"
// magic || rate || main state || n || sponge direction
marshaledSize = len(magicSHA3) + 1 + 200 + 1 + 1
)
func (d *state) MarshalBinary() ([]byte, error) {
return d.AppendBinary(make([]byte, 0, marshaledSize))
}
func (d *state) AppendBinary(b []byte) ([]byte, error) {
switch d.dsbyte {
case dsbyteSHA3:
b = append(b, magicSHA3...)
case dsbyteShake:
b = append(b, magicShake...)
case dsbyteCShake:
b = append(b, magicCShake...)
case dsbyteKeccak:
b = append(b, magicKeccak...)
default:
panic("unknown dsbyte")
}
// rate is at most 168, and n is at most rate.
b = append(b, byte(d.rate))
b = append(b, d.a[:]...)
b = append(b, byte(d.n), byte(d.state))
return b, nil
}
func (d *state) UnmarshalBinary(b []byte) error {
if len(b) != marshaledSize {
return errors.New("sha3: invalid hash state")
}
magic := string(b[:len(magicSHA3)])
b = b[len(magicSHA3):]
switch {
case magic == magicSHA3 && d.dsbyte == dsbyteSHA3:
case magic == magicShake && d.dsbyte == dsbyteShake:
case magic == magicCShake && d.dsbyte == dsbyteCShake:
case magic == magicKeccak && d.dsbyte == dsbyteKeccak:
default:
return errors.New("sha3: invalid hash state identifier")
}
rate := int(b[0])
b = b[1:]
if rate != d.rate {
return errors.New("sha3: invalid hash state function")
}
copy(d.a[:], b)
b = b[len(d.a):]
n, state := int(b[0]), spongeDirection(b[1])
if n > d.rate {
return errors.New("sha3: invalid hash state")
}
d.n = n
if state != spongeAbsorbing && state != spongeSqueezing {
return errors.New("sha3: invalid hash state")
}
d.state = state
return nil
}

View file

@ -16,9 +16,12 @@
// [2] https://doi.org/10.6028/NIST.SP.800-185 // [2] https://doi.org/10.6028/NIST.SP.800-185
import ( import (
"bytes"
"encoding/binary" "encoding/binary"
"errors"
"hash" "hash"
"io" "io"
"math/bits"
) )
// ShakeHash defines the interface to hash functions that support // ShakeHash defines the interface to hash functions that support
@ -50,41 +53,33 @@ type cshakeState struct {
initBlock []byte initBlock []byte
} }
// Consts for configuring initial SHA-3 state func bytepad(data []byte, rate int) []byte {
const ( out := make([]byte, 0, 9+len(data)+rate-1)
dsbyteShake = 0x1f out = append(out, leftEncode(uint64(rate))...)
dsbyteCShake = 0x04 out = append(out, data...)
rate128 = 168 if padlen := rate - len(out)%rate; padlen < rate {
rate256 = 136 out = append(out, make([]byte, padlen)...)
) }
return out
func bytepad(input []byte, w int) []byte {
// leftEncode always returns max 9 bytes
buf := make([]byte, 0, 9+len(input)+w)
buf = append(buf, leftEncode(uint64(w))...)
buf = append(buf, input...)
padlen := w - (len(buf) % w)
return append(buf, make([]byte, padlen)...)
} }
func leftEncode(value uint64) []byte { func leftEncode(x uint64) []byte {
var b [9]byte // Let n be the smallest positive integer for which 2^(8n) > x.
binary.BigEndian.PutUint64(b[1:], value) n := (bits.Len64(x) + 7) / 8
// Trim all but last leading zero bytes if n == 0 {
i := byte(1) n = 1
for i < 8 && b[i] == 0 {
i++
} }
// Prepend number of encoded bytes // Return n || x with n as a byte and x an n bytes in big-endian order.
b[i-1] = 9 - i b := make([]byte, 9)
return b[i-1:] binary.BigEndian.PutUint64(b[1:], x)
b = b[9-n-1:]
b[0] = byte(n)
return b
} }
func newCShake(N, S []byte, rate, outputLen int, dsbyte byte) ShakeHash { func newCShake(N, S []byte, rate, outputLen int, dsbyte byte) ShakeHash {
c := cshakeState{state: &state{rate: rate, outputLen: outputLen, dsbyte: dsbyte}} c := cshakeState{state: &state{rate: rate, outputLen: outputLen, dsbyte: dsbyte}}
c.initBlock = make([]byte, 0, 9+len(N)+9+len(S)) // leftEncode returns max 9 bytes
// leftEncode returns max 9 bytes
c.initBlock = make([]byte, 0, 9*2+len(N)+len(S))
c.initBlock = append(c.initBlock, leftEncode(uint64(len(N))*8)...) c.initBlock = append(c.initBlock, leftEncode(uint64(len(N))*8)...)
c.initBlock = append(c.initBlock, N...) c.initBlock = append(c.initBlock, N...)
c.initBlock = append(c.initBlock, leftEncode(uint64(len(S))*8)...) c.initBlock = append(c.initBlock, leftEncode(uint64(len(S))*8)...)
@ -111,6 +106,30 @@ func (c *state) Clone() ShakeHash {
return c.clone() return c.clone()
} }
func (c *cshakeState) MarshalBinary() ([]byte, error) {
return c.AppendBinary(make([]byte, 0, marshaledSize+len(c.initBlock)))
}
func (c *cshakeState) AppendBinary(b []byte) ([]byte, error) {
b, err := c.state.AppendBinary(b)
if err != nil {
return nil, err
}
b = append(b, c.initBlock...)
return b, nil
}
func (c *cshakeState) UnmarshalBinary(b []byte) error {
if len(b) <= marshaledSize {
return errors.New("sha3: invalid hash state")
}
if err := c.state.UnmarshalBinary(b[:marshaledSize]); err != nil {
return err
}
c.initBlock = bytes.Clone(b[marshaledSize:])
return nil
}
// NewShake128 creates a new SHAKE128 variable-output-length ShakeHash. // NewShake128 creates a new SHAKE128 variable-output-length ShakeHash.
// Its generic security strength is 128 bits against all attacks if at // Its generic security strength is 128 bits against all attacks if at
// least 32 bytes of its output are used. // least 32 bytes of its output are used.
@ -126,11 +145,11 @@ func NewShake256() ShakeHash {
} }
func newShake128Generic() *state { func newShake128Generic() *state {
return &state{rate: rate128, outputLen: 32, dsbyte: dsbyteShake} return &state{rate: rateK256, outputLen: 32, dsbyte: dsbyteShake}
} }
func newShake256Generic() *state { func newShake256Generic() *state {
return &state{rate: rate256, outputLen: 64, dsbyte: dsbyteShake} return &state{rate: rateK512, outputLen: 64, dsbyte: dsbyteShake}
} }
// NewCShake128 creates a new instance of cSHAKE128 variable-output-length ShakeHash, // NewCShake128 creates a new instance of cSHAKE128 variable-output-length ShakeHash,
@ -143,7 +162,7 @@ func NewCShake128(N, S []byte) ShakeHash {
if len(N) == 0 && len(S) == 0 { if len(N) == 0 && len(S) == 0 {
return NewShake128() return NewShake128()
} }
return newCShake(N, S, rate128, 32, dsbyteCShake) return newCShake(N, S, rateK256, 32, dsbyteCShake)
} }
// NewCShake256 creates a new instance of cSHAKE256 variable-output-length ShakeHash, // NewCShake256 creates a new instance of cSHAKE256 variable-output-length ShakeHash,
@ -156,7 +175,7 @@ func NewCShake256(N, S []byte) ShakeHash {
if len(N) == 0 && len(S) == 0 { if len(N) == 0 && len(S) == 0 {
return NewShake256() return NewShake256()
} }
return newCShake(N, S, rate256, 64, dsbyteCShake) return newCShake(N, S, rateK512, 64, dsbyteCShake)
} }
// ShakeSum128 writes an arbitrary-length digest of data into hash. // ShakeSum128 writes an arbitrary-length digest of data into hash.

View file

@ -1,40 +0,0 @@
// Copyright 2015 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 sha3
import (
"crypto/subtle"
"encoding/binary"
"unsafe"
"golang.org/x/sys/cpu"
)
// xorIn xors the bytes in buf into the state.
func xorIn(d *state, buf []byte) {
if cpu.IsBigEndian {
for i := 0; len(buf) >= 8; i++ {
a := binary.LittleEndian.Uint64(buf)
d.a[i] ^= a
buf = buf[8:]
}
} else {
ab := (*[25 * 64 / 8]byte)(unsafe.Pointer(&d.a))
subtle.XORBytes(ab[:], ab[:], buf)
}
}
// copyOut copies uint64s to a byte buffer.
func copyOut(d *state, b []byte) {
if cpu.IsBigEndian {
for i := 0; len(b) >= 8; i++ {
binary.LittleEndian.PutUint64(b, d.a[i])
b = b[8:]
}
} else {
ab := (*[25 * 64 / 8]byte)(unsafe.Pointer(&d.a))
copy(b, ab[:])
}
}

View file

@ -555,6 +555,7 @@ type initiateMsg struct {
} }
gotMsgExtInfo := false gotMsgExtInfo := false
gotUserAuthInfoRequest := false
for { for {
packet, err := c.readPacket() packet, err := c.readPacket()
if err != nil { if err != nil {
@ -585,6 +586,9 @@ type initiateMsg struct {
if msg.PartialSuccess { if msg.PartialSuccess {
return authPartialSuccess, msg.Methods, nil return authPartialSuccess, msg.Methods, nil
} }
if !gotUserAuthInfoRequest {
return authFailure, msg.Methods, unexpectedMessageError(msgUserAuthInfoRequest, packet[0])
}
return authFailure, msg.Methods, nil return authFailure, msg.Methods, nil
case msgUserAuthSuccess: case msgUserAuthSuccess:
return authSuccess, nil, nil return authSuccess, nil, nil
@ -596,6 +600,7 @@ type initiateMsg struct {
if err := Unmarshal(packet, &msg); err != nil { if err := Unmarshal(packet, &msg); err != nil {
return authFailure, nil, err return authFailure, nil, err
} }
gotUserAuthInfoRequest = true
// Manually unpack the prompt/echo pairs. // Manually unpack the prompt/echo pairs.
rest := msg.Prompts rest := msg.Prompts

View file

@ -78,16 +78,11 @@
if err != nil { if err != nil {
// ... // ...
} }
var f func(*html.Node) for n := range doc.Descendants() {
f = func(n *html.Node) {
if n.Type == html.ElementNode && n.Data == "a" { if n.Type == html.ElementNode && n.Data == "a" {
// Do something with n... // Do something with n...
} }
for c := n.FirstChild; c != nil; c = c.NextSibling {
f(c)
} }
}
f(doc)
The relevant specifications include: The relevant specifications include:
https://html.spec.whatwg.org/multipage/syntax.html and https://html.spec.whatwg.org/multipage/syntax.html and

56
vendor/golang.org/x/net/html/iter.go generated vendored Normal file
View file

@ -0,0 +1,56 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build go1.23
package html
import "iter"
// Ancestors returns an iterator over the ancestors of n, starting with n.Parent.
//
// Mutating a Node or its parents while iterating may have unexpected results.
func (n *Node) Ancestors() iter.Seq[*Node] {
_ = n.Parent // eager nil check
return func(yield func(*Node) bool) {
for p := n.Parent; p != nil && yield(p); p = p.Parent {
}
}
}
// ChildNodes returns an iterator over the immediate children of n,
// starting with n.FirstChild.
//
// Mutating a Node or its children while iterating may have unexpected results.
func (n *Node) ChildNodes() iter.Seq[*Node] {
_ = n.FirstChild // eager nil check
return func(yield func(*Node) bool) {
for c := n.FirstChild; c != nil && yield(c); c = c.NextSibling {
}
}
}
// Descendants returns an iterator over all nodes recursively beneath
// n, excluding n itself. Nodes are visited in depth-first preorder.
//
// Mutating a Node or its descendants while iterating may have unexpected results.
func (n *Node) Descendants() iter.Seq[*Node] {
_ = n.FirstChild // eager nil check
return func(yield func(*Node) bool) {
n.descendants(yield)
}
}
func (n *Node) descendants(yield func(*Node) bool) bool {
for c := range n.ChildNodes() {
if !yield(c) || !c.descendants(yield) {
return false
}
}
return true
}

View file

@ -38,6 +38,10 @@
// that it looks like "a<b" rather than "a&lt;b". For element nodes, DataAtom // that it looks like "a<b" rather than "a&lt;b". For element nodes, DataAtom
// is the atom for Data, or zero if Data is not a known tag name. // is the atom for Data, or zero if Data is not a known tag name.
// //
// Node trees may be navigated using the link fields (Parent,
// FirstChild, and so on) or a range loop over iterators such as
// [Node.Descendants].
//
// An empty Namespace implies a "http://www.w3.org/1999/xhtml" namespace. // An empty Namespace implies a "http://www.w3.org/1999/xhtml" namespace.
// Similarly, "math" is short for "http://www.w3.org/1998/Math/MathML", and // Similarly, "math" is short for "http://www.w3.org/1998/Math/MathML", and
// "svg" is short for "http://www.w3.org/2000/svg". // "svg" is short for "http://www.w3.org/2000/svg".

View file

@ -8,8 +8,8 @@
import ( import (
"context" "context"
"crypto/tls"
"errors" "errors"
"net"
"net/http" "net/http"
"sync" "sync"
) )
@ -158,7 +158,7 @@ func (c *dialCall) dial(ctx context.Context, addr string) {
// This code decides which ones live or die. // This code decides which ones live or die.
// The return value used is whether c was used. // The return value used is whether c was used.
// c is never closed. // c is never closed.
func (p *clientConnPool) addConnIfNeeded(key string, t *Transport, c *tls.Conn) (used bool, err error) { func (p *clientConnPool) addConnIfNeeded(key string, t *Transport, c net.Conn) (used bool, err error) {
p.mu.Lock() p.mu.Lock()
for _, cc := range p.conns[key] { for _, cc := range p.conns[key] {
if cc.CanTakeNewRequest() { if cc.CanTakeNewRequest() {
@ -194,8 +194,8 @@ type addConnCall struct {
err error err error
} }
func (c *addConnCall) run(t *Transport, key string, tc *tls.Conn) { func (c *addConnCall) run(t *Transport, key string, nc net.Conn) {
cc, err := t.NewClientConn(tc) cc, err := t.NewClientConn(nc)
p := c.p p := c.p
p.mu.Lock() p.mu.Lock()

View file

@ -306,7 +306,7 @@ func ConfigureServer(s *http.Server, conf *Server) error {
if s.TLSNextProto == nil { if s.TLSNextProto == nil {
s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){} s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){}
} }
protoHandler := func(hs *http.Server, c *tls.Conn, h http.Handler) { protoHandler := func(hs *http.Server, c net.Conn, h http.Handler, sawClientPreface bool) {
if testHookOnConn != nil { if testHookOnConn != nil {
testHookOnConn() testHookOnConn()
} }
@ -326,9 +326,28 @@ type baseContexter interface {
Context: ctx, Context: ctx,
Handler: h, Handler: h,
BaseConfig: hs, BaseConfig: hs,
SawClientPreface: sawClientPreface,
}) })
} }
s.TLSNextProto[NextProtoTLS] = protoHandler s.TLSNextProto[NextProtoTLS] = func(hs *http.Server, c *tls.Conn, h http.Handler) {
protoHandler(hs, c, h, false)
}
// The "unencrypted_http2" TLSNextProto key is used to pass off non-TLS HTTP/2 conns.
//
// A connection passed in this method has already had the HTTP/2 preface read from it.
s.TLSNextProto[nextProtoUnencryptedHTTP2] = func(hs *http.Server, c *tls.Conn, h http.Handler) {
nc, err := unencryptedNetConnFromTLSConn(c)
if err != nil {
if lg := hs.ErrorLog; lg != nil {
lg.Print(err)
} else {
log.Print(err)
}
go c.Close()
return
}
protoHandler(hs, nc, h, true)
}
return nil return nil
} }
@ -2880,6 +2899,11 @@ func (w *responseWriter) SetWriteDeadline(deadline time.Time) error {
return nil return nil
} }
func (w *responseWriter) EnableFullDuplex() error {
// We always support full duplex responses, so this is a no-op.
return nil
}
func (w *responseWriter) Flush() { func (w *responseWriter) Flush() {
w.FlushError() w.FlushError()
} }

View file

@ -202,6 +202,20 @@ func (t *Transport) markNewGoroutine() {
} }
} }
func (t *Transport) now() time.Time {
if t != nil && t.transportTestHooks != nil {
return t.transportTestHooks.group.Now()
}
return time.Now()
}
func (t *Transport) timeSince(when time.Time) time.Duration {
if t != nil && t.transportTestHooks != nil {
return t.now().Sub(when)
}
return time.Since(when)
}
// newTimer creates a new time.Timer, or a synthetic timer in tests. // newTimer creates a new time.Timer, or a synthetic timer in tests.
func (t *Transport) newTimer(d time.Duration) timer { func (t *Transport) newTimer(d time.Duration) timer {
if t.transportTestHooks != nil { if t.transportTestHooks != nil {
@ -281,8 +295,8 @@ func configureTransports(t1 *http.Transport) (*Transport, error) {
if !strSliceContains(t1.TLSClientConfig.NextProtos, "http/1.1") { if !strSliceContains(t1.TLSClientConfig.NextProtos, "http/1.1") {
t1.TLSClientConfig.NextProtos = append(t1.TLSClientConfig.NextProtos, "http/1.1") t1.TLSClientConfig.NextProtos = append(t1.TLSClientConfig.NextProtos, "http/1.1")
} }
upgradeFn := func(authority string, c *tls.Conn) http.RoundTripper { upgradeFn := func(scheme, authority string, c net.Conn) http.RoundTripper {
addr := authorityAddr("https", authority) addr := authorityAddr(scheme, authority)
if used, err := connPool.addConnIfNeeded(addr, t2, c); err != nil { if used, err := connPool.addConnIfNeeded(addr, t2, c); err != nil {
go c.Close() go c.Close()
return erringRoundTripper{err} return erringRoundTripper{err}
@ -293,18 +307,37 @@ func configureTransports(t1 *http.Transport) (*Transport, error) {
// was unknown) // was unknown)
go c.Close() go c.Close()
} }
if scheme == "http" {
return (*unencryptedTransport)(t2)
}
return t2 return t2
} }
if m := t1.TLSNextProto; len(m) == 0 { if t1.TLSNextProto == nil {
t1.TLSNextProto = map[string]func(string, *tls.Conn) http.RoundTripper{ t1.TLSNextProto = make(map[string]func(string, *tls.Conn) http.RoundTripper)
"h2": upgradeFn,
} }
} else { t1.TLSNextProto[NextProtoTLS] = func(authority string, c *tls.Conn) http.RoundTripper {
m["h2"] = upgradeFn return upgradeFn("https", authority, c)
}
// The "unencrypted_http2" TLSNextProto key is used to pass off non-TLS HTTP/2 conns.
t1.TLSNextProto[nextProtoUnencryptedHTTP2] = func(authority string, c *tls.Conn) http.RoundTripper {
nc, err := unencryptedNetConnFromTLSConn(c)
if err != nil {
go c.Close()
return erringRoundTripper{err}
}
return upgradeFn("http", authority, nc)
} }
return t2, nil return t2, nil
} }
// unencryptedTransport is a Transport with a RoundTrip method that
// always permits http:// URLs.
type unencryptedTransport Transport
func (t *unencryptedTransport) RoundTrip(req *http.Request) (*http.Response, error) {
return (*Transport)(t).RoundTripOpt(req, RoundTripOpt{allowHTTP: true})
}
func (t *Transport) connPool() ClientConnPool { func (t *Transport) connPool() ClientConnPool {
t.connPoolOnce.Do(t.initConnPool) t.connPoolOnce.Do(t.initConnPool)
return t.connPoolOrDef return t.connPoolOrDef
@ -324,7 +357,7 @@ type ClientConn struct {
t *Transport t *Transport
tconn net.Conn // usually *tls.Conn, except specialized impls tconn net.Conn // usually *tls.Conn, except specialized impls
tlsState *tls.ConnectionState // nil only for specialized impls tlsState *tls.ConnectionState // nil only for specialized impls
reused uint32 // whether conn is being reused; atomic atomicReused uint32 // whether conn is being reused; atomic
singleUse bool // whether being used for a single http.Request singleUse bool // whether being used for a single http.Request
getConnCalled bool // used by clientConnPool getConnCalled bool // used by clientConnPool
@ -364,6 +397,14 @@ type ClientConn struct {
readIdleTimeout time.Duration readIdleTimeout time.Duration
pingTimeout time.Duration pingTimeout time.Duration
// pendingResets is the number of RST_STREAM frames we have sent to the peer,
// without confirming that the peer has received them. When we send a RST_STREAM,
// we bundle it with a PING frame, unless a PING is already in flight. We count
// the reset stream against the connection's concurrency limit until we get
// a PING response. This limits the number of requests we'll try to send to a
// completely unresponsive connection.
pendingResets int
// reqHeaderMu is a 1-element semaphore channel controlling access to sending new requests. // reqHeaderMu is a 1-element semaphore channel controlling access to sending new requests.
// Write to reqHeaderMu to lock it, read from it to unlock. // Write to reqHeaderMu to lock it, read from it to unlock.
// Lock reqmu BEFORE mu or wmu. // Lock reqmu BEFORE mu or wmu.
@ -423,9 +464,9 @@ type clientStream struct {
firstByte bool // got the first response byte firstByte bool // got the first response byte
pastHeaders bool // got first MetaHeadersFrame (actual headers) pastHeaders bool // got first MetaHeadersFrame (actual headers)
pastTrailers bool // got optional second MetaHeadersFrame (trailers) pastTrailers bool // got optional second MetaHeadersFrame (trailers)
num1xx uint8 // number of 1xx responses seen
readClosed bool // peer sent an END_STREAM flag readClosed bool // peer sent an END_STREAM flag
readAborted bool // read loop reset the stream readAborted bool // read loop reset the stream
totalHeaderSize int64 // total size of 1xx headers seen
trailer http.Header // accumulated trailers trailer http.Header // accumulated trailers
resTrailer *http.Header // client's Response.Trailer resTrailer *http.Header // client's Response.Trailer
@ -530,6 +571,8 @@ type RoundTripOpt struct {
// no cached connection is available, RoundTripOpt // no cached connection is available, RoundTripOpt
// will return ErrNoCachedConn. // will return ErrNoCachedConn.
OnlyCachedConn bool OnlyCachedConn bool
allowHTTP bool // allow http:// URLs
} }
func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
@ -562,7 +605,14 @@ func authorityAddr(scheme string, authority string) (addr string) {
// RoundTripOpt is like RoundTrip, but takes options. // RoundTripOpt is like RoundTrip, but takes options.
func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) { func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) {
if !(req.URL.Scheme == "https" || (req.URL.Scheme == "http" && t.AllowHTTP)) { switch req.URL.Scheme {
case "https":
// Always okay.
case "http":
if !t.AllowHTTP && !opt.allowHTTP {
return nil, errors.New("http2: unencrypted HTTP/2 not enabled")
}
default:
return nil, errors.New("http2: unsupported scheme") return nil, errors.New("http2: unsupported scheme")
} }
@ -573,7 +623,7 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res
t.vlogf("http2: Transport failed to get client conn for %s: %v", addr, err) t.vlogf("http2: Transport failed to get client conn for %s: %v", addr, err)
return nil, err return nil, err
} }
reused := !atomic.CompareAndSwapUint32(&cc.reused, 0, 1) reused := !atomic.CompareAndSwapUint32(&cc.atomicReused, 0, 1)
traceGotConn(req, cc, reused) traceGotConn(req, cc, reused)
res, err := cc.RoundTrip(req) res, err := cc.RoundTrip(req)
if err != nil && retry <= 6 { if err != nil && retry <= 6 {
@ -598,6 +648,22 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res
} }
} }
} }
if err == errClientConnNotEstablished {
// This ClientConn was created recently,
// this is the first request to use it,
// and the connection is closed and not usable.
//
// In this state, cc.idleTimer will remove the conn from the pool
// when it fires. Stop the timer and remove it here so future requests
// won't try to use this connection.
//
// If the timer has already fired and we're racing it, the redundant
// call to MarkDead is harmless.
if cc.idleTimer != nil {
cc.idleTimer.Stop()
}
t.connPool().MarkDead(cc)
}
if err != nil { if err != nil {
t.vlogf("RoundTrip failure: %v", err) t.vlogf("RoundTrip failure: %v", err)
return nil, err return nil, err
@ -618,6 +684,7 @@ func (t *Transport) CloseIdleConnections() {
var ( var (
errClientConnClosed = errors.New("http2: client conn is closed") errClientConnClosed = errors.New("http2: client conn is closed")
errClientConnUnusable = errors.New("http2: client conn not usable") errClientConnUnusable = errors.New("http2: client conn not usable")
errClientConnNotEstablished = errors.New("http2: client conn could not be established")
errClientConnGotGoAway = errors.New("http2: Transport received Server's graceful shutdown GOAWAY") errClientConnGotGoAway = errors.New("http2: Transport received Server's graceful shutdown GOAWAY")
) )
@ -757,6 +824,7 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
pingTimeout: conf.PingTimeout, pingTimeout: conf.PingTimeout,
pings: make(map[[8]byte]chan struct{}), pings: make(map[[8]byte]chan struct{}),
reqHeaderMu: make(chan struct{}, 1), reqHeaderMu: make(chan struct{}, 1),
lastActive: t.now(),
} }
var group synctestGroupInterface var group synctestGroupInterface
if t.transportTestHooks != nil { if t.transportTestHooks != nil {
@ -960,7 +1028,7 @@ func (cc *ClientConn) State() ClientConnState {
return ClientConnState{ return ClientConnState{
Closed: cc.closed, Closed: cc.closed,
Closing: cc.closing || cc.singleUse || cc.doNotReuse || cc.goAway != nil, Closing: cc.closing || cc.singleUse || cc.doNotReuse || cc.goAway != nil,
StreamsActive: len(cc.streams), StreamsActive: len(cc.streams) + cc.pendingResets,
StreamsReserved: cc.streamsReserved, StreamsReserved: cc.streamsReserved,
StreamsPending: cc.pendingRequests, StreamsPending: cc.pendingRequests,
LastIdle: cc.lastIdle, LastIdle: cc.lastIdle,
@ -992,16 +1060,38 @@ func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) {
// writing it. // writing it.
maxConcurrentOkay = true maxConcurrentOkay = true
} else { } else {
maxConcurrentOkay = int64(len(cc.streams)+cc.streamsReserved+1) <= int64(cc.maxConcurrentStreams) // We can take a new request if the total of
// - active streams;
// - reservation slots for new streams; and
// - streams for which we have sent a RST_STREAM and a PING,
// but received no subsequent frame
// is less than the concurrency limit.
maxConcurrentOkay = cc.currentRequestCountLocked() < int(cc.maxConcurrentStreams)
} }
st.canTakeNewRequest = cc.goAway == nil && !cc.closed && !cc.closing && maxConcurrentOkay && st.canTakeNewRequest = cc.goAway == nil && !cc.closed && !cc.closing && maxConcurrentOkay &&
!cc.doNotReuse && !cc.doNotReuse &&
int64(cc.nextStreamID)+2*int64(cc.pendingRequests) < math.MaxInt32 && int64(cc.nextStreamID)+2*int64(cc.pendingRequests) < math.MaxInt32 &&
!cc.tooIdleLocked() !cc.tooIdleLocked()
// If this connection has never been used for a request and is closed,
// then let it take a request (which will fail).
//
// This avoids a situation where an error early in a connection's lifetime
// goes unreported.
if cc.nextStreamID == 1 && cc.streamsReserved == 0 && cc.closed {
st.canTakeNewRequest = true
}
return return
} }
// currentRequestCountLocked reports the number of concurrency slots currently in use,
// including active streams, reserved slots, and reset streams waiting for acknowledgement.
func (cc *ClientConn) currentRequestCountLocked() int {
return len(cc.streams) + cc.streamsReserved + cc.pendingResets
}
func (cc *ClientConn) canTakeNewRequestLocked() bool { func (cc *ClientConn) canTakeNewRequestLocked() bool {
st := cc.idleStateLocked() st := cc.idleStateLocked()
return st.canTakeNewRequest return st.canTakeNewRequest
@ -1014,7 +1104,7 @@ func (cc *ClientConn) tooIdleLocked() bool {
// times are compared based on their wall time. We don't want // times are compared based on their wall time. We don't want
// to reuse a connection that's been sitting idle during // to reuse a connection that's been sitting idle during
// VM/laptop suspend if monotonic time was also frozen. // VM/laptop suspend if monotonic time was also frozen.
return cc.idleTimeout != 0 && !cc.lastIdle.IsZero() && time.Since(cc.lastIdle.Round(0)) > cc.idleTimeout return cc.idleTimeout != 0 && !cc.lastIdle.IsZero() && cc.t.timeSince(cc.lastIdle.Round(0)) > cc.idleTimeout
} }
// onIdleTimeout is called from a time.AfterFunc goroutine. It will // onIdleTimeout is called from a time.AfterFunc goroutine. It will
@ -1578,6 +1668,7 @@ func (cs *clientStream) cleanupWriteRequest(err error) {
cs.reqBodyClosed = make(chan struct{}) cs.reqBodyClosed = make(chan struct{})
} }
bodyClosed := cs.reqBodyClosed bodyClosed := cs.reqBodyClosed
closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil
cc.mu.Unlock() cc.mu.Unlock()
if mustCloseBody { if mustCloseBody {
cs.reqBody.Close() cs.reqBody.Close()
@ -1602,16 +1693,40 @@ func (cs *clientStream) cleanupWriteRequest(err error) {
if cs.sentHeaders { if cs.sentHeaders {
if se, ok := err.(StreamError); ok { if se, ok := err.(StreamError); ok {
if se.Cause != errFromPeer { if se.Cause != errFromPeer {
cc.writeStreamReset(cs.ID, se.Code, err) cc.writeStreamReset(cs.ID, se.Code, false, err)
} }
} else { } else {
cc.writeStreamReset(cs.ID, ErrCodeCancel, err) // We're cancelling an in-flight request.
//
// This could be due to the server becoming unresponsive.
// To avoid sending too many requests on a dead connection,
// we let the request continue to consume a concurrency slot
// until we can confirm the server is still responding.
// We do this by sending a PING frame along with the RST_STREAM
// (unless a ping is already in flight).
//
// For simplicity, we don't bother tracking the PING payload:
// We reset cc.pendingResets any time we receive a PING ACK.
//
// We skip this if the conn is going to be closed on idle,
// because it's short lived and will probably be closed before
// we get the ping response.
ping := false
if !closeOnIdle {
cc.mu.Lock()
if cc.pendingResets == 0 {
ping = true
}
cc.pendingResets++
cc.mu.Unlock()
}
cc.writeStreamReset(cs.ID, ErrCodeCancel, ping, err)
} }
} }
cs.bufPipe.CloseWithError(err) // no-op if already closed cs.bufPipe.CloseWithError(err) // no-op if already closed
} else { } else {
if cs.sentHeaders && !cs.sentEndStream { if cs.sentHeaders && !cs.sentEndStream {
cc.writeStreamReset(cs.ID, ErrCodeNo, nil) cc.writeStreamReset(cs.ID, ErrCodeNo, false, nil)
} }
cs.bufPipe.CloseWithError(errRequestCanceled) cs.bufPipe.CloseWithError(errRequestCanceled)
} }
@ -1633,12 +1748,17 @@ func (cs *clientStream) cleanupWriteRequest(err error) {
// Must hold cc.mu. // Must hold cc.mu.
func (cc *ClientConn) awaitOpenSlotForStreamLocked(cs *clientStream) error { func (cc *ClientConn) awaitOpenSlotForStreamLocked(cs *clientStream) error {
for { for {
cc.lastActive = time.Now() if cc.closed && cc.nextStreamID == 1 && cc.streamsReserved == 0 {
// This is the very first request sent to this connection.
// Return a fatal error which aborts the retry loop.
return errClientConnNotEstablished
}
cc.lastActive = cc.t.now()
if cc.closed || !cc.canTakeNewRequestLocked() { if cc.closed || !cc.canTakeNewRequestLocked() {
return errClientConnUnusable return errClientConnUnusable
} }
cc.lastIdle = time.Time{} cc.lastIdle = time.Time{}
if int64(len(cc.streams)) < int64(cc.maxConcurrentStreams) { if cc.currentRequestCountLocked() < int(cc.maxConcurrentStreams) {
return nil return nil
} }
cc.pendingRequests++ cc.pendingRequests++
@ -2180,10 +2300,10 @@ func (cc *ClientConn) forgetStreamID(id uint32) {
if len(cc.streams) != slen-1 { if len(cc.streams) != slen-1 {
panic("forgetting unknown stream id") panic("forgetting unknown stream id")
} }
cc.lastActive = time.Now() cc.lastActive = cc.t.now()
if len(cc.streams) == 0 && cc.idleTimer != nil { if len(cc.streams) == 0 && cc.idleTimer != nil {
cc.idleTimer.Reset(cc.idleTimeout) cc.idleTimer.Reset(cc.idleTimeout)
cc.lastIdle = time.Now() cc.lastIdle = cc.t.now()
} }
// Wake up writeRequestBody via clientStream.awaitFlowControl and // Wake up writeRequestBody via clientStream.awaitFlowControl and
// wake up RoundTrip if there is a pending request. // wake up RoundTrip if there is a pending request.
@ -2243,7 +2363,6 @@ func isEOFOrNetReadError(err error) bool {
func (rl *clientConnReadLoop) cleanup() { func (rl *clientConnReadLoop) cleanup() {
cc := rl.cc cc := rl.cc
cc.t.connPool().MarkDead(cc)
defer cc.closeConn() defer cc.closeConn()
defer close(cc.readerDone) defer close(cc.readerDone)
@ -2267,6 +2386,24 @@ func (rl *clientConnReadLoop) cleanup() {
} }
cc.closed = true cc.closed = true
// If the connection has never been used, and has been open for only a short time,
// leave it in the connection pool for a little while.
//
// This avoids a situation where new connections are constantly created,
// added to the pool, fail, and are removed from the pool, without any error
// being surfaced to the user.
const unusedWaitTime = 5 * time.Second
idleTime := cc.t.now().Sub(cc.lastActive)
if atomic.LoadUint32(&cc.atomicReused) == 0 && idleTime < unusedWaitTime {
cc.idleTimer = cc.t.afterFunc(unusedWaitTime-idleTime, func() {
cc.t.connPool().MarkDead(cc)
})
} else {
cc.mu.Unlock() // avoid any deadlocks in MarkDead
cc.t.connPool().MarkDead(cc)
cc.mu.Lock()
}
for _, cs := range cc.streams { for _, cs := range cc.streams {
select { select {
case <-cs.peerClosed: case <-cs.peerClosed:
@ -2494,15 +2631,34 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra
if f.StreamEnded() { if f.StreamEnded() {
return nil, errors.New("1xx informational response with END_STREAM flag") return nil, errors.New("1xx informational response with END_STREAM flag")
} }
cs.num1xx++
const max1xxResponses = 5 // arbitrary bound on number of informational responses, same as net/http
if cs.num1xx > max1xxResponses {
return nil, errors.New("http2: too many 1xx informational responses")
}
if fn := cs.get1xxTraceFunc(); fn != nil { if fn := cs.get1xxTraceFunc(); fn != nil {
// If the 1xx response is being delivered to the user,
// then they're responsible for limiting the number
// of responses.
if err := fn(statusCode, textproto.MIMEHeader(header)); err != nil { if err := fn(statusCode, textproto.MIMEHeader(header)); err != nil {
return nil, err return nil, err
} }
} else {
// If the user didn't examine the 1xx response, then we
// limit the size of all 1xx headers.
//
// This differs a bit from the HTTP/1 implementation, which
// limits the size of all 1xx headers plus the final response.
// Use the larger limit of MaxHeaderListSize and
// net/http.Transport.MaxResponseHeaderBytes.
limit := int64(cs.cc.t.maxHeaderListSize())
if t1 := cs.cc.t.t1; t1 != nil && t1.MaxResponseHeaderBytes > limit {
limit = t1.MaxResponseHeaderBytes
}
for _, h := range f.Fields {
cs.totalHeaderSize += int64(h.Size())
}
if cs.totalHeaderSize > limit {
if VerboseLogs {
log.Printf("http2: 1xx informational responses too large")
}
return nil, errors.New("header list too large")
}
} }
if statusCode == 100 { if statusCode == 100 {
traceGot100Continue(cs.trace) traceGot100Continue(cs.trace)
@ -3046,6 +3202,11 @@ func (rl *clientConnReadLoop) processPing(f *PingFrame) error {
close(c) close(c)
delete(cc.pings, f.Data) delete(cc.pings, f.Data)
} }
if cc.pendingResets > 0 {
// See clientStream.cleanupWriteRequest.
cc.pendingResets = 0
cc.cond.Broadcast()
}
return nil return nil
} }
cc := rl.cc cc := rl.cc
@ -3068,13 +3229,20 @@ func (rl *clientConnReadLoop) processPushPromise(f *PushPromiseFrame) error {
return ConnectionError(ErrCodeProtocol) return ConnectionError(ErrCodeProtocol)
} }
func (cc *ClientConn) writeStreamReset(streamID uint32, code ErrCode, err error) { // writeStreamReset sends a RST_STREAM frame.
// When ping is true, it also sends a PING frame with a random payload.
func (cc *ClientConn) writeStreamReset(streamID uint32, code ErrCode, ping bool, err error) {
// TODO: map err to more interesting error codes, once the // TODO: map err to more interesting error codes, once the
// HTTP community comes up with some. But currently for // HTTP community comes up with some. But currently for
// RST_STREAM there's no equivalent to GOAWAY frame's debug // RST_STREAM there's no equivalent to GOAWAY frame's debug
// data, and the error codes are all pretty vague ("cancel"). // data, and the error codes are all pretty vague ("cancel").
cc.wmu.Lock() cc.wmu.Lock()
cc.fr.WriteRSTStream(streamID, code) cc.fr.WriteRSTStream(streamID, code)
if ping {
var payload [8]byte
rand.Read(payload[:])
cc.fr.WritePing(false, payload)
}
cc.bw.Flush() cc.bw.Flush()
cc.wmu.Unlock() cc.wmu.Unlock()
} }
@ -3228,7 +3396,7 @@ func traceGotConn(req *http.Request, cc *ClientConn, reused bool) {
cc.mu.Lock() cc.mu.Lock()
ci.WasIdle = len(cc.streams) == 0 && reused ci.WasIdle = len(cc.streams) == 0 && reused
if ci.WasIdle && !cc.lastActive.IsZero() { if ci.WasIdle && !cc.lastActive.IsZero() {
ci.IdleTime = time.Since(cc.lastActive) ci.IdleTime = cc.t.timeSince(cc.lastActive)
} }
cc.mu.Unlock() cc.mu.Unlock()

32
vendor/golang.org/x/net/http2/unencrypted.go generated vendored Normal file
View file

@ -0,0 +1,32 @@
// Copyright 2024 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 http2
import (
"crypto/tls"
"errors"
"net"
)
const nextProtoUnencryptedHTTP2 = "unencrypted_http2"
// unencryptedNetConnFromTLSConn retrieves a net.Conn wrapped in a *tls.Conn.
//
// TLSNextProto functions accept a *tls.Conn.
//
// When passing an unencrypted HTTP/2 connection to a TLSNextProto function,
// we pass a *tls.Conn with an underlying net.Conn containing the unencrypted connection.
// To be extra careful about mistakes (accidentally dropping TLS encryption in a place
// where we want it), the tls.Conn contains a net.Conn with an UnencryptedNetConn method
// that returns the actual connection we want to use.
func unencryptedNetConnFromTLSConn(tc *tls.Conn) (net.Conn, error) {
conner, ok := tc.NetConn().(interface {
UnencryptedNetConn() net.Conn
})
if !ok {
return nil, errors.New("http2: TLS conn unexpectedly found in unencrypted handoff")
}
return conner.UnencryptedNetConn(), nil
}

8
vendor/modules.txt vendored
View file

@ -1058,7 +1058,7 @@ go.uber.org/multierr
# golang.org/x/arch v0.8.0 # golang.org/x/arch v0.8.0
## explicit; go 1.18 ## explicit; go 1.18
golang.org/x/arch/x86/x86asm golang.org/x/arch/x86/x86asm
# golang.org/x/crypto v0.28.0 # golang.org/x/crypto v0.29.0
## explicit; go 1.20 ## explicit; go 1.20
golang.org/x/crypto/acme golang.org/x/crypto/acme
golang.org/x/crypto/acme/autocert golang.org/x/crypto/acme/autocert
@ -1096,7 +1096,7 @@ golang.org/x/image/webp
golang.org/x/mod/internal/lazyregexp golang.org/x/mod/internal/lazyregexp
golang.org/x/mod/module golang.org/x/mod/module
golang.org/x/mod/semver golang.org/x/mod/semver
# golang.org/x/net v0.30.0 # golang.org/x/net v0.31.0
## explicit; go 1.18 ## explicit; go 1.18
golang.org/x/net/bpf golang.org/x/net/bpf
golang.org/x/net/context golang.org/x/net/context
@ -1120,7 +1120,7 @@ golang.org/x/net/trace
## explicit; go 1.18 ## explicit; go 1.18
golang.org/x/oauth2 golang.org/x/oauth2
golang.org/x/oauth2/internal golang.org/x/oauth2/internal
# golang.org/x/sync v0.8.0 # golang.org/x/sync v0.9.0
## explicit; go 1.18 ## explicit; go 1.18
golang.org/x/sync/errgroup golang.org/x/sync/errgroup
golang.org/x/sync/semaphore golang.org/x/sync/semaphore
@ -1130,7 +1130,7 @@ golang.org/x/sys/cpu
golang.org/x/sys/unix golang.org/x/sys/unix
golang.org/x/sys/windows golang.org/x/sys/windows
golang.org/x/sys/windows/registry golang.org/x/sys/windows/registry
# golang.org/x/text v0.19.0 # golang.org/x/text v0.20.0
## explicit; go 1.18 ## explicit; go 1.18
golang.org/x/text/cases golang.org/x/text/cases
golang.org/x/text/encoding golang.org/x/text/encoding