mirror of https://github.com/subgraph/fw-daemon
Cached DNS name lookups now failover to global cache only populated by local resolver. Added proc-coroner module for detecting process deaths. procsnitch updated to handle multiple levels of "strictness" (necessary to lookup processes generating certain UDP data).shw_dev
parent
51c181a881
commit
c3635093fa
@ -0,0 +1,154 @@
|
||||
package pcoroner
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"strings"
|
||||
"strconv"
|
||||
"sync"
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
|
||||
type WatchProcess struct {
|
||||
Pid int
|
||||
Inode uint64
|
||||
Ppid int
|
||||
Stime int
|
||||
}
|
||||
|
||||
type procCB func(int, interface{})
|
||||
|
||||
|
||||
var pmutex = &sync.Mutex{}
|
||||
var pidMap map[int]WatchProcess = make(map[int]WatchProcess)
|
||||
|
||||
|
||||
func MonitorProcess(pid int) bool {
|
||||
pmutex.Lock()
|
||||
defer pmutex.Unlock()
|
||||
|
||||
_, ok := pidMap[pid]
|
||||
|
||||
if ok {
|
||||
return false
|
||||
}
|
||||
|
||||
watcher := WatchProcess{Pid: pid}
|
||||
watcher.Inode = 0
|
||||
res := checkProcess(&watcher, true)
|
||||
|
||||
if res {
|
||||
pidMap[pid] = watcher
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func UnmonitorProcess(pid int) {
|
||||
pmutex.Lock()
|
||||
defer pmutex.Unlock()
|
||||
delete(pidMap, pid)
|
||||
return
|
||||
}
|
||||
|
||||
func MonitorThread(cbfunc procCB, param interface{}) {
|
||||
for {
|
||||
/* if len(pidMap) == 0 {
|
||||
fmt.Println("TICK")
|
||||
} else { fmt.Println("len = ", len(pidMap)) } */
|
||||
pmutex.Lock()
|
||||
pmutex.Unlock()
|
||||
|
||||
for pkey, pval := range pidMap {
|
||||
// fmt.Printf("PID %v -> %v\n", pkey, pval)
|
||||
res := checkProcess(&pval, false)
|
||||
|
||||
if !res {
|
||||
delete(pidMap, pkey)
|
||||
|
||||
if cbfunc != nil {
|
||||
cbfunc(pkey, param)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
func checkProcess(proc *WatchProcess, init bool) bool {
|
||||
ppath := fmt.Sprintf("/proc/%d/stat", proc.Pid)
|
||||
f, err := os.Open(ppath)
|
||||
if err != nil {
|
||||
// fmt.Printf("Error opening path %s: %s\n", ppath, err)
|
||||
return false
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
fmt.Printf("Error calling stat on file %s: %s\n", ppath, err)
|
||||
return false
|
||||
}
|
||||
sb, ok := fi.Sys().(*syscall.Stat_t)
|
||||
if !ok {
|
||||
fmt.Println("Unexpected error reading stat information from proc file")
|
||||
} else if init {
|
||||
proc.Inode = sb.Ino
|
||||
} else {
|
||||
if sb.Ino != proc.Inode {
|
||||
fmt.Printf("/proc inode mismatch for process %d: %v vs %v\n", proc.Pid, sb.Ino, proc.Inode)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
var buf [512]byte
|
||||
nread, err := f.Read(buf[:])
|
||||
if err != nil {
|
||||
fmt.Printf("Error reading stat for process %d: %v", proc.Pid, err)
|
||||
return true
|
||||
} else if nread <= 0 {
|
||||
fmt.Printf("Unexpected error reading stat for process %d", proc.Pid)
|
||||
return true
|
||||
}
|
||||
|
||||
bstr := string(buf[:])
|
||||
// fmt.Println("sstr = ", bstr)
|
||||
|
||||
fields := strings.Split(bstr, " ")
|
||||
|
||||
if len(fields) < 22 {
|
||||
fmt.Printf("Unexpected error reading data from /proc stat for process %d", proc.Pid)
|
||||
return true
|
||||
}
|
||||
|
||||
ppid, err := strconv.Atoi(fields[3])
|
||||
if err != nil {
|
||||
ppid = -1
|
||||
}
|
||||
|
||||
if init {
|
||||
proc.Ppid = ppid
|
||||
} else if proc.Ppid != ppid {
|
||||
fmt.Printf("Cached process ppid did not match value in /proc: %v vs %v\n", proc.Ppid, ppid)
|
||||
return false
|
||||
}
|
||||
|
||||
stime, err := strconv.Atoi(fields[21])
|
||||
if err != nil {
|
||||
stime = -1
|
||||
}
|
||||
|
||||
if init {
|
||||
proc.Stime = stime
|
||||
} else if proc.Stime != stime {
|
||||
fmt.Printf("Cached process start time did not match value in /proc: %v vs %v\n", proc.Stime, stime)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
Loading…
Reference in new issue