Пример #1
0
//----------------------------------------------- Start Agent when a client is connected
func StartAgent(sess *Session, in chan []byte, out *Buffer) {
	wg.Add(1)
	defer wg.Done()
	defer helper.PrintPanicStack()

	// init session
	sess.MQ = make(chan IPCObject, DEFAULT_MQ_SIZE)
	sess.ConnectTime = time.Now()
	sess.LastPacketTime = time.Now()

	// custom-sec timer, 60-sec
	custom_timer := make(chan int32, 1)
	timer.Add(-1, time.Now().Unix()+CUSTOM_TIMER, custom_timer)

	// cleanup work
	defer func() {
		close_work(sess)
	}()

	// the main message loop
	for {
		select {
		case msg, ok := <-in: // network protocol
			if !ok {
				return
			}

			sess.PacketTime = time.Now()
			if result := UserRequestProxy(sess, msg); result != nil {
				err := out.Send(result)
				if err != nil {
					helper.ERR("cannot send to client", err)
					return
				}
			}
			sess.LastPacketTime = sess.PacketTime
			sess.PacketCount++ // packet count
		case msg := <-sess.MQ: // internal IPC
			if result := IPCRequestProxy(sess, &msg); result != nil {
				err := out.Send(result)
				if err != nil {
					helper.ERR("cannot send ipc response", err)
					return
				}
			}
		case <-custom_timer: // 60-sec timer
			timer_work(sess)
			timer.Add(-1, time.Now().Unix()+CUSTOM_TIMER, custom_timer)
		case <-die:
			sess.Flag |= SESS_KICKED_OUT
		}

		// is the session been kicked out
		if sess.Flag&SESS_KICKED_OUT != 0 {
			return
		}
	}
}
Пример #2
0
//----------------------------------------------- user's timer
func timer_work(sess *Session) {
	if sess.Flag&SESS_LOGGED_IN == 0 {
		return
	}

	// SIGTERM check
	if atomic.LoadInt32(&SIGTERM) == 1 {
		sess.Flag |= SESS_KICKED_OUT
		helper.NOTICE("SIGTERM received, user exits.", sess.User.Id, sess.User.Name)
	}

	// limit rate of request per minute
	config := cfg.Get()
	rpm_limit, _ := strconv.ParseFloat(config["rpm_limit"], 32)
	rpm := float64(sess.PacketCount) / float64(time.Now().Unix()-sess.ConnectTime.Unix()) * 60

	if rpm > rpm_limit {
		sess.Flag |= SESS_KICKED_OUT
		helper.ERR("user RPM too high", sess.User.Id, sess.User.Name, "RPM:", rpm)
		return
	}

	// try save the data
	_flush_work(sess)
}