package extension
import (
"golang.org/x/crypto/cryptobyte"
)
type ALPN struct {
ProtocolNameList []string
}
func (a ALPN ) TypeValue () TypeValue {
return ALPNTypeValue
}
func (a *ALPN ) Marshal () ([]byte , error ) {
var builder cryptobyte .Builder
builder .AddUint16 (uint16 (a .TypeValue ()))
builder .AddUint16LengthPrefixed (func (b *cryptobyte .Builder ) {
b .AddUint16LengthPrefixed (func (b *cryptobyte .Builder ) {
for _ , proto := range a .ProtocolNameList {
p := proto
b .AddUint8LengthPrefixed (func (b *cryptobyte .Builder ) {
b .AddBytes ([]byte (p ))
})
}
})
})
return builder .Bytes ()
}
func (a *ALPN ) Unmarshal (data []byte ) error {
val := cryptobyte .String (data )
var extension uint16
val .ReadUint16 (&extension )
if TypeValue (extension ) != a .TypeValue () {
return errInvalidExtensionType
}
var extData cryptobyte .String
val .ReadUint16LengthPrefixed (&extData )
var protoList cryptobyte .String
if !extData .ReadUint16LengthPrefixed (&protoList ) || protoList .Empty () {
return ErrALPNInvalidFormat
}
for !protoList .Empty () {
var proto cryptobyte .String
if !protoList .ReadUint8LengthPrefixed (&proto ) || proto .Empty () {
return ErrALPNInvalidFormat
}
a .ProtocolNameList = append (a .ProtocolNameList , string (proto ))
}
return nil
}
func ALPNProtocolSelection (supportedProtocols , peerSupportedProtocols []string ) (string , error ) {
if len (supportedProtocols ) == 0 || len (peerSupportedProtocols ) == 0 {
return "" , nil
}
for _ , s := range supportedProtocols {
for _ , c := range peerSupportedProtocols {
if s == c {
return s , nil
}
}
}
return "" , errALPNNoAppProto
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .