Files
go-sam-go/common/util.go
2025-05-27 16:40:15 -04:00

100 lines
2.5 KiB
Go

package common
import (
"math/rand"
"net"
"strconv"
"strings"
"time"
"github.com/samber/oops"
"github.com/sirupsen/logrus"
)
func IgnorePortError(err error) error {
if err == nil {
return nil
}
if strings.Contains(err.Error(), "missing port in address") {
log.Debug("Ignoring 'missing port in address' error")
err = nil
}
return err
}
func SplitHostPort(hostport string) (string, string, error) {
host, port, err := net.SplitHostPort(hostport)
if err != nil {
if IgnorePortError(err) == nil {
log.WithField("host", hostport).Debug("Using full string as host, port set to 0")
host = hostport
port = "0"
}
}
log.WithFields(logrus.Fields{
"host": host,
"port": port,
}).Debug("Split host and port")
return host, port, nil
}
func ExtractPairString(input, value string) string {
log.WithFields(logrus.Fields{"input": input, "value": value}).Debug("ExtractPairString called")
parts := strings.Split(input, " ")
for _, part := range parts {
log.WithField("part", part).Debug("Checking part")
if strings.HasPrefix(part, value) {
kv := strings.SplitN(part, "=", 2)
if len(kv) == 2 {
log.WithFields(logrus.Fields{"key": kv[0], "value": kv[1]}).Debug("Pair extracted")
return kv[1]
}
}
}
log.WithFields(logrus.Fields{"input": input, "value": value}).Debug("No pair found")
return ""
}
func ExtractPairInt(input, value string) int {
rv, err := strconv.Atoi(ExtractPairString(input, value))
if err != nil {
log.WithFields(logrus.Fields{"input": input, "value": value}).Debug("No pair found")
return 0
}
log.WithField("result", rv).Debug("Pair extracted and converted to int")
return rv
}
func ExtractDest(input string) string {
log.WithField("input", input).Debug("ExtractDest called")
dest := strings.Split(input, " ")[0]
log.WithField("dest", dest).Debug("Destination extracted")
return strings.Split(input, " ")[0]
}
var (
randSource = rand.NewSource(time.Now().UnixNano())
randGen = rand.New(randSource)
)
func RandPort() (portNumber string, err error) {
maxAttempts := 30
for range maxAttempts {
p := randGen.Intn(55534) + 10000
port := strconv.Itoa(p)
if l, e := net.Listen("tcp", net.JoinHostPort("localhost", port)); e != nil {
continue
} else {
defer l.Close()
if l, e := net.Listen("udp", net.JoinHostPort("localhost", port)); e != nil {
continue
} else {
defer l.Close()
return strconv.Itoa(l.Addr().(*net.UDPAddr).Port), nil
}
}
}
return "", oops.Errorf("unable to find a pair of available tcp and udp ports in %v attempts", maxAttempts)
}