Beispiel #1
0
func waitStart(pChan <-chan netfilter.NFPacket, chanId uint16, waitChan chan<- uint16, hostIp string) {
	for true {
		p := <-pChan

		port, err := portForPacket(p)
		if err != nil {
			fmt.Println(err)
			p.SetVerdict(netfilter.NF_ACCEPT)
			waitChan <- chanId
			continue
		}

		id, err := port.IdentifierFor()
		if err != nil {
			fmt.Println(err)
			p.SetVerdict(netfilter.NF_ACCEPT)
			waitChan <- chanId
			continue
		}

		cInfo, err := systemd.Connection().GetUnitProperties(id.UnitNameFor())
		if err != nil || cInfo["ActiveState"] != "active" {
			//TODO: Placeholder for container start detection
			fmt.Printf("[%v] Waiting for container %v to start\n", time.Now().Format(time.RFC3339), id)
			time.Sleep(time.Second * 5)
			fmt.Printf("[%v] Container %v started\n", time.Now().Format(time.RFC3339), id)

			iptables.UnidleContainer(id, hostIp)
		}

		p.SetVerdict(netfilter.NF_ACCEPT)
		waitChan <- chanId
	}
}
Beispiel #2
0
func (idler *Idler) Run() {
	for i := range idler.qh {
		if i >= 1 {
			go waitStart(idler.qh[i].GetPackets(), uint16(i), idler.waitChan, idler.hostIp)
		}
	}

	packets := idler.qh[0].GetPackets()
	ticker := time.NewTicker(idler.idleTimeout)
	events, errors := idler.eventListener.Run()

	for true {
		select {
		case e := <-events:
			fmt.Printf("[%v] Event: %v\n", time.Now().Format(time.RFC3339), e)
			switch {
			case e.Type == containers.Stopped || e.Type == containers.Deleted || e.Type == containers.Errored:
				iptables.DeleteContainer(e.Id, idler.hostIp)
			case e.Type == containers.Started:
				iptables.UnidleContainer(e.Id, idler.hostIp)
			case e.Type == containers.Idled:
				//No-op
			}
		case e := <-errors:
			fmt.Printf("Error: %v\n", e)
		case chanId := <-idler.waitChan:
			idler.openChannels[chanId] = ""
		case p := <-packets:
			port, err := portForPacket(p)
			if err != nil {
				fmt.Println(err)
				p.SetVerdict(netfilter.NF_ACCEPT)
				continue
			}

			id, err := port.IdentifierFor()
			if err != nil {
				fmt.Println(err)
				iptables.CleanupRulesForPort(port)
				p.SetVerdict(netfilter.NF_ACCEPT)
				continue
			}

			idler.unidleContainer(id, p)
		case <-ticker.C:
			cpkt, err := iptables.GetDockerContainerPacketCounts(idler.d)
			if err != nil {
				fmt.Printf("Error retrieving packet counts for containers: %v\n", err)
			}

			var packetData bytes.Buffer
			w := new(tabwriter.Writer)
			w.Init(&packetData, 0, 8, 0, '\t', 0)

			fmt.Fprintf(w, "[%v] Packet counts:\n\tContainer\tActive?\tIdled?\tPackets\n", time.Now().Format(time.RFC3339))
			iptables.ResetPacketCount()
			for id, pkts := range cpkt {
				started, err := id.UnitStartOnBoot()
				if err != nil {
					fmt.Printf("Error reading container state for %v: %v\n", id, err)
				}

				var idleFlag bool
				_, err = os.Stat(id.IdleUnitPathFor())
				if err == nil {
					idleFlag = true
				}

				fmt.Fprintf(w, "\t%v\t%v\t%v\t%v", id, started, idleFlag, pkts)
				if started && pkts == 0 {
					if idler.idleContainer(id) {
						fmt.Fprintf(w, "\tidling...")
					}
				}
				fmt.Fprintf(w, "\n")
			}
			w.Flush()
			packetData.WriteTo(os.Stdout)
			fmt.Println("\n")
		}
	}
}