|
|
@@ -92,6 +92,18 @@ type ActiveConnection struct {
|
|
|
dmParser *l7.DmParser
|
|
|
}
|
|
|
|
|
|
+type ActiveAccept struct {
|
|
|
+ Dest netaddr.IPPort
|
|
|
+ ActualDest netaddr.IPPort
|
|
|
+ Pid uint32
|
|
|
+ Fd uint64
|
|
|
+ Timestamp uint64
|
|
|
+ Closed time.Time
|
|
|
+
|
|
|
+ BytesSent uint64
|
|
|
+ BytesReceived uint64
|
|
|
+}
|
|
|
+
|
|
|
type ListenDetails struct {
|
|
|
ClosedAt time.Time
|
|
|
NsIPs []netaddr.IP
|
|
|
@@ -118,6 +130,11 @@ type ConnectionStats struct {
|
|
|
BytesReceived uint64
|
|
|
}
|
|
|
|
|
|
+type AcceptStats struct {
|
|
|
+ BytesSent uint64
|
|
|
+ BytesReceived uint64
|
|
|
+}
|
|
|
+
|
|
|
type Container struct {
|
|
|
id ContainerID
|
|
|
cgroup *cgroup.Cgroup
|
|
|
@@ -142,6 +159,11 @@ type Container struct {
|
|
|
connectLastAttempt map[netaddr.IPPort]time.Time // dst -> time
|
|
|
connectionsActive map[AddrPair]*ActiveConnection
|
|
|
connectionsByPidFd map[PidFd]*ActiveConnection
|
|
|
+
|
|
|
+ acceptsSuccessful map[AddrPair]*AcceptStats
|
|
|
+ acceptLastAttempt map[netaddr.IPPort]time.Time // dst -> time
|
|
|
+ acceptsActive map[AddrPair]*ActiveAccept
|
|
|
+ acceptsByPidFd map[PidFd]*ActiveAccept
|
|
|
|
|
|
l7Stats L7Stats
|
|
|
dnsStats *L7Metrics
|
|
|
@@ -198,6 +220,11 @@ func NewContainer(id ContainerID, cg *cgroup.Cgroup, md *ContainerMetadata, host
|
|
|
connectLastAttempt: map[netaddr.IPPort]time.Time{},
|
|
|
connectionsActive: map[AddrPair]*ActiveConnection{},
|
|
|
connectionsByPidFd: map[PidFd]*ActiveConnection{},
|
|
|
+ acceptsSuccessful: map[AddrPair]*AcceptStats{},
|
|
|
+ acceptLastAttempt: map[netaddr.IPPort]time.Time{},
|
|
|
+ acceptsActive: map[AddrPair]*ActiveAccept{},
|
|
|
+ acceptsByPidFd: map[PidFd]*ActiveAccept{},
|
|
|
+
|
|
|
l7Stats: L7Stats{},
|
|
|
dnsStats: &L7Metrics{},
|
|
|
|
|
|
@@ -341,6 +368,12 @@ func (c *Container) Collect(ch chan<- prometheus.Metric) {
|
|
|
ch <- counter(metrics.NetBytesSent, float64(stats.BytesSent), d.src.String(), d.dst.String())
|
|
|
ch <- counter(metrics.NetBytesReceived, float64(stats.BytesReceived), d.src.String(), d.dst.String())
|
|
|
}
|
|
|
+
|
|
|
+ for d, stats := range c.acceptsSuccessful {
|
|
|
+ ch <- counter(metrics.NetAcceptsSuccessful, float64(0), d.src.String(), d.dst.String())
|
|
|
+ ch <- counter(metrics.NetBytesSent, float64(stats.BytesSent), d.src.String(), d.dst.String())
|
|
|
+ ch <- counter(metrics.NetBytesReceived, float64(stats.BytesReceived), d.src.String(), d.dst.String())
|
|
|
+ }
|
|
|
for dst, count := range c.connectsFailed {
|
|
|
ch <- counter(metrics.NetConnectionsFailed, float64(count), dst.String())
|
|
|
}
|
|
|
@@ -548,6 +581,56 @@ func (c *Container) onListenClose(pid uint32, addr netaddr.IPPort) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+func (c *Container) onAcceptOpen(pid uint32, fd uint64, src, dst netaddr.IPPort, timestamp uint64, failed bool, duration time.Duration) {
|
|
|
+ klog.Infof("accept pid=%d id=%s addr=%s", pid, c.id, dst.IP())
|
|
|
+ if common.PortFilter.ShouldBeSkipped(dst.Port()) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ p := c.processes[pid]
|
|
|
+ if p == nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if dst.IP().IsLoopback() && !p.isHostNs() {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ actualDst, err := c.getActualDestination(p, src, dst)
|
|
|
+ if err != nil {
|
|
|
+ if !common.IsNotExist(err) {
|
|
|
+ klog.Warningf("cannot open NetNs for pid %d: %s", pid, err)
|
|
|
+ }
|
|
|
+ return
|
|
|
+ }
|
|
|
+ switch {
|
|
|
+ case actualDst == nil:
|
|
|
+ actualDst = &dst
|
|
|
+ case actualDst.IP().IsLoopback() && !p.isHostNs():
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if common.ConnectionFilter.ShouldBeSkipped(dst.IP(), actualDst.IP()) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ c.lock.Lock()
|
|
|
+ defer c.lock.Unlock()
|
|
|
+ if !failed {
|
|
|
+ key := AddrPair{src: dst, dst: *actualDst}
|
|
|
+ stats := c.acceptsSuccessful[key]
|
|
|
+ if stats == nil {
|
|
|
+ stats = &AcceptStats{}
|
|
|
+ c.acceptsSuccessful[key] = stats
|
|
|
+ }
|
|
|
+ acceptCon := &ActiveAccept{
|
|
|
+ Dest: dst,
|
|
|
+ ActualDest: *actualDst,
|
|
|
+ Pid: pid,
|
|
|
+ Fd: fd,
|
|
|
+ Timestamp: timestamp,
|
|
|
+ }
|
|
|
+ c.acceptsActive[AddrPair{src: src, dst: dst}] = acceptCon
|
|
|
+ c.acceptsByPidFd[PidFd{Pid: pid, Fd: fd}] = acceptCon
|
|
|
+ }
|
|
|
+ c.acceptLastAttempt[dst] = time.Now()
|
|
|
+}
|
|
|
+
|
|
|
func (c *Container) onConnectionOpen(pid uint32, fd uint64, src, dst netaddr.IPPort, timestamp uint64, failed bool, duration time.Duration) {
|
|
|
if common.PortFilter.ShouldBeSkipped(dst.Port()) {
|
|
|
return
|