func()

in agent/session/plugin/client/client.go [433:508]


func (c *Client) writeLoopRawMode(wg *sync.WaitGroup) int {
	defer wg.Done()
	fname := "writeLoop"

	buff := make([]byte, sendPackageSize)
	br := bufio.NewReader(c.Input)
	if c.PortForward {
		// wait agent build local connect
		time.Sleep(time.Duration(3) * time.Second)
		c.real_connected = true
		if c.verbosemode {
			log.GetLogger().Info("set real_connected true")
		}
	}

	var resend_buff []byte
	for {
		time.Sleep(time.Duration(c.sendInterval) * time.Millisecond)
		// if resend_buff not empty, set read timeout avoid blocking forever
		if c.PortForward && len(resend_buff) > 0 {
			c.Input.(net.Conn).SetReadDeadline(time.Now().Add(1 * time.Second))
		}
		size, err := br.Read(buff)
		if c.PortForward {
			// cancel the read timeout
			c.Input.(net.Conn).SetReadDeadline(time.Time{})
		}
		if err != nil {
			if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
				if c.verbosemode {
					log.GetLogger().Warnln("read from local conn timeout:", err)
				}
			} else {
				log.GetLogger().Errorf("get raw input failed: %v", err)
				// tell agent to close session
				log.GetLogger().Infoln("local conn closed, send CloseMessage")
				if err = c.SendCloseMessage(); err != nil {
					log.GetLogger().Errorf("SendCloseMessage err: %v", err)
				}
				return openPoison(fname, c.poison)
			}
		}
		if size == 0 && len(resend_buff) == 0 {
			continue
		}

		data := buff[:size]

		if c.real_connected == true {
			if len(resend_buff) > 0 {
				time.Sleep(time.Duration(100) * time.Millisecond)
				c.SendStreamDataMessage(resend_buff)
				log.GetLogger().Infoln("agent ready resend user input:", string(resend_buff), len(resend_buff))
				resend_buff = nil
			}
			err = c.SendStreamDataMessage(data)
			if err != nil {
				return openPoison(fname, c.poison)
			}
			if c.verbosemode {
				log.GetLogger().Infoln("send user input:", string(data), size)
			}

		} else {
			if len(resend_buff) == 0 {
				resend_buff = make([]byte, size)
				copy(resend_buff, buff[:size])
				log.GetLogger().Infoln("store user input:", string(data), size)
			}

		}

	}

	return 0
}