mirror of
https://github.com/safing/portmaster
synced 2025-04-20 10:59:10 +00:00
78 lines
1.7 KiB
Go
78 lines
1.7 KiB
Go
package sluice
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
"time"
|
|
|
|
"github.com/safing/portmaster/service/network"
|
|
"github.com/safing/portmaster/service/network/packet"
|
|
)
|
|
|
|
const (
|
|
defaultSluiceTTL = 30 * time.Second
|
|
)
|
|
|
|
var (
|
|
// ErrUnsupported is returned when a protocol is not supported.
|
|
ErrUnsupported = errors.New("unsupported protocol")
|
|
|
|
// ErrSluiceOffline is returned when the sluice for a network is offline.
|
|
ErrSluiceOffline = errors.New("is offline")
|
|
)
|
|
|
|
// Request holds request data for a sluice entry.
|
|
type Request struct {
|
|
ConnInfo *network.Connection
|
|
CallbackFn RequestCallbackFunc
|
|
Expires time.Time
|
|
}
|
|
|
|
// RequestCallbackFunc is called for taking a over handling connection that arrived at the sluice.
|
|
type RequestCallbackFunc func(connInfo *network.Connection, conn net.Conn)
|
|
|
|
// AwaitRequest pre-registers a connection at the sluice for initializing it when it arrives.
|
|
func AwaitRequest(connInfo *network.Connection, callbackFn RequestCallbackFunc) error {
|
|
network := getNetworkFromConnInfo(connInfo)
|
|
if network == "" {
|
|
return ErrUnsupported
|
|
}
|
|
|
|
sluice, ok := getSluice(network)
|
|
if !ok {
|
|
return fmt.Errorf("sluice for network %s %w", network, ErrSluiceOffline)
|
|
}
|
|
|
|
return sluice.AwaitRequest(&Request{
|
|
ConnInfo: connInfo,
|
|
CallbackFn: callbackFn,
|
|
Expires: time.Now().Add(defaultSluiceTTL),
|
|
})
|
|
}
|
|
|
|
func getNetworkFromConnInfo(connInfo *network.Connection) string {
|
|
var network string
|
|
|
|
// protocol
|
|
switch connInfo.IPProtocol { //nolint:exhaustive // Looking for specific values.
|
|
case packet.TCP:
|
|
network = "tcp"
|
|
case packet.UDP:
|
|
network = "udp"
|
|
default:
|
|
return ""
|
|
}
|
|
|
|
// IP version
|
|
switch connInfo.IPVersion {
|
|
case packet.IPv4:
|
|
network += "4"
|
|
case packet.IPv6:
|
|
network += "6"
|
|
default:
|
|
return ""
|
|
}
|
|
|
|
return network
|
|
}
|