package main import ( "encoding/json" "errors" "fmt" "strings" "time" "github.com/julienschmidt/httprouter" "github.com/miekg/dns" "git.nemunai.re/srs/adlin/libadlin" ) type checkGLUE struct { Domain string `json:"domain"` IP string `json:"ip"` } func init() { router.POST("/api/check/GLUE", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { var uc checkGLUE if err := json.Unmarshal(body, &uc); err != nil { return nil, err } return true, check_GLUE_respond(student, uc.Domain, uc.IP) })) } func check_GLUE_respond(student *adlin.Student, domain string, ip string) (err error) { if !strings.HasPrefix(ip, adlin.StudentIP(student.Id, 0).String()) { return fmt.Errorf("%q is not your IP range", ip) } client := dns.Client{Net: "tcp", Timeout: time.Second * 5} m := new(dns.Msg) m.SetQuestion(domain, dns.TypeAAAA) m.RecursionDesired = false m.SetEdns0(4096, true) var r *dns.Msg r, _, err = client.Exchange(m, fmt.Sprintf("[%s]:53", ip)) if err != nil { return } if r == nil { return errors.New("Response from name server is nil") } if r.Rcode != dns.RcodeSuccess { return fmt.Errorf("Name server returns %s", dns.RcodeToString[r.Rcode]) } if len(r.Answer) == 0 { return errors.New("Empty response for this NS record") } found := false for _, answer := range r.Answer { if t, ok := answer.(*dns.AAAA); ok { found = found || t.AAAA.String() == ip } } if !found { return fmt.Errorf("%q not found in records", ip) } return }