Use Cloudflare Go fork, fixed caches not working, use faster signature verification
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
6bdc45f927
commit
c000a83682
21
Dockerfile
21
Dockerfile
|
@ -1,9 +1,22 @@
|
||||||
FROM golang:1.18-rc-bullseye
|
FROM debian:bullseye
|
||||||
|
|
||||||
COPY . /src
|
RUN DEBIAN_FRONTEND=noninteractive apt update && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt install -y \
|
||||||
|
git build-essential \
|
||||||
|
golang
|
||||||
|
|
||||||
WORKDIR /src
|
RUN git clone --depth 1 https://github.com/cloudflare/go.git /src/go && cd /src/go && \
|
||||||
RUN go build -o orbeat . && mv orbeat /usr/bin && rm -rf /src
|
cd src && \
|
||||||
|
./all.bash
|
||||||
|
RUN DEBIAN_FRONTEND=noninteractive apt remove -y golang && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt autoremove -y
|
||||||
|
|
||||||
|
ENV PATH "$PATH:/src/go/bin"
|
||||||
|
|
||||||
|
COPY . /src/orbeat
|
||||||
|
|
||||||
|
WORKDIR /src/orbeat
|
||||||
|
RUN go build -o orbeat . && mv orbeat /usr/bin && rm -rf /src/orbeat
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/bin/orbeat"]
|
ENTRYPOINT ["/usr/bin/orbeat"]
|
207
OrbitalBeat.go
207
OrbitalBeat.go
|
@ -3,7 +3,6 @@ package main
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/ed25519"
|
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
@ -17,6 +16,7 @@ import (
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/cloudflare/circl/sign/ed25519"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
"github.com/multiformats/go-multihash"
|
"github.com/multiformats/go-multihash"
|
||||||
|
@ -29,39 +29,14 @@ import (
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ContentCacheEntry struct {
|
type ContentCacheEntry struct {
|
||||||
Entry ContentEntry
|
Entry ContentEntry
|
||||||
RefCount int64
|
|
||||||
AccessTime time.Time
|
AccessTime time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ContentCacheEntry) valid() bool {
|
|
||||||
return atomic.LoadInt64(&e.RefCount) > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *ContentCacheEntry) borrow() *ContentCacheEntry {
|
|
||||||
if e.valid() {
|
|
||||||
if atomic.AddInt64(&e.RefCount, 1) > 1 {
|
|
||||||
return e
|
|
||||||
} else { //Has already been deallocated or is in the process
|
|
||||||
atomic.AddInt64(&e.RefCount, -1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *ContentCacheEntry) release() {
|
|
||||||
objectCacheMutex.Lock()
|
|
||||||
if atomic.AddInt64(&e.RefCount, -1) == 0 {
|
|
||||||
delete(objectCache, e.Entry.Identifier)
|
|
||||||
}
|
|
||||||
objectCacheMutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
var base32Encoding = base32.NewEncoding("qpzry9x8gf2tvdw0s3jn54khce6mua7l").WithPadding(base32.NoPadding)
|
var base32Encoding = base32.NewEncoding("qpzry9x8gf2tvdw0s3jn54khce6mua7l").WithPadding(base32.NoPadding)
|
||||||
|
|
||||||
var dbHandle *sql.DB
|
var dbHandle *sql.DB
|
||||||
|
@ -72,7 +47,7 @@ var fdlimit int
|
||||||
var fsHandler fasthttp.RequestHandler
|
var fsHandler fasthttp.RequestHandler
|
||||||
|
|
||||||
var objectCacheMutex sync.RWMutex
|
var objectCacheMutex sync.RWMutex
|
||||||
var objectCache = make(map[cid.Cid]*ContentCacheEntry)
|
var objectCache = make(map[string]*ContentCacheEntry)
|
||||||
|
|
||||||
var messageCacheLimit int
|
var messageCacheLimit int
|
||||||
var messageCacheMutex sync.RWMutex
|
var messageCacheMutex sync.RWMutex
|
||||||
|
@ -97,8 +72,36 @@ func getFirstValidContentEntry(entries *[]ContentEntry) *ContentEntry {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleQueryRequest(ctx *fasthttp.RequestCtx, identifier cid.Cid, extraArguments []string) {
|
func guessMimeType(p string) string {
|
||||||
|
//Need a few extra types from base Go
|
||||||
|
ext := strings.ToLower(path.Ext(p))
|
||||||
|
|
||||||
|
switch ext {
|
||||||
|
case ".flac":
|
||||||
|
fallthrough
|
||||||
|
case ".ogg":
|
||||||
|
fallthrough
|
||||||
|
case ".opus":
|
||||||
|
fallthrough
|
||||||
|
case ".tta":
|
||||||
|
fallthrough
|
||||||
|
case ".aac":
|
||||||
|
fallthrough
|
||||||
|
case ".wav":
|
||||||
|
fallthrough
|
||||||
|
case ".alac":
|
||||||
|
return "audio/" + ext[1:]
|
||||||
|
case ".m4a":
|
||||||
|
return "audio/mp4"
|
||||||
|
case ".mp3":
|
||||||
|
return "audio/mpeg;codecs=mp3"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleQueryRequest(ctx *fasthttp.RequestCtx, identifier cid.Cid, extraArguments []string) {
|
||||||
|
cTime := time.Now()
|
||||||
var cacheEntry = tryGetCacheEntryForIdentifier(identifier)
|
var cacheEntry = tryGetCacheEntryForIdentifier(identifier)
|
||||||
|
|
||||||
if cacheEntry == nil {
|
if cacheEntry == nil {
|
||||||
|
@ -107,8 +110,16 @@ func handleQueryRequest(ctx *fasthttp.RequestCtx, identifier cid.Cid, extraArgum
|
||||||
entry := getFirstValidContentEntry(&result)
|
entry := getFirstValidContentEntry(&result)
|
||||||
|
|
||||||
if entry != nil {
|
if entry != nil {
|
||||||
cacheEntry = getCacheEntryForContentEntry(entry)
|
cacheEntry = getCacheEntryForContentEntry(entry, identifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pTime := cTime
|
||||||
|
cTime = time.Now()
|
||||||
|
addServerTimingMetric(ctx, "e", "Content Entry (MISS)", cTime.Sub(pTime))
|
||||||
|
} else {
|
||||||
|
pTime := cTime
|
||||||
|
cTime = time.Now()
|
||||||
|
addServerTimingMetric(ctx, "e", "Content Entry (HIT)", cTime.Sub(pTime))
|
||||||
}
|
}
|
||||||
|
|
||||||
if cacheEntry == nil {
|
if cacheEntry == nil {
|
||||||
|
@ -137,7 +148,6 @@ func handleQueryRequest(ctx *fasthttp.RequestCtx, identifier cid.Cid, extraArgum
|
||||||
ctx.SetStatusCode(fasthttp.StatusNotFound)
|
ctx.SetStatusCode(fasthttp.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer cacheEntry.release()
|
|
||||||
|
|
||||||
mh, _ := multihash.Decode(cacheEntry.Entry.Identifier.Hash())
|
mh, _ := multihash.Decode(cacheEntry.Entry.Identifier.Hash())
|
||||||
|
|
||||||
|
@ -157,6 +167,15 @@ func handleQueryRequest(ctx *fasthttp.RequestCtx, identifier cid.Cid, extraArgum
|
||||||
|
|
||||||
ctx.Request.URI().Reset()
|
ctx.Request.URI().Reset()
|
||||||
ctx.Request.URI().SetPath(cacheEntry.Entry.Path)
|
ctx.Request.URI().SetPath(cacheEntry.Entry.Path)
|
||||||
|
|
||||||
|
pTime := cTime
|
||||||
|
cTime = time.Now()
|
||||||
|
addServerTimingMetric(ctx, "s", "Content Serve", cTime.Sub(pTime))
|
||||||
|
|
||||||
|
mime := guessMimeType(cacheEntry.Entry.Path)
|
||||||
|
if len(mime) > 0 {
|
||||||
|
ctx.Response.Header.SetContentType(mime)
|
||||||
|
}
|
||||||
fsHandler(ctx)
|
fsHandler(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +199,7 @@ func setCORSHeaders(ctx *fasthttp.RequestCtx) {
|
||||||
ctx.Response.Header.Set("Cross-Origin-Opener-Policy", "unsafe-none")
|
ctx.Response.Header.Set("Cross-Origin-Opener-Policy", "unsafe-none")
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCacheEntryForContentEntry(entry *ContentEntry) *ContentCacheEntry {
|
func getCacheEntryForContentEntry(entry *ContentEntry, originalIdentifier cid.Cid) *ContentCacheEntry {
|
||||||
|
|
||||||
cacheEntry := tryGetCacheEntryForIdentifier(entry.Identifier)
|
cacheEntry := tryGetCacheEntryForIdentifier(entry.Identifier)
|
||||||
|
|
||||||
|
@ -200,18 +219,22 @@ func getCacheEntryForContentEntry(entry *ContentEntry) *ContentCacheEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
if item != nil {
|
if item != nil {
|
||||||
delete(objectCache, item.Entry.Identifier)
|
delete(objectCache, item.Entry.Identifier.String())
|
||||||
item.release()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
objectCache[entry.Identifier] = &ContentCacheEntry{
|
c := &ContentCacheEntry{
|
||||||
Entry: *entry,
|
Entry: *entry,
|
||||||
RefCount: 1,
|
|
||||||
AccessTime: time.Now(),
|
AccessTime: time.Now(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return objectCache[entry.Identifier].borrow()
|
objectCache[entry.Identifier.String()] = c
|
||||||
|
|
||||||
|
if originalIdentifier.String() != entry.Identifier.String() {
|
||||||
|
objectCache[originalIdentifier.String()] = c
|
||||||
|
}
|
||||||
|
|
||||||
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func tryGetCacheEntryForIdentifier(identifier cid.Cid) *ContentCacheEntry {
|
func tryGetCacheEntryForIdentifier(identifier cid.Cid) *ContentCacheEntry {
|
||||||
|
@ -219,9 +242,8 @@ func tryGetCacheEntryForIdentifier(identifier cid.Cid) *ContentCacheEntry {
|
||||||
objectCacheMutex.RLock()
|
objectCacheMutex.RLock()
|
||||||
defer objectCacheMutex.RUnlock()
|
defer objectCacheMutex.RUnlock()
|
||||||
|
|
||||||
cacheEntry, ok := objectCache[identifier]
|
cacheEntry, ok := objectCache[identifier.String()]
|
||||||
if ok {
|
if ok {
|
||||||
cacheEntry := cacheEntry.borrow()
|
|
||||||
cacheEntry.AccessTime = time.Now().UTC()
|
cacheEntry.AccessTime = time.Now().UTC()
|
||||||
return cacheEntry
|
return cacheEntry
|
||||||
}
|
}
|
||||||
|
@ -238,12 +260,25 @@ func IsTrustedPublicKey(key ed25519.PublicKey) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addServerTimingMetric(ctx *fasthttp.RequestCtx, name string, desc string, d time.Duration) {
|
||||||
|
v := string(ctx.Response.Header.Peek("Server-Timing"))
|
||||||
|
if len(v) > 0 {
|
||||||
|
ctx.Response.Header.Set("Server-Timing", fmt.Sprintf("%s, %s;desc=\"%s\";dur=%.6F", v, name, desc, float64(d.Nanoseconds())/1e6))
|
||||||
|
} else {
|
||||||
|
ctx.Response.Header.Set("Server-Timing", fmt.Sprintf("%s;desc=\"%s\";dur=%.6F", name, desc, float64(d.Nanoseconds())/1e6))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func handle(ctx *fasthttp.RequestCtx) {
|
func handle(ctx *fasthttp.RequestCtx) {
|
||||||
if len(ctx.Host()) > 0 && string(ctx.Host()) == ctx.TLSConnectionState().ServerName { //Prevents rebinding / DNS stuff
|
if len(ctx.Host()) > 0 && string(ctx.Host()) == ctx.TLSConnectionState().ServerName { //Prevents rebinding / DNS stuff
|
||||||
ctx.SetStatusCode(fasthttp.StatusNotFound)
|
ctx.SetStatusCode(fasthttp.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cTime := time.Now()
|
||||||
|
addServerTimingMetric(ctx, "c", "Connection", ctx.Time().Sub(ctx.ConnTime()))
|
||||||
|
addServerTimingMetric(ctx, "r", "Request Handler", cTime.Sub(ctx.Time()))
|
||||||
|
|
||||||
if ctx.IsGet() || ctx.IsHead() {
|
if ctx.IsGet() || ctx.IsHead() {
|
||||||
log.Printf("Serve %s", string(ctx.Path()))
|
log.Printf("Serve %s", string(ctx.Path()))
|
||||||
setOtherHeaders(ctx)
|
setOtherHeaders(ctx)
|
||||||
|
@ -270,7 +305,21 @@ func handle(ctx *fasthttp.RequestCtx) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !message.verify() {
|
pTime := cTime
|
||||||
|
cTime := time.Now()
|
||||||
|
addServerTimingMetric(ctx, "d", "Decode", cTime.Sub(pTime))
|
||||||
|
|
||||||
|
result, cacheHit := message.verify()
|
||||||
|
|
||||||
|
pTime = cTime
|
||||||
|
cTime = time.Now()
|
||||||
|
if cacheHit {
|
||||||
|
addServerTimingMetric(ctx, "v", "Ed25519 Verify (HIT)", cTime.Sub(pTime))
|
||||||
|
} else {
|
||||||
|
addServerTimingMetric(ctx, "v", "Ed25519 Verify (MISS)", cTime.Sub(pTime))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !result {
|
||||||
ctx.SetStatusCode(fasthttp.StatusForbidden)
|
ctx.SetStatusCode(fasthttp.StatusForbidden)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -304,7 +353,7 @@ func (s *ContentMessage) sign(privateKey ed25519.PrivateKey) {
|
||||||
s.VerificationResult = nil
|
s.VerificationResult = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ContentMessage) verify() bool {
|
func (s *ContentMessage) verify() (bool, bool) {
|
||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
|
|
||||||
issueTime := time.Unix(s.IssueTime, 0)
|
issueTime := time.Unix(s.IssueTime, 0)
|
||||||
|
@ -312,11 +361,11 @@ func (s *ContentMessage) verify() bool {
|
||||||
validityEnd := issueTime.Add(time.Hour * 24) //Only 24 hours after time
|
validityEnd := issueTime.Add(time.Hour * 24) //Only 24 hours after time
|
||||||
|
|
||||||
if validityStart.After(currentTime) {
|
if validityStart.After(currentTime) {
|
||||||
return false
|
return false, false
|
||||||
}
|
}
|
||||||
|
|
||||||
if validityEnd.Before(currentTime) {
|
if validityEnd.Before(currentTime) {
|
||||||
return false
|
return false, false
|
||||||
}
|
}
|
||||||
|
|
||||||
messageCacheMutex.RLock()
|
messageCacheMutex.RLock()
|
||||||
|
@ -324,7 +373,7 @@ func (s *ContentMessage) verify() bool {
|
||||||
cachedMessage, ok := messageCache[k]
|
cachedMessage, ok := messageCache[k]
|
||||||
messageCacheMutex.RUnlock()
|
messageCacheMutex.RUnlock()
|
||||||
if ok {
|
if ok {
|
||||||
return *cachedMessage.VerificationResult
|
return *cachedMessage.VerificationResult, true
|
||||||
}
|
}
|
||||||
|
|
||||||
messageCacheMutex.Lock()
|
messageCacheMutex.Lock()
|
||||||
|
@ -351,7 +400,7 @@ func (s *ContentMessage) verify() bool {
|
||||||
|
|
||||||
messageCache[k] = s
|
messageCache[k] = s
|
||||||
|
|
||||||
return *s.VerificationResult
|
return *s.VerificationResult, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ContentMessage) encodeMessage() []byte {
|
func (s *ContentMessage) encodeMessage() []byte {
|
||||||
|
@ -531,6 +580,16 @@ func createSelfSignedCertificate() ([]byte, []byte) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func processCertificate(c *tls.Certificate) {
|
||||||
|
if c.Leaf == nil {
|
||||||
|
leaf, err := x509.ParseCertificate(c.Certificate[0])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Leaf = leaf
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
//TODO: OCSP
|
//TODO: OCSP
|
||||||
certificatePath := flag.String("certificate", "", "Path to SSL certificate file.")
|
certificatePath := flag.String("certificate", "", "Path to SSL certificate file.")
|
||||||
|
@ -544,7 +603,7 @@ func main() {
|
||||||
|
|
||||||
sniAddressOption := flag.String("sni", "", "Define SNI address if desired. Empty will serve any requests regardless.")
|
sniAddressOption := flag.String("sni", "", "Define SNI address if desired. Empty will serve any requests regardless.")
|
||||||
|
|
||||||
fdLimitOption := flag.Int("fdlimit", 128, "Maximum number of lingering cached open files.")
|
fdLimitOption := flag.Int("fdlimit", 512, "Maximum number of lingering cached open files.")
|
||||||
|
|
||||||
signatureCacheLimitOption := flag.Int("siglimit", 4096, "Maximum number of lingering valid signature cache results.")
|
signatureCacheLimitOption := flag.Int("siglimit", 4096, "Maximum number of lingering valid signature cache results.")
|
||||||
|
|
||||||
|
@ -609,6 +668,8 @@ func main() {
|
||||||
} else {
|
} else {
|
||||||
serverCertificate = bogusCertificate
|
serverCertificate = bogusCertificate
|
||||||
}
|
}
|
||||||
|
processCertificate(&bogusCertificate)
|
||||||
|
processCertificate(&serverCertificate)
|
||||||
|
|
||||||
fs := fasthttp.FS{
|
fs := fasthttp.FS{
|
||||||
Root: "/",
|
Root: "/",
|
||||||
|
@ -623,6 +684,34 @@ func main() {
|
||||||
|
|
||||||
fsHandler = fs.NewRequestHandler()
|
fsHandler = fs.NewRequestHandler()
|
||||||
|
|
||||||
|
tlsConfig := &tls.Config{
|
||||||
|
MinVersion: tls.VersionTLS12,
|
||||||
|
MaxVersion: 0, //max supported, currently TLS 1.3
|
||||||
|
CurvePreferences: []tls.CurveID{
|
||||||
|
tls.X25519,
|
||||||
|
tls.CurveP256,
|
||||||
|
tls.CurveP384,
|
||||||
|
},
|
||||||
|
CipherSuites: []uint16{
|
||||||
|
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||||
|
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||||
|
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||||
|
},
|
||||||
|
PreferServerCipherSuites: false,
|
||||||
|
SessionTicketsDisabled: false,
|
||||||
|
Renegotiation: tls.RenegotiateFreelyAsClient,
|
||||||
|
NextProtos: []string{
|
||||||
|
//"h2",
|
||||||
|
"http/1.1",
|
||||||
|
},
|
||||||
|
GetCertificate: func(info *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||||
|
if isSNIAllowed(info.ServerName) {
|
||||||
|
return &serverCertificate, nil
|
||||||
|
}
|
||||||
|
return &bogusCertificate, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
server := &fasthttp.Server{
|
server := &fasthttp.Server{
|
||||||
ReadTimeout: 5 * time.Second,
|
ReadTimeout: 5 * time.Second,
|
||||||
IdleTimeout: 15 * time.Second,
|
IdleTimeout: 15 * time.Second,
|
||||||
|
@ -631,33 +720,7 @@ func main() {
|
||||||
NoDefaultDate: true,
|
NoDefaultDate: true,
|
||||||
TCPKeepalive: false,
|
TCPKeepalive: false,
|
||||||
DisableKeepalive: true,
|
DisableKeepalive: true,
|
||||||
TLSConfig: &tls.Config{
|
TLSConfig: tlsConfig,
|
||||||
MinVersion: tls.VersionTLS12,
|
|
||||||
MaxVersion: 0, //max supported, currently TLS 1.3
|
|
||||||
CurvePreferences: []tls.CurveID{
|
|
||||||
tls.X25519,
|
|
||||||
tls.CurveP256,
|
|
||||||
tls.CurveP384,
|
|
||||||
},
|
|
||||||
CipherSuites: []uint16{
|
|
||||||
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
|
|
||||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
|
||||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
|
||||||
},
|
|
||||||
PreferServerCipherSuites: false,
|
|
||||||
SessionTicketsDisabled: false,
|
|
||||||
Renegotiation: tls.RenegotiateFreelyAsClient,
|
|
||||||
NextProtos: []string{
|
|
||||||
//"h2",
|
|
||||||
"http/1.1",
|
|
||||||
},
|
|
||||||
GetCertificate: func(info *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
|
||||||
if isSNIAllowed(info.ServerName) {
|
|
||||||
return &serverCertificate, nil
|
|
||||||
}
|
|
||||||
return &bogusCertificate, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Serving on %s", *listenAddress)
|
log.Printf("Serving on %s", *listenAddress)
|
||||||
|
|
3
go.mod
3
go.mod
|
@ -1,8 +1,9 @@
|
||||||
module git.gammaspectra.live/S.O.N.G/OrbitalBeat
|
module git.gammaspectra.live/S.O.N.G/OrbitalBeat
|
||||||
|
|
||||||
go 1.14
|
go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/cloudflare/circl v1.1.0
|
||||||
github.com/ipfs/go-cid v0.1.0
|
github.com/ipfs/go-cid v0.1.0
|
||||||
github.com/lib/pq v1.10.4
|
github.com/lib/pq v1.10.4
|
||||||
github.com/multiformats/go-multihash v0.0.15
|
github.com/multiformats/go-multihash v0.0.15
|
||||||
|
|
12
go.sum
12
go.sum
|
@ -1,5 +1,8 @@
|
||||||
github.com/andybalholm/brotli v1.0.2 h1:JKnhI/XQ75uFBTiuzXpzFrUriDPiZjlOSzh6wXogP0E=
|
github.com/andybalholm/brotli v1.0.2 h1:JKnhI/XQ75uFBTiuzXpzFrUriDPiZjlOSzh6wXogP0E=
|
||||||
github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||||
|
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||||
|
github.com/cloudflare/circl v1.1.0 h1:bZgT/A+cikZnKIwn7xL2OBj012Bmvho/o6RpRvv3GKY=
|
||||||
|
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
|
||||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
github.com/ipfs/go-cid v0.1.0 h1:YN33LQulcRHjfom/i25yoOZR4Telp1Hr/2RU3d0PnC0=
|
github.com/ipfs/go-cid v0.1.0 h1:YN33LQulcRHjfom/i25yoOZR4Telp1Hr/2RU3d0PnC0=
|
||||||
github.com/ipfs/go-cid v0.1.0/go.mod h1:rH5/Xv83Rfy8Rw6xG+id3DYAMUVmem1MowoKwdXmN2o=
|
github.com/ipfs/go-cid v0.1.0/go.mod h1:rH5/Xv83Rfy8Rw6xG+id3DYAMUVmem1MowoKwdXmN2o=
|
||||||
|
@ -33,21 +36,22 @@ github.com/valyala/fasthttp v1.32.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD
|
||||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf h1:B2n+Zi5QeYRDAEodEu72OS36gmTWjgpXr2+cWcBW90o=
|
|
||||||
golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc=
|
|
||||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||||
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
|
||||||
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
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-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
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=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 h1:46ULzRKLh1CwgRq2dC5SlBzEqqNCi8rreOZnNrbqcIY=
|
|
||||||
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 h1:hZR0X1kPW+nwyJ9xRxqZk1vx5RUObAPBdKVvXPDUH/E=
|
|
||||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac h1:oN6lz7iLW/YC7un8pq+9bOLyXrprv2+DKfkJY+2LJJw=
|
||||||
|
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
|
Loading…
Reference in a new issue