diff options
Diffstat (limited to 'tinc.go')
-rw-r--r-- | tinc.go | 125 |
1 files changed, 125 insertions, 0 deletions
@@ -0,0 +1,125 @@ +package main + +import ( + "bufio" + "fmt" + "net" + "os" + "strings" +) + +type Error struct { + File string + Line int + Err error +} + +func (e Error) Error() string { + if e.Line > 0 { + return fmt.Sprintf("%v:%v: %v", e.File, e.Line, e.Err) + } else { + return fmt.Sprintf("%v: %v", e.File, e.Err) + } +} + +func parseConfigLine(line string) (key, val string) { + line = strings.TrimRight(line, "\t ") + keylen := strings.IndexAny(line, "\t =") + if keylen < 0 { + keylen = len(line) + } + + variable := line[:keylen] + + value := strings.TrimLeft(line[keylen:], "\t ") + if strings.HasPrefix(value, "=") { + value = strings.TrimLeft(value[1:], "\t ") + } + + return variable, value +} + +func readConfigFile(fname string) (map[string][]string, error) { + config_tree := make(map[string][]string) + + fp, err := os.Open(fname) + if err != nil { + return nil, Error{File: fname, Err: err} + } + + buffer := bufio.NewScanner(fp) + + lineno := 0 + ignore := false + for buffer.Scan() { + line := buffer.Text() + + lineno++ + + if len(line) == 0 || line[0] == '#' { + continue + } + + if ignore { + if strings.HasPrefix(line, "-----END") { + ignore = false + } + + continue + } + + if strings.HasPrefix(line, "-----BEGIN") { + ignore = true + continue + + } + + variable, value := parseConfigLine(line) + if len(value) == 0 { + err = fmt.Errorf("No value for variable: %s", variable) + return nil, Error{File: fname, Line: lineno, Err: err} + } + variable = strings.ToLower(variable) + config_tree[variable] = append(config_tree[variable], value) + } + + err = buffer.Err() + if err != nil { + return nil, Error{File: fname, Err: err} + } + return config_tree, nil +} + +// Returns a list of public addresses for a host-config in Go +// "net.Dial" format. +func getAddresses(cfg map[string][]string) []string { + var result []string + + for _, node := range cfg["address"] { + var port string + space := strings.IndexByte(node, ' ') + if space < 0 { + if ports, portsOk := cfg["port"]; portsOk { + port = ports[0] + } else { + port = "655" + } + } else { + port = node[space+1:] + node = node[:space] + } + + if isIPv6(node) { + result = append(result, fmt.Sprintf("[%s]:%s", node, port)) + } else { + result = append(result, fmt.Sprintf("%s:%s", node, port)) + } + } + + return result +} + +func isIPv6(node string) bool { + ip := net.ParseIP(node) + return ip != nil && ip.To4() == nil +} |