func (rc *RemoteChannel) Request(ev event.Event) (event.Event, error) { var buf bytes.Buffer auth := NewAuthEvent(rc.SecureTransport) auth.Index = int64(rc.Index) if auth.EncryptMethod == event.Chacha20Encrypter { auth.EncryptMethod = event.Salsa20Encrypter } ctx := randCryptoCtx() ctx.Method = auth.EncryptMethod auth.IV = ctx.EncryptIV event.EncryptEvent(&buf, auth, &ctx) event.EncryptEvent(&buf, ev, &ctx) //event.EncodeEvent(&buf, ev) res, err := rc.C.Request(buf.Bytes()) if nil != err { return nil, err } rbuf := bytes.NewBuffer(res) var rev event.Event err, rev = event.DecryptEvent(rbuf, &ctx) if nil != err { return nil, err } return rev, nil }
func httpInvoke(w http.ResponseWriter, r *http.Request) { b := make([]byte, r.ContentLength) r.Body.Read(b) buf := bytes.NewBuffer(b) ctx := appengine.NewContext(r) var cryptoContext event.CryptoContext err, ev := event.DecryptEvent(buf, &cryptoContext) if nil != err { ctx.Errorf("Decode auth event failed:%v", err) return } //var iv uint64 if auth, ok := ev.(*event.AuthEvent); ok { if !remote.ServerConf.VerifyUser(auth.User) { return } cryptoContext.DecryptIV = auth.IV cryptoContext.EncryptIV = auth.IV cryptoContext.Method = auth.EncryptMethod } else { ctx.Errorf("Expected auth event, but got %T", ev) return } err, ev = event.DecryptEvent(buf, &cryptoContext) if nil != err { ctx.Errorf("Decode http request event failed:%v", err) return } if req, ok := ev.(*event.HTTPRequestEvent); ok { res := fetch(ctx, req) var resbuf bytes.Buffer event.EncryptEvent(&resbuf, res, &cryptoContext) headers := w.Header() headers.Add("Content-Type", "application/octet-stream") headers.Add("Content-Length", strconv.Itoa(resbuf.Len())) w.WriteHeader(http.StatusOK) w.Write(resbuf.Bytes()) } else { ctx.Errorf("Expected http request event, but got %T", ev) return } }
func HandleRequestBuffer(reqbuf *bytes.Buffer, ctx *ConnContext) ([]event.Event, error) { var ress []event.Event for reqbuf.Len() > 0 { var ev event.Event var err error err, ev = event.DecryptEvent(reqbuf, &ctx.CryptoContext) if nil != err { if err != event.EBNR { log.Printf("Failed to decode event for reason:%v %d", err, ctx.CryptoContext.DecryptIV) } return ress, err } res, err := handleEvent(ev, ctx) if nil != res { ress = append(ress, res) } if nil != err { return ress, err } } return ress, nil }
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 } } } }