protocol.go 3.1 KB

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