Example #1
0
func (self RedisDB) UnbanAddr(addr string) (err error) {
	_, err = self.client.Del(IP_BAN_PREFIX + addr).Result()
	isnet, ipnet := util.IsSubnet(addr)
	var start string
	var range_start string

	if isnet {
		min, max := util.IPNet2MinMax(ipnet)
		range_start = util.ZeroIPString(min)
		start = util.ZeroIPString(max)
	} else {
		_, err = self.client.Del(IP_BAN_PREFIX + addr).Result()
		return
	}
	res, err := self.client.ZRangeByLex(IP_RANGE_BAN_KR, redis.ZRangeByScore{Min: "[" + start, Max: "+", Count: 1}).Result()
	if err == nil && len(res) > 0 {
		var range_min string
		range_max := res[0]
		range_min, err = self.client.HGet(IP_RANGE_BAN_PREFIX+range_max, "start").Result()
		if err != nil {
			return
		}
		banned := strings.Compare(range_start, range_min) >= 0
		if banned {
			self.client.ZRem(IP_RANGE_BAN_KR, range_max)
			self.client.Del(IP_RANGE_BAN_PREFIX + range_max)
		}
	}
	return
}
Example #2
0
func (self RedisDB) CheckIPBanned(addr string) (banned bool, err error) {
	banned, err = self.client.Exists(IP_BAN_PREFIX + addr).Result()
	if banned {
		return
	}
	isnet, ipnet := util.IsSubnet(addr)
	var start string
	var range_start string

	if isnet {
		min, max := util.IPNet2MinMax(ipnet)
		range_start = util.ZeroIPString(min)
		start = util.ZeroIPString(max)
	} else {
		ip := net.ParseIP(addr)
		if ip == nil {
			return false, errors.New("Couldn't parse IP")
		}
		start = util.ZeroIPString(ip)
		range_start = start
	}
	res, err := self.client.ZRangeByLex(IP_RANGE_BAN_KR, redis.ZRangeByScore{Min: "[" + start, Max: "+", Count: 1}).Result()
	if err == nil && len(res) > 0 {
		var range_min string
		range_max := res[0]
		range_min, err = self.client.HGet(IP_RANGE_BAN_PREFIX+range_max, "start").Result()
		if err != nil {
			return
		}
		banned = strings.Compare(range_start, range_min) >= 0
	}

	return
}
Example #3
0
func (self RedisDB) GetMessageIDByCIDR(cidr *net.IPNet) (msgids []string, err error) {
	min, max := util.IPNet2MinMax(cidr)
	start := util.ZeroIPString(min)
	stop := util.ZeroIPString(max)
	res, err := self.client.ZRangeByLex(IP_WKR, redis.ZRangeByScore{Min: "[" + start, Max: "[" + stop}).Result()
	if err == nil && len(res) > 0 {
		for _, ip := range res {
			posts, _ := self.client.SMembers(IP_ARTICLE_KR_PREFIX + ip).Result()
			msgids = append(msgids, posts...)
		}
	}
	return
}
Example #4
0
func (self RedisDB) BanAddr(addr string) (err error) {
	isnet, ipnet := util.IsSubnet(addr)
	if !isnet {
		_, err = self.client.HMSet(IP_BAN_PREFIX+addr, "addr", addr, "made", strconv.Itoa(int(util.TimeNow()))).Result()
		return
	}
	isBanned, err := self.CheckIPBanned(addr)
	if !isBanned && err == nil { //make sure this range isn't banned already
		min, max := util.IPNet2MinMax(ipnet)
		start := util.ZeroIPString(min)
		end := util.ZeroIPString(max)
		self.clearIPRange(start, end) //delete all banned ranges that are contained within this range
		_, err = self.client.ZAdd(IP_RANGE_BAN_KR, redis.Z{Score: 0.0, Member: end}).Result()

		if err != nil {
			return
		}
		_, err = self.client.HMSet(IP_RANGE_BAN_PREFIX+end, "start", start, "end", end, "made", strconv.Itoa(int(util.TimeNow()))).Result()
	}

	return
}
Example #5
0
func (self RedisDB) DeleteArticle(msgid string) error {
	p, err := self.GetPost(msgid)
	if err == nil {
		if !p.OP {
			self.client.ZRem(THREAD_POST_WKR+p.Parent, msgid)
		}
		hash, _ := self.client.HGet(ARTICLE_PREFIX+msgid, "message_id_hash").Result()
		if hash != "" {
			self.client.Del(HASH_MESSAGEID_PREFIX + hash)
		}

		//self.client.Del(ARTICLE_PREFIX+msgid, ARTICLE_POST_PREFIX+msgid, ARTICLE_KEY_PREFIX+msgid)
		self.client.ZRem(GROUP_ARTICLE_POSTTIME_WKR_PREFIX+p.Board, msgid)
		self.client.ZRem(ARTICLE_WKR, msgid)

		headers, _ := self.client.SMembers(MESSAGEID_HEADER_KR_PREFIX + msgid).Result()
		for _, h := range headers {
			self.client.SRem(HEADER_KR_PREFIX+h, msgid)
		}
		self.client.Del(MESSAGEID_HEADER_KR_PREFIX + msgid)

		atts, _ := self.client.SMembers(ARTICLE_ATTACHMENT_KR_PREFIX + msgid).Result()
		for _, a := range atts {
			self.client.SRem(ATTACHMENT_ARTICLE_KR_PREFIX+a, msgid)
			exists, _ := self.client.Exists(ATTACHMENT_ARTICLE_KR_PREFIX + a).Result()
			if !exists { //no other post uses this attachment any more
				//TODO delete files from disk
				self.client.Del(ATTACHMENT_PREFIX + a)
			}
		}
		self.client.Del(ARTICLE_ATTACHMENT_KR_PREFIX + msgid)
		self.client.ZRem(ARTICLE_NUMBERS_PREFIX+"group::"+p.Board, msgid)

		addr := p.Addr
		ip := net.ParseIP(addr)
		if ip != nil {
			addr = util.ZeroIPString(ip)
		}
		self.client.SRem(IP_ARTICLE_KR_PREFIX+addr, msgid)
		if ip != nil {
			count, err := self.client.SRem(IP_ARTICLE_KR_PREFIX + addr).Result()
			if err == nil && count <= 0 {
				self.client.ZRem(IP_WKR, addr)
			}
		}
	}
	return err
}
Example #6
0
// register a message with the database
func (self RedisDB) RegisterArticle(message *model.Article) (err error) {
	pipe := self.client.Pipeline()
	defer pipe.Close()

	msgid := message.MessageID
	group := message.Newsgroup

	has, _ := self.HasNewsgroup(group)
	if !has {
		self.RegisterNewsgroup(group)
	}
	has, _ = self.HasArticle(msgid)
	if has {
		return
	}

	//insert IP

	addr := message.Addr
	ip := net.ParseIP(addr)

	if ip != nil {
		addr = util.ZeroIPString(ip)
		pipe.ZAddNX(IP_RANGE_BAN_KR, redis.Z{Score: 0.0, Member: addr})
	}
	pipe.SAdd(IP_ARTICLE_KR_PREFIX+addr, msgid)

	now := util.TimeNow()

	// insert article metadata
	pipe.HMSet(ARTICLE_PREFIX+msgid, "msgid", msgid, "message_id_hash", util.HashMessageID(msgid), "message_newsgroup", group, "time_obtained", strconv.Itoa(int(now)), "message_ref_id", message.Reference)
	pipe.Set(HASH_MESSAGEID_PREFIX+util.HashMessageID(msgid), msgid, 0)

	// update newsgroup
	pipe.ZAddXX(GROUP_POSTTIME_WKR, redis.Z{Score: float64(now), Member: group})
	pipe.ZAddNX(GROUP_ARTICLE_POSTTIME_WKR_PREFIX+group, redis.Z{Score: float64(now), Member: msgid})

	// insert article post
	pipe.HMSet(ARTICLE_POST_PREFIX+msgid, "newsgroup", group, "message_id", msgid, "ref_id", message.Reference, "name", message.Name, "subject", message.Subject, "path", message.Path, "time_posted", strconv.Itoa(int(message.Posted)), "message", message.Text, "addr", addr)

	if group != "ctl" { // control messages aren't added to the global keyring
		pipe.ZAddNX(ARTICLE_WKR, redis.Z{Score: float64(now), Member: msgid})
	}

	// set / update thread state
	if message.Reference == "" {
		// insert new thread for op
		pipe.ZAddNX(GROUP_THREAD_POSTTIME_WKR_PREFIX+group, redis.Z{Score: float64(message.Posted), Member: msgid})
		pipe.ZAddNX(GROUP_THREAD_BUMPTIME_WKR_PREFIX+group, redis.Z{Score: float64(message.Posted), Member: msgid})
		if group != "ctl" {
			pipe.ZAddNX(THREAD_BUMPTIME_WKR, redis.Z{Score: float64(message.Posted), Member: msgid})
		}

	} else {
		ref := message.Reference
		if !util.IsSage(message.Subject) {
			// bump it nigguh
			pipe.ZAddXX(GROUP_THREAD_BUMPTIME_WKR_PREFIX+group, redis.Z{Score: float64(message.Posted), Member: ref})
			pipe.ZAddXX(THREAD_BUMPTIME_WKR, redis.Z{Score: float64(message.Posted), Member: ref})
		}
		// update last posted
		pipe.ZAddXX(GROUP_THREAD_POSTTIME_WKR_PREFIX+group, redis.Z{Score: float64(message.Posted), Member: ref})
		pipe.ZAddNX(THREAD_POST_WKR+ref, redis.Z{Score: float64(message.Posted), Member: msgid})
	}
	// register article header
	for k, val := range message.Header {
		k = strings.ToLower(k)
		for _, v := range val {
			k = strings.ToLower(k)
			header := "Name::" + k + "::Value::" + v
			pipe.SAdd(HEADER_KR_PREFIX+header, msgid)
			pipe.SAdd(MESSAGEID_HEADER_KR_PREFIX+msgid, header)
		}
	}
	// add nntp message numbers
	number, _ := self.client.ZIncrBy(ARTICLE_NUMBERS_PREFIX+"last", float64(1), group).Result()
	pipe.ZAddNX(ARTICLE_NUMBERS_PREFIX+"group::"+group, redis.Z{Score: number, Member: msgid})

	// register all attachments
	atts := message.Attachments
	if atts != nil {
		for _, att := range atts {
			hash := att.Hash
			pipe.SAdd(ATTACHMENT_ARTICLE_KR_PREFIX+hash, msgid)
			pipe.SAdd(ARTICLE_ATTACHMENT_KR_PREFIX+msgid, hash)
			pipe.HSetNX(ATTACHMENT_PREFIX+hash, "message_id", msgid)
			pipe.HSetNX(ATTACHMENT_PREFIX+hash, "sha_hash", hash)
			pipe.HSetNX(ATTACHMENT_PREFIX+hash, "filename", att.Name)
			pipe.HSetNX(ATTACHMENT_PREFIX+hash, "filepath", att.Path)
			pipe.HSetNX(ATTACHMENT_PREFIX+hash, "mime", att.Mime)
		}
	}

	_, err = pipe.Exec()
	if err != nil {
		log.Println("failed to register nntp article", err)
	}
	return
}