Files
Strix/pkg/probe/ports.go
T
eduard256 27117900eb Rewrite Strix from scratch as single binary
Complete architecture rewrite following go2rtc patterns:
- pkg/ for pure logic (camdb, tester, probe, generate)
- internal/ for application glue with Init() modules
- Single HTTP server on :4567 with all endpoints
- zerolog with password masking and memory ring buffer
- Environment-based config only (no YAML files)

API endpoints: /api/search, /api/streams, /api/test,
/api/probe, /api/generate, /api/health, /api/log

Dependencies: go2rtc v1.9.14, go-sqlite3, miekg/dns, zerolog
2026-03-25 10:38:46 +00:00

65 lines
1.0 KiB
Go

package probe
import (
"context"
"fmt"
"net"
"sync"
"time"
)
func ScanPorts(ctx context.Context, ip string, ports []int) (*PortsResult, error) {
if len(ports) == 0 {
return nil, nil
}
deadline, ok := ctx.Deadline()
if !ok {
deadline = time.Now().Add(100 * time.Millisecond)
}
timeout := time.Until(deadline)
if timeout <= 0 {
return nil, context.DeadlineExceeded
}
type hit struct {
port int
latency time.Duration
}
var mu sync.Mutex
var hits []hit
var wg sync.WaitGroup
for _, port := range ports {
wg.Add(1)
go func(port int) {
defer wg.Done()
start := time.Now()
conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", ip, port), timeout)
if err != nil {
return
}
conn.Close()
mu.Lock()
hits = append(hits, hit{port: port, latency: time.Since(start)})
mu.Unlock()
}(port)
}
wg.Wait()
if len(hits) == 0 {
return nil, nil
}
open := make([]int, len(hits))
for i, h := range hits {
open[i] = h.port
}
return &PortsResult{Open: open}, nil
}