diff --git a/service/firewall/interception/windowskext2/handler.go b/service/firewall/interception/windowskext2/handler.go index 9fd96890..3ad67214 100644 --- a/service/firewall/interception/windowskext2/handler.go +++ b/service/firewall/interception/windowskext2/handler.go @@ -208,32 +208,26 @@ func Handler(ctx context.Context, case packetInfo.RedirectionRequestV4 != nil: { req := packetInfo.RedirectionRequestV4 - redirectReq := &ConnectRedirectRequest{ + redirectReq := &BindRedirectRequest{ Request_ID: req.ID, ProcID: req.ProcessID, - Inbound: req.Direction > 0, IpVersion: packet.IPv4, Protocol: packet.IPProtocol(req.Protocol), LocalIP: net.IP(req.LocalIP[:]), - RemoteIP: net.IP(req.RemoteIP[:]), LocalPort: req.LocalPort, - RemotePort: req.RemotePort, } redirectRequests <- redirectReq } case packetInfo.RedirectionRequestV6 != nil: { req := packetInfo.RedirectionRequestV6 - redirectReq := &ConnectRedirectRequest{ + redirectReq := &BindRedirectRequest{ Request_ID: req.ID, ProcID: req.ProcessID, - Inbound: req.Direction > 0, IpVersion: packet.IPv6, Protocol: packet.IPProtocol(req.Protocol), LocalIP: net.IP(req.LocalIP[:]), - RemoteIP: net.IP(req.RemoteIP[:]), LocalPort: req.LocalPort, - RemotePort: req.RemotePort, } redirectRequests <- redirectReq } diff --git a/service/firewall/interception/windowskext2/kext.go b/service/firewall/interception/windowskext2/kext.go index 27452d0a..7da5f22e 100644 --- a/service/firewall/interception/windowskext2/kext.go +++ b/service/firewall/interception/windowskext2/kext.go @@ -170,7 +170,7 @@ func DisableSplitTunnel() error { // If localInterfaceIP is nil, no redirection will be performed (i.e., the connection will go through as normal). // If localInterfaceIP is non-nil, the connection will be redirected to the specified local interface IP. // Note: in case of problems with IP conversion, an error will be returned and no command will be sent to the kext. -func SendRedirectResponseCommand(request *ConnectRedirectRequest, localInterfaceIP *net.IP) error { +func SendRedirectResponseCommand(request *BindRedirectRequest, localInterfaceIP *net.IP) error { // IPv6 if request.IsIPv6() { if localInterfaceIP == nil { diff --git a/service/firewall/interception/windowskext2/redirect_request.go b/service/firewall/interception/windowskext2/redirect_request.go index 55ed7724..c11f7403 100644 --- a/service/firewall/interception/windowskext2/redirect_request.go +++ b/service/firewall/interception/windowskext2/redirect_request.go @@ -6,50 +6,35 @@ import ( "github.com/safing/portmaster/service/network/packet" ) -type ConnectRedirectRequest struct { +type BindRedirectRequest struct { Request_ID uint64 ProcID uint64 - Inbound bool IpVersion packet.IPVersion Protocol packet.IPProtocol LocalIP net.IP - RemoteIP net.IP LocalPort uint16 - RemotePort uint16 } -func (r *ConnectRedirectRequest) ReplyRedirect(localInterfaceIP *net.IP) error { +func (r *BindRedirectRequest) ReplyRedirect(localInterfaceIP *net.IP) error { return SendRedirectResponseCommand(r, localInterfaceIP) } -func (r *ConnectRedirectRequest) ProcessID() uint64 { +func (r *BindRedirectRequest) ProcessID() uint64 { return r.ProcID } -func (r *ConnectRedirectRequest) IsInbound() bool { - return r.Inbound -} - -func (r *ConnectRedirectRequest) IsIPv6() bool { +func (r *BindRedirectRequest) IsIPv6() bool { return r.IpVersion == packet.IPv6 } -func (r *ConnectRedirectRequest) ProtocolType() packet.IPProtocol { +func (r *BindRedirectRequest) ProtocolType() packet.IPProtocol { return r.Protocol } -func (r *ConnectRedirectRequest) LocalAddress() net.IP { +func (r *BindRedirectRequest) LocalAddress() net.IP { return r.LocalIP } -func (r *ConnectRedirectRequest) RemoteAddress() net.IP { - return r.RemoteIP -} - -func (r *ConnectRedirectRequest) LocalPortNumber() uint16 { +func (r *BindRedirectRequest) LocalPortNumber() uint16 { return r.LocalPort } - -func (r *ConnectRedirectRequest) RemotePortNumber() uint16 { - return r.RemotePort -} diff --git a/service/firewall/redirect_requests_handler.go b/service/firewall/redirect_requests_handler.go index f5cd6658..ca88ad6e 100644 --- a/service/firewall/redirect_requests_handler.go +++ b/service/firewall/redirect_requests_handler.go @@ -37,27 +37,53 @@ func handleRedirectRequest(req packet.RedirectRequest) { } }() + pid := req.ProcessID() + if pid <= 0 { + return // Cannot identify process, so cannot apply any profile-based rules. + } + + // TODO: WIP... + /* - fmt.Printf("=================== REDIRECT REQUEST: %v\n", req) - - if req.RemoteAddress().IsLoopback() { + // Split-tunneling only applies to TCP and UDP traffic. + // TODO: Verify whether this check is still needed after the Linux implementation, + // as the Windows driver only sends RedirectRequest notifications for TCP/UDP. + switch req.ProtocolType() { + case packet.TCP, packet.UDP: + default: return } - if req.ProtocolType() != packet.TCP && req.ProtocolType() != packet.UDP { + proc, err := process.GetProcessWithProfile(context.Background(), int(pid)) + if err != nil { + log.Errorf("redirect request: failed to get process for PID %d: %s", pid, err) return } - if req.RemotePortNumber() == 53 { + profile := proc.Profile() + if profile == nil { + log.Tracef("redirect request: process PID %d has no profile, cannot apply split-tunneling", pid) return } + ifIP := strings.TrimSpace(profile.SplitTunnelInterface()) + if len(ifIP) == 0 { + return // No split-tunneling interface set. + } + // TODO: DELME!!! This is just for testing. The correspond interface address should be used here. if req.IsIPv6() { return } - redirectTo = &redirectAddr + ip := net.ParseIP(ifIP) + if ip == nil { + log.Tracef("redirect request: process PID %d profile has no split-tunnel interface set, cannot apply split-tunneling", pid) + return + } - //if req.LocalAddress().Equal() + fmt.Printf("REDIRECT: %s to '%v'\n", profile.LocalProfile().Name, ip) + + + redirectTo = &ip */ } diff --git a/service/network/packet/redirect_request.go b/service/network/packet/redirect_request.go index 6b798cd7..ff968b10 100644 --- a/service/network/packet/redirect_request.go +++ b/service/network/packet/redirect_request.go @@ -14,11 +14,8 @@ type RedirectRequest interface { // Getters: ProcessID() uint64 - IsInbound() bool IsIPv6() bool ProtocolType() IPProtocol LocalAddress() net.IP - RemoteAddress() net.IP LocalPortNumber() uint16 - RemotePortNumber() uint16 } diff --git a/windows_kext/kextinterface/info.go b/windows_kext/kextinterface/info.go index 14ba3206..4ab74206 100644 --- a/windows_kext/kextinterface/info.go +++ b/windows_kext/kextinterface/info.go @@ -132,26 +132,20 @@ type BandwidthStatsArray struct { // RedirectionRequestV4 represents a redirection (split-tunneling) request for IPv4. type RedirectionRequestV4 struct { - ID uint64 - ProcessID uint64 - Direction byte - Protocol byte - LocalIP [4]byte - RemoteIP [4]byte - LocalPort uint16 - RemotePort uint16 + ID uint64 + ProcessID uint64 + Protocol byte + LocalIP [4]byte + LocalPort uint16 } // RedirectionRequestV6 represents a redirection (split-tunneling) request for IPv6. type RedirectionRequestV6 struct { - ID uint64 - ProcessID uint64 - Direction byte - Protocol byte - LocalIP [16]byte - RemoteIP [16]byte - LocalPort uint16 - RemotePort uint16 + ID uint64 + ProcessID uint64 + Protocol byte + LocalIP [16]byte + LocalPort uint16 } type Info struct {