forked from mutecomm/mute
-
Notifications
You must be signed in to change notification settings - Fork 0
/
inner.go
102 lines (92 loc) · 2.57 KB
/
inner.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Copyright (c) 2015 Mute Communications Ltd.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package msg
import (
"encoding/binary"
"io"
"github.com/mutecomm/mute/log"
)
// inner header types
const (
paddingType = 1 // random padding data to fill packet
dataType = 2 // data
signType = 4 // packet will be included in signature
signatureType = 8 // signature
)
// inner header size
const innerHeaderSize = 5 // without any content
type innerHeader struct {
// 1: Padding (random padding data to fill packet)
// 2: Data
// 4: Sign (packet will be included in signature)
// 8: Signature
Type uint8
PLen uint16 // Length of the packet NOT including header.
More uint8 // If set to 1, at least 1 more packet follows.
Skip uint8 // Skip N bytes following header... additional padding scheme. Zero in most cases.
content []byte
}
func newInnerHeader(ihType uint8, more bool, content []byte) *innerHeader {
var ih innerHeader
ih.Type = ihType
ih.PLen = uint16(len(content))
if more {
ih.More = 1
}
ih.content = content
return &ih
}
func (ih *innerHeader) size() int {
return 1 + 2 + 1 + 1 + len(ih.content)
}
func (ih *innerHeader) write(w io.Writer) error {
if err := binary.Write(w, binary.BigEndian, ih.Type); err != nil {
return log.Error(err)
}
if err := binary.Write(w, binary.BigEndian, ih.PLen); err != nil {
return log.Error(err)
}
if err := binary.Write(w, binary.BigEndian, ih.More); err != nil {
return log.Error(err)
}
if err := binary.Write(w, binary.BigEndian, ih.Skip); err != nil {
return log.Error(err)
}
if _, err := w.Write(ih.content); err != nil {
return log.Error(err)
}
return nil
}
func readInnerHeader(r io.Reader) (*innerHeader, error) {
var ih innerHeader
// read Type
if err := binary.Read(r, binary.BigEndian, &ih.Type); err != nil {
return nil, err
}
// check Type
if ih.Type != paddingType &&
ih.Type != dataType &&
ih.Type != dataType|signType &&
ih.Type != signatureType {
return nil, log.Errorf("msg: invalid inner header type %d", ih.Type)
}
// read Plen
if err := binary.Read(r, binary.BigEndian, &ih.PLen); err != nil {
return nil, log.Error(err)
}
// read More
if err := binary.Read(r, binary.BigEndian, &ih.More); err != nil {
return nil, log.Error(err)
}
// read Skip
if err := binary.Read(r, binary.BigEndian, &ih.Skip); err != nil {
return nil, log.Error(err)
}
// read content
ih.content = make([]byte, ih.PLen)
if _, err := io.ReadFull(r, ih.content); err != nil {
return nil, log.Error(err)
}
return &ih, nil
}