func PrintPanicStack(extras ...interface{}) { if x := recover(); x != nil { log.Error(x) i := 0 funcName, file, line, ok := runtime.Caller(i) for ok { log.Errorf("frame %v:[func:%v,file:%v,line:%v]\n", i, runtime.FuncForPC(funcName).Name(), file, line) i++ funcName, file, line, ok = runtime.Caller(i) } for k := range extras { log.Errorf("EXRAS#%v DATA:%v\n", k, spew.Sdump(extras[k])) } } }
// add a service func (p *service_pool) add_service(key, value string) { p.Lock() defer p.Unlock() service_name := filepath.Dir(key) if p.services[service_name] == nil { p.services[service_name] = &service{} log.Tracef("new service type: %v", service_name) } service := p.services[service_name] if conn, err := grpc.Dial(value, grpc.WithTimeout(DEFAULT_DIAL_TIMEOUT)); err == nil { service.clients = append(service.clients, client{key, conn}) log.Tracef("service added: %v -- %v", key, value) } else { log.Errorf("did not connect: %v -- %v err: %v", key, value, err) } }
// client protocol handle proxy func proxy_user_request(sess *Session, p []byte) []byte { start := time.Now() defer utils.PrintPanicStack(sess, p) // 解密 if sess.Flag&SESS_ENCRYPT != 0 { sess.Decoder.Codec(p) } // 封装为reader reader := packet.Reader(p) // 读客户端数据包序列号(1,2,3...) // 可避免重放攻击-REPLAY-ATTACK seq_id, err := reader.ReadU32() if err != nil { log.Error("read client timestamp failed:", err) sess.Flag |= SESS_KICKED_OUT return nil } // 读协议号 b, err := reader.ReadS16() if err != nil { log.Error("read protocol number failed.") sess.Flag |= SESS_KICKED_OUT return nil } // 数据包序列号验证 if seq_id != sess.PacketCount { log.Errorf("illegal packet sequence id:%v should be:%v proto:%v size:%v", seq_id, sess.PacketCount, b, len(p)-6) sess.Flag |= SESS_KICKED_OUT return nil } var ret []byte if b > MAX_PROTO_NUM { // game协议 // 透传 ret, err = forward(sess, p) if err != nil { log.Errorf("service id:%v execute failed", b) sess.Flag |= SESS_KICKED_OUT return nil } } else { // agent保留协议段 [0, MAX_PROTO_NUM] // handle有效性检查 h := client_handler.Handlers[b] if h == nil { log.Errorf("service id:%v not bind", b) sess.Flag |= SESS_KICKED_OUT return nil } // 执行 ret = h(sess, reader) } // 统计处理时间 elasped := time.Now().Sub(start) if b != 0 { // 排除心跳包日志 log.Trace("[REQ]", b) _statter.Timing(1.0, fmt.Sprintf("%v%v", STATSD_PREFIX, b), elasped) } return ret }