コード例 #1
0
ファイル: http.go プロジェクト: yinqiwen/gsnova
func (hc *httpChannel) getHTTPReconnectPeriod() int {
	period := hc.conf.ReconnectPeriod
	if period == 0 {
		period = 30
	}
	if hc.conf.RCPRandomAdjustment > 0 && period > hc.conf.RCPRandomAdjustment {
		adjust := hc.conf.RCPRandomAdjustment
		period = helper.RandBetween(period-adjust, period+adjust)
	}
	return period
}
コード例 #2
0
ファイル: channel.go プロジェクト: yinqiwen/gsnova
func (rc *RemoteChannel) processRead() {
	var buf bytes.Buffer
	reconnectCount := 0
	for rc.running {
		conn := rc.C
		if conn.Closed() {
			rc.closeState = 0
			if rc.authed() && getProxySessionSize() == 0 && !GConf.ChannelKeepAlive {
				time.Sleep(10 * time.Millisecond)
				continue
			}
			if !rc.authed() && reconnectCount > 0 {
				rc.Stop()
				rc.authResult = event.ErrAuthFailed
				log.Printf("Channel[%d] auth failed since remote server disconnect.", rc.Index)
				return
			}
			rc.resetCryptoCtx()
			buf.Reset()
			rc.connSendedEvents = 0
			conn.SetCryptoCtx(&rc.cryptoCtx)
			err := conn.Open()
			reconnectCount++
			if nil != err {
				log.Printf("Channel[%d] connect %s failed:%v.", rc.Index, rc.Addr, err)
				time.Sleep(1 * time.Second)
				continue
			}
			rc.connectTime = time.Now()
			if rc.ReconnectPeriod > 0 {
				period := rc.ReconnectPeriod
				if rc.RCPRandomAdjustment > 0 && rc.RCPRandomAdjustment < period {
					period = helper.RandBetween(period-rc.RCPRandomAdjustment, period+rc.RCPRandomAdjustment)
				}
				rc.nextReconnectTime = rc.connectTime.Add(time.Duration(period) * time.Second)
			}
			log.Printf("Channel[%d] connect %s success.", rc.Index, rc.Addr)
			if rc.OpenJoinAuth {
				rc.Write(nil)
			}
		}
		reader := &helper.BufferChunkReader{conn, nil}
		for {
			//buf.Truncate(buf.Len())
			buf.Grow(8192)
			buf.ReadFrom(reader)
			cerr := reader.Err
			//n, cerr := conn.Read(data)
			//buf.Write(data[0:n])
			if rc.ReconnectPeriod > 0 && rc.closeState == 0 && nil == cerr {
				if rc.nextReconnectTime.Before(time.Now()) {
					rc.closeState = stateCloseToSendReq
					rc.Write(nil) //trigger to write ChannelCloseReqEvent
					log.Printf("Channel[%d] prepare to close %s to reconnect.", rc.Index, rc.Addr)
				}
			}
			for buf.Len() > 0 {
				err, ev := event.DecryptEvent(&buf, &rc.cryptoCtx)
				if nil != err {
					if err == event.EBNR {
						err = nil
					} else {
						log.Printf("Channel[%d]Failed to decode event for reason:%v with iv:%d", rc.Index, err, rc.cryptoCtx.DecryptIV)
						conn.Close()
					}
					break
				}
				switch ev.(type) {
				case *event.NotifyEvent:
					if !rc.authed() {
						auth := ev.(*event.NotifyEvent)
						rc.authResult = int(auth.Code)
						if rc.authResult != event.SuccessAuthed {
							rc.Stop()
							return
						}
						continue
					}
				case *event.ChannelCloseACKEvent:
					conn.Close()
					log.Printf("Channel[%d] close %s after recved close ACK.", rc.Index, rc.Addr)
					continue
				case *event.PortUnicastEvent:
					//log.Printf("Channel[%d] recv %v.", rc.Index, ev)
					rc.C.HandleCtrlEvent(ev)
					continue
				}
				if !rc.authed() {
					log.Printf("[ERROR]Expected auth result event for auth all connection, but got %T.", ev)
					conn.Close()
					continue
				}
				HandleEvent(ev)
			}
			if nil != cerr {
				if cerr != io.EOF && cerr != ErrChannelReadTimeout {
					log.Printf("Failed to read channel for reason:%v", cerr)
				}
				conn.Close()
				break
			}
		}
	}
}