forked from ejoy/goscon
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsproto.go
92 lines (77 loc) · 2.02 KB
/
sproto.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
// +build sproto
package main
import (
"encoding/binary"
"flag"
"io"
"net"
"github.com/xjdrew/gosproto"
)
type SprotoConnWrapper struct {
writer func(wr io.Writer, data []byte) (int, error)
msgType int32
}
func (scw *SprotoConnWrapper) Wrapper(local *net.TCPConn, remote net.Conn) (*net.TCPConn, error) {
aa := &sprotoAnnounceAddr{
RemoteAddr: remote.RemoteAddr().String(),
LocalAddr: remote.LocalAddr().String(),
}
pack := &sprotoPackage{
Type: scw.msgType,
}
c1 := sproto.MustEncode(pack)
c2 := sproto.MustEncode(aa)
data := sproto.Pack(append(c1, c2...))
_, err := scw.writer(local, data)
if err != nil {
return nil, err
}
return local, nil
}
func newSprotoConnWrapper(format string, msgType int) *SprotoConnWrapper {
scw := &SprotoConnWrapper{}
switch len(format) {
case 0:
format = "BS"
case 1:
format = format + "S"
}
var byteOrder binary.ByteOrder
if format[0] == 'B' {
byteOrder = binary.BigEndian
} else {
byteOrder = binary.LittleEndian
}
scw.writer = func(wr io.Writer, data []byte) (n int, err error) {
sz := len(data)
if format[1] == 'S' {
if err = binary.Write(wr, byteOrder, uint16(sz)); err != nil {
return
}
} else {
if err = binary.Write(wr, byteOrder, uint32(sz)); err != nil {
return
}
}
n, err = wr.Write(data)
return
}
scw.msgType = int32(msgType)
return scw
}
var optSprotoWrapper bool
var optSprotoWrpperFormat string
var optSprotoMessageType int
func sprotoConnWrapperHook(provier *LocalConnProvider) {
if !optSprotoWrapper {
return
}
wrapper := newSprotoConnWrapper(optSprotoWrpperFormat, optSprotoMessageType)
provier.MustSetWrapper(wrapper)
}
func init() {
flag.BoolVar(&optSprotoWrapper, "sproto", false, "sproto wrapper")
flag.StringVar(&optSprotoWrpperFormat, "sprotoFormat", "BS", "sproto header format(B/b, S:L)")
flag.IntVar(&optSprotoMessageType, "sprotoMessageType", 3, "sproto message type")
installWrapperHook(sprotoConnWrapperHook)
}