Newer
Older
package backend
import (
"bytes"
"encoding/json"
"log"
"0xacab.org/leap/bitmask-vpn/pkg/bitmask"
"0xacab.org/leap/bitmask-vpn/pkg/config"
)
const (
offStr = "off"
startingStr = "starting"
onStr = "on"
stoppingStr = "stopping"
failedStr = "failed"
)
// ctx will be our glorious global object.
// if we ever switch again to a provider-agnostic app, we should keep a map here.
var ctx *connectionCtx
// The connectionCtx keeps the global state that is passed around to C-land. It
// also serves as the primary way of passing requests from the frontend to the
// Go-core, by letting the UI write some of these variables and processing
// them.
type connectionCtx struct {
AppName string `json:"appName"`
Provider string `json:"provider"`
AskForDonations bool `json:"askForDonations"`
DonateDialog bool `json:"donateDialog"`
DonateURL string `json:"donateURL"`
Status status `json:"status"`
bm bitmask.Bitmask
cfg *config.Config
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
}
func (c connectionCtx) toJson() ([]byte, error) {
stmut.Lock()
defer stmut.Unlock()
b, err := json.Marshal(c)
if err != nil {
log.Println(err)
return nil, err
}
return b, nil
}
func (c connectionCtx) updateStatus() {
if stStr, err := c.bm.GetStatus(); err != nil {
log.Printf("Error getting status: %v", err)
} else {
setStatusFromStr(stStr)
}
statusCh := c.bm.GetStatusCh()
for {
select {
case stStr := <-statusCh:
setStatusFromStr(stStr)
}
}
}
func setStatus(st status) {
stmut.Lock()
defer stmut.Unlock()
ctx.Status = st
go trigger(OnStatusChanged)
}
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// the status type reflects the current VPN status. Go code is responsible for updating
// it; the C gui just watches its changes and pulls its updates via the serialized
// context object.
type status int
const (
off status = iota
starting
on
stopping
failed
unknown
)
func (s status) String() string {
return [...]string{offStr, startingStr, onStr, stoppingStr, failedStr}[s]
}
func (s status) MarshalJSON() ([]byte, error) {
b := bytes.NewBufferString(`"`)
b.WriteString(s.String())
b.WriteString(`"`)
return b.Bytes(), nil
}
func (s status) fromString(st string) status {
switch st {
case offStr:
return off
case startingStr:
return starting
case onStr:
return on
case stoppingStr:
return stopping
case failedStr:
return failed
default:
return unknown
}
}
func setStatusFromStr(stStr string) {
setStatus(unknown.fromString(stStr))
}