コード例 #1
0
ファイル: channel.go プロジェクト: yinqiwen/gsnova
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())
			}
		}
	}
}
コード例 #2
0
ファイル: server.go プロジェクト: yinqiwen/gsnova
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)
				}()
			}
		}
	}
}