protocol.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // Copyright (C) 2015 Audrius Butkevicius and Contributors (see the CONTRIBUTORS file).
  2. package protocol
  3. import (
  4. "errors"
  5. "io"
  6. )
  7. const (
  8. magic = 0x9E79BC40
  9. ProtocolName = "bep-relay"
  10. )
  11. var (
  12. ResponseSuccess = Response{0, "success"}
  13. ResponseNotFound = Response{1, "not found"}
  14. ResponseAlreadyConnected = Response{2, "already connected"}
  15. ResponseUnexpectedMessage = Response{100, "unexpected message"}
  16. )
  17. func WriteMessage(w io.Writer, message interface{}) error {
  18. header := header{
  19. magic: magic,
  20. }
  21. var payload []byte
  22. var err error
  23. switch msg := message.(type) {
  24. case Ping:
  25. payload, err = msg.MarshalXDR()
  26. header.messageType = messageTypePing
  27. case Pong:
  28. payload, err = msg.MarshalXDR()
  29. header.messageType = messageTypePong
  30. case JoinRelayRequest:
  31. payload, err = msg.MarshalXDR()
  32. header.messageType = messageTypeJoinRelayRequest
  33. case JoinSessionRequest:
  34. payload, err = msg.MarshalXDR()
  35. header.messageType = messageTypeJoinSessionRequest
  36. case Response:
  37. payload, err = msg.MarshalXDR()
  38. header.messageType = messageTypeResponse
  39. case ConnectRequest:
  40. payload, err = msg.MarshalXDR()
  41. header.messageType = messageTypeConnectRequest
  42. case SessionInvitation:
  43. payload, err = msg.MarshalXDR()
  44. header.messageType = messageTypeSessionInvitation
  45. case RelayFull:
  46. payload, err = msg.MarshalXDR()
  47. header.messageType = messageTypeRelayFull
  48. default:
  49. err = errors.New("unknown message type")
  50. }
  51. if err != nil {
  52. return err
  53. }
  54. header.messageLength = int32(len(payload))
  55. headerpayload, err := header.MarshalXDR()
  56. if err != nil {
  57. return err
  58. }
  59. _, err = w.Write(append(headerpayload, payload...))
  60. return err
  61. }
  62. func ReadMessage(r io.Reader) (interface{}, error) {
  63. var header header
  64. buf := make([]byte, header.XDRSize())
  65. if _, err := io.ReadFull(r, buf); err != nil {
  66. return nil, err
  67. }
  68. if err := header.UnmarshalXDR(buf); err != nil {
  69. return nil, err
  70. }
  71. if header.magic != magic {
  72. return nil, errors.New("magic mismatch")
  73. }
  74. buf = make([]byte, int(header.messageLength))
  75. if _, err := io.ReadFull(r, buf); err != nil {
  76. return nil, err
  77. }
  78. switch header.messageType {
  79. case messageTypePing:
  80. var msg Ping
  81. err := msg.UnmarshalXDR(buf)
  82. return msg, err
  83. case messageTypePong:
  84. var msg Pong
  85. err := msg.UnmarshalXDR(buf)
  86. return msg, err
  87. case messageTypeJoinRelayRequest:
  88. var msg JoinRelayRequest
  89. err := msg.UnmarshalXDR(buf)
  90. return msg, err
  91. case messageTypeJoinSessionRequest:
  92. var msg JoinSessionRequest
  93. err := msg.UnmarshalXDR(buf)
  94. return msg, err
  95. case messageTypeResponse:
  96. var msg Response
  97. err := msg.UnmarshalXDR(buf)
  98. return msg, err
  99. case messageTypeConnectRequest:
  100. var msg ConnectRequest
  101. err := msg.UnmarshalXDR(buf)
  102. return msg, err
  103. case messageTypeSessionInvitation:
  104. var msg SessionInvitation
  105. err := msg.UnmarshalXDR(buf)
  106. return msg, err
  107. case messageTypeRelayFull:
  108. var msg RelayFull
  109. err := msg.UnmarshalXDR(buf)
  110. return msg, err
  111. }
  112. return nil, errors.New("unknown message type")
  113. }