Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make mutexes private #890

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
38 changes: 19 additions & 19 deletions daemon/firewall/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ type (
callbackBool func() bool

stopChecker struct {
ch chan bool
sync.RWMutex
ch chan bool
rwm sync.RWMutex
}

// Common holds common fields and functionality of both firewalls,
Expand All @@ -36,19 +36,19 @@ type (
Running bool
Intercepting bool
FwEnabled bool
sync.RWMutex
rwm sync.RWMutex
}
)

func (s *stopChecker) exit() <-chan bool {
s.RLock()
defer s.RUnlock()
s.rwm.RLock()
defer s.rwm.RUnlock()
return s.ch
}

func (s *stopChecker) stop() {
s.Lock()
defer s.Unlock()
s.rwm.Lock()
defer s.rwm.Unlock()

if s.ch != nil {
s.ch <- true
Expand All @@ -60,8 +60,8 @@ func (s *stopChecker) stop() {
// SetQueueNum sets the queue number used by the firewall.
// It's the queue where all intercepted connections will be sent.
func (c *Common) SetQueueNum(qNum *int) {
c.Lock()
defer c.Unlock()
c.rwm.Lock()
defer c.rwm.Unlock()

if qNum != nil {
c.QueueNum = uint16(*qNum)
Expand All @@ -71,24 +71,24 @@ func (c *Common) SetQueueNum(qNum *int) {

// IsRunning returns if the firewall is running or not.
func (c *Common) IsRunning() bool {
c.RLock()
defer c.RUnlock()
c.rwm.RLock()
defer c.rwm.RUnlock()

return c != nil && c.Running
}

// IsFirewallEnabled returns if the firewall is running or not.
func (c *Common) IsFirewallEnabled() bool {
c.RLock()
defer c.RUnlock()
c.rwm.RLock()
defer c.rwm.RUnlock()

return c != nil && c.FwEnabled
}

// IsIntercepting returns if the firewall is running or not.
func (c *Common) IsIntercepting() bool {
c.RLock()
defer c.RUnlock()
c.rwm.RLock()
defer c.rwm.RUnlock()

return c != nil && c.Intercepting
}
Expand All @@ -97,8 +97,8 @@ func (c *Common) IsIntercepting() bool {
// We expect to have 2 rules loaded: one to intercept DNS responses and another one
// to intercept network traffic.
func (c *Common) NewRulesChecker(areRulesLoaded callbackBool, reloadRules callback) {
c.Lock()
defer c.Unlock()
c.rwm.Lock()
defer c.rwm.Unlock()
if c.stopCheckerChan != nil {
c.stopCheckerChan.stop()
c.stopCheckerChan = nil
Expand Down Expand Up @@ -130,8 +130,8 @@ Exit:

// StopCheckingRules stops checking if firewall rules are loaded.
func (c *Common) StopCheckingRules() {
c.RLock()
defer c.RUnlock()
c.rwm.RLock()
defer c.rwm.RUnlock()

if c.RulesChecker != nil {
c.RulesChecker.Stop()
Expand Down
86 changes: 48 additions & 38 deletions daemon/firewall/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
// The firewall rules defined by the user are reloaded in these cases:
// - When the file system-fw.json changes.
// - When the firewall rules are not present when listing them.
//
package config

import (
Expand All @@ -20,30 +19,33 @@ import (
// ExprValues holds the statements' options:
// "Name": "ct",
// "Values": [
// {
// "Key": "state",
// "Value": "established"
// },
// {
// "Key": "state",
// "Value": "related"
// }]
//
// {
// "Key": "state",
// "Value": "established"
// },
//
// {
// "Key": "state",
// "Value": "related"
// }]
type ExprValues struct {
Key string
Value string
}

// ExprStatement holds the definition of matches to use against connections.
//{
// "Op": "!=",
// "Name": "tcp",
// "Values": [
// {
// "Key": "dport",
// "Value": "443"
// }
// ]
//}
//
// {
// "Op": "!=",
// "Name": "tcp",
// "Values": [
// {
// "Key": "dport",
// "Value": "443"
// }
// ]
// }
type ExprStatement struct {
Op string // ==, !=, ... Only one per expression set.
Name string // tcp, udp, ct, daddr, log, ...
Expand All @@ -60,7 +62,7 @@ type FwRule struct {
// we need to keep old fields in the struct. Otherwise when receiving a conf from the GUI, the legacy rules would be deleted.
Chain string // TODO: deprecated, remove
Table string // TODO: deprecated, remove
Parameters string // TODO: deprecated: remove
Parameters string // TODO: deprecated, remove

UUID string
Description string
Expand All @@ -70,8 +72,6 @@ type FwRule struct {

Position uint64 `json:",string"`
Enabled bool

*sync.RWMutex
}

// FwChain holds the information that defines a firewall chain.
Expand All @@ -95,18 +95,14 @@ func (fc *FwChain) IsInvalid() bool {
return fc.Name == "" || fc.Family == "" || fc.Table == ""
}

type rulesList struct {
Rule *FwRule
}

type chainsList struct {
Chains []*FwChain
Rule *FwRule // TODO: deprecated, remove
}

// SystemConfig holds the list of rules to be added to the system
type SystemConfig struct {
sync.RWMutex
rwm sync.RWMutex
SystemRules []*chainsList
Version uint32
Enabled bool
Expand All @@ -115,7 +111,7 @@ type SystemConfig struct {
// Config holds the functionality to re/load the firewall configuration from disk.
// This is the configuration to manage the system firewall (iptables, nftables).
type Config struct {
sync.Mutex
mu sync.Mutex
file string
watcher *fsnotify.Watcher
monitorExitChan chan bool
Expand All @@ -129,6 +125,20 @@ type Config struct {
// preload will be called after daemon startup, whilst reload when a modification is performed.
}

// GetSystemRules and SetSystemRules are used to internally lock/unlock the SystemConfig's mutex
func (sc *SystemConfig) GetSystemRules() []*chainsList {
sc.rwm.RLock()
defer sc.rwm.RUnlock()
return sc.SystemRules
}

// GetSystemRules and SetSystemRules are used to internally lock/unlock the SystemConfig's mutex
func (sc *SystemConfig) SetSystemRules(rules []*chainsList) {
sc.rwm.Lock()
defer sc.rwm.Unlock()
sc.SystemRules = rules
}

// NewSystemFwConfig initializes config fields
func (c *Config) NewSystemFwConfig(preLoadCb, reLoadCb func()) (*Config, error) {
var err error
Expand All @@ -138,8 +148,8 @@ func (c *Config) NewSystemFwConfig(preLoadCb, reLoadCb func()) (*Config, error)
return nil, err
}

c.Lock()
defer c.Unlock()
c.mu.Lock()
defer c.mu.Unlock()

c.file = "/etc/opensnitchd/system-fw.json"
c.monitorExitChan = make(chan bool, 1)
Expand All @@ -151,8 +161,8 @@ func (c *Config) NewSystemFwConfig(preLoadCb, reLoadCb func()) (*Config, error)

// LoadDiskConfiguration reads and loads the firewall configuration from disk
func (c *Config) LoadDiskConfiguration(reload bool) {
c.Lock()
defer c.Unlock()
c.mu.Lock()
defer c.mu.Unlock()

raw, err := ioutil.ReadFile(c.file)
if err != nil {
Expand Down Expand Up @@ -180,8 +190,8 @@ func (c *Config) LoadDiskConfiguration(reload bool) {
// loadConfigutation reads the system firewall rules from disk.
// Then the rules are added based on the configuration defined.
func (c *Config) loadConfiguration(rawConfig []byte) {
c.SysConfig.Lock()
defer c.SysConfig.Unlock()
c.SysConfig.rwm.Lock()
defer c.SysConfig.rwm.Unlock()

// delete old system rules, that may be different from the new ones
c.preloadCallback()
Expand Down Expand Up @@ -213,8 +223,8 @@ func (c *Config) SaveConfiguration(rawConfig string) error {

// StopConfigWatcher stops the configuration watcher and stops the subroutine.
func (c *Config) StopConfigWatcher() {
c.Lock()
defer c.Unlock()
c.mu.Lock()
defer c.mu.Unlock()

if c.monitorExitChan != nil {
c.monitorExitChan <- true
Expand All @@ -240,7 +250,7 @@ func (c *Config) monitorConfigWorker() {
}
Exit:
log.Debug("stop monitoring firewall config file")
c.Lock()
c.mu.Lock()
c.monitorExitChan = nil
c.Unlock()
c.mu.Unlock()
}
5 changes: 2 additions & 3 deletions daemon/firewall/iptables/iptables.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ type SystemRule struct {
// SystemChains keeps track of the fw rules that have been added to the system.
type SystemChains struct {
Rules map[string]*SystemRule
sync.RWMutex
rwm sync.RWMutex
}

// Iptables struct holds the fields of the iptables fw
Expand All @@ -64,8 +64,7 @@ type Iptables struct {
regexSystemRulesQuery *regexp.Regexp

chains SystemChains

sync.Mutex
mu sync.Mutex
}

// Fw initializes a new Iptables object
Expand Down
4 changes: 2 additions & 2 deletions daemon/firewall/iptables/monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (ipt *Iptables) AreRulesLoaded() bool {
}

systemRulesLoaded := true
ipt.chains.RLock()
ipt.chains.rwm.RLock()
if len(ipt.chains.Rules) > 0 {
for _, rule := range ipt.chains.Rules {
if chainOut4, err4 := core.Exec("iptables", []string{"-n", "-L", rule.Chain, "-t", rule.Table}); err4 == nil {
Expand All @@ -42,7 +42,7 @@ func (ipt *Iptables) AreRulesLoaded() bool {
}
}
}
ipt.chains.RUnlock()
ipt.chains.rwm.RUnlock()

result := ipt.regexRulesQuery.FindString(outMangle) != "" &&
systemRulesLoaded
Expand Down
4 changes: 2 additions & 2 deletions daemon/firewall/iptables/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ func (ipt *Iptables) RunRule(action Action, enable bool, logError bool, rule []s

rule = append([]string{string(action)}, rule...)

ipt.Lock()
defer ipt.Unlock()
ipt.mu.Lock()
defer ipt.mu.Unlock()

if _, err4 = core.Exec(ipt.bin, rule); err4 != nil {
if logError {
Expand Down
12 changes: 6 additions & 6 deletions daemon/firewall/iptables/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (

// CreateSystemRule creates the custom firewall chains and adds them to the system.
func (ipt *Iptables) CreateSystemRule(rule *config.FwRule, table, chain, hook string, logErrors bool) bool {
ipt.chains.Lock()
defer ipt.chains.Unlock()
ipt.chains.rwm.Lock()
defer ipt.chains.rwm.Unlock()
if rule == nil {
return false
}
Expand Down Expand Up @@ -67,8 +67,8 @@ func (ipt *Iptables) AddSystemRules(reload, backupExistingChains bool) {
// If force is false and the rule has not been previously added,
// it won't try to delete the rules. Otherwise it'll try to delete them.
func (ipt *Iptables) DeleteSystemRules(force, backupExistingChains, logErrors bool) {
ipt.chains.Lock()
defer ipt.chains.Unlock()
ipt.chains.rwm.Lock()
defer ipt.chains.rwm.Unlock()

for _, fwCfg := range ipt.SysConfig.SystemRules {
if fwCfg.Rule == nil {
Expand Down Expand Up @@ -124,8 +124,8 @@ func (ipt *Iptables) AddSystemRule(action Action, rule *config.FwRule, table, ch
if rule == nil {
return nil, nil
}
ipt.RLock()
defer ipt.RUnlock()
ipt.chains.rwm.RLock()
defer ipt.chains.rwm.RUnlock()

chainName := SystemRulePrefix + "-" + chain
if table == "" {
Expand Down
4 changes: 2 additions & 2 deletions daemon/firewall/nftables/monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (

// AreRulesLoaded checks if the firewall rules for intercept traffic are loaded.
func (n *Nft) AreRulesLoaded() bool {
n.Lock()
defer n.Unlock()
n.mu.Lock()
defer n.mu.Unlock()

nRules := 0
chains, err := n.conn.ListChains()
Expand Down
2 changes: 1 addition & 1 deletion daemon/firewall/nftables/nftables.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ var (

// Nft holds the fields of our nftables firewall
type Nft struct {
sync.Mutex
mu sync.Mutex
config.Config
common.Common

Expand Down
Loading