X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=src%2Fcypherpunks.ru%2Fgovpn%2Fcommon.go;h=67774b1d3ccbaab4ee27548451a269e9fb26eadc;hb=b46602d3396ec3beb4a66002dfc8dafd87f541c8;hp=56b0f696527231738a49f1eae7f15988327f76fa;hpb=1872444c2bc15cd9af8b8819080165159f688800;p=govpn.git diff --git a/src/cypherpunks.ru/govpn/common.go b/src/cypherpunks.ru/govpn/common.go index 56b0f69..67774b1 100644 --- a/src/cypherpunks.ru/govpn/common.go +++ b/src/cypherpunks.ru/govpn/common.go @@ -19,15 +19,24 @@ along with this program. If not, see . package govpn import ( - "log" - "os" - "os/exec" + "encoding/hex" + "encoding/json" "runtime" + "strings" + "time" + + "github.com/pkg/errors" ) const ( - TimeoutDefault = 60 - EtherSize = 14 + // ProtocolUDP is UDP transport protocol + ProtocolUDP Protocol = iota + // ProtocolTCP is TCP transport protocol + ProtocolTCP + // ProtocolALL is TCP+UDP transport protocol + ProtocolALL + + EtherSize = 14 // MTUMax is maximum MTU size of Ethernet packet MTUMax = 9000 + EtherSize + 1 // MTUDefault is default MTU size of Ethernet packet @@ -35,35 +44,92 @@ const ( ENV_IFACE = "GOVPN_IFACE" ENV_REMOTE = "GOVPN_REMOTE" + + wrapNewProtocolFromString = "NewProtocolFromString" ) var ( // Version holds release string set at build time - Version string + Version string + protocolText = map[Protocol]string{ + ProtocolUDP: "udp", + ProtocolTCP: "tcp", + ProtocolALL: "all", + } + // TimeoutDefault is default timeout value for various network operations + TimeoutDefault = 60 * time.Second ) -// ScriptCall calls external program/script. -// You have to specify path to it and (inteface name as a rule) something -// that will be the first argument when calling it. Function will return -// it's output and possible error. -func ScriptCall(path, ifaceName, remoteAddr string) ([]byte, error) { - if path == "" { - return nil, nil +// Protocol is a GoVPN supported protocol: either UDP, TCP or both +type Protocol int + +// String converts a Protocol into a string +func (p Protocol) String() string { + return protocolText[p] +} + +// MarshalJSON returns a JSON string from a protocol +func (p Protocol) MarshalJSON() ([]byte, error) { + str := p.String() + output, err := json.Marshal(&str) + return output, errors.Wrap(err, "json.Marshal") +} + +// UnmarshalJSON converts a JSON string into a Protocol +func (p *Protocol) UnmarshalJSON(encoded []byte) error { + var str string + if err := json.Unmarshal(encoded, &str); err != nil { + return errors.Wrapf(err, "Can't unmarshall to string %q", hex.EncodeToString(encoded)) } - if _, err := os.Stat(path); err != nil && os.IsNotExist(err) { - return nil, err + proto, err := NewProtocolFromString(str) + if err != nil { + return errors.Wrap(err, wrapNewProtocolFromString) } - cmd := exec.Command(path) - cmd.Env = append(cmd.Env, ENV_IFACE+"="+ifaceName) - cmd.Env = append(cmd.Env, ENV_REMOTE+"="+remoteAddr) - out, err := cmd.CombinedOutput() + *p = proto + return nil +} + +// UnmarshalYAML converts a YAML string into a Protocol +func (p *Protocol) UnmarshalYAML(unmarshal func(interface{}) error) error { + var str string + err := unmarshal(&str) if err != nil { - log.Println("Script error", path, err, string(out)) + return errors.Wrap(err, "unmarshall") + } + + proto, err := NewProtocolFromString(str) + if err != nil { + return errors.Wrap(err, wrapNewProtocolFromString) + } + *p = proto + return nil +} + +// NewProtocolFromString converts a string into a govpn.Protocol +func NewProtocolFromString(p string) (Protocol, error) { + lowP := strings.ToLower(p) + for k, v := range protocolText { + if strings.ToLower(v) == lowP { + return k, nil + } } - return out, err + + choices := make([]string, len(protocolText)) + var index = 0 + for k, v := range protocolText { + if v == p { + z := k + p = &z + return nil + } + choices[index] = v + index++ + } + + return Protocol(-1), errors.Errorf("Invalid protocol %q: %s", p, strings.Join(choices, ",")) } -// Zero each byte. +// SliceZero zeros each byte. func SliceZero(data []byte) { for i := 0; i < len(data); i++ { data[i] = 0