diff --git a/config.go b/config.go index 55f407b..2e153aa 100644 --- a/config.go +++ b/config.go @@ -63,6 +63,11 @@ func LoadConfig(path string) (state State, err error) { Name: d.Name, NameServer: &nameservers.Njalla{HTTPClient: &state.HTTPClient, Key: d.Key}, }) + case "he.net ddns": + state.Domains = append(state.Domains, Domain{ + Name: d.Name, + NameServer: &nameservers.HeNet{HTTPClient: &state.HTTPClient, Password: d.Key}, + }) default: err = errors.New("I don't know the service type " + d.Type) return diff --git a/nameservers/he_net.go b/nameservers/he_net.go new file mode 100644 index 0000000..6dd4e86 --- /dev/null +++ b/nameservers/he_net.go @@ -0,0 +1,57 @@ +package nameservers + +import ( + "context" + "errors" + "io" + "log" + "net/http" + "net/url" + "strconv" + "strings" +) + +type HeNet struct { + HTTPClient *http.Client + Password string +} + +func (h *HeNet) SetRecord(ctx context.Context, domain string, overrideIp string) (string, error) { + u, _ := url.Parse("https://dyn.dns.he.net/nic/update") + values := url.Values{ + "hostname": {domain}, + "password": {h.Password}, + } + if len(overrideIp) > 0 { + values["myip"] = []string{overrideIp} + } + u.RawQuery = values.Encode() + + req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) + if err != nil { + return "", err + } + resp, err := h.HTTPClient.Do(req) + if err != nil { + return "", err + } + body, err := io.ReadAll(resp.Body) + if err != nil { + return "", err + } + log.Printf("[he.net ddns] Response: %s", string(body)) + + things := strings.Split(string(body), " ") + if len(things) != 2 { + return "", errors.New("Response is weird") + } + + if things[0] != "good" && things[0] != "nochg" { + return "", errors.New("Failed: " + things[0]) + } + if resp.StatusCode < 200 || resp.StatusCode > 299 { + return "", errors.New("Not nice status code: " + strconv.Itoa(resp.StatusCode) + " with body: " + string(body)) + } + + return things[1], nil +}