101 lines
2.4 KiB
Go
101 lines
2.4 KiB
Go
|
package supervisor
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"crypto/tls"
|
||
|
"encoding/json"
|
||
|
"net/http"
|
||
|
"sync"
|
||
|
)
|
||
|
|
||
|
// When experimental post-quantum tunnels are enabled, and we're hitting an
|
||
|
// issue creating the tunnel, we'll report the first error
|
||
|
// to https://pqtunnels.cloudflareresearch.com.
|
||
|
|
||
|
var (
|
||
|
PQKexes = [...]tls.CurveID{
|
||
|
tls.CurveID(0xfe30), // X25519Kyber512Draft00
|
||
|
tls.CurveID(0xfe31), // X25519Kyber768Draft00
|
||
|
}
|
||
|
PQKexNames map[tls.CurveID]string = map[tls.CurveID]string{
|
||
|
tls.CurveID(0xfe30): "X25519Kyber512Draft00",
|
||
|
tls.CurveID(0xfe31): "X25519Kyber768Draft00",
|
||
|
}
|
||
|
|
||
|
pqtMux sync.Mutex // protects pqtSubmitted and pqtWaitForMessage
|
||
|
pqtSubmitted bool // whether an error has already been submitted
|
||
|
|
||
|
// Number of errors to ignore before printing elaborate instructions.
|
||
|
pqtWaitForMessage int
|
||
|
)
|
||
|
|
||
|
func handlePQTunnelError(rep error, config *TunnelConfig) {
|
||
|
needToMessage := false
|
||
|
|
||
|
pqtMux.Lock()
|
||
|
needToSubmit := !pqtSubmitted
|
||
|
if needToSubmit {
|
||
|
pqtSubmitted = true
|
||
|
}
|
||
|
pqtWaitForMessage--
|
||
|
if pqtWaitForMessage < 0 {
|
||
|
pqtWaitForMessage = 5
|
||
|
needToMessage = true
|
||
|
}
|
||
|
pqtMux.Unlock()
|
||
|
|
||
|
if needToMessage {
|
||
|
config.Log.Info().Msgf(
|
||
|
"\n\n" +
|
||
|
"===================================================================================\n" +
|
||
|
"You are hitting an error while using the experimental post-quantum tunnels feature.\n" +
|
||
|
"\n" +
|
||
|
"Please check:\n" +
|
||
|
"\n" +
|
||
|
" https://pqtunnels.cloudflareresearch.com\n" +
|
||
|
"\n" +
|
||
|
"for known problems.\n" +
|
||
|
"===================================================================================\n\n",
|
||
|
)
|
||
|
}
|
||
|
|
||
|
if needToSubmit {
|
||
|
go submitPQTunnelError(rep, config)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func submitPQTunnelError(rep error, config *TunnelConfig) {
|
||
|
body, err := json.Marshal(struct {
|
||
|
Group int `json:"g"`
|
||
|
Message string `json:"m"`
|
||
|
Version string `json:"v"`
|
||
|
}{
|
||
|
Group: int(PQKexes[config.PQKexIdx]),
|
||
|
Message: rep.Error(),
|
||
|
Version: config.ReportedVersion,
|
||
|
})
|
||
|
if err != nil {
|
||
|
config.Log.Err(err).Msg("Failed to create error report")
|
||
|
return
|
||
|
}
|
||
|
|
||
|
resp, err := http.Post(
|
||
|
"https://pqtunnels.cloudflareresearch.com",
|
||
|
"application/json",
|
||
|
bytes.NewBuffer(body),
|
||
|
)
|
||
|
if err != nil {
|
||
|
config.Log.Err(err).Msg(
|
||
|
"Failed to submit post-quantum tunnel error report",
|
||
|
)
|
||
|
return
|
||
|
}
|
||
|
if resp.StatusCode != 200 {
|
||
|
config.Log.Error().Msgf(
|
||
|
"Failed to submit post-quantum tunnel error report: status %d",
|
||
|
resp.StatusCode,
|
||
|
)
|
||
|
}
|
||
|
resp.Body.Close()
|
||
|
}
|