func (rc *RemoteChannel) heartbeat() { ticker := time.NewTicker(time.Duration(rc.HeartBeatPeriod) * time.Second) for rc.running { select { case <-ticker.C: if !rc.C.Closed() && (GConf.ChannelKeepAlive || getProxySessionSize() > 0) { rc.Write(event.NewHeartBeatEvent()) } } } }
func serveProxyConn(conn net.Conn, vs *vpsServer) { if nil != vs { atomic.AddInt32(&vs.aliveConns, 1) } atomic.AddInt32(&totalConn, 1) bufconn := bufio.NewReader(conn) deferFunc := func() { conn.Close() atomic.AddInt32(&totalConn, -1) if nil != vs { atomic.AddInt32(&vs.aliveConns, -1) } } defer deferFunc() ctx := remote.NewConnContext() writeEvents := func(evs []event.Event, buf *bytes.Buffer) error { if len(evs) > 0 { buf.Reset() for _, ev := range evs { if nil != ev { event.EncryptEvent(buf, ev, &ctx.CryptoContext) } } if buf.Len() > 0 { conn.SetWriteDeadline(time.Now().Add(15 * time.Second)) b := buf.Bytes() _, err := conn.Write(b) return err } } return nil } var rbuf bytes.Buffer var wbuf bytes.Buffer writeTaskRunning := false connClosed := false reader := &helper.BufferChunkReader{bufconn, nil} for !connClosed { conn.SetReadDeadline(time.Now().Add(60 * time.Second)) rbuf.Grow(8192) rbuf.ReadFrom(reader) if nil != reader.Err { conn.Close() connClosed = true } ress, err := remote.HandleRequestBuffer(&rbuf, ctx) if nil != err { if err != event.EBNR { log.Printf("[ERROR]connection %s:%d error:%v", ctx.User, ctx.ConnIndex, err) conn.Close() connClosed = true return } } else { writeEvents(ress, &wbuf) if !writeTaskRunning && len(ctx.User) > 0 && ctx.ConnIndex >= 0 { writeTaskRunning = true go func() { var lastEventTime time.Time queue := remote.GetEventQueue(ctx.ConnId, true) for !connClosed { evs, err := queue.PeekMulti(10, 1*time.Millisecond, false) now := time.Now() if ctx.Closing { evs = []event.Event{&event.ChannelCloseACKEvent{}} if remote.ServerConf.MaxDynamicPort > 0 { nvs := selectDynamicVPServer() if nil != nvs { evs = append(evs, &event.PortUnicastEvent{Port: nvs.port}) } } } else { if nil != err { if remote.GetSessionTableSize() > 0 && lastEventTime.Add(10*time.Second).Before(now) { evs = []event.Event{event.NewHeartBeatEvent()} } else { continue } } } err = writeEvents(evs, &wbuf) if nil != err { log.Printf("TCP write error####:%v %d", err, len(evs)) } else { queue.DiscardPeeks(false) } if ctx.Closing { break } lastEventTime = now if nil != err { log.Printf("TCP write error:%v", err) conn.Close() break } else { //queue.DiscardPeeks(false) } } remote.ReleaseEventQueue(queue) }() } } } }