|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
|
|
|
. "fmt"
|
|
|
|
"github.com/miekg/dns"
|
|
|
|
"io/ioutil"
|
|
|
|
"log"
|
|
|
|
"net"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
func load_domain(f string) (Kv, error) {
|
|
|
|
var m1 Kv
|
|
|
|
c, err := ioutil.ReadFile(f)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
err = json.Unmarshal(c, &m1)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return m1, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func parse_addr(s string) (string, string, error) {
|
|
|
|
s2 := strings.SplitN(s, ":", 2)
|
|
|
|
|
|
|
|
if len(s2) != 2 {
|
|
|
|
msg := Sprintf("error %s not well formatted", s)
|
|
|
|
err := errors.New(msg)
|
|
|
|
return "", "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
if s2[0] != "tcp" && s2[0] != "udp" {
|
|
|
|
msg := Sprintf("invalid %s, only tcp or udp allowed", s2[0])
|
|
|
|
err := errors.New(msg)
|
|
|
|
return "", "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
host, port, err := net.SplitHostPort(s2[1])
|
|
|
|
if err != nil {
|
|
|
|
return "", "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check host */
|
|
|
|
ip := net.ParseIP(host)
|
|
|
|
if ip == nil {
|
|
|
|
return "", "", errors.New(Sprintf("invalid host %s", host))
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check port */
|
|
|
|
_, err = strconv.Atoi(port)
|
|
|
|
if err != nil {
|
|
|
|
return "", "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
return s2[0], s2[1], nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func parse_server(s string) (*UpstreamServer, error) {
|
|
|
|
s1 := strings.Split(s, ",")
|
|
|
|
|
|
|
|
if len(s1) != 2 {
|
|
|
|
msg := Sprintf("error %s not well formatted", s)
|
|
|
|
err := errors.New(msg)
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
proto, addr, err := parse_addr(s1[1])
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
var c *dns.Client
|
|
|
|
if proto == "tcp" {
|
|
|
|
c = client_tcp
|
|
|
|
} else {
|
|
|
|
c = client_udp
|
|
|
|
}
|
|
|
|
|
|
|
|
d, err := load_domain(s1[0])
|
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
var sv *UpstreamServer = &UpstreamServer{
|
|
|
|
Addr: addr,
|
|
|
|
domains: d,
|
|
|
|
client: c,
|
|
|
|
Proto: proto,
|
|
|
|
}
|
|
|
|
|
|
|
|
return sv, nil
|
|
|
|
}
|