Skip to content

Commit

Permalink
Send connectivity test result to specified report collector (#112)
Browse files Browse the repository at this point in the history
  • Loading branch information
amircybersec authored Oct 25, 2023
1 parent 375a66d commit 9eb8507
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 2 deletions.
5 changes: 3 additions & 2 deletions x/examples/outline-connectivity/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ Example:
```
# From https://www.reddit.com/r/outlinevpn/wiki/index/prefixing/
KEY=ss://ENCRYPTION_KEY@HOST:PORT/
COLLECTOR_URL=https://collector.example.com/metrics
for PREFIX in POST%20 HTTP%2F1.1%20 %05%C3%9C_%C3%A0%01%20 %16%03%01%40%00%01 %13%03%03%3F %16%03%03%40%00%02; do
go run github.com/Jigsaw-Code/outline-sdk/x/examples/outline-connectivity@latest -transport="$KEY?prefix=$PREFIX" -proto tcp -resolver 8.8.8.8 && echo Prefix "$PREFIX" works!
go run github.com/Jigsaw-Code/outline-sdk/x/examples/outline-connectivity@latest -transport="$KEY?prefix=$PREFIX" -proto tcp -resolver 8.8.8.8 -report-to $COLLECTOR_URL -report-success-rate 0.2 -report-failure-rate 1.0 && echo Prefix "$PREFIX" works!
done
```
```
72 changes: 72 additions & 0 deletions x/examples/outline-connectivity/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@
package main

import (
"bytes"
"context"
"encoding/json"
"errors"
"flag"
"fmt"
"io"
"log"
"math/rand"
"net"
"net/http"
"os"
"path"
"strings"
Expand Down Expand Up @@ -85,6 +88,37 @@ func unwrapAll(err error) error {
}
}

func sendReport(record jsonRecord, collectorURL string) error {
jsonData, err := json.Marshal(record)
if err != nil {
log.Fatalf("Error encoding JSON: %s\n", err)
return err
}

req, err := http.NewRequest("POST", collectorURL, bytes.NewReader(jsonData))
if err != nil {
debugLog.Printf("Error creating the HTTP request: %s\n", err)
return err
}

req.Header.Set("Content-Type", "application/json; charset=utf-8")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Fatalf("Error sending the HTTP request: %s\n", err)
return err
}
defer resp.Body.Close()

respBody, err := io.ReadAll(resp.Body)
if err != nil {
debugLog.Printf("Error reading the HTTP response body: %s\n", err)
return err
}
debugLog.Printf("Response: %s\n", respBody)
return nil
}

func init() {
flag.Usage = func() {
fmt.Fprintf(flag.CommandLine.Output(), "Usage: %s [flags...]\n", path.Base(os.Args[0]))
Expand All @@ -98,8 +132,25 @@ func main() {
domainFlag := flag.String("domain", "example.com.", "Domain name to resolve in the test")
resolverFlag := flag.String("resolver", "8.8.8.8,2001:4860:4860::8888", "Comma-separated list of addresses of DNS resolver to use for the test")
protoFlag := flag.String("proto", "tcp,udp", "Comma-separated list of the protocols to test. Must be \"tcp\", \"udp\", or a combination of them")
reportToFlag := flag.String("report-to", "", "URL to send JSON error reports to")
reportSuccessFlag := flag.Float64("report-success-rate", 0.1, "Report success to collector with this probability - must be between 0 and 1")
reportFailureFlag := flag.Float64("report-failure-rate", 1, "Report failure to collector with this probability - must be between 0 and 1")

flag.Parse()

// Perform custom range validation for sampling rate
if *reportSuccessFlag < 0.0 || *reportSuccessFlag > 1.0 {
fmt.Println("Error: report-success-rate must be between 0 and 1.")
flag.Usage()
return
}

if *reportFailureFlag < 0.0 || *reportFailureFlag > 1.0 {
fmt.Println("Error: report-failure-rate must be between 0 and 1.")
flag.Usage()
return
}

if *verboseFlag {
debugLog = *log.New(os.Stderr, "[DEBUG] ", log.LstdFlags|log.Lmicroseconds|log.Lshortfile)
}
Expand Down Expand Up @@ -159,6 +210,27 @@ func main() {
if err != nil {
log.Fatalf("Failed to output JSON: %v", err)
}
// Send error report to collector if specified
if *reportToFlag != "" {
var samplingRate float64
if success {
samplingRate = *reportSuccessFlag
} else {
samplingRate = *reportFailureFlag
}
// Generate a random number between 0 and 1
random := rand.Float64()
if random < samplingRate {
err = sendReport(record, *reportToFlag)
if err != nil {
log.Fatalf("Report failed: %v", err)
} else {
fmt.Println("Report sent")
}
} else {
fmt.Println("Report was not sent this time")
}
}
}
}
if !success {
Expand Down

0 comments on commit 9eb8507

Please sign in to comment.