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 }
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 } } } }