message.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package networkdb
  2. import "github.com/gogo/protobuf/proto"
  3. const (
  4. // Max udp message size chosen to avoid network packet
  5. // fragmentation.
  6. udpSendBuf = 1400
  7. // Compound message header overhead 1 byte(message type) + 4
  8. // bytes (num messages)
  9. compoundHeaderOverhead = 5
  10. // Overhead for each embedded message in a compound message 4
  11. // bytes (len of embedded message)
  12. compoundOverhead = 4
  13. )
  14. func encodeRawMessage(t MessageType, raw []byte) ([]byte, error) {
  15. gMsg := GossipMessage{
  16. Type: t,
  17. Data: raw,
  18. }
  19. buf, err := proto.Marshal(&gMsg)
  20. if err != nil {
  21. return nil, err
  22. }
  23. return buf, nil
  24. }
  25. func encodeMessage(t MessageType, msg interface{}) ([]byte, error) {
  26. buf, err := proto.Marshal(msg.(proto.Message))
  27. if err != nil {
  28. return nil, err
  29. }
  30. buf, err = encodeRawMessage(t, buf)
  31. if err != nil {
  32. return nil, err
  33. }
  34. return buf, nil
  35. }
  36. func decodeMessage(buf []byte) (MessageType, []byte, error) {
  37. var gMsg GossipMessage
  38. err := proto.Unmarshal(buf, &gMsg)
  39. if err != nil {
  40. return MessageTypeInvalid, nil, err
  41. }
  42. return gMsg.Type, gMsg.Data, nil
  43. }
  44. // makeCompoundMessage takes a list of messages and generates
  45. // a single compound message containing all of them
  46. func makeCompoundMessage(msgs [][]byte) []byte {
  47. cMsg := CompoundMessage{}
  48. cMsg.Messages = make([]*CompoundMessage_SimpleMessage, 0, len(msgs))
  49. for _, m := range msgs {
  50. cMsg.Messages = append(cMsg.Messages, &CompoundMessage_SimpleMessage{
  51. Payload: m,
  52. })
  53. }
  54. buf, err := proto.Marshal(&cMsg)
  55. if err != nil {
  56. return nil
  57. }
  58. gMsg := GossipMessage{
  59. Type: MessageTypeCompound,
  60. Data: buf,
  61. }
  62. buf, err = proto.Marshal(&gMsg)
  63. if err != nil {
  64. return nil
  65. }
  66. return buf
  67. }
  68. // decodeCompoundMessage splits a compound message and returns
  69. // the slices of individual messages. Returns any potential error.
  70. func decodeCompoundMessage(buf []byte) ([][]byte, error) {
  71. var cMsg CompoundMessage
  72. if err := proto.Unmarshal(buf, &cMsg); err != nil {
  73. return nil, err
  74. }
  75. parts := make([][]byte, 0, len(cMsg.Messages))
  76. for _, m := range cMsg.Messages {
  77. parts = append(parts, m.Payload)
  78. }
  79. return parts, nil
  80. }