예제 #1
0
파일: dispatcher.go 프로젝트: grunya404/dns
func AddQuery(q string) Record {
	res := make(chan whois.Record)
	// could offload this in to a seperate anon function to avoid bottleneck
	s, t, err := tlds.DetectDomainAndTLD(q)
	if err != nil {
		log.Error("Whois dipatcher: Unable to detect TLD and domain: %s (%s)", err, q)
		return res
	}
	d, err := domains.GetByNameAndTLD(s, t).One()
	if err != nil {
		log.Error("Whois dispatcher: unable to get domain: %s (%s)", err, s)
		d = domains.New(s, t)
		err = d.Insert()
		if err != nil {
			log.Error("Whois dispatcher: unable to insert domain: %s (%s)", err, d.String())
			return res
		}
	}
	wr := worker.Request{
		Domain: d,
		Record: res,
	}
	Work <- wr
	return res
}
예제 #2
0
파일: watchers.go 프로젝트: grunya404/dns
func Create(w http.ResponseWriter, r *http.Request) {
	var post struct {
		Domain   string `json:"domain"`
		Name     string `json:"name"`
		Interval string `json:"interval"`
	}
	decoder := json.NewDecoder(r.Body)
	err := decoder.Decode(&post)
	if err != nil {
		util.Error(err, w)
		return
	}
	var domain domains.Domain
	if len(post.Name) > 0 {
		name, tld, err := tlds.DetectDomainAndTLD(post.Name)
		if err != nil {
			util.Error(err, w)
			return
		}
		domain, err = domains.GetByNameAndTLD(name, tld).One()
		if err != nil {
			domain = domains.New(name, tld)
			err = domain.Insert()
			if err != nil {
				util.Error(err, w)
				return
			}
		}
	} else {
		domain, err = domains.GetByUUID(post.Domain).One()
		if err != nil {
			util.Error(err, w)
			return
		}
	}
	watcher, err := db.GetByDomain(domain).One()
	if err != nil {
		watcher, err = db.New(domain, post.Interval)
		if err != nil {
			util.Error(err, w)
			return
		}
	}
	watcher.SetLowerInterval(post.Interval)
	user, err := auth.GetUser(r)
	if err != nil {
		util.Error(err, w)
		return
	}
	watcher.AddUser(*user)
	err = watcher.Save()
	log.Info("%+v", watcher)
	dispatcher.AddDomain(domain)
	util.ToJSON(watcher, err, w)
}
예제 #3
0
파일: records.go 프로젝트: grunya404/dns
// New creates a new Record, it takes the entire resource record line, the origin of the zonefile, the tld associated, the ttl and a parse date. It then creates a formalized Record.
func New(line, origin string, tld tlds.TLD, ttl uint, date time.Time, parserID int32) (Record, error) {
	fields := strings.Fields(line)
	r := Record{}

	name := fields[0]
	// set origin if it's not already there
	if !strings.HasSuffix(name, ".") {
		name += "." + origin
	}
	// strip domain name
	name = domains.CleanDomain(name, tld)
	r.Domain = domains.New(name, tld)
	name = strings.TrimSuffix(name, ".")
	name = strings.TrimSuffix(name, r.Domain.TLD.Name)
	name = strings.TrimSuffix(name, r.Domain.Name)
	name = strings.TrimSuffix(name, ".")
	// check if we are referencing top level
	if len(name) == 0 {
		name = "@"
	}
	r.Name = name

	typeIdx := 1
	if len(fields) > 3 {
		fields = util.FilterIN(fields)
	}
	if len(fields) > 3 {
		ttlFromFields, err := strconv.ParseUint(fields[1], 10, 64)
		if err == nil {
			typeIdx = 2
			ttl = uint(ttlFromFields)
		} else {
			log.Warn("Unable to parse RR: len(fields) == %d, fields: %s", len(fields), fields)
		}
	}
	if len(fields) <= typeIdx {
		return r, errors.New("Unable to set typeIdx in getRecord.")
	}
	rt, err := types.Detect(fields[typeIdx])
	if err != nil {
		return r, errors.New("Unable to detect Record Type.")
	}
	r.Type, err = types.New(rt, tld)
	r.Args.Args = fields[typeIdx+1:]
	id := uuid.NewSHA1(uuid.NameSpace_OID, []byte(
		fmt.Sprintf("%v%d", r, parserID),
	))
	r.Date = date
	r.Args.TTL = ttl
	r.UUID = id
	r.Added = time.Now()
	return r, nil
}
예제 #4
0
파일: domains.go 프로젝트: grunya404/dns
func ByName(fn func(http.ResponseWriter, *http.Request, db.Domain)) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		vars := mux.Vars(r)
		name, tld, err := tlds.DetectDomainAndTLD(vars["name"])
		if err != nil {
			util.Error(err, w)
			return
		}
		domain, err := db.GetByNameAndTLD(name, tld).One()
		if err != nil {
			domain = db.New(name, tld)
			err = domain.Insert()
			if err != nil {
				util.Error(err, w)
				return
			}
		}
		fn(w, r, domain)
	}
}
예제 #5
0
파일: whois.go 프로젝트: grunya404/dns
/*
	Search is used for retrieving whois records for a domain. It accepts the following
	GET params:

	+ uuid		- uuid of record
	+ duuid 	- uuid of domain
	+ domain	- string of domain

*/
func Search(w http.ResponseWriter, r *http.Request, params url.Values, limit, offset int) {
	query := db.SELECT
	var domain domains.Domain
	var where []string
	var args []interface{}
	var orderBy string
	i := 1
	for k, _ := range params {
		switch k {
		case "orderBy":
			orderBy = fmt.Sprintf("ORDER BY %s ", params.Get(k))
			if v, ok := params["order"]; ok {
				order := strings.ToLower(v[0])
				if order == "desc" {
					orderBy += "DESC "
				} else if order == "asc" {
					orderBy += "ASC "
				}
			}
		case "uuid":
			where = append(where, fmt.Sprintf(k+" = $%d", i))
			args = append(args, params.Get(k))
			i++
		case "duuid", "domain":
			where = append(where, fmt.Sprintf("domain = $%d", i))
			args = append(args, params.Get(k))
			v := params.Get(k)
			params.Del("duuid")
			params.Del("domain")
			params.Set("domain", v)
			i++
		case "name":
			name, tld, err := tlds.DetectDomainAndTLD(params.Get(k))
			if err != nil {
				util.Error(err, w)
				return
			}
			domain, err = domains.GetByNameAndTLD(name, tld).One()
			if err != nil {
				domain = domains.New(name, tld)
				err = domain.Insert()
				if err != nil {
					util.Error(err, w)
					return
				}
			}
			where = append(where, fmt.Sprintf("domain = $%d", i))
			args = append(args, domain.UUID.String())
			i++
		case "email":
			where = append(where, fmt.Sprintf("emails ? $%d", i))
			args = append(args, params.Get(k))
			i++
		case "raw":
			where = append(where, fmt.Sprintf("raw_whois ->>0 ILIKE $%d", i))
			args = append(args, "%"+params.Get(k)+"%")
			i++
		}
	}
	if len(where) > 0 {
		query += "WHERE " + strings.Join(where, " AND ") + " "
	}
	if len(orderBy) > 0 {
		query += orderBy + " "
	}
	query += fmt.Sprintf("ORDER BY added DESC LIMIT $%d OFFSET $%d", len(args)+1, len(args)+2)
	args = append(args, limit, offset)
	log.Info("Query: " + query)
	log.Info("Args: %+v", args)
	recordList, err := db.GetList(query, args...)
	if err != nil {
		panic(err)
	}
	// check for non sql errors
	// if we have no results dispatch a worker to get one
	if len(recordList) == 0 {
		if len(domain.Name) == 0 {
			// no domain lets grab one using what we assume is a duuid
			if duuid := params.Get("domain"); duuid != "" {
				log.Info("duuid: " + duuid)
				domain, err = domains.GetByUUID(duuid).One()
				if err != nil {
					util.Error(err, w)
					return
				}
			}
		}
		if len(domain.Name) == 0 {
			log.Error("Unable to detect domain for whois lookup, params: %+v", params)
			util.Error(errors.New("Unable to find domain for whois lookup."), w)
			return
		}
		result := <-dispatcher.AddDomain(domain)
		recordList = append(recordList, result)
	}
	util.ToJSON(recordList, err, w)
}