commands.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. package raw
  2. import (
  3. "errors"
  4. "io"
  5. v2net "github.com/v2ray/v2ray-core/common/net"
  6. "github.com/v2ray/v2ray-core/common/protocol"
  7. "github.com/v2ray/v2ray-core/common/serial"
  8. "github.com/v2ray/v2ray-core/common/uuid"
  9. "github.com/v2ray/v2ray-core/transport"
  10. )
  11. var (
  12. ErrorCommandTypeMismatch = errors.New("Command type mismatch.")
  13. ErrorUnknownCommand = errors.New("Unknown command.")
  14. )
  15. func MarshalCommand(command interface{}, writer io.Writer) error {
  16. var factory CommandFactory
  17. switch command.(type) {
  18. case *protocol.CommandSwitchAccount:
  19. factory = new(CommandSwitchAccountFactory)
  20. default:
  21. return ErrorUnknownCommand
  22. }
  23. return factory.Marshal(command, writer)
  24. }
  25. func UnmarshalCommand(cmdId byte, data []byte) (protocol.ResponseCommand, error) {
  26. var factory CommandFactory
  27. switch cmdId {
  28. case 1:
  29. factory = new(CommandSwitchAccountFactory)
  30. default:
  31. return nil, ErrorUnknownCommand
  32. }
  33. return factory.Unmarshal(data)
  34. }
  35. type CommandFactory interface {
  36. Marshal(command interface{}, writer io.Writer) error
  37. Unmarshal(data []byte) (interface{}, error)
  38. }
  39. type CommandSwitchAccountFactory struct {
  40. }
  41. func (this *CommandSwitchAccountFactory) Marshal(command interface{}, writer io.Writer) error {
  42. cmd, ok := command.(*protocol.CommandSwitchAccount)
  43. if !ok {
  44. return ErrorCommandTypeMismatch
  45. }
  46. hostStr := ""
  47. if cmd.Host != nil {
  48. hostStr = cmd.Host.String()
  49. }
  50. writer.Write([]byte{byte(len(hostStr))})
  51. if len(hostStr) > 0 {
  52. writer.Write([]byte(hostStr))
  53. }
  54. writer.Write(cmd.Port.Bytes())
  55. idBytes := cmd.ID.Bytes()
  56. writer.Write(idBytes)
  57. writer.Write(cmd.AlterIds.Bytes())
  58. writer.Write([]byte{byte(cmd.Level)})
  59. writer.Write([]byte{cmd.ValidMin})
  60. return nil
  61. }
  62. func (this *CommandSwitchAccountFactory) Unmarshal(data []byte) (interface{}, error) {
  63. cmd := new(protocol.CommandSwitchAccount)
  64. if len(data) == 0 {
  65. return nil, transport.ErrorCorruptedPacket
  66. }
  67. lenHost := int(data[0])
  68. if len(data) < lenHost+1 {
  69. return nil, transport.ErrorCorruptedPacket
  70. }
  71. if lenHost > 0 {
  72. cmd.Host = v2net.ParseAddress(string(data[1 : 1+lenHost]))
  73. }
  74. portStart := 1 + lenHost
  75. if len(data) < portStart+2 {
  76. return nil, transport.ErrorCorruptedPacket
  77. }
  78. cmd.Port = v2net.PortFromBytes(data[portStart : portStart+2])
  79. idStart := portStart + 2
  80. if len(data) < idStart+16 {
  81. return nil, transport.ErrorCorruptedPacket
  82. }
  83. cmd.ID, _ = uuid.ParseBytes(data[idStart : idStart+16])
  84. alterIdStart := idStart + 16
  85. if len(data) < alterIdStart+2 {
  86. return nil, transport.ErrorCorruptedPacket
  87. }
  88. cmd.AlterIds = serial.BytesLiteral(data[alterIdStart : alterIdStart+2]).Uint16()
  89. levelStart := alterIdStart + 2
  90. if len(data) < levelStart+1 {
  91. return nil, transport.ErrorCorruptedPacket
  92. }
  93. cmd.Level = protocol.UserLevel(data[levelStart])
  94. timeStart := levelStart + 1
  95. if len(data) < timeStart {
  96. return nil, transport.ErrorCorruptedPacket
  97. }
  98. cmd.ValidMin = data[timeStart]
  99. return cmd, nil
  100. }