Speak protocol 3.0 and fall back to 2.0 only when that is the reflector's maximum.
A reflector that has moved to 3.0 will not accept a station that always announces 2.0, and a 2.x reflector still needs one explicit plaintext session. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+66
-27
@@ -15,34 +15,38 @@ import (
|
||||
)
|
||||
|
||||
type loaded struct {
|
||||
host string
|
||||
port int
|
||||
callsign string
|
||||
authKey string
|
||||
talkGroup int
|
||||
enableLogging bool
|
||||
logPath string
|
||||
logNotice string
|
||||
host string
|
||||
port int
|
||||
callsign string
|
||||
authKey string
|
||||
talkGroup int
|
||||
certificateDir string
|
||||
certFatal string
|
||||
enableLogging bool
|
||||
logPath string
|
||||
logNotice string
|
||||
}
|
||||
|
||||
type fileShape struct {
|
||||
Host jsontext.Value `json:"host"`
|
||||
Port jsontext.Value `json:"port"`
|
||||
Callsign jsontext.Value `json:"callsign"`
|
||||
AuthKey jsontext.Value `json:"authKey"`
|
||||
TalkGroup jsontext.Value `json:"talkGroup"`
|
||||
EnableLogging jsontext.Value `json:"enableLogging"`
|
||||
LogFile jsontext.Value `json:"logFile"`
|
||||
Host jsontext.Value `json:"host"`
|
||||
Port jsontext.Value `json:"port"`
|
||||
Callsign jsontext.Value `json:"callsign"`
|
||||
AuthKey jsontext.Value `json:"authKey"`
|
||||
TalkGroup jsontext.Value `json:"talkGroup"`
|
||||
CertificateDir jsontext.Value `json:"certificateDir"`
|
||||
EnableLogging jsontext.Value `json:"enableLogging"`
|
||||
LogFile jsontext.Value `json:"logFile"`
|
||||
}
|
||||
|
||||
type templateFile struct {
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Callsign string `json:"callsign"`
|
||||
AuthKey string `json:"authKey"`
|
||||
TalkGroup int `json:"talkGroup"`
|
||||
EnableLogging bool `json:"enableLogging"`
|
||||
LogFile string `json:"logFile"`
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Callsign string `json:"callsign"`
|
||||
AuthKey string `json:"authKey"`
|
||||
TalkGroup int `json:"talkGroup"`
|
||||
CertificateDir string `json:"certificateDir"`
|
||||
EnableLogging bool `json:"enableLogging"`
|
||||
LogFile string `json:"logFile"`
|
||||
}
|
||||
|
||||
var callsignPattern = regexp.MustCompile(`^[A-Z0-9][A-Z]{0,2}\d[A-Z0-9]{0,3}[A-Z](?:-[A-Z0-9]{1,3})?$`)
|
||||
@@ -66,7 +70,7 @@ func writeTemplate(path string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
body, err := jsonv2.Marshal(templateFile{LogFile: logFile})
|
||||
body, err := jsonv2.Marshal(templateFile{CertificateDir: "./funknetz", LogFile: logFile})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -91,15 +95,19 @@ func parseConfig(path string, body []byte) (loaded, error) {
|
||||
if err := jsonv2.Unmarshal(body, &shape); err != nil {
|
||||
return loaded{}, fmt.Errorf("the file could not be read: %w", err)
|
||||
}
|
||||
if block, notice := blockedLog(shape); block {
|
||||
certBad := present(shape.CertificateDir) && shape.CertificateDir.Kind() != jsontext.KindString
|
||||
if block, notice := blockedLog(shape); block || certBad {
|
||||
cfg, err := parseOperational(shape)
|
||||
if err != nil {
|
||||
return loaded{}, err
|
||||
}
|
||||
cfg.logNotice = notice
|
||||
return cfg, nil
|
||||
if !block {
|
||||
cfg = applyLog(cfg, shape)
|
||||
}
|
||||
return applyCertificate(cfg, shape, path), nil
|
||||
}
|
||||
if missingLog(shape) {
|
||||
if missingCertificate(shape) || missingLog(shape) {
|
||||
if !operationalKindsOK(shape) {
|
||||
return parseOperational(shape)
|
||||
}
|
||||
@@ -116,7 +124,7 @@ func parseConfig(path string, body []byte) (loaded, error) {
|
||||
if err != nil {
|
||||
return loaded{}, err
|
||||
}
|
||||
return applyLog(cfg, shape), nil
|
||||
return applyLog(applyCertificate(cfg, shape, path), shape), nil
|
||||
}
|
||||
|
||||
func parseOperational(shape fileShape) (loaded, error) {
|
||||
@@ -217,6 +225,10 @@ func missingLog(shape fileShape) bool {
|
||||
return !present(shape.EnableLogging) || !present(shape.LogFile)
|
||||
}
|
||||
|
||||
func missingCertificate(shape fileShape) bool {
|
||||
return !present(shape.CertificateDir)
|
||||
}
|
||||
|
||||
func operationalKindsOK(shape fileShape) bool {
|
||||
if present(shape.Host) && shape.Host.Kind() != jsontext.KindString {
|
||||
return false
|
||||
@@ -259,6 +271,7 @@ func withLogDefaults(shape fileShape) (fileShape, error) {
|
||||
shape.Callsign = rawOr(shape.Callsign, `""`)
|
||||
shape.AuthKey = rawOr(shape.AuthKey, `""`)
|
||||
shape.TalkGroup = rawOr(shape.TalkGroup, "0")
|
||||
shape.CertificateDir = rawOr(shape.CertificateDir, `"./funknetz"`)
|
||||
shape.EnableLogging = rawOr(shape.EnableLogging, "false")
|
||||
if !present(shape.LogFile) {
|
||||
logFile, err := defaultLogPath()
|
||||
@@ -316,6 +329,32 @@ func rewriteConfig(path string, shape fileShape) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func applyCertificate(cfg loaded, shape fileShape, configPath string) loaded {
|
||||
if !present(shape.CertificateDir) {
|
||||
cfg.certificateDir = resolveCertDir(configPath, "./funknetz")
|
||||
return cfg
|
||||
}
|
||||
dir, err := stringField("certificateDir", shape.CertificateDir)
|
||||
if err != nil {
|
||||
cfg.certFatal = err.Error()
|
||||
return cfg
|
||||
}
|
||||
if strings.TrimSpace(dir) == "" {
|
||||
cfg.certFatal = "certificateDir is empty"
|
||||
return cfg
|
||||
}
|
||||
cfg.certificateDir = resolveCertDir(configPath, dir)
|
||||
return cfg
|
||||
}
|
||||
|
||||
func resolveCertDir(configPath, dir string) string {
|
||||
dir = strings.TrimSpace(dir)
|
||||
if filepath.IsAbs(dir) {
|
||||
return filepath.Clean(dir)
|
||||
}
|
||||
return filepath.Clean(filepath.Join(filepath.Dir(configPath), dir))
|
||||
}
|
||||
|
||||
func applyLog(cfg loaded, shape fileShape) loaded {
|
||||
if shape.EnableLogging.Kind() != jsontext.KindTrue {
|
||||
return cfg
|
||||
|
||||
Reference in New Issue
Block a user