openvpn-mgt/openvpn.go

114 lines
2.0 KiB
Go

package main
import (
"bufio"
"fmt"
"net"
"sync"
)
type OpenVpnSrv struct {
Remote string `json:"active-vpn"`
Status string `json:"status"`
hold bool
chanHold chan bool
m sync.RWMutex
ret chan []string
buf *bufio.ReadWriter
}
func (s *OpenVpnSrv) Lock() {
s.m.Lock()
}
func (s *OpenVpnSrv) Unlock() {
s.m.Unlock()
}
func NewOpenVpnSrv(conn net.Conn) *OpenVpnSrv {
return &OpenVpnSrv{
buf: bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn)),
hold: false,
chanHold: make(chan bool),
ret: make(chan []string),
}
}
// send a command to the server. Set the channel to receive the response
func (s *OpenVpnSrv) sendCommand(msg []string) (error, []string) {
for _, line := range msg {
if _, err := s.buf.WriteString(line + "\r\n"); err != nil {
return err, nil
}
}
if err := s.buf.Flush(); err != nil {
return err, nil
}
// wait for the response
ret := <-s.ret
return nil, ret
}
func (s *OpenVpnSrv) Response(response []string) {
s.Lock()
s.ret <- response
s.Unlock()
}
func (s *OpenVpnSrv) GetLine() (string, error) {
return s.buf.ReadString('\n')
}
func (s *OpenVpnSrv) ValidRemote(server, port, proto string) {
if s.Remote != "" {
s.sendCommand([]string{fmt.Sprintf("remote MOD %s %s %s", s.Remote, port, proto)})
s.Status = "Connected"
return
}
s.Remote = server
s.sendCommand([]string{"remote ACCEPT"})
}
func (s *OpenVpnSrv) Kill() {
}
func (s *OpenVpnSrv) Version() (error, []string) {
return s.sendCommand([]string{"version"})
}
func (s *OpenVpnSrv) SetRemote(server string) error {
// already the active server, do nothing
if s.Remote == server {
return nil
}
if s.Remote != "" {
s.Kill()
}
s.Remote = server
// release Hold if necessary
s.ReleaseHold()
return nil
}
func (s *OpenVpnSrv) waitForRelase() {
s.hold = true
s.Status = "Hold"
<-s.chanHold
s.sendCommand([]string{"hold release"})
}
func (s *OpenVpnSrv) ReleaseHold() {
if !s.hold {
return
}
s.hold = false
s.chanHold <- true
s.Status = "Waiting for connexion"
}