Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions ech_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package multiaddr

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestECHProtocol(t *testing.T) {
echConfigList := []byte{0x00, 0x04, 0xff, 0xff, 0x00, 0x00}
const encodedECHConfigList = "uAAT__wAA"

protocol := ProtocolWithName("ech")
require.Equal(t, P_ECH, protocol.Code)
require.Equal(t, []byte{0xf9, 0x4c}, protocol.VCode)
require.Equal(t, LengthPrefixedVarSize, protocol.Size)
require.NotNil(t, protocol.Transcoder)
require.Equal(t, "ech", ProtocolWithCode(P_ECH).Name)

component, err := NewComponent("ech", encodedECHConfigList)
require.NoError(t, err)
require.Equal(t, "/ech/"+encodedECHConfigList, component.String())
require.Equal(t, echConfigList, component.RawValue())
require.Equal(t, append([]byte{0xf9, 0x4c, 0x06}, echConfigList...), component.Bytes())

addr, err := NewMultiaddr("/ip4/192.0.2.1/tcp/443/tls/ech/" + encodedECHConfigList)
require.NoError(t, err)
require.Equal(t, "/ip4/192.0.2.1/tcp/443/tls/ech/"+encodedECHConfigList, addr.String())

value, err := addr.ValueForProtocol(P_ECH)
require.NoError(t, err)
require.Equal(t, encodedECHConfigList, value)

fromBytes, err := NewMultiaddrBytes(addr.Bytes())
require.NoError(t, err)
require.True(t, addr.Equal(fromBytes))
}

func TestECHAcceptsAnyMultibaseEncoding(t *testing.T) {
addr, err := NewMultiaddr("/quic-v1/ech/baacp77yaaa")
require.NoError(t, err)
require.Equal(t, "/quic-v1/ech/uAAT__wAA", addr.String())
}

func TestECHRejectsInvalidValues(t *testing.T) {
for _, value := range []string{"not-multibase", "u"} {
_, err := NewComponent("ech", value)
require.Error(t, err)
}
}
9 changes: 9 additions & 0 deletions protocols.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const (
P_GARLIC32 = 447
P_P2P_WEBRTC_DIRECT = 276 // Deprecated. use webrtc-direct instead
P_TLS = 448
P_ECH = 9849
P_SNI = 449
P_NOISE = 454
P_WS = 477
Expand Down Expand Up @@ -245,6 +246,13 @@ var (
Code: P_TLS,
VCode: CodeToVarint(P_TLS),
}
protoECH = Protocol{
Name: "ech",
Code: P_ECH,
VCode: CodeToVarint(P_ECH),
Size: LengthPrefixedVarSize,
Transcoder: TranscoderECH,
}
protoSNI = Protocol{
Name: "sni",
Size: LengthPrefixedVarSize,
Expand Down Expand Up @@ -324,6 +332,7 @@ func init() {
protoUNIX,
protoP2P_WEBRTC_DIRECT,
protoTLS,
protoECH,
protoSNI,
protoNOISE,
protoWS,
Expand Down
27 changes: 27 additions & 0 deletions transcoders.go
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,33 @@ func validateCertHash(b []byte) error {
return err
}

var TranscoderECH = NewTranscoderFromFunctions(echStB, echBtS, validateECH)

func echStB(s string) ([]byte, error) {
_, data, err := multibase.Decode(s)
if err != nil {
return nil, err
}
if err := validateECH(data); err != nil {
return nil, err
}
return data, nil
}

func echBtS(b []byte) (string, error) {
if err := validateECH(b); err != nil {
return "", err
}
return multibase.Encode(multibase.Base64url, b)
}

func validateECH(b []byte) error {
if len(b) == 0 {
return errors.New("empty ECHConfigList")
}
return nil
}

var TranscoderHTTPPath = NewTranscoderFromFunctions(httpPathStB, httpPathBtS, validateHTTPPath)

func httpPathStB(s string) ([]byte, error) {
Expand Down
Loading