func (handler *_TransProxyHandler) forward(server Server, message *gorpc.Message) error { handler.V("forward tunnel(%s) message", handler.device) tunnel := gorpc.NewTunnel() tunnel.ID = handler.device tunnel.Message = message var buff bytes.Buffer err := gorpc.WriteTunnel(&buff, tunnel) if err != nil { return err } message.Code = gorpc.CodeTunnel message.Content = buff.Bytes() err = server.SendMessage(message) if err == nil { handler.V("forward tunnel(%s) message(%p) -- success", handler.device, message) } else { handler.E("forward tunnel(%s) message -- failed\n%s", handler.device, err) } return err }
func (handler *_TunnelClient) SendMessage(device *gorpc.Device, message *gorpc.Message) error { tunnel := gorpc.NewTunnel() tunnel.ID = device tunnel.Message = message var buff bytes.Buffer err := gorpc.WriteTunnel(&buff, tunnel) if err != nil { return err } message.Code = gorpc.CodeTunnel message.Content = buff.Bytes() handler.context.Send(message) return nil }
func (handler *_CryptoServer) MessageReceived(context gorpc.Context, message *gorpc.Message) (*gorpc.Message, error) { if message.Code == gorpc.CodeHeartbeat { return message, nil } if handler.block == nil { handler.V("expect WhoAmI message") // expect whoAmI message if message.Code != gorpc.CodeWhoAmI { context.Close() return nil, gserrors.Newf(gorpc.ErrRPC, "expect WhoAmI message but got(%s)", message.Code) } handler.V("parse WhoAmI message") whoAmI, err := gorpc.ReadWhoAmI(bytes.NewBuffer(message.Content)) if err != nil { context.Close() return nil, err } val, ok := new(big.Int).SetString(string(whoAmI.Context), 0) if !ok { context.Close() return nil, gserrors.Newf(gorpc.ErrRPC, "parse WhoAmI#Context as big.Int error") } dhKey, err := handler.resovler.Resolve(whoAmI.ID) if err != nil { context.Close() return nil, err } message.Code = gorpc.CodeAccept message.Content = []byte(dhKey.Exchange().String()) context.Send(message) key := make([]byte, des.BlockSize) keyval := dhKey.Gen(val).Uint64() binary.BigEndian.PutUint64(key[:8], keyval) handler.V("shared key \n\t%d\n\t%v ", keyval, key) block, err := des.NewCipher(key) if err != nil { context.Close() return nil, gserrors.Newf(err, "create new des Cipher error") } handler.block = block handler.device = whoAmI.ID context.FireActive() for _, message := range handler.cached { message, _ = handler.MessageSending(context, message) context.Send(message) } handler.cached = nil handler.V("%s handshake -- success", context.Name()) return nil, nil } blocksize := handler.block.BlockSize() if len(message.Content)%blocksize != 0 { context.Close() return nil, gserrors.Newf(gorpc.ErrRPC, "invalid encrypt data") } blocks := len(message.Content) / blocksize for i := 0; i < blocks; i++ { offset := i * blocksize v := message.Content[offset : offset+blocksize] handler.block.Decrypt(v, v) } message.Content = PKCS5UnPadding(message.Content) return message, nil }
func (handler *_TransProxyHandler) MessageReceived(context gorpc.Context, message *gorpc.Message) (*gorpc.Message, error) { if message.Code == gorpc.CodeResponse { if server, ok := handler.tunnel(message.Agent); ok { err := handler.forward(server, message) if err != nil { context.Close() } return nil, err } return message, nil } if message.Code != gorpc.CodeRequest { return message, nil } request, err := gorpc.ReadRequest(bytes.NewBuffer(message.Content)) if err != nil { handler.E("[%s] unmarshal request error\n%s", handler.proxy.name, err) return nil, err } service := request.Service if transproxy, ok := handler.transproxy(service); ok { handler.V("forward tunnel(%s) message", handler.device) tunnel := gorpc.NewTunnel() tunnel.ID = handler.device tunnel.Message = message var buff bytes.Buffer err := gorpc.WriteTunnel(&buff, tunnel) if err != nil { return nil, err } message.Code = gorpc.CodeTunnel message.Content = buff.Bytes() err = transproxy.SendMessage(message) if err != nil { context.Close() handler.V("forward tunnel(%s) message(%p) -- failed\n%s", handler.device, message, err) return nil, err } handler.V("forward tunnel(%s) message(%p) -- success", handler.device, message) return nil, err } return message, nil }