ce7cb702218693d08ea6d83464d2457c9250027c
This commit is contained in:
commit
34c5f8963c
1 changed files with 145336 additions and 0 deletions
150
services/short/tunnel/vici.go
Normal file
150
services/short/tunnel/vici.go
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
package tunnel
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/strongswan/govici/vici"
|
||||
"quorate.dev/services/short/config"
|
||||
)
|
||||
|
||||
type auth struct {
|
||||
Method string `vici:"auth"`
|
||||
ID string `vici:"id"`
|
||||
}
|
||||
type child struct {
|
||||
Local []string `vici:"local_ts"`
|
||||
Remote []string `vici:"remote_ts"`
|
||||
Proposals []string `vici:"esp_proposals"`
|
||||
In string `vici:"if_id_in"`
|
||||
Out string `vici:"if_id_out"`
|
||||
Rekey string `vici:"rekey_time"`
|
||||
DPD string `vici:"dpd_action"`
|
||||
}
|
||||
type connection struct {
|
||||
Version string `vici:"version"`
|
||||
Remote []string `vici:"remote_addrs"`
|
||||
Proposals []string `vici:"proposals"`
|
||||
Local auth `vici:"local"`
|
||||
Peer auth `vici:"remote"`
|
||||
Children map[string]child `vici:"children"`
|
||||
Encap string `vici:"encap"`
|
||||
Mobike string `vici:"mobike"`
|
||||
DPD string `vici:"dpd_delay"`
|
||||
Rekey string `vici:"rekey_time"`
|
||||
}
|
||||
type shared struct {
|
||||
ID string `vici:"id"`
|
||||
Type string `vici:"type"`
|
||||
Data string `vici:"data"`
|
||||
Owners []string `vici:"owners"`
|
||||
}
|
||||
|
||||
func dial() (*vici.Session, error) {
|
||||
return vici.NewSession(vici.WithDialContext(func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
conn, err := (&net.Dialer{Timeout: 2 * time.Second}).DialContext(ctx, network, address)
|
||||
if err == nil {
|
||||
err = conn.SetDeadline(time.Now().Add(5 * time.Second))
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
}
|
||||
}
|
||||
return conn, err
|
||||
}))
|
||||
}
|
||||
|
||||
func settings(wan string, p config.Peer, index int) connection {
|
||||
id := strconv.Itoa(42 + index)
|
||||
return connection{
|
||||
Version: "2", Remote: []string{p.Address}, Proposals: []string{"aes256-sha256-modp2048"},
|
||||
Local: auth{Method: "psk", ID: wan}, Peer: auth{Method: "psk", ID: p.Address}, Encap: "yes", Mobike: "no", DPD: "10s", Rekey: "7h",
|
||||
Children: map[string]child{peerName(index): {Local: []string{"0.0.0.0/0"}, Remote: []string{"0.0.0.0/0"}, Proposals: []string{"aes256gcm16-modp2048"}, In: id, Out: id, Rekey: "50m", DPD: "restart"}},
|
||||
}
|
||||
}
|
||||
|
||||
func peerName(index int) string { return fmt.Sprintf("short%d", index) }
|
||||
|
||||
func load(wan string, p config.Peer, index int) error {
|
||||
s, err := dial()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer s.Close()
|
||||
m, err := vici.MarshalMessage(shared{ID: peerName(index), Type: "IKE", Data: p.Secret, Owners: []string{wan, p.Address}})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = s.CommandRequest("load-shared", m); err != nil {
|
||||
return err
|
||||
}
|
||||
m, err = vici.MarshalMessage(map[string]connection{peerName(index): settings(wan, p, index)})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = s.CommandRequest("load-conn", m)
|
||||
return err
|
||||
}
|
||||
|
||||
func initiate(index int) error {
|
||||
s, err := dial()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer s.Close()
|
||||
m := vici.NewMessage()
|
||||
m.Set("child", peerName(index))
|
||||
m.Set("timeout", "-1")
|
||||
_, err = s.CommandRequest("initiate", m)
|
||||
return err
|
||||
}
|
||||
|
||||
func installed() ([]bool, error) {
|
||||
s, err := dial()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer s.Close()
|
||||
messages, err := s.StreamedCommandRequest("list-sas", "list-sa", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return livePeers(messages), nil
|
||||
}
|
||||
|
||||
func livePeers(messages []*vici.Message) []bool {
|
||||
up := make([]bool, 2)
|
||||
for _, m := range messages {
|
||||
for index := range up {
|
||||
conn, ok := m.Get(peerName(index)).(*vici.Message)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if conn.Get("state") != "ESTABLISHED" {
|
||||
continue
|
||||
}
|
||||
children, ok := conn.Get("child-sas").(*vici.Message)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
for _, name := range children.Keys() {
|
||||
c, ok := children.Get(name).(*vici.Message)
|
||||
if ok && c.Get("state") == "INSTALLED" {
|
||||
up[index] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return up
|
||||
}
|
||||
|
||||
func returnPeer(up []bool) int {
|
||||
for index, live := range up {
|
||||
if live {
|
||||
return index
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
Loading…
Reference in a new issue