diff --git a/network/connection.go b/network/connection.go index b1e0a4af..31219259 100644 --- a/network/connection.go +++ b/network/connection.go @@ -317,7 +317,11 @@ func NewConnectionFromFirstPacket(pkt packet.Packet) *Connection { proc, inbound, err := process.GetProcessByConnection(pkt.Ctx(), pkt.Info()) if err != nil { log.Tracer(pkt.Ctx()).Debugf("network: failed to find process of packet %s: %s", pkt, err) - proc = process.GetUnidentifiedProcess(pkt.Ctx()) + if inbound { + proc = process.GetUnsolicitedProcess(pkt.Ctx()) + } else { + proc = process.GetUnidentifiedProcess(pkt.Ctx()) + } } // Create the (remote) entity. diff --git a/network/proc/findpid.go b/network/proc/findpid.go index 3cfb7930..85902d14 100644 --- a/network/proc/findpid.go +++ b/network/proc/findpid.go @@ -23,7 +23,7 @@ func GetPID(socketInfo socket.Info) (pid int) { currentPid := socketInfo.GetPID() // If the current PID already is valid (ie. not unidentified), return it immediately. - if currentPid != socket.UnidentifiedProcessID { + if currentPid != socket.UndefinedProcessID { return currentPid } @@ -91,7 +91,7 @@ func findPID(uid, inode int) (pid int) { } } - return socket.UnidentifiedProcessID + return socket.UndefinedProcessID } func findSocketFromPid(pid int, socketName string) bool { diff --git a/network/proc/tables.go b/network/proc/tables.go index af720b2a..62c4a4c5 100644 --- a/network/proc/tables.go +++ b/network/proc/tables.go @@ -149,7 +149,7 @@ func getTableFromSource(stack uint8, procFile string) (connections []*socket.Con IP: localIP, Port: uint16(localPort), }, - PID: socket.UnidentifiedProcessID, + PID: socket.UndefinedProcessID, UID: int(uid), Inode: int(inode), }) @@ -164,7 +164,7 @@ func getTableFromSource(stack uint8, procFile string) (connections []*socket.Con IP: localIP, Port: uint16(localPort), }, - PID: socket.UnidentifiedProcessID, + PID: socket.UndefinedProcessID, UID: int(uid), Inode: int(inode), }) @@ -191,7 +191,7 @@ func getTableFromSource(stack uint8, procFile string) (connections []*socket.Con IP: remoteIP, Port: uint16(remotePort), }, - PID: socket.UnidentifiedProcessID, + PID: socket.UndefinedProcessID, UID: int(uid), Inode: int(inode), }) diff --git a/network/socket/socket.go b/network/socket/socket.go index 266176dd..18c5b677 100644 --- a/network/socket/socket.go +++ b/network/socket/socket.go @@ -6,8 +6,10 @@ import ( ) const ( - // UnidentifiedProcessID is originally defined in the process pkg, but duplicated here because of import loops. - UnidentifiedProcessID = -1 + // UndefinedProcessID signifies that the process ID is unknown. + // It must match portmaster/process.UndefinedProcessID + // It is duplicated here because of import loops. + UndefinedProcessID = -1 ) // ConnectionInfo holds socket information returned by the system. diff --git a/network/state/lookup.go b/network/state/lookup.go index 86bf76c1..6e2525f1 100644 --- a/network/state/lookup.go +++ b/network/state/lookup.go @@ -60,7 +60,7 @@ func Lookup(pktInfo *packet.Info, fast bool) (pid int, inbound bool, err error) return udp6Table.lookup(pktInfo, fast) default: - return socket.UnidentifiedProcessID, false, errors.New("unsupported protocol for finding process") + return socket.UndefinedProcessID, false, errors.New("unsupported protocol for finding process") } } @@ -108,7 +108,7 @@ func (table *tcpTable) lookup(pktInfo *packet.Info, fast bool) ( } } - return socket.UnidentifiedProcessID, pktInfo.Inbound, ErrConnectionNotFound + return socket.UndefinedProcessID, pktInfo.Inbound, ErrConnectionNotFound } func (table *tcpTable) findSocket(pktInfo *packet.Info) ( @@ -201,7 +201,7 @@ func (table *udpTable) lookup(pktInfo *packet.Info, fast bool) ( } } - return socket.UnidentifiedProcessID, pktInfo.Inbound, ErrConnectionNotFound + return socket.UndefinedProcessID, pktInfo.Inbound, ErrConnectionNotFound } func (table *udpTable) findSocket(pktInfo *packet.Info, isInboundMulticast bool) (socketInfo *socket.BindInfo) { diff --git a/network/state/system_linux.go b/network/state/system_linux.go index 9a0a41ab..abef01c1 100644 --- a/network/state/system_linux.go +++ b/network/state/system_linux.go @@ -18,7 +18,7 @@ func checkPID(socketInfo socket.Info, connInbound bool) (pid int, inbound bool, for i := 0; i <= lookupRetries; i++ { // look for PID pid = proc.GetPID(socketInfo) - if pid != socket.UnidentifiedProcessID { + if pid != socket.UndefinedProcessID { // if we found a PID, return break } diff --git a/process/find.go b/process/find.go index 832c17a7..c04599d7 100644 --- a/process/find.go +++ b/process/find.go @@ -31,6 +31,15 @@ func GetProcessByConnection(ctx context.Context, pktInfo *packet.Info) (process return nil, pktInfo.Inbound, err } + // Fallback to special profiles if PID could not be found. + if pid == UndefinedProcessID { + if connInbound { + pid = UnsolicitedProcessID + } else { + pid = UnidentifiedProcessID + } + } + process, err = GetOrFindProcess(ctx, pid) if err != nil { log.Tracer(ctx).Debugf("process: failed to find (primary) process with PID: %s", err) diff --git a/process/process.go b/process/process.go index 61a9f4fe..8bae2772 100644 --- a/process/process.go +++ b/process/process.go @@ -131,6 +131,8 @@ func loadProcess(ctx context.Context, pid int) (*Process, error) { switch pid { case UnidentifiedProcessID: return GetUnidentifiedProcess(ctx), nil + case UnsolicitedProcessID: + return GetUnsolicitedProcess(ctx), nil case SystemProcessID: return GetSystemProcess(ctx), nil } diff --git a/process/profile.go b/process/profile.go index d440756b..aed3fa90 100644 --- a/process/profile.go +++ b/process/profile.go @@ -34,6 +34,8 @@ func (p *Process) GetProfile(ctx context.Context) (changed bool, err error) { switch p.Pid { case UnidentifiedProcessID: profileID = profile.UnidentifiedProfileID + case UnsolicitedProcessID: + profileID = profile.UnsolicitedProfileID case SystemProcessID: profileID = profile.SystemProfileID case ownPID: diff --git a/process/special.go b/process/special.go index c22d5100..4b6a89e4 100644 --- a/process/special.go +++ b/process/special.go @@ -8,29 +8,43 @@ import ( "golang.org/x/sync/singleflight" "github.com/safing/portbase/log" + "github.com/safing/portmaster/profile" ) const ( - // UnidentifiedProcessID is the PID used for anything that could not be - // attributed to a PID for any reason. - UnidentifiedProcessID = -1 - // UndefinedProcessID is not used by any (virtual) process and signifies that // the PID is unset. - UndefinedProcessID = -2 + UndefinedProcessID = -1 + + // UnidentifiedProcessID is the PID used for outgoing connections that could + // not be attributed to a PID for any reason. + UnidentifiedProcessID = -2 + + // UnsolicitedProcessID is the PID used for incoming connections that could + // not be attributed to a PID for any reason. + UnsolicitedProcessID = -3 // NetworkHostProcessID is the PID used for requests served to the network. NetworkHostProcessID = -255 ) var ( - // unidentifiedProcess is used when a process cannot be found. + // unidentifiedProcess is used for non-attributed outgoing connections. unidentifiedProcess = &Process{ UserID: UnidentifiedProcessID, UserName: "Unknown", Pid: UnidentifiedProcessID, ParentPid: UnidentifiedProcessID, - Name: "Unidentified Processes", + Name: profile.UnidentifiedProfileName, + } + + // unsolicitedProcess is used for non-attributed incoming connections. + unsolicitedProcess = &Process{ + UserID: UnsolicitedProcessID, + UserName: "Unknown", + Pid: UnsolicitedProcessID, + ParentPid: UnsolicitedProcessID, + Name: profile.UnsolicitedProfileName, } // systemProcess is used to represent the Kernel. @@ -39,17 +53,22 @@ var ( UserName: "Kernel", Pid: SystemProcessID, ParentPid: SystemProcessID, - Name: "Operating System", + Name: profile.SystemProfileName, } getSpecialProcessSingleInflight singleflight.Group ) -// GetUnidentifiedProcess returns the special process assigned to unidentified processes. +// GetUnidentifiedProcess returns the special process assigned to non-attributed outgoing connections. func GetUnidentifiedProcess(ctx context.Context) *Process { return getSpecialProcess(ctx, unidentifiedProcess) } +// GetUnsolicitedProcess returns the special process assigned to non-attributed incoming connections. +func GetUnsolicitedProcess(ctx context.Context) *Process { + return getSpecialProcess(ctx, unsolicitedProcess) +} + // GetSystemProcess returns the special process used for the Kernel. func GetSystemProcess(ctx context.Context) *Process { return getSpecialProcess(ctx, systemProcess) diff --git a/profile/special.go b/profile/special.go index 58900afd..c89ac3b1 100644 --- a/profile/special.go +++ b/profile/special.go @@ -10,13 +10,26 @@ const ( // UnidentifiedProfileID is the profile ID used for unidentified processes. UnidentifiedProfileID = "_unidentified" // UnidentifiedProfileName is the name used for unidentified processes. - UnidentifiedProfileName = "Unidentified Processes" + UnidentifiedProfileName = "Unidentified App" // UnidentifiedProfileDescription is the description used for unidentified processes. - UnidentifiedProfileDescription = `This is not a real application, but a collection of connections that could not be attributed to a process. This could be because the Portmaster failed to identify the process, or simply because there is no process waiting for an incoming connection. + UnidentifiedProfileDescription = `Connections that could not be attributed to a specific app. -Seeing a lot of incoming connections here is normal, as this resembles the network chatter of other devices. +The Portmaster attributes connections (only TCP/UDP) to specific apps. When attribution for a connection fails, it ends up here. + +Connections from unsupported protocols (like ICMP/"ping") are always collected here. ` + // UnsolicitedProfileID is the profile ID used for unsolicited connections. + UnsolicitedProfileID = "_unsolicited" + // UnsolicitedProfileName is the name used for unsolicited connections. + UnsolicitedProfileName = "Network Noise" + // UnsolicitedProfileDescription is the description used for unsolicited connections. + UnsolicitedProfileDescription = `Common connections coming from your Local Area Network. + +Local Area Networks usually have quite a lot of traffic from applications that are trying to find things on the network. This might be a computer trying to find a printer, or a file sharing application searching for local peers. These network packets will automatically arrive at your device. + +These connections - the "network noise" - can be found in this app.` + // SystemProfileID is the profile ID used for the system/kernel. SystemProfileID = "_system" // SystemProfileName is the name used for the system/kernel. @@ -68,6 +81,9 @@ func updateSpecialProfileMetadata(profile *Profile, binaryPath string) (ok, chan case UnidentifiedProfileID: newProfileName = UnidentifiedProfileName newDescription = UnidentifiedProfileDescription + case UnsolicitedProfileID: + newProfileName = UnsolicitedProfileName + newDescription = UnsolicitedProfileDescription case SystemProfileID: newProfileName = SystemProfileName newDescription = SystemProfileDescription